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,322 @@
|
|
|
1
|
+
// Pure display helpers for collections: type classification,
|
|
2
|
+
// display-name inference, and the colored type-bubble bookkeeping
|
|
3
|
+
// shared by the collections page and the userscript viewer.
|
|
4
|
+
//
|
|
5
|
+
// The bubble a collection wears says what KIND it is and, for a
|
|
6
|
+
// location-backed one, where it lives:
|
|
7
|
+
// - `scripts` : a container of individually installed
|
|
8
|
+
// scripts (may mix local, web, and GitHub)
|
|
9
|
+
// - `<scheme>-dir` : a scanned directory (`file-dir`, `github-dir`)
|
|
10
|
+
// - `<scheme>-manifest` : a `script_manifest.json` (`file-`, `http-`,
|
|
11
|
+
// `github-manifest`)
|
|
12
|
+
// where the scheme is a display-only label — it doesn't drive the
|
|
13
|
+
// scan/fetch dispatch (which lives in `directories.ts` and keys off URL
|
|
14
|
+
// shape and `isGithubDirCollection` / manifest detection):
|
|
15
|
+
// - github : github.com/* or raw.githubusercontent.com/*
|
|
16
|
+
// - http : any other http(s) URL
|
|
17
|
+
// - file : raw filesystem path or file:// URL
|
|
18
|
+
//
|
|
19
|
+
// Inside a `scripts` collection each row wears its own scheme chip
|
|
20
|
+
// (`makeSchemeChip`), since the collection itself has no single scheme.
|
|
21
|
+
// The light location modules, not directories.ts: the toolbar popup
|
|
22
|
+
// draws type bubbles and must not load the scanning and fetch code.
|
|
23
|
+
import { containerKind, containerPath, isContainerCollection, isFileUrl, isHttpUrl, pathToFileUrl, isManifestCollection, } from '../file-locations.js';
|
|
24
|
+
import { githubRawToBlobUrl } from '../github-urls.js';
|
|
25
|
+
import { isSmDevCollection, scriptSchemeKind } from './location-kinds.js';
|
|
26
|
+
import { MANIFEST_FILENAME } from '../collection-scan.js';
|
|
27
|
+
import { decodeForDisplay } from '../script-display.js';
|
|
28
|
+
// Why a script's enable checkbox is greyed out when its parent is off.
|
|
29
|
+
// Stands in for `ENABLE_TITLE` on every surface that draws one, so the
|
|
30
|
+
// collections page, the viewer's controls row, and the "Other versions"
|
|
31
|
+
// panel all explain it the same way.
|
|
32
|
+
export const COLLECTION_OFF_TITLE = 'Collection is disabled';
|
|
33
|
+
const GITHUB_HOST_RE = /^https?:\/\/(www\.)?github\.com\//i;
|
|
34
|
+
const RAW_GITHUB_HOST_RE = /^https?:\/\/raw\.githubusercontent\.com\//i;
|
|
35
|
+
// Display-only scheme classification of a collection's location.
|
|
36
|
+
// Stable across refreshes because it only depends on the collection
|
|
37
|
+
// path. GitHub recognition is intentionally broad — it covers both the
|
|
38
|
+
// canonical browse URL (`github.com/.../tree/...`) and the raw-content
|
|
39
|
+
// host (`raw.githubusercontent.com/...`) so any scheme of GitHub
|
|
40
|
+
// collection reads as `github` in the UI.
|
|
41
|
+
//
|
|
42
|
+
// A container has no location, so it falls through to `file` — which
|
|
43
|
+
// is the right answer for the one caller that asks about containers
|
|
44
|
+
// (`isLocalCollection` in refresh-targets: a container's local rows are
|
|
45
|
+
// refreshed one by one). Its bubble never comes from here.
|
|
46
|
+
export function inferCollectionType(path) {
|
|
47
|
+
if (GITHUB_HOST_RE.test(path) || RAW_GITHUB_HOST_RE.test(path))
|
|
48
|
+
return 'github';
|
|
49
|
+
if (isHttpUrl(path))
|
|
50
|
+
return 'http';
|
|
51
|
+
return 'file';
|
|
52
|
+
}
|
|
53
|
+
// Fixed human-readable titles for the three built-in default
|
|
54
|
+
// containers. These drive both the displayName backfill and the name
|
|
55
|
+
// the install page shows for a default that doesn't exist yet. The
|
|
56
|
+
// user can rename the row afterwards; the default is recognised by its
|
|
57
|
+
// path (`containerKind`), not by this text.
|
|
58
|
+
export const CONTAINER_DISPLAY_NAMES = {
|
|
59
|
+
file: 'Scripts from local disk',
|
|
60
|
+
http: 'Scripts from web',
|
|
61
|
+
github: 'Scripts from GitHub',
|
|
62
|
+
};
|
|
63
|
+
// The name for a container whose row carries no `displayName` — a
|
|
64
|
+
// pre-rename default, or (never, but defensively) a user-created one
|
|
65
|
+
// saved without a name. Never the raw `container:<uuid>` path.
|
|
66
|
+
export const UNNAMED_COLLECTION = 'Unnamed collection';
|
|
67
|
+
// Bubble label / CSS-key for a container: one word, since a container
|
|
68
|
+
// may hold scripts from every scheme.
|
|
69
|
+
export const SCRIPTS_BUBBLE_KEY = 'scripts';
|
|
70
|
+
// An sm-dev run's test collection: a scripts collection only its run
|
|
71
|
+
// changes.
|
|
72
|
+
export const SM_DEV_BUBBLE_KEY = 'sm-dev';
|
|
73
|
+
// The built-in default containers' names are reserved, whether or not
|
|
74
|
+
// the row exists yet. Without this a user could name their own
|
|
75
|
+
// collection "Scripts from web", and the first web install would then
|
|
76
|
+
// auto-create `container:http` under that same name — two entries in
|
|
77
|
+
// the install dropdown reading identically, in a state that could not
|
|
78
|
+
// be re-created afterwards (the rename would be refused as a
|
|
79
|
+
// duplicate). Returns the kind that owns the name, or null.
|
|
80
|
+
//
|
|
81
|
+
// The owning default itself is exempt: it already has the name, and
|
|
82
|
+
// re-saving its own name must not be refused.
|
|
83
|
+
export function reservedNameOwner(name) {
|
|
84
|
+
const key = name.trim().toLowerCase();
|
|
85
|
+
if (!key)
|
|
86
|
+
return null;
|
|
87
|
+
for (const [kind, label] of Object.entries(CONTAINER_DISPLAY_NAMES)) {
|
|
88
|
+
if (label.toLowerCase() === key)
|
|
89
|
+
return kind;
|
|
90
|
+
}
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
// Why a name can't be used: a built-in collection owns it. The name
|
|
94
|
+
// isn't repeated back — the user is standing at the field they just
|
|
95
|
+
// typed it into.
|
|
96
|
+
export const RESERVED_COLLECTION_NAME = 'Built-in collection name is reserved. Choose another name.';
|
|
97
|
+
// True when the given collection may carry a reserved name: it IS the
|
|
98
|
+
// default that owns it. `path` is the row being created or edited;
|
|
99
|
+
// pass null when creating a user collection, which never may.
|
|
100
|
+
export function mayUseReservedName(name, path) {
|
|
101
|
+
const owner = reservedNameOwner(name);
|
|
102
|
+
return owner === null || (path !== null && path === containerPath(owner));
|
|
103
|
+
}
|
|
104
|
+
// True when two collections would collide on name. Case-insensitive
|
|
105
|
+
// and whitespace-trimmed, since two names that differ only that way
|
|
106
|
+
// would read as one in the install dropdown. `excludeId` lets an edit
|
|
107
|
+
// keep its own current name.
|
|
108
|
+
export function collectionNameInUse(name, collections, excludeId) {
|
|
109
|
+
const key = name.trim().toLowerCase();
|
|
110
|
+
if (!key)
|
|
111
|
+
return false;
|
|
112
|
+
return collections.some((c) => c.id !== excludeId && effectiveDisplayName(c).trim().toLowerCase() === key);
|
|
113
|
+
}
|
|
114
|
+
// True for manifest collections of any scheme. Thin wrapper so callers
|
|
115
|
+
// don't have to import `directories` just for this. Container
|
|
116
|
+
// collections can never be manifests — their `path` is the synthetic
|
|
117
|
+
// `container:…` identifier.
|
|
118
|
+
export function collectionHasManifest(path) {
|
|
119
|
+
if (isContainerCollection(path))
|
|
120
|
+
return false;
|
|
121
|
+
return isManifestCollection(path);
|
|
122
|
+
}
|
|
123
|
+
// Bubble label / CSS-key for a collection: `scripts` for a container
|
|
124
|
+
// (`sm-dev` for an sm-dev run's test collection), `<scheme>-dir` for a
|
|
125
|
+
// scanned directory, `<scheme>-manifest` for a manifest. Same string
|
|
126
|
+
// powers the CSS class (`bubble-<key>`) and the visible text.
|
|
127
|
+
export function collectionBubbleKey(path) {
|
|
128
|
+
if (isSmDevCollection(path))
|
|
129
|
+
return SM_DEV_BUBBLE_KEY;
|
|
130
|
+
if (isContainerCollection(path))
|
|
131
|
+
return SCRIPTS_BUBBLE_KEY;
|
|
132
|
+
const t = inferCollectionType(path);
|
|
133
|
+
return collectionHasManifest(path) ? `${t}-manifest` : `${t}-dir`;
|
|
134
|
+
}
|
|
135
|
+
// The small per-row scheme chip a script wears inside a `scripts`
|
|
136
|
+
// collection — `file` / `http` / `github` / `scratch` — since the collection's own
|
|
137
|
+
// bubble can't say where each of its scripts loads from. Classified
|
|
138
|
+
// from the script's own location (`relativePath` in a container is the
|
|
139
|
+
// full URL/path the user installed).
|
|
140
|
+
export function makeSchemeChip(location) {
|
|
141
|
+
const scheme = scriptSchemeKind(location);
|
|
142
|
+
const span = document.createElement('span');
|
|
143
|
+
span.className = `scheme-chip chip-${scheme}`;
|
|
144
|
+
span.textContent = scheme;
|
|
145
|
+
span.title = {
|
|
146
|
+
file: 'Loaded from a local file',
|
|
147
|
+
http: 'Loaded from the web',
|
|
148
|
+
github: 'Loaded from GitHub',
|
|
149
|
+
scratch: 'Stored only in SourceMonkey',
|
|
150
|
+
}[scheme];
|
|
151
|
+
return span;
|
|
152
|
+
}
|
|
153
|
+
// Openable URL for a collection — the link target the bubble uses. For
|
|
154
|
+
// github raw URLs (manifest collections, post-add-time normalization)
|
|
155
|
+
// we return the `github.com/.../blob/...` page URL instead, since the
|
|
156
|
+
// bubble exists for humans to click — the raw bytes are only used
|
|
157
|
+
// internally for fetching. All other http(s) / file:// URLs pass
|
|
158
|
+
// through; raw filesystem paths become file:// URLs so the anchor has a
|
|
159
|
+
// valid href (Chromium typically refuses to navigate to file:// from a
|
|
160
|
+
// chrome-extension page, but the URL is still readable + copyable).
|
|
161
|
+
// Container collections have no underlying URL — return null and let
|
|
162
|
+
// callers render the bubble as a non-link.
|
|
163
|
+
export function collectionClickUrl(path) {
|
|
164
|
+
if (isContainerCollection(path))
|
|
165
|
+
return null;
|
|
166
|
+
if (isHttpUrl(path)) {
|
|
167
|
+
return githubRawToBlobUrl(path) ?? path;
|
|
168
|
+
}
|
|
169
|
+
if (isFileUrl(path))
|
|
170
|
+
return path;
|
|
171
|
+
return pathToFileUrl(path);
|
|
172
|
+
}
|
|
173
|
+
// Derive a short, human-readable display name from a collection path. The
|
|
174
|
+
// rules trim noise from the beginning, middle, and end of the link:
|
|
175
|
+
// - drop the protocol prefix (https://, http://, file://)
|
|
176
|
+
// - drop any `?query` tail
|
|
177
|
+
// - drop a trailing `/<MANIFEST_FILENAME>` so a manifest collection reads
|
|
178
|
+
// as the directory that hosts it
|
|
179
|
+
// - github.com / raw.githubusercontent.com get scheme-specific
|
|
180
|
+
// simplifications so the common shapes read as `<owner>/<repo>`
|
|
181
|
+
// or `<owner>/<repo>/<ref>/<path>` rather than the full URL
|
|
182
|
+
// - trailing slashes are stripped
|
|
183
|
+
//
|
|
184
|
+
// The result is stable across refreshes (depends only on the path),
|
|
185
|
+
// short enough for the collections-page heading, and a reasonable seed for
|
|
186
|
+
// a future user-renamed displayName.
|
|
187
|
+
export function inferDisplayName(path) {
|
|
188
|
+
const ck = containerKind(path);
|
|
189
|
+
if (ck)
|
|
190
|
+
return CONTAINER_DISPLAY_NAMES[ck];
|
|
191
|
+
// A user-created container has no location to infer from; its name
|
|
192
|
+
// is whatever the user typed, stored in `displayName`.
|
|
193
|
+
if (isContainerCollection(path))
|
|
194
|
+
return '';
|
|
195
|
+
let s = path.trim();
|
|
196
|
+
// Strip the fragment + query first so trailing noise can't leak into
|
|
197
|
+
// any downstream substitution (e.g. `?token=...` on a manifest URL,
|
|
198
|
+
// or `#install-section` on a GreasyFork link).
|
|
199
|
+
const h = s.indexOf('#');
|
|
200
|
+
if (h >= 0)
|
|
201
|
+
s = s.slice(0, h);
|
|
202
|
+
const q = s.indexOf('?');
|
|
203
|
+
if (q >= 0)
|
|
204
|
+
s = s.slice(0, q);
|
|
205
|
+
// Strip the protocol prefix uniformly. Raw fs paths have none and
|
|
206
|
+
// pass through; file:// URLs become bare absolute paths, which is
|
|
207
|
+
// what users typically recognise.
|
|
208
|
+
s = s.replace(/^https?:\/\//i, '').replace(/^file:\/\//i, '');
|
|
209
|
+
// Drop a trailing manifest filename so `…/foo/script_manifest.json`
|
|
210
|
+
// reads as `…/foo`.
|
|
211
|
+
if (s.endsWith('/' + MANIFEST_FILENAME)) {
|
|
212
|
+
s = s.slice(0, -(MANIFEST_FILENAME.length + 1));
|
|
213
|
+
}
|
|
214
|
+
// GitHub-specific simplifications. Each rule has its own anchor on
|
|
215
|
+
// the URL shape; early-return after the first match so a literal
|
|
216
|
+
// directory named `tree` or `blob` (post-rewrite) doesn't get
|
|
217
|
+
// re-consumed by a later rule. Order doesn't matter once we exit
|
|
218
|
+
// after the first hit. Longer literal segments listed first only as
|
|
219
|
+
// a readability hint.
|
|
220
|
+
if (/^(www\.)?github\.com\//i.test(s)) {
|
|
221
|
+
s = s.replace(/^(www\.)?github\.com\//i, '');
|
|
222
|
+
s = applyFirstGithubRule(s);
|
|
223
|
+
}
|
|
224
|
+
else if (/^raw\.githubusercontent\.com\//i.test(s)) {
|
|
225
|
+
s = s.replace(/^raw\.githubusercontent\.com\//i, '');
|
|
226
|
+
// New-style raw URLs carry an extra `/refs/heads/` segment before
|
|
227
|
+
// the branch name; strip it so the form mirrors the legacy shape.
|
|
228
|
+
const m = /^([^\/]+\/[^\/]+)\/refs\/heads\/([^\/]+)(\/.*)?$/.exec(s);
|
|
229
|
+
if (m)
|
|
230
|
+
s = `${m[1]}/${m[2]}${m[3] ?? ''}`;
|
|
231
|
+
}
|
|
232
|
+
// Trim trailing slashes so e.g. `…/dir/` reads as `…/dir`.
|
|
233
|
+
s = s.replace(/\/+$/, '');
|
|
234
|
+
// Decode percent-encoded characters so e.g. a GreasyFork URL with
|
|
235
|
+
// `OnePelotoncom%20Cycle...` reads as `OnePelotoncom Cycle...`.
|
|
236
|
+
// Same decode-for-display rule the rest of the UI follows — see
|
|
237
|
+
// docs/names-and-paths.md.
|
|
238
|
+
return decodeForDisplay(s);
|
|
239
|
+
}
|
|
240
|
+
// Try each github URL-shape rewrite in turn and return on the first
|
|
241
|
+
// hit. Single-pass match avoids the chain-rewrite hazard where a
|
|
242
|
+
// post-rewrite path that happens to contain a literal `blob` / `tree`
|
|
243
|
+
// directory would be re-interpreted by a later rule.
|
|
244
|
+
function applyFirstGithubRule(s) {
|
|
245
|
+
// `<owner>/<repo>/tree/<ref>(/<path>?)` → `<owner>/<repo>(/<path>?)`
|
|
246
|
+
let m = /^([^\/]+\/[^\/]+)\/tree\/[^\/]+(\/.*)?$/.exec(s);
|
|
247
|
+
if (m)
|
|
248
|
+
return m[1] + (m[2] ?? '');
|
|
249
|
+
// `<owner>/<repo>/blob/<ref>/<path>` → `<owner>/<repo>/<ref>/<path>`
|
|
250
|
+
m = /^([^\/]+\/[^\/]+)\/blob\/([^\/]+)(\/.*)?$/.exec(s);
|
|
251
|
+
if (m)
|
|
252
|
+
return `${m[1]}/${m[2]}${m[3] ?? ''}`;
|
|
253
|
+
// `<owner>/<repo>/raw/refs/heads/<branch>/<path>` →
|
|
254
|
+
// `<owner>/<repo>/<branch>/<path>`
|
|
255
|
+
m = /^([^\/]+\/[^\/]+)\/raw\/refs\/heads\/([^\/]+)(\/.*)?$/.exec(s);
|
|
256
|
+
if (m)
|
|
257
|
+
return `${m[1]}/${m[2]}${m[3] ?? ''}`;
|
|
258
|
+
// `<owner>/<repo>/raw/<ref>/<path>` → `<owner>/<repo>/<ref>/<path>`
|
|
259
|
+
m = /^([^\/]+\/[^\/]+)\/raw\/([^\/]+)(\/.*)?$/.exec(s);
|
|
260
|
+
if (m)
|
|
261
|
+
return `${m[1]}/${m[2]}${m[3] ?? ''}`;
|
|
262
|
+
return s;
|
|
263
|
+
}
|
|
264
|
+
// Canonical collections-page anchor for a collection. Lives here (not
|
|
265
|
+
// in collections.ts) so the viewer can link back to the right `#…`
|
|
266
|
+
// without reaching across pages for the helper.
|
|
267
|
+
export function collectionAnchorId(collectionId) {
|
|
268
|
+
return `collection-${collectionId}`;
|
|
269
|
+
}
|
|
270
|
+
// A collections-page fragment that opens a collection's edit dialog
|
|
271
|
+
// (the popup's "Collection options"): this prefix + the collection id.
|
|
272
|
+
export const EDIT_COLLECTION_HASH_PREFIX = 'edit-collection-';
|
|
273
|
+
// Construct the colored type-bubble for a collection. Shared by the
|
|
274
|
+
// collections page (heading) and the userscript viewer (Collection row)
|
|
275
|
+
// so the markup, classes, tooltip, and anchor target all stay in
|
|
276
|
+
// lockstep across both views. Returns an `<a>` for collections backed
|
|
277
|
+
// by a real URL/path, and a `<span>` for container collections (which
|
|
278
|
+
// have no underlying URL to link to).
|
|
279
|
+
export function makeCollectionTypeBubble(path) {
|
|
280
|
+
const key = collectionBubbleKey(path);
|
|
281
|
+
const href = collectionClickUrl(path);
|
|
282
|
+
if (href === null) {
|
|
283
|
+
// No URL to link to, so the tooltip says what this collection IS
|
|
284
|
+
// rather than naming the internal "container" kind — the user never
|
|
285
|
+
// sees that word — and why there is nothing to open: its scripts
|
|
286
|
+
// were installed one at a time and share no parent.
|
|
287
|
+
const span = document.createElement('span');
|
|
288
|
+
span.className = `collection-type-bubble bubble-${key}`;
|
|
289
|
+
span.textContent = key;
|
|
290
|
+
span.title = key === SM_DEV_BUBBLE_KEY
|
|
291
|
+
? 'Scripts an sm-dev run pushed, which only that run changes'
|
|
292
|
+
: 'Collection of individual scripts (no common parent directory)';
|
|
293
|
+
return span;
|
|
294
|
+
}
|
|
295
|
+
const a = document.createElement('a');
|
|
296
|
+
a.className = `collection-type-bubble bubble-${key}`;
|
|
297
|
+
a.textContent = key;
|
|
298
|
+
a.href = href;
|
|
299
|
+
a.target = '_blank';
|
|
300
|
+
a.rel = 'noopener noreferrer';
|
|
301
|
+
// Names what clicking does, which differs by kind: a directory (local
|
|
302
|
+
// or a GitHub tree) opens somewhere you can look around; a manifest
|
|
303
|
+
// opens the one file that lists the scripts.
|
|
304
|
+
a.title = collectionHasManifest(path)
|
|
305
|
+
? `Open manifest: ${path}`
|
|
306
|
+
: `Browse directory: ${path}`;
|
|
307
|
+
return a;
|
|
308
|
+
}
|
|
309
|
+
// Resolve the display name for a stored collection. Prefers the stored
|
|
310
|
+
// `displayName` (the user's own, or the one seeded at add time);
|
|
311
|
+
// otherwise falls back to the inferred one. The very last fallback is
|
|
312
|
+
// the raw `path` — or a placeholder for a container, whose synthetic
|
|
313
|
+
// path is not for showing — so the UI never renders an empty string.
|
|
314
|
+
export function effectiveDisplayName(collection) {
|
|
315
|
+
const stored = collection.displayName?.trim();
|
|
316
|
+
if (stored)
|
|
317
|
+
return stored;
|
|
318
|
+
const inferred = inferDisplayName(collection.path);
|
|
319
|
+
if (inferred)
|
|
320
|
+
return inferred;
|
|
321
|
+
return isContainerCollection(collection.path) ? UNNAMED_COLLECTION : collection.path;
|
|
322
|
+
}
|