mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-25 09:00:22 +00:00
Tests: Import more CSS selector tests from WPT
This commit is contained in:
parent
9dff6bca1f
commit
6c945fc353
Notes:
github-actions[bot]
2024-11-06 20:44:15 +00:00
Author: https://github.com/awesomekling Commit: https://github.com/LadybirdBrowser/ladybird/commit/6c945fc3537 Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/2204
72 changed files with 2798 additions and 0 deletions
|
@ -0,0 +1,65 @@
|
|||
Summary
|
||||
|
||||
Harness status: OK
|
||||
|
||||
Rerun
|
||||
|
||||
Found 54 tests
|
||||
|
||||
30 Pass
|
||||
24 Fail
|
||||
Details
|
||||
Result Test Name MessagePass Expected HTML element to match :first-child with matches, querySelector(), and querySelectorAll()
|
||||
Pass Expected HTML element to match :last-child with matches, querySelector(), and querySelectorAll()
|
||||
Pass Expected HTML element to match :only-child with matches, querySelector(), and querySelectorAll()
|
||||
Pass Expected HTML element to match :first-of-type with matches, querySelector(), and querySelectorAll()
|
||||
Pass Expected HTML element to match :last-of-type with matches, querySelector(), and querySelectorAll()
|
||||
Pass Expected HTML element to match :only-of-type with matches, querySelector(), and querySelectorAll()
|
||||
Fail Expected HTML element to match :nth-child(1) with matches, querySelector(), and querySelectorAll()
|
||||
Fail Expected HTML element to match :nth-child(n) with matches, querySelector(), and querySelectorAll()
|
||||
Fail Expected HTML element to match :nth-last-child(1) with matches, querySelector(), and querySelectorAll()
|
||||
Fail Expected HTML element to match :nth-last-child(n) with matches, querySelector(), and querySelectorAll()
|
||||
Fail Expected HTML element to match :nth-of-type(1) with matches, querySelector(), and querySelectorAll()
|
||||
Fail Expected HTML element to match :nth-of-type(n) with matches, querySelector(), and querySelectorAll()
|
||||
Fail Expected HTML element to match :nth-last-of-type(1) with matches, querySelector(), and querySelectorAll()
|
||||
Fail Expected HTML element to match :nth-last-of-type(n) with matches, querySelector(), and querySelectorAll()
|
||||
Pass Expected HTML element to not match :nth-child(2) with matches, querySelector(), and querySelectorAll()
|
||||
Pass Expected HTML element to not match :nth-last-child(2) with matches, querySelector(), and querySelectorAll()
|
||||
Pass Expected HTML element to not match :nth-of-type(2) with matches, querySelector(), and querySelectorAll()
|
||||
Pass Expected HTML element to not match :nth-last-of-type(2) with matches, querySelector(), and querySelectorAll()
|
||||
Pass Expected DIV element to match :first-child with matches
|
||||
Pass Expected DIV element to match :last-child with matches
|
||||
Pass Expected DIV element to match :only-child with matches
|
||||
Pass Expected DIV element to match :first-of-type with matches
|
||||
Pass Expected DIV element to match :last-of-type with matches
|
||||
Pass Expected DIV element to match :only-of-type with matches
|
||||
Fail Expected DIV element to match :nth-child(1) with matches
|
||||
Fail Expected DIV element to match :nth-child(n) with matches
|
||||
Fail Expected DIV element to match :nth-last-child(1) with matches
|
||||
Fail Expected DIV element to match :nth-last-child(n) with matches
|
||||
Fail Expected DIV element to match :nth-of-type(1) with matches
|
||||
Fail Expected DIV element to match :nth-of-type(n) with matches
|
||||
Fail Expected DIV element to match :nth-last-of-type(1) with matches
|
||||
Fail Expected DIV element to match :nth-last-of-type(n) with matches
|
||||
Pass Expected DIV element to not match :nth-child(2) with matches
|
||||
Pass Expected DIV element to not match :nth-last-child(2) with matches
|
||||
Pass Expected DIV element to not match :nth-of-type(2) with matches
|
||||
Pass Expected DIV element to not match :nth-last-of-type(2) with matches
|
||||
Pass Expected DIV element to match :first-child with matches, querySelector(), and querySelectorAll()
|
||||
Pass Expected DIV element to match :last-child with matches, querySelector(), and querySelectorAll()
|
||||
Pass Expected DIV element to match :only-child with matches, querySelector(), and querySelectorAll()
|
||||
Pass Expected DIV element to match :first-of-type with matches, querySelector(), and querySelectorAll()
|
||||
Pass Expected DIV element to match :last-of-type with matches, querySelector(), and querySelectorAll()
|
||||
Pass Expected DIV element to match :only-of-type with matches, querySelector(), and querySelectorAll()
|
||||
Fail Expected DIV element to match :nth-child(1) with matches, querySelector(), and querySelectorAll()
|
||||
Fail Expected DIV element to match :nth-child(n) with matches, querySelector(), and querySelectorAll()
|
||||
Fail Expected DIV element to match :nth-last-child(1) with matches, querySelector(), and querySelectorAll()
|
||||
Fail Expected DIV element to match :nth-last-child(n) with matches, querySelector(), and querySelectorAll()
|
||||
Fail Expected DIV element to match :nth-of-type(1) with matches, querySelector(), and querySelectorAll()
|
||||
Fail Expected DIV element to match :nth-of-type(n) with matches, querySelector(), and querySelectorAll()
|
||||
Fail Expected DIV element to match :nth-last-of-type(1) with matches, querySelector(), and querySelectorAll()
|
||||
Fail Expected DIV element to match :nth-last-of-type(n) with matches, querySelector(), and querySelectorAll()
|
||||
Pass Expected DIV element to not match :nth-child(2) with matches, querySelector(), and querySelectorAll()
|
||||
Pass Expected DIV element to not match :nth-last-child(2) with matches, querySelector(), and querySelectorAll()
|
||||
Pass Expected DIV element to not match :nth-of-type(2) with matches, querySelector(), and querySelectorAll()
|
||||
Pass Expected DIV element to not match :nth-last-of-type(2) with matches, querySelector(), and querySelectorAll()
|
|
@ -0,0 +1,16 @@
|
|||
Summary
|
||||
|
||||
Harness status: OK
|
||||
|
||||
Rerun
|
||||
|
||||
Found 5 tests
|
||||
|
||||
3 Pass
|
||||
2 Fail
|
||||
Details
|
||||
Result Test Name MessageFail bdi element without dir content attribute
|
||||
Fail bdi element with invalid dir content attribute
|
||||
Pass bdi element with dir=auto content attribute
|
||||
Pass bdi element with dir=ltr content attribute
|
||||
Pass bdi element with dir=rtl content attribute
|
|
@ -0,0 +1,30 @@
|
|||
Summary
|
||||
|
||||
Harness status: OK
|
||||
|
||||
Rerun
|
||||
|
||||
Found 20 tests
|
||||
|
||||
20 Pass
|
||||
Details
|
||||
Result Test Name MessagePass input element whose type attribute is in the telephone state
|
||||
Pass input element whose type attribute is in the telephone state in a RTL block
|
||||
Pass input element whose type attribute is in the password state
|
||||
Pass input element whose type attribute is in the text state
|
||||
Pass input element whose type attribute is in the search state
|
||||
Pass input element whose type attribute is in the url state
|
||||
Pass input element whose type attribute is in the email state
|
||||
Pass input element whose type attribute is in the submit state
|
||||
Pass input element whose type attribute is in the reset state
|
||||
Pass input element whose type attribute is in the button state
|
||||
Pass input element whose type attribute is in the hidden state
|
||||
Pass dynamic changes to type of input elements affect whether value is used for dir=auto
|
||||
Pass input element whose type attribute is in the date state
|
||||
Pass input element whose type attribute is in the time state
|
||||
Pass input element whose type attribute is in the number state
|
||||
Pass input element whose type attribute is in the range state
|
||||
Pass input element whose type attribute is in the color state
|
||||
Pass input element whose type attribute is in the checkbox state
|
||||
Pass input element whose type attribute is in the radio state
|
||||
Pass input element whose type attribute is in the image state
|
|
@ -0,0 +1,32 @@
|
|||
Summary
|
||||
|
||||
Harness status: OK
|
||||
|
||||
Rerun
|
||||
|
||||
Found 22 tests
|
||||
|
||||
22 Pass
|
||||
Details
|
||||
Result Test Name MessagePass Initial directionality of element div1 is ltr
|
||||
Pass Initial directionality of element div1_1 is ltr
|
||||
Pass Initial directionality of element div2 is rtl
|
||||
Pass Initial directionality of element div2_1 is rtl
|
||||
Pass Initial directionality of element div3 is ltr
|
||||
Pass Initial directionality of element div3_1 is rtl
|
||||
Pass Initial directionality of element div3_2 is ltr
|
||||
Pass Initial directionality of element div4 is ltr
|
||||
Pass Initial directionality of element div4_1 is ltr
|
||||
Pass Initial directionality of element div4_1_1 is ltr
|
||||
Pass Updated directionality of element div1 is rtl
|
||||
Pass Updated directionality of element div1_1 is rtl
|
||||
Pass Updated directionality of element div1 is ltr
|
||||
Pass Updated directionality of element div1_1 is ltr
|
||||
Pass Reupdated directionality of element div1 is ltr
|
||||
Pass Reupdated directionality of element div1_1 is ltr
|
||||
Pass Updated directionality of element div2 is ltr
|
||||
Pass Updated directionality of element div3 is rtl
|
||||
Pass Updated directionality of element div3 is ltr
|
||||
Pass Updated directionality of element div4 is rtl
|
||||
Pass Updated directionality of element div4_1 is rtl
|
||||
Pass Updated directionality of element div4_1_1 is rtl
|
|
@ -0,0 +1,15 @@
|
|||
Summary
|
||||
|
||||
Harness status: OK
|
||||
|
||||
Rerun
|
||||
|
||||
Found 4 tests
|
||||
|
||||
3 Pass
|
||||
1 Fail
|
||||
Details
|
||||
Result Test Name MessageFail :dir() allows any ident value but strings other than ltr/rtl don't match Failed to parse selector
|
||||
Pass :dir() requires exactly an ident argument
|
||||
Pass :dir() works in compound selectors
|
||||
Pass :dir() works in complex selectors
|
|
@ -0,0 +1,15 @@
|
|||
Summary
|
||||
|
||||
Harness status: OK
|
||||
|
||||
Rerun
|
||||
|
||||
Found 5 tests
|
||||
|
||||
5 Pass
|
||||
Details
|
||||
Result Test Name MessagePass Whitespace nodes should be ignored.
|
||||
Pass There is the second child element.
|
||||
Pass A comment node should be ignored.
|
||||
Pass Non-whitespace text node should be ignored.
|
||||
Pass The second child should not be matched.
|
|
@ -0,0 +1,19 @@
|
|||
Summary
|
||||
|
||||
Harness status: OK
|
||||
|
||||
Rerun
|
||||
|
||||
Found 9 tests
|
||||
|
||||
9 Pass
|
||||
Details
|
||||
Result Test Name MessagePass Whitespace nodes should be ignored.
|
||||
Pass Thre is another child element of the same type.
|
||||
Pass There is a prior child element of another type.
|
||||
Pass A previous element of the parent should not affect.
|
||||
Pass The parent element of the same type should not affect.
|
||||
Pass A child of the previous element should not affect.
|
||||
Pass The second child element of the same type should not match.
|
||||
Pass The second child element of the same type should not match, the first child has case-different tag name.
|
||||
Pass Dynamic insertion and removal
|
|
@ -0,0 +1,12 @@
|
|||
Summary
|
||||
|
||||
Harness status: OK
|
||||
|
||||
Rerun
|
||||
|
||||
Found 2 tests
|
||||
|
||||
2 Fail
|
||||
Details
|
||||
Result Test Name MessageFail Test ':focus' after 'display:none' on input
|
||||
Fail Test ':focus' after 'display:none' on input's parent
|
|
@ -0,0 +1,13 @@
|
|||
Summary
|
||||
|
||||
Harness status: OK
|
||||
|
||||
Rerun
|
||||
|
||||
Found 3 tests
|
||||
|
||||
3 Pass
|
||||
Details
|
||||
Result Test Name MessagePass Checks that ':focus' pseudo-class matches inside 'focus' event handler
|
||||
Pass Checks that ':focus-visible' pseudo-class matches inside 'focus' event handler
|
||||
Pass Checks that ':focus-within' pseudo-class matches inside 'focus' event handler
|
|
@ -0,0 +1,13 @@
|
|||
Summary
|
||||
|
||||
Harness status: OK
|
||||
|
||||
Rerun
|
||||
|
||||
Found 3 tests
|
||||
|
||||
3 Pass
|
||||
Details
|
||||
Result Test Name MessagePass Checks that ':focus' pseudo-class matches inside 'focusin' event handler
|
||||
Pass Checks that ':focus-visible' pseudo-class matches inside 'focusin' event handler
|
||||
Pass Checks that ':focus-within' pseudo-class matches inside 'focusin' event handler
|
|
@ -0,0 +1,11 @@
|
|||
Summary
|
||||
|
||||
Harness status: OK
|
||||
|
||||
Rerun
|
||||
|
||||
Found 1 tests
|
||||
|
||||
1 Fail
|
||||
Details
|
||||
Result Test Name MessageFail Autofocus should match :focus-visible
|
|
@ -0,0 +1,11 @@
|
|||
Summary
|
||||
|
||||
Harness status: OK
|
||||
|
||||
Rerun
|
||||
|
||||
Found 1 tests
|
||||
|
||||
1 Pass
|
||||
Details
|
||||
Result Test Name MessagePass Programmatic focus on page load should match :focus-visible
|
|
@ -0,0 +1,11 @@
|
|||
Summary
|
||||
|
||||
Harness status: OK
|
||||
|
||||
Rerun
|
||||
|
||||
Found 1 tests
|
||||
|
||||
1 Pass
|
||||
Details
|
||||
Result Test Name MessagePass :focus-visible matches after script focus move
|
|
@ -0,0 +1,48 @@
|
|||
Summary
|
||||
|
||||
Harness status: OK
|
||||
|
||||
Rerun
|
||||
|
||||
Found 38 tests
|
||||
|
||||
38 Pass
|
||||
Details
|
||||
Result Test Name MessagePass ":focus-visible" should be a valid selector
|
||||
Pass By default initial programatic focus matches ':focus-visible', so the element ABBR shows a focus ring with 'outline-style: auto'
|
||||
Pass By default initial programatic focus matches ':focus-visible', so the element ADDRESS shows a focus ring with 'outline-style: auto'
|
||||
Pass By default initial programatic focus matches ':focus-visible', so the element BDI shows a focus ring with 'outline-style: auto'
|
||||
Pass By default initial programatic focus matches ':focus-visible', so the element BLOCKQUOTE shows a focus ring with 'outline-style: auto'
|
||||
Pass By default initial programatic focus matches ':focus-visible', so the element CODE shows a focus ring with 'outline-style: auto'
|
||||
Pass By default initial programatic focus matches ':focus-visible', so the element DD shows a focus ring with 'outline-style: auto'
|
||||
Pass By default initial programatic focus matches ':focus-visible', so the element SUMMARY shows a focus ring with 'outline-style: auto'
|
||||
Pass By default initial programatic focus matches ':focus-visible', so the element DETAILS shows a focus ring with 'outline-style: auto'
|
||||
Pass By default initial programatic focus matches ':focus-visible', so the element DIV shows a focus ring with 'outline-style: auto'
|
||||
Pass By default initial programatic focus matches ':focus-visible', so the element DL shows a focus ring with 'outline-style: auto'
|
||||
Pass By default initial programatic focus matches ':focus-visible', so the element DT shows a focus ring with 'outline-style: auto'
|
||||
Pass By default initial programatic focus matches ':focus-visible', so the element EM shows a focus ring with 'outline-style: auto'
|
||||
Pass By default initial programatic focus matches ':focus-visible', so the element LEGEND shows a focus ring with 'outline-style: auto'
|
||||
Pass By default initial programatic focus matches ':focus-visible', so the element FIGCAPTION shows a focus ring with 'outline-style: auto'
|
||||
Pass By default initial programatic focus matches ':focus-visible', so the element FIGURE shows a focus ring with 'outline-style: auto'
|
||||
Pass By default initial programatic focus matches ':focus-visible', so the element FORM shows a focus ring with 'outline-style: auto'
|
||||
Pass By default initial programatic focus matches ':focus-visible', so the element HR shows a focus ring with 'outline-style: auto'
|
||||
Pass By default initial programatic focus matches ':focus-visible', so the element IMG shows a focus ring with 'outline-style: auto'
|
||||
Pass By default initial programatic focus matches ':focus-visible', so the element LABEL shows a focus ring with 'outline-style: auto'
|
||||
Pass By default initial programatic focus matches ':focus-visible', so the element LI shows a focus ring with 'outline-style: auto'
|
||||
Pass By default initial programatic focus matches ':focus-visible', so the element MARK shows a focus ring with 'outline-style: auto'
|
||||
Pass By default initial programatic focus matches ':focus-visible', so the element METER shows a focus ring with 'outline-style: auto'
|
||||
Pass By default initial programatic focus matches ':focus-visible', so the element OL shows a focus ring with 'outline-style: auto'
|
||||
Pass By default initial programatic focus matches ':focus-visible', so the element PRE shows a focus ring with 'outline-style: auto'
|
||||
Pass By default initial programatic focus matches ':focus-visible', so the element PROGRESS shows a focus ring with 'outline-style: auto'
|
||||
Pass By default initial programatic focus matches ':focus-visible', so the element P shows a focus ring with 'outline-style: auto'
|
||||
Pass By default initial programatic focus matches ':focus-visible', so the element SMALL shows a focus ring with 'outline-style: auto'
|
||||
Pass By default initial programatic focus matches ':focus-visible', so the element S shows a focus ring with 'outline-style: auto'
|
||||
Pass By default initial programatic focus matches ':focus-visible', so the element STRONG shows a focus ring with 'outline-style: auto'
|
||||
Pass By default initial programatic focus matches ':focus-visible', so the element SUB shows a focus ring with 'outline-style: auto'
|
||||
Pass By default initial programatic focus matches ':focus-visible', so the element SUP shows a focus ring with 'outline-style: auto'
|
||||
Pass By default initial programatic focus matches ':focus-visible', so the element CAPTION shows a focus ring with 'outline-style: auto'
|
||||
Pass By default initial programatic focus matches ':focus-visible', so the element TABLE shows a focus ring with 'outline-style: auto'
|
||||
Pass By default initial programatic focus matches ':focus-visible', so the element TD shows a focus ring with 'outline-style: auto'
|
||||
Pass By default initial programatic focus matches ':focus-visible', so the element TIME shows a focus ring with 'outline-style: auto'
|
||||
Pass By default initial programatic focus matches ':focus-visible', so the element UL shows a focus ring with 'outline-style: auto'
|
||||
Pass By default initial programatic focus matches ':focus-visible', so the element U shows a focus ring with 'outline-style: auto'
|
|
@ -0,0 +1,12 @@
|
|||
Summary
|
||||
|
||||
Harness status: OK
|
||||
|
||||
Rerun
|
||||
|
||||
Found 2 tests
|
||||
|
||||
2 Pass
|
||||
Details
|
||||
Result Test Name MessagePass ":focus-visible" should be a valid selector
|
||||
Pass By default initial programatic focus matches ':focus-visible', so the element shows a focus ring with 'outline-style: auto'
|
|
@ -0,0 +1,13 @@
|
|||
Summary
|
||||
|
||||
Harness status: OK
|
||||
|
||||
Rerun
|
||||
|
||||
Found 2 tests
|
||||
|
||||
1 Pass
|
||||
1 Fail
|
||||
Details
|
||||
Result Test Name MessagePass ":focus-visible" should be a valid selector
|
||||
Fail :focus-visible doesn't match on ShadowRoot
|
|
@ -0,0 +1,12 @@
|
|||
Summary
|
||||
|
||||
Harness status: OK
|
||||
|
||||
Rerun
|
||||
|
||||
Found 2 tests
|
||||
|
||||
2 Pass
|
||||
Details
|
||||
Result Test Name MessagePass ":focus-visible" should be a valid selector
|
||||
Pass Script focus without any previous user interaction matches :focus-visible
|
|
@ -0,0 +1,23 @@
|
|||
Summary
|
||||
|
||||
Harness status: OK
|
||||
|
||||
Rerun
|
||||
|
||||
Found 12 tests
|
||||
|
||||
1 Pass
|
||||
11 Fail
|
||||
Details
|
||||
Result Test Name MessagePass Initial State
|
||||
Fail Focus 'target1'
|
||||
Fail Focus 'target2'
|
||||
Fail Focus 'target1' again
|
||||
Fail Focus 'target2' again
|
||||
Fail Focus 'target1' once again
|
||||
Fail Detach 'container1' from the document
|
||||
Fail Try to focus 'target1'
|
||||
Fail Focus 'target2' once again
|
||||
Fail Attach 'container1' in 'container2'
|
||||
Fail Focus 'target1' for the last time
|
||||
Fail Move 'target1' in 'container2'
|
|
@ -0,0 +1,12 @@
|
|||
Summary
|
||||
|
||||
Harness status: OK
|
||||
|
||||
Rerun
|
||||
|
||||
Found 2 tests
|
||||
|
||||
2 Fail
|
||||
Details
|
||||
Result Test Name MessageFail Test ':focus-within' after 'display:none' on input
|
||||
Fail Test ':focus-within' after 'display:none' on input's parent
|
|
@ -0,0 +1,11 @@
|
|||
Summary
|
||||
|
||||
Harness status: OK
|
||||
|
||||
Rerun
|
||||
|
||||
Found 1 tests
|
||||
|
||||
1 Fail
|
||||
Details
|
||||
Result Test Name MessageFail Test string hash collision in bucketing
|
|
@ -0,0 +1,15 @@
|
|||
Summary
|
||||
|
||||
Harness status: OK
|
||||
|
||||
Rerun
|
||||
|
||||
Found 5 tests
|
||||
|
||||
5 Pass
|
||||
Details
|
||||
Result Test Name MessagePass Whitespace nodes should be ignored.
|
||||
Pass There is a prior child element.
|
||||
Pass A comment node should be ignored.
|
||||
Pass Non-whitespace text node should be ignored.
|
||||
Pass The first child should not be matched.
|
|
@ -0,0 +1,19 @@
|
|||
Summary
|
||||
|
||||
Harness status: OK
|
||||
|
||||
Rerun
|
||||
|
||||
Found 9 tests
|
||||
|
||||
9 Pass
|
||||
Details
|
||||
Result Test Name MessagePass Whitespace nodes should be ignored.
|
||||
Pass Thre is another child element of the same type.
|
||||
Pass There is a posterior child element of another type.
|
||||
Pass A next element of the parent should not affect.
|
||||
Pass The parent element of the same type should not affect.
|
||||
Pass A child of the next element should not affect.
|
||||
Pass The first child element of the same type should not match.
|
||||
Pass The first child element of the same type should not match, the last child has a case-different tag name.
|
||||
Pass Dynamic insertion and removal
|
|
@ -0,0 +1,11 @@
|
|||
Summary
|
||||
|
||||
Harness status: OK
|
||||
|
||||
Rerun
|
||||
|
||||
Found 1 tests
|
||||
|
||||
1 Pass
|
||||
Details
|
||||
Result Test Name MessagePass attribute selectors with missing right tokens succeed
|
|
@ -0,0 +1,30 @@
|
|||
Summary
|
||||
|
||||
Harness status: OK
|
||||
|
||||
Rerun
|
||||
|
||||
Found 20 tests
|
||||
|
||||
20 Pass
|
||||
Details
|
||||
Result Test Name MessagePass :not(#a) matches expected elements
|
||||
Pass :not(#a #d) matches expected elements
|
||||
Pass :not(#b div) matches expected elements
|
||||
Pass :not(div div) matches expected elements
|
||||
Pass :not(div + div) matches expected elements
|
||||
Pass :not(main > div) matches expected elements
|
||||
Pass :not(#a, #b) matches expected elements
|
||||
Pass :not(#f, main > div) matches expected elements
|
||||
Pass :not(div + div + div, div + div > div) matches expected elements
|
||||
Pass :not(div:nth-child(1)) matches expected elements
|
||||
Pass :not(:not(div)) matches expected elements
|
||||
Pass :not(:not(:not(div))) matches expected elements
|
||||
Pass :not(div, span) matches expected elements
|
||||
Pass :not(span, p) matches expected elements
|
||||
Pass :not(#unknown, .unknown) matches expected elements
|
||||
Pass :not(#unknown > div, span) matches expected elements
|
||||
Pass :not(#unknown ~ div, span) matches expected elements
|
||||
Pass :not(:hover div) matches expected elements
|
||||
Pass :not(:link div) matches expected elements
|
||||
Pass :not(:visited div) matches expected elements
|
|
@ -0,0 +1,18 @@
|
|||
Summary
|
||||
|
||||
Harness status: OK
|
||||
|
||||
Rerun
|
||||
|
||||
Found 8 tests
|
||||
|
||||
8 Fail
|
||||
Details
|
||||
Result Test Name MessageFail :not(#foo) wins over :not(.foo)
|
||||
Fail :not(div#foo) wins over :not(#foo)
|
||||
Fail :not(.bar, #foo) has same specificity as :not(#foo, .bar)
|
||||
Fail :not(.bar, #foo) wins over :not(.foo, .bar)
|
||||
Fail :not(span + span) wins over :not(span)
|
||||
Fail :not(span, li, p) wins over :not(span, lo, p)
|
||||
Fail :not(span, :not(:not(.a#foo)), p) wins over :not(span, #foo, p)
|
||||
Fail :not(span, #foo, p) wins over :not(span, :where(.a#foo), p)
|
|
@ -0,0 +1,11 @@
|
|||
Summary
|
||||
|
||||
Harness status: OK
|
||||
|
||||
Rerun
|
||||
|
||||
Found 1 tests
|
||||
|
||||
1 Pass
|
||||
Details
|
||||
Result Test Name MessagePass CSS Selectors: :nth-last-child() with no argument
|
|
@ -0,0 +1,14 @@
|
|||
Summary
|
||||
|
||||
Harness status: OK
|
||||
|
||||
Rerun
|
||||
|
||||
Found 3 tests
|
||||
|
||||
2 Pass
|
||||
1 Fail
|
||||
Details
|
||||
Result Test Name MessagePass :nth-of-type selectors matching takes element namespace into account (http://www.w3.org/1999/xhtml)
|
||||
Pass :nth-of-type selectors matching takes element namespace into account (http://dummy1/)
|
||||
Fail :nth-of-type selectors matching takes element namespace into account (http://dummy2/)
|
|
@ -0,0 +1,15 @@
|
|||
Summary
|
||||
|
||||
Harness status: OK
|
||||
|
||||
Rerun
|
||||
|
||||
Found 5 tests
|
||||
|
||||
5 Pass
|
||||
Details
|
||||
Result Test Name MessagePass Whitespace nodes should be ignored.
|
||||
Pass A comment node should be ignored.
|
||||
Pass Non-whitespace text node should be ignored.
|
||||
Pass There is another child element.
|
||||
Pass Dynamic addition and removal
|
|
@ -0,0 +1,15 @@
|
|||
Summary
|
||||
|
||||
Harness status: OK
|
||||
|
||||
Rerun
|
||||
|
||||
Found 5 tests
|
||||
|
||||
5 Pass
|
||||
Details
|
||||
Result Test Name MessagePass Whitespace nodes should be ignored.
|
||||
Pass A comment node should be ignored.
|
||||
Pass Non-whitespace text node should be ignored.
|
||||
Pass There is another child element of a different type.
|
||||
Pass Dynamic addition and removal
|
|
@ -0,0 +1,17 @@
|
|||
Summary
|
||||
|
||||
Harness status: OK
|
||||
|
||||
Rerun
|
||||
|
||||
Found 7 tests
|
||||
|
||||
7 Pass
|
||||
Details
|
||||
Result Test Name MessagePass CSS Selectors Test: :placeholder-shown matching
|
||||
Pass CSS Selectors Test: :placeholder-shown matching 1
|
||||
Pass CSS Selectors Test: :placeholder-shown matching 2
|
||||
Pass CSS Selectors Test: :placeholder-shown matching 3
|
||||
Pass CSS Selectors Test: :placeholder-shown matching 4
|
||||
Pass CSS Selectors Test: :placeholder-shown matching 5
|
||||
Pass CSS Selectors Test: :placeholder-shown matching 6
|
|
@ -0,0 +1,14 @@
|
|||
Summary
|
||||
|
||||
Harness status: OK
|
||||
|
||||
Rerun
|
||||
|
||||
Found 4 tests
|
||||
|
||||
4 Pass
|
||||
Details
|
||||
Result Test Name MessagePass :enabeld should match to enabled controls
|
||||
Pass :disabled should match to enabled controls
|
||||
Pass :not(:enabeld) should match to disabled controls and non-controls
|
||||
Pass :not(:disabled) should match to enabled controls and non-controls
|
|
@ -0,0 +1,14 @@
|
|||
Summary
|
||||
|
||||
Harness status: OK
|
||||
|
||||
Rerun
|
||||
|
||||
Found 3 tests
|
||||
|
||||
2 Pass
|
||||
1 Fail
|
||||
Details
|
||||
Result Test Name MessagePass scope-selector
|
||||
Pass scope-selector 1
|
||||
Fail querySelector() with ":scope" should return the document element, if present in the subtree
|
|
@ -0,0 +1,12 @@
|
|||
Summary
|
||||
|
||||
Harness status: OK
|
||||
|
||||
Rerun
|
||||
|
||||
Found 2 tests
|
||||
|
||||
2 Pass
|
||||
Details
|
||||
Result Test Name MessagePass input:placeholder-shown should not be matched
|
||||
Pass textarea:placeholder-shown should not be matched
|
|
@ -0,0 +1,14 @@
|
|||
Summary
|
||||
|
||||
Harness status: OK
|
||||
|
||||
Rerun
|
||||
|
||||
Found 3 tests
|
||||
|
||||
1 Pass
|
||||
2 Fail
|
||||
Details
|
||||
Result Test Name MessageFail CSS selector should match for Unicode uppercase element
|
||||
Fail Elements with namespace should work the same way
|
||||
Pass `querySelector` should not use Unicode case-folding
|
|
@ -0,0 +1,15 @@
|
|||
Summary
|
||||
|
||||
Harness status: OK
|
||||
|
||||
Rerun
|
||||
|
||||
Found 4 tests
|
||||
|
||||
3 Pass
|
||||
1 Fail
|
||||
Details
|
||||
Result Test Name MessagePass rules include webkit-prefixed pseudo-element should be cascaded
|
||||
Fail webkit-prefixed pseudo-element selectors should be accessible from CSSOM
|
||||
Pass qS and qSA shouldn't throw exception
|
||||
Pass webkit-prefix without dash is invalid
|
|
@ -0,0 +1,11 @@
|
|||
Summary
|
||||
|
||||
Harness status: OK
|
||||
|
||||
Rerun
|
||||
|
||||
Found 1 tests
|
||||
|
||||
1 Pass
|
||||
Details
|
||||
Result Test Name MessagePass x-prefixed pseudo-elements should make the whole rule invalid
|
|
@ -0,0 +1,55 @@
|
|||
<!doctype html>
|
||||
<meta charset=utf-8>
|
||||
<title>Matching of child-indexed pseudo-classes</title>
|
||||
<link rel="author" title="Emilio Cobos Álvarez" href="mailto:ecoal95@gmail.com">
|
||||
<link rel="help" href="https://drafts.csswg.org/selectors-4/#child-index">
|
||||
<script src=../../resources/testharness.js></script>
|
||||
<script src=../../resources/testharnessreport.js></script>
|
||||
<script>
|
||||
var check = function(element, selectors, qsRoot) {
|
||||
for (var i = 0; i < selectors.length; ++i) {
|
||||
var selector = selectors[i][0];
|
||||
var expected = selectors[i][1];
|
||||
test(function() {
|
||||
assert_equals(expected, element.matches(selector));
|
||||
|
||||
if (qsRoot) {
|
||||
assert_equals(expected, element === qsRoot.querySelector(selector));
|
||||
var qsa = qsRoot.querySelectorAll(selector);
|
||||
assert_equals(expected, !!qsa.length && element === qsa[0]);
|
||||
}
|
||||
}, "Expected " + element.tagName + " element to " +
|
||||
(expected ? "match " : "not match ") + selector + " with matches" +
|
||||
(qsRoot ? ", querySelector(), and querySelectorAll()" : ""));
|
||||
}
|
||||
}
|
||||
|
||||
var rootOfSubtreeSelectors = [
|
||||
[ ":first-child", true ],
|
||||
[ ":last-child", true ],
|
||||
[ ":only-child", true ],
|
||||
[ ":first-of-type", true ],
|
||||
[ ":last-of-type", true ],
|
||||
[ ":only-of-type", true ],
|
||||
[ ":nth-child(1)", true ],
|
||||
[ ":nth-child(n)", true ],
|
||||
[ ":nth-last-child(1)", true ],
|
||||
[ ":nth-last-child(n)", true ],
|
||||
[ ":nth-of-type(1)", true ],
|
||||
[ ":nth-of-type(n)", true ],
|
||||
[ ":nth-last-of-type(1)", true ],
|
||||
[ ":nth-last-of-type(n)", true ],
|
||||
[ ":nth-child(2)", false ],
|
||||
[ ":nth-last-child(2)", false],
|
||||
[ ":nth-of-type(2)", false ],
|
||||
[ ":nth-last-of-type(2)", false],
|
||||
];
|
||||
|
||||
check(document.documentElement, rootOfSubtreeSelectors, document);
|
||||
check(document.createElement('div'), rootOfSubtreeSelectors);
|
||||
|
||||
var fragment = document.createDocumentFragment();
|
||||
var div = document.createElement('div');
|
||||
fragment.appendChild(div);
|
||||
check(div, rootOfSubtreeSelectors, fragment);
|
||||
</script>
|
|
@ -0,0 +1,80 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta name="author" title="Ryosuke Niwa" href="mailto:rniwa@webkit.org">
|
||||
<link rel="help" href="https://html.spec.whatwg.org/multipage/dom.html#the-directionality">
|
||||
<script src="../../resources/testharness.js"></script>
|
||||
<script src="../../resources/testharnessreport.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
|
||||
test(() => {
|
||||
const bdi = document.createElement('bdi');
|
||||
assert_true(bdi.matches(':dir(ltr)'));
|
||||
assert_false(bdi.matches(':dir(rtl)'));
|
||||
|
||||
bdi.textContent = '\u05EA';
|
||||
assert_false(bdi.matches(':dir(ltr)'));
|
||||
assert_true(bdi.matches(':dir(rtl)'));
|
||||
}, 'bdi element without dir content attribute');
|
||||
|
||||
test(() => {
|
||||
const bdi = document.createElement('bdi');
|
||||
bdi.setAttribute('dir', 'foo');
|
||||
assert_true(bdi.matches(':dir(ltr)'));
|
||||
assert_false(bdi.matches(':dir(rtl)'));
|
||||
|
||||
bdi.textContent = '\u05EA';
|
||||
assert_false(bdi.matches(':dir(ltr)'));
|
||||
assert_true(bdi.matches(':dir(rtl)'));
|
||||
}, 'bdi element with invalid dir content attribute');
|
||||
|
||||
test(() => {
|
||||
const bdi = document.createElement('bdi');
|
||||
bdi.setAttribute('dir', 'auto');
|
||||
assert_true(bdi.matches(':dir(ltr)'));
|
||||
assert_false(bdi.matches(':dir(rtl)'));
|
||||
|
||||
bdi.textContent = '\u05EA';
|
||||
assert_false(bdi.matches(':dir(ltr)'));
|
||||
assert_true(bdi.matches(':dir(rtl)'));
|
||||
|
||||
bdi.setAttribute('dir', 'AUTO');
|
||||
assert_false(bdi.matches(':dir(ltr)'));
|
||||
assert_true(bdi.matches(':dir(rtl)'));
|
||||
}, 'bdi element with dir=auto content attribute');
|
||||
|
||||
test(() => {
|
||||
const bdi = document.createElement('bdi');
|
||||
bdi.setAttribute('dir', 'ltr');
|
||||
assert_true(bdi.matches(':dir(ltr)'));
|
||||
assert_false(bdi.matches(':dir(rtl)'));
|
||||
|
||||
bdi.setAttribute('dir', 'LTR');
|
||||
assert_true(bdi.matches(':dir(ltr)'));
|
||||
assert_false(bdi.matches(':dir(rtl)'));
|
||||
|
||||
bdi.textContent = '\u05EA';
|
||||
assert_true(bdi.matches(':dir(ltr)'));
|
||||
assert_false(bdi.matches(':dir(rtl)'));
|
||||
}, 'bdi element with dir=ltr content attribute');
|
||||
|
||||
test(() => {
|
||||
const bdi = document.createElement('bdi');
|
||||
bdi.setAttribute('dir', 'rtl');
|
||||
assert_false(bdi.matches(':dir(ltr)'));
|
||||
assert_true(bdi.matches(':dir(rtl)'));
|
||||
|
||||
bdi.setAttribute('dir', 'RTL');
|
||||
assert_false(bdi.matches(':dir(ltr)'));
|
||||
assert_true(bdi.matches(':dir(rtl)'));
|
||||
|
||||
bdi.textContent = '\u05EA';
|
||||
assert_false(bdi.matches(':dir(ltr)'));
|
||||
assert_true(bdi.matches(':dir(rtl)'));
|
||||
}, 'bdi element with dir=rtl content attribute');
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,207 @@
|
|||
<!DOCTYPE html>
|
||||
<meta name="author" title="Ryosuke Niwa" href="mailto:rniwa@webkit.org">
|
||||
<link rel="help" href="https://html.spec.whatwg.org/multipage/dom.html#the-directionality">
|
||||
<script src="../../resources/testharness.js"></script>
|
||||
<script src="../../resources/testharnessreport.js"></script>
|
||||
<body>
|
||||
<script>
|
||||
test(() => {
|
||||
const input = document.createElement('input');
|
||||
input.type = 'tel';
|
||||
assert_true(input.matches(':dir(ltr)'));
|
||||
assert_false(input.matches(':dir(rtl)'));
|
||||
|
||||
input.setAttribute('dir', 'foo');
|
||||
assert_true(input.matches(':dir(ltr)'));
|
||||
assert_false(input.matches(':dir(rtl)'));
|
||||
|
||||
input.setAttribute('dir', 'rtl');
|
||||
assert_false(input.matches(':dir(ltr)'));
|
||||
assert_true(input.matches(':dir(rtl)'));
|
||||
|
||||
input.setAttribute('dir', 'RTL');
|
||||
assert_false(input.matches(':dir(ltr)'));
|
||||
assert_true(input.matches(':dir(rtl)'));
|
||||
|
||||
input.setAttribute('dir', 'ltr');
|
||||
assert_true(input.matches(':dir(ltr)'));
|
||||
assert_false(input.matches(':dir(rtl)'));
|
||||
|
||||
input.setAttribute('dir', 'LTR');
|
||||
assert_true(input.matches(':dir(ltr)'));
|
||||
assert_false(input.matches(':dir(rtl)'));
|
||||
|
||||
input.setAttribute('dir', 'auto');
|
||||
assert_true(input.matches(':dir(ltr)'));
|
||||
assert_false(input.matches(':dir(rtl)'));
|
||||
|
||||
input.value = '\u05EA';
|
||||
assert_false(input.matches(':dir(ltr)'));
|
||||
assert_true(input.matches(':dir(rtl)'));
|
||||
|
||||
input.setAttribute('dir', 'AUTO');
|
||||
assert_false(input.matches(':dir(ltr)'));
|
||||
assert_true(input.matches(':dir(rtl)'));
|
||||
|
||||
input.removeAttribute('dir');
|
||||
assert_true(input.matches(':dir(ltr)'));
|
||||
assert_false(input.matches(':dir(rtl)'));
|
||||
}, 'input element whose type attribute is in the telephone state');
|
||||
|
||||
test(() => {
|
||||
const input = document.createElement('input');
|
||||
input.type = 'tel';
|
||||
|
||||
const container = document.createElement('div');
|
||||
container.setAttribute('dir', 'rtl');
|
||||
container.appendChild(input);
|
||||
|
||||
// Insert the element into the document so that we can also check for
|
||||
// 'direction' in computed style.
|
||||
document.body.appendChild(container);
|
||||
|
||||
assert_true(input.matches(':dir(ltr)'));
|
||||
assert_false(input.matches(':dir(rtl)'));
|
||||
// Per https://html.spec.whatwg.org/multipage/rendering.html#bidi-rendering:
|
||||
assert_equals(getComputedStyle(input).direction, 'ltr');
|
||||
|
||||
// Changing to a different type causes the special type=tel rule to no longer apply.
|
||||
input.type = 'text';
|
||||
assert_false(input.matches(':dir(ltr)'));
|
||||
assert_true(input.matches(':dir(rtl)'));
|
||||
assert_equals(getComputedStyle(input).direction, 'rtl');
|
||||
|
||||
// And restoring type=tel brings back that behavior.
|
||||
input.type = 'tel';
|
||||
assert_true(input.matches(':dir(ltr)'));
|
||||
assert_false(input.matches(':dir(rtl)'));
|
||||
assert_equals(getComputedStyle(input).direction, 'ltr');
|
||||
|
||||
document.body.removeChild(container);
|
||||
}, 'input element whose type attribute is in the telephone state in a RTL block');
|
||||
|
||||
for (const type of ['password', 'text', 'search', 'url', 'email', 'submit', 'reset', 'button', 'hidden']) {
|
||||
test(() => {
|
||||
const input = document.createElement('input');
|
||||
input.type = type;
|
||||
assert_true(input.matches(':dir(ltr)'));
|
||||
assert_false(input.matches(':dir(rtl)'));
|
||||
|
||||
input.setAttribute('dir', 'foo');
|
||||
assert_true(input.matches(':dir(ltr)'));
|
||||
assert_false(input.matches(':dir(rtl)'));
|
||||
|
||||
input.setAttribute('dir', 'rtl');
|
||||
assert_false(input.matches(':dir(ltr)'));
|
||||
assert_true(input.matches(':dir(rtl)'));
|
||||
|
||||
input.setAttribute('dir', 'RTL');
|
||||
assert_false(input.matches(':dir(ltr)'));
|
||||
assert_true(input.matches(':dir(rtl)'));
|
||||
|
||||
input.setAttribute('dir', 'ltr');
|
||||
assert_true(input.matches(':dir(ltr)'));
|
||||
assert_false(input.matches(':dir(rtl)'));
|
||||
|
||||
input.setAttribute('dir', 'LTR');
|
||||
assert_true(input.matches(':dir(ltr)'));
|
||||
assert_false(input.matches(':dir(rtl)'));
|
||||
|
||||
input.setAttribute('dir', 'auto');
|
||||
assert_true(input.matches(':dir(ltr)'));
|
||||
assert_false(input.matches(':dir(rtl)'));
|
||||
|
||||
input.value = '\u05EA';
|
||||
assert_false(input.matches(':dir(ltr)'));
|
||||
assert_true(input.matches(':dir(rtl)'));
|
||||
|
||||
input.setAttribute('dir', 'AUTO');
|
||||
assert_false(input.matches(':dir(ltr)'));
|
||||
assert_true(input.matches(':dir(rtl)'))
|
||||
|
||||
input.removeAttribute('dir');
|
||||
assert_true(input.matches(':dir(ltr)'));
|
||||
assert_false(input.matches(':dir(rtl)'));
|
||||
}, `input element whose type attribute is in the ${type} state`);
|
||||
}
|
||||
|
||||
test(() => {
|
||||
const input = document.createElement('input');
|
||||
input.type = 'text';
|
||||
// bidirectional character type R
|
||||
input.value = '\u05EA';
|
||||
input.setAttribute('dir', 'auto');
|
||||
|
||||
const container = document.createElement('div');
|
||||
container.appendChild(input);
|
||||
|
||||
assert_false(input.matches(':dir(ltr)'));
|
||||
assert_true(input.matches(':dir(rtl)'));
|
||||
|
||||
// Changing to a different type that does't use value causes the bidi rule to no longer apply.
|
||||
input.type = 'radio';
|
||||
assert_true(input.matches(':dir(ltr)'));
|
||||
assert_false(input.matches(':dir(rtl)'));
|
||||
|
||||
// And restoring type=text brings back that behavior.
|
||||
input.type = 'text';
|
||||
assert_false(input.matches(':dir(ltr)'));
|
||||
assert_true(input.matches(':dir(rtl)'));
|
||||
}, 'dynamic changes to type of input elements affect whether value is used for dir=auto');
|
||||
|
||||
for (const type of ['date', 'time', 'number', 'range', 'color', 'checkbox', 'radio', 'image']) {
|
||||
test(() => {
|
||||
const input = document.createElement('input');
|
||||
input.type = type;
|
||||
assert_true(input.matches(':dir(ltr)'));
|
||||
assert_false(input.matches(':dir(rtl)'));
|
||||
|
||||
input.setAttribute('dir', 'foo');
|
||||
assert_true(input.matches(':dir(ltr)'));
|
||||
assert_false(input.matches(':dir(rtl)'));
|
||||
|
||||
input.setAttribute('dir', 'rtl');
|
||||
assert_false(input.matches(':dir(ltr)'));
|
||||
assert_true(input.matches(':dir(rtl)'));
|
||||
|
||||
input.setAttribute('dir', 'RTL');
|
||||
assert_false(input.matches(':dir(ltr)'));
|
||||
assert_true(input.matches(':dir(rtl)'));
|
||||
|
||||
input.setAttribute('dir', 'ltr');
|
||||
assert_true(input.matches(':dir(ltr)'));
|
||||
assert_false(input.matches(':dir(rtl)'));
|
||||
|
||||
input.setAttribute('dir', 'LTR');
|
||||
assert_true(input.matches(':dir(ltr)'));
|
||||
assert_false(input.matches(':dir(rtl)'));
|
||||
|
||||
input.setAttribute('dir', 'auto');
|
||||
assert_true(input.matches(':dir(ltr)'));
|
||||
assert_false(input.matches(':dir(rtl)'));
|
||||
|
||||
input.value = '\u05EA';
|
||||
assert_true(input.matches(':dir(ltr)'));
|
||||
assert_false(input.matches(':dir(rtl)'));
|
||||
|
||||
input.setAttribute('dir', 'AUTO');
|
||||
assert_true(input.matches(':dir(ltr)'));
|
||||
assert_false(input.matches(':dir(rtl)'))
|
||||
|
||||
input.removeAttribute('dir');
|
||||
assert_true(input.matches(':dir(ltr)'));
|
||||
assert_false(input.matches(':dir(rtl)'));
|
||||
|
||||
let rtlParent = document.createElement("div");
|
||||
rtlParent.dir = "rtl";
|
||||
input.dir = "auto";
|
||||
rtlParent.appendChild(input);
|
||||
document.body.appendChild(rtlParent); // Just for good measure.
|
||||
assert_true(input.matches(':dir(ltr)'));
|
||||
assert_false(input.matches(':dir(rtl)'));
|
||||
rtlParent.remove();
|
||||
}, `input element whose type attribute is in the ${type} state`);
|
||||
}
|
||||
|
||||
</script>
|
||||
</body>
|
|
@ -0,0 +1,93 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<link rel="help" href="http://www.w3.org/TR/selectors4/#dir-pseudo">
|
||||
<script src="../../resources/testharness.js"></script>
|
||||
<script src="../../resources/testharnessreport.js"></script>
|
||||
<style>
|
||||
#div4_1 {
|
||||
direction: rtl;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<!-- ת is the Hebrew letter tav, i.e. RTL -->
|
||||
<body>
|
||||
<div id=testDivs>
|
||||
<div id=div1 dir=auto>
|
||||
<div id=div1_1>a</div>
|
||||
</div>
|
||||
<div id=div2 dir=auto>
|
||||
<div id=div2_1>ת</div>
|
||||
</div>
|
||||
<div id=div3 dir=auto>
|
||||
<div id=div3_1 dir=rtl>ת</div>
|
||||
<div id=div3_2>a</div>
|
||||
</div>
|
||||
<div id=div4 dir=auto>
|
||||
<div id=div4_1>
|
||||
<div id=div4_1_1>a</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
<script>
|
||||
function test_directionality(message, element, expected) {
|
||||
test(() => {
|
||||
var isLTR = document.querySelector("#" + element.id + ":dir(ltr)") == element;
|
||||
var isRTL = document.querySelector("#" + element.id + ":dir(rtl)") == element;
|
||||
if (expected == "ltr") {
|
||||
assert_true(isLTR);
|
||||
assert_false(isRTL);
|
||||
} else {
|
||||
assert_false(isLTR);
|
||||
assert_true(isRTL);
|
||||
}
|
||||
}, message + " directionality of element " + element.id + " is " + expected);
|
||||
}
|
||||
|
||||
test_directionality("Initial ", div1, "ltr");
|
||||
test_directionality("Initial ", div1_1, "ltr");
|
||||
test_directionality("Initial ", div2, "rtl");
|
||||
test_directionality("Initial ", div2_1, "rtl");
|
||||
test_directionality("Initial ", div3, "ltr");
|
||||
test_directionality("Initial ", div3_1, "rtl");
|
||||
test_directionality("Initial ", div3_2, "ltr");
|
||||
test_directionality("Initial ", div4, "ltr");
|
||||
test_directionality("Initial ", div4_1, "ltr");
|
||||
test_directionality("Initial ", div4_1_1, "ltr");
|
||||
|
||||
div1_1.innerText = "\u05EA";
|
||||
div1_1.offsetTop;
|
||||
test_directionality("Updated ", div1, "rtl");
|
||||
test_directionality("Updated ", div1_1, "rtl");
|
||||
|
||||
div1_1.dir = "ltr";
|
||||
div1_1.offsetTop;
|
||||
test_directionality("Updated ", div1, "ltr");
|
||||
test_directionality("Updated ", div1_1, "ltr");
|
||||
|
||||
div1_1.innerText = "a";
|
||||
div1_1.offsetTop;
|
||||
test_directionality("Reupdated ", div1, "ltr");
|
||||
test_directionality("Reupdated ", div1_1, "ltr");
|
||||
|
||||
div2_1.remove();
|
||||
div2.offsetTop;
|
||||
test_directionality("Updated ", div2, "ltr");
|
||||
|
||||
div3_1.dir = "";
|
||||
div3_1.offsetTop;
|
||||
test_directionality("Updated ", div3, "rtl");
|
||||
div3.appendChild(div3_1);
|
||||
div3.offsetTop;
|
||||
test_directionality("Updated ", div3, "ltr");
|
||||
|
||||
div4_1_1.innerText = "\u05EA";
|
||||
div4_1_1.offsetTop;
|
||||
test_directionality("Updated ", div4, "rtl");
|
||||
test_directionality("Updated ", div4_1, "rtl");
|
||||
test_directionality("Updated ", div4_1_1, "rtl");
|
||||
</script>
|
||||
</html>
|
|
@ -0,0 +1,71 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<link rel="help" href="http://www.w3.org/TR/selectors4/#dir-pseudo">
|
||||
<script src="../../resources/testharness.js"></script>
|
||||
<script src="../../resources/testharnessreport.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id=outer>
|
||||
<div id=div1></div>
|
||||
<div id=div2 dir=ltr>
|
||||
<div id=div2_1></div>
|
||||
<div id=div2_2 dir=ltr></div>
|
||||
<div id=div2_3 dir=rtl></div>
|
||||
</div>
|
||||
<div id=div3 dir=rtl>
|
||||
<div id=div3_1>
|
||||
<div id=div3_1_1></div>
|
||||
</div>
|
||||
<div id=div3_2 dir=ltr></div>
|
||||
<div id=div3_3 dir=rtl></div>
|
||||
</div>
|
||||
<div id=div4 dir=lol></div>
|
||||
<div id=div5 dir=auto></div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
<script>
|
||||
test(() => {
|
||||
assert_equals(document.querySelector(":dir(lol)"), null);
|
||||
assert_equals(document.querySelector(":dir(lol )"), null);
|
||||
assert_equals(document.querySelector(":dir( auto)"), null);
|
||||
assert_equals(document.querySelector(":dir(\nauto\t)"), null);
|
||||
}, ":dir() allows any ident value but strings other than ltr/rtl don't match");
|
||||
|
||||
test(() => {
|
||||
assert_throws_dom("SYNTAX_ERR", () => { document.querySelector(":dir()"); });
|
||||
assert_throws_dom("SYNTAX_ERR", () => { document.querySelector(":dir(ltr, rtl)"); });
|
||||
assert_throws_dom("SYNTAX_ERR", () => { document.querySelector(":dir('ltr')"); });
|
||||
}, ":dir() requires exactly an ident argument");
|
||||
|
||||
test(() => {
|
||||
assert_equals(document.querySelector(":dir(rtl)"), div2_3);
|
||||
assert_equals(document.querySelector("*:dir(rtl)"), div2_3);
|
||||
assert_equals(document.querySelector("div:dir(ltr)"), outer);
|
||||
assert_equals(document.querySelector("div:dir(ltr):dir(ltr)"), outer);
|
||||
assert_equals(document.querySelector(":dir(rtl)#div3_3"), div3_3);
|
||||
assert_equals(document.querySelector(":nth-child(2):dir(rtl)"), null);
|
||||
assert_equals(document.querySelector(":nth-child(3):dir(rtl)"), div2_3);
|
||||
assert_equals(document.querySelector(":nth-child(4):dir(ltr)"), div4);
|
||||
assert_equals(document.querySelector(":nth-last-child(3):dir(rtl)"), div3);
|
||||
}, ":dir() works in compound selectors");
|
||||
|
||||
test(() => {
|
||||
assert_equals(document.querySelector("#div2 :dir(ltr)"), div2_1);
|
||||
assert_equals(document.querySelector(":dir(rtl) div"), div3_1);
|
||||
assert_equals(document.querySelector("div + :dir(ltr)"), div2);
|
||||
assert_equals(document.querySelector(":dir(ltr) + :dir(rtl)"), div2_3);
|
||||
assert_equals(document.querySelector(":dir(rtl) :dir(rtl)"), div3_1);
|
||||
assert_equals(document.querySelector(":dir(rtl) + :dir(ltr)"), div3_2);
|
||||
assert_equals(document.querySelector(":dir(rtl) ~ :dir(rtl)"), div3_3);
|
||||
assert_equals(document.querySelector(":dir(rtl) :dir(ltr)"), div3_2);
|
||||
assert_equals(document.querySelector("* :dir(rtl) *"), div3_1);
|
||||
assert_equals(document.querySelector("div :dir(rtl) div"), div3_1);
|
||||
assert_equals(document.querySelector(":dir(ltr) :dir(rtl) + :dir(ltr)"), div3_2);
|
||||
assert_equals(document.querySelector(":dir(ltr) + :dir(rtl) + * + *"), div5);
|
||||
assert_equals(document.querySelector(":dir(rtl) > * > :dir(rtl)"), div3_1_1);
|
||||
}, ":dir() works in complex selectors");
|
||||
</script>
|
||||
</html>
|
|
@ -0,0 +1,52 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Selectors :first-child</title>
|
||||
<link rel="help" href="https://drafts.csswg.org/selectors-4/#the-first-child-pseudo">
|
||||
<script src="../../resources/testharness.js"></script>
|
||||
<script src="../../resources/testharnessreport.js"></script>
|
||||
<!--
|
||||
See also:
|
||||
* child-indexed-pseudo-class.html
|
||||
* child-indexed-no-parent.html
|
||||
* invalidation/first-child-last-child.html
|
||||
-->
|
||||
<body>
|
||||
|
||||
<div>
|
||||
<div id="target1">Whitespace nodes should be ignored.</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div id="target2">There is the second child element.</div>
|
||||
<blockquote></blockquote>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<!-- -->
|
||||
<div id="target3">A comment node should be ignored.</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
.
|
||||
<div id="target4">Non-whitespace text node should be ignored.</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<blockquote></blockquote>
|
||||
<div id="target5" data-expected="false">The second child should not be matched.</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
for (let i = 1; i <= 5; ++i) {
|
||||
let target = document.querySelector(`#target${i}`);
|
||||
test(() => {
|
||||
if (target.dataset.expected == 'false')
|
||||
assert_false(target.matches(':first-child'));
|
||||
else
|
||||
assert_true(target.matches(':first-child'));
|
||||
}, target.textContent);
|
||||
}
|
||||
</script>
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Selectors :first-of-type</title>
|
||||
<link rel="help" href="https://drafts.csswg.org/selectors-4/#the-first-of-type-pseudo">
|
||||
<script src="../../resources/testharness.js"></script>
|
||||
<script src="../../resources/testharnessreport.js"></script>
|
||||
<!--
|
||||
See also:
|
||||
* of-type-selectors.html
|
||||
* child-indexed-pseudo-class.html
|
||||
* child-indexed-no-parent.html
|
||||
-->
|
||||
<body>
|
||||
|
||||
<div>
|
||||
<div id="target1">Whitespace nodes should be ignored.</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div id="target2">Thre is another child element of the same type.</div>
|
||||
<div></div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<blockquote></blockquote>
|
||||
<div id="target3">There is a prior child element of another type.</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div></div>
|
||||
<blockquote>
|
||||
<div id="target4">A previous element of the parent should not affect.</div>
|
||||
</blockquote>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div>
|
||||
<div id="target5">The parent element of the same type should not affect.</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<blockquote>
|
||||
<div></div>
|
||||
</blockquote>
|
||||
<div id="target6">A child of the previous element should not affect.</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div></div>
|
||||
<div id="target7" data-expected="false">The second child element of the same
|
||||
type should not match.</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<DIV></DIV>
|
||||
<div id="target8" data-expected="false">The second child element of the same
|
||||
type should not match, the first child has case-different tag name.</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div id="insertBefore1"></div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
for (let i = 1; i <= 8; ++i) {
|
||||
let target = document.querySelector(`#target${i}`);
|
||||
test(() => {
|
||||
if (target.dataset.expected == 'false')
|
||||
assert_false(target.matches('div:first-of-type'));
|
||||
else
|
||||
assert_true(target.matches('div:first-of-type'));
|
||||
}, target.textContent.replaceAll('\n', ' '));
|
||||
}
|
||||
|
||||
test(() => {
|
||||
const ib1 = document.querySelector('#insertBefore1');
|
||||
const target = document.createElement('div');
|
||||
assert_true(ib1.matches('div:first-of-type'));
|
||||
ib1.parentNode.insertBefore(target, ib1);
|
||||
assert_true(target.matches('div:first-of-type'));
|
||||
assert_false(ib1.matches('div:first-of-type'));
|
||||
|
||||
target.remove();
|
||||
assert_true(ib1.matches('div:first-of-type'));
|
||||
}, 'Dynamic insertion and removal');
|
||||
</script>
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>Selectors Level 4: focus</title>
|
||||
<link rel="author" title="Manuel Rego Casasnovas" href="mailto:rego@igalia.com">
|
||||
<link rel="help" href="https://drafts.csswg.org/selectors-4/#focus-pseudo">
|
||||
<link rel="help" href="https://html.spec.whatwg.org/multipage/interaction.html#focus-fixup-rule">
|
||||
<meta name="assert" content="Checks ':focus' pseudo-class after 'display: none'.">
|
||||
<script src="../../resources/testharness.js"></script>
|
||||
<script src="../../resources/testharnessreport.js"></script>
|
||||
<div id="wrapper">
|
||||
<input id="input">
|
||||
</div>
|
||||
<script>
|
||||
"use strict";
|
||||
|
||||
const wrapper = document.getElementById("wrapper");
|
||||
const input = document.getElementById("input");
|
||||
|
||||
async_test((t) => {
|
||||
input.focus();
|
||||
window.requestAnimationFrame(() => {
|
||||
t.step(() => assert_true(input.matches(":focus"),
|
||||
"Check input matches ':focus' after being focused"));
|
||||
|
||||
input.style.display = "none";
|
||||
window.requestAnimationFrame(() => {
|
||||
t.step(() => assert_false(input.matches(":focus"),
|
||||
"Check input doesn't match ':focus' after getting 'display: none'"));
|
||||
input.style.display = "inline";
|
||||
t.done();
|
||||
});
|
||||
});
|
||||
}, "Test ':focus' after 'display:none' on input");
|
||||
|
||||
async_test((t) => {
|
||||
input.focus();
|
||||
window.requestAnimationFrame(() => {
|
||||
t.step(() => assert_true(input.matches(":focus"),
|
||||
"Check input matches ':focus' after being focused"));
|
||||
|
||||
wrapper.style.display = "none";
|
||||
window.requestAnimationFrame(() => {
|
||||
t.step(() => assert_false(input.matches(":focus"),
|
||||
"Check input doesn't match ':focus' after parent got 'display: none'"));
|
||||
wrapper.style.display = "block";
|
||||
t.done();
|
||||
});
|
||||
});
|
||||
}, "Test ':focus' after 'display:none' on input's parent");
|
||||
</script>
|
|
@ -0,0 +1,43 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>Selectors Level 4: :focus, :focus-visible and :focus-within in focus event</title>
|
||||
<link rel="help" href="https://drafts.csswg.org/selectors-4/#focus-pseudo">
|
||||
<link rel="help" href="https://drafts.csswg.org/selectors-4/#focus-visible-pseudo">
|
||||
<link rel="help" href="https://drafts.csswg.org/selectors-4/#focus-within-pseudo">
|
||||
<link rel="help" href="https://w3c.github.io/uievents/#event-type-focus">
|
||||
<link rel="help" href="https://crbug.com/523126">
|
||||
<meta name='author' title='Takayoshi Kochi' href='mailto:kochi@chromium.org'>
|
||||
<meta name='author' title='Manuel Rego Casasnovas' href='mailto:rego@igalia.com'>
|
||||
<script src="../../resources/testharness.js"></script>
|
||||
<script src="../../resources/testharnessreport.js"></script>
|
||||
<input type="text">
|
||||
<script>
|
||||
var input = document.querySelector('input');
|
||||
input.addEventListener('focus', function(e) {
|
||||
test(() => {
|
||||
try {
|
||||
var focusPseudo = document.querySelector(':focus');
|
||||
assert_equals(e.target, focusPseudo, "':focus' matches event.target");
|
||||
} catch (error) {
|
||||
assert_unreached("':focus' is an invalid selector. SyntaxError: " + error);
|
||||
}
|
||||
}, "Checks that ':focus' pseudo-class matches inside 'focus' event handler");
|
||||
test(() => {
|
||||
try {
|
||||
var focusVisiblePseudo = document.querySelector(':focus-visible');
|
||||
assert_equals(e.target, focusVisiblePseudo, "':focus-visible' matches event.target");
|
||||
} catch (error) {
|
||||
assert_unreached("':focus-visible' is an invalid selector. SyntaxError: " + error);
|
||||
}
|
||||
}, "Checks that ':focus-visible' pseudo-class matches inside 'focus' event handler");
|
||||
test(() => {
|
||||
try {
|
||||
var focusWithinPseudo = document.querySelector(':focus-within');
|
||||
assert_equals(document.documentElement, focusWithinPseudo, "':focus-within' matches document.documentElement");
|
||||
} catch (error) {
|
||||
assert_unreached("':focus-within' is an invalid selector. SyntaxError: " + error);
|
||||
}
|
||||
}, "Checks that ':focus-within' pseudo-class matches inside 'focus' event handler");
|
||||
}, false);
|
||||
input.focus();
|
||||
</script>
|
|
@ -0,0 +1,41 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>Selectors Level 4: :focus, :focus-visible and :focus-within in focusin event</title>
|
||||
<link rel="help" href="https://drafts.csswg.org/selectors-4/#focus-pseudo">
|
||||
<link rel="help" href="https://drafts.csswg.org/selectors-4/#focus-visible-pseudo">
|
||||
<link rel="help" href="https://drafts.csswg.org/selectors-4/#focus-within-pseudo">
|
||||
<link rel="help" href="https://w3c.github.io/uievents/#event-type-focusin">
|
||||
<meta name='author' title='Manuel Rego Casasnovas' href='mailto:rego@igalia.com'>
|
||||
<script src="../../resources/testharness.js"></script>
|
||||
<script src="../../resources/testharnessreport.js"></script>
|
||||
<input type="text">
|
||||
<script>
|
||||
var input = document.querySelector('input');
|
||||
input.addEventListener('focusin', function(e) {
|
||||
test(() => {
|
||||
try {
|
||||
var focusPseudo = document.querySelector(':focus');
|
||||
assert_equals(e.target, focusPseudo, "':focus' matches event.target");
|
||||
} catch (error) {
|
||||
assert_unreached("':focus' is an invalid selector. SyntaxError: " + error);
|
||||
}
|
||||
}, "Checks that ':focus' pseudo-class matches inside 'focusin' event handler");
|
||||
test(() => {
|
||||
try {
|
||||
var focusVisiblePseudo = document.querySelector(':focus-visible');
|
||||
assert_equals(e.target, focusVisiblePseudo, "':focus-visible' matches event.target");
|
||||
} catch (error) {
|
||||
assert_unreached("':focus-visible' is an invalid selector. SyntaxError: " + error);
|
||||
}
|
||||
}, "Checks that ':focus-visible' pseudo-class matches inside 'focusin' event handler");
|
||||
test(() => {
|
||||
try {
|
||||
var focusWithinPseudo = document.querySelector(':focus-within');
|
||||
assert_equals(document.documentElement, focusWithinPseudo, "':focus-within' matches document.documentElement");
|
||||
} catch (error) {
|
||||
assert_unreached("':focus-within' is an invalid selector. SyntaxError: " + error);
|
||||
}
|
||||
}, "Checks that ':focus-within' pseudo-class matches inside 'focusin' event handler");
|
||||
}, false);
|
||||
input.focus();
|
||||
</script>
|
|
@ -0,0 +1,45 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>CSS Test (Selectors): Keyboard focus enables :focus-visible</title>
|
||||
<link rel="author" title="Alice Boxhall" href="aboxhall@chromium.org" />
|
||||
<link rel="help" href="https://drafts.csswg.org/selectors-4/#the-focus-visible-pseudo" />
|
||||
<script src="../../resources/testharness.js"></script>
|
||||
<script src="../../resources/testharnessreport.js"></script>
|
||||
<script src="/html/interaction/focus/the-autofocus-attribute/resources/utils.js"></script>
|
||||
<style>
|
||||
@supports not selector(:focus-visible) {
|
||||
#button:focus {
|
||||
outline: red solid 5px;
|
||||
background-color: red;
|
||||
}
|
||||
}
|
||||
|
||||
:focus-visible {
|
||||
outline: green solid 5px;
|
||||
}
|
||||
|
||||
#button:focus:not(:focus-visible) {
|
||||
background-color: red;
|
||||
outline: 0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
This test checks that any element focused via an <code>autofocus</code> attribute will have <code>:focus-visible</code> matching enabled.
|
||||
<ul id="instructions">
|
||||
<li>If the button that says "I will be focused automatically" has a red background, then the test result is FAILURE. If it has a green outline, then the test result is SUCCESS.</li>
|
||||
</ul>
|
||||
<br />
|
||||
<button id="button" autofocus tabindex="-1">I will be focused automatically.</button>
|
||||
<script>
|
||||
promise_test(async function() {
|
||||
await waitUntilStableAutofocusState();
|
||||
assert_equals(document.activeElement, button, "Should have correct focused element");
|
||||
assert_equals(getComputedStyle(button).outlineColor, "rgb(0, 128, 0)", `outlineColor for ${button.tagName}#${button.id} should be green`);
|
||||
assert_not_equals(getComputedStyle(button).backgroundColor, "rgb(255, 0, 0)", `backgroundColor for ${button.tagName}#${button.id} should NOT be red`);
|
||||
}, "Autofocus should match :focus-visible");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,49 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>CSS Test (Selectors): Keyboard focus enables :focus-visible</title>
|
||||
<link rel="author" title="Alice Boxhall" href="aboxhall@chromium.org" />
|
||||
<link rel="help" href="https://drafts.csswg.org/selectors-4/#the-focus-visible-pseudo" />
|
||||
<script src="../../resources/testharness.js"></script>
|
||||
<script src="../../resources/testharnessreport.js"></script>
|
||||
<style>
|
||||
@supports not selector(:focus-visible) {
|
||||
:focus {
|
||||
outline: red solid 5px;
|
||||
background-color: red;
|
||||
}
|
||||
}
|
||||
|
||||
:focus-visible {
|
||||
outline: green solid 5px;
|
||||
}
|
||||
|
||||
:focus:not(:focus-visible) {
|
||||
background-color: red;
|
||||
outline: 0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
This test checks that any element focused programmatically on page load will have <code>:focus-visible</code> matching enabled.
|
||||
<ul id="instructions">
|
||||
<li>If the element that says "I will be focused automatically" has a red background, then the test result is FAILURE. If the element has a green outline, then the test result is SUCCESS.</li>
|
||||
</ul>
|
||||
<br />
|
||||
<div id="el" tabindex="-1">I will be focused automatically.</div>
|
||||
<script>
|
||||
window.addEventListener('load', () => {
|
||||
el.focus();
|
||||
});
|
||||
|
||||
async_test(function(t) {
|
||||
el.addEventListener("focus", t.step_func(function() {
|
||||
assert_equals(getComputedStyle(el).outlineColor, "rgb(0, 128, 0)", `outlineColor for ${el.tagName}#${el.id} should be green`);
|
||||
assert_not_equals(getComputedStyle(el).backgroundColor, "rgb(255, 0, 0)", `backgroundColor for ${el.tagName}#${el.id} should NOT be red`);
|
||||
t.done();
|
||||
}));
|
||||
}, "Programmatic focus on page load should match :focus-visible");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,43 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8" />
|
||||
<title>CSS Selectors Test: :focus-visible matches after script focus move</title>
|
||||
<link rel="author" title="Manuel Rego Casasnovas" href="mailto:rego@igalia.com">
|
||||
<link rel="help" href="https://drafts.csswg.org/selectors-4/#the-focus-visible-pseudo" />
|
||||
<meta name="assert" content="This test checks that if the active element matches ':focus-visible' and a script causes focus to move elsewhere, the newly focused element should match ':focus-visible'.">
|
||||
<script src="../../resources/testharness.js"></script>
|
||||
<script src="../../resources/testharnessreport.js"></script>
|
||||
<style>
|
||||
@supports not selector(:focus-visible) {
|
||||
:focus {
|
||||
outline: red solid 5px;
|
||||
background-color: red;
|
||||
}
|
||||
}
|
||||
|
||||
:focus-visible {
|
||||
background: lime;
|
||||
}
|
||||
|
||||
:focus:not(:focus-visible) {
|
||||
background-color: red;
|
||||
}
|
||||
</style>
|
||||
|
||||
<input id="input"></input>
|
||||
<div id="target" tabindex="0">Target</div>
|
||||
|
||||
<script>
|
||||
async_test(function(t) {
|
||||
input.addEventListener("focus", t.step_func(function() {
|
||||
assert_equals(getComputedStyle(input).backgroundColor, "rgb(0, 255, 0)", `backgroundColor for ${input.tagName}#${input.id} should be lime`);
|
||||
target.focus();
|
||||
}));
|
||||
|
||||
target.addEventListener("focus", t.step_func(function() {
|
||||
assert_equals(getComputedStyle(target).backgroundColor, "rgb(0, 255, 0)", `backgroundColor for ${target.tagName}#${target.id} should be lime`);
|
||||
t.done();
|
||||
}));
|
||||
|
||||
input.focus();
|
||||
}, ":focus-visible matches after script focus move");
|
||||
</script>
|
|
@ -0,0 +1,93 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8" />
|
||||
<title>CSS Test (Selectors): By default programatic focus matches :focus-visible and it shows an auto focus ring</title>
|
||||
<link rel="author" title="Manuel Rego Casasnovas" href="mailto:rego@igalia.com">
|
||||
<link rel="help" href="https://drafts.csswg.org/selectors-4/#the-focus-visible-pseudo" />
|
||||
<link rel="help" href="https://html.spec.whatwg.org/#phrasing-content-3" />
|
||||
<meta name="timeout" content="long">
|
||||
<script src="../../resources/testharness.js"></script>
|
||||
<script src="../../resources/testharnessreport.js"></script>
|
||||
<script src="../support/parsing-testcommon.js"></script>
|
||||
<style>
|
||||
#warning {
|
||||
display: none;
|
||||
background: red;
|
||||
}
|
||||
|
||||
@supports not selector(:focus-visible) {
|
||||
#instructions {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#warning {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<p>This test checks that by default, if using JavaScript to focus an element triggers <code>:focus-visible</code> matching, then the element should show a focus ring with <code>outline-style: auto</code>.</p>
|
||||
<ol id="instructions">
|
||||
<li>Focus the following elements with the keyaboard navigation (pressing TAB), if the elements show a focus ring with <code>outline-style: auto</code>, then the test result is SUCCESS.</li>
|
||||
</ol>
|
||||
<p id="warning">Your user-agent does not support <code>:focus-visible</code> pseudo-class, please SKIP this test.</p>
|
||||
|
||||
<abbr tabindex="0">abbr</abbr>
|
||||
<address tabindex="0">address</address>
|
||||
<a href="#">a</a>
|
||||
<bdi tabindex="0">bdi</bdi>
|
||||
<blockquote tabindex="0">blockquote</blockquote>
|
||||
<code tabindex="0">code</code>
|
||||
<dd tabindex="0">dd</dd>
|
||||
<details open><summary tabindex="0">summary</summary></details>
|
||||
<details tabindex="0"></details>
|
||||
<div tabindex="0">div</div>
|
||||
<dl tabindex="0">dl</dl>
|
||||
<dt tabindex="0">dt</dt>
|
||||
<em tabindex="0">em</em>
|
||||
<fieldset><legend tabindex="0">legend</legend></fieldset>
|
||||
<figcaption tabindex="0">figcaption</figcaption>
|
||||
<figure tabindex="0">figure</figure>
|
||||
<form tabindex="0">form</form>
|
||||
<hr tabindex="0" />
|
||||
<img tabindex="0" src="/images/green.png" />
|
||||
<label tabindex="0">label</label>
|
||||
<li tabindex="0">li</li>
|
||||
<mark tabindex="0">mark</mark>
|
||||
<meter tabindex="0"></meter>
|
||||
<ol tabindex="0">ol</ol>
|
||||
<pre tabindex="0">pre</pre>
|
||||
<progress tabindex="0"></progress>
|
||||
<p tabindex="0">p</p>
|
||||
<small tabindex="0">small</small>
|
||||
<s tabindex="0">s</s>
|
||||
<strong tabindex="0">strong</strong>
|
||||
<sub tabindex="0">sub</sub>
|
||||
<sup tabindex="0">sup</sup>
|
||||
<table><caption tabindex="0">caption</caption></table>
|
||||
<table tabindex="0"><td>table</td></table>
|
||||
<table><td tabindex="0">td</td></table>
|
||||
<time tabindex="0">time</time>
|
||||
<ul tabindex="0">ul</ul>
|
||||
<u tabindex="0">u</u>
|
||||
|
||||
<script>
|
||||
setup({ explicit_done: true });
|
||||
|
||||
// Check that :focus-visible is supported.
|
||||
test_valid_selector(':focus-visible');
|
||||
|
||||
const elements = document.querySelectorAll("[tabindex]");
|
||||
for (let i = 0; i < elements.length; i++) {
|
||||
const target = elements[i];
|
||||
promise_test(() => {
|
||||
return new Promise(resolve => {
|
||||
target.addEventListener("focus", resolve);
|
||||
target.focus();
|
||||
if (i == (elements.length - 1))
|
||||
done();
|
||||
}).then(() => {
|
||||
assert_equals(getComputedStyle(target).outlineStyle, "auto", `outline-style for ${target.tagName} should be auto`);
|
||||
});
|
||||
}, `By default initial programatic focus matches ':focus-visible', so the element ${target.tagName} shows a focus ring with 'outline-style: auto'`);
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,44 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8" />
|
||||
<title>CSS Test (Selectors): By default initial programatic focus matches :focus-visible and it shows an auto focus ring</title>
|
||||
<link rel="author" title="Manuel Rego Casasnovas" href="mailto:rego@igalia.com">
|
||||
<link rel="help" href="https://drafts.csswg.org/selectors-4/#the-focus-visible-pseudo" />
|
||||
<link rel="help" href="https://html.spec.whatwg.org/#phrasing-content-3" />
|
||||
<script src="../../resources/testharness.js"></script>
|
||||
<script src="../../resources/testharnessreport.js"></script>
|
||||
<script src="../support/parsing-testcommon.js"></script>
|
||||
<style>
|
||||
#warning {
|
||||
display: none;
|
||||
background: red;
|
||||
}
|
||||
|
||||
@supports not selector(:focus-visible) {
|
||||
#instructions {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#warning {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<p>This test checks that by default, if using JavaScript to focus an element triggers <code>:focus-visible</code> matching, then the element should show a focus ring with <code>outline-style: auto</code>.</p>
|
||||
<ol id="instructions">
|
||||
<li>If the element below that says "Target" show a focus ring with <code>outline-style: auto</code>, then the test result is SUCCESS.</li>
|
||||
</ol>
|
||||
<p id="warning">Your user-agent does not support <code>:focus-visible</code> pseudo-class, please SKIP this test.</p>
|
||||
<div id="target" tabindex="0">Target</div>
|
||||
<script>
|
||||
// Check that :focus-visible is supported.
|
||||
test_valid_selector(':focus-visible');
|
||||
|
||||
async_test(function(t) {
|
||||
target.addEventListener("focus", t.step_func(function() {
|
||||
assert_equals(getComputedStyle(target).outlineStyle, "auto", `outline-style for ${target.tagName}#${target.id} should be auto`);
|
||||
t.done();
|
||||
}));
|
||||
target.focus();
|
||||
}, "By default initial programatic focus matches ':focus-visible', so the element shows a focus ring with 'outline-style: auto'");
|
||||
</script>
|
|
@ -0,0 +1,62 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8" />
|
||||
<title>CSS Test (Selectors): :focus-visible doesn't match on ShadowRoot</title>
|
||||
<link rel="author" title="Manuel Rego Casasnovas" href="mailto:rego@igalia.com">
|
||||
<link rel="help" href="https://drafts.csswg.org/selectors-4/#the-focus-visible-pseudo" />
|
||||
<script src="../../resources/testharness.js"></script>
|
||||
<script src="../../resources/testharnessreport.js"></script>
|
||||
<script src="../support/parsing-testcommon.js"></script>
|
||||
<style>
|
||||
#warning {
|
||||
display: none;
|
||||
background: red;
|
||||
}
|
||||
|
||||
@supports not selector(:focus-visible) {
|
||||
#instructions {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#warning {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
#host:focus-visible {
|
||||
outline: 0;
|
||||
background-color: red;
|
||||
}
|
||||
</style>
|
||||
|
||||
<p>This test checks that <code>:focus-visible</code> doesn't math on ShadowRoot.</p>
|
||||
<ol id="instructions">
|
||||
<li>The input should be focused on load, if it's not focused, focus it via mouse or keyboard.</li>
|
||||
<li>If you see no red the test result is SUCCESS.</li>
|
||||
</ol>
|
||||
<p id="warning">Your user-agent does not support <code>:focus-visible</code> pseudo-class, please SKIP this test.</p>
|
||||
|
||||
<div id="host" style="height: 100px;"></div>
|
||||
|
||||
<script>
|
||||
const shadowRoot = host.attachShadow({mode: 'open', delegatesFocus: true});
|
||||
shadowRoot.innerHTML = '<input id="target" autofocus value="Focus me">';
|
||||
|
||||
// Check that :focus-visible is supported.
|
||||
test_valid_selector(':focus-visible');
|
||||
|
||||
async_test((t) => {
|
||||
host.focus();
|
||||
window.requestAnimationFrame(t.step_func_done(() => {
|
||||
assert_not_equals(getComputedStyle(host).backgroundColor, "rgb(255, 0, 0)", `backgroundColor for ${host.tagName}#${host.id} should NOT be red`);
|
||||
|
||||
let focusVisiblePseudoAll = document.querySelectorAll(':focus-visible');
|
||||
assert_equals(focusVisiblePseudoAll.length, 0, "No element matches ':focus-visible'");
|
||||
|
||||
let focusVisibleShadowDOMPseudoAll = shadowRoot.querySelectorAll(':focus-visible');
|
||||
assert_equals(focusVisibleShadowDOMPseudoAll.length, 1, "Only one element matches ':focus-visible' in the Shadow DOM");
|
||||
|
||||
let target = shadowRoot.getElementById("target");
|
||||
assert_equals(target, focusVisibleShadowDOMPseudoAll[0], "${target.tagName}#${target.id} matches ':focus-visible'");
|
||||
}));
|
||||
}, ":focus-visible doesn't match on ShadowRoot");
|
||||
</script>
|
|
@ -0,0 +1,54 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8" />
|
||||
<title>CSS Test (Selectors): Script focus without any previous user interaction matches :focus-visible</title>
|
||||
<link rel="author" title="Manuel Rego Casasnovas" href="mailto:rego@igalia.com">
|
||||
<link rel="help" href="https://drafts.csswg.org/selectors-4/#the-focus-visible-pseudo" />
|
||||
<script src="../../resources/testharness.js"></script>
|
||||
<script src="../../resources/testharnessreport.js"></script>
|
||||
<script src="../support/parsing-testcommon.js"></script>
|
||||
<style>
|
||||
#warning {
|
||||
display: none;
|
||||
background: red;
|
||||
}
|
||||
|
||||
@supports not selector(:focus-visible) {
|
||||
#instructions {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#warning {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
:focus-visible {
|
||||
outline: solid thick green;
|
||||
}
|
||||
|
||||
:focus:not(:focus-visible) {
|
||||
background-color: red;
|
||||
}
|
||||
</style>
|
||||
|
||||
<p>This test checks that a script focus when the user hasn't interacted with the page yet, always matches <code>:focus-visible</code>.</p>
|
||||
<ol id="instructions">
|
||||
<li>If the element that says "Focused" has a red background then the test result is FAILURE, if it has a green outline then the test result is SUCCESS.</li>
|
||||
</ol>
|
||||
<p id="warning">Your user-agent does not support <code>:focus-visible</code> pseudo-class, please SKIP this test.</p>
|
||||
|
||||
<div id="target" tabindex="0">Focused</div>
|
||||
|
||||
<script>
|
||||
// Check that :focus-visible is supported.
|
||||
test_valid_selector(':focus-visible');
|
||||
|
||||
async_test(function(t) {
|
||||
target.addEventListener("focus", t.step_func_done(function() {
|
||||
assert_equals(getComputedStyle(target).outlineColor, "rgb(0, 128, 0)", `outlineColor for ${target.tagName}#${target.id} should be green`);
|
||||
assert_not_equals(getComputedStyle(target).backgroundColor, "rgb(255, 0, 0)", `backgroundColor for ${target.tagName}#${target.id} should NOT be red`);
|
||||
}));
|
||||
}, "Script focus without any previous user interaction matches :focus-visible");
|
||||
|
||||
target.focus();
|
||||
</script>
|
|
@ -0,0 +1,158 @@
|
|||
<!DOCTYPE html>
|
||||
<html id="html">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Selectors Level 4: focus-within</title>
|
||||
<link rel="author" title="Benjamin Poulain" href="mailto:bpoulain@apple.com">
|
||||
<link rel="author" title="Manuel Rego Casasnovas" href="mailto:rego@igalia.com">
|
||||
<link rel="help" href="https://drafts.csswg.org/selectors-4/#focus-within-pseudo">
|
||||
<meta name="assert" content="Checks the basic features of the ':focus-within' pseudo class.">
|
||||
<script src="../../resources/testharness.js"></script>
|
||||
<script src="../../resources/testharnessreport.js"></script>
|
||||
<style>
|
||||
* {
|
||||
background-color: white;
|
||||
}
|
||||
:focus-within {
|
||||
background-color: rgb(1, 2, 3);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body id="body">
|
||||
<div id="test">
|
||||
<div id="container1">
|
||||
<div id="sibling1"></div>
|
||||
<div id="sibling2">
|
||||
<input id="target1">
|
||||
</div>
|
||||
<div id="sibling3"></div>
|
||||
</div>
|
||||
<div id="container2">
|
||||
<div id="sibling4"></div>
|
||||
<div id="sibling5">
|
||||
<textarea id="target2"></textarea>
|
||||
</div>
|
||||
<div id="sibling6"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id=log></div>
|
||||
|
||||
<script>
|
||||
"use strict";
|
||||
|
||||
function elementsStyledWithFocusWithinSelector() {
|
||||
let elements = [];
|
||||
for (let element of document.querySelectorAll("*")) {
|
||||
if (getComputedStyle(element).backgroundColor === 'rgb(1, 2, 3)') {
|
||||
elements.push(element.id);
|
||||
}
|
||||
}
|
||||
return elements;
|
||||
}
|
||||
|
||||
function elementsMatchingFocusWithinSelector() {
|
||||
let elements = [];
|
||||
for (let element of document.querySelectorAll(":focus-within")) {
|
||||
elements.push(element.id);
|
||||
}
|
||||
return elements;
|
||||
}
|
||||
|
||||
test(
|
||||
function() {
|
||||
assert_array_equals(elementsStyledWithFocusWithinSelector(), []);
|
||||
assert_array_equals(elementsMatchingFocusWithinSelector(), []);
|
||||
}, "Initial State");
|
||||
|
||||
var container1 = document.getElementById("container1");
|
||||
var container2 = document.getElementById("container2");
|
||||
var target1 = document.getElementById("target1");
|
||||
var target2 = document.getElementById("target2");
|
||||
|
||||
test(
|
||||
function() {
|
||||
target1.focus();
|
||||
assert_array_equals(elementsStyledWithFocusWithinSelector(), ["html", "body", "test", "container1", "sibling2", "target1"]);
|
||||
assert_array_equals(elementsMatchingFocusWithinSelector(), ["html", "body", "test", "container1", "sibling2", "target1"]);
|
||||
}, "Focus 'target1'");
|
||||
|
||||
test(
|
||||
function() {
|
||||
target2.focus();
|
||||
assert_array_equals(elementsStyledWithFocusWithinSelector(), ["html", "body", "test", "container2", "sibling5", "target2"]);
|
||||
assert_array_equals(elementsMatchingFocusWithinSelector(), ["html", "body", "test", "container2", "sibling5", "target2"]);
|
||||
}, "Focus 'target2'");
|
||||
|
||||
test(
|
||||
function() {
|
||||
target1.focus();
|
||||
assert_array_equals(elementsStyledWithFocusWithinSelector(), ["html", "body", "test", "container1", "sibling2", "target1"]);
|
||||
assert_array_equals(elementsMatchingFocusWithinSelector(), ["html", "body", "test", "container1", "sibling2", "target1"]);
|
||||
}, "Focus 'target1' again");
|
||||
|
||||
test(
|
||||
function() {
|
||||
target2.focus();
|
||||
assert_array_equals(elementsStyledWithFocusWithinSelector(), ["html", "body", "test", "container2", "sibling5", "target2"]);
|
||||
assert_array_equals(elementsMatchingFocusWithinSelector(), ["html", "body", "test", "container2", "sibling5", "target2"]);
|
||||
}, "Focus 'target2' again");
|
||||
|
||||
test(
|
||||
function() {
|
||||
target1.focus();
|
||||
assert_array_equals(elementsStyledWithFocusWithinSelector(), ["html", "body", "test", "container1", "sibling2", "target1"]);
|
||||
assert_array_equals(elementsMatchingFocusWithinSelector(), ["html", "body", "test", "container1", "sibling2", "target1"]);
|
||||
}, "Focus 'target1' once again");
|
||||
|
||||
test(
|
||||
function() {
|
||||
container1.parentElement.removeChild(container1);
|
||||
assert_array_equals(elementsStyledWithFocusWithinSelector(), []);
|
||||
assert_array_equals(elementsMatchingFocusWithinSelector(), []);
|
||||
assert_equals(container1.querySelectorAll(":focus-within").length, 0);
|
||||
assert_false(target1.matches(":focus"));
|
||||
assert_false(target2.matches(":focus"));
|
||||
}, "Detach 'container1' from the document");
|
||||
|
||||
test(
|
||||
function() {
|
||||
target1.focus();
|
||||
assert_array_equals(elementsStyledWithFocusWithinSelector(), []);
|
||||
assert_array_equals(elementsMatchingFocusWithinSelector(), []);
|
||||
assert_equals(container1.querySelectorAll(":focus-within").length, 0);
|
||||
assert_false(target1.matches(":focus"));
|
||||
assert_false(target2.matches(":focus"));
|
||||
}, "Try to focus 'target1'");
|
||||
|
||||
test(
|
||||
function() {
|
||||
target2.focus();
|
||||
assert_array_equals(elementsStyledWithFocusWithinSelector(), ["html", "body", "test", "container2", "sibling5", "target2"]);
|
||||
assert_array_equals(elementsMatchingFocusWithinSelector(), ["html", "body", "test", "container2", "sibling5", "target2"]);
|
||||
}, "Focus 'target2' once again");
|
||||
|
||||
test(
|
||||
function() {
|
||||
container2.appendChild(container1);
|
||||
assert_array_equals(elementsStyledWithFocusWithinSelector(), ["html", "body", "test", "container2", "sibling5", "target2"]);
|
||||
assert_array_equals(elementsMatchingFocusWithinSelector(), ["html", "body", "test", "container2", "sibling5", "target2"]);
|
||||
}, "Attach 'container1' in 'container2'");
|
||||
|
||||
test(
|
||||
function() {
|
||||
target1.focus();
|
||||
assert_array_equals(elementsStyledWithFocusWithinSelector(), ["html", "body", "test", "container2", "container1", "sibling2", "target1"]);
|
||||
assert_array_equals(elementsMatchingFocusWithinSelector(), ["html", "body", "test", "container2", "container1", "sibling2", "target1"]);
|
||||
}, "Focus 'target1' for the last time");
|
||||
|
||||
test(
|
||||
function() {
|
||||
container2.appendChild(target1);
|
||||
assert_array_equals(elementsStyledWithFocusWithinSelector(), []);
|
||||
assert_array_equals(elementsMatchingFocusWithinSelector(), []);
|
||||
assert_false(target1.matches(":focus"));
|
||||
assert_false(target2.matches(":focus"));
|
||||
}, "Move 'target1' in 'container2'");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,58 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>Selectors Level 4: focus-within</title>
|
||||
<link rel="author" title="Manuel Rego Casasnovas" href="mailto:rego@igalia.com">
|
||||
<link rel="help" href="https://drafts.csswg.org/selectors-4/#focus-within-pseudo">
|
||||
<link rel="help" href="https://html.spec.whatwg.org/multipage/interaction.html#focus-fixup-rule">
|
||||
<meta name="assert" content="Checks ':focus-within' pseudo-class after 'display: none'.">
|
||||
<script src="../../resources/testharness.js"></script>
|
||||
<script src="../../resources/testharnessreport.js"></script>
|
||||
<div id="wrapper">
|
||||
<input id="input">
|
||||
</div>
|
||||
<script>
|
||||
"use strict";
|
||||
|
||||
const wrapper = document.getElementById("wrapper");
|
||||
const input = document.getElementById("input");
|
||||
|
||||
async_test((t) => {
|
||||
input.focus();
|
||||
window.requestAnimationFrame(() => {
|
||||
t.step(() => assert_true(input.matches(":focus-within"),
|
||||
"Check input matches ':focus-within' after being focused"));
|
||||
t.step(() => assert_true(wrapper.matches(":focus-within"),
|
||||
"Check wrapper matches ':focus-within' after child was focused"));
|
||||
|
||||
input.style.display = "none";
|
||||
window.requestAnimationFrame(() => {
|
||||
t.step(() => assert_false(input.matches(":focus-within"),
|
||||
"Check input doesn't match ':focus-within' after getting 'display: none'"));
|
||||
t.step(() => assert_false(wrapper.matches(":focus-within"),
|
||||
"Check wrapper doesn't match ':focus-within' after child got 'display: none'"));
|
||||
input.style.display = "inline";
|
||||
t.done();
|
||||
});
|
||||
});
|
||||
}, "Test ':focus-within' after 'display:none' on input");
|
||||
|
||||
async_test((t) => {
|
||||
input.focus();
|
||||
window.requestAnimationFrame(() => {
|
||||
t.step(() => assert_true(input.matches(":focus-within"),
|
||||
"Check input matches ':focus-within' after being focused"));
|
||||
t.step(() => assert_true(wrapper.matches(":focus-within"),
|
||||
"Check wrapper matches ':focus-within' after child was focused"));
|
||||
|
||||
wrapper.style.display = "none";
|
||||
window.requestAnimationFrame(() => {
|
||||
t.step(() => assert_false(input.matches(":focus-within"),
|
||||
"Check input doesn't match ':focus-within' after parent got 'display: none'"));
|
||||
t.step(() => assert_false(wrapper.matches(":focus-within"),
|
||||
"Check wrapper doesn't match ':focus-within' after getting 'display: none'"));
|
||||
wrapper.style.display = "block";
|
||||
t.done();
|
||||
});
|
||||
});
|
||||
}, "Test ':focus-within' after 'display:none' on input's parent");
|
||||
</script>
|
|
@ -0,0 +1,45 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test string hash collision in bucketing</title>
|
||||
<meta rel="author" href="mailto:sesse@chromium.org" title="Steinar H. Gunderson">
|
||||
<link rel="help" href="https://www.w3.org/TR/css3-selectors/#selectors"/>
|
||||
<script src="../../resources/testharness.js"></script>
|
||||
<script src="../../resources/testharnessreport.js"></script>
|
||||
<style>
|
||||
/* These strings all collide in Blink's AtomicString hash function. */
|
||||
.abetfx { --a: a; }
|
||||
.adqcne { --b: b; }
|
||||
.anztgy { --c: c; }
|
||||
.jkeyea { --d: d; }
|
||||
.ltjjvc { --e: e; }
|
||||
.osniry { --f: f; }
|
||||
.otgvil { --g: g; }
|
||||
.ppvdzg { --h: h; }
|
||||
.pwkbxn { --i: i; }
|
||||
.rkefup { --j: j; }
|
||||
.wsqwrf { --k: k; }
|
||||
.zzpnvg { --l: l; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="d" class="abetfx adqcne anztgy jkeyea ltjjvc osniry otgvil ppvdzg pwkbxn rkefup wsqwrf zzpnvg">Some text</div>
|
||||
<script>
|
||||
test(() => {
|
||||
const cs = getComputedStyle(d);
|
||||
assert_equals('a', cs.getPropertyValue('--a'));
|
||||
assert_equals('b', cs.getPropertyValue('--b'));
|
||||
assert_equals('c', cs.getPropertyValue('--c'));
|
||||
assert_equals('d', cs.getPropertyValue('--d'));
|
||||
assert_equals('e', cs.getPropertyValue('--e'));
|
||||
assert_equals('f', cs.getPropertyValue('--f'));
|
||||
assert_equals('g', cs.getPropertyValue('--g'));
|
||||
assert_equals('h', cs.getPropertyValue('--h'));
|
||||
assert_equals('i', cs.getPropertyValue('--i'));
|
||||
assert_equals('j', cs.getPropertyValue('--j'));
|
||||
assert_equals('k', cs.getPropertyValue('--k'));
|
||||
assert_equals('l', cs.getPropertyValue('--l'));
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,52 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Selectors :last-child</title>
|
||||
<link rel="help" href="https://drafts.csswg.org/selectors-4/#the-last-child-pseudo">
|
||||
<script src="../../resources/testharness.js"></script>
|
||||
<script src="../../resources/testharnessreport.js"></script>
|
||||
<!--
|
||||
See also:
|
||||
* child-indexed-pseudo-class.html
|
||||
* child-indexed-no-parent.html
|
||||
* invalidation/first-child-last-child.html
|
||||
-->
|
||||
<body>
|
||||
|
||||
<div>
|
||||
<div id="target1">Whitespace nodes should be ignored.</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<blockquote></blockquote>
|
||||
<div id="target2">There is a prior child element.</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div id="target3">A comment node should be ignored.</div>
|
||||
<!-- -->
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div id="target4">Non-whitespace text node should be ignored.</div>
|
||||
.
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div id="target5" data-expected="false">The first child should not be matched.</div>
|
||||
<blockquote></blockquote>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
for (let i = 1; i <= 5; ++i) {
|
||||
let target = document.querySelector(`#target${i}`);
|
||||
test(() => {
|
||||
if (target.dataset.expected == 'false')
|
||||
assert_false(target.matches(':last-child'));
|
||||
else
|
||||
assert_true(target.matches(':last-child'));
|
||||
}, target.textContent);
|
||||
}
|
||||
</script>
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Selectors :last-of-type</title>
|
||||
<link rel="help" href="https://drafts.csswg.org/selectors-4/#the-last-of-type-pseudo">
|
||||
<script src="../../resources/testharness.js"></script>
|
||||
<script src="../../resources/testharnessreport.js"></script>
|
||||
<!--
|
||||
See also:
|
||||
* child-indexed-pseudo-class.html
|
||||
* child-indexed-no-parent.html
|
||||
-->
|
||||
<body>
|
||||
|
||||
<div>
|
||||
<div id="target1">Whitespace nodes should be ignored.</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div></div>
|
||||
<div id="target2">Thre is another child element of the same type.</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div id="target3">There is a posterior child element of another type.</div>
|
||||
<blockquote></blockquote>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<blockquote>
|
||||
<div id="target4">A next element of the parent should not affect.</div>
|
||||
</blockquote>
|
||||
<div></div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div>
|
||||
<div id="target5">The parent element of the same type should not affect.</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div id="target6">A child of the next element should not affect.</div>
|
||||
<blockquote>
|
||||
<div></div>
|
||||
</blockquote>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div id="target7" data-expected="false">The first child element of the same
|
||||
type should not match.</div>
|
||||
<div></div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div id="target8" data-expected="false">The first child element of the same
|
||||
type should not match, the last child has a case-different tag name.</div>
|
||||
<DIV></DIV>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div id="insertAfter1"></div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
for (let i = 1; i <= 8; ++i) {
|
||||
let target = document.querySelector(`#target${i}`);
|
||||
test(() => {
|
||||
if (target.dataset.expected == 'false')
|
||||
assert_false(target.matches('div:last-of-type'));
|
||||
else
|
||||
assert_true(target.matches('div:last-of-type'));
|
||||
}, target.textContent.replaceAll('\n', ' '));
|
||||
}
|
||||
|
||||
test(() => {
|
||||
const ia1 = document.querySelector('#insertAfter1');
|
||||
const target = document.createElement('div');
|
||||
assert_true(ia1.matches('div:last-of-type'));
|
||||
ia1.parentNode.insertBefore(target, ia1.nextSibling);
|
||||
assert_true(target.matches('div:last-of-type'));
|
||||
assert_false(ia1.matches('div:last-of-type'));
|
||||
|
||||
target.remove();
|
||||
assert_true(ia1.matches('div:last-of-type'));
|
||||
}, 'Dynamic insertion and removal');
|
||||
</script>
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta id="expected" charset="utf-8">
|
||||
<title>Selectors: attribute selectors with missing right token</title>
|
||||
<link rel="author" title="Eric Willigers" href="mailto:ericwilligers@chromium.org">
|
||||
<link rel="help" href="https://drafts.csswg.org/selectors-4/#attribute-selectors">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-syntax/#rule-defs">
|
||||
<meta name="assert" content="Checks attribute selectors with missing right token are matched.">
|
||||
<script src="../../resources/testharness.js"></script>
|
||||
<script src="../../resources/testharnessreport.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
|
||||
<div id="container">
|
||||
<span></span>
|
||||
<span class="cls"></span>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
test(() => {
|
||||
assert_equals(document.querySelector('meta[charset="utf-8"'), expected);
|
||||
assert_equals(document.querySelector('meta[charset="utf-8'), expected);
|
||||
|
||||
assert_equals(container.querySelectorAll('span:not([class]').length, 1);
|
||||
assert_equals(container.querySelectorAll('span:not([class').length, 1);
|
||||
}, "attribute selectors with missing right tokens succeed");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,46 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Matching behavior for :not with complex selector list</title>
|
||||
<script src="../../resources/testharness.js"></script>
|
||||
<script src="../../resources/testharnessreport.js"></script>
|
||||
<link rel="help" href="https://drafts.csswg.org/selectors/#negation">
|
||||
|
||||
<main id=main>
|
||||
<div id=a><div id=d></div></div>
|
||||
<div id=b><div id=e></div></div>
|
||||
<div id=c><div id=f></div></div>
|
||||
</main>
|
||||
|
||||
<script>
|
||||
function formatElements(elements) {
|
||||
return elements.map(e => e.id).sort().join();
|
||||
}
|
||||
|
||||
// Test that |selector| returns the given elements in #main.
|
||||
function test_selector(selector, expected) {
|
||||
test(function() {
|
||||
let actual = Array.from(main.querySelectorAll(selector));
|
||||
assert_equals(formatElements(actual), formatElements(expected));
|
||||
}, `${selector} matches expected elements`);
|
||||
}
|
||||
|
||||
test_selector(':not(#a)', [b, c, d, e, f]);
|
||||
test_selector(':not(#a #d)', [a, b, c, e, f]);
|
||||
test_selector(':not(#b div)', [a, b, c, d, f]);
|
||||
test_selector(':not(div div)', [a, b, c]);
|
||||
test_selector(':not(div + div)', [a, d, e, f]);
|
||||
test_selector(':not(main > div)', [d, e, f]);
|
||||
test_selector(':not(#a, #b)', [c, d, e, f]);
|
||||
test_selector(':not(#f, main > div)', [d, e]);
|
||||
test_selector(':not(div + div + div, div + div > div)', [a, b, d]);
|
||||
test_selector(':not(div:nth-child(1))', [b, c]);
|
||||
test_selector(':not(:not(div))', [a, b, c, d, e, f]);
|
||||
test_selector(':not(:not(:not(div)))', []);
|
||||
test_selector(':not(div, span)', []);
|
||||
test_selector(':not(span, p)', [a, b, c, d, e, f]);
|
||||
test_selector(':not(#unknown, .unknown)', [a, b, c, d, e, f]);
|
||||
test_selector(':not(#unknown > div, span)', [a, b, c, d, e, f]);
|
||||
test_selector(':not(#unknown ~ div, span)', [a, b, c, d, e, f]);
|
||||
test_selector(':not(:hover div)', [a, b, c, d, e, f]);
|
||||
test_selector(':not(:link div)', [a, b, c, d, e, f]);
|
||||
test_selector(':not(:visited div)', [a, b, c, d, e, f]);
|
||||
</script>
|
|
@ -0,0 +1,50 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Specificity for complex :not selectors</title>
|
||||
<script src="../../resources/testharness.js"></script>
|
||||
<script src="../../resources/testharnessreport.js"></script>
|
||||
<link rel="help" href="https://drafts.csswg.org/selectors/#negation">
|
||||
<style>
|
||||
main :not(#foo) { --t0:PASS; }
|
||||
main :not(.foo) { --t0:FAIL; }
|
||||
|
||||
main :not(div#foo) { --t1:PASS; }
|
||||
main :not(#foo) { --t1:FAIL; }
|
||||
|
||||
main :not(.bar, #foo) { --t2:FAIL; }
|
||||
main :not(#foo, .bar) { --t2:PASS; }
|
||||
|
||||
main :not(.bar, #foo) { --t3:PASS; }
|
||||
main :not(.foo, .bar) { --t3:FAIL; }
|
||||
|
||||
main :not(span + span) { --t4:PASS; }
|
||||
main :not(span) { --t4:FAIL; }
|
||||
|
||||
main :not(span, li, #foo) { --t5:PASS; }
|
||||
main :not(span, li, p) { --t5:FAIL; }
|
||||
|
||||
main :not(span, :not(:not(.a#foo)), p) { --t6:PASS; }
|
||||
main :not(span, #foo, p) { --t6:FAIL; }
|
||||
|
||||
main :not(span, #foo, p) { --t7:PASS; }
|
||||
main :not(span, :where(.a#foo), p) { --t7:FAIL; }
|
||||
</style>
|
||||
<main id=main>
|
||||
<div id=div></div>
|
||||
</main>
|
||||
<script>
|
||||
function test_value(name, description) {
|
||||
test(function() {
|
||||
let actual = getComputedStyle(div).getPropertyValue(name);
|
||||
assert_equals(actual, 'PASS');
|
||||
}, description);
|
||||
}
|
||||
|
||||
test_value('--t0', ':not(#foo) wins over :not(.foo)');
|
||||
test_value('--t1', ':not(div#foo) wins over :not(#foo)');
|
||||
test_value('--t2', ':not(.bar, #foo) has same specificity as :not(#foo, .bar)');
|
||||
test_value('--t3', ':not(.bar, #foo) wins over :not(.foo, .bar)');
|
||||
test_value('--t4', ':not(span + span) wins over :not(span)');
|
||||
test_value('--t5', ':not(span, li, p) wins over :not(span, lo, p)');
|
||||
test_value('--t6', ':not(span, :not(:not(.a#foo)), p) wins over :not(span, #foo, p)');
|
||||
test_value('--t7', ':not(span, #foo, p) wins over :not(span, :where(.a#foo), p)');
|
||||
</script>
|
|
@ -0,0 +1,24 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>CSS Selectors: :nth-last-child() with no argument</title>
|
||||
<link rel="help" href="https://crbug.com/355451192">
|
||||
<link rel="help" href="https://drafts.csswg.org/selectors-4/#child-index">
|
||||
<script src="../../resources/testharness.js"></script>
|
||||
<script src="../../resources/testharnessreport.js"></script>
|
||||
<style>
|
||||
#target:nth-last-child() { color: red; }
|
||||
#target { color: green; }
|
||||
</style>
|
||||
<head>
|
||||
<body>
|
||||
<body>
|
||||
<div id="target">Test passes if this line is green.</div>
|
||||
<script>
|
||||
test(() => {
|
||||
assert_equals(getComputedStyle(target).color, 'rgb(0, 128, 0)');
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
<!DOCTYPE html>
|
||||
<title>CSS Selectors Test: :*-of-type with namespace</title>
|
||||
<link rel="help" href="https://drafts.csswg.org/selectors/#typed-child-index">
|
||||
<script src="../../resources/testharness.js"></script>
|
||||
<script src="../../resources/testharnessreport.js"></script>
|
||||
<style>
|
||||
[test-span]:nth-of-type(100) {
|
||||
color: green;
|
||||
}
|
||||
</style>
|
||||
<div id="container"></div>
|
||||
<script>
|
||||
|
||||
setup(() => {
|
||||
function appendSpans(parent) {
|
||||
for (let i = 0; i < 99; i++) {
|
||||
parent.appendChild(document.createElement("span"));
|
||||
}
|
||||
const test_span = document.createElement("span");
|
||||
test_span.setAttribute("test-span", "");
|
||||
parent.appendChild(test_span);
|
||||
}
|
||||
|
||||
function appendSpansNS(parent, namespace) {
|
||||
for (let i = 0; i < 99; i++) {
|
||||
parent.appendChild(document.createElementNS(namespace, "span"));
|
||||
}
|
||||
const test_span = document.createElementNS(namespace, "span");
|
||||
test_span.setAttribute("test-span", "");
|
||||
parent.appendChild(test_span);
|
||||
}
|
||||
|
||||
appendSpans(container);
|
||||
appendSpansNS(container, "http://dummy1/");
|
||||
appendSpansNS(container, "http://dummy2/");
|
||||
});
|
||||
|
||||
const green = "rgb(0, 128, 0)";
|
||||
|
||||
for (let span of container.querySelectorAll("[test-span]")) {
|
||||
test(() => {
|
||||
assert_equals(getComputedStyle(span).color, green,
|
||||
"span with namespace: " + span.namespaceURI
|
||||
+ " should have a green color");
|
||||
}, ":nth-of-type selectors matching takes element namespace into account ("
|
||||
+ span.namespaceURI + ")");
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,61 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Selectors :only-child</title>
|
||||
<link rel="help" href="https://drafts.csswg.org/selectors-4/#the-only-child-pseudo">
|
||||
<script src="../../resources/testharness.js"></script>
|
||||
<script src="../../resources/testharnessreport.js"></script>
|
||||
<!--
|
||||
See also child-indexed-pseudo-class.html.
|
||||
-->
|
||||
<body>
|
||||
|
||||
<div>
|
||||
<div id="target1">Whitespace nodes should be ignored.</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div id="target2">A comment node should be ignored.</div>
|
||||
<!-- -->
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div id="target3">Non-whitespace text node should be ignored.</div>
|
||||
.
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<blockquote></blockquote>
|
||||
<div id="target4" data-expected="false">There is another child element.</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div id="target5"></div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
for (let i = 1; i <= 4; ++i) {
|
||||
let target = document.querySelector(`#target${i}`);
|
||||
test(() => {
|
||||
if (target.dataset.expected == 'false')
|
||||
assert_false(target.matches(':only-child'));
|
||||
else
|
||||
assert_true(target.matches(':only-child'));
|
||||
}, target.textContent);
|
||||
}
|
||||
|
||||
test(() => {
|
||||
const target = document.querySelector('#target5');
|
||||
assert_true(target.matches(':only-child'));
|
||||
|
||||
const another = target.parentNode.appendChild(document.createElement('div'));
|
||||
assert_false(target.matches(':only-child'));
|
||||
assert_false(another.matches(':only-child'));
|
||||
|
||||
another.remove();
|
||||
assert_true(target.matches(':only-child'));
|
||||
}, 'Dynamic addition and removal');
|
||||
|
||||
</script>
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Selectors :only-of-type</title>
|
||||
<link rel="help" href="https://drafts.csswg.org/selectors-4/#the-only-of-type-pseudo">
|
||||
<script src="../../resources/testharness.js"></script>
|
||||
<script src="../../resources/testharnessreport.js"></script>
|
||||
<!--
|
||||
See also child-indexed-pseudo-class.html.
|
||||
-->
|
||||
<body>
|
||||
|
||||
<div>
|
||||
<div id="target1">Whitespace nodes should be ignored.</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div id="target2">A comment node should be ignored.</div>
|
||||
<!-- -->
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div id="target3">Non-whitespace text node should be ignored.</div>
|
||||
.
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<blockquote></blockquote>
|
||||
<div id="target4" data-expected="false">There is another child element of a different type.</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div id="target5"></div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
for (let i = 1; i <= 4; ++i) {
|
||||
let target = document.querySelector(`#target${i}`);
|
||||
test(() => {
|
||||
if (target.dataset.expected == 'true')
|
||||
assert_false(target.matches(':only-of-type'));
|
||||
else
|
||||
assert_true(target.matches(':only-of-type'));
|
||||
}, target.textContent);
|
||||
}
|
||||
|
||||
test(() => {
|
||||
const target = document.querySelector('#target5');
|
||||
assert_true(target.matches(':only-of-type'));
|
||||
|
||||
const of_different_type = target.parentNode.appendChild(document.createElement('span'));
|
||||
assert_true(of_different_type.matches(':only-of-type'));
|
||||
assert_true(target.matches(':only-of-type'));
|
||||
|
||||
const another_of_type = target.parentNode.appendChild(document.createElement('div'));
|
||||
assert_false(target.matches(':only-of-type'));
|
||||
assert_false(another_of_type.matches(':only-of-type'));
|
||||
|
||||
another_of_type.remove();
|
||||
assert_true(target.matches(':only-of-type'));
|
||||
}, 'Dynamic addition and removal');
|
||||
|
||||
</script>
|
|
@ -0,0 +1,41 @@
|
|||
<!DOCTYPE html>
|
||||
<title>CSS Selectors Test: :placeholder-shown matching</title>
|
||||
<link rel="help" href="https://drafts.csswg.org/selectors/#placeholder">
|
||||
<script src="../../resources/testharness.js"></script>
|
||||
<script src="../../resources/testharnessreport.js"></script>
|
||||
<style>
|
||||
:not(:placeholder-shown) + #t1,
|
||||
:placeholder-shown + #t2,
|
||||
:placeholder-shown + #t3,
|
||||
:placeholder-shown + #t4,
|
||||
:not(:placeholder-shown) + #t5,
|
||||
:not(:placeholder-shown) + #t6,
|
||||
:not(:placeholder-shown) + #t7 {
|
||||
color: green;
|
||||
}
|
||||
</style>
|
||||
<input type="text"><span id="t1">Should be green</span>
|
||||
<input type="text" placeholder><span id="t2">Should be green</span>
|
||||
<input type="text" placeholder=""><span id="t3">Should be green</span>
|
||||
<input type="text" placeholder="placeholder"><span id="t4">Should be green</span>
|
||||
<input type="text" placeholder value="value"><span id="t5">Should be green</span>
|
||||
<input type="text" placeholder="" value="value"><span id="t6">Should be green</span>
|
||||
<input type="text" placeholder="placeholder" value="value"><span id="t7">Should be green</span>
|
||||
<script>
|
||||
const green = "rgb(0, 128, 0)";
|
||||
|
||||
test(() => assert_equals(getComputedStyle(t1).color, green,
|
||||
"No placeholder attribute"));
|
||||
test(() => assert_equals(getComputedStyle(t2).color, green,
|
||||
"Placeholder attribute without value"));
|
||||
test(() => assert_equals(getComputedStyle(t3).color, green,
|
||||
"Placeholder attribute - empty string"));
|
||||
test(() => assert_equals(getComputedStyle(t4).color, green,
|
||||
"Placeholder attribute - non-empty string"));
|
||||
test(() => assert_equals(getComputedStyle(t5).color, green,
|
||||
"Placeholder attribute without value - input text"));
|
||||
test(() => assert_equals(getComputedStyle(t6).color, green,
|
||||
"Placeholder attribute - empty string - input text"));
|
||||
test(() => assert_equals(getComputedStyle(t7).color, green,
|
||||
"Placeholder attribute - non-empty string - input text"));
|
||||
</script>
|
|
@ -0,0 +1,51 @@
|
|||
<!DOCTYPE html>
|
||||
<link rel="help" href="https://drafts.csswg.org/selectors-4/#enableddisabled">
|
||||
<script src="../../resources/testharness.js"></script>
|
||||
<script src="../../resources/testharnessreport.js"></script>
|
||||
<body>
|
||||
<div id="container">
|
||||
<button id="button_enabled"></button>
|
||||
<button id="button_disabled" disabled></button>
|
||||
<input id="input_enabled">
|
||||
<input id="input_disabled" disabled>
|
||||
<select id="select_enabled"></select>
|
||||
<select id="select_disabled" disabled></select>
|
||||
<textarea id="textarea_enabled"></textarea>
|
||||
<textarea id="textarea_disabled" disabled></textarea>
|
||||
<span id="incapable"></span>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
test(() => {
|
||||
const container = document.querySelector('#container');
|
||||
const matched = container.querySelectorAll(':enabled');
|
||||
for (let element of matched) {
|
||||
assert_true(element.id.endsWith('_enabled'), element.id);
|
||||
}
|
||||
}, ':enabeld should match to enabled controls');
|
||||
|
||||
test(() => {
|
||||
const container = document.querySelector('#container');
|
||||
const matched = container.querySelectorAll(':disabled');
|
||||
for (let element of matched) {
|
||||
assert_true(element.id.endsWith('_disabled'), element.id);
|
||||
}
|
||||
}, ':disabled should match to enabled controls');
|
||||
|
||||
test(() => {
|
||||
const container = document.querySelector('#container');
|
||||
const matched = container.querySelectorAll(':not(:enabled)');
|
||||
for (let element of matched) {
|
||||
assert_true(element.id.endsWith('_disabled') || element.id == 'incapable', element.id);
|
||||
}
|
||||
}, ':not(:enabeld) should match to disabled controls and non-controls');
|
||||
|
||||
test(() => {
|
||||
const container = document.querySelector('#container');
|
||||
const matched = container.querySelectorAll(':not(:disabled)');
|
||||
for (let element of matched) {
|
||||
assert_true(element.id.endsWith('_enabled') || element.id == 'incapable', element.id);
|
||||
}
|
||||
}, ':not(:disabled) should match to enabled controls and non-controls');
|
||||
</script>
|
||||
</body>
|
|
@ -0,0 +1,37 @@
|
|||
<!doctype html>
|
||||
<link rel='help' href='https://drafts.csswg.org/selectors-4/#the-scope-pseudo'>
|
||||
<meta name='description' content=':scope should match when context object is a ShadowRoot or a DocumentFragment'>
|
||||
<script src='../../resources/testharness.js'></script>
|
||||
<script src='../../resources/testharnessreport.js'></script>
|
||||
<div id='shadowHost'></div>
|
||||
<script>
|
||||
'use strict'
|
||||
const shadowHost = document.getElementById("shadowHost");
|
||||
const shadowRoot = shadowHost.attachShadow({mode:'open'})
|
||||
shadowRoot.appendChild(document.createElement("div"));
|
||||
|
||||
test (() => {
|
||||
assert_equals(shadowRoot.querySelectorAll(':scope > div').length, 0, 'should not match in shadow root');
|
||||
});
|
||||
|
||||
const documentFragment = document.createDocumentFragment();
|
||||
documentFragment.appendChild(document.createElement("div"));
|
||||
|
||||
test(() => {
|
||||
assert_equals(documentFragment.querySelectorAll(':scope > div').length, 0, 'should not match in document fragment');
|
||||
});
|
||||
|
||||
test(() => {
|
||||
assert_equals(shadowRoot.firstChild.querySelector(':scope'), null, 'should return null');
|
||||
assert_equals(shadowRoot.firstChild.querySelectorAll(':scope').length, 0, 'should return 0');
|
||||
|
||||
assert_equals(shadowRoot.querySelector(':scope'), null, 'should return null');
|
||||
assert_equals(shadowRoot.querySelectorAll(':scope').length, 0, 'should return 0');
|
||||
|
||||
assert_equals(documentFragment.querySelector(':scope'), null, 'should return null');
|
||||
assert_equals(documentFragment.querySelectorAll(':scope').length, 0, 'should return 0');
|
||||
|
||||
assert_equals(document.querySelector(':scope'), document.documentElement, 'should return the document element');
|
||||
assert_equals(document.querySelectorAll(':scope').length, 1, 'should return 1');
|
||||
}, 'querySelector() with ":scope" should return the document element, if present in the subtree');
|
||||
</script>
|
|
@ -0,0 +1,22 @@
|
|||
<!DOCTYPE html>
|
||||
<title>When non-empty placeholder becomes empty, :placeholder-shown test</title>
|
||||
<script src="../../resources/testharness.js"></script>
|
||||
<script src="../../resources/testharnessreport.js"></script>
|
||||
<link rel="help" href="https://drafts.csswg.org/selectors-4/#placeholder">
|
||||
<input id="myinput" type="text" placeholder="FAIL">
|
||||
<textarea id="mytextarea" placeholder="FAIL"></textarea>
|
||||
<script>
|
||||
test(() => {
|
||||
const input = document.querySelector("input");
|
||||
input.placeholder = "";
|
||||
input.value = "NO RED";
|
||||
assert_false(input.matches(":placeholder-shown"));
|
||||
}, "input:placeholder-shown should not be matched");
|
||||
|
||||
test(() => {
|
||||
const textarea = document.querySelector("textarea");
|
||||
textarea.placeholder = "";
|
||||
textarea.value = "No RED";
|
||||
assert_false(textarea.matches(":placeholder-shown"));
|
||||
}, "textarea:placeholder-shown should not be matched");
|
||||
</script>
|
|
@ -0,0 +1,40 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Test element names are case-insensitive only in ASCII range</title>
|
||||
<link rel="help" href="https://www.w3.org/TR/selectors-4/#case-sensitive">
|
||||
<link rel="author" title="Koji Ishii" href="mailto:kojii@chromium.org">
|
||||
<script src='../../resources/testharness.js'></script>
|
||||
<script src='../../resources/testharnessreport.js'></script>
|
||||
<style>
|
||||
\212A {
|
||||
display: block;
|
||||
background: lime;
|
||||
width: 200px;
|
||||
height: 100px;
|
||||
}
|
||||
</style>
|
||||
<body>
|
||||
<p>You should see a green square below.</p>
|
||||
<div id="container"></div>
|
||||
<script>
|
||||
// Insert from JavaScript to avoid parser doing something special.
|
||||
let test_element = document.createElement('\u212A');
|
||||
container.appendChild(test_element);
|
||||
let test_element_with_ns = document.createElementNS('https://dummy.ns', '\u212A');
|
||||
container.appendChild(test_element_with_ns);
|
||||
|
||||
test(() => {
|
||||
assert_equals(test_element.offsetHeight, 100);
|
||||
}, 'CSS selector should match for Unicode uppercase element');
|
||||
|
||||
test(() => {
|
||||
// Elements in different namespace cannot compute style or height.
|
||||
// Test the height of the container instead.
|
||||
assert_equals(container.offsetHeight, 200);
|
||||
}, 'Elements with namespace should work the same way');
|
||||
|
||||
test(() => {
|
||||
let e = document.querySelector('k');
|
||||
assert_equals(e, null);
|
||||
}, '`querySelector` should not use Unicode case-folding');
|
||||
</script>
|
||||
</body>
|
|
@ -0,0 +1,48 @@
|
|||
<!DOCTYPE html>
|
||||
<title>WebKit-prefixed pseudo-elements</title>
|
||||
<link rel="author" title="Xidorn Quan" href="https://www.upsuper.org">
|
||||
<link rel="author" title="Mozilla" href="https://www.mozilla.org">
|
||||
<link rel="help" href="https://drafts.csswg.org/selectors-4/#compat">
|
||||
<meta name="assert" content="WebKit-prefixed pseudo-elements should always be valid">
|
||||
<script src="../../resources/testharness.js"></script>
|
||||
<script src="../../resources/testharnessreport.js"></script>
|
||||
<style id="style">
|
||||
#test {
|
||||
color: rgb(255, 0, 0);
|
||||
}
|
||||
span::-webkit-something-invalid, #test, ::-WeBkIt-sOmEtHiNg-NoNeXiSt123, ::-webkit-\ escaped {
|
||||
color: rgb(0, 255, 0);
|
||||
}
|
||||
::-webkitfoo, #test {
|
||||
color: rgb(255, 0, 0);
|
||||
}
|
||||
</style>
|
||||
<body>
|
||||
<div id="test"></div>
|
||||
<script>
|
||||
test(() => {
|
||||
let elem = document.getElementById("test");
|
||||
assert_equals(getComputedStyle(elem).color, "rgb(0, 255, 0)");
|
||||
}, "rules include webkit-prefixed pseudo-element should be cascaded");
|
||||
|
||||
test(() => {
|
||||
let sheet = document.getElementById("style").sheet;
|
||||
assert_equals(sheet.cssRules[1].selectorText,
|
||||
"span::-webkit-something-invalid, " +
|
||||
"#test, ::-webkit-something-nonexist123, " +
|
||||
"::-webkit-\\ escaped");
|
||||
}, "webkit-prefixed pseudo-element selectors should be accessible from CSSOM");
|
||||
|
||||
test(() => {
|
||||
document.querySelector("span::-webkit-something-invalid");
|
||||
document.querySelectorAll("span::-webkit-something-invalid");
|
||||
}, "qS and qSA shouldn't throw exception");
|
||||
|
||||
test(() => {
|
||||
let sheet = document.getElementById("style").sheet;
|
||||
assert_equals(sheet.cssRules.length, 2);
|
||||
assert_throws_dom("SyntaxError", () => document.querySelector("span::-webkitfoo"));
|
||||
assert_throws_dom("SyntaxError", () => document.querySelectorAll("span::-webkitfoo"));
|
||||
}, "webkit-prefix without dash is invalid");
|
||||
</script>
|
||||
</body>
|
|
@ -0,0 +1,22 @@
|
|||
<!doctype html>
|
||||
<title>CSS Test: 'x-' prefixed pseudo-elements don't parse correctly</title>
|
||||
<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
|
||||
<link rel="author" title="Mozilla" href="https://www.mozilla.org">
|
||||
<link rel="help" href="https://drafts.csswg.org/selectors-4/#pseudo-elements">
|
||||
<script src="../../resources/testharness.js"></script>
|
||||
<script src="../../resources/testharnessreport.js"></script>
|
||||
<style>
|
||||
p {
|
||||
color: green;
|
||||
}
|
||||
::x-something-nobody-would-think-of, p {
|
||||
color: red;
|
||||
}
|
||||
</style>
|
||||
<p>Should be green
|
||||
<script>
|
||||
test(function() {
|
||||
let p = document.querySelector('p');
|
||||
assert_equals(getComputedStyle(p).color, "rgb(0, 128, 0)");
|
||||
}, "x-prefixed pseudo-elements should make the whole rule invalid")
|
||||
</script>
|
Loading…
Reference in a new issue