Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Test :state() pseudo-class invalidation with :has()

PASS Test :has() invalidation with :state() pseudo-classes

Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<!doctype html>
<title>:has() invalidation with :state() pseudo-class</title>
<link rel="author" title="Keith Cirkel" href="mailto:[email protected]" />
<link rel="help" href="https://drafts.csswg.org/selectors/#relational" />
<link rel="help" href="https://github.com/whatwg/html/pull/8467" />
<style>
#subject {
background-color: #f00;
}
#subject:has(:state(--green)) {
background-color: #0f0;
}
#subject:has(:state(--blue)) {
background-color: #00f;
}
</style>
<body>
Test :state() pseudo-class invalidation with :has()
<div id="subject">
<my-element id="child"></my-element>
</div>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
const RED = "rgb(255, 0, 0)";
const GREEN = "rgb(0, 255, 0)";
const BLUE = "rgb(0, 0, 255)";

test(() => {
customElements.define(
"my-element",
class MyElement extends HTMLElement {
connectedCallback() {
this.elementInternals = this.attachInternals();
}
},
);
assert_equals(getComputedStyle(subject).backgroundColor, RED);
child.elementInternals.states.add("--green");
assert_equals(getComputedStyle(subject).backgroundColor, GREEN);
child.elementInternals.states.clear();
assert_equals(getComputedStyle(subject).backgroundColor, RED);

child.elementInternals.states.add("--blue");
assert_equals(getComputedStyle(subject).backgroundColor, BLUE);
child.elementInternals.states.clear();
assert_equals(getComputedStyle(subject).backgroundColor, RED);

child.elementInternals.states.add("--green");
child.elementInternals.states.add("--blue");
assert_equals(getComputedStyle(subject).backgroundColor, BLUE);
child.elementInternals.states.delete("--blue");
assert_equals(getComputedStyle(subject).backgroundColor, GREEN);
child.elementInternals.states.delete("--green");
assert_equals(getComputedStyle(subject).backgroundColor, RED);
}, "Test :has() invalidation with :state() pseudo-classes");
</script>
</body>
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@

FAIL ":state(--foo)" should be a valid selector ':state(--foo)' is not a valid selector.
FAIL ":state(bar)" should be a valid selector ':state(bar)' is not a valid selector.
FAIL ":state(--)" should be a valid selector ':state(--)' is not a valid selector.
FAIL ":state(--0)" should be a valid selector ':state(--0)' is not a valid selector.
FAIL ":host(:state(--foo))" should be a valid selector ':host(:state(--foo))' is not a valid selector.
FAIL "my-input[type=\"foo\"]:state(checked)" should be a valid selector 'my-input[type="foo"]:state(checked)' is not a valid selector.
FAIL "my-input[type=\"foo\"]:state(--0)::before" should be a valid selector 'my-input[type="foo"]:state(--0)::before' is not a valid selector.
FAIL "my-input[type=\"foo\"]:state(--0)::part(inner)" should be a valid selector 'my-input[type="foo"]:state(--0)::part(inner)' is not a valid selector.
FAIL "my-input[type=\"foo\"]:state(--0)::part(inner):state(bar)" should be a valid selector 'my-input[type="foo"]:state(--0)::part(inner):state(bar)' is not a valid selector.
FAIL "::part(inner):state(bar)::before" should be a valid selector '::part(inner):state(bar)::before' is not a valid selector.
FAIL "::part(inner):state(bar)::after" should be a valid selector '::part(inner):state(bar)::after' is not a valid selector.
PASS ":state(--foo)" should be a valid selector
PASS ":state(bar)" should be a valid selector
PASS ":state(--)" should be a valid selector
PASS ":state(--0)" should be a valid selector
PASS ":host(:state(--foo))" should be a valid selector
PASS "my-input[type=\"foo\"]:state(checked)" should be a valid selector
PASS "my-input[type=\"foo\"]:state(--0)::before" should be a valid selector
PASS "my-input[type=\"foo\"]:state(--0)::part(inner)" should be a valid selector
PASS "my-input[type=\"foo\"]:state(--0)::part(inner):state(bar)" should be a valid selector
PASS "::part(inner):state(bar)::before" should be a valid selector
PASS "::part(inner):state(bar)::after" should be a valid selector
PASS ":state" should be an invalid selector
PASS ":state(" should be an invalid selector
PASS ":state()" should be an invalid selector
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@

FAIL CustomStateSet behavior of ElementInternals.states: Initial state Can't find variable: CustomStateSet
FAIL CustomStateSet behavior of ElementInternals.states: Exceptions assert_throws_dom: function "() => { i.states.add(''); }" threw object "TypeError: undefined is not an object (evaluating 'i.states.add')" that is not a DOMException SyntaxError: property "code" is equal to undefined, expected 12
FAIL CustomStateSet behavior of ElementInternals.states: Modifications undefined is not an object (evaluating 'i.states.add')
FAIL Updating a CustomStateSet while iterating it should work undefined is not an object (evaluating 'i.states.add')
PASS CustomStateSet behavior of ElementInternals.states: Initial state
PASS CustomStateSet behavior of ElementInternals.states: Exceptions
PASS CustomStateSet behavior of ElementInternals.states: Modifications
PASS Updating a CustomStateSet while iterating it should work

Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@
test(() => {
let i = (new TestElement()).internals;
assert_throws_js(TypeError, () => { i.states.supports('foo'); });
assert_throws_dom('SyntaxError', () => { i.states.add(''); });
assert_throws_dom('SyntaxError', () => { i.states.add('--a\tb'); });
}, 'CustomStateSet behavior of ElementInternals.states: Exceptions');

test(() => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@

FAIL :--foo parsing passes ':--' is not a valid selector.
PASS :--foo parsing failures
FAIL :--foo serialization undefined is not an object (evaluating 'document.styleSheets[0].cssRules[1].cssText')
FAIL :--foo in simple cases ':--foo' is not a valid selector.
FAIL :--foo and other pseudo classes undefined is not an object (evaluating 'states.add')
FAIL :--foo and ::part() undefined is not an object (evaluating 'innerStates.add')
FAIL :--foo and :host() undefined is not an object (evaluating 'outer.i.states.add')
PASS :state() parsing passes
PASS :state() parsing failures
PASS :state(foo) serialization
PASS :state(foo) in simple cases
PASS :state(foo) and other pseudo classes
FAIL :state(foo) and ::part() assert_equals: ::part() followed by :state(innerFoo) expected "0.5" but got "0"
PASS :state(foo) and :host()

Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@
#state-and-part::part(inner) {
opacity: 0;
}
#state-and-part::part(inner):--innerFoo {
#state-and-part::part(inner):state(innerFoo) {
opacity: 0.5;
}
#state-and-part:--outerFoo::part(inner) {
#state-and-part:state(outerFoo)::part(inner) {
opacity: 0.25;
}
:--\(escaped\ state {}
:state(--\)escaped\ state) {}
</style>
<body>
<script>
Expand All @@ -37,7 +37,7 @@
:host {
border-style: solid;
}
:host(:--dotted) {
:host(:state(dotted)) {
border-style: dotted;
}
</style>
Expand All @@ -54,38 +54,44 @@
customElements.define('container-element', ContainerElement);

test(() => {
document.querySelector(':--');
document.querySelector(':--16px');
}, ':--foo parsing passes');
document.querySelector(':state(foo)');
document.querySelector(':state(--foo)');
document.querySelector(':state(--)');
document.querySelector(':state(--16px)');
}, ':state() parsing passes');

test(() => {
assert_throws_dom('SyntaxError', () => { document.querySelector(':--('); });
assert_throws_dom('SyntaxError', () => { document.querySelector(':--()'); });
assert_throws_dom('SyntaxError', () => { document.querySelector(':state()'); });
assert_throws_dom('SyntaxError', () => { document.querySelector(':--)'); });
assert_throws_dom('SyntaxError', () => { document.querySelector(':--='); });
assert_throws_dom('SyntaxError', () => { document.querySelector(':--name=value'); });
}, ':--foo parsing failures');
assert_throws_dom('SyntaxError', () => { document.querySelector(':state(--name=value'); });
assert_throws_dom('SyntaxError', () => { document.querySelector(':state(--name=value)'); });
}, ':state() parsing failures');

test(() => {
assert_equals(document.styleSheets[0].cssRules[1].cssText,
'#state-and-part::part(inner):--innerFoo { opacity: 0.5; }');
'#state-and-part::part(inner):state(innerFoo) { opacity: 0.5; }');
assert_equals(document.styleSheets[0].cssRules[3].selectorText,
':--\\(escaped\\ state');
}, ':--foo serialization');
':state(--\\)escaped\\ state)');
}, ':state(foo) serialization');

test(() => {
let element = new TestElement();
let states = element.i.states;

assert_false(element.matches(':--foo'));
assert_true(element.matches(':not(:--foo)'));
states.add('--foo');
assert_true(element.matches(':--foo'));
assert_true(element.matches(':is(:--foo)'));
assert_false(element.matches(':state(foo)'));
assert_true(element.matches(':not(:state(foo))'));
states.add('foo');
assert_true(element.matches(':state(foo)'));
assert_true(element.matches(':is(:state(foo))'));
element.classList.add('c1', 'c2');
assert_true(element.matches('.c1:--foo'));
assert_true(element.matches(':--foo.c1'));
assert_true(element.matches('.c2:--foo.c1'));
}, ':--foo in simple cases');
assert_true(element.matches('.c1:state(foo)'));
assert_true(element.matches(':state(foo).c1'));
assert_true(element.matches('.c2:state(foo).c1'));
}, ':state(foo) in simple cases');

test(() => {
let element = new TestElement();
Expand All @@ -94,10 +100,10 @@
element.focus();
let states = element.i.states;

states.add('--foo');
assert_true(element.matches(':focus:--foo'));
assert_true(element.matches(':--foo:focus'));
}, ':--foo and other pseudo classes');
states.add('foo');
assert_true(element.matches(':focus:state(foo)'));
assert_true(element.matches(':state(foo):focus'));
}, ':state(foo) and other pseudo classes');

test(() => {
let outer = new ContainerElement();
Expand All @@ -106,27 +112,27 @@
let inner = outer.innerElement;
let innerStates = inner.i.states;

innerStates.add('--innerFoo');
innerStates.add(':state(innerFoo)');
assert_equals(getComputedStyle(inner).opacity, '0.5',
'::part() followed by :--foo');
innerStates.delete('--innerFoo');
innerStates.add('--innerfoo');
'::part() followed by :state(innerFoo)');
innerStates.delete('innerFoo');
innerStates.add('innerfoo');
assert_equals(getComputedStyle(inner).opacity, '0',
':--foo matching should be case-sensitive');
innerStates.delete('--innerfoo');
':state(foo) matching should be case-sensitive');
innerStates.delete('innerfoo');

outer.i.states.add('--outerFoo');
outer.i.states.add('outerFoo');
assert_equals(getComputedStyle(inner).opacity, '0.25',
':--foo followed by ::part()');
}, ':--foo and ::part()');
':state(foo) followed by ::part()');
}, ':state(foo) and ::part()');

test(() => {
let outer = new ContainerElement();
document.body.appendChild(outer);

assert_equals(getComputedStyle(outer).borderStyle, 'solid');
outer.i.states.add('--dotted');
outer.i.states.add('dotted');
assert_equals(getComputedStyle(outer).borderStyle, 'dotted');
}, ':--foo and :host()');
}, ':state(foo) and :host()');
</script>
</body>
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@

FAIL customstateset doesn't crash after GC on detached node promise_test: Unhandled rejection with value: object "TypeError: undefined is not an object (evaluating 'states.add')"
PASS customstateset doesn't crash after GC on detached node

Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,17 @@ PASS idl_test validation
PASS Partial interface ElementInternals: original interface defined
PASS Partial interface ElementInternals: member names are unique
PASS ElementInternals includes ARIAMixin: member names are unique
FAIL CustomStateSet interface: existence and properties of interface object assert_own_property: self does not have own property "CustomStateSet" expected property "CustomStateSet" missing
FAIL CustomStateSet interface object length assert_own_property: self does not have own property "CustomStateSet" expected property "CustomStateSet" missing
FAIL CustomStateSet interface object name assert_own_property: self does not have own property "CustomStateSet" expected property "CustomStateSet" missing
FAIL CustomStateSet interface: existence and properties of interface prototype object assert_own_property: self does not have own property "CustomStateSet" expected property "CustomStateSet" missing
FAIL CustomStateSet interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "CustomStateSet" expected property "CustomStateSet" missing
FAIL CustomStateSet interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "CustomStateSet" expected property "CustomStateSet" missing
FAIL CustomStateSet interface: setlike<DOMString> undefined is not an object (evaluating 'this.get_interface_object().prototype')
FAIL CustomStateSet interface: operation add(DOMString) assert_own_property: self does not have own property "CustomStateSet" expected property "CustomStateSet" missing
FAIL CustomStateSet must be primary interface of customStateSet assert_equals: wrong typeof object expected "object" but got "undefined"
FAIL Stringification of customStateSet assert_equals: wrong typeof object expected "object" but got "undefined"
FAIL CustomStateSet interface: customStateSet must inherit property "add(DOMString)" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined"
FAIL CustomStateSet interface: calling add(DOMString) on customStateSet with too few arguments must throw TypeError assert_equals: wrong typeof object expected "object" but got "undefined"
FAIL ElementInternals interface: attribute states assert_true: The prototype object must have a property "states" expected true got false
PASS CustomStateSet interface: existence and properties of interface object
PASS CustomStateSet interface object length
PASS CustomStateSet interface object name
PASS CustomStateSet interface: existence and properties of interface prototype object
PASS CustomStateSet interface: existence and properties of interface prototype object's "constructor" property
PASS CustomStateSet interface: existence and properties of interface prototype object's @@unscopables property
PASS CustomStateSet interface: setlike<DOMString>
PASS CustomStateSet interface: operation add(DOMString)
PASS CustomStateSet must be primary interface of customStateSet
PASS Stringification of customStateSet
PASS CustomStateSet interface: customStateSet must inherit property "add(DOMString)" with the proper type
PASS CustomStateSet interface: calling add(DOMString) on customStateSet with too few arguments must throw TypeError
PASS ElementInternals interface: attribute states

Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@

PASS state selector has no influence when state is not applied
FAIL state selector has influence when state is applied assert_equals: expected "rgb(0, 255, 0)" but got "rgb(255, 0, 0)"
PASS state selector only applies on given ident

Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<meta name="timeout" content="long" />
<meta
name="author"
title="Keith Cirkel"
href="mailto:[email protected]"
/>
<link rel="help" href="https://wicg.github.io/custom-state-pseudo-class/" />
<title>:state() css selector applies in shadow roots</title>

<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
</head>
<body>
<custom-state id="myCE"> I should be green </custom-state>
<style></style>
<script>
customElements.define(
"custom-state",
class extends HTMLElement {
connectedCallback() {
this.elementInternals = this.attachInternals();
const css = new CSSStyleSheet();
css.replaceSync(`
:host {
color: #f00;
}
:host:state(green) {
color: #0f0;
}
`);
this.attachShadow({ mode: "open" }).adoptedStyleSheets.push(css);
}
},
);

test(function () {
assert_false(myCE.elementInternals.states.has("green"));
assert_equals(
getComputedStyle(myCE).getPropertyValue("color"),
"rgb(255, 0, 0)",
);
}, "state selector has no influence when state is not applied");

test(function (t) {
myCE.elementInternals.states.add("green");
t.add_cleanup(() => {
myCE.elementInternals.states.delete("green");
});
assert_true(myCE.elementInternals.states.has("green"));
assert_equals(
getComputedStyle(myCE).getPropertyValue("color"),
"rgb(0, 255, 0)",
);
}, "state selector has influence when state is applied");

test(function (t) {
myCE.elementInternals.states.add("foo");
t.add_cleanup(() => {
myCE.elementInternals.states.delete("foo");
});
assert_false(myCE.elementInternals.states.has("green"));
assert_true(myCE.elementInternals.states.has("foo"));
assert_equals(
getComputedStyle(myCE).getPropertyValue("color"),
"rgb(255, 0, 0)",
);
}, "state selector only applies on given ident");
</script>
</body>
</html>
Loading