Skip to content

Commit a33bdb6

Browse files
committed
Update Picviewer CE+.user.js
1 parent 2af014b commit a33bdb6

File tree

1 file changed

+102
-7
lines changed

1 file changed

+102
-7
lines changed

Picviewer CE+/Picviewer CE+.user.js

Lines changed: 102 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
// @description:ja 画像を強力に閲覧できるツール。ポップアップ表示、拡大・縮小、回転、一括保存などの機能を自動で実行できます
1313
// @description:pt-BR Poderosa ferramenta de visualização de imagens on-line, que pode pop-up/dimensionar/girar/salvar em lote imagens automaticamente
1414
// @description:ru Мощный онлайн-инструмент для просмотра изображений, который может автоматически отображать/масштабировать/вращать/пакетно сохранять изображения
15-
// @version 2025.10.7.1
15+
// @version 2025.10.10.1
1616
// @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg==
1717
// @namespace https://github.com/hoothin/UserScripts
1818
// @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B
@@ -12455,15 +12455,109 @@ ImgOps | https://imgops.com/#b#`;
1245512455
});
1245612456
}
1245712457
var prefs;
12458-
var escapeHTMLPolicy;
12459-
if (unsafeWindow.trustedTypes && unsafeWindow.trustedTypes.createPolicy) {
12460-
escapeHTMLPolicy=unsafeWindow.trustedTypes.createPolicy('pvcep_default', {
12461-
createHTML: (string, sink) => string,
12462-
createScriptURL: string => string,
12463-
createScript: string => string
12458+
12459+
function parseTrustedTypes(cspString) {
12460+
const policies = new Set();
12461+
const ttRegex = /trusted-types\s+([^;]+)/gi;
12462+
let match;
12463+
while ((match = ttRegex.exec(cspString)) !== null) {
12464+
match[1].trim().split(/\s+/)
12465+
.forEach(name => {
12466+
if (name !== "'allow-duplicates'" && name !== "'none'") {
12467+
policies.add(name.replace(/'/g, ''));
12468+
}
12469+
});
12470+
}
12471+
return Array.from(policies);
12472+
}
12473+
12474+
async function getAvailablePolicyNamesOptimized() {
12475+
if (unsafeWindow.trustedTypes && unsafeWindow.trustedTypes.getPolicyNames) {
12476+
const existingNames = unsafeWindow.trustedTypes.getPolicyNames();
12477+
if (existingNames.length > 0) {
12478+
return new Set(existingNames);
12479+
}
12480+
}
12481+
12482+
const meta = document.querySelector('meta[http-equiv="Content-Security-Policy"]');
12483+
if (meta) {
12484+
const metaNames = parseTrustedTypes(meta.content);
12485+
if (metaNames.length > 0) {
12486+
return new Set(metaNames);
12487+
}
12488+
}
12489+
12490+
return new Promise((resolve) => {
12491+
GM_xmlhttpRequest({
12492+
method: "HEAD",
12493+
url: window.location.href,
12494+
onload: function(response) {
12495+
const cspHeader = response.responseHeaders.split('\r\n')
12496+
.filter(h => h.toLowerCase().startsWith('content-security-policy:'))
12497+
.map(h => h.substring(26).trim())
12498+
.join('; ');
12499+
12500+
const headerNames = parseTrustedTypes(cspHeader);
12501+
if (headerNames.length > 0) {
12502+
resolve(new Set(headerNames));
12503+
} else {
12504+
resolve(new Set());
12505+
}
12506+
},
12507+
onerror: function(error) {
12508+
resolve(new Set());
12509+
}
12510+
});
1246412511
});
1246512512
}
1246612513

12514+
function isTrustedTypesEnforced() {
12515+
try {
12516+
document.createElement('div').innerHTML = '';
12517+
return false;
12518+
} catch (e) {
12519+
return true;
12520+
}
12521+
}
12522+
12523+
async function createPolicy() {
12524+
if (unsafeWindow.trustedTypes && unsafeWindow.trustedTypes.createPolicy && isTrustedTypesEnforced()) {
12525+
const allowedNames = await getAvailablePolicyNamesOptimized();
12526+
12527+
if (allowedNames.size === 0) {
12528+
escapeHTMLPolicy = unsafeWindow.trustedTypes.createPolicy('pvcep_default', {
12529+
createHTML: (string, sink) => string,
12530+
createScriptURL: string => string,
12531+
createScript: string => string
12532+
});
12533+
return;
12534+
}
12535+
12536+
for (const name of allowedNames) {
12537+
if (name === '*') continue;
12538+
try {
12539+
escapeHTMLPolicy = unsafeWindow.trustedTypes.createPolicy(name, {
12540+
createHTML: (string, sink) => string,
12541+
createScriptURL: string => string,
12542+
createScript: string => string
12543+
});
12544+
break;
12545+
} catch (e) {
12546+
try {
12547+
escapeHTMLPolicy = unsafeWindow.trustedTypes.policies.get(name);
12548+
if (escapeHTMLPolicy) {
12549+
break;
12550+
}
12551+
} catch (e2) {
12552+
console.warn(`create '${name}' failed`);
12553+
}
12554+
}
12555+
}
12556+
}
12557+
}
12558+
12559+
let escapeHTMLPolicy = null;
12560+
1246712561
function getBody(doc){
1246812562
return doc.body || doc.querySelector('body') || doc;
1246912563
}
@@ -12477,6 +12571,7 @@ ImgOps | https://imgops.com/#b#`;
1247712571
return escapeHTMLPolicy?escapeHTMLPolicy.createScript(html):html;
1247812572
}
1247912573
async function init(topObject,window,document,arrayFn,envir,storage,unsafeWindow){
12574+
await createPolicy();
1248012575
// 默认设置,请到设置界面修改
1248112576
prefs={
1248212577
floatBar:{//浮动工具栏相关设置.

0 commit comments

Comments
 (0)