mirror of
https://github.com/element-hq/element-call.git
synced 2026-09-11 17:56:27 +00:00
113 lines
3.8 KiB
TypeScript
113 lines
3.8 KiB
TypeScript
/*
|
|
Copyright 2026 Element Creations Ltd.
|
|
|
|
SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
|
Please see LICENSE in the repository root for full details.
|
|
*/
|
|
|
|
import { describe, expect, it } from "vitest";
|
|
import postcss from "postcss";
|
|
|
|
import { ROOT_SELECTOR, scopeStylesToRoot } from "./scopeStylesToRoot";
|
|
|
|
const inRoot = `:where(${ROOT_SELECTOR}, ${ROOT_SELECTOR} *)`;
|
|
const isRoot = `:where(${ROOT_SELECTOR})`;
|
|
|
|
async function scope(css: string, file = "base.css"): Promise<string> {
|
|
const result = await postcss([scopeStylesToRoot()]).process(css, {
|
|
from: file,
|
|
});
|
|
return result.css;
|
|
}
|
|
|
|
describe("scopeStylesToRoot", () => {
|
|
it("makes the root stand in for the document", async () => {
|
|
expect(await scope("html { line-height: 1.15 }")).toBe(
|
|
`${isRoot} { line-height: 1.15 }`,
|
|
);
|
|
expect(await scope("body { margin: 0 }")).toBe(`${isRoot} { margin: 0 }`);
|
|
expect(await scope(":root { --a: 1 }")).toBe(`${isRoot} { --a: 1 }`);
|
|
expect(await scope("body.no-scroll-body { position: fixed }")).toBe(
|
|
`${isRoot}.no-scroll-body { position: fixed }`,
|
|
);
|
|
expect(await scope("body .x { color: red }")).toBe(
|
|
`${isRoot} .x { color: red }`,
|
|
);
|
|
});
|
|
|
|
it("collapses selectors that all became the root", async () => {
|
|
expect(await scope("html, body, input { font: inherit }")).toBe(
|
|
`${isRoot},input${inRoot} { font: inherit }`,
|
|
);
|
|
});
|
|
|
|
it("confines everything else to the root and what is inside it", async () => {
|
|
expect(await scope("h1 { margin: 0 }")).toBe(`h1${inRoot} { margin: 0 }`);
|
|
expect(await scope(".cpd-theme-dark { --a: 1 }")).toBe(
|
|
`.cpd-theme-dark${inRoot} { --a: 1 }`,
|
|
);
|
|
expect(await scope("* { box-sizing: border-box }")).toBe(
|
|
`*${inRoot} { box-sizing: border-box }`,
|
|
);
|
|
expect(await scope(".a > .b + .c { color: red }")).toBe(
|
|
`.a>.b+.c${inRoot} { color: red }`,
|
|
);
|
|
});
|
|
|
|
it("keeps pseudo-elements last", async () => {
|
|
expect(await scope("button::-moz-focus-inner { border: 0 }")).toBe(
|
|
`button${inRoot}::-moz-focus-inner { border: 0 }`,
|
|
);
|
|
expect(await scope(".a .b:hover::after { content: '' }")).toBe(
|
|
`.a .b:hover${inRoot}::after { content: '' }`,
|
|
);
|
|
expect(await scope("p:first-letter { color: red }")).toBe(
|
|
`p${inRoot}:first-letter { color: red }`,
|
|
);
|
|
});
|
|
|
|
it("leaves alone what already names the root", async () => {
|
|
const css = `${ROOT_SELECTOR}[data-platform="ios"] { --a: 1 }`;
|
|
expect(await scope(css)).toBe(css);
|
|
});
|
|
|
|
it("reaches into layers and media queries", async () => {
|
|
expect(
|
|
await scope(
|
|
"@layer normalize { h1 { margin: 0 } } @media (min-width: 1px) { p { margin: 0 } }",
|
|
),
|
|
).toBe(
|
|
`@layer normalize { h1${inRoot} { margin: 0 } } @media (min-width: 1px) { p${inRoot} { margin: 0 } }`,
|
|
);
|
|
});
|
|
|
|
it("does not touch keyframes or nested rules", async () => {
|
|
expect(
|
|
await scope("@keyframes spin { from { opacity: 0 } to { opacity: 1 } }"),
|
|
).toBe("@keyframes spin { from { opacity: 0 } to { opacity: 1 } }");
|
|
expect(
|
|
await scope(
|
|
".a { color: red; &:hover { color: blue } .b { color: green } }",
|
|
),
|
|
).toBe(
|
|
`.a${inRoot} { color: red; &:hover { color: blue } .b { color: green } }`,
|
|
);
|
|
});
|
|
|
|
it("only touches the bare selectors of a CSS module", async () => {
|
|
const file = "Settings.module.css";
|
|
expect(await scope("pre { font-size: 1px }", file)).toBe(
|
|
`pre${inRoot} { font-size: 1px }`,
|
|
);
|
|
expect(await scope(".modal pre { font-size: 1px }", file)).toBe(
|
|
`.modal pre${inRoot} { font-size: 1px }`,
|
|
);
|
|
expect(await scope(".box_abc12 { border: 0 }", file)).toBe(
|
|
".box_abc12 { border: 0 }",
|
|
);
|
|
expect(await scope(".a .b_abc12:hover { border: 0 }", file)).toBe(
|
|
".a .b_abc12:hover { border: 0 }",
|
|
);
|
|
});
|
|
});
|