Add MathJax support

This commit is contained in:
benweet 2013-05-14 00:10:02 +01:00
parent bd154bd245
commit 6c83a8f67c
7 changed files with 101 additions and 46 deletions

View File

@ -494,14 +494,6 @@
</label> </label>
</div> </div>
</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"> <div class="control-group">
<label class="control-label" for="input-settings-converter-type">Converter</label> <label class="control-label" for="input-settings-converter-type">Converter</label>
<div class="controls"> <div class="controls">
@ -514,12 +506,28 @@
</div> </div>
</div> </div>
<div class="control-group"> <div class="control-group">
<label class="control-label" for="input-settings-enable-mathjax">MathJax support <label class="control-label" for="input-settings-enable-mathjax">MathJax
</label> support </label>
<div class="controls"> <div class="controls">
<input type="checkbox" id="input-settings-enable-mathjax" /> <input type="checkbox" id="input-settings-enable-mathjax" />
</div> </div>
</div> </div>
<div class="control-group">
<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-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"> <div class="control-group">
<label class="control-label" <label class="control-label"
for="input-settings-editor-font-size">Editor font size</label> for="input-settings-editor-font-size">Editor font size</label>

View File

@ -118,13 +118,13 @@
var that = this, var that = this,
panels; panels;
this.run = function () { this.run = function (previewWrapper) {
if (panels) if (panels)
return; // already initialized return; // already initialized
panels = new PanelCollection(idPostfix); panels = new PanelCollection(idPostfix);
var commandManager = new CommandManager(hooks, getString); 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; var undoManager, uiManager;
if (!/\?noundo/.test(doc.location.href)) { if (!/\?noundo/.test(doc.location.href)) {
@ -821,14 +821,14 @@
this.init(); this.init();
}; };
function PreviewManager(converter, panels, previewRefreshCallback) { function PreviewManager(converter, panels, previewRefreshCallback, previewWrapper) {
var managerObj = this; var managerObj = this;
var timeout; var timeout;
var elapsedTime; var elapsedTime;
var oldInputText; var oldInputText;
var maxDelay = 3000; 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 // Adds event listeners to elements
var setupEvents = function (inputElem, listener) { var setupEvents = function (inputElem, listener) {
@ -887,6 +887,9 @@
pushPreviewHtml(text); pushPreviewHtml(text);
}; };
if(previewWrapper !== undefined) {
makePreviewHtml = previewWrapper(makePreviewHtml);
}
// setTimeout is already used. Used as an event listener. // setTimeout is already used. Used as an event listener.
var applyTimeout = function () { var applyTimeout = function () {

View File

@ -9,10 +9,10 @@ var DROPBOX_APP_SECRET = "851fgnucpezy84t";
var BITLY_ACCESS_TOKEN = "317e033bfd48cf31155a68a536b1860013b09c4c"; var BITLY_ACCESS_TOKEN = "317e033bfd48cf31155a68a536b1860013b09c4c";
var DEFAULT_FILE_TITLE = "Title"; var DEFAULT_FILE_TITLE = "Title";
var GDRIVE_DEFAULT_FILE_TITLE = "New Markdown document"; var GDRIVE_DEFAULT_FILE_TITLE = "New Markdown document";
var CHECK_ONLINE_PERIOD = 60000; var CHECK_ONLINE_PERIOD = 120000;
var AJAX_TIMEOUT = 15000; var AJAX_TIMEOUT = 30000;
var ASYNC_TASK_DEFAULT_TIMEOUT = 30000; var ASYNC_TASK_DEFAULT_TIMEOUT = 60000;
var ASYNC_TASK_LONG_TIMEOUT = 90000; var ASYNC_TASK_LONG_TIMEOUT = 120000;
var SYNC_PERIOD = 180000; var SYNC_PERIOD = 180000;
var USER_IDLE_THRESHOLD = 300000; var USER_IDLE_THRESHOLD = 300000;
var WELCOME_DOCUMENT_TITLE = "Welcome document"; var WELCOME_DOCUMENT_TITLE = "Welcome document";

View File

@ -208,6 +208,7 @@ define(
core.settings = { core.settings = {
converterType : "markdown-extra-prettify", converterType : "markdown-extra-prettify",
enableMathJax : true, enableMathJax : true,
lazyRendering : true,
layoutOrientation : "horizontal", layoutOrientation : "horizontal",
scrollLink : true, scrollLink : true,
editorFontSize : 14, editorFontSize : 14,
@ -236,6 +237,8 @@ define(
$("#input-settings-converter-type").val(core.settings.converterType); $("#input-settings-converter-type").val(core.settings.converterType);
// MathJax // MathJax
$("#input-settings-enable-mathjax").prop("checked", core.settings.enableMathJax); $("#input-settings-enable-mathjax").prop("checked", core.settings.enableMathJax);
// Lazy rendering
$("#input-settings-lazy-rendering").prop("checked", core.settings.lazyRendering);
// Editor font size // Editor font size
$("#input-settings-editor-font-size").val(core.settings.editorFontSize); $("#input-settings-editor-font-size").val(core.settings.editorFontSize);
// Default content // Default content
@ -258,6 +261,8 @@ define(
newSettings.enableMathJax = $("#input-settings-enable-mathjax").prop("checked"); newSettings.enableMathJax = $("#input-settings-enable-mathjax").prop("checked");
// Scroll Link // Scroll Link
newSettings.scrollLink = $("#input-settings-scroll-link").prop("checked"); newSettings.scrollLink = $("#input-settings-scroll-link").prop("checked");
// Lazy Rendering
newSettings.lazyRendering = $("#input-settings-lazy-rendering").prop("checked");
// Editor font size // Editor font size
newSettings.editorFontSize = core.getInputIntValue($("#input-settings-editor-font-size"), event, 1, 99); newSettings.editorFontSize = core.getInputIntValue($("#input-settings-editor-font-size"), event, 1, 99);
// Default content // Default content
@ -360,21 +365,23 @@ define(
// apply Scroll Link // apply Scroll Link
lastEditorScrollTop = -9; lastEditorScrollTop = -9;
skipScrollLink = false;
scrollLink(); scrollLink();
}, 500); }, 500);
// -9 is less than -5 // -9 is less than -5
var lastEditorScrollTop = -9; var lastEditorScrollTop = -9;
var lastPreviewScrollTop = -9; var lastPreviewScrollTop = -9;
var skipScrollLink = false;
var scrollLink = _.debounce(function() { var scrollLink = _.debounce(function() {
if(mdSectionList.length === 0 || mdSectionList.length !== htmlSectionList.length) { if(skipScrollLink === true || mdSectionList.length === 0 || mdSectionList.length !== htmlSectionList.length) {
return; return;
} }
var editorElt = $("#wmd-input"); var editorElt = $("#wmd-input");
var editorScrollTop = editorElt.scrollTop(); var editorScrollTop = editorElt.scrollTop();
var previewElt = $("#wmd-preview"); var previewElt = $("#wmd-preview");
var previewScrollTop = previewElt.scrollTop(); 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 // Find the section corresponding to the offset
var sectionIndex = undefined; var sectionIndex = undefined;
var srcSection = _.find(srcSectionList, function(section, index) { var srcSection = _.find(srcSectionList, function(section, index) {
@ -389,19 +396,24 @@ define(
var destSection = destSectionList[sectionIndex]; var destSection = destSectionList[sectionIndex];
var destScrollTop = destSection.startOffset + destSection.height * posInSection; var destScrollTop = destSection.startOffset + destSection.height * posInSection;
destScrollTop = _.min([destScrollTop, destElt.prop('scrollHeight') - destElt.outerHeight()]); destScrollTop = _.min([destScrollTop, destElt.prop('scrollHeight') - destElt.outerHeight()]);
destElt.animate({scrollTop: destScrollTop}, 600, callback); if(Math.abs(destScrollTop - lastDestScrollTop) < 5) {
return destScrollTop; // Skip the animation in case it's not necessary
return;
}
destElt.animate({scrollTop: destScrollTop}, 600, function() {
callback(destScrollTop);
});
} }
if(Math.abs(editorScrollTop - lastEditorScrollTop) > 5) { if(Math.abs(editorScrollTop - lastEditorScrollTop) > 5) {
lastEditorScrollTop = editorScrollTop; lastEditorScrollTop = editorScrollTop;
previewScrollTop = animate(editorScrollTop, mdSectionList, previewElt, htmlSectionList, function() { animate(editorScrollTop, mdSectionList, previewElt, htmlSectionList, lastPreviewScrollTop, function(destScrollTop) {
lastPreviewScrollTop = previewElt.scrollTop(); lastPreviewScrollTop = destScrollTop;
}); });
} }
else if(Math.abs(previewScrollTop - lastPreviewScrollTop) > 5) { else if(Math.abs(previewScrollTop - lastPreviewScrollTop) > 5) {
lastPreviewScrollTop = previewScrollTop; lastPreviewScrollTop = previewScrollTop;
editorScrollTop = animate(previewScrollTop, htmlSectionList, editorElt, mdSectionList, function() { animate(previewScrollTop, htmlSectionList, editorElt, mdSectionList, lastEditorScrollTop, function(destScrollTop) {
lastEditorScrollTop = editorElt.scrollTop(); lastEditorScrollTop = destScrollTop;
}); });
} }
}, 600); }, 600);
@ -475,6 +487,9 @@ define(
// Create the PageDown editor // Create the PageDown editor
var insertLinkCallback = undefined; var insertLinkCallback = undefined;
core.createEditor = function(onTextChange) { core.createEditor = function(onTextChange) {
skipScrollLink = true;
lastPreviewScrollTop = -9;
$("#wmd-input, #wmd-preview").scrollTop(0);
$("#wmd-button-bar").empty(); $("#wmd-button-bar").empty();
var converter = new Markdown.Converter(); var converter = new Markdown.Converter();
if(core.settings.converterType.indexOf("markdown-extra") === 0) { if(core.settings.converterType.indexOf("markdown-extra") === 0) {
@ -504,11 +519,9 @@ define(
if(core.settings.converterType == "markdown-extra-prettify") { if(core.settings.converterType == "markdown-extra-prettify") {
editor.hooks.chain("onPreviewRefresh", prettyPrint); editor.hooks.chain("onPreviewRefresh", prettyPrint);
} }
function previewFinished() { var previewRefreshFinished = function() {
if(viewerMode === false && core.settings.scrollLink === true) { if(viewerMode === false && core.settings.scrollLink === true) {
// MathJax may have change the scroll position. Restore it function updateScrollLinkSections() {
$("#wmd-preview").scrollTop(lastPreviewScrollTop);
// Update Scroll Link sections
// Modify scroll position of the preview not the editor // Modify scroll position of the preview not the editor
lastEditorScrollTop = -9; lastEditorScrollTop = -9;
buildSections(); buildSections();
@ -518,19 +531,28 @@ define(
buildSections(); buildSections();
}); });
} }
// MathJax may have change the scroll position. Restore it
$("#wmd-preview").scrollTop(lastPreviewScrollTop);
_.defer(updateScrollLinkSections);
} }
};
// MathJax // MathJax
if(core.settings.enableMathJax === true) { if(core.settings.enableMathJax === true) {
mathjaxEditing.prepareWmdForMathJax(editor, [["$", "$"], ["\\\\(", "\\\\)"]], previewFinished); mathjaxEditing.prepareWmdForMathJax(editor, [["$", "$"], ["\\\\(", "\\\\)"]], function() {
skipScrollLink = true;
}, previewRefreshFinished);
} }
else { else {
editor.hooks.chain("onPreviewRefresh", previewFinished); editor.hooks.chain("onPreviewRefresh", previewRefreshFinished);
} }
// Custom insert link dialog // Custom insert link dialog
editor.hooks.set("insertLinkDialog", function (callback) { editor.hooks.set("insertLinkDialog", function (callback) {
insertLinkCallback = callback; insertLinkCallback = callback;
core.resetModalInputs(); core.resetModalInputs();
$("#modal-insert-link").modal(); $("#modal-insert-link").modal();
_.defer(function() {
$("#input-insert-link").focus();
});
return true; return true;
}); });
// Custom insert image dialog // Custom insert image dialog
@ -538,12 +560,22 @@ define(
insertLinkCallback = callback; insertLinkCallback = callback;
core.resetModalInputs(); core.resetModalInputs();
$("#modal-insert-image").modal(); $("#modal-insert-image").modal();
_.defer(function() {
$("#input-insert-image").focus();
});
return true; 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; firstChange = false;
$("#wmd-input").bind('input propertychange', _.throttle(editor.refreshPreview, 1000));
// Hide default buttons // Hide default buttons
$(".wmd-button-row").addClass("btn-group").find("li:not(.wmd-spacer)") $(".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.', 'Therefore, if your document does not contain any title, the mapping will be linear and consequently less efficient.',
].join("") ].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({ $(".tooltip-default-content").tooltip({
html: true, html: true,
container: '#modal-settings', container: '#modal-settings',

2
js/main-min.js vendored

File diff suppressed because one or more lines are too long

View File

@ -151,12 +151,14 @@ define([ "../lib/MathJax/MathJax" ], function() {
// This is run to restart MathJax after it has finished // This is run to restart MathJax after it has finished
// the previous run (that may have been canceled) // the previous run (that may have been canceled)
// //
var refreshCallback = undefined; var beforeRefreshCallback = undefined;
var afterRefreshCallback = undefined;
function RestartMJ() { function RestartMJ() {
pending = false; pending = false;
HUB.cancelTypeset = false; // won't need to do this in the future HUB.cancelTypeset = false; // won't need to do this in the future
HUB.Queue(beforeRefreshCallback);
HUB.Queue([ "Typeset", HUB, preview ]); 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. // to handle escaping the math.
// Create a preview refresh hook to handle starting MathJax. // Create a preview refresh hook to handle starting MathJax.
// //
function prepareWmdForMathJax(editorObject, delimiters, callback) { function prepareWmdForMathJax(editorObject, delimiters, beforeRefresh, afterRefresh) {
refreshCallback = callback; beforeRefreshCallback = beforeRefresh;
afterRefreshCallback = afterRefresh;
preview = document.getElementById("wmd-preview"); preview = document.getElementById("wmd-preview");
inline = delimiters[0][0]; inline = delimiters[0][0];

View File

@ -125,10 +125,14 @@ define(["jquery", "core", "async-runner", "download-provider", "gist-provider",
_.each(provider.sharingAttributes, function(attributeName) { _.each(provider.sharingAttributes, function(attributeName) {
var parameter = core.getURLParameter(attributeName); var parameter = core.getURLParameter(attributeName);
if(!parameter) { if(!parameter) {
importParameters = undefined;
return; return;
} }
importParameters[attributeName] = parameter; importParameters[attributeName] = parameter;
}); });
if(importParameters === undefined) {
return;
}
$("#wmd-preview, #file-title").hide(); $("#wmd-preview, #file-title").hide();
provider.importPublic(importParameters, function(error, title, content) { provider.importPublic(importParameters, function(error, title, content) {
$("#wmd-preview, #file-title").show(); $("#wmd-preview, #file-title").show();