Add MathJax support
This commit is contained in:
parent
bd154bd245
commit
6c83a8f67c
28
index.html
28
index.html
@ -494,14 +494,6 @@
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label" for="input-settings-scroll-link">Scroll
|
||||
Link <a href="#" class="tooltip-scroll-link">(?)</a>
|
||||
</label>
|
||||
<div class="controls">
|
||||
<input type="checkbox" id="input-settings-scroll-link" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label" for="input-settings-converter-type">Converter</label>
|
||||
<div class="controls">
|
||||
@ -513,13 +505,29 @@
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label" for="input-settings-enable-mathjax">MathJax
|
||||
support </label>
|
||||
<div class="controls">
|
||||
<input type="checkbox" id="input-settings-enable-mathjax" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label" for="input-settings-enable-mathjax">MathJax support
|
||||
<label class="control-label" for="input-settings-lazy-rendering">Lazy
|
||||
rendering <a href="#" class="tooltip-lazy-rendering">(?)</a>
|
||||
</label>
|
||||
<div class="controls">
|
||||
<input type="checkbox" id="input-settings-enable-mathjax" />
|
||||
<input type="checkbox" id="input-settings-lazy-rendering" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label" for="input-settings-scroll-link">Scroll
|
||||
Link <a href="#" class="tooltip-scroll-link">(?)</a>
|
||||
</label>
|
||||
<div class="controls">
|
||||
<input type="checkbox" id="input-settings-scroll-link" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label"
|
||||
for="input-settings-editor-font-size">Editor font size</label>
|
||||
|
@ -118,13 +118,13 @@
|
||||
var that = this,
|
||||
panels;
|
||||
|
||||
this.run = function () {
|
||||
this.run = function (previewWrapper) {
|
||||
if (panels)
|
||||
return; // already initialized
|
||||
|
||||
panels = new PanelCollection(idPostfix);
|
||||
var commandManager = new CommandManager(hooks, getString);
|
||||
var previewManager = new PreviewManager(markdownConverter, panels, function () { hooks.onPreviewRefresh(); });
|
||||
var previewManager = new PreviewManager(markdownConverter, panels, function () { hooks.onPreviewRefresh(); }, previewWrapper);
|
||||
var undoManager, uiManager;
|
||||
|
||||
if (!/\?noundo/.test(doc.location.href)) {
|
||||
@ -821,14 +821,14 @@
|
||||
this.init();
|
||||
};
|
||||
|
||||
function PreviewManager(converter, panels, previewRefreshCallback) {
|
||||
function PreviewManager(converter, panels, previewRefreshCallback, previewWrapper) {
|
||||
|
||||
var managerObj = this;
|
||||
var timeout;
|
||||
var elapsedTime;
|
||||
var oldInputText;
|
||||
var maxDelay = 3000;
|
||||
var startType = "manual"; // The other legal value is "manual"
|
||||
var startType = "delayed"; // The other legal value is "manual"
|
||||
|
||||
// Adds event listeners to elements
|
||||
var setupEvents = function (inputElem, listener) {
|
||||
@ -887,6 +887,9 @@
|
||||
|
||||
pushPreviewHtml(text);
|
||||
};
|
||||
if(previewWrapper !== undefined) {
|
||||
makePreviewHtml = previewWrapper(makePreviewHtml);
|
||||
}
|
||||
|
||||
// setTimeout is already used. Used as an event listener.
|
||||
var applyTimeout = function () {
|
||||
|
@ -9,10 +9,10 @@ var DROPBOX_APP_SECRET = "851fgnucpezy84t";
|
||||
var BITLY_ACCESS_TOKEN = "317e033bfd48cf31155a68a536b1860013b09c4c";
|
||||
var DEFAULT_FILE_TITLE = "Title";
|
||||
var GDRIVE_DEFAULT_FILE_TITLE = "New Markdown document";
|
||||
var CHECK_ONLINE_PERIOD = 60000;
|
||||
var AJAX_TIMEOUT = 15000;
|
||||
var ASYNC_TASK_DEFAULT_TIMEOUT = 30000;
|
||||
var ASYNC_TASK_LONG_TIMEOUT = 90000;
|
||||
var CHECK_ONLINE_PERIOD = 120000;
|
||||
var AJAX_TIMEOUT = 30000;
|
||||
var ASYNC_TASK_DEFAULT_TIMEOUT = 60000;
|
||||
var ASYNC_TASK_LONG_TIMEOUT = 120000;
|
||||
var SYNC_PERIOD = 180000;
|
||||
var USER_IDLE_THRESHOLD = 300000;
|
||||
var WELCOME_DOCUMENT_TITLE = "Welcome document";
|
||||
|
83
js/core.js
83
js/core.js
@ -208,6 +208,7 @@ define(
|
||||
core.settings = {
|
||||
converterType : "markdown-extra-prettify",
|
||||
enableMathJax : true,
|
||||
lazyRendering : true,
|
||||
layoutOrientation : "horizontal",
|
||||
scrollLink : true,
|
||||
editorFontSize : 14,
|
||||
@ -236,6 +237,8 @@ define(
|
||||
$("#input-settings-converter-type").val(core.settings.converterType);
|
||||
// MathJax
|
||||
$("#input-settings-enable-mathjax").prop("checked", core.settings.enableMathJax);
|
||||
// Lazy rendering
|
||||
$("#input-settings-lazy-rendering").prop("checked", core.settings.lazyRendering);
|
||||
// Editor font size
|
||||
$("#input-settings-editor-font-size").val(core.settings.editorFontSize);
|
||||
// Default content
|
||||
@ -258,6 +261,8 @@ define(
|
||||
newSettings.enableMathJax = $("#input-settings-enable-mathjax").prop("checked");
|
||||
// Scroll Link
|
||||
newSettings.scrollLink = $("#input-settings-scroll-link").prop("checked");
|
||||
// Lazy Rendering
|
||||
newSettings.lazyRendering = $("#input-settings-lazy-rendering").prop("checked");
|
||||
// Editor font size
|
||||
newSettings.editorFontSize = core.getInputIntValue($("#input-settings-editor-font-size"), event, 1, 99);
|
||||
// Default content
|
||||
@ -360,21 +365,23 @@ define(
|
||||
|
||||
// apply Scroll Link
|
||||
lastEditorScrollTop = -9;
|
||||
skipScrollLink = false;
|
||||
scrollLink();
|
||||
}, 500);
|
||||
|
||||
// -9 is less than -5
|
||||
var lastEditorScrollTop = -9;
|
||||
var lastPreviewScrollTop = -9;
|
||||
var skipScrollLink = false;
|
||||
var scrollLink = _.debounce(function() {
|
||||
if(mdSectionList.length === 0 || mdSectionList.length !== htmlSectionList.length) {
|
||||
if(skipScrollLink === true || mdSectionList.length === 0 || mdSectionList.length !== htmlSectionList.length) {
|
||||
return;
|
||||
}
|
||||
var editorElt = $("#wmd-input");
|
||||
var editorScrollTop = editorElt.scrollTop();
|
||||
var previewElt = $("#wmd-preview");
|
||||
var previewScrollTop = previewElt.scrollTop();
|
||||
function animate(srcScrollTop, srcSectionList, destElt, destSectionList, callback) {
|
||||
function animate(srcScrollTop, srcSectionList, destElt, destSectionList, lastDestScrollTop, callback) {
|
||||
// Find the section corresponding to the offset
|
||||
var sectionIndex = undefined;
|
||||
var srcSection = _.find(srcSectionList, function(section, index) {
|
||||
@ -389,19 +396,24 @@ define(
|
||||
var destSection = destSectionList[sectionIndex];
|
||||
var destScrollTop = destSection.startOffset + destSection.height * posInSection;
|
||||
destScrollTop = _.min([destScrollTop, destElt.prop('scrollHeight') - destElt.outerHeight()]);
|
||||
destElt.animate({scrollTop: destScrollTop}, 600, callback);
|
||||
return destScrollTop;
|
||||
if(Math.abs(destScrollTop - lastDestScrollTop) < 5) {
|
||||
// Skip the animation in case it's not necessary
|
||||
return;
|
||||
}
|
||||
destElt.animate({scrollTop: destScrollTop}, 600, function() {
|
||||
callback(destScrollTop);
|
||||
});
|
||||
}
|
||||
if(Math.abs(editorScrollTop - lastEditorScrollTop) > 5) {
|
||||
lastEditorScrollTop = editorScrollTop;
|
||||
previewScrollTop = animate(editorScrollTop, mdSectionList, previewElt, htmlSectionList, function() {
|
||||
lastPreviewScrollTop = previewElt.scrollTop();
|
||||
animate(editorScrollTop, mdSectionList, previewElt, htmlSectionList, lastPreviewScrollTop, function(destScrollTop) {
|
||||
lastPreviewScrollTop = destScrollTop;
|
||||
});
|
||||
}
|
||||
else if(Math.abs(previewScrollTop - lastPreviewScrollTop) > 5) {
|
||||
lastPreviewScrollTop = previewScrollTop;
|
||||
editorScrollTop = animate(previewScrollTop, htmlSectionList, editorElt, mdSectionList, function() {
|
||||
lastEditorScrollTop = editorElt.scrollTop();
|
||||
animate(previewScrollTop, htmlSectionList, editorElt, mdSectionList, lastEditorScrollTop, function(destScrollTop) {
|
||||
lastEditorScrollTop = destScrollTop;
|
||||
});
|
||||
}
|
||||
}, 600);
|
||||
@ -475,6 +487,9 @@ define(
|
||||
// Create the PageDown editor
|
||||
var insertLinkCallback = undefined;
|
||||
core.createEditor = function(onTextChange) {
|
||||
skipScrollLink = true;
|
||||
lastPreviewScrollTop = -9;
|
||||
$("#wmd-input, #wmd-preview").scrollTop(0);
|
||||
$("#wmd-button-bar").empty();
|
||||
var converter = new Markdown.Converter();
|
||||
if(core.settings.converterType.indexOf("markdown-extra") === 0) {
|
||||
@ -504,33 +519,40 @@ define(
|
||||
if(core.settings.converterType == "markdown-extra-prettify") {
|
||||
editor.hooks.chain("onPreviewRefresh", prettyPrint);
|
||||
}
|
||||
function previewFinished() {
|
||||
var previewRefreshFinished = function() {
|
||||
if(viewerMode === false && core.settings.scrollLink === true) {
|
||||
// MathJax may have change the scroll position. Restore it
|
||||
$("#wmd-preview").scrollTop(lastPreviewScrollTop);
|
||||
// Update Scroll Link sections
|
||||
// Modify scroll position of the preview not the editor
|
||||
lastEditorScrollTop = -9;
|
||||
buildSections();
|
||||
// Preview may change if images are loading
|
||||
$("#wmd-preview img").load(function() {
|
||||
function updateScrollLinkSections() {
|
||||
// Modify scroll position of the preview not the editor
|
||||
lastEditorScrollTop = -9;
|
||||
buildSections();
|
||||
});
|
||||
// Preview may change if images are loading
|
||||
$("#wmd-preview img").load(function() {
|
||||
lastEditorScrollTop = -9;
|
||||
buildSections();
|
||||
});
|
||||
}
|
||||
// MathJax may have change the scroll position. Restore it
|
||||
$("#wmd-preview").scrollTop(lastPreviewScrollTop);
|
||||
_.defer(updateScrollLinkSections);
|
||||
}
|
||||
}
|
||||
};
|
||||
// MathJax
|
||||
if(core.settings.enableMathJax === true) {
|
||||
mathjaxEditing.prepareWmdForMathJax(editor, [["$", "$"], ["\\\\(", "\\\\)"]], previewFinished);
|
||||
mathjaxEditing.prepareWmdForMathJax(editor, [["$", "$"], ["\\\\(", "\\\\)"]], function() {
|
||||
skipScrollLink = true;
|
||||
}, previewRefreshFinished);
|
||||
}
|
||||
else {
|
||||
editor.hooks.chain("onPreviewRefresh", previewFinished);
|
||||
editor.hooks.chain("onPreviewRefresh", previewRefreshFinished);
|
||||
}
|
||||
// Custom insert link dialog
|
||||
editor.hooks.set("insertLinkDialog", function (callback) {
|
||||
insertLinkCallback = callback;
|
||||
core.resetModalInputs();
|
||||
$("#modal-insert-link").modal();
|
||||
_.defer(function() {
|
||||
$("#input-insert-link").focus();
|
||||
});
|
||||
return true;
|
||||
});
|
||||
// Custom insert image dialog
|
||||
@ -538,12 +560,22 @@ define(
|
||||
insertLinkCallback = callback;
|
||||
core.resetModalInputs();
|
||||
$("#modal-insert-image").modal();
|
||||
_.defer(function() {
|
||||
$("#input-insert-image").focus();
|
||||
});
|
||||
return true;
|
||||
});
|
||||
|
||||
editor.run();
|
||||
var previewWrapper = function(makePreview) {
|
||||
return makePreview;
|
||||
};
|
||||
if(core.settings.lazyRendering === true) {
|
||||
previewWrapper = function(makePreview) {
|
||||
return _.debounce(makePreview, 500);
|
||||
};
|
||||
}
|
||||
editor.run(previewWrapper);
|
||||
firstChange = false;
|
||||
$("#wmd-input").bind('input propertychange', _.throttle(editor.refreshPreview, 1000));
|
||||
|
||||
// Hide default buttons
|
||||
$(".wmd-button-row").addClass("btn-group").find("li:not(.wmd-spacer)")
|
||||
@ -845,6 +877,11 @@ define(
|
||||
'Therefore, if your document does not contain any title, the mapping will be linear and consequently less efficient.',
|
||||
].join("")
|
||||
});
|
||||
$(".tooltip-lazy-rendering").tooltip({
|
||||
container: '#modal-settings',
|
||||
placement: 'right',
|
||||
title: 'Disable preview rendering while typing in order to offload CPU. Refresh preview after 500 ms of inactivity.'
|
||||
});
|
||||
$(".tooltip-default-content").tooltip({
|
||||
html: true,
|
||||
container: '#modal-settings',
|
||||
|
2
js/main-min.js
vendored
2
js/main-min.js
vendored
File diff suppressed because one or more lines are too long
@ -151,12 +151,14 @@ define([ "../lib/MathJax/MathJax" ], function() {
|
||||
// This is run to restart MathJax after it has finished
|
||||
// the previous run (that may have been canceled)
|
||||
//
|
||||
var refreshCallback = undefined;
|
||||
var beforeRefreshCallback = undefined;
|
||||
var afterRefreshCallback = undefined;
|
||||
function RestartMJ() {
|
||||
pending = false;
|
||||
HUB.cancelTypeset = false; // won't need to do this in the future
|
||||
HUB.Queue(beforeRefreshCallback);
|
||||
HUB.Queue([ "Typeset", HUB, preview ]);
|
||||
HUB.Queue(refreshCallback);
|
||||
HUB.Queue(afterRefreshCallback);
|
||||
}
|
||||
|
||||
//
|
||||
@ -177,8 +179,9 @@ define([ "../lib/MathJax/MathJax" ], function() {
|
||||
// to handle escaping the math.
|
||||
// Create a preview refresh hook to handle starting MathJax.
|
||||
//
|
||||
function prepareWmdForMathJax(editorObject, delimiters, callback) {
|
||||
refreshCallback = callback;
|
||||
function prepareWmdForMathJax(editorObject, delimiters, beforeRefresh, afterRefresh) {
|
||||
beforeRefreshCallback = beforeRefresh;
|
||||
afterRefreshCallback = afterRefresh;
|
||||
preview = document.getElementById("wmd-preview");
|
||||
inline = delimiters[0][0];
|
||||
|
||||
|
@ -125,10 +125,14 @@ define(["jquery", "core", "async-runner", "download-provider", "gist-provider",
|
||||
_.each(provider.sharingAttributes, function(attributeName) {
|
||||
var parameter = core.getURLParameter(attributeName);
|
||||
if(!parameter) {
|
||||
importParameters = undefined;
|
||||
return;
|
||||
}
|
||||
importParameters[attributeName] = parameter;
|
||||
});
|
||||
if(importParameters === undefined) {
|
||||
return;
|
||||
}
|
||||
$("#wmd-preview, #file-title").hide();
|
||||
provider.importPublic(importParameters, function(error, title, content) {
|
||||
$("#wmd-preview, #file-title").show();
|
||||
|
Loading…
Reference in New Issue
Block a user