Auto merge of #7965 - frewsxcv:labelable-elements-label-attribute, r=nox

Implement 'labels' attribute on 'labelable elements'



<!-- Reviewable:start -->
[<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/7965)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2015-11-01 20:51:18 +05:30
commit 0e70a1f8a8
22 changed files with 184 additions and 63 deletions

View file

@ -4968,9 +4968,6 @@
[HTMLInputElement interface: operation setCustomValidity(DOMString)]
expected: FAIL
[HTMLInputElement interface: attribute labels]
expected: FAIL
[HTMLInputElement interface: operation select()]
expected: FAIL
@ -5103,9 +5100,6 @@
[HTMLInputElement interface: calling setCustomValidity(DOMString) on document.createElement("input") with too few arguments must throw TypeError]
expected: FAIL
[HTMLInputElement interface: document.createElement("input") must inherit property "labels" with the proper type (48)]
expected: FAIL
[HTMLInputElement interface: document.createElement("input") must inherit property "select" with the proper type (49)]
expected: FAIL
@ -5169,9 +5163,6 @@
[HTMLButtonElement interface: operation setCustomValidity(DOMString)]
expected: FAIL
[HTMLButtonElement interface: attribute labels]
expected: FAIL
[HTMLButtonElement interface: document.createElement("button") must inherit property "autofocus" with the proper type (0)]
expected: FAIL
@ -5199,9 +5190,6 @@
[HTMLButtonElement interface: calling setCustomValidity(DOMString) on document.createElement("button") with too few arguments must throw TypeError]
expected: FAIL
[HTMLButtonElement interface: document.createElement("button") must inherit property "labels" with the proper type (18)]
expected: FAIL
[HTMLSelectElement interface: existence and properties of interface object]
expected: FAIL
@ -5256,9 +5244,6 @@
[HTMLSelectElement interface: operation setCustomValidity(DOMString)]
expected: FAIL
[HTMLSelectElement interface: attribute labels]
expected: FAIL
[HTMLSelectElement interface: document.createElement("select") must inherit property "autocomplete" with the proper type (0)]
expected: FAIL
@ -5313,9 +5298,6 @@
[HTMLSelectElement interface: calling setCustomValidity(DOMString) on document.createElement("select") with too few arguments must throw TypeError]
expected: FAIL
[HTMLSelectElement interface: document.createElement("select") must inherit property "labels" with the proper type (26)]
expected: FAIL
[HTMLDataListElement interface: existence and properties of interface object]
expected: FAIL
@ -5385,9 +5367,6 @@
[HTMLTextAreaElement interface: operation setCustomValidity(DOMString)]
expected: FAIL
[HTMLTextAreaElement interface: attribute labels]
expected: FAIL
[HTMLTextAreaElement interface: operation select()]
expected: FAIL
@ -5451,9 +5430,6 @@
[HTMLTextAreaElement interface: calling setCustomValidity(DOMString) on document.createElement("textarea") with too few arguments must throw TypeError]
expected: FAIL
[HTMLTextAreaElement interface: document.createElement("textarea") must inherit property "labels" with the proper type (25)]
expected: FAIL
[HTMLTextAreaElement interface: document.createElement("textarea") must inherit property "select" with the proper type (26)]
expected: FAIL
@ -5622,9 +5598,6 @@
[HTMLOutputElement interface: operation setCustomValidity(DOMString)]
expected: FAIL
[HTMLOutputElement interface: attribute labels]
expected: FAIL
[HTMLOutputElement interface: document.createElement("output") must inherit property "htmlFor" with the proper type (0)]
expected: FAIL
@ -5658,9 +5631,6 @@
[HTMLOutputElement interface: calling setCustomValidity(DOMString) on document.createElement("output") with too few arguments must throw TypeError]
expected: FAIL
[HTMLOutputElement interface: document.createElement("output") must inherit property "labels" with the proper type (12)]
expected: FAIL
[HTMLProgressElement interface: existence and properties of interface object]
expected: FAIL
@ -5673,9 +5643,6 @@
[HTMLProgressElement interface: attribute position]
expected: FAIL
[HTMLProgressElement interface: attribute labels]
expected: FAIL
[HTMLProgressElement interface: document.createElement("progress") must inherit property "value" with the proper type (0)]
expected: FAIL
@ -5685,9 +5652,6 @@
[HTMLProgressElement interface: document.createElement("progress") must inherit property "position" with the proper type (2)]
expected: FAIL
[HTMLProgressElement interface: document.createElement("progress") must inherit property "labels" with the proper type (3)]
expected: FAIL
[HTMLMeterElement interface: existence and properties of interface object]
expected: FAIL
@ -5709,9 +5673,6 @@
[HTMLMeterElement interface: attribute optimum]
expected: FAIL
[HTMLMeterElement interface: attribute labels]
expected: FAIL
[HTMLMeterElement interface: document.createElement("meter") must inherit property "value" with the proper type (0)]
expected: FAIL
@ -5730,9 +5691,6 @@
[HTMLMeterElement interface: document.createElement("meter") must inherit property "optimum" with the proper type (5)]
expected: FAIL
[HTMLMeterElement interface: document.createElement("meter") must inherit property "labels" with the proper type (6)]
expected: FAIL
[HTMLFieldSetElement interface: existence and properties of interface object]
expected: FAIL

View file

@ -3,12 +3,3 @@
[A non-control follows by a control with same ID.]
expected: FAIL
[A form control has multiple labels.]
expected: FAIL
[A form control has no label 1.]
expected: FAIL
[A form control has no label 2.]
expected: FAIL

View file

@ -3,3 +3,6 @@
[Check if the keygen element is a labelable element]
expected: FAIL
[Check if the keygen element can access 'labels']
expected: FAIL

View file

@ -53,6 +53,7 @@
"A label element not in a document should not label an element in a document.");
document.body.appendChild(label);
assert_equals(label.control, document.getElementById("test1"));
label.remove();
}, "A label element not in a document can not label any element in the document.");
test(function () {
@ -63,6 +64,7 @@
document.getElementById("lbl1").insertBefore(input, document.getElementById("test2"));
assert_equals(document.getElementById("lbl1").control, input,
"The first labelable descendant of a label element in tree order should be its labeled control.");
input.remove();
}, "The labeled control for a label element that has no 'for' attribute is the first labelable element which is a descendant of that label element.");
test(function () {
@ -95,12 +97,19 @@
document.getElementById("fm").insertBefore(newLabel, document.getElementById("lbl0"));
assert_array_equals(document.getElementById("test7").labels, [newLabel, document.getElementById("lbl5"), document.getElementById("lbl6")],
"The labels for a form control should be returned in tree order.");
newLabel.remove();
}, "A form control has multiple labels.");
test(function () {
var labels = document.getElementById("test3").labels;
assert_true(labels instanceof NodeList, "A form control's 'labels' property should be an instance of a NodeList.");
assert_equals(labels.length, 1, "The form control has an ancestor with no explicit associated label, and is the first labelable descendant.");
}, "A form control has an implicit label.");
test(function () {
var labels = document.getElementById("test4").labels;
assert_true(labels instanceof NodeList, "A form control's 'labels' property should be an instance of a NodeList.");
assert_equals(labels.length, 0, "The number of labels should be 0 if the associated form control isn't referenced by any <label>.");
assert_equals(labels.length, 0, "The form control has an ancestor with no explicit associated label, but is *not* the first labelable descendant");
}, "A form control has no label 1.");
test(function () {

View file

@ -36,61 +36,121 @@
</form>
<script>
function testLabelsAttr(formElementId, labelElementId, hasLabels) {
var elem = document.getElementById(formElementId);
if (labelElementId) {
assert_equals(elem.labels.length, 1);
assert_equals(elem.labels[0].id, labelElementId);
} else {
assert_equals(elem.labels.length, 0);
}
}
test(function() {
assert_equals(document.getElementById("lbl0").control.id, "testoutput", "An output element should be labelable.");
}, "Check if the output element is a labelable element");
test(function() {
testLabelsAttr("testoutput", "lbl0");
}, "Check if the output element can access 'labels'");
test(function() {
assert_equals(document.getElementById("lbl1").control.id, "testprogress", "A progress element should be labelable.");
}, "Check if the progress element is a labelable element");
test(function() {
testLabelsAttr("testprogress", "lbl1");
}, "Check if the progress element can access 'labels'");
test(function() {
assert_equals(document.getElementById("lbl2").control.id, "testselect", "A select element should be labelable.");
}, "Check if the select element is a labelable element");
test(function() {
testLabelsAttr("testselect", "lbl2");
}, "Check if the select element can access 'labels'");
test(function() {
assert_equals(document.getElementById("lbl3").control.id, "testarea", "A textarea element should be labelable.");
}, "Check if the textarea element is a labelable form-element");
test(function() {
testLabelsAttr("testarea", "lbl3");
}, "Check if the textarea element can access 'labels'");
test(function() {
assert_equals(document.getElementById("lbl4").control.id, "testButton", "A button element should be labelable.");
}, "Check if the button element is a labelable element");
test(function() {
testLabelsAttr("testButton", "lbl4");
}, "Check if the button element can access 'labels'");
test(function() {
assert_equals(document.getElementById("lbl5").control, null, "An input element in hidden state should not be labelable.");
}, "Check if the hidden input element is not a labelable element.");
test(function() {
testLabelsAttr("testHidden", null);
}, "Check if the hidden input element can access 'labels'");
test(function() {
assert_equals(document.getElementById("lbl6").control.id, "testRadio", "An input element in radio state should be labelable.");
}, "Check if the input element in radio state is a labelable element");
test(function() {
testLabelsAttr("testRadio", "lbl6");
}, "Check if the input element in radio state can access 'labels'");
test(function() {
assert_equals(document.getElementById("lbl7").control.id, "testkeygen", "A keygen element should be labelable.");
}, "Check if the keygen element is a labelable element");
test(function() {
testLabelsAttr("testkeygen", "lbl7");
}, "Check if the keygen element can access 'labels'");
test(function() {
assert_equals(document.getElementById("lbl8").control.id, "testmeter", "A meter element should be labelable.");
}, "Check if the meter element is a labelable element");
test(function() {
testLabelsAttr("testmeter", "lbl8");
}, "Check if the meter element can access 'labels'");
test(function() {
assert_not_equals(document.getElementById("lbl9").control, document.getElementById("testfieldset"));
assert_equals(document.getElementById("lbl9").control, null, "A fieldset element should not be labelable.");
}, "Check if the fieldset element is not a labelable element");
test(function() {
assert_equals(document.getElementById("testfieldset").labels, undefined);
}, "Check if the fieldset element can access 'labels'");
test(function() {
assert_not_equals(document.getElementById("lbl9").control, document.getElementById("testlabel"));
assert_equals(document.getElementById("lbl10").control, null, "A label element should not be labelable.");
}, "Check if the label element is not a labelable element");
test(function() {
assert_equals(document.getElementById("testlabel").labels, undefined);
}, "Check if the label element can access 'labels'");
test(function() {
assert_not_equals(document.getElementById("lbl9").control, document.getElementById("testobject"));
assert_equals(document.getElementById("lbl11").control, null, "An object element should not be labelable.");
}, "Check if the object element is not a labelable element");
test(function() {
assert_equals(document.getElementById("testobject").labels, undefined);
}, "Check if the object element can access 'labels'");
test(function() {
assert_not_equals(document.getElementById("lbl9").control, document.getElementById("testimg"));
assert_equals(document.getElementById("lbl12").control, null, "An img element should not be labelable.");
}, "Check if the img element is not a labelable element");
test(function() {
assert_equals(document.getElementById("lbl9").labels, undefined);
}, "Check if the img element can access 'labels'");
</script>