diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /testing/web-platform/tests/html/semantics/selectors | |
parent | Initial commit. (diff) | |
download | firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esr
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'testing/web-platform/tests/html/semantics/selectors')
31 files changed, 1303 insertions, 0 deletions
diff --git a/testing/web-platform/tests/html/semantics/selectors/META.yml b/testing/web-platform/tests/html/semantics/selectors/META.yml new file mode 100644 index 0000000000..3195b8671c --- /dev/null +++ b/testing/web-platform/tests/html/semantics/selectors/META.yml @@ -0,0 +1,2 @@ +suggested_reviewers: + - lilles diff --git a/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/active-disabled.html b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/active-disabled.html new file mode 100644 index 0000000000..a75a157c58 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/active-disabled.html @@ -0,0 +1,54 @@ +<!DOCTYPE html> +<link rel=author href="mailto:jarhar@chromium.org"> +<link rel=help href="https://github.com/whatwg/html/pull/7465"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-actions.js"></script> +<script src="/resources/testdriver-vendor.js"></script> + +<label id=buttonlabel for=disabledbutton>label for disabled button</label> +<button id=disabledbutton disabled>disabled</button> + +<button id=buttonparent disabled> + <div id=buttonchild>child of disabled</div> +</button> + +<input id=disabledinput disabled> + +<textarea id=disabledtextarea disabled>disabled textarea</textarea> + +<script> +function testElement(description, clickElement, checkElement) { + promise_test(async () => { + if (!checkElement) + checkElement = clickElement; + + await (new test_driver.Actions() + .pointerMove(2, 2, {origin: clickElement}) + .pointerDown()) + .send(); + + assert_true(checkElement.matches(':active')); + + await (new test_driver.Actions() + .pointerUp()) + .send(); + }, description); +} + +testElement('Clicking on a disabled button should make it match the :active selector.', + disabledbutton); + +testElement('Clicking the label for a disabled button should make the button match the :active selector.', + buttonlabel, disabledbutton); + +testElement('Clicking on a child of a disabled button should make the button match the :active selector.', + buttonchild, buttonparent); + +testElement('Clicking on a disabled input should make it match the :active selector.', + disabledinput); + +testElement('Clicking on a disabled textarea should make it match the :active selector.', + disabledtextarea); +</script> diff --git a/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/autofill.html b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/autofill.html new file mode 100644 index 0000000000..b7c3644bdb --- /dev/null +++ b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/autofill.html @@ -0,0 +1,11 @@ +<!doctype html> +<meta charset=utf-8> +<title>Selector: pseudo-classes (:autofill)</title> +<link rel=help href="https://html.spec.whatwg.org/multipage/#pseudo-classes"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/parsing-testcommon.js"></script> +<script> +test_valid_selector(":autofill"); +test_valid_selector(":-webkit-autofill", [":autofill", ":-webkit-autofill"]); +</script> diff --git a/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/checked-001-manual.html b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/checked-001-manual.html new file mode 100644 index 0000000000..76a963a600 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/checked-001-manual.html @@ -0,0 +1,18 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN"> +<html> + <head> + <title>CSS Selectors (:checked)</title> + <link rel="author" title="Ian Hickson" href="mailto:ian@hixie.ch"/> + <link rel="alternate" href="http://www.hixie.ch/tests/adhoc/css/selectors/checked/001.html"/> + <style type="text/css"> + :checked, :checked + span { border: solid blue; color: blue; background: navy; } + </style> + </head> + <body> + <p>Anything that is checked below should be blue.</p> + <p><input checked type="checkbox"> <span>X</span></p> + <p><input checked type="radio" name="x"> <span>X</span> <input checked type="radio" name="x"> <span>X</span></p> + <p><select><option selected>X</option></select></p> + <p><select size="2"><option selected>X</option></select></p> + </body> +</html>
\ No newline at end of file diff --git a/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/checked-type-change.html b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/checked-type-change.html new file mode 100644 index 0000000000..661d9e4355 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/checked-type-change.html @@ -0,0 +1,24 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Selector: pseudo-class :checked input type change</title> +<link rel="author" title="Rune Lillesveen" href="mailto:rune@opera.com"> +<link rel="help" href="https://html.spec.whatwg.org/multipage/#pseudo-classes"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<style> + span { color: red } + :checked + span { color: green } +</style> +<input id="checked" type="text" checked> +<span id="sibling">This text should be green.</span> +<script> + test(() => { + assert_equals(getComputedStyle(sibling).color, "rgb(255, 0, 0)", + "Not matching :checked for type=text"); + + checked.type = "radio"; + + assert_equals(getComputedStyle(sibling).color, "rgb(0, 128, 0)", + "Matching :checked for type=radio"); + }, "Evaluation of :checked changes on input type change."); +</script> diff --git a/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/checked.html b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/checked.html new file mode 100644 index 0000000000..754c2342bc --- /dev/null +++ b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/checked.html @@ -0,0 +1,44 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<title>Selector: pseudo-classes (:checked)</title> +<link rel="author" title="Denis Ah-Kang" href="mailto:denis@w3.org" id=link1> +<link rel=help href="https://html.spec.whatwg.org/multipage/#pseudo-classes" id=link2> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="utils.js"></script> +<div id="log"></div> +<select id=select1> + <optgroup label="options" id=optgroup1> + <option value="option1" id=option1 selected>option1 + <option value="option2" id=option2>option2 + <option value="option2" id=option3 checked>option3 +</select> +<input type=checkbox id=checkbox1 checked> +<input type=checkbox id=checkbox2> +<input type=checkbox id=checkbox3 selected> +<input type=radio id=radio1 checked> +<input type=radio id=radio2> +<form> + <p><input type=submit contextmenu=formmenu id="submitbutton"></p> + <menu type=context id=formmenu> + <!-- historical; these should *not* match --> + <menuitem type=checkbox checked default id=menuitem1> + <menuitem type=checkbox default id=menuitem2> + <menuitem type=checkbox id=menuitem3> + <menuitem type=radio checked id=menuitem4> + <menuitem type=radio id=menuitem5> + </menu> +</form> + +<script> + testSelectorIdsMatch(":checked", ["option1", "checkbox1", "radio1"], "':checked' matches checked <input>s in checkbox and radio button states, selected <option>s"); + + document.getElementById("checkbox1").removeAttribute("type"); // change type of input + document.getElementById("radio1").removeAttribute("type"); // change type of input + testSelectorIdsMatch(":checked", ["option1"], "':checked' should no longer match <input>s whose type checkbox/radio has been removed"); + + document.getElementById("option2").selected = "selected"; // select option2 + document.getElementById("checkbox2").click(); // check chekbox2 + document.getElementById("radio2").click(); // check radio2 + testSelectorIdsMatch(":checked", ["option2", "checkbox2", "radio2"], "':checked' matches clicked checkbox and radio buttons"); +</script> diff --git a/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/default.html b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/default.html new file mode 100644 index 0000000000..3187801f67 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/default.html @@ -0,0 +1,64 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<title>Selector: pseudo-classes (:default)</title> +<link rel="author" title="Denis Ah-Kang" href="mailto:denis@w3.org" id=link1> +<link rel=help href="https://html.spec.whatwg.org/multipage/#pseudo-classes" id=link2> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="utils.js"></script> +<div id="log"></div> +<form> + <button id=button1 type=button>button1</button> + <button id=button2 type=submit>button2</button> +</form> +<form> + <button id=button3 type=reset>button3</button> + <button id=button4>button4</button> +</form> +<button id=button5 type=submit>button5</button> +<form id=form1> + <input type=text id=input1> +</form> +<input type=text id=input2 form=form1> +<form> + <input type=submit id=input3> + <input type=submit id=input4> +</form> +<form> + <input type=image id=input5> + <input type=image id=input6> +</form> +<form> + <input type=submit id=input7> +</form> +<input type=checkbox id=checkbox1 checked> +<input type=checkbox id=checkbox2> +<input type=checkbox id=checkbox3 default> +<input type=radio name=radios id=radio1 checked> +<input type=radio name=radios id=radio2> +<input type=radio name=radios id=radio3 default> +<select id=select1> + <optgroup label="options" id=optgroup1> + <option value="option1" id=option1>option1 + <option value="option2" id=option2 selected>option2 +</select> +<dialog id="dialog"> + <input type=submit id=input8> +</dialog> +<form> + <button id=button6 type='invalid'>button6</button> + <button id=button7>button7</button> +</form> +<form> + <button id=button8>button8</button> + <button id=button9>button9</button> +</form> + + +<script> + testSelectorIdsMatch(":default", ["button2", "button4", "input3", "input5", "input7", "checkbox1", "radio1", "option2", "button6", "button8"], "':default' matches <button>s that are their form's default button, <input>s of type submit/image that are their form's default button, checked <input>s and selected <option>s"); + + document.getElementById("button1").type = "submit"; // change the form's default button + testSelectorIdsMatch(":default", ["button1", "button4", "input3", "input5", "input7", "checkbox1", "radio1", "option2", "button6", "button8"], "':default' matches dynamically changed form's default buttons"); + +</script> diff --git a/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/dir-dynamic.html b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/dir-dynamic.html new file mode 100644 index 0000000000..8f2951f8ef --- /dev/null +++ b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/dir-dynamic.html @@ -0,0 +1,47 @@ +<!doctype html> +<html> +<head> + <meta charset="utf-8"> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <link rel="author" title="Vincent Hilla" href="mailto:vhilla@mozilla.com"> + <link rel="help" href="https://html.spec.whatwg.org/#the-directionality"> +</head> +<body> + <input id="inp"/> + <textarea id="ta"></textarea> + <div id="div"></div> + <pre id="pre"></pre> + + <script> + function doTest(e) { + e.dir = "ltr"; + assert_true(e.matches(":dir(ltr)"), "dir to ltr on " + e.tagName + " element"); + + e.dir = "rtl"; + assert_true(e.matches(":dir(rtl)"), "dir to rtl on " + e.tagName + " element"); + + e.dir = "auto"; + assert_true(e.matches(":dir(ltr)"), "dir to auto, empty text on " + e.tagName + " element"); + + e.value = "\u05D0;"; + e.textContent = "\u05D0;"; + assert_true(e.matches(":dir(rtl)"), "auto dir, text to Hebrew on " + e.tagName + " element"); + + e.dir = "ltr"; + assert_true(e.matches(":dir(ltr)"), "dir to ltr, Hebrew text on " + e.tagName + " element"); + + e.dir = "auto"; + assert_true(e.matches(":dir(rtl)"), "dir to auto, Hebrew text on " + e.tagName + " element"); + + e.removeAttribute("dir"); + assert_true(e.matches(":dir(ltr)"), "dir removed, Hebrew text on " + e.tagName + " element"); + } + + const elements = [inp, ta, div, pre]; + for (const e of elements) { + test(() => doTest(e), "Dynamically changing dir, text on " + e.tagName.toLowerCase() + " element"); + } + </script> +</body> +</html> diff --git a/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/dir-html-input-dynamic-text.html b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/dir-html-input-dynamic-text.html new file mode 100644 index 0000000000..0c50cec369 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/dir-html-input-dynamic-text.html @@ -0,0 +1,21 @@ +<!doctype html> +<meta charset="utf-8"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1622900"> +<link rel="help" href="https://html.spec.whatwg.org/#the-directionality"> +<input value="ltr" dir="auto"> +<script> +test(function() { + let input = document.querySelector("input"); + assert_true(input.matches(":dir(ltr)"), "Input with ltr value should match dir(ltr)"); + input.textContent = "ﷺ"; + assert_true(input.matches(":dir(ltr)"), "Should still match dir(ltr) after text change"); + input.value = "ltr2"; + assert_true(input.matches(":dir(ltr)"), "Should still match dir(ltr) after value change"); + input.value = "ﷺ"; + assert_true(input.matches(":dir(rtl)"), "Should match dir(rtl) after value change"); + input.textContent = "ltr"; + assert_true(input.matches(":dir(rtl)"), "Should match dir(rtl) after text change"); +}, ":dir on <input> isn't altered by text children") +</script> diff --git a/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/dir.html b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/dir.html new file mode 100644 index 0000000000..588c3c6850 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/dir.html @@ -0,0 +1,99 @@ +<!DOCTYPE html> +<html id=html> + <head id=head> + <meta charset=utf-8 id=meta> + <title id=title>Selector: pseudo-classes (:dir(ltr), :dir(rtl))</title> + <link rel="author" title="Denis Ah-Kang" href="mailto:denis@w3.org" id=link1> + <link rel=help href="https://html.spec.whatwg.org/multipage/#pseudo-classes" id=link2> + <script src="/resources/testharness.js" id=script1></script> + <script src="/resources/testharnessreport.js" id=script2></script> + <script src="utils.js" id=script3></script> + <style id=style> + #span1 {direction: rtl;} + #span5, #span6 {display: none;} + </style> + </head> + <body id=body> + <div id="log"></div> + <bdo dir="rtl" id=bdo1>WERBEH</bdo> + <bdo dir="ltr" id=bdo2>HEBREW</bdo> + <bdi id=bdi1>HEBREW</bdi> + <bdi dir="rtl" id=bdi2>WERBEH</bdi> + <bdi dir="ltr" id=bdi3>HEBREW</bdi> + <bdi id=bdi4>إيان</bdi> + <span id=span1>WERBEH</span> + <span dir="rtl" id=span2>WERBEH</span> + <span dir="ltr" id=span3>HEBREW</span> + ‮<span id=span4>WERBEH</span>‬ + <span dir="rtl" id=span5>WERBEH</span> + <span dir="ltr" id=span6>HEBREW</span> + <span dir="rtl" id=span7> + <input type=tel id=input-tel1> + <input type=tel id=input-tel2 dir="invalid"> + </span> + <input type=tel id=input-tel3 dir="rtl"> + <bdo dir="auto" id=bdo3>HEBREW</bdo> + <bdo dir="auto" id=bdo4>إيان</bdo> + <bdo dir="ltr" id=bdo5>עברית</bdo> + <textarea dir="auto" id="ta1">إيان</textarea> + <textarea dir="auto" id="ta2">HEBREWإيان</textarea> + <textarea dir="auto" id="ta3">إيان</textarea> + <pre dir="auto" id="pre1">إيان</pre> + <pre dir="auto" id="pre2">HEBREWإيان</pre> + + <script id=script4> + ta3.value = "HEBREW"; + + const rtlElements = [ + "bdo1", + "bdi2", + "bdi4", + "span2", + "span5", + "span7", + "input-tel3", + "bdo4", + "ta1", + "pre1", + ]; + + testSelectorIdsMatch(":dir(rtl)", rtlElements, "':dir(rtl)' matches all elements whose directionality is 'rtl'."); + + const ltrElements = [ + "html", + "head", + "meta", + "title", + "link1", + "link2", + "script1", + "script2", + "script3", + "style", + "body", + "log", + "bdo2", + "bdi1", + "bdi3", + "span1", + "span3", + "span4", + "span6", + "input-tel1", + "input-tel2", + "bdo3", + "bdo5", + "ta2", + "ta3", + "pre2", + "script4", + ]; + + testSelectorIdsMatch(":dir(ltr)", ltrElements, "':dir(ltr)' matches all elements whose directionality is 'ltr'."); + + const bdo = document.createElement("bdo"); + bdo.setAttribute("dir", "ltr"); + testSelectorIdsMatch(":dir(ltr)", ltrElements, "':dir(ltr)' doesn't match elements not in the document."); + </script> + </body> +</html> diff --git a/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/dir01.html b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/dir01.html new file mode 100644 index 0000000000..61bbd574a3 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/dir01.html @@ -0,0 +1,18 @@ +<!DOCTYPE html> +<meta charset=iso-8859-8 id=meta> +<title id=title>Selector: pseudo-classes (:dir(ltr), :dir(rtl)) in iso-8859-8 documents</title> +<link rel="author" title="Denis Ah-Kang" href="mailto:denis@w3.org" id=link1> +<link rel=help href="https://html.spec.whatwg.org/multipage/#pseudo-classes" id=link2> +<script src="/resources/testharness.js" id=script1></script> +<script src="/resources/testharnessreport.js" id=script2></script> +<script src="utils.js" id=script3></script> +<div id="log"></div> +<div>This text is left to right<div id=div1 style="direction:rtl">this is right to left</div></div> +<div>This text is left to right<span id=div2 style="direction:rtl">this is left to right</span></div> + +<script> + var ltr = new Array(), + all = document.querySelectorAll('*'); + for(var i = all.length; i--; ltr.unshift(all[i])); + testSelectorElementsMatch(":dir(ltr)", ltr, "direction doesn't affect :dir()"); +</script> diff --git a/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/disabled.html b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/disabled.html new file mode 100644 index 0000000000..f960043929 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/disabled.html @@ -0,0 +1,59 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<title>Selector: pseudo-classes (:disabled)</title> +<link rel="author" title="Denis Ah-Kang" href="mailto:denis@w3.org" id=link1> +<link rel=help href="https://html.spec.whatwg.org/multipage/#pseudo-classes" id=link2> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="utils.js"></script> +<style> + #input4 {display:none;} +</style> +<div id="log"></div> +<button id=button1 type=submit>button1</button> +<button id=button2 disabled>button2</button> +<input id=input1> +<input id=input2 disabled> +<input id=input3 readonly> +<input id=input4> +<select id=select1> + <optgroup label="options" id=optgroup1> + <option value="option1" id=option1 selected>option1 +</select> +<select disabled id=select2> + <optgroup label="options" disabled id=optgroup2> + <option value="option2" disabled id=option2>option2 +</select> +<textarea id=textarea1>textarea1</textarea> +<textarea disabled id=textarea2>textarea2</textarea> +<fieldset disabled id=fieldset2> + <legend><input type=checkbox id=club></legend> + <p><label>Name on card: <input id=clubname required></label></p> + <p><label>Card number: <input id=clubnum required pattern="[-0-9]+"></label></p> +</fieldset> +<label disabled></label> +<object disabled></object> +<output disabled></output> +<img disabled/> +<meter disabled></meter> +<progress disabled></progress> + +<script> + testSelectorIdsMatch(":disabled", ["button2", "input2", "select2", "optgroup2", "option2", "textarea2", "clubname", "clubnum"], "':disabled' should match only disabled elements"); + + document.getElementById("button2").removeAttribute("disabled"); + testSelectorIdsMatch(":disabled", ["input2", "select2", "optgroup2", "option2", "textarea2", "clubname", "clubnum"], "':disabled' should not match elements whose disabled attribute has been removed"); + + document.getElementById("button1").setAttribute("disabled", "disabled"); + testSelectorIdsMatch(":disabled", ["button1", "input2", "select2", "optgroup2", "option2", "textarea2", "clubname", "clubnum"], "':disabled' should also match elements whose disabled attribute has been set"); + + document.getElementById("button1").setAttribute("disabled", "disabled"); + testSelectorIdsMatch(":disabled", ["button1", "input2", "select2", "optgroup2", "option2", "textarea2", "clubname", "clubnum"], "':disabled' should also match elements whose disabled attribute has been set twice"); + + document.getElementById("input2").setAttribute("type", "submit"); // change input type to submit + testSelectorIdsMatch(":disabled", ["button1", "input2", "select2", "optgroup2", "option2", "textarea2", "clubname", "clubnum"], "':disabled' should also match disabled elements whose type has changed"); + + var input = document.createElement("input"); + input.setAttribute("disabled", "disabled"); + testSelectorIdsMatch(":disabled", ["button1", "input2", "select2", "optgroup2", "option2", "textarea2", "clubname", "clubnum"], "':disabled' should not match elements not in the document"); +</script> diff --git a/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/enabled.html b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/enabled.html new file mode 100644 index 0000000000..1948343c18 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/enabled.html @@ -0,0 +1,42 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<title>Selector: pseudo-classes (:enabled)</title> +<link rel="author" title="Denis Ah-Kang" href="mailto:denis@w3.org" id=link1> +<link rel=help href="https://html.spec.whatwg.org/multipage/#pseudo-classes" id=link2> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="utils.js"></script> +<div id="log"></div> +<a id=link3></a> +<area id=link4></area> +<link id=link5></link> +<a href="http://www.w3.org" id=link6></a> +<area href="http://www.w3.org" id=link7></area> +<link href="http://www.w3.org" id=link8></link> +<button id=button1>button1</button> +<button id=button2 disabled>button2</button> +<input id=input1> +<input id=input2 disabled> +<select id=select1> + <optgroup label="options" id=optgroup1> + <option value="option1" id=option1 selected>option1 +</select> +<select disabled id=select2> + <optgroup label="options" disabled id=optgroup2> + <option value="option2" disabled id=option2>option2 +</select> +<textarea id=textarea1>textarea1</textarea> +<textarea disabled id=textarea2>textarea2</textarea> +<form> + <p><input type=submit contextmenu=formmenu id=submitbutton></p> + <menu type=context id=formmenu> + <!-- historical; these should *not* match --> + <menuitem command="submitbutton" default id=menuitem1> + <menuitem command="resetbutton" disabled id=menuitem2> + </menu> +</form> +<fieldset id=fieldset1></fieldset> + +<script> + testSelectorIdsMatch(":enabled", ["button1", "input1", "select1", "optgroup1", "option1", "textarea1", "submitbutton", "fieldset1"], "':enabled' elements that are not disabled"); +</script> diff --git a/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/focus-autofocus.html b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/focus-autofocus.html new file mode 100644 index 0000000000..80a75bb99e --- /dev/null +++ b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/focus-autofocus.html @@ -0,0 +1,24 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<title>Selector: pseudo-classes (:focus for autofocus)</title> +<link rel="author" title="Kent Tamura" href="mailto:tkent@chromium.org"> +<link rel=help href="https://html.spec.whatwg.org/multipage/#pseudo-classes"> +<link rel=help href="https://html.spec.whatwg.org/multipage/forms.html#autofocusing-a-form-control:-the-autofocus-attribute"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<body> +<script> +// This test can't be merged to focus.html because element.focus() may affect +// autofocus behavior. +var autofocusTest = async_test(":focus selector should work with an autofocused element."); +var input = document.createElement("input"); +input.autofocus = true; +input.addEventListener("focus", function() { + autofocusTest.step(function() { + assert_array_equals(document.querySelectorAll(":focus"), [input]) + autofocusTest.done(); + }); +}, false); +document.body.appendChild(input); +</script> +</body> diff --git a/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/focus-iframe.html b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/focus-iframe.html new file mode 100644 index 0000000000..a269f1c671 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/focus-iframe.html @@ -0,0 +1,5 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<title>Selector: pseudo-classes (:focus)</title> +<link rel="author" title="Denis Ah-Kang" href="mailto:denis@w3.org"> +<input id="inputiframe" type=text value="foobar" /> diff --git a/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/focus.html b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/focus.html new file mode 100644 index 0000000000..a319b24ef0 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/focus.html @@ -0,0 +1,51 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<title>Selector: pseudo-classes (:focus)</title> +<link rel="author" title="Denis Ah-Kang" href="mailto:denis@w3.org" id=link1> +<link rel=help href="https://html.spec.whatwg.org/multipage/#pseudo-classes" id=link2> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="utils.js"></script> +<body id=body tabindex=0> + <div id="log"></div> + <button id=button1 type=submit>button1</button> + <input id=input1> + <input id=input2 disabled> + <textarea id=textarea1>textarea1</textarea> + <input type=checkbox id=checkbox1 checked> + <input type=radio id=radio1 checked> + <div tabindex=0 id=div1>hello</div> + <div contenteditable id=div2>content</div> + <iframe src="focus-iframe.html" id=iframe></iframe> + + <script> + setup({explicit_done: true}); + + onload = function() { + if (document.hasFocus() || frames[0].document.hasFocus()) { + run_test() + } else { + window.onfocus = run_test; + } + } + + function run_test() { + document.getElementById("input1").focus(); // set the focus on input1 + testSelectorIdsMatch(":focus", ["input1"], "input1 has the focus"); + + document.getElementById("div1").focus(); + testSelectorIdsMatch(":focus", ["div1"], "tabindex attribute makes the element focusable"); + + document.getElementById("div2").focus(); + testSelectorIdsMatch(":focus", ["div2"], "editable elements are focusable"); + + document.body.focus(); + testSelectorIdsMatch(":focus", ["body"], "':focus' matches focussed body with tabindex"); + + document.getElementById("iframe").contentDocument.getElementById("inputiframe").focus(); + testSelectorIdsMatch(":focus", [], "':focus' doesn't match focused elements in iframe"); + + done(); + } + </script> +</body> diff --git a/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/indeterminate-radio.html b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/indeterminate-radio.html new file mode 100644 index 0000000000..4a7b2d6ece --- /dev/null +++ b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/indeterminate-radio.html @@ -0,0 +1,26 @@ +<!DOCTYPE HTML> +<meta charset="utf-8"> +<title>:indeterminate and input type=radio</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<style type="text/css"> +#test { + color: green; +} +input:indeterminate + #test { + color: red; +} +</style> +<input type="radio" name="radios"> +<div id="test"></div> +<input type="radio" name="radios" checked> +<script type="text/javascript"> +test(function() { + document.getElementsByTagName("input")[0].indeterminate = true; + var target = document.getElementById("test"); + var val = getComputedStyle(target, null).getPropertyValue("color"); + assert_equals(val, "rgb(0, 128, 0)", + "The indeterminate IDL attribute should not cause the " + + ":indeterminate pseudo-class to match on input type=radio"); +}) +</script> diff --git a/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/indeterminate-type-change.html b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/indeterminate-type-change.html new file mode 100644 index 0000000000..b3e4cce302 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/indeterminate-type-change.html @@ -0,0 +1,24 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Selector: pseudo-class :indeterminate input type change</title> +<link rel="author" title="Rune Lillesveen" href="mailto:rune@opera.com"> +<link rel="help" href="https://html.spec.whatwg.org/multipage/#pseudo-classes"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<style> + span { color: red } + :indeterminate + span { color: green } +</style> +<input id="indeterminate" type="text"> +<span id="sibling">This text should be green.</span> +<script> + test(() => { + assert_equals(getComputedStyle(sibling).color, "rgb(255, 0, 0)", + "Not matching :indeterminate for type=text"); + + indeterminate.type = "radio"; + + assert_equals(getComputedStyle(sibling).color, "rgb(0, 128, 0)", + "Matching :indeterminate for type=radio"); + }, "Evaluation of :indeterminate changes on input type change."); +</script> diff --git a/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/indeterminate.html b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/indeterminate.html new file mode 100644 index 0000000000..df04846676 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/indeterminate.html @@ -0,0 +1,37 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<title>Selector: pseudo-classes (:indeterminate)</title> +<link rel="author" title="Denis Ah-Kang" href="mailto:denis@w3.org" id=link1> +<link rel=help href="https://html.spec.whatwg.org/multipage/#pseudo-classes" id=link2> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="utils.js"></script> +<div id="log"></div> +<input type=checkbox id=checkbox1> +<input type=checkbox id=checkbox2> +<input type=radio id=radio1 checked> +<input type=radio name=radiogroup id=radio2> +<input type=radio name=radiogroup id=radio3> +<input type=radio name=group2 id=radio4> +<input type=radio name=group2 id=radio5> +<progress id="progress1"></progress> +<progress id="progress2" value=10></progress> + +<script> + testSelectorIdsMatch(":indeterminate", ["radio2", "radio3", "radio4", "radio5", "progress1"], "':progress' matches <input>s radio buttons whose radio button group contains no checked input and <progress> elements without value attribute"); + + document.getElementById("radio2").setAttribute("checked", "checked"); + testSelectorIdsMatch(":indeterminate", ["radio4", "radio5", "progress1"], "dynamically check a radio input in a radio button group"); + + document.getElementById("radio4").click(); + testSelectorIdsMatch(":indeterminate", ["progress1"], "click on radio4 which is in the indeterminate state"); + + document.getElementById("progress1").setAttribute("value", "20"); + testSelectorIdsMatch(":indeterminate", [], "adding a value to progress1 should put it in a determinate state"); + + document.getElementById("progress2").removeAttribute("value"); + testSelectorIdsMatch(":indeterminate", ["progress2"], "removing progress2's value should put it in an indeterminate state"); + + document.getElementById("checkbox1").indeterminate = true; // set checkbox1 in the indeterminate state + testSelectorIdsMatch(":indeterminate", ["checkbox1", "progress2"], "':progress' also matches <input> checkbox whose indeterminate IDL is set to true"); +</script> diff --git a/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/inrange-outofrange-type-change.html b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/inrange-outofrange-type-change.html new file mode 100644 index 0000000000..9c1be9ca27 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/inrange-outofrange-type-change.html @@ -0,0 +1,43 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Selector: pseudo-classes (:in-range, :out-of-range) input type change</title> +<link rel="author" title="Rune Lillesveen" href="mailto:rune@opera.com"> +<link rel="help" href="https://html.spec.whatwg.org/multipage/#pseudo-classes"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<style> + span { + color: red; + } + #t1:in-range + span { + color: green; + } + #t2:out-of-range + span { + color: green; + } +</style> +<input id="t1" type="text" min="0" max="10" value="5"> +<span id="sibling1">This text should be green.</span> +<input id="t2" type="text" min="0" max="10" value="50"> +<span id="sibling2">This text should be green.</span> +<script> + test(() => { + assert_equals(getComputedStyle(sibling1).color, "rgb(255, 0, 0)", + "Not matching :in-range for type=text"); + + t1.type = "number"; + + assert_equals(getComputedStyle(sibling1).color, "rgb(0, 128, 0)", + "Matching :in-range for type=number"); + }, "Evaluation of :in-range changes for input type change."); + + test(() => { + assert_equals(getComputedStyle(sibling2).color, "rgb(255, 0, 0)", + "Not matching :out-of-range for type=text"); + + t2.type = "number"; + + assert_equals(getComputedStyle(sibling2).color, "rgb(0, 128, 0)", + "Matching :in-range for type=number"); + }, "Evaluation of :out-of-range changes for input type change."); +</script> diff --git a/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/inrange-outofrange.html b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/inrange-outofrange.html new file mode 100644 index 0000000000..e9acbb3741 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/inrange-outofrange.html @@ -0,0 +1,84 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<title>Selector: pseudo-classes (:in-range, :out-of-range)</title> +<link rel="author" title="Denis Ah-Kang" href="mailto:denis@w3.org" id="link1"> +<link rel="author" title="Chris Rebert" href="http://chrisrebert.com" id="link2"> +<link rel="help" href="https://html.spec.whatwg.org/multipage/#selector-in-range" id="link3"> +<link rel="help" href="https://html.spec.whatwg.org/multipage/#selector-out-of-range" id="link4"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="utils.js"></script> +<div id="log"></div> +<input type=number value=0 min=0 max=10 id=number1> +<input type=number value=0 min=0 max=10 id=number2 disabled> +<input type=number value=0 min=1 max=10 id=number3> +<input type=number value=11 min=0 max=10 id=number4> +<input type=number value=0 min=0 max=10 id=number5 readonly> + +<input type="date" min="2005-10-10" max="2020-10-10" value="2010-10-10" id="datein"> +<input type="date" min="2010-10-10" max="2020-10-10" value="2005-10-10" id="dateunder"> +<input type="date" min="2010-10-10" max="2020-10-10" value="2030-10-10" id="dateover"> + +<input type="time" min="01:00:00" max="05:00:00" value="02:00:00" id="timein"> +<input type="time" min="02:00:00" max="05:00:00" value="01:00:00" id="timeunder"> +<input type="time" min="02:00:00" max="05:00:00" value="07:00:00" id="timeover"> + +<input type="week" min="2016-W05" max="2016-W10" value="2016-W07" id="weekin"> +<input type="week" min="2016-W05" max="2016-W10" value="2016-W02" id="weekunder"> +<input type="week" min="2016-W05" max="2016-W10" value="2016-W26" id="weekover"> + +<input type="month" min="2000-04" max="2000-09" value="2000-06" id="monthin"> +<input type="month" min="2000-04" max="2000-09" value="2000-02" id="monthunder"> +<input type="month" min="2000-04" max="2000-09" value="2000-11" id="monthover"> + +<input type="datetime-local" min="2008-03-12T23:59:59" max="2015-02-13T23:59:59" value="2012-11-28T23:59:59" id="datetimelocalin"> +<input type="datetime-local" min="2008-03-12T23:59:59" max="2015-02-13T23:59:59" value="2008-03-01T23:59:59" id="datetimelocalunder"> +<input type="datetime-local" min="2008-03-12T23:59:59" max="2015-02-13T23:59:59" value="2016-01-01T23:59:59" id="datetimelocalover"> + +<!-- None of the following have range limitations since they have neither min nor max attributes --> +<input type="number" value="0" id="numbernolimit"> +<input type="date" value="2010-10-10" id="datenolimit"> +<input type="time" value="02:00:00" id="timenolimit"> +<input type="week" value="2016-W07" id="weeknolimit"> +<input type="month" value="2000-06" id="monthnolimit"> +<input type="datetime-local" value="2012-11-28T23:59:59" id="datetimelocalnolimit"> + +<!-- range inputs have default minimum of 0 and default maximum of 100 --> +<input type="range" value="50" id="range0"> + +<!-- range input's value gets immediately clamped to the nearest boundary point --> +<input type="range" min="2" max="7" value="5" id="range1"> +<input type="range" min="2" max="7" value="1" id="range2"> +<input type="range" min="2" max="7" value="9" id="range3"> + +<!-- None of the following input types can have range limitations --> +<input min="1" value="0" type="text"> +<input min="1" value="0" type="search"> +<input min="1" value="0" type="url"> +<input min="1" value="0" type="tel"> +<input min="1" value="0" type="email"> +<input min="1" value="0" type="password"> +<input min="1" value="#000000" type="color"> +<input min="1" value="0" type="checkbox"> +<input min="1" value="0" type="radio"> +<input min="1" value="0" type="file"> +<input min="1" value="0" type="submit"> +<input min="1" value="0" type="image"> +<!-- The following types are also barred from constraint validation --> +<input min="1" value="0" type="hidden"> +<input min="1" value="0" type="button"> +<input min="1" value="0" type="reset"> + +<script> + testSelectorIdsMatch(":in-range", ["number1", "datein", "timein", "weekin", "monthin", "datetimelocalin", "range0", "range1", "range2", "range3"], "':in-range' matches all elements that are candidates for constraint validation, have range limitations, and that are neither suffering from an underflow nor suffering from an overflow"); + + testSelectorIdsMatch(":out-of-range", ["number3", "number4", "dateunder", "dateover", "timeunder", "timeover", "weekunder", "weekover", "monthunder", "monthover", "datetimelocalunder", "datetimelocalover"], "':out-of-range' matches all elements that are candidates for constraint validation, have range limitations, and that are either suffering from an underflow or suffering from an overflow"); + + document.getElementById("number1").value = -10; + testSelectorIdsMatch(":in-range", ["datein", "timein", "weekin", "monthin", "datetimelocalin", "range0", "range1", "range2", "range3"], "':in-range' update number1's value < min"); + testSelectorIdsMatch(":out-of-range", ["number1", "number3", "number4", "dateunder", "dateover", "timeunder", "timeover", "weekunder", "weekover", "monthunder", "monthover", "datetimelocalunder", "datetimelocalover"], "':out-of-range' update number1's value < min"); + + document.getElementById("number3").min = 0; + testSelectorIdsMatch(":in-range", ["number3", "datein", "timein", "weekin", "monthin", "datetimelocalin", "range0", "range1", "range2", "range3"], "':in-range' update number3's min < value"); + testSelectorIdsMatch(":out-of-range", ["number1", "number4", "dateunder", "dateover", "timeunder", "timeover", "weekunder", "weekover", "monthunder", "monthover", "datetimelocalunder", "datetimelocalover"], "':out-of-range' update number3's min < value"); +</script> diff --git a/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/invalid-after-clone.html b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/invalid-after-clone.html new file mode 100644 index 0000000000..92345602a8 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/invalid-after-clone.html @@ -0,0 +1,28 @@ +<!doctype html> +<meta charset="utf-8"> +<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io"> +<link rel="author" title="Mozilla" href="https://mozilla.org"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<input> +<textarea></textarea> +<script> +promise_test(async () => { + for (let tag of ["input", "textarea"]) { + let element = document.querySelector(tag); + await test_driver.send_keys(element, 'something'); + + assert_true(element.validity.valid, tag + ' should be valid'); + + element.maxLength = 0; + assert_true(element.matches(":invalid"), tag + ' should match :invalid'); + assert_false(element.validity.valid, tag + ' should be invalid'); + + let clone = element.cloneNode(true); + assert_true(clone.matches(":invalid"), tag + ' clone should match :invalid'); + assert_false(clone.validity.valid, tag + 'clone should be invalid'); + } +}, 'Cloned invalid inputs / textareas with interactive changes get their validity state copied correctly'); +</script> diff --git a/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/link.html b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/link.html new file mode 100644 index 0000000000..e9733eca70 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/link.html @@ -0,0 +1,21 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<title>Selector: pseudo-classes (:link)</title> +<link rel="author" title="Denis Ah-Kang" href="mailto:denis@w3.org" id=link1> +<link rel=help href="https://html.spec.whatwg.org/multipage/#pseudo-classes" id=link2> +<link rel=stylesheet href="non-existent.css" id=link3> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="utils.js"></script> +<div id="log"></div> +<a id=link4></a> +<area id=link5></area> +<link id=link6></link> +<a href="http://www.w3.org" id=link7></a> +<area href="http://www.w3.org" id=link8></area> +<link href="http://www.w3.org" id=link9></link> +<a href="http://[" id=link10></a> + +<script> + testSelectorIdsMatch(":link", ["link7", "link8", "link10"], "Only <a>s and <area>s that have a href attribute match ':link'"); +</script> diff --git a/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/placeholder-shown-type-change.html b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/placeholder-shown-type-change.html new file mode 100644 index 0000000000..206ae80c75 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/placeholder-shown-type-change.html @@ -0,0 +1,27 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Selector: pseudo-class :placeholder-shown input type change</title> +<link rel="author" title="Rune Lillesveen" href="mailto:rune@opera.com"> +<link rel="help" href="https://html.spec.whatwg.org/multipage/#pseudo-classes"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<style> + span { + color: red; + } + :placeholder-shown + span { + color: green; + } +</style> +<input id="input" type="submit" placeholder="placeholder"></input> +<span id="sibling">This text should be green.</span> +<script> + test(() => { + assert_equals(getComputedStyle(sibling).color, "rgb(255, 0, 0)", + "Not matching :placeholder-shown for type=submit"); + + input.type = "text"; + assert_equals(getComputedStyle(sibling).color, "rgb(0, 128, 0)", + "Matching :placeholder-shown for type=text"); + }, "Evaluation of :placeholder-shown changes for input type change."); +</script> diff --git a/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/readwrite-readonly-type-change.html b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/readwrite-readonly-type-change.html new file mode 100644 index 0000000000..90ef1d25d4 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/readwrite-readonly-type-change.html @@ -0,0 +1,36 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Selector: pseudo-classes (:read-write, :read-only) input type change</title> +<link rel="author" title="Rune Lillesveen" href="mailto:rune@opera.com"> +<link rel="help" href="https://html.spec.whatwg.org/multipage/#pseudo-classes"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<style> + span { + color: red; + background-color: pink; + } + :required + span { + color: green; + } + :not(:optional) + span { + background-color: lime; + } +</style> +<input id="hiddenInput" type="hidden" required> +<span id="sibling">This text should be green on lime background.</span> +<script> + test(() => { + assert_equals(getComputedStyle(sibling).color, "rgb(255, 0, 0)", + "Not matching :required for type=hidden"); + assert_equals(getComputedStyle(sibling).backgroundColor, "rgb(255, 192, 203)", + "Matching :optional for type=hidden"); + + hiddenInput.type = "text"; + + assert_equals(getComputedStyle(sibling).color, "rgb(0, 128, 0)", + "Matching :required for type=text"); + assert_equals(getComputedStyle(sibling).backgroundColor, "rgb(0, 255, 0)", + "Matching :not(:optional) for type=text"); + }, "Evaluation of :required and :optional changes for input type change."); +</script> diff --git a/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/readwrite-readonly.html b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/readwrite-readonly.html new file mode 100644 index 0000000000..fc112f3ceb --- /dev/null +++ b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/readwrite-readonly.html @@ -0,0 +1,100 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<title>Selector: pseudo-classes (:read-write, :read-only)</title> +<link rel=help href="https://html.spec.whatwg.org/multipage/#pseudo-classes" id=link2> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="utils.js"></script> +<div id="log"></div> + +<div id=set0> +<!-- The readonly attribute does not apply to the following input types --> +<input id=checkbox1 type=checkbox> +<input id=hidden1 type=hidden value=abc> +<input id=range1 type=range> +<input id=color1 type=color> +<input id=radio1 type=radio> +<input id=file1 type=file> +<input id=submit1 type=submit> +<input id=image1 type=image> +<input id=button1 type=button value="Button"> +<input id=reset1 type=reset> +</div> + +<div id=set1> +<input id=input1> +<input id=input2 readonly> +<input id=input3 disabled> +<input id=input4 type=checkbox> +<input id=input5 type=checkbox readonly> +</div> + +<div id=set2> +<textarea id=textarea1>textarea1</textarea> +<textarea readonly id=textarea2>textarea2</textarea> +</div> + +<div id=set3> +<textarea id=textarea3>textarea3</textarea> +<textarea disabled id=textarea4>textarea4</textarea> +</div> + +<div id=set4> +<p id=p1>paragraph1.</p> +<p id=p2 contenteditable>paragraph2.</p> +</div> + +<script> + testSelectorIdsMatch("#set0 :read-write", [], "The :read-write pseudo-class must not match input elements to which the readonly attribute does not apply"); + + testSelectorIdsMatch("#set0 :read-only", ["checkbox1", "hidden1", "range1", "color1", "radio1", "file1", "submit1", "image1", "button1", "reset1"], "The :read-only pseudo-class must match input elements to which the readonly attribute does not apply"); + + testSelectorIdsMatch("#set1 :read-write", ["input1"], "The :read-write pseudo-class must match input elements to which the readonly attribute applies, and that are mutable"); + + testSelectorIdsMatch("#set1 :read-only", ["input2", "input3", "input4", "input5"], "The :read-only pseudo-class must not match input elements to which the readonly attribute applies, and that are mutable"); + + document.getElementById("input1").setAttribute("readonly", "readonly"); + testSelectorIdsMatch("#set1 :read-write", [], "The :read-write pseudo-class must not match input elements after the readonly attribute has been added"); + + testSelectorIdsMatch("#set1 :read-only", ["input1", "input2", "input3", "input4", "input5"], "The :read-only pseudo-class must match input elements after the readonly attribute has been added"); + + document.getElementById("input1").removeAttribute("readonly"); + testSelectorIdsMatch("#set1 :read-write", ["input1"], "The :read-write pseudo-class must not match input elements after the readonly attribute has been removed"); + + testSelectorIdsMatch("#set1 :read-only", ["input2", "input3", "input4", "input5"], "The :read-only pseudo-class must match input elements after the readonly attribute has been removed"); + + document.getElementById("input1").disabled = true; + testSelectorIdsMatch("#set1 :read-write", [], "The :read-write pseudo-class must not match input elements after the disabled attribute has been added"); + + testSelectorIdsMatch("#set1 :read-only", ["input1", "input2", "input3", "input4", "input5"], "The :read-only pseudo-class must match input elements after the disabled attribute has been added"); + + document.getElementById("input1").disabled = false; + + testSelectorIdsMatch("#set1 :read-write", ["input1"], "The :read-write pseudo-class must match input elements after the disabled attribute has been removed"); + + testSelectorIdsMatch("#set1 :read-only", ["input2", "input3", "input4", "input5"], "The :read-only pseudo-class must not match input elements after the disabled attribute has been removed"); + + testSelectorIdsMatch("#set2 :read-write", ["textarea1"], "The :read-write pseudo-class must match textarea elements that do not have a readonly attribute, and that are not disabled"); + + testSelectorIdsMatch("#set2 :read-only", ["textarea2"], "The :read-only pseudo-class must match textarea elements that have a readonly attribute, or that are disabled"); + + document.getElementById("textarea1").setAttribute("readonly", "readonly"); + testSelectorIdsMatch("#set2 :read-write", [], "The :read-write pseudo-class must match textarea elements after the readonly attribute has been added"); + + testSelectorIdsMatch("#set2 :read-only", ["textarea1", "textarea2"], "The :read-only pseudo-class must match textarea elements after the readonly attribute has been added"); + + testSelectorIdsMatch("#set3 :read-write", ["textarea3"], "The :read-write pseudo-class must not match textarea elements that are disabled"); + + testSelectorIdsMatch("#set3 :read-only", ["textarea4"], "The :read-only pseudo-class must match textarea elements that are disabled"); + + testSelectorIdsMatch("#set4 :read-write", ["p2"], "The :read-write pseudo-class must match elements that are editable"); + + testSelectorIdsMatch("#set4 :read-only", ["p1"], "The :read-only pseudo-class must not match elements that are editable"); + + document.designMode = "on"; + + testSelectorIdsMatch("#set4 :read-write", ["p1", "p2"], "The :read-write pseudo-class must match elements that are editing hosts"); + + testSelectorIdsMatch("#set4 :read-only", [], "The :read-only pseudo-class must not match elements that are editing hosts"); + +</script> diff --git a/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/required-optional-hidden.html b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/required-optional-hidden.html new file mode 100644 index 0000000000..fe3d6e2f42 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/required-optional-hidden.html @@ -0,0 +1,36 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Selector: pseudo-classes (:required, :optional) for hidden input</title> +<link rel="author" title="Rune Lillesveen" href="mailto:rune@opera.com"> +<link rel="help" href="https://html.spec.whatwg.org/multipage/#pseudo-classes"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<style> + span { + color: red; + background-color: pink; + } + :required + span { + color: green; + } + :not(:optional) + span { + background-color: lime; + } +</style> +<input id="hiddenInput" type="hidden" required> +<span id="sibling">This text should be green on lime background.</span> +<script> + test(() => { + assert_equals(getComputedStyle(sibling).color, "rgb(255, 0, 0)", + "Not matching :required for type=hidden"); + assert_equals(getComputedStyle(sibling).backgroundColor, "rgb(255, 192, 203)", + "Matching :optional for type=hidden"); + + hiddenInput.type = "text"; + + assert_equals(getComputedStyle(sibling).color, "rgb(0, 128, 0)", + "Matching :required for type=text"); + assert_equals(getComputedStyle(sibling).backgroundColor, "rgb(0, 255, 0)", + "Matching :not(:optional) for type=text"); + }, "Evaluation of :required and :optional changes for input type change."); +</script> diff --git a/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/required-optional.html b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/required-optional.html new file mode 100644 index 0000000000..f06fdfa1e0 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/required-optional.html @@ -0,0 +1,35 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<title>Selector: pseudo-classes (:required, :optional)</title> +<link rel="author" title="Denis Ah-Kang" href="mailto:denis@w3.org" id=link1> +<link rel=help href="https://html.spec.whatwg.org/multipage/#pseudo-classes" id=link2> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="utils.js"></script> +<div id="log"></div> +<input type=text id=text1 value="foobar" required> +<input type=text id=text2 required> +<input type=text id=text3> +<select id=select1 required> + <optgroup label="options" id=optgroup1> + <option value="option1" id=option1>option1 +</select> +<select id=select2> + <optgroup label="options" id=optgroup2> + <option value="option2" id=option2>option2 +</select> +<textarea required id=textarea1>textarea1</textarea> +<textarea id=textarea2>textarea2</textarea> + +<script> + testSelectorIdsMatch(":required", ["text1", "text2", "select1", "textarea1"], "':required' matches required <input>s, <select>s and <textarea>s"); + testSelectorIdsMatch(":optional", ["text3", "select2", "textarea2"], "':optional' matches elements <input>s, <select>s and <textarea>s that are not required"); + + document.getElementById("text1").removeAttribute("required"); + testSelectorIdsMatch(":required", ["text2", "select1", "textarea1"], "':required' doesn't match elements whose required attribute has been removed"); + testSelectorIdsMatch(":optional", ["text1", "text3", "select2", "textarea2"], "':optional' matches elements whose required attribute has been removed"); + + document.getElementById("select2").setAttribute("required", "required"); + testSelectorIdsMatch(":required", ["text2", "select1", "select2", "textarea1"], "':required' matches elements whose required attribute has been added"); + testSelectorIdsMatch(":optional", ["text1", "text3", "textarea2"], "':optional' doesn't match elements whose required attribute has been added"); +</script> diff --git a/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/utils.js b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/utils.js new file mode 100644 index 0000000000..7a2fb77f10 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/utils.js @@ -0,0 +1,20 @@ +function getElementsByIds(ids) { + var result = []; + ids.forEach(function(id) { + result.push(document.getElementById(id)); + }); + return result; +} + +function testSelectorIdsMatch(selector, ids, testName) { + test(function(){ + var elements = document.querySelectorAll(selector); + assert_array_equals([...elements], getElementsByIds(ids)); + }, testName); +} + +function testSelectorElementsMatch(selector, elements, testName) { + test(function(){ + assert_array_equals([...document.querySelectorAll(selector)], elements); + }, testName); +} diff --git a/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/valid-invalid-fieldset-disconnected.html b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/valid-invalid-fieldset-disconnected.html new file mode 100644 index 0000000000..6ad329438a --- /dev/null +++ b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/valid-invalid-fieldset-disconnected.html @@ -0,0 +1,57 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<title>Selector: pseudo-classes (:valid, :invalid) on disconnected fieldset element</title> +<link rel=help href="https://html.spec.whatwg.org/multipage/semantics-other.html#selector-valid"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<fieldset id=fieldset1> + <input id=input1> +</fieldset> + +<fieldset id=fieldset2> + <select id=select1 required multiple> + <option>foo + </select> +</fieldset> + +<script> +test(() => { + const fieldset = document.querySelector("#fieldset1"); + const input = document.querySelector("#input1"); + + assert_true(fieldset.matches(":valid")); + assert_false(fieldset.matches(":invalid")); + + fieldset.remove(); + input.setCustomValidity("foo"); + + assert_false(fieldset.matches(":valid")); + assert_true(fieldset.matches(":invalid")); + + input.setCustomValidity(""); + + assert_true(fieldset.matches(":valid")); + assert_false(fieldset.matches(":invalid")); +}, "<input> element becomes invalid inside disconnected <fieldset>"); + +test(() => { + const fieldset = document.querySelector("#fieldset2"); + const select = document.querySelector("#select1"); + + assert_false(fieldset.matches(":valid")); + assert_true(fieldset.matches(":invalid")); + + fieldset.remove(); + select.required = false; + + assert_true(fieldset.matches(":valid")); + assert_false(fieldset.matches(":invalid")); + + select.required = true; + select.firstElementChild.selected = true; + + assert_true(fieldset.matches(":valid")); + assert_false(fieldset.matches(":invalid")); +}, "<select> element becomes valid inside disconnected <fieldset>"); +</script> diff --git a/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/valid-invalid.html b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/valid-invalid.html new file mode 100644 index 0000000000..d93407707f --- /dev/null +++ b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/valid-invalid.html @@ -0,0 +1,146 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset=utf-8> +<title>Selector: pseudo-classes (:valid, :invalid)</title> +<link rel="author" title="Denis Ah-Kang" href="mailto:denis@w3.org" id=link1> +<link rel=help href="https://html.spec.whatwg.org/multipage/#pseudo-classes" id=link2> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="utils.js"></script> +<style> + #styleTests form, #styleTests fieldset, #failExample { background-color:red; } + #styleTests > :valid, #validExample { background-color:green; } + #styleTests > :invalid, #invalidExample { background-color:lime; } +</style> +</head> +<body> +<div id="log"></div> +<div id='simpleConstraints'> + <input type=text id=text1 value="foobar" required> + <input type=text id=text2 required> +</div> +<div id='FormSelection'> + <form id=form1> + <input type=text id=text3 value="foobar" required> + </form> + <form id=form2> + <input type=text id=text4 required> + </form> +</div> +<div id='FieldSetSelection'> + <fieldset id=fieldset1> + <input type=text id=text5 value="foobar" required> + </fieldset> + <fieldset id=fieldset2> + <input type=text id=text6 required> + </fieldset> +</div> +<div id='patternConstraints'> + <input type=text id=text7 value="AAA" pattern="[0-9][A-Z]{3}"> + <input type=text id=text8 value="0AAA" pattern="[0-9][A-Z]{3}"> +</div> +<div id='numberConstraints'> + <input type=number id=number1 value=0 min=1> + <input type=number id=number2 value=1 min=1> +</div> +<div id='styleTests'> + <form> + </form> + <form> + <input type=text min=8 value=4> + </form> + <form> + <input type=number min=8 value=4> + </form> + <fieldset> + </fieldset> + <fieldset> + <input type=text min=8 value=4> + </fieldset> + <fieldset> + <input type=number min=8 value=4> + </fieldset> + <div id='validExample'></div> + <div id='invalidExample'></div> + <div id='failExample'></div> +</div> +<script> + testSelectorIdsMatch("#simpleConstraints :valid", ["text1"], "':valid' matches elements that satisfy their constraints"); + + testSelectorIdsMatch("#FormSelection :valid", ["form1", "text3"], "':valid' matches form elements that are not the form owner of any elements that themselves are candidates for constraint validation but do not satisfy their constraints"); + + testSelectorIdsMatch("#FieldSetSelection :valid", ["fieldset1", "text5"], "':valid' matches fieldset elements that have no descendant elements that themselves are candidates for constraint validation but do not satisfy their constraints"); + + testSelectorIdsMatch("#patternConstraints :valid", [ "text8" ], "':valid' matches elements that satisfy their pattern constraints"); + + testSelectorIdsMatch("#numberConstraints :valid", [ "number2" ], "':valid' matches elements that satisfy their number constraints"); + + + testSelectorIdsMatch("#simpleConstraints :invalid", ["text2"], "':invalid' matches elements that do not satisfy their simple text constraints"); + + testSelectorIdsMatch("#FormSelection :invalid", ["form2", "text4"], "':invalid' matches form elements that are the form owner of one or more elements that themselves are candidates for constraint validation but do not satisfy their constraints"); + + testSelectorIdsMatch("#FieldSetSelection :invalid", ["fieldset2", "text6"], "':invalid' matches fieldset elements that have of one or more descendant elements that themselves are candidates for constraint validation but do not satisfy their constraints"); + + testSelectorIdsMatch("#patternConstraints :invalid", ["text7"], "':invalid' matches elements that do not satisfy their pattern constraints"); + + testSelectorIdsMatch("#numberConstraints :invalid", ["number1"], "':invalid' matches elements that do not satisfy their number constraints"); + + document.getElementById("text7").value="0BBB"; + testSelectorIdsMatch("#patternConstraints :valid", [ "text7", "text8" ], "':valid' matches new elements that satisfy their constraints"); + testSelectorIdsMatch("#patternConstraints :invalid", [], "':invalid' doesn't match new elements that satisfy their constraints"); + + document.getElementById("text8").value="BBB"; + testSelectorIdsMatch("#patternConstraints :valid", ["text7"], "':valid' doesn't match new elements that do not satisfy their constraints"); + testSelectorIdsMatch("#patternConstraints :invalid", ["text8"], "':invalid' matches new elements that do not satisfy their constraints"); + + function getBGColor(elem) { + return getComputedStyle(elem).backgroundColor; + } + + function testStyles(type) { + var elems = document.querySelectorAll("#styleTests " + type), + empty = elems[0], + valid = elems[1], + invalid = elems[2], + validInput = valid.querySelector("input"), + invalidInput = invalid.querySelector("input"), + expectedValidBGColor = getBGColor(document.getElementById("validExample")), + expectedInvalidBGColor = getBGColor(document.getElementById("invalidExample")), + expectedFailBGColor = getBGColor(document.getElementById("failExample")); + + test(function() { + assert_equals(getBGColor(empty), expectedValidBGColor, "wrong background-color"); + }, 'empty ' + type + ' correctly styled on page-load'); + + test(function() { + assert_equals(getBGColor(valid), expectedValidBGColor, "wrong background-color"); + }, 'valid ' + type + ' correctly styled on page-load'); + test(function() { + assert_equals(getBGColor(invalid), expectedInvalidBGColor, "wrong background-color"); + }, 'invalid ' + type + ' correctly styled on page-load'); + + test(function() { + empty.appendChild(validInput.cloneNode()); + assert_equals(getBGColor(empty), expectedValidBGColor, "wrong background-color"); + }, 'programmatically adding valid to empty ' + type + ' results in correct style'); + test(function() { + empty.appendChild(invalidInput.cloneNode()); + assert_equals(getBGColor(empty), expectedInvalidBGColor, "wrong background-color"); + }, 'programmatically adding invalid to empty ' + type + ' results in correct style'); + + validInput.type = "number"; + invalidInput.type = "text"; + test(function() { + assert_equals(getBGColor(valid), expectedInvalidBGColor, "wrong background-color"); + }, 'programmatically-invalidated ' + type + ' correctly styled'); + test(function() { + assert_equals(getBGColor(invalid), expectedValidBGColor, "wrong background-color"); + }, 'programmatically-validated ' + type + ' correctly styled'); + } + test(testStyles.bind(undefined, "form"), ":valid/:invalid styling for <form>"); + test(testStyles.bind(undefined, "fieldset"), ":valid/:invalid styling for <fieldset>"); +</script> +</body> +</html> |