Upgraded eslint

This commit is contained in:
Benoit Schweblin 2018-05-06 01:46:33 +01:00
parent b896a2e086
commit 1d8b67c321
124 changed files with 4730 additions and 2287 deletions

View File

@ -2,6 +2,7 @@ var path = require('path')
var webpack = require('webpack') var webpack = require('webpack')
var utils = require('./utils') var utils = require('./utils')
var config = require('../config') var config = require('../config')
var VueLoaderPlugin = require('vue-loader/lib/plugin')
var vueLoaderConfig = require('./vue-loader.conf') var vueLoaderConfig = require('./vue-loader.conf')
var StylelintPlugin = require('stylelint-webpack-plugin') var StylelintPlugin = require('stylelint-webpack-plugin')
var FaviconsWebpackPlugin = require('favicons-webpack-plugin') var FaviconsWebpackPlugin = require('favicons-webpack-plugin')
@ -81,6 +82,7 @@ module.exports = {
] ]
}, },
plugins: [ plugins: [
new VueLoaderPlugin(),
new StylelintPlugin({ new StylelintPlugin({
files: ['**/*.vue', '**/*.scss'] files: ['**/*.vue', '**/*.scss']
}), }),

View File

@ -98,6 +98,7 @@ var webpackConfig = merge(baseWebpackConfig, {
ServiceWorker: { ServiceWorker: {
events: true events: true
}, },
AppCache: true,
excludes: ['**/.*', '**/*.map', '**/index.html', '**/static/oauth2/callback.html', '**/icons-*/*.png', '**/static/fonts/KaTeX_*'], excludes: ['**/.*', '**/*.map', '**/index.html', '**/static/oauth2/callback.html', '**/icons-*/*.png', '**/static/fonts/KaTeX_*'],
externals: ['/', '/app', '/oauth2/callback'] externals: ['/', '/app', '/oauth2/callback']
}) })

View File

@ -14,7 +14,7 @@ function resolve (dir) {
module.exports = { module.exports = {
entry: { entry: {
style: './src/components/style.scss' style: './src/styles/'
}, },
module: { module: {
rules: [{ rules: [{

5741
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -28,13 +28,13 @@
"clipboard": "^1.7.1", "clipboard": "^1.7.1",
"compression": "^1.7.0", "compression": "^1.7.0",
"diff-match-patch": "^1.0.0", "diff-match-patch": "^1.0.0",
"file-saver": "^1.3.3", "file-saver": "^1.3.8",
"google-id-token-verifier": "^0.2.3", "google-id-token-verifier": "^0.2.3",
"handlebars": "^4.0.10", "handlebars": "^4.0.10",
"indexeddbshim": "^3.0.4", "indexeddbshim": "^3.6.2",
"js-yaml": "^3.9.1", "js-yaml": "^3.11.0",
"katex": "^0.9.0-alpha1", "katex": "^0.9.0",
"markdown-it": "^8.3.1", "markdown-it": "^8.4.1",
"markdown-it-abbr": "^1.0.4", "markdown-it-abbr": "^1.0.4",
"markdown-it-deflist": "^2.0.2", "markdown-it-deflist": "^2.0.2",
"markdown-it-emoji": "^1.3.0", "markdown-it-emoji": "^1.3.0",
@ -46,20 +46,20 @@
"markdown-it-sup": "^1.0.0", "markdown-it-sup": "^1.0.0",
"mermaid": "^7.1.0", "mermaid": "^7.1.0",
"mousetrap": "^1.6.1", "mousetrap": "^1.6.1",
"normalize-scss": "^7.0.0", "normalize-scss": "^7.0.1",
"prismjs": "^1.6.0", "prismjs": "^1.6.0",
"request": "^2.82.0", "request": "^2.85.0",
"serve-static": "^1.12.6", "serve-static": "^1.13.2",
"tmp": "^0.0.33", "tmp": "^0.0.33",
"turndown": "^4.0.1", "turndown": "^4.0.2",
"vue": "^2.5.16", "vue": "^2.5.16",
"vuex": "^3.0.1" "vuex": "^3.0.1"
}, },
"devDependencies": { "devDependencies": {
"autoprefixer": "^6.7.2", "autoprefixer": "^6.7.2",
"babel-core": "^6.22.1", "babel-core": "^6.26.3",
"babel-eslint": "^7.1.1", "babel-eslint": "^8.2.3",
"babel-loader": "^6.2.10", "babel-loader": "^7.1.4",
"babel-plugin-transform-runtime": "^6.22.0", "babel-plugin-transform-runtime": "^6.22.0",
"babel-polyfill": "^6.23.0", "babel-polyfill": "^6.23.0",
"babel-preset-env": "^1.3.2", "babel-preset-env": "^1.3.2",
@ -68,49 +68,50 @@
"chalk": "^1.1.3", "chalk": "^1.1.3",
"connect-history-api-fallback": "^1.3.0", "connect-history-api-fallback": "^1.3.0",
"copy-webpack-plugin": "^4.5.1", "copy-webpack-plugin": "^4.5.1",
"css-loader": "^0.28.7", "css-loader": "^0.28.11",
"eslint": "^3.19.0", "eslint": "^4.19.1",
"eslint-config-airbnb-base": "^11.1.3", "eslint-config-airbnb-base": "^12.1.0",
"eslint-friendly-formatter": "^2.0.7", "eslint-friendly-formatter": "^4.0.1",
"eslint-import-resolver-webpack": "^0.8.1", "eslint-import-resolver-webpack": "^0.9.0",
"eslint-loader": "^1.7.1", "eslint-loader": "^2.0.0",
"eslint-plugin-html": "^2.0.0", "eslint-plugin-html": "^4.0.3",
"eslint-plugin-import": "^2.2.0", "eslint-plugin-import": "^2.11.0",
"eventsource-polyfill": "^0.9.6", "eventsource-polyfill": "^0.9.6",
"express": "^4.15.5", "express": "^4.16.3",
"extract-text-webpack-plugin": "^2.0.0", "extract-text-webpack-plugin": "^2.0.0",
"favicons-webpack-plugin": "^0.0.7", "favicons-webpack-plugin": "^0.0.9",
"file-loader": "^0.11.1", "file-loader": "^1.1.11",
"friendly-errors-webpack-plugin": "^1.1.3", "friendly-errors-webpack-plugin": "^1.7.0",
"gulp": "^3.9.1", "gulp": "^3.9.1",
"gulp-concat": "^2.6.1", "gulp-concat": "^2.6.1",
"html-webpack-plugin": "^2.28.0", "html-webpack-plugin": "^3.2.0",
"http-proxy-middleware": "^0.17.3", "http-proxy-middleware": "^0.18.0",
"ignore-loader": "^0.1.2", "ignore-loader": "^0.1.2",
"node-sass": "^4.5.3", "node-sass": "^4.9.0",
"npm-bump": "^0.0.23", "npm-bump": "^0.0.23",
"offline-plugin": "^4.8.4", "offline-plugin": "^5.0.3",
"opn": "^4.0.2", "opn": "^4.0.2",
"optimize-css-assets-webpack-plugin": "^1.3.0", "optimize-css-assets-webpack-plugin": "^1.3.2",
"ora": "^1.2.0", "ora": "^1.2.0",
"raw-loader": "^0.5.1", "raw-loader": "^0.5.1",
"rimraf": "^2.6.0", "rimraf": "^2.6.0",
"sass-loader": "^6.0.5", "sass-loader": "^7.0.1",
"semver": "^5.3.0", "semver": "^5.5.0",
"shelljs": "^0.7.6", "shelljs": "^0.8.1",
"stylelint": "^9.2.0",
"stylelint-config-standard": "^16.0.0", "stylelint-config-standard": "^16.0.0",
"stylelint-processor-html": "^1.0.0", "stylelint-processor-html": "^1.0.0",
"stylelint-webpack-plugin": "^0.7.0", "stylelint-webpack-plugin": "^0.10.4",
"url-loader": "^0.5.8", "url-loader": "^1.0.1",
"vue-loader": "^12.1.0", "vue-loader": "^15.0.9",
"vue-style-loader": "^3.0.1", "vue-style-loader": "^4.1.0",
"vue-template-compiler": "^2.3.3", "vue-template-compiler": "^2.5.16",
"webpack": "^2.6.1", "webpack": "^2.6.1",
"webpack-bundle-analyzer": "^2.2.1", "webpack-bundle-analyzer": "^2.2.1",
"webpack-dev-middleware": "^1.10.0", "webpack-dev-middleware": "^1.10.0",
"webpack-hot-middleware": "^2.18.0", "webpack-hot-middleware": "^2.18.0",
"webpack-merge": "^4.1.0", "webpack-merge": "^4.1.2",
"worker-loader": "^0.8.1" "worker-loader": "^1.1.1"
}, },
"engines": { "engines": {
"node": ">= 4.0.0", "node": ">= 4.0.0",

View File

@ -29,5 +29,8 @@ exports.githubToken = (req, res) => {
githubToken(req.query.clientId, req.query.code) githubToken(req.query.clientId, req.query.code)
.then( .then(
token => res.send(token), token => res.send(token),
err => res.status(400).send(err ? err.message || err.toString() : 'bad_code')); err => res
.status(400)
.send(err ? err.message || err.toString() : 'bad_code'),
);
}; };

View File

@ -1,5 +1,5 @@
/* global window */ /* global window */
const spawn = require('child_process').spawn; const { spawn } = require('child_process');
const fs = require('fs'); const fs = require('fs');
const tmp = require('tmp'); const tmp = require('tmp');
const user = require('./user'); const user = require('./user');
@ -76,7 +76,7 @@ exports.generate = (req, res) => {
params.push('--toc'); params.push('--toc');
} }
options.tocDepth = parseInt(options.tocDepth, 10); options.tocDepth = parseInt(options.tocDepth, 10);
if (!isNaN(options.tocDepth)) { if (!Number.isNaN(options.tocDepth)) {
params.push('--toc-depth', options.tocDepth); params.push('--toc-depth', options.tocDepth);
} }
options.highlightStyle = highlightStyles.indexOf(options.highlightStyle) !== -1 ? options.highlightStyle : 'kate'; options.highlightStyle = highlightStyles.indexOf(options.highlightStyle) !== -1 ? options.highlightStyle : 'kate';

View File

@ -1,5 +1,5 @@
/* global window,MathJax */ /* global window,MathJax */
const spawn = require('child_process').spawn; const { spawn } = require('child_process');
const fs = require('fs'); const fs = require('fs');
const tmp = require('tmp'); const tmp = require('tmp');
const user = require('./user'); const user = require('./user');
@ -84,13 +84,13 @@ exports.generate = (req, res) => {
// Margins // Margins
const marginTop = parseInt(`${options.marginTop}`, 10); const marginTop = parseInt(`${options.marginTop}`, 10);
params.push('-T', isNaN(marginTop) ? 25 : marginTop); params.push('-T', Number.isNaN(marginTop) ? 25 : marginTop);
const marginRight = parseInt(`${options.marginRight}`, 10); const marginRight = parseInt(`${options.marginRight}`, 10);
params.push('-R', isNaN(marginRight) ? 25 : marginRight); params.push('-R', Number.isNaN(marginRight) ? 25 : marginRight);
const marginBottom = parseInt(`${options.marginBottom}`, 10); const marginBottom = parseInt(`${options.marginBottom}`, 10);
params.push('-B', isNaN(marginBottom) ? 25 : marginBottom); params.push('-B', Number.isNaN(marginBottom) ? 25 : marginBottom);
const marginLeft = parseInt(`${options.marginLeft}`, 10); const marginLeft = parseInt(`${options.marginLeft}`, 10);
params.push('-L', isNaN(marginLeft) ? 25 : marginLeft); params.push('-L', Number.isNaN(marginLeft) ? 25 : marginLeft);
// Header // Header
if (options.headerCenter) { if (options.headerCenter) {

View File

@ -2,10 +2,12 @@ const request = require('request');
const AWS = require('aws-sdk'); const AWS = require('aws-sdk');
const verifier = require('google-id-token-verifier'); const verifier = require('google-id-token-verifier');
const BUCKET_NAME = process.env.USER_BUCKET_NAME || 'stackedit-users'; const {
const PAYPAL_URI = process.env.PAYPAL_URI || 'https://www.paypal.com/cgi-bin/webscr'; USER_BUCKET_NAME = 'stackedit-users',
const PAYPAL_RECEIVER_EMAIL = process.env.PAYPAL_RECEIVER_EMAIL || 'stackedit.sales@gmail.com'; PAYPAL_URI = 'https://www.paypal.com/cgi-bin/webscr',
const GOOGLE_CLIENT_ID = process.env.GOOGLE_CLIENT_ID; PAYPAL_RECEIVER_EMAIL = 'stackedit.sales@gmail.com',
GOOGLE_CLIENT_ID,
} = process.env;
const s3Client = new AWS.S3(); const s3Client = new AWS.S3();
const cb = (resolve, reject) => (err, res) => { const cb = (resolve, reject) => (err, res) => {
@ -18,21 +20,22 @@ const cb = (resolve, reject) => (err, res) => {
exports.getUser = id => new Promise((resolve, reject) => { exports.getUser = id => new Promise((resolve, reject) => {
s3Client.getObject({ s3Client.getObject({
Bucket: BUCKET_NAME, Bucket: USER_BUCKET_NAME,
Key: id, Key: id,
}, cb(resolve, reject)); }, cb(resolve, reject));
}) })
.then( .then(
res => JSON.parse(`${res.Body}`), res => JSON.parse(`${res.Body}`),
(err) => { (err) => {
if (err.code !== 'NoSuchKey') { if (err.code !== 'NoSuchKey') {
throw err; throw err;
} }
}); },
);
exports.putUser = (id, user) => new Promise((resolve, reject) => { exports.putUser = (id, user) => new Promise((resolve, reject) => {
s3Client.putObject({ s3Client.putObject({
Bucket: BUCKET_NAME, Bucket: USER_BUCKET_NAME,
Key: id, Key: id,
Body: JSON.stringify(user), Body: JSON.stringify(user),
}, cb(resolve, reject)); }, cb(resolve, reject));
@ -40,20 +43,24 @@ exports.putUser = (id, user) => new Promise((resolve, reject) => {
exports.removeUser = id => new Promise((resolve, reject) => { exports.removeUser = id => new Promise((resolve, reject) => {
s3Client.deleteObject({ s3Client.deleteObject({
Bucket: BUCKET_NAME, Bucket: USER_BUCKET_NAME,
Key: id, Key: id,
}, cb(resolve, reject)); }, cb(resolve, reject));
}); });
exports.getUserFromToken = idToken => new Promise( exports.getUserFromToken = idToken => new Promise((resolve, reject) => verifier
(resolve, reject) => verifier.verify(idToken, GOOGLE_CLIENT_ID, cb(resolve, reject))) .verify(idToken, GOOGLE_CLIENT_ID, cb(resolve, reject)))
.then(tokenInfo => exports.getUser(tokenInfo.sub)); .then(tokenInfo => exports.getUser(tokenInfo.sub));
exports.userInfo = (req, res) => exports.getUserFromToken(req.query.idToken) exports.userInfo = (req, res) => exports.getUserFromToken(req.query.idToken)
.then(user => res.send(Object.assign({ .then(
sponsorUntil: 0, user => res.send(Object.assign({
}, user)), sponsorUntil: 0,
err => res.status(400).send(err ? err.message || err.toString() : 'invalid_token')); }, user)),
err => res
.status(400)
.send(err ? err.message || err.toString() : 'invalid_token'),
);
exports.paypalIpn = (req, res, next) => Promise.resolve() exports.paypalIpn = (req, res, next) => Promise.resolve()
.then(() => { .then(() => {

View File

@ -10,6 +10,9 @@
<script> <script>
import Vue from 'vue'; import Vue from 'vue';
import '../styles';
import '../styles/markdownHighlighting.scss';
import '../styles/app.scss';
import Layout from './Layout'; import Layout from './Layout';
import Modal from './Modal'; import Modal from './Modal';
import Notification from './Notification'; import Notification from './Notification';
@ -26,7 +29,7 @@ import store from '../store';
Vue.directive('focus', { Vue.directive('focus', {
inserted(el) { inserted(el) {
el.focus(); el.focus();
const value = el.value; const { value } = el;
if (value && el.setSelectionRange) { if (value && el.setSelectionRange) {
el.setSelectionRange(0, value.length); el.setSelectionRange(0, value.length);
} }
@ -106,7 +109,3 @@ export default {
}, },
}; };
</script> </script>
<style lang="scss">
@import 'common/app';
</style>

View File

@ -49,7 +49,7 @@ export default {
</script> </script>
<style lang="scss"> <style lang="scss">
@import 'common/variables.scss'; @import '../styles/variables.scss';
.button-bar { .button-bar {
position: absolute; position: absolute;

View File

@ -28,7 +28,7 @@ export default {
</script> </script>
<style lang="scss"> <style lang="scss">
@import 'common/variables.scss'; @import '../styles/variables.scss';
.code-editor { .code-editor {
margin: 0; margin: 0;

View File

@ -66,13 +66,14 @@ export default {
editorElt.querySelectorAll(`.discussion-editor-highlighting--${discussionId}`) editorElt.querySelectorAll(`.discussion-editor-highlighting--${discussionId}`)
.cl_each(elt => elt.classList.add('discussion-editor-highlighting--selected')); .cl_each(elt => elt.classList.add('discussion-editor-highlighting--selected'));
} }
}); },
);
}, },
}; };
</script> </script>
<style lang="scss"> <style lang="scss">
@import 'common/variables.scss'; @import '../styles/variables.scss';
.editor { .editor {
position: absolute; position: absolute;

View File

@ -67,7 +67,8 @@ export default {
this.$store.dispatch('explorer/openNode', currentFileId); this.$store.dispatch('explorer/openNode', currentFileId);
}, { }, {
immediate: true, immediate: true,
}); },
);
}, },
}; };
</script> </script>

View File

@ -98,7 +98,7 @@ export default {
return true; return true;
}, },
submitNewChild(cancel) { submitNewChild(cancel) {
const newChildNode = this.$store.state.explorer.newChildNode; const { newChildNode } = this.$store.state.explorer;
if (!cancel && !newChildNode.isNil && newChildNode.item.name) { if (!cancel && !newChildNode.isNil && newChildNode.item.name) {
if (newChildNode.isFolder) { if (newChildNode.isFolder) {
fileSvc.storeItem(newChildNode.item) fileSvc.storeItem(newChildNode.item)
@ -111,7 +111,7 @@ export default {
this.$store.commit('explorer/setNewItem', null); this.$store.commit('explorer/setNewItem', null);
}, },
submitEdit(cancel) { submitEdit(cancel) {
const item = this.$store.getters['explorer/editingNode'].item; const { item } = this.$store.getters['explorer/editingNode'];
const value = this.editingValue; const value = this.editingValue;
this.setEditingId(null); this.setEditingId(null);
if (!cancel && item.id && value) { if (!cancel && item.id && value) {

View File

@ -70,7 +70,8 @@ class DynamicClassApplier {
() => ({ () => ({
start: this.startMarker.offset, start: this.startMarker.offset,
end: this.endMarker.offset, end: this.endMarker.offset,
})); }),
);
} }
} }
@ -126,7 +127,10 @@ export default {
offsetList.forEach((offset, i) => { offsetList.forEach((offset, i) => {
const key = `${offset.start}:${offset.end}`; const key = `${offset.start}:${offset.end}`;
this.classAppliers[key] = oldClassAppliers[key] || new DynamicClassApplier( this.classAppliers[key] = oldClassAppliers[key] || new DynamicClassApplier(
'find-replace-highlighting', offset, i > 200); 'find-replace-highlighting',
offset,
i > 200,
);
}); });
} catch (e) { } catch (e) {
// Ignore // Ignore
@ -156,9 +160,9 @@ export default {
this.findPosition = 0; this.findPosition = 0;
}, },
find(mode = 'forward') { find(mode = 'forward') {
const selectedClassApplier = this.selectedClassApplier; const { selectedClassApplier } = this;
this.unselectClassApplier(); this.unselectClassApplier();
const selectionMgr = editorSvc.clEditor.selectionMgr; const { selectionMgr } = editorSvc.clEditor;
const startOffset = Math.min(selectionMgr.selectionStart, selectionMgr.selectionEnd); const startOffset = Math.min(selectionMgr.selectionStart, selectionMgr.selectionEnd);
const endOffset = Math.max(selectionMgr.selectionStart, selectionMgr.selectionEnd); const endOffset = Math.max(selectionMgr.selectionStart, selectionMgr.selectionEnd);
const keys = Object.keys(this.classAppliers); const keys = Object.keys(this.classAppliers);
@ -206,7 +210,10 @@ export default {
return; return;
} }
editorSvc.clEditor.replaceAll( editorSvc.clEditor.replaceAll(
this.replaceRegex, this.replaceText, this.selectedClassApplier.startMarker.offset); this.replaceRegex,
this.replaceText,
this.selectedClassApplier.startMarker.offset,
);
this.$nextTick(() => this.find()); this.$nextTick(() => this.find());
} }
}, },
@ -227,7 +234,9 @@ export default {
// Highlight occurences // Highlight occurences
this.debouncedHighlightOccurrences = cledit.Utils.debounce( this.debouncedHighlightOccurrences = cledit.Utils.debounce(
() => this.highlightOccurrences(), 25); () => this.highlightOccurrences(),
25,
);
// Refresh highlighting when find text changes or changing options // Refresh highlighting when find text changes or changing options
this.$watch(() => this.findText, this.debouncedHighlightOccurrences); this.$watch(() => this.findText, this.debouncedHighlightOccurrences);
this.$watch(() => this.findCaseSensitive, this.debouncedHighlightOccurrences); this.$watch(() => this.findCaseSensitive, this.debouncedHighlightOccurrences);
@ -273,7 +282,7 @@ export default {
</script> </script>
<style lang="scss"> <style lang="scss">
@import 'common/variables.scss'; @import '../styles/variables.scss';
.find-replace { .find-replace {
padding: 0 35px 0 25px; padding: 0 35px 0 25px;

View File

@ -140,7 +140,7 @@ export default {
</script> </script>
<style lang="scss"> <style lang="scss">
@import 'common/variables.scss'; @import '../styles/variables.scss';
.layout { .layout {
position: absolute; position: absolute;

View File

@ -141,7 +141,7 @@ export default {
} }
if (isFocusIn && this.config) { if (isFocusIn && this.config) {
const modalInner = this.$el.querySelector('.modal__inner-2'); const modalInner = this.$el.querySelector('.modal__inner-2');
let target = evt.target; let { target } = evt;
while (target) { while (target) {
if (target === modalInner) { if (target === modalInner) {
return; return;
@ -166,7 +166,7 @@ export default {
</script> </script>
<style lang="scss"> <style lang="scss">
@import 'common/variables.scss'; @import '../styles/variables.scss';
.modal { .modal {
position: absolute; position: absolute;

View File

@ -224,7 +224,9 @@ export default {
() => { () => {
this.title = ''; this.title = '';
this.editTitle(false); this.editTitle(false);
}, { immediate: true }); },
{ immediate: true },
);
}, },
mounted() { mounted() {
this.titleFakeElt = this.$el.querySelector('.navigation-bar__title--fake'); this.titleFakeElt = this.$el.querySelector('.navigation-bar__title--fake');
@ -235,7 +237,7 @@ export default {
</script> </script>
<style lang="scss"> <style lang="scss">
@import 'common/variables.scss'; @import '../styles/variables.scss';
.navigation-bar { .navigation-bar {
position: absolute; position: absolute;

View File

@ -23,7 +23,7 @@ export default {
</script> </script>
<style lang="scss"> <style lang="scss">
@import 'common/variables.scss'; @import '../styles/variables.scss';
.notification { .notification {
position: absolute; position: absolute;

View File

@ -22,7 +22,7 @@ import { mapGetters, mapActions } from 'vuex';
import CommentList from './gutters/CommentList'; import CommentList from './gutters/CommentList';
import PreviewNewDiscussionButton from './gutters/PreviewNewDiscussionButton'; import PreviewNewDiscussionButton from './gutters/PreviewNewDiscussionButton';
const appUri = `${location.protocol}//${location.host}`; const appUri = `${window.location.protocol}//${window.location.host}`;
export default { export default {
components: { components: {
@ -98,13 +98,14 @@ export default {
previewElt.querySelectorAll(`.discussion-preview-highlighting--${discussionId}`) previewElt.querySelectorAll(`.discussion-preview-highlighting--${discussionId}`)
.cl_each(elt => elt.classList.add('discussion-preview-highlighting--selected')); .cl_each(elt => elt.classList.add('discussion-preview-highlighting--selected'));
} }
}); },
);
}, },
}; };
</script> </script>
<style lang="scss"> <style lang="scss">
@import 'common/variables.scss'; @import '../styles/variables.scss';
.preview, .preview,
.preview__inner-1 { .preview__inner-1 {

View File

@ -93,7 +93,7 @@ export default {
</script> </script>
<style lang="scss"> <style lang="scss">
@import 'common/variables.scss'; @import '../styles/variables.scss';
.side-bar { .side-bar {
overflow: hidden; overflow: hidden;

View File

@ -92,7 +92,7 @@ export default {
this.htmlSelection = true; this.htmlSelection = true;
if (!text) { if (!text) {
this.htmlSelection = false; this.htmlSelection = false;
text = editorSvc.previewCtx.text; ({ text } = editorSvc.previewCtx);
} }
if (text != null) { if (text != null) {
this.htmlStats.forEach((stat) => { this.htmlStats.forEach((stat) => {

View File

@ -126,7 +126,7 @@ export default {
<style lang="scss"> <style lang="scss">
@import 'common/variables.scss'; @import '../styles/variables.scss';
.tour { .tour {
position: absolute; position: absolute;

View File

@ -10,7 +10,9 @@ const nextTickExecCbs = cledit.Utils.debounce(() => {
} }
if (savedSelection) { if (savedSelection) {
editorSvc.clEditor.selectionMgr.setSelectionStartEnd( editorSvc.clEditor.selectionMgr.setSelectionStartEnd(
savedSelection.start, savedSelection.end); savedSelection.start,
savedSelection.end,
);
} }
savedSelection = null; savedSelection = null;
}); });

View File

@ -40,14 +40,22 @@ export default class PreviewClassApplier {
const offset = this.offsetGetter(); const offset = this.offsetGetter();
if (offset) { if (offset) {
const offsetStart = editorSvc.getPreviewOffset( const offsetStart = editorSvc.getPreviewOffset(
offset.start, editorSvc.previewCtx.sectionDescList); offset.start,
editorSvc.previewCtx.sectionDescList,
);
const offsetEnd = editorSvc.getPreviewOffset( const offsetEnd = editorSvc.getPreviewOffset(
offset.end, editorSvc.previewCtx.sectionDescList); offset.end,
editorSvc.previewCtx.sectionDescList,
);
if (offsetStart != null && offsetEnd != null && offsetStart !== offsetEnd) { if (offsetStart != null && offsetEnd != null && offsetStart !== offsetEnd) {
const start = cledit.Utils.findContainer( const start = cledit.Utils.findContainer(
editorSvc.previewElt, Math.min(offsetStart, offsetEnd)); editorSvc.previewElt,
Math.min(offsetStart, offsetEnd),
);
const end = cledit.Utils.findContainer( const end = cledit.Utils.findContainer(
editorSvc.previewElt, Math.max(offsetStart, offsetEnd)); editorSvc.previewElt,
Math.max(offsetStart, offsetEnd),
);
const range = document.createRange(); const range = document.createRange();
range.setStart(start.container, start.offsetInContainer); range.setStart(start.container, start.offsetInContainer);
range.setEnd(end.container, end.offsetInContainer); range.setEnd(end.container, end.offsetInContainer);

View File

@ -51,7 +51,8 @@ export default {
this.$store.dispatch('modal/commentDeletion') this.$store.dispatch('modal/commentDeletion')
.then( .then(
() => this.$store.dispatch('discussion/cleanCurrentFile', { filterComment: this.comment }), () => this.$store.dispatch('discussion/cleanCurrentFile', { filterComment: this.comment }),
() => { /* Cancel */ }); () => { /* Cancel */ },
);
}, },
}, },
mounted() { mounted() {
@ -63,8 +64,7 @@ export default {
let scrollerMirrorElt; let scrollerMirrorElt;
const getScrollerMirrorElt = () => { const getScrollerMirrorElt = () => {
if (!scrollerMirrorElt) { if (!scrollerMirrorElt) {
scrollerMirrorElt = document.querySelector( scrollerMirrorElt = document.querySelector(`.comment-list .comment--${commentId} .comment__text-inner`);
`.comment-list .comment--${commentId} .comment__text-inner`);
} }
return scrollerMirrorElt || { scrollTop: 0 }; return scrollerMirrorElt || { scrollTop: 0 };
}; };

View File

@ -107,10 +107,13 @@ export default {
this.currentDiscussionLastCommentId this.currentDiscussionLastCommentId
&& this.$el.querySelector(`.comment--${this.currentDiscussionLastCommentId}`), && this.$el.querySelector(`.comment--${this.currentDiscussionLastCommentId}`),
this.$el.querySelector('.comment--new'), this.$el.querySelector('.comment--new'),
true); true,
);
} else { } else {
tops[discussionId] = getTop(discussion, tops[discussionId] = getTop(
this.$el.querySelector(`.comment--discussion-${discussionId}`)); discussion,
this.$el.querySelector(`.comment--discussion-${discussionId}`),
);
} }
}); });
this.tops = tops; this.tops = tops;
@ -120,7 +123,8 @@ export default {
this.$watch( this.$watch(
() => this.updateTopsTrigger, () => this.updateTopsTrigger,
() => this.updateTops(), () => this.updateTops(),
{ immediate: true }); { immediate: true },
);
const layoutSettings = this.$store.getters['data/layoutSettings']; const layoutSettings = this.$store.getters['data/layoutSettings'];
this.scrollerElt = layoutSettings.showEditor this.scrollerElt = layoutSettings.showEditor
@ -161,7 +165,8 @@ export default {
this.$watch( this.$watch(
() => this.updateStickyTrigger, () => this.updateStickyTrigger,
() => this.updateSticky(), () => this.updateSticky(),
{ immediate: true }); { immediate: true },
);
// Move preview discussions once previewCtxWithDiffs has been calculated // Move preview discussions once previewCtxWithDiffs has been calculated
if (!editorSvc.previewCtxWithDiffs) { if (!editorSvc.previewCtxWithDiffs) {
@ -178,7 +183,7 @@ export default {
</script> </script>
<style lang="scss"> <style lang="scss">
@import '../common/variables.scss'; @import '../../styles/variables.scss';
.comment-list { .comment-list {
position: absolute; position: absolute;

View File

@ -99,14 +99,15 @@ export default {
() => this.$store.dispatch('discussion/cleanCurrentFile', { () => this.$store.dispatch('discussion/cleanCurrentFile', {
filterDiscussion: this.currentDiscussion, filterDiscussion: this.currentDiscussion,
}), }),
() => { /* Cancel */ }); () => { /* Cancel */ },
);
}, },
}, },
}; };
</script> </script>
<style lang="scss"> <style lang="scss">
@import '../common/variables.scss'; @import '../../styles/variables.scss';
.current-discussion { .current-discussion {
position: absolute; position: absolute;

View File

@ -86,9 +86,11 @@ export default {
const clEditor = cledit(preElt, scrollerElt, true); const clEditor = cledit(preElt, scrollerElt, true);
clEditor.init({ clEditor.init({
sectionHighlighter: section => Prism.highlight( sectionHighlighter: section => Prism.highlight(
section.text, editorSvc.prismGrammars[section.data]), section.text,
sectionParser: text => markdownConversionSvc.parseSections( editorSvc.prismGrammars[section.data],
editorSvc.converter, text).sections, ),
sectionParser: text => markdownConversionSvc
.parseSections(editorSvc.converter, text).sections,
content: this.$store.state.discussion.newCommentText, content: this.$store.state.discussion.newCommentText,
selectionStart: this.$store.state.discussion.newCommentSelection.start, selectionStart: this.$store.state.discussion.newCommentSelection.start,
selectionEnd: this.$store.state.discussion.newCommentSelection.end, selectionEnd: this.$store.state.discussion.newCommentSelection.end,
@ -114,14 +116,14 @@ export default {
clEditor.focus(); clEditor.focus();
} }
}), }),
{ immediate: true }); { immediate: true },
);
if (isSticky) { if (isSticky) {
let scrollerMirrorElt; let scrollerMirrorElt;
const getScrollerMirrorElt = () => { const getScrollerMirrorElt = () => {
if (!scrollerMirrorElt) { if (!scrollerMirrorElt) {
scrollerMirrorElt = document.querySelector( scrollerMirrorElt = document.querySelector('.comment-list .comment--new .comment__text-inner');
'.comment-list .comment--new .comment__text-inner');
} }
return scrollerMirrorElt || { scrollTop: 0 }; return scrollerMirrorElt || { scrollTop: 0 };
}; };
@ -150,7 +152,7 @@ export default {
); );
this.$watch( this.$watch(
() => this.$store.state.discussion.newCommentText, () => this.$store.state.discussion.newCommentText,
newCommentText => clEditor.setContent(newCommentText), newCommentText => clEditor.setContent(newCommentText),
); );
} }
}, },

View File

@ -28,7 +28,7 @@ export default {
) { ) {
this.selection = editorSvc.getTrimmedSelection(); this.selection = editorSvc.getTrimmedSelection();
if (this.selection) { if (this.selection) {
const text = editorSvc.previewCtxWithDiffs.text; const { text } = editorSvc.previewCtxWithDiffs;
offset = editorSvc.getPreviewOffset(this.selection.end); offset = editorSvc.getPreviewOffset(this.selection.end);
while (offset && text[offset - 1] === '\n') { while (offset && text[offset - 1] === '\n') {
offset -= 1; offset -= 1;
@ -46,7 +46,8 @@ export default {
editorSvc.$on('previewSelectionRange', () => this.checkSelection()); editorSvc.$on('previewSelectionRange', () => this.checkSelection());
this.$watch( this.$watch(
() => this.$store.getters['layout/styles'].previewWidth, () => this.$store.getters['layout/styles'].previewWidth,
() => this.checkSelection()); () => this.checkSelection(),
);
this.checkSelection(); this.checkSelection();
}); });
}, },

View File

@ -33,7 +33,7 @@ export default {
</script> </script>
<style lang="scss"> <style lang="scss">
@import '../common/variables.scss'; @import '../../styles/variables.scss';
.sticky-comment { .sticky-comment {
position: absolute; position: absolute;

View File

@ -113,13 +113,15 @@ export default {
let revisionContentPromise = revisionContentPromises[revision.id]; let revisionContentPromise = revisionContentPromises[revision.id];
if (!revisionContentPromise) { if (!revisionContentPromise) {
revisionContentPromise = new Promise((resolve, reject) => { revisionContentPromise = new Promise((resolve, reject) => {
const syncToken = this.syncToken; const { syncToken } = this;
const currentFile = this.$store.getters['file/current']; const currentFile = this.$store.getters['file/current'];
this.$store.dispatch('queue/enqueue', this.$store.dispatch(
'queue/enqueue',
() => Promise.resolve() () => Promise.resolve()
.then(() => this.workspaceProvider.getRevisionContent( .then(() => this.workspaceProvider
syncToken, currentFile.id, revision.id)) .getRevisionContent(syncToken, currentFile.id, revision.id))
.then(resolve, reject)); .then(resolve, reject),
);
}); });
revisionContentPromises[revision.id] = revisionContentPromise; revisionContentPromises[revision.id] = revisionContentPromise;
revisionContentPromise.catch(() => { revisionContentPromise.catch(() => {
@ -130,7 +132,7 @@ export default {
this.$store.dispatch('content/setRevisionContent', revisionContent)); this.$store.dispatch('content/setRevisionContent', revisionContent));
}, },
refreshHighlighters() { refreshHighlighters() {
const revisionContent = this.$store.state.content.revisionContent; const { revisionContent } = this.$store.state.content;
editorClassAppliers.forEach(editorClassApplier => editorClassApplier.stop()); editorClassAppliers.forEach(editorClassApplier => editorClassApplier.stop());
editorClassAppliers = []; editorClassAppliers = [];
previewClassAppliers.forEach(previewClassApplier => previewClassApplier.stop()); previewClassAppliers.forEach(previewClassApplier => previewClassApplier.stop());
@ -145,9 +147,13 @@ export default {
end: offset + text.length, end: offset + text.length,
}; };
editorClassAppliers.push(new EditorClassApplier( editorClassAppliers.push(new EditorClassApplier(
[`revision-diff--${utils.uid()}`, ...classes], offsets)); [`revision-diff--${utils.uid()}`, ...classes],
offsets,
));
previewClassAppliers.push(new PreviewClassApplier( previewClassAppliers.push(new PreviewClassApplier(
[`revision-diff--${utils.uid()}`, ...classes], offsets)); [`revision-diff--${utils.uid()}`, ...classes],
offsets,
));
} }
offset += text.length; offset += text.length;
}); });
@ -164,8 +170,8 @@ export default {
() => this.refreshTrigger, () => this.refreshTrigger,
() => { () => {
this.allRevisions = []; this.allRevisions = [];
const id = this.$store.getters['file/current'].id; const { id } = this.$store.getters['file/current'];
const syncToken = this.syncToken; const { syncToken } = this;
if (id && syncToken) { if (id && syncToken) {
if (id !== cachedFileId) { if (id !== cachedFileId) {
this.setRevisionContent(); this.setRevisionContent();
@ -173,10 +179,12 @@ export default {
revisionContentPromises = {}; revisionContentPromises = {};
const currentFile = this.$store.getters['file/current']; const currentFile = this.$store.getters['file/current'];
revisionsPromise = new Promise((resolve, reject) => { revisionsPromise = new Promise((resolve, reject) => {
this.$store.dispatch('queue/enqueue', this.$store.dispatch(
'queue/enqueue',
() => Promise.resolve() () => Promise.resolve()
.then(() => this.workspaceProvider.listRevisions(syncToken, currentFile.id)) .then(() => this.workspaceProvider.listRevisions(syncToken, currentFile.id))
.then(resolve, reject)); .then(resolve, reject),
);
}) })
.catch(() => { .catch(() => {
cachedFileId = null; cachedFileId = null;
@ -191,16 +199,18 @@ export default {
}); });
} }
} }
}, { immediate: true }); }, { immediate: true },
);
const loadOne = () => { const loadOne = () => {
if (!this.destroyed) { if (!this.destroyed) {
this.$store.dispatch('queue/enqueue', this.$store.dispatch(
'queue/enqueue',
() => { () => {
let loadPromise; let loadPromise;
this.revisions.some((revision) => { this.revisions.some((revision) => {
if (!revision.created) { if (!revision.created) {
const syncToken = this.syncToken; const { syncToken } = this;
const currentFile = this.$store.getters['file/current']; const currentFile = this.$store.getters['file/current'];
loadPromise = this.workspaceProvider loadPromise = this.workspaceProvider
.loadRevision(syncToken, currentFile.id, revision) .loadRevision(syncToken, currentFile.id, revision)
@ -209,19 +219,22 @@ export default {
return loadPromise; return loadPromise;
}); });
return loadPromise; return loadPromise;
}); },
);
} }
}; };
this.$watch( this.$watch(
() => this.revisions, () => this.revisions,
() => loadOne(), () => loadOne(),
{ immediate: true }); { immediate: true },
);
// Watch diffs changes // Watch diffs changes
this.$watch( this.$watch(
() => this.$store.state.content.revisionContent, () => this.$store.state.content.revisionContent,
() => this.refreshHighlighters()); () => this.refreshHighlighters(),
);
// Close revision // Close revision
this.onKeyup = (evt) => { this.onKeyup = (evt) => {
@ -246,7 +259,7 @@ export default {
</script> </script>
<style lang="scss"> <style lang="scss">
@import '../common/variables.scss'; @import '../../styles/variables.scss';
.history { .history {
padding: 5px 5px 50px; padding: 5px 5px 50px;

View File

@ -53,31 +53,25 @@ export default {
MenuEntry, MenuEntry,
}, },
methods: { methods: {
onImportMarkdown(evt) { async onImportMarkdown(evt) {
const file = evt.target.files[0]; const file = evt.target.files[0];
readFile(file) const content = await readFile(file);
.then(content => fileSvc.createFile({ const item = await fileSvc.createFile({
...Provider.parseContent(content), ...Provider.parseContent(content),
name: file.name, name: file.name,
}) });
.then( this.$store.commit('file/setCurrentId', item.id);
item => this.$store.commit('file/setCurrentId', item.id)),
() => { /* Cancel */ });
}, },
onImportHtml(evt) { async onImportHtml(evt) {
const file = evt.target.files[0]; const file = evt.target.files[0];
readFile(file) const content = await readFile(file);
.then(content => fileSvc.createFile({ const sanitizedContent = htmlSanitizer.sanitizeHtml(content)
...Provider.parseContent( .replace(/&#160;/g, ' '); // Replace non-breaking spaces with classic spaces
turndownService.turndown( const item = await fileSvc.createFile({
htmlSanitizer.sanitizeHtml(content) ...Provider.parseContent(turndownService.turndown(sanitizedContent)),
.replace(/&#160;/g, ' '), // Replace non-breaking spaces with classic spaces name: file.name,
)), });
name: file.name, this.$store.commit('file/setCurrentId', item.id);
}))
.then(
item => this.$store.commit('file/setCurrentId', item.id),
() => { /* Cancel */ });
}, },
}, },
}; };

View File

@ -116,7 +116,7 @@ export default {
.catch(() => { /* Cancel */ }); .catch(() => { /* Cancel */ });
}, },
print() { print() {
print(); window.print();
}, },
}, },
}; };

View File

@ -95,8 +95,8 @@ export default {
reset() { reset() {
return this.$store.dispatch('modal/reset') return this.$store.dispatch('modal/reset')
.then(() => { .then(() => {
location.href = '#reset=true'; window.location.href = '#reset=true';
location.reload(); window.location.reload();
}); });
}, },
about() { about() {

View File

@ -170,13 +170,17 @@ export default {
}, },
openGoogleDrive(token) { openGoogleDrive(token) {
return googleHelper.openPicker(token, 'doc') return googleHelper.openPicker(token, 'doc')
.then(files => this.$store.dispatch('queue/enqueue', .then(files => this.$store.dispatch(
() => googleDriveProvider.openFiles(token, files))); 'queue/enqueue',
() => googleDriveProvider.openFiles(token, files),
));
}, },
openDropbox(token) { openDropbox(token) {
return dropboxHelper.openChooser(token) return dropboxHelper.openChooser(token)
.then(paths => this.$store.dispatch('queue/enqueue', .then(paths => this.$store.dispatch(
() => dropboxProvider.openFiles(token, paths))); 'queue/enqueue',
() => dropboxProvider.openFiles(token, paths),
));
}, },
saveGoogleDrive(token) { saveGoogleDrive(token) {
return openSyncModal(token, 'googleDriveSave') return openSyncModal(token, 'googleDriveSave')
@ -191,8 +195,10 @@ export default {
type: 'githubOpen', type: 'githubOpen',
token, token,
}) })
.then(syncLocation => this.$store.dispatch('queue/enqueue', .then(syncLocation => this.$store.dispatch(
() => githubProvider.openFile(token, syncLocation))); 'queue/enqueue',
() => githubProvider.openFile(token, syncLocation),
));
}, },
saveGithub(token) { saveGithub(token) {
return openSyncModal(token, 'githubSave') return openSyncModal(token, 'githubSave')

View File

@ -74,7 +74,7 @@ export default {
</script> </script>
<style lang="scss"> <style lang="scss">
@import '../common/variables.scss'; @import '../../styles/variables.scss';
.workspace .menu-entry { .workspace .menu-entry {
padding-top: 12px; padding-top: 12px;

View File

@ -10,7 +10,7 @@
</template> </template>
<style lang="scss"> <style lang="scss">
@import '../../common/variables.scss'; @import '../../../styles/variables.scss';
.menu-entry { .menu-entry {
text-align: left; text-align: left;

View File

@ -223,7 +223,7 @@ export default {
</script> </script>
<style lang="scss"> <style lang="scss">
@import '../common/variables.scss'; @import '../../styles/variables.scss';
.modal__inner-1--file-properties { .modal__inner-1--file-properties {
max-width: 540px; max-width: 540px;

View File

@ -56,7 +56,7 @@ export default modalTemplate({
}, },
methods: { methods: {
resolve() { resolve() {
const config = this.config; const { config } = this;
const currentFile = this.$store.getters['file/current']; const currentFile = this.$store.getters['file/current'];
config.resolve(); config.resolve();
exportSvc.exportToDisk(currentFile.id, 'html', this.allTemplates[this.selectedTemplate]); exportSvc.exportToDisk(currentFile.id, 'html', this.allTemplates[this.selectedTemplate]);

View File

@ -48,13 +48,13 @@ export default modalTemplate({
if (!this.url) { if (!this.url) {
this.setError('url'); this.setError('url');
} else { } else {
const callback = this.config.callback; const { callback } = this.config;
this.config.resolve(); this.config.resolve();
callback(this.url); callback(this.url);
} }
}, },
reject() { reject() {
const callback = this.config.callback; const { callback } = this.config;
this.config.reject(); this.config.reject();
callback(null); callback(null);
}, },
@ -62,7 +62,7 @@ export default modalTemplate({
return googleHelper.addPhotosAccount(); return googleHelper.addPhotosAccount();
}, },
openGooglePhotos(token) { openGooglePhotos(token) {
const callback = this.config.callback; const { callback } = this.config;
this.config.reject(); this.config.reject();
googleHelper.openPicker(token, 'img') googleHelper.openPicker(token, 'img')
.then(res => res[0] && this.$store.dispatch('modal/open', { .then(res => res[0] && this.$store.dispatch('modal/open', {

View File

@ -25,13 +25,13 @@ export default modalTemplate({
if (!this.url) { if (!this.url) {
this.setError('url'); this.setError('url');
} else { } else {
const callback = this.config.callback; const { callback } = this.config;
this.config.resolve(); this.config.resolve();
callback(this.url); callback(this.url);
} }
}, },
reject() { reject() {
const callback = this.config.callback; const { callback } = this.config;
this.config.reject(); this.config.reject();
callback(null); callback(null);
}, },

View File

@ -42,7 +42,7 @@ export default modalTemplate({
this.config.resolve(); this.config.resolve();
const currentFile = this.$store.getters['file/current']; const currentFile = this.$store.getters['file/current'];
const currentContent = this.$store.getters['content/current']; const currentContent = this.$store.getters['content/current'];
const selectedFormat = this.selectedFormat; const { selectedFormat } = this;
this.$store.dispatch('queue/enqueue', () => Promise.all([ this.$store.dispatch('queue/enqueue', () => Promise.all([
Promise.resolve().then(() => { Promise.resolve().then(() => {
const sponsorToken = this.$store.getters['workspace/sponsorToken']; const sponsorToken = this.$store.getters['workspace/sponsorToken'];
@ -64,15 +64,15 @@ export default modalTemplate({
blob: true, blob: true,
timeout: 60000, timeout: 60000,
}) })
.then((res) => { .then((res) => {
FileSaver.saveAs(res.body, `${currentFile.name}.${selectedFormat}`); FileSaver.saveAs(res.body, `${currentFile.name}.${selectedFormat}`);
}, (err) => { }, (err) => {
if (err.status !== 401) { if (err.status !== 401) {
throw err; throw err;
} }
this.$store.dispatch('modal/sponsorOnly') this.$store.dispatch('modal/sponsorOnly')
.catch(() => { /* Cancel */ }); .catch(() => { /* Cancel */ });
})) }))
.catch((err) => { .catch((err) => {
console.error(err); // eslint-disable-line no-console console.error(err); // eslint-disable-line no-console
this.$store.dispatch('notification/error', err); this.$store.dispatch('notification/error', err);

View File

@ -43,7 +43,10 @@ export default modalTemplate({
}), }),
sponsorSvc.getToken(), sponsorSvc.getToken(),
exportSvc.applyTemplate( exportSvc.applyTemplate(
currentFile.id, this.allTemplates[this.selectedTemplate], true), currentFile.id,
this.allTemplates[this.selectedTemplate],
true,
),
]) ])
.then(([sponsorToken, token, html]) => networkSvc.request({ .then(([sponsorToken, token, html]) => networkSvc.request({
method: 'POST', method: 'POST',
@ -57,15 +60,15 @@ export default modalTemplate({
blob: true, blob: true,
timeout: 60000, timeout: 60000,
}) })
.then((res) => { .then((res) => {
FileSaver.saveAs(res.body, `${currentFile.name}.pdf`); FileSaver.saveAs(res.body, `${currentFile.name}.pdf`);
}, (err) => { }, (err) => {
if (err.status !== 401) { if (err.status !== 401) {
throw err; throw err;
} }
this.$store.dispatch('modal/sponsorOnly') this.$store.dispatch('modal/sponsorOnly')
.catch(() => { /* Cancel */ }); .catch(() => { /* Cancel */ });
})) }))
.catch((err) => { .catch((err) => {
console.error(err); // eslint-disable-line no-console console.error(err); // eslint-disable-line no-console
this.$store.dispatch('notification/error', err); this.$store.dispatch('notification/error', err);

View File

@ -59,7 +59,7 @@ export default {
</script> </script>
<style lang="scss"> <style lang="scss">
@import '../common/variables.scss'; @import '../../styles/variables.scss';
.modal__inner-1--publish-management { .modal__inner-1--publish-management {
max-width: 560px; max-width: 560px;

View File

@ -81,7 +81,7 @@ export default {
</script> </script>
<style lang="scss"> <style lang="scss">
@import '../common/variables.scss'; @import '../../styles/variables.scss';
.modal__inner-1--settings { .modal__inner-1--settings {
max-width: 600px; max-width: 600px;

View File

@ -63,7 +63,7 @@ export default {
</script> </script>
<style lang="scss"> <style lang="scss">
@import '../common/variables.scss'; @import '../../styles/variables.scss';
.modal__inner-1--sponsor { .modal__inner-1--sponsor {
max-width: 380px; max-width: 380px;

View File

@ -59,7 +59,7 @@ export default {
</script> </script>
<style lang="scss"> <style lang="scss">
@import '../common/variables.scss'; @import '../../styles/variables.scss';
.modal__inner-1--sync-management { .modal__inner-1--sync-management {
max-width: 560px; max-width: 560px;

View File

@ -105,10 +105,12 @@ export default {
this.templates = templates; this.templates = templates;
this.selectedId = this.config.selectedId; this.selectedId = this.config.selectedId;
if (!templates[this.selectedId]) { if (!templates[this.selectedId]) {
this.selectedId = Object.keys(templates)[0]; [this.selectedId] = Object.keys(templates);
} }
this.isEditing = false; this.isEditing = false;
}, { immediate: true }); },
{ immediate: true },
);
this.$watch('selectedId', (selectedId) => { this.$watch('selectedId', (selectedId) => {
const template = this.templates[selectedId]; const template = this.templates[selectedId];
this.showHelpers = template.helpers !== emptyTemplateHelpers; this.showHelpers = template.helpers !== emptyTemplateHelpers;
@ -137,7 +139,7 @@ export default {
}, },
remove() { remove() {
delete this.templates[this.selectedId]; delete this.templates[this.selectedId];
this.selectedId = Object.keys(this.templates)[0]; [this.selectedId] = Object.keys(this.templates);
}, },
submitEdit(cancel) { submitEdit(cancel) {
const template = this.templates[this.selectedId]; const template = this.templates[this.selectedId];

View File

@ -87,7 +87,7 @@ export default {
</script> </script>
<style lang="scss"> <style lang="scss">
@import '../common/variables.scss'; @import '../../styles/variables.scss';
.modal__inner-1--workspace-management { .modal__inner-1--workspace-management {
max-width: 560px; max-width: 560px;

View File

@ -24,7 +24,7 @@ export default {
'config', 'config',
]), ]),
showSponsorButton() { showSponsorButton() {
const type = this.$store.getters['modal/config'].type; const { type } = this.$store.getters['modal/config'];
return !this.$store.getters.isSponsor && type !== 'sponsor' && type !== 'signInForSponsorship'; return !this.$store.getters.isSponsor && type !== 'sponsor' && type !== 'signInForSponsorship';
}, },
}, },
@ -49,7 +49,7 @@ export default {
</script> </script>
<style lang="scss"> <style lang="scss">
@import '../../common/variables.scss'; @import '../../../styles/variables.scss';
.modal__close-button { .modal__close-button {
position: absolute; position: absolute;

View File

@ -54,7 +54,10 @@ export default modalTemplate({
} else { } else {
// Return new location // Return new location
const location = bloggerPageProvider.makeLocation( const location = bloggerPageProvider.makeLocation(
this.config.token, this.blogUrl, this.pageId); this.config.token,
this.blogUrl,
this.pageId,
);
location.templateId = this.selectedTemplate; location.templateId = this.selectedTemplate;
this.config.resolve(location); this.config.resolve(location);
} }

View File

@ -55,7 +55,10 @@ export default modalTemplate({
} else { } else {
// Return new location // Return new location
const location = bloggerProvider.makeLocation( const location = bloggerProvider.makeLocation(
this.config.token, this.blogUrl, this.postId); this.config.token,
this.blogUrl,
this.postId,
);
location.templateId = this.selectedTemplate; location.templateId = this.selectedTemplate;
this.config.resolve(location); this.config.resolve(location);
} }

View File

@ -65,7 +65,11 @@ export default modalTemplate({
} else { } else {
// Return new location // Return new location
const location = gistProvider.makeLocation( const location = gistProvider.makeLocation(
this.config.token, this.filename, this.isPublic, this.gistId); this.config.token,
this.filename,
this.isPublic,
this.gistId,
);
location.templateId = this.selectedTemplate; location.templateId = this.selectedTemplate;
this.config.resolve(location); this.config.resolve(location);
} }

View File

@ -51,7 +51,11 @@ export default modalTemplate({
} else { } else {
// Return new location // Return new location
const location = gistProvider.makeLocation( const location = gistProvider.makeLocation(
this.config.token, this.filename, this.isPublic, this.gistId); this.config.token,
this.filename,
this.isPublic,
this.gistId,
);
this.config.resolve(location); this.config.resolve(location);
} }
}, },

View File

@ -58,7 +58,12 @@ export default modalTemplate({
} else { } else {
// Return new location // Return new location
const location = githubProvider.makeLocation( const location = githubProvider.makeLocation(
this.config.token, parsedRepo.owner, parsedRepo.repo, this.branch || 'master', this.path); this.config.token,
parsedRepo.owner,
parsedRepo.repo,
this.branch || 'master',
this.path,
);
this.config.resolve(location); this.config.resolve(location);
} }
} }

View File

@ -73,7 +73,12 @@ export default modalTemplate({
} else { } else {
// Return new location // Return new location
const location = githubProvider.makeLocation( const location = githubProvider.makeLocation(
this.config.token, parsedRepo[1], parsedRepo[2], this.branch || 'master', this.path); this.config.token,
parsedRepo[1],
parsedRepo[2],
this.branch || 'master',
this.path,
);
location.templateId = this.selectedTemplate; location.templateId = this.selectedTemplate;
this.config.resolve(location); this.config.resolve(location);
} }

View File

@ -58,7 +58,12 @@ export default modalTemplate({
} }
if (parsedRepo && this.path) { if (parsedRepo && this.path) {
const location = githubProvider.makeLocation( const location = githubProvider.makeLocation(
this.config.token, parsedRepo.owner, parsedRepo.repo, this.branch || 'master', this.path); this.config.token,
parsedRepo.owner,
parsedRepo.repo,
this.branch || 'master',
this.path,
);
this.config.resolve(location); this.config.resolve(location);
} }
}, },

View File

@ -76,12 +76,12 @@ export default modalTemplate({
this.$store.dispatch('data/patchLocalSettings', { this.$store.dispatch('data/patchLocalSettings', {
googleDriveFolderId: folders[0].id, googleDriveFolderId: folders[0].id,
}); });
})); }),
);
}, },
resolve() { resolve() {
// Return new location // Return new location
const location = googleDriveProvider.makeLocation( const location = googleDriveProvider.makeLocation(this.config.token, this.fileId);
this.config.token, this.fileId);
if (this.format) { if (this.format) {
location.templateId = this.selectedTemplate; location.templateId = this.selectedTemplate;
} }

View File

@ -49,12 +49,16 @@ export default modalTemplate({
this.$store.dispatch('data/patchLocalSettings', { this.$store.dispatch('data/patchLocalSettings', {
googleDriveFolderId: folders[0].id, googleDriveFolderId: folders[0].id,
}); });
})); }),
);
}, },
resolve() { resolve() {
// Return new location // Return new location
const location = googleDriveProvider.makeLocation( const location = googleDriveProvider.makeLocation(
this.config.token, this.fileId, this.folderId); this.config.token,
this.fileId,
this.folderId,
);
this.config.resolve(location); this.config.resolve(location);
}, },
}, },

View File

@ -40,7 +40,8 @@ export default modalTemplate({
this.$store.dispatch('data/patchLocalSettings', { this.$store.dispatch('data/patchLocalSettings', {
googleDriveWorkspaceFolderId: folders[0].id, googleDriveWorkspaceFolderId: folders[0].id,
}); });
})); }),
);
}, },
resolve() { resolve() {
const url = utils.addQueryParams('app', { const url = utils.addQueryParams('app', {

View File

@ -42,20 +42,20 @@ export default {
}, },
methods: { methods: {
resolve() { resolve() {
let url = this.config.url; let { url } = this.config;
const size = parseInt(this.size, 10); const size = parseInt(this.size, 10);
if (!isNaN(size)) { if (!Number.isNaN(size)) {
url = makeThumbnail(url, size); url = makeThumbnail(url, size);
} }
if (this.title) { if (this.title) {
url += ` "${this.title}"`; url += ` "${this.title}"`;
} }
const callback = this.config.callback; const { callback } = this.config;
this.config.resolve(); this.config.resolve();
callback(url); callback(url);
}, },
reject() { reject() {
const callback = this.config.callback; const { callback } = this.config;
this.config.reject(); this.config.reject();
callback(null); callback(null);
}, },

View File

@ -57,7 +57,10 @@ export default modalTemplate({
} else { } else {
// Return new location // Return new location
const location = wordpressProvider.makeLocation( const location = wordpressProvider.makeLocation(
this.config.token, this.domain, this.postId); this.config.token,
this.domain,
this.postId,
);
location.templateId = this.selectedTemplate; location.templateId = this.selectedTemplate;
this.config.resolve(location); this.config.resolve(location);
} }

View File

@ -62,7 +62,11 @@ export default modalTemplate({
} else { } else {
// Return new location // Return new location
const location = zendeskProvider.makeLocation( const location = zendeskProvider.makeLocation(
this.config.token, this.sectionId, this.locale || 'en-us', this.articleId); this.config.token,
this.sectionId,
this.locale || 'en-us',
this.articleId,
);
location.templateId = this.selectedTemplate; location.templateId = this.selectedTemplate;
this.config.resolve(location); this.config.resolve(location);
} }

View File

@ -1 +0,0 @@
@import './common/base';

View File

@ -10,8 +10,7 @@ function attrSet(token, name, value) {
} }
module.exports = (md) => { module.exports = (md) => {
md.core.ruler.after('inline', 'tasklist', (state) => { md.core.ruler.after('inline', 'tasklist', ({ tokens, Token }) => {
const tokens = state.tokens;
for (let i = 2; i < tokens.length; i += 1) { for (let i = 2; i < tokens.length; i += 1) {
const token = tokens[i]; const token = tokens[i];
if (token.content if (token.content
@ -24,7 +23,7 @@ module.exports = (md) => {
) { ) {
const cross = token.content[1].toLowerCase(); const cross = token.content[1].toLowerCase();
if (cross === ' ' || cross === 'x') { if (cross === ' ' || cross === 'x') {
const checkbox = new state.Token('html_inline', '', 0); const checkbox = new Token('html_inline', '', 0);
if (cross === ' ') { if (cross === ' ') {
checkbox.content = '<span class="task-list-item-checkbox" type="checkbox">&#9744;</span>'; checkbox.content = '<span class="task-list-item-checkbox" type="checkbox">&#9744;</span>';
} else { } else {

View File

@ -51,8 +51,8 @@ const inlineBaseRules2 = [
'text_collapse', 'text_collapse',
]; ];
extensionSvc.onGetOptions( extensionSvc.onGetOptions((options, properties) => Object
(options, properties) => Object.assign(options, properties.extensions.markdown)); .assign(options, properties.extensions.markdown));
extensionSvc.onInitConverter(0, (markdown, options) => { extensionSvc.onInitConverter(0, (markdown, options) => {
markdown.set({ markdown.set({

View File

@ -117,6 +117,6 @@ extensionSvc.onGetOptions((options, properties) => {
}); });
extensionSvc.onSectionPreview((elt) => { extensionSvc.onSectionPreview((elt) => {
elt.querySelectorAll('.prism.language-mermaid').cl_each( elt.querySelectorAll('.prism.language-mermaid')
diagramElt => render(diagramElt.parentNode)); .cl_each(diagramElt => render(diagramElt.parentNode));
}); });

View File

@ -13,24 +13,22 @@ if (!indexedDB) {
throw new Error('Your browser is not supported. Please upgrade to the latest version.'); throw new Error('Your browser is not supported. Please upgrade to the latest version.');
} }
if (NODE_ENV === 'production') { OfflinePluginRuntime.install({
OfflinePluginRuntime.install({ onUpdateReady: () => {
onUpdateReady: () => { // Tells to new SW to take control immediately
// Tells to new SW to take control immediately OfflinePluginRuntime.applyUpdate();
OfflinePluginRuntime.applyUpdate(); },
}, onUpdated: () => {
onUpdated: () => { if (!store.state.light) {
if (!store.state.light) { localDbSvc.sync()
localDbSvc.sync() .then(() => {
.then(() => { localStorage.updated = true;
localStorage.updated = true; // Reload the webpage to load into the new version
// Reload the webpage to load into the new version window.location.reload();
location.reload(); });
}); }
} },
}, });
});
}
if (localStorage.updated) { if (localStorage.updated) {
store.dispatch('notification/info', 'StackEdit has just updated itself!'); store.dispatch('notification/info', 'StackEdit has just updated itself!');

View File

@ -63,7 +63,7 @@ function StyleAttribute(name, unit, defaultValue, wrap = identity) {
this.name = name; this.name = name;
this.setStart = (animation) => { this.setStart = (animation) => {
let value = parseFloat(animation.elt.style[name]); let value = parseFloat(animation.elt.style[name]);
if (isNaN(value)) { if (Number.isNaN(value)) {
value = animation.$current[name] || defaultValue; value = animation.$current[name] || defaultValue;
} }
animation.$start[name] = value; animation.$start[name] = value;
@ -157,7 +157,7 @@ class Animation {
const onTransitionEnd = (evt) => { const onTransitionEnd = (evt) => {
if (evt.target === this.elt) { if (evt.target === this.elt) {
this.elt.removeEventListener(transitionEndEvent, onTransitionEnd); this.elt.removeEventListener(transitionEndEvent, onTransitionEnd);
const endCb = this.$end.endCb; const { endCb } = this.$end;
this.$end.endCb = undefined; this.$end.endCb = undefined;
if (endCb) { if (endCb) {
endCb(); endCb();

View File

@ -12,7 +12,7 @@ function cledit(contentElt, scrollEltOpt, isMarkdown = false) {
$markers: {}, $markers: {},
}; };
cledit.Utils.createEventHooks(editor); cledit.Utils.createEventHooks(editor);
const debounce = cledit.Utils.debounce; const { debounce } = cledit.Utils;
contentElt.setAttribute('tabindex', '0'); // To have focus even when disabled contentElt.setAttribute('tabindex', '0'); // To have focus even when disabled
editor.toggleEditable = (isEditable) => { editor.toggleEditable = (isEditable) => {
@ -21,7 +21,7 @@ function cledit(contentElt, scrollEltOpt, isMarkdown = false) {
editor.toggleEditable(true); editor.toggleEditable(true);
function getTextContent() { function getTextContent() {
// Markdown-it sanitization (Mac/DOS to Unix) // Markdown-it sanitization (Mac/DOS to Unix)
let textContent = contentElt.textContent.replace(/\r[\n\u0085]?|[\u2424\u2028\u0085]/g, '\n'); let textContent = contentElt.textContent.replace(/\r[\n\u0085]?|[\u2424\u2028\u0085]/g, '\n');
if (textContent.slice(-1) !== '\n') { if (textContent.slice(-1) !== '\n') {
textContent += '\n'; textContent += '\n';
@ -258,8 +258,10 @@ function cledit(contentElt, scrollEltOpt, isMarkdown = false) {
window.addEventListener('resize', windowResizeListener); window.addEventListener('resize', windowResizeListener);
// Provokes selection changes and does not fire mouseup event on Chrome/OSX // Provokes selection changes and does not fire mouseup event on Chrome/OSX
contentElt.addEventListener('contextmenu', contentElt.addEventListener(
selectionMgr.saveSelectionState.cl_bind(selectionMgr, true, false)); 'contextmenu',
selectionMgr.saveSelectionState.cl_bind(selectionMgr, true, false),
);
contentElt.addEventListener('keydown', keydownHandler((evt) => { contentElt.addEventListener('keydown', keydownHandler((evt) => {
selectionMgr.saveSelectionState(); selectionMgr.saveSelectionState();
@ -344,7 +346,7 @@ function cledit(contentElt, scrollEltOpt, isMarkdown = false) {
undoMgr.setCurrentMode('single'); undoMgr.setCurrentMode('single');
evt.preventDefault(); evt.preventDefault();
let data; let data;
let clipboardData = evt.clipboardData; let { clipboardData } = evt;
if (clipboardData) { if (clipboardData) {
data = clipboardData.getData('text/plain'); data = clipboardData.getData('text/plain');
if (turndownService) { if (turndownService) {
@ -362,7 +364,7 @@ function cledit(contentElt, scrollEltOpt, isMarkdown = false) {
} }
} }
} else { } else {
clipboardData = window.clipboardData; ({ clipboardData } = window.clipboardData);
data = clipboardData && clipboardData.getData('Text'); data = clipboardData && clipboardData.getData('Text');
} }
if (!data) { if (!data) {
@ -382,8 +384,9 @@ function cledit(contentElt, scrollEltOpt, isMarkdown = false) {
function addKeystroke(keystroke) { function addKeystroke(keystroke) {
const keystrokes = Array.isArray(keystroke) ? keystroke : [keystroke]; const keystrokes = Array.isArray(keystroke) ? keystroke : [keystroke];
editor.$keystrokes = editor.$keystrokes.concat(keystrokes).sort( editor.$keystrokes = editor.$keystrokes
(keystroke1, keystroke2) => keystroke1.priority - keystroke2.priority); .concat(keystrokes)
.sort((keystroke1, keystroke2) => keystroke1.priority - keystroke2.priority);
} }
addKeystroke(cledit.defaultKeystrokes); addKeystroke(cledit.defaultKeystrokes);

View File

@ -33,10 +33,10 @@ function Highlighter(editor) {
section.forceHighlighting = true; section.forceHighlighting = true;
if (!noContentFix) { if (!noContentFix) {
if (useBr) { if (useBr) {
section.elt.getElementsByClassName('hd-lf').cl_each( section.elt.getElementsByClassName('hd-lf')
lfElt => lfElt.parentNode.removeChild(lfElt)); .cl_each(lfElt => lfElt.parentNode.removeChild(lfElt));
section.elt.getElementsByTagName('br').cl_each( section.elt.getElementsByTagName('br')
brElt => brElt.parentNode.replaceChild(document.createTextNode('\n'), brElt)); .cl_each(brElt => brElt.parentNode.replaceChild(document.createTextNode('\n'), brElt));
} }
if (section.elt.textContent.slice(-1) !== '\n') { if (section.elt.textContent.slice(-1) !== '\n') {
section.elt.appendChild(document.createTextNode('\n')); section.elt.appendChild(document.createTextNode('\n'));
@ -127,7 +127,7 @@ function Highlighter(editor) {
const leftSections = sectionList.slice(0, leftIndex); const leftSections = sectionList.slice(0, leftIndex);
modifiedSections = newSectionList.slice(leftIndex, newSectionList.length + rightIndex); modifiedSections = newSectionList.slice(leftIndex, newSectionList.length + rightIndex);
const rightSections = sectionList.slice(sectionList.length + rightIndex, sectionList.length); const rightSections = sectionList.slice(sectionList.length + rightIndex, sectionList.length);
insertBeforeSection = rightSections[0]; [insertBeforeSection] = rightSections;
sectionsToRemove = sectionList.slice(leftIndex, sectionList.length + rightIndex); sectionsToRemove = sectionList.slice(leftIndex, sectionList.length + rightIndex);
sectionList = leftSections.concat(modifiedSections).concat(rightSections); sectionList = leftSections.concat(modifiedSections).concat(rightSections);
} }

View File

@ -165,7 +165,10 @@ cledit.defaultKeystrokes = [
// Custom jump behavior // Custom jump behavior
const textContent = editor.getContent(); const textContent = editor.getContent();
const offset = getNextWordOffset( const offset = getNextWordOffset(
textContent, editor.selectionMgr.selectionEnd, evt.which === 37); textContent,
editor.selectionMgr.selectionEnd,
evt.which === 37,
);
if (evt.shiftKey) { if (evt.shiftKey) {
// rebuild the state completely // rebuild the state completely
const min = Math.min(editor.selectionMgr.selectionStart, offset); const min = Math.min(editor.selectionMgr.selectionStart, offset);

View File

@ -1,7 +1,7 @@
import cledit from './cleditCore'; import cledit from './cleditCore';
function SelectionMgr(editor) { function SelectionMgr(editor) {
const debounce = cledit.Utils.debounce; const { debounce } = cledit.Utils;
const contentElt = editor.$contentElt; const contentElt = editor.$contentElt;
const scrollElt = editor.$scrollElt; const scrollElt = editor.$scrollElt;
cledit.Utils.createEventHooks(this); cledit.Utils.createEventHooks(this);
@ -29,10 +29,10 @@ function SelectionMgr(editor) {
this.createRange = (start, end) => { this.createRange = (start, end) => {
const range = document.createRange(); const range = document.createRange();
const startContainer = isNaN(start) ? start : this.findContainer(start < 0 ? 0 : start); const startContainer = Number.isNaN(start) ? start : this.findContainer(start < 0 ? 0 : start);
let endContainer = startContainer; let endContainer = startContainer;
if (start !== end) { if (start !== end) {
endContainer = isNaN(end) ? end : this.findContainer(end < 0 ? 0 : end); endContainer = Number.isNaN(end) ? end : this.findContainer(end < 0 ? 0 : end);
} }
range.setStart(startContainer.container, startContainer.offsetInContainer); range.setStart(startContainer.container, startContainer.offsetInContainer);
range.setEnd(endContainer.container, endContainer.offsetInContainer); range.setEnd(endContainer.container, endContainer.offsetInContainer);
@ -42,7 +42,10 @@ function SelectionMgr(editor) {
let adjustScroll; let adjustScroll;
const debouncedUpdateCursorCoordinates = debounce(() => { const debouncedUpdateCursorCoordinates = debounce(() => {
const coordinates = this.getCoordinates( const coordinates = this.getCoordinates(
this.selectionEnd, this.selectionEndContainer, this.selectionEndOffset); this.selectionEnd,
this.selectionEndContainer,
this.selectionEndOffset,
);
if (this.cursorCoordinates.top !== coordinates.top || if (this.cursorCoordinates.top !== coordinates.top ||
this.cursorCoordinates.height !== coordinates.height || this.cursorCoordinates.height !== coordinates.height ||
this.cursorCoordinates.left !== coordinates.left this.cursorCoordinates.left !== coordinates.left
@ -163,10 +166,10 @@ function SelectionMgr(editor) {
function getNodeIndex(node) { function getNodeIndex(node) {
let i = 0; let i = 0;
let previousSibling = node.previousSibling; let { previousSibling } = node;
while (previousSibling) { while (previousSibling) {
i += 1; i += 1;
previousSibling = previousSibling.previousSibling; ({ previousSibling } = previousSibling);
} }
return i; return i;
} }
@ -235,8 +238,8 @@ function SelectionMgr(editor) {
const save = () => { const save = () => {
let result; let result;
if (this.hasFocus()) { if (this.hasFocus()) {
let selectionStart = this.selectionStart; let { selectionStart } = this;
let selectionEnd = this.selectionEnd; let { selectionEnd } = this;
const selection = window.getSelection(); const selection = window.getSelection();
if (selection.rangeCount > 0) { if (selection.rangeCount > 0) {
const selectionRange = selection.getRangeAt(0); const selectionRange = selection.getRangeAt(0);
@ -271,8 +274,8 @@ function SelectionMgr(editor) {
selection.anchorNode, selection.anchorNode,
selection.anchorOffset, selection.anchorOffset,
selection.focusNode, selection.focusNode,
selection.focusOffset) === 1 selection.focusOffset,
) { ) === 1) {
selectionStart = offset + selectionText.length; selectionStart = offset + selectionText.length;
selectionEnd = offset; selectionEnd = offset;
} else { } else {
@ -337,8 +340,8 @@ function SelectionMgr(editor) {
let offsetInContainer = offsetInContainerParam; let offsetInContainer = offsetInContainerParam;
if (!container) { if (!container) {
const offset = this.findContainer(inputOffset); const offset = this.findContainer(inputOffset);
container = offset.container; ({ container } = offset);
offsetInContainer = offset.offsetInContainer; ({ offsetInContainer } = offset);
} }
let containerElt = container; let containerElt = container;
if (!containerElt.hasChildNodes() && container.parentNode) { if (!containerElt.hasChildNodes() && container.parentNode) {

View File

@ -15,7 +15,7 @@ function UndoMgr(editor) {
let currentState; let currentState;
let previousPatches = []; let previousPatches = [];
let currentPatches = []; let currentPatches = [];
const debounce = cledit.Utils.debounce; const { debounce } = cledit.Utils;
this.options = { this.options = {
undoStackMaxSize: 200, undoStackMaxSize: 200,
@ -166,7 +166,7 @@ function UndoMgr(editor) {
this.init = (options) => { this.init = (options) => {
this.options.cl_extend(options || {}); this.options.cl_extend(options || {});
selectionMgr = editor.selectionMgr; ({ selectionMgr } = editor);
if (!currentState) { if (!currentState) {
currentState = new State(); currentState = new State();
} }

View File

@ -78,7 +78,8 @@ function restoreDiscussionOffsets(content, markerKeys) {
} }
count += 1; count += 1;
return ''; return '';
}); },
);
// Sanitize offsets // Sanitize offsets
Object.keys(content.discussions).forEach((discussionId) => { Object.keys(content.discussions).forEach((discussionId) => {
const discussion = content.discussions[discussionId]; const discussion = content.discussions[discussionId];

View File

@ -91,8 +91,8 @@ const editorSvc = Object.assign(new Vue(), editorSvcDiscussions, editorSvcUtils,
this.previewCtxWithDiffs = null; this.previewCtxWithDiffs = null;
editorSvc.$emit('previewCtxWithDiffs', null); editorSvc.$emit('previewCtxWithDiffs', null);
const options = { const options = {
sectionHighlighter: section => Prism.highlight( sectionHighlighter: section => Prism
section.text, this.prismGrammars[section.data]), .highlight(section.text, this.prismGrammars[section.data]),
sectionParser: (text) => { sectionParser: (text) => {
this.parsingCtx = markdownConversionSvc.parseSections(this.converter, text); this.parsingCtx = markdownConversionSvc.parseSections(this.converter, text);
return this.parsingCtx.sections; return this.parsingCtx.sections;
@ -114,7 +114,7 @@ const editorSvc = Object.assign(new Vue(), editorSvcDiscussions, editorSvcUtils,
convert() { convert() {
this.conversionCtx = markdownConversionSvc.convert(this.parsingCtx, this.conversionCtx); this.conversionCtx = markdownConversionSvc.convert(this.parsingCtx, this.conversionCtx);
this.$emit('conversionCtx', this.conversionCtx); this.$emit('conversionCtx', this.conversionCtx);
tokens = this.parsingCtx.markdownState.tokens; ({ tokens } = this.parsingCtx.markdownState);
}, },
/** /**
@ -139,7 +139,11 @@ const editorSvc = Object.assign(new Vue(), editorSvcDiscussions, editorSvcUtils,
if (sectionDesc.editorElt !== section.elt) { if (sectionDesc.editorElt !== section.elt) {
// Force textToPreviewDiffs computation // Force textToPreviewDiffs computation
sectionDesc = new SectionDesc( sectionDesc = new SectionDesc(
section, sectionDesc.previewElt, sectionDesc.tocElt, sectionDesc.html); section,
sectionDesc.previewElt,
sectionDesc.tocElt,
sectionDesc.html,
);
} }
sectionDescList.push(sectionDesc); sectionDescList.push(sectionDesc);
previewHtml += sectionDesc.html; previewHtml += sectionDesc.html;
@ -256,7 +260,9 @@ const editorSvc = Object.assign(new Vue(), editorSvcDiscussions, editorSvcUtils,
sectionDesc.previewText = sectionDesc.previewElt.textContent; sectionDesc.previewText = sectionDesc.previewElt.textContent;
} }
sectionDesc.textToPreviewDiffs = diffMatchPatch.diff_main( sectionDesc.textToPreviewDiffs = diffMatchPatch.diff_main(
sectionDesc.section.text, sectionDesc.previewText); sectionDesc.section.text,
sectionDesc.previewText,
);
hasOne = true; hasOne = true;
} }
return false; return false;
@ -316,7 +322,9 @@ const editorSvc = Object.assign(new Vue(), editorSvcDiscussions, editorSvcUtils,
const editorEndOffset = editorSvc.getEditorOffset(previewSelectionEndOffset); const editorEndOffset = editorSvc.getEditorOffset(previewSelectionEndOffset);
if (editorStartOffset != null && editorEndOffset != null) { if (editorStartOffset != null && editorEndOffset != null) {
editorSvc.clEditor.selectionMgr.setSelectionStartEnd( editorSvc.clEditor.selectionMgr.setSelectionStartEnd(
editorStartOffset, editorEndOffset); editorStartOffset,
editorEndOffset,
);
} }
} }
editorSvc.previewSelectionRange = range; editorSvc.previewSelectionRange = range;
@ -559,17 +567,21 @@ const editorSvc = Object.assign(new Vue(), editorSvcDiscussions, editorSvcUtils,
this.applyContent(); this.applyContent();
}, { }, {
immediate: true, immediate: true,
}); },
);
// Disable editor if hidden or if no content is loaded // Disable editor if hidden or if no content is loaded
store.watch( store.watch(
() => store.getters['content/isCurrentEditable'], () => store.getters['content/isCurrentEditable'],
editable => this.clEditor.toggleEditable(!!editable), { editable => this.clEditor.toggleEditable(!!editable), {
immediate: true, immediate: true,
}); },
);
store.watch(() => utils.serializeObject(store.getters['layout/styles']), store.watch(
() => this.measureSectionDimensions(false, true, true)); () => utils.serializeObject(store.getters['layout/styles']),
() => this.measureSectionDimensions(false, true, true),
);
this.initHighlighters(); this.initHighlighters();
this.$emit('inited'); this.$emit('inited');

View File

@ -65,8 +65,10 @@ function syncDiscussionMarkers(content, writeOffsets) {
}); });
if (writeOffsets && newDiscussion) { if (writeOffsets && newDiscussion) {
store.commit('discussion/patchNewDiscussion', store.commit(
discussions[store.state.discussion.newDiscussionId]); 'discussion/patchNewDiscussion',
discussions[store.state.discussion.newDiscussionId],
);
} }
} }
@ -115,7 +117,7 @@ function reversePatches(patches) {
export default { export default {
createClEditor(editorElt) { createClEditor(editorElt) {
this.clEditor = cledit(editorElt, editorElt.parentNode, true); this.clEditor = cledit(editorElt, editorElt.parentNode, true);
clEditor = this.clEditor; ({ clEditor } = this);
clEditor.on('contentChanged', (text) => { clEditor.on('contentChanged', (text) => {
const oldContent = store.getters['content/current']; const oldContent = store.getters['content/current'];
const newContent = { const newContent = {
@ -175,7 +177,7 @@ export default {
} }
}, },
getTrimmedSelection() { getTrimmedSelection() {
const selectionMgr = clEditor.selectionMgr; const { selectionMgr } = clEditor;
let start = Math.min(selectionMgr.selectionStart, selectionMgr.selectionEnd); let start = Math.min(selectionMgr.selectionStart, selectionMgr.selectionEnd);
let end = Math.max(selectionMgr.selectionStart, selectionMgr.selectionEnd); let end = Math.max(selectionMgr.selectionStart, selectionMgr.selectionEnd);
const text = clEditor.getContent(); const text = clEditor.getContent();
@ -217,7 +219,10 @@ export default {
editorClassAppliers = {}; editorClassAppliers = {};
Object.keys(discussions).forEach((discussionId) => { Object.keys(discussions).forEach((discussionId) => {
const classApplier = oldEditorClassAppliers[discussionId] || new EditorClassApplier( const classApplier = oldEditorClassAppliers[discussionId] || new EditorClassApplier(
classGetter('editor', discussionId), offsetGetter(discussionId), { discussionId }); classGetter('editor', discussionId),
offsetGetter(discussionId),
{ discussionId },
);
editorClassAppliers[discussionId] = classApplier; editorClassAppliers[discussionId] = classApplier;
}); });
// Clean unused class appliers // Clean unused class appliers
@ -232,7 +237,10 @@ export default {
previewClassAppliers = {}; previewClassAppliers = {};
Object.keys(discussions).forEach((discussionId) => { Object.keys(discussions).forEach((discussionId) => {
const classApplier = oldPreviewClassAppliers[discussionId] || new PreviewClassApplier( const classApplier = oldPreviewClassAppliers[discussionId] || new PreviewClassApplier(
classGetter('preview', discussionId), offsetGetter(discussionId), { discussionId }); classGetter('preview', discussionId),
offsetGetter(discussionId),
{ discussionId },
);
previewClassAppliers[discussionId] = classApplier; previewClassAppliers[discussionId] = classApplier;
}); });
// Clean unused class appliers // Clean unused class appliers

View File

@ -10,13 +10,11 @@ export default {
* Get an object describing the position of the scroll bar in the file. * Get an object describing the position of the scroll bar in the file.
*/ */
getScrollPosition(elt = store.getters['layout/styles'].showEditor getScrollPosition(elt = store.getters['layout/styles'].showEditor
? this.editorElt ? this.editorElt : this.previewElt) {
: this.previewElt,
) {
const dimensionKey = elt === this.editorElt const dimensionKey = elt === this.editorElt
? 'editorDimension' ? 'editorDimension'
: 'previewDimension'; : 'previewDimension';
const scrollTop = elt.parentNode.scrollTop; const { scrollTop } = elt.parentNode;
let result; let result;
if (this.previewCtxMeasured) { if (this.previewCtxMeasured) {
this.previewCtxMeasured.sectionDescList.some((sectionDesc, sectionIdx) => { this.previewCtxMeasured.sectionDescList.some((sectionDesc, sectionIdx) => {
@ -39,7 +37,7 @@ export default {
* Restore the scroll position from the current file content state. * Restore the scroll position from the current file content state.
*/ */
restoreScrollPosition() { restoreScrollPosition() {
const scrollPosition = store.getters['contentState/current'].scrollPosition; const { scrollPosition } = store.getters['contentState/current'];
if (scrollPosition && this.previewCtxMeasured) { if (scrollPosition && this.previewCtxMeasured) {
const sectionDesc = this.previewCtxMeasured.sectionDescList[scrollPosition.sectionIdx]; const sectionDesc = this.previewCtxMeasured.sectionDescList[scrollPosition.sectionIdx];
if (sectionDesc) { if (sectionDesc) {

View File

@ -94,7 +94,7 @@ export default {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const timeoutId = setTimeout(() => { const timeoutId = setTimeout(() => {
worker.terminate(); worker.terminate();
reject('Template generation timeout.'); reject(new Error('Template generation timeout.'));
}, 10000); }, 10000);
worker.addEventListener('message', (e) => { worker.addEventListener('message', (e) => {
clearTimeout(timeoutId); clearTimeout(timeoutId);
@ -102,7 +102,7 @@ export default {
// e.data can contain unsafe data if helpers attempts to call postMessage // e.data can contain unsafe data if helpers attempts to call postMessage
const [err, result] = e.data; const [err, result] = e.data;
if (err) { if (err) {
reject(`${err}`); reject(new Error(`${err}`));
} else { } else {
resolve(`${result}`); resolve(`${result}`);
} }

View File

@ -7,22 +7,29 @@ export default {
/** /**
* Create a file in the store with the specified fields. * Create a file in the store with the specified fields.
*/ */
createFile(fields = {}, background = false) { createFile({
name,
parentId,
text,
properties,
discussions,
comments,
} = {}, background = false) {
const id = utils.uid(); const id = utils.uid();
const file = { const file = {
id, id,
name: utils.sanitizeName(fields.name), name: utils.sanitizeName(name),
parentId: fields.parentId || null, parentId: parentId || null,
}; };
const content = { const content = {
id: `${id}/content`, id: `${id}/content`,
text: utils.sanitizeText(fields.text || store.getters['data/computedSettings'].newFileContent), text: utils.sanitizeText(text || store.getters['data/computedSettings'].newFileContent),
properties: utils.sanitizeText( properties: utils
fields.properties || store.getters['data/computedSettings'].newFileProperties), .sanitizeText(properties || store.getters['data/computedSettings'].newFileProperties),
discussions: fields.discussions || {}, discussions: discussions || {},
comments: fields.comments || {}, comments: comments || {},
}; };
const nameStripped = file.name !== utils.defaultName && file.name !== fields.name; const nameStripped = file.name !== utils.defaultName && file.name !== name;
// Check if there is a path conflict // Check if there is a path conflict
const workspaceUniquePaths = store.getters['workspace/hasUniquePaths']; const workspaceUniquePaths = store.getters['workspace/hasUniquePaths'];
@ -35,8 +42,8 @@ export default {
// Show warning dialogs and then save in the store // Show warning dialogs and then save in the store
return Promise.resolve() return Promise.resolve()
.then(() => !background && nameStripped && store.dispatch('modal/stripName', fields.name)) .then(() => !background && nameStripped && store.dispatch('modal/stripName', name))
.then(() => !background && pathConflict && store.dispatch('modal/pathConflict', fields.name)) .then(() => !background && pathConflict && store.dispatch('modal/pathConflict', name))
.then(() => { .then(() => {
store.commit('content/setItem', content); store.commit('content/setItem', content);
store.commit('file/setItem', file); store.commit('file/setItem', file);
@ -131,12 +138,12 @@ export default {
* Add a prefix to its name and return true otherwise. * Add a prefix to its name and return true otherwise.
*/ */
makePathUnique(id) { makePathUnique(id) {
const item = store.getters.allItemMap[id]; const { pathItems, allItemMap, itemPaths } = store.getters;
const item = allItemMap[id];
if (!item) { if (!item) {
return false; return false;
} }
let path = store.getters.itemPaths[id]; let path = itemPaths[id];
const pathItems = store.getters.pathItems;
if (pathItems[path].length === 1) { if (pathItems[path].length === 1) {
return false; return false;
} }

View File

@ -6,8 +6,8 @@ import fileSvc from './fileSvc';
const dbVersion = 1; const dbVersion = 1;
const dbStoreName = 'objects'; const dbStoreName = 'objects';
const exportWorkspace = utils.queryParams.exportWorkspace; const { exportWorkspace } = utils.queryParams;
const silent = utils.queryParams.silent; const { silent } = utils.queryParams;
const resetApp = utils.queryParams.reset; const resetApp = utils.queryParams.reset;
const deleteMarkerMaxAge = 1000; const deleteMarkerMaxAge = 1000;
const checkSponsorshipAfter = (5 * 60 * 1000) + (30 * 1000); // tokenExpirationMargin + 30 sec const checkSponsorshipAfter = (5 * 60 * 1000) + (30 * 1000); // tokenExpirationMargin + 30 sec
@ -37,7 +37,7 @@ class Connection {
request.onsuccess = (event) => { request.onsuccess = (event) => {
this.db = event.target.result; this.db = event.target.result;
this.db.onversionchange = () => location.reload(); this.db.onversionchange = () => window.location.reload();
this.getTxCbs.forEach(({ onTx, onError }) => this.createTx(onTx, onError)); this.getTxCbs.forEach(({ onTx, onError }) => this.createTx(onTx, onError));
this.getTxCbs = null; this.getTxCbs = null;
@ -51,16 +51,15 @@ class Connection {
// the fall-through behavior is what we want. // the fall-through behavior is what we want.
/* eslint-disable no-fallthrough */ /* eslint-disable no-fallthrough */
switch (oldVersion) { switch (oldVersion) {
case 0: case 0: {
{ // Create store
// Create store const dbStore = eventDb.createObjectStore(dbStoreName, {
const dbStore = eventDb.createObjectStore(dbStoreName, { keyPath: 'id',
keyPath: 'id', });
}); dbStore.createIndex('tx', 'tx', {
dbStore.createIndex('tx', 'tx', { unique: false,
unique: false, });
}); }
}
default: default:
} }
/* eslint-enable no-fallthrough */ /* eslint-enable no-fallthrough */
@ -158,7 +157,7 @@ const localDbSvc = {
* Read and apply all changes from the DB since previous transaction. * Read and apply all changes from the DB since previous transaction.
*/ */
readAll(tx, cb) { readAll(tx, cb) {
let lastTx = this.lastTx; let { lastTx } = this;
const dbStore = tx.objectStore(dbStoreName); const dbStore = tx.objectStore(dbStoreName);
const index = dbStore.index('tx'); const index = dbStore.index('tx');
const range = window.IDBKeyRange.lowerBound(this.lastTx, true); const range = window.IDBKeyRange.lowerBound(this.lastTx, true);
@ -171,7 +170,7 @@ const localDbSvc = {
lastTx = item.tx; lastTx = item.tx;
if (this.lastTx && item.tx - this.lastTx > deleteMarkerMaxAge) { if (this.lastTx && item.tx - this.lastTx > deleteMarkerMaxAge) {
// We may have missed some delete markers // We may have missed some delete markers
location.reload(); window.location.reload();
return; return;
} }
} }
@ -355,16 +354,14 @@ const localDbSvc = {
.then(() => { .then(() => {
// Reset the app if reset flag was passed // Reset the app if reset flag was passed
if (resetApp) { if (resetApp) {
return Promise.all( return Promise.all(Object.keys(store.getters['data/workspaces'])
Object.keys(store.getters['data/workspaces']) .map(workspaceId => localDbSvc.removeWorkspace(workspaceId)))
.map(workspaceId => localDbSvc.removeWorkspace(workspaceId)),
)
.then(() => utils.localStorageDataIds.forEach((id) => { .then(() => utils.localStorageDataIds.forEach((id) => {
// Clean data stored in localStorage // Clean data stored in localStorage
localStorage.removeItem(`data/${id}`); localStorage.removeItem(`data/${id}`);
})) }))
.then(() => { .then(() => {
location.reload(); window.location.reload();
throw new Error('reload'); throw new Error('reload');
}); });
} }
@ -388,7 +385,7 @@ const localDbSvc = {
// Save welcome file content hash if not done already // Save welcome file content hash if not done already
const hash = utils.hash(welcomeFile); const hash = utils.hash(welcomeFile);
const welcomeFileHashes = store.getters['data/localSettings'].welcomeFileHashes; const { welcomeFileHashes } = store.getters['data/localSettings'];
if (!welcomeFileHashes[hash]) { if (!welcomeFileHashes[hash]) {
store.dispatch('data/patchLocalSettings', { store.dispatch('data/patchLocalSettings', {
welcomeFileHashes: { welcomeFileHashes: {
@ -410,7 +407,7 @@ const localDbSvc = {
// Enable sponsorship // Enable sponsorship
if (utils.queryParams.paymentSuccess) { if (utils.queryParams.paymentSuccess) {
location.hash = ''; // PaymentSuccess param is always on its own window.location.hash = ''; // PaymentSuccess param is always on its own
store.dispatch('modal/paymentSuccess') store.dispatch('modal/paymentSuccess')
.catch(() => { /* Cancel */ }); .catch(() => { /* Cancel */ });
const sponsorToken = store.getters['workspace/sponsorToken']; const sponsorToken = store.getters['workspace/sponsorToken'];
@ -463,8 +460,10 @@ const localDbSvc = {
// Cancel new discussion // Cancel new discussion
store.commit('discussion/setCurrentDiscussionId'); store.commit('discussion/setCurrentDiscussionId');
// Open the gutter if file contains discussions // Open the gutter if file contains discussions
store.commit('discussion/setCurrentDiscussionId', store.commit(
store.getters['discussion/nextDiscussionId']); 'discussion/setCurrentDiscussionId',
store.getters['discussion/nextDiscussionId'],
);
}, },
(err) => { (err) => {
// Failure (content is not available), go back to previous file // Failure (content is not available), go back to previous file
@ -480,7 +479,8 @@ const localDbSvc = {
} }
}, { }, {
immediate: true, immediate: true,
}); },
);
}); });
}, },
}; };

View File

@ -224,7 +224,7 @@ export default {
parsingCtx.markdownCoreRules.slice(2).forEach(rule => rule(parsingCtx.markdownState)); parsingCtx.markdownCoreRules.slice(2).forEach(rule => rule(parsingCtx.markdownState));
parsingCtx.markdownState.isConverted = true; parsingCtx.markdownState.isConverted = true;
} }
const tokens = parsingCtx.markdownState.tokens; const { tokens } = parsingCtx.markdownState;
const html = parsingCtx.converter.renderer.render( const html = parsingCtx.converter.renderer.render(
tokens, tokens,
parsingCtx.converter.options, parsingCtx.converter.options,
@ -240,7 +240,10 @@ export default {
let htmlSectionDiff; let htmlSectionDiff;
if (previousConversionCtx) { if (previousConversionCtx) {
const oldSectionHash = hashArray( const oldSectionHash = hashArray(
previousConversionCtx.htmlSectionList, valueHash, valueArray); previousConversionCtx.htmlSectionList,
valueHash,
valueArray,
);
htmlSectionDiff = diffMatchPatch.diff_main(oldSectionHash, newSectionHash, false); htmlSectionDiff = diffMatchPatch.diff_main(oldSectionHash, newSectionHash, false);
} else { } else {
htmlSectionDiff = [ htmlSectionDiff = [
@ -264,8 +267,7 @@ export default {
*/ */
highlight(markdown, converter = this.defaultConverter, grammars = this.defaultPrismGrammars) { highlight(markdown, converter = this.defaultConverter, grammars = this.defaultPrismGrammars) {
const parsingCtx = this.parseSections(converter, markdown); const parsingCtx = this.parseSections(converter, markdown);
return parsingCtx.sections.map( return parsingCtx.sections
section => Prism.highlight(section.text, grammars[section.data]), .map(section => Prism.highlight(section.text, grammars[section.data])).join('');
).join('');
}, },
}; };

View File

@ -121,7 +121,7 @@ export default {
// Open a tab otherwise // Open a tab otherwise
wnd = window.open(authorizeUrl); wnd = window.open(authorizeUrl);
if (!wnd) { if (!wnd) {
return Promise.reject('The authorize window was blocked.'); return Promise.reject(new Error('The authorize window was blocked.'));
} }
} }
@ -145,21 +145,23 @@ export default {
if (silent) { if (silent) {
iframeElt.onerror = () => clean() iframeElt.onerror = () => clean()
.then(() => reject('Unknown error.')); .then(() => reject(new Error('Unknown error.')));
closeTimeout = setTimeout( closeTimeout = setTimeout(
() => clean() () => clean()
.then(() => { .then(() => {
isConnectionDown = true; isConnectionDown = true;
store.commit('setOffline', true); store.commit('setOffline', true);
store.commit('updateLastOfflineCheck'); store.commit('updateLastOfflineCheck');
reject('You are offline.'); reject(new Error('You are offline.'));
}), }),
networkTimeout); networkTimeout,
);
} else { } else {
closeTimeout = setTimeout( closeTimeout = setTimeout(
() => clean() () => clean()
.then(() => reject('Timeout.')), .then(() => reject(new Error('Timeout.'))),
oauth2AuthorizationTimeout); oauth2AuthorizationTimeout,
);
} }
msgHandler = event => event.source === wnd && event.origin === utils.origin && clean() msgHandler = event => event.source === wnd && event.origin === utils.origin && clean()
@ -167,7 +169,7 @@ export default {
const data = utils.parseQueryParams(`${event.data}`.slice(1)); const data = utils.parseQueryParams(`${event.data}`.slice(1));
if (data.error || data.state !== state) { if (data.error || data.state !== state) {
console.error(data); // eslint-disable-line no-console console.error(data); // eslint-disable-line no-console
reject('Could not get required authorization.'); reject(new Error('Could not get required authorization.'));
} else { } else {
resolve({ resolve({
accessToken: data.access_token, accessToken: data.access_token,
@ -181,7 +183,7 @@ export default {
window.addEventListener('message', msgHandler); window.addEventListener('message', msgHandler);
if (!silent) { if (!silent) {
checkClosedInterval = setInterval(() => wnd.closed && clean() checkClosedInterval = setInterval(() => wnd.closed && clean()
.then(() => reject('Authorize window was closed.')), 250); .then(() => reject(new Error('Authorize window was closed.'))), 250);
} }
}); });
}, },
@ -253,9 +255,9 @@ export default {
if (offlineCheck) { if (offlineCheck) {
isConnectionDown = true; isConnectionDown = true;
store.commit('setOffline', true); store.commit('setOffline', true);
reject('You are offline.'); reject(new Error('You are offline.'));
} else { } else {
reject('Network request failed.'); reject(new Error('Network request failed.'));
} }
}; };
@ -264,9 +266,9 @@ export default {
if (offlineCheck) { if (offlineCheck) {
isConnectionDown = true; isConnectionDown = true;
store.commit('setOffline', true); store.commit('setOffline', true);
reject('You are offline.'); reject(new Error('You are offline.'));
} else { } else {
reject('Network request timeout.'); reject(new Error('Network request timeout.'));
} }
}, config.timeout); }, config.timeout);
@ -282,12 +284,11 @@ export default {
.catch((err) => { .catch((err) => {
// Try again later in case of retriable error // Try again later in case of retriable error
if (isRetriable(err) && retryAfter < maxRetryAfter) { if (isRetriable(err) && retryAfter < maxRetryAfter) {
return new Promise( return new Promise((resolve) => {
(resolve) => { setTimeout(resolve, retryAfter);
setTimeout(resolve, retryAfter); // Exponential backoff
// Exponential backoff retryAfter *= 2;
retryAfter *= 2; })
})
.then(attempt); .then(attempt);
} }
throw err; throw err;

View File

@ -2,7 +2,7 @@ import cledit from '../cledit';
import editorSvc from '../editorSvc'; import editorSvc from '../editorSvc';
import store from '../../store'; import store from '../../store';
const Keystroke = cledit.Keystroke; const { Keystroke } = cledit;
const indentRegexp = /^ {0,3}>[ ]*|^[ \t]*[*+-][ \t](?:\[[ xX]\][ \t])?|^([ \t]*)\d+\.[ \t](?:\[[ xX]\][ \t])?|^\s+/; const indentRegexp = /^ {0,3}>[ ]*|^[ \t]*[*+-][ \t](?:\[[ xX]\][ \t])?|^([ \t]*)\d+\.[ \t](?:\[[ xX]\][ \t])?|^\s+/;
let clearNewline; let clearNewline;
let lastSelection; let lastSelection;
@ -32,7 +32,9 @@ function fixNumberedList(state, indent) {
lines.some((line) => { lines.some((line) => {
const match = line.replace( const match = line.replace(
/^[ \t]*/, wholeMatch => wholeMatch.replace(/\t/g, ' ')).match(indentRegex); /^[ \t]*/,
wholeMatch => wholeMatch.replace(/\t/g, ' '),
).match(indentRegex);
if (!match || line.match(/^#+ /)) { // Line not empty, not indented, or title if (!match || line.match(/^#+ /)) { // Line not empty, not indented, or title
flush(); flush();
return true; return true;

View File

@ -162,17 +162,19 @@ store.watch(
isScrollEditor = showEditor; isScrollEditor = showEditor;
isScrollPreview = !showEditor; isScrollPreview = !showEditor;
skipAnimation = true; skipAnimation = true;
}); },
);
store.watch( store.watch(
() => store.getters['file/current'].id, () => store.getters['file/current'].id,
() => { () => {
skipAnimation = true; skipAnimation = true;
}); },
);
editorSvc.$on('previewCtxMeasured', (previewCtxMeasured) => { editorSvc.$on('previewCtxMeasured', (previewCtxMeasured) => {
if (previewCtxMeasured) { if (previewCtxMeasured) {
sectionDescList = previewCtxMeasured.sectionDescList; ({ sectionDescList } = previewCtxMeasured);
forceScrollSync(); forceScrollSync();
} }
}); });

View File

@ -45,7 +45,7 @@ const methods = {
const replacement = `${param2 || ''}`; const replacement = `${param2 || ''}`;
if (text && replacement) { if (text && replacement) {
setTimeout(() => { setTimeout(() => {
const selectionMgr = editorSvc.clEditor.selectionMgr; const { selectionMgr } = editorSvc.clEditor;
let offset = selectionMgr.selectionStart; let offset = selectionMgr.selectionStart;
if (offset === selectionMgr.selectionEnd) { if (offset === selectionMgr.selectionEnd) {
const range = selectionMgr.createRange(offset - text.length, offset); const range = selectionMgr.createRange(offset - text.length, offset);
@ -85,4 +85,5 @@ store.watch(
}); });
}, { }, {
immediate: true, immediate: true,
}); },
);

View File

@ -7,10 +7,10 @@ editorSvc.$on('inited', () => {
if (!elt || elt === editorSvc.previewElt) { if (!elt || elt === editorSvc.previewElt) {
return offset; return offset;
} }
let previousSibling = elt.previousSibling; let { previousSibling } = elt;
while (previousSibling) { while (previousSibling) {
offset += previousSibling.textContent.length; offset += previousSibling.textContent.length;
previousSibling = previousSibling.previousSibling; ({ previousSibling } = previousSibling);
} }
return offset + getPreviewOffset(elt.parentNode); return offset + getPreviewOffset(elt.parentNode);
}; };

View File

@ -53,11 +53,11 @@ export default new Provider({
.then((workspace) => { .then((workspace) => {
// Fix the URL hash // Fix the URL hash
utils.setQueryParams(workspaceParams); utils.setQueryParams(workspaceParams);
if (workspace.url !== location.href) { if (workspace.url !== window.location.href) {
store.dispatch('data/patchWorkspaces', { store.dispatch('data/patchWorkspaces', {
[workspace.id]: { [workspace.id]: {
...workspace, ...workspace,
url: location.href, url: window.location.href,
}, },
}); });
} }

View File

@ -20,7 +20,11 @@ export default new Provider({
}, },
downloadContent(token, syncLocation) { downloadContent(token, syncLocation) {
return githubHelper.downloadFile( return githubHelper.downloadFile(
token, syncLocation.owner, syncLocation.repo, syncLocation.branch, syncLocation.path, token,
syncLocation.owner,
syncLocation.repo,
syncLocation.branch,
syncLocation.path,
) )
.then(({ sha, content }) => { .then(({ sha, content }) => {
savedSha[syncLocation.id] = sha; savedSha[syncLocation.id] = sha;

View File

@ -40,7 +40,7 @@ export default new Provider({
}, },
initWorkspace() { initWorkspace() {
const [owner, repo] = (utils.queryParams.repo || '').split('/'); const [owner, repo] = (utils.queryParams.repo || '').split('/');
const branch = utils.queryParams.branch; const { branch } = utils.queryParams;
const workspaceParams = { const workspaceParams = {
providerId: this.id, providerId: this.id,
repo: `${owner}/${repo}`, repo: `${owner}/${repo}`,
@ -84,11 +84,11 @@ export default new Provider({
} }
// Fix the URL hash // Fix the URL hash
utils.setQueryParams(workspaceParams); utils.setQueryParams(workspaceParams);
if (workspace.url !== location.href) { if (workspace.url !== window.location.href) {
store.dispatch('data/patchWorkspaces', { store.dispatch('data/patchWorkspaces', {
[workspaceId]: { [workspaceId]: {
...workspace, ...workspace,
url: location.href, url: window.location.href,
}, },
}); });
} }
@ -494,8 +494,8 @@ export default new Provider({
getRevisionContent(token, fileId, revisionId) { getRevisionContent(token, fileId, revisionId) {
const { owner, repo } = getWorkspaceWithOwner(); const { owner, repo } = getWorkspaceWithOwner();
return getSyncData(fileId) return getSyncData(fileId)
.then(syncData => githubHelper.downloadFile( .then(syncData => githubHelper
token, owner, repo, revisionId, getAbsolutePath(syncData))) .downloadFile(token, owner, repo, revisionId, getAbsolutePath(syncData)))
.then(({ content }) => Provider.parseContent(content, `${fileId}/content`)); .then(({ content }) => Provider.parseContent(content, `${fileId}/content`));
}, },
}); });

View File

@ -101,8 +101,10 @@ export default new Provider({
return this.makeLocation(token, null, googleHelper.driveActionFolder.id); return this.makeLocation(token, null, googleHelper.driveActionFolder.id);
}); });
case 'open': case 'open':
return store.dispatch('queue/enqueue', return store.dispatch(
() => this.openFiles(token, googleHelper.driveActionFiles)); 'queue/enqueue',
() => this.openFiles(token, googleHelper.driveActionFiles),
);
default: default:
return null; return null;
} }
@ -171,7 +173,7 @@ export default new Provider({
}; };
return this.downloadContent(token, syncLocation) return this.downloadContent(token, syncLocation)
.then(content => fileSvc.createFile({ .then(content => fileSvc.createFile({
name, name: driveFile.name,
parentId: store.getters['file/current'].parentId, parentId: store.getters['file/current'].parentId,
text: content.text, text: content.text,
properties: content.properties, properties: content.properties,

View File

@ -25,8 +25,8 @@ export default new Provider({
folderId, folderId,
}); });
const makeWorkspaceId = folderId => folderId && utils.makeWorkspaceId( const makeWorkspaceId = folderId => folderId
makeWorkspaceParams(folderId)); && utils.makeWorkspaceId(makeWorkspaceParams(folderId));
const getWorkspace = folderId => const getWorkspace = folderId =>
store.getters['data/sanitizedWorkspaces'][makeWorkspaceId(folderId)]; store.getters['data/sanitizedWorkspaces'][makeWorkspaceId(folderId)];
@ -100,7 +100,7 @@ export default new Provider({
sub: token.sub, sub: token.sub,
name: folder.name, name: folder.name,
providerId: this.id, providerId: this.id,
url: location.href, url: window.location.href,
folderId: folder.id, folderId: folder.id,
teamDriveId: folder.teamDriveId, teamDriveId: folder.teamDriveId,
dataFolderId: properties.dataFolderId, dataFolderId: properties.dataFolderId,
@ -141,7 +141,7 @@ export default new Provider({
...folder, ...folder,
appProperties: {}, appProperties: {},
}) })
.then(() => folder.id))) .then(() => folder.id)))
// If workspace does not exist, initialize one // If workspace does not exist, initialize one
.then(folderId => getWorkspace(folderId) || googleHelper.getFile(token, folderId) .then(folderId => getWorkspace(folderId) || googleHelper.getFile(token, folderId)
.then((folder) => { .then((folder) => {
@ -157,11 +157,11 @@ export default new Provider({
.then((workspace) => { .then((workspace) => {
// Fix the URL hash // Fix the URL hash
utils.setQueryParams(makeWorkspaceParams(workspace.folderId)); utils.setQueryParams(makeWorkspaceParams(workspace.folderId));
if (workspace.url !== location.href) { if (workspace.url !== window.location.href) {
store.dispatch('data/patchWorkspaces', { store.dispatch('data/patchWorkspaces', {
[workspace.id]: { [workspace.id]: {
...workspace, ...workspace,
url: location.href, url: window.location.href,
}, },
}); });
} }
@ -233,7 +233,7 @@ export default new Provider({
parentIds[syncData.id] = id; parentIds[syncData.id] = id;
}); });
result.changes.forEach((change) => { result.changes.forEach((change) => {
const id = ((change.file || {}).appProperties || {}).id; const { id } = (change.file || {}).appProperties || {};
if (id) { if (id) {
parentIds[change.fileId] = id; parentIds[change.fileId] = id;
} }
@ -253,7 +253,7 @@ export default new Provider({
let contentChange; let contentChange;
if (change.file) { if (change.file) {
// Ignore changes in files that are not in the workspace // Ignore changes in files that are not in the workspace
const appProperties = change.file.appProperties; const { appProperties } = change.file;
if (!appProperties || appProperties.folderId !== workspace.folderId if (!appProperties || appProperties.folderId !== workspace.folderId
) { ) {
return; return;

View File

@ -24,10 +24,13 @@ const request = (token, options, args) => networkSvc.request({
export default { export default {
startOauth2(fullAccess, sub = null, silent = false) { startOauth2(fullAccess, sub = null, silent = false) {
return networkSvc.startOauth2( return networkSvc.startOauth2(
'https://www.dropbox.com/oauth2/authorize', { 'https://www.dropbox.com/oauth2/authorize',
{
client_id: getAppKey(fullAccess), client_id: getAppKey(fullAccess),
response_type: 'token', response_type: 'token',
}, silent) },
silent,
)
// Call the user info endpoint // Call the user info endpoint
.then(({ accessToken }) => request({ accessToken }, { .then(({ accessToken }) => request({ accessToken }, {
method: 'POST', method: 'POST',
@ -56,7 +59,7 @@ export default {
} }
return networkSvc.loadScript('https://www.dropbox.com/static/api/2/dropins.js') return networkSvc.loadScript('https://www.dropbox.com/static/api/2/dropins.js')
.then(() => { .then(() => {
Dropbox = window.Dropbox; ({ Dropbox } = window);
}); });
}, },
addAccount(fullAccess = false) { addAccount(fullAccess = false) {

View File

@ -30,10 +30,13 @@ const getCommitMessage = (name, path) => {
export default { export default {
startOauth2(scopes, sub = null, silent = false) { startOauth2(scopes, sub = null, silent = false) {
return networkSvc.startOauth2( return networkSvc.startOauth2(
'https://github.com/login/oauth/authorize', { 'https://github.com/login/oauth/authorize',
{
client_id: clientId, client_id: clientId,
scope: scopes.join(' '), scope: scopes.join(' '),
}, silent) },
silent,
)
// Exchange code with token // Exchange code with token
.then(data => networkSvc.request({ .then(data => networkSvc.request({
method: 'GET', method: 'GET',

View File

@ -13,7 +13,7 @@ const driveAppDataScopes = ['https://www.googleapis.com/auth/drive.appdata'];
const getDriveScopes = token => [token.driveFullAccess const getDriveScopes = token => [token.driveFullAccess
? 'https://www.googleapis.com/auth/drive' ? 'https://www.googleapis.com/auth/drive'
: 'https://www.googleapis.com/auth/drive.file', : 'https://www.googleapis.com/auth/drive.file',
'https://www.googleapis.com/auth/drive.install']; 'https://www.googleapis.com/auth/drive.install'];
const bloggerScopes = ['https://www.googleapis.com/auth/blogger']; const bloggerScopes = ['https://www.googleapis.com/auth/blogger'];
const photosScopes = ['https://www.googleapis.com/auth/photos']; const photosScopes = ['https://www.googleapis.com/auth/photos'];
@ -52,7 +52,7 @@ export default {
}, },
}, true) }, true)
.catch((err) => { .catch((err) => {
const reason = ((((err.body || {}).error || {}).errors || [])[0] || {}).reason; const { reason } = (((err.body || {}).error || {}).errors || [])[0] || {};
if (reason === 'authError') { if (reason === 'authError') {
// Mark the token as revoked and get a new one // Mark the token as revoked and get a new one
store.dispatch('data/setGoogleToken', { store.dispatch('data/setGoogleToken', {
@ -116,7 +116,8 @@ export default {
multipartRequestBody += closeDelimiter; multipartRequestBody += closeDelimiter;
options.url = options.url.replace( options.url = options.url.replace(
'https://www.googleapis.com/', 'https://www.googleapis.com/',
'https://www.googleapis.com/upload/'); 'https://www.googleapis.com/upload/',
);
return this.request(refreshedToken, { return this.request(refreshedToken, {
...options, ...options,
params: { params: {
@ -212,7 +213,8 @@ export default {
}, },
startOauth2(scopes, sub = null, silent = false) { startOauth2(scopes, sub = null, silent = false) {
return networkSvc.startOauth2( return networkSvc.startOauth2(
'https://accounts.google.com/o/oauth2/v2/auth', { 'https://accounts.google.com/o/oauth2/v2/auth',
{
client_id: clientId, client_id: clientId,
response_type: 'token id_token', response_type: 'token id_token',
scope: ['openid', ...scopes].join(' '), scope: ['openid', ...scopes].join(' '),
@ -220,7 +222,9 @@ export default {
login_hint: sub, login_hint: sub,
prompt: silent ? 'none' : null, prompt: silent ? 'none' : null,
nonce: utils.uid(), nonce: utils.uid(),
}, silent) },
silent,
)
// Call the token info endpoint // Call the token info endpoint
.then(data => networkSvc.request({ .then(data => networkSvc.request({
method: 'POST', method: 'POST',
@ -300,7 +304,7 @@ export default {
})); }));
}, },
refreshToken(token, scopes = []) { refreshToken(token, scopes = []) {
const sub = token.sub; const { sub } = token;
const lastToken = store.getters['data/googleTokens'][sub]; const lastToken = store.getters['data/googleTokens'][sub];
const mergedScopes = [...new Set([ const mergedScopes = [...new Set([
...scopes, ...scopes,
@ -339,16 +343,16 @@ export default {
return Promise.resolve(); return Promise.resolve();
} }
return networkSvc.loadScript('https://apis.google.com/js/api.js') return networkSvc.loadScript('https://apis.google.com/js/api.js')
.then(() => Promise.all(libraries.map( .then(() => Promise.all(libraries
library => new Promise((resolve, reject) => window.gapi.load(library, { .map(library => new Promise((resolve, reject) => window.gapi.load(library, {
callback: resolve, callback: resolve,
onerror: reject, onerror: reject,
timeout: 30000, timeout: 30000,
ontimeout: reject, ontimeout: reject,
}))))) })))))
.then(() => { .then(() => {
gapi = window.gapi; ({ gapi } = window);
google = window.google; ({ google } = window);
}); });
}, },
getSponsorship(token) { getSponsorship(token) {
@ -455,8 +459,8 @@ export default {
fields: 'id,name,mimeType,appProperties,teamDriveId', fields: 'id,name,mimeType,appProperties,teamDriveId',
supportsTeamDrives: true, supportsTeamDrives: true,
}, },
}) }))
.then(res => res.body)); .then(res => res.body);
}, },
downloadFile(token, id) { downloadFile(token, id) {
return this.refreshToken(token, getDriveScopes(token)) return this.refreshToken(token, getDriveScopes(token))
@ -484,16 +488,25 @@ export default {
}, },
downloadFileRevision(token, fileId, revisionId) { downloadFileRevision(token, fileId, revisionId) {
return this.refreshToken(token, getDriveScopes(token)) return this.refreshToken(token, getDriveScopes(token))
.then(refreshedToken => this.downloadFileRevisionInternal( .then(refreshedToken => this
refreshedToken, fileId, revisionId)); .downloadFileRevisionInternal(refreshedToken, fileId, revisionId));
}, },
downloadAppDataFileRevision(token, fileId, revisionId) { downloadAppDataFileRevision(token, fileId, revisionId) {
return this.refreshToken(token, driveAppDataScopes) return this.refreshToken(token, driveAppDataScopes)
.then(refreshedToken => this.downloadFileRevisionInternal( .then(refreshedToken => this
refreshedToken, fileId, revisionId)); .downloadFileRevisionInternal(refreshedToken, fileId, revisionId));
}, },
uploadBlogger( uploadBlogger(
token, blogUrl, blogId, postId, title, content, labels, isDraft, published, isPage, token,
blogUrl,
blogId,
postId,
title,
content,
labels,
isDraft,
published,
isPage,
) { ) {
return this.refreshToken(token, bloggerScopes) return this.refreshToken(token, bloggerScopes)
.then(refreshedToken => Promise.resolve() .then(refreshedToken => Promise.resolve()

View File

@ -15,11 +15,14 @@ const request = (token, options) => networkSvc.request({
export default { export default {
startOauth2(sub = null, silent = false) { startOauth2(sub = null, silent = false) {
return networkSvc.startOauth2( return networkSvc.startOauth2(
'https://public-api.wordpress.com/oauth2/authorize', { 'https://public-api.wordpress.com/oauth2/authorize',
{
client_id: clientId, client_id: clientId,
response_type: 'token', response_type: 'token',
scope: 'global', scope: 'global',
}, silent) },
silent,
)
// Call the user info endpoint // Call the user info endpoint
.then(data => request({ accessToken: data.accessToken }, { .then(data => request({ accessToken: data.accessToken }, {
url: 'https://public-api.wordpress.com/rest/v1.1/me', url: 'https://public-api.wordpress.com/rest/v1.1/me',
@ -42,7 +45,7 @@ export default {
})); }));
}, },
refreshToken(token) { refreshToken(token) {
const sub = token.sub; const { sub } = token;
const lastToken = store.getters['data/wordpressTokens'][sub]; const lastToken = store.getters['data/wordpressTokens'][sub];
return Promise.resolve() return Promise.resolve()

View File

@ -12,11 +12,14 @@ const request = (token, options) => networkSvc.request({
export default { export default {
startOauth2(subdomain, clientId, sub = null, silent = false) { startOauth2(subdomain, clientId, sub = null, silent = false) {
return networkSvc.startOauth2( return networkSvc.startOauth2(
`https://${subdomain}.zendesk.com/oauth/authorizations/new`, { `https://${subdomain}.zendesk.com/oauth/authorizations/new`,
{
client_id: clientId, client_id: clientId,
response_type: 'token', response_type: 'token',
scope: 'read hc:write', scope: 'read hc:write',
}, silent) },
silent,
)
// Call the user info endpoint // Call the user info endpoint
.then(({ accessToken }) => request({ accessToken }, { .then(({ accessToken }) => request({ accessToken }, {
url: `https://${subdomain}.zendesk.com/api/v2/users/me.json`, url: `https://${subdomain}.zendesk.com/api/v2/users/me.json`,

View File

@ -39,7 +39,7 @@ const ensureDate = (value, defaultValue) => {
}; };
function publish(publishLocation) { function publish(publishLocation) {
const fileId = publishLocation.fileId; const { fileId } = publishLocation;
const template = store.getters['data/allTemplates'][publishLocation.templateId]; const template = store.getters['data/allTemplates'][publishLocation.templateId];
return exportSvc.applyTemplate(fileId, template) return exportSvc.applyTemplate(fileId, template)
.then(html => localDbSvc.loadItem(`${fileId}/content`) .then(html => localDbSvc.loadItem(`${fileId}/content`)
@ -107,7 +107,8 @@ function publishFile(fileId) {
err => localDbSvc.unloadContents() err => localDbSvc.unloadContents()
.then(() => { .then(() => {
throw err; throw err;
})); }),
);
} }
function requestPublish() { function requestPublish() {
@ -124,7 +125,7 @@ function requestPublish() {
clearInterval(intervalId); clearInterval(intervalId);
if (!hasCurrentFilePublishLocations()) { if (!hasCurrentFilePublishLocations()) {
// Cancel sync // Cancel sync
reject('Publish not possible.'); reject(new Error('Publish not possible.'));
return; return;
} }
publishFile(store.getters['file/current'].id) publishFile(store.getters['file/current'].id)
@ -140,12 +141,14 @@ function createPublishLocation(publishLocation) {
publishLocation.id = utils.uid(); publishLocation.id = utils.uid();
const currentFile = store.getters['file/current']; const currentFile = store.getters['file/current'];
publishLocation.fileId = currentFile.id; publishLocation.fileId = currentFile.id;
store.dispatch('queue/enqueue', store.dispatch(
'queue/enqueue',
() => publish(publishLocation) () => publish(publishLocation)
.then((publishLocationToStore) => { .then((publishLocationToStore) => {
store.commit('publishLocation/setItem', publishLocationToStore); store.commit('publishLocation/setItem', publishLocationToStore);
store.dispatch('notification/info', `A new publication location was added to "${currentFile.name}".`); store.dispatch('notification/info', `A new publication location was added to "${currentFile.name}".`);
})); }),
);
} }
export default { export default {

Some files were not shown because too many files have changed in this diff Show More