From 68d3399294abd37a3e8dba68118ee66578347ff7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Vr=C3=A1na?= Date: Tue, 20 Jul 2021 15:10:40 +0200 Subject: [PATCH] [search addon] Make compatible with Trusted Types https://web.dev/trusted-types/ doesn't allow string innerHTML assignments. This change avoids it by using DOM instead. --- addon/search/search.js | 50 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 44 insertions(+), 6 deletions(-) diff --git a/addon/search/search.js b/addon/search/search.js index 118f1112f1..4f94599136 100644 --- a/addon/search/search.js +++ b/addon/search/search.js @@ -189,18 +189,54 @@ if (state.annotate) { state.annotate.clear(); state.annotate = null; } });} + function el(tag, attrs, content) { + var element = document.createElement(tag); + for (var key in attrs) { + element[key] = attrs[key]; + } + for (var i = 2; i < arguments.length; i++) { + var child = arguments[i] + element.appendChild(typeof child == "string" ? document.createTextNode(child) : child); + } + return element; + } function getQueryDialog(cm) { - return '' + cm.phrase("Search:") + ' ' + cm.phrase("(Use /re/ syntax for regexp search)") + ''; + var fragment = document.createDocumentFragment(); + fragment.appendChild(el('span', {className: 'CodeMirror-search-label'}, cm.phrase("Search:"))); + fragment.appendChild(document.createTextNode(' ')); + fragment.appendChild(el('input', {type: 'text', 'style': 'width: 10em', className: 'CodeMirror-search-field'})); + fragment.appendChild(document.createTextNode(' ')); + fragment.appendChild(el('span', {style: 'color: #888', className: 'CodeMirror-search-hint'}, cm.phrase("(Use /re/ syntax for regexp search)"))); + return fragment; } function getReplaceQueryDialog(cm) { - return ' ' + cm.phrase("(Use /re/ syntax for regexp search)") + ''; + var fragment = document.createDocumentFragment(); + fragment.appendChild(document.createTextNode(' ')); + fragment.appendChild(el('input', {type: 'text', 'style': 'width: 10em', className: 'CodeMirror-search-field'})); + fragment.appendChild(document.createTextNode(' ')); + fragment.appendChild(el('span', {style: 'color: #888', className: 'CodeMirror-search-hint'}, cm.phrase("(Use /re/ syntax for regexp search)"))); + return fragment; } function getReplacementQueryDialog(cm) { - return '' + cm.phrase("With:") + ' '; + var fragment = document.createDocumentFragment(); + fragment.appendChild(el('span', {className: 'CodeMirror-search-label'}, cm.phrase("With:"))); + fragment.appendChild(document.createTextNode(' ')); + fragment.appendChild(el('input', {type: 'text', 'style': 'width: 10em', className: 'CodeMirror-search-field'})); + return fragment; } function getDoReplaceConfirm(cm) { - return '' + cm.phrase("Replace?") + ' '; + var fragment = document.createDocumentFragment(); + fragment.appendChild(el('span', {className: 'CodeMirror-search-label'}, cm.phrase("Replace?"))); + fragment.appendChild(document.createTextNode(' ')); + fragment.appendChild(el('button', {}, cm.phrase("Yes"))); + fragment.appendChild(document.createTextNode(' ')); + fragment.appendChild(el('button', {}, cm.phrase("No"))); + fragment.appendChild(document.createTextNode(' ')); + fragment.appendChild(el('button', {}, cm.phrase("All"))); + fragment.appendChild(document.createTextNode(' ')); + fragment.appendChild(el('button', {}, cm.phrase("Stop"))); + return fragment; } function replaceAll(cm, query, text) { @@ -217,8 +253,10 @@ function replace(cm, all) { if (cm.getOption("readOnly")) return; var query = cm.getSelection() || getSearchState(cm).lastQuery; - var dialogText = '' + (all ? cm.phrase("Replace all:") : cm.phrase("Replace:")) + ''; - dialog(cm, dialogText + getReplaceQueryDialog(cm), dialogText, query, function(query) { + var fragment = document.createDocumentFragment(); + fragment.appendChild(el('span', {className: 'CodeMirror-search-label'}, (all ? cm.phrase("Replace all:") : cm.phrase("Replace:")))); + fragment.appendChild(getReplaceQueryDialog(cm)); + dialog(cm, fragment, dialogText, query, function(query) { if (!query) return; query = parseQuery(query); dialog(cm, getReplacementQueryDialog(cm), cm.phrase("Replace with:"), "", function(text) {