@prenta/admin 0.97.2 → 0.97.4
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/CHANGELOG.md +28 -0
- package/dist/__tests__/views/canvas-surface-shared.test.js +16 -0
- package/dist/__tests__/views/canvas-surface-shared.test.js.map +1 -1
- package/dist/components/seo/primitives.d.ts +20 -0
- package/dist/components/seo/primitives.d.ts.map +1 -1
- package/dist/components/seo/primitives.js +20 -0
- package/dist/components/seo/primitives.js.map +1 -1
- package/dist/views/page-editor/SitePreviewFrame.d.ts.map +1 -1
- package/dist/views/page-editor/SitePreviewFrame.js +31 -4
- package/dist/views/page-editor/SitePreviewFrame.js.map +1 -1
- package/package.json +3 -3
- package/src/__tests__/views/canvas-surface-shared.test.ts +19 -0
- package/src/components/seo/primitives.tsx +20 -0
- package/src/views/page-editor/SitePreviewFrame.tsx +35 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,33 @@
|
|
|
1
1
|
# @actuate-media/cms-admin
|
|
2
2
|
|
|
3
|
+
## 0.97.4
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- d165fe1: Site preview measures from a sentinel, not from padding arithmetic
|
|
8
|
+
|
|
9
|
+
`SitePreviewFrame` was the third copy of `container.clientWidth - 48` and the one left alone when the page and post canvases were unified, because it scales an **iframe** rather than a rendered surface and cannot render `CanvasSurface`.
|
|
10
|
+
|
|
11
|
+
Sharing the component was never the point; not writing `p-6` down a second time, in a second unit, four hundred lines from the class it mirrors, was. The 48 disagreed with reality the moment a scrollbar appeared and would have rotted silently if the gutter ever changed — nothing failing, the preview just scaling slightly wrong.
|
|
12
|
+
|
|
13
|
+
It now measures from a zero-height sentinel rendered as the first child of the padded container, subject to the same padding, scrollbar and host scaling as the frame, so its `offsetWidth` IS the usable width. Height still comes from the container — a zero-height sentinel can say nothing about it — but the vertical gutter is derived from the measured horizontal one rather than hardcoded again.
|
|
14
|
+
|
|
15
|
+
The source-level test that pins the other two canvases gained a third case, kept separate because the assertion is about the measurement and not about rendering the shared surface.
|
|
16
|
+
|
|
17
|
+
## 0.97.3
|
|
18
|
+
|
|
19
|
+
### Patch Changes
|
|
20
|
+
|
|
21
|
+
- a7ea557: Visual coverage for version history and the stacked editor layout
|
|
22
|
+
|
|
23
|
+
Two surfaces the visual suite never had, closing followup 21. It goes from 85 baselines to 91.
|
|
24
|
+
|
|
25
|
+
`page-editor-history` captures the rail overlay, an older version selected, its inline diff, the review bar, and the changed-section outline on a canvas rendering that older version. `page-editor` joins the responsive set, photographing the stacked layout at 375 and 768 where the rail stops being a column and sits above the canvas — the editor's largest layout change, previously asserted only by measurement.
|
|
26
|
+
|
|
27
|
+
The version chain is seeded at absolute dates and the surface pins the browser clock just after them, because the panel's "Today" / "Yesterday" headings are computed from `new Date()` and would otherwise re-photograph differently at every midnight.
|
|
28
|
+
|
|
29
|
+
Worth recording why the surface also _asserts_ those headings: removing the clock freeze to prove it mattered left the screenshot passing. A text probe showed the labels had silently become "JUN 15" / "JUN 14" — two short strings, far under the 1% diff threshold. The baseline cannot see that drift, so the assertion is the guard and the screenshot is the record.
|
|
30
|
+
|
|
3
31
|
## 0.97.2
|
|
4
32
|
|
|
5
33
|
### Patch Changes
|
|
@@ -49,5 +49,21 @@ describe('canvas surface is shared, not copied', () => {
|
|
|
49
49
|
expect(read(rel), `${rel} re-implements the scale`).not.toMatch(/fitScale/);
|
|
50
50
|
}
|
|
51
51
|
});
|
|
52
|
+
/**
|
|
53
|
+
* `SitePreviewFrame` was the third copy of `clientWidth - 48` and the one
|
|
54
|
+
* followup 2 left alone, because it scales an IFRAME rather than a rendered
|
|
55
|
+
* surface and cannot render `CanvasSurface`. It can still measure the same
|
|
56
|
+
* way, and now does: the padding arithmetic is gone even though the
|
|
57
|
+
* component is not shared.
|
|
58
|
+
*
|
|
59
|
+
* Kept apart from CANVASES on purpose — the assertion here is about the
|
|
60
|
+
* measurement, not about rendering the shared surface, and folding it in
|
|
61
|
+
* would make the other two tests claim something untrue about it.
|
|
62
|
+
*/
|
|
63
|
+
it('the site preview measures from a sentinel too, though it cannot share the surface', () => {
|
|
64
|
+
const preview = read('src/views/page-editor/SitePreviewFrame.tsx');
|
|
65
|
+
expect(preview, 'SitePreviewFrame still does padding arithmetic').not.toMatch(/clientWidth\s*-\s*\d/);
|
|
66
|
+
expect(preview, 'SitePreviewFrame does not measure from a sentinel').toMatch(/sentinelRef/);
|
|
67
|
+
});
|
|
52
68
|
});
|
|
53
69
|
//# sourceMappingURL=canvas-surface-shared.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"canvas-surface-shared.test.js","sourceRoot":"","sources":["../../../src/__tests__/views/canvas-surface-shared.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AACxC,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAA;AAE7C;;;;;;;;;;;;;GAaG;AAEH,MAAM,GAAG,GAAG,aAAa,CAAC,IAAI,GAAG,CAAC,WAAW,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;AAEhE;;;;;GAKG;AACH,MAAM,IAAI,GAAG,CAAC,GAAW,EAAE,EAAE,CAC3B,YAAY,CAAC,GAAG,GAAG,GAAG,EAAE,MAAM,CAAC;KAC5B,OAAO,CAAC,mBAAmB,EAAE,EAAE,CAAC;KAChC,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC,CAAA;AAEjC,MAAM,QAAQ,GAAG;IACf,wCAAwC;IACxC,4CAA4C;CAC7C,CAAA;AAED,QAAQ,CAAC,sCAAsC,EAAE,GAAG,EAAE;IACpD,EAAE,CAAC,mDAAmD,EAAE,GAAG,EAAE;QAC3D,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;YAC3B,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,GAAG,gCAAgC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,aAAa,CAAC,CAAA;QACtF,CAAC;IACH,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,gCAAgC,EAAE,GAAG,EAAE;QACxC,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;YAC3B,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,GAAG,6BAA6B,CAAC,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAA;QAClF,CAAC;IACH,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,sDAAsD,EAAE,GAAG,EAAE;QAC9D,MAAM,OAAO,GAAG,IAAI,CAAC,yCAAyC,CAAC,CAAA;QAC/D,MAAM,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC,CAAA;QACtC,MAAM,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,CAAA;QAEnC,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;YAC3B,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,GAAG,6BAA6B,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,aAAa,CAAC,CAAA;YACjF,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,GAAG,0BAA0B,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,CAAA;QAC7E,CAAC;IACH,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
|
|
1
|
+
{"version":3,"file":"canvas-surface-shared.test.js","sourceRoot":"","sources":["../../../src/__tests__/views/canvas-surface-shared.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AACxC,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAA;AAE7C;;;;;;;;;;;;;GAaG;AAEH,MAAM,GAAG,GAAG,aAAa,CAAC,IAAI,GAAG,CAAC,WAAW,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;AAEhE;;;;;GAKG;AACH,MAAM,IAAI,GAAG,CAAC,GAAW,EAAE,EAAE,CAC3B,YAAY,CAAC,GAAG,GAAG,GAAG,EAAE,MAAM,CAAC;KAC5B,OAAO,CAAC,mBAAmB,EAAE,EAAE,CAAC;KAChC,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC,CAAA;AAEjC,MAAM,QAAQ,GAAG;IACf,wCAAwC;IACxC,4CAA4C;CAC7C,CAAA;AAED,QAAQ,CAAC,sCAAsC,EAAE,GAAG,EAAE;IACpD,EAAE,CAAC,mDAAmD,EAAE,GAAG,EAAE;QAC3D,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;YAC3B,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,GAAG,gCAAgC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,aAAa,CAAC,CAAA;QACtF,CAAC;IACH,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,gCAAgC,EAAE,GAAG,EAAE;QACxC,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;YAC3B,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,GAAG,6BAA6B,CAAC,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAA;QAClF,CAAC;IACH,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,sDAAsD,EAAE,GAAG,EAAE;QAC9D,MAAM,OAAO,GAAG,IAAI,CAAC,yCAAyC,CAAC,CAAA;QAC/D,MAAM,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC,CAAA;QACtC,MAAM,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,CAAA;QAEnC,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;YAC3B,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,GAAG,6BAA6B,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,aAAa,CAAC,CAAA;YACjF,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,GAAG,0BAA0B,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,CAAA;QAC7E,CAAC;IACH,CAAC,CAAC,CAAA;IAEF;;;;;;;;;;OAUG;IACH,EAAE,CAAC,mFAAmF,EAAE,GAAG,EAAE;QAC3F,MAAM,OAAO,GAAG,IAAI,CAAC,4CAA4C,CAAC,CAAA;QAClE,MAAM,CAAC,OAAO,EAAE,gDAAgD,CAAC,CAAC,GAAG,CAAC,OAAO,CAC3E,sBAAsB,CACvB,CAAA;QACD,MAAM,CAAC,OAAO,EAAE,mDAAmD,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC,CAAA;IAC7F,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
|
|
@@ -25,6 +25,26 @@ export declare function gradeMeta(grade: SeoGrade): GradeMeta;
|
|
|
25
25
|
*
|
|
26
26
|
* Both now derive from this function, so settling that question is a one-line
|
|
27
27
|
* change with nowhere to miss.
|
|
28
|
+
*
|
|
29
|
+
* ## Settled: the floor is 60, and the handoff is amended
|
|
30
|
+
*
|
|
31
|
+
* Kept at 60 rather than moved to the handoff's 55, for three reasons:
|
|
32
|
+
*
|
|
33
|
+
* 1. **The fourth band carries information three cannot.** A score of 0 means
|
|
34
|
+
* *never audited*, which is a different claim from *audited and failing* —
|
|
35
|
+
* and the product already leans on it: the Posts and Pages lists show an
|
|
36
|
+
* unaudited page grey, not red. The handoff's three-band scheme cannot say
|
|
37
|
+
* that.
|
|
38
|
+
* 2. **Precedent.** `tokens.json` already records a deliberate deviation from
|
|
39
|
+
* the handoff (`--muted`, darkened for WCAG AA) under the convention that
|
|
40
|
+
* "a documented deviation stays documented instead of decaying into drift".
|
|
41
|
+
* Same situation, same resolution.
|
|
42
|
+
* 3. **Asymmetric cost.** For an SEO product a false "you're fine" is worse
|
|
43
|
+
* than a false "needs work", so the stricter floor is the safer default.
|
|
44
|
+
*
|
|
45
|
+
* The stake is the 55-59 band. If that is ever revisited, change it here and
|
|
46
|
+
* every surface follows — which is the point of the guard in
|
|
47
|
+
* `__tests__/components/seo-score-bands.test.ts`.
|
|
28
48
|
*/
|
|
29
49
|
export declare function gradeFromScore(score: number): SeoGrade;
|
|
30
50
|
export declare function severityMeta(severity: SeoSeverity): GradeMeta;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"primitives.d.ts","sourceRoot":"","sources":["../../../src/components/seo/primitives.tsx"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAItC,OAAO,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAA;AAIrE,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,EAAE,EAAE,MAAM,CAAA;IACV,GAAG,EAAE,MAAM,CAAA;CACZ;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,QAAQ,GAAG,SAAS,CAqBpD;AAED
|
|
1
|
+
{"version":3,"file":"primitives.d.ts","sourceRoot":"","sources":["../../../src/components/seo/primitives.tsx"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAItC,OAAO,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAA;AAIrE,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,EAAE,EAAE,MAAM,CAAA;IACV,GAAG,EAAE,MAAM,CAAA;CACZ;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,QAAQ,GAAG,SAAS,CAqBpD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,CAKtD;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,WAAW,GAAG,SAAS,CAmB7D;AAYD,wBAAgB,cAAc,CAAC,EAC7B,KAAK,EACL,IAAI,GACL,EAAE;IACD,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,UAAU,GAAG,SAAS,CAAA;CACxD,2CAEA;AAED,yDAAyD;AACzD,wBAAgB,WAAW,CAAC,EAAE,KAAK,EAAE,SAAc,EAAE,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,2CAoB3F;AAED,wBAAgB,SAAS,CAAC,EAAE,KAAK,EAAE,EAAE;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,2CAUrD;AAID,wBAAgB,WAAW,CAAC,EAC1B,KAAK,EACL,WAAW,EACX,MAAM,EACN,QAAQ,EACR,SAAc,GACf,EAAE;IACD,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,MAAM,CAAC,EAAE,SAAS,CAAA;IAClB,QAAQ,EAAE,SAAS,CAAA;IACnB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,2CAeA;AAED,wBAAgB,UAAU,CAAC,EAAE,KAAkB,EAAE,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,2CAWpE;AAED,wBAAgB,aAAa,CAAC,EAC5B,IAAI,EACJ,KAAK,EACL,WAAW,EACX,MAAM,GACP,EAAE;IACD,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,MAAM,CAAC,EAAE,SAAS,CAAA;CACnB,2CAaA;AAED,wBAAgB,aAAa,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;CAAE,2CAkB5F;AAID,eAAO,MAAM,UAAU,kQAC0O,CAAA;AAEjQ,eAAO,MAAM,YAAY,wQAC8O,CAAA;AAEvQ,eAAO,MAAM,YAAY,iNACuL,CAAA"}
|
|
@@ -38,6 +38,26 @@ export function gradeMeta(grade) {
|
|
|
38
38
|
*
|
|
39
39
|
* Both now derive from this function, so settling that question is a one-line
|
|
40
40
|
* change with nowhere to miss.
|
|
41
|
+
*
|
|
42
|
+
* ## Settled: the floor is 60, and the handoff is amended
|
|
43
|
+
*
|
|
44
|
+
* Kept at 60 rather than moved to the handoff's 55, for three reasons:
|
|
45
|
+
*
|
|
46
|
+
* 1. **The fourth band carries information three cannot.** A score of 0 means
|
|
47
|
+
* *never audited*, which is a different claim from *audited and failing* —
|
|
48
|
+
* and the product already leans on it: the Posts and Pages lists show an
|
|
49
|
+
* unaudited page grey, not red. The handoff's three-band scheme cannot say
|
|
50
|
+
* that.
|
|
51
|
+
* 2. **Precedent.** `tokens.json` already records a deliberate deviation from
|
|
52
|
+
* the handoff (`--muted`, darkened for WCAG AA) under the convention that
|
|
53
|
+
* "a documented deviation stays documented instead of decaying into drift".
|
|
54
|
+
* Same situation, same resolution.
|
|
55
|
+
* 3. **Asymmetric cost.** For an SEO product a false "you're fine" is worse
|
|
56
|
+
* than a false "needs work", so the stricter floor is the safer default.
|
|
57
|
+
*
|
|
58
|
+
* The stake is the 55-59 band. If that is ever revisited, change it here and
|
|
59
|
+
* every surface follows — which is the point of the guard in
|
|
60
|
+
* `__tests__/components/seo-score-bands.test.ts`.
|
|
41
61
|
*/
|
|
42
62
|
export function gradeFromScore(score) {
|
|
43
63
|
if (score >= 80)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"primitives.js","sourceRoot":"","sources":["../../../src/components/seo/primitives.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAQZ,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AACrD,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,eAAe,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AACzF,OAAO,EAAE,WAAW,EAAwB,MAAM,sBAAsB,CAAA;AAYxE,MAAM,UAAU,SAAS,CAAC,KAAe;IACvC,QAAQ,KAAK,EAAE,CAAC;QACd,KAAK,MAAM;YACT,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,EAAE,EAAE,EAAE,eAAe,EAAE,GAAG,EAAE,YAAY,EAAE,CAAA;QACxF,KAAK,MAAM;YACT,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,EAAE,EAAE,EAAE,eAAe,EAAE,GAAG,EAAE,YAAY,EAAE,CAAA;QACxF,KAAK,MAAM;YACT,OAAO;gBACL,KAAK,EAAE,MAAM;gBACb,IAAI,EAAE,kBAAkB;gBACxB,EAAE,EAAE,mBAAmB;gBACvB,GAAG,EAAE,gBAAgB;aACtB,CAAA;QACH;YACE,OAAO;gBACL,KAAK,EAAE,UAAU;gBACjB,IAAI,EAAE,kBAAkB;gBACxB,EAAE,EAAE,mBAAmB;gBACvB,GAAG,EAAE,gBAAgB;aACtB,CAAA;IACL,CAAC;AACH,CAAC;AAED
|
|
1
|
+
{"version":3,"file":"primitives.js","sourceRoot":"","sources":["../../../src/components/seo/primitives.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SitePreviewFrame.d.ts","sourceRoot":"","sources":["../../../src/views/page-editor/SitePreviewFrame.tsx"],"names":[],"mappings":"AAKA,OAAO,EAUL,KAAK,qBAAqB,EAE3B,MAAM,6BAA6B,CAAA;AACpC,OAAO,EAAe,KAAK,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAE7D,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,yBAAyB;IACxC,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,UAAU,qBAAqB;IAC7B,uEAAuE;IACvE,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;IAClB,QAAQ,EAAE,UAAU,CAAA;IACpB,2EAA2E;IAC3E,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,sFAAsF;IACtF,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,0EAA0E;IAC1E,QAAQ,CAAC,EAAE,qBAAqB,EAAE,CAAA;IAClC;;;OAGG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAA;IAC7B,+EAA+E;IAC/E,eAAe,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,EAAE,SAAS,CAAC,EAAE,MAAM,KAAK,IAAI,CAAA;IACxE,kDAAkD;IAClD,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,iBAAiB,KAAK,IAAI,CAAA;IAChD,sEAAsE;IACtE,oBAAoB,CAAC,EAAE,CAAC,OAAO,EAAE,yBAAyB,KAAK,IAAI,CAAA;CACpE;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,GAAG,EACH,QAAQ,EACR,SAAS,EACT,KAAsB,EACtB,UAAiB,EACjB,QAAQ,EACR,oBAAwB,EACxB,eAAe,EACf,YAAY,EACZ,oBAAoB,GACrB,EAAE,qBAAqB,
|
|
1
|
+
{"version":3,"file":"SitePreviewFrame.d.ts","sourceRoot":"","sources":["../../../src/views/page-editor/SitePreviewFrame.tsx"],"names":[],"mappings":"AAKA,OAAO,EAUL,KAAK,qBAAqB,EAE3B,MAAM,6BAA6B,CAAA;AACpC,OAAO,EAAe,KAAK,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAE7D,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,yBAAyB;IACxC,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,UAAU,qBAAqB;IAC7B,uEAAuE;IACvE,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;IAClB,QAAQ,EAAE,UAAU,CAAA;IACpB,2EAA2E;IAC3E,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,sFAAsF;IACtF,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,0EAA0E;IAC1E,QAAQ,CAAC,EAAE,qBAAqB,EAAE,CAAA;IAClC;;;OAGG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAA;IAC7B,+EAA+E;IAC/E,eAAe,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,EAAE,SAAS,CAAC,EAAE,MAAM,KAAK,IAAI,CAAA;IACxE,kDAAkD;IAClD,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,iBAAiB,KAAK,IAAI,CAAA;IAChD,sEAAsE;IACtE,oBAAoB,CAAC,EAAE,CAAC,OAAO,EAAE,yBAAyB,KAAK,IAAI,CAAA;CACpE;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,GAAG,EACH,QAAQ,EACR,SAAS,EACT,KAAsB,EACtB,UAAiB,EACjB,QAAQ,EACR,oBAAwB,EACxB,eAAe,EACf,YAAY,EACZ,oBAAoB,GACrB,EAAE,qBAAqB,2CAiLvB"}
|
|
@@ -14,6 +14,7 @@ import { getViewport } from './viewports.js';
|
|
|
14
14
|
export function SitePreviewFrame({ src, viewport, reloadKey, title = 'Site preview', selectedId = null, sections, suppressSectionsEcho = 0, onSelectSection, onCanvasEdit, onCanvasRequestMedia, }) {
|
|
15
15
|
const vp = getViewport(viewport);
|
|
16
16
|
const containerRef = useRef(null);
|
|
17
|
+
const sentinelRef = useRef(null);
|
|
17
18
|
const iframeRef = useRef(null);
|
|
18
19
|
const [scale, setScale] = useState(1);
|
|
19
20
|
const [frameHeight, setFrameHeight] = useState(600);
|
|
@@ -21,13 +22,38 @@ export function SitePreviewFrame({ src, viewport, reloadKey, title = 'Site previ
|
|
|
21
22
|
const [canvasReady, setCanvasReady] = useState(false);
|
|
22
23
|
const canvasOrigin = canvasOriginFromSrc(src);
|
|
23
24
|
const lastSuppressRef = useRef(suppressSectionsEcho);
|
|
25
|
+
/**
|
|
26
|
+
* Measure from a zero-height sentinel, never `clientWidth - 48`.
|
|
27
|
+
*
|
|
28
|
+
* The 48 was `p-6` written down a second time, in a second unit, four
|
|
29
|
+
* hundred lines from the class it mirrors. It disagrees with reality the
|
|
30
|
+
* moment a scrollbar appears, and it rots silently if the gutter ever
|
|
31
|
+
* changes — nothing fails, the preview just scales slightly wrong.
|
|
32
|
+
*
|
|
33
|
+
* The sentinel is subject to the same padding, the same scrollbar and the
|
|
34
|
+
* same host scaling as the frame, so its `offsetWidth` IS the usable width
|
|
35
|
+
* and there is no arithmetic to get wrong. Same rule as `CanvasSurface`,
|
|
36
|
+
* which is where this was first learned; this file is the third copy of the
|
|
37
|
+
* arithmetic and the last one to go.
|
|
38
|
+
*
|
|
39
|
+
* Height still comes from the container, because the sentinel is
|
|
40
|
+
* deliberately zero-height and can say nothing about it — but it is read as
|
|
41
|
+
* `clientHeight - (clientWidth - sentinelWidth)`, deriving the vertical
|
|
42
|
+
* gutter from the measured horizontal one rather than hardcoding it again.
|
|
43
|
+
* That holds for the symmetric `p-6` this uses and degrades to the old
|
|
44
|
+
* behaviour rather than breaking if it ever stops being symmetric.
|
|
45
|
+
*/
|
|
24
46
|
useLayoutEffect(() => {
|
|
25
47
|
const container = containerRef.current;
|
|
26
|
-
|
|
48
|
+
const sentinel = sentinelRef.current;
|
|
49
|
+
if (!container || !sentinel)
|
|
27
50
|
return;
|
|
28
51
|
const recompute = () => {
|
|
29
|
-
const availableW =
|
|
30
|
-
|
|
52
|
+
const availableW = sentinel.offsetWidth;
|
|
53
|
+
if (availableW <= 0)
|
|
54
|
+
return;
|
|
55
|
+
const gutter = Math.max(0, container.clientWidth - availableW);
|
|
56
|
+
const availableH = container.clientHeight - gutter;
|
|
31
57
|
const next = Math.min(1, availableW / vp.width);
|
|
32
58
|
setScale(next > 0 ? next : 1);
|
|
33
59
|
setFrameHeight(availableH > 0 ? availableH : 600);
|
|
@@ -35,6 +61,7 @@ export function SitePreviewFrame({ src, viewport, reloadKey, title = 'Site previ
|
|
|
35
61
|
recompute();
|
|
36
62
|
const ro = new ResizeObserver(recompute);
|
|
37
63
|
ro.observe(container);
|
|
64
|
+
ro.observe(sentinel);
|
|
38
65
|
return () => ro.disconnect();
|
|
39
66
|
}, [vp.width]);
|
|
40
67
|
useEffect(() => {
|
|
@@ -128,7 +155,7 @@ export function SitePreviewFrame({ src, viewport, reloadKey, title = 'Site previ
|
|
|
128
155
|
}, PREVIEW_SECTIONS_DEBOUNCE_MS);
|
|
129
156
|
return () => window.clearTimeout(timer);
|
|
130
157
|
}, [canvasOrigin, loaded, canvasReady, sections, reloadKey, suppressSectionsEcho]);
|
|
131
|
-
return (_jsxs("div", { ref: containerRef, className: "bg-muted relative h-full overflow-hidden p-6", children: [(!src || !loaded) && (_jsxs("div", { className: "absolute inset-0 z-10 flex flex-col items-center justify-center gap-2", "aria-live": "polite", children: [_jsx(Loader2, { className: "text-muted-foreground h-6 w-6 animate-spin", "aria-hidden": true }), _jsx("span", { className: "text-muted-foreground text-sm", children: "Loading site preview\u2026" })] })), src && (_jsx("div", { className: "mx-auto", style: { width: vp.width * scale, height: frameHeight }, children: _jsx("iframe", { ref: iframeRef, src: src, title: title, onLoad: () => setLoaded(true), className: "border-border bg-card rounded-xl border shadow-sm", style: {
|
|
158
|
+
return (_jsxs("div", { ref: containerRef, className: "bg-muted relative h-full overflow-hidden p-6", children: [_jsx("div", { ref: sentinelRef, "aria-hidden": true, className: "h-0" }), (!src || !loaded) && (_jsxs("div", { className: "absolute inset-0 z-10 flex flex-col items-center justify-center gap-2", "aria-live": "polite", children: [_jsx(Loader2, { className: "text-muted-foreground h-6 w-6 animate-spin", "aria-hidden": true }), _jsx("span", { className: "text-muted-foreground text-sm", children: "Loading site preview\u2026" })] })), src && (_jsx("div", { className: "mx-auto", style: { width: vp.width * scale, height: frameHeight }, children: _jsx("iframe", { ref: iframeRef, src: src, title: title, onLoad: () => setLoaded(true), className: "border-border bg-card rounded-xl border shadow-sm", style: {
|
|
132
159
|
width: vp.width,
|
|
133
160
|
height: frameHeight / scale,
|
|
134
161
|
transform: `scale(${scale})`,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SitePreviewFrame.js","sourceRoot":"","sources":["../../../src/views/page-editor/SitePreviewFrame.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AACpE,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AACtC,OAAO,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAA;AACzE,OAAO,EACL,mBAAmB,EACnB,sBAAsB,EACtB,oBAAoB,EACpB,4BAA4B,EAC5B,sBAAsB,EACtB,4BAA4B,EAC5B,uBAAuB,GAKxB,MAAM,6BAA6B,CAAA;AACpC,OAAO,EAAE,WAAW,EAAmB,MAAM,gBAAgB,CAAA;AAqC7D;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,EAC/B,GAAG,EACH,QAAQ,EACR,SAAS,EACT,KAAK,GAAG,cAAc,EACtB,UAAU,GAAG,IAAI,EACjB,QAAQ,EACR,oBAAoB,GAAG,CAAC,EACxB,eAAe,EACf,YAAY,EACZ,oBAAoB,GACE;IACtB,MAAM,EAAE,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAA;IAChC,MAAM,YAAY,GAAG,MAAM,CAAiB,IAAI,CAAC,CAAA;IACjD,MAAM,SAAS,GAAG,MAAM,CAAoB,IAAI,CAAC,CAAA;IACjD,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAA;IACrC,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAA;IACnD,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAA;IAC3C,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAA;IACrD,MAAM,YAAY,GAAG,mBAAmB,CAAC,GAAG,CAAC,CAAA;IAC7C,MAAM,eAAe,GAAG,MAAM,CAAC,oBAAoB,CAAC,CAAA;IAEpD,eAAe,CAAC,GAAG,EAAE;QACnB,MAAM,SAAS,GAAG,YAAY,CAAC,OAAO,CAAA;QACtC,IAAI,CAAC,SAAS;YAAE,OAAM;
|
|
1
|
+
{"version":3,"file":"SitePreviewFrame.js","sourceRoot":"","sources":["../../../src/views/page-editor/SitePreviewFrame.tsx"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prenta/admin",
|
|
3
|
-
"version": "0.97.
|
|
3
|
+
"version": "0.97.4",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -100,11 +100,11 @@
|
|
|
100
100
|
"vitest": "^4.1.0",
|
|
101
101
|
"@prenta/core": "0.123.0",
|
|
102
102
|
"@prenta/plugin-ai": "0.6.0",
|
|
103
|
+
"@prenta/plugin-commerce": "0.2.0",
|
|
103
104
|
"@prenta/component-blocks": "0.3.0",
|
|
104
105
|
"@prenta/plugin-blocks": "0.2.0",
|
|
105
|
-
"@prenta/plugin-commerce": "0.2.0",
|
|
106
|
-
"@prenta/plugin-forms": "0.1.0",
|
|
107
106
|
"@prenta/plugin-media": "0.2.0",
|
|
107
|
+
"@prenta/plugin-forms": "0.1.0",
|
|
108
108
|
"@prenta/plugin-seo": "0.1.0",
|
|
109
109
|
"@prenta/plugin-navigation": "0.3.0",
|
|
110
110
|
"@prenta/sections-react": "0.17.2"
|
|
@@ -58,4 +58,23 @@ describe('canvas surface is shared, not copied', () => {
|
|
|
58
58
|
expect(read(rel), `${rel} re-implements the scale`).not.toMatch(/fitScale/)
|
|
59
59
|
}
|
|
60
60
|
})
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* `SitePreviewFrame` was the third copy of `clientWidth - 48` and the one
|
|
64
|
+
* followup 2 left alone, because it scales an IFRAME rather than a rendered
|
|
65
|
+
* surface and cannot render `CanvasSurface`. It can still measure the same
|
|
66
|
+
* way, and now does: the padding arithmetic is gone even though the
|
|
67
|
+
* component is not shared.
|
|
68
|
+
*
|
|
69
|
+
* Kept apart from CANVASES on purpose — the assertion here is about the
|
|
70
|
+
* measurement, not about rendering the shared surface, and folding it in
|
|
71
|
+
* would make the other two tests claim something untrue about it.
|
|
72
|
+
*/
|
|
73
|
+
it('the site preview measures from a sentinel too, though it cannot share the surface', () => {
|
|
74
|
+
const preview = read('src/views/page-editor/SitePreviewFrame.tsx')
|
|
75
|
+
expect(preview, 'SitePreviewFrame still does padding arithmetic').not.toMatch(
|
|
76
|
+
/clientWidth\s*-\s*\d/,
|
|
77
|
+
)
|
|
78
|
+
expect(preview, 'SitePreviewFrame does not measure from a sentinel').toMatch(/sentinelRef/)
|
|
79
|
+
})
|
|
61
80
|
})
|
|
@@ -56,6 +56,26 @@ export function gradeMeta(grade: SeoGrade): GradeMeta {
|
|
|
56
56
|
*
|
|
57
57
|
* Both now derive from this function, so settling that question is a one-line
|
|
58
58
|
* change with nowhere to miss.
|
|
59
|
+
*
|
|
60
|
+
* ## Settled: the floor is 60, and the handoff is amended
|
|
61
|
+
*
|
|
62
|
+
* Kept at 60 rather than moved to the handoff's 55, for three reasons:
|
|
63
|
+
*
|
|
64
|
+
* 1. **The fourth band carries information three cannot.** A score of 0 means
|
|
65
|
+
* *never audited*, which is a different claim from *audited and failing* —
|
|
66
|
+
* and the product already leans on it: the Posts and Pages lists show an
|
|
67
|
+
* unaudited page grey, not red. The handoff's three-band scheme cannot say
|
|
68
|
+
* that.
|
|
69
|
+
* 2. **Precedent.** `tokens.json` already records a deliberate deviation from
|
|
70
|
+
* the handoff (`--muted`, darkened for WCAG AA) under the convention that
|
|
71
|
+
* "a documented deviation stays documented instead of decaying into drift".
|
|
72
|
+
* Same situation, same resolution.
|
|
73
|
+
* 3. **Asymmetric cost.** For an SEO product a false "you're fine" is worse
|
|
74
|
+
* than a false "needs work", so the stricter floor is the safer default.
|
|
75
|
+
*
|
|
76
|
+
* The stake is the 55-59 band. If that is ever revisited, change it here and
|
|
77
|
+
* every surface follows — which is the point of the guard in
|
|
78
|
+
* `__tests__/components/seo-score-bands.test.ts`.
|
|
59
79
|
*/
|
|
60
80
|
export function gradeFromScore(score: number): SeoGrade {
|
|
61
81
|
if (score >= 80) return 'good'
|
|
@@ -73,6 +73,7 @@ export function SitePreviewFrame({
|
|
|
73
73
|
}: SitePreviewFrameProps) {
|
|
74
74
|
const vp = getViewport(viewport)
|
|
75
75
|
const containerRef = useRef<HTMLDivElement>(null)
|
|
76
|
+
const sentinelRef = useRef<HTMLDivElement>(null)
|
|
76
77
|
const iframeRef = useRef<HTMLIFrameElement>(null)
|
|
77
78
|
const [scale, setScale] = useState(1)
|
|
78
79
|
const [frameHeight, setFrameHeight] = useState(600)
|
|
@@ -81,12 +82,36 @@ export function SitePreviewFrame({
|
|
|
81
82
|
const canvasOrigin = canvasOriginFromSrc(src)
|
|
82
83
|
const lastSuppressRef = useRef(suppressSectionsEcho)
|
|
83
84
|
|
|
85
|
+
/**
|
|
86
|
+
* Measure from a zero-height sentinel, never `clientWidth - 48`.
|
|
87
|
+
*
|
|
88
|
+
* The 48 was `p-6` written down a second time, in a second unit, four
|
|
89
|
+
* hundred lines from the class it mirrors. It disagrees with reality the
|
|
90
|
+
* moment a scrollbar appears, and it rots silently if the gutter ever
|
|
91
|
+
* changes — nothing fails, the preview just scales slightly wrong.
|
|
92
|
+
*
|
|
93
|
+
* The sentinel is subject to the same padding, the same scrollbar and the
|
|
94
|
+
* same host scaling as the frame, so its `offsetWidth` IS the usable width
|
|
95
|
+
* and there is no arithmetic to get wrong. Same rule as `CanvasSurface`,
|
|
96
|
+
* which is where this was first learned; this file is the third copy of the
|
|
97
|
+
* arithmetic and the last one to go.
|
|
98
|
+
*
|
|
99
|
+
* Height still comes from the container, because the sentinel is
|
|
100
|
+
* deliberately zero-height and can say nothing about it — but it is read as
|
|
101
|
+
* `clientHeight - (clientWidth - sentinelWidth)`, deriving the vertical
|
|
102
|
+
* gutter from the measured horizontal one rather than hardcoding it again.
|
|
103
|
+
* That holds for the symmetric `p-6` this uses and degrades to the old
|
|
104
|
+
* behaviour rather than breaking if it ever stops being symmetric.
|
|
105
|
+
*/
|
|
84
106
|
useLayoutEffect(() => {
|
|
85
107
|
const container = containerRef.current
|
|
86
|
-
|
|
108
|
+
const sentinel = sentinelRef.current
|
|
109
|
+
if (!container || !sentinel) return
|
|
87
110
|
const recompute = () => {
|
|
88
|
-
const availableW =
|
|
89
|
-
|
|
111
|
+
const availableW = sentinel.offsetWidth
|
|
112
|
+
if (availableW <= 0) return
|
|
113
|
+
const gutter = Math.max(0, container.clientWidth - availableW)
|
|
114
|
+
const availableH = container.clientHeight - gutter
|
|
90
115
|
const next = Math.min(1, availableW / vp.width)
|
|
91
116
|
setScale(next > 0 ? next : 1)
|
|
92
117
|
setFrameHeight(availableH > 0 ? availableH : 600)
|
|
@@ -94,6 +119,7 @@ export function SitePreviewFrame({
|
|
|
94
119
|
recompute()
|
|
95
120
|
const ro = new ResizeObserver(recompute)
|
|
96
121
|
ro.observe(container)
|
|
122
|
+
ro.observe(sentinel)
|
|
97
123
|
return () => ro.disconnect()
|
|
98
124
|
}, [vp.width])
|
|
99
125
|
|
|
@@ -186,6 +212,12 @@ export function SitePreviewFrame({
|
|
|
186
212
|
|
|
187
213
|
return (
|
|
188
214
|
<div ref={containerRef} className="bg-muted relative h-full overflow-hidden p-6">
|
|
215
|
+
{/*
|
|
216
|
+
* Zero-height sentinel — see the measurement effect above. Must stay the
|
|
217
|
+
* first child and must stay zero-height. `absolute` would defeat it: it
|
|
218
|
+
* has to sit in the padding box to inherit the gutter it is measuring.
|
|
219
|
+
*/}
|
|
220
|
+
<div ref={sentinelRef} aria-hidden className="h-0" />
|
|
189
221
|
{(!src || !loaded) && (
|
|
190
222
|
<div
|
|
191
223
|
className="absolute inset-0 z-10 flex flex-col items-center justify-center gap-2"
|