Make diagram configurable

This commit is contained in:
benweet 2014-04-26 01:53:06 +01:00
parent fd901e07ba
commit bf778a9945
16 changed files with 2540 additions and 2380 deletions

1
.gitignore vendored
View File

@ -1,4 +1,5 @@
.project
.idea
.settings
node_modules
Thumbs.db

View File

@ -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) {

View File

@ -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 = {
"&": "&amp;",
"<": "&lt;",
"\u00a0": ' ',
"\u00a0": ' '
};
return function(str) {
return str.replace(/[&<\u00a0]/g, function(s) {

View File

@ -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);
};

View File

@ -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;
});

View File

@ -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;
});

View File

@ -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">

View File

@ -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>

View File

@ -0,0 +1,23 @@
You can create sequence diagrams like this:
<br />
<br />
```sequence<br />
Alice-&gt;Bob: Hello Bob, how are you?
Bob--&gt;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=&gt;start: Start<br />
e=&gt;end<br />
op=&gt;operation: My Operation<br />
cond=&gt;condition: Yes or No?<br />
st-&gt;op-&gt;cond<br />
cond(yes)-&gt;e<br />
cond(no)-&gt;op<br />
```<br />
<a target="_blank" href="http://adrai.github.io/flowchart.js/">More info</a>

View File

@ -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;
});

View File

@ -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;

View File

@ -256,6 +256,10 @@ a {
}
}
.text-danger:hover {
color: @state-danger-text;
}
.layout-panel() {
position: absolute;
top: 0;

View File

@ -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([
'"': '&quot;',
"'": '&#39;',
"/": '&#x2F;',
"\u00a0": ' ',
"\u00a0": ' '
};
// Escape HTML entities