max / goingson
- Co-Authored-By
- Claude Opus 5 (1M context) <noreply@anthropic.com>
4 files changed,
+100 insertions,
-26 deletions
| @@ -1387,7 +1387,7 @@ | |||
| 1387 | 1387 | "libc", | |
| 1388 | 1388 | "option-ext", | |
| 1389 | 1389 | "redox_users", | |
| 1390 | - | "windows-sys 0.60.2", | |
| 1390 | + | "windows-sys 0.61.2", | |
| 1391 | 1391 | ] | |
| 1392 | 1392 | ||
| 1393 | 1393 | [[package]] | |
| @@ -1628,7 +1628,7 @@ | |||
| 1628 | 1628 | checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" | |
| 1629 | 1629 | dependencies = [ | |
| 1630 | 1630 | "libc", | |
| 1631 | - | "windows-sys 0.60.2", | |
| 1631 | + | "windows-sys 0.61.2", | |
| 1632 | 1632 | ] | |
| 1633 | 1633 | ||
| 1634 | 1634 | [[package]] | |
| @@ -3650,7 +3650,7 @@ | |||
| 3650 | 3650 | "png 0.18.1", | |
| 3651 | 3651 | "serde", | |
| 3652 | 3652 | "thiserror 2.0.20", | |
| 3653 | - | "windows-sys 0.60.2", | |
| 3653 | + | "windows-sys 0.61.2", | |
| 3654 | 3654 | ] | |
| 3655 | 3655 | ||
| 3656 | 3656 | [[package]] | |
| @@ -3783,7 +3783,7 @@ | |||
| 3783 | 3783 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
| 3784 | 3784 | checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" | |
| 3785 | 3785 | dependencies = [ | |
| 3786 | - | "windows-sys 0.60.2", | |
| 3786 | + | "windows-sys 0.61.2", | |
| 3787 | 3787 | ] | |
| 3788 | 3788 | ||
| 3789 | 3789 | [[package]] | |
| @@ -4717,7 +4717,7 @@ | |||
| 4717 | 4717 | ||
| 4718 | 4718 | [[package]] | |
| 4719 | 4719 | name = "quasi-http" | |
| 4720 | - | version = "0.67.0" | |
| 4720 | + | version = "0.68.0" | |
| 4721 | 4721 | dependencies = [ | |
| 4722 | 4722 | "form_urlencoded", | |
| 4723 | 4723 | "http", | |
| @@ -4726,7 +4726,7 @@ | |||
| 4726 | 4726 | ||
| 4727 | 4727 | [[package]] | |
| 4728 | 4728 | name = "quasi-notifs" | |
| 4729 | - | version = "0.67.0" | |
| 4729 | + | version = "0.68.0" | |
| 4730 | 4730 | dependencies = [ | |
| 4731 | 4731 | "quasi-router", | |
| 4732 | 4732 | "synckit-config", | |
| @@ -4734,14 +4734,14 @@ | |||
| 4734 | 4734 | ||
| 4735 | 4735 | [[package]] | |
| 4736 | 4736 | name = "quasi-router" | |
| 4737 | - | version = "0.67.0" | |
| 4737 | + | version = "0.68.0" | |
| 4738 | 4738 | dependencies = [ | |
| 4739 | 4739 | "makeover-layout", | |
| 4740 | 4740 | ] | |
| 4741 | 4741 | ||
| 4742 | 4742 | [[package]] | |
| 4743 | 4743 | name = "quasi-tauri" | |
| 4744 | - | version = "0.67.0" | |
| 4744 | + | version = "0.68.0" | |
| 4745 | 4745 | dependencies = [ | |
| 4746 | 4746 | "http", | |
| 4747 | 4747 | "quasi-http", | |
| @@ -4767,7 +4767,7 @@ | |||
| 4767 | 4767 | ||
| 4768 | 4768 | [[package]] | |
| 4769 | 4769 | name = "quasi-webview" | |
| 4770 | - | version = "0.67.0" | |
| 4770 | + | version = "0.68.0" | |
| 4771 | 4771 | dependencies = [ | |
| 4772 | 4772 | "docengine", | |
| 4773 | 4773 | "makeover-layout", | |
| @@ -5206,7 +5206,7 @@ | |||
| 5206 | 5206 | "errno", | |
| 5207 | 5207 | "libc", | |
| 5208 | 5208 | "linux-raw-sys", | |
| 5209 | - | "windows-sys 0.60.2", | |
| 5209 | + | "windows-sys 0.61.2", | |
| 5210 | 5210 | ] | |
| 5211 | 5211 | ||
| 5212 | 5212 | [[package]] | |
| @@ -5263,7 +5263,7 @@ | |||
| 5263 | 5263 | "security-framework", | |
| 5264 | 5264 | "security-framework-sys", | |
| 5265 | 5265 | "webpki-root-certs", | |
| 5266 | - | "windows-sys 0.60.2", | |
| 5266 | + | "windows-sys 0.61.2", | |
| 5267 | 5267 | ] | |
| 5268 | 5268 | ||
| 5269 | 5269 | [[package]] | |
| @@ -5803,7 +5803,7 @@ | |||
| 5803 | 5803 | checksum = "c3d1e2c7f27f8d4cb10542a02c49005dbd6e93095799d6f3be745fae9f8fedd4" | |
| 5804 | 5804 | dependencies = [ | |
| 5805 | 5805 | "libc", | |
| 5806 | - | "windows-sys 0.60.2", | |
| 5806 | + | "windows-sys 0.61.2", | |
| 5807 | 5807 | ] | |
| 5808 | 5808 | ||
| 5809 | 5809 | [[package]] | |
| @@ -6578,7 +6578,7 @@ | |||
| 6578 | 6578 | "getrandom 0.4.3", | |
| 6579 | 6579 | "once_cell", | |
| 6580 | 6580 | "rustix", | |
| 6581 | - | "windows-sys 0.60.2", | |
| 6581 | + | "windows-sys 0.61.2", | |
| 6582 | 6582 | ] | |
| 6583 | 6583 | ||
| 6584 | 6584 | [[package]] | |
| @@ -6600,7 +6600,7 @@ | |||
| 6600 | 6600 | "parking_lot", | |
| 6601 | 6601 | "rustix", | |
| 6602 | 6602 | "signal-hook", | |
| 6603 | - | "windows-sys 0.60.2", | |
| 6603 | + | "windows-sys 0.61.2", | |
| 6604 | 6604 | ] | |
| 6605 | 6605 | ||
| 6606 | 6606 | [[package]] | |
| @@ -7082,7 +7082,7 @@ | |||
| 7082 | 7082 | "png 0.18.1", | |
| 7083 | 7083 | "serde", | |
| 7084 | 7084 | "thiserror 2.0.20", | |
| 7085 | - | "windows-sys 0.60.2", | |
| 7085 | + | "windows-sys 0.61.2", | |
| 7086 | 7086 | ] | |
| 7087 | 7087 | ||
| 7088 | 7088 | [[package]] | |
| @@ -7117,7 +7117,7 @@ | |||
| 7117 | 7117 | dependencies = [ | |
| 7118 | 7118 | "memoffset", | |
| 7119 | 7119 | "tempfile", | |
| 7120 | - | "windows-sys 0.60.2", | |
| 7120 | + | "windows-sys 0.61.2", | |
| 7121 | 7121 | ] | |
| 7122 | 7122 | ||
| 7123 | 7123 | [[package]] | |
| @@ -7647,7 +7647,7 @@ | |||
| 7647 | 7647 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
| 7648 | 7648 | checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" | |
| 7649 | 7649 | dependencies = [ | |
| 7650 | - | "windows-sys 0.60.2", | |
| 7650 | + | "windows-sys 0.61.2", | |
| 7651 | 7651 | ] | |
| 7652 | 7652 | ||
| 7653 | 7653 | [[package]] | |
| @@ -8506,15 +8506,15 @@ | |||
| 8506 | 8506 | ||
| 8507 | 8507 | [[patch.unused]] | |
| 8508 | 8508 | name = "quasi-axum" | |
| 8509 | - | version = "0.67.0" | |
| 8509 | + | version = "0.68.0" | |
| 8510 | 8510 | ||
| 8511 | 8511 | [[patch.unused]] | |
| 8512 | 8512 | name = "quasi-basics" | |
| 8513 | - | version = "0.67.0" | |
| 8513 | + | version = "0.68.0" | |
| 8514 | 8514 | ||
| 8515 | 8515 | [[patch.unused]] | |
| 8516 | 8516 | name = "quasi-immediate" | |
| 8517 | - | version = "0.67.0" | |
| 8517 | + | version = "0.68.0" | |
| 8518 | 8518 | ||
| 8519 | 8519 | [[patch.unused]] | |
| 8520 | 8520 | name = "quasi-store" |
| @@ -36,7 +36,7 @@ | |||
| 36 | 36 | makeover-geometry = "0.7" | |
| 37 | 37 | # Only to write its selection and clock scripts into the frontend. Those two are | |
| 38 | 38 | # the whole of `frontend/js/` since the swap. | |
| 39 | - | quasi-webview = { git = "https://makenot.work/git/max/quasi.git", version = "0.67" } | |
| 39 | + | quasi-webview = { git = "https://makenot.work/git/max/quasi.git", version = "0.68" } | |
| 40 | 40 | ||
| 41 | 41 | [dependencies] | |
| 42 | 42 | goingson-core = { workspace = true } | |
| @@ -54,10 +54,10 @@ | |||
| 54 | 54 | # dependency's source even with the feature off -- so a public clone could not | |
| 55 | 55 | # build at all against a URL it could not reach. quasi went public that day and | |
| 56 | 56 | # the URL moved here with it. | |
| 57 | - | quasi-router = { git = "https://makenot.work/git/max/quasi.git", version = "0.67" } | |
| 58 | - | quasi-http = { git = "https://makenot.work/git/max/quasi.git", version = "0.67" } | |
| 59 | - | quasi-webview = { git = "https://makenot.work/git/max/quasi.git", version = "0.67" } | |
| 60 | - | quasi-tauri = { git = "https://makenot.work/git/max/quasi.git", version = "0.67" } | |
| 57 | + | quasi-router = { git = "https://makenot.work/git/max/quasi.git", version = "0.68" } | |
| 58 | + | quasi-http = { git = "https://makenot.work/git/max/quasi.git", version = "0.68" } | |
| 59 | + | quasi-webview = { git = "https://makenot.work/git/max/quasi.git", version = "0.68" } | |
| 60 | + | quasi-tauri = { git = "https://makenot.work/git/max/quasi.git", version = "0.68" } | |
| 61 | 61 | ||
| 62 | 62 | # The notification declaration, and it is NOT behind the `quasi` feature: the | |
| 63 | 63 | # watcher is desktop app behaviour rather than a described screen, and the | |
| @@ -74,7 +74,7 @@ | |||
| 74 | 74 | # before it has ported its screens cannot take it. `notifications::Notifier` is | |
| 75 | 75 | # the eight lines meanwhile, and it goes when the flip makes quasi-router | |
| 76 | 76 | # unconditional here. | |
| 77 | - | quasi-notifs = { git = "https://makenot.work/git/max/quasi.git", version = "0.67", features = ["synckit", "describe"] } | |
| 77 | + | quasi-notifs = { git = "https://makenot.work/git/max/quasi.git", version = "0.68", features = ["synckit", "describe"] } | |
| 78 | 78 | ||
| 79 | 79 | # Tauri | |
| 80 | 80 | tauri = { workspace = true, features = ["image-png", "devtools"] } |
| @@ -613,6 +613,7 @@ | |||
| 613 | 613 | ("quasi-download.js", quasi_webview::DOWNLOAD_JS), | |
| 614 | 614 | ("quasi-fill.js", quasi_webview::FILL_JS), | |
| 615 | 615 | ("quasi-reveal.js", quasi_webview::REVEAL_JS), | |
| 616 | + | ("quasi-copy.js", quasi_webview::COPY_JS), | |
| 616 | 617 | ("quasi-repeat.js", quasi_webview::REPEAT_JS), | |
| 617 | 618 | ("quasi-awaiting.js", quasi_webview::AWAITING_JS), | |
| 618 | 619 | ] { |
| @@ -1,0 +1,73 @@ | |||
| 1 | + | // Putting a described value on the clipboard. | |
| 2 | + | // | |
| 3 | + | // `c3e145e0`. An `Act` can say that pressing it copies a value, and this is the | |
| 4 | + | // browser's half. It replaces seven `window.<name>` globals across 14 sites on | |
| 5 | + | // the MNW server, six of which scraped the text back off the DOM at press time | |
| 6 | + | // and one of which read an element by id. | |
| 7 | + | // | |
| 8 | + | // It reads one attribute the node emitter writes and nothing else: | |
| 9 | + | // `data-copies` carries the value. An ordinary escaped attribute, so nothing | |
| 10 | + | // here is a program built out of app text -- the same rule that makes this a | |
| 11 | + | // script rather than an emitted _hyperscript program. A licence key reading | |
| 12 | + | // `"; alert(1); "` is a value in an attribute here and could not be one in a | |
| 13 | + | // program. | |
| 14 | + | // | |
| 15 | + | // What it does NOT do is say "Copied!". Every shipped site relabelled its own | |
| 16 | + | // button and reverted, six at 1500ms and one at 2000ms, and that is a temporary | |
| 17 | + | // label rather than a copy: it belongs to `makeover-timing` and to mnw-server | |
| 18 | + | // `033c722f`. Splitting them is deliberate -- a host with no notion of a | |
| 19 | + | // reverting label still needs to be told the act copies something. | |
| 20 | + | (() => { | |
| 21 | + | "use strict"; | |
| 22 | + | ||
| 23 | + | /** The value to put on the clipboard. */ | |
| 24 | + | const VALUE = "data-copies"; | |
| 25 | + | ||
| 26 | + | /** | |
| 27 | + | * Write `text` to the clipboard, preferring the async API. | |
| 28 | + | * | |
| 29 | + | * `navigator.clipboard` is unavailable on an insecure origin and can be | |
| 30 | + | * refused by permissions policy, and neither is an error worth surfacing to | |
| 31 | + | * a reader who pressed a copy button. The fallback is the old selection | |
| 32 | + | * dance, which works in both cases and is why it is still here. | |
| 33 | + | */ | |
| 34 | + | const write = async (text) => { | |
| 35 | + | try { | |
| 36 | + | if (navigator.clipboard?.writeText) { | |
| 37 | + | await navigator.clipboard.writeText(text); | |
| 38 | + | return; | |
| 39 | + | } | |
| 40 | + | } catch { | |
| 41 | + | // Fall through: refused, or no permission. The fallback below does | |
| 42 | + | // not ask for one. | |
| 43 | + | } | |
| 44 | + | ||
| 45 | + | const carrier = document.createElement("textarea"); | |
| 46 | + | carrier.value = text; | |
| 47 | + | // Off-screen rather than hidden: a `display: none` element cannot be | |
| 48 | + | // selected, and selecting is the whole mechanism here. | |
| 49 | + | carrier.setAttribute("readonly", ""); | |
| 50 | + | carrier.style.position = "fixed"; | |
| 51 | + | carrier.style.top = "-9999px"; | |
| 52 | + | document.body.appendChild(carrier); | |
| 53 | + | carrier.select(); | |
| 54 | + | try { | |
| 55 | + | document.execCommand("copy"); | |
| 56 | + | } catch { | |
| 57 | + | // Nothing left to try. The reader sees no change, which is the | |
| 58 | + | // same outcome as a page that never described the copy at all. | |
| 59 | + | } | |
| 60 | + | carrier.remove(); | |
| 61 | + | }; | |
| 62 | + | ||
| 63 | + | // One delegated listener rather than one per control, for `FILL_JS`' | |
| 64 | + | // reason: these controls arrive in swaps, so binding per element would mean | |
| 65 | + | // rebinding on every swap. | |
| 66 | + | document.addEventListener("click", (event) => { | |
| 67 | + | const control = event.target?.closest?.(`[${VALUE}]`); | |
| 68 | + | if (!control) { | |
| 69 | + | return; | |
| 70 | + | } | |
| 71 | + | void write(control.getAttribute(VALUE) ?? ""); | |
| 72 | + | }); | |
| 73 | + | })(); |