hyperframes 0.7.56 → 0.7.58
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/cli.js +4595 -3123
- package/dist/commands/contrast-audit.browser.js +79 -19
- package/dist/commands/layout-audit.browser.js +490 -24
- package/dist/hyperframe-runtime.js +50 -30
- package/dist/hyperframe.manifest.json +1 -1
- package/dist/hyperframe.runtime.iife.js +50 -30
- package/dist/hyperframes-player.global.js +2 -2
- package/dist/hyperframes-slideshow.global.js +25 -25
- package/dist/skills/hyperframes-cli/SKILL.md +41 -12
- package/dist/skills/hyperframes-cli/references/cloud.md +123 -0
- package/dist/skills/hyperframes-cli/references/lint-validate-inspect.md +1 -1
- package/dist/skills/hyperframes-cli/references/preview-render.md +3 -3
- package/dist/studio/assets/hyperframes-player-CtTDO63S.js +459 -0
- package/dist/studio/assets/{index-CmVCjZjp.js → index-B_UvTX3E.js} +205 -205
- package/dist/studio/assets/{index-BWnOxAiH.js → index-C47jAC3Q.js} +1 -1
- package/dist/studio/assets/{index-C4csZims.js → index-DeQPzqwH.js} +1 -1
- package/dist/studio/assets/index-uahwWkgw.css +1 -0
- package/dist/studio/{chunk-5QSIMBEJ.js → chunk-OBAG3GWK.js} +33 -21
- package/dist/studio/chunk-OBAG3GWK.js.map +1 -0
- package/dist/studio/{domEditingLayers-6LQGKPOI.js → domEditingLayers-2CKWGEHS.js} +2 -2
- package/dist/studio/index.d.ts +41 -4
- package/dist/studio/index.html +2 -2
- package/dist/studio/index.js +7436 -5423
- package/dist/studio/index.js.map +1 -1
- package/package.json +2 -1
- package/dist/studio/assets/hyperframes-player-BBrKzTGd.js +0 -459
- package/dist/studio/assets/index-D-GyYi2d.css +0 -1
- package/dist/studio/chunk-5QSIMBEJ.js.map +0 -1
- /package/dist/studio/{domEditingLayers-6LQGKPOI.js.map → domEditingLayers-2CKWGEHS.js.map} +0 -0
|
@@ -58,28 +58,29 @@ window.__contrastAuditPrepare = function () {
|
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
function parseColor(c) {
|
|
61
|
-
var m = c.match(
|
|
62
|
-
if (!m)
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
61
|
+
var m = (c || "").match(/^rgba?\(([^)]+)\)$/i);
|
|
62
|
+
if (!m) {
|
|
63
|
+
var mix = (c || "").match(
|
|
64
|
+
/^color-mix\(\s*in\s+srgb\s*,\s*(rgba?\([^)]+\))\s+(\d+(?:\.\d+)?|\.\d+)%\s*,\s*(rgba?\([^)]+\))\s+(\d+(?:\.\d+)?|\.\d+)%\s*\)$/i,
|
|
65
|
+
);
|
|
66
|
+
if (!mix) return null;
|
|
67
|
+
var first = parseColor(mix[1]);
|
|
68
|
+
var second = parseColor(mix[3]);
|
|
69
|
+
var firstWeight = parseFloat(mix[2]);
|
|
70
|
+
var secondWeight = parseFloat(mix[4]);
|
|
71
|
+
var weightTotal = firstWeight + secondWeight;
|
|
72
|
+
if (!first || !second || !isFinite(weightTotal) || weightTotal <= 0) return null;
|
|
73
|
+
return first.map(function (channel, index) {
|
|
74
|
+
return (channel * firstWeight + second[index] * secondWeight) / weightTotal;
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
77
|
var p = m[1].split(",").map(function (s) {
|
|
78
78
|
return parseFloat(s.trim());
|
|
79
79
|
});
|
|
80
80
|
if (
|
|
81
|
+
(p.length !== 3 && p.length !== 4) ||
|
|
81
82
|
p.some(function (v) {
|
|
82
|
-
return
|
|
83
|
+
return !isFinite(v);
|
|
83
84
|
})
|
|
84
85
|
)
|
|
85
86
|
return null;
|
|
@@ -131,6 +132,12 @@ window.__contrastAuditPrepare = function () {
|
|
|
131
132
|
return !paintsAnyProbePoint(el, rect);
|
|
132
133
|
}
|
|
133
134
|
|
|
135
|
+
function isIntentionallyOccluded(el, rect) {
|
|
136
|
+
if (typeof document.elementFromPoint !== "function") return false;
|
|
137
|
+
if (!el.closest || !el.closest("[data-layout-allow-occlusion]")) return false;
|
|
138
|
+
return !paintsAnyProbePoint(el, rect);
|
|
139
|
+
}
|
|
140
|
+
|
|
134
141
|
var out = [];
|
|
135
142
|
var restores = [];
|
|
136
143
|
// Registered BEFORE the walk starts (not after it finishes) and pushed to
|
|
@@ -200,6 +207,10 @@ window.__contrastAuditPrepare = function () {
|
|
|
200
207
|
if (rect.width < 8 || rect.height < 8) continue;
|
|
201
208
|
if (rect.right <= 0 || rect.bottom <= 0) continue;
|
|
202
209
|
if (isClippedAway(el, rect)) continue;
|
|
210
|
+
// The layout audit's explicit occlusion opt-out means this text is allowed
|
|
211
|
+
// to sit behind another scene. Skip contrast only while every probe point
|
|
212
|
+
// is actually covered; the same copy is audited normally when visible.
|
|
213
|
+
if (isIntentionallyOccluded(el, rect)) continue;
|
|
203
214
|
|
|
204
215
|
// For SVG text, `fill` is the paint that's actually rendered; `color` is
|
|
205
216
|
// frequently just the inherited/initial value and unrelated to what's on
|
|
@@ -208,8 +219,12 @@ window.__contrastAuditPrepare = function () {
|
|
|
208
219
|
// `color` rather than crashing parseColor or reporting a fabricated
|
|
209
220
|
// black.
|
|
210
221
|
var isSvgText = isSvgTextElement(el);
|
|
211
|
-
var fg = isSvgText ?
|
|
222
|
+
var fg = isSvgText ? parseColor(cs.fill) || parseColor(cs.color) : parseColor(cs.color);
|
|
223
|
+
if (!fg) continue;
|
|
212
224
|
if (fg[3] <= 0.01) continue;
|
|
225
|
+
var strokeWidth = parseFloat(cs.webkitTextStrokeWidth || "0");
|
|
226
|
+
var stroke = strokeWidth > 0 ? parseColor(cs.webkitTextStrokeColor || "") : null;
|
|
227
|
+
if (stroke && stroke[3] <= 0.01) stroke = null;
|
|
213
228
|
|
|
214
229
|
var fontSize = parseFloat(cs.fontSize);
|
|
215
230
|
var fontWeight = Number(cs.fontWeight) || 400;
|
|
@@ -241,6 +256,13 @@ window.__contrastAuditPrepare = function () {
|
|
|
241
256
|
origFillPriority = el.style.getPropertyPriority("fill");
|
|
242
257
|
el.style.setProperty("fill", "transparent", "important");
|
|
243
258
|
}
|
|
259
|
+
var origStrokeColor = null,
|
|
260
|
+
origStrokeColorPriority = null;
|
|
261
|
+
if (stroke) {
|
|
262
|
+
origStrokeColor = el.style.getPropertyValue("-webkit-text-stroke-color");
|
|
263
|
+
origStrokeColorPriority = el.style.getPropertyPriority("-webkit-text-stroke-color");
|
|
264
|
+
el.style.setProperty("-webkit-text-stroke-color", "transparent", "important");
|
|
265
|
+
}
|
|
244
266
|
restores.push({
|
|
245
267
|
el: el,
|
|
246
268
|
origTransition: origTransition,
|
|
@@ -249,6 +271,9 @@ window.__contrastAuditPrepare = function () {
|
|
|
249
271
|
origColorPriority: origColorPriority,
|
|
250
272
|
origFill: origFill,
|
|
251
273
|
origFillPriority: origFillPriority,
|
|
274
|
+
origStrokeColor: origStrokeColor,
|
|
275
|
+
origStrokeColorPriority: origStrokeColorPriority,
|
|
276
|
+
hasStroke: !!stroke,
|
|
252
277
|
isSvgText: isSvgText,
|
|
253
278
|
});
|
|
254
279
|
|
|
@@ -256,6 +281,7 @@ window.__contrastAuditPrepare = function () {
|
|
|
256
281
|
selector: selectorOf(el),
|
|
257
282
|
text: (el.textContent || "").trim().slice(0, 50),
|
|
258
283
|
fg: fg,
|
|
284
|
+
stroke: stroke,
|
|
259
285
|
fontSize: fontSize,
|
|
260
286
|
fontWeight: fontWeight,
|
|
261
287
|
large: large,
|
|
@@ -277,6 +303,15 @@ function __contrastAuditRestoreAll() {
|
|
|
277
303
|
if (r.origFill) r.el.style.setProperty("fill", r.origFill, r.origFillPriority);
|
|
278
304
|
else r.el.style.removeProperty("fill");
|
|
279
305
|
}
|
|
306
|
+
if (r.hasStroke) {
|
|
307
|
+
if (r.origStrokeColor)
|
|
308
|
+
r.el.style.setProperty(
|
|
309
|
+
"-webkit-text-stroke-color",
|
|
310
|
+
r.origStrokeColor,
|
|
311
|
+
r.origStrokeColorPriority,
|
|
312
|
+
);
|
|
313
|
+
else r.el.style.removeProperty("-webkit-text-stroke-color");
|
|
314
|
+
}
|
|
280
315
|
if (r.origTransition)
|
|
281
316
|
r.el.style.setProperty("transition", r.origTransition, r.origTransitionPriority);
|
|
282
317
|
else r.el.style.removeProperty("transition");
|
|
@@ -361,17 +396,25 @@ window.__contrastAuditFinish = async function (imgBase64, time, candidates) {
|
|
|
361
396
|
var stepY = Math.max(1, Math.floor((y1 - y0) / 6));
|
|
362
397
|
var rr = [],
|
|
363
398
|
gg = [],
|
|
364
|
-
bb = []
|
|
399
|
+
bb = [],
|
|
400
|
+
aa = [];
|
|
365
401
|
for (var y = y0; y <= y1; y += stepY) {
|
|
366
402
|
for (var x = x0; x <= x1; x += stepX) {
|
|
367
403
|
var idx = (y * w + x) * 4;
|
|
368
404
|
rr.push(px[idx]);
|
|
369
405
|
gg.push(px[idx + 1]);
|
|
370
406
|
bb.push(px[idx + 2]);
|
|
407
|
+
aa.push(px[idx + 3]);
|
|
371
408
|
}
|
|
372
409
|
}
|
|
373
410
|
if (rr.length === 0) continue;
|
|
374
411
|
|
|
412
|
+
// A transparent sampled backdrop is supplied by the downstream editor,
|
|
413
|
+
// not this composition. WCAG contrast cannot be inferred until that live
|
|
414
|
+
// video/image is known, so do not invent an opaque browser default and
|
|
415
|
+
// hard-fail an otherwise valid alpha overlay.
|
|
416
|
+
if (median(aa) < 255) continue;
|
|
417
|
+
|
|
375
418
|
var bgR = median(rr),
|
|
376
419
|
bgG = median(gg),
|
|
377
420
|
bgB = median(bb);
|
|
@@ -384,6 +427,23 @@ window.__contrastAuditFinish = async function (imgBase64, time, candidates) {
|
|
|
384
427
|
|
|
385
428
|
var ratio = +wcagRatio(compR, compG, compB, bgR, bgG, bgB).toFixed(2);
|
|
386
429
|
|
|
430
|
+
// A solid text stroke is part of the visible glyph paint. Use whichever
|
|
431
|
+
// of fill or stroke provides the stronger edge contrast, rather than
|
|
432
|
+
// failing readable outlined captions based on fill alone.
|
|
433
|
+
if (c.stroke) {
|
|
434
|
+
var stroke = c.stroke;
|
|
435
|
+
var strokeR = Math.round(stroke[0] * stroke[3] + bgR * (1 - stroke[3]));
|
|
436
|
+
var strokeG = Math.round(stroke[1] * stroke[3] + bgG * (1 - stroke[3]));
|
|
437
|
+
var strokeB = Math.round(stroke[2] * stroke[3] + bgB * (1 - stroke[3]));
|
|
438
|
+
var strokeRatio = +wcagRatio(strokeR, strokeG, strokeB, bgR, bgG, bgB).toFixed(2);
|
|
439
|
+
if (strokeRatio > ratio) {
|
|
440
|
+
compR = strokeR;
|
|
441
|
+
compG = strokeG;
|
|
442
|
+
compB = strokeB;
|
|
443
|
+
ratio = strokeRatio;
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
|
|
387
447
|
out.push({
|
|
388
448
|
time: time,
|
|
389
449
|
selector: c.selector,
|