1
0
mirror of https://github.com/BookStackApp/BookStack.git synced 2025-08-07 23:03:00 +03:00

Made MD editor display a sandboxed iframe

- Also added escaping of srcdoc elements in escape logic.

Related to #1531
This commit is contained in:
Dan Brown
2019-08-26 12:16:50 +01:00
parent 2dfe6c2d56
commit 7cc17934a8
6 changed files with 39 additions and 15 deletions

View File

@@ -18,6 +18,8 @@ class MarkdownEditor {
this.markdown.use(mdTasksLists, {label: true});
this.display = this.elem.querySelector('.markdown-display');
this.displayDoc = this.display.contentDocument;
this.displayStylesLoaded = false;
this.input = this.elem.querySelector('textarea');
this.htmlInput = this.elem.querySelector('input[name=html]');
this.cm = code.markdownEditor(this.input);
@@ -38,7 +40,7 @@ class MarkdownEditor {
let lastClick = 0;
// Prevent markdown display link click redirect
this.display.addEventListener('click', event => {
this.displayDoc.addEventListener('click', event => {
let isDblClick = Date.now() - lastClick < 300;
let link = event.target.closest('a');
@@ -96,17 +98,37 @@ class MarkdownEditor {
// Update the input content and render the display.
updateAndRender() {
let content = this.cm.getValue();
const content = this.cm.getValue();
this.input.value = content;
let html = this.markdown.render(content);
const html = this.markdown.render(content);
window.$events.emit('editor-html-change', html);
window.$events.emit('editor-markdown-change', content);
this.display.innerHTML = html;
// Set body content
this.displayDoc.body.className = 'page-content';
this.displayDoc.body.innerHTML = html;
this.htmlInput.value = html;
// Copy styles from page head and set custom styles for editor
this.loadStylesIntoDisplay();
}
loadStylesIntoDisplay() {
if (this.displayStylesLoaded) return;
this.displayDoc.documentElement.className = 'markdown-editor-display';
this.displayDoc.head.innerHTML = '';
const styles = document.head.querySelectorAll('style,link[rel=stylesheet]');
for (let style of styles) {
const copy = style.cloneNode(true);
this.displayDoc.head.appendChild(copy);
}
this.displayStylesLoaded = true;
}
onMarkdownScroll(lineCount) {
const elems = this.display.children;
const elems = this.displayDoc.body.children;
if (elems.length <= lineCount) return;
const topElem = (lineCount === -1) ? elems[elems.length-1] : elems[lineCount];