diff options
8 files changed, 108 insertions, 106 deletions
diff --git a/components/script/dom/htmltablerowelement.rs b/components/script/dom/htmltablerowelement.rs index a485048b240..a35d5d79d66 100644 --- a/components/script/dom/htmltablerowelement.rs +++ b/components/script/dom/htmltablerowelement.rs @@ -8,11 +8,13 @@ use dom::bindings::codegen::Bindings::HTMLTableRowElementBinding::{self, HTMLTab use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods; use dom::bindings::codegen::InheritTypes::{HTMLElementCast, HTMLTableDataCellElementDerived}; use dom::bindings::codegen::InheritTypes::{HTMLTableHeaderCellElementDerived, NodeCast}; +use dom::bindings::error::{ErrorResult, Fallible}; use dom::bindings::js::{JS, MutNullableHeap, Root, RootedReference}; use dom::document::Document; use dom::element::{AttributeMutation, Element}; use dom::htmlcollection::{CollectionFilter, HTMLCollection}; use dom::htmlelement::HTMLElement; +use dom::htmltabledatacellelement::HTMLTableDataCellElement; use dom::node::{Node, window_from_node}; use dom::virtualmethods::VirtualMethods; use std::cell::Cell; @@ -73,6 +75,24 @@ impl HTMLTableRowElementMethods for HTMLTableRowElement { HTMLCollection::create(window.r(), NodeCast::from_ref(self), filter) }) } + + // https://html.spec.whatwg.org/multipage/#dom-tr-insertcell + fn InsertCell(&self, index: i32) -> Fallible<Root<HTMLElement>> { + let node = NodeCast::from_ref(self); + node.insert_cell_or_row( + index, + || self.Cells(), + || HTMLTableDataCellElement::new("td".to_owned(), None, node.owner_doc().r())) + } + + // https://html.spec.whatwg.org/multipage/#dom-tr-deletecell + fn DeleteCell(&self, index: i32) -> ErrorResult { + let node = NodeCast::from_ref(self); + node.delete_cell_or_row( + index, + || self.Cells(), + |n| n.is_htmltabledatacellelement()) + } } impl VirtualMethods for HTMLTableRowElement { diff --git a/components/script/dom/htmltablesectionelement.rs b/components/script/dom/htmltablesectionelement.rs index a384afcaae7..dfc2ceb5900 100644 --- a/components/script/dom/htmltablesectionelement.rs +++ b/components/script/dom/htmltablesectionelement.rs @@ -4,12 +4,9 @@ use cssparser::RGBA; use dom::attr::Attr; -use dom::bindings::codegen::Bindings::HTMLCollectionBinding::HTMLCollectionMethods; use dom::bindings::codegen::Bindings::HTMLTableSectionElementBinding::{self, HTMLTableSectionElementMethods}; use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods; -use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLElementCast}; -use dom::bindings::codegen::InheritTypes::{HTMLTableRowElementDerived, NodeCast}; -use dom::bindings::error::Error; +use dom::bindings::codegen::InheritTypes::{HTMLElementCast, HTMLTableRowElementDerived, NodeCast}; use dom::bindings::error::{ErrorResult, Fallible}; use dom::bindings::js::{Root, RootedReference}; use dom::document::Document; @@ -20,7 +17,6 @@ use dom::htmltablerowelement::HTMLTableRowElement; use dom::node::{Node, window_from_node}; use dom::virtualmethods::VirtualMethods; use std::cell::Cell; -use std::iter; use util::str::{self, DOMString}; #[dom_struct] @@ -67,57 +63,20 @@ impl HTMLTableSectionElementMethods for HTMLTableSectionElement { // https://html.spec.whatwg.org/multipage/#dom-tbody-insertrow fn InsertRow(&self, index: i32) -> Fallible<Root<HTMLElement>> { - if index < -1 { - return Err(Error::IndexSize); - } - let node = NodeCast::from_ref(self); - let tr = HTMLTableRowElement::new("tr".to_owned(), None, node.owner_doc().r()); - - let after_node = if index == -1 { - None - } else { - match self.Rows() - .elements_iter() - .map(NodeCast::from_root) - .map(Some) - .chain(iter::once(None)) - .nth(index as usize) { - None => return Err(Error::IndexSize), - Some(node) => node, - } - }; - - { - let tr_node = NodeCast::from_ref(tr.r()); - try!(node.InsertBefore(tr_node, after_node.r())); - } - - Ok(HTMLElementCast::from_root(tr)) + node.insert_cell_or_row( + index, + || self.Rows(), + || HTMLTableRowElement::new("tr".to_owned(), None, node.owner_doc().r())) } // https://html.spec.whatwg.org/multipage/#dom-tbody-deleterow fn DeleteRow(&self, index: i32) -> ErrorResult { - let element = match index { - index if index < -1 => return Err(Error::IndexSize), - -1 => { - let last_child = NodeCast::from_ref(self).GetLastChild(); - match last_child.and_then(|node| node.inclusively_preceding_siblings() - .filter_map(ElementCast::to_root) - .filter(|n| n.is_htmltablerowelement()) - .next()) { - Some(element) => element, - None => return Ok(()), - } - }, - index => match self.Rows().Item(index as u32) { - Some(element) => element, - None => return Err(Error::IndexSize), - }, - }; - - NodeCast::from_ref(element.r()).remove_self(); - Ok(()) + let node = NodeCast::from_ref(self); + node.delete_cell_or_row( + index, + || self.Rows(), + |n| n.is_htmltablerowelement()) } } diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs index daacdd09fa0..7fbb409daca 100644 --- a/components/script/dom/node.rs +++ b/components/script/dom/node.rs @@ -14,10 +14,13 @@ use dom::bindings::codegen::Bindings::AttrBinding::AttrMethods; use dom::bindings::codegen::Bindings::CharacterDataBinding::CharacterDataMethods; use dom::bindings::codegen::Bindings::DocumentBinding::DocumentMethods; use dom::bindings::codegen::Bindings::ElementBinding::ElementMethods; +use dom::bindings::codegen::Bindings::HTMLCollectionBinding::HTMLCollectionMethods; use dom::bindings::codegen::Bindings::NamedNodeMapBinding::NamedNodeMapMethods; use dom::bindings::codegen::Bindings::NodeBinding::{NodeConstants, NodeMethods}; use dom::bindings::codegen::Bindings::NodeListBinding::NodeListMethods; use dom::bindings::codegen::Bindings::ProcessingInstructionBinding::ProcessingInstructionMethods; +use dom::bindings::codegen::InheritTypes::HTMLElementBase; +use dom::bindings::codegen::InheritTypes::HTMLElementCast; use dom::bindings::codegen::InheritTypes::{CharacterDataCast, CharacterDataTypeId}; use dom::bindings::codegen::InheritTypes::{DocumentCast, DocumentDerived, DocumentTypeCast}; use dom::bindings::codegen::InheritTypes::{ElementCast, ElementDerived, ElementTypeId}; @@ -43,6 +46,8 @@ use dom::documentfragment::DocumentFragment; use dom::documenttype::DocumentType; use dom::element::{Element, ElementCreator}; use dom::eventtarget::EventTarget; +use dom::htmlcollection::HTMLCollection; +use dom::htmlelement::HTMLElement; use dom::nodelist::NodeList; use dom::processinginstruction::ProcessingInstruction; use dom::text::Text; @@ -60,7 +65,7 @@ use selectors::parser::parse_author_origin_selector_list_from_str; use std::borrow::ToOwned; use std::cell::{Cell, Ref, RefCell, RefMut}; use std::default::Default; -use std::iter::{FilterMap, Peekable}; +use std::iter::{self, FilterMap, Peekable}; use std::mem; use std::slice::ref_slice; use std::sync::Arc; @@ -918,6 +923,66 @@ impl Node { } Ok(fragment) } + + /// Used by `HTMLTableSectionElement::InsertRow` and `HTMLTableRowElement::InsertCell` + pub fn insert_cell_or_row<F, G, I>(&self, index: i32, get_items: F, new_child: G) -> Fallible<Root<HTMLElement>> + where F: Fn() -> Root<HTMLCollection>, + G: Fn() -> Root<I>, + I: NodeBase + HTMLElementBase + Reflectable, + { + if index < -1 { + return Err(Error::IndexSize); + } + + let tr = new_child(); + + let after_node = if index == -1 { + None + } else { + match get_items().elements_iter() + .map(NodeCast::from_root) + .map(Some) + .chain(iter::once(None)) + .nth(index as usize) { + None => return Err(Error::IndexSize), + Some(node) => node, + } + }; + + { + let tr_node = NodeCast::from_ref(tr.r()); + try!(self.InsertBefore(tr_node, after_node.r())); + } + + Ok(HTMLElementCast::from_root(tr)) + } + + /// Used by `HTMLTableSectionElement::DeleteRow` and `HTMLTableRowElement::DeleteCell` + pub fn delete_cell_or_row<F, G>(&self, index: i32, get_items: F, is_delete_type: G) -> ErrorResult + where F: Fn() -> Root<HTMLCollection>, + G: Fn(&Element) -> bool + { + let element = match index { + index if index < -1 => return Err(Error::IndexSize), + -1 => { + let last_child = NodeCast::from_ref(self).GetLastChild(); + match last_child.and_then(|node| node.inclusively_preceding_siblings() + .filter_map(ElementCast::to_root) + .filter(|elem| is_delete_type(elem)) + .next()) { + Some(element) => element, + None => return Ok(()), + } + }, + index => match get_items().Item(index as u32) { + Some(element) => element, + None => return Err(Error::IndexSize), + }, + }; + + NodeCast::from_ref(element.r()).remove_self(); + Ok(()) + } } diff --git a/components/script/dom/webidls/HTMLTableRowElement.webidl b/components/script/dom/webidls/HTMLTableRowElement.webidl index 9ddf710653f..66538630c9d 100644 --- a/components/script/dom/webidls/HTMLTableRowElement.webidl +++ b/components/script/dom/webidls/HTMLTableRowElement.webidl @@ -8,8 +8,10 @@ interface HTMLTableRowElement : HTMLElement { //readonly attribute long rowIndex; //readonly attribute long sectionRowIndex; readonly attribute HTMLCollection cells; - //HTMLElement insertCell(optional long index = -1); - //void deleteCell(long index); + [Throws] + HTMLElement insertCell(optional long index = -1); + [Throws] + void deleteCell(long index); // also has obsolete members }; diff --git a/tests/wpt/metadata/html/dom/interfaces.html.ini b/tests/wpt/metadata/html/dom/interfaces.html.ini index 1f0d15443e4..205cff1f1af 100644 --- a/tests/wpt/metadata/html/dom/interfaces.html.ini +++ b/tests/wpt/metadata/html/dom/interfaces.html.ini @@ -4707,12 +4707,6 @@ [HTMLTableRowElement interface: attribute sectionRowIndex] expected: FAIL - [HTMLTableRowElement interface: operation insertCell(long)] - expected: FAIL - - [HTMLTableRowElement interface: operation deleteCell(long)] - expected: FAIL - [HTMLTableRowElement interface: attribute align] expected: FAIL @@ -4731,18 +4725,6 @@ [HTMLTableRowElement interface: document.createElement("tr") must inherit property "sectionRowIndex" with the proper type (1)] expected: FAIL - [HTMLTableRowElement interface: document.createElement("tr") must inherit property "insertCell" with the proper type (3)] - expected: FAIL - - [HTMLTableRowElement interface: calling insertCell(long) on document.createElement("tr") with too few arguments must throw TypeError] - expected: FAIL - - [HTMLTableRowElement interface: document.createElement("tr") must inherit property "deleteCell" with the proper type (4)] - expected: FAIL - - [HTMLTableRowElement interface: calling deleteCell(long) on document.createElement("tr") with too few arguments must throw TypeError] - expected: FAIL - [HTMLTableRowElement interface: document.createElement("tr") must inherit property "align" with the proper type (5)] expected: FAIL diff --git a/tests/wpt/metadata/html/semantics/tabular-data/the-tr-element/deleteCell.html.ini b/tests/wpt/metadata/html/semantics/tabular-data/the-tr-element/deleteCell.html.ini deleted file mode 100644 index af92617f38a..00000000000 --- a/tests/wpt/metadata/html/semantics/tabular-data/the-tr-element/deleteCell.html.ini +++ /dev/null @@ -1,14 +0,0 @@ -[deleteCell.html] - type: testharness - [HTMLTableRowElement deleteCell(0)] - expected: FAIL - - [HTMLTableRowElement deleteCell(-1)] - expected: FAIL - - [HTMLTableRowElement deleteCell(-2)] - expected: FAIL - - [HTMLTableRowElement deleteCell(cells.length)] - expected: FAIL - diff --git a/tests/wpt/metadata/html/semantics/tabular-data/the-tr-element/insertCell.html.ini b/tests/wpt/metadata/html/semantics/tabular-data/the-tr-element/insertCell.html.ini deleted file mode 100644 index 1c5d7a7c76e..00000000000 --- a/tests/wpt/metadata/html/semantics/tabular-data/the-tr-element/insertCell.html.ini +++ /dev/null @@ -1,20 +0,0 @@ -[insertCell.html] - type: testharness - [HTMLTableRowElement insertCell(0)] - expected: FAIL - - [HTMLTableRowElement insertCell(-1)] - expected: FAIL - - [HTMLTableRowElement insertCell(cells.length)] - expected: FAIL - - [HTMLTableRowElement insertCell()] - expected: FAIL - - [HTMLTableRowElement insertCell(-2)] - expected: FAIL - - [HTMLTableRowElement insertCell(cells.length + 1)] - expected: FAIL - diff --git a/tests/wpt/web-platform-tests/html/semantics/tabular-data/the-tr-element/deleteCell.html b/tests/wpt/web-platform-tests/html/semantics/tabular-data/the-tr-element/deleteCell.html index 9262364eec8..1400d32e1b1 100644 --- a/tests/wpt/web-platform-tests/html/semantics/tabular-data/the-tr-element/deleteCell.html +++ b/tests/wpt/web-platform-tests/html/semantics/tabular-data/the-tr-element/deleteCell.html @@ -43,4 +43,12 @@ test(function () { }); }, "HTMLTableRowElement deleteCell(cells.length)"); +test(function () { + assert_equals(tr.cells.length, 1); + tr.deleteCell(-1); + assert_equals(tr.cells.length, 0); + tr.deleteCell(-1); + assert_equals(tr.cells.length, 0); +}, "HTMLTableRowElement deleteCell(-1) with no cells"); + </script> |