diff options
author | bors-servo <metajack+bors@gmail.com> | 2014-12-15 19:33:46 -0700 |
---|---|---|
committer | bors-servo <metajack+bors@gmail.com> | 2014-12-15 19:33:46 -0700 |
commit | 8e31e5f98747e4b42dafcc4b076fac46aeb09310 (patch) | |
tree | e7797b853ac10f987b3623fd184bb515cc6bdadd /components/script | |
parent | 88ec52dd617bafe384553ef38325c552fb4f1e23 (diff) | |
parent | a1ea44b294e73f4397887fe806fc5bc95499efda (diff) | |
download | servo-8e31e5f98747e4b42dafcc4b076fac46aeb09310.tar.gz servo-8e31e5f98747e4b42dafcc4b076fac46aeb09310.zip |
auto merge of #4289 : pcwalton/servo/hacker-news, r=SimonSapin
This patch provides some of the groundwork for column spans greater than
1. It implements the column-span CSS property as well as the
corresponding colspan attribute; although the former is not
well-specified outside of CSS multi-column layout, INTRINSIC refers to
it. Although width is distributed to spanning columns, they do not yet
contribute minimum and preferred widths; this will be implemented in a
follow-up.
The parsing for the legacy bgcolor and border attributes is
implemented according to the WHATWG HTML specification.
Additionally, this patch cleans up some miscellaneous formatting issues,
refactors layout/css somewhat to eliminate needless levels of
indirection, and cleans up the handling of table rowgroups.
New Hacker News screenshot: http://i.imgur.com/hnl2a7E.png
Diffstat (limited to 'components/script')
-rw-r--r-- | components/script/dom/bindings/trace.rs | 4 | ||||
-rw-r--r-- | components/script/dom/document.rs | 10 | ||||
-rw-r--r-- | components/script/dom/element.rs | 113 | ||||
-rw-r--r-- | components/script/dom/htmlbodyelement.rs | 54 | ||||
-rw-r--r-- | components/script/dom/htmltablecellelement.rs | 37 | ||||
-rw-r--r-- | components/script/dom/htmltableelement.rs | 92 | ||||
-rw-r--r-- | components/script/dom/htmltablerowelement.rs | 63 | ||||
-rw-r--r-- | components/script/dom/htmltablesectionelement.rs | 66 | ||||
-rw-r--r-- | components/script/dom/node.rs | 18 | ||||
-rw-r--r-- | components/script/dom/virtualmethods.rs | 27 | ||||
-rw-r--r-- | components/script/layout_interface.rs | 3 |
11 files changed, 436 insertions, 51 deletions
diff --git a/components/script/dom/bindings/trace.rs b/components/script/dom/bindings/trace.rs index afd329137c0..b877d022c2e 100644 --- a/components/script/dom/bindings/trace.rs +++ b/components/script/dom/bindings/trace.rs @@ -32,6 +32,7 @@ use dom::bindings::utils::{Reflectable, Reflector, WindowProxyHandler}; use dom::node::{Node, TrustedNodeAddress}; use collections::hash::{Hash, Hasher}; +use cssparser::RGBA; use geom::rect::Rect; use html5ever::tree_builder::QuirksMode; use hyper::header::Headers; @@ -48,7 +49,7 @@ use script_traits::UntrustedNodeAddress; use servo_msg::compositor_msg::ScriptListener; use servo_msg::constellation_msg::ConstellationChan; use servo_util::smallvec::{SmallVec1, SmallVec}; -use servo_util::str::LengthOrPercentageOrAuto; +use servo_util::str::{LengthOrPercentageOrAuto}; use std::cell::{Cell, RefCell}; use std::collections::HashMap; use std::comm::{Receiver, Sender}; @@ -214,6 +215,7 @@ no_jsmanaged_fields!(LayoutChan) no_jsmanaged_fields!(WindowProxyHandler) no_jsmanaged_fields!(UntrustedNodeAddress) no_jsmanaged_fields!(LengthOrPercentageOrAuto) +no_jsmanaged_fields!(RGBA) impl<'a> JSTraceable for &'a str { #[inline] diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index c4dc787ac26..4fdb8a9befd 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -61,6 +61,7 @@ use servo_util::namespace; use servo_util::str::{DOMString, split_html_space_chars}; use html5ever::tree_builder::{QuirksMode, NoQuirks, LimitedQuirks, Quirks}; +use layout_interface::{LayoutChan, SetQuirksModeMsg}; use string_cache::{Atom, QualName}; use url::Url; @@ -217,6 +218,15 @@ impl<'a> DocumentHelpers<'a> for JSRef<'a, Document> { fn set_quirks_mode(self, mode: QuirksMode) { self.quirks_mode.set(mode); + + match mode { + Quirks => { + let window = self.window.root(); + let LayoutChan(ref layout_chan) = window.page().layout_chan; + layout_chan.send(SetQuirksModeMsg); + } + NoQuirks | LimitedQuirks => {} + } } fn set_last_modified(self, value: DOMString) { diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs index 1e55f9f73c2..69846d40543 100644 --- a/components/script/dom/element.rs +++ b/components/script/dom/element.rs @@ -15,8 +15,12 @@ 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::{HTMLBodyElementDerived, HTMLInputElementCast}; +use dom::bindings::codegen::InheritTypes::{HTMLInputElementDerived, HTMLTableElementCast}; +use dom::bindings::codegen::InheritTypes::{HTMLTableElementDerived, HTMLTableCellElementDerived}; +use dom::bindings::codegen::InheritTypes::{HTMLTableRowElementDerived}; +use dom::bindings::codegen::InheritTypes::{HTMLTableSectionElementDerived, NodeCast}; use dom::bindings::js::{MutNullableJS, JS, JSRef, Temporary, TemporaryPushable}; use dom::bindings::js::{OptionalRootable, Root}; use dom::bindings::utils::{Reflectable, Reflector}; @@ -29,22 +33,28 @@ use dom::document::{Document, DocumentHelpers, LayoutDocumentHelpers}; use dom::domtokenlist::DOMTokenList; use dom::event::Event; use dom::eventtarget::{EventTarget, NodeTargetTypeId, EventTargetHelpers}; +use dom::htmlbodyelement::{HTMLBodyElement, HTMLBodyElementHelpers}; 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::htmltablerowelement::{HTMLTableRowElement, HTMLTableRowElementHelpers}; +use dom::htmltablesectionelement::{HTMLTableSectionElement, HTMLTableSectionElementHelpers}; +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::{matches, parse_selector_list_from_str}; -use style; +use style::{mod, AuthorOrigin, BgColorSimpleColorAttribute, BorderUnsignedIntegerAttribute}; +use style::{ColSpanUnsignedIntegerAttribute, IntegerAttribute, LengthAttribute, ParserContext}; +use style::{SimpleColorAttribute, SizeIntegerAttribute, UnsignedIntegerAttribute}; +use style::{WidthLengthAttribute, matches}; use servo_util::namespace; use servo_util::str::{DOMString, LengthOrPercentageOrAuto}; +use cssparser::RGBA; use std::ascii::AsciiExt; use std::cell::{Ref, RefMut}; use std::default::Default; @@ -201,6 +211,10 @@ 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>; + unsafe fn get_simple_color_attribute_for_layout(&self, attribute: SimpleColorAttribute) + -> Option<RGBA>; 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 +299,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 +337,61 @@ 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 { + // Don't panic since `:-servo-nonzero-border` can cause this to be called on + // arbitrary elements. + None + } + } + ColSpanUnsignedIntegerAttribute => { + if self.is_htmltablecellelement() { + let this: &HTMLTableCellElement = mem::transmute(self); + this.get_colspan() + } else { + // Don't panic since `display` can cause this to be called on arbitrary + // elements. + None + } + } + } + } + + #[inline] + #[allow(unrooted_must_root)] + unsafe fn get_simple_color_attribute_for_layout(&self, attribute: SimpleColorAttribute) + -> Option<RGBA> { + match attribute { + BgColorSimpleColorAttribute => { + if self.is_htmlbodyelement() { + let this: &HTMLBodyElement = mem::transmute(self); + this.get_background_color() + } else if self.is_htmltableelement() { + let this: &HTMLTableElement = mem::transmute(self); + this.get_background_color() + } else if self.is_htmltablecellelement() { + let this: &HTMLTableCellElement = mem::transmute(self); + this.get_background_color() + } else if self.is_htmltablerowelement() { + let this: &HTMLTableRowElement = mem::transmute(self); + this.get_background_color() + } else if self.is_htmltablesectionelement() { + let this: &HTMLTableSectionElement = mem::transmute(self); + this.get_background_color() + } else { + None + } + } + } + } + // Getters used in components/layout/wrapper.rs fn local_name<'a>(&'a self) -> &'a Atom { @@ -947,7 +1020,10 @@ impl<'a> ElementMethods for JSRef<'a, Element> { // http://dom.spec.whatwg.org/#dom-element-matches fn Matches(self, selectors: DOMString) -> Fallible<bool> { - match parse_selector_list_from_str(selectors.as_slice()) { + let parser_context = ParserContext { + origin: AuthorOrigin, + }; + match style::parse_selector_list_from_str(&parser_context, selectors.as_slice()) { Err(()) => Err(Syntax), Ok(ref selectors) => { let root: JSRef<Node> = NodeCast::from_ref(self); @@ -1222,6 +1298,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/htmlbodyelement.rs b/components/script/dom/htmlbodyelement.rs index d088a6b8626..917b02913a7 100644 --- a/components/script/dom/htmlbodyelement.rs +++ b/components/script/dom/htmlbodyelement.rs @@ -2,11 +2,9 @@ * 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::Bindings::EventHandlerBinding::EventHandlerNonNull; -use dom::bindings::codegen::Bindings::HTMLBodyElementBinding; -use dom::bindings::codegen::Bindings::HTMLBodyElementBinding::HTMLBodyElementMethods; +use dom::bindings::codegen::Bindings::HTMLBodyElementBinding::{mod, HTMLBodyElementMethods}; use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods; use dom::bindings::codegen::InheritTypes::EventTargetCast; use dom::bindings::codegen::InheritTypes::{HTMLBodyElementDerived, HTMLElementCast}; @@ -19,11 +17,14 @@ use dom::htmlelement::HTMLElement; use dom::node::{Node, ElementNodeTypeId, window_from_node}; use dom::virtualmethods::VirtualMethods; -use servo_util::str::DOMString; +use cssparser::RGBA; +use servo_util::str::{mod, DOMString}; +use std::cell::Cell; #[dom_struct] pub struct HTMLBodyElement { - htmlelement: HTMLElement + htmlelement: HTMLElement, + background_color: Cell<Option<RGBA>>, } impl HTMLBodyElementDerived for EventTarget { @@ -33,14 +34,20 @@ impl HTMLBodyElementDerived for EventTarget { } impl HTMLBodyElement { - fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: JSRef<Document>) -> HTMLBodyElement { + fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: JSRef<Document>) + -> HTMLBodyElement { HTMLBodyElement { - htmlelement: HTMLElement::new_inherited(HTMLBodyElementTypeId, localName, prefix, document) + htmlelement: HTMLElement::new_inherited(HTMLBodyElementTypeId, + localName, + prefix, + document), + background_color: Cell::new(None), } } #[allow(unrooted_must_root)] - pub fn new(localName: DOMString, prefix: Option<DOMString>, document: JSRef<Document>) -> Temporary<HTMLBodyElement> { + pub fn new(localName: DOMString, prefix: Option<DOMString>, document: JSRef<Document>) + -> Temporary<HTMLBodyElement> { let element = HTMLBodyElement::new_inherited(localName, prefix, document); Node::reflect_node(box element, document, HTMLBodyElementBinding::Wrap) } @@ -58,6 +65,16 @@ impl<'a> HTMLBodyElementMethods for JSRef<'a, HTMLBodyElement> { } } +pub trait HTMLBodyElementHelpers { + fn get_background_color(&self) -> Option<RGBA>; +} + +impl HTMLBodyElementHelpers for HTMLBodyElement { + fn get_background_color(&self) -> Option<RGBA> { + self.background_color.get() + } +} + impl<'a> VirtualMethods for JSRef<'a, HTMLBodyElement> { fn super_type<'a>(&'a self) -> Option<&'a VirtualMethods> { let element: &JSRef<HTMLElement> = HTMLElementCast::from_borrowed_ref(self); @@ -91,6 +108,25 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLBodyElement> { name.slice_from(2), attr.value().as_slice().to_string()); } + + match attr.local_name() { + &atom!("bgcolor") => { + self.background_color.set(str::parse_legacy_color(attr.value().as_slice()).ok()) + } + _ => {} + } + } + + 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!("bgcolor") => self.background_color.set(None), + _ => {} + } } } diff --git a/components/script/dom/htmltablecellelement.rs b/components/script/dom/htmltablecellelement.rs index cee07540301..9ca84b0e70f 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}; @@ -15,13 +14,15 @@ use dom::htmlelement::HTMLElement; use dom::node::ElementNodeTypeId; use dom::virtualmethods::VirtualMethods; -use servo_util::str::{AutoLpa, DOMString, LengthOrPercentageOrAuto}; -use servo_util::str; +use cssparser::RGBA; +use servo_util::str::{mod, AutoLpa, DOMString, LengthOrPercentageOrAuto}; use std::cell::Cell; #[dom_struct] pub struct HTMLTableCellElement { htmlelement: HTMLElement, + background_color: Cell<Option<RGBA>>, + colspan: Cell<Option<u32>>, width: Cell<LengthOrPercentageOrAuto>, } @@ -36,10 +37,16 @@ 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) + background_color: Cell::new(None), + colspan: Cell::new(None), + width: Cell::new(AutoLpa), } } @@ -50,10 +57,20 @@ impl HTMLTableCellElement { } pub trait HTMLTableCellElementHelpers { + fn get_background_color(&self) -> Option<RGBA>; + fn get_colspan(&self) -> Option<u32>; fn get_width(&self) -> LengthOrPercentageOrAuto; } impl HTMLTableCellElementHelpers for HTMLTableCellElement { + fn get_background_color(&self) -> Option<RGBA> { + self.background_color.get() + } + + fn get_colspan(&self) -> Option<u32> { + self.colspan.get() + } + fn get_width(&self) -> LengthOrPercentageOrAuto { self.width.get() } @@ -72,6 +89,12 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLTableCellElement> { } match attr.local_name() { + &atom!("bgcolor") => { + self.background_color.set(str::parse_legacy_color(attr.value().as_slice()).ok()) + } + &atom!("colspan") => { + self.colspan.set(str::parse_unsigned_integer(attr.value().as_slice().chars())); + } &atom!("width") => self.width.set(str::parse_length(attr.value().as_slice())), _ => () } @@ -84,6 +107,8 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLTableCellElement> { } match attr.local_name() { + &atom!("bgcolor") => self.background_color.set(None), + &atom!("colspan") => self.colspan.set(None), &atom!("width") => self.width.set(AutoLpa), _ => () } diff --git a/components/script/dom/htmltableelement.rs b/components/script/dom/htmltableelement.rs index 7dddf98bdc4..d2c9e723b78 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,18 @@ 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 cssparser::RGBA; +use servo_util::str::{mod, AutoLpa, DOMString, LengthOrPercentageOrAuto}; +use std::cell::Cell; #[dom_struct] pub struct HTMLTableElement { htmlelement: HTMLElement, + background_color: Cell<Option<RGBA>>, + border: Cell<Option<u32>>, + width: Cell<LengthOrPercentageOrAuto>, } impl HTMLTableElementDerived for EventTarget { @@ -28,14 +37,22 @@ 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), + background_color: Cell::new(None), + 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 +94,66 @@ impl<'a> HTMLTableElementMethods for JSRef<'a, HTMLTableElement> { }); } } + +pub trait HTMLTableElementHelpers { + fn get_background_color(&self) -> Option<RGBA>; + fn get_border(&self) -> Option<u32>; + fn get_width(&self) -> LengthOrPercentageOrAuto; +} + +impl HTMLTableElementHelpers for HTMLTableElement { + fn get_background_color(&self) -> Option<RGBA> { + self.background_color.get() + } + + 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!("bgcolor") => { + self.background_color.set(str::parse_legacy_color(attr.value().as_slice()).ok()) + } + &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())), + _ => () + } + } + + 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!("bgcolor") => self.background_color.set(None), + &atom!("border") => self.border.set(None), + &atom!("width") => self.width.set(AutoLpa), + _ => () + } + } +} + diff --git a/components/script/dom/htmltablerowelement.rs b/components/script/dom/htmltablerowelement.rs index 3edf4a0e64f..500c7d74472 100644 --- a/components/script/dom/htmltablerowelement.rs +++ b/components/script/dom/htmltablerowelement.rs @@ -2,8 +2,9 @@ * 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, AttrHelpers}; use dom::bindings::codegen::Bindings::HTMLTableRowElementBinding; -use dom::bindings::codegen::InheritTypes::HTMLTableRowElementDerived; +use dom::bindings::codegen::InheritTypes::{HTMLElementCast, HTMLTableRowElementDerived}; use dom::bindings::js::{JSRef, Temporary}; use dom::bindings::utils::{Reflectable, Reflector}; use dom::document::Document; @@ -11,11 +12,16 @@ use dom::element::HTMLTableRowElementTypeId; use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlelement::HTMLElement; use dom::node::{Node, ElementNodeTypeId}; -use servo_util::str::DOMString; +use dom::virtualmethods::VirtualMethods; + +use cssparser::RGBA; +use servo_util::str::{mod, DOMString}; +use std::cell::Cell; #[dom_struct] pub struct HTMLTableRowElement { htmlelement: HTMLElement, + background_color: Cell<Option<RGBA>>, } impl HTMLTableRowElementDerived for EventTarget { @@ -25,9 +31,14 @@ impl HTMLTableRowElementDerived for EventTarget { } impl HTMLTableRowElement { - fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: JSRef<Document>) -> HTMLTableRowElement { + fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: JSRef<Document>) + -> HTMLTableRowElement { HTMLTableRowElement { - htmlelement: HTMLElement::new_inherited(HTMLTableRowElementTypeId, localName, prefix, document) + htmlelement: HTMLElement::new_inherited(HTMLTableRowElementTypeId, + localName, + prefix, + document), + background_color: Cell::new(None), } } @@ -45,3 +56,47 @@ impl Reflectable for HTMLTableRowElement { self.htmlelement.reflector() } } + +pub trait HTMLTableRowElementHelpers { + fn get_background_color(&self) -> Option<RGBA>; +} + +impl HTMLTableRowElementHelpers for HTMLTableRowElement { + fn get_background_color(&self) -> Option<RGBA> { + self.background_color.get() + } +} + +impl<'a> VirtualMethods for JSRef<'a, HTMLTableRowElement> { + 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!("bgcolor") => { + self.background_color.set(str::parse_legacy_color(attr.value().as_slice()).ok()) + } + _ => {} + } + } + + 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!("bgcolor") => self.background_color.set(None), + _ => {} + } + } +} + diff --git a/components/script/dom/htmltablesectionelement.rs b/components/script/dom/htmltablesectionelement.rs index d10e4b82b44..b191e21bde0 100644 --- a/components/script/dom/htmltablesectionelement.rs +++ b/components/script/dom/htmltablesectionelement.rs @@ -2,8 +2,9 @@ * 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, AttrHelpers}; use dom::bindings::codegen::Bindings::HTMLTableSectionElementBinding; -use dom::bindings::codegen::InheritTypes::HTMLTableSectionElementDerived; +use dom::bindings::codegen::InheritTypes::{HTMLElementCast, HTMLTableSectionElementDerived}; use dom::bindings::js::{JSRef, Temporary}; use dom::bindings::utils::{Reflectable, Reflector}; use dom::document::Document; @@ -11,11 +12,16 @@ use dom::element::HTMLTableSectionElementTypeId; use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlelement::HTMLElement; use dom::node::{Node, ElementNodeTypeId}; -use servo_util::str::DOMString; +use dom::virtualmethods::VirtualMethods; + +use cssparser::RGBA; +use servo_util::str::{mod, DOMString}; +use std::cell::Cell; #[dom_struct] pub struct HTMLTableSectionElement { htmlelement: HTMLElement, + background_color: Cell<Option<RGBA>>, } impl HTMLTableSectionElementDerived for EventTarget { @@ -25,14 +31,20 @@ impl HTMLTableSectionElementDerived for EventTarget { } impl HTMLTableSectionElement { - fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: JSRef<Document>) -> HTMLTableSectionElement { + fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: JSRef<Document>) + -> HTMLTableSectionElement { HTMLTableSectionElement { - htmlelement: HTMLElement::new_inherited(HTMLTableSectionElementTypeId, localName, prefix, document) + htmlelement: HTMLElement::new_inherited(HTMLTableSectionElementTypeId, + localName, + prefix, + document), + background_color: Cell::new(None), } } #[allow(unrooted_must_root)] - pub fn new(localName: DOMString, prefix: Option<DOMString>, document: JSRef<Document>) -> Temporary<HTMLTableSectionElement> { + pub fn new(localName: DOMString, prefix: Option<DOMString>, document: JSRef<Document>) + -> Temporary<HTMLTableSectionElement> { let element = HTMLTableSectionElement::new_inherited(localName, prefix, document); Node::reflect_node(box element, document, HTMLTableSectionElementBinding::Wrap) } @@ -43,3 +55,47 @@ impl Reflectable for HTMLTableSectionElement { self.htmlelement.reflector() } } + +pub trait HTMLTableSectionElementHelpers { + fn get_background_color(&self) -> Option<RGBA>; +} + +impl HTMLTableSectionElementHelpers for HTMLTableSectionElement { + fn get_background_color(&self) -> Option<RGBA> { + self.background_color.get() + } +} + +impl<'a> VirtualMethods for JSRef<'a, HTMLTableSectionElement> { + 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!("bgcolor") => { + self.background_color.set(str::parse_legacy_color(attr.value().as_slice()).ok()) + } + _ => {} + } + } + + 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!("bgcolor") => self.background_color.set(None), + _ => {} + } + } +} + diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs index ecfccf8aefc..0871a266df3 100644 --- a/components/script/dom/node.rs +++ b/components/script/dom/node.rs @@ -50,7 +50,7 @@ use devtools_traits::NodeInfo; use script_traits::UntrustedNodeAddress; use servo_util::geometry::Au; use servo_util::str::{DOMString, null_str_as_empty}; -use style::{parse_selector_list_from_str, matches, SelectorList}; +use style::{matches, AuthorOrigin, ParserContext, SelectorList}; use js::jsapi::{JSContext, JSObject, JSTracer, JSRuntime}; use js::jsfriendapi; @@ -60,8 +60,7 @@ use std::cell::{Cell, RefCell, Ref, RefMut}; use std::default::Default; use std::iter::{FilterMap, Peekable}; use std::mem; -use style; -use style::ComputedValues; +use style::{mod, ComputedValues}; use sync::Arc; use uuid; use string_cache::QualName; @@ -741,7 +740,10 @@ impl<'a> NodeHelpers<'a> for JSRef<'a, Node> { // http://dom.spec.whatwg.org/#dom-parentnode-queryselector fn query_selector(self, selectors: DOMString) -> Fallible<Option<Temporary<Element>>> { // Step 1. - match parse_selector_list_from_str(selectors.as_slice()) { + let parser_context = ParserContext { + origin: AuthorOrigin, + }; + match style::parse_selector_list_from_str(&parser_context, selectors.as_slice()) { // Step 2. Err(()) => return Err(Syntax), // Step 3. @@ -758,11 +760,15 @@ impl<'a> NodeHelpers<'a> for JSRef<'a, Node> { /// Get an iterator over all nodes which match a set of selectors /// Be careful not to do anything which may manipulate the DOM tree whilst iterating, otherwise /// the iterator may be invalidated - unsafe fn query_selector_iter(self, selectors: DOMString) -> Fallible<QuerySelectorIterator<'a>> { + unsafe fn query_selector_iter(self, selectors: DOMString) + -> Fallible<QuerySelectorIterator<'a>> { // Step 1. let nodes; let root = self.ancestors().last().unwrap_or(self.clone()); - match parse_selector_list_from_str(selectors.as_slice()) { + let parser_context = ParserContext { + origin: AuthorOrigin, + }; + match style::parse_selector_list_from_str(&parser_context, selectors.as_slice()) { // Step 2. Err(()) => return Err(Syntax), // Step 3. diff --git a/components/script/dom/virtualmethods.rs b/components/script/dom/virtualmethods.rs index a90055bc50d..94a74124eca 100644 --- a/components/script/dom/virtualmethods.rs +++ b/components/script/dom/virtualmethods.rs @@ -22,7 +22,10 @@ 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::HTMLTableRowElementCast; +use dom::bindings::codegen::InheritTypes::HTMLTableSectionElementCast; use dom::bindings::codegen::InheritTypes::HTMLTextAreaElementCast; use dom::bindings::codegen::InheritTypes::HTMLTitleElementCast; use dom::bindings::js::JSRef; @@ -46,7 +49,10 @@ 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::HTMLTableRowElementTypeId; +use dom::element::HTMLTableSectionElementTypeId; use dom::element::HTMLTextAreaElementTypeId; use dom::element::HTMLTitleElementTypeId; use dom::event::Event; @@ -67,7 +73,10 @@ 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::htmltablerowelement::HTMLTableRowElement; +use dom::htmltablesectionelement::HTMLTableSectionElement; use dom::htmltextareaelement::HTMLTextAreaElement; use dom::htmltitleelement::HTMLTitleElement; use dom::node::{Node, NodeHelpers, ElementNodeTypeId, CloneChildrenFlag}; @@ -226,9 +235,25 @@ 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(); + let element: &'a JSRef<'a, HTMLTableCellElement> = + HTMLTableCellElementCast::to_borrowed_ref(node).unwrap(); + element as &'a VirtualMethods + 'a + } + ElementNodeTypeId(HTMLTableRowElementTypeId) => { + let element: &'a JSRef<'a, HTMLTableRowElement> = + HTMLTableRowElementCast::to_borrowed_ref(node).unwrap(); + element as &'a VirtualMethods + 'a + } + ElementNodeTypeId(HTMLTableSectionElementTypeId) => { + let element: &'a JSRef<'a, HTMLTableSectionElement> = + HTMLTableSectionElementCast::to_borrowed_ref(node).unwrap(); element as &'a VirtualMethods + 'a } ElementNodeTypeId(HTMLTextAreaElementTypeId) => { diff --git a/components/script/layout_interface.rs b/components/script/layout_interface.rs index c3afb15c057..0f3f4fbacbf 100644 --- a/components/script/layout_interface.rs +++ b/components/script/layout_interface.rs @@ -29,6 +29,9 @@ pub enum Msg { /// Adds the given stylesheet to the document. LoadStylesheetMsg(Url), + /// Puts a document into quirks mode, causing the quirks mode stylesheet to be loaded. + SetQuirksModeMsg, + /// Requests a reflow. ReflowMsg(Box<Reflow>), |