@fasl-work/caos-app-shell 0.9.0 → 0.9.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.
- package/gate/inpage.mjs +41 -7
- package/package.json +1 -1
- package/styles.css +2 -2
package/gate/inpage.mjs
CHANGED
|
@@ -531,20 +531,27 @@ export function installLib() {
|
|
|
531
531
|
// ---- 0.8.0 measures ----------------------------------------------------------------------------------------
|
|
532
532
|
|
|
533
533
|
/** The part of the page the ancestors of an element let it show when they CUT their content (overflow hidden or
|
|
534
|
-
* clip). A scroll container does not cut (a reader scrolls it), and neither does the viewport
|
|
534
|
+
* clip). A scroll container does not cut (a reader scrolls it), and neither does the viewport; and what lies beyond
|
|
535
|
+
* the first scroll container on an axis is a matter of scroll position, so the walk stops there on that axis (0.9.1:
|
|
536
|
+
* the contained `.app-shell`, viewport-high with its overflow hidden, read every documentation figure below the fold
|
|
537
|
+
* as "outside the drawing"). */
|
|
535
538
|
const cutArea = (el) => {
|
|
536
539
|
const area = { left: -Infinity, top: -Infinity, right: Infinity, bottom: Infinity };
|
|
537
|
-
|
|
540
|
+
let x = true;
|
|
541
|
+
let y = true;
|
|
542
|
+
for (let a = el.parentElement; a && a !== document.body && a !== document.documentElement && (x || y); a = a.parentElement) {
|
|
538
543
|
const s = getComputedStyle(a);
|
|
539
544
|
const ar = a.getBoundingClientRect();
|
|
540
|
-
if (s.overflowX === 'hidden' || s.overflowX === 'clip') {
|
|
545
|
+
if (x && (s.overflowX === 'hidden' || s.overflowX === 'clip')) {
|
|
541
546
|
area.left = Math.max(area.left, ar.left);
|
|
542
547
|
area.right = Math.min(area.right, ar.right);
|
|
543
548
|
}
|
|
544
|
-
if (s.overflowY === 'hidden' || s.overflowY === 'clip') {
|
|
549
|
+
if (y && (s.overflowY === 'hidden' || s.overflowY === 'clip')) {
|
|
545
550
|
area.top = Math.max(area.top, ar.top);
|
|
546
551
|
area.bottom = Math.min(area.bottom, ar.bottom);
|
|
547
552
|
}
|
|
553
|
+
if (s.overflowX === 'auto' || s.overflowX === 'scroll') x = false;
|
|
554
|
+
if (s.overflowY === 'auto' || s.overflowY === 'scroll') y = false;
|
|
548
555
|
}
|
|
549
556
|
return area;
|
|
550
557
|
};
|
|
@@ -719,6 +726,29 @@ export function installLib() {
|
|
|
719
726
|
for (let i = layers.length - 1; i >= 0; i -= 1) base = over(layers[i], base);
|
|
720
727
|
return base;
|
|
721
728
|
};
|
|
729
|
+
/** The colour an SVG text element is painted on: the last filled shape painted before it whose box holds its centre. */
|
|
730
|
+
const svgBackdrop = (text, page) => {
|
|
731
|
+
const svg = text.closest('svg');
|
|
732
|
+
if (!svg) return page;
|
|
733
|
+
const r = text.getBoundingClientRect();
|
|
734
|
+
const cx = r.left + r.width / 2;
|
|
735
|
+
const cy = r.top + r.height / 2;
|
|
736
|
+
let found = null;
|
|
737
|
+
for (const shape of svg.querySelectorAll('rect, circle, ellipse, polygon, path')) {
|
|
738
|
+
if (!(shape.compareDocumentPosition(text) & Node.DOCUMENT_POSITION_FOLLOWING)) continue;
|
|
739
|
+
const ss = getComputedStyle(shape);
|
|
740
|
+
if (ss.display === 'none' || ss.visibility === 'hidden') continue;
|
|
741
|
+
const fill = parseColor(ss.fill);
|
|
742
|
+
if (!fill || fill.a === 0) continue;
|
|
743
|
+
const b = shape.getBoundingClientRect();
|
|
744
|
+
if (cx < b.left || cx > b.right || cy < b.top || cy > b.bottom) continue;
|
|
745
|
+
const a = fill.a * Number(ss.fillOpacity || 1) * opacityOf(shape);
|
|
746
|
+
if (a <= 0.05) continue;
|
|
747
|
+
found = { ...fill, a };
|
|
748
|
+
}
|
|
749
|
+
return found ? over(found, page) : page;
|
|
750
|
+
};
|
|
751
|
+
|
|
722
752
|
const opacityOf = (el) => {
|
|
723
753
|
let o = 1;
|
|
724
754
|
for (let a = el; a; a = a.parentElement) o *= Number(getComputedStyle(a).opacity || 1);
|
|
@@ -753,8 +783,12 @@ export function installLib() {
|
|
|
753
783
|
const fg = parseColor(isSvg ? s.fill : s.color);
|
|
754
784
|
if (!fg) continue;
|
|
755
785
|
const host = isSvg ? el.closest('svg')?.parentElement ?? el : el;
|
|
756
|
-
const
|
|
757
|
-
if (!
|
|
786
|
+
const page = backdrop(host);
|
|
787
|
+
if (!page) continue;
|
|
788
|
+
// SVG text sits on what the drawing painted under it (a label on a bar): the last filled shape before it whose
|
|
789
|
+
// box holds the text's centre, composited over the page (0.9.1: a marker in the page colour on a red bar read
|
|
790
|
+
// 1.06:1 against the page)
|
|
791
|
+
const bg = isSvg ? svgBackdrop(el, page) : page;
|
|
758
792
|
const alpha = fg.a * opacityOf(el);
|
|
759
793
|
const shownColor = over({ ...fg, a: alpha }, bg);
|
|
760
794
|
const l1 = lum(shownColor);
|
|
@@ -763,7 +797,7 @@ export function installLib() {
|
|
|
763
797
|
const px = parseFloat(s.fontSize) || 16;
|
|
764
798
|
const bold = Number(s.fontWeight) >= 700;
|
|
765
799
|
const need = px >= 24 || (bold && px >= 18.66) ? 3 : 4.5;
|
|
766
|
-
if (ratio + 1e-6 < need) out.push(`${describe(el)}: contrast ${ratio.toFixed(2)}:1, below ${need}:1 (${s.
|
|
800
|
+
if (ratio + 1e-6 < need) out.push(`${describe(el)}: contrast ${ratio.toFixed(2)}:1, below ${need}:1 (${isSvg ? s.fill : s.color} on rgb(${Math.round(bg.r)}, ${Math.round(bg.g)}, ${Math.round(bg.b)}))`);
|
|
767
801
|
}
|
|
768
802
|
return out.slice(0, 10);
|
|
769
803
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fasl-work/caos-app-shell",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.1",
|
|
4
4
|
"description": "Shared web-app shell, workbench primitives, content primitives, design system and measured gate for the CAOS / Faena public apps (ADR-0016, ADR-0017, ADR-0071).",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Felipe Santibáñez-Leal",
|
package/styles.css
CHANGED
|
@@ -56,8 +56,8 @@
|
|
|
56
56
|
--color-accent-fg: #ffffff;
|
|
57
57
|
--color-accent-soft: #ddf4ff;
|
|
58
58
|
--color-accent-2: #0a7886;
|
|
59
|
-
--color-magenta: #
|
|
60
|
-
--color-good: #
|
|
59
|
+
--color-magenta: #b93785;
|
|
60
|
+
--color-good: #197c36;
|
|
61
61
|
--color-warn: #946300;
|
|
62
62
|
--color-bad: #cf222e;
|
|
63
63
|
--color-shadow: 0 1px 2px rgba(31, 35, 40, 0.06), 0 4px 10px rgba(31, 35, 40, 0.04);
|