diff --git a/app/src/protyle/toolbar/index.ts b/app/src/protyle/toolbar/index.ts index ff88bcc84..f78dcb36f 100644 --- a/app/src/protyle/toolbar/index.ts +++ b/app/src/protyle/toolbar/index.ts @@ -995,7 +995,7 @@ export class Toolbar { /// #endif const textElement = this.subElement.querySelector(".b3-text-field") as HTMLTextAreaElement; if (types.includes("NodeHTMLBlock")) { - textElement.value = renderElement.querySelector("protyle-html").getAttribute("data-content") || ""; + textElement.value = Lute.UnEscapeHTMLStr(renderElement.querySelector("protyle-html").getAttribute("data-content") || ""); } else if (isInlineMemo) { textElement.value = Lute.UnEscapeHTMLStr(renderElement.getAttribute("data-inline-memo-content") || ""); } else { diff --git a/app/stage/protyle/js/protyle-html.js b/app/stage/protyle/js/protyle-html.js index 0956319e8..0326f92cc 100644 --- a/app/stage/protyle/js/protyle-html.js +++ b/app/stage/protyle/js/protyle-html.js @@ -3,51 +3,53 @@ //# sourceMappingURL=purify.min.js.map class ProtyleHtml extends HTMLElement { - constructor () { - super() - const shadowRoot = this.attachShadow({mode: 'open'}) - this.display = this.shadowRoot - const dataContent = this.getAttribute('data-content') - this.display.innerHTML = dataContent - } - - static get observedAttributes () { - return ['data-content'] - } - - attributeChangedCallback (name, oldValue, newValue) { - if (name === 'data-content') { - let dataContent = Lute.UnEscapeHTMLStr(this.getAttribute('data-content')) - - if (!window.siyuan.config.editor.allowHTMLBLockScript) { - // Do not execute scripts in HTML blocks by default to prevent XSS https://github.com/siyuan-note/siyuan/issues/11172 - dataContent = DOMPurify.sanitize(dataContent); - } - - this.display.innerHTML = dataContent - - const el = document.createElement('div') - el.innerHTML = dataContent - const scripts = el.getElementsByTagName('script') - let fatalHTML = '' - for (const script of scripts) { - if (script.textContent.indexOf('document.write') > -1) { - fatalHTML += `
${window.siyuan.languages.htmlBlockError}
-` - } else { - const s = document.createElement('script') - for (const attr of script.attributes) { - s.setAttribute(attr.name, attr.value); - } - s.textContent = script.textContent - this.display.appendChild(s) - } - } - if (fatalHTML) { - this.display.innerHTML += fatalHTML - } + constructor() { + super() + const shadowRoot = this.attachShadow({mode: 'open'}) + this.display = this.shadowRoot + // https://github.com/siyuan-note/siyuan/issues/11321 + this.setAttribute('data-content', Lute.EscapeHTMLStr(this.getAttribute('data-content'))) + const dataContent = this.getAttribute('data-content') + this.display.innerHTML = dataContent + } + + static get observedAttributes() { + return ['data-content'] + } + + attributeChangedCallback(name, oldValue, newValue) { + if (name === 'data-content') { + let dataContent = Lute.UnEscapeHTMLStr(this.getAttribute('data-content')) + + if (!window.siyuan.config.editor.allowHTMLBLockScript) { + // Do not execute scripts in HTML blocks by default to prevent XSS https://github.com/siyuan-note/siyuan/issues/11172 + dataContent = DOMPurify.sanitize(dataContent); + } + + this.display.innerHTML = dataContent + + const el = document.createElement('div') + el.innerHTML = dataContent + const scripts = el.getElementsByTagName('script') + let fatalHTML = '' + for (const script of scripts) { + if (script.textContent.indexOf('document.write') > -1) { + fatalHTML += `
${window.siyuan.languages.htmlBlockError}
+` + } else { + const s = document.createElement('script') + for (const attr of script.attributes) { + s.setAttribute(attr.name, attr.value); + } + s.textContent = script.textContent + this.display.appendChild(s) + } + } + if (fatalHTML) { + this.display.innerHTML += fatalHTML + } + } } - } } customElements.define('protyle-html', ProtyleHtml)