studio-engine 0.141.1 → 0.141.2
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.
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e37b982954e7699c21010d1269c9f8bb50e3f4b900b580216ab2a61907000cbb
|
|
4
|
+
data.tar.gz: 2288aaaee5f9f64ed85893a1ea3d5c6f2027316fc00e1da2ef1370e597037994
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9ba01f6b9d3ca61b788e4076c04e1e9699fa602214d026267cf82e0839ea4a2b89f93d66e2ec7b532475bbd32fb77481ae6d4680594ea075c6c0c189f19bcc20
|
|
7
|
+
data.tar.gz: f6f06cecfe7ef957aef4b61ecc586f972b264f9e13e2ca7502154b947fdcbc9a63a3d138b8c3903bace7f4200be6046ec4dcc41b89d863c70e8e438d30d80e38
|
data/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,13 @@ The format is [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). This pro
|
|
|
4
4
|
|
|
5
5
|
## Unreleased
|
|
6
6
|
|
|
7
|
+
## 0.141.2 — 2026-11-09
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- **The link-preview card shows text typed before its controller loads.** The `link-preview-card` controller is registered lazily, so an operator could type in /admin/link_preview before it listened, and the card kept the saved title. `connect()` now paints the card from the fields as they stand (`paintAll` in `studio/link_preview_card`). No host change.
|
|
12
|
+
- **An in-page jump ends at the browser's scrollend, not at a quiet spell.** `studio/in_page_links` ended a smooth jump after 150 ms with no scroll event, even in a browser that fires `scrollend`. On a slow main thread (a phone, or CI at 8x CPU) a smooth scroll's frames come further apart than that, so the jump ended at its first frame: the tab highlight followed the passing sections, and a target that moved on the way (a lazy feed above it) was not aimed at again. Now only `scrollend` ends a scroll that moved, where the browser has it; the quiet spell stays for a browser without it, and the 400 ms cap still ends a scroll that never starts. Nothing for a consumer to do.
|
|
13
|
+
|
|
7
14
|
## 0.141.1 — 2026-11-09
|
|
8
15
|
|
|
9
16
|
### Fixed
|
|
@@ -7,8 +7,13 @@
|
|
|
7
7
|
//
|
|
8
8
|
// The repaint is studio/link_preview_card. One listener on the root takes the
|
|
9
9
|
// `input` of every [data-link-preview-input] inside it.
|
|
10
|
+
//
|
|
11
|
+
// The controller is registered lazily, so its module arrives after the page has
|
|
12
|
+
// loaded and an operator can type before connect() listens. That input event is
|
|
13
|
+
// gone, so connect() also paints the card from the fields as they stand
|
|
14
|
+
// (e2e/site_identity.spec.js holds the module back to prove it).
|
|
10
15
|
import { Controller } from "@hotwired/stimulus"
|
|
11
|
-
import { paintCard } from "studio/link_preview_card"
|
|
16
|
+
import { paintCard, paintAll } from "studio/link_preview_card"
|
|
12
17
|
|
|
13
18
|
export default class extends Controller {
|
|
14
19
|
connect() {
|
|
@@ -17,6 +22,7 @@ export default class extends Controller {
|
|
|
17
22
|
if (input && input.matches && input.matches("[data-link-preview-input]")) paintCard(this.element, input)
|
|
18
23
|
}
|
|
19
24
|
this.element.addEventListener("input", this.repaint)
|
|
25
|
+
paintAll(this.element)
|
|
20
26
|
}
|
|
21
27
|
|
|
22
28
|
disconnect() {
|
|
@@ -36,7 +36,10 @@ export const SCROLL_END_EVENT = "studio:in-page-scroll-end"
|
|
|
36
36
|
export const STATE_KEY = "studioInPage"
|
|
37
37
|
// The mark on a target that took tabindex=-1 for focus here; engine.css draws no ring on it.
|
|
38
38
|
export const FOCUS_MARK = "data-in-page-focus"
|
|
39
|
-
// No scroll for this long ends the scroll, where the browser has no scrollend event.
|
|
39
|
+
// No scroll for this long ends the scroll, where the browser has no scrollend event. Where it
|
|
40
|
+
// has one, only scrollend ends a scroll that moved: on a slow main thread (a phone, or CI at
|
|
41
|
+
// 8x CPU) a smooth scroll's frames come further apart than this, and a quiet spell ended the
|
|
42
|
+
// jump at its first frame. Then the target moved and nothing aimed again.
|
|
40
43
|
export const SETTLE_MS = 150
|
|
41
44
|
// A scroll the reader never sees move still ends: the cap for a scroll that never starts.
|
|
42
45
|
export const START_CAP_MS = 400
|
|
@@ -188,9 +191,11 @@ export function installInPageLinks(doc) {
|
|
|
188
191
|
// target was at the start. Content that grows on the way (a lazy frame the scroll passes,
|
|
189
192
|
// the navbar's collapse) moves the target, so the scroll aims again, up to MAX_AIMS times,
|
|
190
193
|
// until the reader takes over (a wheel, a touch, a key, a press). The end is the browser's
|
|
191
|
-
// scrollend where it has one, a quiet spell where not; then the end event, once.
|
|
194
|
+
// scrollend where it has one, a quiet spell where not; then the end event, once. A scroll
|
|
195
|
+
// that never starts ends at the cap either way.
|
|
192
196
|
const jump = (target, behavior) => {
|
|
193
197
|
if (settling) settling()
|
|
198
|
+
const hasScrollend = "onscrollend" in win
|
|
194
199
|
let quiet = null
|
|
195
200
|
let cap = null
|
|
196
201
|
let aims = 0
|
|
@@ -226,7 +231,9 @@ export function installInPageLinks(doc) {
|
|
|
226
231
|
const onScroll = () => {
|
|
227
232
|
win.clearTimeout(cap)
|
|
228
233
|
reaim()
|
|
229
|
-
|
|
234
|
+
// The scroll has started: with scrollend, it alone ends it (an aim's cap is spent too).
|
|
235
|
+
if (hasScrollend) win.clearTimeout(quiet)
|
|
236
|
+
else wait(SETTLE_MS)
|
|
230
237
|
}
|
|
231
238
|
const stop = () => {
|
|
232
239
|
reader = true
|
|
@@ -234,7 +241,7 @@ export function installInPageLinks(doc) {
|
|
|
234
241
|
}
|
|
235
242
|
settling = stop
|
|
236
243
|
win.addEventListener("scroll", onScroll, { passive: true })
|
|
237
|
-
if (
|
|
244
|
+
if (hasScrollend) win.addEventListener("scrollend", end)
|
|
238
245
|
for (const name of INPUTS) win.addEventListener(name, takeOver, { capture: true, passive: true })
|
|
239
246
|
cap = win.setTimeout(end, START_CAP_MS)
|
|
240
247
|
scrollTo(target, behavior)
|
|
@@ -32,3 +32,11 @@ export function paintCard(page, input) {
|
|
|
32
32
|
target.textContent = text
|
|
33
33
|
return text
|
|
34
34
|
}
|
|
35
|
+
|
|
36
|
+
// Repaints the card from every [data-link-preview-input] on the page, as each
|
|
37
|
+
// field stands now. The controller calls it on connect: it is registered
|
|
38
|
+
// lazily, so an operator can type before it listens, and that input event is
|
|
39
|
+
// gone.
|
|
40
|
+
export function paintAll(page) {
|
|
41
|
+
page.querySelectorAll("[data-link-preview-input]").forEach((input) => paintCard(page, input))
|
|
42
|
+
}
|
data/lib/studio/version.rb
CHANGED