aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/script/dom/htmltablerowelement.rs20
-rw-r--r--components/script/dom/htmltablesectionelement.rs61
-rw-r--r--components/script/dom/node.rs67
-rw-r--r--components/script/dom/webidls/HTMLTableRowElement.webidl6
-rw-r--r--tests/wpt/metadata/html/dom/interfaces.html.ini18
-rw-r--r--tests/wpt/metadata/html/semantics/tabular-data/the-tr-element/deleteCell.html.ini14
-rw-r--r--tests/wpt/metadata/html/semantics/tabular-data/the-tr-element/insertCell.html.ini20
-rw-r--r--tests/wpt/web-platform-tests/html/semantics/tabular-data/the-tr-element/deleteCell.html8
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>