New partialRendering extension
This commit is contained in:
		
							parent
							
								
									0d6d329e6a
								
							
						
					
					
						commit
						539f39a2d9
					
				| @ -153,22 +153,26 @@ define([ | ||||
|     var onAsyncPreviewCallbackList = getExtensionCallbackList("onAsyncPreview"); | ||||
|     // The number of times we expect tryFinished to be called
 | ||||
|     var nbAsyncPreviewCallback = onAsyncPreviewCallbackList.length + 1; | ||||
|     var previewContentsElt = undefined; | ||||
|     var previewContentsJQElt = undefined; | ||||
|     extensionMgr["onAsyncPreview"] = function() { | ||||
|         logger.log("onAsyncPreview"); | ||||
|         // Call onPreviewFinished callbacks when all async preview are finished
 | ||||
|         var counter = 0; | ||||
|         function tryFinished() { | ||||
|             if(++counter === nbAsyncPreviewCallback) { | ||||
|                 var html = ""; | ||||
|                 $("#preview-contents > .preview-content").each(function() { | ||||
|                     html += $(this).html(); | ||||
|                 _.defer(function() { | ||||
|                     var html = ""; | ||||
|                     _.each(previewContentsElt.children, function(elt) { | ||||
|                         html += elt.innerHTML; | ||||
|                     }); | ||||
|                     onPreviewFinished(utils.trim(html)); | ||||
|                     logger.log("Preview time: " + (new Date() - extensionMgr.previewStartTime)); | ||||
|                 }); | ||||
|                 onPreviewFinished(utils.trim(html)); | ||||
|                 logger.log("Preview time: " + (new Date() - extensionMgr.previewStartTime)); | ||||
|             } | ||||
|         } | ||||
|         // We assume images are loading in the preview
 | ||||
|         $("#preview-contents").waitForImages(tryFinished); | ||||
|         previewContentsJQElt.waitForImages(tryFinished); | ||||
|         _.each(onAsyncPreviewCallbackList, function(asyncPreviewCallback) { | ||||
|             asyncPreviewCallback(tryFinished); | ||||
|         }); | ||||
| @ -184,6 +188,9 @@ define([ | ||||
|     } | ||||
| 
 | ||||
|     extensionMgr["onReady"] = function() { | ||||
|         previewContentsElt = document.getElementById('preview-contents'); | ||||
|         previewContentsJQElt = $(previewContentsElt); | ||||
|          | ||||
|         // Create accordion in settings dialog
 | ||||
|         _.chain(extensionList).sortBy(function(extension) { | ||||
|             return extension.extensionName.toLowerCase(); | ||||
|  | ||||
| @ -30,6 +30,7 @@ define([ | ||||
|         selectedFileDesc = fileDesc; | ||||
|     }; | ||||
| 
 | ||||
|     var textareaElt = undefined; | ||||
|     buttonHtmlCode.onPreviewFinished = function(html) { | ||||
|         try { | ||||
|             var htmlCode = _.template(buttonHtmlCode.config.template, { | ||||
| @ -37,7 +38,7 @@ define([ | ||||
|                 documentMarkdown: selectedFileDesc.content, | ||||
|                 documentHTML: html | ||||
|             }); | ||||
|             $("#input-html-code").val(htmlCode); | ||||
|             textareaElt.value = htmlCode; | ||||
|         } | ||||
|         catch(e) { | ||||
|             extensionMgr.onError(e); | ||||
| @ -46,6 +47,7 @@ define([ | ||||
|     }; | ||||
| 
 | ||||
|     buttonHtmlCode.onReady = function() { | ||||
|         textareaElt = document.getElementById('input-html-code'); | ||||
|         $(".action-html-code").click(function() { | ||||
|             _.defer(function() { | ||||
|                 $("#input-html-code").each(function() { | ||||
|  | ||||
| @ -43,12 +43,29 @@ define([ | ||||
|     buttonStat.onCreatePreviewButton = function() { | ||||
|         return $(_.template(buttonStatHTML, buttonStat.config)); | ||||
|     }; | ||||
|      | ||||
|     var previewContentsElt = undefined; | ||||
|     var value1Elt = undefined; | ||||
|     var value2Elt = undefined; | ||||
|     var value3Elt = undefined; | ||||
|     buttonStat.onReady = function() { | ||||
|         previewContentsElt = document.getElementById('preview-contents'); | ||||
|         value1Elt = document.getElementById('span-stat-value1'); | ||||
|         value2Elt = document.getElementById('span-stat-value2'); | ||||
|         value3Elt = document.getElementById('span-stat-value3'); | ||||
|     }; | ||||
| 
 | ||||
|     buttonStat.onPreviewFinished = function() { | ||||
|         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-value2").text((text.match(new RegExp(buttonStat.config.value2, "g")) || []).length); | ||||
|         $("#span-stat-value3").text((text.match(new RegExp(buttonStat.config.value3, "g")) || []).length); | ||||
|         var previewContentsEltClone = previewContentsElt.cloneNode(true); | ||||
|         var scriptEltList = previewContentsEltClone.getElementsByTagName('script'); | ||||
|         for(var i = scriptEltList.length-1; i >= 0; i--) { | ||||
|             var scriptElt = scriptEltList[i]; | ||||
|             scriptElt.parentNode.removeChild(scriptElt); | ||||
|         } | ||||
|         var text = previewContentsEltClone.textContent; | ||||
|         value1Elt.textContent = (text.match(new RegExp(buttonStat.config.value1, "g")) || []).length; | ||||
|         value2Elt.textContent = (text.match(new RegExp(buttonStat.config.value2, "g")) || []).length; | ||||
|         value3Elt.textContent = (text.match(new RegExp(buttonStat.config.value3, "g")) || []).length; | ||||
|     }; | ||||
| 
 | ||||
|     return buttonStat; | ||||
|  | ||||
| @ -10,12 +10,14 @@ define([ | ||||
| 
 | ||||
|     var libraries = { | ||||
|         "Bootstrap": "http://twitter.github.io/bootstrap/", | ||||
|         "crel": "https://github.com/KoryNunn/crel", | ||||
|         "CSS Browser Selector": "https://github.com/rafaelp/css_browser_selector/", | ||||
|         "Dropbox-js": "https://github.com/dropbox/dropbox-js", | ||||
|         "FileSaver.js": "https://github.com/eligrey/FileSaver.js/", | ||||
|         "Gatekeeper": "https://github.com/prose/gatekeeper", | ||||
|         "Github.js": "https://github.com/michael/github", | ||||
|         "Glyphicons": "http://glyphicons.com/", | ||||
|         "Highlight.js": "http://softwaremaniacs.org/soft/highlight/en/", | ||||
|         "jGrowl": "https://github.com/stanlemon/jGrowl/", | ||||
|         "jQuery": "http://jquery.com/", | ||||
|         "jQuery Mouse Wheel Plugin": "https://github.com/brandonaaron/jquery-mousewheel", | ||||
| @ -34,6 +36,7 @@ define([ | ||||
| 
 | ||||
|     var projects = { | ||||
|         "StackEdit Download Proxy": "https://github.com/benweet/stackedit-download-proxy", | ||||
|         "StackEdit Picasa Proxy": "https://github.com/benweet/stackedit-picasa-proxy", | ||||
|         "StackEdit SSH Proxy": "https://github.com/benweet/stackedit-ssh-proxy", | ||||
|         "StackEdit Tumblr Proxy": "https://github.com/benweet/stackedit-tumblr-proxy", | ||||
|         "StackEdit WordPress Proxy": "https://github.com/benweet/stackedit-wordpress-proxy", | ||||
|  | ||||
| @ -1,10 +1,11 @@ | ||||
| define([ | ||||
|     "jquery", | ||||
|     "underscore", | ||||
|     "utils", | ||||
|     "classes/Extension", | ||||
|     "text!html/markdownExtraSettingsBlock.html", | ||||
|     "libs/Markdown.Extra", | ||||
| ], function($, utils, Extension, markdownExtraSettingsBlockHTML) { | ||||
| ], function($, _, utils, Extension, markdownExtraSettingsBlockHTML) { | ||||
| 
 | ||||
|     var markdownExtra = new Extension("markdownExtra", "Markdown Extra", true); | ||||
|     markdownExtra.settingsBlock = markdownExtraSettingsBlockHTML; | ||||
| @ -50,9 +51,10 @@ define([ | ||||
|         }; | ||||
|         if(markdownExtra.config.highlighter == "highlight") { | ||||
|             options.highlighter = "prettify"; | ||||
|             var previewContentsElt = document.getElementById('preview-contents'); | ||||
|             editor.hooks.chain("onPreviewRefresh", function() { | ||||
|                 $('.prettyprint').each(function(i, e) { | ||||
|                     hljs.highlightBlock(e); | ||||
|                 _.each(previewContentsElt.querySelectorAll('.prettyprint'), function(elt) { | ||||
|                     hljs.highlightBlock(elt); | ||||
|                 }); | ||||
|             }); | ||||
|         } | ||||
| @ -61,7 +63,7 @@ define([ | ||||
|             editor.hooks.chain("onPreviewRefresh", prettyPrint); | ||||
|         } | ||||
|         Markdown.Extra.init(converter, options); | ||||
|          | ||||
| 
 | ||||
|         // Store extensions list in converter for partialRendering
 | ||||
|         converter.extraExtensions = markdownExtra.config.extensions; | ||||
|     }; | ||||
|  | ||||
| @ -1,9 +1,9 @@ | ||||
| define([ | ||||
|     "jquery", | ||||
|     "underscore", | ||||
|     "crel", | ||||
|     "classes/Extension", | ||||
|     "text!html/partialRenderingSettingsBlock.html", | ||||
| ], function($, _, Extension, partialRenderingSettingsBlockHTML) { | ||||
| ], function(_, crel, Extension, partialRenderingSettingsBlockHTML) { | ||||
| 
 | ||||
|     var partialRendering = new Extension("partialRendering", "Partial Rendering", true); | ||||
|     partialRendering.settingsBlock = partialRenderingSettingsBlockHTML; | ||||
| @ -14,12 +14,12 @@ define([ | ||||
|     var linkDefinition = undefined; | ||||
|     var sectionsToRemove = []; | ||||
|     var modifiedSections = []; | ||||
|     var insertAfterSection = undefined; | ||||
|     var insertBeforeSection = undefined; | ||||
|     var fileChanged = false; | ||||
|     function updateSectionList(newSectionList, newLinkDefinition) { | ||||
|         modifiedSections = []; | ||||
|         sectionsToRemove = []; | ||||
|         insertAfterSection = undefined; | ||||
|         insertBeforeSection = undefined; | ||||
| 
 | ||||
|         // Render everything if file or linkDefinition changed
 | ||||
|         if(fileChanged === true || linkDefinition != newLinkDefinition) { | ||||
| @ -59,7 +59,7 @@ define([ | ||||
|         var leftSections = sectionList.slice(0, leftIndex); | ||||
|         modifiedSections = newSectionList.slice(leftIndex, newSectionList.length + rightIndex); | ||||
|         var rightSections = sectionList.slice(sectionList.length + rightIndex, sectionList.length); | ||||
|         insertAfterSection = _.last(leftSections); | ||||
|         insertBeforeSection = _.first(rightSections); | ||||
|         sectionsToRemove = sectionList.slice(leftIndex, sectionList.length + rightIndex); | ||||
|         sectionList = leftSections.concat(modifiedSections).concat(rightSections); | ||||
|     } | ||||
| @ -72,17 +72,8 @@ define([ | ||||
|         hasFootnotes = false; | ||||
|         _.each(sectionListParam, function(text) { | ||||
|             text += "\n\n"; | ||||
|              | ||||
|             // Strip link definitions
 | ||||
|             text = text.replace(/^```.*\n[\s\S]*?\n```|^[ ]{0,3}\[(.+)\]:[ \t]*\n?[ \t]*<?(\S+?)>?(?=\s|$)[ \t]*\n?[ \t]*((\n*)["(](.+?)[")][ \t]*)?(?:\n+)/gm, function(wholeMatch, link) { | ||||
|                 if(link) { | ||||
|                     newLinkDefinition += wholeMatch; | ||||
|                     return ""; | ||||
|                 } | ||||
|                 return wholeMatch; | ||||
|             }); | ||||
| 
 | ||||
|             // And footnotes eventually
 | ||||
|             // Strip footnotes
 | ||||
|             if(doFootnotes) { | ||||
|                 text = text.replace(/^```.*\n[\s\S]*?\n```|\n[ ]{0,3}\[\^(.+?)\]\:[ \t]*\n?([\s\S]*?)\n{1,2}((?=\n[ ]{0,3}\S)|$)/g, function(wholeMatch, footnote) { | ||||
|                     if(footnote) { | ||||
| @ -94,6 +85,15 @@ define([ | ||||
|                 }); | ||||
|             } | ||||
| 
 | ||||
|             // Strip link definitions
 | ||||
|             text = text.replace(/^```.*\n[\s\S]*?\n```|^[ ]{0,3}\[(.+)\]:[ \t]*\n?[ \t]*<?(\S+?)>?(?=\s|$)[ \t]*\n?[ \t]*((\n*)["(](.+?)[")][ \t]*)?(?:\n+)/gm, function(wholeMatch, link) { | ||||
|                 if(link) { | ||||
|                     newLinkDefinition += wholeMatch; | ||||
|                     return ""; | ||||
|                 } | ||||
|                 return wholeMatch; | ||||
|             }); | ||||
| 
 | ||||
|             // Skip space only sections
 | ||||
|             if(/\S/.test(text)) { | ||||
|                 // Add section to the newSectionList
 | ||||
| @ -107,56 +107,73 @@ define([ | ||||
|         updateSectionList(newSectionList, newLinkDefinition); | ||||
|     }; | ||||
| 
 | ||||
|     var footnoteContainerElt = $('<div id="wmd-preview-section-footnotes" class="preview-content">'); | ||||
|     var footnoteList = {}; | ||||
|     var footnoteContainerElt = undefined; | ||||
|     var previewContentsElt = undefined; | ||||
|     var footnoteMap = {}; | ||||
|     function refreshSections() { | ||||
| 
 | ||||
|         // Remove outdated sections
 | ||||
|         _.each(sectionsToRemove, function(section) { | ||||
|             $("#wmd-preview-section-" + section.id).remove(); | ||||
|             var sectionElt = document.getElementById("wmd-preview-section-" + section.id); | ||||
|             previewContentsElt.removeChild(sectionElt); | ||||
|         }); | ||||
| 
 | ||||
|         var wmdPreviewElt = $("#wmd-preview"); | ||||
|         var insertAfterSectionElt = insertAfterSection === undefined ? wmdPreviewElt : $("#wmd-preview-section-" + insertAfterSection.id); | ||||
|         var wmdPreviewElt = document.getElementById("wmd-preview"); | ||||
|         var markdownEltList = Array.prototype.slice.call(wmdPreviewElt.childNodes); | ||||
|         wmdPreviewElt.innerHTML = ''; | ||||
|         var newSectionEltList = document.createDocumentFragment(); | ||||
|         _.each(modifiedSections, function(section) { | ||||
|             var sectionElt = $('<div id="wmd-preview-section-' + section.id + '" class="wmd-preview-section preview-content">'); | ||||
|             _.some(wmdPreviewElt.contents(), function(elt, index) { | ||||
|                 elt = $(elt); | ||||
|                 if(index !== 0 && elt.is(".wmd-title")) { | ||||
|                     return true; | ||||
|             var sectionElt = crel('div', { | ||||
|                 id: 'wmd-preview-section-' + section.id, | ||||
|                 class: 'wmd-preview-section preview-content' | ||||
|             }); | ||||
|             var isFirst = true; | ||||
|             while(markdownEltList.length !== 0) { | ||||
|                 var elt = markdownEltList[0]; | ||||
|                 if(isFirst === false && /(^| )wmd-title($| )/.test(elt.className)) { | ||||
|                     // Stop when encountered the next wmd-title
 | ||||
|                     break; | ||||
|                 } | ||||
|                 else if(elt.is("div.footnotes")) { | ||||
|                     elt.find("ol > li").each(function() { | ||||
|                         var footnoteElt = $(this).clone(); | ||||
|                         var id = footnoteElt.attr("id").substring(3); | ||||
|                         footnoteList[id] = footnoteElt; | ||||
|                 isFirst = false; | ||||
|                 if(elt.tagName == 'DIV' && elt.className == 'footnotes') { | ||||
|                     _.each(elt.querySelectorAll("ol > li"), function(footnoteElt) { | ||||
|                         // Store each footnote in our footnote map
 | ||||
|                         var id = footnoteElt.id.substring(3); | ||||
|                         footnoteMap[id] = footnoteElt; | ||||
|                     }); | ||||
|                     elt.remove(); | ||||
|                 } | ||||
|                 else { | ||||
|                     sectionElt.append(elt); | ||||
|                     sectionElt.appendChild(elt); | ||||
|                 } | ||||
|             }); | ||||
|             insertAfterSectionElt.after(sectionElt); | ||||
|             insertAfterSectionElt = sectionElt; | ||||
|                 markdownEltList.shift(); | ||||
|             }; | ||||
|             newSectionEltList.appendChild(sectionElt); | ||||
|         }); | ||||
|         var insertBeforeElt = footnoteContainerElt; | ||||
|         if(insertBeforeSection !== undefined) { | ||||
|             insertBeforeElt = document.getElementById("wmd-preview-section-" + insertBeforeSection.id); | ||||
|         } | ||||
|         previewContentsElt.insertBefore(newSectionEltList, insertBeforeElt); | ||||
| 
 | ||||
|         // Rewrite footnotes in the footer and update footnote numbers
 | ||||
|         footnoteContainerElt.empty(); | ||||
|         footnoteContainerElt.innerHTML = ''; | ||||
|         var usedFootnoteIds = []; | ||||
|         if(hasFootnotes === true) { | ||||
|             var footnoteElts = $("<ol>"); | ||||
|             $("#preview-contents a.footnote").each(function(index) { | ||||
|                 var id=$(this).text(index + 1).attr("id").substring(6); | ||||
|             var footnoteElts = crel('ol'); | ||||
|             _.each(previewContentsElt.querySelectorAll('a.footnote'), function(elt, index) { | ||||
|                 elt.textContent = index + 1; | ||||
|                 var id = elt.id.substring(6); | ||||
|                 usedFootnoteIds.push(id); | ||||
|                 footnoteElts.append(footnoteList[id].clone()); | ||||
|                 footnoteElts.appendChild(footnoteMap[id].cloneNode(true)); | ||||
|             }); | ||||
|             if(usedFootnoteIds.length > 0) { | ||||
|                 // Append the whole footnotes at the end of the document
 | ||||
|                 footnoteContainerElt.html($('<div class="footnotes">').append("<hr>").append(footnoteElts)); | ||||
|                 footnoteContainerElt.appendChild(crel('div', { | ||||
|                     class: 'footnotes' | ||||
|                 }, crel('hr'), footnoteElts)); | ||||
|             } | ||||
|             // Keep used footnotes only in our map
 | ||||
|             footnoteList = _.pick(footnoteList, usedFootnoteIds); | ||||
|             footnoteMap = _.pick(footnoteMap, usedFootnoteIds); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| @ -175,12 +192,18 @@ define([ | ||||
|     }; | ||||
| 
 | ||||
|     partialRendering.onReady = function() { | ||||
|         $("#preview-contents").append(footnoteContainerElt); | ||||
|         $("#wmd-preview").hide(); | ||||
|         footnoteContainerElt = crel('div', { | ||||
|             id: 'wmd-preview-section-footnotes', | ||||
|             class: 'preview-content' | ||||
|         }); | ||||
|         previewContentsElt = document.getElementById("preview-contents"); | ||||
|         previewContentsElt.appendChild(footnoteContainerElt); | ||||
|     }; | ||||
| 
 | ||||
|     partialRendering.onFileSelected = function() { | ||||
|         fileChanged = true; | ||||
|     }; | ||||
| 
 | ||||
|     partialRendering.onFileOpen = function() { | ||||
|         if(converter.extraExtensions) { | ||||
|             doFootnotes = _.some(converter.extraExtensions, function(extension) { | ||||
|  | ||||
| @ -15,6 +15,9 @@ define([ | ||||
|         sectionList = sectionListParam; | ||||
|     }; | ||||
| 
 | ||||
|     var editorElt = undefined; | ||||
|     var previewElt = undefined; | ||||
|     var textareaElt = undefined; | ||||
|     var mdSectionList = []; | ||||
|     var htmlSectionList = []; | ||||
|     function pxToFloat(px) { | ||||
| @ -25,10 +28,7 @@ define([ | ||||
|     var buildSections = _.debounce(function() { | ||||
| 
 | ||||
|         // Try to find Markdown sections by looking for titles
 | ||||
|         var editorElt = $("#wmd-input"); | ||||
|         mdSectionList = []; | ||||
|         // This textarea is used to measure sections height
 | ||||
|         var textareaElt = $("#md-section-helper"); | ||||
|         // It has to be the same width as wmd-input
 | ||||
|         textareaElt.width(editorElt.width()); | ||||
|         // Consider wmd-input top padding (will be used for 1st and last
 | ||||
| @ -65,14 +65,14 @@ define([ | ||||
|         }); | ||||
| 
 | ||||
|         // Try to find corresponding sections in the preview
 | ||||
|         var previewElt = $(".preview-container"); | ||||
|         htmlSectionList = []; | ||||
|         var htmlSectionOffset = 0; | ||||
|         var previewScrollTop = previewElt.scrollTop(); | ||||
|         // Each title element is a section separator
 | ||||
|         $("#preview-contents > .preview-content").children(".wmd-title").each(function() { | ||||
|         previewElt.find(".preview-content > .wmd-title").each(function() { | ||||
|             var titleElt = $(this); | ||||
|             // Consider div scroll position and header element top margin
 | ||||
|             var newSectionOffset = $(this).position().top + previewScrollTop + pxToFloat($(this).css('margin-top')); | ||||
|             var newSectionOffset = titleElt.position().top + previewScrollTop + pxToFloat(titleElt.css('margin-top')); | ||||
|             htmlSectionList.push({ | ||||
|                 startOffset: htmlSectionOffset, | ||||
|                 endOffset: newSectionOffset, | ||||
| @ -100,9 +100,7 @@ define([ | ||||
|         if(mdSectionList.length === 0 || mdSectionList.length !== htmlSectionList.length) { | ||||
|             return; | ||||
|         } | ||||
|         var editorElt = $("#wmd-input"); | ||||
|         var editorScrollTop = editorElt.scrollTop(); | ||||
|         var previewElt = $(".preview-container"); | ||||
|         var previewScrollTop = previewElt.scrollTop(); | ||||
|         function animate(srcScrollTop, srcSectionList, destElt, destSectionList, currentDestScrollTop, callback) { | ||||
|             // Find the section corresponding to the offset
 | ||||
| @ -160,6 +158,12 @@ define([ | ||||
|     }; | ||||
| 
 | ||||
|     scrollLink.onLayoutCreated = function() { | ||||
|         editorElt = $("#wmd-input"); | ||||
|         previewElt = $(".preview-container"); | ||||
|          | ||||
|         // This textarea is used to measure sections height
 | ||||
|         textareaElt = $("#md-section-helper"); | ||||
|          | ||||
|         $(".preview-container").bind("keyup mouseup mousewheel", function() { | ||||
|             isScrollPreview = true; | ||||
|             isScrollEditor = false; | ||||
| @ -172,19 +176,20 @@ define([ | ||||
|         }); | ||||
|     }; | ||||
| 
 | ||||
|     var previewContentsElt = undefined; | ||||
|     scrollLink.onEditorConfigure = function(editor) { | ||||
|         previewContentsElt = $("#preview-contents"); | ||||
|         editor.getConverter().hooks.chain("postConversion", function(text) { | ||||
|             // To avoid losing scrolling position before elements are fully
 | ||||
|             // loaded
 | ||||
|             var previewElt = $("#preview-contents"); | ||||
|             previewElt.height(previewElt.height()); | ||||
|             previewContentsElt.height(previewContentsElt.height()); | ||||
|             return text; | ||||
|         }); | ||||
|     }; | ||||
| 
 | ||||
|     scrollLink.onPreviewFinished = function() { | ||||
|         // Now set the correct height
 | ||||
|         $("#preview-contents").height("auto"); | ||||
|         previewContentsElt.height("auto"); | ||||
|         isScrollEditor = true; | ||||
|         buildSections(); | ||||
|     }; | ||||
|  | ||||
| @ -90,10 +90,11 @@ define([ | ||||
|     } | ||||
| 
 | ||||
|     // Build the TOC
 | ||||
|     var previewContentsElt = undefined; | ||||
|     function buildToc() { | ||||
|         var anchorList = {}; | ||||
|         function createAnchor(element) { | ||||
|             var id = element.prop("id") || utils.slugify(element.text()); | ||||
|             var id = element.id || utils.slugify(element.textContent); | ||||
|             var anchor = id; | ||||
|             var index = 0; | ||||
|             while (_.has(anchorList, anchor)) { | ||||
| @ -101,31 +102,35 @@ define([ | ||||
|             } | ||||
|             anchorList[anchor] = true; | ||||
|             // Update the id of the element
 | ||||
|             element.prop("id", anchor); | ||||
|             element.id = anchor; | ||||
|             return anchor; | ||||
|         } | ||||
| 
 | ||||
|         var elementList = []; | ||||
|         $("#preview-contents > .preview-content").children("h1, h2, h3, h4, h5, h6").each(function() { | ||||
|             elementList.push(new TocElement($(this).prop("tagName"), createAnchor($(this)), $(this).text())); | ||||
|         _.each(previewContentsElt.querySelectorAll('.preview-content > .wmd-title'), function(elt) { | ||||
|             elementList.push(new TocElement(elt.tagName, createAnchor(elt), elt.textContent)); | ||||
|         }); | ||||
|         elementList = groupTags(elementList); | ||||
|         return '<div class="toc">\n<ul>\n' + elementList.join("") + '</ul>\n</div>\n'; | ||||
|     } | ||||
| 
 | ||||
|     toc.onEditorConfigure = function(editor) { | ||||
|         var tocExp = new RegExp("^" + toc.config.marker + "$", "g") | ||||
|         previewContentsElt = document.getElementById('preview-contents'); | ||||
|         var tocEltList = document.querySelectorAll('.table-of-contents'); | ||||
|         var tocExp = new RegExp("^" + toc.config.marker + "$", "g"); | ||||
|         // Run TOC generation when conversion is finished directly on HTML
 | ||||
|         editor.hooks.chain("onPreviewRefresh", function() { | ||||
|             var htmlToc = buildToc(); | ||||
|             // Replace toc paragraphs
 | ||||
|             $("#preview-contents p").each(function() { | ||||
|                 if(tocExp.test($(this).html())) { | ||||
|                     $(this).html(htmlToc); | ||||
|             _.each(previewContentsElt.getElementsByTagName('p'), function(elt) { | ||||
|                 if(tocExp.test(elt.innerHTML)) { | ||||
|                     elt.innerHTML = htmlToc; | ||||
|                 } | ||||
|             }); | ||||
|             // Add toc in the TOC button 
 | ||||
|             $(".table-of-contents").html(htmlToc); | ||||
|             _.each(tocEltList, function(elt) { | ||||
|                 elt.innerHTML = htmlToc; | ||||
|             }); | ||||
|         }); | ||||
|     }; | ||||
| 
 | ||||
|  | ||||
| @ -482,6 +482,9 @@ | ||||
|   // Find and convert footnotes references.
 | ||||
|   Markdown.Extra.prototype.doFootnotes = function(text) { | ||||
|     var self = this; | ||||
|     if(self.isConvertingFootnote === true) { | ||||
|       return text; | ||||
|     } | ||||
| 
 | ||||
|     var footnoteCounter = 0; | ||||
|     text = text.replace(/\[\^(.+?)\]/g, function(wholeMatch, m1) { | ||||
| @ -512,7 +515,9 @@ | ||||
|     for(var i=0; i<self.usedFootnotes.length; i++) { | ||||
|       var id = self.usedFootnotes[i]; | ||||
|       var footnote = self.footnotes[id]; | ||||
|       self.isConvertingFootnote = true; | ||||
|       var formattedfootnote = convertSpans(footnote, self); | ||||
|       delete self.isConvertingFootnote; | ||||
|       text += '<li id="fn:' | ||||
|         + id | ||||
|         + '">' | ||||
|  | ||||
| @ -4,6 +4,7 @@ requirejs.config({ | ||||
|     paths: { | ||||
|         "jquery": "libs/jquery", | ||||
|         "underscore": "libs/underscore", | ||||
|         "crel": "libs/crel", | ||||
|         "jgrowl": "libs/jgrowl", | ||||
|         "mousetrap": "libs/mousetrap", | ||||
|         "toMarkdown": "libs/to-markdown", | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 benweet
						benweet