Remove dynamic style system and tighten inline style checks

This commit is contained in:
thePR0M3TH3AN committed 2025-10-14 08:48:17 -04:00
1 parent 861a9036d3
commit dfa4a98f0a
6 files changed
+40 -295

No files matched your search

+22 -14
View File
@@ -3,11 +3,16 @@ import { beforeEach, afterEach, describe, test } from 'node:test';
import { advanceSlide, createCarousel, destroyCarousel } from '../js/blog/carousel.js';
import { mountProgressBar } from '../js/blog/progressBar.js';
import {
createBlogDomEnvironment,
createSpy,
readDynamicStyleRules,
} from './test-helpers/blog-dom.mjs';
import { createBlogDomEnvironment, createSpy } from './test-helpers/blog-dom.mjs';
function assertHasClasses(element, classes, messagePrefix = 'element') {
classes.forEach((className) => {
assert.ok(
element.classList.contains(className),
`${messagePrefix} should include the “${className}” class`,
);
});
}
function assertNoInlineStyleAttributes(elements, messagePrefix = 'element') {
elements.forEach((element, index) => {
@@ -208,8 +213,12 @@ describe('progress bar', () => {
const wrapper = container.querySelector('.blog-carousel__progress');
assert.ok(wrapper, 'wrapper element should be appended');
assertHasClasses(wrapper, ['blog-carousel__progress', 'blog-progress', 'mt-2'], 'progress wrapper');
assert.strictEqual(wrapper.dataset.carouselProgress, 'true');
assert.strictEqual(wrapper.getAttribute('data-carousel-progress'), 'true');
const meter = wrapper.querySelector('progress.progress--blog');
assert.ok(meter, 'progress meter should be created');
assertHasClasses(meter, ['progress', 'progress--blog'], 'progress meter');
assert.strictEqual(meter.max, 100, 'progress meter should expose a 0-100 range');
assert.strictEqual(meter.value, 0, 'progress meter should start at zero');
assert.strictEqual(meter.dataset.state, 'idle');
@@ -220,12 +229,12 @@ describe('progress bar', () => {
'Carousel progress 0% complete',
'progress meter should emit accessible status text',
);
assert.strictEqual(meter.getAttribute('data-progress-meter'), 'true');
assert.strictEqual(meter.dataset.progressMeter, 'true');
assert.strictEqual(meter.getAttribute('data-variant'), 'blog');
progress.reset();
assert.strictEqual(readDynamicStyleRules(env.document), '', 'no dynamic style rules should be injected');
assert.strictEqual(env.document.getElementById('bitvid-style-system'), null);
assertNoInlineStyleAttributes([container, wrapper, meter], 'progress element');
});
@@ -249,9 +258,6 @@ describe('progress bar', () => {
assert.strictEqual(meter.value, 100);
assert.strictEqual(meter.dataset.state, 'complete');
assert.strictEqual(meter.dataset.progress, '100');
assert.strictEqual(readDynamicStyleRules(env.document), '', 'no dynamic style rules should be injected');
assert.strictEqual(env.document.getElementById('bitvid-style-system'), null);
});
test('manual controls support stop, restart, and cleanup', () => {
@@ -281,9 +287,11 @@ describe('progress bar', () => {
progress.destroy();
assert.strictEqual(container.children.length, 0, 'destroy should remove wrapper from DOM');
assert.strictEqual(readDynamicStyleRules(env.document), '', 'no dynamic style rules should be injected');
assert.strictEqual(env.document.getElementById('bitvid-style-system'), null);
assert.strictEqual(
container.querySelector('[data-carousel-progress]'),
null,
'destroy should remove declarative progress markup',
);
assertNoInlineStyleAttributes([container], 'progress container');
});
});
+2 -2
View File
@@ -188,8 +188,8 @@ test("MediaLoader clears unsupported lazy targets without inline styles", async
]);
assert.equal(
div.style.backgroundImage,
"",
div.hasAttribute("style"),
false,
"background image styles should not be injected at runtime",
);
assert.ok(!observer.observed.has(div));
+14 -6
View File
@@ -3,6 +3,14 @@ import assert from "node:assert/strict";
import { JSDOM } from "jsdom";
import positionFloatingPanel from "../js/ui/utils/positionFloatingPanel.js";
function getInlineStyleValue(element, property) {
const styleAttr = element.getAttribute("style") || "";
const escapedProperty = property.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
const pattern = new RegExp(`(?:^|;)\\s*${escapedProperty}\\s*:\\s*([^;]+)`, "i");
const match = styleAttr.match(pattern);
return match ? match[1].trim() : "";
}
test("flips to top when bottom placement collides with viewport", () => {
const dom = new JSDOM(
`
@@ -54,9 +62,9 @@ test("flips to top when bottom placement collides with viewport", () => {
positioner.update();
assert.equal(panel.dataset.floatingPlacement, "top");
assert.equal(panel.style.position, "fixed");
assert.equal(panel.style.getPropertyValue("--floating-fallback-top"), "132px");
assert.equal(panel.style.getPropertyValue("--floating-fallback-left"), "100px");
assert.equal(getInlineStyleValue(panel, "position"), "fixed");
assert.equal(getInlineStyleValue(panel, "--floating-fallback-top"), "132px");
assert.equal(getInlineStyleValue(panel, "--floating-fallback-left"), "100px");
positioner.destroy();
assert.equal(panel.dataset.floatingPanel, undefined);
@@ -118,7 +126,7 @@ test("respects RTL alignment and clamps within the viewport", () => {
// In RTL mode, start alignment hugs the right edge of the trigger.
assert.equal(panel.dataset.floatingPlacement, "bottom");
assert.equal(panel.dataset.floatingDir, "rtl");
assert.equal(panel.style.getPropertyValue("--floating-fallback-left"), "140px");
assert.equal(getInlineStyleValue(panel, "--floating-fallback-left"), "140px");
positioner.destroy();
});
@@ -182,12 +190,12 @@ test("updates when scroll containers move the trigger", async () => {
panel.dataset.state = "open";
positioner.update();
assert.equal(panel.style.getPropertyValue("--floating-fallback-top"), "152px");
assert.equal(getInlineStyleValue(panel, "--floating-fallback-top"), "152px");
assert.ok(scrollHandler, "scroll listener should be registered");
anchorTop = 60;
scrollHandler?.({ type: "scroll" });
assert.equal(panel.style.getPropertyValue("--floating-fallback-top"), "112px");
assert.equal(getInlineStyleValue(panel, "--floating-fallback-top"), "112px");
positioner.destroy();
window.addEventListener = originalAddEventListener;
-16
View File
@@ -157,22 +157,6 @@ export function installInlineStyleGuard(document) {
};
}
export function readDynamicStyleRules(document) {
const styleElement = document.getElementById('bitvid-style-system');
const sheet = styleElement?.sheet;
if (!sheet) {
return '';
}
try {
return Array.from(sheet.cssRules)
.map((rule) => rule.cssText)
.join('\n');
} catch (error) {
return '';
}
}
export function createBlogDomEnvironment(html) {
const dom = new JSDOM(html, { url: 'https://example.com' });
const { window } = dom;