Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement cells, rows, cellIndex IDL attributes and insertRow, deleteRow, insertCell, deleteCell, and cellIndex IDL methods for tabular data #6936

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

@@ -3,8 +3,16 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use dom::attr::{Attr, AttrHelpers, AttrValue};
use dom::bindings::codegen::Bindings::HTMLCollectionBinding::HTMLCollectionMethods;
use dom::bindings::codegen::Bindings::HTMLTableCellElementBinding::HTMLTableCellElementMethods;
use dom::bindings::codegen::InheritTypes::{HTMLElementCast, HTMLTableCellElementDerived};
use dom::bindings::codegen::Bindings::HTMLTableRowElementBinding::HTMLTableRowElementMethods;
use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
use dom::bindings::codegen::InheritTypes::ElementCast;
use dom::bindings::codegen::InheritTypes::HTMLElementCast;
use dom::bindings::codegen::InheritTypes::HTMLTableCellElementDerived;
use dom::bindings::codegen::InheritTypes::HTMLTableRowElementCast;
use dom::bindings::codegen::InheritTypes::NodeCast;
use dom::bindings::js::Root;
use dom::document::Document;
use dom::element::ElementTypeId;
use dom::eventtarget::{EventTarget, EventTargetTypeId};
@@ -79,6 +87,21 @@ impl<'a> HTMLTableCellElementMethods for &'a HTMLTableCellElement {
// https://html.spec.whatwg.org/multipage/#dom-tdth-colspan
make_uint_getter!(ColSpan, "colspan", DEFAULT_COLSPAN);
make_uint_setter!(SetColSpan, "colspan");

// https://html.spec.whatwg.org/multipage/#dom-tdth-cellindex
fn CellIndex(self) -> i32 {
if let Some(tr) = NodeCast::from_ref(self).GetParentNode() {
if let Some(tr) = HTMLTableRowElementCast::to_root(tr) {
let this = Some(Root::from_ref(ElementCast::from_ref(self)));
for i in 0..tr.Cells().Length() {
if tr.Cells().Item(i) == this {
return i as i32;
}
}
}
}
return -1;
}
}

pub trait HTMLTableCellElementHelpers {
@@ -6,9 +6,12 @@ use dom::attr::{Attr, AttrHelpers, AttrValue};
use dom::bindings::codegen::Bindings::HTMLTableElementBinding;
use dom::bindings::codegen::Bindings::HTMLTableElementBinding::HTMLTableElementMethods;
use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
use dom::bindings::codegen::InheritTypes::ElementCast;
use dom::bindings::codegen::InheritTypes::HTMLElementCast;
use dom::bindings::codegen::InheritTypes::HTMLTableCaptionElementCast;
use dom::bindings::codegen::InheritTypes::HTMLTableElementDerived;
use dom::bindings::codegen::InheritTypes::HTMLTableSectionElementDerived;
use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLElementCast, HTMLTableCaptionElementCast};
use dom::bindings::codegen::InheritTypes::{HTMLTableElementDerived, NodeCast};
use dom::bindings::codegen::InheritTypes::NodeCast;
use dom::bindings::js::{Root, RootedReference};
use dom::document::Document;
use dom::element::{ElementHelpers, ElementTypeId};
@@ -72,9 +75,7 @@ impl<'a> HTMLTableElementMethods for &'a HTMLTableElement {
fn GetCaption(self) -> Option<Root<HTMLTableCaptionElement>> {
let node = NodeCast::from_ref(self);
node.children()
.filter_map(|c| {
HTMLTableCaptionElementCast::to_ref(c.r()).map(Root::from_ref)
})
.filter_map(HTMLTableCaptionElementCast::to_root)
.next()
}

@@ -93,8 +94,8 @@ impl<'a> HTMLTableElementMethods for &'a HTMLTableElement {
}

// https://html.spec.whatwg.org/multipage/#dom-table-createcaption
fn CreateCaption(self) -> Root<HTMLElement> {
let caption = match self.GetCaption() {
fn CreateCaption(self) -> Root<HTMLTableCaptionElement> {
match self.GetCaption() {
Some(caption) => caption,
None => {
let caption = HTMLTableCaptionElement::new("caption".to_owned(),
@@ -103,8 +104,7 @@ impl<'a> HTMLTableElementMethods for &'a HTMLTableElement {
self.SetCaption(Some(caption.r()));
caption
}
};
HTMLElementCast::from_root(caption)
}
}

// https://html.spec.whatwg.org/multipage/#dom-table-deletecaption
@@ -3,24 +3,45 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use dom::attr::{Attr, AttrHelpers};
use dom::bindings::codegen::Bindings::HTMLCollectionBinding::HTMLCollectionMethods;
use dom::bindings::codegen::Bindings::HTMLTableRowElementBinding;
use dom::bindings::codegen::InheritTypes::{HTMLElementCast, HTMLTableRowElementDerived};
use dom::bindings::js::Root;
use dom::bindings::codegen::Bindings::HTMLTableRowElementBinding::HTMLTableRowElementMethods;
use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
use dom::bindings::codegen::InheritTypes::HTMLElementCast;
use dom::bindings::codegen::InheritTypes::HTMLTableDataCellElementDerived;
use dom::bindings::codegen::InheritTypes::HTMLTableHeaderCellElementDerived;
use dom::bindings::codegen::InheritTypes::HTMLTableRowElementDerived;
use dom::bindings::codegen::InheritTypes::NodeCast;
use dom::bindings::error::Error::IndexSize;
use dom::bindings::error::{ErrorResult, Fallible};
use dom::bindings::js::{JS, MutNullableHeap, Root, RootedReference};
use dom::document::Document;
use dom::element::ElementTypeId;
use dom::element::{Element, ElementTypeId};
use dom::eventtarget::{EventTarget, EventTargetTypeId};
use dom::htmlcollection::{CollectionFilter, HTMLCollection};
use dom::htmlelement::{HTMLElement, HTMLElementTypeId};
use dom::node::{Node, NodeTypeId};
use dom::htmltabledatacellelement::HTMLTableDataCellElement;
use dom::node::{Node, NodeHelpers, NodeTypeId, window_from_node};
use dom::virtualmethods::VirtualMethods;

use cssparser::RGBA;
use std::cell::Cell;
use util::str::{self, DOMString};

#[derive(JSTraceable)]
struct CellsFilter;
impl CollectionFilter for CellsFilter {
fn filter(&self, elem: &Element, root: &Node) -> bool {
(elem.is_htmltableheadercellelement() || elem.is_htmltabledatacellelement())
&& NodeCast::from_ref(elem).GetParentNode().r() == Some(root)
}
}

#[dom_struct]
#[derive(HeapSizeOf)]
pub struct HTMLTableRowElement {
htmlelement: HTMLElement,
cells: MutNullableHeap<JS<HTMLCollection>>,
background_color: Cell<Option<RGBA>>,
}

@@ -40,6 +61,7 @@ impl HTMLTableRowElement {
localName,
prefix,
document),
cells: Default::default(),
background_color: Cell::new(None),
}
}
@@ -64,6 +86,50 @@ impl<'a> HTMLTableRowElementHelpers for &'a HTMLTableRowElement {
}
}

impl <'a> HTMLTableRowElementMethods for &'a HTMLTableRowElement {
// https://html.spec.whatwg.org/multipage/#dom-tr-cells
fn Cells(self) -> Root<HTMLCollection> {
self.cells.or_init(|| {
let window = window_from_node(self);
let filter = box CellsFilter;
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>> {
if index < -1 || index > self.Cells().Length() as i32 {
return Err(IndexSize);
}

let this = NodeCast::from_ref(self);
let td = HTMLTableDataCellElement::new("td".to_owned(), None, this.owner_doc().r());
if index == -1 || index == self.Cells().Length() as i32 {
try!(this.AppendChild(NodeCast::from_ref(td.r())));
} else {
let reference = NodeCast::from_root(self.Cells().Item(index as u32).unwrap());
try!(this.InsertBefore(NodeCast::from_ref(td.r()), Some(reference.r())));
}
Ok(HTMLElementCast::from_root(td))
}

// https://html.spec.whatwg.org/multipage/#dom-tr-deletecell
fn DeleteCell(self, index: i32) -> ErrorResult {
if index < -1 || index >= self.Cells().Length() as i32 {
return Err(IndexSize);
}

let index = if index == -1 {
self.Cells().Length() as i32 - 1
} else {
index
};

NodeCast::from_ref(self.Cells().Item(index as u32).unwrap().r()).remove_self();
Ok(())
}
}

impl<'a> VirtualMethods for &'a HTMLTableRowElement {
fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> {
let htmlelement: &&HTMLElement = HTMLElementCast::from_borrowed_ref(self);
@@ -3,24 +3,42 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use dom::attr::{Attr, AttrHelpers};
use dom::bindings::codegen::Bindings::HTMLCollectionBinding::HTMLCollectionMethods;
use dom::bindings::codegen::Bindings::HTMLTableSectionElementBinding;
use dom::bindings::codegen::Bindings::HTMLTableSectionElementBinding::HTMLTableSectionElementMethods;
use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
use dom::bindings::codegen::InheritTypes::{HTMLElementCast, HTMLTableSectionElementDerived};
use dom::bindings::js::Root;
use dom::bindings::codegen::InheritTypes::{HTMLTableRowElementDerived, NodeCast};
use dom::bindings::error::Error::IndexSize;
use dom::bindings::error::{ErrorResult, Fallible};
use dom::bindings::js::{JS, MutNullableHeap, Root, RootedReference};
use dom::document::Document;
use dom::element::ElementTypeId;
use dom::element::{Element, ElementTypeId};
use dom::eventtarget::{EventTarget, EventTargetTypeId};
use dom::htmlcollection::{CollectionFilter, HTMLCollection};
use dom::htmlelement::{HTMLElement, HTMLElementTypeId};
use dom::node::{Node, NodeTypeId};
use dom::htmltablerowelement::HTMLTableRowElement;
use dom::node::{Node, NodeHelpers, NodeTypeId, window_from_node};
use dom::virtualmethods::VirtualMethods;

use cssparser::RGBA;
use std::cell::Cell;
use util::str::{self, DOMString};

#[derive(JSTraceable)]
struct RowsFilter;
impl CollectionFilter for RowsFilter {
fn filter(&self, elem: &Element, root: &Node) -> bool {
elem.is_htmltablerowelement()
&& NodeCast::from_ref(elem).GetParentNode().r() == Some(root)
}
}

#[dom_struct]
#[derive(HeapSizeOf)]
pub struct HTMLTableSectionElement {
htmlelement: HTMLElement,
rows: MutNullableHeap<JS<HTMLCollection>>,
background_color: Cell<Option<RGBA>>,
}

@@ -40,6 +58,7 @@ impl HTMLTableSectionElement {
localName,
prefix,
document),
rows: Default::default(),
background_color: Cell::new(None),
}
}
@@ -62,6 +81,50 @@ impl<'a> HTMLTableSectionElementHelpers for &'a HTMLTableSectionElement {
}
}

impl <'a> HTMLTableSectionElementMethods for &'a HTMLTableSectionElement {
// https://html.spec.whatwg.org/multipage/#dom-tbody-rows
fn Rows(self) -> Root<HTMLCollection> {
self.rows.or_init(|| {
let window = window_from_node(self);
let filter = box RowsFilter;
HTMLCollection::create(window.r(), NodeCast::from_ref(self), filter)
})
}

// https://html.spec.whatwg.org/multipage/#dom-tbody-insertrow
fn InsertRow(self, index: i32) -> Fallible<Root<HTMLElement>> {
if index < -1 || index > self.Rows().Length() as i32 {
return Err(IndexSize);
}

let this = NodeCast::from_ref(self);
let tr = HTMLTableRowElement::new("tr".to_owned(), None, this.owner_doc().r());
if index == -1 || index == self.Rows().Length() as i32 {
try!(this.AppendChild(NodeCast::from_ref(tr.r())));
} else {
let reference = NodeCast::from_root(self.Rows().Item(index as u32).unwrap());
try!(this.InsertBefore(NodeCast::from_ref(tr.r()), Some(reference.r())));
}
Ok(HTMLElementCast::from_root(tr))
}

// https://html.spec.whatwg.org/multipage/#dom-tr-deletecell
fn DeleteRow(self, index: i32) -> ErrorResult {
if index < -1 || index >= self.Rows().Length() as i32 {
return Err(IndexSize);
}

let index = if index == -1 {
self.Rows().Length() as i32 - 1
} else {
index
};

NodeCast::from_ref(self.Rows().Item(index as u32).unwrap().r()).remove_self();
Ok(())
}
}

impl<'a> VirtualMethods for &'a HTMLTableSectionElement {
fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> {
let htmlelement: &&HTMLElement = HTMLElementCast::from_borrowed_ref(self);
@@ -8,7 +8,7 @@ interface HTMLTableCellElement : HTMLElement {
attribute unsigned long colSpan;
// attribute unsigned long rowSpan;
//[PutForwards=value] readonly attribute DOMSettableTokenList headers;
//readonly attribute long cellIndex;
readonly attribute long cellIndex;

// also has obsolete members
};
@@ -6,7 +6,7 @@
// https://www.whatwg.org/html/#htmltableelement
interface HTMLTableElement : HTMLElement {
attribute HTMLTableCaptionElement? caption;
HTMLElement createCaption();
HTMLTableCaptionElement createCaption();

This comment has been minimized.

This comment has been minimized.

@dzbarsky

dzbarsky Oct 5, 2015

Author Member

It lets us get rid of the HTMLElementCasts, and it doesn't really matter what type you declare as being returned in the IDL, what matters is the properties/methods on the type actually returned.

This comment has been minimized.

@dzbarsky

dzbarsky Oct 5, 2015

Author Member

We can probably file a spec bug for this if we care

This comment has been minimized.

@nox

nox Oct 5, 2015

Member

I would rather keep the casts for now.

void deleteCaption();
// attribute HTMLTableSectionElement? tHead;
//HTMLElement createTHead();
@@ -7,9 +7,11 @@
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);
readonly attribute HTMLCollection cells;
[Throws]
HTMLElement insertCell(optional long index = -1);
[Throws]
void deleteCell(long index);

// also has obsolete members
};
@@ -5,9 +5,11 @@

// https://www.whatwg.org/html/#htmltablesectionelement
interface HTMLTableSectionElement : HTMLElement {
//readonly attribute HTMLCollection rows;
//HTMLElement insertRow(optional long index = -1);
//void deleteRow(long index);
readonly attribute HTMLCollection rows;
[Throws]
HTMLElement insertRow(optional long index = -1);
[Throws]
void deleteRow(long index);

// also has obsolete members
};
"path": "html/semantics/tabular-data/the-table-element/table-rows.html",
"url": "/html/semantics/tabular-data/the-table-element/table-rows.html"
},
{
"path": "html/semantics/tabular-data/the-tbody-element/rows.html",
"url": "/html/semantics/tabular-data/the-tbody-element/rows.html"
},
{
"path": "html/semantics/tabular-data/the-tbody-element/deleteRow.html",
"url": "/html/semantics/tabular-data/the-tbody-element/deleteRow.html"
"path": "html/semantics/tabular-data/the-tbody-element/insertRow.html",
"url": "/html/semantics/tabular-data/the-tbody-element/insertRow.html"
},
{
"path": "html/semantics/tabular-data/the-tr-element/cells.html",
"url": "/html/semantics/tabular-data/the-tr-element/cells.html"
},
{
"path": "html/semantics/tabular-data/the-tr-element/deleteCell.html",
"url": "/html/semantics/tabular-data/the-tr-element/deleteCell.html"
"rev": "acd60f9e55532f03fc905e61591b7fd7db2f08d1",
"url_base": "/",
"version": 2
}
}
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.