diff --git a/components/script/dom/htmltableelement.rs b/components/script/dom/htmltableelement.rs index 4ea908675b1..4b5cd44773d 100644 --- a/components/script/dom/htmltableelement.rs +++ b/components/script/dom/htmltableelement.rs @@ -4,10 +4,11 @@ use cssparser::RGBA; use dom::attr::{Attr, AttrValue}; +use dom::bindings::codegen::Bindings::HTMLCollectionBinding::HTMLCollectionMethods; use dom::bindings::codegen::Bindings::HTMLTableElementBinding; use dom::bindings::codegen::Bindings::HTMLTableElementBinding::HTMLTableElementMethods; use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods; -use dom::bindings::error::{Error, ErrorResult}; +use dom::bindings::error::{Error, ErrorResult, Fallible}; use dom::bindings::inheritance::Castable; use dom::bindings::js::{JS, LayoutJS, MutNullableHeap, Root, RootedReference}; use dom::document::Document; @@ -166,8 +167,8 @@ impl HTMLTableElementMethods for HTMLTableElement { } // https://html.spec.whatwg.org/multipage/#dom-table-createcaption - fn CreateCaption(&self) -> Root { - let caption = match self.GetCaption() { + fn CreateCaption(&self) -> Root { + match self.GetCaption() { Some(caption) => caption, None => { let caption = HTMLTableCaptionElement::new(atom!("caption"), @@ -176,8 +177,7 @@ impl HTMLTableElementMethods for HTMLTableElement { self.SetCaption(Some(caption.r())); caption } - }; - Root::upcast(caption) + } } // https://html.spec.whatwg.org/multipage/#dom-table-deletecaption @@ -282,6 +282,61 @@ impl HTMLTableElementMethods for HTMLTableElement { tbody } + // https://html.spec.whatwg.org/multipage/#dom-table-insertrow + fn InsertRow(&self, index: i32) -> Fallible> { + let rows = self.Rows(); + let number_of_row_elements = rows.Length(); + + if index < -1 || index > number_of_row_elements as i32 { + return Err(Error::IndexSize); + } + + let new_row = HTMLTableRowElement::new(atom!("tr"), + None, + document_from_node(self).r()); + let node = self.upcast::(); + + if number_of_row_elements == 0 { + // append new row to last or new tbody in table + if let Some(last_tbody) = node.rev_children() + .filter_map(Root::downcast::) + .find(|n| n.is::() && n.local_name() == &atom!("tbody")) { + last_tbody.upcast::().AppendChild(new_row.upcast::()) + .expect("InsertRow failed to append first row."); + } else { + let tbody = self.CreateTBody(); + node.AppendChild(tbody.upcast()) + .expect("InsertRow failed to append new tbody."); + + tbody.upcast::().AppendChild(new_row.upcast::()) + .expect("InsertRow failed to append first row."); + } + } else if index == number_of_row_elements as i32 || index == -1 { + // append new row to parent of last row in table + let last_row = rows.Item(number_of_row_elements - 1) + .expect("InsertRow failed to find last row in table."); + + let last_row_parent = + last_row.upcast::().GetParentNode() + .expect("InsertRow failed to find parent of last row in table."); + + last_row_parent.upcast::().AppendChild(new_row.upcast::()) + .expect("InsertRow failed to append last row."); + } else { + // insert new row before the index-th row in rows using the same parent + let ith_row = rows.Item(index as u32) + .expect("InsertRow failed to find a row in table."); + + let ith_row_parent = ith_row.upcast::().GetParentNode() + .expect("InsertRow failed to find parent of a row in table."); + + ith_row_parent.upcast::().InsertBefore(new_row.upcast::(), Some(ith_row.upcast::())) + .expect("InsertRow failed to append row"); + } + + Ok(new_row) + } + // https://html.spec.whatwg.org/multipage/#dom-table-bgcolor make_getter!(BgColor, "bgcolor"); diff --git a/components/script/dom/webidls/HTMLTableElement.webidl b/components/script/dom/webidls/HTMLTableElement.webidl index af95685b5b5..dacd0da7aa2 100644 --- a/components/script/dom/webidls/HTMLTableElement.webidl +++ b/components/script/dom/webidls/HTMLTableElement.webidl @@ -6,7 +6,7 @@ // https://html.spec.whatwg.org/multipage/#htmltableelement interface HTMLTableElement : HTMLElement { attribute HTMLTableCaptionElement? caption; - HTMLElement createCaption(); + HTMLTableCaptionElement createCaption(); void deleteCaption(); [SetterThrows] attribute HTMLTableSectionElement? tHead; @@ -19,10 +19,8 @@ interface HTMLTableElement : HTMLElement { readonly attribute HTMLCollection tBodies; HTMLTableSectionElement createTBody(); readonly attribute HTMLCollection rows; - //HTMLElement insertRow(optional long index = -1); + [Throws] HTMLTableRowElement insertRow(optional long index = -1); //void deleteRow(long index); - // attribute boolean sortable; - //void stopSorting(); // also has obsolete members }; diff --git a/tests/wpt/metadata/MANIFEST.json b/tests/wpt/metadata/MANIFEST.json index 31ec16b06d5..823ca7747f4 100644 --- a/tests/wpt/metadata/MANIFEST.json +++ b/tests/wpt/metadata/MANIFEST.json @@ -40499,6 +40499,12 @@ ] }, "testharness": { + "html/semantics/tabular-data/the-table-element/insertRow-method-03.html": [ + { + "path": "html/semantics/tabular-data/the-table-element/insertRow-method-03.html", + "url": "/html/semantics/tabular-data/the-table-element/insertRow-method-03.html" + } + ], "html/semantics/tabular-data/the-table-element/tFoot.html": [ { "path": "html/semantics/tabular-data/the-table-element/tFoot.html", diff --git a/tests/wpt/metadata/html/dom/interfaces.html.ini b/tests/wpt/metadata/html/dom/interfaces.html.ini index e16a669de1a..f7f6399a95e 100644 --- a/tests/wpt/metadata/html/dom/interfaces.html.ini +++ b/tests/wpt/metadata/html/dom/interfaces.html.ini @@ -4128,9 +4128,6 @@ [HTMLAreaElement interface: document.createElement("area") must inherit property "noHref" with the proper type (10)] expected: FAIL - [HTMLTableElement interface: operation insertRow(long)] - expected: FAIL - [HTMLTableElement interface: operation deleteRow(long)] expected: FAIL @@ -4161,12 +4158,6 @@ [HTMLTableElement interface: attribute cellSpacing] expected: FAIL - [HTMLTableElement interface: document.createElement("table") must inherit property "insertRow" with the proper type (12)] - expected: FAIL - - [HTMLTableElement interface: calling insertRow(long) on document.createElement("table") with too few arguments must throw TypeError] - expected: FAIL - [HTMLTableElement interface: document.createElement("table") must inherit property "deleteRow" with the proper type (13)] expected: FAIL diff --git a/tests/wpt/metadata/html/semantics/tabular-data/the-table-element/insertRow-method-01.html.ini b/tests/wpt/metadata/html/semantics/tabular-data/the-table-element/insertRow-method-01.html.ini deleted file mode 100644 index ddad3e3878a..00000000000 --- a/tests/wpt/metadata/html/semantics/tabular-data/the-table-element/insertRow-method-01.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[insertRow-method-01.html] - type: testharness - [insertRow(): INDEX_SIZE_ERR] - expected: FAIL - diff --git a/tests/wpt/metadata/html/semantics/tabular-data/the-table-element/insertRow-method-02.html.ini b/tests/wpt/metadata/html/semantics/tabular-data/the-table-element/insertRow-method-02.html.ini deleted file mode 100644 index 22418c828ba..00000000000 --- a/tests/wpt/metadata/html/semantics/tabular-data/the-table-element/insertRow-method-02.html.ini +++ /dev/null @@ -1,8 +0,0 @@ -[insertRow-method-02.html] - type: testharness - [insertRow(): Empty table] - expected: FAIL - - [insertRow should insert a tr element] - expected: FAIL - diff --git a/tests/wpt/metadata/html/semantics/tabular-data/the-table-element/table-insertRow.html.ini b/tests/wpt/metadata/html/semantics/tabular-data/the-table-element/table-insertRow.html.ini deleted file mode 100644 index c3f049f5a36..00000000000 --- a/tests/wpt/metadata/html/semantics/tabular-data/the-table-element/table-insertRow.html.ini +++ /dev/null @@ -1,11 +0,0 @@ -[table-insertRow.html] - type: testharness - [insertRow should not copy prefixes] - expected: FAIL - - [insertRow should insert into a tbody, not into a thead, if table.rows is empty] - expected: FAIL - - [insertRow should insert into a tbody, not into a tfoot, if table.rows is empty] - expected: FAIL - diff --git a/tests/wpt/web-platform-tests/html/semantics/tabular-data/the-table-element/insertRow-method-03.html b/tests/wpt/web-platform-tests/html/semantics/tabular-data/the-table-element/insertRow-method-03.html new file mode 100644 index 00000000000..19c3ceb3c63 --- /dev/null +++ b/tests/wpt/web-platform-tests/html/semantics/tabular-data/the-table-element/insertRow-method-03.html @@ -0,0 +1,32 @@ + +insertRow(): non-empty table + + + + +
+
+ + +
+
+