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) {
 | 
			
		||||
 | 
			
		||||
@ -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
 | 
			
		||||
@ -194,6 +195,7 @@ define([
 | 
			
		||||
		};
 | 
			
		||||
		this.saveSelectionState = (function() {
 | 
			
		||||
			var timeoutId;
 | 
			
		||||
 | 
			
		||||
			function save(adjustScroll) {
 | 
			
		||||
				clearTimeout(timeoutId);
 | 
			
		||||
				timeoutId = undefined;
 | 
			
		||||
@ -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() {
 | 
			
		||||
@ -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
 | 
			
		||||
@ -749,6 +768,7 @@ define([
 | 
			
		||||
					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))) {
 | 
			
		||||
@ -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
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user