synthesisui 0.16.505 → 0.16.506
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/dist/color-forms.js +8 -1
- package/dist/install-marks.js +1 -1
- package/dist/reading/page-script.js +19 -2
- package/dist/reading/read-page.js +24 -2
- package/package.json +1 -1
package/dist/color-forms.js
CHANGED
|
@@ -37,7 +37,14 @@ const clamp255 = (n) => Math.max(0, Math.min(255, Math.round(n)));
|
|
|
37
37
|
const hex2 = (n) => clamp255(n).toString(16).padStart(2, "0");
|
|
38
38
|
/** `#f0a` -> `#ff00aa`, e `#ff00aa80` devolve o alfa junto. */
|
|
39
39
|
function fromHex(raw) {
|
|
40
|
-
|
|
40
|
+
/**
|
|
41
|
+
* O `#` É OBRIGATÓRIO: sem ele, um peso de fonte (`300`) é hex de três dígitos e vira `#330000`. Medido em 22/10 no
|
|
42
|
+
* sistema lido de stripe.com: 30 variáveis `--hds-font-*-weight` entraram como cores escuras. Em CSS, hex sem `#`
|
|
43
|
+
* não é cor.
|
|
44
|
+
*/
|
|
45
|
+
if (!raw.trim().startsWith("#"))
|
|
46
|
+
return null;
|
|
47
|
+
const h = raw.trim().slice(1);
|
|
41
48
|
if (!/^[0-9a-f]{3,8}$/i.test(h))
|
|
42
49
|
return null;
|
|
43
50
|
const dup = (s) => s
|
package/dist/install-marks.js
CHANGED
|
@@ -592,7 +592,7 @@ export const COUNTED_DIFFERENTLY = "this run counts a value as named only when Y
|
|
|
592
592
|
* E (E02, no mesmo PR) guarda o tamanho de título sem papel para a próxima leitura perguntar, e cobra o papel que a pessoa
|
|
593
593
|
* escolheu no "não" (`decided` no rules.json): um hook pinado antes diz "papel novo" uma vez e nunca cobra.
|
|
594
594
|
*/
|
|
595
|
-
export const CHECKER_SINCE = "0.16.
|
|
595
|
+
export const CHECKER_SINCE = "0.16.506";
|
|
596
596
|
/**
|
|
597
597
|
* A ÚLTIMA VERSÃO EM QUE OS LEITORES PASSARAM A PRODUZIR UM CENSO DIFERENTE.
|
|
598
598
|
*
|
|
@@ -16,13 +16,19 @@ export const PAGE_SCRIPT = String.raw `(() => {
|
|
|
16
16
|
const cs = getComputedStyle(e);
|
|
17
17
|
if (cs.backgroundImage && cs.backgroundImage !== "none") img = img || /url\(|gradient/.test(cs.backgroundImage);
|
|
18
18
|
const bg = parse(cs.backgroundColor); if (bg && bg.a > 0) { camadas.push(bg); if (bg.a >= 1) break; }
|
|
19
|
-
if (e.parentElement && [...e.parentElement.children].some((s) => s !== e && /^(VIDEO|IMG)$/.test(s.tagName) && getComputedStyle(s).position === "absolute")) img = true;
|
|
19
|
+
if (e.parentElement && [...e.parentElement.children].some((s) => s !== e && /^(VIDEO|IMG|CANVAS|svg)$/.test(s.tagName) && getComputedStyle(s).position === "absolute")) img = true;
|
|
20
20
|
}
|
|
21
21
|
let cor = { r: 255, g: 255, b: 255, a: 1 };
|
|
22
22
|
for (let i = camadas.length - 1; i >= 0; i--) cor = mix(camadas[i], cor);
|
|
23
23
|
return { cor, img };
|
|
24
24
|
};
|
|
25
25
|
const secao = (el) => { for (let e = el; e; e = e.parentElement) { if (/^(SECTION|HEADER|FOOTER|NAV|MAIN|ASIDE|ARTICLE|DIALOG)$/.test(e.tagName) || e.id) return e.tagName.toLowerCase() + (e.id ? "#" + e.id : ""); } return "body"; };
|
|
26
|
+
/* O QUE MISTURA O QUE ESTÁ EMBAIXO, medido uma vez: em stripe.com (22/10) o título é desenhado duas vezes, uma cópia
|
|
27
|
+
verde opaca e, por cima, a mesma frase com mix-blend-mode: hard-light - a tela mostra a mistura, e a cópia de baixo
|
|
28
|
+
sozinha nunca aparece. Um texto debaixo de qualquer um destes (ancestral ou camada por cima) tem pintura que o
|
|
29
|
+
estilo não conta. O desfoque de fundo (backdrop-filter) só conta POR CIMA do texto: no cartão de vidro que o
|
|
30
|
+
contém, ele desfoca o que está atrás do cartão, e o texto segue com a cor dele (medido em linear.app, 22/10). */
|
|
31
|
+
const misturadores = [...document.querySelectorAll("body *")].filter((e) => { const c = getComputedStyle(e); return c.mixBlendMode !== "normal" || (c.backdropFilter && c.backdropFilter !== "none") || c.webkitBackgroundClip === "text" || c.backgroundClip === "text"; }).slice(0, 200).map((e) => { const q = e.getBoundingClientRect(); const c = getComputedStyle(e); return { e, so: !(c.mixBlendMode !== "normal" || c.webkitBackgroundClip === "text" || c.backgroundClip === "text"), x: q.left + scrollX, y: q.top + scrollY, w: q.width, h: q.height }; });
|
|
26
32
|
const textos = [];
|
|
27
33
|
const walker = document.createTreeWalker(document.body, NodeFilter.SHOW_TEXT);
|
|
28
34
|
const vistos = new Set();
|
|
@@ -49,12 +55,23 @@ export const PAGE_SCRIPT = String.raw `(() => {
|
|
|
49
55
|
}
|
|
50
56
|
let op = 1; for (let e = el; e; e = e.parentElement) op *= Number(getComputedStyle(e).opacity);
|
|
51
57
|
const cor = parse(cs.color); if (cor) cor.a *= op;
|
|
58
|
+
/* A PINTURA QUE O ESTILO NÃO CONTA (22/10, stripe.com): o título é rgba(0, 14, 255, .5) com mix-blend-mode:
|
|
59
|
+
hard-light sobre um degradê animado - a cor na tela é a mistura, e nenhum "color" a revela. Texto misturado,
|
|
60
|
+
recortado no fundo (background-clip: text), sem tinta própria ou sob filtro: só a foto diz o contraste. */
|
|
61
|
+
let mistura = false;
|
|
62
|
+
for (let e = el; e && e !== document.documentElement && !mistura; e = e.parentElement) {
|
|
63
|
+
const c = getComputedStyle(e);
|
|
64
|
+
if (c.filter && c.filter !== "none") mistura = true;
|
|
65
|
+
}
|
|
66
|
+
const cx = r.left + scrollX + r.width / 2, cy = r.top + scrollY + r.height / 2;
|
|
67
|
+
if (!mistura) mistura = misturadores.some((m) => (m.e === el || !el.contains(m.e)) && !(m.so && m.e.contains(el)) && cx >= m.x && cx <= m.x + m.w && cy >= m.y && cy <= m.y + m.h);
|
|
68
|
+
if (/^rgba\([^)]*,\s*0\)$|^transparent$/.test(cs.webkitTextFillColor || "")) mistura = true;
|
|
52
69
|
const f = fundo(el);
|
|
53
70
|
textos.push({
|
|
54
71
|
texto: txt.slice(0, 60), tag: el.tagName.toLowerCase(),
|
|
55
72
|
papel: (el.closest("h1,h2,h3,h4,h5,h6,button,a,label,th,figcaption,blockquote,input") || { tagName: "" }).tagName.toLowerCase() || null,
|
|
56
73
|
tam: parseFloat(cs.fontSize), familia: cs.fontFamily.split(",")[0].replace(/["']/g, "").trim(), peso: Number(cs.fontWeight),
|
|
57
|
-
cor, fundo: f.cor, sobreImagem: f.img, decorativo: !!el.closest("[aria-hidden=true]"),
|
|
74
|
+
cor, fundo: f.cor, sobreImagem: f.img, mistura, decorativo: !!el.closest("[aria-hidden=true]"),
|
|
58
75
|
cartao, corrido, giro, enfase, comp,
|
|
59
76
|
cls: [el, ...(tit && tit !== el ? [tit] : []), el.parentElement].filter(Boolean).map((x) => x.getAttribute("class") || "").join(" | ").slice(0, 600),
|
|
60
77
|
secao: secao(el), x: r.left + scrollX, y: r.top + scrollY, w: r.width, h: r.height,
|
|
@@ -78,12 +78,34 @@ export async function readSite(browser, base, routes, opts = {}) {
|
|
|
78
78
|
};
|
|
79
79
|
try {
|
|
80
80
|
for (const rota of routes) {
|
|
81
|
-
const
|
|
81
|
+
const timed = async (disp, w, h) => {
|
|
82
|
+
const t = performance.now();
|
|
83
|
+
const textos = await open(rota, disp, w, h);
|
|
84
|
+
opts.onWidth?.(disp, Math.round(performance.now() - t));
|
|
85
|
+
return textos;
|
|
86
|
+
};
|
|
87
|
+
const byWidth = [];
|
|
88
|
+
if (opts.oneAtATime)
|
|
89
|
+
for (const [disp, w, h] of VIEWPORTS)
|
|
90
|
+
byWidth.push(await timed(disp, w, h));
|
|
91
|
+
else
|
|
92
|
+
byWidth.push(...(await Promise.all(VIEWPORTS.map(([disp, w, h]) => timed(disp, w, h)))));
|
|
82
93
|
for (const textos of byWidth)
|
|
83
94
|
seen.push(...textos);
|
|
84
95
|
}
|
|
85
96
|
const reading = classify(seen);
|
|
86
|
-
|
|
97
|
+
/**
|
|
98
|
+
* Sem a foto, o par cuja pintura o estilo não conta (`mistura`) sai: o número dele seria da cor declarada, e não da
|
|
99
|
+
* que se vê. Medido em 22/10 em stripe.com - o título acusado a 2,39 : 1 era um azul translúcido misturado sobre um
|
|
100
|
+
* degradê, e o "depois" o pintou de verde. Com a foto (o CLI), quem decide é o pixel, como sempre.
|
|
101
|
+
*/
|
|
102
|
+
if (opts.skipPixels)
|
|
103
|
+
reading.contraste = reading.contraste.filter((c) => c.razao >= 1.2 && !c.sample.mistura);
|
|
104
|
+
else {
|
|
105
|
+
const t = performance.now();
|
|
106
|
+
reading.contraste = await confirmByPixels(reading.contraste, (t) => pages.get(`${t.rota}|${t.disp}`));
|
|
107
|
+
opts.onWidth?.("pixels", Math.round(performance.now() - t));
|
|
108
|
+
}
|
|
87
109
|
return { reading, seen, pages, statuses, close };
|
|
88
110
|
}
|
|
89
111
|
catch (e) {
|
package/package.json
CHANGED