Upgraded eslint
This commit is contained in:
parent
b896a2e086
commit
1d8b67c321
@ -2,6 +2,7 @@ var path = require('path')
|
|||||||
var webpack = require('webpack')
|
var webpack = require('webpack')
|
||||||
var utils = require('./utils')
|
var utils = require('./utils')
|
||||||
var config = require('../config')
|
var config = require('../config')
|
||||||
|
var VueLoaderPlugin = require('vue-loader/lib/plugin')
|
||||||
var vueLoaderConfig = require('./vue-loader.conf')
|
var vueLoaderConfig = require('./vue-loader.conf')
|
||||||
var StylelintPlugin = require('stylelint-webpack-plugin')
|
var StylelintPlugin = require('stylelint-webpack-plugin')
|
||||||
var FaviconsWebpackPlugin = require('favicons-webpack-plugin')
|
var FaviconsWebpackPlugin = require('favicons-webpack-plugin')
|
||||||
@ -81,6 +82,7 @@ module.exports = {
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
|
new VueLoaderPlugin(),
|
||||||
new StylelintPlugin({
|
new StylelintPlugin({
|
||||||
files: ['**/*.vue', '**/*.scss']
|
files: ['**/*.vue', '**/*.scss']
|
||||||
}),
|
}),
|
||||||
|
@ -98,6 +98,7 @@ var webpackConfig = merge(baseWebpackConfig, {
|
|||||||
ServiceWorker: {
|
ServiceWorker: {
|
||||||
events: true
|
events: true
|
||||||
},
|
},
|
||||||
|
AppCache: true,
|
||||||
excludes: ['**/.*', '**/*.map', '**/index.html', '**/static/oauth2/callback.html', '**/icons-*/*.png', '**/static/fonts/KaTeX_*'],
|
excludes: ['**/.*', '**/*.map', '**/index.html', '**/static/oauth2/callback.html', '**/icons-*/*.png', '**/static/fonts/KaTeX_*'],
|
||||||
externals: ['/', '/app', '/oauth2/callback']
|
externals: ['/', '/app', '/oauth2/callback']
|
||||||
})
|
})
|
||||||
|
@ -14,7 +14,7 @@ function resolve (dir) {
|
|||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
entry: {
|
entry: {
|
||||||
style: './src/components/style.scss'
|
style: './src/styles/'
|
||||||
},
|
},
|
||||||
module: {
|
module: {
|
||||||
rules: [{
|
rules: [{
|
||||||
|
5741
package-lock.json
generated
5741
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
79
package.json
79
package.json
@ -28,13 +28,13 @@
|
|||||||
"clipboard": "^1.7.1",
|
"clipboard": "^1.7.1",
|
||||||
"compression": "^1.7.0",
|
"compression": "^1.7.0",
|
||||||
"diff-match-patch": "^1.0.0",
|
"diff-match-patch": "^1.0.0",
|
||||||
"file-saver": "^1.3.3",
|
"file-saver": "^1.3.8",
|
||||||
"google-id-token-verifier": "^0.2.3",
|
"google-id-token-verifier": "^0.2.3",
|
||||||
"handlebars": "^4.0.10",
|
"handlebars": "^4.0.10",
|
||||||
"indexeddbshim": "^3.0.4",
|
"indexeddbshim": "^3.6.2",
|
||||||
"js-yaml": "^3.9.1",
|
"js-yaml": "^3.11.0",
|
||||||
"katex": "^0.9.0-alpha1",
|
"katex": "^0.9.0",
|
||||||
"markdown-it": "^8.3.1",
|
"markdown-it": "^8.4.1",
|
||||||
"markdown-it-abbr": "^1.0.4",
|
"markdown-it-abbr": "^1.0.4",
|
||||||
"markdown-it-deflist": "^2.0.2",
|
"markdown-it-deflist": "^2.0.2",
|
||||||
"markdown-it-emoji": "^1.3.0",
|
"markdown-it-emoji": "^1.3.0",
|
||||||
@ -46,20 +46,20 @@
|
|||||||
"markdown-it-sup": "^1.0.0",
|
"markdown-it-sup": "^1.0.0",
|
||||||
"mermaid": "^7.1.0",
|
"mermaid": "^7.1.0",
|
||||||
"mousetrap": "^1.6.1",
|
"mousetrap": "^1.6.1",
|
||||||
"normalize-scss": "^7.0.0",
|
"normalize-scss": "^7.0.1",
|
||||||
"prismjs": "^1.6.0",
|
"prismjs": "^1.6.0",
|
||||||
"request": "^2.82.0",
|
"request": "^2.85.0",
|
||||||
"serve-static": "^1.12.6",
|
"serve-static": "^1.13.2",
|
||||||
"tmp": "^0.0.33",
|
"tmp": "^0.0.33",
|
||||||
"turndown": "^4.0.1",
|
"turndown": "^4.0.2",
|
||||||
"vue": "^2.5.16",
|
"vue": "^2.5.16",
|
||||||
"vuex": "^3.0.1"
|
"vuex": "^3.0.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"autoprefixer": "^6.7.2",
|
"autoprefixer": "^6.7.2",
|
||||||
"babel-core": "^6.22.1",
|
"babel-core": "^6.26.3",
|
||||||
"babel-eslint": "^7.1.1",
|
"babel-eslint": "^8.2.3",
|
||||||
"babel-loader": "^6.2.10",
|
"babel-loader": "^7.1.4",
|
||||||
"babel-plugin-transform-runtime": "^6.22.0",
|
"babel-plugin-transform-runtime": "^6.22.0",
|
||||||
"babel-polyfill": "^6.23.0",
|
"babel-polyfill": "^6.23.0",
|
||||||
"babel-preset-env": "^1.3.2",
|
"babel-preset-env": "^1.3.2",
|
||||||
@ -68,49 +68,50 @@
|
|||||||
"chalk": "^1.1.3",
|
"chalk": "^1.1.3",
|
||||||
"connect-history-api-fallback": "^1.3.0",
|
"connect-history-api-fallback": "^1.3.0",
|
||||||
"copy-webpack-plugin": "^4.5.1",
|
"copy-webpack-plugin": "^4.5.1",
|
||||||
"css-loader": "^0.28.7",
|
"css-loader": "^0.28.11",
|
||||||
"eslint": "^3.19.0",
|
"eslint": "^4.19.1",
|
||||||
"eslint-config-airbnb-base": "^11.1.3",
|
"eslint-config-airbnb-base": "^12.1.0",
|
||||||
"eslint-friendly-formatter": "^2.0.7",
|
"eslint-friendly-formatter": "^4.0.1",
|
||||||
"eslint-import-resolver-webpack": "^0.8.1",
|
"eslint-import-resolver-webpack": "^0.9.0",
|
||||||
"eslint-loader": "^1.7.1",
|
"eslint-loader": "^2.0.0",
|
||||||
"eslint-plugin-html": "^2.0.0",
|
"eslint-plugin-html": "^4.0.3",
|
||||||
"eslint-plugin-import": "^2.2.0",
|
"eslint-plugin-import": "^2.11.0",
|
||||||
"eventsource-polyfill": "^0.9.6",
|
"eventsource-polyfill": "^0.9.6",
|
||||||
"express": "^4.15.5",
|
"express": "^4.16.3",
|
||||||
"extract-text-webpack-plugin": "^2.0.0",
|
"extract-text-webpack-plugin": "^2.0.0",
|
||||||
"favicons-webpack-plugin": "^0.0.7",
|
"favicons-webpack-plugin": "^0.0.9",
|
||||||
"file-loader": "^0.11.1",
|
"file-loader": "^1.1.11",
|
||||||
"friendly-errors-webpack-plugin": "^1.1.3",
|
"friendly-errors-webpack-plugin": "^1.7.0",
|
||||||
"gulp": "^3.9.1",
|
"gulp": "^3.9.1",
|
||||||
"gulp-concat": "^2.6.1",
|
"gulp-concat": "^2.6.1",
|
||||||
"html-webpack-plugin": "^2.28.0",
|
"html-webpack-plugin": "^3.2.0",
|
||||||
"http-proxy-middleware": "^0.17.3",
|
"http-proxy-middleware": "^0.18.0",
|
||||||
"ignore-loader": "^0.1.2",
|
"ignore-loader": "^0.1.2",
|
||||||
"node-sass": "^4.5.3",
|
"node-sass": "^4.9.0",
|
||||||
"npm-bump": "^0.0.23",
|
"npm-bump": "^0.0.23",
|
||||||
"offline-plugin": "^4.8.4",
|
"offline-plugin": "^5.0.3",
|
||||||
"opn": "^4.0.2",
|
"opn": "^4.0.2",
|
||||||
"optimize-css-assets-webpack-plugin": "^1.3.0",
|
"optimize-css-assets-webpack-plugin": "^1.3.2",
|
||||||
"ora": "^1.2.0",
|
"ora": "^1.2.0",
|
||||||
"raw-loader": "^0.5.1",
|
"raw-loader": "^0.5.1",
|
||||||
"rimraf": "^2.6.0",
|
"rimraf": "^2.6.0",
|
||||||
"sass-loader": "^6.0.5",
|
"sass-loader": "^7.0.1",
|
||||||
"semver": "^5.3.0",
|
"semver": "^5.5.0",
|
||||||
"shelljs": "^0.7.6",
|
"shelljs": "^0.8.1",
|
||||||
|
"stylelint": "^9.2.0",
|
||||||
"stylelint-config-standard": "^16.0.0",
|
"stylelint-config-standard": "^16.0.0",
|
||||||
"stylelint-processor-html": "^1.0.0",
|
"stylelint-processor-html": "^1.0.0",
|
||||||
"stylelint-webpack-plugin": "^0.7.0",
|
"stylelint-webpack-plugin": "^0.10.4",
|
||||||
"url-loader": "^0.5.8",
|
"url-loader": "^1.0.1",
|
||||||
"vue-loader": "^12.1.0",
|
"vue-loader": "^15.0.9",
|
||||||
"vue-style-loader": "^3.0.1",
|
"vue-style-loader": "^4.1.0",
|
||||||
"vue-template-compiler": "^2.3.3",
|
"vue-template-compiler": "^2.5.16",
|
||||||
"webpack": "^2.6.1",
|
"webpack": "^2.6.1",
|
||||||
"webpack-bundle-analyzer": "^2.2.1",
|
"webpack-bundle-analyzer": "^2.2.1",
|
||||||
"webpack-dev-middleware": "^1.10.0",
|
"webpack-dev-middleware": "^1.10.0",
|
||||||
"webpack-hot-middleware": "^2.18.0",
|
"webpack-hot-middleware": "^2.18.0",
|
||||||
"webpack-merge": "^4.1.0",
|
"webpack-merge": "^4.1.2",
|
||||||
"worker-loader": "^0.8.1"
|
"worker-loader": "^1.1.1"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 4.0.0",
|
"node": ">= 4.0.0",
|
||||||
|
@ -29,5 +29,8 @@ exports.githubToken = (req, res) => {
|
|||||||
githubToken(req.query.clientId, req.query.code)
|
githubToken(req.query.clientId, req.query.code)
|
||||||
.then(
|
.then(
|
||||||
token => res.send(token),
|
token => res.send(token),
|
||||||
err => res.status(400).send(err ? err.message || err.toString() : 'bad_code'));
|
err => res
|
||||||
|
.status(400)
|
||||||
|
.send(err ? err.message || err.toString() : 'bad_code'),
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* global window */
|
/* global window */
|
||||||
const spawn = require('child_process').spawn;
|
const { spawn } = require('child_process');
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const tmp = require('tmp');
|
const tmp = require('tmp');
|
||||||
const user = require('./user');
|
const user = require('./user');
|
||||||
@ -76,7 +76,7 @@ exports.generate = (req, res) => {
|
|||||||
params.push('--toc');
|
params.push('--toc');
|
||||||
}
|
}
|
||||||
options.tocDepth = parseInt(options.tocDepth, 10);
|
options.tocDepth = parseInt(options.tocDepth, 10);
|
||||||
if (!isNaN(options.tocDepth)) {
|
if (!Number.isNaN(options.tocDepth)) {
|
||||||
params.push('--toc-depth', options.tocDepth);
|
params.push('--toc-depth', options.tocDepth);
|
||||||
}
|
}
|
||||||
options.highlightStyle = highlightStyles.indexOf(options.highlightStyle) !== -1 ? options.highlightStyle : 'kate';
|
options.highlightStyle = highlightStyles.indexOf(options.highlightStyle) !== -1 ? options.highlightStyle : 'kate';
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* global window,MathJax */
|
/* global window,MathJax */
|
||||||
const spawn = require('child_process').spawn;
|
const { spawn } = require('child_process');
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const tmp = require('tmp');
|
const tmp = require('tmp');
|
||||||
const user = require('./user');
|
const user = require('./user');
|
||||||
@ -84,13 +84,13 @@ exports.generate = (req, res) => {
|
|||||||
|
|
||||||
// Margins
|
// Margins
|
||||||
const marginTop = parseInt(`${options.marginTop}`, 10);
|
const marginTop = parseInt(`${options.marginTop}`, 10);
|
||||||
params.push('-T', isNaN(marginTop) ? 25 : marginTop);
|
params.push('-T', Number.isNaN(marginTop) ? 25 : marginTop);
|
||||||
const marginRight = parseInt(`${options.marginRight}`, 10);
|
const marginRight = parseInt(`${options.marginRight}`, 10);
|
||||||
params.push('-R', isNaN(marginRight) ? 25 : marginRight);
|
params.push('-R', Number.isNaN(marginRight) ? 25 : marginRight);
|
||||||
const marginBottom = parseInt(`${options.marginBottom}`, 10);
|
const marginBottom = parseInt(`${options.marginBottom}`, 10);
|
||||||
params.push('-B', isNaN(marginBottom) ? 25 : marginBottom);
|
params.push('-B', Number.isNaN(marginBottom) ? 25 : marginBottom);
|
||||||
const marginLeft = parseInt(`${options.marginLeft}`, 10);
|
const marginLeft = parseInt(`${options.marginLeft}`, 10);
|
||||||
params.push('-L', isNaN(marginLeft) ? 25 : marginLeft);
|
params.push('-L', Number.isNaN(marginLeft) ? 25 : marginLeft);
|
||||||
|
|
||||||
// Header
|
// Header
|
||||||
if (options.headerCenter) {
|
if (options.headerCenter) {
|
||||||
|
@ -2,10 +2,12 @@ const request = require('request');
|
|||||||
const AWS = require('aws-sdk');
|
const AWS = require('aws-sdk');
|
||||||
const verifier = require('google-id-token-verifier');
|
const verifier = require('google-id-token-verifier');
|
||||||
|
|
||||||
const BUCKET_NAME = process.env.USER_BUCKET_NAME || 'stackedit-users';
|
const {
|
||||||
const PAYPAL_URI = process.env.PAYPAL_URI || 'https://www.paypal.com/cgi-bin/webscr';
|
USER_BUCKET_NAME = 'stackedit-users',
|
||||||
const PAYPAL_RECEIVER_EMAIL = process.env.PAYPAL_RECEIVER_EMAIL || 'stackedit.sales@gmail.com';
|
PAYPAL_URI = 'https://www.paypal.com/cgi-bin/webscr',
|
||||||
const GOOGLE_CLIENT_ID = process.env.GOOGLE_CLIENT_ID;
|
PAYPAL_RECEIVER_EMAIL = 'stackedit.sales@gmail.com',
|
||||||
|
GOOGLE_CLIENT_ID,
|
||||||
|
} = process.env;
|
||||||
const s3Client = new AWS.S3();
|
const s3Client = new AWS.S3();
|
||||||
|
|
||||||
const cb = (resolve, reject) => (err, res) => {
|
const cb = (resolve, reject) => (err, res) => {
|
||||||
@ -18,21 +20,22 @@ const cb = (resolve, reject) => (err, res) => {
|
|||||||
|
|
||||||
exports.getUser = id => new Promise((resolve, reject) => {
|
exports.getUser = id => new Promise((resolve, reject) => {
|
||||||
s3Client.getObject({
|
s3Client.getObject({
|
||||||
Bucket: BUCKET_NAME,
|
Bucket: USER_BUCKET_NAME,
|
||||||
Key: id,
|
Key: id,
|
||||||
}, cb(resolve, reject));
|
}, cb(resolve, reject));
|
||||||
})
|
})
|
||||||
.then(
|
.then(
|
||||||
res => JSON.parse(`${res.Body}`),
|
res => JSON.parse(`${res.Body}`),
|
||||||
(err) => {
|
(err) => {
|
||||||
if (err.code !== 'NoSuchKey') {
|
if (err.code !== 'NoSuchKey') {
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
});
|
},
|
||||||
|
);
|
||||||
|
|
||||||
exports.putUser = (id, user) => new Promise((resolve, reject) => {
|
exports.putUser = (id, user) => new Promise((resolve, reject) => {
|
||||||
s3Client.putObject({
|
s3Client.putObject({
|
||||||
Bucket: BUCKET_NAME,
|
Bucket: USER_BUCKET_NAME,
|
||||||
Key: id,
|
Key: id,
|
||||||
Body: JSON.stringify(user),
|
Body: JSON.stringify(user),
|
||||||
}, cb(resolve, reject));
|
}, cb(resolve, reject));
|
||||||
@ -40,20 +43,24 @@ exports.putUser = (id, user) => new Promise((resolve, reject) => {
|
|||||||
|
|
||||||
exports.removeUser = id => new Promise((resolve, reject) => {
|
exports.removeUser = id => new Promise((resolve, reject) => {
|
||||||
s3Client.deleteObject({
|
s3Client.deleteObject({
|
||||||
Bucket: BUCKET_NAME,
|
Bucket: USER_BUCKET_NAME,
|
||||||
Key: id,
|
Key: id,
|
||||||
}, cb(resolve, reject));
|
}, cb(resolve, reject));
|
||||||
});
|
});
|
||||||
|
|
||||||
exports.getUserFromToken = idToken => new Promise(
|
exports.getUserFromToken = idToken => new Promise((resolve, reject) => verifier
|
||||||
(resolve, reject) => verifier.verify(idToken, GOOGLE_CLIENT_ID, cb(resolve, reject)))
|
.verify(idToken, GOOGLE_CLIENT_ID, cb(resolve, reject)))
|
||||||
.then(tokenInfo => exports.getUser(tokenInfo.sub));
|
.then(tokenInfo => exports.getUser(tokenInfo.sub));
|
||||||
|
|
||||||
exports.userInfo = (req, res) => exports.getUserFromToken(req.query.idToken)
|
exports.userInfo = (req, res) => exports.getUserFromToken(req.query.idToken)
|
||||||
.then(user => res.send(Object.assign({
|
.then(
|
||||||
sponsorUntil: 0,
|
user => res.send(Object.assign({
|
||||||
}, user)),
|
sponsorUntil: 0,
|
||||||
err => res.status(400).send(err ? err.message || err.toString() : 'invalid_token'));
|
}, user)),
|
||||||
|
err => res
|
||||||
|
.status(400)
|
||||||
|
.send(err ? err.message || err.toString() : 'invalid_token'),
|
||||||
|
);
|
||||||
|
|
||||||
exports.paypalIpn = (req, res, next) => Promise.resolve()
|
exports.paypalIpn = (req, res, next) => Promise.resolve()
|
||||||
.then(() => {
|
.then(() => {
|
||||||
|
@ -10,6 +10,9 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
|
import '../styles';
|
||||||
|
import '../styles/markdownHighlighting.scss';
|
||||||
|
import '../styles/app.scss';
|
||||||
import Layout from './Layout';
|
import Layout from './Layout';
|
||||||
import Modal from './Modal';
|
import Modal from './Modal';
|
||||||
import Notification from './Notification';
|
import Notification from './Notification';
|
||||||
@ -26,7 +29,7 @@ import store from '../store';
|
|||||||
Vue.directive('focus', {
|
Vue.directive('focus', {
|
||||||
inserted(el) {
|
inserted(el) {
|
||||||
el.focus();
|
el.focus();
|
||||||
const value = el.value;
|
const { value } = el;
|
||||||
if (value && el.setSelectionRange) {
|
if (value && el.setSelectionRange) {
|
||||||
el.setSelectionRange(0, value.length);
|
el.setSelectionRange(0, value.length);
|
||||||
}
|
}
|
||||||
@ -106,7 +109,3 @@ export default {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
|
||||||
@import 'common/app';
|
|
||||||
</style>
|
|
||||||
|
@ -49,7 +49,7 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@import 'common/variables.scss';
|
@import '../styles/variables.scss';
|
||||||
|
|
||||||
.button-bar {
|
.button-bar {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
@ -28,7 +28,7 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@import 'common/variables.scss';
|
@import '../styles/variables.scss';
|
||||||
|
|
||||||
.code-editor {
|
.code-editor {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
@ -66,13 +66,14 @@ export default {
|
|||||||
editorElt.querySelectorAll(`.discussion-editor-highlighting--${discussionId}`)
|
editorElt.querySelectorAll(`.discussion-editor-highlighting--${discussionId}`)
|
||||||
.cl_each(elt => elt.classList.add('discussion-editor-highlighting--selected'));
|
.cl_each(elt => elt.classList.add('discussion-editor-highlighting--selected'));
|
||||||
}
|
}
|
||||||
});
|
},
|
||||||
|
);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@import 'common/variables.scss';
|
@import '../styles/variables.scss';
|
||||||
|
|
||||||
.editor {
|
.editor {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
@ -67,7 +67,8 @@ export default {
|
|||||||
this.$store.dispatch('explorer/openNode', currentFileId);
|
this.$store.dispatch('explorer/openNode', currentFileId);
|
||||||
}, {
|
}, {
|
||||||
immediate: true,
|
immediate: true,
|
||||||
});
|
},
|
||||||
|
);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
@ -98,7 +98,7 @@ export default {
|
|||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
submitNewChild(cancel) {
|
submitNewChild(cancel) {
|
||||||
const newChildNode = this.$store.state.explorer.newChildNode;
|
const { newChildNode } = this.$store.state.explorer;
|
||||||
if (!cancel && !newChildNode.isNil && newChildNode.item.name) {
|
if (!cancel && !newChildNode.isNil && newChildNode.item.name) {
|
||||||
if (newChildNode.isFolder) {
|
if (newChildNode.isFolder) {
|
||||||
fileSvc.storeItem(newChildNode.item)
|
fileSvc.storeItem(newChildNode.item)
|
||||||
@ -111,7 +111,7 @@ export default {
|
|||||||
this.$store.commit('explorer/setNewItem', null);
|
this.$store.commit('explorer/setNewItem', null);
|
||||||
},
|
},
|
||||||
submitEdit(cancel) {
|
submitEdit(cancel) {
|
||||||
const item = this.$store.getters['explorer/editingNode'].item;
|
const { item } = this.$store.getters['explorer/editingNode'];
|
||||||
const value = this.editingValue;
|
const value = this.editingValue;
|
||||||
this.setEditingId(null);
|
this.setEditingId(null);
|
||||||
if (!cancel && item.id && value) {
|
if (!cancel && item.id && value) {
|
||||||
|
@ -70,7 +70,8 @@ class DynamicClassApplier {
|
|||||||
() => ({
|
() => ({
|
||||||
start: this.startMarker.offset,
|
start: this.startMarker.offset,
|
||||||
end: this.endMarker.offset,
|
end: this.endMarker.offset,
|
||||||
}));
|
}),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,7 +127,10 @@ export default {
|
|||||||
offsetList.forEach((offset, i) => {
|
offsetList.forEach((offset, i) => {
|
||||||
const key = `${offset.start}:${offset.end}`;
|
const key = `${offset.start}:${offset.end}`;
|
||||||
this.classAppliers[key] = oldClassAppliers[key] || new DynamicClassApplier(
|
this.classAppliers[key] = oldClassAppliers[key] || new DynamicClassApplier(
|
||||||
'find-replace-highlighting', offset, i > 200);
|
'find-replace-highlighting',
|
||||||
|
offset,
|
||||||
|
i > 200,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// Ignore
|
// Ignore
|
||||||
@ -156,9 +160,9 @@ export default {
|
|||||||
this.findPosition = 0;
|
this.findPosition = 0;
|
||||||
},
|
},
|
||||||
find(mode = 'forward') {
|
find(mode = 'forward') {
|
||||||
const selectedClassApplier = this.selectedClassApplier;
|
const { selectedClassApplier } = this;
|
||||||
this.unselectClassApplier();
|
this.unselectClassApplier();
|
||||||
const selectionMgr = editorSvc.clEditor.selectionMgr;
|
const { selectionMgr } = editorSvc.clEditor;
|
||||||
const startOffset = Math.min(selectionMgr.selectionStart, selectionMgr.selectionEnd);
|
const startOffset = Math.min(selectionMgr.selectionStart, selectionMgr.selectionEnd);
|
||||||
const endOffset = Math.max(selectionMgr.selectionStart, selectionMgr.selectionEnd);
|
const endOffset = Math.max(selectionMgr.selectionStart, selectionMgr.selectionEnd);
|
||||||
const keys = Object.keys(this.classAppliers);
|
const keys = Object.keys(this.classAppliers);
|
||||||
@ -206,7 +210,10 @@ export default {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
editorSvc.clEditor.replaceAll(
|
editorSvc.clEditor.replaceAll(
|
||||||
this.replaceRegex, this.replaceText, this.selectedClassApplier.startMarker.offset);
|
this.replaceRegex,
|
||||||
|
this.replaceText,
|
||||||
|
this.selectedClassApplier.startMarker.offset,
|
||||||
|
);
|
||||||
this.$nextTick(() => this.find());
|
this.$nextTick(() => this.find());
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -227,7 +234,9 @@ export default {
|
|||||||
|
|
||||||
// Highlight occurences
|
// Highlight occurences
|
||||||
this.debouncedHighlightOccurrences = cledit.Utils.debounce(
|
this.debouncedHighlightOccurrences = cledit.Utils.debounce(
|
||||||
() => this.highlightOccurrences(), 25);
|
() => this.highlightOccurrences(),
|
||||||
|
25,
|
||||||
|
);
|
||||||
// Refresh highlighting when find text changes or changing options
|
// Refresh highlighting when find text changes or changing options
|
||||||
this.$watch(() => this.findText, this.debouncedHighlightOccurrences);
|
this.$watch(() => this.findText, this.debouncedHighlightOccurrences);
|
||||||
this.$watch(() => this.findCaseSensitive, this.debouncedHighlightOccurrences);
|
this.$watch(() => this.findCaseSensitive, this.debouncedHighlightOccurrences);
|
||||||
@ -273,7 +282,7 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@import 'common/variables.scss';
|
@import '../styles/variables.scss';
|
||||||
|
|
||||||
.find-replace {
|
.find-replace {
|
||||||
padding: 0 35px 0 25px;
|
padding: 0 35px 0 25px;
|
||||||
|
@ -140,7 +140,7 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@import 'common/variables.scss';
|
@import '../styles/variables.scss';
|
||||||
|
|
||||||
.layout {
|
.layout {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
@ -141,7 +141,7 @@ export default {
|
|||||||
}
|
}
|
||||||
if (isFocusIn && this.config) {
|
if (isFocusIn && this.config) {
|
||||||
const modalInner = this.$el.querySelector('.modal__inner-2');
|
const modalInner = this.$el.querySelector('.modal__inner-2');
|
||||||
let target = evt.target;
|
let { target } = evt;
|
||||||
while (target) {
|
while (target) {
|
||||||
if (target === modalInner) {
|
if (target === modalInner) {
|
||||||
return;
|
return;
|
||||||
@ -166,7 +166,7 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@import 'common/variables.scss';
|
@import '../styles/variables.scss';
|
||||||
|
|
||||||
.modal {
|
.modal {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
@ -224,7 +224,9 @@ export default {
|
|||||||
() => {
|
() => {
|
||||||
this.title = '';
|
this.title = '';
|
||||||
this.editTitle(false);
|
this.editTitle(false);
|
||||||
}, { immediate: true });
|
},
|
||||||
|
{ immediate: true },
|
||||||
|
);
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.titleFakeElt = this.$el.querySelector('.navigation-bar__title--fake');
|
this.titleFakeElt = this.$el.querySelector('.navigation-bar__title--fake');
|
||||||
@ -235,7 +237,7 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@import 'common/variables.scss';
|
@import '../styles/variables.scss';
|
||||||
|
|
||||||
.navigation-bar {
|
.navigation-bar {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
@ -23,7 +23,7 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@import 'common/variables.scss';
|
@import '../styles/variables.scss';
|
||||||
|
|
||||||
.notification {
|
.notification {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
@ -22,7 +22,7 @@ import { mapGetters, mapActions } from 'vuex';
|
|||||||
import CommentList from './gutters/CommentList';
|
import CommentList from './gutters/CommentList';
|
||||||
import PreviewNewDiscussionButton from './gutters/PreviewNewDiscussionButton';
|
import PreviewNewDiscussionButton from './gutters/PreviewNewDiscussionButton';
|
||||||
|
|
||||||
const appUri = `${location.protocol}//${location.host}`;
|
const appUri = `${window.location.protocol}//${window.location.host}`;
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
@ -98,13 +98,14 @@ export default {
|
|||||||
previewElt.querySelectorAll(`.discussion-preview-highlighting--${discussionId}`)
|
previewElt.querySelectorAll(`.discussion-preview-highlighting--${discussionId}`)
|
||||||
.cl_each(elt => elt.classList.add('discussion-preview-highlighting--selected'));
|
.cl_each(elt => elt.classList.add('discussion-preview-highlighting--selected'));
|
||||||
}
|
}
|
||||||
});
|
},
|
||||||
|
);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@import 'common/variables.scss';
|
@import '../styles/variables.scss';
|
||||||
|
|
||||||
.preview,
|
.preview,
|
||||||
.preview__inner-1 {
|
.preview__inner-1 {
|
||||||
|
@ -93,7 +93,7 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@import 'common/variables.scss';
|
@import '../styles/variables.scss';
|
||||||
|
|
||||||
.side-bar {
|
.side-bar {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
@ -92,7 +92,7 @@ export default {
|
|||||||
this.htmlSelection = true;
|
this.htmlSelection = true;
|
||||||
if (!text) {
|
if (!text) {
|
||||||
this.htmlSelection = false;
|
this.htmlSelection = false;
|
||||||
text = editorSvc.previewCtx.text;
|
({ text } = editorSvc.previewCtx);
|
||||||
}
|
}
|
||||||
if (text != null) {
|
if (text != null) {
|
||||||
this.htmlStats.forEach((stat) => {
|
this.htmlStats.forEach((stat) => {
|
||||||
|
@ -126,7 +126,7 @@ export default {
|
|||||||
|
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@import 'common/variables.scss';
|
@import '../styles/variables.scss';
|
||||||
|
|
||||||
.tour {
|
.tour {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
@ -10,7 +10,9 @@ const nextTickExecCbs = cledit.Utils.debounce(() => {
|
|||||||
}
|
}
|
||||||
if (savedSelection) {
|
if (savedSelection) {
|
||||||
editorSvc.clEditor.selectionMgr.setSelectionStartEnd(
|
editorSvc.clEditor.selectionMgr.setSelectionStartEnd(
|
||||||
savedSelection.start, savedSelection.end);
|
savedSelection.start,
|
||||||
|
savedSelection.end,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
savedSelection = null;
|
savedSelection = null;
|
||||||
});
|
});
|
||||||
|
@ -40,14 +40,22 @@ export default class PreviewClassApplier {
|
|||||||
const offset = this.offsetGetter();
|
const offset = this.offsetGetter();
|
||||||
if (offset) {
|
if (offset) {
|
||||||
const offsetStart = editorSvc.getPreviewOffset(
|
const offsetStart = editorSvc.getPreviewOffset(
|
||||||
offset.start, editorSvc.previewCtx.sectionDescList);
|
offset.start,
|
||||||
|
editorSvc.previewCtx.sectionDescList,
|
||||||
|
);
|
||||||
const offsetEnd = editorSvc.getPreviewOffset(
|
const offsetEnd = editorSvc.getPreviewOffset(
|
||||||
offset.end, editorSvc.previewCtx.sectionDescList);
|
offset.end,
|
||||||
|
editorSvc.previewCtx.sectionDescList,
|
||||||
|
);
|
||||||
if (offsetStart != null && offsetEnd != null && offsetStart !== offsetEnd) {
|
if (offsetStart != null && offsetEnd != null && offsetStart !== offsetEnd) {
|
||||||
const start = cledit.Utils.findContainer(
|
const start = cledit.Utils.findContainer(
|
||||||
editorSvc.previewElt, Math.min(offsetStart, offsetEnd));
|
editorSvc.previewElt,
|
||||||
|
Math.min(offsetStart, offsetEnd),
|
||||||
|
);
|
||||||
const end = cledit.Utils.findContainer(
|
const end = cledit.Utils.findContainer(
|
||||||
editorSvc.previewElt, Math.max(offsetStart, offsetEnd));
|
editorSvc.previewElt,
|
||||||
|
Math.max(offsetStart, offsetEnd),
|
||||||
|
);
|
||||||
const range = document.createRange();
|
const range = document.createRange();
|
||||||
range.setStart(start.container, start.offsetInContainer);
|
range.setStart(start.container, start.offsetInContainer);
|
||||||
range.setEnd(end.container, end.offsetInContainer);
|
range.setEnd(end.container, end.offsetInContainer);
|
||||||
|
@ -51,7 +51,8 @@ export default {
|
|||||||
this.$store.dispatch('modal/commentDeletion')
|
this.$store.dispatch('modal/commentDeletion')
|
||||||
.then(
|
.then(
|
||||||
() => this.$store.dispatch('discussion/cleanCurrentFile', { filterComment: this.comment }),
|
() => this.$store.dispatch('discussion/cleanCurrentFile', { filterComment: this.comment }),
|
||||||
() => { /* Cancel */ });
|
() => { /* Cancel */ },
|
||||||
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
@ -63,8 +64,7 @@ export default {
|
|||||||
let scrollerMirrorElt;
|
let scrollerMirrorElt;
|
||||||
const getScrollerMirrorElt = () => {
|
const getScrollerMirrorElt = () => {
|
||||||
if (!scrollerMirrorElt) {
|
if (!scrollerMirrorElt) {
|
||||||
scrollerMirrorElt = document.querySelector(
|
scrollerMirrorElt = document.querySelector(`.comment-list .comment--${commentId} .comment__text-inner`);
|
||||||
`.comment-list .comment--${commentId} .comment__text-inner`);
|
|
||||||
}
|
}
|
||||||
return scrollerMirrorElt || { scrollTop: 0 };
|
return scrollerMirrorElt || { scrollTop: 0 };
|
||||||
};
|
};
|
||||||
|
@ -107,10 +107,13 @@ export default {
|
|||||||
this.currentDiscussionLastCommentId
|
this.currentDiscussionLastCommentId
|
||||||
&& this.$el.querySelector(`.comment--${this.currentDiscussionLastCommentId}`),
|
&& this.$el.querySelector(`.comment--${this.currentDiscussionLastCommentId}`),
|
||||||
this.$el.querySelector('.comment--new'),
|
this.$el.querySelector('.comment--new'),
|
||||||
true);
|
true,
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
tops[discussionId] = getTop(discussion,
|
tops[discussionId] = getTop(
|
||||||
this.$el.querySelector(`.comment--discussion-${discussionId}`));
|
discussion,
|
||||||
|
this.$el.querySelector(`.comment--discussion-${discussionId}`),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.tops = tops;
|
this.tops = tops;
|
||||||
@ -120,7 +123,8 @@ export default {
|
|||||||
this.$watch(
|
this.$watch(
|
||||||
() => this.updateTopsTrigger,
|
() => this.updateTopsTrigger,
|
||||||
() => this.updateTops(),
|
() => this.updateTops(),
|
||||||
{ immediate: true });
|
{ immediate: true },
|
||||||
|
);
|
||||||
|
|
||||||
const layoutSettings = this.$store.getters['data/layoutSettings'];
|
const layoutSettings = this.$store.getters['data/layoutSettings'];
|
||||||
this.scrollerElt = layoutSettings.showEditor
|
this.scrollerElt = layoutSettings.showEditor
|
||||||
@ -161,7 +165,8 @@ export default {
|
|||||||
this.$watch(
|
this.$watch(
|
||||||
() => this.updateStickyTrigger,
|
() => this.updateStickyTrigger,
|
||||||
() => this.updateSticky(),
|
() => this.updateSticky(),
|
||||||
{ immediate: true });
|
{ immediate: true },
|
||||||
|
);
|
||||||
|
|
||||||
// Move preview discussions once previewCtxWithDiffs has been calculated
|
// Move preview discussions once previewCtxWithDiffs has been calculated
|
||||||
if (!editorSvc.previewCtxWithDiffs) {
|
if (!editorSvc.previewCtxWithDiffs) {
|
||||||
@ -178,7 +183,7 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@import '../common/variables.scss';
|
@import '../../styles/variables.scss';
|
||||||
|
|
||||||
.comment-list {
|
.comment-list {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
@ -99,14 +99,15 @@ export default {
|
|||||||
() => this.$store.dispatch('discussion/cleanCurrentFile', {
|
() => this.$store.dispatch('discussion/cleanCurrentFile', {
|
||||||
filterDiscussion: this.currentDiscussion,
|
filterDiscussion: this.currentDiscussion,
|
||||||
}),
|
}),
|
||||||
() => { /* Cancel */ });
|
() => { /* Cancel */ },
|
||||||
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@import '../common/variables.scss';
|
@import '../../styles/variables.scss';
|
||||||
|
|
||||||
.current-discussion {
|
.current-discussion {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
@ -86,9 +86,11 @@ export default {
|
|||||||
const clEditor = cledit(preElt, scrollerElt, true);
|
const clEditor = cledit(preElt, scrollerElt, true);
|
||||||
clEditor.init({
|
clEditor.init({
|
||||||
sectionHighlighter: section => Prism.highlight(
|
sectionHighlighter: section => Prism.highlight(
|
||||||
section.text, editorSvc.prismGrammars[section.data]),
|
section.text,
|
||||||
sectionParser: text => markdownConversionSvc.parseSections(
|
editorSvc.prismGrammars[section.data],
|
||||||
editorSvc.converter, text).sections,
|
),
|
||||||
|
sectionParser: text => markdownConversionSvc
|
||||||
|
.parseSections(editorSvc.converter, text).sections,
|
||||||
content: this.$store.state.discussion.newCommentText,
|
content: this.$store.state.discussion.newCommentText,
|
||||||
selectionStart: this.$store.state.discussion.newCommentSelection.start,
|
selectionStart: this.$store.state.discussion.newCommentSelection.start,
|
||||||
selectionEnd: this.$store.state.discussion.newCommentSelection.end,
|
selectionEnd: this.$store.state.discussion.newCommentSelection.end,
|
||||||
@ -114,14 +116,14 @@ export default {
|
|||||||
clEditor.focus();
|
clEditor.focus();
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
{ immediate: true });
|
{ immediate: true },
|
||||||
|
);
|
||||||
|
|
||||||
if (isSticky) {
|
if (isSticky) {
|
||||||
let scrollerMirrorElt;
|
let scrollerMirrorElt;
|
||||||
const getScrollerMirrorElt = () => {
|
const getScrollerMirrorElt = () => {
|
||||||
if (!scrollerMirrorElt) {
|
if (!scrollerMirrorElt) {
|
||||||
scrollerMirrorElt = document.querySelector(
|
scrollerMirrorElt = document.querySelector('.comment-list .comment--new .comment__text-inner');
|
||||||
'.comment-list .comment--new .comment__text-inner');
|
|
||||||
}
|
}
|
||||||
return scrollerMirrorElt || { scrollTop: 0 };
|
return scrollerMirrorElt || { scrollTop: 0 };
|
||||||
};
|
};
|
||||||
@ -150,7 +152,7 @@ export default {
|
|||||||
);
|
);
|
||||||
this.$watch(
|
this.$watch(
|
||||||
() => this.$store.state.discussion.newCommentText,
|
() => this.$store.state.discussion.newCommentText,
|
||||||
newCommentText => clEditor.setContent(newCommentText),
|
newCommentText => clEditor.setContent(newCommentText),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -28,7 +28,7 @@ export default {
|
|||||||
) {
|
) {
|
||||||
this.selection = editorSvc.getTrimmedSelection();
|
this.selection = editorSvc.getTrimmedSelection();
|
||||||
if (this.selection) {
|
if (this.selection) {
|
||||||
const text = editorSvc.previewCtxWithDiffs.text;
|
const { text } = editorSvc.previewCtxWithDiffs;
|
||||||
offset = editorSvc.getPreviewOffset(this.selection.end);
|
offset = editorSvc.getPreviewOffset(this.selection.end);
|
||||||
while (offset && text[offset - 1] === '\n') {
|
while (offset && text[offset - 1] === '\n') {
|
||||||
offset -= 1;
|
offset -= 1;
|
||||||
@ -46,7 +46,8 @@ export default {
|
|||||||
editorSvc.$on('previewSelectionRange', () => this.checkSelection());
|
editorSvc.$on('previewSelectionRange', () => this.checkSelection());
|
||||||
this.$watch(
|
this.$watch(
|
||||||
() => this.$store.getters['layout/styles'].previewWidth,
|
() => this.$store.getters['layout/styles'].previewWidth,
|
||||||
() => this.checkSelection());
|
() => this.checkSelection(),
|
||||||
|
);
|
||||||
this.checkSelection();
|
this.checkSelection();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -33,7 +33,7 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@import '../common/variables.scss';
|
@import '../../styles/variables.scss';
|
||||||
|
|
||||||
.sticky-comment {
|
.sticky-comment {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
@ -113,13 +113,15 @@ export default {
|
|||||||
let revisionContentPromise = revisionContentPromises[revision.id];
|
let revisionContentPromise = revisionContentPromises[revision.id];
|
||||||
if (!revisionContentPromise) {
|
if (!revisionContentPromise) {
|
||||||
revisionContentPromise = new Promise((resolve, reject) => {
|
revisionContentPromise = new Promise((resolve, reject) => {
|
||||||
const syncToken = this.syncToken;
|
const { syncToken } = this;
|
||||||
const currentFile = this.$store.getters['file/current'];
|
const currentFile = this.$store.getters['file/current'];
|
||||||
this.$store.dispatch('queue/enqueue',
|
this.$store.dispatch(
|
||||||
|
'queue/enqueue',
|
||||||
() => Promise.resolve()
|
() => Promise.resolve()
|
||||||
.then(() => this.workspaceProvider.getRevisionContent(
|
.then(() => this.workspaceProvider
|
||||||
syncToken, currentFile.id, revision.id))
|
.getRevisionContent(syncToken, currentFile.id, revision.id))
|
||||||
.then(resolve, reject));
|
.then(resolve, reject),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
revisionContentPromises[revision.id] = revisionContentPromise;
|
revisionContentPromises[revision.id] = revisionContentPromise;
|
||||||
revisionContentPromise.catch(() => {
|
revisionContentPromise.catch(() => {
|
||||||
@ -130,7 +132,7 @@ export default {
|
|||||||
this.$store.dispatch('content/setRevisionContent', revisionContent));
|
this.$store.dispatch('content/setRevisionContent', revisionContent));
|
||||||
},
|
},
|
||||||
refreshHighlighters() {
|
refreshHighlighters() {
|
||||||
const revisionContent = this.$store.state.content.revisionContent;
|
const { revisionContent } = this.$store.state.content;
|
||||||
editorClassAppliers.forEach(editorClassApplier => editorClassApplier.stop());
|
editorClassAppliers.forEach(editorClassApplier => editorClassApplier.stop());
|
||||||
editorClassAppliers = [];
|
editorClassAppliers = [];
|
||||||
previewClassAppliers.forEach(previewClassApplier => previewClassApplier.stop());
|
previewClassAppliers.forEach(previewClassApplier => previewClassApplier.stop());
|
||||||
@ -145,9 +147,13 @@ export default {
|
|||||||
end: offset + text.length,
|
end: offset + text.length,
|
||||||
};
|
};
|
||||||
editorClassAppliers.push(new EditorClassApplier(
|
editorClassAppliers.push(new EditorClassApplier(
|
||||||
[`revision-diff--${utils.uid()}`, ...classes], offsets));
|
[`revision-diff--${utils.uid()}`, ...classes],
|
||||||
|
offsets,
|
||||||
|
));
|
||||||
previewClassAppliers.push(new PreviewClassApplier(
|
previewClassAppliers.push(new PreviewClassApplier(
|
||||||
[`revision-diff--${utils.uid()}`, ...classes], offsets));
|
[`revision-diff--${utils.uid()}`, ...classes],
|
||||||
|
offsets,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
offset += text.length;
|
offset += text.length;
|
||||||
});
|
});
|
||||||
@ -164,8 +170,8 @@ export default {
|
|||||||
() => this.refreshTrigger,
|
() => this.refreshTrigger,
|
||||||
() => {
|
() => {
|
||||||
this.allRevisions = [];
|
this.allRevisions = [];
|
||||||
const id = this.$store.getters['file/current'].id;
|
const { id } = this.$store.getters['file/current'];
|
||||||
const syncToken = this.syncToken;
|
const { syncToken } = this;
|
||||||
if (id && syncToken) {
|
if (id && syncToken) {
|
||||||
if (id !== cachedFileId) {
|
if (id !== cachedFileId) {
|
||||||
this.setRevisionContent();
|
this.setRevisionContent();
|
||||||
@ -173,10 +179,12 @@ export default {
|
|||||||
revisionContentPromises = {};
|
revisionContentPromises = {};
|
||||||
const currentFile = this.$store.getters['file/current'];
|
const currentFile = this.$store.getters['file/current'];
|
||||||
revisionsPromise = new Promise((resolve, reject) => {
|
revisionsPromise = new Promise((resolve, reject) => {
|
||||||
this.$store.dispatch('queue/enqueue',
|
this.$store.dispatch(
|
||||||
|
'queue/enqueue',
|
||||||
() => Promise.resolve()
|
() => Promise.resolve()
|
||||||
.then(() => this.workspaceProvider.listRevisions(syncToken, currentFile.id))
|
.then(() => this.workspaceProvider.listRevisions(syncToken, currentFile.id))
|
||||||
.then(resolve, reject));
|
.then(resolve, reject),
|
||||||
|
);
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
cachedFileId = null;
|
cachedFileId = null;
|
||||||
@ -191,16 +199,18 @@ export default {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, { immediate: true });
|
}, { immediate: true },
|
||||||
|
);
|
||||||
|
|
||||||
const loadOne = () => {
|
const loadOne = () => {
|
||||||
if (!this.destroyed) {
|
if (!this.destroyed) {
|
||||||
this.$store.dispatch('queue/enqueue',
|
this.$store.dispatch(
|
||||||
|
'queue/enqueue',
|
||||||
() => {
|
() => {
|
||||||
let loadPromise;
|
let loadPromise;
|
||||||
this.revisions.some((revision) => {
|
this.revisions.some((revision) => {
|
||||||
if (!revision.created) {
|
if (!revision.created) {
|
||||||
const syncToken = this.syncToken;
|
const { syncToken } = this;
|
||||||
const currentFile = this.$store.getters['file/current'];
|
const currentFile = this.$store.getters['file/current'];
|
||||||
loadPromise = this.workspaceProvider
|
loadPromise = this.workspaceProvider
|
||||||
.loadRevision(syncToken, currentFile.id, revision)
|
.loadRevision(syncToken, currentFile.id, revision)
|
||||||
@ -209,19 +219,22 @@ export default {
|
|||||||
return loadPromise;
|
return loadPromise;
|
||||||
});
|
});
|
||||||
return loadPromise;
|
return loadPromise;
|
||||||
});
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.$watch(
|
this.$watch(
|
||||||
() => this.revisions,
|
() => this.revisions,
|
||||||
() => loadOne(),
|
() => loadOne(),
|
||||||
{ immediate: true });
|
{ immediate: true },
|
||||||
|
);
|
||||||
|
|
||||||
// Watch diffs changes
|
// Watch diffs changes
|
||||||
this.$watch(
|
this.$watch(
|
||||||
() => this.$store.state.content.revisionContent,
|
() => this.$store.state.content.revisionContent,
|
||||||
() => this.refreshHighlighters());
|
() => this.refreshHighlighters(),
|
||||||
|
);
|
||||||
|
|
||||||
// Close revision
|
// Close revision
|
||||||
this.onKeyup = (evt) => {
|
this.onKeyup = (evt) => {
|
||||||
@ -246,7 +259,7 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@import '../common/variables.scss';
|
@import '../../styles/variables.scss';
|
||||||
|
|
||||||
.history {
|
.history {
|
||||||
padding: 5px 5px 50px;
|
padding: 5px 5px 50px;
|
||||||
|
@ -53,31 +53,25 @@ export default {
|
|||||||
MenuEntry,
|
MenuEntry,
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
onImportMarkdown(evt) {
|
async onImportMarkdown(evt) {
|
||||||
const file = evt.target.files[0];
|
const file = evt.target.files[0];
|
||||||
readFile(file)
|
const content = await readFile(file);
|
||||||
.then(content => fileSvc.createFile({
|
const item = await fileSvc.createFile({
|
||||||
...Provider.parseContent(content),
|
...Provider.parseContent(content),
|
||||||
name: file.name,
|
name: file.name,
|
||||||
})
|
});
|
||||||
.then(
|
this.$store.commit('file/setCurrentId', item.id);
|
||||||
item => this.$store.commit('file/setCurrentId', item.id)),
|
|
||||||
() => { /* Cancel */ });
|
|
||||||
},
|
},
|
||||||
onImportHtml(evt) {
|
async onImportHtml(evt) {
|
||||||
const file = evt.target.files[0];
|
const file = evt.target.files[0];
|
||||||
readFile(file)
|
const content = await readFile(file);
|
||||||
.then(content => fileSvc.createFile({
|
const sanitizedContent = htmlSanitizer.sanitizeHtml(content)
|
||||||
...Provider.parseContent(
|
.replace(/ /g, ' '); // Replace non-breaking spaces with classic spaces
|
||||||
turndownService.turndown(
|
const item = await fileSvc.createFile({
|
||||||
htmlSanitizer.sanitizeHtml(content)
|
...Provider.parseContent(turndownService.turndown(sanitizedContent)),
|
||||||
.replace(/ /g, ' '), // Replace non-breaking spaces with classic spaces
|
name: file.name,
|
||||||
)),
|
});
|
||||||
name: file.name,
|
this.$store.commit('file/setCurrentId', item.id);
|
||||||
}))
|
|
||||||
.then(
|
|
||||||
item => this.$store.commit('file/setCurrentId', item.id),
|
|
||||||
() => { /* Cancel */ });
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -116,7 +116,7 @@ export default {
|
|||||||
.catch(() => { /* Cancel */ });
|
.catch(() => { /* Cancel */ });
|
||||||
},
|
},
|
||||||
print() {
|
print() {
|
||||||
print();
|
window.print();
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -95,8 +95,8 @@ export default {
|
|||||||
reset() {
|
reset() {
|
||||||
return this.$store.dispatch('modal/reset')
|
return this.$store.dispatch('modal/reset')
|
||||||
.then(() => {
|
.then(() => {
|
||||||
location.href = '#reset=true';
|
window.location.href = '#reset=true';
|
||||||
location.reload();
|
window.location.reload();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
about() {
|
about() {
|
||||||
|
@ -170,13 +170,17 @@ export default {
|
|||||||
},
|
},
|
||||||
openGoogleDrive(token) {
|
openGoogleDrive(token) {
|
||||||
return googleHelper.openPicker(token, 'doc')
|
return googleHelper.openPicker(token, 'doc')
|
||||||
.then(files => this.$store.dispatch('queue/enqueue',
|
.then(files => this.$store.dispatch(
|
||||||
() => googleDriveProvider.openFiles(token, files)));
|
'queue/enqueue',
|
||||||
|
() => googleDriveProvider.openFiles(token, files),
|
||||||
|
));
|
||||||
},
|
},
|
||||||
openDropbox(token) {
|
openDropbox(token) {
|
||||||
return dropboxHelper.openChooser(token)
|
return dropboxHelper.openChooser(token)
|
||||||
.then(paths => this.$store.dispatch('queue/enqueue',
|
.then(paths => this.$store.dispatch(
|
||||||
() => dropboxProvider.openFiles(token, paths)));
|
'queue/enqueue',
|
||||||
|
() => dropboxProvider.openFiles(token, paths),
|
||||||
|
));
|
||||||
},
|
},
|
||||||
saveGoogleDrive(token) {
|
saveGoogleDrive(token) {
|
||||||
return openSyncModal(token, 'googleDriveSave')
|
return openSyncModal(token, 'googleDriveSave')
|
||||||
@ -191,8 +195,10 @@ export default {
|
|||||||
type: 'githubOpen',
|
type: 'githubOpen',
|
||||||
token,
|
token,
|
||||||
})
|
})
|
||||||
.then(syncLocation => this.$store.dispatch('queue/enqueue',
|
.then(syncLocation => this.$store.dispatch(
|
||||||
() => githubProvider.openFile(token, syncLocation)));
|
'queue/enqueue',
|
||||||
|
() => githubProvider.openFile(token, syncLocation),
|
||||||
|
));
|
||||||
},
|
},
|
||||||
saveGithub(token) {
|
saveGithub(token) {
|
||||||
return openSyncModal(token, 'githubSave')
|
return openSyncModal(token, 'githubSave')
|
||||||
|
@ -74,7 +74,7 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@import '../common/variables.scss';
|
@import '../../styles/variables.scss';
|
||||||
|
|
||||||
.workspace .menu-entry {
|
.workspace .menu-entry {
|
||||||
padding-top: 12px;
|
padding-top: 12px;
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@import '../../common/variables.scss';
|
@import '../../../styles/variables.scss';
|
||||||
|
|
||||||
.menu-entry {
|
.menu-entry {
|
||||||
text-align: left;
|
text-align: left;
|
||||||
|
@ -223,7 +223,7 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@import '../common/variables.scss';
|
@import '../../styles/variables.scss';
|
||||||
|
|
||||||
.modal__inner-1--file-properties {
|
.modal__inner-1--file-properties {
|
||||||
max-width: 540px;
|
max-width: 540px;
|
||||||
|
@ -56,7 +56,7 @@ export default modalTemplate({
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
resolve() {
|
resolve() {
|
||||||
const config = this.config;
|
const { config } = this;
|
||||||
const currentFile = this.$store.getters['file/current'];
|
const currentFile = this.$store.getters['file/current'];
|
||||||
config.resolve();
|
config.resolve();
|
||||||
exportSvc.exportToDisk(currentFile.id, 'html', this.allTemplates[this.selectedTemplate]);
|
exportSvc.exportToDisk(currentFile.id, 'html', this.allTemplates[this.selectedTemplate]);
|
||||||
|
@ -48,13 +48,13 @@ export default modalTemplate({
|
|||||||
if (!this.url) {
|
if (!this.url) {
|
||||||
this.setError('url');
|
this.setError('url');
|
||||||
} else {
|
} else {
|
||||||
const callback = this.config.callback;
|
const { callback } = this.config;
|
||||||
this.config.resolve();
|
this.config.resolve();
|
||||||
callback(this.url);
|
callback(this.url);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
reject() {
|
reject() {
|
||||||
const callback = this.config.callback;
|
const { callback } = this.config;
|
||||||
this.config.reject();
|
this.config.reject();
|
||||||
callback(null);
|
callback(null);
|
||||||
},
|
},
|
||||||
@ -62,7 +62,7 @@ export default modalTemplate({
|
|||||||
return googleHelper.addPhotosAccount();
|
return googleHelper.addPhotosAccount();
|
||||||
},
|
},
|
||||||
openGooglePhotos(token) {
|
openGooglePhotos(token) {
|
||||||
const callback = this.config.callback;
|
const { callback } = this.config;
|
||||||
this.config.reject();
|
this.config.reject();
|
||||||
googleHelper.openPicker(token, 'img')
|
googleHelper.openPicker(token, 'img')
|
||||||
.then(res => res[0] && this.$store.dispatch('modal/open', {
|
.then(res => res[0] && this.$store.dispatch('modal/open', {
|
||||||
|
@ -25,13 +25,13 @@ export default modalTemplate({
|
|||||||
if (!this.url) {
|
if (!this.url) {
|
||||||
this.setError('url');
|
this.setError('url');
|
||||||
} else {
|
} else {
|
||||||
const callback = this.config.callback;
|
const { callback } = this.config;
|
||||||
this.config.resolve();
|
this.config.resolve();
|
||||||
callback(this.url);
|
callback(this.url);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
reject() {
|
reject() {
|
||||||
const callback = this.config.callback;
|
const { callback } = this.config;
|
||||||
this.config.reject();
|
this.config.reject();
|
||||||
callback(null);
|
callback(null);
|
||||||
},
|
},
|
||||||
|
@ -42,7 +42,7 @@ export default modalTemplate({
|
|||||||
this.config.resolve();
|
this.config.resolve();
|
||||||
const currentFile = this.$store.getters['file/current'];
|
const currentFile = this.$store.getters['file/current'];
|
||||||
const currentContent = this.$store.getters['content/current'];
|
const currentContent = this.$store.getters['content/current'];
|
||||||
const selectedFormat = this.selectedFormat;
|
const { selectedFormat } = this;
|
||||||
this.$store.dispatch('queue/enqueue', () => Promise.all([
|
this.$store.dispatch('queue/enqueue', () => Promise.all([
|
||||||
Promise.resolve().then(() => {
|
Promise.resolve().then(() => {
|
||||||
const sponsorToken = this.$store.getters['workspace/sponsorToken'];
|
const sponsorToken = this.$store.getters['workspace/sponsorToken'];
|
||||||
@ -64,15 +64,15 @@ export default modalTemplate({
|
|||||||
blob: true,
|
blob: true,
|
||||||
timeout: 60000,
|
timeout: 60000,
|
||||||
})
|
})
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
FileSaver.saveAs(res.body, `${currentFile.name}.${selectedFormat}`);
|
FileSaver.saveAs(res.body, `${currentFile.name}.${selectedFormat}`);
|
||||||
}, (err) => {
|
}, (err) => {
|
||||||
if (err.status !== 401) {
|
if (err.status !== 401) {
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
this.$store.dispatch('modal/sponsorOnly')
|
this.$store.dispatch('modal/sponsorOnly')
|
||||||
.catch(() => { /* Cancel */ });
|
.catch(() => { /* Cancel */ });
|
||||||
}))
|
}))
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
console.error(err); // eslint-disable-line no-console
|
console.error(err); // eslint-disable-line no-console
|
||||||
this.$store.dispatch('notification/error', err);
|
this.$store.dispatch('notification/error', err);
|
||||||
|
@ -43,7 +43,10 @@ export default modalTemplate({
|
|||||||
}),
|
}),
|
||||||
sponsorSvc.getToken(),
|
sponsorSvc.getToken(),
|
||||||
exportSvc.applyTemplate(
|
exportSvc.applyTemplate(
|
||||||
currentFile.id, this.allTemplates[this.selectedTemplate], true),
|
currentFile.id,
|
||||||
|
this.allTemplates[this.selectedTemplate],
|
||||||
|
true,
|
||||||
|
),
|
||||||
])
|
])
|
||||||
.then(([sponsorToken, token, html]) => networkSvc.request({
|
.then(([sponsorToken, token, html]) => networkSvc.request({
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
@ -57,15 +60,15 @@ export default modalTemplate({
|
|||||||
blob: true,
|
blob: true,
|
||||||
timeout: 60000,
|
timeout: 60000,
|
||||||
})
|
})
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
FileSaver.saveAs(res.body, `${currentFile.name}.pdf`);
|
FileSaver.saveAs(res.body, `${currentFile.name}.pdf`);
|
||||||
}, (err) => {
|
}, (err) => {
|
||||||
if (err.status !== 401) {
|
if (err.status !== 401) {
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
this.$store.dispatch('modal/sponsorOnly')
|
this.$store.dispatch('modal/sponsorOnly')
|
||||||
.catch(() => { /* Cancel */ });
|
.catch(() => { /* Cancel */ });
|
||||||
}))
|
}))
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
console.error(err); // eslint-disable-line no-console
|
console.error(err); // eslint-disable-line no-console
|
||||||
this.$store.dispatch('notification/error', err);
|
this.$store.dispatch('notification/error', err);
|
||||||
|
@ -59,7 +59,7 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@import '../common/variables.scss';
|
@import '../../styles/variables.scss';
|
||||||
|
|
||||||
.modal__inner-1--publish-management {
|
.modal__inner-1--publish-management {
|
||||||
max-width: 560px;
|
max-width: 560px;
|
||||||
|
@ -81,7 +81,7 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@import '../common/variables.scss';
|
@import '../../styles/variables.scss';
|
||||||
|
|
||||||
.modal__inner-1--settings {
|
.modal__inner-1--settings {
|
||||||
max-width: 600px;
|
max-width: 600px;
|
||||||
|
@ -63,7 +63,7 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@import '../common/variables.scss';
|
@import '../../styles/variables.scss';
|
||||||
|
|
||||||
.modal__inner-1--sponsor {
|
.modal__inner-1--sponsor {
|
||||||
max-width: 380px;
|
max-width: 380px;
|
||||||
|
@ -59,7 +59,7 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@import '../common/variables.scss';
|
@import '../../styles/variables.scss';
|
||||||
|
|
||||||
.modal__inner-1--sync-management {
|
.modal__inner-1--sync-management {
|
||||||
max-width: 560px;
|
max-width: 560px;
|
||||||
|
@ -105,10 +105,12 @@ export default {
|
|||||||
this.templates = templates;
|
this.templates = templates;
|
||||||
this.selectedId = this.config.selectedId;
|
this.selectedId = this.config.selectedId;
|
||||||
if (!templates[this.selectedId]) {
|
if (!templates[this.selectedId]) {
|
||||||
this.selectedId = Object.keys(templates)[0];
|
[this.selectedId] = Object.keys(templates);
|
||||||
}
|
}
|
||||||
this.isEditing = false;
|
this.isEditing = false;
|
||||||
}, { immediate: true });
|
},
|
||||||
|
{ immediate: true },
|
||||||
|
);
|
||||||
this.$watch('selectedId', (selectedId) => {
|
this.$watch('selectedId', (selectedId) => {
|
||||||
const template = this.templates[selectedId];
|
const template = this.templates[selectedId];
|
||||||
this.showHelpers = template.helpers !== emptyTemplateHelpers;
|
this.showHelpers = template.helpers !== emptyTemplateHelpers;
|
||||||
@ -137,7 +139,7 @@ export default {
|
|||||||
},
|
},
|
||||||
remove() {
|
remove() {
|
||||||
delete this.templates[this.selectedId];
|
delete this.templates[this.selectedId];
|
||||||
this.selectedId = Object.keys(this.templates)[0];
|
[this.selectedId] = Object.keys(this.templates);
|
||||||
},
|
},
|
||||||
submitEdit(cancel) {
|
submitEdit(cancel) {
|
||||||
const template = this.templates[this.selectedId];
|
const template = this.templates[this.selectedId];
|
||||||
|
@ -87,7 +87,7 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@import '../common/variables.scss';
|
@import '../../styles/variables.scss';
|
||||||
|
|
||||||
.modal__inner-1--workspace-management {
|
.modal__inner-1--workspace-management {
|
||||||
max-width: 560px;
|
max-width: 560px;
|
||||||
|
@ -24,7 +24,7 @@ export default {
|
|||||||
'config',
|
'config',
|
||||||
]),
|
]),
|
||||||
showSponsorButton() {
|
showSponsorButton() {
|
||||||
const type = this.$store.getters['modal/config'].type;
|
const { type } = this.$store.getters['modal/config'];
|
||||||
return !this.$store.getters.isSponsor && type !== 'sponsor' && type !== 'signInForSponsorship';
|
return !this.$store.getters.isSponsor && type !== 'sponsor' && type !== 'signInForSponsorship';
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -49,7 +49,7 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@import '../../common/variables.scss';
|
@import '../../../styles/variables.scss';
|
||||||
|
|
||||||
.modal__close-button {
|
.modal__close-button {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
@ -54,7 +54,10 @@ export default modalTemplate({
|
|||||||
} else {
|
} else {
|
||||||
// Return new location
|
// Return new location
|
||||||
const location = bloggerPageProvider.makeLocation(
|
const location = bloggerPageProvider.makeLocation(
|
||||||
this.config.token, this.blogUrl, this.pageId);
|
this.config.token,
|
||||||
|
this.blogUrl,
|
||||||
|
this.pageId,
|
||||||
|
);
|
||||||
location.templateId = this.selectedTemplate;
|
location.templateId = this.selectedTemplate;
|
||||||
this.config.resolve(location);
|
this.config.resolve(location);
|
||||||
}
|
}
|
||||||
|
@ -55,7 +55,10 @@ export default modalTemplate({
|
|||||||
} else {
|
} else {
|
||||||
// Return new location
|
// Return new location
|
||||||
const location = bloggerProvider.makeLocation(
|
const location = bloggerProvider.makeLocation(
|
||||||
this.config.token, this.blogUrl, this.postId);
|
this.config.token,
|
||||||
|
this.blogUrl,
|
||||||
|
this.postId,
|
||||||
|
);
|
||||||
location.templateId = this.selectedTemplate;
|
location.templateId = this.selectedTemplate;
|
||||||
this.config.resolve(location);
|
this.config.resolve(location);
|
||||||
}
|
}
|
||||||
|
@ -65,7 +65,11 @@ export default modalTemplate({
|
|||||||
} else {
|
} else {
|
||||||
// Return new location
|
// Return new location
|
||||||
const location = gistProvider.makeLocation(
|
const location = gistProvider.makeLocation(
|
||||||
this.config.token, this.filename, this.isPublic, this.gistId);
|
this.config.token,
|
||||||
|
this.filename,
|
||||||
|
this.isPublic,
|
||||||
|
this.gistId,
|
||||||
|
);
|
||||||
location.templateId = this.selectedTemplate;
|
location.templateId = this.selectedTemplate;
|
||||||
this.config.resolve(location);
|
this.config.resolve(location);
|
||||||
}
|
}
|
||||||
|
@ -51,7 +51,11 @@ export default modalTemplate({
|
|||||||
} else {
|
} else {
|
||||||
// Return new location
|
// Return new location
|
||||||
const location = gistProvider.makeLocation(
|
const location = gistProvider.makeLocation(
|
||||||
this.config.token, this.filename, this.isPublic, this.gistId);
|
this.config.token,
|
||||||
|
this.filename,
|
||||||
|
this.isPublic,
|
||||||
|
this.gistId,
|
||||||
|
);
|
||||||
this.config.resolve(location);
|
this.config.resolve(location);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -58,7 +58,12 @@ export default modalTemplate({
|
|||||||
} else {
|
} else {
|
||||||
// Return new location
|
// Return new location
|
||||||
const location = githubProvider.makeLocation(
|
const location = githubProvider.makeLocation(
|
||||||
this.config.token, parsedRepo.owner, parsedRepo.repo, this.branch || 'master', this.path);
|
this.config.token,
|
||||||
|
parsedRepo.owner,
|
||||||
|
parsedRepo.repo,
|
||||||
|
this.branch || 'master',
|
||||||
|
this.path,
|
||||||
|
);
|
||||||
this.config.resolve(location);
|
this.config.resolve(location);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -73,7 +73,12 @@ export default modalTemplate({
|
|||||||
} else {
|
} else {
|
||||||
// Return new location
|
// Return new location
|
||||||
const location = githubProvider.makeLocation(
|
const location = githubProvider.makeLocation(
|
||||||
this.config.token, parsedRepo[1], parsedRepo[2], this.branch || 'master', this.path);
|
this.config.token,
|
||||||
|
parsedRepo[1],
|
||||||
|
parsedRepo[2],
|
||||||
|
this.branch || 'master',
|
||||||
|
this.path,
|
||||||
|
);
|
||||||
location.templateId = this.selectedTemplate;
|
location.templateId = this.selectedTemplate;
|
||||||
this.config.resolve(location);
|
this.config.resolve(location);
|
||||||
}
|
}
|
||||||
|
@ -58,7 +58,12 @@ export default modalTemplate({
|
|||||||
}
|
}
|
||||||
if (parsedRepo && this.path) {
|
if (parsedRepo && this.path) {
|
||||||
const location = githubProvider.makeLocation(
|
const location = githubProvider.makeLocation(
|
||||||
this.config.token, parsedRepo.owner, parsedRepo.repo, this.branch || 'master', this.path);
|
this.config.token,
|
||||||
|
parsedRepo.owner,
|
||||||
|
parsedRepo.repo,
|
||||||
|
this.branch || 'master',
|
||||||
|
this.path,
|
||||||
|
);
|
||||||
this.config.resolve(location);
|
this.config.resolve(location);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -76,12 +76,12 @@ export default modalTemplate({
|
|||||||
this.$store.dispatch('data/patchLocalSettings', {
|
this.$store.dispatch('data/patchLocalSettings', {
|
||||||
googleDriveFolderId: folders[0].id,
|
googleDriveFolderId: folders[0].id,
|
||||||
});
|
});
|
||||||
}));
|
}),
|
||||||
|
);
|
||||||
},
|
},
|
||||||
resolve() {
|
resolve() {
|
||||||
// Return new location
|
// Return new location
|
||||||
const location = googleDriveProvider.makeLocation(
|
const location = googleDriveProvider.makeLocation(this.config.token, this.fileId);
|
||||||
this.config.token, this.fileId);
|
|
||||||
if (this.format) {
|
if (this.format) {
|
||||||
location.templateId = this.selectedTemplate;
|
location.templateId = this.selectedTemplate;
|
||||||
}
|
}
|
||||||
|
@ -49,12 +49,16 @@ export default modalTemplate({
|
|||||||
this.$store.dispatch('data/patchLocalSettings', {
|
this.$store.dispatch('data/patchLocalSettings', {
|
||||||
googleDriveFolderId: folders[0].id,
|
googleDriveFolderId: folders[0].id,
|
||||||
});
|
});
|
||||||
}));
|
}),
|
||||||
|
);
|
||||||
},
|
},
|
||||||
resolve() {
|
resolve() {
|
||||||
// Return new location
|
// Return new location
|
||||||
const location = googleDriveProvider.makeLocation(
|
const location = googleDriveProvider.makeLocation(
|
||||||
this.config.token, this.fileId, this.folderId);
|
this.config.token,
|
||||||
|
this.fileId,
|
||||||
|
this.folderId,
|
||||||
|
);
|
||||||
this.config.resolve(location);
|
this.config.resolve(location);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -40,7 +40,8 @@ export default modalTemplate({
|
|||||||
this.$store.dispatch('data/patchLocalSettings', {
|
this.$store.dispatch('data/patchLocalSettings', {
|
||||||
googleDriveWorkspaceFolderId: folders[0].id,
|
googleDriveWorkspaceFolderId: folders[0].id,
|
||||||
});
|
});
|
||||||
}));
|
}),
|
||||||
|
);
|
||||||
},
|
},
|
||||||
resolve() {
|
resolve() {
|
||||||
const url = utils.addQueryParams('app', {
|
const url = utils.addQueryParams('app', {
|
||||||
|
@ -42,20 +42,20 @@ export default {
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
resolve() {
|
resolve() {
|
||||||
let url = this.config.url;
|
let { url } = this.config;
|
||||||
const size = parseInt(this.size, 10);
|
const size = parseInt(this.size, 10);
|
||||||
if (!isNaN(size)) {
|
if (!Number.isNaN(size)) {
|
||||||
url = makeThumbnail(url, size);
|
url = makeThumbnail(url, size);
|
||||||
}
|
}
|
||||||
if (this.title) {
|
if (this.title) {
|
||||||
url += ` "${this.title}"`;
|
url += ` "${this.title}"`;
|
||||||
}
|
}
|
||||||
const callback = this.config.callback;
|
const { callback } = this.config;
|
||||||
this.config.resolve();
|
this.config.resolve();
|
||||||
callback(url);
|
callback(url);
|
||||||
},
|
},
|
||||||
reject() {
|
reject() {
|
||||||
const callback = this.config.callback;
|
const { callback } = this.config;
|
||||||
this.config.reject();
|
this.config.reject();
|
||||||
callback(null);
|
callback(null);
|
||||||
},
|
},
|
||||||
|
@ -57,7 +57,10 @@ export default modalTemplate({
|
|||||||
} else {
|
} else {
|
||||||
// Return new location
|
// Return new location
|
||||||
const location = wordpressProvider.makeLocation(
|
const location = wordpressProvider.makeLocation(
|
||||||
this.config.token, this.domain, this.postId);
|
this.config.token,
|
||||||
|
this.domain,
|
||||||
|
this.postId,
|
||||||
|
);
|
||||||
location.templateId = this.selectedTemplate;
|
location.templateId = this.selectedTemplate;
|
||||||
this.config.resolve(location);
|
this.config.resolve(location);
|
||||||
}
|
}
|
||||||
|
@ -62,7 +62,11 @@ export default modalTemplate({
|
|||||||
} else {
|
} else {
|
||||||
// Return new location
|
// Return new location
|
||||||
const location = zendeskProvider.makeLocation(
|
const location = zendeskProvider.makeLocation(
|
||||||
this.config.token, this.sectionId, this.locale || 'en-us', this.articleId);
|
this.config.token,
|
||||||
|
this.sectionId,
|
||||||
|
this.locale || 'en-us',
|
||||||
|
this.articleId,
|
||||||
|
);
|
||||||
location.templateId = this.selectedTemplate;
|
location.templateId = this.selectedTemplate;
|
||||||
this.config.resolve(location);
|
this.config.resolve(location);
|
||||||
}
|
}
|
||||||
|
@ -1 +0,0 @@
|
|||||||
@import './common/base';
|
|
@ -10,8 +10,7 @@ function attrSet(token, name, value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
module.exports = (md) => {
|
module.exports = (md) => {
|
||||||
md.core.ruler.after('inline', 'tasklist', (state) => {
|
md.core.ruler.after('inline', 'tasklist', ({ tokens, Token }) => {
|
||||||
const tokens = state.tokens;
|
|
||||||
for (let i = 2; i < tokens.length; i += 1) {
|
for (let i = 2; i < tokens.length; i += 1) {
|
||||||
const token = tokens[i];
|
const token = tokens[i];
|
||||||
if (token.content
|
if (token.content
|
||||||
@ -24,7 +23,7 @@ module.exports = (md) => {
|
|||||||
) {
|
) {
|
||||||
const cross = token.content[1].toLowerCase();
|
const cross = token.content[1].toLowerCase();
|
||||||
if (cross === ' ' || cross === 'x') {
|
if (cross === ' ' || cross === 'x') {
|
||||||
const checkbox = new state.Token('html_inline', '', 0);
|
const checkbox = new Token('html_inline', '', 0);
|
||||||
if (cross === ' ') {
|
if (cross === ' ') {
|
||||||
checkbox.content = '<span class="task-list-item-checkbox" type="checkbox">☐</span>';
|
checkbox.content = '<span class="task-list-item-checkbox" type="checkbox">☐</span>';
|
||||||
} else {
|
} else {
|
||||||
|
@ -51,8 +51,8 @@ const inlineBaseRules2 = [
|
|||||||
'text_collapse',
|
'text_collapse',
|
||||||
];
|
];
|
||||||
|
|
||||||
extensionSvc.onGetOptions(
|
extensionSvc.onGetOptions((options, properties) => Object
|
||||||
(options, properties) => Object.assign(options, properties.extensions.markdown));
|
.assign(options, properties.extensions.markdown));
|
||||||
|
|
||||||
extensionSvc.onInitConverter(0, (markdown, options) => {
|
extensionSvc.onInitConverter(0, (markdown, options) => {
|
||||||
markdown.set({
|
markdown.set({
|
||||||
|
@ -117,6 +117,6 @@ extensionSvc.onGetOptions((options, properties) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
extensionSvc.onSectionPreview((elt) => {
|
extensionSvc.onSectionPreview((elt) => {
|
||||||
elt.querySelectorAll('.prism.language-mermaid').cl_each(
|
elt.querySelectorAll('.prism.language-mermaid')
|
||||||
diagramElt => render(diagramElt.parentNode));
|
.cl_each(diagramElt => render(diagramElt.parentNode));
|
||||||
});
|
});
|
||||||
|
34
src/index.js
34
src/index.js
@ -13,24 +13,22 @@ if (!indexedDB) {
|
|||||||
throw new Error('Your browser is not supported. Please upgrade to the latest version.');
|
throw new Error('Your browser is not supported. Please upgrade to the latest version.');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NODE_ENV === 'production') {
|
OfflinePluginRuntime.install({
|
||||||
OfflinePluginRuntime.install({
|
onUpdateReady: () => {
|
||||||
onUpdateReady: () => {
|
// Tells to new SW to take control immediately
|
||||||
// Tells to new SW to take control immediately
|
OfflinePluginRuntime.applyUpdate();
|
||||||
OfflinePluginRuntime.applyUpdate();
|
},
|
||||||
},
|
onUpdated: () => {
|
||||||
onUpdated: () => {
|
if (!store.state.light) {
|
||||||
if (!store.state.light) {
|
localDbSvc.sync()
|
||||||
localDbSvc.sync()
|
.then(() => {
|
||||||
.then(() => {
|
localStorage.updated = true;
|
||||||
localStorage.updated = true;
|
// Reload the webpage to load into the new version
|
||||||
// Reload the webpage to load into the new version
|
window.location.reload();
|
||||||
location.reload();
|
});
|
||||||
});
|
}
|
||||||
}
|
},
|
||||||
},
|
});
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (localStorage.updated) {
|
if (localStorage.updated) {
|
||||||
store.dispatch('notification/info', 'StackEdit has just updated itself!');
|
store.dispatch('notification/info', 'StackEdit has just updated itself!');
|
||||||
|
@ -63,7 +63,7 @@ function StyleAttribute(name, unit, defaultValue, wrap = identity) {
|
|||||||
this.name = name;
|
this.name = name;
|
||||||
this.setStart = (animation) => {
|
this.setStart = (animation) => {
|
||||||
let value = parseFloat(animation.elt.style[name]);
|
let value = parseFloat(animation.elt.style[name]);
|
||||||
if (isNaN(value)) {
|
if (Number.isNaN(value)) {
|
||||||
value = animation.$current[name] || defaultValue;
|
value = animation.$current[name] || defaultValue;
|
||||||
}
|
}
|
||||||
animation.$start[name] = value;
|
animation.$start[name] = value;
|
||||||
@ -157,7 +157,7 @@ class Animation {
|
|||||||
const onTransitionEnd = (evt) => {
|
const onTransitionEnd = (evt) => {
|
||||||
if (evt.target === this.elt) {
|
if (evt.target === this.elt) {
|
||||||
this.elt.removeEventListener(transitionEndEvent, onTransitionEnd);
|
this.elt.removeEventListener(transitionEndEvent, onTransitionEnd);
|
||||||
const endCb = this.$end.endCb;
|
const { endCb } = this.$end;
|
||||||
this.$end.endCb = undefined;
|
this.$end.endCb = undefined;
|
||||||
if (endCb) {
|
if (endCb) {
|
||||||
endCb();
|
endCb();
|
||||||
|
@ -12,7 +12,7 @@ function cledit(contentElt, scrollEltOpt, isMarkdown = false) {
|
|||||||
$markers: {},
|
$markers: {},
|
||||||
};
|
};
|
||||||
cledit.Utils.createEventHooks(editor);
|
cledit.Utils.createEventHooks(editor);
|
||||||
const debounce = cledit.Utils.debounce;
|
const { debounce } = cledit.Utils;
|
||||||
|
|
||||||
contentElt.setAttribute('tabindex', '0'); // To have focus even when disabled
|
contentElt.setAttribute('tabindex', '0'); // To have focus even when disabled
|
||||||
editor.toggleEditable = (isEditable) => {
|
editor.toggleEditable = (isEditable) => {
|
||||||
@ -21,7 +21,7 @@ function cledit(contentElt, scrollEltOpt, isMarkdown = false) {
|
|||||||
editor.toggleEditable(true);
|
editor.toggleEditable(true);
|
||||||
|
|
||||||
function getTextContent() {
|
function getTextContent() {
|
||||||
// Markdown-it sanitization (Mac/DOS to Unix)
|
// Markdown-it sanitization (Mac/DOS to Unix)
|
||||||
let textContent = contentElt.textContent.replace(/\r[\n\u0085]?|[\u2424\u2028\u0085]/g, '\n');
|
let textContent = contentElt.textContent.replace(/\r[\n\u0085]?|[\u2424\u2028\u0085]/g, '\n');
|
||||||
if (textContent.slice(-1) !== '\n') {
|
if (textContent.slice(-1) !== '\n') {
|
||||||
textContent += '\n';
|
textContent += '\n';
|
||||||
@ -258,8 +258,10 @@ function cledit(contentElt, scrollEltOpt, isMarkdown = false) {
|
|||||||
window.addEventListener('resize', windowResizeListener);
|
window.addEventListener('resize', windowResizeListener);
|
||||||
|
|
||||||
// Provokes selection changes and does not fire mouseup event on Chrome/OSX
|
// Provokes selection changes and does not fire mouseup event on Chrome/OSX
|
||||||
contentElt.addEventListener('contextmenu',
|
contentElt.addEventListener(
|
||||||
selectionMgr.saveSelectionState.cl_bind(selectionMgr, true, false));
|
'contextmenu',
|
||||||
|
selectionMgr.saveSelectionState.cl_bind(selectionMgr, true, false),
|
||||||
|
);
|
||||||
|
|
||||||
contentElt.addEventListener('keydown', keydownHandler((evt) => {
|
contentElt.addEventListener('keydown', keydownHandler((evt) => {
|
||||||
selectionMgr.saveSelectionState();
|
selectionMgr.saveSelectionState();
|
||||||
@ -344,7 +346,7 @@ function cledit(contentElt, scrollEltOpt, isMarkdown = false) {
|
|||||||
undoMgr.setCurrentMode('single');
|
undoMgr.setCurrentMode('single');
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
let data;
|
let data;
|
||||||
let clipboardData = evt.clipboardData;
|
let { clipboardData } = evt;
|
||||||
if (clipboardData) {
|
if (clipboardData) {
|
||||||
data = clipboardData.getData('text/plain');
|
data = clipboardData.getData('text/plain');
|
||||||
if (turndownService) {
|
if (turndownService) {
|
||||||
@ -362,7 +364,7 @@ function cledit(contentElt, scrollEltOpt, isMarkdown = false) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
clipboardData = window.clipboardData;
|
({ clipboardData } = window.clipboardData);
|
||||||
data = clipboardData && clipboardData.getData('Text');
|
data = clipboardData && clipboardData.getData('Text');
|
||||||
}
|
}
|
||||||
if (!data) {
|
if (!data) {
|
||||||
@ -382,8 +384,9 @@ function cledit(contentElt, scrollEltOpt, isMarkdown = false) {
|
|||||||
|
|
||||||
function addKeystroke(keystroke) {
|
function addKeystroke(keystroke) {
|
||||||
const keystrokes = Array.isArray(keystroke) ? keystroke : [keystroke];
|
const keystrokes = Array.isArray(keystroke) ? keystroke : [keystroke];
|
||||||
editor.$keystrokes = editor.$keystrokes.concat(keystrokes).sort(
|
editor.$keystrokes = editor.$keystrokes
|
||||||
(keystroke1, keystroke2) => keystroke1.priority - keystroke2.priority);
|
.concat(keystrokes)
|
||||||
|
.sort((keystroke1, keystroke2) => keystroke1.priority - keystroke2.priority);
|
||||||
}
|
}
|
||||||
addKeystroke(cledit.defaultKeystrokes);
|
addKeystroke(cledit.defaultKeystrokes);
|
||||||
|
|
||||||
|
@ -33,10 +33,10 @@ function Highlighter(editor) {
|
|||||||
section.forceHighlighting = true;
|
section.forceHighlighting = true;
|
||||||
if (!noContentFix) {
|
if (!noContentFix) {
|
||||||
if (useBr) {
|
if (useBr) {
|
||||||
section.elt.getElementsByClassName('hd-lf').cl_each(
|
section.elt.getElementsByClassName('hd-lf')
|
||||||
lfElt => lfElt.parentNode.removeChild(lfElt));
|
.cl_each(lfElt => lfElt.parentNode.removeChild(lfElt));
|
||||||
section.elt.getElementsByTagName('br').cl_each(
|
section.elt.getElementsByTagName('br')
|
||||||
brElt => brElt.parentNode.replaceChild(document.createTextNode('\n'), brElt));
|
.cl_each(brElt => brElt.parentNode.replaceChild(document.createTextNode('\n'), brElt));
|
||||||
}
|
}
|
||||||
if (section.elt.textContent.slice(-1) !== '\n') {
|
if (section.elt.textContent.slice(-1) !== '\n') {
|
||||||
section.elt.appendChild(document.createTextNode('\n'));
|
section.elt.appendChild(document.createTextNode('\n'));
|
||||||
@ -127,7 +127,7 @@ function Highlighter(editor) {
|
|||||||
const leftSections = sectionList.slice(0, leftIndex);
|
const leftSections = sectionList.slice(0, leftIndex);
|
||||||
modifiedSections = newSectionList.slice(leftIndex, newSectionList.length + rightIndex);
|
modifiedSections = newSectionList.slice(leftIndex, newSectionList.length + rightIndex);
|
||||||
const rightSections = sectionList.slice(sectionList.length + rightIndex, sectionList.length);
|
const rightSections = sectionList.slice(sectionList.length + rightIndex, sectionList.length);
|
||||||
insertBeforeSection = rightSections[0];
|
[insertBeforeSection] = rightSections;
|
||||||
sectionsToRemove = sectionList.slice(leftIndex, sectionList.length + rightIndex);
|
sectionsToRemove = sectionList.slice(leftIndex, sectionList.length + rightIndex);
|
||||||
sectionList = leftSections.concat(modifiedSections).concat(rightSections);
|
sectionList = leftSections.concat(modifiedSections).concat(rightSections);
|
||||||
}
|
}
|
||||||
|
@ -165,7 +165,10 @@ cledit.defaultKeystrokes = [
|
|||||||
// Custom jump behavior
|
// Custom jump behavior
|
||||||
const textContent = editor.getContent();
|
const textContent = editor.getContent();
|
||||||
const offset = getNextWordOffset(
|
const offset = getNextWordOffset(
|
||||||
textContent, editor.selectionMgr.selectionEnd, evt.which === 37);
|
textContent,
|
||||||
|
editor.selectionMgr.selectionEnd,
|
||||||
|
evt.which === 37,
|
||||||
|
);
|
||||||
if (evt.shiftKey) {
|
if (evt.shiftKey) {
|
||||||
// rebuild the state completely
|
// rebuild the state completely
|
||||||
const min = Math.min(editor.selectionMgr.selectionStart, offset);
|
const min = Math.min(editor.selectionMgr.selectionStart, offset);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import cledit from './cleditCore';
|
import cledit from './cleditCore';
|
||||||
|
|
||||||
function SelectionMgr(editor) {
|
function SelectionMgr(editor) {
|
||||||
const debounce = cledit.Utils.debounce;
|
const { debounce } = cledit.Utils;
|
||||||
const contentElt = editor.$contentElt;
|
const contentElt = editor.$contentElt;
|
||||||
const scrollElt = editor.$scrollElt;
|
const scrollElt = editor.$scrollElt;
|
||||||
cledit.Utils.createEventHooks(this);
|
cledit.Utils.createEventHooks(this);
|
||||||
@ -29,10 +29,10 @@ function SelectionMgr(editor) {
|
|||||||
|
|
||||||
this.createRange = (start, end) => {
|
this.createRange = (start, end) => {
|
||||||
const range = document.createRange();
|
const range = document.createRange();
|
||||||
const startContainer = isNaN(start) ? start : this.findContainer(start < 0 ? 0 : start);
|
const startContainer = Number.isNaN(start) ? start : this.findContainer(start < 0 ? 0 : start);
|
||||||
let endContainer = startContainer;
|
let endContainer = startContainer;
|
||||||
if (start !== end) {
|
if (start !== end) {
|
||||||
endContainer = isNaN(end) ? end : this.findContainer(end < 0 ? 0 : end);
|
endContainer = Number.isNaN(end) ? end : this.findContainer(end < 0 ? 0 : end);
|
||||||
}
|
}
|
||||||
range.setStart(startContainer.container, startContainer.offsetInContainer);
|
range.setStart(startContainer.container, startContainer.offsetInContainer);
|
||||||
range.setEnd(endContainer.container, endContainer.offsetInContainer);
|
range.setEnd(endContainer.container, endContainer.offsetInContainer);
|
||||||
@ -42,7 +42,10 @@ function SelectionMgr(editor) {
|
|||||||
let adjustScroll;
|
let adjustScroll;
|
||||||
const debouncedUpdateCursorCoordinates = debounce(() => {
|
const debouncedUpdateCursorCoordinates = debounce(() => {
|
||||||
const coordinates = this.getCoordinates(
|
const coordinates = this.getCoordinates(
|
||||||
this.selectionEnd, this.selectionEndContainer, this.selectionEndOffset);
|
this.selectionEnd,
|
||||||
|
this.selectionEndContainer,
|
||||||
|
this.selectionEndOffset,
|
||||||
|
);
|
||||||
if (this.cursorCoordinates.top !== coordinates.top ||
|
if (this.cursorCoordinates.top !== coordinates.top ||
|
||||||
this.cursorCoordinates.height !== coordinates.height ||
|
this.cursorCoordinates.height !== coordinates.height ||
|
||||||
this.cursorCoordinates.left !== coordinates.left
|
this.cursorCoordinates.left !== coordinates.left
|
||||||
@ -163,10 +166,10 @@ function SelectionMgr(editor) {
|
|||||||
|
|
||||||
function getNodeIndex(node) {
|
function getNodeIndex(node) {
|
||||||
let i = 0;
|
let i = 0;
|
||||||
let previousSibling = node.previousSibling;
|
let { previousSibling } = node;
|
||||||
while (previousSibling) {
|
while (previousSibling) {
|
||||||
i += 1;
|
i += 1;
|
||||||
previousSibling = previousSibling.previousSibling;
|
({ previousSibling } = previousSibling);
|
||||||
}
|
}
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
@ -235,8 +238,8 @@ function SelectionMgr(editor) {
|
|||||||
const save = () => {
|
const save = () => {
|
||||||
let result;
|
let result;
|
||||||
if (this.hasFocus()) {
|
if (this.hasFocus()) {
|
||||||
let selectionStart = this.selectionStart;
|
let { selectionStart } = this;
|
||||||
let selectionEnd = this.selectionEnd;
|
let { selectionEnd } = this;
|
||||||
const selection = window.getSelection();
|
const selection = window.getSelection();
|
||||||
if (selection.rangeCount > 0) {
|
if (selection.rangeCount > 0) {
|
||||||
const selectionRange = selection.getRangeAt(0);
|
const selectionRange = selection.getRangeAt(0);
|
||||||
@ -271,8 +274,8 @@ function SelectionMgr(editor) {
|
|||||||
selection.anchorNode,
|
selection.anchorNode,
|
||||||
selection.anchorOffset,
|
selection.anchorOffset,
|
||||||
selection.focusNode,
|
selection.focusNode,
|
||||||
selection.focusOffset) === 1
|
selection.focusOffset,
|
||||||
) {
|
) === 1) {
|
||||||
selectionStart = offset + selectionText.length;
|
selectionStart = offset + selectionText.length;
|
||||||
selectionEnd = offset;
|
selectionEnd = offset;
|
||||||
} else {
|
} else {
|
||||||
@ -337,8 +340,8 @@ function SelectionMgr(editor) {
|
|||||||
let offsetInContainer = offsetInContainerParam;
|
let offsetInContainer = offsetInContainerParam;
|
||||||
if (!container) {
|
if (!container) {
|
||||||
const offset = this.findContainer(inputOffset);
|
const offset = this.findContainer(inputOffset);
|
||||||
container = offset.container;
|
({ container } = offset);
|
||||||
offsetInContainer = offset.offsetInContainer;
|
({ offsetInContainer } = offset);
|
||||||
}
|
}
|
||||||
let containerElt = container;
|
let containerElt = container;
|
||||||
if (!containerElt.hasChildNodes() && container.parentNode) {
|
if (!containerElt.hasChildNodes() && container.parentNode) {
|
||||||
|
@ -15,7 +15,7 @@ function UndoMgr(editor) {
|
|||||||
let currentState;
|
let currentState;
|
||||||
let previousPatches = [];
|
let previousPatches = [];
|
||||||
let currentPatches = [];
|
let currentPatches = [];
|
||||||
const debounce = cledit.Utils.debounce;
|
const { debounce } = cledit.Utils;
|
||||||
|
|
||||||
this.options = {
|
this.options = {
|
||||||
undoStackMaxSize: 200,
|
undoStackMaxSize: 200,
|
||||||
@ -166,7 +166,7 @@ function UndoMgr(editor) {
|
|||||||
|
|
||||||
this.init = (options) => {
|
this.init = (options) => {
|
||||||
this.options.cl_extend(options || {});
|
this.options.cl_extend(options || {});
|
||||||
selectionMgr = editor.selectionMgr;
|
({ selectionMgr } = editor);
|
||||||
if (!currentState) {
|
if (!currentState) {
|
||||||
currentState = new State();
|
currentState = new State();
|
||||||
}
|
}
|
||||||
|
@ -78,7 +78,8 @@ function restoreDiscussionOffsets(content, markerKeys) {
|
|||||||
}
|
}
|
||||||
count += 1;
|
count += 1;
|
||||||
return '';
|
return '';
|
||||||
});
|
},
|
||||||
|
);
|
||||||
// Sanitize offsets
|
// Sanitize offsets
|
||||||
Object.keys(content.discussions).forEach((discussionId) => {
|
Object.keys(content.discussions).forEach((discussionId) => {
|
||||||
const discussion = content.discussions[discussionId];
|
const discussion = content.discussions[discussionId];
|
||||||
|
@ -91,8 +91,8 @@ const editorSvc = Object.assign(new Vue(), editorSvcDiscussions, editorSvcUtils,
|
|||||||
this.previewCtxWithDiffs = null;
|
this.previewCtxWithDiffs = null;
|
||||||
editorSvc.$emit('previewCtxWithDiffs', null);
|
editorSvc.$emit('previewCtxWithDiffs', null);
|
||||||
const options = {
|
const options = {
|
||||||
sectionHighlighter: section => Prism.highlight(
|
sectionHighlighter: section => Prism
|
||||||
section.text, this.prismGrammars[section.data]),
|
.highlight(section.text, this.prismGrammars[section.data]),
|
||||||
sectionParser: (text) => {
|
sectionParser: (text) => {
|
||||||
this.parsingCtx = markdownConversionSvc.parseSections(this.converter, text);
|
this.parsingCtx = markdownConversionSvc.parseSections(this.converter, text);
|
||||||
return this.parsingCtx.sections;
|
return this.parsingCtx.sections;
|
||||||
@ -114,7 +114,7 @@ const editorSvc = Object.assign(new Vue(), editorSvcDiscussions, editorSvcUtils,
|
|||||||
convert() {
|
convert() {
|
||||||
this.conversionCtx = markdownConversionSvc.convert(this.parsingCtx, this.conversionCtx);
|
this.conversionCtx = markdownConversionSvc.convert(this.parsingCtx, this.conversionCtx);
|
||||||
this.$emit('conversionCtx', this.conversionCtx);
|
this.$emit('conversionCtx', this.conversionCtx);
|
||||||
tokens = this.parsingCtx.markdownState.tokens;
|
({ tokens } = this.parsingCtx.markdownState);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -139,7 +139,11 @@ const editorSvc = Object.assign(new Vue(), editorSvcDiscussions, editorSvcUtils,
|
|||||||
if (sectionDesc.editorElt !== section.elt) {
|
if (sectionDesc.editorElt !== section.elt) {
|
||||||
// Force textToPreviewDiffs computation
|
// Force textToPreviewDiffs computation
|
||||||
sectionDesc = new SectionDesc(
|
sectionDesc = new SectionDesc(
|
||||||
section, sectionDesc.previewElt, sectionDesc.tocElt, sectionDesc.html);
|
section,
|
||||||
|
sectionDesc.previewElt,
|
||||||
|
sectionDesc.tocElt,
|
||||||
|
sectionDesc.html,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
sectionDescList.push(sectionDesc);
|
sectionDescList.push(sectionDesc);
|
||||||
previewHtml += sectionDesc.html;
|
previewHtml += sectionDesc.html;
|
||||||
@ -256,7 +260,9 @@ const editorSvc = Object.assign(new Vue(), editorSvcDiscussions, editorSvcUtils,
|
|||||||
sectionDesc.previewText = sectionDesc.previewElt.textContent;
|
sectionDesc.previewText = sectionDesc.previewElt.textContent;
|
||||||
}
|
}
|
||||||
sectionDesc.textToPreviewDiffs = diffMatchPatch.diff_main(
|
sectionDesc.textToPreviewDiffs = diffMatchPatch.diff_main(
|
||||||
sectionDesc.section.text, sectionDesc.previewText);
|
sectionDesc.section.text,
|
||||||
|
sectionDesc.previewText,
|
||||||
|
);
|
||||||
hasOne = true;
|
hasOne = true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -316,7 +322,9 @@ const editorSvc = Object.assign(new Vue(), editorSvcDiscussions, editorSvcUtils,
|
|||||||
const editorEndOffset = editorSvc.getEditorOffset(previewSelectionEndOffset);
|
const editorEndOffset = editorSvc.getEditorOffset(previewSelectionEndOffset);
|
||||||
if (editorStartOffset != null && editorEndOffset != null) {
|
if (editorStartOffset != null && editorEndOffset != null) {
|
||||||
editorSvc.clEditor.selectionMgr.setSelectionStartEnd(
|
editorSvc.clEditor.selectionMgr.setSelectionStartEnd(
|
||||||
editorStartOffset, editorEndOffset);
|
editorStartOffset,
|
||||||
|
editorEndOffset,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
editorSvc.previewSelectionRange = range;
|
editorSvc.previewSelectionRange = range;
|
||||||
@ -559,17 +567,21 @@ const editorSvc = Object.assign(new Vue(), editorSvcDiscussions, editorSvcUtils,
|
|||||||
this.applyContent();
|
this.applyContent();
|
||||||
}, {
|
}, {
|
||||||
immediate: true,
|
immediate: true,
|
||||||
});
|
},
|
||||||
|
);
|
||||||
|
|
||||||
// Disable editor if hidden or if no content is loaded
|
// Disable editor if hidden or if no content is loaded
|
||||||
store.watch(
|
store.watch(
|
||||||
() => store.getters['content/isCurrentEditable'],
|
() => store.getters['content/isCurrentEditable'],
|
||||||
editable => this.clEditor.toggleEditable(!!editable), {
|
editable => this.clEditor.toggleEditable(!!editable), {
|
||||||
immediate: true,
|
immediate: true,
|
||||||
});
|
},
|
||||||
|
);
|
||||||
|
|
||||||
store.watch(() => utils.serializeObject(store.getters['layout/styles']),
|
store.watch(
|
||||||
() => this.measureSectionDimensions(false, true, true));
|
() => utils.serializeObject(store.getters['layout/styles']),
|
||||||
|
() => this.measureSectionDimensions(false, true, true),
|
||||||
|
);
|
||||||
|
|
||||||
this.initHighlighters();
|
this.initHighlighters();
|
||||||
this.$emit('inited');
|
this.$emit('inited');
|
||||||
|
@ -65,8 +65,10 @@ function syncDiscussionMarkers(content, writeOffsets) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (writeOffsets && newDiscussion) {
|
if (writeOffsets && newDiscussion) {
|
||||||
store.commit('discussion/patchNewDiscussion',
|
store.commit(
|
||||||
discussions[store.state.discussion.newDiscussionId]);
|
'discussion/patchNewDiscussion',
|
||||||
|
discussions[store.state.discussion.newDiscussionId],
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,7 +117,7 @@ function reversePatches(patches) {
|
|||||||
export default {
|
export default {
|
||||||
createClEditor(editorElt) {
|
createClEditor(editorElt) {
|
||||||
this.clEditor = cledit(editorElt, editorElt.parentNode, true);
|
this.clEditor = cledit(editorElt, editorElt.parentNode, true);
|
||||||
clEditor = this.clEditor;
|
({ clEditor } = this);
|
||||||
clEditor.on('contentChanged', (text) => {
|
clEditor.on('contentChanged', (text) => {
|
||||||
const oldContent = store.getters['content/current'];
|
const oldContent = store.getters['content/current'];
|
||||||
const newContent = {
|
const newContent = {
|
||||||
@ -175,7 +177,7 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
getTrimmedSelection() {
|
getTrimmedSelection() {
|
||||||
const selectionMgr = clEditor.selectionMgr;
|
const { selectionMgr } = clEditor;
|
||||||
let start = Math.min(selectionMgr.selectionStart, selectionMgr.selectionEnd);
|
let start = Math.min(selectionMgr.selectionStart, selectionMgr.selectionEnd);
|
||||||
let end = Math.max(selectionMgr.selectionStart, selectionMgr.selectionEnd);
|
let end = Math.max(selectionMgr.selectionStart, selectionMgr.selectionEnd);
|
||||||
const text = clEditor.getContent();
|
const text = clEditor.getContent();
|
||||||
@ -217,7 +219,10 @@ export default {
|
|||||||
editorClassAppliers = {};
|
editorClassAppliers = {};
|
||||||
Object.keys(discussions).forEach((discussionId) => {
|
Object.keys(discussions).forEach((discussionId) => {
|
||||||
const classApplier = oldEditorClassAppliers[discussionId] || new EditorClassApplier(
|
const classApplier = oldEditorClassAppliers[discussionId] || new EditorClassApplier(
|
||||||
classGetter('editor', discussionId), offsetGetter(discussionId), { discussionId });
|
classGetter('editor', discussionId),
|
||||||
|
offsetGetter(discussionId),
|
||||||
|
{ discussionId },
|
||||||
|
);
|
||||||
editorClassAppliers[discussionId] = classApplier;
|
editorClassAppliers[discussionId] = classApplier;
|
||||||
});
|
});
|
||||||
// Clean unused class appliers
|
// Clean unused class appliers
|
||||||
@ -232,7 +237,10 @@ export default {
|
|||||||
previewClassAppliers = {};
|
previewClassAppliers = {};
|
||||||
Object.keys(discussions).forEach((discussionId) => {
|
Object.keys(discussions).forEach((discussionId) => {
|
||||||
const classApplier = oldPreviewClassAppliers[discussionId] || new PreviewClassApplier(
|
const classApplier = oldPreviewClassAppliers[discussionId] || new PreviewClassApplier(
|
||||||
classGetter('preview', discussionId), offsetGetter(discussionId), { discussionId });
|
classGetter('preview', discussionId),
|
||||||
|
offsetGetter(discussionId),
|
||||||
|
{ discussionId },
|
||||||
|
);
|
||||||
previewClassAppliers[discussionId] = classApplier;
|
previewClassAppliers[discussionId] = classApplier;
|
||||||
});
|
});
|
||||||
// Clean unused class appliers
|
// Clean unused class appliers
|
||||||
|
@ -10,13 +10,11 @@ export default {
|
|||||||
* Get an object describing the position of the scroll bar in the file.
|
* Get an object describing the position of the scroll bar in the file.
|
||||||
*/
|
*/
|
||||||
getScrollPosition(elt = store.getters['layout/styles'].showEditor
|
getScrollPosition(elt = store.getters['layout/styles'].showEditor
|
||||||
? this.editorElt
|
? this.editorElt : this.previewElt) {
|
||||||
: this.previewElt,
|
|
||||||
) {
|
|
||||||
const dimensionKey = elt === this.editorElt
|
const dimensionKey = elt === this.editorElt
|
||||||
? 'editorDimension'
|
? 'editorDimension'
|
||||||
: 'previewDimension';
|
: 'previewDimension';
|
||||||
const scrollTop = elt.parentNode.scrollTop;
|
const { scrollTop } = elt.parentNode;
|
||||||
let result;
|
let result;
|
||||||
if (this.previewCtxMeasured) {
|
if (this.previewCtxMeasured) {
|
||||||
this.previewCtxMeasured.sectionDescList.some((sectionDesc, sectionIdx) => {
|
this.previewCtxMeasured.sectionDescList.some((sectionDesc, sectionIdx) => {
|
||||||
@ -39,7 +37,7 @@ export default {
|
|||||||
* Restore the scroll position from the current file content state.
|
* Restore the scroll position from the current file content state.
|
||||||
*/
|
*/
|
||||||
restoreScrollPosition() {
|
restoreScrollPosition() {
|
||||||
const scrollPosition = store.getters['contentState/current'].scrollPosition;
|
const { scrollPosition } = store.getters['contentState/current'];
|
||||||
if (scrollPosition && this.previewCtxMeasured) {
|
if (scrollPosition && this.previewCtxMeasured) {
|
||||||
const sectionDesc = this.previewCtxMeasured.sectionDescList[scrollPosition.sectionIdx];
|
const sectionDesc = this.previewCtxMeasured.sectionDescList[scrollPosition.sectionIdx];
|
||||||
if (sectionDesc) {
|
if (sectionDesc) {
|
||||||
|
@ -94,7 +94,7 @@ export default {
|
|||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const timeoutId = setTimeout(() => {
|
const timeoutId = setTimeout(() => {
|
||||||
worker.terminate();
|
worker.terminate();
|
||||||
reject('Template generation timeout.');
|
reject(new Error('Template generation timeout.'));
|
||||||
}, 10000);
|
}, 10000);
|
||||||
worker.addEventListener('message', (e) => {
|
worker.addEventListener('message', (e) => {
|
||||||
clearTimeout(timeoutId);
|
clearTimeout(timeoutId);
|
||||||
@ -102,7 +102,7 @@ export default {
|
|||||||
// e.data can contain unsafe data if helpers attempts to call postMessage
|
// e.data can contain unsafe data if helpers attempts to call postMessage
|
||||||
const [err, result] = e.data;
|
const [err, result] = e.data;
|
||||||
if (err) {
|
if (err) {
|
||||||
reject(`${err}`);
|
reject(new Error(`${err}`));
|
||||||
} else {
|
} else {
|
||||||
resolve(`${result}`);
|
resolve(`${result}`);
|
||||||
}
|
}
|
||||||
|
@ -7,22 +7,29 @@ export default {
|
|||||||
/**
|
/**
|
||||||
* Create a file in the store with the specified fields.
|
* Create a file in the store with the specified fields.
|
||||||
*/
|
*/
|
||||||
createFile(fields = {}, background = false) {
|
createFile({
|
||||||
|
name,
|
||||||
|
parentId,
|
||||||
|
text,
|
||||||
|
properties,
|
||||||
|
discussions,
|
||||||
|
comments,
|
||||||
|
} = {}, background = false) {
|
||||||
const id = utils.uid();
|
const id = utils.uid();
|
||||||
const file = {
|
const file = {
|
||||||
id,
|
id,
|
||||||
name: utils.sanitizeName(fields.name),
|
name: utils.sanitizeName(name),
|
||||||
parentId: fields.parentId || null,
|
parentId: parentId || null,
|
||||||
};
|
};
|
||||||
const content = {
|
const content = {
|
||||||
id: `${id}/content`,
|
id: `${id}/content`,
|
||||||
text: utils.sanitizeText(fields.text || store.getters['data/computedSettings'].newFileContent),
|
text: utils.sanitizeText(text || store.getters['data/computedSettings'].newFileContent),
|
||||||
properties: utils.sanitizeText(
|
properties: utils
|
||||||
fields.properties || store.getters['data/computedSettings'].newFileProperties),
|
.sanitizeText(properties || store.getters['data/computedSettings'].newFileProperties),
|
||||||
discussions: fields.discussions || {},
|
discussions: discussions || {},
|
||||||
comments: fields.comments || {},
|
comments: comments || {},
|
||||||
};
|
};
|
||||||
const nameStripped = file.name !== utils.defaultName && file.name !== fields.name;
|
const nameStripped = file.name !== utils.defaultName && file.name !== name;
|
||||||
|
|
||||||
// Check if there is a path conflict
|
// Check if there is a path conflict
|
||||||
const workspaceUniquePaths = store.getters['workspace/hasUniquePaths'];
|
const workspaceUniquePaths = store.getters['workspace/hasUniquePaths'];
|
||||||
@ -35,8 +42,8 @@ export default {
|
|||||||
|
|
||||||
// Show warning dialogs and then save in the store
|
// Show warning dialogs and then save in the store
|
||||||
return Promise.resolve()
|
return Promise.resolve()
|
||||||
.then(() => !background && nameStripped && store.dispatch('modal/stripName', fields.name))
|
.then(() => !background && nameStripped && store.dispatch('modal/stripName', name))
|
||||||
.then(() => !background && pathConflict && store.dispatch('modal/pathConflict', fields.name))
|
.then(() => !background && pathConflict && store.dispatch('modal/pathConflict', name))
|
||||||
.then(() => {
|
.then(() => {
|
||||||
store.commit('content/setItem', content);
|
store.commit('content/setItem', content);
|
||||||
store.commit('file/setItem', file);
|
store.commit('file/setItem', file);
|
||||||
@ -131,12 +138,12 @@ export default {
|
|||||||
* Add a prefix to its name and return true otherwise.
|
* Add a prefix to its name and return true otherwise.
|
||||||
*/
|
*/
|
||||||
makePathUnique(id) {
|
makePathUnique(id) {
|
||||||
const item = store.getters.allItemMap[id];
|
const { pathItems, allItemMap, itemPaths } = store.getters;
|
||||||
|
const item = allItemMap[id];
|
||||||
if (!item) {
|
if (!item) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
let path = store.getters.itemPaths[id];
|
let path = itemPaths[id];
|
||||||
const pathItems = store.getters.pathItems;
|
|
||||||
if (pathItems[path].length === 1) {
|
if (pathItems[path].length === 1) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -6,8 +6,8 @@ import fileSvc from './fileSvc';
|
|||||||
|
|
||||||
const dbVersion = 1;
|
const dbVersion = 1;
|
||||||
const dbStoreName = 'objects';
|
const dbStoreName = 'objects';
|
||||||
const exportWorkspace = utils.queryParams.exportWorkspace;
|
const { exportWorkspace } = utils.queryParams;
|
||||||
const silent = utils.queryParams.silent;
|
const { silent } = utils.queryParams;
|
||||||
const resetApp = utils.queryParams.reset;
|
const resetApp = utils.queryParams.reset;
|
||||||
const deleteMarkerMaxAge = 1000;
|
const deleteMarkerMaxAge = 1000;
|
||||||
const checkSponsorshipAfter = (5 * 60 * 1000) + (30 * 1000); // tokenExpirationMargin + 30 sec
|
const checkSponsorshipAfter = (5 * 60 * 1000) + (30 * 1000); // tokenExpirationMargin + 30 sec
|
||||||
@ -37,7 +37,7 @@ class Connection {
|
|||||||
|
|
||||||
request.onsuccess = (event) => {
|
request.onsuccess = (event) => {
|
||||||
this.db = event.target.result;
|
this.db = event.target.result;
|
||||||
this.db.onversionchange = () => location.reload();
|
this.db.onversionchange = () => window.location.reload();
|
||||||
|
|
||||||
this.getTxCbs.forEach(({ onTx, onError }) => this.createTx(onTx, onError));
|
this.getTxCbs.forEach(({ onTx, onError }) => this.createTx(onTx, onError));
|
||||||
this.getTxCbs = null;
|
this.getTxCbs = null;
|
||||||
@ -51,16 +51,15 @@ class Connection {
|
|||||||
// the fall-through behavior is what we want.
|
// the fall-through behavior is what we want.
|
||||||
/* eslint-disable no-fallthrough */
|
/* eslint-disable no-fallthrough */
|
||||||
switch (oldVersion) {
|
switch (oldVersion) {
|
||||||
case 0:
|
case 0: {
|
||||||
{
|
// Create store
|
||||||
// Create store
|
const dbStore = eventDb.createObjectStore(dbStoreName, {
|
||||||
const dbStore = eventDb.createObjectStore(dbStoreName, {
|
keyPath: 'id',
|
||||||
keyPath: 'id',
|
});
|
||||||
});
|
dbStore.createIndex('tx', 'tx', {
|
||||||
dbStore.createIndex('tx', 'tx', {
|
unique: false,
|
||||||
unique: false,
|
});
|
||||||
});
|
}
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
/* eslint-enable no-fallthrough */
|
/* eslint-enable no-fallthrough */
|
||||||
@ -158,7 +157,7 @@ const localDbSvc = {
|
|||||||
* Read and apply all changes from the DB since previous transaction.
|
* Read and apply all changes from the DB since previous transaction.
|
||||||
*/
|
*/
|
||||||
readAll(tx, cb) {
|
readAll(tx, cb) {
|
||||||
let lastTx = this.lastTx;
|
let { lastTx } = this;
|
||||||
const dbStore = tx.objectStore(dbStoreName);
|
const dbStore = tx.objectStore(dbStoreName);
|
||||||
const index = dbStore.index('tx');
|
const index = dbStore.index('tx');
|
||||||
const range = window.IDBKeyRange.lowerBound(this.lastTx, true);
|
const range = window.IDBKeyRange.lowerBound(this.lastTx, true);
|
||||||
@ -171,7 +170,7 @@ const localDbSvc = {
|
|||||||
lastTx = item.tx;
|
lastTx = item.tx;
|
||||||
if (this.lastTx && item.tx - this.lastTx > deleteMarkerMaxAge) {
|
if (this.lastTx && item.tx - this.lastTx > deleteMarkerMaxAge) {
|
||||||
// We may have missed some delete markers
|
// We may have missed some delete markers
|
||||||
location.reload();
|
window.location.reload();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -355,16 +354,14 @@ const localDbSvc = {
|
|||||||
.then(() => {
|
.then(() => {
|
||||||
// Reset the app if reset flag was passed
|
// Reset the app if reset flag was passed
|
||||||
if (resetApp) {
|
if (resetApp) {
|
||||||
return Promise.all(
|
return Promise.all(Object.keys(store.getters['data/workspaces'])
|
||||||
Object.keys(store.getters['data/workspaces'])
|
.map(workspaceId => localDbSvc.removeWorkspace(workspaceId)))
|
||||||
.map(workspaceId => localDbSvc.removeWorkspace(workspaceId)),
|
|
||||||
)
|
|
||||||
.then(() => utils.localStorageDataIds.forEach((id) => {
|
.then(() => utils.localStorageDataIds.forEach((id) => {
|
||||||
// Clean data stored in localStorage
|
// Clean data stored in localStorage
|
||||||
localStorage.removeItem(`data/${id}`);
|
localStorage.removeItem(`data/${id}`);
|
||||||
}))
|
}))
|
||||||
.then(() => {
|
.then(() => {
|
||||||
location.reload();
|
window.location.reload();
|
||||||
throw new Error('reload');
|
throw new Error('reload');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -388,7 +385,7 @@ const localDbSvc = {
|
|||||||
|
|
||||||
// Save welcome file content hash if not done already
|
// Save welcome file content hash if not done already
|
||||||
const hash = utils.hash(welcomeFile);
|
const hash = utils.hash(welcomeFile);
|
||||||
const welcomeFileHashes = store.getters['data/localSettings'].welcomeFileHashes;
|
const { welcomeFileHashes } = store.getters['data/localSettings'];
|
||||||
if (!welcomeFileHashes[hash]) {
|
if (!welcomeFileHashes[hash]) {
|
||||||
store.dispatch('data/patchLocalSettings', {
|
store.dispatch('data/patchLocalSettings', {
|
||||||
welcomeFileHashes: {
|
welcomeFileHashes: {
|
||||||
@ -410,7 +407,7 @@ const localDbSvc = {
|
|||||||
|
|
||||||
// Enable sponsorship
|
// Enable sponsorship
|
||||||
if (utils.queryParams.paymentSuccess) {
|
if (utils.queryParams.paymentSuccess) {
|
||||||
location.hash = ''; // PaymentSuccess param is always on its own
|
window.location.hash = ''; // PaymentSuccess param is always on its own
|
||||||
store.dispatch('modal/paymentSuccess')
|
store.dispatch('modal/paymentSuccess')
|
||||||
.catch(() => { /* Cancel */ });
|
.catch(() => { /* Cancel */ });
|
||||||
const sponsorToken = store.getters['workspace/sponsorToken'];
|
const sponsorToken = store.getters['workspace/sponsorToken'];
|
||||||
@ -463,8 +460,10 @@ const localDbSvc = {
|
|||||||
// Cancel new discussion
|
// Cancel new discussion
|
||||||
store.commit('discussion/setCurrentDiscussionId');
|
store.commit('discussion/setCurrentDiscussionId');
|
||||||
// Open the gutter if file contains discussions
|
// Open the gutter if file contains discussions
|
||||||
store.commit('discussion/setCurrentDiscussionId',
|
store.commit(
|
||||||
store.getters['discussion/nextDiscussionId']);
|
'discussion/setCurrentDiscussionId',
|
||||||
|
store.getters['discussion/nextDiscussionId'],
|
||||||
|
);
|
||||||
},
|
},
|
||||||
(err) => {
|
(err) => {
|
||||||
// Failure (content is not available), go back to previous file
|
// Failure (content is not available), go back to previous file
|
||||||
@ -480,7 +479,8 @@ const localDbSvc = {
|
|||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
immediate: true,
|
immediate: true,
|
||||||
});
|
},
|
||||||
|
);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -224,7 +224,7 @@ export default {
|
|||||||
parsingCtx.markdownCoreRules.slice(2).forEach(rule => rule(parsingCtx.markdownState));
|
parsingCtx.markdownCoreRules.slice(2).forEach(rule => rule(parsingCtx.markdownState));
|
||||||
parsingCtx.markdownState.isConverted = true;
|
parsingCtx.markdownState.isConverted = true;
|
||||||
}
|
}
|
||||||
const tokens = parsingCtx.markdownState.tokens;
|
const { tokens } = parsingCtx.markdownState;
|
||||||
const html = parsingCtx.converter.renderer.render(
|
const html = parsingCtx.converter.renderer.render(
|
||||||
tokens,
|
tokens,
|
||||||
parsingCtx.converter.options,
|
parsingCtx.converter.options,
|
||||||
@ -240,7 +240,10 @@ export default {
|
|||||||
let htmlSectionDiff;
|
let htmlSectionDiff;
|
||||||
if (previousConversionCtx) {
|
if (previousConversionCtx) {
|
||||||
const oldSectionHash = hashArray(
|
const oldSectionHash = hashArray(
|
||||||
previousConversionCtx.htmlSectionList, valueHash, valueArray);
|
previousConversionCtx.htmlSectionList,
|
||||||
|
valueHash,
|
||||||
|
valueArray,
|
||||||
|
);
|
||||||
htmlSectionDiff = diffMatchPatch.diff_main(oldSectionHash, newSectionHash, false);
|
htmlSectionDiff = diffMatchPatch.diff_main(oldSectionHash, newSectionHash, false);
|
||||||
} else {
|
} else {
|
||||||
htmlSectionDiff = [
|
htmlSectionDiff = [
|
||||||
@ -264,8 +267,7 @@ export default {
|
|||||||
*/
|
*/
|
||||||
highlight(markdown, converter = this.defaultConverter, grammars = this.defaultPrismGrammars) {
|
highlight(markdown, converter = this.defaultConverter, grammars = this.defaultPrismGrammars) {
|
||||||
const parsingCtx = this.parseSections(converter, markdown);
|
const parsingCtx = this.parseSections(converter, markdown);
|
||||||
return parsingCtx.sections.map(
|
return parsingCtx.sections
|
||||||
section => Prism.highlight(section.text, grammars[section.data]),
|
.map(section => Prism.highlight(section.text, grammars[section.data])).join('');
|
||||||
).join('');
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -121,7 +121,7 @@ export default {
|
|||||||
// Open a tab otherwise
|
// Open a tab otherwise
|
||||||
wnd = window.open(authorizeUrl);
|
wnd = window.open(authorizeUrl);
|
||||||
if (!wnd) {
|
if (!wnd) {
|
||||||
return Promise.reject('The authorize window was blocked.');
|
return Promise.reject(new Error('The authorize window was blocked.'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,21 +145,23 @@ export default {
|
|||||||
|
|
||||||
if (silent) {
|
if (silent) {
|
||||||
iframeElt.onerror = () => clean()
|
iframeElt.onerror = () => clean()
|
||||||
.then(() => reject('Unknown error.'));
|
.then(() => reject(new Error('Unknown error.')));
|
||||||
closeTimeout = setTimeout(
|
closeTimeout = setTimeout(
|
||||||
() => clean()
|
() => clean()
|
||||||
.then(() => {
|
.then(() => {
|
||||||
isConnectionDown = true;
|
isConnectionDown = true;
|
||||||
store.commit('setOffline', true);
|
store.commit('setOffline', true);
|
||||||
store.commit('updateLastOfflineCheck');
|
store.commit('updateLastOfflineCheck');
|
||||||
reject('You are offline.');
|
reject(new Error('You are offline.'));
|
||||||
}),
|
}),
|
||||||
networkTimeout);
|
networkTimeout,
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
closeTimeout = setTimeout(
|
closeTimeout = setTimeout(
|
||||||
() => clean()
|
() => clean()
|
||||||
.then(() => reject('Timeout.')),
|
.then(() => reject(new Error('Timeout.'))),
|
||||||
oauth2AuthorizationTimeout);
|
oauth2AuthorizationTimeout,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
msgHandler = event => event.source === wnd && event.origin === utils.origin && clean()
|
msgHandler = event => event.source === wnd && event.origin === utils.origin && clean()
|
||||||
@ -167,7 +169,7 @@ export default {
|
|||||||
const data = utils.parseQueryParams(`${event.data}`.slice(1));
|
const data = utils.parseQueryParams(`${event.data}`.slice(1));
|
||||||
if (data.error || data.state !== state) {
|
if (data.error || data.state !== state) {
|
||||||
console.error(data); // eslint-disable-line no-console
|
console.error(data); // eslint-disable-line no-console
|
||||||
reject('Could not get required authorization.');
|
reject(new Error('Could not get required authorization.'));
|
||||||
} else {
|
} else {
|
||||||
resolve({
|
resolve({
|
||||||
accessToken: data.access_token,
|
accessToken: data.access_token,
|
||||||
@ -181,7 +183,7 @@ export default {
|
|||||||
window.addEventListener('message', msgHandler);
|
window.addEventListener('message', msgHandler);
|
||||||
if (!silent) {
|
if (!silent) {
|
||||||
checkClosedInterval = setInterval(() => wnd.closed && clean()
|
checkClosedInterval = setInterval(() => wnd.closed && clean()
|
||||||
.then(() => reject('Authorize window was closed.')), 250);
|
.then(() => reject(new Error('Authorize window was closed.'))), 250);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -253,9 +255,9 @@ export default {
|
|||||||
if (offlineCheck) {
|
if (offlineCheck) {
|
||||||
isConnectionDown = true;
|
isConnectionDown = true;
|
||||||
store.commit('setOffline', true);
|
store.commit('setOffline', true);
|
||||||
reject('You are offline.');
|
reject(new Error('You are offline.'));
|
||||||
} else {
|
} else {
|
||||||
reject('Network request failed.');
|
reject(new Error('Network request failed.'));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -264,9 +266,9 @@ export default {
|
|||||||
if (offlineCheck) {
|
if (offlineCheck) {
|
||||||
isConnectionDown = true;
|
isConnectionDown = true;
|
||||||
store.commit('setOffline', true);
|
store.commit('setOffline', true);
|
||||||
reject('You are offline.');
|
reject(new Error('You are offline.'));
|
||||||
} else {
|
} else {
|
||||||
reject('Network request timeout.');
|
reject(new Error('Network request timeout.'));
|
||||||
}
|
}
|
||||||
}, config.timeout);
|
}, config.timeout);
|
||||||
|
|
||||||
@ -282,12 +284,11 @@ export default {
|
|||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
// Try again later in case of retriable error
|
// Try again later in case of retriable error
|
||||||
if (isRetriable(err) && retryAfter < maxRetryAfter) {
|
if (isRetriable(err) && retryAfter < maxRetryAfter) {
|
||||||
return new Promise(
|
return new Promise((resolve) => {
|
||||||
(resolve) => {
|
setTimeout(resolve, retryAfter);
|
||||||
setTimeout(resolve, retryAfter);
|
// Exponential backoff
|
||||||
// Exponential backoff
|
retryAfter *= 2;
|
||||||
retryAfter *= 2;
|
})
|
||||||
})
|
|
||||||
.then(attempt);
|
.then(attempt);
|
||||||
}
|
}
|
||||||
throw err;
|
throw err;
|
||||||
|
@ -2,7 +2,7 @@ import cledit from '../cledit';
|
|||||||
import editorSvc from '../editorSvc';
|
import editorSvc from '../editorSvc';
|
||||||
import store from '../../store';
|
import store from '../../store';
|
||||||
|
|
||||||
const Keystroke = cledit.Keystroke;
|
const { Keystroke } = cledit;
|
||||||
const indentRegexp = /^ {0,3}>[ ]*|^[ \t]*[*+-][ \t](?:\[[ xX]\][ \t])?|^([ \t]*)\d+\.[ \t](?:\[[ xX]\][ \t])?|^\s+/;
|
const indentRegexp = /^ {0,3}>[ ]*|^[ \t]*[*+-][ \t](?:\[[ xX]\][ \t])?|^([ \t]*)\d+\.[ \t](?:\[[ xX]\][ \t])?|^\s+/;
|
||||||
let clearNewline;
|
let clearNewline;
|
||||||
let lastSelection;
|
let lastSelection;
|
||||||
@ -32,7 +32,9 @@ function fixNumberedList(state, indent) {
|
|||||||
|
|
||||||
lines.some((line) => {
|
lines.some((line) => {
|
||||||
const match = line.replace(
|
const match = line.replace(
|
||||||
/^[ \t]*/, wholeMatch => wholeMatch.replace(/\t/g, ' ')).match(indentRegex);
|
/^[ \t]*/,
|
||||||
|
wholeMatch => wholeMatch.replace(/\t/g, ' '),
|
||||||
|
).match(indentRegex);
|
||||||
if (!match || line.match(/^#+ /)) { // Line not empty, not indented, or title
|
if (!match || line.match(/^#+ /)) { // Line not empty, not indented, or title
|
||||||
flush();
|
flush();
|
||||||
return true;
|
return true;
|
||||||
|
@ -162,17 +162,19 @@ store.watch(
|
|||||||
isScrollEditor = showEditor;
|
isScrollEditor = showEditor;
|
||||||
isScrollPreview = !showEditor;
|
isScrollPreview = !showEditor;
|
||||||
skipAnimation = true;
|
skipAnimation = true;
|
||||||
});
|
},
|
||||||
|
);
|
||||||
|
|
||||||
store.watch(
|
store.watch(
|
||||||
() => store.getters['file/current'].id,
|
() => store.getters['file/current'].id,
|
||||||
() => {
|
() => {
|
||||||
skipAnimation = true;
|
skipAnimation = true;
|
||||||
});
|
},
|
||||||
|
);
|
||||||
|
|
||||||
editorSvc.$on('previewCtxMeasured', (previewCtxMeasured) => {
|
editorSvc.$on('previewCtxMeasured', (previewCtxMeasured) => {
|
||||||
if (previewCtxMeasured) {
|
if (previewCtxMeasured) {
|
||||||
sectionDescList = previewCtxMeasured.sectionDescList;
|
({ sectionDescList } = previewCtxMeasured);
|
||||||
forceScrollSync();
|
forceScrollSync();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -45,7 +45,7 @@ const methods = {
|
|||||||
const replacement = `${param2 || ''}`;
|
const replacement = `${param2 || ''}`;
|
||||||
if (text && replacement) {
|
if (text && replacement) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
const selectionMgr = editorSvc.clEditor.selectionMgr;
|
const { selectionMgr } = editorSvc.clEditor;
|
||||||
let offset = selectionMgr.selectionStart;
|
let offset = selectionMgr.selectionStart;
|
||||||
if (offset === selectionMgr.selectionEnd) {
|
if (offset === selectionMgr.selectionEnd) {
|
||||||
const range = selectionMgr.createRange(offset - text.length, offset);
|
const range = selectionMgr.createRange(offset - text.length, offset);
|
||||||
@ -85,4 +85,5 @@ store.watch(
|
|||||||
});
|
});
|
||||||
}, {
|
}, {
|
||||||
immediate: true,
|
immediate: true,
|
||||||
});
|
},
|
||||||
|
);
|
||||||
|
@ -7,10 +7,10 @@ editorSvc.$on('inited', () => {
|
|||||||
if (!elt || elt === editorSvc.previewElt) {
|
if (!elt || elt === editorSvc.previewElt) {
|
||||||
return offset;
|
return offset;
|
||||||
}
|
}
|
||||||
let previousSibling = elt.previousSibling;
|
let { previousSibling } = elt;
|
||||||
while (previousSibling) {
|
while (previousSibling) {
|
||||||
offset += previousSibling.textContent.length;
|
offset += previousSibling.textContent.length;
|
||||||
previousSibling = previousSibling.previousSibling;
|
({ previousSibling } = previousSibling);
|
||||||
}
|
}
|
||||||
return offset + getPreviewOffset(elt.parentNode);
|
return offset + getPreviewOffset(elt.parentNode);
|
||||||
};
|
};
|
||||||
|
@ -53,11 +53,11 @@ export default new Provider({
|
|||||||
.then((workspace) => {
|
.then((workspace) => {
|
||||||
// Fix the URL hash
|
// Fix the URL hash
|
||||||
utils.setQueryParams(workspaceParams);
|
utils.setQueryParams(workspaceParams);
|
||||||
if (workspace.url !== location.href) {
|
if (workspace.url !== window.location.href) {
|
||||||
store.dispatch('data/patchWorkspaces', {
|
store.dispatch('data/patchWorkspaces', {
|
||||||
[workspace.id]: {
|
[workspace.id]: {
|
||||||
...workspace,
|
...workspace,
|
||||||
url: location.href,
|
url: window.location.href,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,11 @@ export default new Provider({
|
|||||||
},
|
},
|
||||||
downloadContent(token, syncLocation) {
|
downloadContent(token, syncLocation) {
|
||||||
return githubHelper.downloadFile(
|
return githubHelper.downloadFile(
|
||||||
token, syncLocation.owner, syncLocation.repo, syncLocation.branch, syncLocation.path,
|
token,
|
||||||
|
syncLocation.owner,
|
||||||
|
syncLocation.repo,
|
||||||
|
syncLocation.branch,
|
||||||
|
syncLocation.path,
|
||||||
)
|
)
|
||||||
.then(({ sha, content }) => {
|
.then(({ sha, content }) => {
|
||||||
savedSha[syncLocation.id] = sha;
|
savedSha[syncLocation.id] = sha;
|
||||||
|
@ -40,7 +40,7 @@ export default new Provider({
|
|||||||
},
|
},
|
||||||
initWorkspace() {
|
initWorkspace() {
|
||||||
const [owner, repo] = (utils.queryParams.repo || '').split('/');
|
const [owner, repo] = (utils.queryParams.repo || '').split('/');
|
||||||
const branch = utils.queryParams.branch;
|
const { branch } = utils.queryParams;
|
||||||
const workspaceParams = {
|
const workspaceParams = {
|
||||||
providerId: this.id,
|
providerId: this.id,
|
||||||
repo: `${owner}/${repo}`,
|
repo: `${owner}/${repo}`,
|
||||||
@ -84,11 +84,11 @@ export default new Provider({
|
|||||||
}
|
}
|
||||||
// Fix the URL hash
|
// Fix the URL hash
|
||||||
utils.setQueryParams(workspaceParams);
|
utils.setQueryParams(workspaceParams);
|
||||||
if (workspace.url !== location.href) {
|
if (workspace.url !== window.location.href) {
|
||||||
store.dispatch('data/patchWorkspaces', {
|
store.dispatch('data/patchWorkspaces', {
|
||||||
[workspaceId]: {
|
[workspaceId]: {
|
||||||
...workspace,
|
...workspace,
|
||||||
url: location.href,
|
url: window.location.href,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -494,8 +494,8 @@ export default new Provider({
|
|||||||
getRevisionContent(token, fileId, revisionId) {
|
getRevisionContent(token, fileId, revisionId) {
|
||||||
const { owner, repo } = getWorkspaceWithOwner();
|
const { owner, repo } = getWorkspaceWithOwner();
|
||||||
return getSyncData(fileId)
|
return getSyncData(fileId)
|
||||||
.then(syncData => githubHelper.downloadFile(
|
.then(syncData => githubHelper
|
||||||
token, owner, repo, revisionId, getAbsolutePath(syncData)))
|
.downloadFile(token, owner, repo, revisionId, getAbsolutePath(syncData)))
|
||||||
.then(({ content }) => Provider.parseContent(content, `${fileId}/content`));
|
.then(({ content }) => Provider.parseContent(content, `${fileId}/content`));
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -101,8 +101,10 @@ export default new Provider({
|
|||||||
return this.makeLocation(token, null, googleHelper.driveActionFolder.id);
|
return this.makeLocation(token, null, googleHelper.driveActionFolder.id);
|
||||||
});
|
});
|
||||||
case 'open':
|
case 'open':
|
||||||
return store.dispatch('queue/enqueue',
|
return store.dispatch(
|
||||||
() => this.openFiles(token, googleHelper.driveActionFiles));
|
'queue/enqueue',
|
||||||
|
() => this.openFiles(token, googleHelper.driveActionFiles),
|
||||||
|
);
|
||||||
default:
|
default:
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -171,7 +173,7 @@ export default new Provider({
|
|||||||
};
|
};
|
||||||
return this.downloadContent(token, syncLocation)
|
return this.downloadContent(token, syncLocation)
|
||||||
.then(content => fileSvc.createFile({
|
.then(content => fileSvc.createFile({
|
||||||
name,
|
name: driveFile.name,
|
||||||
parentId: store.getters['file/current'].parentId,
|
parentId: store.getters['file/current'].parentId,
|
||||||
text: content.text,
|
text: content.text,
|
||||||
properties: content.properties,
|
properties: content.properties,
|
||||||
|
@ -25,8 +25,8 @@ export default new Provider({
|
|||||||
folderId,
|
folderId,
|
||||||
});
|
});
|
||||||
|
|
||||||
const makeWorkspaceId = folderId => folderId && utils.makeWorkspaceId(
|
const makeWorkspaceId = folderId => folderId
|
||||||
makeWorkspaceParams(folderId));
|
&& utils.makeWorkspaceId(makeWorkspaceParams(folderId));
|
||||||
|
|
||||||
const getWorkspace = folderId =>
|
const getWorkspace = folderId =>
|
||||||
store.getters['data/sanitizedWorkspaces'][makeWorkspaceId(folderId)];
|
store.getters['data/sanitizedWorkspaces'][makeWorkspaceId(folderId)];
|
||||||
@ -100,7 +100,7 @@ export default new Provider({
|
|||||||
sub: token.sub,
|
sub: token.sub,
|
||||||
name: folder.name,
|
name: folder.name,
|
||||||
providerId: this.id,
|
providerId: this.id,
|
||||||
url: location.href,
|
url: window.location.href,
|
||||||
folderId: folder.id,
|
folderId: folder.id,
|
||||||
teamDriveId: folder.teamDriveId,
|
teamDriveId: folder.teamDriveId,
|
||||||
dataFolderId: properties.dataFolderId,
|
dataFolderId: properties.dataFolderId,
|
||||||
@ -141,7 +141,7 @@ export default new Provider({
|
|||||||
...folder,
|
...folder,
|
||||||
appProperties: {},
|
appProperties: {},
|
||||||
})
|
})
|
||||||
.then(() => folder.id)))
|
.then(() => folder.id)))
|
||||||
// If workspace does not exist, initialize one
|
// If workspace does not exist, initialize one
|
||||||
.then(folderId => getWorkspace(folderId) || googleHelper.getFile(token, folderId)
|
.then(folderId => getWorkspace(folderId) || googleHelper.getFile(token, folderId)
|
||||||
.then((folder) => {
|
.then((folder) => {
|
||||||
@ -157,11 +157,11 @@ export default new Provider({
|
|||||||
.then((workspace) => {
|
.then((workspace) => {
|
||||||
// Fix the URL hash
|
// Fix the URL hash
|
||||||
utils.setQueryParams(makeWorkspaceParams(workspace.folderId));
|
utils.setQueryParams(makeWorkspaceParams(workspace.folderId));
|
||||||
if (workspace.url !== location.href) {
|
if (workspace.url !== window.location.href) {
|
||||||
store.dispatch('data/patchWorkspaces', {
|
store.dispatch('data/patchWorkspaces', {
|
||||||
[workspace.id]: {
|
[workspace.id]: {
|
||||||
...workspace,
|
...workspace,
|
||||||
url: location.href,
|
url: window.location.href,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -233,7 +233,7 @@ export default new Provider({
|
|||||||
parentIds[syncData.id] = id;
|
parentIds[syncData.id] = id;
|
||||||
});
|
});
|
||||||
result.changes.forEach((change) => {
|
result.changes.forEach((change) => {
|
||||||
const id = ((change.file || {}).appProperties || {}).id;
|
const { id } = (change.file || {}).appProperties || {};
|
||||||
if (id) {
|
if (id) {
|
||||||
parentIds[change.fileId] = id;
|
parentIds[change.fileId] = id;
|
||||||
}
|
}
|
||||||
@ -253,7 +253,7 @@ export default new Provider({
|
|||||||
let contentChange;
|
let contentChange;
|
||||||
if (change.file) {
|
if (change.file) {
|
||||||
// Ignore changes in files that are not in the workspace
|
// Ignore changes in files that are not in the workspace
|
||||||
const appProperties = change.file.appProperties;
|
const { appProperties } = change.file;
|
||||||
if (!appProperties || appProperties.folderId !== workspace.folderId
|
if (!appProperties || appProperties.folderId !== workspace.folderId
|
||||||
) {
|
) {
|
||||||
return;
|
return;
|
||||||
|
@ -24,10 +24,13 @@ const request = (token, options, args) => networkSvc.request({
|
|||||||
export default {
|
export default {
|
||||||
startOauth2(fullAccess, sub = null, silent = false) {
|
startOauth2(fullAccess, sub = null, silent = false) {
|
||||||
return networkSvc.startOauth2(
|
return networkSvc.startOauth2(
|
||||||
'https://www.dropbox.com/oauth2/authorize', {
|
'https://www.dropbox.com/oauth2/authorize',
|
||||||
|
{
|
||||||
client_id: getAppKey(fullAccess),
|
client_id: getAppKey(fullAccess),
|
||||||
response_type: 'token',
|
response_type: 'token',
|
||||||
}, silent)
|
},
|
||||||
|
silent,
|
||||||
|
)
|
||||||
// Call the user info endpoint
|
// Call the user info endpoint
|
||||||
.then(({ accessToken }) => request({ accessToken }, {
|
.then(({ accessToken }) => request({ accessToken }, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
@ -56,7 +59,7 @@ export default {
|
|||||||
}
|
}
|
||||||
return networkSvc.loadScript('https://www.dropbox.com/static/api/2/dropins.js')
|
return networkSvc.loadScript('https://www.dropbox.com/static/api/2/dropins.js')
|
||||||
.then(() => {
|
.then(() => {
|
||||||
Dropbox = window.Dropbox;
|
({ Dropbox } = window);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
addAccount(fullAccess = false) {
|
addAccount(fullAccess = false) {
|
||||||
|
@ -30,10 +30,13 @@ const getCommitMessage = (name, path) => {
|
|||||||
export default {
|
export default {
|
||||||
startOauth2(scopes, sub = null, silent = false) {
|
startOauth2(scopes, sub = null, silent = false) {
|
||||||
return networkSvc.startOauth2(
|
return networkSvc.startOauth2(
|
||||||
'https://github.com/login/oauth/authorize', {
|
'https://github.com/login/oauth/authorize',
|
||||||
|
{
|
||||||
client_id: clientId,
|
client_id: clientId,
|
||||||
scope: scopes.join(' '),
|
scope: scopes.join(' '),
|
||||||
}, silent)
|
},
|
||||||
|
silent,
|
||||||
|
)
|
||||||
// Exchange code with token
|
// Exchange code with token
|
||||||
.then(data => networkSvc.request({
|
.then(data => networkSvc.request({
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
|
@ -13,7 +13,7 @@ const driveAppDataScopes = ['https://www.googleapis.com/auth/drive.appdata'];
|
|||||||
const getDriveScopes = token => [token.driveFullAccess
|
const getDriveScopes = token => [token.driveFullAccess
|
||||||
? 'https://www.googleapis.com/auth/drive'
|
? 'https://www.googleapis.com/auth/drive'
|
||||||
: 'https://www.googleapis.com/auth/drive.file',
|
: 'https://www.googleapis.com/auth/drive.file',
|
||||||
'https://www.googleapis.com/auth/drive.install'];
|
'https://www.googleapis.com/auth/drive.install'];
|
||||||
const bloggerScopes = ['https://www.googleapis.com/auth/blogger'];
|
const bloggerScopes = ['https://www.googleapis.com/auth/blogger'];
|
||||||
const photosScopes = ['https://www.googleapis.com/auth/photos'];
|
const photosScopes = ['https://www.googleapis.com/auth/photos'];
|
||||||
|
|
||||||
@ -52,7 +52,7 @@ export default {
|
|||||||
},
|
},
|
||||||
}, true)
|
}, true)
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
const reason = ((((err.body || {}).error || {}).errors || [])[0] || {}).reason;
|
const { reason } = (((err.body || {}).error || {}).errors || [])[0] || {};
|
||||||
if (reason === 'authError') {
|
if (reason === 'authError') {
|
||||||
// Mark the token as revoked and get a new one
|
// Mark the token as revoked and get a new one
|
||||||
store.dispatch('data/setGoogleToken', {
|
store.dispatch('data/setGoogleToken', {
|
||||||
@ -116,7 +116,8 @@ export default {
|
|||||||
multipartRequestBody += closeDelimiter;
|
multipartRequestBody += closeDelimiter;
|
||||||
options.url = options.url.replace(
|
options.url = options.url.replace(
|
||||||
'https://www.googleapis.com/',
|
'https://www.googleapis.com/',
|
||||||
'https://www.googleapis.com/upload/');
|
'https://www.googleapis.com/upload/',
|
||||||
|
);
|
||||||
return this.request(refreshedToken, {
|
return this.request(refreshedToken, {
|
||||||
...options,
|
...options,
|
||||||
params: {
|
params: {
|
||||||
@ -212,7 +213,8 @@ export default {
|
|||||||
},
|
},
|
||||||
startOauth2(scopes, sub = null, silent = false) {
|
startOauth2(scopes, sub = null, silent = false) {
|
||||||
return networkSvc.startOauth2(
|
return networkSvc.startOauth2(
|
||||||
'https://accounts.google.com/o/oauth2/v2/auth', {
|
'https://accounts.google.com/o/oauth2/v2/auth',
|
||||||
|
{
|
||||||
client_id: clientId,
|
client_id: clientId,
|
||||||
response_type: 'token id_token',
|
response_type: 'token id_token',
|
||||||
scope: ['openid', ...scopes].join(' '),
|
scope: ['openid', ...scopes].join(' '),
|
||||||
@ -220,7 +222,9 @@ export default {
|
|||||||
login_hint: sub,
|
login_hint: sub,
|
||||||
prompt: silent ? 'none' : null,
|
prompt: silent ? 'none' : null,
|
||||||
nonce: utils.uid(),
|
nonce: utils.uid(),
|
||||||
}, silent)
|
},
|
||||||
|
silent,
|
||||||
|
)
|
||||||
// Call the token info endpoint
|
// Call the token info endpoint
|
||||||
.then(data => networkSvc.request({
|
.then(data => networkSvc.request({
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
@ -300,7 +304,7 @@ export default {
|
|||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
refreshToken(token, scopes = []) {
|
refreshToken(token, scopes = []) {
|
||||||
const sub = token.sub;
|
const { sub } = token;
|
||||||
const lastToken = store.getters['data/googleTokens'][sub];
|
const lastToken = store.getters['data/googleTokens'][sub];
|
||||||
const mergedScopes = [...new Set([
|
const mergedScopes = [...new Set([
|
||||||
...scopes,
|
...scopes,
|
||||||
@ -339,16 +343,16 @@ export default {
|
|||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
return networkSvc.loadScript('https://apis.google.com/js/api.js')
|
return networkSvc.loadScript('https://apis.google.com/js/api.js')
|
||||||
.then(() => Promise.all(libraries.map(
|
.then(() => Promise.all(libraries
|
||||||
library => new Promise((resolve, reject) => window.gapi.load(library, {
|
.map(library => new Promise((resolve, reject) => window.gapi.load(library, {
|
||||||
callback: resolve,
|
callback: resolve,
|
||||||
onerror: reject,
|
onerror: reject,
|
||||||
timeout: 30000,
|
timeout: 30000,
|
||||||
ontimeout: reject,
|
ontimeout: reject,
|
||||||
})))))
|
})))))
|
||||||
.then(() => {
|
.then(() => {
|
||||||
gapi = window.gapi;
|
({ gapi } = window);
|
||||||
google = window.google;
|
({ google } = window);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
getSponsorship(token) {
|
getSponsorship(token) {
|
||||||
@ -455,8 +459,8 @@ export default {
|
|||||||
fields: 'id,name,mimeType,appProperties,teamDriveId',
|
fields: 'id,name,mimeType,appProperties,teamDriveId',
|
||||||
supportsTeamDrives: true,
|
supportsTeamDrives: true,
|
||||||
},
|
},
|
||||||
})
|
}))
|
||||||
.then(res => res.body));
|
.then(res => res.body);
|
||||||
},
|
},
|
||||||
downloadFile(token, id) {
|
downloadFile(token, id) {
|
||||||
return this.refreshToken(token, getDriveScopes(token))
|
return this.refreshToken(token, getDriveScopes(token))
|
||||||
@ -484,16 +488,25 @@ export default {
|
|||||||
},
|
},
|
||||||
downloadFileRevision(token, fileId, revisionId) {
|
downloadFileRevision(token, fileId, revisionId) {
|
||||||
return this.refreshToken(token, getDriveScopes(token))
|
return this.refreshToken(token, getDriveScopes(token))
|
||||||
.then(refreshedToken => this.downloadFileRevisionInternal(
|
.then(refreshedToken => this
|
||||||
refreshedToken, fileId, revisionId));
|
.downloadFileRevisionInternal(refreshedToken, fileId, revisionId));
|
||||||
},
|
},
|
||||||
downloadAppDataFileRevision(token, fileId, revisionId) {
|
downloadAppDataFileRevision(token, fileId, revisionId) {
|
||||||
return this.refreshToken(token, driveAppDataScopes)
|
return this.refreshToken(token, driveAppDataScopes)
|
||||||
.then(refreshedToken => this.downloadFileRevisionInternal(
|
.then(refreshedToken => this
|
||||||
refreshedToken, fileId, revisionId));
|
.downloadFileRevisionInternal(refreshedToken, fileId, revisionId));
|
||||||
},
|
},
|
||||||
uploadBlogger(
|
uploadBlogger(
|
||||||
token, blogUrl, blogId, postId, title, content, labels, isDraft, published, isPage,
|
token,
|
||||||
|
blogUrl,
|
||||||
|
blogId,
|
||||||
|
postId,
|
||||||
|
title,
|
||||||
|
content,
|
||||||
|
labels,
|
||||||
|
isDraft,
|
||||||
|
published,
|
||||||
|
isPage,
|
||||||
) {
|
) {
|
||||||
return this.refreshToken(token, bloggerScopes)
|
return this.refreshToken(token, bloggerScopes)
|
||||||
.then(refreshedToken => Promise.resolve()
|
.then(refreshedToken => Promise.resolve()
|
||||||
|
@ -15,11 +15,14 @@ const request = (token, options) => networkSvc.request({
|
|||||||
export default {
|
export default {
|
||||||
startOauth2(sub = null, silent = false) {
|
startOauth2(sub = null, silent = false) {
|
||||||
return networkSvc.startOauth2(
|
return networkSvc.startOauth2(
|
||||||
'https://public-api.wordpress.com/oauth2/authorize', {
|
'https://public-api.wordpress.com/oauth2/authorize',
|
||||||
|
{
|
||||||
client_id: clientId,
|
client_id: clientId,
|
||||||
response_type: 'token',
|
response_type: 'token',
|
||||||
scope: 'global',
|
scope: 'global',
|
||||||
}, silent)
|
},
|
||||||
|
silent,
|
||||||
|
)
|
||||||
// Call the user info endpoint
|
// Call the user info endpoint
|
||||||
.then(data => request({ accessToken: data.accessToken }, {
|
.then(data => request({ accessToken: data.accessToken }, {
|
||||||
url: 'https://public-api.wordpress.com/rest/v1.1/me',
|
url: 'https://public-api.wordpress.com/rest/v1.1/me',
|
||||||
@ -42,7 +45,7 @@ export default {
|
|||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
refreshToken(token) {
|
refreshToken(token) {
|
||||||
const sub = token.sub;
|
const { sub } = token;
|
||||||
const lastToken = store.getters['data/wordpressTokens'][sub];
|
const lastToken = store.getters['data/wordpressTokens'][sub];
|
||||||
|
|
||||||
return Promise.resolve()
|
return Promise.resolve()
|
||||||
|
@ -12,11 +12,14 @@ const request = (token, options) => networkSvc.request({
|
|||||||
export default {
|
export default {
|
||||||
startOauth2(subdomain, clientId, sub = null, silent = false) {
|
startOauth2(subdomain, clientId, sub = null, silent = false) {
|
||||||
return networkSvc.startOauth2(
|
return networkSvc.startOauth2(
|
||||||
`https://${subdomain}.zendesk.com/oauth/authorizations/new`, {
|
`https://${subdomain}.zendesk.com/oauth/authorizations/new`,
|
||||||
|
{
|
||||||
client_id: clientId,
|
client_id: clientId,
|
||||||
response_type: 'token',
|
response_type: 'token',
|
||||||
scope: 'read hc:write',
|
scope: 'read hc:write',
|
||||||
}, silent)
|
},
|
||||||
|
silent,
|
||||||
|
)
|
||||||
// Call the user info endpoint
|
// Call the user info endpoint
|
||||||
.then(({ accessToken }) => request({ accessToken }, {
|
.then(({ accessToken }) => request({ accessToken }, {
|
||||||
url: `https://${subdomain}.zendesk.com/api/v2/users/me.json`,
|
url: `https://${subdomain}.zendesk.com/api/v2/users/me.json`,
|
||||||
|
@ -39,7 +39,7 @@ const ensureDate = (value, defaultValue) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
function publish(publishLocation) {
|
function publish(publishLocation) {
|
||||||
const fileId = publishLocation.fileId;
|
const { fileId } = publishLocation;
|
||||||
const template = store.getters['data/allTemplates'][publishLocation.templateId];
|
const template = store.getters['data/allTemplates'][publishLocation.templateId];
|
||||||
return exportSvc.applyTemplate(fileId, template)
|
return exportSvc.applyTemplate(fileId, template)
|
||||||
.then(html => localDbSvc.loadItem(`${fileId}/content`)
|
.then(html => localDbSvc.loadItem(`${fileId}/content`)
|
||||||
@ -107,7 +107,8 @@ function publishFile(fileId) {
|
|||||||
err => localDbSvc.unloadContents()
|
err => localDbSvc.unloadContents()
|
||||||
.then(() => {
|
.then(() => {
|
||||||
throw err;
|
throw err;
|
||||||
}));
|
}),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function requestPublish() {
|
function requestPublish() {
|
||||||
@ -124,7 +125,7 @@ function requestPublish() {
|
|||||||
clearInterval(intervalId);
|
clearInterval(intervalId);
|
||||||
if (!hasCurrentFilePublishLocations()) {
|
if (!hasCurrentFilePublishLocations()) {
|
||||||
// Cancel sync
|
// Cancel sync
|
||||||
reject('Publish not possible.');
|
reject(new Error('Publish not possible.'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
publishFile(store.getters['file/current'].id)
|
publishFile(store.getters['file/current'].id)
|
||||||
@ -140,12 +141,14 @@ function createPublishLocation(publishLocation) {
|
|||||||
publishLocation.id = utils.uid();
|
publishLocation.id = utils.uid();
|
||||||
const currentFile = store.getters['file/current'];
|
const currentFile = store.getters['file/current'];
|
||||||
publishLocation.fileId = currentFile.id;
|
publishLocation.fileId = currentFile.id;
|
||||||
store.dispatch('queue/enqueue',
|
store.dispatch(
|
||||||
|
'queue/enqueue',
|
||||||
() => publish(publishLocation)
|
() => publish(publishLocation)
|
||||||
.then((publishLocationToStore) => {
|
.then((publishLocationToStore) => {
|
||||||
store.commit('publishLocation/setItem', publishLocationToStore);
|
store.commit('publishLocation/setItem', publishLocationToStore);
|
||||||
store.dispatch('notification/info', `A new publication location was added to "${currentFile.name}".`);
|
store.dispatch('notification/info', `A new publication location was added to "${currentFile.name}".`);
|
||||||
}));
|
}),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user