Implement deleteRow and insertRow for <table> element

Continued from #6936
This commit is contained in:
Corey Farwell 2015-10-04 17:17:45 -04:00
parent 02d8894945
commit 3d383f21ae
8 changed files with 81 additions and 77 deletions

View file

@ -160,7 +160,7 @@ impl HTMLCollection {
HTMLCollection::create(window, root, box ElementChildFilter) HTMLCollection::create(window, root, box ElementChildFilter)
} }
fn elements_iter(&self) -> HTMLCollectionElementsIter { pub fn elements_iter(&self) -> HTMLCollectionElementsIter {
let ref filter = self.collection.1; let ref filter = self.collection.1;
let root = self.collection.0.root(); let root = self.collection.0.root();
let mut node_iter = root.traverse_preorder(); let mut node_iter = root.traverse_preorder();
@ -173,7 +173,7 @@ impl HTMLCollection {
} }
} }
struct HTMLCollectionElementsIter<'a> { pub struct HTMLCollectionElementsIter<'a> {
node_iter: TreeIterator, node_iter: TreeIterator,
root: Root<Node>, root: Root<Node>,
filter: &'a Box<CollectionFilter>, filter: &'a Box<CollectionFilter>,

View file

@ -4,19 +4,25 @@
use cssparser::RGBA; use cssparser::RGBA;
use dom::attr::Attr; use dom::attr::Attr;
use dom::bindings::codegen::Bindings::HTMLCollectionBinding::HTMLCollectionMethods;
use dom::bindings::codegen::Bindings::HTMLTableSectionElementBinding::{self, HTMLTableSectionElementMethods}; use dom::bindings::codegen::Bindings::HTMLTableSectionElementBinding::{self, HTMLTableSectionElementMethods};
use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods; use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
use dom::bindings::codegen::InheritTypes::ElementCast;
use dom::bindings::codegen::InheritTypes::NodeCast; use dom::bindings::codegen::InheritTypes::NodeCast;
use dom::bindings::codegen::InheritTypes::{HTMLElementCast, HTMLTableRowElementDerived, HTMLTableSectionElementDerived}; use dom::bindings::codegen::InheritTypes::{HTMLElementCast, HTMLTableRowElementDerived, HTMLTableSectionElementDerived};
use dom::bindings::error::Error;
use dom::bindings::error::{ErrorResult, Fallible};
use dom::bindings::js::{Root, RootedReference}; use dom::bindings::js::{Root, RootedReference};
use dom::document::Document; use dom::document::Document;
use dom::element::{AttributeMutation, Element, ElementTypeId}; use dom::element::{AttributeMutation, Element, ElementTypeId};
use dom::eventtarget::{EventTarget, EventTargetTypeId}; use dom::eventtarget::{EventTarget, EventTargetTypeId};
use dom::htmlcollection::{CollectionFilter, HTMLCollection}; use dom::htmlcollection::{CollectionFilter, HTMLCollection};
use dom::htmlelement::{HTMLElement, HTMLElementTypeId}; use dom::htmlelement::{HTMLElement, HTMLElementTypeId};
use dom::htmltablerowelement::HTMLTableRowElement;
use dom::node::{Node, NodeTypeId, window_from_node}; use dom::node::{Node, NodeTypeId, window_from_node};
use dom::virtualmethods::VirtualMethods; use dom::virtualmethods::VirtualMethods;
use std::cell::Cell; use std::cell::Cell;
use std::iter;
use util::str::{self, DOMString}; use util::str::{self, DOMString};
#[dom_struct] #[dom_struct]
@ -71,6 +77,61 @@ impl HTMLTableSectionElementMethods for HTMLTableSectionElement {
fn Rows(&self) -> Root<HTMLCollection> { fn Rows(&self) -> Root<HTMLCollection> {
HTMLCollection::create(&window_from_node(self), NodeCast::from_ref(self), box RowsFilter) HTMLCollection::create(&window_from_node(self), NodeCast::from_ref(self), box RowsFilter)
} }
// 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))
}
// 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(())
}
} }
impl VirtualMethods for HTMLTableSectionElement { impl VirtualMethods for HTMLTableSectionElement {

View file

@ -6,8 +6,10 @@
// https://html.spec.whatwg.org/multipage/#htmltablesectionelement // https://html.spec.whatwg.org/multipage/#htmltablesectionelement
interface HTMLTableSectionElement : HTMLElement { interface HTMLTableSectionElement : HTMLElement {
readonly attribute HTMLCollection rows; readonly attribute HTMLCollection rows;
//HTMLElement insertRow(optional long index = -1); [Throws]
//void deleteRow(long index); HTMLElement insertRow(optional long index = -1);
[Throws]
void deleteRow(long index);
// also has obsolete members // also has obsolete members
}; };

View file

@ -4650,12 +4650,6 @@
[HTMLTableSectionElement interface: existence and properties of interface object] [HTMLTableSectionElement interface: existence and properties of interface object]
expected: FAIL expected: FAIL
[HTMLTableSectionElement interface: operation insertRow(long)]
expected: FAIL
[HTMLTableSectionElement interface: operation deleteRow(long)]
expected: FAIL
[HTMLTableSectionElement interface: attribute align] [HTMLTableSectionElement interface: attribute align]
expected: FAIL expected: FAIL
@ -4668,18 +4662,6 @@
[HTMLTableSectionElement interface: attribute vAlign] [HTMLTableSectionElement interface: attribute vAlign]
expected: FAIL expected: FAIL
[HTMLTableSectionElement interface: document.createElement("tbody") must inherit property "insertRow" with the proper type (1)]
expected: FAIL
[HTMLTableSectionElement interface: calling insertRow(long) on document.createElement("tbody") with too few arguments must throw TypeError]
expected: FAIL
[HTMLTableSectionElement interface: document.createElement("tbody") must inherit property "deleteRow" with the proper type (2)]
expected: FAIL
[HTMLTableSectionElement interface: calling deleteRow(long) on document.createElement("tbody") with too few arguments must throw TypeError]
expected: FAIL
[HTMLTableSectionElement interface: document.createElement("tbody") must inherit property "align" with the proper type (3)] [HTMLTableSectionElement interface: document.createElement("tbody") must inherit property "align" with the proper type (3)]
expected: FAIL expected: FAIL
@ -4692,18 +4674,6 @@
[HTMLTableSectionElement interface: document.createElement("tbody") must inherit property "vAlign" with the proper type (6)] [HTMLTableSectionElement interface: document.createElement("tbody") must inherit property "vAlign" with the proper type (6)]
expected: FAIL expected: FAIL
[HTMLTableSectionElement interface: document.createElement("thead") must inherit property "insertRow" with the proper type (1)]
expected: FAIL
[HTMLTableSectionElement interface: calling insertRow(long) on document.createElement("thead") with too few arguments must throw TypeError]
expected: FAIL
[HTMLTableSectionElement interface: document.createElement("thead") must inherit property "deleteRow" with the proper type (2)]
expected: FAIL
[HTMLTableSectionElement interface: calling deleteRow(long) on document.createElement("thead") with too few arguments must throw TypeError]
expected: FAIL
[HTMLTableSectionElement interface: document.createElement("thead") must inherit property "align" with the proper type (3)] [HTMLTableSectionElement interface: document.createElement("thead") must inherit property "align" with the proper type (3)]
expected: FAIL expected: FAIL
@ -4716,18 +4686,6 @@
[HTMLTableSectionElement interface: document.createElement("thead") must inherit property "vAlign" with the proper type (6)] [HTMLTableSectionElement interface: document.createElement("thead") must inherit property "vAlign" with the proper type (6)]
expected: FAIL expected: FAIL
[HTMLTableSectionElement interface: document.createElement("tfoot") must inherit property "insertRow" with the proper type (1)]
expected: FAIL
[HTMLTableSectionElement interface: calling insertRow(long) on document.createElement("tfoot") with too few arguments must throw TypeError]
expected: FAIL
[HTMLTableSectionElement interface: document.createElement("tfoot") must inherit property "deleteRow" with the proper type (2)]
expected: FAIL
[HTMLTableSectionElement interface: calling deleteRow(long) on document.createElement("tfoot") with too few arguments must throw TypeError]
expected: FAIL
[HTMLTableSectionElement interface: document.createElement("tfoot") must inherit property "align" with the proper type (3)] [HTMLTableSectionElement interface: document.createElement("tfoot") must inherit property "align" with the proper type (3)]
expected: FAIL expected: FAIL

View file

@ -1,14 +0,0 @@
[deleteRow.html]
type: testharness
[HTMLTableSectionElement deleteRow(0)]
expected: FAIL
[HTMLTableSectionElement deleteRow(-1)]
expected: FAIL
[HTMLTableSectionElement deleteRow(rows.length)]
expected: FAIL
[HTMLTableSectionElement deleteRow(-2)]
expected: FAIL

View file

@ -1,17 +0,0 @@
[insertRow.html]
type: testharness
[HTMLTableSectionElement insertRow(0)]
expected: FAIL
[HTMLTableSectionElement insertRow(-1)]
expected: FAIL
[HTMLTableSectionElement insertRow()]
expected: FAIL
[HTMLTableSectionElement insertRow(-2)]
expected: FAIL
[HTMLTableSectionElement insertRow(rows.length + 1)]
expected: FAIL

View file

@ -43,4 +43,12 @@ test(function () {
}); });
}, "HTMLTableSectionElement deleteRow(-2)"); }, "HTMLTableSectionElement deleteRow(-2)");
test(function () {
assert_equals(tbody.rows.length, 1);
tbody.deleteRow(-1);
assert_equals(tbody.rows.length, 0);
tbody.deleteRow(-1);
assert_equals(tbody.rows.length, 0);
}, "HTMLTableSectionElement deleteRow(-1) with no rows");
</script> </script>

View file

@ -35,6 +35,12 @@ test(function () {
assert_equals(tbody.rows.length, 4); assert_equals(tbody.rows.length, 4);
}, "HTMLTableSectionElement insertRow()"); }, "HTMLTableSectionElement insertRow()");
test(function () {
var trEle = tbody.insertRow(tbody.rows.length);
assert_equals(tbody.rows[tbody.rows.length - 1], trEle);
assert_equals(tbody.rows.length, 5);
}, "HTMLTableSectionElement insertRow(rows.length)");
test(function () { test(function () {
assert_throws("IndexSizeError", function () { assert_throws("IndexSizeError", function () {
tbody.insertRow(-2); tbody.insertRow(-2);