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