181 lines
7.1 KiB
HTML
181 lines
7.1 KiB
HTML
<!DOCTYPE html>
|
|
<title>Pseudo-elements allowed after ::part()</title>
|
|
<link rel="help" href="https://drafts.csswg.org/css-shadow-parts/">
|
|
<meta name="flags" content="ahem">
|
|
<link rel="stylesheet" href="/fonts/ahem.css">
|
|
<script src="/resources/testharness.js"></script>
|
|
<script src="/resources/testharnessreport.js"></script>
|
|
<script src="../support/parsing-testcommon.js"></script>
|
|
|
|
<body>
|
|
<span style="font-family: Ahem">X</span>
|
|
|
|
<script>
|
|
"use strict";
|
|
|
|
test_invalid_selector("::part(mypart)::part(anotherpart)");
|
|
test_invalid_selector("::part(mypart)::notarealpseudoelement");
|
|
|
|
test_valid_selector("::part(mypart)::after");
|
|
test_valid_selector("::part(mypart)::backdrop");
|
|
test_valid_selector("::part(mypart)::before");
|
|
test_valid_selector("::part(mypart)::cue");
|
|
test_valid_selector("::part(mypart)::details-content");
|
|
test_valid_selector("::part(mypart)::file-selector-button");
|
|
test_valid_selector("::part(mypart)::first-letter");
|
|
test_valid_selector("::part(mypart)::first-line");
|
|
test_valid_selector("::part(mypart)::grammar-error");
|
|
test_valid_selector("::part(mypart)::highlight(myhighlight)");
|
|
test_valid_selector("::part(mypart)::marker");
|
|
test_valid_selector("::part(mypart)::placeholder");
|
|
test_valid_selector("::part(mypart)::search-text");
|
|
test_valid_selector("::part(mypart)::selection");
|
|
test_valid_selector("::part(mypart)::spelling-error");
|
|
test_valid_selector("::part(mypart)::target-text");
|
|
test_valid_selector("::part(mypart)::view-transition");
|
|
test_valid_selector("::part(mypart)::view-transition-group(*)");
|
|
test_valid_selector("::part(mypart)::view-transition-image-pair(*)");
|
|
test_valid_selector("::part(mypart)::view-transition-new(*)");
|
|
test_valid_selector("::part(mypart)::view-transition-old(*)");
|
|
|
|
// to be used inside of a promise_test() function.
|
|
async function run_part_test(t, style_rules, part_html, assertion) {
|
|
let container = document.createElement("div");
|
|
let shadow = container.attachShadow({mode: "open"});
|
|
shadow.innerHTML = `
|
|
${part_html}
|
|
<slot></slot>
|
|
`;
|
|
document.body.append(container);
|
|
let style = document.createElement("style");
|
|
style.innerText = style_rules;
|
|
document.head.append(style);
|
|
t.add_cleanup(() => {
|
|
container.remove();
|
|
style.remove();
|
|
});
|
|
await assertion(container, shadow.firstElementChild);
|
|
}
|
|
|
|
function test_with_part(style_rules, part_html, assertion) {
|
|
promise_test(async (t) => {
|
|
await run_part_test(t, style_rules, part_html, assertion);
|
|
}, `::part styles with ${style_rules} and ${part_html}`);
|
|
}
|
|
|
|
// Generate a random-looking color using the string input as a "seed"
|
|
// (so different tests use different colors).
|
|
function generate_color(str) {
|
|
let sum = Array.from(str).reduce((sum, char) => sum + char.charCodeAt(0), 0);
|
|
return `rgb(${sum % 255}, ${(sum * 2 + 17) % 255}, ${(sum * 3 + 139) % 255})`;
|
|
}
|
|
|
|
function test_pseudo_computed_style(pseudo_element, tag, attributes) {
|
|
promise_test(async (t) => {
|
|
let our_color = generate_color(pseudo_element);
|
|
await run_part_test(t,
|
|
`::part(mypart)${pseudo_element} {
|
|
background: ${our_color};
|
|
}`,
|
|
`<${tag} ${attributes} part='mypart'></${tag}>`,
|
|
async (container, part) => {
|
|
assert_equals(getComputedStyle(part, pseudo_element).backgroundColor, our_color);
|
|
});
|
|
|
|
}, `computed style for ::part()${pseudo_element}`);
|
|
}
|
|
|
|
test_pseudo_computed_style("::after", "div", "");
|
|
test_pseudo_computed_style("::backdrop", "div", "popover='auto'");
|
|
test_pseudo_computed_style("::before", "div", "");
|
|
// NOTE: not testing :cue at all.
|
|
test_pseudo_computed_style("::details-content", "details", "");
|
|
test_pseudo_computed_style("::file-selector-button", "input", "type='file'");
|
|
test_pseudo_computed_style("::first-letter", "div", "");
|
|
test_pseudo_computed_style("::first-line", "div", "");
|
|
test_pseudo_computed_style("::grammar-error", "div", "");
|
|
test_pseudo_computed_style("::highlight(myhighlight)", "div", "");
|
|
test_pseudo_computed_style("::placeholder", "input", "type='text' placeholder='enter text'");
|
|
test_pseudo_computed_style("::search-text", "div", "");
|
|
test_pseudo_computed_style("::selection", "div", "");
|
|
test_pseudo_computed_style("::spelling-error", "div", "");
|
|
test_pseudo_computed_style("::target-text", "div", "");
|
|
// NOTE: Not yet testing computed style for view transition
|
|
// pseudo-elements since they currently only apply to the root element
|
|
// (but are intended to apply to others later).
|
|
|
|
test_with_part(`::part(mypart)::after {
|
|
display: block;
|
|
content: "";
|
|
height: 77px;
|
|
}`,
|
|
`<div part='mypart'></div>`,
|
|
async (container, part) => {
|
|
assert_equals(container.getBoundingClientRect().height, 77);
|
|
});
|
|
|
|
test_with_part(`::part(mypart)::before {
|
|
display: block;
|
|
content: "";
|
|
height: 46px;
|
|
}`,
|
|
`<div part='mypart'></div>`,
|
|
async (container, part) => {
|
|
assert_equals(container.getBoundingClientRect().height, 46);
|
|
});
|
|
|
|
test_with_part(`::part(mypart)::details-content {
|
|
height: 371px;
|
|
}`,
|
|
`<details part='mypart'><summary style="height:47px">summary</summary>details</details>`,
|
|
async (container, part) => {
|
|
assert_equals(container.getBoundingClientRect().height, 371 + 47);
|
|
});
|
|
|
|
test_with_part(`::part(mypart)::file-selector-button {
|
|
height: 94px;
|
|
padding: 0;
|
|
margin: 0;
|
|
border: none;
|
|
appearance: none;
|
|
}`,
|
|
`<input type=file part=mypart>`,
|
|
async (container, part) => {
|
|
assert_equals(container.getBoundingClientRect().height, 94);
|
|
});
|
|
|
|
test_with_part(`::part(mypart) {
|
|
font: 20px/1 Ahem;
|
|
}
|
|
::part(mypart)::first-letter {
|
|
font-size: 86px;
|
|
}`,
|
|
`<div part=mypart>X<br>X</div>`,
|
|
async (container, part) => {
|
|
await document.fonts.ready;
|
|
assert_equals(container.getBoundingClientRect().height, 86 + 20);
|
|
});
|
|
|
|
test_with_part(`::part(mypart) {
|
|
font: 20px/1 Ahem;
|
|
}
|
|
::part(mypart)::first-line {
|
|
font-size: 86px;
|
|
}`,
|
|
`<div part=mypart>X<br>X</div>`,
|
|
async (container, part) => {
|
|
await document.fonts.ready;
|
|
assert_equals(container.getBoundingClientRect().height, 86 + 20);
|
|
});
|
|
|
|
test_with_part(`::part(mypart)::marker {
|
|
font: 63px/1.0 Ahem;
|
|
content: "X";
|
|
}`,
|
|
`<li style="list-style-position: inside" part="mypart"></li>`,
|
|
async (container, part) => {
|
|
await document.fonts.ready;
|
|
assert_equals(container.getBoundingClientRect().height, 63);
|
|
});
|
|
|
|
</script>
|