Skip to content

Commit

Permalink
[search addon] Make compatible with Trusted Types
Browse files Browse the repository at this point in the history
https://web.dev/trusted-types/ doesn't allow string innerHTML assignments. This change avoids it by using DOM instead.
  • Loading branch information
vrana authored and marijnh committed Jul 20, 2021
1 parent cf6cc38 commit 68d3399
Showing 1 changed file with 44 additions and 6 deletions.
50 changes: 44 additions & 6 deletions addon/search/search.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 '<span class="CodeMirror-search-label">' + cm.phrase("Search:") + '</span> <input type="text" style="width: 10em" class="CodeMirror-search-field"/> <span style="color: #888" class="CodeMirror-search-hint">' + cm.phrase("(Use /re/ syntax for regexp search)") + '</span>';
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 ' <input type="text" style="width: 10em" class="CodeMirror-search-field"/> <span style="color: #888" class="CodeMirror-search-hint">' + cm.phrase("(Use /re/ syntax for regexp search)") + '</span>';
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 '<span class="CodeMirror-search-label">' + cm.phrase("With:") + '</span> <input type="text" style="width: 10em" class="CodeMirror-search-field"/>';
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 '<span class="CodeMirror-search-label">' + cm.phrase("Replace?") + '</span> <button>' + cm.phrase("Yes") + '</button> <button>' + cm.phrase("No") + '</button> <button>' + cm.phrase("All") + '</button> <button>' + cm.phrase("Stop") + '</button> ';
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) {
Expand All @@ -217,8 +253,10 @@
function replace(cm, all) {
if (cm.getOption("readOnly")) return;
var query = cm.getSelection() || getSearchState(cm).lastQuery;
var dialogText = '<span class="CodeMirror-search-label">' + (all ? cm.phrase("Replace all:") : cm.phrase("Replace:")) + '</span>';
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) {
Expand Down

0 comments on commit 68d3399

Please sign in to comment.