b8e2a6e910
Front components run in a Web Worker with a fake DOM. Until now the worker had a hand-rolled `style` object for remote elements and the host had its own separate CSS-string parser: two implementations of the same parsing that kept drifting apart (several review rounds fixed edge cases in one copy but not the other). What changed: - One shared `createStyleProxy` now backs `element.style` in the worker, and one shared `parseCssDeclarations` feeds both the worker proxy and the host's `parseCssString`. Most of the diff is existing logic split out of `installStylePropertyOnRemoteElements` into small single-purpose utils (`splitCssDeclarations`, `stripImportantPriorityFromCssValue`, `normalizeCssPropertyName`, `formatCssValue`, ...), not new behavior. - `!important` is stripped from values instead of tracked. Nothing ever read priorities back, and the host applies styles through React inline styles, which cannot express `!important`. Rendering note: `color: red !important` used to reach React as an invalid value (property silently not applied); it now applies, without the priority. - Style writes flush to the host synchronously, exactly as on main. - The parser handles quotes, escapes and parentheses; CSS comments inside hand-written `cssText` are not supported. This shared proxy is also the base for the worker `getComputedStyle` stub in the geometry PR. Second of three PRs splitting the geometry mirror work.
55 lines
1.7 KiB
TypeScript
55 lines
1.7 KiB
TypeScript
import { splitCssDeclarations } from '../splitCssDeclarations';
|
|
|
|
describe('splitCssDeclarations', () => {
|
|
it('should split plain declarations on semicolons', () => {
|
|
expect(splitCssDeclarations('color: red; font-size: 14px')).toEqual([
|
|
'color: red',
|
|
' font-size: 14px',
|
|
]);
|
|
});
|
|
|
|
it('should keep semicolons inside quoted strings', () => {
|
|
expect(splitCssDeclarations('content: "a;b"; color: red')).toEqual([
|
|
'content: "a;b"',
|
|
' color: red',
|
|
]);
|
|
});
|
|
|
|
it('should keep semicolons inside single quoted strings', () => {
|
|
expect(splitCssDeclarations("content: 'a;b'")).toEqual(["content: 'a;b'"]);
|
|
});
|
|
|
|
it('should keep semicolons after an escaped quote inside a string', () => {
|
|
expect(splitCssDeclarations('content: "a\\";b"; color: red')).toEqual([
|
|
'content: "a\\";b"',
|
|
' color: red',
|
|
]);
|
|
});
|
|
|
|
it('should keep semicolons inside url parentheses', () => {
|
|
expect(
|
|
splitCssDeclarations(
|
|
'background: url(data:image/png;base64,abc); color: red',
|
|
),
|
|
).toEqual(['background: url(data:image/png;base64,abc)', ' color: red']);
|
|
});
|
|
|
|
it('should keep slash star sequences as plain characters', () => {
|
|
expect(
|
|
splitCssDeclarations(
|
|
'background: url(http://example.com/a/*/b.png); color: red',
|
|
),
|
|
).toEqual(['background: url(http://example.com/a/*/b.png)', ' color: red']);
|
|
});
|
|
|
|
it('should handle nested parentheses', () => {
|
|
expect(
|
|
splitCssDeclarations('width: calc(min(10px; 2px)); color: red'),
|
|
).toEqual(['width: calc(min(10px; 2px))', ' color: red']);
|
|
});
|
|
|
|
it('should return the whole text when there is no top level semicolon', () => {
|
|
expect(splitCssDeclarations('color: red')).toEqual(['color: red']);
|
|
});
|
|
});
|