aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/htmltableelement.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/script/dom/htmltableelement.rs')
-rw-r--r--components/script/dom/htmltableelement.rs363
1 files changed, 198 insertions, 165 deletions
diff --git a/components/script/dom/htmltableelement.rs b/components/script/dom/htmltableelement.rs
index 56e9876b753..2fa44f3ad37 100644
--- a/components/script/dom/htmltableelement.rs
+++ b/components/script/dom/htmltableelement.rs
@@ -1,57 +1,61 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
+
+use crate::dom::attr::Attr;
+use crate::dom::bindings::codegen::Bindings::HTMLCollectionBinding::HTMLCollectionMethods;
+use crate::dom::bindings::codegen::Bindings::HTMLTableElementBinding::HTMLTableElementMethods;
+use crate::dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
+use crate::dom::bindings::error::{Error, ErrorResult, Fallible};
+use crate::dom::bindings::inheritance::Castable;
+use crate::dom::bindings::root::{Dom, DomRoot, LayoutDom, MutNullableDom};
+use crate::dom::bindings::str::DOMString;
+use crate::dom::document::Document;
+use crate::dom::element::{AttributeMutation, Element, LayoutElementHelpers};
+use crate::dom::htmlcollection::{CollectionFilter, HTMLCollection};
+use crate::dom::htmlelement::HTMLElement;
+use crate::dom::htmltablecaptionelement::HTMLTableCaptionElement;
+use crate::dom::htmltablecolelement::HTMLTableColElement;
+use crate::dom::htmltablerowelement::HTMLTableRowElement;
+use crate::dom::htmltablesectionelement::HTMLTableSectionElement;
+use crate::dom::node::{document_from_node, window_from_node, Node};
+use crate::dom::virtualmethods::VirtualMethods;
use cssparser::RGBA;
-use dom::attr::Attr;
-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, Fallible};
-use dom::bindings::inheritance::Castable;
-use dom::bindings::js::{JS, LayoutJS, MutNullableJS, Root, RootedReference};
-use dom::bindings::str::DOMString;
-use dom::document::Document;
-use dom::element::{AttributeMutation, Element, RawLayoutElementHelpers};
-use dom::htmlcollection::{CollectionFilter, HTMLCollection};
-use dom::htmlelement::HTMLElement;
-use dom::htmltablecaptionelement::HTMLTableCaptionElement;
-use dom::htmltablecolelement::HTMLTableColElement;
-use dom::htmltablerowelement::HTMLTableRowElement;
-use dom::htmltablesectionelement::HTMLTableSectionElement;
-use dom::node::{Node, document_from_node, window_from_node};
-use dom::virtualmethods::VirtualMethods;
use dom_struct::dom_struct;
-use html5ever_atoms::LocalName;
+use html5ever::{LocalName, Prefix};
use std::cell::Cell;
-use style::attr::{AttrValue, LengthOrPercentageOrAuto, parse_unsigned_integer};
+use style::attr::{parse_unsigned_integer, AttrValue, LengthOrPercentageOrAuto};
#[dom_struct]
pub struct HTMLTableElement {
htmlelement: HTMLElement,
border: Cell<Option<u32>>,
cellspacing: Cell<Option<u32>>,
- tbodies: MutNullableJS<HTMLCollection>,
+ tbodies: MutNullableDom<HTMLCollection>,
}
#[allow(unrooted_must_root)]
-#[derive(JSTraceable, HeapSizeOf)]
+#[derive(JSTraceable, MallocSizeOf)]
struct TableRowFilter {
- sections: Vec<JS<Node>>,
+ sections: Vec<Dom<Node>>,
}
impl CollectionFilter for TableRowFilter {
fn filter(&self, elem: &Element, root: &Node) -> bool {
elem.is::<HTMLTableRowElement>() &&
- (root.is_parent_of(elem.upcast())
- || self.sections.iter().any(|ref section| section.is_parent_of(elem.upcast())))
+ (root.is_parent_of(elem.upcast()) ||
+ self.sections
+ .iter()
+ .any(|ref section| section.is_parent_of(elem.upcast())))
}
}
impl HTMLTableElement {
- fn new_inherited(local_name: LocalName, prefix: Option<DOMString>, document: &Document)
- -> HTMLTableElement {
+ fn new_inherited(
+ local_name: LocalName,
+ prefix: Option<Prefix>,
+ document: &Document,
+ ) -> HTMLTableElement {
HTMLTableElement {
htmlelement: HTMLElement::new_inherited(local_name, prefix, document),
border: Cell::new(None),
@@ -61,11 +65,20 @@ impl HTMLTableElement {
}
#[allow(unrooted_must_root)]
- pub fn new(local_name: LocalName, prefix: Option<DOMString>, document: &Document)
- -> Root<HTMLTableElement> {
- Node::reflect_node(box HTMLTableElement::new_inherited(local_name, prefix, document),
- document,
- HTMLTableElementBinding::Wrap)
+ pub fn new(
+ local_name: LocalName,
+ prefix: Option<Prefix>,
+ document: &Document,
+ ) -> DomRoot<HTMLTableElement> {
+ let n = Node::reflect_node(
+ Box::new(HTMLTableElement::new_inherited(
+ local_name, prefix, document,
+ )),
+ document,
+ );
+
+ n.upcast::<Node>().set_weird_parser_insertion_mode();
+ n
}
pub fn get_border(&self) -> Option<u32> {
@@ -74,24 +87,30 @@ impl HTMLTableElement {
// https://html.spec.whatwg.org/multipage/#dom-table-thead
// https://html.spec.whatwg.org/multipage/#dom-table-tfoot
- fn get_first_section_of_type(&self, atom: &LocalName) -> Option<Root<HTMLTableSectionElement>> {
+ fn get_first_section_of_type(
+ &self,
+ atom: &LocalName,
+ ) -> Option<DomRoot<HTMLTableSectionElement>> {
self.upcast::<Node>()
.child_elements()
.find(|n| n.is::<HTMLTableSectionElement>() && n.local_name() == atom)
- .and_then(|n| n.downcast().map(Root::from_ref))
+ .and_then(|n| n.downcast().map(DomRoot::from_ref))
}
// https://html.spec.whatwg.org/multipage/#dom-table-thead
// https://html.spec.whatwg.org/multipage/#dom-table-tfoot
- fn set_first_section_of_type<P>(&self,
- atom: &LocalName,
- section: Option<&HTMLTableSectionElement>,
- reference_predicate: P)
- -> ErrorResult
- where P: FnMut(&Root<Element>) -> bool {
+ fn set_first_section_of_type<P>(
+ &self,
+ atom: &LocalName,
+ section: Option<&HTMLTableSectionElement>,
+ reference_predicate: P,
+ ) -> ErrorResult
+ where
+ P: FnMut(&DomRoot<Element>) -> bool,
+ {
if let Some(e) = section {
if e.upcast::<Element>().local_name() != atom {
- return Err(Error::HierarchyRequest)
+ return Err(Error::HierarchyRequest);
}
}
@@ -101,9 +120,9 @@ impl HTMLTableElement {
if let Some(section) = section {
let reference_element = node.child_elements().find(reference_predicate);
- let reference_node = reference_element.r().map(|e| e.upcast());
+ let reference_node = reference_element.as_ref().map(|e| e.upcast());
- try!(node.InsertBefore(section.upcast(), reference_node));
+ node.InsertBefore(section.upcast(), reference_node)?;
}
Ok(())
@@ -111,19 +130,18 @@ impl HTMLTableElement {
// https://html.spec.whatwg.org/multipage/#dom-table-createthead
// https://html.spec.whatwg.org/multipage/#dom-table-createtfoot
- fn create_section_of_type(&self, atom: &LocalName) -> Root<HTMLTableSectionElement> {
+ fn create_section_of_type(&self, atom: &LocalName) -> DomRoot<HTMLTableSectionElement> {
if let Some(section) = self.get_first_section_of_type(atom) {
- return section
+ return section;
}
- let section = HTMLTableSectionElement::new(atom.clone(),
- None,
- &document_from_node(self));
+ let section = HTMLTableSectionElement::new(atom.clone(), None, &document_from_node(self));
match atom {
&local_name!("thead") => self.SetTHead(Some(&section)),
&local_name!("tfoot") => self.SetTFoot(Some(&section)),
- _ => unreachable!("unexpected section type")
- }.expect("unexpected section type");
+ _ => unreachable!("unexpected section type"),
+ }
+ .expect("unexpected section type");
section
}
@@ -138,25 +156,31 @@ impl HTMLTableElement {
fn get_rows(&self) -> TableRowFilter {
TableRowFilter {
- sections: self.upcast::<Node>()
- .children()
- .filter_map(|ref node|
- node.downcast::<HTMLTableSectionElement>().map(|_| JS::from_ref(&**node)))
- .collect()
+ sections: self
+ .upcast::<Node>()
+ .children()
+ .filter_map(|ref node| {
+ node.downcast::<HTMLTableSectionElement>()
+ .map(|_| Dom::from_ref(&**node))
+ })
+ .collect(),
}
}
}
impl HTMLTableElementMethods for HTMLTableElement {
// https://html.spec.whatwg.org/multipage/#dom-table-rows
- fn Rows(&self) -> Root<HTMLCollection> {
+ fn Rows(&self) -> DomRoot<HTMLCollection> {
let filter = self.get_rows();
- HTMLCollection::new(&window_from_node(self), self.upcast(), box filter)
+ HTMLCollection::new(&window_from_node(self), self.upcast(), Box::new(filter))
}
// https://html.spec.whatwg.org/multipage/#dom-table-caption
- fn GetCaption(&self) -> Option<Root<HTMLTableCaptionElement>> {
- self.upcast::<Node>().children().filter_map(Root::downcast).next()
+ fn GetCaption(&self) -> Option<DomRoot<HTMLTableCaptionElement>> {
+ self.upcast::<Node>()
+ .children()
+ .filter_map(DomRoot::downcast)
+ .next()
}
// https://html.spec.whatwg.org/multipage/#dom-table-caption
@@ -167,22 +191,24 @@ impl HTMLTableElementMethods for HTMLTableElement {
if let Some(caption) = new_caption {
let node = self.upcast::<Node>();
- node.InsertBefore(caption.upcast(), node.GetFirstChild().r())
+ node.InsertBefore(caption.upcast(), node.GetFirstChild().as_deref())
.expect("Insertion failed");
}
}
// https://html.spec.whatwg.org/multipage/#dom-table-createcaption
- fn CreateCaption(&self) -> Root<HTMLTableCaptionElement> {
+ fn CreateCaption(&self) -> DomRoot<HTMLTableCaptionElement> {
match self.GetCaption() {
Some(caption) => caption,
None => {
- let caption = HTMLTableCaptionElement::new(local_name!("caption"),
- None,
- &document_from_node(self));
+ let caption = HTMLTableCaptionElement::new(
+ local_name!("caption"),
+ None,
+ &document_from_node(self),
+ );
self.SetCaption(Some(&caption));
caption
- }
+ },
}
}
@@ -193,9 +219,8 @@ impl HTMLTableElementMethods for HTMLTableElement {
}
}
-
// https://html.spec.whatwg.org/multipage/#dom-table-thead
- fn GetTHead(&self) -> Option<Root<HTMLTableSectionElement>> {
+ fn GetTHead(&self) -> Option<DomRoot<HTMLTableSectionElement>> {
self.get_first_section_of_type(&local_name!("thead"))
}
@@ -207,7 +232,7 @@ impl HTMLTableElementMethods for HTMLTableElement {
}
// https://html.spec.whatwg.org/multipage/#dom-table-createthead
- fn CreateTHead(&self) -> Root<HTMLTableSectionElement> {
+ fn CreateTHead(&self) -> DomRoot<HTMLTableSectionElement> {
self.create_section_of_type(&local_name!("thead"))
}
@@ -217,7 +242,7 @@ impl HTMLTableElementMethods for HTMLTableElement {
}
// https://html.spec.whatwg.org/multipage/#dom-table-tfoot
- fn GetTFoot(&self) -> Option<Root<HTMLTableSectionElement>> {
+ fn GetTFoot(&self) -> Option<DomRoot<HTMLTableSectionElement>> {
self.get_first_section_of_type(&local_name!("tfoot"))
}
@@ -233,7 +258,6 @@ impl HTMLTableElementMethods for HTMLTableElement {
if name == &local_name!("thead") || name == &local_name!("tbody") {
return false;
}
-
}
true
@@ -241,7 +265,7 @@ impl HTMLTableElementMethods for HTMLTableElement {
}
// https://html.spec.whatwg.org/multipage/#dom-table-createtfoot
- fn CreateTFoot(&self) -> Root<HTMLTableSectionElement> {
+ fn CreateTFoot(&self) -> DomRoot<HTMLTableSectionElement> {
self.create_section_of_type(&local_name!("tfoot"))
}
@@ -251,45 +275,42 @@ impl HTMLTableElementMethods for HTMLTableElement {
}
// https://html.spec.whatwg.org/multipage/#dom-table-tbodies
- fn TBodies(&self) -> Root<HTMLCollection> {
+ fn TBodies(&self) -> DomRoot<HTMLCollection> {
#[derive(JSTraceable)]
struct TBodiesFilter;
impl CollectionFilter for TBodiesFilter {
fn filter(&self, elem: &Element, root: &Node) -> bool {
elem.is::<HTMLTableSectionElement>() &&
elem.local_name() == &local_name!("tbody") &&
- elem.upcast::<Node>().GetParentNode().r() == Some(root)
+ elem.upcast::<Node>().GetParentNode().as_deref() == Some(root)
}
}
self.tbodies.or_init(|| {
let window = window_from_node(self);
- let filter = box TBodiesFilter;
+ let filter = Box::new(TBodiesFilter);
HTMLCollection::create(&window, self.upcast(), filter)
})
}
-
// https://html.spec.whatwg.org/multipage/#dom-table-createtbody
- fn CreateTBody(&self) -> Root<HTMLTableSectionElement> {
- let tbody = HTMLTableSectionElement::new(local_name!("tbody"),
- None,
- &document_from_node(self));
+ fn CreateTBody(&self) -> DomRoot<HTMLTableSectionElement> {
+ let tbody =
+ HTMLTableSectionElement::new(local_name!("tbody"), None, &document_from_node(self));
let node = self.upcast::<Node>();
- let last_tbody =
- node.rev_children()
- .filter_map(Root::downcast::<Element>)
- .find(|n| n.is::<HTMLTableSectionElement>() && n.local_name() == &local_name!("tbody"));
- let reference_element =
- last_tbody.and_then(|t| t.upcast::<Node>().GetNextSibling());
-
- node.InsertBefore(tbody.upcast(), reference_element.r())
+ let last_tbody = node
+ .rev_children()
+ .filter_map(DomRoot::downcast::<Element>)
+ .find(|n| n.is::<HTMLTableSectionElement>() && n.local_name() == &local_name!("tbody"));
+ let reference_element = last_tbody.and_then(|t| t.upcast::<Node>().GetNextSibling());
+
+ node.InsertBefore(tbody.upcast(), reference_element.as_deref())
.expect("Insertion failed");
tbody
}
// https://html.spec.whatwg.org/multipage/#dom-table-insertrow
- fn InsertRow(&self, index: i32) -> Fallible<Root<HTMLTableRowElement>> {
+ fn InsertRow(&self, index: i32) -> Fallible<DomRoot<HTMLTableRowElement>> {
let rows = self.Rows();
let number_of_row_elements = rows.Length();
@@ -297,47 +318,62 @@ impl HTMLTableElementMethods for HTMLTableElement {
return Err(Error::IndexSize);
}
- let new_row = HTMLTableRowElement::new(local_name!("tr"),
- None,
- &document_from_node(self));
+ let new_row = HTMLTableRowElement::new(local_name!("tr"), None, &document_from_node(self));
let node = self.upcast::<Node>();
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::<Element>)
- .find(|n| n.is::<HTMLTableSectionElement>() && n.local_name() == &local_name!("tbody")) {
- last_tbody.upcast::<Node>().AppendChild(new_row.upcast::<Node>())
- .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::<Node>().AppendChild(new_row.upcast::<Node>())
- .expect("InsertRow failed to append first row.");
- }
+ if let Some(last_tbody) = node
+ .rev_children()
+ .filter_map(DomRoot::downcast::<Element>)
+ .find(|n| {
+ n.is::<HTMLTableSectionElement>() && n.local_name() == &local_name!("tbody")
+ })
+ {
+ last_tbody
+ .upcast::<Node>()
+ .AppendChild(new_row.upcast::<Node>())
+ .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::<Node>()
+ .AppendChild(new_row.upcast::<Node>())
+ .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::<Node>().GetParentNode()
- .expect("InsertRow failed to find parent of last row in table.");
-
- last_row_parent.upcast::<Node>().AppendChild(new_row.upcast::<Node>())
- .expect("InsertRow failed to append last row.");
+ 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::<Node>()
+ .GetParentNode()
+ .expect("InsertRow failed to find parent of last row in table.");
+
+ last_row_parent
+ .upcast::<Node>()
+ .AppendChild(new_row.upcast::<Node>())
+ .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::<Node>().GetParentNode()
- .expect("InsertRow failed to find parent of a row in table.");
-
- ith_row_parent.upcast::<Node>().InsertBefore(new_row.upcast::<Node>(), Some(ith_row.upcast::<Node>()))
- .expect("InsertRow failed to append row");
+ let ith_row = rows
+ .Item(index as u32)
+ .expect("InsertRow failed to find a row in table.");
+
+ let ith_row_parent = ith_row
+ .upcast::<Node>()
+ .GetParentNode()
+ .expect("InsertRow failed to find parent of a row in table.");
+
+ ith_row_parent
+ .upcast::<Node>()
+ .InsertBefore(new_row.upcast::<Node>(), Some(ith_row.upcast::<Node>()))
+ .expect("InsertRow failed to append row");
}
Ok(new_row)
@@ -355,7 +391,7 @@ impl HTMLTableElementMethods for HTMLTableElement {
return Err(Error::IndexSize);
}
// Step 3.
- Root::upcast::<Node>(rows.Item(index as u32).unwrap()).remove_self();
+ DomRoot::upcast::<Node>(rows.Item(index as u32).unwrap()).remove_self();
Ok(())
}
@@ -373,52 +409,42 @@ impl HTMLTableElementMethods for HTMLTableElement {
}
pub trait HTMLTableElementLayoutHelpers {
- fn get_background_color(&self) -> Option<RGBA>;
- fn get_border(&self) -> Option<u32>;
- fn get_cellspacing(&self) -> Option<u32>;
- fn get_width(&self) -> LengthOrPercentageOrAuto;
+ fn get_background_color(self) -> Option<RGBA>;
+ fn get_border(self) -> Option<u32>;
+ fn get_cellspacing(self) -> Option<u32>;
+ fn get_width(self) -> LengthOrPercentageOrAuto;
}
-impl HTMLTableElementLayoutHelpers for LayoutJS<HTMLTableElement> {
- #[allow(unsafe_code)]
- fn get_background_color(&self) -> Option<RGBA> {
- unsafe {
- (*self.upcast::<Element>().unsafe_get())
- .get_attr_for_layout(&ns!(), &local_name!("bgcolor"))
- .and_then(AttrValue::as_color)
- .cloned()
- }
+impl HTMLTableElementLayoutHelpers for LayoutDom<'_, HTMLTableElement> {
+ fn get_background_color(self) -> Option<RGBA> {
+ self.upcast::<Element>()
+ .get_attr_for_layout(&ns!(), &local_name!("bgcolor"))
+ .and_then(AttrValue::as_color)
+ .cloned()
}
#[allow(unsafe_code)]
- fn get_border(&self) -> Option<u32> {
- unsafe {
- (*self.unsafe_get()).border.get()
- }
+ fn get_border(self) -> Option<u32> {
+ unsafe { (*self.unsafe_get()).border.get() }
}
#[allow(unsafe_code)]
- fn get_cellspacing(&self) -> Option<u32> {
- unsafe {
- (*self.unsafe_get()).cellspacing.get()
- }
+ fn get_cellspacing(self) -> Option<u32> {
+ unsafe { (*self.unsafe_get()).cellspacing.get() }
}
- #[allow(unsafe_code)]
- fn get_width(&self) -> LengthOrPercentageOrAuto {
- unsafe {
- (*self.upcast::<Element>().unsafe_get())
- .get_attr_for_layout(&ns!(), &local_name!("width"))
- .map(AttrValue::as_dimension)
- .cloned()
- .unwrap_or(LengthOrPercentageOrAuto::Auto)
- }
+ fn get_width(self) -> LengthOrPercentageOrAuto {
+ self.upcast::<Element>()
+ .get_attr_for_layout(&ns!(), &local_name!("width"))
+ .map(AttrValue::as_dimension)
+ .cloned()
+ .unwrap_or(LengthOrPercentageOrAuto::Auto)
}
}
impl VirtualMethods for HTMLTableElement {
- fn super_type(&self) -> Option<&VirtualMethods> {
- Some(self.upcast::<HTMLElement>() as &VirtualMethods)
+ fn super_type(&self) -> Option<&dyn VirtualMethods> {
+ Some(self.upcast::<HTMLElement>() as &dyn VirtualMethods)
}
fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation) {
@@ -426,14 +452,18 @@ impl VirtualMethods for HTMLTableElement {
match *attr.local_name() {
local_name!("border") => {
// According to HTML5 § 14.3.9, invalid values map to 1px.
- self.border.set(mutation.new_value(attr).map(|value| {
- parse_unsigned_integer(value.chars()).unwrap_or(1)
- }));
- }
+ self.border.set(
+ mutation
+ .new_value(attr)
+ .map(|value| parse_unsigned_integer(value.chars()).unwrap_or(1)),
+ );
+ },
local_name!("cellspacing") => {
- self.cellspacing.set(mutation.new_value(attr).and_then(|value| {
- parse_unsigned_integer(value.chars()).ok()
- }));
+ self.cellspacing.set(
+ mutation
+ .new_value(attr)
+ .and_then(|value| parse_unsigned_integer(value.chars()).ok()),
+ );
},
_ => {},
}
@@ -444,7 +474,10 @@ impl VirtualMethods for HTMLTableElement {
local_name!("border") => AttrValue::from_u32(value.into(), 1),
local_name!("width") => AttrValue::from_nonzero_dimension(value.into()),
local_name!("bgcolor") => AttrValue::from_legacy_color(value.into()),
- _ => self.super_type().unwrap().parse_plain_attribute(local_name, value),
+ _ => self
+ .super_type()
+ .unwrap()
+ .parse_plain_attribute(local_name, value),
}
}
}