sourcemonkey 0.0.0-stage → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +87 -2
- package/dist/bytes.js +37 -0
- package/dist/channel-placeholder.js +5 -0
- package/dist/collection-scan.js +17 -0
- package/dist/collections.html +353 -0
- package/dist/compare.html +358 -0
- package/dist/composed-source.js +205 -0
- package/dist/connect-prompt.html +47 -0
- package/dist/debug/icons.html +211 -0
- package/dist/debug/storage.html +163 -0
- package/dist/debug-log.js +75 -0
- package/dist/diagnostic-location.js +64 -0
- package/dist/eval-hook.js +308 -0
- package/dist/extension/background.js +5263 -0
- package/dist/extension/channel.js +133 -0
- package/dist/extension/code-links.js +187 -0
- package/dist/extension/code-tabs.js +460 -0
- package/dist/extension/collection-dialog.js +619 -0
- package/dist/extension/collection-display.js +322 -0
- package/dist/extension/collections.js +2905 -0
- package/dist/extension/compare.js +867 -0
- package/dist/extension/concurrency.js +186 -0
- package/dist/extension/connect-grants.js +109 -0
- package/dist/extension/connect-prompt-page.js +70 -0
- package/dist/extension/connect-prompt.js +266 -0
- package/dist/extension/copy-button.js +63 -0
- package/dist/extension/copy-dialog.js +502 -0
- package/dist/extension/copy-preference.js +66 -0
- package/dist/extension/debug/icons.js +203 -0
- package/dist/extension/debug/storage.js +365 -0
- package/dist/extension/deep-link.js +77 -0
- package/dist/extension/delete-dialog.js +432 -0
- package/dist/extension/delete-icon.js +40 -0
- package/dist/extension/details-tooltips.js +66 -0
- package/dist/extension/directories.js +679 -0
- package/dist/extension/export-backup.js +407 -0
- package/dist/extension/export-dialog.js +142 -0
- package/dist/extension/file-access.js +74 -0
- package/dist/extension/file-changes.js +346 -0
- package/dist/extension/frame-info.js +85 -0
- package/dist/extension/github-provider.js +336 -0
- package/dist/extension/glyph.js +84 -0
- package/dist/extension/gm-bindings.js +601 -0
- package/dist/extension/gm-download.js +419 -0
- package/dist/extension/gm-menu.js +228 -0
- package/dist/extension/gm-notification.js +141 -0
- package/dist/extension/gm-originator-map.js +23 -0
- package/dist/extension/gm-tab-data.js +121 -0
- package/dist/extension/gm-tab.js +160 -0
- package/dist/extension/gm-url-change.js +111 -0
- package/dist/extension/gm-url-scheme.js +27 -0
- package/dist/extension/gm-values.js +176 -0
- package/dist/extension/gm-window-control.js +104 -0
- package/dist/extension/gm-xhr-headers.js +333 -0
- package/dist/extension/gm-xhr.js +584 -0
- package/dist/extension/injector.js +3145 -0
- package/dist/extension/install-capture.js +277 -0
- package/dist/extension/line-diff.js +233 -0
- package/dist/extension/local-copy.js +560 -0
- package/dist/extension/local-delete.js +276 -0
- package/dist/extension/location-kinds.js +108 -0
- package/dist/extension/log-format.js +158 -0
- package/dist/extension/managed-changes.js +361 -0
- package/dist/extension/managed-items.js +57 -0
- package/dist/extension/match-index.js +375 -0
- package/dist/extension/missing-scripts.js +66 -0
- package/dist/extension/more-menu.js +109 -0
- package/dist/extension/move-dialog.js +197 -0
- package/dist/extension/offscreen.js +37 -0
- package/dist/extension/options.js +504 -0
- package/dist/extension/page-heading.js +170 -0
- package/dist/extension/page-links.js +199 -0
- package/dist/extension/parse-check-client.js +70 -0
- package/dist/extension/parse-check.js +161 -0
- package/dist/extension/parse-sandbox-host.js +172 -0
- package/dist/extension/parse-sandbox.js +175 -0
- package/dist/extension/popup-commands-open.js +41 -0
- package/dist/extension/popup-view.js +387 -0
- package/dist/extension/popup.js +703 -0
- package/dist/extension/prism-userscript.js +53 -0
- package/dist/extension/refresh-error.js +136 -0
- package/dist/extension/refresh-targets.js +160 -0
- package/dist/extension/related-versions.js +1144 -0
- package/dist/extension/resize-observer-loop.js +19 -0
- package/dist/extension/row-cache.js +387 -0
- package/dist/extension/script-blobs.js +413 -0
- package/dist/extension/script-details.js +658 -0
- package/dist/extension/script-enablement.js +285 -0
- package/dist/extension/script-identity.js +310 -0
- package/dist/extension/script-keys.js +54 -0
- package/dist/extension/script-log-id.js +155 -0
- package/dist/extension/script-log.js +290 -0
- package/dist/extension/script-rejection.js +104 -0
- package/dist/extension/script-sites.js +158 -0
- package/dist/extension/script-store.js +3507 -0
- package/dist/extension/script-updater.js +991 -0
- package/dist/extension/script-url-hash.js +61 -0
- package/dist/extension/select-all.js +37 -0
- package/dist/extension/select-open-guard.js +90 -0
- package/dist/extension/site-icon.js +1261 -0
- package/dist/extension/sm-dev-link.js +302 -0
- package/dist/extension/solo-click.js +58 -0
- package/dist/extension/sticky-numbers.js +188 -0
- package/dist/extension/storage-breakdown.js +253 -0
- package/dist/extension/storage-scan.js +86 -0
- package/dist/extension/storage-usage.js +194 -0
- package/dist/extension/structural-keys.js +29 -0
- package/dist/extension/sw-teardown.js +36 -0
- package/dist/extension/tab-status.js +403 -0
- package/dist/extension/toolbar-summary.js +105 -0
- package/dist/extension/user-scripts-access.js +43 -0
- package/dist/extension/userscript.js +3672 -0
- package/dist/extension/value-store.js +204 -0
- package/dist/extension/version-probe-fetch.js +68 -0
- package/dist/extension/worker-client.js +109 -0
- package/dist/extension/worker-ops.js +171 -0
- package/dist/extension/zip-writer.js +24 -0
- package/dist/external-files.js +878 -0
- package/dist/file-loader.js +436 -0
- package/dist/file-locations.js +439 -0
- package/dist/generated-wrappers.js +5 -0
- package/dist/github-auth.js +148 -0
- package/dist/github-urls.js +46 -0
- package/dist/gm-api-catalog.js +217 -0
- package/dist/gm-connect.js +273 -0
- package/dist/gm-xhr-types.js +5 -0
- package/dist/http-read.js +142 -0
- package/dist/icons/icon-128.png +0 -0
- package/dist/icons/icon-16.png +0 -0
- package/dist/icons/icon-48.png +0 -0
- package/dist/local-file-overrides.js +558 -0
- package/dist/manifest.json +38 -0
- package/dist/markup-response.js +126 -0
- package/dist/match-targets.js +305 -0
- package/dist/menu-captions.js +22 -0
- package/dist/offscreen.html +39 -0
- package/dist/options.html +197 -0
- package/dist/parse-check-protocol.js +51 -0
- package/dist/parse-location.js +171 -0
- package/dist/parse-sandbox.html +56 -0
- package/dist/phase-timing.js +155 -0
- package/dist/popup.html +197 -0
- package/dist/public-suffixes.js +6957 -0
- package/dist/run-context.js +31 -0
- package/dist/runtime-messages.js +34 -0
- package/dist/sandboxed-page.js +35 -0
- package/dist/script-build.js +787 -0
- package/dist/script-display.js +383 -0
- package/dist/script-icon.js +43 -0
- package/dist/script-links.js +204 -0
- package/dist/script-source-url.js +214 -0
- package/dist/script-world.js +65 -0
- package/dist/sm-dev-protocol.js +84 -0
- package/dist/source-map.js +177 -0
- package/dist/stack-link.js +138 -0
- package/dist/styles.css +825 -0
- package/dist/unsafe-window-use.js +229 -0
- package/dist/url-match.js +734 -0
- package/dist/userscript-header.js +248 -0
- package/dist/userscript.html +1165 -0
- package/dist/vendor/fflate.LICENSE +21 -0
- package/dist/vendor/fflate.js +2692 -0
- package/dist/vendor/prism/prism-line-numbers.css +1 -0
- package/dist/vendor/prism/prism-line-numbers.js +1 -0
- package/dist/vendor/prism/prism.css +1 -0
- package/dist/vendor/prism/prism.js +1946 -0
- package/dist/version-compare.js +141 -0
- package/dist/version-probe.js +120 -0
- package/lib/build-info.json +1 -0
- package/lib/bytes.d.ts +3 -0
- package/lib/bytes.js +37 -0
- package/lib/channel-placeholder.d.ts +1 -0
- package/lib/channel-placeholder.js +5 -0
- package/lib/collection-scan.d.ts +8 -0
- package/lib/collection-scan.js +17 -0
- package/lib/composed-source.d.ts +28 -0
- package/lib/composed-source.js +205 -0
- package/lib/debug-log.d.ts +9 -0
- package/lib/debug-log.js +75 -0
- package/lib/diagnostic-location.d.ts +8 -0
- package/lib/diagnostic-location.js +64 -0
- package/lib/eval-hook.d.ts +34 -0
- package/lib/eval-hook.js +308 -0
- package/lib/external-files.d.ts +111 -0
- package/lib/external-files.js +878 -0
- package/lib/file-loader.d.ts +48 -0
- package/lib/file-loader.js +436 -0
- package/lib/file-locations.d.ts +44 -0
- package/lib/file-locations.js +439 -0
- package/lib/generated-wrappers.d.ts +11 -0
- package/lib/generated-wrappers.js +5 -0
- package/lib/github-auth.d.ts +12 -0
- package/lib/github-auth.js +148 -0
- package/lib/github-urls.d.ts +1 -0
- package/lib/github-urls.js +46 -0
- package/lib/gm-api-catalog.d.ts +24 -0
- package/lib/gm-api-catalog.js +217 -0
- package/lib/gm-connect.d.ts +34 -0
- package/lib/gm-connect.js +273 -0
- package/lib/gm-xhr-types.d.ts +68 -0
- package/lib/gm-xhr-types.js +5 -0
- package/lib/harness/browser-extensions.d.ts +73 -0
- package/lib/harness/browser-extensions.js +285 -0
- package/lib/harness/browser-lang.d.ts +20 -0
- package/lib/harness/browser-lang.js +86 -0
- package/lib/harness/browser-launch.d.ts +14 -0
- package/lib/harness/browser-launch.js +184 -0
- package/lib/harness/checks.d.ts +110 -0
- package/lib/harness/checks.js +321 -0
- package/lib/harness/cli.d.ts +2 -0
- package/lib/harness/cli.js +2259 -0
- package/lib/harness/command-args.d.ts +91 -0
- package/lib/harness/command-args.js +369 -0
- package/lib/harness/command-lines.d.ts +80 -0
- package/lib/harness/command-lines.js +180 -0
- package/lib/harness/command-list.d.ts +206 -0
- package/lib/harness/command-list.js +1475 -0
- package/lib/harness/console-commands.d.ts +463 -0
- package/lib/harness/console-commands.js +3216 -0
- package/lib/harness/download-watch.d.ts +21 -0
- package/lib/harness/download-watch.js +156 -0
- package/lib/harness/extension-backend.d.ts +41 -0
- package/lib/harness/extension-backend.js +100 -0
- package/lib/harness/extension-host.d.ts +112 -0
- package/lib/harness/extension-host.js +552 -0
- package/lib/harness/extension-launch.d.ts +67 -0
- package/lib/harness/extension-launch.js +285 -0
- package/lib/harness/extension-link.d.ts +315 -0
- package/lib/harness/extension-link.js +607 -0
- package/lib/harness/external-manager.d.ts +146 -0
- package/lib/harness/external-manager.js +414 -0
- package/lib/harness/fixture.d.ts +165 -0
- package/lib/harness/fixture.js +461 -0
- package/lib/harness/frame-sessions.d.ts +71 -0
- package/lib/harness/frame-sessions.js +248 -0
- package/lib/harness/frames.d.ts +68 -0
- package/lib/harness/frames.js +216 -0
- package/lib/harness/help-format.d.ts +17 -0
- package/lib/harness/help-format.js +127 -0
- package/lib/harness/host.d.ts +352 -0
- package/lib/harness/host.js +423 -0
- package/lib/harness/index.d.ts +8 -0
- package/lib/harness/index.js +10 -0
- package/lib/harness/input-file.d.ts +18 -0
- package/lib/harness/input-file.js +61 -0
- package/lib/harness/json-output.d.ts +565 -0
- package/lib/harness/json-output.js +71 -0
- package/lib/harness/manager-actions.d.ts +21 -0
- package/lib/harness/manager-actions.js +129 -0
- package/lib/harness/manager-commands.d.ts +142 -0
- package/lib/harness/manager-commands.js +1196 -0
- package/lib/harness/manager-fetch.d.ts +33 -0
- package/lib/harness/manager-fetch.js +239 -0
- package/lib/harness/managers.d.ts +24 -0
- package/lib/harness/managers.js +27 -0
- package/lib/harness/output-style.d.ts +125 -0
- package/lib/harness/output-style.js +322 -0
- package/lib/harness/page-commands.d.ts +134 -0
- package/lib/harness/page-commands.js +1141 -0
- package/lib/harness/page-output.d.ts +67 -0
- package/lib/harness/page-output.js +139 -0
- package/lib/harness/page-watch.d.ts +171 -0
- package/lib/harness/page-watch.js +607 -0
- package/lib/harness/parse-check-node.d.ts +3 -0
- package/lib/harness/parse-check-node.js +132 -0
- package/lib/harness/path-args.d.ts +22 -0
- package/lib/harness/path-args.js +148 -0
- package/lib/harness/playwright-chromium.d.ts +16 -0
- package/lib/harness/playwright-chromium.js +86 -0
- package/lib/harness/prepare.d.ts +168 -0
- package/lib/harness/prepare.js +364 -0
- package/lib/harness/prompt-editor.d.ts +17 -0
- package/lib/harness/prompt-editor.js +354 -0
- package/lib/harness/prompt-history.d.ts +13 -0
- package/lib/harness/prompt-history.js +89 -0
- package/lib/harness/rebuild-advice.d.ts +6 -0
- package/lib/harness/rebuild-advice.js +39 -0
- package/lib/harness/run-log.d.ts +47 -0
- package/lib/harness/run-log.js +140 -0
- package/lib/harness/run-logs.d.ts +132 -0
- package/lib/harness/run-logs.js +241 -0
- package/lib/harness/run.d.ts +194 -0
- package/lib/harness/run.js +1973 -0
- package/lib/harness/runs.d.ts +229 -0
- package/lib/harness/runs.js +726 -0
- package/lib/harness/save-html.d.ts +39 -0
- package/lib/harness/save-html.js +89 -0
- package/lib/harness/saved-pages.d.ts +120 -0
- package/lib/harness/saved-pages.js +275 -0
- package/lib/harness/script-mark.d.ts +17 -0
- package/lib/harness/script-mark.js +56 -0
- package/lib/harness/snapshot.d.ts +143 -0
- package/lib/harness/snapshot.js +474 -0
- package/lib/harness/stuck-tabs.d.ts +19 -0
- package/lib/harness/stuck-tabs.js +131 -0
- package/lib/harness/tab-refs.d.ts +20 -0
- package/lib/harness/tab-refs.js +80 -0
- package/lib/harness/tampermonkey.d.ts +71 -0
- package/lib/harness/tampermonkey.js +356 -0
- package/lib/harness/tm-ids.d.ts +18 -0
- package/lib/harness/tm-ids.js +88 -0
- package/lib/harness/violentmonkey.d.ts +34 -0
- package/lib/harness/violentmonkey.js +162 -0
- package/lib/harness/wait.d.ts +77 -0
- package/lib/harness/wait.js +458 -0
- package/lib/http-read.d.ts +30 -0
- package/lib/http-read.js +142 -0
- package/lib/local-file-overrides.d.ts +35 -0
- package/lib/local-file-overrides.js +558 -0
- package/lib/manifest.json +38 -0
- package/lib/markup-response.d.ts +11 -0
- package/lib/markup-response.js +126 -0
- package/lib/match-targets.d.ts +18 -0
- package/lib/match-targets.js +305 -0
- package/lib/menu-captions.d.ts +1 -0
- package/lib/menu-captions.js +22 -0
- package/lib/parse-check-protocol.d.ts +27 -0
- package/lib/parse-check-protocol.js +51 -0
- package/lib/parse-location.d.ts +12 -0
- package/lib/parse-location.js +171 -0
- package/lib/phase-timing.d.ts +12 -0
- package/lib/phase-timing.js +155 -0
- package/lib/public-suffixes.d.ts +1 -0
- package/lib/public-suffixes.js +6957 -0
- package/lib/run-context.d.ts +2 -0
- package/lib/run-context.js +31 -0
- package/lib/runtime-messages.d.ts +10 -0
- package/lib/runtime-messages.js +34 -0
- package/lib/sandboxed-page.d.ts +5 -0
- package/lib/sandboxed-page.js +35 -0
- package/lib/script-build.d.ts +111 -0
- package/lib/script-build.js +787 -0
- package/lib/script-display.d.ts +51 -0
- package/lib/script-display.js +383 -0
- package/lib/script-icon.d.ts +16 -0
- package/lib/script-icon.js +43 -0
- package/lib/script-links.d.ts +24 -0
- package/lib/script-links.js +204 -0
- package/lib/script-source-url.d.ts +8 -0
- package/lib/script-source-url.js +214 -0
- package/lib/script-world.d.ts +6 -0
- package/lib/script-world.js +65 -0
- package/lib/sm-dev-protocol.d.ts +251 -0
- package/lib/sm-dev-protocol.js +84 -0
- package/lib/source-map.d.ts +32 -0
- package/lib/source-map.js +177 -0
- package/lib/stack-link.d.ts +15 -0
- package/lib/stack-link.js +138 -0
- package/lib/unsafe-window-use.d.ts +1 -0
- package/lib/unsafe-window-use.js +229 -0
- package/lib/url-match.d.ts +40 -0
- package/lib/url-match.js +734 -0
- package/lib/userscript-header.d.ts +33 -0
- package/lib/userscript-header.js +248 -0
- package/lib/version-compare.d.ts +6 -0
- package/lib/version-compare.js +141 -0
- package/lib/version-probe.d.ts +17 -0
- package/lib/version-probe.js +120 -0
- package/package.json +55 -3
- package/skills/SourceMonkey-dev/SKILL.md +868 -0
- package/skills/SourceMonkey-dev/references/cdp.md +293 -0
- package/skills/SourceMonkey-dev/references/commands.md +297 -0
- package/skills/SourceMonkey-dev/references/other-managers.md +63 -0
- package/skills/SourceMonkey-dev/references/specs.md +46 -0
- package/skills/SourceMonkey-friction/SKILL.md +103 -0
- package/skills/SourceMonkey-friction/references/template.md +59 -0
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { StoredScript } from './script-build.js';
|
|
2
|
+
import { type ParsedHeader } from './userscript-header.js';
|
|
3
|
+
import { type VersionProbe } from './version-probe.js';
|
|
4
|
+
export declare const ENABLE_TITLE = "Enable this script";
|
|
5
|
+
export declare function decodeForDisplay(text: string): string;
|
|
6
|
+
export declare function leafName(path: string): string;
|
|
7
|
+
export declare function displayLocation(urlOrPath: string): string;
|
|
8
|
+
export declare function scriptBasename(urlOrPath: string): string;
|
|
9
|
+
export declare function logIdSuffix(logId: string): string;
|
|
10
|
+
/** The script number a log ID ends with (`foo.user.js#E4` → 4), or null for none. */
|
|
11
|
+
export declare function logIdScriptNumber(logId: string): number | null;
|
|
12
|
+
export declare function scriptDisplayName(script: Pick<StoredScript, 'header' | 'relativePath'>, fallback?: string): string;
|
|
13
|
+
export declare function compareScriptNames(a: string, b: string): number;
|
|
14
|
+
export declare function headerDisplayName(header: ParsedHeader | null | undefined): string;
|
|
15
|
+
export declare function scriptLabel(header: ParsedHeader | null | undefined, location: string): string;
|
|
16
|
+
export declare function appendWithSlashBreaks(el: HTMLElement, text: string): void;
|
|
17
|
+
export declare function formatBytes(size: number): string;
|
|
18
|
+
export declare function formatStorageUsage(used: number, quota: number): string;
|
|
19
|
+
export declare function formatQuota(bytes: number): string;
|
|
20
|
+
export declare function formatScriptSize(script: Pick<StoredScript, 'status' | 'size'>): string;
|
|
21
|
+
export type DisplayStatus = 'ok' | 'invalid' | 'rejected' | 'refresh-failed' | 'outdated' | 'warning' | 'error';
|
|
22
|
+
export type LoadState = Exclude<DisplayStatus, 'warning' | 'error'>;
|
|
23
|
+
export declare const LOAD_STATES: readonly LoadState[];
|
|
24
|
+
export declare function isLoadState(value: unknown): value is LoadState;
|
|
25
|
+
export type LogLevelForStatus = 'info' | 'warning' | 'error';
|
|
26
|
+
export declare function effectiveScriptStatus(script: Pick<StoredScript, 'status' | 'refreshError'>, maxLogLevel: LogLevelForStatus | undefined, outdated?: boolean, rejected?: boolean): DisplayStatus;
|
|
27
|
+
export declare function scriptOutdatedProbe(script: Pick<StoredScript, 'header' | 'versionProbes'>): VersionProbe | null;
|
|
28
|
+
export declare function formatScriptStatusLabel(status: DisplayStatus): string;
|
|
29
|
+
export declare function viewerUrl(scriptId: string, tab?: 'log'): string;
|
|
30
|
+
export declare function compareUrl(base: {
|
|
31
|
+
script: string;
|
|
32
|
+
} | {
|
|
33
|
+
preview: string;
|
|
34
|
+
}, other: string): string;
|
|
35
|
+
export declare function previewUrl(location: string): string;
|
|
36
|
+
export interface ScriptStatusView {
|
|
37
|
+
status: DisplayStatus;
|
|
38
|
+
label: string;
|
|
39
|
+
title?: string;
|
|
40
|
+
}
|
|
41
|
+
export declare function scriptStatusView(script: Pick<StoredScript, 'status' | 'refreshError' | 'errorMessage' | 'errorLocation' | 'header' | 'versionProbes'>, maxLogLevel: LogLevelForStatus | undefined, rejection: string | undefined): ScriptStatusView;
|
|
42
|
+
export declare function stripSriFragment(urlOrRef: string): string;
|
|
43
|
+
export declare function fullSource(script: StoredScript): string;
|
|
44
|
+
export declare function requireBasename(url: string, ref: string): string;
|
|
45
|
+
export interface PendingOnDisk {
|
|
46
|
+
modified: number;
|
|
47
|
+
deleted: number;
|
|
48
|
+
added: number;
|
|
49
|
+
manifest?: true;
|
|
50
|
+
}
|
|
51
|
+
export declare function pendingSummary(counts: PendingOnDisk): string;
|
|
@@ -0,0 +1,383 @@
|
|
|
1
|
+
// Display helpers shared by the collections page, the userscript viewer,
|
|
2
|
+
// the script preview, and the service worker.
|
|
3
|
+
//
|
|
4
|
+
// Two groups live here: the script-status row formatting (size +
|
|
5
|
+
// status label) both pages render, and the name/path formatting that
|
|
6
|
+
// turns a stored URL into something a human wants to read. Pure
|
|
7
|
+
// functions — no DOM, no chrome.* calls. (`version-probe.js` is the
|
|
8
|
+
// pure half of the probe module; its fetching half lives in
|
|
9
|
+
// `version-probe-fetch.js` and is deliberately not reachable here.)
|
|
10
|
+
import { getValue, joinFullSource } from './userscript-header.js';
|
|
11
|
+
import { outdatedProbe, probeLabel } from './version-probe.js';
|
|
12
|
+
import { describeDiagnostic } from './diagnostic-location.js';
|
|
13
|
+
// ---------- Names and paths ----------
|
|
14
|
+
// Anything of the form `<scheme>://…`. Used to decide whether
|
|
15
|
+
// percent-decoding is safe: URL path segments are encoded, on-disk
|
|
16
|
+
// names are literal.
|
|
17
|
+
const ABSOLUTE_URL_RE = /^[a-z][a-z0-9+.-]*:\/\//i;
|
|
18
|
+
// Percent-decode for display. Never throws: a lone `%` (a literal
|
|
19
|
+
// percent in a filename) would make decodeURIComponent raise URIError,
|
|
20
|
+
// and losing the whole string is far worse than leaving one escape
|
|
21
|
+
// undecoded.
|
|
22
|
+
// Tooltip on a script's enable checkbox, wherever one is drawn: the
|
|
23
|
+
// collections page's per-row toggle, the viewer's controls row, the
|
|
24
|
+
// "Other versions" panel, and the toolbar popup's rows. The viewer and
|
|
25
|
+
// the popup append a multi-enable hint to it where other copies exist
|
|
26
|
+
// (see `enableTitle` in solo-click.ts); the collections page shows it
|
|
27
|
+
// bare.
|
|
28
|
+
export const ENABLE_TITLE = 'Enable this script';
|
|
29
|
+
export function decodeForDisplay(text) {
|
|
30
|
+
try {
|
|
31
|
+
return decodeURIComponent(text);
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
return text;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
// Last `/`-separated segment of a path. No decoding — callers that
|
|
38
|
+
// want a display form pass the result through decodeForDisplay.
|
|
39
|
+
export function leafName(path) {
|
|
40
|
+
const slash = path.lastIndexOf('/');
|
|
41
|
+
return slash < 0 ? path : path.slice(slash + 1);
|
|
42
|
+
}
|
|
43
|
+
// Readable form of a stored location — the string a heading, tooltip,
|
|
44
|
+
// or title shows. Scripts installed from the web (GreasyFork above
|
|
45
|
+
// all) carry their human name inside the URL path, so the stored URL
|
|
46
|
+
// is a wall of `%20` / `%F0%9F…`; Chrome's own omnibox shows those
|
|
47
|
+
// decoded and so do we.
|
|
48
|
+
//
|
|
49
|
+
// Only absolute URLs are decoded. A relativePath from a local directory
|
|
50
|
+
// collection is a literal on-disk name, where a `%20` really is a
|
|
51
|
+
// percent followed by two digits.
|
|
52
|
+
//
|
|
53
|
+
// Display only: hrefs, clipboard copies, fetches, and stored values
|
|
54
|
+
// all keep the encoded form.
|
|
55
|
+
export function displayLocation(urlOrPath) {
|
|
56
|
+
return ABSOLUTE_URL_RE.test(urlOrPath) ? decodeForDisplay(urlOrPath) : urlOrPath;
|
|
57
|
+
}
|
|
58
|
+
// Short display name for a script's location: the URL's filename (no
|
|
59
|
+
// query string, decoded), or the last path segment for an on-disk
|
|
60
|
+
// relativePath. Falls back to the whole input when a URL-shaped string
|
|
61
|
+
// won't parse or has an empty path, so the caller always has something
|
|
62
|
+
// to render.
|
|
63
|
+
//
|
|
64
|
+
// The second `leafName` is not redundant: an escaped `%2F` decodes to
|
|
65
|
+
// a real slash, and this feeds log IDs — a "basename" carrying a path
|
|
66
|
+
// separator would read as a directory in every log line.
|
|
67
|
+
export function scriptBasename(urlOrPath) {
|
|
68
|
+
if (!ABSOLUTE_URL_RE.test(urlOrPath))
|
|
69
|
+
return leafName(urlOrPath);
|
|
70
|
+
try {
|
|
71
|
+
return leafName(decodeForDisplay(leafName(new URL(urlOrPath).pathname))) || urlOrPath;
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
return leafName(urlOrPath);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
// The trailing suffix a log ID carries: the script's number (`#E4`),
|
|
78
|
+
// or `#N` for an unnumbered script sharing its basename; '' for none.
|
|
79
|
+
// Anchored to that shape rather than the first `#` in the string: log
|
|
80
|
+
// IDs are decoded filenames, so a script whose URL carries a `%23` has
|
|
81
|
+
// a literal `#` mid-name and would otherwise render half its own name
|
|
82
|
+
// as a suffix.
|
|
83
|
+
export function logIdSuffix(logId) {
|
|
84
|
+
return /#E?\d+$/.exec(logId)?.[0] ?? '';
|
|
85
|
+
}
|
|
86
|
+
/** The script number a log ID ends with (`foo.user.js#E4` → 4), or null for none. */
|
|
87
|
+
export function logIdScriptNumber(logId) {
|
|
88
|
+
const n = /#E(\d+)$/.exec(logId)?.[1];
|
|
89
|
+
return n === undefined ? null : Number(n);
|
|
90
|
+
}
|
|
91
|
+
// The name to show for a script in badges, menus, the collections list,
|
|
92
|
+
// and match listings: its `@name` when it declares a usable one, else
|
|
93
|
+
// its location in readable form. Shared so every surface labels the
|
|
94
|
+
// same script the same way.
|
|
95
|
+
//
|
|
96
|
+
// A whitespace-only `@name` counts as no name — a header that parsed
|
|
97
|
+
// but declared `// @name ` must not paint a blank row where a name
|
|
98
|
+
// belongs.
|
|
99
|
+
//
|
|
100
|
+
// `fallback` lets a caller substitute its own location text (the
|
|
101
|
+
// collections page shortens a container script's URL to its basename);
|
|
102
|
+
// omitted, the whole location is used.
|
|
103
|
+
export function scriptDisplayName(script, fallback) {
|
|
104
|
+
return headerDisplayName(script.header) || fallback || displayLocation(script.relativePath);
|
|
105
|
+
}
|
|
106
|
+
// The order scripts are listed in wherever names are shown in a list:
|
|
107
|
+
// case-insensitive, with numbers compared by value ("Item 9" before
|
|
108
|
+
// "Item 10"). Shared so every list orders the same scripts alike.
|
|
109
|
+
const nameCollator = new Intl.Collator(undefined, { sensitivity: 'base', numeric: true });
|
|
110
|
+
export function compareScriptNames(a, b) {
|
|
111
|
+
return nameCollator.compare(a, b);
|
|
112
|
+
}
|
|
113
|
+
// The `@name` a header declares, or '' when it declares none usable.
|
|
114
|
+
// Split out so the viewer's heading label and every other surface agree
|
|
115
|
+
// on what counts as a name — a future change to the rule (a localized
|
|
116
|
+
// `@name:en`, different trimming) must not land in only one of them.
|
|
117
|
+
export function headerDisplayName(header) {
|
|
118
|
+
return (header ? getValue(header, 'name')?.trim() : undefined) || '';
|
|
119
|
+
}
|
|
120
|
+
// The script's `@name`, or its location when it declares no usable one.
|
|
121
|
+
// The location is NOT appended to a name that exists — a heading
|
|
122
|
+
// carrying both runs the width of the window, and the details panel's
|
|
123
|
+
// `Location` row is where a reader goes for the full path.
|
|
124
|
+
//
|
|
125
|
+
// `headerDisplayName`, not a local read of `@name`: the viewer must not
|
|
126
|
+
// disagree with the collections page about what a script is called.
|
|
127
|
+
export function scriptLabel(header, location) {
|
|
128
|
+
return headerDisplayName(header) || displayLocation(location);
|
|
129
|
+
}
|
|
130
|
+
// Lives here rather than in collection-display.ts, its first caller: this
|
|
131
|
+
// module is a leaf, and page-heading.ts needs the helper on the early
|
|
132
|
+
// path where dragging in collection-display's scan/network graph would
|
|
133
|
+
// undo the point of loading early.
|
|
134
|
+
// Append a path / URL string to an element, inserting a `<wbr>` after
|
|
135
|
+
// each `/` so the browser prefers slash boundaries when wrapping a
|
|
136
|
+
// long value. Combined with `overflow-wrap: anywhere` on the element,
|
|
137
|
+
// the wrap order becomes: spaces first, then slashes, then anywhere
|
|
138
|
+
// inside a word only when nothing else fits. The slash itself stays
|
|
139
|
+
// attached to the preceding segment so it reads as `foo/` then a
|
|
140
|
+
// break, not a `/bar` continuation.
|
|
141
|
+
//
|
|
142
|
+
// Use this for any field that may render a long path or URL: the
|
|
143
|
+
// collections page display name, the viewer's Location row, the Match /
|
|
144
|
+
// Exclude pattern rows, etc.
|
|
145
|
+
export function appendWithSlashBreaks(el, text) {
|
|
146
|
+
const doc = el.ownerDocument;
|
|
147
|
+
const parts = text.split('/');
|
|
148
|
+
parts.forEach((part, i) => {
|
|
149
|
+
if (i > 0) {
|
|
150
|
+
el.appendChild(doc.createTextNode('/'));
|
|
151
|
+
el.appendChild(doc.createElement('wbr'));
|
|
152
|
+
}
|
|
153
|
+
if (part)
|
|
154
|
+
el.appendChild(doc.createTextNode(part));
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
// Format a byte count for the size column. Returns "12 KB", "950 B",
|
|
158
|
+
// "1.4 MB", etc. — short enough to fit comfortably alongside filename +
|
|
159
|
+
// status. Whole KB: a tenth of a KB is never the interesting part. The
|
|
160
|
+
// MB switch is on the ROUNDED KB, so 1023.6 KB reads "1.0 MB", not
|
|
161
|
+
// "1024 KB".
|
|
162
|
+
export function formatBytes(size) {
|
|
163
|
+
if (size < 1024)
|
|
164
|
+
return `${size} B`;
|
|
165
|
+
const kb = Math.round(size / 1024);
|
|
166
|
+
if (kb < 1024)
|
|
167
|
+
return `${kb} KB`;
|
|
168
|
+
return `${(size / (1024 * 1024)).toFixed(1)} MB`;
|
|
169
|
+
}
|
|
170
|
+
// Storage use against a quota, both in MB: `9.9 MB of 10 MB (99%)`.
|
|
171
|
+
// One unit on both sides, since `10,106 KB of 10 MB` reads as over the
|
|
172
|
+
// limit at a glance. Rounded DOWN, so a store that still has room never
|
|
173
|
+
// reads as `10.0 MB of 10 MB (100%)`.
|
|
174
|
+
export function formatStorageUsage(used, quota) {
|
|
175
|
+
const tenths = Math.floor((used / (1024 * 1024)) * 10) / 10;
|
|
176
|
+
const percent = Math.floor((used / quota) * 100);
|
|
177
|
+
return `${tenths.toFixed(1)} MB of ${formatQuota(quota)} (${percent}%)`;
|
|
178
|
+
}
|
|
179
|
+
// A storage quota: `10 MB` for a whole number of MB (Chrome's is), not
|
|
180
|
+
// `10.0 MB`.
|
|
181
|
+
export function formatQuota(bytes) {
|
|
182
|
+
const mb = bytes / (1024 * 1024);
|
|
183
|
+
return Number.isInteger(mb) ? `${mb} MB` : `${mb.toFixed(1)} MB`;
|
|
184
|
+
}
|
|
185
|
+
// Text shown in the "Size" cell. Size is independent of status:
|
|
186
|
+
// `invalid` rows that retain prior content still show its byte count,
|
|
187
|
+
// and a 0-byte file shows "0 B" (distinct from unknown). Only rows
|
|
188
|
+
// that have never successfully loaded — `size == null` — render as
|
|
189
|
+
// "—" to signal "unknown".
|
|
190
|
+
export function formatScriptSize(script) {
|
|
191
|
+
if (script.size == null)
|
|
192
|
+
return '—';
|
|
193
|
+
return formatBytes(script.size);
|
|
194
|
+
}
|
|
195
|
+
export const LOAD_STATES = ['ok', 'invalid', 'rejected', 'refresh-failed', 'outdated'];
|
|
196
|
+
export function isLoadState(value) {
|
|
197
|
+
return LOAD_STATES.includes(value);
|
|
198
|
+
}
|
|
199
|
+
// `outdated` and `rejected` come in as caller-computed flags rather
|
|
200
|
+
// than being derived here: neither lives on the script row (one is a
|
|
201
|
+
// version probe, the other is session state the injector writes), and
|
|
202
|
+
// the collections page's repaint path rebuilds status cells from DOM
|
|
203
|
+
// datasets with no script row in hand. Both callers read `outdated`
|
|
204
|
+
// from `scriptOutdatedProbe` below and `rejected` from the shared
|
|
205
|
+
// rejection map, so the two surfaces can't drift.
|
|
206
|
+
export function effectiveScriptStatus(script, maxLogLevel, outdated = false, rejected = false) {
|
|
207
|
+
if (script.status === 'invalid')
|
|
208
|
+
return 'invalid';
|
|
209
|
+
if (rejected)
|
|
210
|
+
return 'rejected';
|
|
211
|
+
if (script.refreshError)
|
|
212
|
+
return 'refresh-failed';
|
|
213
|
+
if (outdated)
|
|
214
|
+
return 'outdated';
|
|
215
|
+
if (maxLogLevel === 'error')
|
|
216
|
+
return 'error';
|
|
217
|
+
if (maxLogLevel === 'warning')
|
|
218
|
+
return 'warning';
|
|
219
|
+
return 'ok';
|
|
220
|
+
}
|
|
221
|
+
// The probe (if any) saying an upstream copy is ahead of the version we
|
|
222
|
+
// hold. Null whenever nothing is ahead, nothing was probed, or either
|
|
223
|
+
// side has no `@version` to compare.
|
|
224
|
+
export function scriptOutdatedProbe(script) {
|
|
225
|
+
const loadedVersion = script.header ? getValue(script.header, 'version') : undefined;
|
|
226
|
+
return outdatedProbe(loadedVersion, script.versionProbes);
|
|
227
|
+
}
|
|
228
|
+
// Text shown in the "Status" cell. REJECTED means the script is fine but Chrome refused to register it. REFRESH
|
|
229
|
+
// FAILED means the script still runs from its cached copy but the last
|
|
230
|
+
// update attempt failed. OUTDATED means a newer version exists at a URL
|
|
231
|
+
// we deliberately don't update from. WARNING / ERROR mean the script
|
|
232
|
+
// loaded fine but its Log carries entries at that level (see
|
|
233
|
+
// `effectiveScriptStatus`).
|
|
234
|
+
export function formatScriptStatusLabel(status) {
|
|
235
|
+
switch (status) {
|
|
236
|
+
case 'ok': return 'OK';
|
|
237
|
+
case 'invalid': return 'INVALID';
|
|
238
|
+
case 'rejected': return 'REJECTED';
|
|
239
|
+
case 'refresh-failed': return 'REFRESH FAILED';
|
|
240
|
+
case 'outdated': return 'OUTDATED';
|
|
241
|
+
case 'warning': return 'WARNING';
|
|
242
|
+
case 'error': return 'ERROR';
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
// The viewer URL for a stored script, optionally landing on its Log
|
|
246
|
+
// pane. Shared by every in-page surface that links to or navigates to
|
|
247
|
+
// a script, so none of them can drift on how the tab is addressed.
|
|
248
|
+
//
|
|
249
|
+
// Page-relative, not the absolute `chrome.runtime.getURL(...)` form:
|
|
250
|
+
// every extension page lives at the extension root, so the browser
|
|
251
|
+
// resolves it against the current page, and the long
|
|
252
|
+
// `chrome-extension://<id>/` prefix stays out of a table that can hold
|
|
253
|
+
// hundreds of rows with two links each. The service worker builds the
|
|
254
|
+
// absolute form instead (`viewerUrlForScript` in background.ts)
|
|
255
|
+
// because it has no page to be relative to.
|
|
256
|
+
export function viewerUrl(scriptId, tab) {
|
|
257
|
+
const params = new URLSearchParams({ script: scriptId });
|
|
258
|
+
// The viewer parses `#Log` via parseHash and lands on the Log pane.
|
|
259
|
+
return `userscript.html?${params.toString()}${tab === 'log' ? '#Log' : ''}`;
|
|
260
|
+
}
|
|
261
|
+
// The compare page for two copies of a script (src/extension/compare.ts). The
|
|
262
|
+
// right-hand side is the base: the copy on screen, or the download a
|
|
263
|
+
// preview is showing; `other` is the copy to hold up against it.
|
|
264
|
+
export function compareUrl(base, other) {
|
|
265
|
+
const params = new URLSearchParams('script' in base ? { script: base.script } : { preview: base.preview });
|
|
266
|
+
params.set('other', other);
|
|
267
|
+
return `compare.html?${params.toString()}`;
|
|
268
|
+
}
|
|
269
|
+
// The install-preview URL for a location the user typed or pasted.
|
|
270
|
+
// Page-relative for the same reason `viewerUrl` is; callers that need
|
|
271
|
+
// the absolute form wrap it in `chrome.runtime.getURL`.
|
|
272
|
+
export function previewUrl(location) {
|
|
273
|
+
return `userscript.html?preview=${encodeURIComponent(location)}`;
|
|
274
|
+
}
|
|
275
|
+
// What a script's Status cell should say. The label follows
|
|
276
|
+
// `effectiveScriptStatus`; the hover text follows whatever the cell is
|
|
277
|
+
// actually showing — Chrome's rejection reason, the refresh-failure
|
|
278
|
+
// reason, the newer version found upstream, or the load error.
|
|
279
|
+
//
|
|
280
|
+
// Shared by the viewer's own Status row and the "Other versions"
|
|
281
|
+
// panel's Status column, which would otherwise explain the same
|
|
282
|
+
// verdict two ways. The collections page keeps its own copy of this
|
|
283
|
+
// logic: its repaint path rebuilds status cells from DOM datasets with
|
|
284
|
+
// no script row in hand, which is exactly what this takes.
|
|
285
|
+
export function scriptStatusView(script, maxLogLevel, rejection) {
|
|
286
|
+
const outdated = scriptOutdatedProbe(script);
|
|
287
|
+
const status = effectiveScriptStatus(script, maxLogLevel, outdated !== null, rejection !== undefined);
|
|
288
|
+
return { status, label: formatScriptStatusLabel(status), title: statusTitle() };
|
|
289
|
+
function statusTitle() {
|
|
290
|
+
if (status === 'rejected' && rejection)
|
|
291
|
+
return rejection;
|
|
292
|
+
if (status === 'refresh-failed')
|
|
293
|
+
return script.refreshError;
|
|
294
|
+
if (status === 'outdated' && outdated) {
|
|
295
|
+
return `Version ${outdated.version} at ${probeLabel(outdated.kinds)}: ${outdated.url}`;
|
|
296
|
+
}
|
|
297
|
+
if (script.errorMessage)
|
|
298
|
+
return describeDiagnostic(script.errorMessage, script.errorLocation);
|
|
299
|
+
return undefined;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
// Drop a Subresource Integrity fragment from a `@require` / `@resource`
|
|
303
|
+
// reference, for DISPLAY only.
|
|
304
|
+
//
|
|
305
|
+
// Lives here rather than in `file-loader.ts` (which owns resolution and
|
|
306
|
+
// fetching) precisely because loading must never use it — it sits
|
|
307
|
+
// beside `displayLocation`, the other transform every human-facing URL
|
|
308
|
+
// goes through.
|
|
309
|
+
//
|
|
310
|
+
// Tampermonkey carries the expected hash in the URL fragment, as a
|
|
311
|
+
// comma-separated list of `<algo>=<hex>` or `<algo>-<base64>` parts:
|
|
312
|
+
//
|
|
313
|
+
// @require https://example.com/lib.js#sha256=e3b0c44298fc1c149…
|
|
314
|
+
// @require https://example.com/lib.js#md5=abc,sha256=def
|
|
315
|
+
//
|
|
316
|
+
// A 64-hex-digit tail is most of the width of a tooltip or a details
|
|
317
|
+
// row and tells the reader nothing they can act on, so every surface
|
|
318
|
+
// that shows a ref to a human strips it. Fetching, resolution, dedup,
|
|
319
|
+
// storage, and error messages all keep the verbatim form — an error
|
|
320
|
+
// should name what the author actually wrote.
|
|
321
|
+
//
|
|
322
|
+
// Only stripped when EVERY comma-separated part looks like a hash
|
|
323
|
+
// declaration. An ordinary fragment (`#section`) is content the author
|
|
324
|
+
// meant, so it survives; a malformed hash tail survives too, which is
|
|
325
|
+
// the right way round — a reader wondering why validation didn't happen
|
|
326
|
+
// needs to see what they typed.
|
|
327
|
+
//
|
|
328
|
+
// SourceMonkey does not yet validate these hashes; see TODO.md.
|
|
329
|
+
const SRI_PART_RE = /^(?:md5|sha1|sha256|sha384|sha512)[=-]\S+$/i;
|
|
330
|
+
export function stripSriFragment(urlOrRef) {
|
|
331
|
+
const hash = urlOrRef.indexOf('#');
|
|
332
|
+
if (hash < 0)
|
|
333
|
+
return urlOrRef;
|
|
334
|
+
const fragment = urlOrRef.slice(hash + 1);
|
|
335
|
+
if (!fragment)
|
|
336
|
+
return urlOrRef;
|
|
337
|
+
if (!fragment.split(',').every((part) => SRI_PART_RE.test(part)))
|
|
338
|
+
return urlOrRef;
|
|
339
|
+
return urlOrRef.slice(0, hash);
|
|
340
|
+
}
|
|
341
|
+
// A stored script's text as it was on disk, rebuilt from the stored
|
|
342
|
+
// split: what is above the header, the header, the body. The same
|
|
343
|
+
// string the injector splices into the registered code, so the viewer's
|
|
344
|
+
// main tab line N matches the file's line N AND the injected line N
|
|
345
|
+
// (modulo any @require sections that sit before the main script). The
|
|
346
|
+
// compare page diffs this too.
|
|
347
|
+
export function fullSource(script) {
|
|
348
|
+
return joinFullSource(script.leadingText ?? '', script.headerText ?? '', script.bodyText);
|
|
349
|
+
}
|
|
350
|
+
// Pull a display basename off a require's resolved URL. Falls back to
|
|
351
|
+
// the verbatim ref if URL parsing fails — won't happen for entries we
|
|
352
|
+
// stored (the resolver wouldn't have accepted the URL otherwise), but
|
|
353
|
+
// the fallback keeps a future shape change from breaking the tab UI.
|
|
354
|
+
// Not `scriptBasename`: that one falls back to the whole URL, and a
|
|
355
|
+
// require tab labeled with a full CDN URL would wreck the tab strip.
|
|
356
|
+
export function requireBasename(url, ref) {
|
|
357
|
+
let name;
|
|
358
|
+
try {
|
|
359
|
+
name = leafName(new URL(url).pathname);
|
|
360
|
+
}
|
|
361
|
+
catch {
|
|
362
|
+
return ref;
|
|
363
|
+
}
|
|
364
|
+
return name ? decodeForDisplay(name) : ref;
|
|
365
|
+
}
|
|
366
|
+
// The counts in words, per kind, since each is a different thing to go
|
|
367
|
+
// and check: `1 file modified, 2 new files`. Empty when nothing differs.
|
|
368
|
+
export function pendingSummary(counts) {
|
|
369
|
+
const files = (n) => `${n} ${n === 1 ? 'file' : 'files'}`;
|
|
370
|
+
const parts = [];
|
|
371
|
+
if (counts.manifest)
|
|
372
|
+
parts.push('the manifest changed');
|
|
373
|
+
if (counts.modified > 0)
|
|
374
|
+
parts.push(`${files(counts.modified)} modified`);
|
|
375
|
+
if (counts.deleted > 0)
|
|
376
|
+
parts.push(`${files(counts.deleted)} deleted`);
|
|
377
|
+
if (counts.added > 0)
|
|
378
|
+
parts.push(`${counts.added} new ${counts.added === 1 ? 'file' : 'files'}`);
|
|
379
|
+
if (parts.length === 0)
|
|
380
|
+
return '';
|
|
381
|
+
const text = parts.join(', ');
|
|
382
|
+
return `${text[0].toUpperCase()}${text.slice(1)}`;
|
|
383
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export declare const MAX_ICON_BYTES: number;
|
|
2
|
+
export declare function isIconContentType(contentType: string): boolean;
|
|
3
|
+
interface IconHeader {
|
|
4
|
+
tags: {
|
|
5
|
+
tag: string;
|
|
6
|
+
locale?: string;
|
|
7
|
+
value: string;
|
|
8
|
+
line?: number;
|
|
9
|
+
}[];
|
|
10
|
+
}
|
|
11
|
+
export declare function iconDeclFromHeader(header: IconHeader | null): {
|
|
12
|
+
ref: string;
|
|
13
|
+
line?: number;
|
|
14
|
+
} | null;
|
|
15
|
+
export declare function iconRefFromHeader(header: IconHeader | null): string | null;
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
// A script's own icon (`@icon` and its aliases): which header tag names
|
|
2
|
+
// it, and the rules an icon file has to meet to be shown. Shared by the
|
|
3
|
+
// pages that paint icons (`extension/site-icon.ts`) and the load-time
|
|
4
|
+
// check that warns about an icon that can't be shown
|
|
5
|
+
// (`checkScriptIcon` in `external-files.ts`), so both apply one rule.
|
|
6
|
+
// Tag priority for a script-declared icon. `@icon` is the only form
|
|
7
|
+
// documented by all three managers (TM/VM/GM, i.e. Tampermonkey,
|
|
8
|
+
// Violentmonkey, Greasemonkey); the rest are TM-only aliases. The
|
|
9
|
+
// smaller variants come first so a script that declares both a regular
|
|
10
|
+
// and a 64×64 icon picks the one closer to our 16×16 display size.
|
|
11
|
+
const ICON_HEADER_TAGS = ['icon', 'iconurl', 'defaulticon', 'icon64url', 'icon64'];
|
|
12
|
+
// Largest icon file we will show. An icon is drawn at 16px, so anything
|
|
13
|
+
// near this is far bigger than it needs to be.
|
|
14
|
+
export const MAX_ICON_BYTES = 128 * 1024;
|
|
15
|
+
// Whether a response's Content-Type is one an icon can have.
|
|
16
|
+
export function isIconContentType(contentType) {
|
|
17
|
+
return contentType.startsWith('image/');
|
|
18
|
+
}
|
|
19
|
+
// The icon declaration that wins: its reference, raw (just trimmed and
|
|
20
|
+
// non-empty), and the header line it is on. Null when none is set.
|
|
21
|
+
export function iconDeclFromHeader(header) {
|
|
22
|
+
if (!header)
|
|
23
|
+
return null;
|
|
24
|
+
for (const tag of ICON_HEADER_TAGS) {
|
|
25
|
+
for (const e of header.tags) {
|
|
26
|
+
if (e.tag !== tag || e.locale !== undefined)
|
|
27
|
+
continue;
|
|
28
|
+
const trimmed = e.value.trim();
|
|
29
|
+
if (trimmed)
|
|
30
|
+
return e.line === undefined ? { ref: trimmed } : { ref: trimmed, line: e.line };
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
// Read the highest-priority icon reference declared in the parsed
|
|
36
|
+
// metadata, or null when none is set. The reference comes back raw
|
|
37
|
+
// (just trimmed + non-empty); resolving it into an absolute URL —
|
|
38
|
+
// including the relative-path-against-script-parent rules and `..`
|
|
39
|
+
// rejection — is the file-loader's job and happens at render time
|
|
40
|
+
// when the script's `fileUrl` is in scope.
|
|
41
|
+
export function iconRefFromHeader(header) {
|
|
42
|
+
return iconDeclFromHeader(header)?.ref ?? null;
|
|
43
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export declare const RESOLVABLE_HEADER_TAGS: ReadonlySet<string>;
|
|
2
|
+
export declare const MATCH_HEADER_TAGS: ReadonlySet<string>;
|
|
3
|
+
export interface TextRun {
|
|
4
|
+
kind: 'text' | 'url';
|
|
5
|
+
value: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function splitTextByUrls(text: string): TextRun[];
|
|
8
|
+
export interface ParsedTagLine {
|
|
9
|
+
before: string;
|
|
10
|
+
tag: string;
|
|
11
|
+
locale?: string;
|
|
12
|
+
value: string;
|
|
13
|
+
after: string;
|
|
14
|
+
}
|
|
15
|
+
export declare function parseTagLine(line: string): ParsedTagLine | null;
|
|
16
|
+
export interface ResourceValueParts {
|
|
17
|
+
prefix: string;
|
|
18
|
+
url: string;
|
|
19
|
+
suffix: string;
|
|
20
|
+
}
|
|
21
|
+
export declare function splitResourceValue(value: string): ResourceValueParts | null;
|
|
22
|
+
export declare function connectLinkUrl(raw: string): string | null;
|
|
23
|
+
export declare function isHeaderOpenLine(line: string): boolean;
|
|
24
|
+
export declare function isHeaderCloseLine(line: string): boolean;
|