() && n.local_name() == atom)
+ .and_then(|n| n.downcast().map(Root::from_ref))
+ }
+
+ // https://html.spec.whatwg.org/multipage/#dom-table-thead
+ // https://html.spec.whatwg.org/multipage/#dom-table-tfoot
+ fn set_first_section_of_type(&self,
+ atom: &Atom,
+ section: Option<&HTMLTableSectionElement>,
+ reference_predicate: P)
+ -> ErrorResult
+ where P: FnMut(&Root) -> bool {
+ if let Some(e) = section {
+ if e.upcast::().local_name() != atom {
+ return Err(Error::HierarchyRequest)
+ }
+ }
+
+ self.delete_first_section_of_type(atom);
+
+ let node = self.upcast::();
+
+ if let Some(section) = section {
+ let reference_element = node.child_elements().find(reference_predicate);
+ let reference_node = reference_element.r().map(|e| e.upcast());
+
+ try!(node.InsertBefore(section.upcast(), reference_node));
+ }
+
+ Ok(())
+ }
+
+ // https://html.spec.whatwg.org/multipage/#dom-table-createthead
+ // https://html.spec.whatwg.org/multipage/#dom-table-createtfoot
+ fn create_section_of_type(&self, atom: &Atom) -> Root {
+ if let Some(section) = self.get_first_section_of_type(atom) {
+ return section
+ }
+
+ let section = HTMLTableSectionElement::new(atom.clone(),
+ None,
+ document_from_node(self).r());
+ match atom {
+ &atom!("thead") => self.SetTHead(Some(§ion)),
+ &atom!("tfoot") => self.SetTFoot(Some(§ion)),
+ _ => unreachable!("unexpected section type")
+ }.expect("unexpected section type");
+
+ section
+ }
+
+ // https://html.spec.whatwg.org/multipage/#dom-table-deletethead
+ // https://html.spec.whatwg.org/multipage/#dom-table-deletetfoot
+ fn delete_first_section_of_type(&self, atom: &Atom) {
+ if let Some(thead) = self.get_first_section_of_type(atom) {
+ thead.upcast::().remove_self();
+ }
+ }
}
impl HTMLTableElementMethods for HTMLTableElement {
@@ -119,6 +187,83 @@ impl HTMLTableElementMethods for HTMLTableElement {
}
}
+
+ // https://html.spec.whatwg.org/multipage/#dom-table-thead
+ fn GetTHead(&self) -> Option> {
+ self.get_first_section_of_type(&atom!("thead"))
+ }
+
+ // https://html.spec.whatwg.org/multipage/#dom-table-thead
+ fn SetTHead(&self, thead: Option<&HTMLTableSectionElement>) -> ErrorResult {
+ self.set_first_section_of_type(&atom!("thead"), thead, |n| {
+ !n.is::() && !n.is::()
+ })
+ }
+
+ // https://html.spec.whatwg.org/multipage/#dom-table-createthead
+ fn CreateTHead(&self) -> Root {
+ self.create_section_of_type(&atom!("thead"))
+ }
+
+ // https://html.spec.whatwg.org/multipage/#dom-table-deletethead
+ fn DeleteTHead(&self) {
+ self.delete_first_section_of_type(&atom!("thead"))
+ }
+
+ // https://html.spec.whatwg.org/multipage/#dom-table-tfoot
+ fn GetTFoot(&self) -> Option> {
+ self.get_first_section_of_type(&atom!("tfoot"))
+ }
+
+ // https://html.spec.whatwg.org/multipage/#dom-table-tfoot
+ fn SetTFoot(&self, tfoot: Option<&HTMLTableSectionElement>) -> ErrorResult {
+ self.set_first_section_of_type(&atom!("tfoot"), tfoot, |n| {
+ if n.is::() || n.is::() {
+ return false;
+ }
+
+ if n.is::() {
+ let name = n.local_name();
+ if name == &atom!("thead") || name == &atom!("tbody") {
+ return false;
+ }
+
+ }
+
+ true
+ })
+ }
+
+ // https://html.spec.whatwg.org/multipage/#dom-table-createtfoot
+ fn CreateTFoot(&self) -> Root {
+ self.create_section_of_type(&atom!("tfoot"))
+ }
+
+ // https://html.spec.whatwg.org/multipage/#dom-table-deletetfoot
+ fn DeleteTFoot(&self) {
+ self.delete_first_section_of_type(&atom!("tfoot"))
+ }
+
+ // https://html.spec.whatwg.org/multipage/#dom-table-tbodies
+ fn TBodies(&self) -> Root {
+ #[derive(JSTraceable)]
+ struct TBodiesFilter;
+ impl CollectionFilter for TBodiesFilter {
+ fn filter(&self, elem: &Element, root: &Node) -> bool {
+ elem.is::()
+ && elem.local_name() == &atom!("tbody")
+ && elem.upcast::().GetParentNode().r() == Some(root)
+ }
+ }
+
+ self.tbodies.or_init(|| {
+ let window = window_from_node(self);
+ let filter = box TBodiesFilter;
+ HTMLCollection::create(window.r(), self.upcast(), filter)
+ })
+ }
+
+
// https://html.spec.whatwg.org/multipage/#dom-table-createtbody
fn CreateTBody(&self) -> Root {
let tbody = HTMLTableSectionElement::new(atom!("tbody"),
diff --git a/components/script/dom/webidls/HTMLTableElement.webidl b/components/script/dom/webidls/HTMLTableElement.webidl
index 2697f4c1e931..af95685b5b59 100644
--- a/components/script/dom/webidls/HTMLTableElement.webidl
+++ b/components/script/dom/webidls/HTMLTableElement.webidl
@@ -8,13 +8,15 @@ interface HTMLTableElement : HTMLElement {
attribute HTMLTableCaptionElement? caption;
HTMLElement createCaption();
void deleteCaption();
- // attribute HTMLTableSectionElement? tHead;
- //HTMLElement createTHead();
- //void deleteTHead();
- // attribute HTMLTableSectionElement? tFoot;
- //HTMLElement createTFoot();
- //void deleteTFoot();
- //readonly attribute HTMLCollection tBodies;
+ [SetterThrows]
+ attribute HTMLTableSectionElement? tHead;
+ HTMLTableSectionElement createTHead();
+ void deleteTHead();
+ [SetterThrows]
+ attribute HTMLTableSectionElement? tFoot;
+ HTMLTableSectionElement createTFoot();
+ void deleteTFoot();
+ readonly attribute HTMLCollection tBodies;
HTMLTableSectionElement createTBody();
readonly attribute HTMLCollection rows;
//HTMLElement insertRow(optional long index = -1);
diff --git a/tests/wpt/metadata/MANIFEST.json b/tests/wpt/metadata/MANIFEST.json
index 02e777e3aa77..213cb9b5e5c0 100644
--- a/tests/wpt/metadata/MANIFEST.json
+++ b/tests/wpt/metadata/MANIFEST.json
@@ -35059,7 +35059,22 @@
},
"local_changes": {
"deleted": [],
- "items": {},
+ "items": {
+ "testharness": {
+ "html/semantics/tabular-data/the-table-element/tFoot.html": [
+ {
+ "path": "html/semantics/tabular-data/the-table-element/tFoot.html",
+ "url": "/html/semantics/tabular-data/the-table-element/tFoot.html"
+ }
+ ],
+ "html/semantics/tabular-data/the-table-element/tHead.html": [
+ {
+ "path": "html/semantics/tabular-data/the-table-element/tHead.html",
+ "url": "/html/semantics/tabular-data/the-table-element/tHead.html"
+ }
+ ]
+ }
+ },
"reftest_nodes": {}
},
"reftest_nodes": {
diff --git a/tests/wpt/metadata/dom/nodes/getElementsByClassName-20.htm.ini b/tests/wpt/metadata/dom/nodes/getElementsByClassName-20.htm.ini
deleted file mode 100644
index b3ae75b2960a..000000000000
--- a/tests/wpt/metadata/dom/nodes/getElementsByClassName-20.htm.ini
+++ /dev/null
@@ -1,5 +0,0 @@
-[getElementsByClassName-20.htm]
- type: testharness
- [get elements in document then add element to collection]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/dom/nodes/getElementsByClassName-22.htm.ini b/tests/wpt/metadata/dom/nodes/getElementsByClassName-22.htm.ini
deleted file mode 100644
index edb0b18eec8b..000000000000
--- a/tests/wpt/metadata/dom/nodes/getElementsByClassName-22.htm.ini
+++ /dev/null
@@ -1,5 +0,0 @@
-[getElementsByClassName-22.htm]
- type: testharness
- [move item in collection order]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/dom/nodes/getElementsByClassName-25.htm.ini b/tests/wpt/metadata/dom/nodes/getElementsByClassName-25.htm.ini
deleted file mode 100644
index b75ced052c31..000000000000
--- a/tests/wpt/metadata/dom/nodes/getElementsByClassName-25.htm.ini
+++ /dev/null
@@ -1,5 +0,0 @@
-[getElementsByClassName-25.htm]
- type: testharness
- [verify spacing is handled correctly]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/html/dom/interfaces.html.ini b/tests/wpt/metadata/html/dom/interfaces.html.ini
index ba5f8cadb8f0..9b2d7668ea7f 100644
--- a/tests/wpt/metadata/html/dom/interfaces.html.ini
+++ b/tests/wpt/metadata/html/dom/interfaces.html.ini
@@ -4152,27 +4152,6 @@
[HTMLAreaElement interface: document.createElement("area") must inherit property "noHref" with the proper type (10)]
expected: FAIL
- [HTMLTableElement interface: attribute tHead]
- expected: FAIL
-
- [HTMLTableElement interface: operation createTHead()]
- expected: FAIL
-
- [HTMLTableElement interface: operation deleteTHead()]
- expected: FAIL
-
- [HTMLTableElement interface: attribute tFoot]
- expected: FAIL
-
- [HTMLTableElement interface: operation createTFoot()]
- expected: FAIL
-
- [HTMLTableElement interface: operation deleteTFoot()]
- expected: FAIL
-
- [HTMLTableElement interface: attribute tBodies]
- expected: FAIL
-
[HTMLTableElement interface: operation insertRow(long)]
expected: FAIL
@@ -4206,27 +4185,6 @@
[HTMLTableElement interface: attribute cellSpacing]
expected: FAIL
- [HTMLTableElement interface: document.createElement("table") must inherit property "tHead" with the proper type (3)]
- expected: FAIL
-
- [HTMLTableElement interface: document.createElement("table") must inherit property "createTHead" with the proper type (4)]
- expected: FAIL
-
- [HTMLTableElement interface: document.createElement("table") must inherit property "deleteTHead" with the proper type (5)]
- expected: FAIL
-
- [HTMLTableElement interface: document.createElement("table") must inherit property "tFoot" with the proper type (6)]
- expected: FAIL
-
- [HTMLTableElement interface: document.createElement("table") must inherit property "createTFoot" with the proper type (7)]
- expected: FAIL
-
- [HTMLTableElement interface: document.createElement("table") must inherit property "deleteTFoot" with the proper type (8)]
- expected: FAIL
-
- [HTMLTableElement interface: document.createElement("table") must inherit property "tBodies" with the proper type (9)]
- expected: FAIL
-
[HTMLTableElement interface: document.createElement("table") must inherit property "insertRow" with the proper type (12)]
expected: FAIL
diff --git a/tests/wpt/web-platform-tests/html/semantics/tabular-data/the-table-element/tFoot.html b/tests/wpt/web-platform-tests/html/semantics/tabular-data/the-table-element/tFoot.html
new file mode 100644
index 000000000000..52c6972fefd0
--- /dev/null
+++ b/tests/wpt/web-platform-tests/html/semantics/tabular-data/the-table-element/tFoot.html
@@ -0,0 +1,48 @@
+
+
+tFoot tests
+
+
+
+
diff --git a/tests/wpt/web-platform-tests/html/semantics/tabular-data/the-table-element/tHead.html b/tests/wpt/web-platform-tests/html/semantics/tabular-data/the-table-element/tHead.html
new file mode 100644
index 000000000000..ea2ebf1281da
--- /dev/null
+++ b/tests/wpt/web-platform-tests/html/semantics/tabular-data/the-table-element/tHead.html
@@ -0,0 +1,66 @@
+
+
+tHead tests
+
+
+
+
+