Skip to content

Commit be5577c

Browse files
committed
Update searchJumper.user.js
1 parent 7b7e9e8 commit be5577c

File tree

1 file changed

+70
-2
lines changed

1 file changed

+70
-2
lines changed

searchJumper.user.js

Lines changed: 70 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -820,6 +820,11 @@
820820
parseHTMLToFragment(String(html), fragment, targetDoc);
821821
return fragment;
822822
}
823+
let canDirectSetHTML = true;
824+
let canPolicySetHTML = true;
825+
let escapeHTMLPolicy;
826+
let escapeHTMLCreator;
827+
const MY_POLICY_NAME = 'searchjumper_default';
823828
const SVG_NS = 'http://www.w3.org/2000/svg';
824829
const VOID_TAGS = {
825830
area: true,
@@ -837,6 +842,15 @@
837842
track: true,
838843
wbr: true
839844
};
845+
const RAW_TEXT_TAGS = {
846+
script: true,
847+
style: true,
848+
textarea: true,
849+
title: true,
850+
xmp: true,
851+
plaintext: true,
852+
noscript: true
853+
};
840854
const HTML_ENTITIES = {
841855
amp: '&',
842856
lt: '<',
@@ -861,7 +875,7 @@
861875
}
862876
function parseHTMLToFragment(html, fragment, doc) {
863877
const stack = [fragment];
864-
const tokenRe = /<!--[\s\S]*?-->|<\/?[a-zA-Z][^>]*>|[^<]+/g;
878+
const tokenRe = /<!--[\s\S]*?-->|<!doctype[^>]*>|<\/?[a-zA-Z][^>]*>|[^<]+/gi;
865879
let match;
866880
while ((match = tokenRe.exec(html))) {
867881
const token = match[0];
@@ -873,6 +887,9 @@
873887
if (token.indexOf('<!--') === 0) {
874888
continue;
875889
}
890+
if (/^<!doctype/i.test(token)) {
891+
continue;
892+
}
876893
if (token[1] === '/') {
877894
const tag = token.slice(2, -1).trim().toLowerCase();
878895
for (let i = stack.length - 1; i > 0; i--) {
@@ -906,13 +923,64 @@
906923
const selfClosing = token.endsWith('/>');
907924
if (!selfClosing && !VOID_TAGS[tagName]) {
908925
stack.push(el);
926+
if (RAW_TEXT_TAGS[tagName]) {
927+
const closeRe = new RegExp('<\\/\\s*' + tagName + '\\s*>', 'ig');
928+
closeRe.lastIndex = tokenRe.lastIndex;
929+
const closeMatch = closeRe.exec(html);
930+
if (closeMatch) {
931+
const rawText = html.slice(tokenRe.lastIndex, closeMatch.index);
932+
if (rawText) el.appendChild(doc.createTextNode(rawText));
933+
tokenRe.lastIndex = closeMatch.index + closeMatch[0].length;
934+
stack.pop();
935+
}
936+
}
909937
}
910938
}
911939
}
940+
function ensureEscapeHTMLPolicy() {
941+
if (!canPolicySetHTML) return null;
942+
if (escapeHTMLCreator) return escapeHTMLPolicy;
943+
const createPolicy = _unsafeWindow && _unsafeWindow.trustedTypes && _unsafeWindow.trustedTypes.createPolicy;
944+
if (typeof createPolicy !== "function") return (canPolicySetHTML = false, null);
945+
try {
946+
escapeHTMLPolicy = createPolicy(MY_POLICY_NAME, {
947+
createHTML: (string, sink) => string,
948+
createScriptURL: string => string,
949+
createScript: string => string
950+
});
951+
} catch (e) {}
952+
escapeHTMLCreator = escapeHTMLPolicy && escapeHTMLPolicy.createHTML;
953+
if (!escapeHTMLCreator) canPolicySetHTML = false;
954+
return escapeHTMLPolicy;
955+
}
956+
function tryDirectSetHTML(target, htmlStr) {
957+
if (!canDirectSetHTML) return false;
958+
try {
959+
target.innerHTML = htmlStr;
960+
return true;
961+
} catch (e) {
962+
canDirectSetHTML = false;
963+
return false;
964+
}
965+
}
966+
function tryPolicySetHTML(target, htmlStr) {
967+
if (!canPolicySetHTML) return false;
968+
ensureEscapeHTMLPolicy();
969+
if (!escapeHTMLCreator) return false;
970+
try {
971+
target.innerHTML = escapeHTMLCreator(htmlStr);
972+
return true;
973+
} catch (e) {
974+
canPolicySetHTML = false;
975+
return false;
976+
}
977+
}
912978
function setHTML(target, html, doc) {
913979
if (!target) return;
980+
const htmlStr = html === null || html === undefined ? '' : String(html);
981+
if (tryDirectSetHTML(target, htmlStr) || tryPolicySetHTML(target, htmlStr)) return;
914982
const targetDoc = doc || target.ownerDocument || document;
915-
const fragment = createHTML(html, targetDoc);
983+
const fragment = createHTML(htmlStr, targetDoc);
916984
while (target.firstChild) {
917985
target.removeChild(target.firstChild);
918986
}

0 commit comments

Comments
 (0)