Make diagram configurable
This commit is contained in:
parent
fd901e07ba
commit
bf778a9945
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,4 +1,5 @@
|
||||
.project
|
||||
.idea
|
||||
.settings
|
||||
node_modules
|
||||
Thumbs.db
|
||||
|
@ -12,12 +12,10 @@ define([
|
||||
"eventMgr",
|
||||
"text!html/bodyIndex.html",
|
||||
"text!html/bodyViewer.html",
|
||||
"text!html/settingsTemplateTooltip.html",
|
||||
"text!html/settingsShortcutsExtensionTooltip.html",
|
||||
"text!html/settingsUserCustomExtensionTooltip.html",
|
||||
"text!html/tooltipSettingsTemplate.html",
|
||||
"storage",
|
||||
'pagedown',
|
||||
], function($, _, crel, editor, layout, constants, utils, storage, settings, eventMgr, bodyIndexHTML, bodyViewerHTML, settingsTemplateTooltipHTML, settingsShortcutsExtensionTooltipHTML, settingsUserCustomExtensionTooltipHTML) {
|
||||
'pagedown'
|
||||
], function($, _, crel, editor, layout, constants, utils, storage, settings, eventMgr, bodyIndexHTML, bodyViewerHTML, settingsTemplateTooltipHTML) {
|
||||
|
||||
var core = {};
|
||||
|
||||
@ -29,6 +27,7 @@ define([
|
||||
var userActive = false;
|
||||
var windowUnique = true;
|
||||
var userLastActivity = 0;
|
||||
|
||||
function setUserActive() {
|
||||
isUserReal = true;
|
||||
userActive = true;
|
||||
@ -48,6 +47,7 @@ define([
|
||||
|
||||
// Used to only have 1 window of the application in the same browser
|
||||
var windowId;
|
||||
|
||||
function checkWindowUnique() {
|
||||
if(isUserReal === false || windowUnique === false) {
|
||||
return;
|
||||
@ -85,6 +85,7 @@ define([
|
||||
eventMgr.onOfflineChanged(false);
|
||||
}
|
||||
}
|
||||
|
||||
function checkOnline() {
|
||||
// Try to reconnect if we are offline but we have some network
|
||||
if(isOffline === true && navigator.onLine === true && offlineTime + constants.CHECK_ONLINE_PERIOD < utils.currentTime) {
|
||||
@ -102,6 +103,7 @@ define([
|
||||
|
||||
// Load settings in settings dialog
|
||||
var $themeInputElt;
|
||||
|
||||
function loadSettings() {
|
||||
|
||||
// Layout orientation
|
||||
@ -389,6 +391,7 @@ define([
|
||||
|
||||
// Hot theme switcher in the settings
|
||||
var currentTheme = window.theme;
|
||||
|
||||
function applyTheme(theme) {
|
||||
theme = theme || 'default';
|
||||
if(currentTheme != theme) {
|
||||
@ -405,6 +408,7 @@ define([
|
||||
currentTheme = theme;
|
||||
}
|
||||
}
|
||||
|
||||
$themeInputElt = $("#input-settings-theme");
|
||||
$themeInputElt.on("change", function() {
|
||||
applyTheme(this.value);
|
||||
@ -477,42 +481,12 @@ define([
|
||||
utils.resetModalInputs();
|
||||
});
|
||||
|
||||
// Tooltips
|
||||
var openedTooltip;
|
||||
function createTooltip(selector, content) {
|
||||
_.each(document.querySelectorAll(selector), function(tooltipElt) {
|
||||
var $tooltipElt = $(tooltipElt);
|
||||
$tooltipElt.tooltip({
|
||||
html: true,
|
||||
container: $tooltipElt.parents('.modal-content'),
|
||||
placement: 'right',
|
||||
trigger: 'manual',
|
||||
title: content
|
||||
}).click(function() {
|
||||
var elt = this;
|
||||
if(openedTooltip && openedTooltip[0] === elt) {
|
||||
return;
|
||||
}
|
||||
utils.defer(function() {
|
||||
$(document).on("click.close-tooltip", function() {
|
||||
openedTooltip && openedTooltip.tooltip('hide');
|
||||
openedTooltip = undefined;
|
||||
$(document).off("click.close-tooltip");
|
||||
});
|
||||
openedTooltip = $(elt).tooltip('show');
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
createTooltip(".tooltip-lazy-rendering", 'Disable preview rendering while typing in order to offload CPU. Refresh preview after 500 ms of inactivity.');
|
||||
createTooltip(".tooltip-default-content", [
|
||||
utils.createTooltip(".tooltip-lazy-rendering", 'Disable preview rendering while typing in order to offload CPU. Refresh preview after 500 ms of inactivity.');
|
||||
utils.createTooltip(".tooltip-default-content", [
|
||||
'Thanks for supporting StackEdit by adding a backlink in your documents!<br/><br/>',
|
||||
'<b class="text-danger">NOTE: Backlinks in Stack Exchange Q/A are not welcome.</b>'
|
||||
].join(''));
|
||||
createTooltip(".tooltip-shortcuts-extension", settingsShortcutsExtensionTooltipHTML);
|
||||
createTooltip(".tooltip-usercustom-extension", settingsUserCustomExtensionTooltipHTML);
|
||||
createTooltip(".tooltip-template", settingsTemplateTooltipHTML);
|
||||
utils.createTooltip(".tooltip-template", settingsTemplateTooltipHTML);
|
||||
|
||||
// Avoid dropdown panels to close on click
|
||||
$("div.dropdown-menu").click(function(e) {
|
||||
|
@ -13,7 +13,7 @@ define([
|
||||
'rangy',
|
||||
'MutationObservers',
|
||||
'libs/prism-markdown'
|
||||
], function ($, _, utils, settings, eventMgr, Prism, diff_match_patch, jsondiffpatch, crel, rangy) {
|
||||
], function($, _, utils, settings, eventMgr, Prism, diff_match_patch, jsondiffpatch, crel, rangy) {
|
||||
|
||||
var editor = {};
|
||||
var scrollTop = 0;
|
||||
@ -90,6 +90,7 @@ define([
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
var watcher = new Watcher();
|
||||
editor.watcher = watcher;
|
||||
|
||||
@ -99,7 +100,7 @@ define([
|
||||
return JSON.stringify(obj);
|
||||
},
|
||||
arrays: {
|
||||
detectMove: false,
|
||||
detectMove: false
|
||||
},
|
||||
textDiff: {
|
||||
minLength: 9999999
|
||||
@ -116,7 +117,7 @@ define([
|
||||
var text = '';
|
||||
while(walker.nextNode()) {
|
||||
text = walker.currentNode.nodeValue || '';
|
||||
if (text.length > offset) {
|
||||
if(text.length > offset) {
|
||||
return {
|
||||
container: walker.currentNode,
|
||||
offset: offset
|
||||
@ -135,7 +136,7 @@ define([
|
||||
var range = document.createRange();
|
||||
var offset = _.isObject(start) ? start : this.findOffset(start);
|
||||
range.setStart(offset.container, offset.offset);
|
||||
if (end && end != start) {
|
||||
if(end && end != start) {
|
||||
offset = _.isObject(end) ? end : this.findOffset(end);
|
||||
}
|
||||
range.setEnd(offset.container, offset.offset);
|
||||
@ -194,6 +195,7 @@ define([
|
||||
};
|
||||
this.saveSelectionState = (function() {
|
||||
var timeoutId;
|
||||
|
||||
function save(adjustScroll) {
|
||||
clearTimeout(timeoutId);
|
||||
timeoutId = undefined;
|
||||
@ -206,18 +208,18 @@ define([
|
||||
if(selection.rangeCount > 0) {
|
||||
var selectionRange = selection.getRangeAt(0);
|
||||
var element = selectionRange.startContainer;
|
||||
if ((contentElt.compareDocumentPosition(element) & 0x10)) {
|
||||
if((contentElt.compareDocumentPosition(element) & 0x10)) {
|
||||
range = selectionRange;
|
||||
var container = element;
|
||||
var offset = range.startOffset;
|
||||
do {
|
||||
while (element = element.previousSibling) {
|
||||
if (element.textContent) {
|
||||
while(element = element.previousSibling) {
|
||||
if(element.textContent) {
|
||||
offset += element.textContent.length;
|
||||
}
|
||||
}
|
||||
element = container = container.parentNode;
|
||||
} while (element && element != inputElt);
|
||||
} while(element && element != inputElt);
|
||||
|
||||
if(selection.isBackwards()) {
|
||||
selectionStart = offset + (range + '').length;
|
||||
@ -233,6 +235,7 @@ define([
|
||||
}
|
||||
undoMgr.saveSelectionState();
|
||||
}
|
||||
|
||||
return function(debounced, adjustScroll) {
|
||||
adjustScroll = _.isBoolean(adjustScroll) ? adjustScroll : false;
|
||||
if(debounced) {
|
||||
@ -311,6 +314,7 @@ define([
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
var selectionMgr = new SelectionMgr();
|
||||
editor.selectionMgr = selectionMgr;
|
||||
$(document).on('selectionchange', '.editor-content', _.bind(selectionMgr.saveSelectionState, selectionMgr, true));
|
||||
@ -321,9 +325,11 @@ define([
|
||||
}
|
||||
selectionMgr.saveSelectionState(true, true);
|
||||
}
|
||||
|
||||
editor.adjustCursorPosition = adjustCursorPosition;
|
||||
|
||||
var textContent;
|
||||
|
||||
function setValue(value) {
|
||||
var startOffset = diffMatchPatch.diff_commonPrefix(textContent, value);
|
||||
if(startOffset === textContent.length) {
|
||||
@ -339,6 +345,7 @@ define([
|
||||
range.deleteContents();
|
||||
range.insertNode(document.createTextNode(replacement));
|
||||
}
|
||||
|
||||
editor.setValue = setValue;
|
||||
|
||||
function replacePreviousText(text, replacement) {
|
||||
@ -356,17 +363,20 @@ define([
|
||||
selectionMgr.setSelectionStartEnd(offset, offset);
|
||||
return true;
|
||||
}
|
||||
|
||||
editor.replacePreviousText = replacePreviousText;
|
||||
|
||||
function setValueNoWatch(value) {
|
||||
setValue(value);
|
||||
textContent = value;
|
||||
}
|
||||
|
||||
editor.setValueNoWatch = setValueNoWatch;
|
||||
|
||||
function getValue() {
|
||||
return textContent;
|
||||
}
|
||||
|
||||
editor.getValue = getValue;
|
||||
|
||||
function focus() {
|
||||
@ -374,6 +384,7 @@ define([
|
||||
selectionMgr.setSelectionStartEnd();
|
||||
inputElt.scrollTop = scrollTop;
|
||||
}
|
||||
|
||||
editor.focus = focus;
|
||||
|
||||
function UndoMgr() {
|
||||
@ -387,8 +398,10 @@ define([
|
||||
this.setCommandMode = function() {
|
||||
this.currentMode = 'command';
|
||||
};
|
||||
this.setMode = function() {}; // For compatibility with PageDown
|
||||
this.onButtonStateChange = function() {}; // To be overridden by PageDown
|
||||
this.setMode = function() {
|
||||
}; // For compatibility with PageDown
|
||||
this.onButtonStateChange = function() {
|
||||
}; // To be overridden by PageDown
|
||||
this.saveState = utils.debounce(function() {
|
||||
redoStack = [];
|
||||
var currentTime = Date.now();
|
||||
@ -467,6 +480,7 @@ define([
|
||||
this.onButtonStateChange();
|
||||
adjustCursorPosition();
|
||||
}
|
||||
|
||||
this.undo = function() {
|
||||
var state = undoStack.pop();
|
||||
if(!state) {
|
||||
@ -501,6 +515,7 @@ define([
|
||||
checkContentChange();
|
||||
};
|
||||
}
|
||||
|
||||
var undoMgr = new UndoMgr();
|
||||
editor.undoMgr = undoMgr;
|
||||
|
||||
@ -510,11 +525,13 @@ define([
|
||||
undoMgr.saveState();
|
||||
}
|
||||
}
|
||||
|
||||
eventMgr.addListener('onDiscussionCreated', onComment);
|
||||
eventMgr.addListener('onDiscussionRemoved', onComment);
|
||||
eventMgr.addListener('onCommentsChanged', onComment);
|
||||
|
||||
var trailingLfNode;
|
||||
|
||||
function checkContentChange() {
|
||||
var newTextContent = inputElt.textContent;
|
||||
if(contentElt.lastChild === trailingLfNode && trailingLfNode.textContent.slice(-1) == '\n') {
|
||||
@ -608,6 +625,7 @@ define([
|
||||
});
|
||||
return changed;
|
||||
}
|
||||
|
||||
editor.adjustCommentOffsets = adjustCommentOffsets;
|
||||
|
||||
editor.init = function() {
|
||||
@ -638,7 +656,7 @@ define([
|
||||
// See https://gist.github.com/shimondoodkin/1081133
|
||||
if(/AppleWebKit\/([\d.]+)/.exec(navigator.userAgent)) {
|
||||
var $editableFix = $('<input style="width:1px;height:1px;border:none;margin:0;padding:0;" tabIndex="-1">').appendTo('html');
|
||||
$contentElt.blur(function () {
|
||||
$contentElt.blur(function() {
|
||||
$editableFix[0].setSelectionRange(0, 0);
|
||||
$editableFix.blur();
|
||||
});
|
||||
@ -647,17 +665,17 @@ define([
|
||||
inputElt.focus = focus;
|
||||
|
||||
Object.defineProperty(inputElt, 'value', {
|
||||
get: function () {
|
||||
get: function() {
|
||||
return textContent;
|
||||
},
|
||||
set: setValue
|
||||
});
|
||||
|
||||
Object.defineProperty(inputElt, 'selectionStart', {
|
||||
get: function () {
|
||||
get: function() {
|
||||
return Math.min(selectionMgr.selectionStart, selectionMgr.selectionEnd);
|
||||
},
|
||||
set: function (value) {
|
||||
set: function(value) {
|
||||
selectionMgr.setSelectionStartEnd(value);
|
||||
},
|
||||
|
||||
@ -666,10 +684,10 @@ define([
|
||||
});
|
||||
|
||||
Object.defineProperty(inputElt, 'selectionEnd', {
|
||||
get: function () {
|
||||
get: function() {
|
||||
return Math.max(selectionMgr.selectionStart, selectionMgr.selectionEnd);
|
||||
},
|
||||
set: function (value) {
|
||||
set: function(value) {
|
||||
selectionMgr.setSelectionStartEnd(undefined, value);
|
||||
},
|
||||
|
||||
@ -678,7 +696,8 @@ define([
|
||||
});
|
||||
|
||||
var clearNewline = false;
|
||||
$contentElt.on('keydown', function (evt) {
|
||||
$contentElt
|
||||
.on('keydown', function(evt) {
|
||||
if(
|
||||
evt.which === 17 || // Ctrl
|
||||
evt.which === 91 || // Cmd
|
||||
@ -694,9 +713,9 @@ define([
|
||||
adjustCursorPosition();
|
||||
}
|
||||
|
||||
switch (evt.which) {
|
||||
switch(evt.which) {
|
||||
case 9: // Tab
|
||||
if (!cmdOrCtrl) {
|
||||
if(!cmdOrCtrl) {
|
||||
action('indent', {
|
||||
inverse: evt.shiftKey
|
||||
});
|
||||
@ -713,16 +732,16 @@ define([
|
||||
}
|
||||
})
|
||||
.on('mouseup', _.bind(selectionMgr.saveSelectionState, selectionMgr, true))
|
||||
.on('paste', function () {
|
||||
.on('paste', function() {
|
||||
undoMgr.currentMode = 'paste';
|
||||
adjustCursorPosition();
|
||||
})
|
||||
.on('cut', function () {
|
||||
.on('cut', function() {
|
||||
undoMgr.currentMode = 'cut';
|
||||
adjustCursorPosition();
|
||||
});
|
||||
|
||||
var action = function (action, options) {
|
||||
var action = function(action, options) {
|
||||
options = options || {};
|
||||
|
||||
var textContent = getValue();
|
||||
@ -743,22 +762,23 @@ define([
|
||||
};
|
||||
|
||||
var actions = {
|
||||
indent: function (state, options) {
|
||||
indent: function(state, options) {
|
||||
function strSplice(str, i, remove, add) {
|
||||
remove = +remove || 0;
|
||||
add = add || '';
|
||||
return str.slice(0, i) + add + str.slice(i + remove);
|
||||
}
|
||||
|
||||
var lf = state.before.lastIndexOf('\n') + 1;
|
||||
if (options.inverse) {
|
||||
if (/\s/.test(state.before.charAt(lf))) {
|
||||
if(options.inverse) {
|
||||
if(/\s/.test(state.before.charAt(lf))) {
|
||||
state.before = strSplice(state.before, lf, 1);
|
||||
|
||||
state.selectionStart--;
|
||||
state.selectionEnd--;
|
||||
}
|
||||
state.selection = state.selection.replace(/^[ \t]/gm, '');
|
||||
} else if (state.selection) {
|
||||
} else if(state.selection) {
|
||||
state.before = strSplice(state.before, lf, 0, '\t');
|
||||
state.selection = state.selection.replace(/\r?\n(?=[\s\S])/g, '\n\t');
|
||||
state.selectionStart++;
|
||||
@ -773,7 +793,7 @@ define([
|
||||
state.selectionEnd = state.selectionStart + state.selection.length;
|
||||
},
|
||||
|
||||
newline: function (state) {
|
||||
newline: function(state) {
|
||||
var lf = state.before.lastIndexOf('\n') + 1;
|
||||
if(clearNewline) {
|
||||
state.before = state.before.substring(0, lf);
|
||||
@ -801,7 +821,7 @@ define([
|
||||
state.selection = '';
|
||||
state.selectionStart += indent.length + 1;
|
||||
state.selectionEnd = state.selectionStart;
|
||||
},
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
@ -809,6 +829,7 @@ define([
|
||||
var sectionsToRemove = [];
|
||||
var modifiedSections = [];
|
||||
var insertBeforeSection;
|
||||
|
||||
function updateSectionList(newSectionList) {
|
||||
|
||||
modifiedSections = [];
|
||||
@ -912,7 +933,7 @@ define([
|
||||
|
||||
function addTrailingLfNode() {
|
||||
trailingLfNode = crel('span', {
|
||||
class: 'token lf',
|
||||
class: 'token lf'
|
||||
});
|
||||
trailingLfNode.textContent = '\n';
|
||||
contentElt.appendChild(trailingLfNode);
|
||||
@ -922,7 +943,7 @@ define([
|
||||
var entityMap = {
|
||||
"&": "&",
|
||||
"<": "<",
|
||||
"\u00a0": ' ',
|
||||
"\u00a0": ' '
|
||||
};
|
||||
return function(str) {
|
||||
return str.replace(/[&<\u00a0]/g, function(s) {
|
||||
|
@ -11,8 +11,9 @@ define([
|
||||
'crel',
|
||||
'sequence-diagram',
|
||||
'flow-chart',
|
||||
'pagedown-extra',
|
||||
], function($, _, utils, logger, Extension, markdownExtraSettingsBlockHTML, prettify, hljs, crel, sequenceDiagram, flowChart) {
|
||||
'text!html/tooltipMarkdownExtraDiagrams.html',
|
||||
'pagedown-extra'
|
||||
], function($, _, utils, logger, Extension, markdownExtraSettingsBlockHTML, prettify, hljs, crel, sequenceDiagram, flowChart, tooltipMarkdownExtraDiagramsHTML) {
|
||||
|
||||
var markdownExtra = new Extension("markdownExtra", "Markdown Extra", true);
|
||||
markdownExtra.settingsBlock = markdownExtraSettingsBlockHTML;
|
||||
@ -25,7 +26,7 @@ define([
|
||||
"footnotes",
|
||||
"smartypants",
|
||||
"strikethrough",
|
||||
"newlines",
|
||||
"newlines"
|
||||
],
|
||||
intraword: true,
|
||||
comments: true,
|
||||
@ -38,6 +39,7 @@ define([
|
||||
return extension == extensionName;
|
||||
});
|
||||
}
|
||||
|
||||
utils.setInputChecked("#input-markdownextra-fencedcodegfm", hasExtension("fenced_code_gfm"));
|
||||
utils.setInputChecked("#input-markdownextra-tables", hasExtension("tables"));
|
||||
utils.setInputChecked("#input-markdownextra-deflist", hasExtension("def_list"));
|
||||
@ -49,6 +51,7 @@ define([
|
||||
utils.setInputChecked("#input-markdownextra-intraword", markdownExtra.config.intraword);
|
||||
utils.setInputChecked("#input-markdownextra-comments", markdownExtra.config.comments);
|
||||
utils.setInputValue("#input-markdownextra-highlighter", markdownExtra.config.highlighter);
|
||||
utils.setInputChecked("#input-markdownextra-diagrams", markdownExtra.config.diagrams);
|
||||
};
|
||||
|
||||
markdownExtra.onSaveSettings = function(newConfig) {
|
||||
@ -64,6 +67,7 @@ define([
|
||||
newConfig.intraword = utils.getInputChecked("#input-markdownextra-intraword");
|
||||
newConfig.comments = utils.getInputChecked("#input-markdownextra-comments");
|
||||
newConfig.highlighter = utils.getInputValue("#input-markdownextra-highlighter");
|
||||
newConfig.diagrams = utils.getInputChecked("#input-markdownextra-diagrams");
|
||||
};
|
||||
|
||||
var eventMgr;
|
||||
@ -74,6 +78,126 @@ define([
|
||||
var previewContentsElt;
|
||||
markdownExtra.onReady = function() {
|
||||
previewContentsElt = document.getElementById('preview-contents');
|
||||
utils.createTooltip(".tooltip-markdown-extra-diagrams", tooltipMarkdownExtraDiagramsHTML);
|
||||
};
|
||||
|
||||
var onAsyncPreview = function(cb) {
|
||||
cb();
|
||||
};
|
||||
markdownExtra.onAsyncPreview = function(cb) {
|
||||
onAsyncPreview(cb);
|
||||
};
|
||||
|
||||
var extraOptions;
|
||||
markdownExtra.onInit = function() {
|
||||
var sequenceDiagramEltList, flowChartEltList, highlightEltList, prettifyEltList;
|
||||
extraOptions = {
|
||||
extensions: markdownExtra.config.extensions
|
||||
};
|
||||
|
||||
function doSequenceDiagram(cb) {
|
||||
if(sequenceDiagramEltList.length === 0) {
|
||||
return cb();
|
||||
}
|
||||
var sequenceDiagramElt = sequenceDiagramEltList.pop();
|
||||
try {
|
||||
var diagram = sequenceDiagram.parse(sequenceDiagramElt.textContent);
|
||||
var preElt = sequenceDiagramElt.parentNode;
|
||||
var containerElt = crel('div', {
|
||||
class: 'sequence-diagram'
|
||||
});
|
||||
preElt.parentNode.replaceChild(containerElt, preElt);
|
||||
diagram.drawSVG(containerElt, {
|
||||
theme: 'simple'
|
||||
});
|
||||
}
|
||||
catch(e) {
|
||||
}
|
||||
_.delay(doSequenceDiagram, 0, cb);
|
||||
}
|
||||
|
||||
function doFlowChart(cb) {
|
||||
if(flowChartEltList.length === 0) {
|
||||
return cb();
|
||||
}
|
||||
var flowChartElt = flowChartEltList.pop();
|
||||
try {
|
||||
var chart = flowChart.parse(flowChartElt.textContent);
|
||||
var preElt = flowChartElt.parentNode;
|
||||
var containerElt = crel('div', {
|
||||
class: 'flow-chart'
|
||||
});
|
||||
preElt.parentNode.replaceChild(containerElt, preElt);
|
||||
chart.drawSVG(containerElt, {
|
||||
'line-width': 2
|
||||
});
|
||||
}
|
||||
catch(e) {
|
||||
}
|
||||
_.delay(doFlowChart, 0, cb);
|
||||
}
|
||||
|
||||
function doHighlight(cb) {
|
||||
if(highlightEltList.length === 0) {
|
||||
return cb();
|
||||
}
|
||||
var highlightElt = highlightEltList.pop();
|
||||
hljs.highlightBlock(highlightElt);
|
||||
highlightElt.highlighted = true;
|
||||
_.delay(doHighlight, 0, cb);
|
||||
}
|
||||
|
||||
function doPrettify(cb) {
|
||||
if(prettifyEltList.length === 0) {
|
||||
return cb();
|
||||
}
|
||||
var prettifyElt = prettifyEltList.pop();
|
||||
var html = prettify.prettyPrintOne(prettifyElt.innerHTML);
|
||||
prettifyElt.innerHTML = html;
|
||||
prettifyElt.highlighted = true;
|
||||
_.delay(doPrettify, 0, cb);
|
||||
}
|
||||
|
||||
if(markdownExtra.config.highlighter == "highlight") {
|
||||
extraOptions.highlighter = "prettify";
|
||||
var afterHighlight = onAsyncPreview;
|
||||
onAsyncPreview = function(cb) {
|
||||
highlightEltList = _.filter(previewContentsElt.querySelectorAll('.prettyprint > code'), function(elt) {
|
||||
return !elt.highlighted;
|
||||
});
|
||||
_.delay(doHighlight, 0, function() {
|
||||
afterHighlight(cb);
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
if(markdownExtra.config.highlighter == "prettify") {
|
||||
extraOptions.highlighter = "prettify";
|
||||
var afterPrettify = onAsyncPreview;
|
||||
onAsyncPreview = function(cb) {
|
||||
prettifyEltList = _.filter(previewContentsElt.querySelectorAll('.prettyprint > code'), function(elt) {
|
||||
return !elt.highlighted;
|
||||
});
|
||||
_.delay(doPrettify, 0, function() {
|
||||
afterPrettify(cb);
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
if(markdownExtra.config.diagrams) {
|
||||
extraOptions.highlighter = "prettify";
|
||||
var afterDiagrams = onAsyncPreview;
|
||||
onAsyncPreview = function(cb) {
|
||||
sequenceDiagramEltList = Array.prototype.slice.call(previewContentsElt.querySelectorAll('.prettyprint > .language-sequence'));
|
||||
flowChartEltList = Array.prototype.slice.call(previewContentsElt.querySelectorAll('.prettyprint > .language-flow'));
|
||||
_.delay(doSequenceDiagram, 0, function() {
|
||||
_.delay(doFlowChart, 0, function() {
|
||||
afterDiagrams(cb);
|
||||
});
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
markdownExtra.onPagedownConfigure = function(editor) {
|
||||
@ -95,62 +219,6 @@ define([
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
var extraOptions = {
|
||||
extensions: markdownExtra.config.extensions
|
||||
};
|
||||
|
||||
function doSequenceDiagrams() {
|
||||
_.each(previewContentsElt.querySelectorAll('.prettyprint > .language-sequence'), function(elt) {
|
||||
try {
|
||||
var diagram = sequenceDiagram.parse(elt.textContent);
|
||||
var preElt = elt.parentNode;
|
||||
var containerElt = crel('div', {
|
||||
class: 'sequence-diagram'
|
||||
});
|
||||
preElt.parentNode.replaceChild(containerElt, preElt);
|
||||
diagram.drawSVG(containerElt, {
|
||||
theme: 'simple'
|
||||
});
|
||||
}
|
||||
catch(e) {
|
||||
console.error(e);
|
||||
}
|
||||
});
|
||||
_.each(previewContentsElt.querySelectorAll('.prettyprint > .language-flow'), function(elt) {
|
||||
try {
|
||||
var chart = flowChart.parse(elt.textContent);
|
||||
var preElt = elt.parentNode;
|
||||
var containerElt = crel('div', {
|
||||
class: 'flow-chart'
|
||||
});
|
||||
preElt.parentNode.replaceChild(containerElt, preElt);
|
||||
chart.drawSVG(containerElt, {
|
||||
'line-width': 2
|
||||
});
|
||||
}
|
||||
catch(e) {
|
||||
console.error(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
if(markdownExtra.config.highlighter == "highlight") {
|
||||
extraOptions.highlighter = "prettify";
|
||||
editor.hooks.chain("onPreviewRefresh", function() {
|
||||
doSequenceDiagrams();
|
||||
_.each(previewContentsElt.querySelectorAll('.prettyprint > code'), function(elt) {
|
||||
!elt.highlighted && hljs.highlightBlock(elt);
|
||||
elt.highlighted = true;
|
||||
});
|
||||
});
|
||||
}
|
||||
else if(markdownExtra.config.highlighter == "prettify") {
|
||||
extraOptions.highlighter = "prettify";
|
||||
editor.hooks.chain("onPreviewRefresh", function() {
|
||||
doSequenceDiagrams();
|
||||
prettify.prettyPrint();
|
||||
});
|
||||
}
|
||||
Markdown.Extra.init(converter, extraOptions);
|
||||
};
|
||||
|
||||
|
@ -6,12 +6,13 @@ define([
|
||||
"classes/Extension",
|
||||
"text!extensions/shortcutsDefaultMapping.settings",
|
||||
"text!html/shortcutsSettingsBlock.html",
|
||||
], function($, _, utils, mousetrap, Extension, shortcutsDefaultMapping, shortcutsSettingsBlockHTML) {
|
||||
"text!html/tooltipSettingsShortcutsExtension.html"
|
||||
], function($, _, utils, mousetrap, Extension, shortcutsDefaultMapping, shortcutsSettingsBlockHTML, tooltipSettingsShortcutsExtensionHTML) {
|
||||
|
||||
var shortcuts = new Extension("shortcuts", "Shortcuts", true, true);
|
||||
shortcuts.settingsBlock = shortcutsSettingsBlockHTML;
|
||||
shortcuts.defaultConfig = {
|
||||
mapping: shortcutsDefaultMapping,
|
||||
mapping: shortcutsDefaultMapping
|
||||
};
|
||||
|
||||
var eventMgr;
|
||||
@ -69,5 +70,9 @@ define([
|
||||
}
|
||||
};
|
||||
|
||||
shortcuts.onReady = function() {
|
||||
utils.createTooltip(".tooltip-shortcuts-extension", tooltipSettingsShortcutsExtensionHTML);
|
||||
};
|
||||
|
||||
return shortcuts;
|
||||
});
|
||||
|
@ -6,12 +6,13 @@ define([
|
||||
"fileSystem",
|
||||
"settings",
|
||||
"text!html/userCustomSettingsBlock.html",
|
||||
], function($, _, utils, Extension, fileSystem, settings, userCustomSettingsBlockHTML) {
|
||||
"text!html/tooltipUserCustomExtension.html"
|
||||
], function($, _, utils, Extension, fileSystem, settings, userCustomSettingsBlockHTML, tooltipUserCustomExtensionHTML) {
|
||||
|
||||
var userCustom = new Extension("userCustom", "UserCustom extension", true);
|
||||
userCustom.settingsBlock = userCustomSettingsBlockHTML;
|
||||
userCustom.defaultConfig = {
|
||||
code: "",
|
||||
code: ""
|
||||
};
|
||||
|
||||
var fileMgr;
|
||||
@ -61,5 +62,9 @@ define([
|
||||
}
|
||||
};
|
||||
|
||||
userCustom.onReady = function() {
|
||||
utils.createTooltip(".tooltip-usercustom-extension", tooltipUserCustomExtensionHTML);
|
||||
};
|
||||
|
||||
return userCustom;
|
||||
});
|
@ -198,7 +198,7 @@
|
||||
</ul>
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon"><i class="icon-search"></i></span><input
|
||||
type="text" class="form-control" placeholder="Find document"></input>
|
||||
type="text" class="form-control" placeholder="Find document" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel-content">
|
||||
@ -278,7 +278,7 @@
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon"><i class="icon-globe"></i></span><input
|
||||
id="input-insert-link" type="text" class="col-sm-5 form-control"
|
||||
placeholder='http://example.com/ "optional title"'></input>
|
||||
placeholder='http://example.com/ "optional title"' />
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
@ -305,7 +305,7 @@
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon"><i class="icon-picture"></i></span><input
|
||||
id="input-insert-image" type="text" class="col-sm-5 form-control"
|
||||
placeholder='http://example.com/image.jpg "optional title"'></input>
|
||||
placeholder='http://example.com/image.jpg "optional title"' />
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
@ -963,7 +963,7 @@
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-4 control-label"
|
||||
for="input-settings-gdrive-multiaccount">Google Drive multi-accounts</a>
|
||||
for="input-settings-gdrive-multiaccount">Google Drive multi-accounts
|
||||
</label>
|
||||
<div class="col-sm-7">
|
||||
<select id="input-settings-gdrive-multiaccount" class="form-control">
|
||||
@ -1082,7 +1082,7 @@
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-4 control-label"
|
||||
for="input-settings-markdown-mime-type">Markdown MIME type</a>
|
||||
for="input-settings-markdown-mime-type">Markdown MIME type
|
||||
</label>
|
||||
<div class="col-sm-7">
|
||||
<select id="input-settings-markdown-mime-type" class="form-control">
|
||||
@ -1159,7 +1159,7 @@
|
||||
data-dismiss="modal"><i class="icon-help-circled"></i>
|
||||
Welcome document</a> <a href="#"
|
||||
class="btn btn-block btn-primary action-welcome-tour"
|
||||
data-dismiss="modal" data-dismiss="modal"><i
|
||||
data-dismiss="modal"><i
|
||||
class="icon-help-circled"></i> Welcome tour</a>
|
||||
</div>
|
||||
<div class="tab-pane-button-container">
|
||||
|
@ -100,6 +100,15 @@
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-4 control-label"
|
||||
for="input-markdownextra-diagrams">Diagrams <a href="#" class="tooltip-markdown-extra-diagrams">(?)</a></label>
|
||||
<div class="col-sm-7">
|
||||
<div class="checkbox">
|
||||
<input type="checkbox" id="input-markdownextra-diagrams">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="help-block pull-right"><a target="_blank"
|
||||
href="https://github.com/jmcmanus/pagedown-extra">More info</a></span>
|
23
public/res/html/tooltipMarkdownExtraDiagrams.html
Normal file
23
public/res/html/tooltipMarkdownExtraDiagrams.html
Normal file
@ -0,0 +1,23 @@
|
||||
You can create sequence diagrams like this:
|
||||
<br />
|
||||
<br />
|
||||
```sequence<br />
|
||||
Alice->Bob: Hello Bob, how are you?
|
||||
Bob-->Alice: I am good thanks!
|
||||
```<br />
|
||||
<a target="_blank" href="http://bramp.github.io/js-sequence-diagrams/">More info</a>
|
||||
<br />
|
||||
<br />
|
||||
Or flow charts like this:
|
||||
<br />
|
||||
<br />
|
||||
```flow<br />
|
||||
st=>start: Start<br />
|
||||
e=>end<br />
|
||||
op=>operation: My Operation<br />
|
||||
cond=>condition: Yes or No?<br />
|
||||
st->op->cond<br />
|
||||
cond(yes)->e<br />
|
||||
cond(no)->op<br />
|
||||
```<br />
|
||||
<a target="_blank" href="http://adrai.github.io/flowchart.js/">More info</a>
|
@ -230,6 +230,15 @@ define([
|
||||
version = "v18";
|
||||
}
|
||||
|
||||
if(version == 'v18') {
|
||||
if(_.has(localStorage, 'settings')) {
|
||||
settings = JSON.parse(localStorage.settings);
|
||||
((settings.extensionSettings || {}).markdownExtra || {}).diagrams = true;
|
||||
localStorage.settings = JSON.stringify(settings);
|
||||
}
|
||||
version = "v19";
|
||||
}
|
||||
|
||||
localStorage.version = version;
|
||||
return localStorage;
|
||||
});
|
||||
|
@ -132,6 +132,7 @@ hr {
|
||||
|
||||
.sequence-diagram, .flow-chart {
|
||||
text-align: center;
|
||||
margin-bottom: @p-margin;
|
||||
text {
|
||||
font-size: 1em !important;
|
||||
font-family: @font-family-sans-serif !important;
|
||||
|
@ -256,6 +256,10 @@ a {
|
||||
}
|
||||
}
|
||||
|
||||
.text-danger:hover {
|
||||
color: @state-danger-text;
|
||||
}
|
||||
|
||||
.layout-panel() {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
|
@ -5,7 +5,7 @@ define([
|
||||
"crel",
|
||||
"xregexp",
|
||||
"stacktrace",
|
||||
"FileSaver",
|
||||
"FileSaver"
|
||||
], function($, _, storage, crel, XRegExp, printStackTrace, saveAs) {
|
||||
|
||||
var utils = {};
|
||||
@ -31,10 +31,12 @@ define([
|
||||
// Implements underscore debounce using our defer function
|
||||
utils.debounce = function(func, context) {
|
||||
var isExpected = false;
|
||||
|
||||
function later() {
|
||||
isExpected = false;
|
||||
func.call(context);
|
||||
}
|
||||
|
||||
return function() {
|
||||
if(isExpected === true) {
|
||||
return;
|
||||
@ -47,12 +49,19 @@ define([
|
||||
// Generates a 24 chars length random string (should be enough to prevent collisions)
|
||||
utils.randomString = (function() {
|
||||
var max = Math.pow(36, 6);
|
||||
|
||||
function s6() {
|
||||
// Linear [0-9a-z]{6} random string
|
||||
return ('000000' + (Math.random() * max | 0).toString(36)).slice(-6);
|
||||
}
|
||||
|
||||
return function() {
|
||||
return [s6(), s6(), s6(), s6()].join('');
|
||||
return [
|
||||
s6(),
|
||||
s6(),
|
||||
s6(),
|
||||
s6()
|
||||
].join('');
|
||||
};
|
||||
})();
|
||||
|
||||
@ -242,7 +251,7 @@ define([
|
||||
// Create a backdrop and add to the body
|
||||
utils.createBackdrop = function(parent) {
|
||||
var result = crel('div', {
|
||||
'class': 'modal-backdrop fade',
|
||||
'class': 'modal-backdrop fade'
|
||||
});
|
||||
parent = parent || document.body;
|
||||
parent.appendChild(result);
|
||||
@ -257,6 +266,28 @@ define([
|
||||
return result;
|
||||
};
|
||||
|
||||
var openedTooltip;
|
||||
utils.createTooltip = function(selector, content) {
|
||||
_.each(document.querySelectorAll(selector), function(tooltipElt) {
|
||||
var $tooltipElt = $(tooltipElt);
|
||||
$tooltipElt.tooltip({
|
||||
html: true,
|
||||
container: $tooltipElt.parents('.modal-content'),
|
||||
placement: 'right',
|
||||
trigger: 'manual',
|
||||
title: content
|
||||
}).click(function() {
|
||||
var elt = this;
|
||||
if(openedTooltip && openedTooltip[0] === elt) {
|
||||
return;
|
||||
}
|
||||
utils.defer(function() {
|
||||
openedTooltip = $(elt).tooltip('show');
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// Create an centered popup window
|
||||
utils.popupWindow = function(url, title, width, height) {
|
||||
var left = (screen.width / 2) - (width / 2);
|
||||
@ -297,6 +328,15 @@ define([
|
||||
redirectCallbackCancel && redirectCallbackCancel();
|
||||
});
|
||||
});
|
||||
$(document).on('click', function() {
|
||||
// Close opened tooltip if any
|
||||
openedTooltip && openedTooltip.tooltip('hide');
|
||||
openedTooltip = undefined;
|
||||
});
|
||||
$(document).on('click', '.tooltip', function(evt) {
|
||||
// Avoid tooltip to close when clicking inside
|
||||
evt.stopPropagation();
|
||||
});
|
||||
};
|
||||
|
||||
var entityMap = {
|
||||
@ -306,7 +346,7 @@ define([
|
||||
'"': '"',
|
||||
"'": ''',
|
||||
"/": '/',
|
||||
"\u00a0": ' ',
|
||||
"\u00a0": ' '
|
||||
};
|
||||
|
||||
// Escape HTML entities
|
||||
@ -433,7 +473,7 @@ define([
|
||||
str = encodeURI(str);
|
||||
length = str.length;
|
||||
|
||||
while (offset < length) {
|
||||
while(offset < length) {
|
||||
char = str[offset];
|
||||
offset += 1;
|
||||
|
||||
@ -456,14 +496,14 @@ define([
|
||||
|
||||
var imax = bytes.length - bytes.length % 3;
|
||||
|
||||
for (i = 0; i < imax; i += 3) {
|
||||
for(i = 0; i < imax; i += 3) {
|
||||
b10 = (bytes[i] << 16) | (bytes[i + 1] << 8) | bytes[i + 2];
|
||||
x.push(alpha.charAt(b10 >> 18));
|
||||
x.push(alpha.charAt((b10 >> 12) & 0x3F));
|
||||
x.push(alpha.charAt((b10 >> 6) & 0x3f));
|
||||
x.push(alpha.charAt(b10 & 0x3f));
|
||||
}
|
||||
switch (bytes.length - imax) {
|
||||
switch(bytes.length - imax) {
|
||||
case 1:
|
||||
b10 = bytes[i] << 16;
|
||||
x.push(alpha.charAt(b10 >> 18) + alpha.charAt((b10 >> 12) & 0x3F) + padchar + padchar);
|
||||
@ -750,7 +790,7 @@ define([
|
||||
|
||||
window.perfTest = function(cb) {
|
||||
var startTime = Date.now();
|
||||
for(var i=0; i<10000; i++) {
|
||||
for(var i = 0; i < 10000; i++) {
|
||||
cb();
|
||||
}
|
||||
console.log('Run 10,000 times in ' + (Date.now() - startTime) + 'ms');
|
||||
|
Loading…
Reference in New Issue
Block a user