diff options
Diffstat (limited to 'components/script/dom')
-rw-r--r-- | components/script/dom/element.rs | 61 | ||||
-rw-r--r-- | components/script/dom/htmltablecellelement.rs | 25 | ||||
-rw-r--r-- | components/script/dom/htmltableelement.rs | 77 | ||||
-rw-r--r-- | components/script/dom/virtualmethods.rs | 8 |
4 files changed, 151 insertions, 20 deletions
diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs index 1e55f9f73c2..db2b8d3d096 100644 --- a/components/script/dom/element.rs +++ b/components/script/dom/element.rs @@ -15,8 +15,10 @@ use dom::bindings::codegen::Bindings::ElementBinding::ElementMethods; use dom::bindings::codegen::Bindings::EventBinding::EventMethods; use dom::bindings::codegen::Bindings::HTMLInputElementBinding::HTMLInputElementMethods; use dom::bindings::codegen::Bindings::NamedNodeMapBinding::NamedNodeMapMethods; -use dom::bindings::codegen::InheritTypes::{ElementDerived, HTMLInputElementDerived, HTMLTableCellElementDerived}; -use dom::bindings::codegen::InheritTypes::{HTMLInputElementCast, NodeCast, EventTargetCast, ElementCast}; +use dom::bindings::codegen::InheritTypes::{ElementCast, ElementDerived, EventTargetCast}; +use dom::bindings::codegen::InheritTypes::{HTMLInputElementCast, HTMLInputElementDerived}; +use dom::bindings::codegen::InheritTypes::{HTMLTableElementCast, HTMLTableElementDerived}; +use dom::bindings::codegen::InheritTypes::{HTMLTableCellElementDerived, NodeCast}; use dom::bindings::js::{MutNullableJS, JS, JSRef, Temporary, TemporaryPushable}; use dom::bindings::js::{OptionalRootable, Root}; use dom::bindings::utils::{Reflectable, Reflector}; @@ -32,14 +34,16 @@ use dom::eventtarget::{EventTarget, NodeTargetTypeId, EventTargetHelpers}; use dom::htmlcollection::HTMLCollection; use dom::htmlinputelement::{HTMLInputElement, RawLayoutHTMLInputElementHelpers}; use dom::htmlserializer::serialize; +use dom::htmltableelement::{HTMLTableElement, HTMLTableElementHelpers}; use dom::htmltablecellelement::{HTMLTableCellElement, HTMLTableCellElementHelpers}; -use dom::node::{CLICK_IN_PROGRESS, ElementNodeTypeId, Node, NodeHelpers, NodeIterator}; -use dom::node::{document_from_node, window_from_node, LayoutNodeHelpers, NodeStyleDamaged}; -use dom::node::{OtherNodeDamage}; +use dom::node::{CLICK_IN_PROGRESS, ElementNodeTypeId, LayoutNodeHelpers, Node, NodeHelpers}; +use dom::node::{NodeIterator, NodeStyleDamaged, OtherNodeDamage, document_from_node}; +use dom::node::{window_from_node}; use dom::nodelist::NodeList; use dom::virtualmethods::{VirtualMethods, vtable_for}; use devtools_traits::AttrInfo; -use style::{IntegerAttribute, LengthAttribute, SizeIntegerAttribute, WidthLengthAttribute}; +use style::{BorderUnsignedIntegerAttribute, IntegerAttribute, LengthAttribute}; +use style::{SizeIntegerAttribute, UnsignedIntegerAttribute, WidthLengthAttribute}; use style::{matches, parse_selector_list_from_str}; use style; use servo_util::namespace; @@ -201,6 +205,8 @@ pub trait RawLayoutElementHelpers { unsafe fn get_integer_attribute_for_layout(&self, integer_attribute: IntegerAttribute) -> Option<i32>; unsafe fn get_checked_state_for_layout(&self) -> bool; + unsafe fn get_unsigned_integer_attribute_for_layout(&self, attribute: UnsignedIntegerAttribute) + -> Option<u32>; fn local_name<'a>(&'a self) -> &'a Atom; fn namespace<'a>(&'a self) -> &'a Namespace; fn style_attribute<'a>(&'a self) -> &'a DOMRefCell<Option<style::PropertyDeclarationBlock>>; @@ -285,11 +291,15 @@ impl RawLayoutElementHelpers for Element { -> LengthOrPercentageOrAuto { match length_attribute { WidthLengthAttribute => { - if !self.is_htmltablecellelement() { - panic!("I'm not a table cell!") + if self.is_htmltableelement() { + let this: &HTMLTableElement = mem::transmute(self); + this.get_width() + } else if self.is_htmltablecellelement() { + let this: &HTMLTableCellElement = mem::transmute(self); + this.get_width() + } else { + panic!("I'm not a table or table cell!") } - let this: &HTMLTableCellElement = mem::transmute(self); - this.get_width() } } } @@ -319,6 +329,26 @@ impl RawLayoutElementHelpers for Element { this.get_checked_state_for_layout() } + unsafe fn get_unsigned_integer_attribute_for_layout(&self, + attribute: UnsignedIntegerAttribute) + -> Option<u32> { + match attribute { + BorderUnsignedIntegerAttribute => { + if self.is_htmltableelement() { + let this: &HTMLTableElement = mem::transmute(self); + this.get_border() + } else if self.is_htmltablecellelement() { + let this: &HTMLTableCellElement = mem::transmute(self); + this.get_border() + } else { + // Don't panic since `:-servo-nonzero-border` can cause this to be called on + // arbitrary elements. + None + } + } + } + } + // Getters used in components/layout/wrapper.rs fn local_name<'a>(&'a self) -> &'a Atom { @@ -1222,6 +1252,17 @@ impl<'a> style::TElement<'a> for JSRef<'a, Element> { } } } + fn has_nonzero_border(self) -> bool { + match HTMLTableElementCast::to_ref(self) { + None => false, + Some(this) => { + match this.get_border() { + None | Some(0) => false, + Some(_) => true, + } + } + } + } } pub trait ActivationElementHelpers<'a> { diff --git a/components/script/dom/htmltablecellelement.rs b/components/script/dom/htmltablecellelement.rs index cee07540301..622389397e9 100644 --- a/components/script/dom/htmltablecellelement.rs +++ b/components/script/dom/htmltablecellelement.rs @@ -2,8 +2,7 @@ * 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/. */ -use dom::attr::Attr; -use dom::attr::AttrHelpers; +use dom::attr::{Attr, AttrHelpers}; use dom::bindings::codegen::InheritTypes::{HTMLElementCast, HTMLTableCellElementDerived}; use dom::bindings::js::JSRef; use dom::bindings::utils::{Reflectable, Reflector}; @@ -22,6 +21,7 @@ use std::cell::Cell; #[dom_struct] pub struct HTMLTableCellElement { htmlelement: HTMLElement, + border: Cell<Option<u32>>, width: Cell<LengthOrPercentageOrAuto>, } @@ -36,10 +36,15 @@ impl HTMLTableCellElementDerived for EventTarget { } impl HTMLTableCellElement { - pub fn new_inherited(type_id: ElementTypeId, tag_name: DOMString, prefix: Option<DOMString>, document: JSRef<Document>) -> HTMLTableCellElement { + pub fn new_inherited(type_id: ElementTypeId, + tag_name: DOMString, + prefix: Option<DOMString>, + document: JSRef<Document>) + -> HTMLTableCellElement { HTMLTableCellElement { htmlelement: HTMLElement::new_inherited(type_id, tag_name, prefix, document), - width: Cell::new(AutoLpa) + border: Cell::new(None), + width: Cell::new(AutoLpa), } } @@ -50,10 +55,15 @@ impl HTMLTableCellElement { } pub trait HTMLTableCellElementHelpers { + fn get_border(&self) -> Option<u32>; fn get_width(&self) -> LengthOrPercentageOrAuto; } impl HTMLTableCellElementHelpers for HTMLTableCellElement { + fn get_border(&self) -> Option<u32> { + self.border.get() + } + fn get_width(&self) -> LengthOrPercentageOrAuto { self.width.get() } @@ -72,6 +82,12 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLTableCellElement> { } match attr.local_name() { + &atom!("border") => { + // According to HTML5 § 14.3.9, invalid values map to 1px. + self.border.set(Some(str::parse_unsigned_integer(attr.value() + .as_slice() + .chars()).unwrap_or(1))) + } &atom!("width") => self.width.set(str::parse_length(attr.value().as_slice())), _ => () } @@ -84,6 +100,7 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLTableCellElement> { } match attr.local_name() { + &atom!("border") => self.border.set(None), &atom!("width") => self.width.set(AutoLpa), _ => () } diff --git a/components/script/dom/htmltableelement.rs b/components/script/dom/htmltableelement.rs index 7dddf98bdc4..9a7acd02559 100644 --- a/components/script/dom/htmltableelement.rs +++ b/components/script/dom/htmltableelement.rs @@ -2,10 +2,12 @@ * 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/. */ -use dom::bindings::codegen::Bindings::HTMLTableElementBinding; +use dom::attr::{Attr, AttrHelpers}; use dom::bindings::codegen::Bindings::HTMLTableElementBinding::HTMLTableElementMethods; -use dom::bindings::codegen::InheritTypes::{HTMLTableElementDerived, NodeCast, HTMLTableCaptionElementCast}; +use dom::bindings::codegen::Bindings::HTMLTableElementBinding; use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods; +use dom::bindings::codegen::InheritTypes::{HTMLElementCast, HTMLTableCaptionElementCast}; +use dom::bindings::codegen::InheritTypes::{HTMLTableElementDerived, NodeCast}; use dom::bindings::js::{JSRef, Temporary}; use dom::bindings::utils::{Reflectable, Reflector}; use dom::document::Document; @@ -14,11 +16,16 @@ use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlelement::HTMLElement; use dom::htmltablecaptionelement::HTMLTableCaptionElement; use dom::node::{Node, NodeHelpers, ElementNodeTypeId}; -use servo_util::str::DOMString; +use dom::virtualmethods::VirtualMethods; + +use servo_util::str::{mod, AutoLpa, DOMString, LengthOrPercentageOrAuto}; +use std::cell::Cell; #[dom_struct] pub struct HTMLTableElement { htmlelement: HTMLElement, + border: Cell<Option<u32>>, + width: Cell<LengthOrPercentageOrAuto>, } impl HTMLTableElementDerived for EventTarget { @@ -28,14 +35,21 @@ impl HTMLTableElementDerived for EventTarget { } impl HTMLTableElement { - fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: JSRef<Document>) -> HTMLTableElement { + fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: JSRef<Document>) + -> HTMLTableElement { HTMLTableElement { - htmlelement: HTMLElement::new_inherited(HTMLTableElementTypeId, localName, prefix, document) + htmlelement: HTMLElement::new_inherited(HTMLTableElementTypeId, + localName, + prefix, + document), + border: Cell::new(None), + width: Cell::new(AutoLpa), } } #[allow(unrooted_must_root)] - pub fn new(localName: DOMString, prefix: Option<DOMString>, document: JSRef<Document>) -> Temporary<HTMLTableElement> { + pub fn new(localName: DOMString, prefix: Option<DOMString>, document: JSRef<Document>) + -> Temporary<HTMLTableElement> { let element = HTMLTableElement::new_inherited(localName, prefix, document); Node::reflect_node(box element, document, HTMLTableElementBinding::Wrap) } @@ -77,3 +91,54 @@ impl<'a> HTMLTableElementMethods for JSRef<'a, HTMLTableElement> { }); } } + +pub trait HTMLTableElementHelpers { + fn get_border(&self) -> Option<u32>; + fn get_width(&self) -> LengthOrPercentageOrAuto; +} + +impl HTMLTableElementHelpers for HTMLTableElement { + fn get_border(&self) -> Option<u32> { + self.border.get() + } + fn get_width(&self) -> LengthOrPercentageOrAuto { + self.width.get() + } +} + +impl<'a> VirtualMethods for JSRef<'a, HTMLTableElement> { + fn super_type<'a>(&'a self) -> Option<&'a VirtualMethods> { + let htmlelement: &JSRef<HTMLElement> = HTMLElementCast::from_borrowed_ref(self); + Some(htmlelement as &VirtualMethods) + } + + fn after_set_attr(&self, attr: JSRef<Attr>) { + match self.super_type() { + Some(ref s) => s.after_set_attr(attr), + _ => () + } + + match attr.local_name() { + &atom!("border") => { + // According to HTML5 § 14.3.9, invalid values map to 1px. + self.border.set(Some(str::parse_unsigned_integer(attr.value() + .as_slice() + .chars()).unwrap_or(1))) + } + _ => () + } + } + + fn before_remove_attr(&self, attr: JSRef<Attr>) { + match self.super_type() { + Some(ref s) => s.before_remove_attr(attr), + _ => () + } + + match attr.local_name() { + &atom!("border") => self.border.set(None), + _ => () + } + } +} + diff --git a/components/script/dom/virtualmethods.rs b/components/script/dom/virtualmethods.rs index a90055bc50d..2f75127c513 100644 --- a/components/script/dom/virtualmethods.rs +++ b/components/script/dom/virtualmethods.rs @@ -22,6 +22,7 @@ use dom::bindings::codegen::InheritTypes::HTMLOptionElementCast; use dom::bindings::codegen::InheritTypes::HTMLScriptElementCast; use dom::bindings::codegen::InheritTypes::HTMLSelectElementCast; use dom::bindings::codegen::InheritTypes::HTMLStyleElementCast; +use dom::bindings::codegen::InheritTypes::HTMLTableElementCast; use dom::bindings::codegen::InheritTypes::HTMLTableCellElementCast; use dom::bindings::codegen::InheritTypes::HTMLTextAreaElementCast; use dom::bindings::codegen::InheritTypes::HTMLTitleElementCast; @@ -46,6 +47,7 @@ use dom::element::HTMLScriptElementTypeId; use dom::element::HTMLSelectElementTypeId; use dom::element::HTMLStyleElementTypeId; use dom::element::HTMLTableDataCellElementTypeId; +use dom::element::HTMLTableElementTypeId; use dom::element::HTMLTableHeaderCellElementTypeId; use dom::element::HTMLTextAreaElementTypeId; use dom::element::HTMLTitleElementTypeId; @@ -67,6 +69,7 @@ use dom::htmloptionelement::HTMLOptionElement; use dom::htmlscriptelement::HTMLScriptElement; use dom::htmlselectelement::HTMLSelectElement; use dom::htmlstyleelement::HTMLStyleElement; +use dom::htmltableelement::HTMLTableElement; use dom::htmltablecellelement::HTMLTableCellElement; use dom::htmltextareaelement::HTMLTextAreaElement; use dom::htmltitleelement::HTMLTitleElement; @@ -226,6 +229,11 @@ pub fn vtable_for<'a>(node: &'a JSRef<'a, Node>) -> &'a VirtualMethods + 'a { let element: &'a JSRef<'a, HTMLStyleElement> = HTMLStyleElementCast::to_borrowed_ref(node).unwrap(); element as &'a VirtualMethods + 'a } + ElementNodeTypeId(HTMLTableElementTypeId) => { + let element: &'a JSRef<'a, HTMLTableElement> = + HTMLTableElementCast::to_borrowed_ref(node).unwrap(); + element as &'a VirtualMethods + 'a + } ElementNodeTypeId(HTMLTableDataCellElementTypeId) | ElementNodeTypeId(HTMLTableHeaderCellElementTypeId) => { let element: &'a JSRef<'a, HTMLTableCellElement> = HTMLTableCellElementCast::to_borrowed_ref(node).unwrap(); |