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,358 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8" />
|
|
5
|
+
<title>SourceMonkey | Compare</title>
|
|
6
|
+
<link rel="stylesheet" href="styles.css" />
|
|
7
|
+
<style>
|
|
8
|
+
html { height: 100%; margin: 0; }
|
|
9
|
+
body {
|
|
10
|
+
min-height: 100%;
|
|
11
|
+
margin: 0;
|
|
12
|
+
font: 14px system-ui, sans-serif;
|
|
13
|
+
color: #222;
|
|
14
|
+
display: flex;
|
|
15
|
+
flex-direction: column;
|
|
16
|
+
box-sizing: border-box;
|
|
17
|
+
}
|
|
18
|
+
/* Same full-bleed column as the viewer: the header bar and the
|
|
19
|
+
page share a 16px inset and nothing else constrains the width —
|
|
20
|
+
two files side by side want all of it. */
|
|
21
|
+
.page-main {
|
|
22
|
+
flex: 1 1 auto;
|
|
23
|
+
min-height: 0;
|
|
24
|
+
display: flex;
|
|
25
|
+
flex-direction: column;
|
|
26
|
+
padding: 16px;
|
|
27
|
+
box-sizing: border-box;
|
|
28
|
+
}
|
|
29
|
+
h1 { overflow-wrap: anywhere; word-break: normal; }
|
|
30
|
+
.message { margin: 0 0 11px; }
|
|
31
|
+
.message:empty { display: none; }
|
|
32
|
+
.message.error { color: #b00020; }
|
|
33
|
+
|
|
34
|
+
/* ---- The fields table: Field | one side | swap | other side ---- */
|
|
35
|
+
/* The viewer's details card, with a third column. */
|
|
36
|
+
#fields {
|
|
37
|
+
margin: 0 0 11px;
|
|
38
|
+
padding: 8px 11px;
|
|
39
|
+
border: 1px solid #ddd;
|
|
40
|
+
border-radius: 4px;
|
|
41
|
+
background: #f5f7fa;
|
|
42
|
+
}
|
|
43
|
+
#fields:empty { display: none; }
|
|
44
|
+
table.fields { border-collapse: collapse; width: 100%; }
|
|
45
|
+
table.fields th,
|
|
46
|
+
table.fields td {
|
|
47
|
+
text-align: left;
|
|
48
|
+
vertical-align: top;
|
|
49
|
+
padding: 0.15em 0.8em 0.15em 0;
|
|
50
|
+
}
|
|
51
|
+
table.fields th { font-weight: 600; color: #555; white-space: nowrap; }
|
|
52
|
+
/* The head is the two rows that tell the copies apart — the
|
|
53
|
+
collection, in the heading's weight, and the location under it
|
|
54
|
+
— ruled off from the fields below. */
|
|
55
|
+
table.fields thead tr.side-collection td { font-weight: 600; }
|
|
56
|
+
table.fields thead tr.side-location td { font-size: 12.5px; color: #555; }
|
|
57
|
+
/* When the two differ these rows take only the background tint:
|
|
58
|
+
the collection name and the path stay in their own colours,
|
|
59
|
+
readable beside the bubble, which keeps its own too. */
|
|
60
|
+
table.fields thead tr.side-collection.differs td.value { color: #222; }
|
|
61
|
+
table.fields thead tr.side-location.differs td.value { color: #555; }
|
|
62
|
+
table.fields thead tr.side-location th,
|
|
63
|
+
table.fields thead tr.side-location td { padding-bottom: 6px; border-bottom: 1px solid #d5dae2; }
|
|
64
|
+
table.fields tbody tr:first-child th,
|
|
65
|
+
table.fields tbody tr:first-child td { padding-top: 6px; }
|
|
66
|
+
/* The "not installed" side of a preview comparison. */
|
|
67
|
+
.side-preview { font-style: italic; color: #555; }
|
|
68
|
+
/* Both value columns take the same share; the swap column is as
|
|
69
|
+
narrow as its button. */
|
|
70
|
+
table.fields td.value { width: 45%; overflow-wrap: anywhere; word-break: normal; }
|
|
71
|
+
table.fields .swap-col { width: 1px; padding: 0 0.5em; text-align: center; vertical-align: middle; }
|
|
72
|
+
/* A row whose two values differ wears the diff's own colours, so
|
|
73
|
+
the table reads as the diff of the header. */
|
|
74
|
+
tr.differs td.value.left { background: var(--diff-del-bg); color: var(--diff-del-fg); }
|
|
75
|
+
tr.differs td.value.right { background: var(--diff-add-bg); color: var(--diff-add-fg); }
|
|
76
|
+
/* A list value: one item per line, and an item the other side
|
|
77
|
+
lacks is what carries the row's tint. */
|
|
78
|
+
table.fields ul { margin: 0; padding-left: 1.1em; }
|
|
79
|
+
tr.differs td.value.left li.only { background: #f7c4c4; }
|
|
80
|
+
tr.differs td.value.right li.only { background: #bfe8c9; }
|
|
81
|
+
/* A field one side declares and the other does not. */
|
|
82
|
+
.none { color: #999; }
|
|
83
|
+
/* The collection's bubble and name, as the viewer's Collection
|
|
84
|
+
row draws them (`collectionCell`, script-details.ts). */
|
|
85
|
+
.collection-cell { display: inline-flex; align-items: baseline; gap: 0.5em; min-width: 0; }
|
|
86
|
+
/* Not the type bubble: it is a link too, and keeps its own white
|
|
87
|
+
text on its own colour, tinted row or not. */
|
|
88
|
+
.collection-cell a:not(.collection-type-bubble),
|
|
89
|
+
tr.side-location a { color: inherit; text-decoration: none; }
|
|
90
|
+
.collection-cell a:not(.collection-type-bubble):hover,
|
|
91
|
+
tr.side-location a:hover { text-decoration: underline; }
|
|
92
|
+
|
|
93
|
+
/* ---- View controls, right-aligned on their own row above the tabs ---- */
|
|
94
|
+
.view-row {
|
|
95
|
+
display: flex;
|
|
96
|
+
justify-content: flex-end;
|
|
97
|
+
align-items: center;
|
|
98
|
+
gap: 0.8em;
|
|
99
|
+
margin: 0 0 6px;
|
|
100
|
+
font-size: 12.5px;
|
|
101
|
+
color: #555;
|
|
102
|
+
}
|
|
103
|
+
.view-row:empty { display: none; }
|
|
104
|
+
/* A segmented control: the shared button surface (styles.css),
|
|
105
|
+
the segments joined edge to edge, and the chosen one held
|
|
106
|
+
down — pressed darker, sunk with an inset shadow — so which
|
|
107
|
+
state is in force reads as the button that stays pushed. */
|
|
108
|
+
.seg { display: inline-flex; }
|
|
109
|
+
.seg button {
|
|
110
|
+
font-size: 12.5px;
|
|
111
|
+
padding: 0 10px;
|
|
112
|
+
border-radius: 0;
|
|
113
|
+
}
|
|
114
|
+
.seg button:first-child { border-radius: 3px 0 0 3px; }
|
|
115
|
+
.seg button:last-child { border-radius: 0 3px 3px 0; }
|
|
116
|
+
.seg button + button { margin-left: -1px; }
|
|
117
|
+
.seg button.on {
|
|
118
|
+
background: var(--btn-bg-active);
|
|
119
|
+
border-color: #999;
|
|
120
|
+
box-shadow: inset 0 2px 3px rgba(0, 0, 0, 0.2);
|
|
121
|
+
font-weight: 600;
|
|
122
|
+
/* The pressed one stays on top so its darker border shows on
|
|
123
|
+
both sides where the segments overlap. */
|
|
124
|
+
position: relative;
|
|
125
|
+
z-index: 1;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/* ---- Tabs: one per file, each with its verdict chip ---- */
|
|
129
|
+
/* The strip itself is shared with the viewer (styles.css). */
|
|
130
|
+
.tab .chip {
|
|
131
|
+
margin-left: 0.6em;
|
|
132
|
+
padding: 0 0.4em;
|
|
133
|
+
border-radius: 3px;
|
|
134
|
+
font-family: system-ui, sans-serif;
|
|
135
|
+
font-size: 10px;
|
|
136
|
+
font-weight: 600;
|
|
137
|
+
letter-spacing: 0.04em;
|
|
138
|
+
text-transform: uppercase;
|
|
139
|
+
color: #fff;
|
|
140
|
+
vertical-align: 1px;
|
|
141
|
+
}
|
|
142
|
+
/* The versions panel's SAME green and DIFFERENT blue; amber for a
|
|
143
|
+
file only one side has, the colour of "not the same thing"
|
|
144
|
+
elsewhere on these pages. */
|
|
145
|
+
.chip-same { background: #166534; }
|
|
146
|
+
.chip-different { background: var(--chip-different); }
|
|
147
|
+
.chip-added, .chip-removed { background: #b67200; }
|
|
148
|
+
|
|
149
|
+
/* ---- The diff box ---- */
|
|
150
|
+
:root {
|
|
151
|
+
--chip-different: #1d4ed8;
|
|
152
|
+
--diff-del-bg: #fde8e8;
|
|
153
|
+
--diff-del-fg: #8a1c1c;
|
|
154
|
+
--diff-add-bg: #e3f6e8;
|
|
155
|
+
--diff-add-fg: #14532d;
|
|
156
|
+
}
|
|
157
|
+
/* The box fills what is left of the window and the lines scroll
|
|
158
|
+
inside it, as the viewer's code box does: that puts the scroll
|
|
159
|
+
bars at the window's edge, where they can be reached, rather
|
|
160
|
+
than under a page's worth of code. Basis 0 so its content never
|
|
161
|
+
sizes the page; the floor below keeps a useful number of lines
|
|
162
|
+
in view under a tall fields table, letting the PAGE scroll then
|
|
163
|
+
— the one case this page accepts a page-level scroll bar.
|
|
164
|
+
20 lines at this box's line height, plus the summary strip and
|
|
165
|
+
the border. Meets the active tab the way the viewer's box does. */
|
|
166
|
+
.page-main { --code-box-min: calc(20 * 1.5 * 13px + 30px + 2px); }
|
|
167
|
+
.diff-box {
|
|
168
|
+
flex: 1 1 0;
|
|
169
|
+
min-height: var(--code-box-min);
|
|
170
|
+
display: flex;
|
|
171
|
+
flex-direction: column;
|
|
172
|
+
box-sizing: border-box;
|
|
173
|
+
margin-top: -1px;
|
|
174
|
+
border: 1px solid #ccc;
|
|
175
|
+
border-radius: 0 4px 4px 4px;
|
|
176
|
+
background: #fafafa;
|
|
177
|
+
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
|
|
178
|
+
font-size: 13px;
|
|
179
|
+
line-height: 1.5;
|
|
180
|
+
overflow: hidden;
|
|
181
|
+
}
|
|
182
|
+
.diff-box[hidden] { display: none; }
|
|
183
|
+
.diff-body { flex: 1 1 auto; min-height: 0; overflow: auto; }
|
|
184
|
+
.diff-body:focus, .diff-body .pane:focus { outline: 2px solid #4a90e2; outline-offset: -2px; }
|
|
185
|
+
/* Side by side: two panes, each its own scroller, split down the
|
|
186
|
+
middle so both are always in view. */
|
|
187
|
+
.diff-body.split { display: flex; overflow: hidden; }
|
|
188
|
+
/* Sideways scroll bars always, in both: one pane with a bar and
|
|
189
|
+
one without would have different heights to scroll, and the
|
|
190
|
+
linked scroll would hit the end in one before the other. */
|
|
191
|
+
.diff-body.split .pane { flex: 1 1 50%; min-width: 0; overflow: auto; overflow-x: scroll; }
|
|
192
|
+
.diff-body.split .pane.right { border-left: 1px solid #ccc; }
|
|
193
|
+
/* The one line of summary: the counts, right-aligned, then the
|
|
194
|
+
Up/Down arrows that jump between change blocks. The arrows are
|
|
195
|
+
icon buttons shrunk to the strip's line (the two custom
|
|
196
|
+
properties, styles.css), and the strip is held at their
|
|
197
|
+
height whether or not it has them (`No differences` has
|
|
198
|
+
none), so the lines do not shift between tabs. That height
|
|
199
|
+
is within the 30px the box's floor (`--code-box-min`, above)
|
|
200
|
+
reserves for the strip. */
|
|
201
|
+
.diff-summary {
|
|
202
|
+
--icon-btn-size: 20px;
|
|
203
|
+
--icon-btn-glyph: 14px;
|
|
204
|
+
min-height: 20px;
|
|
205
|
+
flex: 0 0 auto;
|
|
206
|
+
display: flex;
|
|
207
|
+
justify-content: flex-end;
|
|
208
|
+
align-items: center;
|
|
209
|
+
gap: 0.4em;
|
|
210
|
+
padding: 4px 12px;
|
|
211
|
+
border-bottom: 1px solid #e3e3e3;
|
|
212
|
+
background: #f3f4f6;
|
|
213
|
+
font-family: system-ui, sans-serif;
|
|
214
|
+
font-size: 12.5px;
|
|
215
|
+
color: #555;
|
|
216
|
+
}
|
|
217
|
+
.diff-summary .diff-counts { margin-right: 0.6em; }
|
|
218
|
+
.diff-summary .removed { color: var(--diff-del-fg); font-weight: 600; }
|
|
219
|
+
.diff-summary .added { color: var(--diff-add-fg); font-weight: 600; }
|
|
220
|
+
table.diff { border-collapse: collapse; width: 100%; }
|
|
221
|
+
table.diff td { padding: 0 8px; white-space: pre; vertical-align: top; }
|
|
222
|
+
/* Line-number gutters: fixed, dim, not selectable, so copying a
|
|
223
|
+
run of lines copies the code. */
|
|
224
|
+
table.diff td.num {
|
|
225
|
+
width: 3ch;
|
|
226
|
+
min-width: 3ch;
|
|
227
|
+
text-align: right;
|
|
228
|
+
color: #999;
|
|
229
|
+
user-select: none;
|
|
230
|
+
padding-right: 4px;
|
|
231
|
+
border-right: 1px solid #e5e5e5;
|
|
232
|
+
}
|
|
233
|
+
table.diff td.sign { width: 1ch; color: #888; user-select: none; text-align: center; padding: 0 2px; }
|
|
234
|
+
table.diff tr.del td { background: var(--diff-del-bg); }
|
|
235
|
+
table.diff tr.del td.code { color: var(--diff-del-fg); }
|
|
236
|
+
table.diff tr.add td { background: var(--diff-add-bg); }
|
|
237
|
+
table.diff tr.add td.code { color: var(--diff-add-fg); }
|
|
238
|
+
table.diff tr.del td.num, table.diff tr.add td.num { color: inherit; opacity: 0.6; }
|
|
239
|
+
/* The block the arrows last jumped to: its line numbers in the
|
|
240
|
+
DIFFERENT chip's blue, with a bar down the gutter's edge, on
|
|
241
|
+
each of its rows (the blanks across from it too, side by
|
|
242
|
+
side). In the gutter and not on the lines, so the change's
|
|
243
|
+
own colours are what the block shows. An inset shadow rather
|
|
244
|
+
than a border: nothing moves. Same specificity as the del/add
|
|
245
|
+
gutter rule above, so this one has to come after it. */
|
|
246
|
+
table.diff tr.current td.num {
|
|
247
|
+
color: var(--chip-different);
|
|
248
|
+
opacity: 1;
|
|
249
|
+
font-weight: 600;
|
|
250
|
+
box-shadow: inset 3px 0 0 var(--chip-different);
|
|
251
|
+
}
|
|
252
|
+
/* `@@ -a,n +b,m @@`: the seam between two hunks. */
|
|
253
|
+
table.diff tr.hunk td { background: #eef2f7; color: #4b5563; font-size: 12px; padding: 2px 8px; }
|
|
254
|
+
/* A pane's blank across from a line only the other side has. Its
|
|
255
|
+
cells are all empty, and a row of empty cells has no height —
|
|
256
|
+
which would put the two panes' rows out of step by exactly the
|
|
257
|
+
lines one side lacks. The no-break space gives it a line. */
|
|
258
|
+
table.diff tr.filler td { background: #f3f3f3; }
|
|
259
|
+
table.diff tr.filler td.code::after { content: "\00a0"; }
|
|
260
|
+
</style>
|
|
261
|
+
</head>
|
|
262
|
+
<body>
|
|
263
|
+
<!-- Shared glyph sprite: the one copy of every inline SVG glyph in the
|
|
264
|
+
extension. scripts/build.mjs inlines it into each page wherever the
|
|
265
|
+
page writes an `#include glyph-sprite` marker comment. (Spelling
|
|
266
|
+
that marker out here would be nice, but its own closing `--` plus
|
|
267
|
+
`>` would end THIS comment and spill the rest onto the page.)
|
|
268
|
+
|
|
269
|
+
One source of truth: the markup used to be copy-pasted into each
|
|
270
|
+
page's HTML, which is how two pages end up with glyphs that have
|
|
271
|
+
quietly drifted apart.
|
|
272
|
+
|
|
273
|
+
Each symbol is defined once per page and referenced by a `use`
|
|
274
|
+
element, so a hundred rows share one copy of the path data instead
|
|
275
|
+
of inlining it per row.
|
|
276
|
+
|
|
277
|
+
#sm-globe favicon placeholder until a site icon loads, and
|
|
278
|
+
the permanent icon for a script with no resolvable
|
|
279
|
+
origin (src/extension/site-icon.ts; styling on
|
|
280
|
+
`.site-icon-globe`).
|
|
281
|
+
#sm-trash remove SourceMonkey's record of a script.
|
|
282
|
+
#sm-trash-file delete the script FILE from disk — the same can,
|
|
283
|
+
badged with a disk. Both painted by
|
|
284
|
+
src/extension/delete-icon.ts, which explains the pair.
|
|
285
|
+
The can is drawn ~19% smaller than #sm-trash — its
|
|
286
|
+
own inner scale(.9) inside the normalizing
|
|
287
|
+
wrapper's scale(.9) — so the badge has a corner to
|
|
288
|
+
sit in without swallowing the can. Deliberate: the two appear in the same
|
|
289
|
+
column in the "Other versions" panel, and the
|
|
290
|
+
badged one has to stay a can at 15px.
|
|
291
|
+
#sm-copy the viewer's "copy this to the clipboard" button,
|
|
292
|
+
#sm-check and the checkmark it flashes on success
|
|
293
|
+
(src/extension/copy-button.ts).
|
|
294
|
+
#sm-refresh refetch a collection, a script, or one row of the
|
|
295
|
+
"Other versions" table. Its busy state is this
|
|
296
|
+
same arc spinning (`.btn-glyph.spinning`), so the
|
|
297
|
+
button never changes shape mid-refresh.
|
|
298
|
+
#sm-gear open a collection's rename / options dialog.
|
|
299
|
+
#sm-open open a location in a new tab (the collection
|
|
300
|
+
dialog's button beside its location box).
|
|
301
|
+
#sm-swap the compare page's "swap the two sides" button:
|
|
302
|
+
two arrows, one each way, the same width so their
|
|
303
|
+
ends line up.
|
|
304
|
+
|
|
305
|
+
Colour comes from `currentColor`, so a button's own `color` (and
|
|
306
|
+
its hover) drives the glyph.
|
|
307
|
+
|
|
308
|
+
OPTICAL SIZING — read before editing a path or a stroke width.
|
|
309
|
+
Identical 16px boxes do not make icons look the same size; the ink
|
|
310
|
+
inside them has to match too. As drawn, these ranged from 18 to
|
|
311
|
+
23.3 units of 24, and the gear read ~22% larger than the arrow. So
|
|
312
|
+
a glyph that needed resizing is wrapped in
|
|
313
|
+
<g transform="translate(12 12) scale(k) translate(-12 -12)">
|
|
314
|
+
and its `stroke-width` is DIVIDED by the same k. Consequences:
|
|
315
|
+
- The number in the file is not the number that renders. Every
|
|
316
|
+
glyph here strokes at 1.75 units once its wrapper is applied
|
|
317
|
+
(1.9/... , 1.95/.9, 1.667*1.05, 1.825*.959). Change a stroke
|
|
318
|
+
width and you break that unless you change k with it.
|
|
319
|
+
- #sm-refresh translates by -13, not -12: Feather's rotate-cw is
|
|
320
|
+
drawn a unit right of centre, and this puts it back. It is not
|
|
321
|
+
a typo.
|
|
322
|
+
- #sm-copy and #sm-check are deliberately outside this: they
|
|
323
|
+
stroke at 2.0 in the 14px copy button. That button sits beside
|
|
324
|
+
the 1.75 set only in the collection dialog, next to #sm-open,
|
|
325
|
+
where the smaller box evens out the heavier stroke. -->
|
|
326
|
+
<svg width="0" height="0" style="position:absolute" aria-hidden="true">
|
|
327
|
+
<symbol id="sm-globe" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"></circle><path d="M2 12h20"></path><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"></path></symbol>
|
|
328
|
+
<symbol id="sm-trash" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><path d="M3.5 6h17"></path><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6"></path><path d="M9 6V4a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2v2"></path><path d="M10 10.5v7"></path><path d="M14 10.5v7"></path></symbol>
|
|
329
|
+
<symbol id="sm-trash-file" viewBox="0 0 24 24"><g transform="translate(12 12) scale(.9) translate(-12 -12)"><mask id="sm-trash-file-cut" maskUnits="userSpaceOnUse" x="0" y="0" width="24" height="24"><rect width="24" height="24" fill="#fff"></rect><circle cx="19.6" cy="19.6" r="5.2" fill="#000"></circle></mask><g mask="url(#sm-trash-file-cut)" transform="translate(-.7 -1.5) scale(.9)" fill="none" stroke="currentColor" stroke-width="2.167" stroke-linecap="round" stroke-linejoin="round"><path d="M3.5 6h17"></path><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6"></path><path d="M9 6V4a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2v2"></path><path d="M10 10.5v7"></path><path d="M14 10.5v7"></path></g><g transform="translate(14.53 14.36) scale(.422)" fill="none" stroke="currentColor" stroke-width="4.611" stroke-linecap="round" stroke-linejoin="round"><ellipse cx="12" cy="5" rx="9" ry="3"></ellipse><path d="M3 5v14c0 1.66 4.03 3 9 3s9-1.34 9-3V5"></path></g></g></symbol>
|
|
330
|
+
<symbol id="sm-copy" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></symbol>
|
|
331
|
+
<symbol id="sm-check" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"></polyline></symbol>
|
|
332
|
+
<symbol id="sm-refresh" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.667" stroke-linecap="round" stroke-linejoin="round"><g transform="translate(12 12) scale(1.05) translate(-13 -12)"><path d="M20.49 15a9 9 0 1 1-2.12-9.36L23 10"></path><polyline points="23 4 23 10 17 10"></polyline></g></symbol>
|
|
333
|
+
<symbol id="sm-swap" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><path d="M3 7.5h18"></path><path d="M16.5 3l4.5 4.5-4.5 4.5"></path><path d="M21 16.5H3"></path><path d="M7.5 12L3 16.5 7.5 21"></path></symbol>
|
|
334
|
+
<symbol id="sm-gear" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.825" stroke-linecap="round" stroke-linejoin="round"><g transform="translate(12 12) scale(.959) translate(-12 -12)"><circle cx="12" cy="12" r="3.1"></circle><path d="M19.4 14.6a1.6 1.6 0 0 0 .32 1.77l.06.06a1.95 1.95 0 1 1-2.76 2.76l-.06-.06a1.6 1.6 0 0 0-1.77-.32 1.6 1.6 0 0 0-.97 1.47V21a1.95 1.95 0 1 1-3.9 0v-.1a1.6 1.6 0 0 0-1.05-1.47 1.6 1.6 0 0 0-1.77.32l-.06.06a1.95 1.95 0 1 1-2.76-2.76l.06-.06a1.6 1.6 0 0 0 .32-1.77 1.6 1.6 0 0 0-1.47-.97H3a1.95 1.95 0 1 1 0-3.9h.1a1.6 1.6 0 0 0 1.47-1.05 1.6 1.6 0 0 0-.32-1.77l-.06-.06a1.95 1.95 0 1 1 2.76-2.76l.06.06a1.6 1.6 0 0 0 1.77.32H9a1.6 1.6 0 0 0 .97-1.47V3a1.95 1.95 0 1 1 3.9 0v.1a1.6 1.6 0 0 0 .97 1.47 1.6 1.6 0 0 0 1.77-.32l.06-.06a1.95 1.95 0 1 1 2.76 2.76l-.06.06a1.6 1.6 0 0 0-.32 1.77V9a1.6 1.6 0 0 0 1.47.97H21a1.95 1.95 0 1 1 0 3.9h-.1a1.6 1.6 0 0 0-1.47.97z"></path></g></symbol>
|
|
335
|
+
<symbol id="sm-open" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"></path><polyline points="15 3 21 3 21 9"></polyline><path d="M10 14L21 3"></path></symbol>
|
|
336
|
+
</svg>
|
|
337
|
+
<header class="page-header">
|
|
338
|
+
<div class="page-header-inner">
|
|
339
|
+
<a class="page-home page-icon-link" href="collections.html" target="_blank"
|
|
340
|
+
rel="noopener" tabindex="-1" aria-hidden="true">
|
|
341
|
+
<img class="page-icon" src="icons/icon-48.png" alt="" />
|
|
342
|
+
</a>
|
|
343
|
+
<!-- The same brand run the viewer ships in its markup, so the bar
|
|
344
|
+
reads "SourceMonkey | Compare |" from the first paint. -->
|
|
345
|
+
<h1 id="heading"><a class="heading-prefix brand page-home" href="collections.html"
|
|
346
|
+
target="_blank" rel="noopener" title="Open the collections page">SourceMonkey</a><span class="heading-prefix brand"> | </span><span class="heading-prefix">Compare</span><span class="heading-prefix brand"> | </span></h1>
|
|
347
|
+
</div>
|
|
348
|
+
</header>
|
|
349
|
+
<div class="page-main">
|
|
350
|
+
<p id="message" class="message"></p>
|
|
351
|
+
<div id="fields"></div>
|
|
352
|
+
<div id="view-row" class="view-row"></div>
|
|
353
|
+
<div id="tabs" class="tabs" role="tablist" hidden></div>
|
|
354
|
+
<div id="diff" class="diff-box" hidden></div>
|
|
355
|
+
</div>
|
|
356
|
+
<script src="extension/compare.js" type="module"></script>
|
|
357
|
+
</body>
|
|
358
|
+
</html>
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
// ---------- Concatenated user source (requires + body) ----------
|
|
2
|
+
//
|
|
3
|
+
// Every prefetched `@require` body, in declaration order, in front of
|
|
4
|
+
// the **full on-disk script source** (leadingText + headerText +
|
|
5
|
+
// bodyText). This is the single arrangement every run path uses:
|
|
6
|
+
//
|
|
7
|
+
// - the default registration (`wrapCombinedEntry` → one js[] entry);
|
|
8
|
+
// - the reload-fast-path swap eval (`buildSwapEvalBody`), where
|
|
9
|
+
// `handleCheckPending` in background.ts sends the same text as the
|
|
10
|
+
// run-new body.
|
|
11
|
+
//
|
|
12
|
+
// Concatenation IS the feature, not an implementation detail: one
|
|
13
|
+
// script means one lexical scope, so a library's top-level
|
|
14
|
+
// `const`/`let`/`class` is simply visible to the main body — the same
|
|
15
|
+
// thing TM/VM get by concatenating into one IIFE. See
|
|
16
|
+
// docs/injection-modes.md for what the separate-entries arrangement
|
|
17
|
+
// cost us instead.
|
|
18
|
+
//
|
|
19
|
+
// A `;\n` separator between segments guards the seam against ASI
|
|
20
|
+
// (Automatic Semicolon Insertion). ASI won't fire when the next line
|
|
21
|
+
// could continue the previous statement, so a library ending in an
|
|
22
|
+
// expression followed by a body opening with `(`, `[`, `` ` ``, `+`,
|
|
23
|
+
// `-` or `/` would parse as a single statement. Each file was fine on
|
|
24
|
+
// its own; concatenation is what creates the hazard.
|
|
25
|
+
//
|
|
26
|
+
// The leading `// @require <url>` per require makes the concatenated
|
|
27
|
+
// code easier to scan when no source map is applied. Line comment (not
|
|
28
|
+
// block) so URLs with `*/` in their path don't prematurely close it.
|
|
29
|
+
//
|
|
30
|
+
// ---------- Why this lives in its own module ----------
|
|
31
|
+
//
|
|
32
|
+
// Several callers need to agree on the layout, and they live in
|
|
33
|
+
// different extension contexts:
|
|
34
|
+
//
|
|
35
|
+
// - `src/extension/injector.ts` (service worker) emits the registered entry
|
|
36
|
+
// and its source map.
|
|
37
|
+
// - `background.ts`'s swap path emits the same text for `(0,eval)`.
|
|
38
|
+
// - `src/extension/userscript.ts` (the viewer page) re-derives the SAME
|
|
39
|
+
// segment list to map `Error.stack` line numbers in the Log tab
|
|
40
|
+
// back to the original file — V8 leaves `err.stack` in generated
|
|
41
|
+
// coordinates even when it has the map. See docs/script-log.md.
|
|
42
|
+
//
|
|
43
|
+
// The viewer recomputes rather than reading a persisted map because
|
|
44
|
+
// the inputs are already on the `StoredScript` row it has loaded, and
|
|
45
|
+
// a persisted copy would be one more thing to invalidate. Sharing this
|
|
46
|
+
// one function is what keeps "where line N came from" a single answer
|
|
47
|
+
// instead of two that can drift.
|
|
48
|
+
import { joinFullSource } from './userscript-header.js';
|
|
49
|
+
import { buildRequireSourceUrl, buildSourceUrl } from './script-source-url.js';
|
|
50
|
+
// ---------- The two layouts, and why the viewer can tell them apart ----------
|
|
51
|
+
//
|
|
52
|
+
// **With `@require`s.** The preamble (GM bindings, prelude, wrap head)
|
|
53
|
+
// occupies generated line 0 on its own and the concatenated user
|
|
54
|
+
// source starts at `USER_SOURCE_START_LINE`. Line numbers shift, so
|
|
55
|
+
// the entry carries a source map and the viewer remaps stack refs
|
|
56
|
+
// through the segment list.
|
|
57
|
+
//
|
|
58
|
+
// **Without `@require`s.** Nothing is concatenated, so nothing may
|
|
59
|
+
// shift: the body's first line SHARES generated line 0 with the
|
|
60
|
+
// preamble, making generated line N equal original line N. No map is
|
|
61
|
+
// emitted and the viewer passes refs through untouched.
|
|
62
|
+
//
|
|
63
|
+
// The viewer distinguishes the two by whether there are segments at
|
|
64
|
+
// all — `composeSource` returns none for a script without requires —
|
|
65
|
+
// so it never has to know which run path produced the code. That only
|
|
66
|
+
// holds while `wrapCombinedEntry` and `buildSwapEvalBody` agree on
|
|
67
|
+
// BOTH layouts. They are the only two producers; keep them in step.
|
|
68
|
+
//
|
|
69
|
+
// The no-require layout costs one thing, deliberately: the body's
|
|
70
|
+
// first line shares a physical line with the preamble, so a frame
|
|
71
|
+
// reported at line 1 carries a column offset by the preamble's length.
|
|
72
|
+
// Line 1 of a userscript is its `// ==UserScript==` marker, so this
|
|
73
|
+
// has never been observed; the code view suppresses the column accent
|
|
74
|
+
// there rather than showing a wrong one.
|
|
75
|
+
export const USER_SOURCE_START_LINE = 1;
|
|
76
|
+
export function composeSource(script, opts = {}) {
|
|
77
|
+
const mainSource = joinFullSource(script.leadingText ?? '', script.headerText ?? '', script.bodyText);
|
|
78
|
+
const requires = script.requires ?? [];
|
|
79
|
+
const startLine = opts.startLine ?? 0;
|
|
80
|
+
if (requires.length === 0) {
|
|
81
|
+
return {
|
|
82
|
+
text: mainSource,
|
|
83
|
+
segments: [],
|
|
84
|
+
lineCount: countLines(mainSource),
|
|
85
|
+
mainStart: 0,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
// Build the text incrementally and derive every line number from
|
|
89
|
+
// what has ACTUALLY been emitted, rather than adding up expected
|
|
90
|
+
// line counts alongside a `join()`. The two drift: a require whose
|
|
91
|
+
// source ends in a lone `\r` fuses with a joining `\n` into a single
|
|
92
|
+
// CRLF, so one terminator appears where the arithmetic assumed two
|
|
93
|
+
// and every mapping from that seam onward — including the whole user
|
|
94
|
+
// body — shifts by a line. CR-only line endings are exactly the
|
|
95
|
+
// population `\r` is in `LINE_TERMINATORS` for, and nothing
|
|
96
|
+
// normalizes newlines on the way in (file-loader stores the decoded
|
|
97
|
+
// bytes verbatim).
|
|
98
|
+
const segments = [];
|
|
99
|
+
let text = '';
|
|
100
|
+
// 0-based generated line that the NEXT character appended will land
|
|
101
|
+
// on. `countLines('')` is 1, so an empty buffer is line 0.
|
|
102
|
+
const nextLine = () => startLine + countLines(text) - 1;
|
|
103
|
+
for (const [i, r] of requires.entries()) {
|
|
104
|
+
text += `// @require ${r.url}\n`;
|
|
105
|
+
const url = opts.requireUrls?.[i];
|
|
106
|
+
if (url) {
|
|
107
|
+
segments.push({
|
|
108
|
+
url,
|
|
109
|
+
content: r.source,
|
|
110
|
+
generatedLine: nextLine(),
|
|
111
|
+
lineCount: countLines(r.source),
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
// The trailing-`\r` guard: append the extra `\n` here so the
|
|
115
|
+
// source's own last line stays a line of its own, instead of being
|
|
116
|
+
// swallowed by the separator that follows.
|
|
117
|
+
text += r.source.endsWith('\r') ? `${r.source}\n` : r.source;
|
|
118
|
+
// Terminate the source's last line, then the `;` seam guard on a
|
|
119
|
+
// line of its own.
|
|
120
|
+
text += '\n;\n';
|
|
121
|
+
}
|
|
122
|
+
if (opts.mainUrl) {
|
|
123
|
+
segments.push({
|
|
124
|
+
url: opts.mainUrl,
|
|
125
|
+
content: mainSource,
|
|
126
|
+
generatedLine: nextLine(),
|
|
127
|
+
lineCount: countLines(mainSource),
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
const mainStart = text.length;
|
|
131
|
+
text += mainSource;
|
|
132
|
+
return { text, segments, lineCount: countLines(text), mainStart };
|
|
133
|
+
}
|
|
134
|
+
export function stackLayout(script, logLabel) {
|
|
135
|
+
const entryUrl = buildSourceUrl(logLabel);
|
|
136
|
+
const { segments, lineCount } = composeSource(script, {
|
|
137
|
+
requireUrls: (script.requires ?? []).map((r) => buildRequireSourceUrl(logLabel, r.url)),
|
|
138
|
+
mainUrl: entryUrl,
|
|
139
|
+
startLine: USER_SOURCE_START_LINE,
|
|
140
|
+
});
|
|
141
|
+
return { entryUrl, segments, lineCount };
|
|
142
|
+
}
|
|
143
|
+
// Count lines the way V8 does, which is what the source map has to
|
|
144
|
+
// agree with. Counting only `\n` silently shifts every mapping after
|
|
145
|
+
// the offending character:
|
|
146
|
+
//
|
|
147
|
+
// - a lone `\r` is a line terminator (files with mangled endings);
|
|
148
|
+
// - so are U+2028 / U+2029, and V8 counts a RAW U+2028 as a break
|
|
149
|
+
// even inside a string literal (legal since ES2019, and minified
|
|
150
|
+
// CDN bundles do embed them).
|
|
151
|
+
//
|
|
152
|
+
// `\r\n` must count as one, hence the alternation order.
|
|
153
|
+
const LINE_TERMINATORS = /\r\n|[\n\r\u2028\u2029]/g;
|
|
154
|
+
// `buildParseCheckSource` below measures its own preamble with it: a
|
|
155
|
+
// parse-check line offset that counted terminators differently from the
|
|
156
|
+
// segment list it is compared against would misattribute every error in
|
|
157
|
+
// the file.
|
|
158
|
+
function countLines(text) {
|
|
159
|
+
if (text === '')
|
|
160
|
+
return 1;
|
|
161
|
+
const matches = text.match(LINE_TERMINATORS);
|
|
162
|
+
return matches ? matches.length + 1 : 1;
|
|
163
|
+
}
|
|
164
|
+
// Public entry point for the swap-eval path, which needs the text only.
|
|
165
|
+
export function composeRequiredBody(script) {
|
|
166
|
+
return composeSource(script).text;
|
|
167
|
+
}
|
|
168
|
+
export function buildParseCheckSource(script) {
|
|
169
|
+
// A blank first line of our own, so the user's first line is never at
|
|
170
|
+
// offset 0: a `#!` hashbang is legal only there, so it stays the
|
|
171
|
+
// syntax error it also is in the real injected entry (which wraps the
|
|
172
|
+
// source), and the location probes can't be handed a source that
|
|
173
|
+
// parses as a shebang script. Blank, not a statement, so a leading
|
|
174
|
+
// `"use strict"` still applies, as in the injected entry (see
|
|
175
|
+
// USER_SCOPE_OPEN in injector.ts). The offset below is derived from it rather than
|
|
176
|
+
// assumed to be 1 — the same discipline `composeSource` applies
|
|
177
|
+
// internally, and for the same reason: assumed line counts drift
|
|
178
|
+
// from emitted ones.
|
|
179
|
+
const preamble = '\n';
|
|
180
|
+
const startLine = countLines(preamble) - 1;
|
|
181
|
+
const requires = script.requires ?? [];
|
|
182
|
+
const composed = composeSource(script, {
|
|
183
|
+
requireUrls: requires.map((r) => r.url),
|
|
184
|
+
mainUrl: script.relativePath,
|
|
185
|
+
startLine,
|
|
186
|
+
});
|
|
187
|
+
return {
|
|
188
|
+
text: preamble + composed.text,
|
|
189
|
+
// `composeSource` emits no segments for a script with no
|
|
190
|
+
// `@require`s — the viewer keys "pass stack refs through unmapped"
|
|
191
|
+
// off exactly that, so it stays as it is. Here the opposite is
|
|
192
|
+
// wanted: one segment for the body means every reported line
|
|
193
|
+
// resolves through the same lookup, with no second code path for
|
|
194
|
+
// the majority of scripts.
|
|
195
|
+
segments: composed.segments.length > 0
|
|
196
|
+
? composed.segments
|
|
197
|
+
: [{
|
|
198
|
+
url: script.relativePath,
|
|
199
|
+
content: composed.text,
|
|
200
|
+
generatedLine: startLine,
|
|
201
|
+
lineCount: composed.lineCount,
|
|
202
|
+
}],
|
|
203
|
+
lineCount: startLine + composed.lineCount,
|
|
204
|
+
};
|
|
205
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8" />
|
|
5
|
+
<title>SourceMonkey | Network permission required</title>
|
|
6
|
+
<link rel="stylesheet" href="styles.css" />
|
|
7
|
+
<style>
|
|
8
|
+
body { font: 14px system-ui, sans-serif; margin: 0; color: #222; background: #fff; --page-width: 100%; }
|
|
9
|
+
.page-body { padding: 14px 16px; }
|
|
10
|
+
p { margin: 0 0 10px; line-height: 18px; }
|
|
11
|
+
.target { font-weight: 600; overflow-wrap: anywhere; }
|
|
12
|
+
.question { font-weight: 600; margin-top: 14px; }
|
|
13
|
+
.actions { display: flex; flex-wrap: wrap; gap: 8px; margin: 6px 0 4px; }
|
|
14
|
+
.actions button { padding: 0 11px; }
|
|
15
|
+
.actions button.primary { font-weight: 600; }
|
|
16
|
+
#error { color: #b00020; }
|
|
17
|
+
a { color: #0b57d0; }
|
|
18
|
+
</style>
|
|
19
|
+
</head>
|
|
20
|
+
<body>
|
|
21
|
+
<header class="page-header">
|
|
22
|
+
<div class="page-header-inner">
|
|
23
|
+
<img class="page-icon" src="icons/icon-48.png" alt="" />
|
|
24
|
+
<h1><span class="brand">SourceMonkey |</span> Network permission required</h1>
|
|
25
|
+
</div>
|
|
26
|
+
</header>
|
|
27
|
+
<div class="page-body">
|
|
28
|
+
<p>Script <a id="script" class="target" href="#" target="_blank" rel="noopener"></a>
|
|
29
|
+
is requesting access to <a id="site" class="target" href="#" target="_blank" rel="noopener"></a>.</p>
|
|
30
|
+
<p>Granting this permission allows the script to act as you on the target page.</p>
|
|
31
|
+
<p>You can revoke permissions on the script's page.</p>
|
|
32
|
+
<p id="error" hidden></p>
|
|
33
|
+
<p class="question">Allow one time?</p>
|
|
34
|
+
<div class="actions">
|
|
35
|
+
<button id="once" type="button" title="Allow this request one time">Allow once</button>
|
|
36
|
+
<button id="cancel" type="button" title="Deny this request one time">Cancel</button>
|
|
37
|
+
</div>
|
|
38
|
+
<p class="question">Allow permanently?</p>
|
|
39
|
+
<div class="actions">
|
|
40
|
+
<button id="allow" type="button" class="primary" title="Allow access to this site every time">Allow</button>
|
|
41
|
+
<button id="deny" type="button" title="Deny access to this site every time">Deny</button>
|
|
42
|
+
<button id="allow-all" type="button" title="Allow this script all access to ALL sites">Allow all sites</button>
|
|
43
|
+
</div>
|
|
44
|
+
</div>
|
|
45
|
+
<script type="module" src="extension/connect-prompt-page.js"></script>
|
|
46
|
+
</body>
|
|
47
|
+
</html>
|