mirror of
https://github.com/servo/servo.git
synced 2025-08-03 04:30:10 +01:00
Implement HTMLTableRowElement insertCell and deleteCell
This commit is contained in:
parent
e31ad01103
commit
1f58169263
8 changed files with 108 additions and 106 deletions
|
@ -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 {
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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(())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue