\
- visited \
-
\
- \
- \
-
From 5bc642d02e8955b200bb21cf30e863fdf0c53765 Mon Sep 17 00:00:00 2001 From: BoHong Li Date: Thu, 9 Mar 2017 02:41:05 +0800 Subject: Use JavaScript Standard Style (part 2) Fixed all fail on frontend code. --- public/js/cover.js | 739 ++-- public/js/extra.js | 1944 ++++++----- public/js/google-drive-picker.js | 227 +- public/js/google-drive-upload.js | 225 +- public/js/history.js | 500 ++- public/js/htmlExport.js | 12 +- public/js/index.js | 7123 +++++++++++++++++++------------------- public/js/lib/common/login.js | 133 +- public/js/lib/config/index.js | 28 +- public/js/locale.js | 42 +- public/js/pretty.js | 211 +- public/js/render.js | 76 +- public/js/reveal-markdown.js | 741 ++-- public/js/slide.js | 195 +- public/js/syncscroll.js | 604 ++-- public/vendor/md-toc.js | 214 +- 16 files changed, 6386 insertions(+), 6628 deletions(-) (limited to 'public') diff --git a/public/js/cover.js b/public/js/cover.js index bc6e73f9..a45a1c13 100644 --- a/public/js/cover.js +++ b/public/js/cover.js @@ -1,7 +1,10 @@ -require('./locale'); +/* eslint-env browser, jquery */ +/* global moment, serverurl */ -require('../css/cover.css'); -require('../css/site.css'); +require('./locale') + +require('../css/cover.css') +require('../css/site.css') import { checkIfAuth, @@ -9,7 +12,7 @@ import { getLoginState, resetCheckAuth, setloginStateChangeEvent -} from './lib/common/login'; +} from './lib/common/login' import { clearDuplicatedHistory, @@ -23,411 +26,403 @@ import { removeHistory, saveHistory, saveStorageHistoryToServer -} from './history'; +} from './history' -import { saveAs } from 'file-saver'; -import List from 'list.js'; -import S from 'string'; +import { saveAs } from 'file-saver' +import List from 'list.js' +import S from 'string' const options = { - valueNames: ['id', 'text', 'timestamp', 'fromNow', 'time', 'tags', 'pinned'], - item: '
\
- visited \
-
\
- \
- \
-
' +
+ ' visited ' +
+ '
' +
+ '' +
+ '' +
+ '
${highlighted}
\n`;
-};
+ const token = tokens[idx]
+ const info = token.info ? md.utils.unescapeAll(token.info).trim() : ''
+ let langName = ''
+ let highlighted
+
+ if (info) {
+ langName = info.split(/\s+/g)[0]
+ if (/!$/.test(info)) token.attrJoin('class', 'wrap')
+ token.attrJoin('class', options.langPrefix + langName.replace(/=$|=\d+$|=\+$|!$|=!$/, ''))
+ token.attrJoin('class', 'hljs')
+ token.attrJoin('class', 'raw')
+ }
+
+ if (options.highlight) {
+ highlighted = options.highlight(token.content, langName) || md.utils.escapeHtml(token.content)
+ } else {
+ highlighted = md.utils.escapeHtml(token.content)
+ }
+
+ if (highlighted.indexOf('${highlighted}
\n`
+}
/* Defined regex markdown it plugins */
-import Plugin from 'markdown-it-regexp';
+import Plugin from 'markdown-it-regexp'
-//youtube
+// youtube
const youtubePlugin = new Plugin(
// regexp to match
/{%youtube\s*([\d\D]*?)\s*%}/,
(match, utils) => {
- const videoid = match[1];
- if (!videoid) return;
- const div = $('');
- div.attr('data-videoid', videoid);
- const thumbnail_src = `//img.youtube.com/vi/${videoid}/hqdefault.jpg`;
- const image = ``;
- div.append(image);
- const icon = '';
- div.append(icon);
- return div[0].outerHTML;
+ const videoid = match[1]
+ if (!videoid) return
+ const div = $('')
+ div.attr('data-videoid', videoid)
+ const thumbnailSrc = `//img.youtube.com/vi/${videoid}/hqdefault.jpg`
+ const image = ``
+ div.append(image)
+ const icon = ''
+ div.append(icon)
+ return div[0].outerHTML
}
-);
-//vimeo
+)
+// vimeo
const vimeoPlugin = new Plugin(
// regexp to match
/{%vimeo\s*([\d\D]*?)\s*%}/,
(match, utils) => {
- const videoid = match[1];
- if (!videoid) return;
- const div = $('');
- div.attr('data-videoid', videoid);
- const icon = '';
- div.append(icon);
- return div[0].outerHTML;
+ const videoid = match[1]
+ if (!videoid) return
+ const div = $('')
+ div.attr('data-videoid', videoid)
+ const icon = ''
+ div.append(icon)
+ return div[0].outerHTML
}
-);
-//gist
+)
+// gist
const gistPlugin = new Plugin(
// regexp to match
/{%gist\s*([\d\D]*?)\s*%}/,
(match, utils) => {
- const gistid = match[1];
- const code = `
`;
- return code;
+ const gistid = match[1]
+ const code = `
`
+ return code
}
-);
-//TOC
+)
+// TOC
const tocPlugin = new Plugin(
// regexp to match
/^\[TOC\]$/i,
(match, utils) => ''
-);
-//slideshare
+)
+// slideshare
const slidesharePlugin = new Plugin(
// regexp to match
/{%slideshare\s*([\d\D]*?)\s*%}/,
(match, utils) => {
- const slideshareid = match[1];
- const div = $('');
- div.attr('data-slideshareid', slideshareid);
- return div[0].outerHTML;
+ const slideshareid = match[1]
+ const div = $('')
+ div.attr('data-slideshareid', slideshareid)
+ return div[0].outerHTML
}
-);
-//speakerdeck
+)
+// speakerdeck
const speakerdeckPlugin = new Plugin(
// regexp to match
/{%speakerdeck\s*([\d\D]*?)\s*%}/,
(match, utils) => {
- const speakerdeckid = match[1];
- const div = $('');
- div.attr('data-speakerdeckid', speakerdeckid);
- return div[0].outerHTML;
+ const speakerdeckid = match[1]
+ const div = $('')
+ div.attr('data-speakerdeckid', speakerdeckid)
+ return div[0].outerHTML
}
-);
-//pdf
+)
+// pdf
const pdfPlugin = new Plugin(
// regexp to match
/{%pdf\s*([\d\D]*?)\s*%}/,
(match, utils) => {
- const pdfurl = match[1];
- if (!isValidURL(pdfurl)) return match[0];
- const div = $('');
- div.attr('data-pdfurl', pdfurl);
- return div[0].outerHTML;
+ const pdfurl = match[1]
+ if (!isValidURL(pdfurl)) return match[0]
+ const div = $('')
+ div.attr('data-pdfurl', pdfurl)
+ return div[0].outerHTML
}
-);
+)
-//yaml meta, from https://github.com/eugeneware/remarkable-meta
-function get(state, line) {
- const pos = state.bMarks[line];
- const max = state.eMarks[line];
- return state.src.substr(pos, max - pos);
+// yaml meta, from https://github.com/eugeneware/remarkable-meta
+function get (state, line) {
+ const pos = state.bMarks[line]
+ const max = state.eMarks[line]
+ return state.src.substr(pos, max - pos)
}
-function meta(state, start, end, silent) {
- if (start !== 0 || state.blkIndent !== 0) return false;
- if (state.tShift[start] < 0) return false;
- if (!get(state, start).match(/^---$/)) return false;
-
- const data = [];
- for (var line = start + 1; line < end; line++) {
- const str = get(state, line);
- if (str.match(/^(\.{3}|-{3})$/)) break;
- if (state.tShift[line] < 0) break;
- data.push(str);
- }
-
- if (line >= end) return false;
-
- try {
- md.meta = jsyaml.safeLoad(data.join('\n')) || {};
- delete md.metaError;
- } catch(err) {
- md.metaError = err;
- console.warn(err);
- return false;
- }
-
- state.line = line + 1;
-
- return true;
+function meta (state, start, end, silent) {
+ if (start !== 0 || state.blkIndent !== 0) return false
+ if (state.tShift[start] < 0) return false
+ if (!get(state, start).match(/^---$/)) return false
+
+ const data = []
+ for (var line = start + 1; line < end; line++) {
+ const str = get(state, line)
+ if (str.match(/^(\.{3}|-{3})$/)) break
+ if (state.tShift[line] < 0) break
+ data.push(str)
+ }
+
+ if (line >= end) return false
+
+ try {
+ md.meta = window.jsyaml.safeLoad(data.join('\n')) || {}
+ delete md.metaError
+ } catch (err) {
+ md.metaError = err
+ console.warn(err)
+ return false
+ }
+
+ state.line = line + 1
+
+ return true
}
-function metaPlugin(md) {
- md.meta = md.meta || {};
- md.block.ruler.before('code', 'meta', meta, {
- alt: []
- });
+function metaPlugin (md) {
+ md.meta = md.meta || {}
+ md.block.ruler.before('code', 'meta', meta, {
+ alt: []
+ })
}
-md.use(metaPlugin);
-md.use(youtubePlugin);
-md.use(vimeoPlugin);
-md.use(gistPlugin);
-md.use(tocPlugin);
-md.use(slidesharePlugin);
-md.use(speakerdeckPlugin);
-md.use(pdfPlugin);
+md.use(metaPlugin)
+md.use(youtubePlugin)
+md.use(vimeoPlugin)
+md.use(gistPlugin)
+md.use(tocPlugin)
+md.use(slidesharePlugin)
+md.use(speakerdeckPlugin)
+md.use(pdfPlugin)
export default {
md
-};
+}
diff --git a/public/js/google-drive-picker.js b/public/js/google-drive-picker.js
index 94aa77ff..5006cd25 100644
--- a/public/js/google-drive-picker.js
+++ b/public/js/google-drive-picker.js
@@ -1,119 +1,118 @@
-/**!
+/** !
* Google Drive File Picker Example
* By Daniel Lo Nigro (http://dan.cx/)
*/
-(function() {
- /**
- * Initialise a Google Driver file picker
- */
- var FilePicker = window.FilePicker = function(options) {
- // Config
- this.apiKey = options.apiKey;
- this.clientId = options.clientId;
-
- // Elements
- this.buttonEl = options.buttonEl;
-
- // Events
- this.onSelect = options.onSelect;
- this.buttonEl.on('click', this.open.bind(this));
-
- // Disable the button until the API loads, as it won't work properly until then.
- this.buttonEl.prop('disabled', true);
+(function () {
+ /**
+ * Initialise a Google Driver file picker
+ */
+ var FilePicker = window.FilePicker = function (options) {
+ // Config
+ this.apiKey = options.apiKey
+ this.clientId = options.clientId
- // Load the drive API
- gapi.client.setApiKey(this.apiKey);
- gapi.client.load('drive', 'v2', this._driveApiLoaded.bind(this));
- google.load('picker', '1', { callback: this._pickerApiLoaded.bind(this) });
- }
+ // Elements
+ this.buttonEl = options.buttonEl
- FilePicker.prototype = {
- /**
- * Open the file picker.
- */
- open: function() {
- // Check if the user has already authenticated
- var token = gapi.auth.getToken();
- if (token) {
- this._showPicker();
- } else {
- // The user has not yet authenticated with Google
- // We need to do the authentication before displaying the Drive picker.
- this._doAuth(false, function() { this._showPicker(); }.bind(this));
- }
- },
-
- /**
- * Show the file picker once authentication has been done.
- * @private
- */
- _showPicker: function() {
- var accessToken = gapi.auth.getToken().access_token;
- var view = new google.picker.DocsView();
- view.setMimeTypes("text/markdown,text/html");
- view.setIncludeFolders(true);
- view.setOwnedByMe(true);
- this.picker = new google.picker.PickerBuilder().
- enableFeature(google.picker.Feature.NAV_HIDDEN).
- addView(view).
- setAppId(this.clientId).
- setOAuthToken(accessToken).
- setCallback(this._pickerCallback.bind(this)).
- build().
- setVisible(true);
- },
-
- /**
- * Called when a file has been selected in the Google Drive file picker.
- * @private
- */
- _pickerCallback: function(data) {
- if (data[google.picker.Response.ACTION] == google.picker.Action.PICKED) {
- var file = data[google.picker.Response.DOCUMENTS][0],
- id = file[google.picker.Document.ID],
- request = gapi.client.drive.files.get({
- fileId: id
- });
-
- request.execute(this._fileGetCallback.bind(this));
- }
- },
- /**
- * Called when file details have been retrieved from Google Drive.
- * @private
- */
- _fileGetCallback: function(file) {
- if (this.onSelect) {
- this.onSelect(file);
- }
- },
-
- /**
- * Called when the Google Drive file picker API has finished loading.
- * @private
- */
- _pickerApiLoaded: function() {
- this.buttonEl.prop('disabled', false);
- },
-
- /**
- * Called when the Google Drive API has finished loading.
- * @private
- */
- _driveApiLoaded: function() {
- this._doAuth(true);
- },
-
- /**
- * Authenticate with Google Drive via the Google JavaScript API.
- * @private
- */
- _doAuth: function(immediate, callback) {
- gapi.auth.authorize({
- client_id: this.clientId,
- scope: 'https://www.googleapis.com/auth/drive.readonly',
- immediate: immediate
- }, callback ? callback : function() {});
- }
- };
-}());
+ // Events
+ this.onSelect = options.onSelect
+ this.buttonEl.on('click', this.open.bind(this))
+
+ // Disable the button until the API loads, as it won't work properly until then.
+ this.buttonEl.prop('disabled', true)
+
+ // Load the drive API
+ window.gapi.client.setApiKey(this.apiKey)
+ window.gapi.client.load('drive', 'v2', this._driveApiLoaded.bind(this))
+ window.google.load('picker', '1', { callback: this._pickerApiLoaded.bind(this) })
+ }
+
+ FilePicker.prototype = {
+ /**
+ * Open the file picker.
+ */
+ open: function () {
+ // Check if the user has already authenticated
+ var token = window.gapi.auth.getToken()
+ if (token) {
+ this._showPicker()
+ } else {
+ // The user has not yet authenticated with Google
+ // We need to do the authentication before displaying the Drive picker.
+ this._doAuth(false, function () { this._showPicker() }.bind(this))
+ }
+ },
+
+ /**
+ * Show the file picker once authentication has been done.
+ * @private
+ */
+ _showPicker: function () {
+ var accessToken = window.gapi.auth.getToken().access_token
+ var view = new window.google.picker.DocsView()
+ view.setMimeTypes('text/markdown,text/html')
+ view.setIncludeFolders(true)
+ view.setOwnedByMe(true)
+ this.picker = new window.google.picker.PickerBuilder()
+ .enableFeature(window.google.picker.Feature.NAV_HIDDEN)
+ .addView(view)
+ .setAppId(this.clientId)
+ .setOAuthToken(accessToken)
+ .setCallback(this._pickerCallback.bind(this))
+ .build()
+ .setVisible(true)
+ },
+
+ /**
+ * Called when a file has been selected in the Google Drive file picker.
+ * @private
+ */
+ _pickerCallback: function (data) {
+ if (data[window.google.picker.Response.ACTION] === window.google.picker.Action.PICKED) {
+ var file = data[window.google.picker.Response.DOCUMENTS][0]
+ var id = file[window.google.picker.Document.ID]
+ var request = window.gapi.client.drive.files.get({
+ fileId: id
+ })
+ request.execute(this._fileGetCallback.bind(this))
+ }
+ },
+ /**
+ * Called when file details have been retrieved from Google Drive.
+ * @private
+ */
+ _fileGetCallback: function (file) {
+ if (this.onSelect) {
+ this.onSelect(file)
+ }
+ },
+
+ /**
+ * Called when the Google Drive file picker API has finished loading.
+ * @private
+ */
+ _pickerApiLoaded: function () {
+ this.buttonEl.prop('disabled', false)
+ },
+
+ /**
+ * Called when the Google Drive API has finished loading.
+ * @private
+ */
+ _driveApiLoaded: function () {
+ this._doAuth(true)
+ },
+
+ /**
+ * Authenticate with Google Drive via the Google JavaScript API.
+ * @private
+ */
+ _doAuth: function (immediate, callback) {
+ window.gapi.auth.authorize({
+ client_id: this.clientId,
+ scope: 'https://www.googleapis.com/auth/drive.readonly',
+ immediate: immediate
+ }, callback || function () {})
+ }
+ }
+}())
diff --git a/public/js/google-drive-upload.js b/public/js/google-drive-upload.js
index eabc5b7f..6c0e8a62 100644
--- a/public/js/google-drive-upload.js
+++ b/public/js/google-drive-upload.js
@@ -1,30 +1,31 @@
+/* eslint-env browser, jquery */
/**
* Helper for implementing retries with backoff. Initial retry
* delay is 1 second, increasing by 2x (+jitter) for subsequent retries
*
* @constructor
*/
-var RetryHandler = function() {
- this.interval = 1000; // Start at one second
- this.maxInterval = 60 * 1000; // Don't wait longer than a minute
-};
+var RetryHandler = function () {
+ this.interval = 1000 // Start at one second
+ this.maxInterval = 60 * 1000 // Don't wait longer than a minute
+}
/**
* Invoke the function after waiting
*
* @param {function} fn Function to invoke
*/
-RetryHandler.prototype.retry = function(fn) {
- setTimeout(fn, this.interval);
- this.interval = this.nextInterval_();
-};
+RetryHandler.prototype.retry = function (fn) {
+ setTimeout(fn, this.interval)
+ this.interval = this.nextInterval_()
+}
/**
* Reset the counter (e.g. after successful request.)
*/
-RetryHandler.prototype.reset = function() {
- this.interval = 1000;
-};
+RetryHandler.prototype.reset = function () {
+ this.interval = 1000
+}
/**
* Calculate the next wait time.
@@ -32,10 +33,10 @@ RetryHandler.prototype.reset = function() {
*
* @private
*/
-RetryHandler.prototype.nextInterval_ = function() {
- var interval = this.interval * 2 + this.getRandomInt_(0, 1000);
- return Math.min(interval, this.maxInterval);
-};
+RetryHandler.prototype.nextInterval_ = function () {
+ var interval = this.interval * 2 + this.getRandomInt_(0, 1000)
+ return Math.min(interval, this.maxInterval)
+}
/**
* Get a random int in the range of min to max. Used to add jitter to wait times.
@@ -44,10 +45,9 @@ RetryHandler.prototype.nextInterval_ = function() {
* @param {number} max Upper bounds
* @private
*/
-RetryHandler.prototype.getRandomInt_ = function(min, max) {
- return Math.floor(Math.random() * (max - min + 1) + min);
-};
-
+RetryHandler.prototype.getRandomInt_ = function (min, max) {
+ return Math.floor(Math.random() * (max - min + 1) + min)
+}
/**
* Helper class for resumable uploads using XHR/CORS. Can upload any Blob-like item, whether
@@ -75,116 +75,115 @@ RetryHandler.prototype.getRandomInt_ = function(min, max) {
* @param {function} [options.onProgress] Callback for status for the in-progress upload
* @param {function} [options.onError] Callback if upload fails
*/
-var MediaUploader = function(options) {
- var noop = function() {};
- this.file = options.file;
- this.contentType = options.contentType || this.file.type || 'application/octet-stream';
+var MediaUploader = function (options) {
+ var noop = function () {}
+ this.file = options.file
+ this.contentType = options.contentType || this.file.type || 'application/octet-stream'
this.metadata = options.metadata || {
'title': this.file.name,
'mimeType': this.contentType
- };
- this.token = options.token;
- this.onComplete = options.onComplete || noop;
- this.onProgress = options.onProgress || noop;
- this.onError = options.onError || noop;
- this.offset = options.offset || 0;
- this.chunkSize = options.chunkSize || 0;
- this.retryHandler = new RetryHandler();
+ }
+ this.token = options.token
+ this.onComplete = options.onComplete || noop
+ this.onProgress = options.onProgress || noop
+ this.onError = options.onError || noop
+ this.offset = options.offset || 0
+ this.chunkSize = options.chunkSize || 0
+ this.retryHandler = new RetryHandler()
- this.url = options.url;
+ this.url = options.url
if (!this.url) {
- var params = options.params || {};
- params.uploadType = 'resumable';
- this.url = this.buildUrl_(options.fileId, params, options.baseUrl);
+ var params = options.params || {}
+ params.uploadType = 'resumable'
+ this.url = this.buildUrl_(options.fileId, params, options.baseUrl)
}
- this.httpMethod = options.fileId ? 'PUT' : 'POST';
-};
+ this.httpMethod = options.fileId ? 'PUT' : 'POST'
+}
/**
* Initiate the upload.
*/
-MediaUploader.prototype.upload = function() {
- var self = this;
- var xhr = new XMLHttpRequest();
+MediaUploader.prototype.upload = function () {
+ var xhr = new XMLHttpRequest()
- xhr.open(this.httpMethod, this.url, true);
- xhr.setRequestHeader('Authorization', 'Bearer ' + this.token);
- xhr.setRequestHeader('Content-Type', 'application/json');
- xhr.setRequestHeader('X-Upload-Content-Length', this.file.size);
- xhr.setRequestHeader('X-Upload-Content-Type', this.contentType);
+ xhr.open(this.httpMethod, this.url, true)
+ xhr.setRequestHeader('Authorization', 'Bearer ' + this.token)
+ xhr.setRequestHeader('Content-Type', 'application/json')
+ xhr.setRequestHeader('X-Upload-Content-Length', this.file.size)
+ xhr.setRequestHeader('X-Upload-Content-Type', this.contentType)
- xhr.onload = function(e) {
+ xhr.onload = function (e) {
if (e.target.status < 400) {
- var location = e.target.getResponseHeader('Location');
- this.url = location;
- this.sendFile_();
+ var location = e.target.getResponseHeader('Location')
+ this.url = location
+ this.sendFile_()
} else {
- this.onUploadError_(e);
+ this.onUploadError_(e)
}
- }.bind(this);
- xhr.onerror = this.onUploadError_.bind(this);
- xhr.send(JSON.stringify(this.metadata));
-};
+ }.bind(this)
+ xhr.onerror = this.onUploadError_.bind(this)
+ xhr.send(JSON.stringify(this.metadata))
+}
/**
* Send the actual file content.
*
* @private
*/
-MediaUploader.prototype.sendFile_ = function() {
- var content = this.file;
- var end = this.file.size;
+MediaUploader.prototype.sendFile_ = function () {
+ var content = this.file
+ var end = this.file.size
if (this.offset || this.chunkSize) {
// Only bother to slice the file if we're either resuming or uploading in chunks
if (this.chunkSize) {
- end = Math.min(this.offset + this.chunkSize, this.file.size);
+ end = Math.min(this.offset + this.chunkSize, this.file.size)
}
- content = content.slice(this.offset, end);
+ content = content.slice(this.offset, end)
}
- var xhr = new XMLHttpRequest();
- xhr.open('PUT', this.url, true);
- xhr.setRequestHeader('Content-Type', this.contentType);
- xhr.setRequestHeader('Content-Range', "bytes " + this.offset + "-" + (end - 1) + "/" + this.file.size);
- xhr.setRequestHeader('X-Upload-Content-Type', this.file.type);
+ var xhr = new XMLHttpRequest()
+ xhr.open('PUT', this.url, true)
+ xhr.setRequestHeader('Content-Type', this.contentType)
+ xhr.setRequestHeader('Content-Range', 'bytes ' + this.offset + '-' + (end - 1) + '/' + this.file.size)
+ xhr.setRequestHeader('X-Upload-Content-Type', this.file.type)
if (xhr.upload) {
- xhr.upload.addEventListener('progress', this.onProgress);
+ xhr.upload.addEventListener('progress', this.onProgress)
}
- xhr.onload = this.onContentUploadSuccess_.bind(this);
- xhr.onerror = this.onContentUploadError_.bind(this);
- xhr.send(content);
-};
+ xhr.onload = this.onContentUploadSuccess_.bind(this)
+ xhr.onerror = this.onContentUploadError_.bind(this)
+ xhr.send(content)
+}
/**
* Query for the state of the file for resumption.
*
* @private
*/
-MediaUploader.prototype.resume_ = function() {
- var xhr = new XMLHttpRequest();
- xhr.open('PUT', this.url, true);
- xhr.setRequestHeader('Content-Range', "bytes */" + this.file.size);
- xhr.setRequestHeader('X-Upload-Content-Type', this.file.type);
+MediaUploader.prototype.resume_ = function () {
+ var xhr = new XMLHttpRequest()
+ xhr.open('PUT', this.url, true)
+ xhr.setRequestHeader('Content-Range', 'bytes */' + this.file.size)
+ xhr.setRequestHeader('X-Upload-Content-Type', this.file.type)
if (xhr.upload) {
- xhr.upload.addEventListener('progress', this.onProgress);
+ xhr.upload.addEventListener('progress', this.onProgress)
}
- xhr.onload = this.onContentUploadSuccess_.bind(this);
- xhr.onerror = this.onContentUploadError_.bind(this);
- xhr.send();
-};
+ xhr.onload = this.onContentUploadSuccess_.bind(this)
+ xhr.onerror = this.onContentUploadError_.bind(this)
+ xhr.send()
+}
/**
* Extract the last saved range if available in the request.
*
* @param {XMLHttpRequest} xhr Request object
*/
-MediaUploader.prototype.extractRange_ = function(xhr) {
- var range = xhr.getResponseHeader('Range');
+MediaUploader.prototype.extractRange_ = function (xhr) {
+ var range = xhr.getResponseHeader('Range')
if (range) {
- this.offset = parseInt(range.match(/\d+/g).pop(), 10) + 1;
+ this.offset = parseInt(range.match(/\d+/g).pop(), 10) + 1
}
-};
+}
/**
* Handle successful responses for uploads. Depending on the context,
@@ -194,17 +193,17 @@ MediaUploader.prototype.extractRange_ = function(xhr) {
* @private
* @param {object} e XHR event
*/
-MediaUploader.prototype.onContentUploadSuccess_ = function(e) {
- if (e.target.status == 200 || e.target.status == 201) {
- this.onComplete(e.target.response);
- } else if (e.target.status == 308) {
- this.extractRange_(e.target);
- this.retryHandler.reset();
- this.sendFile_();
+MediaUploader.prototype.onContentUploadSuccess_ = function (e) {
+ if (e.target.status === 200 || e.target.status === 201) {
+ this.onComplete(e.target.response)
+ } else if (e.target.status === 308) {
+ this.extractRange_(e.target)
+ this.retryHandler.reset()
+ this.sendFile_()
} else {
- this.onContentUploadError_(e);
+ this.onContentUploadError_(e)
}
-};
+}
/**
* Handles errors for uploads. Either retries or aborts depending
@@ -213,13 +212,13 @@ MediaUploader.prototype.onContentUploadSuccess_ = function(e) {
* @private
* @param {object} e XHR event
*/
-MediaUploader.prototype.onContentUploadError_ = function(e) {
+MediaUploader.prototype.onContentUploadError_ = function (e) {
if (e.target.status && e.target.status < 500) {
- this.onError(e.target.response);
+ this.onError(e.target.response)
} else {
- this.retryHandler.retry(this.resume_.bind(this));
+ this.retryHandler.retry(this.resume_.bind(this))
}
-};
+}
/**
* Handles errors for the initial request.
@@ -227,9 +226,9 @@ MediaUploader.prototype.onContentUploadError_ = function(e) {
* @private
* @param {object} e XHR event
*/
-MediaUploader.prototype.onUploadError_ = function(e) {
- this.onError(e.target.response); // TODO - Retries for initial upload
-};
+MediaUploader.prototype.onUploadError_ = function (e) {
+ this.onError(e.target.response) // TODO - Retries for initial upload
+}
/**
* Construct a query string from a hash/object
@@ -238,12 +237,12 @@ MediaUploader.prototype.onUploadError_ = function(e) {
* @param {object} [params] Key/value pairs for query string
* @return {string} query string
*/
-MediaUploader.prototype.buildQuery_ = function(params) {
- params = params || {};
- return Object.keys(params).map(function(key) {
- return encodeURIComponent(key) + '=' + encodeURIComponent(params[key]);
- }).join('&');
-};
+MediaUploader.prototype.buildQuery_ = function (params) {
+ params = params || {}
+ return Object.keys(params).map(function (key) {
+ return encodeURIComponent(key) + '=' + encodeURIComponent(params[key])
+ }).join('&')
+}
/**
* Build the drive upload URL
@@ -253,16 +252,16 @@ MediaUploader.prototype.buildQuery_ = function(params) {
* @param {object} [params] Query parameters
* @return {string} URL
*/
-MediaUploader.prototype.buildUrl_ = function(id, params, baseUrl) {
- var url = baseUrl || 'https://www.googleapis.com/upload/drive/v2/files/';
+MediaUploader.prototype.buildUrl_ = function (id, params, baseUrl) {
+ var url = baseUrl || 'https://www.googleapis.com/upload/drive/v2/files/'
if (id) {
- url += id;
+ url += id
}
- var query = this.buildQuery_(params);
+ var query = this.buildQuery_(params)
if (query) {
- url += '?' + query;
+ url += '?' + query
}
- return url;
-};
+ return url
+}
-window.MediaUploader = MediaUploader;
+window.MediaUploader = MediaUploader
diff --git a/public/js/history.js b/public/js/history.js
index 34b2cba7..e14b80d8 100644
--- a/public/js/history.js
+++ b/public/js/history.js
@@ -1,372 +1,328 @@
-import store from 'store';
-import S from 'string';
+/* eslint-env browser, jquery */
+/* global serverurl, Cookies, moment */
+
+import store from 'store'
+import S from 'string'
import {
checkIfAuth
-} from './lib/common/login';
+} from './lib/common/login'
import {
urlpath
-} from './lib/config';
+} from './lib/config'
-window.migrateHistoryFromTempCallback = null;
+window.migrateHistoryFromTempCallback = null
-migrateHistoryFromTemp();
+migrateHistoryFromTemp()
-function migrateHistoryFromTemp() {
- if (url('#tempid')) {
- $.get(`${serverurl}/temp`, {
- tempid: url('#tempid')
- })
- .done(data => {
- if (data && data.temp) {
- getStorageHistory(olddata => {
- if (!olddata || olddata.length == 0) {
- saveHistoryToStorage(JSON.parse(data.temp));
- }
- });
- }
- })
- .always(() => {
- let hash = location.hash.split('#')[1];
- hash = hash.split('&');
- for (let i = 0; i < hash.length; i++)
- if (hash[i].indexOf('tempid') == 0) {
- hash.splice(i, 1);
- i--;
- }
- hash = hash.join('&');
- location.hash = hash;
- if (migrateHistoryFromTempCallback)
- migrateHistoryFromTempCallback();
- });
- }
+function migrateHistoryFromTemp () {
+ if (window.url('#tempid')) {
+ $.get(`${serverurl}/temp`, {
+ tempid: window.url('#tempid')
+ })
+ .done(data => {
+ if (data && data.temp) {
+ getStorageHistory(olddata => {
+ if (!olddata || olddata.length === 0) {
+ saveHistoryToStorage(JSON.parse(data.temp))
+ }
+ })
+ }
+ })
+ .always(() => {
+ let hash = location.hash.split('#')[1]
+ hash = hash.split('&')
+ for (let i = 0; i < hash.length; i++) {
+ if (hash[i].indexOf('tempid') === 0) {
+ hash.splice(i, 1)
+ i--
+ }
+ }
+ hash = hash.join('&')
+ location.hash = hash
+ if (window.migrateHistoryFromTempCallback) { window.migrateHistoryFromTempCallback() }
+ })
+ }
}
-export function saveHistory(notehistory) {
- checkIfAuth(
+export function saveHistory (notehistory) {
+ checkIfAuth(
() => {
- saveHistoryToServer(notehistory);
+ saveHistoryToServer(notehistory)
},
() => {
- saveHistoryToStorage(notehistory);
+ saveHistoryToStorage(notehistory)
}
- );
+ )
}
-function saveHistoryToStorage(notehistory) {
- if (store.enabled)
- store.set('notehistory', JSON.stringify(notehistory));
- else
- saveHistoryToCookie(notehistory);
+function saveHistoryToStorage (notehistory) {
+ if (store.enabled) { store.set('notehistory', JSON.stringify(notehistory)) } else { saveHistoryToCookie(notehistory) }
}
-function saveHistoryToCookie(notehistory) {
- Cookies.set('notehistory', notehistory, {
- expires: 365
- });
+function saveHistoryToCookie (notehistory) {
+ Cookies.set('notehistory', notehistory, {
+ expires: 365
+ })
}
-function saveHistoryToServer(notehistory) {
- $.post(`${serverurl}/history`, {
- history: JSON.stringify(notehistory)
- });
+function saveHistoryToServer (notehistory) {
+ $.post(`${serverurl}/history`, {
+ history: JSON.stringify(notehistory)
+ })
}
-function saveCookieHistoryToStorage(callback) {
- store.set('notehistory', Cookies.get('notehistory'));
- callback();
-}
-
-export function saveStorageHistoryToServer(callback) {
- const data = store.get('notehistory');
- if (data) {
- $.post(`${serverurl}/history`, {
- history: data
- })
- .done(data => {
- callback(data);
- });
- }
-}
-
-function saveCookieHistoryToServer(callback) {
+export function saveStorageHistoryToServer (callback) {
+ const data = store.get('notehistory')
+ if (data) {
$.post(`${serverurl}/history`, {
- history: Cookies.get('notehistory')
- })
- .done(data => {
- callback(data);
- });
+ history: data
+ })
+ .done(data => {
+ callback(data)
+ })
+ }
}
-export function clearDuplicatedHistory(notehistory) {
- const newnotehistory = [];
- for (let i = 0; i < notehistory.length; i++) {
- let found = false;
- for (let j = 0; j < newnotehistory.length; j++) {
- const id = notehistory[i].id.replace(/\=+$/, '');
- const newId = newnotehistory[j].id.replace(/\=+$/, '');
- if (id == newId || notehistory[i].id == newnotehistory[j].id || !notehistory[i].id || !newnotehistory[j].id) {
- const time = (typeof notehistory[i].time === 'number' ? moment(notehistory[i].time) : moment(notehistory[i].time, 'MMMM Do YYYY, h:mm:ss a'));
- const newTime = (typeof newnotehistory[i].time === 'number' ? moment(newnotehistory[i].time) : moment(newnotehistory[i].time, 'MMMM Do YYYY, h:mm:ss a'));
- if(time >= newTime) {
- newnotehistory[j] = notehistory[i];
- }
- found = true;
- break;
- }
+export function clearDuplicatedHistory (notehistory) {
+ const newnotehistory = []
+ for (let i = 0; i < notehistory.length; i++) {
+ let found = false
+ for (let j = 0; j < newnotehistory.length; j++) {
+ const id = notehistory[i].id.replace(/=+$/, '')
+ const newId = newnotehistory[j].id.replace(/=+$/, '')
+ if (id === newId || notehistory[i].id === newnotehistory[j].id || !notehistory[i].id || !newnotehistory[j].id) {
+ const time = (typeof notehistory[i].time === 'number' ? moment(notehistory[i].time) : moment(notehistory[i].time, 'MMMM Do YYYY, h:mm:ss a'))
+ const newTime = (typeof newnotehistory[i].time === 'number' ? moment(newnotehistory[i].time) : moment(newnotehistory[i].time, 'MMMM Do YYYY, h:mm:ss a'))
+ if (time >= newTime) {
+ newnotehistory[j] = notehistory[i]
}
- if (!found)
- newnotehistory.push(notehistory[i]);
+ found = true
+ break
+ }
}
- return newnotehistory;
+ if (!found) { newnotehistory.push(notehistory[i]) }
+ }
+ return newnotehistory
}
-function addHistory(id, text, time, tags, pinned, notehistory) {
+function addHistory (id, text, time, tags, pinned, notehistory) {
// only add when note id exists
- if (id) {
- notehistory.push({
- id,
- text,
- time,
- tags,
- pinned
- });
- }
- return notehistory;
+ if (id) {
+ notehistory.push({
+ id,
+ text,
+ time,
+ tags,
+ pinned
+ })
+ }
+ return notehistory
}
-export function removeHistory(id, notehistory) {
- for (let i = 0; i < notehistory.length; i++) {
- if (notehistory[i].id == id) {
- notehistory.splice(i, 1);
- i -= 1;
- }
+export function removeHistory (id, notehistory) {
+ for (let i = 0; i < notehistory.length; i++) {
+ if (notehistory[i].id === id) {
+ notehistory.splice(i, 1)
+ i -= 1
}
- return notehistory;
+ }
+ return notehistory
}
-//used for inner
-export function writeHistory(title, tags) {
- checkIfAuth(
+// used for inner
+export function writeHistory (title, tags) {
+ checkIfAuth(
() => {
// no need to do this anymore, this will count from server-side
// writeHistoryToServer(title, tags);
},
() => {
- writeHistoryToStorage(title, tags);
+ writeHistoryToStorage(title, tags)
}
- );
+ )
}
-function writeHistoryToServer(title, tags) {
- $.get(`${serverurl}/history`)
- .done(data => {
- try {
- if (data.history) {
- var notehistory = data.history;
- } else {
- var notehistory = [];
- }
- } catch (err) {
- var notehistory = [];
- }
- if (!notehistory)
- notehistory = [];
-
- const newnotehistory = generateHistory(title, tags, notehistory);
- saveHistoryToServer(newnotehistory);
- })
- .fail((xhr, status, error) => {
- console.error(xhr.responseText);
- });
+function writeHistoryToCookie (title, tags) {
+ var notehistory
+ try {
+ notehistory = Cookies.getJSON('notehistory')
+ } catch (err) {
+ notehistory = []
+ }
+ if (!notehistory) { notehistory = [] }
+ const newnotehistory = generateHistory(title, tags, notehistory)
+ saveHistoryToCookie(newnotehistory)
}
-function writeHistoryToCookie(title, tags) {
- try {
- var notehistory = Cookies.getJSON('notehistory');
- } catch (err) {
- var notehistory = [];
- }
- if (!notehistory)
- notehistory = [];
-
- const newnotehistory = generateHistory(title, tags, notehistory);
- saveHistoryToCookie(newnotehistory);
-}
-
-function writeHistoryToStorage(title, tags) {
- if (store.enabled) {
- let data = store.get('notehistory');
- if (data) {
- if (typeof data == "string")
- data = JSON.parse(data);
- var notehistory = data;
- } else
- var notehistory = [];
- if (!notehistory)
- notehistory = [];
-
- const newnotehistory = generateHistory(title, tags, notehistory);
- saveHistoryToStorage(newnotehistory);
+function writeHistoryToStorage (title, tags) {
+ if (store.enabled) {
+ let data = store.get('notehistory')
+ var notehistory
+ if (data) {
+ if (typeof data === 'string') { data = JSON.parse(data) }
+ notehistory = data
} else {
- writeHistoryToCookie(title, tags);
+ notehistory = []
}
+ if (!notehistory) { notehistory = [] }
+
+ const newnotehistory = generateHistory(title, tags, notehistory)
+ saveHistoryToStorage(newnotehistory)
+ } else {
+ writeHistoryToCookie(title, tags)
+ }
}
if (!Array.isArray) {
- Array.isArray = arg => Object.prototype.toString.call(arg) === '[object Array]';
+ Array.isArray = arg => Object.prototype.toString.call(arg) === '[object Array]'
}
-function renderHistory(title, tags) {
- //console.debug(tags);
- const id = urlpath ? location.pathname.slice(urlpath.length + 1, location.pathname.length).split('/')[1] : location.pathname.split('/')[1];
- return {
- id,
- text: title,
- time: moment().valueOf(),
- tags
- };
+function renderHistory (title, tags) {
+ // console.debug(tags);
+ const id = urlpath ? location.pathname.slice(urlpath.length + 1, location.pathname.length).split('/')[1] : location.pathname.split('/')[1]
+ return {
+ id,
+ text: title,
+ time: moment().valueOf(),
+ tags
+ }
}
-function generateHistory(title, tags, notehistory) {
- const info = renderHistory(title, tags);
- //keep any pinned data
- let pinned = false;
- for (let i = 0; i < notehistory.length; i++) {
- if (notehistory[i].id == info.id && notehistory[i].pinned) {
- pinned = true;
- break;
- }
+function generateHistory (title, tags, notehistory) {
+ const info = renderHistory(title, tags)
+ // keep any pinned data
+ let pinned = false
+ for (let i = 0; i < notehistory.length; i++) {
+ if (notehistory[i].id === info.id && notehistory[i].pinned) {
+ pinned = true
+ break
}
- notehistory = removeHistory(info.id, notehistory);
- notehistory = addHistory(info.id, info.text, info.time, info.tags, pinned, notehistory);
- notehistory = clearDuplicatedHistory(notehistory);
- return notehistory;
+ }
+ notehistory = removeHistory(info.id, notehistory)
+ notehistory = addHistory(info.id, info.text, info.time, info.tags, pinned, notehistory)
+ notehistory = clearDuplicatedHistory(notehistory)
+ return notehistory
}
-//used for outer
-export function getHistory(callback) {
- checkIfAuth(
+// used for outer
+export function getHistory (callback) {
+ checkIfAuth(
() => {
- getServerHistory(callback);
+ getServerHistory(callback)
},
() => {
- getStorageHistory(callback);
+ getStorageHistory(callback)
}
- );
+ )
}
-function getServerHistory(callback) {
- $.get(`${serverurl}/history`)
+function getServerHistory (callback) {
+ $.get(`${serverurl}/history`)
.done(data => {
- if (data.history) {
- callback(data.history);
- }
+ if (data.history) {
+ callback(data.history)
+ }
})
.fail((xhr, status, error) => {
- console.error(xhr.responseText);
- });
+ console.error(xhr.responseText)
+ })
}
-function getCookieHistory(callback) {
- callback(Cookies.getJSON('notehistory'));
+function getCookieHistory (callback) {
+ callback(Cookies.getJSON('notehistory'))
}
-export function getStorageHistory(callback) {
- if (store.enabled) {
- let data = store.get('notehistory');
- if (data) {
- if (typeof data == "string")
- data = JSON.parse(data);
- callback(data);
- } else
- getCookieHistory(callback);
- } else {
- getCookieHistory(callback);
- }
+export function getStorageHistory (callback) {
+ if (store.enabled) {
+ let data = store.get('notehistory')
+ if (data) {
+ if (typeof data === 'string') { data = JSON.parse(data) }
+ callback(data)
+ } else { getCookieHistory(callback) }
+ } else {
+ getCookieHistory(callback)
+ }
}
-export function parseHistory(list, callback) {
- checkIfAuth(
+export function parseHistory (list, callback) {
+ checkIfAuth(
() => {
- parseServerToHistory(list, callback);
+ parseServerToHistory(list, callback)
},
() => {
- parseStorageToHistory(list, callback);
+ parseStorageToHistory(list, callback)
}
- );
+ )
}
-export function parseServerToHistory(list, callback) {
- $.get(`${serverurl}/history`)
+export function parseServerToHistory (list, callback) {
+ $.get(`${serverurl}/history`)
.done(data => {
- if (data.history) {
- parseToHistory(list, data.history, callback);
- }
+ if (data.history) {
+ parseToHistory(list, data.history, callback)
+ }
})
.fail((xhr, status, error) => {
- console.error(xhr.responseText);
- });
+ console.error(xhr.responseText)
+ })
}
-function parseCookieToHistory(list, callback) {
- const notehistory = Cookies.getJSON('notehistory');
- parseToHistory(list, notehistory, callback);
+function parseCookieToHistory (list, callback) {
+ const notehistory = Cookies.getJSON('notehistory')
+ parseToHistory(list, notehistory, callback)
}
-export function parseStorageToHistory(list, callback) {
- if (store.enabled) {
- let data = store.get('notehistory');
- if (data) {
- if (typeof data == "string")
- data = JSON.parse(data);
- parseToHistory(list, data, callback);
- } else
- parseCookieToHistory(list, callback);
- } else {
- parseCookieToHistory(list, callback);
- }
+export function parseStorageToHistory (list, callback) {
+ if (store.enabled) {
+ let data = store.get('notehistory')
+ if (data) {
+ if (typeof data === 'string') { data = JSON.parse(data) }
+ parseToHistory(list, data, callback)
+ } else { parseCookieToHistory(list, callback) }
+ } else {
+ parseCookieToHistory(list, callback)
+ }
}
-function parseToHistory(list, notehistory, callback) {
- if (!callback) return;
- else if (!list || !notehistory) callback(list, notehistory);
- else if (notehistory && notehistory.length > 0) {
- for (let i = 0; i < notehistory.length; i++) {
- //parse time to timestamp and fromNow
- const timestamp = (typeof notehistory[i].time === 'number' ? moment(notehistory[i].time) : moment(notehistory[i].time, 'MMMM Do YYYY, h:mm:ss a'));
- notehistory[i].timestamp = timestamp.valueOf();
- notehistory[i].fromNow = timestamp.fromNow();
- notehistory[i].time = timestamp.format('llll');
+function parseToHistory (list, notehistory, callback) {
+ if (!callback) return
+ else if (!list || !notehistory) callback(list, notehistory)
+ else if (notehistory && notehistory.length > 0) {
+ for (let i = 0; i < notehistory.length; i++) {
+ // parse time to timestamp and fromNow
+ const timestamp = (typeof notehistory[i].time === 'number' ? moment(notehistory[i].time) : moment(notehistory[i].time, 'MMMM Do YYYY, h:mm:ss a'))
+ notehistory[i].timestamp = timestamp.valueOf()
+ notehistory[i].fromNow = timestamp.fromNow()
+ notehistory[i].time = timestamp.format('llll')
// prevent XSS
- notehistory[i].text = S(notehistory[i].text).escapeHTML().s;
- notehistory[i].tags = (notehistory[i].tags && notehistory[i].tags.length > 0) ? S(notehistory[i].tags).escapeHTML().s.split(',') : [];
+ notehistory[i].text = S(notehistory[i].text).escapeHTML().s
+ notehistory[i].tags = (notehistory[i].tags && notehistory[i].tags.length > 0) ? S(notehistory[i].tags).escapeHTML().s.split(',') : []
// add to list
- if (notehistory[i].id && list.get('id', notehistory[i].id).length == 0)
- list.add(notehistory[i]);
- }
+ if (notehistory[i].id && list.get('id', notehistory[i].id).length === 0) { list.add(notehistory[i]) }
}
- callback(list, notehistory);
+ }
+ callback(list, notehistory)
}
-export function postHistoryToServer(noteId, data, callback) {
- $.post(`${serverurl}/history/${noteId}`, data)
+export function postHistoryToServer (noteId, data, callback) {
+ $.post(`${serverurl}/history/${noteId}`, data)
.done(result => callback(null, result))
.fail((xhr, status, error) => {
- console.error(xhr.responseText);
- return callback(error, null);
- });
+ console.error(xhr.responseText)
+ return callback(error, null)
+ })
}
-export function deleteServerHistory(noteId, callback) {
- $.ajax({
- url: `${serverurl}/history${noteId ? '/' + noteId : ""}`,
- type: 'DELETE'
- })
+export function deleteServerHistory (noteId, callback) {
+ $.ajax({
+ url: `${serverurl}/history${noteId ? '/' + noteId : ''}`,
+ type: 'DELETE'
+ })
.done(result => callback(null, result))
.fail((xhr, status, error) => {
- console.error(xhr.responseText);
- return callback(error, null);
- });
+ console.error(xhr.responseText)
+ return callback(error, null)
+ })
}
diff --git a/public/js/htmlExport.js b/public/js/htmlExport.js
index 1c2c5eb9..1a873aca 100644
--- a/public/js/htmlExport.js
+++ b/public/js/htmlExport.js
@@ -1,6 +1,6 @@
-require('../css/github-extract.css');
-require('../css/markdown.css');
-require('../css/extra.css');
-require('../css/slide-preview.css');
-require('../css/google-font.css');
-require('../css/site.css');
+require('../css/github-extract.css')
+require('../css/markdown.css')
+require('../css/extra.css')
+require('../css/slide-preview.css')
+require('../css/google-font.css')
+require('../css/site.css')
diff --git a/public/js/index.js b/public/js/index.js
index f0c476ef..e672a68d 100644
--- a/public/js/index.js
+++ b/public/js/index.js
@@ -1,26 +1,30 @@
-/* jquery and jquery plugins */
-require('../vendor/showup/showup');
+/* eslint-env browser, jquery */
+/* global CodeMirror, Cookies, moment, editor, ui, Spinner,
+ modeType, Idle, serverurl, key, gapi, Dropbox, FilePicker
+ ot, MediaUploader, hex2rgb, num_loaded, Visibility */
-require('../css/index.css');
-require('../css/extra.css');
-require('../css/slide-preview.css');
-require('../css/site.css');
+require('../vendor/showup/showup')
-require('highlight.js/styles/github-gist.css');
+require('../css/index.css')
+require('../css/extra.css')
+require('../css/slide-preview.css')
+require('../css/site.css')
-var toMarkdown = require('to-markdown');
+require('highlight.js/styles/github-gist.css')
-var saveAs = require('file-saver').saveAs;
-var randomColor = require('randomcolor');
+var toMarkdown = require('to-markdown')
-var _ = require("lodash");
+var saveAs = require('file-saver').saveAs
+var randomColor = require('randomcolor')
-var List = require('list.js');
+var _ = require('lodash')
+
+var List = require('list.js')
import {
checkLoginStateChanged,
setloginStateChangeEvent
-} from './lib/common/login';
+} from './lib/common/login'
import {
debug,
@@ -31,7 +35,7 @@ import {
noteurl,
urlpath,
version
-} from './lib/config';
+} from './lib/config'
import {
autoLinkify,
@@ -53,14 +57,14 @@ import {
updateLastChange,
updateLastChangeUser,
updateOwner
-} from './extra';
+} from './extra'
import {
clearMap,
setupSyncAreas,
syncScrollToEdit,
syncScrollToView
-} from './syncscroll';
+} from './syncscroll'
import {
writeHistory,
@@ -68,4007 +72,3856 @@ import {
getHistory,
saveHistory,
removeHistory
-} from './history';
+} from './history'
-var renderer = require('./render');
-var preventXSS = renderer.preventXSS;
+var renderer = require('./render')
+var preventXSS = renderer.preventXSS
-var defaultTextHeight = 20;
-var viewportMargin = 20;
-var mac = CodeMirror.keyMap["default"] == CodeMirror.keyMap.macDefault;
-var defaultEditorMode = 'gfm';
+var defaultTextHeight = 20
+var viewportMargin = 20
+var mac = CodeMirror.keyMap['default'] === CodeMirror.keyMap.macDefault
+var defaultEditorMode = 'gfm'
var defaultExtraKeys = {
- "F10": function (cm) {
- cm.setOption("fullScreen", !cm.getOption("fullScreen"));
- },
- "Esc": function (cm) {
- if (cm.getOption('keyMap').substr(0, 3) === 'vim') return CodeMirror.Pass;
- else if (cm.getOption("fullScreen")) cm.setOption("fullScreen", false);
- },
- "Cmd-S": function () {
- return false;
- },
- "Ctrl-S": function () {
- return false;
- },
- "Enter": "newlineAndIndentContinueMarkdownList",
- "Tab": function (cm) {
- var tab = '\t';
- var spaces = Array(parseInt(cm.getOption("indentUnit")) + 1).join(" ");
- //auto indent whole line when in list or blockquote
- var cursor = cm.getCursor();
- var line = cm.getLine(cursor.line);
- var regex = /^(\s*)(>[> ]*|[*+-]\s|(\d+)([.)]))/;
- var match;
- var multiple = cm.getSelection().split('\n').length > 1 || cm.getSelections().length > 1;
- if (multiple) {
- cm.execCommand('defaultTab');
- } else if ((match = regex.exec(line)) !== null) {
- var ch = match[1].length;
- var pos = {
- line: cursor.line,
- ch: ch
- };
- if (cm.getOption('indentWithTabs'))
- cm.replaceRange(tab, pos, pos, '+input');
- else
- cm.replaceRange(spaces, pos, pos, '+input');
- } else {
- if (cm.getOption('indentWithTabs'))
- cm.execCommand('defaultTab');
- else {
- cm.replaceSelection(spaces);
- }
- }
- },
- "Cmd-Left": "goLineLeftSmart",
- "Cmd-Right": "goLineRight",
- "Ctrl-C": function (cm) {
- if (!mac && cm.getOption('keyMap').substr(0, 3) === 'vim') document.execCommand("copy");
- else return CodeMirror.Pass;
- },
- "Ctrl-*": function (cm) {
- wrapTextWith(cm, '*');
- },
- "Shift-Ctrl-8": function (cm) {
- wrapTextWith(cm, '*');
- },
- "Ctrl-_": function (cm) {
- wrapTextWith(cm, '_');
- },
- "Shift-Ctrl--": function (cm) {
- wrapTextWith(cm, '_');
- },
- "Ctrl-~": function (cm) {
- wrapTextWith(cm, '~');
- },
- "Shift-Ctrl-`": function (cm) {
- wrapTextWith(cm, '~');
- },
- "Ctrl-^": function (cm) {
- wrapTextWith(cm, '^');
- },
- "Shift-Ctrl-6": function (cm) {
- wrapTextWith(cm, '^');
- },
- "Ctrl-+": function (cm) {
- wrapTextWith(cm, '+');
- },
- "Shift-Ctrl-=": function (cm) {
- wrapTextWith(cm, '+');
- },
- "Ctrl-=": function (cm) {
- wrapTextWith(cm, '=');
- },
- "Shift-Ctrl-Backspace": function (cm) {
- wrapTextWith(cm, 'Backspace');
- }
-};
-
-var wrapSymbols = ['*', '_', '~', '^', '+', '='];
-
-function wrapTextWith(cm, symbol) {
- if (!cm.getSelection()) {
- return CodeMirror.Pass;
+ 'F10': function (cm) {
+ cm.setOption('fullScreen', !cm.getOption('fullScreen'))
+ },
+ 'Esc': function (cm) {
+ if (cm.getOption('keyMap').substr(0, 3) === 'vim') return CodeMirror.Pass
+ else if (cm.getOption('fullScreen')) cm.setOption('fullScreen', false)
+ },
+ 'Cmd-S': function () {
+ return false
+ },
+ 'Ctrl-S': function () {
+ return false
+ },
+ 'Enter': 'newlineAndIndentContinueMarkdownList',
+ 'Tab': function (cm) {
+ var tab = '\t'
+ var spaces = Array(parseInt(cm.getOption('indentUnit')) + 1).join(' ')
+ // auto indent whole line when in list or blockquote
+ var cursor = cm.getCursor()
+ var line = cm.getLine(cursor.line)
+ var regex = /^(\s*)(>[> ]*|[*+-]\s|(\d+)([.)]))/
+ var match
+ var multiple = cm.getSelection().split('\n').length > 1 || cm.getSelections().length > 1
+ if (multiple) {
+ cm.execCommand('defaultTab')
+ } else if ((match = regex.exec(line)) !== null) {
+ var ch = match[1].length
+ var pos = {
+ line: cursor.line,
+ ch: ch
+ }
+ if (cm.getOption('indentWithTabs')) { cm.replaceRange(tab, pos, pos, '+input') } else { cm.replaceRange(spaces, pos, pos, '+input') }
} else {
- var ranges = cm.listSelections();
- for (var i = 0; i < ranges.length; i++) {
- var range = ranges[i];
- if (!range.empty()) {
- var from = range.from(), to = range.to();
- if (symbol !== 'Backspace') {
- cm.replaceRange(symbol, to, to, '+input');
- cm.replaceRange(symbol, from, from, '+input');
+ if (cm.getOption('indentWithTabs')) { cm.execCommand('defaultTab') } else {
+ cm.replaceSelection(spaces)
+ }
+ }
+ },
+ 'Cmd-Left': 'goLineLeftSmart',
+ 'Cmd-Right': 'goLineRight',
+ 'Ctrl-C': function (cm) {
+ if (!mac && cm.getOption('keyMap').substr(0, 3) === 'vim') document.execCommand('copy')
+ else return CodeMirror.Pass
+ },
+ 'Ctrl-*': function (cm) {
+ wrapTextWith(cm, '*')
+ },
+ 'Shift-Ctrl-8': function (cm) {
+ wrapTextWith(cm, '*')
+ },
+ 'Ctrl-_': function (cm) {
+ wrapTextWith(cm, '_')
+ },
+ 'Shift-Ctrl--': function (cm) {
+ wrapTextWith(cm, '_')
+ },
+ 'Ctrl-~': function (cm) {
+ wrapTextWith(cm, '~')
+ },
+ 'Shift-Ctrl-`': function (cm) {
+ wrapTextWith(cm, '~')
+ },
+ 'Ctrl-^': function (cm) {
+ wrapTextWith(cm, '^')
+ },
+ 'Shift-Ctrl-6': function (cm) {
+ wrapTextWith(cm, '^')
+ },
+ 'Ctrl-+': function (cm) {
+ wrapTextWith(cm, '+')
+ },
+ 'Shift-Ctrl-=': function (cm) {
+ wrapTextWith(cm, '+')
+ },
+ 'Ctrl-=': function (cm) {
+ wrapTextWith(cm, '=')
+ },
+ 'Shift-Ctrl-Backspace': function (cm) {
+ wrapTextWith(cm, 'Backspace')
+ }
+}
+
+var wrapSymbols = ['*', '_', '~', '^', '+', '=']
+
+function wrapTextWith (cm, symbol) {
+ if (!cm.getSelection()) {
+ return CodeMirror.Pass
+ } else {
+ var ranges = cm.listSelections()
+ for (var i = 0; i < ranges.length; i++) {
+ var range = ranges[i]
+ if (!range.empty()) {
+ var from = range.from()
+ var to = range.to()
+ if (symbol !== 'Backspace') {
+ cm.replaceRange(symbol, to, to, '+input')
+ cm.replaceRange(symbol, from, from, '+input')
// workaround selection range not correct after add symbol
- var _ranges = cm.listSelections();
- var anchorIndex = editor.indexFromPos(_ranges[i].anchor);
- var headIndex = editor.indexFromPos(_ranges[i].head);
- if (anchorIndex > headIndex) {
- _ranges[i].anchor.ch--;
- } else {
- _ranges[i].head.ch--;
- }
- cm.setSelections(_ranges);
- } else {
- var preEndPos = {
- line: to.line,
- ch: to.ch + 1
- };
- var preText = cm.getRange(to, preEndPos);
- var preIndex = wrapSymbols.indexOf(preText);
- var postEndPos = {
- line: from.line,
- ch: from.ch - 1
- };
- var postText = cm.getRange(postEndPos, from);
- var postIndex = wrapSymbols.indexOf(postText);
+ var _ranges = cm.listSelections()
+ var anchorIndex = window.editor.indexFromPos(_ranges[i].anchor)
+ var headIndex = window.editor.indexFromPos(_ranges[i].head)
+ if (anchorIndex > headIndex) {
+ _ranges[i].anchor.ch--
+ } else {
+ _ranges[i].head.ch--
+ }
+ cm.setSelections(_ranges)
+ } else {
+ var preEndPos = {
+ line: to.line,
+ ch: to.ch + 1
+ }
+ var preText = cm.getRange(to, preEndPos)
+ var preIndex = wrapSymbols.indexOf(preText)
+ var postEndPos = {
+ line: from.line,
+ ch: from.ch - 1
+ }
+ var postText = cm.getRange(postEndPos, from)
+ var postIndex = wrapSymbols.indexOf(postText)
// check if surround symbol are list in array and matched
- if (preIndex > -1 && postIndex > -1 && preIndex === postIndex) {
- cm.replaceRange("", to, preEndPos, '+delete');
- cm.replaceRange("", postEndPos, from, '+delete');
- }
- }
- }
+ if (preIndex > -1 && postIndex > -1 && preIndex === postIndex) {
+ cm.replaceRange('', to, preEndPos, '+delete')
+ cm.replaceRange('', postEndPos, from, '+delete')
+ }
}
+ }
}
+ }
}
-var idleTime = 300000; //5 mins
-var updateViewDebounce = 100;
-var cursorMenuThrottle = 50;
-var cursorActivityDebounce = 50;
-var cursorAnimatePeriod = 100;
-var supportContainers = ['success', 'info', 'warning', 'danger'];
-var supportCodeModes = ['javascript', 'typescript', 'jsx', 'htmlmixed', 'htmlembedded', 'css', 'xml', 'clike', 'clojure', 'ruby', 'python', 'shell', 'php', 'sql', 'haskell', 'coffeescript', 'yaml', 'pug', 'lua', 'cmake', 'nginx', 'perl', 'sass', 'r', 'dockerfile', 'tiddlywiki', 'mediawiki', 'go'];
-var supportCharts = ['sequence', 'flow', 'graphviz', 'mermaid'];
+var idleTime = 300000 // 5 mins
+var updateViewDebounce = 100
+var cursorMenuThrottle = 50
+var cursorActivityDebounce = 50
+var cursorAnimatePeriod = 100
+var supportContainers = ['success', 'info', 'warning', 'danger']
+var supportCodeModes = ['javascript', 'typescript', 'jsx', 'htmlmixed', 'htmlembedded', 'css', 'xml', 'clike', 'clojure', 'ruby', 'python', 'shell', 'php', 'sql', 'haskell', 'coffeescript', 'yaml', 'pug', 'lua', 'cmake', 'nginx', 'perl', 'sass', 'r', 'dockerfile', 'tiddlywiki', 'mediawiki', 'go']
+var supportCharts = ['sequence', 'flow', 'graphviz', 'mermaid']
var supportHeaders = [
- {
- text: '# h1',
- search: '#'
- },
- {
- text: '## h2',
- search: '##'
- },
- {
- text: '### h3',
- search: '###'
- },
- {
- text: '#### h4',
- search: '####'
- },
- {
- text: '##### h5',
- search: '#####'
- },
- {
- text: '###### h6',
- search: '######'
- },
- {
- text: '###### tags: `example`',
- search: '###### tags:'
- }
-];
+ {
+ text: '# h1',
+ search: '#'
+ },
+ {
+ text: '## h2',
+ search: '##'
+ },
+ {
+ text: '### h3',
+ search: '###'
+ },
+ {
+ text: '#### h4',
+ search: '####'
+ },
+ {
+ text: '##### h5',
+ search: '#####'
+ },
+ {
+ text: '###### h6',
+ search: '######'
+ },
+ {
+ text: '###### tags: `example`',
+ search: '###### tags:'
+ }
+]
var supportReferrals = [
- {
- text: '[reference link]',
- search: '[]'
- },
- {
- text: '[reference]: https:// "title"',
- search: '[]:'
- },
- {
- text: '[^footnote link]',
- search: '[^]'
- },
- {
- text: '[^footnote reference]: https:// "title"',
- search: '[^]:'
- },
- {
- text: '^[inline footnote]',
- search: '^[]'
- },
- {
- text: '[link text][reference]',
- search: '[][]'
- },
- {
- text: '[link text](https:// "title")',
- search: '[]()'
- },
- {
- text: '![image alt][reference]',
- search: '![][]'
- },
- {
- text: '![image alt](https:// "title")',
- search: '![]()'
- },
- {
- text: '![image alt](https:// "title" =WidthxHeight)',
- search: '![]()'
- },
- {
- text: '[TOC]',
- search: '[]'
- }
-];
+ {
+ text: '[reference link]',
+ search: '[]'
+ },
+ {
+ text: '[reference]: https:// "title"',
+ search: '[]:'
+ },
+ {
+ text: '[^footnote link]',
+ search: '[^]'
+ },
+ {
+ text: '[^footnote reference]: https:// "title"',
+ search: '[^]:'
+ },
+ {
+ text: '^[inline footnote]',
+ search: '^[]'
+ },
+ {
+ text: '[link text][reference]',
+ search: '[][]'
+ },
+ {
+ text: '[link text](https:// "title")',
+ search: '[]()'
+ },
+ {
+ text: '![image alt][reference]',
+ search: '![][]'
+ },
+ {
+ text: '![image alt](https:// "title")',
+ search: '![]()'
+ },
+ {
+ text: '![image alt](https:// "title" =WidthxHeight)',
+ search: '![]()'
+ },
+ {
+ text: '[TOC]',
+ search: '[]'
+ }
+]
var supportExternals = [
- {
- text: '{%youtube youtubeid %}',
- search: 'youtube'
- },
- {
- text: '{%vimeo vimeoid %}',
- search: 'vimeo'
- },
- {
- text: '{%gist gistid %}',
- search: 'gist'
- },
- {
- text: '{%slideshare slideshareid %}',
- search: 'slideshare'
- },
- {
- text: '{%speakerdeck speakerdeckid %}',
- search: 'speakerdeck'
- },
- {
- text: '{%pdf pdfurl %}',
- search: 'pdf'
- }
-];
+ {
+ text: '{%youtube youtubeid %}',
+ search: 'youtube'
+ },
+ {
+ text: '{%vimeo vimeoid %}',
+ search: 'vimeo'
+ },
+ {
+ text: '{%gist gistid %}',
+ search: 'gist'
+ },
+ {
+ text: '{%slideshare slideshareid %}',
+ search: 'slideshare'
+ },
+ {
+ text: '{%speakerdeck speakerdeckid %}',
+ search: 'speakerdeck'
+ },
+ {
+ text: '{%pdf pdfurl %}',
+ search: 'pdf'
+ }
+]
var supportExtraTags = [
- {
- text: '[name tag]',
- search: '[]',
- command: function () {
- return '[name=' + personalInfo.name + ']';
- },
- },
- {
- text: '[time tag]',
- search: '[]',
- command: function () {
- return '[time=' + moment().format('llll') + ']';
- },
- },
- {
- text: '[my color tag]',
- search: '[]',
- command: function () {
- return '[color=' + personalInfo.color + ']';
- }
- },
- {
- text: '[random color tag]',
- search: '[]',
- command: function () {
- var color = randomColor();
- return '[color=' + color + ']';
- }
- }
-];
+ {
+ text: '[name tag]',
+ search: '[]',
+ command: function () {
+ return '[name=' + window.personalInfo.name + ']'
+ }
+ },
+ {
+ text: '[time tag]',
+ search: '[]',
+ command: function () {
+ return '[time=' + moment().format('llll') + ']'
+ }
+ },
+ {
+ text: '[my color tag]',
+ search: '[]',
+ command: function () {
+ return '[color=' + window.personalInfo.color + ']'
+ }
+ },
+ {
+ text: '[random color tag]',
+ search: '[]',
+ command: function () {
+ var color = randomColor()
+ return '[color=' + color + ']'
+ }
+ }
+]
window.modeType = {
- edit: {
- name: "edit"
- },
- view: {
- name: "view"
- },
- both: {
- name: "both"
- }
-};
+ edit: {
+ name: 'edit'
+ },
+ view: {
+ name: 'view'
+ },
+ both: {
+ name: 'both'
+ }
+}
var statusType = {
- connected: {
- msg: "CONNECTED",
- label: "label-warning",
- fa: "fa-wifi"
- },
- online: {
- msg: "ONLINE",
- label: "label-primary",
- fa: "fa-users"
- },
- offline: {
- msg: "OFFLINE",
- label: "label-danger",
- fa: "fa-plug"
- }
-};
-var defaultMode = modeType.view;
-
-//global vars
-window.loaded = false;
-window.needRefresh = false;
-window.isDirty = false;
-window.editShown = false;
-window.visibleXS = false;
-window.visibleSM = false;
-window.visibleMD = false;
-window.visibleLG = false;
-window.isTouchDevice = 'ontouchstart' in document.documentElement;
-window.currentMode = defaultMode;
-window.currentStatus = statusType.offline;
+ connected: {
+ msg: 'CONNECTED',
+ label: 'label-warning',
+ fa: 'fa-wifi'
+ },
+ online: {
+ msg: 'ONLINE',
+ label: 'label-primary',
+ fa: 'fa-users'
+ },
+ offline: {
+ msg: 'OFFLINE',
+ label: 'label-danger',
+ fa: 'fa-plug'
+ }
+}
+var defaultMode = modeType.view
+
+// global vars
+window.loaded = false
+window.needRefresh = false
+window.isDirty = false
+window.editShown = false
+window.visibleXS = false
+window.visibleSM = false
+window.visibleMD = false
+window.visibleLG = false
+window.isTouchDevice = 'ontouchstart' in document.documentElement
+window.currentMode = defaultMode
+window.currentStatus = statusType.offline
window.lastInfo = {
- needRestore: false,
- cursor: null,
- scroll: null,
- edit: {
- scroll: {
- left: null,
- top: null
- },
- cursor: {
- line: null,
- ch: null
- },
- selections: null
+ needRestore: false,
+ cursor: null,
+ scroll: null,
+ edit: {
+ scroll: {
+ left: null,
+ top: null
},
- view: {
- scroll: {
- left: null,
- top: null
- }
+ cursor: {
+ line: null,
+ ch: null
},
- history: null
-};
-window.personalInfo = {};
-window.onlineUsers = [];
+ selections: null
+ },
+ view: {
+ scroll: {
+ left: null,
+ top: null
+ }
+ },
+ history: null
+}
+window.personalInfo = {}
+window.onlineUsers = []
window.fileTypes = {
- "pl": "perl",
- "cgi": "perl",
- "js": "javascript",
- "php": "php",
- "sh": "bash",
- "rb": "ruby",
- "html": "html",
- "py": "python"
-};
-
-//editor settings
-var textit = document.getElementById("textit");
-if (!textit) throw new Error("There was no textit area!");
+ 'pl': 'perl',
+ 'cgi': 'perl',
+ 'js': 'javascript',
+ 'php': 'php',
+ 'sh': 'bash',
+ 'rb': 'ruby',
+ 'html': 'html',
+ 'py': 'python'
+}
+
+// editor settings
+var textit = document.getElementById('textit')
+if (!textit) throw new Error('There was no textit area!')
window.editor = CodeMirror.fromTextArea(textit, {
- mode: defaultEditorMode,
- backdrop: defaultEditorMode,
- keyMap: "sublime",
- viewportMargin: viewportMargin,
- styleActiveLine: true,
- lineNumbers: true,
- lineWrapping: true,
- showCursorWhenSelecting: true,
- highlightSelectionMatches: true,
- indentUnit: 4,
- continueComments: "Enter",
- theme: "one-dark",
- inputStyle: "textarea",
- matchBrackets: true,
- autoCloseBrackets: true,
- matchTags: {
- bothTags: true
- },
- autoCloseTags: true,
- foldGutter: true,
- gutters: ["CodeMirror-linenumbers", "authorship-gutters", "CodeMirror-foldgutter"],
- extraKeys: defaultExtraKeys,
- flattenSpans: true,
- addModeClass: true,
- readOnly: true,
- autoRefresh: true,
- otherCursors: true,
- placeholder: "← Start by entering a title here\n===\nVisit /features if you don't know what to do.\nHappy hacking :)"
-});
-var inlineAttach = inlineAttachment.editors.codemirror4.attach(editor);
-defaultTextHeight = parseInt($(".CodeMirror").css('line-height'));
-
-var statusBarTemplate = null;
-var statusBar = null;
-var statusPanel = null;
-var statusCursor = null;
-var statusFile = null;
-var statusIndicators = null;
-var statusLength = null;
-var statusKeymap = null;
-var statusIndent = null;
-var statusTheme = null;
-var statusSpellcheck = null;
-var statusPreferences = null;
-
-function getStatusBarTemplate(callback) {
- $.get(serverurl + '/views/statusbar.html', function (template) {
- statusBarTemplate = template;
- if (callback) callback();
- });
-}
-getStatusBarTemplate();
-
-function addStatusBar() {
- if (!statusBarTemplate) {
- getStatusBarTemplate(addStatusBar);
- return;
- }
- statusBar = $(statusBarTemplate);
- statusCursor = statusBar.find('.status-cursor');
- statusFile = statusBar.find('.status-file');
- statusIndicators = statusBar.find('.status-indicators');
- statusIndent = statusBar.find('.status-indent');
- statusKeymap = statusBar.find('.status-keymap');
- statusLength = statusBar.find('.status-length');
- statusTheme = statusBar.find('.status-theme');
- statusSpellcheck = statusBar.find('.status-spellcheck');
- statusPreferences = statusBar.find('.status-preferences');
- statusPanel = editor.addPanel(statusBar[0], {
- position: "bottom"
- });
-
- setIndent();
- setKeymap();
- setTheme();
- setSpellcheck();
- setPreferences();
-}
-
-function setIndent() {
- var cookieIndentType = Cookies.get('indent_type');
- var cookieTabSize = parseInt(Cookies.get('tab_size'));
- var cookieSpaceUnits = parseInt(Cookies.get('space_units'));
- if (cookieIndentType) {
- if (cookieIndentType == 'tab') {
- editor.setOption('indentWithTabs', true);
- if (cookieTabSize)
- editor.setOption('indentUnit', cookieTabSize);
- } else if (cookieIndentType == 'space') {
- editor.setOption('indentWithTabs', false);
- if (cookieSpaceUnits)
- editor.setOption('indentUnit', cookieSpaceUnits);
- }
- }
- if (cookieTabSize)
- editor.setOption('tabSize', cookieTabSize);
-
- var type = statusIndicators.find('.indent-type');
- var widthLabel = statusIndicators.find('.indent-width-label');
- var widthInput = statusIndicators.find('.indent-width-input');
-
- function setType() {
- if (editor.getOption('indentWithTabs')) {
- Cookies.set('indent_type', 'tab', {
- expires: 365
- });
- type.text('Tab Size:');
- } else {
- Cookies.set('indent_type', 'space', {
- expires: 365
- });
- type.text('Spaces:');
- }
- }
- setType();
-
- function setUnit() {
- var unit = editor.getOption('indentUnit');
- if (editor.getOption('indentWithTabs')) {
- Cookies.set('tab_size', unit, {
- expires: 365
- });
- } else {
- Cookies.set('space_units', unit, {
- expires: 365
- });
- }
- widthLabel.text(unit);
+ mode: defaultEditorMode,
+ backdrop: defaultEditorMode,
+ keyMap: 'sublime',
+ viewportMargin: viewportMargin,
+ styleActiveLine: true,
+ lineNumbers: true,
+ lineWrapping: true,
+ showCursorWhenSelecting: true,
+ highlightSelectionMatches: true,
+ indentUnit: 4,
+ continueComments: 'Enter',
+ theme: 'one-dark',
+ inputStyle: 'textarea',
+ matchBrackets: true,
+ autoCloseBrackets: true,
+ matchTags: {
+ bothTags: true
+ },
+ autoCloseTags: true,
+ foldGutter: true,
+ gutters: ['CodeMirror-linenumbers', 'authorship-gutters', 'CodeMirror-foldgutter'],
+ extraKeys: defaultExtraKeys,
+ flattenSpans: true,
+ addModeClass: true,
+ readOnly: true,
+ autoRefresh: true,
+ otherCursors: true,
+ placeholder: "← Start by entering a title here\n===\nVisit /features if you don't know what to do.\nHappy hacking :)"
+})
+var inlineAttach = window.inlineAttachment.editors.codemirror4.attach(editor)
+defaultTextHeight = parseInt($('.CodeMirror').css('line-height'))
+
+var statusBarTemplate = null
+var statusBar = null
+var statusCursor = null
+var statusFile = null
+var statusIndicators = null
+var statusLength = null
+var statusTheme = null
+var statusSpellcheck = null
+
+function getStatusBarTemplate (callback) {
+ $.get(serverurl + '/views/statusbar.html', function (template) {
+ statusBarTemplate = template
+ if (callback) callback()
+ })
+}
+getStatusBarTemplate()
+
+function addStatusBar () {
+ if (!statusBarTemplate) {
+ getStatusBarTemplate(addStatusBar)
+ return
+ }
+ statusBar = $(statusBarTemplate)
+ statusCursor = statusBar.find('.status-cursor')
+ statusFile = statusBar.find('.status-file')
+ statusIndicators = statusBar.find('.status-indicators')
+ statusBar.find('.status-indent')
+ statusBar.find('.status-keymap')
+ statusLength = statusBar.find('.status-length')
+ statusTheme = statusBar.find('.status-theme')
+ statusSpellcheck = statusBar.find('.status-spellcheck')
+ statusBar.find('.status-preferences')
+ editor.addPanel(statusBar[0], {
+ position: 'bottom'
+ })
+
+ setIndent()
+ setKeymap()
+ setTheme()
+ setSpellcheck()
+ setPreferences()
+}
+
+function setIndent () {
+ var cookieIndentType = Cookies.get('indent_type')
+ var cookieTabSize = parseInt(Cookies.get('tab_size'))
+ var cookieSpaceUnits = parseInt(Cookies.get('space_units'))
+ if (cookieIndentType) {
+ if (cookieIndentType === 'tab') {
+ editor.setOption('indentWithTabs', true)
+ if (cookieTabSize) { editor.setOption('indentUnit', cookieTabSize) }
+ } else if (cookieIndentType === 'space') {
+ editor.setOption('indentWithTabs', false)
+ if (cookieSpaceUnits) { editor.setOption('indentUnit', cookieSpaceUnits) }
+ }
+ }
+ if (cookieTabSize) { editor.setOption('tabSize', cookieTabSize) }
+
+ var type = statusIndicators.find('.indent-type')
+ var widthLabel = statusIndicators.find('.indent-width-label')
+ var widthInput = statusIndicators.find('.indent-width-input')
+
+ function setType () {
+ if (editor.getOption('indentWithTabs')) {
+ Cookies.set('indent_type', 'tab', {
+ expires: 365
+ })
+ type.text('Tab Size:')
+ } else {
+ Cookies.set('indent_type', 'space', {
+ expires: 365
+ })
+ type.text('Spaces:')
+ }
+ }
+ setType()
+
+ function setUnit () {
+ var unit = editor.getOption('indentUnit')
+ if (editor.getOption('indentWithTabs')) {
+ Cookies.set('tab_size', unit, {
+ expires: 365
+ })
+ } else {
+ Cookies.set('space_units', unit, {
+ expires: 365
+ })
+ }
+ widthLabel.text(unit)
+ }
+ setUnit()
+
+ type.click(function () {
+ if (editor.getOption('indentWithTabs')) {
+ editor.setOption('indentWithTabs', false)
+ cookieSpaceUnits = parseInt(Cookies.get('space_units'))
+ if (cookieSpaceUnits) { editor.setOption('indentUnit', cookieSpaceUnits) }
+ } else {
+ editor.setOption('indentWithTabs', true)
+ cookieTabSize = parseInt(Cookies.get('tab_size'))
+ if (cookieTabSize) {
+ editor.setOption('indentUnit', cookieTabSize)
+ editor.setOption('tabSize', cookieTabSize)
+ }
+ }
+ setType()
+ setUnit()
+ })
+ widthLabel.click(function () {
+ if (widthLabel.is(':visible')) {
+ widthLabel.addClass('hidden')
+ widthInput.removeClass('hidden')
+ widthInput.val(editor.getOption('indentUnit'))
+ widthInput.select()
+ } else {
+ widthLabel.removeClass('hidden')
+ widthInput.addClass('hidden')
+ }
+ })
+ widthInput.on('change', function () {
+ var val = parseInt(widthInput.val())
+ if (!val) val = editor.getOption('indentUnit')
+ if (val < 1) val = 1
+ else if (val > 10) val = 10
+
+ if (editor.getOption('indentWithTabs')) {
+ editor.setOption('tabSize', val)
+ }
+ editor.setOption('indentUnit', val)
+ setUnit()
+ })
+ widthInput.on('blur', function () {
+ widthLabel.removeClass('hidden')
+ widthInput.addClass('hidden')
+ })
+}
+
+function setKeymap () {
+ var cookieKeymap = Cookies.get('keymap')
+ if (cookieKeymap) { editor.setOption('keyMap', cookieKeymap) }
+
+ var label = statusIndicators.find('.ui-keymap-label')
+ var sublime = statusIndicators.find('.ui-keymap-sublime')
+ var emacs = statusIndicators.find('.ui-keymap-emacs')
+ var vim = statusIndicators.find('.ui-keymap-vim')
+
+ function setKeymapLabel () {
+ var keymap = editor.getOption('keyMap')
+ Cookies.set('keymap', keymap, {
+ expires: 365
+ })
+ label.text(keymap)
+ restoreOverrideEditorKeymap()
+ setOverrideBrowserKeymap()
+ }
+ setKeymapLabel()
+
+ sublime.click(function () {
+ editor.setOption('keyMap', 'sublime')
+ setKeymapLabel()
+ })
+ emacs.click(function () {
+ editor.setOption('keyMap', 'emacs')
+ setKeymapLabel()
+ })
+ vim.click(function () {
+ editor.setOption('keyMap', 'vim')
+ setKeymapLabel()
+ })
+}
+
+function setTheme () {
+ var cookieTheme = Cookies.get('theme')
+ if (cookieTheme) {
+ editor.setOption('theme', cookieTheme)
+ }
+
+ var themeToggle = statusTheme.find('.ui-theme-toggle')
+ themeToggle.click(function () {
+ var theme = editor.getOption('theme')
+ if (theme === 'one-dark') {
+ theme = 'default'
+ } else {
+ theme = 'one-dark'
}
- setUnit();
-
- type.click(function () {
- if (editor.getOption('indentWithTabs')) {
- editor.setOption('indentWithTabs', false);
- cookieSpaceUnits = parseInt(Cookies.get('space_units'));
- if (cookieSpaceUnits)
- editor.setOption('indentUnit', cookieSpaceUnits)
- } else {
- editor.setOption('indentWithTabs', true);
- cookieTabSize = parseInt(Cookies.get('tab_size'));
- if (cookieTabSize) {
- editor.setOption('indentUnit', cookieTabSize);
- editor.setOption('tabSize', cookieTabSize);
- }
- }
- setType();
- setUnit();
- });
- widthLabel.click(function () {
- if (widthLabel.is(':visible')) {
- widthLabel.addClass('hidden');
- widthInput.removeClass('hidden');
- widthInput.val(editor.getOption('indentUnit'));
- widthInput.select();
- } else {
- widthLabel.removeClass('hidden');
- widthInput.addClass('hidden');
- }
- });
- widthInput.on('change', function () {
- var val = parseInt(widthInput.val());
- if (!val) val = editor.getOption('indentUnit');
- if (val < 1) val = 1;
- else if (val > 10) val = 10;
-
- if (editor.getOption('indentWithTabs')) {
- editor.setOption('tabSize', val);
- }
- editor.setOption('indentUnit', val);
- setUnit();
- });
- widthInput.on('blur', function () {
- widthLabel.removeClass('hidden');
- widthInput.addClass('hidden');
- });
-}
-
-function setKeymap() {
- var cookieKeymap = Cookies.get('keymap');
- if (cookieKeymap)
- editor.setOption('keyMap', cookieKeymap);
-
- var label = statusIndicators.find('.ui-keymap-label');
- var sublime = statusIndicators.find('.ui-keymap-sublime');
- var emacs = statusIndicators.find('.ui-keymap-emacs');
- var vim = statusIndicators.find('.ui-keymap-vim');
-
- function setKeymapLabel() {
- var keymap = editor.getOption('keyMap');
- Cookies.set('keymap', keymap, {
- expires: 365
- });
- label.text(keymap);
- restoreOverrideEditorKeymap();
- setOverrideBrowserKeymap();
- }
- setKeymapLabel();
-
- sublime.click(function () {
- editor.setOption('keyMap', 'sublime');
- setKeymapLabel();
- });
- emacs.click(function () {
- editor.setOption('keyMap', 'emacs');
- setKeymapLabel();
- });
- vim.click(function () {
- editor.setOption('keyMap', 'vim');
- setKeymapLabel();
- });
-}
-
-function setTheme() {
- var cookieTheme = Cookies.get('theme');
- if (cookieTheme) {
- editor.setOption('theme', cookieTheme);
- }
-
- var themeToggle = statusTheme.find('.ui-theme-toggle');
- themeToggle.click(function () {
- var theme = editor.getOption('theme');
- if (theme == "one-dark") {
- theme = "default";
- } else {
- theme = "one-dark";
- }
- editor.setOption('theme', theme);
- Cookies.set('theme', theme, {
- expires: 365
- });
- checkTheme();
- });
- function checkTheme() {
- var theme = editor.getOption('theme');
- if (theme == "one-dark") {
- themeToggle.removeClass('active');
- } else {
- themeToggle.addClass('active');
- }
+ editor.setOption('theme', theme)
+ Cookies.set('theme', theme, {
+ expires: 365
+ })
+ checkTheme()
+ })
+ function checkTheme () {
+ var theme = editor.getOption('theme')
+ if (theme === 'one-dark') {
+ themeToggle.removeClass('active')
+ } else {
+ themeToggle.addClass('active')
}
- checkTheme();
+ }
+ checkTheme()
}
-function setSpellcheck() {
- var cookieSpellcheck = Cookies.get('spellcheck');
- if (cookieSpellcheck) {
- var mode = null;
- if (cookieSpellcheck === 'true' || cookieSpellcheck === true) {
- mode = 'spell-checker';
- } else {
- mode = defaultEditorMode;
- }
- if (mode && mode !== editor.getOption('mode')) {
- editor.setOption('mode', mode);
- }
- }
-
- var spellcheckToggle = statusSpellcheck.find('.ui-spellcheck-toggle');
- spellcheckToggle.click(function () {
- var mode = editor.getOption('mode');
- if (mode == defaultEditorMode) {
- mode = "spell-checker";
- } else {
- mode = defaultEditorMode;
- }
- if (mode && mode !== editor.getOption('mode')) {
- editor.setOption('mode', mode);
- }
- Cookies.set('spellcheck', (mode == "spell-checker"), {
- expires: 365
- });
- checkSpellcheck();
- });
- function checkSpellcheck() {
- var mode = editor.getOption('mode');
- if (mode == defaultEditorMode) {
- spellcheckToggle.removeClass('active');
- } else {
- spellcheckToggle.addClass('active');
- }
+function setSpellcheck () {
+ var cookieSpellcheck = Cookies.get('spellcheck')
+ if (cookieSpellcheck) {
+ var mode = null
+ if (cookieSpellcheck === 'true' || cookieSpellcheck === true) {
+ mode = 'spell-checker'
+ } else {
+ mode = defaultEditorMode
}
- checkSpellcheck();
-
- //workaround spellcheck might not activate beacuse the ajax loading
- if (num_loaded < 2) {
- var spellcheckTimer = setInterval(function () {
- if (num_loaded >= 2) {
- if (editor.getOption('mode') == "spell-checker")
- editor.setOption('mode', "spell-checker");
- clearInterval(spellcheckTimer);
- }
- }, 100);
+ if (mode && mode !== editor.getOption('mode')) {
+ editor.setOption('mode', mode)
}
-}
+ }
-var jumpToAddressBarKeymapName = mac ? "Cmd-L" : "Ctrl-L";
-var jumpToAddressBarKeymapValue = null;
-function resetEditorKeymapToBrowserKeymap() {
- var keymap = editor.getOption('keyMap');
- if (!jumpToAddressBarKeymapValue) {
- jumpToAddressBarKeymapValue = CodeMirror.keyMap[keymap][jumpToAddressBarKeymapName];
- delete CodeMirror.keyMap[keymap][jumpToAddressBarKeymapName];
- }
-}
-function restoreOverrideEditorKeymap() {
- var keymap = editor.getOption('keyMap');
- if (jumpToAddressBarKeymapValue) {
- CodeMirror.keyMap[keymap][jumpToAddressBarKeymapName] = jumpToAddressBarKeymapValue;
- jumpToAddressBarKeymapValue = null;
- }
-}
-function setOverrideBrowserKeymap() {
- var overrideBrowserKeymap = $('.ui-preferences-override-browser-keymap label > input[type="checkbox"]');
- if(overrideBrowserKeymap.is(":checked")) {
- Cookies.set('preferences-override-browser-keymap', true, {
- expires: 365
- });
- restoreOverrideEditorKeymap();
+ var spellcheckToggle = statusSpellcheck.find('.ui-spellcheck-toggle')
+ spellcheckToggle.click(function () {
+ var mode = editor.getOption('mode')
+ if (mode === defaultEditorMode) {
+ mode = 'spell-checker'
} else {
- Cookies.remove('preferences-override-browser-keymap');
- resetEditorKeymapToBrowserKeymap();
+ mode = defaultEditorMode
}
-}
-
-function setPreferences() {
- var overrideBrowserKeymap = $('.ui-preferences-override-browser-keymap label > input[type="checkbox"]');
- var cookieOverrideBrowserKeymap = Cookies.get('preferences-override-browser-keymap');
- if (cookieOverrideBrowserKeymap && cookieOverrideBrowserKeymap === "true") {
- overrideBrowserKeymap.prop('checked', true);
- } else {
- overrideBrowserKeymap.prop('checked', false);
+ if (mode && mode !== editor.getOption('mode')) {
+ editor.setOption('mode', mode)
}
- setOverrideBrowserKeymap();
-
- overrideBrowserKeymap.change(function() {
- setOverrideBrowserKeymap();
- });
-}
-
-var selection = null;
-
-function updateStatusBar() {
- if (!statusBar) return;
- var cursor = editor.getCursor();
- var cursorText = 'Line ' + (cursor.line + 1) + ', Columns ' + (cursor.ch + 1);
- if (selection) {
- var anchor = selection.anchor;
- var head = selection.head;
- var start = head.line <= anchor.line ? head : anchor;
- var end = head.line >= anchor.line ? head : anchor;
- var selectionText = ' — Selected ';
- var selectionCharCount = Math.abs(head.ch - anchor.ch);
- // borrow from brackets EditorStatusBar.js
- if (start.line !== end.line) {
- var lines = end.line - start.line + 1;
- if (end.ch === 0) {
- lines--;
- }
- selectionText += lines + ' lines';
- } else if (selectionCharCount > 0)
- selectionText += selectionCharCount + ' columns';
- if (start.line !== end.line || selectionCharCount > 0)
- cursorText += selectionText;
- }
- statusCursor.text(cursorText);
- var fileText = ' — ' + editor.lineCount() + ' Lines';
- statusFile.text(fileText);
- var docLength = editor.getValue().length;
- statusLength.text('Length ' + docLength);
- if (docLength > (docmaxlength * 0.95)) {
- statusLength.css('color', 'red');
- statusLength.attr('title', 'Your almost reach note max length limit.');
- } else if (docLength > (docmaxlength * 0.8)) {
- statusLength.css('color', 'orange');
- statusLength.attr('title', 'You nearly fill the note, consider to make more pieces.');
+ Cookies.set('spellcheck', (mode === 'spell-checker'), {
+ expires: 365
+ })
+ checkSpellcheck()
+ })
+ function checkSpellcheck () {
+ var mode = editor.getOption('mode')
+ if (mode === defaultEditorMode) {
+ spellcheckToggle.removeClass('active')
} else {
- statusLength.css('color', 'white');
- statusLength.attr('title', 'You could write up to ' + docmaxlength + ' characters in this note.');
- }
-}
-
-//ui vars
+ spellcheckToggle.addClass('active')
+ }
+ }
+ checkSpellcheck()
+
+ // workaround spellcheck might not activate beacuse the ajax loading
+ /* eslint-disable camelcase */
+ if (num_loaded < 2) {
+ var spellcheckTimer = setInterval(function () {
+ if (num_loaded >= 2) {
+ if (editor.getOption('mode') === 'spell-checker') { editor.setOption('mode', 'spell-checker') }
+ clearInterval(spellcheckTimer)
+ }
+ }, 100)
+ }
+ /* eslint-endable camelcase */
+}
+
+var jumpToAddressBarKeymapName = mac ? 'Cmd-L' : 'Ctrl-L'
+var jumpToAddressBarKeymapValue = null
+function resetEditorKeymapToBrowserKeymap () {
+ var keymap = editor.getOption('keyMap')
+ if (!jumpToAddressBarKeymapValue) {
+ jumpToAddressBarKeymapValue = CodeMirror.keyMap[keymap][jumpToAddressBarKeymapName]
+ delete CodeMirror.keyMap[keymap][jumpToAddressBarKeymapName]
+ }
+}
+function restoreOverrideEditorKeymap () {
+ var keymap = editor.getOption('keyMap')
+ if (jumpToAddressBarKeymapValue) {
+ CodeMirror.keyMap[keymap][jumpToAddressBarKeymapName] = jumpToAddressBarKeymapValue
+ jumpToAddressBarKeymapValue = null
+ }
+}
+function setOverrideBrowserKeymap () {
+ var overrideBrowserKeymap = $('.ui-preferences-override-browser-keymap label > input[type="checkbox"]')
+ if (overrideBrowserKeymap.is(':checked')) {
+ Cookies.set('preferences-override-browser-keymap', true, {
+ expires: 365
+ })
+ restoreOverrideEditorKeymap()
+ } else {
+ Cookies.remove('preferences-override-browser-keymap')
+ resetEditorKeymapToBrowserKeymap()
+ }
+}
+
+function setPreferences () {
+ var overrideBrowserKeymap = $('.ui-preferences-override-browser-keymap label > input[type="checkbox"]')
+ var cookieOverrideBrowserKeymap = Cookies.get('preferences-override-browser-keymap')
+ if (cookieOverrideBrowserKeymap && cookieOverrideBrowserKeymap === 'true') {
+ overrideBrowserKeymap.prop('checked', true)
+ } else {
+ overrideBrowserKeymap.prop('checked', false)
+ }
+ setOverrideBrowserKeymap()
+
+ overrideBrowserKeymap.change(function () {
+ setOverrideBrowserKeymap()
+ })
+}
+
+var selection = null
+
+function updateStatusBar () {
+ if (!statusBar) return
+ var cursor = editor.getCursor()
+ var cursorText = 'Line ' + (cursor.line + 1) + ', Columns ' + (cursor.ch + 1)
+ if (selection) {
+ var anchor = selection.anchor
+ var head = selection.head
+ var start = head.line <= anchor.line ? head : anchor
+ var end = head.line >= anchor.line ? head : anchor
+ var selectionText = ' — Selected '
+ var selectionCharCount = Math.abs(head.ch - anchor.ch)
+ // borrow from brackets EditorStatusBar.js
+ if (start.line !== end.line) {
+ var lines = end.line - start.line + 1
+ if (end.ch === 0) {
+ lines--
+ }
+ selectionText += lines + ' lines'
+ } else if (selectionCharCount > 0) { selectionText += selectionCharCount + ' columns' }
+ if (start.line !== end.line || selectionCharCount > 0) { cursorText += selectionText }
+ }
+ statusCursor.text(cursorText)
+ var fileText = ' — ' + editor.lineCount() + ' Lines'
+ statusFile.text(fileText)
+ var docLength = editor.getValue().length
+ statusLength.text('Length ' + docLength)
+ if (docLength > (docmaxlength * 0.95)) {
+ statusLength.css('color', 'red')
+ statusLength.attr('title', 'Your almost reach note max length limit.')
+ } else if (docLength > (docmaxlength * 0.8)) {
+ statusLength.css('color', 'orange')
+ statusLength.attr('title', 'You nearly fill the note, consider to make more pieces.')
+ } else {
+ statusLength.css('color', 'white')
+ statusLength.attr('title', 'You could write up to ' + docmaxlength + ' characters in this note.')
+ }
+}
+
+// ui vars
window.ui = {
- spinner: $(".ui-spinner"),
- content: $(".ui-content"),
- toolbar: {
- shortStatus: $(".ui-short-status"),
- status: $(".ui-status"),
- new: $(".ui-new"),
- publish: $(".ui-publish"),
- extra: {
- revision: $(".ui-extra-revision"),
- slide: $(".ui-extra-slide")
- },
- download: {
- markdown: $(".ui-download-markdown"),
- html: $(".ui-download-html"),
- rawhtml: $(".ui-download-raw-html"),
- pdf: $(".ui-download-pdf-beta"),
- },
- export: {
- dropbox: $(".ui-save-dropbox"),
- googleDrive: $(".ui-save-google-drive"),
- gist: $(".ui-save-gist"),
- snippet: $(".ui-save-snippet")
- },
- import: {
- dropbox: $(".ui-import-dropbox"),
- googleDrive: $(".ui-import-google-drive"),
- gist: $(".ui-import-gist"),
- snippet: $(".ui-import-snippet"),
- clipboard: $(".ui-import-clipboard")
- },
- mode: $(".ui-mode"),
- edit: $(".ui-edit"),
- view: $(".ui-view"),
- both: $(".ui-both"),
- uploadImage: $(".ui-upload-image")
+ spinner: $('.ui-spinner'),
+ content: $('.ui-content'),
+ toolbar: {
+ shortStatus: $('.ui-short-status'),
+ status: $('.ui-status'),
+ new: $('.ui-new'),
+ publish: $('.ui-publish'),
+ extra: {
+ revision: $('.ui-extra-revision'),
+ slide: $('.ui-extra-slide')
},
- infobar: {
- lastchange: $(".ui-lastchange"),
- lastchangeuser: $(".ui-lastchangeuser"),
- nolastchangeuser: $(".ui-no-lastchangeuser"),
- permission: {
- permission: $(".ui-permission"),
- label: $(".ui-permission-label"),
- freely: $(".ui-permission-freely"),
- editable: $(".ui-permission-editable"),
- locked: $(".ui-permission-locked"),
- private: $(".ui-permission-private"),
- limited: $(".ui-permission-limited"),
- protected: $(".ui-permission-protected")
- },
- delete: $(".ui-delete-note")
+ download: {
+ markdown: $('.ui-download-markdown'),
+ html: $('.ui-download-html'),
+ rawhtml: $('.ui-download-raw-html'),
+ pdf: $('.ui-download-pdf-beta')
},
- toc: {
- toc: $('.ui-toc'),
- affix: $('.ui-affix-toc'),
- label: $('.ui-toc-label'),
- dropdown: $('.ui-toc-dropdown')
+ export: {
+ dropbox: $('.ui-save-dropbox'),
+ googleDrive: $('.ui-save-google-drive'),
+ gist: $('.ui-save-gist'),
+ snippet: $('.ui-save-snippet')
},
- area: {
- edit: $(".ui-edit-area"),
- view: $(".ui-view-area"),
- codemirror: $(".ui-edit-area .CodeMirror"),
- codemirrorScroll: $(".ui-edit-area .CodeMirror .CodeMirror-scroll"),
- codemirrorSizer: $(".ui-edit-area .CodeMirror .CodeMirror-sizer"),
- codemirrorSizerInner: $(".ui-edit-area .CodeMirror .CodeMirror-sizer > div"),
- markdown: $(".ui-view-area .markdown-body"),
- resize: {
- handle: $('.ui-resizable-handle'),
- syncToggle: $('.ui-sync-toggle')
- }
+ import: {
+ dropbox: $('.ui-import-dropbox'),
+ googleDrive: $('.ui-import-google-drive'),
+ gist: $('.ui-import-gist'),
+ snippet: $('.ui-import-snippet'),
+ clipboard: $('.ui-import-clipboard')
},
- modal: {
- snippetImportProjects: $("#snippetImportModalProjects"),
- snippetImportSnippets: $("#snippetImportModalSnippets"),
- revision: $("#revisionModal")
- }
-};
-
-//page actions
+ mode: $('.ui-mode'),
+ edit: $('.ui-edit'),
+ view: $('.ui-view'),
+ both: $('.ui-both'),
+ uploadImage: $('.ui-upload-image')
+ },
+ infobar: {
+ lastchange: $('.ui-lastchange'),
+ lastchangeuser: $('.ui-lastchangeuser'),
+ nolastchangeuser: $('.ui-no-lastchangeuser'),
+ permission: {
+ permission: $('.ui-permission'),
+ label: $('.ui-permission-label'),
+ freely: $('.ui-permission-freely'),
+ editable: $('.ui-permission-editable'),
+ locked: $('.ui-permission-locked'),
+ private: $('.ui-permission-private'),
+ limited: $('.ui-permission-limited'),
+ protected: $('.ui-permission-protected')
+ },
+ delete: $('.ui-delete-note')
+ },
+ toc: {
+ toc: $('.ui-toc'),
+ affix: $('.ui-affix-toc'),
+ label: $('.ui-toc-label'),
+ dropdown: $('.ui-toc-dropdown')
+ },
+ area: {
+ edit: $('.ui-edit-area'),
+ view: $('.ui-view-area'),
+ codemirror: $('.ui-edit-area .CodeMirror'),
+ codemirrorScroll: $('.ui-edit-area .CodeMirror .CodeMirror-scroll'),
+ codemirrorSizer: $('.ui-edit-area .CodeMirror .CodeMirror-sizer'),
+ codemirrorSizerInner: $('.ui-edit-area .CodeMirror .CodeMirror-sizer > div'),
+ markdown: $('.ui-view-area .markdown-body'),
+ resize: {
+ handle: $('.ui-resizable-handle'),
+ syncToggle: $('.ui-sync-toggle')
+ }
+ },
+ modal: {
+ snippetImportProjects: $('#snippetImportModalProjects'),
+ snippetImportSnippets: $('#snippetImportModalSnippets'),
+ revision: $('#revisionModal')
+ }
+}
+
+// page actions
var opts = {
- lines: 11, // The number of lines to draw
- length: 20, // The length of each line
- width: 2, // The line thickness
- radius: 30, // The radius of the inner circle
- corners: 0, // Corner roundness (0..1)
- rotate: 0, // The rotation offset
- direction: 1, // 1: clockwise, -1: counterclockwise
- color: '#000', // #rgb or #rrggbb or array of colors
- speed: 1.1, // Rounds per second
- trail: 60, // Afterglow percentage
- shadow: false, // Whether to render a shadow
- hwaccel: true, // Whether to use hardware acceleration
- className: 'spinner', // The CSS class to assign to the spinner
- zIndex: 2e9, // The z-index (defaults to 2000000000)
- top: '50%', // Top position relative to parent
- left: '50%' // Left position relative to parent
-};
-var spinner = new Spinner(opts).spin(ui.spinner[0]);
-
-//idle
+ lines: 11, // The number of lines to draw
+ length: 20, // The length of each line
+ width: 2, // The line thickness
+ radius: 30, // The radius of the inner circle
+ corners: 0, // Corner roundness (0..1)
+ rotate: 0, // The rotation offset
+ direction: 1, // 1: clockwise, -1: counterclockwise
+ color: '#000', // #rgb or #rrggbb or array of colors
+ speed: 1.1, // Rounds per second
+ trail: 60, // Afterglow percentage
+ shadow: false, // Whether to render a shadow
+ hwaccel: true, // Whether to use hardware acceleration
+ className: 'spinner', // The CSS class to assign to the spinner
+ zIndex: 2e9, // The z-index (defaults to 2000000000)
+ top: '50%', // Top position relative to parent
+ left: '50%' // Left position relative to parent
+}
+
+/* eslint-disable no-unused-vars */
+var spinner = new Spinner(opts).spin(ui.spinner[0])
+/* eslint-enable no-unused-vars */
+
+// idle
var idle = new Idle({
- onAway: function () {
- idle.isAway = true;
- emitUserStatus();
- updateOnlineStatus();
- },
- onAwayBack: function () {
- idle.isAway = false;
- emitUserStatus();
- updateOnlineStatus();
- setHaveUnreadChanges(false);
- updateTitleReminder();
- },
- awayTimeout: idleTime
-});
+ onAway: function () {
+ idle.isAway = true
+ emitUserStatus()
+ updateOnlineStatus()
+ },
+ onAwayBack: function () {
+ idle.isAway = false
+ emitUserStatus()
+ updateOnlineStatus()
+ setHaveUnreadChanges(false)
+ updateTitleReminder()
+ },
+ awayTimeout: idleTime
+})
ui.area.codemirror.on('touchstart', function () {
- idle.onActive();
-});
+ idle.onActive()
+})
-var haveUnreadChanges = false;
+var haveUnreadChanges = false
-function setHaveUnreadChanges(bool) {
- if (!loaded) return;
- if (bool && (idle.isAway || Visibility.hidden())) {
- haveUnreadChanges = true;
- } else if (!bool && !idle.isAway && !Visibility.hidden()) {
- haveUnreadChanges = false;
- }
+function setHaveUnreadChanges (bool) {
+ if (!window.loaded) return
+ if (bool && (idle.isAway || Visibility.hidden())) {
+ haveUnreadChanges = true
+ } else if (!bool && !idle.isAway && !Visibility.hidden()) {
+ haveUnreadChanges = false
+ }
}
-function updateTitleReminder() {
- if (!loaded) return;
- if (haveUnreadChanges) {
- document.title = '• ' + renderTitle(ui.area.markdown);
- } else {
- document.title = renderTitle(ui.area.markdown);
- }
+function updateTitleReminder () {
+ if (!window.loaded) return
+ if (haveUnreadChanges) {
+ document.title = '• ' + renderTitle(ui.area.markdown)
+ } else {
+ document.title = renderTitle(ui.area.markdown)
+ }
}
-function setRefreshModal(status) {
- $('#refreshModal').modal('show');
- $('#refreshModal').find('.modal-body > div').hide();
- $('#refreshModal').find('.' + status).show();
+function setRefreshModal (status) {
+ $('#refreshModal').modal('show')
+ $('#refreshModal').find('.modal-body > div').hide()
+ $('#refreshModal').find('.' + status).show()
}
-function setNeedRefresh() {
- needRefresh = true;
- editor.setOption('readOnly', true);
- socket.disconnect();
- showStatus(statusType.offline);
+function setNeedRefresh () {
+ window.needRefresh = true
+ editor.setOption('readOnly', true)
+ socket.disconnect()
+ showStatus(statusType.offline)
}
setloginStateChangeEvent(function () {
- setRefreshModal('user-state-changed');
- setNeedRefresh();
-});
+ setRefreshModal('user-state-changed')
+ setNeedRefresh()
+})
-//visibility
-var wasFocus = false;
+// visibility
+var wasFocus = false
Visibility.change(function (e, state) {
- var hidden = Visibility.hidden();
- if (hidden) {
- if (editorHasFocus()) {
- wasFocus = true;
- editor.getInputField().blur();
- }
- } else {
- if (wasFocus) {
- if (!visibleXS) {
- editor.focus();
- editor.refresh();
- }
- wasFocus = false;
- }
- setHaveUnreadChanges(false);
- }
- updateTitleReminder();
-});
+ var hidden = Visibility.hidden()
+ if (hidden) {
+ if (editorHasFocus()) {
+ wasFocus = true
+ editor.getInputField().blur()
+ }
+ } else {
+ if (wasFocus) {
+ if (!window.visibleXS) {
+ editor.focus()
+ editor.refresh()
+ }
+ wasFocus = false
+ }
+ setHaveUnreadChanges(false)
+ }
+ updateTitleReminder()
+})
-//when page ready
+// when page ready
$(document).ready(function () {
- idle.checkAway();
- checkResponsive();
- //if in smaller screen, we don't need advanced scrollbar
- var scrollbarStyle;
- if (visibleXS) {
- scrollbarStyle = 'native';
- } else {
- scrollbarStyle = 'overlay';
- }
- if (scrollbarStyle != editor.getOption('scrollbarStyle')) {
- editor.setOption('scrollbarStyle', scrollbarStyle);
- clearMap();
- }
- checkEditorStyle();
+ idle.checkAway()
+ checkResponsive()
+ // if in smaller screen, we don't need advanced scrollbar
+ var scrollbarStyle
+ if (window.visibleXS) {
+ scrollbarStyle = 'native'
+ } else {
+ scrollbarStyle = 'overlay'
+ }
+ if (scrollbarStyle !== editor.getOption('scrollbarStyle')) {
+ editor.setOption('scrollbarStyle', scrollbarStyle)
+ clearMap()
+ }
+ checkEditorStyle()
/* we need this only on touch devices */
- if (isTouchDevice) {
+ if (window.isTouchDevice) {
/* cache dom references */
- var $body = jQuery('body');
+ var $body = jQuery('body')
/* bind events */
- $(document)
+ $(document)
.on('focus', 'textarea, input', function () {
- $body.addClass('fixfixed');
+ $body.addClass('fixfixed')
})
.on('blur', 'textarea, input', function () {
- $body.removeClass('fixfixed');
- });
- }
- //showup
- $().showUp('.navbar', {
- upClass: 'navbar-hide',
- downClass: 'navbar-show'
- });
- //tooltip
- $('[data-toggle="tooltip"]').tooltip();
+ $body.removeClass('fixfixed')
+ })
+ }
+ // showup
+ $().showUp('.navbar', {
+ upClass: 'navbar-hide',
+ downClass: 'navbar-show'
+ })
+ // tooltip
+ $('[data-toggle="tooltip"]').tooltip()
// shortcuts
// allow on all tags
- key.filter = function (e) { return true; };
- key('ctrl+alt+e', function (e) {
- changeMode(modeType.edit);
- });
- key('ctrl+alt+v', function (e) {
- changeMode(modeType.view);
- });
- key('ctrl+alt+b', function (e) {
- changeMode(modeType.both);
- });
+ key.filter = function (e) { return true }
+ key('ctrl+alt+e', function (e) {
+ changeMode(modeType.edit)
+ })
+ key('ctrl+alt+v', function (e) {
+ changeMode(modeType.view)
+ })
+ key('ctrl+alt+b', function (e) {
+ changeMode(modeType.both)
+ })
// toggle-dropdown
- $(document).on('click', '.toggle-dropdown .dropdown-menu', function (e) {
- e.stopPropagation();
- });
-});
-//when page resize
+ $(document).on('click', '.toggle-dropdown .dropdown-menu', function (e) {
+ e.stopPropagation()
+ })
+})
+// when page resize
$(window).resize(function () {
- checkLayout();
- checkEditorStyle();
- checkTocStyle();
- checkCursorMenu();
- windowResize();
-});
-//when page unload
+ checkLayout()
+ checkEditorStyle()
+ checkTocStyle()
+ checkCursorMenu()
+ windowResize()
+})
+// when page unload
$(window).on('unload', function () {
- //updateHistoryInner();
-});
+ // updateHistoryInner();
+})
$(window).on('error', function () {
- //setNeedRefresh();
-});
-
-setupSyncAreas(ui.area.codemirrorScroll, ui.area.view, ui.area.markdown);
+ // setNeedRefresh();
+})
-function autoSyncscroll() {
- if (editorHasFocus()) {
- syncScrollToView();
+setupSyncAreas(ui.area.codemirrorScroll, ui.area.view, ui.area.markdown)
+
+function autoSyncscroll () {
+ if (editorHasFocus()) {
+ syncScrollToView()
+ } else {
+ syncScrollToEdit()
+ }
+}
+
+var windowResizeDebounce = 200
+var windowResize = _.debounce(windowResizeInner, windowResizeDebounce)
+
+function windowResizeInner (callback) {
+ checkLayout()
+ checkResponsive()
+ checkEditorStyle()
+ checkTocStyle()
+ checkCursorMenu()
+ // refresh editor
+ if (window.loaded) {
+ if (editor.getOption('scrollbarStyle') === 'native') {
+ setTimeout(function () {
+ clearMap()
+ autoSyncscroll()
+ updateScrollspy()
+ if (callback && typeof callback === 'function') { callback() }
+ }, 1)
} else {
- syncScrollToEdit();
- }
-}
-
-var windowResizeDebounce = 200;
-var windowResize = _.debounce(windowResizeInner, windowResizeDebounce);
-
-function windowResizeInner(callback) {
- checkLayout();
- checkResponsive();
- checkEditorStyle();
- checkTocStyle();
- checkCursorMenu();
- //refresh editor
- if (loaded) {
- if (editor.getOption('scrollbarStyle') === 'native') {
- setTimeout(function () {
- clearMap();
- autoSyncscroll();
- updateScrollspy();
- if (callback && typeof callback === 'function')
- callback();
- }, 1);
- } else {
// force it load all docs at once to prevent scroll knob blink
- editor.setOption('viewportMargin', Infinity);
- setTimeout(function () {
- clearMap();
- autoSyncscroll();
- editor.setOption('viewportMargin', viewportMargin);
- //add or update user cursors
- for (var i = 0; i < onlineUsers.length; i++) {
- if (onlineUsers[i].id != personalInfo.id)
- buildCursor(onlineUsers[i]);
- }
- updateScrollspy();
- if (callback && typeof callback === 'function')
- callback();
- }, 1);
+ editor.setOption('viewportMargin', Infinity)
+ setTimeout(function () {
+ clearMap()
+ autoSyncscroll()
+ editor.setOption('viewportMargin', viewportMargin)
+ // add or update user cursors
+ for (var i = 0; i < window.onlineUsers.length; i++) {
+ if (window.onlineUsers[i].id !== window.personalInfo.id) { buildCursor(window.onlineUsers[i]) }
}
+ updateScrollspy()
+ if (callback && typeof callback === 'function') { callback() }
+ }, 1)
}
+ }
}
-function checkLayout() {
- var navbarHieght = $('.navbar').outerHeight();
- $('body').css('padding-top', navbarHieght + 'px');
+function checkLayout () {
+ var navbarHieght = $('.navbar').outerHeight()
+ $('body').css('padding-top', navbarHieght + 'px')
}
-function editorHasFocus() {
- return $(editor.getInputField()).is(":focus");
+function editorHasFocus () {
+ return $(editor.getInputField()).is(':focus')
}
-//768-792px have a gap
-function checkResponsive() {
- visibleXS = $(".visible-xs").is(":visible");
- visibleSM = $(".visible-sm").is(":visible");
- visibleMD = $(".visible-md").is(":visible");
- visibleLG = $(".visible-lg").is(":visible");
+// 768-792px have a gap
+function checkResponsive () {
+ window.visibleXS = $('.visible-xs').is(':visible')
+ window.visibleSM = $('.visible-sm').is(':visible')
+ window.visibleMD = $('.visible-md').is(':visible')
+ window.visibleLG = $('.visible-lg').is(':visible')
- if (visibleXS && currentMode == modeType.both)
- if (editorHasFocus())
- changeMode(modeType.edit);
- else
- changeMode(modeType.view);
+ if (window.visibleXS && window.currentMode === modeType.both) {
+ if (editorHasFocus()) { changeMode(modeType.edit) } else { changeMode(modeType.view) }
+ }
- emitUserStatus();
+ emitUserStatus()
}
-var lastEditorWidth = 0;
-var previousFocusOnEditor = null;
+var lastEditorWidth = 0
+var previousFocusOnEditor = null
-function checkEditorStyle() {
- var desireHeight = statusBar ? (ui.area.edit.height() - statusBar.outerHeight()) : ui.area.edit.height();
+function checkEditorStyle () {
+ var desireHeight = statusBar ? (ui.area.edit.height() - statusBar.outerHeight()) : ui.area.edit.height()
// set editor height and min height based on scrollbar style and mode
- var scrollbarStyle = editor.getOption('scrollbarStyle');
- if (scrollbarStyle == 'overlay' || currentMode == modeType.both) {
- ui.area.codemirrorScroll.css('height', desireHeight + 'px');
- ui.area.codemirrorScroll.css('min-height', '');
- checkEditorScrollbar();
- } else if (scrollbarStyle == 'native') {
- ui.area.codemirrorScroll.css('height', '');
- ui.area.codemirrorScroll.css('min-height', desireHeight + 'px');
- }
+ var scrollbarStyle = editor.getOption('scrollbarStyle')
+ if (scrollbarStyle === 'overlay' || window.currentMode === modeType.both) {
+ ui.area.codemirrorScroll.css('height', desireHeight + 'px')
+ ui.area.codemirrorScroll.css('min-height', '')
+ checkEditorScrollbar()
+ } else if (scrollbarStyle === 'native') {
+ ui.area.codemirrorScroll.css('height', '')
+ ui.area.codemirrorScroll.css('min-height', desireHeight + 'px')
+ }
// workaround editor will have wrong doc height when editor height changed
- editor.setSize(null, ui.area.edit.height());
- //make editor resizable
- if (!ui.area.resize.handle.length) {
- ui.area.edit.resizable({
- handles: 'e',
- maxWidth: $(window).width() * 0.7,
- minWidth: $(window).width() * 0.2,
- create: function (e, ui) {
- $(this).parent().on('resize', function (e) {
- e.stopPropagation();
- });
- },
- start: function (e) {
- editor.setOption('viewportMargin', Infinity);
- },
- resize: function (e) {
- ui.area.resize.syncToggle.stop(true, true).show();
- checkTocStyle();
- },
- stop: function (e) {
- lastEditorWidth = ui.area.edit.width();
+ editor.setSize(null, ui.area.edit.height())
+ // make editor resizable
+ if (!ui.area.resize.handle.length) {
+ ui.area.edit.resizable({
+ handles: 'e',
+ maxWidth: $(window).width() * 0.7,
+ minWidth: $(window).width() * 0.2,
+ create: function (e, ui) {
+ $(this).parent().on('resize', function (e) {
+ e.stopPropagation()
+ })
+ },
+ start: function (e) {
+ editor.setOption('viewportMargin', Infinity)
+ },
+ resize: function (e) {
+ ui.area.resize.syncToggle.stop(true, true).show()
+ checkTocStyle()
+ },
+ stop: function (e) {
+ lastEditorWidth = ui.area.edit.width()
// workaround that scroll event bindings
- preventSyncScrollToView = 2;
- preventSyncScrollToEdit = true;
- editor.setOption('viewportMargin', viewportMargin);
- if (editorHasFocus()) {
- windowResizeInner(function () {
- ui.area.codemirrorScroll.scroll();
- });
- } else {
- windowResizeInner(function () {
- ui.area.view.scroll();
- });
- }
- checkEditorScrollbar();
- }
- });
- ui.area.resize.handle = $('.ui-resizable-handle');
- }
- if (!ui.area.resize.syncToggle.length) {
- ui.area.resize.syncToggle = $('');
- ui.area.resize.syncToggle.hover(function () {
- previousFocusOnEditor = editorHasFocus();
- }, function () {
- previousFocusOnEditor = null;
- });
- ui.area.resize.syncToggle.click(function () {
- syncscroll = !syncscroll;
- checkSyncToggle();
- });
- ui.area.resize.handle.append(ui.area.resize.syncToggle);
- ui.area.resize.syncToggle.hide();
- ui.area.resize.handle.hover(function () {
- ui.area.resize.syncToggle.stop(true, true).delay(200).fadeIn(100);
- }, function () {
- ui.area.resize.syncToggle.stop(true, true).delay(300).fadeOut(300);
- });
- }
-}
-
-function checkSyncToggle() {
- if (syncscroll) {
- if (previousFocusOnEditor) {
- preventSyncScrollToView = false;
- syncScrollToView();
+ window.preventSyncScrollToView = 2
+ window.preventSyncScrollToEdit = true
+ editor.setOption('viewportMargin', viewportMargin)
+ if (editorHasFocus()) {
+ windowResizeInner(function () {
+ ui.area.codemirrorScroll.scroll()
+ })
} else {
- preventSyncScrollToEdit = false;
- syncScrollToEdit();
+ windowResizeInner(function () {
+ ui.area.view.scroll()
+ })
}
- ui.area.resize.syncToggle.find('i').removeClass('fa-unlink').addClass('fa-link');
+ checkEditorScrollbar()
+ }
+ })
+ ui.area.resize.handle = $('.ui-resizable-handle')
+ }
+ if (!ui.area.resize.syncToggle.length) {
+ ui.area.resize.syncToggle = $('')
+ ui.area.resize.syncToggle.hover(function () {
+ previousFocusOnEditor = editorHasFocus()
+ }, function () {
+ previousFocusOnEditor = null
+ })
+ ui.area.resize.syncToggle.click(function () {
+ window.syncscroll = !window.syncscroll
+ checkSyncToggle()
+ })
+ ui.area.resize.handle.append(ui.area.resize.syncToggle)
+ ui.area.resize.syncToggle.hide()
+ ui.area.resize.handle.hover(function () {
+ ui.area.resize.syncToggle.stop(true, true).delay(200).fadeIn(100)
+ }, function () {
+ ui.area.resize.syncToggle.stop(true, true).delay(300).fadeOut(300)
+ })
+ }
+}
+
+function checkSyncToggle () {
+ if (window.syncscroll) {
+ if (previousFocusOnEditor) {
+ window.preventSyncScrollToView = false
+ syncScrollToView()
} else {
- ui.area.resize.syncToggle.find('i').removeClass('fa-link').addClass('fa-unlink');
+ window.preventSyncScrollToEdit = false
+ syncScrollToEdit()
}
+ ui.area.resize.syncToggle.find('i').removeClass('fa-unlink').addClass('fa-link')
+ } else {
+ ui.area.resize.syncToggle.find('i').removeClass('fa-link').addClass('fa-unlink')
+ }
}
var checkEditorScrollbar = _.debounce(function () {
- editor.operation(checkEditorScrollbarInner);
-}, 50);
+ editor.operation(checkEditorScrollbarInner)
+}, 50)
-function checkEditorScrollbarInner() {
+function checkEditorScrollbarInner () {
// workaround simple scroll bar knob
// will get wrong position when editor height changed
- var scrollInfo = editor.getScrollInfo();
- editor.scrollTo(null, scrollInfo.top - 1);
- editor.scrollTo(null, scrollInfo.top);
-}
-
-function checkTocStyle() {
- //toc right
- var paddingRight = parseFloat(ui.area.markdown.css('padding-right'));
- var right = ($(window).width() - (ui.area.markdown.offset().left + ui.area.markdown.outerWidth() - paddingRight));
- ui.toc.toc.css('right', right + 'px');
- //affix toc left
- var newbool;
- var rightMargin = (ui.area.markdown.parent().outerWidth() - ui.area.markdown.outerWidth()) / 2;
- //for ipad or wider device
- if (rightMargin >= 133) {
- newbool = true;
- var affixLeftMargin = (ui.toc.affix.outerWidth() - ui.toc.affix.width()) / 2;
- var left = ui.area.markdown.offset().left + ui.area.markdown.outerWidth() - affixLeftMargin;
- ui.toc.affix.css('left', left + 'px');
- ui.toc.affix.css('width', rightMargin + 'px');
- } else {
- newbool = false;
- }
- //toc scrollspy
- ui.toc.toc.removeClass('scrollspy-body, scrollspy-view');
- ui.toc.affix.removeClass('scrollspy-body, scrollspy-view');
- if (currentMode == modeType.both) {
- ui.toc.toc.addClass('scrollspy-view');
- ui.toc.affix.addClass('scrollspy-view');
- } else if (currentMode != modeType.both && !newbool) {
- ui.toc.toc.addClass('scrollspy-body');
- ui.toc.affix.addClass('scrollspy-body');
- } else {
- ui.toc.toc.addClass('scrollspy-view');
- ui.toc.affix.addClass('scrollspy-body');
- }
- if (newbool != enoughForAffixToc) {
- enoughForAffixToc = newbool;
- generateScrollspy();
- }
-}
-
-function showStatus(type, num) {
- currentStatus = type;
- var shortStatus = ui.toolbar.shortStatus;
- var status = ui.toolbar.status;
- var label = $('');
- var fa = $('');
- var msg = "";
- var shortMsg = "";
-
- shortStatus.html("");
- status.html("");
-
- switch (currentStatus) {
- case statusType.connected:
- label.addClass(statusType.connected.label);
- fa.addClass(statusType.connected.fa);
- msg = statusType.connected.msg;
- break;
- case statusType.online:
- label.addClass(statusType.online.label);
- fa.addClass(statusType.online.fa);
- shortMsg = num;
- msg = num + " " + statusType.online.msg;
- break;
- case statusType.offline:
- label.addClass(statusType.offline.label);
- fa.addClass(statusType.offline.fa);
- msg = statusType.offline.msg;
- break;
- }
-
- label.append(fa);
- var shortLabel = label.clone();
-
- shortLabel.append(" " + shortMsg);
- shortStatus.append(shortLabel);
-
- label.append(" " + msg);
- status.append(label);
-}
-
-function toggleMode() {
- switch (currentMode) {
- case modeType.edit:
- changeMode(modeType.view);
- break;
- case modeType.view:
- changeMode(modeType.edit);
- break;
- case modeType.both:
- changeMode(modeType.view);
- break;
- }
-}
-
-var lastMode = null;
-
-function changeMode(type) {
+ var scrollInfo = editor.getScrollInfo()
+ editor.scrollTo(null, scrollInfo.top - 1)
+ editor.scrollTo(null, scrollInfo.top)
+}
+
+function checkTocStyle () {
+ // toc right
+ var paddingRight = parseFloat(ui.area.markdown.css('padding-right'))
+ var right = ($(window).width() - (ui.area.markdown.offset().left + ui.area.markdown.outerWidth() - paddingRight))
+ ui.toc.toc.css('right', right + 'px')
+ // affix toc left
+ var newbool
+ var rightMargin = (ui.area.markdown.parent().outerWidth() - ui.area.markdown.outerWidth()) / 2
+ // for ipad or wider device
+ if (rightMargin >= 133) {
+ newbool = true
+ var affixLeftMargin = (ui.toc.affix.outerWidth() - ui.toc.affix.width()) / 2
+ var left = ui.area.markdown.offset().left + ui.area.markdown.outerWidth() - affixLeftMargin
+ ui.toc.affix.css('left', left + 'px')
+ ui.toc.affix.css('width', rightMargin + 'px')
+ } else {
+ newbool = false
+ }
+ // toc scrollspy
+ ui.toc.toc.removeClass('scrollspy-body, scrollspy-view')
+ ui.toc.affix.removeClass('scrollspy-body, scrollspy-view')
+ if (window.currentMode === modeType.both) {
+ ui.toc.toc.addClass('scrollspy-view')
+ ui.toc.affix.addClass('scrollspy-view')
+ } else if (window.currentMode !== modeType.both && !newbool) {
+ ui.toc.toc.addClass('scrollspy-body')
+ ui.toc.affix.addClass('scrollspy-body')
+ } else {
+ ui.toc.toc.addClass('scrollspy-view')
+ ui.toc.affix.addClass('scrollspy-body')
+ }
+ if (newbool !== enoughForAffixToc) {
+ enoughForAffixToc = newbool
+ generateScrollspy()
+ }
+}
+
+function showStatus (type, num) {
+ window.currentStatus = type
+ var shortStatus = ui.toolbar.shortStatus
+ var status = ui.toolbar.status
+ var label = $('')
+ var fa = $('')
+ var msg = ''
+ var shortMsg = ''
+
+ shortStatus.html('')
+ status.html('')
+
+ switch (window.currentStatus) {
+ case statusType.connected:
+ label.addClass(statusType.connected.label)
+ fa.addClass(statusType.connected.fa)
+ msg = statusType.connected.msg
+ break
+ case statusType.online:
+ label.addClass(statusType.online.label)
+ fa.addClass(statusType.online.fa)
+ shortMsg = num
+ msg = num + ' ' + statusType.online.msg
+ break
+ case statusType.offline:
+ label.addClass(statusType.offline.label)
+ fa.addClass(statusType.offline.fa)
+ msg = statusType.offline.msg
+ break
+ }
+
+ label.append(fa)
+ var shortLabel = label.clone()
+
+ shortLabel.append(' ' + shortMsg)
+ shortStatus.append(shortLabel)
+
+ label.append(' ' + msg)
+ status.append(label)
+}
+
+function toggleMode () {
+ switch (window.currentMode) {
+ case modeType.edit:
+ changeMode(modeType.view)
+ break
+ case modeType.view:
+ changeMode(modeType.edit)
+ break
+ case modeType.both:
+ changeMode(modeType.view)
+ break
+ }
+}
+
+var lastMode = null
+
+function changeMode (type) {
// lock navbar to prevent it hide after changeMode
- lockNavbar();
- saveInfo();
- if (type) {
- lastMode = currentMode;
- currentMode = type;
- }
- var responsiveClass = "col-lg-6 col-md-6 col-sm-6";
- var scrollClass = "ui-scrollable";
- ui.area.codemirror.removeClass(scrollClass);
- ui.area.edit.removeClass(responsiveClass);
- ui.area.view.removeClass(scrollClass);
- ui.area.view.removeClass(responsiveClass);
- switch (currentMode) {
- case modeType.edit:
- ui.area.edit.show();
- ui.area.view.hide();
- if (!editShown) {
- editor.refresh();
- editShown = true;
- }
- break;
- case modeType.view:
- ui.area.edit.hide();
- ui.area.view.show();
- break;
- case modeType.both:
- ui.area.codemirror.addClass(scrollClass);
- ui.area.edit.addClass(responsiveClass).show();
- ui.area.view.addClass(scrollClass);
- ui.area.view.show();
- break;
- }
+ lockNavbar()
+ saveInfo()
+ if (type) {
+ lastMode = window.currentMode
+ window.currentMode = type
+ }
+ var responsiveClass = 'col-lg-6 col-md-6 col-sm-6'
+ var scrollClass = 'ui-scrollable'
+ ui.area.codemirror.removeClass(scrollClass)
+ ui.area.edit.removeClass(responsiveClass)
+ ui.area.view.removeClass(scrollClass)
+ ui.area.view.removeClass(responsiveClass)
+ switch (window.currentMode) {
+ case modeType.edit:
+ ui.area.edit.show()
+ ui.area.view.hide()
+ if (!window.editShown) {
+ editor.refresh()
+ window.editShown = true
+ }
+ break
+ case modeType.view:
+ ui.area.edit.hide()
+ ui.area.view.show()
+ break
+ case modeType.both:
+ ui.area.codemirror.addClass(scrollClass)
+ ui.area.edit.addClass(responsiveClass).show()
+ ui.area.view.addClass(scrollClass)
+ ui.area.view.show()
+ break
+ }
// save mode to url
- if (history.replaceState && loaded) history.replaceState(null, "", serverurl + '/' + noteid + '?' + currentMode.name);
- if (currentMode == modeType.view) {
- editor.getInputField().blur();
- }
- if (currentMode == modeType.edit || currentMode == modeType.both) {
- ui.toolbar.uploadImage.fadeIn();
- //add and update status bar
- if (!statusBar) {
- addStatusBar();
- updateStatusBar();
- }
- //work around foldGutter might not init properly
- editor.setOption('foldGutter', false);
- editor.setOption('foldGutter', true);
- } else {
- ui.toolbar.uploadImage.fadeOut();
- }
- if (currentMode != modeType.edit) {
- $(document.body).css('background-color', 'white');
- updateView();
- } else {
- $(document.body).css('background-color', ui.area.codemirror.css('background-color'));
- }
- //check resizable editor style
- if (currentMode == modeType.both) {
- if (lastEditorWidth > 0)
- ui.area.edit.css('width', lastEditorWidth + 'px');
- else
- ui.area.edit.css('width', '');
- ui.area.resize.handle.show();
- } else {
- ui.area.edit.css('width', '');
- ui.area.resize.handle.hide();
- }
-
- windowResizeInner();
-
- restoreInfo();
-
- if (lastMode == modeType.view && currentMode == modeType.both) {
- preventSyncScrollToView = 2;
- syncScrollToEdit(null, true);
- }
-
- if (lastMode == modeType.edit && currentMode == modeType.both) {
- preventSyncScrollToEdit = 2;
- syncScrollToView(null, true);
- }
-
- if (lastMode == modeType.both && currentMode != modeType.both) {
- preventSyncScrollToView = false;
- preventSyncScrollToEdit = false;
- }
-
- if (lastMode != modeType.edit && currentMode == modeType.edit) {
- editor.refresh();
- }
-
- $(document.body).scrollspy('refresh');
- ui.area.view.scrollspy('refresh');
-
- ui.toolbar.both.removeClass("active");
- ui.toolbar.edit.removeClass("active");
- ui.toolbar.view.removeClass("active");
- var modeIcon = ui.toolbar.mode.find('i');
- modeIcon.removeClass('fa-pencil').removeClass('fa-eye');
- if (ui.area.edit.is(":visible") && ui.area.view.is(":visible")) { //both
- ui.toolbar.both.addClass("active");
- modeIcon.addClass('fa-eye');
- } else if (ui.area.edit.is(":visible")) { //edit
- ui.toolbar.edit.addClass("active");
- modeIcon.addClass('fa-eye');
- } else if (ui.area.view.is(":visible")) { //view
- ui.toolbar.view.addClass("active");
- modeIcon.addClass('fa-pencil');
- }
- unlockNavbar();
-}
-
-function lockNavbar() {
- $('.navbar').addClass('locked');
+ if (history.replaceState && window.loaded) history.replaceState(null, '', serverurl + '/' + noteid + '?' + window.currentMode.name)
+ if (window.currentMode === modeType.view) {
+ editor.getInputField().blur()
+ }
+ if (window.currentMode === modeType.edit || window.currentMode === modeType.both) {
+ ui.toolbar.uploadImage.fadeIn()
+ // add and update status bar
+ if (!statusBar) {
+ addStatusBar()
+ updateStatusBar()
+ }
+ // work around foldGutter might not init properly
+ editor.setOption('foldGutter', false)
+ editor.setOption('foldGutter', true)
+ } else {
+ ui.toolbar.uploadImage.fadeOut()
+ }
+ if (window.currentMode !== modeType.edit) {
+ $(document.body).css('background-color', 'white')
+ updateView()
+ } else {
+ $(document.body).css('background-color', ui.area.codemirror.css('background-color'))
+ }
+ // check resizable editor style
+ if (window.currentMode === modeType.both) {
+ if (lastEditorWidth > 0) { ui.area.edit.css('width', lastEditorWidth + 'px') } else { ui.area.edit.css('width', '') }
+ ui.area.resize.handle.show()
+ } else {
+ ui.area.edit.css('width', '')
+ ui.area.resize.handle.hide()
+ }
+
+ windowResizeInner()
+
+ restoreInfo()
+
+ if (lastMode === modeType.view && window.currentMode === modeType.both) {
+ window.preventSyncScrollToView = 2
+ syncScrollToEdit(null, true)
+ }
+
+ if (lastMode === modeType.edit && window.currentMode === modeType.both) {
+ window.preventSyncScrollToEdit = 2
+ syncScrollToView(null, true)
+ }
+
+ if (lastMode === modeType.both && window.currentMode !== modeType.both) {
+ window.preventSyncScrollToView = false
+ window.preventSyncScrollToEdit = false
+ }
+
+ if (lastMode !== modeType.edit && window.currentMode === modeType.edit) {
+ editor.refresh()
+ }
+
+ $(document.body).scrollspy('refresh')
+ ui.area.view.scrollspy('refresh')
+
+ ui.toolbar.both.removeClass('active')
+ ui.toolbar.edit.removeClass('active')
+ ui.toolbar.view.removeClass('active')
+ var modeIcon = ui.toolbar.mode.find('i')
+ modeIcon.removeClass('fa-pencil').removeClass('fa-eye')
+ if (ui.area.edit.is(':visible') && ui.area.view.is(':visible')) { // both
+ ui.toolbar.both.addClass('active')
+ modeIcon.addClass('fa-eye')
+ } else if (ui.area.edit.is(':visible')) { // edit
+ ui.toolbar.edit.addClass('active')
+ modeIcon.addClass('fa-eye')
+ } else if (ui.area.view.is(':visible')) { // view
+ ui.toolbar.view.addClass('active')
+ modeIcon.addClass('fa-pencil')
+ }
+ unlockNavbar()
+}
+
+function lockNavbar () {
+ $('.navbar').addClass('locked')
}
var unlockNavbar = _.debounce(function () {
- $('.navbar').removeClass('locked');
-}, 200);
-
-function closestIndex(arr, closestTo) {
- var closest = Math.max.apply(null, arr); //Get the highest number in arr in case it match nothing.
- var index = 0;
- for (var i = 0; i < arr.length; i++) { //Loop the array
- if (arr[i] >= closestTo && arr[i] < closest) {
- closest = arr[i]; //Check if it's higher than your number, but lower than your closest value
- index = i;
- }
- }
- return index; // return the value
-}
+ $('.navbar').removeClass('locked')
+}, 200)
-function showMessageModal(title, header, href, text, success) {
- var modal = $('.message-modal');
- modal.find('.modal-title').html(title);
- modal.find('.modal-body h5').html(header);
- if (href)
- modal.find('.modal-body a').attr('href', href).text(text);
- else
- modal.find('.modal-body a').removeAttr('href').text(text);
- modal.find('.modal-footer button').removeClass('btn-default btn-success btn-danger')
- if (success)
- modal.find('.modal-footer button').addClass('btn-success');
- else
- modal.find('.modal-footer button').addClass('btn-danger');
- modal.modal('show');
+function showMessageModal (title, header, href, text, success) {
+ var modal = $('.message-modal')
+ modal.find('.modal-title').html(title)
+ modal.find('.modal-body h5').html(header)
+ if (href) { modal.find('.modal-body a').attr('href', href).text(text) } else { modal.find('.modal-body a').removeAttr('href').text(text) }
+ modal.find('.modal-footer button').removeClass('btn-default btn-success btn-danger')
+ if (success) { modal.find('.modal-footer button').addClass('btn-success') } else { modal.find('.modal-footer button').addClass('btn-danger') }
+ modal.modal('show')
}
// check if dropbox app key is set and load scripts
if (DROPBOX_APP_KEY) {
- $('' );
-
- var leadingWs = text.match( /^\n?(\s*)/ )[1].length,
- leadingTabs = text.match( /^\n?(\t*)/ )[1].length;
-
- if( leadingTabs > 0 ) {
- text = text.replace( new RegExp('\\n?\\t{' + leadingTabs + '}','g'), '\n' );
- }
- else if( leadingWs > 1 ) {
- text = text.replace( new RegExp('\\n? {' + leadingWs + '}', 'g'), '\n' );
- }
-
- return text;
-
- }
-
- /**
- * Given a markdown slide section element, this will
- * return all arguments that aren't related to markdown
- * parsing. Used to forward any other user-defined arguments
- * to the output markdown slide.
- */
- function getForwardedAttributes( section ) {
-
- var attributes = section.attributes;
- var result = [];
-
- for( var i = 0, len = attributes.length; i < len; i++ ) {
- var name = attributes[i].name,
- value = attributes[i].value;
-
- // disregard attributes that are used for markdown loading/parsing
- if( /data\-(markdown|separator|vertical|notes)/gi.test( name ) ) continue;
-
- if( value ) {
- result.push( name + '="' + value + '"' );
- }
- else {
- result.push( name );
- }
- }
-
- return result.join( ' ' );
-
- }
-
- /**
- * Inspects the given options and fills out default
- * values for what's not defined.
- */
- function getSlidifyOptions( options ) {
-
- options = options || {};
- options.separator = options.separator || DEFAULT_SLIDE_SEPARATOR;
- options.notesSeparator = options.notesSeparator || DEFAULT_NOTES_SEPARATOR;
- options.attributes = options.attributes || '';
-
- return options;
-
- }
-
- /**
- * Helper function for constructing a markdown slide.
- */
- function createMarkdownSlide( content, options ) {
-
- options = getSlidifyOptions( options );
-
- var notesMatch = content.split( new RegExp( options.notesSeparator, 'mgi' ) );
-
- if( notesMatch.length === 2 ) {
- content = notesMatch[0] + '';
- }
-
- // prevent script end tags in the content from interfering
- // with parsing
- content = content.replace( /<\/script>/g, SCRIPT_END_PLACEHOLDER );
-
- return '';
-
- }
-
- /**
- * Parses a data string into multiple slides based
- * on the passed in separator arguments.
- */
- function slidify( markdown, options ) {
-
- options = getSlidifyOptions( options );
-
- var separatorRegex = new RegExp( options.separator + ( options.verticalSeparator ? '|' + options.verticalSeparator : '' ), 'mg' ),
- horizontalSeparatorRegex = new RegExp( options.separator );
-
- var matches,
- lastIndex = 0,
- isHorizontal,
- wasHorizontal = true,
- content,
- sectionStack = [];
-
- // iterate until all blocks between separators are stacked up
- while( matches = separatorRegex.exec( markdown ) ) {
- notes = null;
-
- // determine direction (horizontal by default)
- isHorizontal = horizontalSeparatorRegex.test( matches[0] );
-
- if( !isHorizontal && wasHorizontal ) {
- // create vertical stack
- sectionStack.push( [] );
- }
-
- // pluck slide content from markdown input
- content = markdown.substring( lastIndex, matches.index );
-
- if( isHorizontal && wasHorizontal ) {
- // add to horizontal stack
- sectionStack.push( content );
- }
- else {
- // add to vertical stack
- sectionStack[sectionStack.length-1].push( content );
- }
-
- lastIndex = separatorRegex.lastIndex;
- wasHorizontal = isHorizontal;
- }
-
- // add the remaining slide
- ( wasHorizontal ? sectionStack : sectionStack[sectionStack.length-1] ).push( markdown.substring( lastIndex ) );
-
- var markdownSections = '';
-
- // flatten the hierarchical stack, and insert Remember that you need to serve the presentation HTML from a HTTP server.
' + - 'Remember that you need to serve the presentation HTML from a HTTP server.
' + + '${highlighted}
\n`;
- }
-
- return `${highlighted}
\n`;
-};
+ const token = tokens[idx]
+ const info = token.info ? md.utils.unescapeAll(token.info).trim() : ''
+ let langName = ''
+ let highlighted
+
+ if (info) {
+ langName = info.split(/\s+/g)[0]
+ if (/!$/.test(info)) token.attrJoin('class', 'wrap')
+ token.attrJoin('class', options.langPrefix + langName.replace(/=$|=\d+$|=\+$|!$|=!/, ''))
+ token.attrJoin('class', 'hljs')
+ token.attrJoin('class', 'raw')
+ }
+
+ if (options.highlight) {
+ highlighted = options.highlight(token.content, langName) || md.utils.escapeHtml(token.content)
+ } else {
+ highlighted = md.utils.escapeHtml(token.content)
+ }
+
+ if (highlighted.indexOf('${highlighted}
\n`
+ }
+
+ return `${highlighted}
\n`
+}
md.renderer.rules.code_block = (tokens, idx, options, env, self) => {
- if (tokens[idx].map && tokens[idx].level === 0) {
- const startline = tokens[idx].map[0] + 1;
- const endline = tokens[idx].map[1];
- return `${md.utils.escapeHtml(tokens[idx].content)}
\n`;
- }
- return `${md.utils.escapeHtml(tokens[idx].content)}
\n`;
-};
-function renderContainer(tokens, idx, options, env, self) {
- tokens[idx].attrJoin('role', 'alert');
- tokens[idx].attrJoin('class', 'alert');
- tokens[idx].attrJoin('class', `alert-${tokens[idx].info.trim()}`);
- addPart(tokens, idx);
- return self.renderToken(...arguments);
+ if (tokens[idx].map && tokens[idx].level === 0) {
+ const startline = tokens[idx].map[0] + 1
+ const endline = tokens[idx].map[1]
+ return `${md.utils.escapeHtml(tokens[idx].content)}
\n`
+ }
+ return `${md.utils.escapeHtml(tokens[idx].content)}
\n`
+}
+function renderContainer (tokens, idx, options, env, self) {
+ tokens[idx].attrJoin('role', 'alert')
+ tokens[idx].attrJoin('class', 'alert')
+ tokens[idx].attrJoin('class', `alert-${tokens[idx].info.trim()}`)
+ addPart(tokens, idx)
+ return self.renderToken(...arguments)
}
-md.use(markdownitContainer, 'success', { render: renderContainer });
-md.use(markdownitContainer, 'info', { render: renderContainer });
-md.use(markdownitContainer, 'warning', { render: renderContainer });
-md.use(markdownitContainer, 'danger', { render: renderContainer });
+md.use(markdownitContainer, 'success', { render: renderContainer })
+md.use(markdownitContainer, 'info', { render: renderContainer })
+md.use(markdownitContainer, 'warning', { render: renderContainer })
+md.use(markdownitContainer, 'danger', { render: renderContainer })
// FIXME: expose syncscroll to window
-window.syncscroll = true;
+window.syncscroll = true
-window.preventSyncScrollToEdit = false;
-window.preventSyncScrollToView = false;
+window.preventSyncScrollToEdit = false
+window.preventSyncScrollToView = false
-const editScrollThrottle = 5;
-const viewScrollThrottle = 5;
-const buildMapThrottle = 100;
+const editScrollThrottle = 5
+const viewScrollThrottle = 5
+const buildMapThrottle = 100
-let viewScrolling = false;
-let editScrolling = false;
+let viewScrolling = false
+let editScrolling = false
-let editArea = null;
-let viewArea = null;
-let markdownArea = null;
+let editArea = null
+let viewArea = null
+let markdownArea = null
-export function setupSyncAreas(edit, view, markdown) {
- editArea = edit;
- viewArea = view;
- markdownArea = markdown;
- editArea.on('scroll', _.throttle(syncScrollToView, editScrollThrottle));
- viewArea.on('scroll', _.throttle(syncScrollToEdit, viewScrollThrottle));
+export function setupSyncAreas (edit, view, markdown) {
+ editArea = edit
+ viewArea = view
+ markdownArea = markdown
+ editArea.on('scroll', _.throttle(syncScrollToView, editScrollThrottle))
+ viewArea.on('scroll', _.throttle(syncScrollToEdit, viewScrollThrottle))
}
-let scrollMap, lineHeightMap, viewTop, viewBottom;
+let scrollMap, lineHeightMap, viewTop, viewBottom
-export function clearMap() {
- scrollMap = null;
- lineHeightMap = null;
- viewTop = null;
- viewBottom = null;
+export function clearMap () {
+ scrollMap = null
+ lineHeightMap = null
+ viewTop = null
+ viewBottom = null
}
-window.viewAjaxCallback = clearMap;
+window.viewAjaxCallback = clearMap
-const buildMap = _.throttle(buildMapInner, buildMapThrottle);
+const buildMap = _.throttle(buildMapInner, buildMapThrottle)
// Build offsets for each line (lines can be wrapped)
// That's a bit dirty to process each line everytime, but ok for demo.
// Optimizations are required only for big texts.
-function buildMapInner(callback) {
- if (!viewArea || !markdownArea) return;
- let i, offset, nonEmptyList, pos, a, b, _lineHeightMap, linesCount, acc, _scrollMap;
-
- offset = viewArea.scrollTop() - viewArea.offset().top;
- _scrollMap = [];
- nonEmptyList = [];
- _lineHeightMap = [];
- viewTop = 0;
- viewBottom = viewArea[0].scrollHeight - viewArea.height();
-
- acc = 0;
- const lines = editor.getValue().split('\n');
- const lineHeight = editor.defaultTextHeight();
- for (i = 0; i < lines.length; i++) {
- const str = lines[i];
-
- _lineHeightMap.push(acc);
-
- if (str.length === 0) {
- acc++;
- continue;
- }
-
- const h = editor.heightAtLine(i + 1) - editor.heightAtLine(i);
- acc += Math.round(h / lineHeight);
+function buildMapInner (callback) {
+ if (!viewArea || !markdownArea) return
+ let i, offset, nonEmptyList, pos, a, b, _lineHeightMap, linesCount, acc, _scrollMap
+
+ offset = viewArea.scrollTop() - viewArea.offset().top
+ _scrollMap = []
+ nonEmptyList = []
+ _lineHeightMap = []
+ viewTop = 0
+ viewBottom = viewArea[0].scrollHeight - viewArea.height()
+
+ acc = 0
+ const lines = window.editor.getValue().split('\n')
+ const lineHeight = window.editor.defaultTextHeight()
+ for (i = 0; i < lines.length; i++) {
+ const str = lines[i]
+
+ _lineHeightMap.push(acc)
+
+ if (str.length === 0) {
+ acc++
+ continue
}
- _lineHeightMap.push(acc);
- linesCount = acc;
- for (i = 0; i < linesCount; i++) {
- _scrollMap.push(-1);
- }
+ const h = window.editor.heightAtLine(i + 1) - window.editor.heightAtLine(i)
+ acc += Math.round(h / lineHeight)
+ }
+ _lineHeightMap.push(acc)
+ linesCount = acc
+
+ for (i = 0; i < linesCount; i++) {
+ _scrollMap.push(-1)
+ }
- nonEmptyList.push(0);
+ nonEmptyList.push(0)
// make the first line go top
- _scrollMap[0] = viewTop;
-
- const parts = markdownArea.find('.part').toArray();
- for (i = 0; i < parts.length; i++) {
- const $el = $(parts[i]);
- let t = $el.attr('data-startline') - 1;
- if (t === '') {
- return;
- }
- t = _lineHeightMap[t];
- if (t !== 0 && t !== nonEmptyList[nonEmptyList.length - 1]) {
- nonEmptyList.push(t);
- }
- _scrollMap[t] = Math.round($el.offset().top + offset - 10);
+ _scrollMap[0] = viewTop
+
+ const parts = markdownArea.find('.part').toArray()
+ for (i = 0; i < parts.length; i++) {
+ const $el = $(parts[i])
+ let t = $el.attr('data-startline') - 1
+ if (t === '') {
+ return
}
+ t = _lineHeightMap[t]
+ if (t !== 0 && t !== nonEmptyList[nonEmptyList.length - 1]) {
+ nonEmptyList.push(t)
+ }
+ _scrollMap[t] = Math.round($el.offset().top + offset - 10)
+ }
- nonEmptyList.push(linesCount);
- _scrollMap[linesCount] = viewArea[0].scrollHeight;
-
- pos = 0;
- for (i = 1; i < linesCount; i++) {
- if (_scrollMap[i] !== -1) {
- pos++;
- continue;
- }
+ nonEmptyList.push(linesCount)
+ _scrollMap[linesCount] = viewArea[0].scrollHeight
- a = nonEmptyList[pos];
- b = nonEmptyList[pos + 1];
- _scrollMap[i] = Math.round((_scrollMap[b] * (i - a) + _scrollMap[a] * (b - i)) / (b - a));
+ pos = 0
+ for (i = 1; i < linesCount; i++) {
+ if (_scrollMap[i] !== -1) {
+ pos++
+ continue
}
- _scrollMap[0] = 0;
+ a = nonEmptyList[pos]
+ b = nonEmptyList[pos + 1]
+ _scrollMap[i] = Math.round((_scrollMap[b] * (i - a) + _scrollMap[a] * (b - i)) / (b - a))
+ }
+
+ _scrollMap[0] = 0
- scrollMap = _scrollMap;
- lineHeightMap = _lineHeightMap;
+ scrollMap = _scrollMap
+ lineHeightMap = _lineHeightMap
- if (loaded && callback) callback();
+ if (window.loaded && callback) callback()
}
// sync view scroll progress to edit
-let viewScrollingTimer = null;
-
-export function syncScrollToEdit(event, preventAnimate) {
- if (currentMode != modeType.both || !syncscroll || !editArea) return;
- if (preventSyncScrollToEdit) {
- if (typeof preventSyncScrollToEdit === 'number') {
- preventSyncScrollToEdit--;
- } else {
- preventSyncScrollToEdit = false;
- }
- return;
- }
- if (!scrollMap || !lineHeightMap) {
- buildMap(() => {
- syncScrollToEdit(event, preventAnimate);
- });
- return;
- }
- if (editScrolling) return;
-
- const scrollTop = viewArea[0].scrollTop;
- let lineIndex = 0;
- for (var i = 0, l = scrollMap.length; i < l; i++) {
- if (scrollMap[i] > scrollTop) {
- break;
- } else {
- lineIndex = i;
- }
- }
- let lineNo = 0;
- let lineDiff = 0;
- for (var i = 0, l = lineHeightMap.length; i < l; i++) {
- if (lineHeightMap[i] > lineIndex) {
- break;
- } else {
- lineNo = lineHeightMap[i];
- lineDiff = lineHeightMap[i + 1] - lineNo;
- }
- }
+let viewScrollingTimer = null
- let posTo = 0;
- let topDiffPercent = 0;
- let posToNextDiff = 0;
- const scrollInfo = editor.getScrollInfo();
- const textHeight = editor.defaultTextHeight();
- const preLastLineHeight = scrollInfo.height - scrollInfo.clientHeight - textHeight;
- const preLastLineNo = Math.round(preLastLineHeight / textHeight);
- const preLastLinePos = scrollMap[preLastLineNo];
-
- if (scrollInfo.height > scrollInfo.clientHeight && scrollTop >= preLastLinePos) {
- posTo = preLastLineHeight;
- topDiffPercent = (scrollTop - preLastLinePos) / (viewBottom - preLastLinePos);
- posToNextDiff = textHeight * topDiffPercent;
- posTo += Math.ceil(posToNextDiff);
+export function syncScrollToEdit (event, preventAnimate) {
+ if (window.currentMode !== window.modeType.both || !window.syncscroll || !editArea) return
+ if (window.preventSyncScrollToEdit) {
+ if (typeof window.preventSyncScrollToEdit === 'number') {
+ window.preventSyncScrollToEdit--
} else {
- posTo = lineNo * textHeight;
- topDiffPercent = (scrollTop - scrollMap[lineNo]) / (scrollMap[lineNo + lineDiff] - scrollMap[lineNo]);
- posToNextDiff = textHeight * lineDiff * topDiffPercent;
- posTo += Math.ceil(posToNextDiff);
+ window.preventSyncScrollToEdit = false
}
-
- if (preventAnimate) {
- editArea.scrollTop(posTo);
+ return
+ }
+ if (!scrollMap || !lineHeightMap) {
+ buildMap(() => {
+ syncScrollToEdit(event, preventAnimate)
+ })
+ return
+ }
+ if (editScrolling) return
+
+ const scrollTop = viewArea[0].scrollTop
+ let lineIndex = 0
+ for (let i = 0, l = scrollMap.length; i < l; i++) {
+ if (scrollMap[i] > scrollTop) {
+ break
} else {
- const posDiff = Math.abs(scrollInfo.top - posTo);
- var duration = posDiff / 50;
- duration = duration >= 100 ? duration : 100;
- editArea.stop(true, true).animate({
- scrollTop: posTo
- }, duration, "linear");
+ lineIndex = i
}
-
- viewScrolling = true;
- clearTimeout(viewScrollingTimer);
- viewScrollingTimer = setTimeout(viewScrollingTimeoutInner, duration * 1.5);
+ }
+ let lineNo = 0
+ let lineDiff = 0
+ for (let i = 0, l = lineHeightMap.length; i < l; i++) {
+ if (lineHeightMap[i] > lineIndex) {
+ break
+ } else {
+ lineNo = lineHeightMap[i]
+ lineDiff = lineHeightMap[i + 1] - lineNo
+ }
+ }
+
+ let posTo = 0
+ let topDiffPercent = 0
+ let posToNextDiff = 0
+ const scrollInfo = window.editor.getScrollInfo()
+ const textHeight = window.editor.defaultTextHeight()
+ const preLastLineHeight = scrollInfo.height - scrollInfo.clientHeight - textHeight
+ const preLastLineNo = Math.round(preLastLineHeight / textHeight)
+ const preLastLinePos = scrollMap[preLastLineNo]
+
+ if (scrollInfo.height > scrollInfo.clientHeight && scrollTop >= preLastLinePos) {
+ posTo = preLastLineHeight
+ topDiffPercent = (scrollTop - preLastLinePos) / (viewBottom - preLastLinePos)
+ posToNextDiff = textHeight * topDiffPercent
+ posTo += Math.ceil(posToNextDiff)
+ } else {
+ posTo = lineNo * textHeight
+ topDiffPercent = (scrollTop - scrollMap[lineNo]) / (scrollMap[lineNo + lineDiff] - scrollMap[lineNo])
+ posToNextDiff = textHeight * lineDiff * topDiffPercent
+ posTo += Math.ceil(posToNextDiff)
+ }
+
+ if (preventAnimate) {
+ editArea.scrollTop(posTo)
+ } else {
+ const posDiff = Math.abs(scrollInfo.top - posTo)
+ var duration = posDiff / 50
+ duration = duration >= 100 ? duration : 100
+ editArea.stop(true, true).animate({
+ scrollTop: posTo
+ }, duration, 'linear')
+ }
+
+ viewScrolling = true
+ clearTimeout(viewScrollingTimer)
+ viewScrollingTimer = setTimeout(viewScrollingTimeoutInner, duration * 1.5)
}
-function viewScrollingTimeoutInner() {
- viewScrolling = false;
+function viewScrollingTimeoutInner () {
+ viewScrolling = false
}
// sync edit scroll progress to view
-let editScrollingTimer = null;
-
-export function syncScrollToView(event, preventAnimate) {
- if (currentMode != modeType.both || !syncscroll || !viewArea) return;
- if (preventSyncScrollToView) {
- if (typeof preventSyncScrollToView === 'number') {
- preventSyncScrollToView--;
- } else {
- preventSyncScrollToView = false;
- }
- return;
- }
- if (!scrollMap || !lineHeightMap) {
- buildMap(() => {
- syncScrollToView(event, preventAnimate);
- });
- return;
- }
- if (viewScrolling) return;
-
- let lineNo, posTo;
- let topDiffPercent, posToNextDiff;
- const scrollInfo = editor.getScrollInfo();
- const textHeight = editor.defaultTextHeight();
- lineNo = Math.floor(scrollInfo.top / textHeight);
- // if reach the last line, will start lerp to the bottom
- const diffToBottom = (scrollInfo.top + scrollInfo.clientHeight) - (scrollInfo.height - textHeight);
- if (scrollInfo.height > scrollInfo.clientHeight && diffToBottom > 0) {
- topDiffPercent = diffToBottom / textHeight;
- posTo = scrollMap[lineNo + 1];
- posToNextDiff = (viewBottom - posTo) * topDiffPercent;
- posTo += Math.floor(posToNextDiff);
- } else {
- topDiffPercent = (scrollInfo.top % textHeight) / textHeight;
- posTo = scrollMap[lineNo];
- posToNextDiff = (scrollMap[lineNo + 1] - posTo) * topDiffPercent;
- posTo += Math.floor(posToNextDiff);
- }
+let editScrollingTimer = null
- if (preventAnimate) {
- viewArea.scrollTop(posTo);
+export function syncScrollToView (event, preventAnimate) {
+ if (window.currentMode !== window.modeType.both || !window.syncscroll || !viewArea) return
+ if (window.preventSyncScrollToView) {
+ if (typeof preventSyncScrollToView === 'number') {
+ window.preventSyncScrollToView--
} else {
- const posDiff = Math.abs(viewArea.scrollTop() - posTo);
- var duration = posDiff / 50;
- duration = duration >= 100 ? duration : 100;
- viewArea.stop(true, true).animate({
- scrollTop: posTo
- }, duration, "linear");
+ window.preventSyncScrollToView = false
}
-
- editScrolling = true;
- clearTimeout(editScrollingTimer);
- editScrollingTimer = setTimeout(editScrollingTimeoutInner, duration * 1.5);
+ return
+ }
+ if (!scrollMap || !lineHeightMap) {
+ buildMap(() => {
+ syncScrollToView(event, preventAnimate)
+ })
+ return
+ }
+ if (viewScrolling) return
+
+ let lineNo, posTo
+ let topDiffPercent, posToNextDiff
+ const scrollInfo = window.editor.getScrollInfo()
+ const textHeight = window.editor.defaultTextHeight()
+ lineNo = Math.floor(scrollInfo.top / textHeight)
+ // if reach the last line, will start lerp to the bottom
+ const diffToBottom = (scrollInfo.top + scrollInfo.clientHeight) - (scrollInfo.height - textHeight)
+ if (scrollInfo.height > scrollInfo.clientHeight && diffToBottom > 0) {
+ topDiffPercent = diffToBottom / textHeight
+ posTo = scrollMap[lineNo + 1]
+ posToNextDiff = (viewBottom - posTo) * topDiffPercent
+ posTo += Math.floor(posToNextDiff)
+ } else {
+ topDiffPercent = (scrollInfo.top % textHeight) / textHeight
+ posTo = scrollMap[lineNo]
+ posToNextDiff = (scrollMap[lineNo + 1] - posTo) * topDiffPercent
+ posTo += Math.floor(posToNextDiff)
+ }
+
+ if (preventAnimate) {
+ viewArea.scrollTop(posTo)
+ } else {
+ const posDiff = Math.abs(viewArea.scrollTop() - posTo)
+ var duration = posDiff / 50
+ duration = duration >= 100 ? duration : 100
+ viewArea.stop(true, true).animate({
+ scrollTop: posTo
+ }, duration, 'linear')
+ }
+
+ editScrolling = true
+ clearTimeout(editScrollingTimer)
+ editScrollingTimer = setTimeout(editScrollingTimeoutInner, duration * 1.5)
}
-function editScrollingTimeoutInner() {
- editScrolling = false;
+function editScrollingTimeoutInner () {
+ editScrolling = false
}
diff --git a/public/vendor/md-toc.js b/public/vendor/md-toc.js
index 200275a5..f93f7921 100755
--- a/public/vendor/md-toc.js
+++ b/public/vendor/md-toc.js
@@ -1,129 +1,123 @@
+/* eslint-env browser, jquery */
/**
* md-toc.js v1.0.2
* https://github.com/yijian166/md-toc.js
*/
(function (window) {
- function Toc(id, options) {
- this.el = document.getElementById(id);
- if (!this.el) return;
- this.options = options || {};
- this.tocLevel = parseInt(options.level) || 0;
- this.tocClass = options['class'] || 'toc';
- this.ulClass = options['ulClass'];
- this.tocTop = parseInt(options.top) || 0;
- this.elChilds = this.el.children;
- this.process = options['process'];
- if (!this.elChilds.length) return;
- this._init();
- }
+ function Toc (id, options) {
+ this.el = document.getElementById(id)
+ if (!this.el) return
+ this.options = options || {}
+ this.tocLevel = parseInt(options.level) || 0
+ this.tocClass = options['class'] || 'toc'
+ this.ulClass = options['ulClass']
+ this.tocTop = parseInt(options.top) || 0
+ this.elChilds = this.el.children
+ this.process = options['process']
+ if (!this.elChilds.length) return
+ this._init()
+ }
- Toc.prototype._init = function () {
- this._collectTitleElements();
- this._createTocContent();
- this._showToc();
- };
+ Toc.prototype._init = function () {
+ this._collectTitleElements()
+ this._createTocContent()
+ this._showToc()
+ }
- Toc.prototype._collectTitleElements = function () {
- this._elTitlesNames = [],
- this.elTitleElements = [];
- for (var i = 1; i < 7; i++) {
- if (this.el.getElementsByTagName('h' + i).length) {
- this._elTitlesNames.push('h' + i);
- }
- }
+ Toc.prototype._collectTitleElements = function () {
+ this._elTitlesNames = []
+ this.elTitleElements = []
+ for (var i = 1; i < 7; i++) {
+ if (this.el.getElementsByTagName('h' + i).length) {
+ this._elTitlesNames.push('h' + i)
+ }
+ }
- this._elTitlesNames.length = this._elTitlesNames.length > this.tocLevel ? this.tocLevel : this._elTitlesNames.length;
+ this._elTitlesNames.length = this._elTitlesNames.length > this.tocLevel ? this.tocLevel : this._elTitlesNames.length
- for (var j = 0; j < this.elChilds.length; j++) {
- this._elChildName = this.elChilds[j].tagName.toLowerCase();
- if (this._elTitlesNames.toString().match(this._elChildName)) {
- this.elTitleElements.push(this.elChilds[j]);
- }
- }
- };
+ for (var j = 0; j < this.elChilds.length; j++) {
+ this._elChildName = this.elChilds[j].tagName.toLowerCase()
+ if (this._elTitlesNames.toString().match(this._elChildName)) {
+ this.elTitleElements.push(this.elChilds[j])
+ }
+ }
+ }
- Toc.prototype._createTocContent = function () {
- this._elTitleElementsLen = this.elTitleElements.length;
- if (!this._elTitleElementsLen) return;
- this.tocContent = '';
- this._tempLists = [];
+ Toc.prototype._createTocContent = function () {
+ this._elTitleElementsLen = this.elTitleElements.length
+ if (!this._elTitleElementsLen) return
+ this.tocContent = ''
+ this._tempLists = []
- var url = location.origin + location.pathname;
- for (var i = 0; i < this._elTitleElementsLen; i++) {
- var j = i + 1;
- this._elTitleElement = this.elTitleElements[i];
- this._elTitleElementName = this._elTitleElement.tagName;
- this._elTitleElementText = (typeof this.process === 'function' ? this.process(this._elTitleElement) : this._elTitleElement.innerHTML).replace(/<(?:.|\n)*?>/gm, '');
- var id = this._elTitleElement.getAttribute('id');
- if (!id) {
- this._elTitleElement.setAttribute('id', 'tip' + i);
- id = '#tip' + i;
- } else {
- id = '#' + id;
- }
+ for (var i = 0; i < this._elTitleElementsLen; i++) {
+ var j = i + 1
+ this._elTitleElement = this.elTitleElements[i]
+ this._elTitleElementName = this._elTitleElement.tagName
+ this._elTitleElementText = (typeof this.process === 'function' ? this.process(this._elTitleElement) : this._elTitleElement.innerHTML).replace(/<(?:.|\n)*?>/gm, '')
+ var id = this._elTitleElement.getAttribute('id')
+ if (!id) {
+ this._elTitleElement.setAttribute('id', 'tip' + i)
+ id = '#tip' + i
+ } else {
+ id = '#' + id
+ }
- this.tocContent += '