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
package/dist/styles.css
ADDED
|
@@ -0,0 +1,825 @@
|
|
|
1
|
+
/* Shared stylesheet linked from every SourceMonkey extension page
|
|
2
|
+
(collections.html, options.html, userscript.html). Pages still carry
|
|
3
|
+
their own page-specific styles in a <style> block; rules here are
|
|
4
|
+
for elements that show up on more than one page. New cross-page
|
|
5
|
+
styles belong in this file rather than copy-pasted into each
|
|
6
|
+
<style> block.
|
|
7
|
+
|
|
8
|
+
Currently shared:
|
|
9
|
+
- the collection-type bubble + its display-name sibling (DOM helper in
|
|
10
|
+
src/extension/collection-display.ts, used on the collections page heading and the
|
|
11
|
+
userscript viewer's Collection row), and the per-row scheme chip a
|
|
12
|
+
script wears inside a scripts collection;
|
|
13
|
+
- the warning banner box, whose file-access variant (DOM helper in
|
|
14
|
+
src/extension/file-access.ts) renders on both the collections page and the
|
|
15
|
+
viewer / install preview;
|
|
16
|
+
- the modal dialog shell, shared by the create / edit collection
|
|
17
|
+
dialog (src/extension/collection-dialog.ts) and the move-script dialog
|
|
18
|
+
(src/extension/move-dialog.ts);
|
|
19
|
+
- the "Install into" dropdown (src/extension/related-versions.ts), in the
|
|
20
|
+
install page's callout and its versions table;
|
|
21
|
+
- the removal buttons' glyph sizing and destructive colour
|
|
22
|
+
(src/extension/delete-icon.ts), on every page that has a remove button;
|
|
23
|
+
- the icon-button layout and spin state (src/extension/glyph.ts), shared by
|
|
24
|
+
the Refresh / options buttons on the collections page and the
|
|
25
|
+
viewer. */
|
|
26
|
+
|
|
27
|
+
/* Warning banner. Pages keep their own margin and colour variants
|
|
28
|
+
(`.banner.installed` on the viewer) in their
|
|
29
|
+
<style> block; everything below is common to every banner. */
|
|
30
|
+
.banner {
|
|
31
|
+
border: 1px solid #d97706;
|
|
32
|
+
background: #fffbeb;
|
|
33
|
+
padding: 10px 14px;
|
|
34
|
+
border-radius: 6px;
|
|
35
|
+
margin-bottom: 10px;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.banner strong { display: block; margin-bottom: 4px; }
|
|
39
|
+
|
|
40
|
+
/* A banner for something that stops scripts running, not a warning: red,
|
|
41
|
+
as the popup's bar for the same problem. */
|
|
42
|
+
.banner.banner-error { border-color: #e57373; background: #fdecea; color: #b71c1c; }
|
|
43
|
+
.banner.banner-error a { color: inherit; }
|
|
44
|
+
|
|
45
|
+
.banner p { margin: 4px 0; line-height: 16px; }
|
|
46
|
+
|
|
47
|
+
/* The `chrome://extensions/?id=…` link a permission banner can end
|
|
48
|
+
with. Styled as inline code because that's what it is — an address
|
|
49
|
+
the user may prefer to copy rather than click. */
|
|
50
|
+
.banner a.chrome-link {
|
|
51
|
+
display: inline-block;
|
|
52
|
+
background: #fef3c7;
|
|
53
|
+
padding: 0.15em 0.4em;
|
|
54
|
+
border-radius: 3px;
|
|
55
|
+
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
|
|
56
|
+
color: #92400e;
|
|
57
|
+
text-decoration: none;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.banner a.chrome-link { cursor: pointer; }
|
|
61
|
+
.banner a.chrome-link:hover { text-decoration: underline; }
|
|
62
|
+
|
|
63
|
+
/* A setting's name in a banner sentence: marked, but no bigger or
|
|
64
|
+
louder than the text around it. */
|
|
65
|
+
.banner code {
|
|
66
|
+
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
|
|
67
|
+
font-size: 0.9em;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.collection-display-name {
|
|
71
|
+
/* Prefer space / slash boundaries when wrapping. `<wbr>` markers
|
|
72
|
+
inserted after each `/` (see appendWithSlashBreaks in
|
|
73
|
+
src/extension/collection-display.ts) give the browser preferred break points
|
|
74
|
+
before it has to break inside a word. */
|
|
75
|
+
overflow-wrap: anywhere;
|
|
76
|
+
word-break: normal;
|
|
77
|
+
min-width: 0;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.collection-type-bubble {
|
|
81
|
+
display: inline-block;
|
|
82
|
+
padding: 1px 8px;
|
|
83
|
+
border-radius: 10px;
|
|
84
|
+
font-size: 11px;
|
|
85
|
+
font-weight: 600;
|
|
86
|
+
text-transform: uppercase;
|
|
87
|
+
letter-spacing: 0.04em;
|
|
88
|
+
color: #fff;
|
|
89
|
+
text-decoration: none;
|
|
90
|
+
/* Whole px: 1.5 x 11px = 16.5 would make its whole row fractional. */
|
|
91
|
+
line-height: 16px;
|
|
92
|
+
white-space: nowrap;
|
|
93
|
+
flex: 0 0 auto;
|
|
94
|
+
}
|
|
95
|
+
.collection-type-bubble:hover { opacity: 0.85; }
|
|
96
|
+
|
|
97
|
+
/* Kind + scheme: `-dir` in the scheme's base hue, `-manifest` darker,
|
|
98
|
+
and a neutral grey for a scripts collection, which has no scheme of
|
|
99
|
+
its own. `http-dir` is unreachable through the add paths (a plain
|
|
100
|
+
web directory can't be listed) but a legacy or hand-written row
|
|
101
|
+
still renders, and a bubble with no rule would be white on white. */
|
|
102
|
+
.bubble-file-dir { background: #d97706; }
|
|
103
|
+
.bubble-http-dir { background: #2563eb; }
|
|
104
|
+
.bubble-file-manifest { background: #92400e; }
|
|
105
|
+
.bubble-http-manifest { background: #1e3a8a; }
|
|
106
|
+
.bubble-github-dir { background: #6f42c1; }
|
|
107
|
+
.bubble-github-manifest { background: #4c2889; }
|
|
108
|
+
.bubble-scripts { background: #4b5563; }
|
|
109
|
+
/* An sm-dev run's test collection: a darker shade of the cyan "T" on
|
|
110
|
+
the toolbar icon in sm-dev's tabs, dark enough for white text. */
|
|
111
|
+
.bubble-sm-dev { background: #00838f; }
|
|
112
|
+
/* Form states, not collection kinds — only the collection dialog's Type
|
|
113
|
+
row ever wears these: red for a location (or an empty form) that
|
|
114
|
+
can't become a collection, grey while its verdict is being fetched. */
|
|
115
|
+
.bubble-invalid { background: #b00; }
|
|
116
|
+
.bubble-checking { background: #9ca3af; }
|
|
117
|
+
|
|
118
|
+
/* The per-row scheme chip inside a scripts collection: the same hues
|
|
119
|
+
as the bubbles, smaller, so a mixed collection still says where each
|
|
120
|
+
script loads from. */
|
|
121
|
+
.scheme-chip {
|
|
122
|
+
display: inline-block;
|
|
123
|
+
min-width: 2.2em;
|
|
124
|
+
text-align: center;
|
|
125
|
+
padding: 0 5px;
|
|
126
|
+
border-radius: 8px;
|
|
127
|
+
font-size: 10px;
|
|
128
|
+
font-weight: 600;
|
|
129
|
+
text-transform: uppercase;
|
|
130
|
+
letter-spacing: 0.04em;
|
|
131
|
+
color: #fff;
|
|
132
|
+
line-height: 14px;
|
|
133
|
+
white-space: nowrap;
|
|
134
|
+
}
|
|
135
|
+
.chip-file { background: #d97706; }
|
|
136
|
+
.chip-http { background: #2563eb; }
|
|
137
|
+
.chip-github { background: #6f42c1; }
|
|
138
|
+
.chip-scratch { background: #0f766e; }
|
|
139
|
+
|
|
140
|
+
/* ---- Modal dialog shell ---- */
|
|
141
|
+
/* `.sm-dialog` is the shell — frame, title bar, body grid, error slot,
|
|
142
|
+
action row — shared by the create / edit collection dialog
|
|
143
|
+
(src/extension/collection-dialog.ts) and the move-script dialog
|
|
144
|
+
(src/extension/move-dialog.ts). Each dialog also carries its own identity
|
|
145
|
+
class, which is what page code and tests select on. */
|
|
146
|
+
dialog.sm-dialog {
|
|
147
|
+
border: 1px solid #bbb;
|
|
148
|
+
border-radius: 8px;
|
|
149
|
+
padding: 0;
|
|
150
|
+
width: 520px;
|
|
151
|
+
max-width: calc(100vw - 2em);
|
|
152
|
+
color: #222;
|
|
153
|
+
font: 14px system-ui, sans-serif;
|
|
154
|
+
box-shadow: 0 12px 40px rgba(0, 0, 0, 0.18);
|
|
155
|
+
background: #fff;
|
|
156
|
+
box-sizing: border-box;
|
|
157
|
+
}
|
|
158
|
+
dialog.sm-dialog::backdrop { background: rgba(20, 24, 32, 0.35); }
|
|
159
|
+
/* Wider than the shared default: every row here can hold a long name
|
|
160
|
+
or path — the collection name, the file name with its subdirectory,
|
|
161
|
+
each dependency's path, the description. */
|
|
162
|
+
dialog.sm-dialog.copy-dialog { width: 680px; }
|
|
163
|
+
/* Same reason as the copy dialog: every row holds a path. */
|
|
164
|
+
dialog.sm-dialog.delete-dialog { width: 680px; }
|
|
165
|
+
/* Its result line can hold the saved file's whole path. */
|
|
166
|
+
dialog.sm-dialog.export-dialog { width: 560px; }
|
|
167
|
+
.export-dialog .dlg-intro { grid-column: 1 / -1; margin: 0; }
|
|
168
|
+
/* Checkbox, then label, with the hint under the label rather than under
|
|
169
|
+
the checkbox. The label is `display: contents` so its checkbox and
|
|
170
|
+
text sit in the grid's columns and a click on the text still ticks. */
|
|
171
|
+
.export-dialog .dlg-option { display: grid; grid-template-columns: auto 1fr; column-gap: 6px; align-items: baseline; }
|
|
172
|
+
.export-dialog .dlg-option .dlg-check { display: contents; }
|
|
173
|
+
.export-dialog .dlg-option .dlg-hint { grid-column: 2; }
|
|
174
|
+
.export-dialog .dlg-includes { display: flex; flex-direction: column; gap: 8px; padding-top: 5px; }
|
|
175
|
+
.export-dialog .dlg-result { grid-column: 1 / -1; overflow-wrap: anywhere; }
|
|
176
|
+
.export-dialog .dlg-result[hidden] { display: none; }
|
|
177
|
+
.export-dialog .dlg-result p { margin: 0 0 4px; }
|
|
178
|
+
.export-dialog .dlg-saved-path { overflow-wrap: anywhere; }
|
|
179
|
+
.export-dialog .dlg-saved .copy-btn { display: inline-flex; vertical-align: middle; width: 20px; height: 20px; margin-left: 0.4em; }
|
|
180
|
+
.sm-dialog .dlg-title {
|
|
181
|
+
font-size: 1em;
|
|
182
|
+
font-weight: 600;
|
|
183
|
+
margin: 0;
|
|
184
|
+
padding: 12px 16px;
|
|
185
|
+
border-bottom: 1px solid #e5e7eb;
|
|
186
|
+
}
|
|
187
|
+
.sm-dialog .dlg-body {
|
|
188
|
+
margin: 0;
|
|
189
|
+
padding: 14px 16px 4px;
|
|
190
|
+
display: grid;
|
|
191
|
+
grid-template-columns: max-content 1fr;
|
|
192
|
+
column-gap: 12px;
|
|
193
|
+
row-gap: 12px;
|
|
194
|
+
align-items: start;
|
|
195
|
+
}
|
|
196
|
+
.sm-dialog .dlg-label { padding-top: 5px; color: #444; }
|
|
197
|
+
/* Slot for a control the dialog rebuilds per open. Fills its grid
|
|
198
|
+
column the way the collection dialog's text inputs do. */
|
|
199
|
+
.sm-dialog .dlg-slot { min-width: 0; }
|
|
200
|
+
.sm-dialog .dlg-slot select { width: 100%; font: inherit; padding: 4px 7px; }
|
|
201
|
+
.sm-dialog .dlg-label[hidden] { display: none; }
|
|
202
|
+
/* The location box with its copy and open-in-a-new-tab buttons. It and
|
|
203
|
+
its label centre on each other: the label can take two lines. */
|
|
204
|
+
.sm-dialog .dlg-location { display: flex; gap: 6px; align-items: center; min-width: 0; align-self: center; }
|
|
205
|
+
.sm-dialog .dlg-location-label { align-self: center; padding-top: 0; }
|
|
206
|
+
.sm-dialog .dlg-location[hidden] { display: none; }
|
|
207
|
+
.sm-dialog .dlg-location input { flex: 1; min-width: 0; }
|
|
208
|
+
/* Its two buttons are one pair: the open button takes the copy
|
|
209
|
+
button's look (square, white, its border and hover) rather than the
|
|
210
|
+
page's grey, padded `.icon-btn`. */
|
|
211
|
+
.sm-dialog .dlg-location .copy-btn,
|
|
212
|
+
.sm-dialog .dlg-location .dlg-open-location {
|
|
213
|
+
width: var(--icon-btn-size);
|
|
214
|
+
min-width: 0;
|
|
215
|
+
height: var(--icon-btn-size);
|
|
216
|
+
padding: 0;
|
|
217
|
+
border: 1px solid #bbb;
|
|
218
|
+
border-radius: 3px;
|
|
219
|
+
background: #fff;
|
|
220
|
+
color: #444;
|
|
221
|
+
}
|
|
222
|
+
.sm-dialog .dlg-location button:hover:not(:disabled) { background: #eee; }
|
|
223
|
+
.sm-dialog .dlg-location button:active:not(:disabled) { background: #ddd; }
|
|
224
|
+
.sm-dialog .dlg-location button:disabled { cursor: default; opacity: 0.5; }
|
|
225
|
+
.sm-dialog input[type="text"],
|
|
226
|
+
.sm-dialog textarea {
|
|
227
|
+
width: 100%;
|
|
228
|
+
box-sizing: border-box;
|
|
229
|
+
font: inherit;
|
|
230
|
+
padding: 4px 7px;
|
|
231
|
+
}
|
|
232
|
+
/* A one-line box that grows to fit its value — `autoGrow` sets the
|
|
233
|
+
height, these bound it. Whole-px line metrics so N lines is an exact
|
|
234
|
+
height: 19 + 8 padding + 2 border = 29px for one line, 86px for the
|
|
235
|
+
four this caps at, after which it scrolls. Not user-resizable: the
|
|
236
|
+
content already decides the height. */
|
|
237
|
+
.sm-dialog textarea {
|
|
238
|
+
line-height: 19px;
|
|
239
|
+
min-height: 29px;
|
|
240
|
+
max-height: 86px;
|
|
241
|
+
resize: none;
|
|
242
|
+
overflow-y: auto;
|
|
243
|
+
}
|
|
244
|
+
.sm-dialog input[type="text"][hidden] { display: none; }
|
|
245
|
+
.sm-dialog input[type="text"]:disabled {
|
|
246
|
+
background: #f3f4f6;
|
|
247
|
+
color: #666;
|
|
248
|
+
border-color: #d1d5db;
|
|
249
|
+
}
|
|
250
|
+
/* `border-style` too: the UA gives text inputs an inset border, and
|
|
251
|
+
recolouring an inset border shades each side a different tint. */
|
|
252
|
+
.sm-dialog input[type="text"].invalid { border-style: solid; border-color: #b00; outline-color: #b00; }
|
|
253
|
+
/* The Type row: the inferred bubble, plus a hint for the one state
|
|
254
|
+
that has nothing to report in the error slot yet. */
|
|
255
|
+
.sm-dialog .dlg-type { display: flex; gap: 8px; align-items: baseline; padding-top: 3px; }
|
|
256
|
+
/* The shared bubble dims on hover because everywhere else it is a link.
|
|
257
|
+
This one is a report, not a target. */
|
|
258
|
+
.sm-dialog .dlg-type .collection-type-bubble:hover { opacity: 1; }
|
|
259
|
+
.sm-dialog .dlg-check {
|
|
260
|
+
display: flex;
|
|
261
|
+
gap: 6px;
|
|
262
|
+
align-items: baseline;
|
|
263
|
+
cursor: pointer;
|
|
264
|
+
}
|
|
265
|
+
.sm-dialog .dlg-check input { margin: 0; position: relative; top: 1px; flex: 0 0 auto; }
|
|
266
|
+
.sm-dialog .dlg-hint { color: #666; font-size: 0.85em; }
|
|
267
|
+
.sm-dialog .dlg-check.off { opacity: 0.5; cursor: default; }
|
|
268
|
+
.sm-dialog .dlg-error-row {
|
|
269
|
+
display: flex;
|
|
270
|
+
gap: 8px;
|
|
271
|
+
align-items: baseline;
|
|
272
|
+
padding: 8px 16px 0;
|
|
273
|
+
}
|
|
274
|
+
.sm-dialog .dlg-error {
|
|
275
|
+
color: #b00;
|
|
276
|
+
/* Messages that name a file and then say what to do put the two on
|
|
277
|
+
separate lines. Every other message is one line and unaffected. */
|
|
278
|
+
white-space: pre-line;
|
|
279
|
+
margin: 0;
|
|
280
|
+
min-height: 1.3em;
|
|
281
|
+
line-height: 1.3;
|
|
282
|
+
}
|
|
283
|
+
.sm-dialog .dlg-error.warn { color: #92400e; }
|
|
284
|
+
/* Offered inside the error line — today only "Install script", under
|
|
285
|
+
the "this is a single script" verdict. Its own height: this sits
|
|
286
|
+
INSIDE a line of message text, so the shared button height would
|
|
287
|
+
grow the error row around it. */
|
|
288
|
+
.sm-dialog .dlg-error-action {
|
|
289
|
+
height: 18px;
|
|
290
|
+
font: inherit;
|
|
291
|
+
padding: 1px 8px;
|
|
292
|
+
cursor: pointer;
|
|
293
|
+
flex: 0 0 auto;
|
|
294
|
+
}
|
|
295
|
+
.sm-dialog .dlg-error-action[hidden] { display: none; }
|
|
296
|
+
/* Copy dialog (src/extension/copy-dialog.ts): read-only values in the body
|
|
297
|
+
grid, the dependency list under its checkbox, and the file-access
|
|
298
|
+
banner slot above the form. */
|
|
299
|
+
.sm-dialog .dlg-static { padding-top: 5px; min-width: 0; overflow-wrap: anywhere; }
|
|
300
|
+
.sm-dialog .dlg-target-name { font-weight: 600; }
|
|
301
|
+
.sm-dialog .dlg-banner:empty { display: none; }
|
|
302
|
+
.sm-dialog .dlg-banner { padding: 12px 16px 0; }
|
|
303
|
+
.sm-dialog .dlg-banner > * { margin: 0; }
|
|
304
|
+
.sm-dialog .dlg-deps { min-width: 0; padding-top: 3px; }
|
|
305
|
+
.sm-dialog .dlg-deps .dlg-hint { margin-top: 3px; }
|
|
306
|
+
/* The delete dialog's headed lists (src/extension/delete-dialog.ts): one block
|
|
307
|
+
per reason, stacked, each hidden whole when it holds no files.
|
|
308
|
+
Scoped to that dialog — the copy dialog builds its checkbox and list
|
|
309
|
+
inside a `.dlg-deps` of its own, and stacking that one would move a
|
|
310
|
+
row this feature has no business touching. */
|
|
311
|
+
.delete-dialog .dlg-deps { display: flex; flex-direction: column; gap: 8px; }
|
|
312
|
+
/* Beats the `display: flex` above, which would otherwise leave a script
|
|
313
|
+
with no dependency files an empty grid row and its row-gap. */
|
|
314
|
+
.delete-dialog .dlg-deps[hidden] { display: none; }
|
|
315
|
+
.delete-dialog .dlg-dep-group[hidden] { display: none; }
|
|
316
|
+
.delete-dialog .dlg-dep-group .dlg-hint { margin-top: 0; }
|
|
317
|
+
/* A path + its copy button on one line: the script file's full path,
|
|
318
|
+
and each dependency file in the lists below it. */
|
|
319
|
+
.delete-dialog .dlg-path-row { display: flex; align-items: center; gap: 0.4em; }
|
|
320
|
+
.delete-dialog .dlg-path-row > span { overflow-wrap: anywhere; }
|
|
321
|
+
/* `display: flex` on an `li` drops its marker; `list-item` inside the
|
|
322
|
+
flex row would break the layout, so the bullet comes back as a
|
|
323
|
+
pseudo-element. */
|
|
324
|
+
.delete-dialog li.dlg-path-row { list-style: none; position: relative; }
|
|
325
|
+
.delete-dialog li.dlg-path-row::before { content: '•'; position: absolute; left: -1em; }
|
|
326
|
+
/* One size everywhere in the dialog: the rows differ in font size, so
|
|
327
|
+
the button's `em` sizing would otherwise differ with them. */
|
|
328
|
+
.delete-dialog .dlg-path-row .copy-btn { width: 20px; height: 20px; }
|
|
329
|
+
.sm-dialog .dlg-deps-list {
|
|
330
|
+
margin: 4px 0 0;
|
|
331
|
+
padding-left: 1.2em;
|
|
332
|
+
font-size: 0.85em;
|
|
333
|
+
color: #444;
|
|
334
|
+
max-height: 6.5em;
|
|
335
|
+
overflow-y: auto;
|
|
336
|
+
}
|
|
337
|
+
.sm-dialog .dlg-deps-list:empty { display: none; }
|
|
338
|
+
/* A dependency file the copy would overwrite, marked in the list. The
|
|
339
|
+
warning colour, not the error one: the same fact the line at the
|
|
340
|
+
bottom of the dialog reports, and Replace is a choice, not a fault. */
|
|
341
|
+
.sm-dialog .dlg-exists { color: #92400e; }
|
|
342
|
+
/* A second line under a field's label, for what it accepts that its
|
|
343
|
+
name doesn't say. */
|
|
344
|
+
.sm-dialog .dlg-label-note { display: block; font-size: 0.85em; color: #666; }
|
|
345
|
+
/* A heading INSIDE the body grid, spanning both its columns. */
|
|
346
|
+
.sm-dialog .dlg-section { grid-column: 1 / -1; font-weight: 600; }
|
|
347
|
+
/* `<original> -> [new value]` in one field row. */
|
|
348
|
+
.sm-dialog .dlg-arrow { display: flex; gap: 7px; align-items: center; min-width: 0; }
|
|
349
|
+
.sm-dialog .dlg-arrow input[type="text"] { flex: 1 1 auto; min-width: 0; }
|
|
350
|
+
/* The old value is shown in full, never elided. It takes exactly the
|
|
351
|
+
width its text needs (`flex-shrink: 0`, so the box beside it gives
|
|
352
|
+
way first rather than the two splitting the squeeze and wrapping it
|
|
353
|
+
mid-version as `1.0.` / `6`), and stops at half the row — a version
|
|
354
|
+
longer than that wraps inside its half. */
|
|
355
|
+
.sm-dialog .dlg-was {
|
|
356
|
+
flex: 0 0 auto;
|
|
357
|
+
max-width: 50%;
|
|
358
|
+
overflow-wrap: anywhere;
|
|
359
|
+
}
|
|
360
|
+
.sm-dialog .dlg-arrow-mark { color: #666; flex: 0 0 auto; }
|
|
361
|
+
/* Copy's dependency hint + list while the box is unticked: what would
|
|
362
|
+
happen, not what will. Same dimming as the unavailable checkbox. */
|
|
363
|
+
.sm-dialog .dimmed { opacity: 0.5; }
|
|
364
|
+
.sm-dialog .dlg-deps-list li { overflow-wrap: anywhere; }
|
|
365
|
+
.sm-dialog .dlg-actions {
|
|
366
|
+
display: flex;
|
|
367
|
+
justify-content: flex-end;
|
|
368
|
+
align-items: center;
|
|
369
|
+
gap: 8px;
|
|
370
|
+
padding: 12px 16px 14px;
|
|
371
|
+
}
|
|
372
|
+
.sm-dialog .dlg-actions button { padding: 0 11px; }
|
|
373
|
+
.sm-dialog .dlg-actions button.primary { font-weight: 600; }
|
|
374
|
+
/* The confirm of a dialog that destroys something (src/extension/delete-dialog.ts).
|
|
375
|
+
Coloured, not just bold: the button is one click from files leaving
|
|
376
|
+
the disk with nothing to undo it. */
|
|
377
|
+
.sm-dialog .dlg-actions button.danger { color: #b00; }
|
|
378
|
+
@keyframes sm-spin { to { transform: rotate(360deg); } }
|
|
379
|
+
.sm-dialog .busy-spinner {
|
|
380
|
+
display: inline-block;
|
|
381
|
+
width: 12px;
|
|
382
|
+
height: 12px;
|
|
383
|
+
border: 2px solid #ccc;
|
|
384
|
+
border-top-color: #555;
|
|
385
|
+
border-radius: 50%;
|
|
386
|
+
animation: sm-spin 0.7s linear infinite;
|
|
387
|
+
box-sizing: border-box;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
/* ---- "Install into" dropdown (src/extension/related-versions.ts) ---- */
|
|
391
|
+
/* Ellipsised, not clipped: the control gives way to its neighbours
|
|
392
|
+
where a collection name is longer than the row (see the install
|
|
393
|
+
callout and the panel's offer row), and Chrome sizes the OPEN list
|
|
394
|
+
to its widest option, so the full name is still readable there. */
|
|
395
|
+
select.install-target {
|
|
396
|
+
font: inherit;
|
|
397
|
+
padding: 3px 6px;
|
|
398
|
+
max-width: 100%;
|
|
399
|
+
text-overflow: ellipsis;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
/* ---- Icon buttons (src/extension/glyph.ts, src/extension/delete-icon.ts) ---- */
|
|
403
|
+
|
|
404
|
+
/* Every button whose content is a glyph — the removal cans, the
|
|
405
|
+
refresh arrow, the options gear — is one control with one look, on
|
|
406
|
+
every page. `.icon-btn` is put on by the code that paints the glyph,
|
|
407
|
+
so a button can't get the icon without the box.
|
|
408
|
+
|
|
409
|
+
The box is SET, not inferred. Letting each button size itself off
|
|
410
|
+
its content is what gave five identically-sized icons five different
|
|
411
|
+
button widths: three padding values, a text arrow measuring
|
|
412
|
+
differently from an SVG, and `align-self: stretch` on one of them.
|
|
413
|
+
Here the height and the glyph are both fixed, so every icon button
|
|
414
|
+
in a row lines up by construction, and the whole-pixel rule for the
|
|
415
|
+
collections page and the versions panel (docs/architecture.md,
|
|
416
|
+
"Extension-page styling") falls out for free — no `em` in any
|
|
417
|
+
vertical metric.
|
|
418
|
+
|
|
419
|
+
A dense context can shrink the pair by redefining the two custom
|
|
420
|
+
properties on an ancestor; nothing else needs to change. */
|
|
421
|
+
:root {
|
|
422
|
+
--icon-btn-size: 26px;
|
|
423
|
+
--icon-btn-glyph: 16px;
|
|
424
|
+
/* One button surface for every page. Chrome's own button paints no
|
|
425
|
+
hover or press state once an author background is set, and setting
|
|
426
|
+
one on only SOME buttons (the removal cans' red hover) left a row
|
|
427
|
+
where half the controls reacted to the pointer and half didn't.
|
|
428
|
+
So the whole progression is ours, and it only ever gets darker:
|
|
429
|
+
rest -> hover -> pressed. */
|
|
430
|
+
--btn-bg: #f6f6f6;
|
|
431
|
+
--btn-bg-hover: #e7e7e7;
|
|
432
|
+
--btn-bg-active: #d6d6d6;
|
|
433
|
+
--btn-border: #bbb;
|
|
434
|
+
--btn-fg: #222;
|
|
435
|
+
/* The destructive pair, same direction of travel. */
|
|
436
|
+
--btn-bg-danger-hover: #f5c2c7;
|
|
437
|
+
--btn-bg-danger-active: #e9a3ab;
|
|
438
|
+
--btn-fg-danger: #a3372c;
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
/* THE button surface, for every button in the extension — both pages,
|
|
442
|
+
the Options page, and every dialog. Anything that does not opt out
|
|
443
|
+
rests, hovers and presses the same, and the press is always DARKER
|
|
444
|
+
than the hover, never lighter.
|
|
445
|
+
|
|
446
|
+
`:where()` puts the whole thing at zero specificity, which is what
|
|
447
|
+
makes it safe to apply this broadly: it is a baseline, not an
|
|
448
|
+
override. Any class rule beats it, so a control keeps whatever it
|
|
449
|
+
sets for itself — but only what it actually sets. A rule that
|
|
450
|
+
declares a background and no height gets its own background and
|
|
451
|
+
THIS height; the fold triangle and the code tabs each pin a height
|
|
452
|
+
because of that, not by default.
|
|
453
|
+
|
|
454
|
+
Chrome paints no hover or press state on a native button, and the
|
|
455
|
+
moment any author background is set it stops painting one at all.
|
|
456
|
+
So this is not decoration: without it, whether a button reacts to
|
|
457
|
+
being pressed depended on whether some page had happened to style
|
|
458
|
+
it. */
|
|
459
|
+
:where(button) {
|
|
460
|
+
/* One height too, not just one surface. A button that isn't in some
|
|
461
|
+
hand-kept list of selectors still has to line up with the ones
|
|
462
|
+
beside it — the alternative is finding them one at a time. A
|
|
463
|
+
control that genuinely needs another size sets its own `height`
|
|
464
|
+
in a class rule, which (like everything here) outranks this. */
|
|
465
|
+
box-sizing: border-box;
|
|
466
|
+
height: var(--icon-btn-size);
|
|
467
|
+
font: inherit;
|
|
468
|
+
line-height: 1;
|
|
469
|
+
border: 1px solid var(--btn-border);
|
|
470
|
+
border-radius: 3px;
|
|
471
|
+
background: var(--btn-bg);
|
|
472
|
+
color: var(--btn-fg);
|
|
473
|
+
cursor: pointer;
|
|
474
|
+
}
|
|
475
|
+
:where(button:hover:not(:disabled)) { background: var(--btn-bg-hover); }
|
|
476
|
+
:where(button:active:not(:disabled)) { background: var(--btn-bg-active); }
|
|
477
|
+
:where(button:disabled) { cursor: not-allowed; opacity: 0.5; }
|
|
478
|
+
/* The blue ring the rest of the extension already uses (the code tabs,
|
|
479
|
+
the copy button, the panel's rows). The removal buttons carried their
|
|
480
|
+
own copy of this before their per-page rules were folded in here; a
|
|
481
|
+
glyph has no shape of its own to show focus with, so it can't be left
|
|
482
|
+
to the UA's. */
|
|
483
|
+
:where(button:focus-visible) { outline: 2px solid #4a90e2; outline-offset: 1px; }
|
|
484
|
+
|
|
485
|
+
/* `font: inherit` above takes the bold from a `<th>`, and the versions
|
|
486
|
+
table's "Refresh all" sits in a header cell. */
|
|
487
|
+
.versions-table button { font-weight: 400; }
|
|
488
|
+
|
|
489
|
+
/* What makes it an ICON button, on top of the shared surface above:
|
|
490
|
+
a square minimum so a lone glyph gets a box rather than a slot, and
|
|
491
|
+
centring for the glyph (plus a label, where it has one). */
|
|
492
|
+
.icon-btn {
|
|
493
|
+
min-width: var(--icon-btn-size);
|
|
494
|
+
padding: 0 6px;
|
|
495
|
+
/* Snug around a lone glyph; a labelled one takes the roomier padding
|
|
496
|
+
of the text buttons it sits beside (`.icon-btn` is a class and
|
|
497
|
+
would otherwise outrank a page's own `button` rule). */
|
|
498
|
+
display: inline-flex;
|
|
499
|
+
align-items: center;
|
|
500
|
+
justify-content: center;
|
|
501
|
+
gap: 0.4em;
|
|
502
|
+
vertical-align: middle;
|
|
503
|
+
}
|
|
504
|
+
.icon-btn:has(.btn-label) { padding: 0 11px; }
|
|
505
|
+
/* An author `display` outranks the UA's `[hidden] { display: none }`,
|
|
506
|
+
and this codebase does hide buttons with the attribute. */
|
|
507
|
+
.icon-btn[hidden] { display: none; }
|
|
508
|
+
.icon-btn:disabled { cursor: not-allowed; opacity: 0.4; }
|
|
509
|
+
|
|
510
|
+
/* The glyph fills a fixed square inside that box; it never sizes off
|
|
511
|
+
the font, so a button in 13px text and one in 14px text still hold
|
|
512
|
+
the same icon. */
|
|
513
|
+
.icon-btn .btn-glyph,
|
|
514
|
+
.icon-btn .delete-icon {
|
|
515
|
+
width: var(--icon-btn-glyph);
|
|
516
|
+
height: var(--icon-btn-glyph);
|
|
517
|
+
display: block;
|
|
518
|
+
flex: none;
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
/* Destructive: the removal cans hover red, and the one that deletes a
|
|
522
|
+
FILE also rests red. Shape (the disk badge on its glyph) and colour
|
|
523
|
+
both say it, because colour on its own isn't a cue every user gets. */
|
|
524
|
+
.icon-btn.remove-script:hover:not(:disabled),
|
|
525
|
+
.icon-btn.versions-remove:hover:not(:disabled) {
|
|
526
|
+
background: var(--btn-bg-danger-hover);
|
|
527
|
+
color: #b00;
|
|
528
|
+
}
|
|
529
|
+
.icon-btn.remove-script:active:not(:disabled),
|
|
530
|
+
.icon-btn.versions-remove:active:not(:disabled) { background: var(--btn-bg-danger-active); }
|
|
531
|
+
.icon-btn.deletes-file { color: var(--btn-fg-danger); }
|
|
532
|
+
|
|
533
|
+
/* In-flight. The glyph spins in place instead of the label changing to
|
|
534
|
+
"Refreshing…" — an icon-only button has no label to change, and a
|
|
535
|
+
fixed box means nothing moves while it spins. */
|
|
536
|
+
.btn-glyph.spinning {
|
|
537
|
+
animation: sm-spin 1.1s linear infinite;
|
|
538
|
+
transform-origin: 50% 50%;
|
|
539
|
+
}
|
|
540
|
+
@media (prefers-reduced-motion: reduce) {
|
|
541
|
+
.btn-glyph.spinning { animation: none; opacity: 0.55; }
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
/* ---- Page header bar (every extension page) ---- */
|
|
545
|
+
|
|
546
|
+
/* One bar across the top of every page: the extension icon, the
|
|
547
|
+
"SourceMonkey | <page>" heading, and whatever cross-page navigation
|
|
548
|
+
that page offers, pushed to the right edge.
|
|
549
|
+
|
|
550
|
+
Brown rather than the obvious green: the bar sits directly above the
|
|
551
|
+
viewer's green "Other versions" card and the amber warning banner
|
|
552
|
+
slot, and a green bar would read as the top of that card. Brown is
|
|
553
|
+
where the monkey icon's own colours live, and it is desaturated
|
|
554
|
+
enough not to be mistaken for the amber banner. */
|
|
555
|
+
:root {
|
|
556
|
+
--brand-fg: #6b4423;
|
|
557
|
+
--header-bg: #f2e9dc;
|
|
558
|
+
--header-border: #b59a78;
|
|
559
|
+
/* The content column every page centres. The bar's contents honour
|
|
560
|
+
it too, so the heading starts at the same x as the page body
|
|
561
|
+
underneath rather than at the window edge. Pages that run
|
|
562
|
+
full-bleed (the viewer) leave it unset. */
|
|
563
|
+
--page-width: none;
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
/* Full-bleed background; the inner row is what gets constrained. The
|
|
567
|
+
16px side padding matches the page body's, so the two content edges
|
|
568
|
+
line up at every window width. */
|
|
569
|
+
.page-header {
|
|
570
|
+
background: var(--header-bg);
|
|
571
|
+
border-bottom: 1px solid var(--header-border);
|
|
572
|
+
padding: 0 16px;
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
.page-header-inner {
|
|
576
|
+
display: flex;
|
|
577
|
+
align-items: center;
|
|
578
|
+
gap: 10px;
|
|
579
|
+
/* Whole pixels, like the rest of the vertical metrics — see
|
|
580
|
+
docs/architecture.md, "Extension-page styling". */
|
|
581
|
+
padding: 8px 0;
|
|
582
|
+
max-width: var(--page-width);
|
|
583
|
+
margin: 0 auto;
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
.page-icon {
|
|
587
|
+
flex: 0 0 auto;
|
|
588
|
+
width: 24px;
|
|
589
|
+
height: 24px;
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
/* The heading takes the row's slack so the actions sit at the right
|
|
593
|
+
edge; `min-width: 0` lets a long script name wrap instead of
|
|
594
|
+
pushing them off. */
|
|
595
|
+
.page-header h1 {
|
|
596
|
+
flex: 1 1 auto;
|
|
597
|
+
min-width: 0;
|
|
598
|
+
margin: 0;
|
|
599
|
+
font-size: 1.15em;
|
|
600
|
+
font-weight: 700;
|
|
601
|
+
color: #222;
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
/* The product name and the separators after it, in the brand colour —
|
|
605
|
+
the same split the icon makes visually. The page name between or after
|
|
606
|
+
them stays in the heading's own colour.
|
|
607
|
+
|
|
608
|
+
Two shapes wear it, both rendering the same thing:
|
|
609
|
+
- Collections and Options spell it in their markup, as one span
|
|
610
|
+
around `SourceMonkey |`.
|
|
611
|
+
- The viewer builds it (`headingPrefixEl`, src/extension/page-heading.ts), a
|
|
612
|
+
span per term, because its heading has a page name in the middle
|
|
613
|
+
("SourceMonkey | Install | <script>"). Those spans wear
|
|
614
|
+
`.heading-prefix` as well. */
|
|
615
|
+
.page-header h1 .brand { color: var(--brand-fg); }
|
|
616
|
+
|
|
617
|
+
/* The icon and the product name are a link home to the collections
|
|
618
|
+
page (src/extension/page-links.ts). Styled to look like the bar, not like a
|
|
619
|
+
link: it is chrome, and underlining it permanently would read as an
|
|
620
|
+
error. The underline on hover is what says it is clickable.
|
|
621
|
+
|
|
622
|
+
Deliberately NO colour here. The product name is `.brand` inside the
|
|
623
|
+
`<h1>`, so the rule above already paints it, and a `color` on this
|
|
624
|
+
selector would tie with that one on specificity and win on source
|
|
625
|
+
order — leaving a near-black "SourceMonkey" beside a brown `|`. */
|
|
626
|
+
.page-header a.page-home { text-decoration: none; }
|
|
627
|
+
.page-header a.page-home:hover { text-decoration: underline; }
|
|
628
|
+
|
|
629
|
+
/* The icon's wrapper: flex so the anchor is exactly the image's box
|
|
630
|
+
with no inline-layout gap under it, and `flex: 0 0 auto` because the
|
|
631
|
+
anchor is now the row's item, not the image. It sits outside the
|
|
632
|
+
`<h1>`, so nothing else colours it and the link blue has to be
|
|
633
|
+
turned off here. */
|
|
634
|
+
.page-header .page-icon-link {
|
|
635
|
+
flex: 0 0 auto;
|
|
636
|
+
display: flex;
|
|
637
|
+
color: inherit;
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
.page-header-actions {
|
|
641
|
+
flex: 0 0 auto;
|
|
642
|
+
display: flex;
|
|
643
|
+
align-items: center;
|
|
644
|
+
gap: 6px;
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
/* The page's own content column, under the bar. Content-box sizing so
|
|
648
|
+
`--page-width` means the text column, not the column plus padding —
|
|
649
|
+
that is what makes it line up with the bar's inner row. */
|
|
650
|
+
.page-body {
|
|
651
|
+
box-sizing: content-box;
|
|
652
|
+
max-width: var(--page-width);
|
|
653
|
+
margin: 0 auto;
|
|
654
|
+
padding: 24px 16px;
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
/* Square icon-only copy-to-clipboard button (src/extension/copy-button.ts), beside
|
|
658
|
+
a path in the viewer's Location row and the delete dialog's file row.
|
|
659
|
+
Swaps the copy icon for a checkmark while the .copied class is on it
|
|
660
|
+
(set briefly after a successful clipboard write). */
|
|
661
|
+
.copy-btn {
|
|
662
|
+
flex: 0 0 auto;
|
|
663
|
+
width: 1.6em;
|
|
664
|
+
height: 1.6em;
|
|
665
|
+
padding: 0;
|
|
666
|
+
display: inline-flex;
|
|
667
|
+
align-items: center;
|
|
668
|
+
justify-content: center;
|
|
669
|
+
border: 1px solid #bbb;
|
|
670
|
+
border-radius: 3px;
|
|
671
|
+
background: #fff;
|
|
672
|
+
color: #444;
|
|
673
|
+
cursor: pointer;
|
|
674
|
+
}
|
|
675
|
+
.copy-btn:hover { background: #eee; }
|
|
676
|
+
.copy-btn:active { background: #ddd; }
|
|
677
|
+
.copy-btn:focus-visible { outline: 2px solid #4a90e2; outline-offset: 1px; }
|
|
678
|
+
.copy-btn svg { width: 14px; height: 14px; display: block; }
|
|
679
|
+
.copy-btn .check-icon { display: none; color: #166534; }
|
|
680
|
+
.copy-btn.copied .copy-icon { display: none; }
|
|
681
|
+
.copy-btn.copied .check-icon { display: block; }
|
|
682
|
+
|
|
683
|
+
/* "deleted" / "modified" chip after a local file path whose file has
|
|
684
|
+
gone or changed on disk since it was read (src/extension/file-changes.ts).
|
|
685
|
+
Sized like `.scheme-chip` above but square-cornered like the
|
|
686
|
+
viewer's tab marks, so it reads as a remark on the path rather than
|
|
687
|
+
a collection kind. Red for a file that isn't there; amber for one
|
|
688
|
+
that is, but differs from what is loaded. */
|
|
689
|
+
.file-change-chip {
|
|
690
|
+
display: inline-block;
|
|
691
|
+
margin-left: 0.5em;
|
|
692
|
+
padding: 0 0.4em;
|
|
693
|
+
border-radius: 3px;
|
|
694
|
+
color: #fff;
|
|
695
|
+
font-size: 10px;
|
|
696
|
+
font-weight: 600;
|
|
697
|
+
text-transform: uppercase;
|
|
698
|
+
letter-spacing: 0.04em;
|
|
699
|
+
vertical-align: 1px;
|
|
700
|
+
cursor: default;
|
|
701
|
+
/* `text-indent` inherits into an inline-block and would shove the
|
|
702
|
+
word out of the chip on the collections page's hanging-indent
|
|
703
|
+
name cells. */
|
|
704
|
+
text-indent: 0;
|
|
705
|
+
/* A chip is one word and never breaks: in a flex row it must not
|
|
706
|
+
shrink (the path beside it wraps instead), and inherited
|
|
707
|
+
`overflow-wrap: anywhere` / `word-break` must not split it. */
|
|
708
|
+
flex: 0 0 auto;
|
|
709
|
+
white-space: nowrap;
|
|
710
|
+
overflow-wrap: normal;
|
|
711
|
+
word-break: normal;
|
|
712
|
+
}
|
|
713
|
+
.file-change-chip-missing { background: #b91c1c; }
|
|
714
|
+
/* Teal for "differs from what is loaded": a modified file, and the
|
|
715
|
+
collection whose refresh would pick such changes up. Chosen to be
|
|
716
|
+
unlike the amber the FILE-DIR bubble wears, which sits inches away. */
|
|
717
|
+
.file-change-chip-modified,
|
|
718
|
+
.file-change-chip-pending { background: #0f766e; }
|
|
719
|
+
/* Inside a flex row that already spaces its children with `gap` (the
|
|
720
|
+
viewer's Location and Local overrides rows), the margin would double
|
|
721
|
+
the gap on the chip's left only. */
|
|
722
|
+
.filename-cell > .file-change-chip,
|
|
723
|
+
.local-override-cell > .file-change-chip { margin-left: 0; }
|
|
724
|
+
|
|
725
|
+
/* ---- Tab strip over a code box (src/extension/code-tabs.ts, src/extension/compare.ts) ---- */
|
|
726
|
+
|
|
727
|
+
/* One file per tab: the viewer's main script, `@require`s and Log; the
|
|
728
|
+
compare page's per-file diffs. The active tab's bottom border takes
|
|
729
|
+
the box's own colour so it "opens into" the box below, which sits
|
|
730
|
+
1px up to meet it (each page's own `margin-top: -1px`). */
|
|
731
|
+
.tabs {
|
|
732
|
+
display: flex;
|
|
733
|
+
flex: 0 0 auto;
|
|
734
|
+
gap: 3px;
|
|
735
|
+
margin: 0;
|
|
736
|
+
padding: 0;
|
|
737
|
+
overflow-x: auto;
|
|
738
|
+
}
|
|
739
|
+
/* An author `display` outranks the UA's `[hidden] { display: none }`. */
|
|
740
|
+
.tabs[hidden] { display: none; }
|
|
741
|
+
.tab {
|
|
742
|
+
/* Its own height: a tab sizes to its label and the strip's bottom
|
|
743
|
+
edge, and the shared button height squeezes the label's line box. */
|
|
744
|
+
height: auto;
|
|
745
|
+
font: inherit;
|
|
746
|
+
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
|
|
747
|
+
font-size: 12px;
|
|
748
|
+
line-height: 1.2;
|
|
749
|
+
padding: 0.45em 0.9em;
|
|
750
|
+
border: 1px solid #ccc;
|
|
751
|
+
border-radius: 4px 4px 0 0;
|
|
752
|
+
background: #e4e4e4;
|
|
753
|
+
color: #555;
|
|
754
|
+
cursor: pointer;
|
|
755
|
+
white-space: nowrap;
|
|
756
|
+
}
|
|
757
|
+
.tab:hover { background: #efefef; }
|
|
758
|
+
/* Hover lightens a tab toward the selected look, so pressing goes the
|
|
759
|
+
other way to stay a press. */
|
|
760
|
+
.tab:active:not(.active) { background: #d4d4d4; }
|
|
761
|
+
.tab.active {
|
|
762
|
+
background: #fafafa;
|
|
763
|
+
color: #222;
|
|
764
|
+
font-weight: 600;
|
|
765
|
+
border-bottom-color: #fafafa;
|
|
766
|
+
}
|
|
767
|
+
.tab:focus-visible { outline: 2px solid #4a90e2; outline-offset: -2px; }
|
|
768
|
+
|
|
769
|
+
/* ---- Site favicons (src/extension/site-icon.ts) ---- */
|
|
770
|
+
|
|
771
|
+
/* The icons inside a slot: one clickable <a> (or inert <span>) per
|
|
772
|
+
site, each a globe until the real favicon lands. The slot itself is
|
|
773
|
+
each page's own — a table's fixed-width column on the collections
|
|
774
|
+
page, the heading's on the viewer and compare pages (below). */
|
|
775
|
+
.site-icon-inner {
|
|
776
|
+
display: block;
|
|
777
|
+
width: 16px;
|
|
778
|
+
height: 16px;
|
|
779
|
+
flex: 0 0 auto;
|
|
780
|
+
color: #888;
|
|
781
|
+
}
|
|
782
|
+
a.site-icon-inner { text-decoration: none; }
|
|
783
|
+
a.site-icon-inner:hover { color: #444; }
|
|
784
|
+
.site-icon img { width: 16px; height: 16px; display: block; }
|
|
785
|
+
.site-icon-globe { width: 16px; height: 16px; display: block; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
|
|
786
|
+
|
|
787
|
+
/* Slot for the site favicons, sitting between the heading's
|
|
788
|
+
product prefix and the script's name. Always present, and at
|
|
789
|
+
least one icon wide, so the name starts at the same offset past
|
|
790
|
+
the prefix whether or not a favicon resolves. Holds one
|
|
791
|
+
clickable <a> per distinct site the script's @match names
|
|
792
|
+
(side by side, 2px gap), or one inert <span> when it names
|
|
793
|
+
none.
|
|
794
|
+
Inner content is a globe placeholder until the real favicon
|
|
795
|
+
loads. */
|
|
796
|
+
.page-header h1 .site-icon {
|
|
797
|
+
display: inline-flex;
|
|
798
|
+
gap: 2px;
|
|
799
|
+
min-width: 16px;
|
|
800
|
+
height: 16px;
|
|
801
|
+
margin-right: 0.4em;
|
|
802
|
+
/* Centred on the heading's CAP band, not on its baseline or its
|
|
803
|
+
descender line. `text-bottom` sits the 16px square on the
|
|
804
|
+
font's descender, which puts its centre ~1.4px below the
|
|
805
|
+
centre of the letters beside it — visible as a favicon
|
|
806
|
+
hanging low. The heading is 16.1px with a 12px cap height, so
|
|
807
|
+
2px of the square below the baseline centres the two. */
|
|
808
|
+
vertical-align: -2px;
|
|
809
|
+
}
|
|
810
|
+
|
|
811
|
+
/* The menu a ⋯ button opens (src/extension/more-menu.ts), on the
|
|
812
|
+
toolbar popup and the collections page. Each page styles its own
|
|
813
|
+
`button.more-menu`. */
|
|
814
|
+
.menu {
|
|
815
|
+
position: fixed; z-index: 10; min-width: 220px;
|
|
816
|
+
background: #fff; border: 1px solid #c9c2b8; border-radius: 6px;
|
|
817
|
+
box-shadow: 0 6px 18px rgba(0, 0, 0, 0.16); padding: 4px 0;
|
|
818
|
+
}
|
|
819
|
+
.menu button {
|
|
820
|
+
display: block; width: 100%; height: auto; text-align: left;
|
|
821
|
+
border: none; border-radius: 0; background: transparent; padding: 5px 12px; font-size: 12.5px;
|
|
822
|
+
}
|
|
823
|
+
.menu button:hover:not(:disabled), .menu button:focus-visible { background: #f3efe9; }
|
|
824
|
+
.menu button:disabled { color: #a0a0a0; cursor: default; }
|
|
825
|
+
.menu hr { border: none; border-top: 1px solid var(--rule, #e3ddd4); margin: 4px 0; }
|