2
0
mirror of https://github.com/Ionaru/easy-markdown-editor synced 2025-09-24 16:40:55 -06:00

virtual dom preview renderer with html2idom

This commit is contained in:
Benedikt Rötsch 2019-04-08 14:01:07 +08:00
parent aa0304fdaa
commit 2b323bf366
2 changed files with 552 additions and 123 deletions

591
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -13,7 +13,7 @@ require('codemirror/mode/gfm/gfm.js');
require('codemirror/mode/xml/xml.js'); require('codemirror/mode/xml/xml.js');
var CodeMirrorSpellChecker = require('codemirror-spell-checker'); var CodeMirrorSpellChecker = require('codemirror-spell-checker');
var marked = require('marked'); var marked = require('marked');
var patchHTML = require('html2idom/light').patchHTML;
// Some variables // Some variables
var isMac = /Mac/.test(navigator.platform); var isMac = /Mac/.test(navigator.platform);
@ -757,25 +757,20 @@ function toggleSideBySide(editor) {
var wrapper = cm.getWrapperElement(); var wrapper = cm.getWrapperElement();
var preview = wrapper.nextSibling; var preview = wrapper.nextSibling;
var toolbarButton = editor.toolbarElements && editor.toolbarElements['side-by-side']; var toolbarButton = editor.toolbarElements && editor.toolbarElements['side-by-side'];
var useSideBySideListener = false;
if (/editor-preview-active-side/.test(preview.className)) { if (/editor-preview-active-side/.test(preview.className)) {
editor.renderPreview(false); // stop rendering
preview.className = preview.className.replace( preview.className = preview.className.replace(
/\s*editor-preview-active-side\s*/g, '' /\s*editor-preview-active-side\s*/g, ''
); );
if (toolbarButton) toolbarButton.className = toolbarButton.className.replace(/\s*active\s*/g, ''); if (toolbarButton) toolbarButton.className = toolbarButton.className.replace(/\s*active\s*/g, '');
wrapper.className = wrapper.className.replace(/\s*CodeMirror-sided\s*/g, ' '); wrapper.className = wrapper.className.replace(/\s*CodeMirror-sided\s*/g, ' ');
} else { } else {
// When the preview button is clicked for the first time, editor.renderPreview(preview);
// give some time for the transition from editor.css to fire and the view to slide from right to left, if (!cm.getOption('fullScreen')) toggleFullScreen(editor);
// instead of just appearing.
setTimeout(function () {
if (!cm.getOption('fullScreen'))
toggleFullScreen(editor);
preview.className += ' editor-preview-active-side'; preview.className += ' editor-preview-active-side';
}, 1);
if (toolbarButton) toolbarButton.className += ' active'; if (toolbarButton) toolbarButton.className += ' active';
wrapper.className += ' CodeMirror-sided'; wrapper.className += ' CodeMirror-sided';
useSideBySideListener = true;
} }
// Hide normal preview if active // Hide normal preview if active
@ -790,21 +785,6 @@ function toggleSideBySide(editor) {
toolbar_div.className = toolbar_div.className.replace(/\s*disabled-for-preview*/g, ''); toolbar_div.className = toolbar_div.className.replace(/\s*disabled-for-preview*/g, '');
} }
var sideBySideRenderingFunction = function () {
preview.innerHTML = editor.options.previewRender(editor.value(), preview);
};
if (!cm.sideBySideRenderingFunction) {
cm.sideBySideRenderingFunction = sideBySideRenderingFunction;
}
if (useSideBySideListener) {
preview.innerHTML = editor.options.previewRender(editor.value(), preview);
cm.on('update', cm.sideBySideRenderingFunction);
} else {
cm.off('update', cm.sideBySideRenderingFunction);
}
// Refresh to fix selection being off (#309) // Refresh to fix selection being off (#309)
cm.refresh(); cm.refresh();
} }
@ -820,11 +800,13 @@ function togglePreview(editor) {
var toolbar = editor.options.toolbar ? editor.toolbarElements.preview : false; var toolbar = editor.options.toolbar ? editor.toolbarElements.preview : false;
var preview = wrapper.lastChild; var preview = wrapper.lastChild;
if (!preview || !/editor-preview/.test(preview.className)) { if (!preview || !/editor-preview/.test(preview.className)) {
// initialize the preview element and the preview function
preview = document.createElement('div'); preview = document.createElement('div');
preview.className = 'editor-preview'; preview.className = 'editor-preview';
wrapper.appendChild(preview); wrapper.appendChild(preview);
} }
if (/editor-preview-active/.test(preview.className)) { if (/editor-preview-active/.test(preview.className)) {
editor.renderPreview(false); // stop rendering
preview.className = preview.className.replace( preview.className = preview.className.replace(
/\s*editor-preview-active\s*/g, '' /\s*editor-preview-active\s*/g, ''
); );
@ -833,6 +815,8 @@ function togglePreview(editor) {
toolbar_div.className = toolbar_div.className.replace(/\s*disabled-for-preview*/g, ''); toolbar_div.className = toolbar_div.className.replace(/\s*disabled-for-preview*/g, '');
} }
} else { } else {
editor.renderPreview(preview);
// When the preview button is clicked for the first time, // When the preview button is clicked for the first time,
// give some time for the transition from editor.css to fire and the view to slide from right to left, // give some time for the transition from editor.css to fire and the view to slide from right to left,
// instead of just appearing. // instead of just appearing.
@ -844,7 +828,6 @@ function togglePreview(editor) {
toolbar_div.className += ' disabled-for-preview'; toolbar_div.className += ' disabled-for-preview';
} }
} }
preview.innerHTML = editor.options.previewRender(editor.value(), preview);
// Turn off side by side if needed // Turn off side by side if needed
var sidebyside = cm.getWrapperElement().nextSibling; var sidebyside = cm.getWrapperElement().nextSibling;
@ -1629,12 +1612,12 @@ EasyMDE.prototype.render = function (el) {
this.codemirror.getScrollerElement().style.minHeight = options.minHeight; this.codemirror.getScrollerElement().style.minHeight = options.minHeight;
if (options.forceSync === true) {
var cm = this.codemirror; var cm = this.codemirror;
cm.on('change', function () { var editor = this;
cm.save(); cm.on('change', function() {
editor.renderPreview();
if (options.forceSync === true) cm.save();
}); });
}
this.gui = {}; this.gui = {};
@ -1652,12 +1635,31 @@ EasyMDE.prototype.render = function (el) {
this._rendered = this.element; this._rendered = this.element;
// Fixes CodeMirror bug (#344) // Fixes CodeMirror bug (#344)
var temp_cm = this.codemirror; setTimeout(cm.refresh, 0);
setTimeout(function () { };
temp_cm.refresh();
}.bind(temp_cm), 0); /**
* Set preview target and remember it
* Render the current markdown content inside it
*/
EasyMDE.prototype.renderPreview = function(previewTarget) {
var editor = this;
if (previewTarget === false) {
// stop rendering preview
editor.previewElement = null;
}
if (typeof previewTarget === 'object' && previewTarget.nodeType === 1) {
// remember new preview target
editor.previewElement = previewTarget;
}
if (!editor.previewElement) {
return;
}
patchHTML(
editor.previewElement,
editor.options.previewRender(editor.value())
);
}; };
// Safari, in Private Browsing Mode, looks like it supports localStorage but all calls to setItem throw QuotaExceededError. We're going to detect this and set a variable accordingly. // Safari, in Private Browsing Mode, looks like it supports localStorage but all calls to setItem throw QuotaExceededError. We're going to detect this and set a variable accordingly.
@ -2021,11 +2023,7 @@ EasyMDE.prototype.value = function (val) {
return cm.getValue(); return cm.getValue();
} else { } else {
cm.getDoc().setValue(val); cm.getDoc().setValue(val);
if (this.isPreviewActive()) { this.renderPreview();
var wrapper = cm.getWrapperElement();
var preview = wrapper.lastChild;
preview.innerHTML = this.options.previewRender(val, preview);
}
return this; return this;
} }
}; };