@godxjp/ui 32.12.1 → 32.13.1

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.
@@ -54,6 +54,14 @@
54
54
  --prose-quote-border-width: initial;
55
55
  --prose-quote-space-inline: var(--space-3);
56
56
  --prose-code-font-size: calc(1em / var(--font-size-ratio));
57
+ --prose-code-block-font-size: 1em;
58
+
59
+ --prose-heading-h1-font-size: calc(
60
+ 1em * var(--font-size-ratio) * var(--font-size-ratio) * var(--font-size-ratio)
61
+ );
62
+ --prose-heading-h2-font-size: calc(1em * var(--font-size-ratio) * var(--font-size-ratio));
63
+ --prose-heading-h3-font-size: calc(1em * var(--font-size-ratio));
64
+ --prose-heading-h4-font-size: 1em;
57
65
  --prose-code-space-inline: var(--space-1);
58
66
 
59
67
  --prose-cell-image-max-inline-size: 20rem;
@@ -63,6 +71,8 @@
63
71
  --block-editor-gutter-inline-size: calc(2 * var(--control-height-xs) + var(--space-2));
64
72
 
65
73
  --block-editor-compact-gutter-inline-size: var(--block-editor-frame-padding);
74
+
75
+ --block-editor-raw-block-head-font-size: calc(1em / var(--font-size-ratio));
66
76
  --block-editor-min-height: var(--band-height-3xl);
67
77
 
68
78
  --block-editor-frame-padding: var(--space-3);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@godxjp/ui",
3
- "version": "32.12.1",
4
- "godxUiMcp": "32.12.1",
3
+ "version": "32.13.1",
4
+ "godxUiMcp": "32.13.1",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
7
7
  "type": "git",
@@ -1496,19 +1496,38 @@ export function parseTextZoom(spec) {
1496
1496
 
1497
1497
  /**
1498
1498
  * Did the override reach the page? (pure). `before`/`after` are `snapshotText()` results of the
1499
- * SAME document (same text-bearing elements, same order). Applied = the override's computed values
1500
- * reached at least one text element AND the geometry moved; either half alone is not enough — a
1501
- * computed value with zero geometry change is a render that was never re-laid out, and geometry
1502
- * that moved without the values is something else moving.
1499
+ * SAME document. Applied = the override's computed values reached EVERY visible text element AND
1500
+ * the geometry moved; either half alone is not enough — a computed value with zero geometry change
1501
+ * is a render that was never re-laid out, and geometry that moved without the values is something
1502
+ * else moving.
1503
+ *
1504
+ * "Every", not "any" (gh#1320): "took > 0" reported `applied: true` on an editor whose four h2
1505
+ * blocks kept their size (ratio 0.897), so a heading smaller than its own body passed as evidence.
1506
+ * The tolerance is ZERO visible elements; what is exempt is listed on the snapshot
1507
+ * (`exempt`: hidden, zero-area / sr-only, aria-hidden, inside an svg) and never counted.
1508
+ *
1509
+ * Elements are paired by index when the two snapshots agree there, otherwise by their `key`
1510
+ * (selector + text): a bar that folds under larger text, or an editor that re-creates a block,
1511
+ * changes the list, and pairing by index alone would compare unrelated elements.
1503
1512
  */
1504
1513
  export function textOverrideVerdict(mode, before, after, { zoom = 200 } = {}) {
1505
- const n = Math.min(before.texts.length, after.texts.length);
1514
+ const used = new Set();
1515
+ const pairs = [];
1516
+ before.texts.forEach((a, i) => {
1517
+ const same = after.texts[i];
1518
+ let j = same && !used.has(i) && (same.key ?? null) === (a.key ?? null) ? i : -1;
1519
+ if (j < 0 && a.key != null)
1520
+ j = after.texts.findIndex((b, k) => !used.has(k) && b.key === a.key);
1521
+ if (j < 0) return;
1522
+ used.add(j);
1523
+ pairs.push([a, after.texts[j]]);
1524
+ });
1525
+ const n = pairs.length;
1506
1526
  let moved = 0;
1507
1527
  let maxShiftPx = 0;
1508
1528
  let took = 0;
1509
- for (let i = 0; i < n; i++) {
1510
- const a = before.texts[i];
1511
- const b = after.texts[i];
1529
+ const notTaken = [];
1530
+ for (const [a, b] of pairs) {
1512
1531
  const shift = Math.max(
1513
1532
  Math.abs(a.x - b.x),
1514
1533
  Math.abs(a.y - b.y),
@@ -1523,6 +1542,14 @@ export function textOverrideVerdict(mode, before, after, { zoom = 200 } = {}) {
1523
1542
  Math.abs(b.wordSpacingPx - 0.16 * b.fontPx) <= 0.5
1524
1543
  : Math.abs(b.fontPx - (a.fontPx * zoom) / 100) <= 0.5;
1525
1544
  if (ok) took++;
1545
+ else if (!a.exempt && !b.exempt)
1546
+ notTaken.push({
1547
+ selector: a.selector ?? "?",
1548
+ text: a.text ?? "",
1549
+ ...(mode === "text-zoom"
1550
+ ? { fontPx: a.fontPx, expectedPx: +((a.fontPx * zoom) / 100).toFixed(2), gotPx: b.fontPx }
1551
+ : { letterSpacingPx: b.letterSpacingPx, wordSpacingPx: b.wordSpacingPx }),
1552
+ });
1526
1553
  }
1527
1554
  const delta = {
1528
1555
  textElements: n,
@@ -1537,7 +1564,15 @@ export function textOverrideVerdict(mode, before, after, { zoom = 200 } = {}) {
1537
1564
  else if (took === 0) reason = `the ${mode} values reached 0 of ${n} text elements`;
1538
1565
  else if (moved === 0 && delta.documentHeightPx === 0 && delta.documentWidthPx === 0)
1539
1566
  reason = "zero geometry delta against the unmodified render";
1540
- return { applied: reason === null, reason, appliedRatio, delta };
1567
+ else if (notTaken.length)
1568
+ reason =
1569
+ `override partially applied: ${notTaken.length} of ${n} visible text elements did not take it — ` +
1570
+ notTaken
1571
+ .slice(0, 5)
1572
+ .map((m) => `${m.selector} "${m.text}"`)
1573
+ .join(", ") +
1574
+ (notTaken.length > 5 ? `, … ${notTaken.length - 5} more` : "");
1575
+ return { applied: reason === null, reason, appliedRatio, delta, notTaken };
1541
1576
  }
1542
1577
 
1543
1578
  /** Text-bearing elements' boxes + computed text metrics, in document order. Runs in the page. */
@@ -1554,11 +1589,36 @@ export function snapshotText() {
1554
1589
  seen.add(p);
1555
1590
  owners.push(p);
1556
1591
  }
1592
+ // `tag#id` or `tag.class.class`, three levels up — enough to find the element, stable across a
1593
+ // re-render that re-creates it (no data attributes, no indices).
1594
+ const step = (el) =>
1595
+ el.tagName.toLowerCase() +
1596
+ (el.id
1597
+ ? `#${el.id}`
1598
+ : [...el.classList]
1599
+ .slice(0, 2)
1600
+ .map((c) => `.${c}`)
1601
+ .join(""));
1602
+ const selectorOf = (el) => {
1603
+ const parts = [];
1604
+ for (let e = el; e && e !== document.body && parts.length < 3; e = e.parentElement)
1605
+ parts.unshift(step(e));
1606
+ return parts.join(" > ");
1607
+ };
1557
1608
  const texts = owners.map((el) => {
1558
1609
  const r = el.getBoundingClientRect();
1559
1610
  const s = getComputedStyle(el);
1560
1611
  const fontPx = parseFloat(s.fontSize) || 0;
1561
1612
  const px = (v) => (v === "normal" ? 0 : parseFloat(v) || 0);
1613
+ const selector = selectorOf(el);
1614
+ const text = (el.textContent || "").replace(/\s+/g, " ").trim().slice(0, 40);
1615
+ // Not text a reader sees, so never counted as "did not take the override".
1616
+ const exempt =
1617
+ r.width <= 1 ||
1618
+ r.height <= 1 ||
1619
+ s.visibility !== "visible" ||
1620
+ Number(s.opacity) === 0 ||
1621
+ !!el.closest('[aria-hidden="true"], svg');
1562
1622
  return {
1563
1623
  x: r.left + se.scrollLeft,
1564
1624
  y: r.top + se.scrollTop,
@@ -1567,6 +1627,10 @@ export function snapshotText() {
1567
1627
  fontPx,
1568
1628
  letterSpacingPx: px(s.letterSpacing),
1569
1629
  wordSpacingPx: px(s.wordSpacing),
1630
+ selector,
1631
+ text,
1632
+ key: `${selector}|${text}`,
1633
+ exempt,
1570
1634
  };
1571
1635
  });
1572
1636
  return { texts, docHeight: se.scrollHeight, docWidth: se.scrollWidth };
@@ -1642,6 +1706,8 @@ async function runEvidence(page, url, viewport, mode, { zoom, screenshots }) {
1642
1706
  ...(mode === "text-zoom" ? { zoomPercent: zoom } : null),
1643
1707
  applied: verdict.applied,
1644
1708
  appliedRatio: verdict.appliedRatio,
1709
+ // The visible text elements that did NOT take the override (gh#1320): selector + snippet.
1710
+ notTaken: verdict.notTaken,
1645
1711
  delta: verdict.delta,
1646
1712
  c01: "not-run",
1647
1713
  screenshots: screenshots ? { base, override } : null,