New partialRendering extension

This commit is contained in:
benweet 2013-07-25 00:20:56 +01:00
parent 4ee5e5bbb0
commit ab06427a38
15 changed files with 143 additions and 52 deletions

View File

@ -2,7 +2,7 @@
@page { @page {
margin: 25mm 25mm 25mm 25mm; margin: 25mm 25mm 25mm 25mm;
} }
#wmd-preview { #preview-contents {
padding: 0px; padding: 0px;
margin: 0px; margin: 0px;
} }
@ -16,7 +16,7 @@ body {
tab-size: 4; tab-size: 4;
} }
#wmd-preview { #preview-contents {
padding: 19px; padding: 19px;
margin-bottom: 50px; margin-bottom: 50px;
} }
@ -46,7 +46,7 @@ div,span,a,ul,li,textarea,input,button {
text-shadow: none !important; text-shadow: none !important;
} }
.btn,.navbar-inner,#wmd-preview,.add-on { .btn,.navbar-inner,.add-on {
border: none !important; border: none !important;
} }
@ -720,7 +720,7 @@ table tbody+tbody {
border-top: 2px solid #dddddd; border-top: 2px solid #dddddd;
} }
#wmd-preview blockquote { #preview-contents blockquote {
border-color: #ddd; border-color: #ddd;
border-color: rgba(0, 0, 0, 0.15); border-color: rgba(0, 0, 0, 0.15);
} }
@ -796,7 +796,7 @@ input[type="file"] {
background-color: rgba(215, 215, 215, 0.75) !important; background-color: rgba(215, 215, 215, 0.75) !important;
} }
.viewer #wmd-preview { .viewer #preview-contents {
max-width: 1024px; max-width: 1024px;
margin: 50px auto; margin: 50px auto;
} }

View File

@ -181,7 +181,7 @@ define([
extensionMgr.onLayoutConfigure(layoutGlobalConfig); extensionMgr.onLayoutConfigure(layoutGlobalConfig);
if(settings.layoutOrientation == "horizontal") { if(settings.layoutOrientation == "horizontal") {
$(".ui-layout-south").remove(); $(".ui-layout-south").remove();
$(".preview-container").html('<div id="extension-preview-buttons"></div><div id="wmd-preview"></div>'); $(".preview-container").html('<div id="extension-preview-buttons"></div><div id="preview-contents"><div id="wmd-preview" class="preview-content"></div></div>');
layout = $('body').layout($.extend(layoutGlobalConfig, { layout = $('body').layout($.extend(layoutGlobalConfig, {
east__resizable: true, east__resizable: true,
east__size: .5, east__size: .5,
@ -190,7 +190,7 @@ define([
} }
else if(settings.layoutOrientation == "vertical") { else if(settings.layoutOrientation == "vertical") {
$(".ui-layout-east").remove(); $(".ui-layout-east").remove();
$(".preview-container").html('<div id="extension-preview-buttons"></div><div id="wmd-preview"></div>'); $(".preview-container").html('<div id="extension-preview-buttons"></div><div id="preview-contents"><div id="wmd-preview" class="preview-content"></div></div>');
layout = $('body').layout($.extend(layoutGlobalConfig, { layout = $('body').layout($.extend(layoutGlobalConfig, {
south__resizable: true, south__resizable: true,
south__size: .5, south__size: .5,
@ -299,6 +299,7 @@ define([
else { else {
previewWrapper = function(makePreview) { previewWrapper = function(makePreview) {
return function() { return function() {
window.previewStartTime = new Date().getTime();
makePreview(); makePreview();
if(documentContent === undefined) { if(documentContent === undefined) {
previewContainerElt.scrollTop(fileDesc.previewScrollTop); previewContainerElt.scrollTop(fileDesc.previewScrollTop);

View File

@ -158,11 +158,16 @@ define([
var counter = 0; var counter = 0;
function tryFinished() { function tryFinished() {
if(++counter === nbAsyncPreviewCallback) { if(++counter === nbAsyncPreviewCallback) {
onPreviewFinished(); var html = "";
$("#preview-contents > .preview-content").each(function() {
html += $(this).html();
});
onPreviewFinished(html);
console.log("Preview time: " + (new Date().getTime() - window.previewStartTime));
} }
} }
// We assume images are loading in the preview // We assume images are loading in the preview
$("#wmd-preview").waitForImages(tryFinished); $("#preview-contents").waitForImages(tryFinished);
_.each(onAsyncPreviewCallbackList, function(asyncPreviewCallback) { _.each(onAsyncPreviewCallbackList, function(asyncPreviewCallback) {
asyncPreviewCallback(tryFinished); asyncPreviewCallback(tryFinished);
}); });

View File

@ -30,12 +30,12 @@ define([
selectedFileDesc = fileDesc; selectedFileDesc = fileDesc;
}; };
buttonHtmlCode.onPreviewFinished = function() { buttonHtmlCode.onPreviewFinished = function(html) {
try { try {
var htmlCode = _.template(buttonHtmlCode.config.template, { var htmlCode = _.template(buttonHtmlCode.config.template, {
documentTitle: selectedFileDesc.title, documentTitle: selectedFileDesc.title,
documentMarkdown: selectedFileDesc.content, documentMarkdown: selectedFileDesc.content,
documentHTML: $("#wmd-preview").html() documentHTML: html
}); });
$("#input-html-code").val(htmlCode); $("#input-html-code").val(htmlCode);
} }

View File

@ -45,7 +45,7 @@ define([
}; };
buttonStat.onPreviewFinished = function() { buttonStat.onPreviewFinished = function() {
var text = $("#wmd-preview").clone().find("script").remove().end().text(); var text = $("#preview-contents").clone().find("script").remove().end().text();
$("#span-stat-value1").text((text.match(new RegExp(buttonStat.config.value1, "g")) || []).length); $("#span-stat-value1").text((text.match(new RegExp(buttonStat.config.value1, "g")) || []).length);
$("#span-stat-value2").text((text.match(new RegExp(buttonStat.config.value2, "g")) || []).length); $("#span-stat-value2").text((text.match(new RegExp(buttonStat.config.value2, "g")) || []).length);
$("#span-stat-value3").text((text.match(new RegExp(buttonStat.config.value3, "g")) || []).length); $("#span-stat-value3").text((text.match(new RegExp(buttonStat.config.value3, "g")) || []).length);

View File

@ -17,7 +17,7 @@ define([
}; };
documentSelector.onLoadSettings = function() { documentSelector.onLoadSettings = function() {
utils.setInputValue("#select-document-selector-orderby", documentSelector.config.sortBy); utils.setInputValue("#select-document-selector-orderby", documentSelector.config.orderBy);
utils.setInputValue("#input-document-selector-shortcut-previous", documentSelector.config.shortcutPrevious); utils.setInputValue("#input-document-selector-shortcut-previous", documentSelector.config.shortcutPrevious);
utils.setInputValue("#input-document-selector-shortcut-next", documentSelector.config.shortcutNext); utils.setInputValue("#input-document-selector-shortcut-next", documentSelector.config.shortcutNext);
}; };

View File

@ -61,6 +61,7 @@ define([
}); });
}; };
var converter = undefined;
var ready = false; // true after initial typeset is complete var ready = false; // true after initial typeset is complete
var pending = false; // true when MathJax has been requested var pending = false; // true when MathJax has been requested
var preview = null; // the preview container var preview = null; // the preview container
@ -209,7 +210,7 @@ define([
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([ "Typeset", HUB, preview ]); HUB.Queue([ "Typeset", HUB, converter.eltList || preview ]);
HUB.Queue(afterRefreshCallback); HUB.Queue(afterRefreshCallback);
} }
@ -236,9 +237,9 @@ define([
mathJax.onEditorConfigure = function(editorObject) { mathJax.onEditorConfigure = function(editorObject) {
preview = document.getElementById("wmd-preview"); preview = document.getElementById("wmd-preview");
var converterObject = editorObject.getConverter(); converter = editorObject.getConverter();
converterObject.hooks.chain("preConversion", removeMath); converter.hooks.chain("preConversion", removeMath);
converterObject.hooks.chain("postConversion", replaceMath); converter.hooks.chain("postConversion", replaceMath);
}; };
mathJax.onAsyncPreview = function(callback) { mathJax.onAsyncPreview = function(callback) {
afterRefreshCallback = callback; afterRefreshCallback = callback;

View File

@ -9,8 +9,46 @@ define([
partialRendering.settingsBlock = partialRenderingSettingsBlockHTML; partialRendering.settingsBlock = partialRenderingSettingsBlockHTML;
var converter = undefined; var converter = undefined;
var sectionList = []; var sectionIdGenerator = 0;
var convertedSectionsList = []; var sectionList = [
{
text: ""
}
];
var sectionsToRemove = undefined;
function updateSectionList(newSectionList) {
// Find modified sections starting from left
var leftIndex = sectionList.length;
_.some(sectionList, function(section, index) {
if(index >= newSectionList.length || section.text != newSectionList[index].text) {
leftIndex = index;
return true;
}
});
// Find modified sections starting from right
var rightIndex = -sectionList.length;
_.some(sectionList.slice().reverse(), function(section, index) {
if(index >= newSectionList.length || section.text != newSectionList[newSectionList.length - index - 1].text) {
rightIndex = -index;
return true;
}
});
if(leftIndex === sectionList.length && rightIndex === -leftIndex) {
// No modification detected...
return;
}
// Create an array composed of left unmodified, modified, right
// unmodified sections
var leftSections = sectionList.slice(0, leftIndex);
var modifiedSections = newSectionList.slice(leftIndex, newSectionList.length + rightIndex);
var rightSections = sectionList.slice(sectionList.length + rightIndex, sectionList.length);
sectionsToRemove = sectionList.slice(leftIndex, sectionList.length + rightIndex);
sectionList = leftSections.concat(modifiedSections).concat(rightSections);
}
var hasFootnotes = false; var hasFootnotes = false;
function extractSections(text) { function extractSections(text) {
@ -43,44 +81,78 @@ define([
if(title) { if(title) {
// We just found a title which means end of the previous section // We just found a title which means end of the previous section
if(matchOffset > offset) { if(matchOffset > offset) {
newSectionList.push(text.substring(offset, matchOffset) + "\n" + linkDefinition); newSectionList.push({
id: ++sectionIdGenerator,
text: text.substring(offset, matchOffset) + "\n" + linkDefinition
});
offset = matchOffset; offset = matchOffset;
} }
} }
return ""; return "";
}); });
// Last section // Last section
newSectionList.push(text.substring(offset, text.length) + linkDefinition); newSectionList.push({
id: ++sectionIdGenerator,
text: text.substring(offset, text.length) + linkDefinition
});
sectionList = newSectionList; updateSectionList(newSectionList);
} }
var isRendering = false; var isRendering = false;
var footnoteContainer = $('<div>');
var footnoteContainerFirstChild = $('<div>').appendTo(footnoteContainer);
function renderSections() { function renderSections() {
// Renders sections converter.eltList = [];
// Remove outdated sections
_.each(sectionsToRemove, function(section) {
$("#wmd-preview-section-" + section.id).remove();
footnoteContainer.find("#footnotes-section-" + section.id).remove();
});
var footnoteContainerElt = $("#wmd-preview-section-footnotes");
footnoteContainerElt.empty();
// Renders modified sections
isRendering = true; isRendering = true;
convertedSectionsList = _.map(sectionList, converter.makeHtml); var previousSectionElt = $("#wmd-preview");
var previousFootnoteElt = footnoteContainerFirstChild;
_.each(sectionList, function(section) {
if(section.isConverted === true) {
previousSectionElt = $("#wmd-preview-section-" + section.id);
footnoteContainer.find("#footnotes-section-" + section.id).each(function() {
previousFootnoteElt = $(this);
});
return;
}
var sectionHtml = converter.makeHtml(section.text);
var sectionElt = $('<div id="wmd-preview-section-' + section.id + '" class="preview-content">').html(sectionHtml);
sectionElt.find("div.footnotes").each(function() {
var footnoteElt = $(this).attr("id", "footnotes-section-" + section.id);
previousFootnoteElt.after(footnoteElt);
previousFootnoteElt = footnoteElt;
});
previousSectionElt.after(sectionElt);
previousSectionElt = sectionElt;
converter.eltList.push(sectionElt[0]);
section.isConverted = true;
});
isRendering = false; isRendering = false;
$("#wmd-preview").html(convertedSectionsList.join("")); // Rewrite footnotes in the footer
// Move footnotes in the footer...
if(hasFootnotes === true) { if(hasFootnotes === true) {
// Recreate a footnote list // Recreate a footnote list
var footnoteElts = $("<ol>"); var footnoteElts = $("<ol>");
$("#wmd-preview > div.footnotes > ol > li").each(function(index) { footnoteContainer.find("div.footnotes > ol > li").each(function(index) {
hasFootnotes = true; hasFootnotes = true;
var elt = $(this); var elt = $(this);
footnoteElts.append(elt); footnoteElts.append(elt.clone());
// Restore footnotes numbers // Restore footnotes numbers
var refId = "#fnref\\:" + elt.attr("id").substring(3); var refId = "#fnref\\:" + elt.attr("id").substring(3);
$(refId).text(index + 1); $(refId).text(index + 1);
}); });
// Append the whole footnotes at the end of the document // Append the whole footnotes at the end of the document
$("#wmd-preview > div.footnotes").remove(); footnoteContainerElt.html($('<div class="footnotes">').append("<hr>").append(footnoteElts));
$("#wmd-preview").append($('<div class="footnotes">').append("<hr>").append(footnoteElts));
} }
} }
partialRendering.onEditorConfigure = function(editor) { partialRendering.onEditorConfigure = function(editor) {
@ -97,5 +169,10 @@ define([
}); });
}; };
partialRendering.onReady = function() {
$("#preview-contents").append($('<div id="wmd-preview-section-footnotes" class="preview-content">'));
};
return partialRendering; return partialRendering;
}); });

View File

@ -70,7 +70,7 @@ define([
var htmlSectionOffset = 0; var htmlSectionOffset = 0;
var previewScrollTop = previewElt.scrollTop(); var previewScrollTop = previewElt.scrollTop();
// Each title element is a section separator // Each title element is a section separator
$("#wmd-preview").children("h1,h2,h3,h4,h5,h6").each(function() { $("#preview-contents > .preview-content").children("h1,h2,h3,h4,h5,h6").each(function() {
// Consider div scroll position and header element top margin // Consider div scroll position and header element top margin
var newSectionOffset = $(this).position().top + previewScrollTop + pxToFloat($(this).css('margin-top')); var newSectionOffset = $(this).position().top + previewScrollTop + pxToFloat($(this).css('margin-top'));
htmlSectionList.push({ htmlSectionList.push({
@ -176,7 +176,7 @@ define([
editor.getConverter().hooks.chain("postConversion", function(text) { editor.getConverter().hooks.chain("postConversion", function(text) {
// To avoid losing scrolling position before elements are fully // To avoid losing scrolling position before elements are fully
// loaded // loaded
var previewElt = $("#wmd-preview"); var previewElt = $("#preview-contents");
previewElt.height(previewElt.height()); previewElt.height(previewElt.height());
return text; return text;
}); });
@ -184,7 +184,7 @@ define([
scrollLink.onPreviewFinished = function() { scrollLink.onPreviewFinished = function() {
// Now set the correct height // Now set the correct height
$("#wmd-preview").height("auto"); $("#preview-contents").height("auto");
isScrollEditor = true; isScrollEditor = true;
buildSections(); buildSections();
}; };

View File

@ -106,7 +106,7 @@ define([
} }
var elementList = []; var elementList = [];
$("#wmd-preview").children("h1, h2, h3, h4, h5, h6").each(function() { $("#preview-contents > .preview-content").children("h1, h2, h3, h4, h5, h6").each(function() {
elementList.push(new TocElement($(this).prop("tagName"), createAnchor($(this)), $(this).text())); elementList.push(new TocElement($(this).prop("tagName"), createAnchor($(this)), $(this).text()));
}); });
elementList = groupTags(elementList); elementList = groupTags(elementList);
@ -117,9 +117,11 @@ define([
// Run TOC generation when conversion is finished directly on HTML // Run TOC generation when conversion is finished directly on HTML
editor.hooks.chain("onPreviewRefresh", function() { editor.hooks.chain("onPreviewRefresh", function() {
var htmlToc = buildToc(); var htmlToc = buildToc();
var html = $("#wmd-preview").html(); $("#preview-contents > .preview-content").each(function() {
html = html.replace(new RegExp("<p>" + toc.config.marker + "<\\/p>", "g"), htmlToc); var html = $(this).html();
$("#wmd-preview").html(html); html = html.replace(new RegExp("<p>" + toc.config.marker + "<\\/p>", "g"), htmlToc);
$(this).html(html);
});
$(".table-of-contents").html(htmlToc); $(".table-of-contents").html(htmlToc);
}); });
}; };

View File

@ -121,6 +121,13 @@ define([
}); });
} }
// Get the html from the onPreviewFinished callback
var previewHtml = undefined;
extensionMgr.addHookCallback("onPreviewFinished", function(html) {
previewHtml = html;
});
var publishRunning = false; var publishRunning = false;
publisher.publish = function() { publisher.publish = function() {
// If publish is running or offline // If publish is running or offline
@ -131,7 +138,7 @@ define([
publishRunning = true; publishRunning = true;
extensionMgr.onPublishRunning(true); extensionMgr.onPublishRunning(true);
publishFileDesc = fileMgr.currentFile; publishFileDesc = fileMgr.currentFile;
publishHTML = $("#wmd-preview").html(); publishHTML = previewHtml;
publishAttributesList = _.values(publishFileDesc.publishLocations); publishAttributesList = _.values(publishFileDesc.publishLocations);
publishLocation(function(errorFlag) { publishLocation(function(errorFlag) {
publishRunning = false; publishRunning = false;
@ -190,7 +197,7 @@ define([
// Perform provider's publishing // Perform provider's publishing
var fileDesc = fileMgr.currentFile; var fileDesc = fileMgr.currentFile;
var html = $("#wmd-preview").html(); var html = previewHtml;
var content = getPublishContent(fileDesc, publishAttributes, html); var content = getPublishContent(fileDesc, publishAttributes, html);
provider.publish(publishAttributes, fileDesc.title, content, function(error) { provider.publish(publishAttributes, fileDesc.title, content, function(error) {
if(error === undefined) { if(error === undefined) {
@ -234,14 +241,12 @@ define([
utils.saveAs(content, title + ".md"); utils.saveAs(content, title + ".md");
}); });
$(".action-download-html").click(function() { $(".action-download-html").click(function() {
var content = $("#wmd-preview").html();
var title = fileMgr.currentFile.title; var title = fileMgr.currentFile.title;
utils.saveAs(content, title + ".html"); utils.saveAs(previewHtml, title + ".html");
}); });
$(".action-download-template").click(function() { $(".action-download-template").click(function() {
var fileDesc = fileMgr.currentFile; var fileDesc = fileMgr.currentFile;
var html = $("#wmd-preview").html(); var content = publisher.applyTemplate(fileDesc, undefined, previewHtml);
var content = publisher.applyTemplate(fileDesc, undefined, html);
utils.saveAs(content, fileDesc.title + (settings.template.indexOf("documentHTML") === -1 ? ".md" : ".html")); utils.saveAs(content, fileDesc.title + (settings.template.indexOf("documentHTML") === -1 ? ".md" : ".html"));
}); });
}); });

View File

@ -98,9 +98,9 @@ define([
if(importParameters === undefined) { if(importParameters === undefined) {
return; return;
} }
$("#wmd-preview, #file-title").hide(); $("#preview-contents, #file-title").hide();
provider.importPublic(importParameters, function(error, title, content) { provider.importPublic(importParameters, function(error, title, content) {
$("#wmd-preview, #file-title").show(); $("#preview-contents, #file-title").show();
if(error) { if(error) {
return; return;
} }

View File

@ -1,6 +1,6 @@
body, body,
.btn, .btn,
#wmd-preview, #preview-contents,
.modal-footer, .modal-footer,
pre, pre,
input[disabled], input[disabled],

View File

@ -1,6 +1,6 @@
body, body,
.btn, .btn,
#wmd-preview, #preview-contents,
.modal-footer, .modal-footer,
input[disabled], input[disabled],
select[disabled], select[disabled],
@ -54,11 +54,11 @@ blockquote {
border-color: #333; border-color: #333;
} }
#wmd-preview { #preview-contents {
color: #ccc; color: #ccc;
} }
#wmd-preview blockquote { #preview-contents blockquote {
border-color: #444; border-color: #444;
} }

View File

@ -76,7 +76,7 @@
</div> </div>
<div id="wmd-button-bar" class="hide"></div> <div id="wmd-button-bar" class="hide"></div>
<textarea id="wmd-input" class="hide"></textarea> <textarea id="wmd-input" class="hide"></textarea>
<div id="wmd-preview"></div> <div id="preview-container"></div>
<div id="modal-non-unique" class="modal hide"> <div id="modal-non-unique" class="modal hide">
<div class="modal-header"> <div class="modal-header">