aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/layout/wrapper.rs12
-rw-r--r--components/script/dom/bindings/trace.rs3
-rw-r--r--components/script/dom/element.rs41
-rw-r--r--components/script/dom/htmlbodyelement.rs53
-rw-r--r--components/script/dom/htmltablecellelement.rs14
-rw-r--r--components/script/dom/htmltableelement.rs13
-rw-r--r--components/servo/Cargo.lock3
-rw-r--r--components/style/legacy.rs70
-rw-r--r--components/style/lib.rs5
-rw-r--r--components/style/node.rs5
-rw-r--r--components/style/selector_matching.rs4
-rw-r--r--components/util/Cargo.toml3
-rw-r--r--components/util/lib.rs1
-rw-r--r--components/util/str.rs133
-rw-r--r--ports/cef/Cargo.lock2
-rw-r--r--ports/gonk/Cargo.lock2
-rw-r--r--tests/ref/basic.list1
-rw-r--r--tests/ref/legacy_td_bgcolor_attribute_a.html20
-rw-r--r--tests/ref/legacy_td_bgcolor_attribute_ref.html21
19 files changed, 370 insertions, 36 deletions
diff --git a/components/layout/wrapper.rs b/components/layout/wrapper.rs
index ba16eb885a9..41c05e1646c 100644
--- a/components/layout/wrapper.rs
+++ b/components/layout/wrapper.rs
@@ -53,14 +53,14 @@ use script::dom::node::{HAS_CHANGED, IS_DIRTY, HAS_DIRTY_SIBLINGS, HAS_DIRTY_DES
use script::dom::text::Text;
use script::layout_interface::LayoutChan;
use servo_msg::constellation_msg::{PipelineId, SubpageId};
-use servo_util::str::{LengthOrPercentageOrAuto, is_whitespace};
+use servo_util::str::{LengthOrPercentageOrAuto, SimpleColor, is_whitespace};
use std::kinds::marker::ContravariantLifetime;
use std::mem;
use string_cache::{Atom, Namespace};
use style::computed_values::{content, display, white_space};
use style::{AnyNamespace, AttrSelector, BorderUnsignedIntegerAttribute, IntegerAttribute};
-use style::{LengthAttribute, PropertyDeclarationBlock, SpecificNamespace, TElement};
-use style::{TElementAttributes, TNode, UnsignedIntegerAttribute};
+use style::{LengthAttribute, PropertyDeclarationBlock, SimpleColorAttribute, SpecificNamespace};
+use style::{TElement, TElementAttributes, TNode, UnsignedIntegerAttribute};
use url::Url;
use std::cell::{Ref, RefMut};
@@ -612,6 +612,12 @@ impl<'le> TElementAttributes for LayoutElement<'le> {
self.element.get_unsigned_integer_attribute_for_layout(attribute)
}
}
+
+ fn get_simple_color_attribute(self, attribute: SimpleColorAttribute) -> Option<SimpleColor> {
+ unsafe {
+ self.element.get_simple_color_attribute_for_layout(attribute)
+ }
+ }
}
fn get_content(content_list: &content::T) -> String {
diff --git a/components/script/dom/bindings/trace.rs b/components/script/dom/bindings/trace.rs
index afd329137c0..d5acb22ad7b 100644
--- a/components/script/dom/bindings/trace.rs
+++ b/components/script/dom/bindings/trace.rs
@@ -48,7 +48,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, SimpleColor};
use std::cell::{Cell, RefCell};
use std::collections::HashMap;
use std::comm::{Receiver, Sender};
@@ -214,6 +214,7 @@ no_jsmanaged_fields!(LayoutChan)
no_jsmanaged_fields!(WindowProxyHandler)
no_jsmanaged_fields!(UntrustedNodeAddress)
no_jsmanaged_fields!(LengthOrPercentageOrAuto)
+no_jsmanaged_fields!(SimpleColor)
impl<'a> JSTraceable for &'a str {
#[inline]
diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs
index db2b8d3d096..0cdf78b697d 100644
--- a/components/script/dom/element.rs
+++ b/components/script/dom/element.rs
@@ -16,9 +16,10 @@ 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::{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::codegen::InheritTypes::{HTMLBodyElementDerived, HTMLInputElementCast};
+use dom::bindings::codegen::InheritTypes::{HTMLInputElementDerived, HTMLTableElementCast};
+use dom::bindings::codegen::InheritTypes::{HTMLTableElementDerived, HTMLTableCellElementDerived};
+use dom::bindings::codegen::InheritTypes::{NodeCast};
use dom::bindings::js::{MutNullableJS, JS, JSRef, Temporary, TemporaryPushable};
use dom::bindings::js::{OptionalRootable, Root};
use dom::bindings::utils::{Reflectable, Reflector};
@@ -31,6 +32,7 @@ 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;
@@ -42,12 +44,11 @@ use dom::node::{window_from_node};
use dom::nodelist::NodeList;
use dom::virtualmethods::{VirtualMethods, vtable_for};
use devtools_traits::AttrInfo;
-use style::{BorderUnsignedIntegerAttribute, IntegerAttribute, LengthAttribute};
-use style::{SizeIntegerAttribute, UnsignedIntegerAttribute, WidthLengthAttribute};
-use style::{matches, parse_selector_list_from_str};
-use style;
+use style::{mod, BgColorSimpleColorAttribute, BorderUnsignedIntegerAttribute, IntegerAttribute};
+use style::{LengthAttribute, SimpleColorAttribute, SizeIntegerAttribute, UnsignedIntegerAttribute};
+use style::{WidthLengthAttribute, matches, parse_selector_list_from_str};
use servo_util::namespace;
-use servo_util::str::{DOMString, LengthOrPercentageOrAuto};
+use servo_util::str::{DOMString, LengthOrPercentageOrAuto, SimpleColor};
use std::ascii::AsciiExt;
use std::cell::{Ref, RefMut};
@@ -207,6 +208,8 @@ pub trait RawLayoutElementHelpers {
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<SimpleColor>;
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>>;
@@ -349,6 +352,28 @@ impl RawLayoutElementHelpers for Element {
}
}
+ #[inline]
+ #[allow(unrooted_must_root)]
+ unsafe fn get_simple_color_attribute_for_layout(&self, attribute: SimpleColorAttribute)
+ -> Option<SimpleColor> {
+ 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 {
+ panic!("I'm not a body, table, or table cell!")
+ }
+ }
+ }
+ }
+
// Getters used in components/layout/wrapper.rs
fn local_name<'a>(&'a self) -> &'a Atom {
diff --git a/components/script/dom/htmlbodyelement.rs b/components/script/dom/htmlbodyelement.rs
index d088a6b8626..ebfe1e8025a 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,13 @@ use dom::htmlelement::HTMLElement;
use dom::node::{Node, ElementNodeTypeId, window_from_node};
use dom::virtualmethods::VirtualMethods;
-use servo_util::str::DOMString;
+use servo_util::str::{mod, DOMString, SimpleColor};
+use std::cell::Cell;
#[dom_struct]
pub struct HTMLBodyElement {
- htmlelement: HTMLElement
+ htmlelement: HTMLElement,
+ background_color: Cell<Option<SimpleColor>>,
}
impl HTMLBodyElementDerived for EventTarget {
@@ -33,14 +33,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 +64,16 @@ impl<'a> HTMLBodyElementMethods for JSRef<'a, HTMLBodyElement> {
}
}
+pub trait HTMLBodyElementHelpers {
+ fn get_background_color(&self) -> Option<SimpleColor>;
+}
+
+impl HTMLBodyElementHelpers for HTMLBodyElement {
+ fn get_background_color(&self) -> Option<SimpleColor> {
+ 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 +107,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 622389397e9..25a5e9e78b0 100644
--- a/components/script/dom/htmltablecellelement.rs
+++ b/components/script/dom/htmltablecellelement.rs
@@ -14,13 +14,13 @@ use dom::htmlelement::HTMLElement;
use dom::node::ElementNodeTypeId;
use dom::virtualmethods::VirtualMethods;
-use servo_util::str::{AutoLpa, DOMString, LengthOrPercentageOrAuto};
-use servo_util::str;
+use servo_util::str::{mod, AutoLpa, DOMString, LengthOrPercentageOrAuto, SimpleColor};
use std::cell::Cell;
#[dom_struct]
pub struct HTMLTableCellElement {
htmlelement: HTMLElement,
+ background_color: Cell<Option<SimpleColor>>,
border: Cell<Option<u32>>,
width: Cell<LengthOrPercentageOrAuto>,
}
@@ -43,6 +43,7 @@ impl HTMLTableCellElement {
-> HTMLTableCellElement {
HTMLTableCellElement {
htmlelement: HTMLElement::new_inherited(type_id, tag_name, prefix, document),
+ background_color: Cell::new(None),
border: Cell::new(None),
width: Cell::new(AutoLpa),
}
@@ -55,11 +56,16 @@ impl HTMLTableCellElement {
}
pub trait HTMLTableCellElementHelpers {
+ fn get_background_color(&self) -> Option<SimpleColor>;
fn get_border(&self) -> Option<u32>;
fn get_width(&self) -> LengthOrPercentageOrAuto;
}
impl HTMLTableCellElementHelpers for HTMLTableCellElement {
+ fn get_background_color(&self) -> Option<SimpleColor> {
+ self.background_color.get()
+ }
+
fn get_border(&self) -> Option<u32> {
self.border.get()
}
@@ -82,6 +88,9 @@ 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!("border") => {
// According to HTML5 § 14.3.9, invalid values map to 1px.
self.border.set(Some(str::parse_unsigned_integer(attr.value()
@@ -100,6 +109,7 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLTableCellElement> {
}
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/htmltableelement.rs b/components/script/dom/htmltableelement.rs
index 9a7acd02559..4ece4c8b9f9 100644
--- a/components/script/dom/htmltableelement.rs
+++ b/components/script/dom/htmltableelement.rs
@@ -18,12 +18,13 @@ use dom::htmltablecaptionelement::HTMLTableCaptionElement;
use dom::node::{Node, NodeHelpers, ElementNodeTypeId};
use dom::virtualmethods::VirtualMethods;
-use servo_util::str::{mod, AutoLpa, DOMString, LengthOrPercentageOrAuto};
+use servo_util::str::{mod, AutoLpa, DOMString, LengthOrPercentageOrAuto, SimpleColor};
use std::cell::Cell;
#[dom_struct]
pub struct HTMLTableElement {
htmlelement: HTMLElement,
+ background_color: Cell<Option<SimpleColor>>,
border: Cell<Option<u32>>,
width: Cell<LengthOrPercentageOrAuto>,
}
@@ -42,6 +43,7 @@ impl HTMLTableElement {
localName,
prefix,
document),
+ background_color: Cell::new(None),
border: Cell::new(None),
width: Cell::new(AutoLpa),
}
@@ -93,11 +95,16 @@ impl<'a> HTMLTableElementMethods for JSRef<'a, HTMLTableElement> {
}
pub trait HTMLTableElementHelpers {
+ fn get_background_color(&self) -> Option<SimpleColor>;
fn get_border(&self) -> Option<u32>;
fn get_width(&self) -> LengthOrPercentageOrAuto;
}
impl HTMLTableElementHelpers for HTMLTableElement {
+ fn get_background_color(&self) -> Option<SimpleColor> {
+ self.background_color.get()
+ }
+
fn get_border(&self) -> Option<u32> {
self.border.get()
}
@@ -119,6 +126,9 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLTableElement> {
}
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()
@@ -136,6 +146,7 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLTableElement> {
}
match attr.local_name() {
+ &atom!("bgcolor") => self.background_color.set(None),
&atom!("border") => self.border.set(None),
_ => ()
}
diff --git a/components/servo/Cargo.lock b/components/servo/Cargo.lock
index bb04bd528af..6c4b2708b9e 100644
--- a/components/servo/Cargo.lock
+++ b/components/servo/Cargo.lock
@@ -121,7 +121,7 @@ dependencies = [
[[package]]
name = "cssparser"
version = "0.1.0"
-source = "git+https://github.com/servo/rust-cssparser#cbbfd66f794bd019bbdeaefc88b29eff455b62e5"
+source = "git+https://github.com/servo/rust-cssparser#3f98f1308b769b5d61efc6c133ac520df2b074ac"
dependencies = [
"encoding 0.2.0 (git+https://github.com/lifthrasiir/rust-encoding)",
]
@@ -672,6 +672,7 @@ dependencies = [
name = "util"
version = "0.0.1"
dependencies = [
+ "cssparser 0.1.0 (git+https://github.com/servo/rust-cssparser)",
"geom 0.1.0 (git+https://github.com/servo/rust-geom)",
"layers 0.1.0 (git+https://github.com/servo/rust-layers)",
"string_cache 0.0.0 (git+https://github.com/servo/string-cache)",
diff --git a/components/style/legacy.rs b/components/style/legacy.rs
index 8eb9a7d1e56..f818fb02480 100644
--- a/components/style/legacy.rs
+++ b/components/style/legacy.rs
@@ -6,11 +6,12 @@
//! `<input size>`, and so forth.
use node::{TElement, TElementAttributes, TNode};
-use properties::{BorderBottomWidthDeclaration, BorderLeftWidthDeclaration};
-use properties::{BorderRightWidthDeclaration, BorderTopWidthDeclaration, SpecifiedValue};
-use properties::{WidthDeclaration, specified};
+use properties::{BackgroundColorDeclaration, BorderBottomWidthDeclaration};
+use properties::{BorderLeftWidthDeclaration, BorderRightWidthDeclaration};
+use properties::{BorderTopWidthDeclaration, SpecifiedValue, WidthDeclaration, specified};
use selector_matching::{DeclarationBlock, Stylist};
+use cssparser::{RGBA, RGBAColor};
use servo_util::geometry::Au;
use servo_util::smallvec::VecLike;
use servo_util::str::{AutoLpa, LengthLpa, PercentageLpa};
@@ -33,11 +34,22 @@ pub enum UnsignedIntegerAttribute {
BorderUnsignedIntegerAttribute,
}
+/// Legacy presentational attributes that take a simple color as defined in HTML5 § 2.4.6.
+pub enum SimpleColorAttribute {
+ /// `<body bgcolor>`
+ BgColorSimpleColorAttribute,
+}
+
/// Extension methods for `Stylist` that cause rules to be synthesized for legacy attributes.
pub trait PresentationalHintSynthesis {
/// Synthesizes rules from various HTML attributes (mostly legacy junk from HTML4) that confer
/// *presentational hints* as defined in the HTML5 specification. This handles stuff like
/// `<body bgcolor>`, `<input size>`, `<td width>`, and so forth.
+ ///
+ /// NB: Beware! If you add an attribute to this list, be sure to add it to
+ /// `common_style_affecting_attributes` or `rare_style_affecting_attributes` as appropriate. If
+ /// you don't, you risk strange random nondeterministic failures due to false positives in
+ /// style sharing.
fn synthesize_presentational_hints_for_legacy_attributes<'a,E,N,V>(
&self,
node: &N,
@@ -47,6 +59,18 @@ pub trait PresentationalHintSynthesis {
TElementAttributes,
N: TNode<'a,E>,
V: VecLike<DeclarationBlock>;
+ /// Synthesizes rules for the legacy `bgcolor` attribute.
+ fn synthesize_presentational_hint_for_legacy_background_color_attribute<'a,E,V>(
+ &self,
+ element: E,
+ matching_rules_list:
+ &mut V,
+ shareable: &mut bool)
+ where
+ E: TElement<'a> +
+ TElementAttributes,
+ V: VecLike<
+ DeclarationBlock>;
/// Synthesizes rules for the legacy `border` attribute.
fn synthesize_presentational_hint_for_legacy_border_attribute<'a,E,V>(
&self,
@@ -87,17 +111,31 @@ impl PresentationalHintSynthesis for Stylist {
*shareable = false
}
}
+ self.synthesize_presentational_hint_for_legacy_background_color_attribute(
+ element,
+ matching_rules_list,
+ shareable);
self.synthesize_presentational_hint_for_legacy_border_attribute(
element,
matching_rules_list,
shareable);
}
name if *name == atom!("table") => {
+ self.synthesize_presentational_hint_for_legacy_background_color_attribute(
+ element,
+ matching_rules_list,
+ shareable);
self.synthesize_presentational_hint_for_legacy_border_attribute(
element,
matching_rules_list,
shareable);
}
+ name if *name == atom!("body") => {
+ self.synthesize_presentational_hint_for_legacy_background_color_attribute(
+ element,
+ matching_rules_list,
+ shareable);
+ }
name if *name == atom!("input") => {
match element.get_integer_attribute(SizeIntegerAttribute) {
Some(value) if value != 0 => {
@@ -123,6 +161,32 @@ impl PresentationalHintSynthesis for Stylist {
}
}
+ fn synthesize_presentational_hint_for_legacy_background_color_attribute<'a,E,V>(
+ &self,
+ element: E,
+ matching_rules_list:
+ &mut V,
+ shareable: &mut bool)
+ where
+ E: TElement<'a> +
+ TElementAttributes,
+ V: VecLike<
+ DeclarationBlock> {
+ match element.get_simple_color_attribute(BgColorSimpleColorAttribute) {
+ None => {}
+ Some(color) => {
+ matching_rules_list.vec_push(DeclarationBlock::from_declaration(
+ BackgroundColorDeclaration(SpecifiedValue(RGBAColor(RGBA {
+ red: color.red as f32 / 255.0,
+ green: color.green as f32 / 255.0,
+ blue: color.blue as f32 / 255.0,
+ alpha: 1.0,
+ })))));
+ *shareable = false
+ }
+ }
+ }
+
fn synthesize_presentational_hint_for_legacy_border_attribute<'a,E,V>(
&self,
element: E,
diff --git a/components/style/lib.rs b/components/style/lib.rs
index 23a674151b4..f2344e3e807 100644
--- a/components/style/lib.rs
+++ b/components/style/lib.rs
@@ -54,8 +54,9 @@ pub use selectors::{PseudoElement, Before, After, SelectorList, parse_selector_l
pub use selectors::{AttrSelector, NamespaceConstraint, SpecificNamespace, AnyNamespace};
pub use selectors::{SimpleSelector, LocalNameSelector};
pub use cssparser::{Color, RGBA};
-pub use legacy::{BorderUnsignedIntegerAttribute, IntegerAttribute, LengthAttribute};
-pub use legacy::{SizeIntegerAttribute, UnsignedIntegerAttribute, WidthLengthAttribute};
+pub use legacy::{BgColorSimpleColorAttribute, BorderUnsignedIntegerAttribute, IntegerAttribute};
+pub use legacy::{LengthAttribute, SimpleColorAttribute, SizeIntegerAttribute};
+pub use legacy::{UnsignedIntegerAttribute, WidthLengthAttribute};
pub use font_face::{Source, LocalSource, UrlSource_};
mod stylesheets;
diff --git a/components/style/node.rs b/components/style/node.rs
index 3d9ad18e623..4866f27e6c5 100644
--- a/components/style/node.rs
+++ b/components/style/node.rs
@@ -5,9 +5,9 @@
//! Traits that nodes must implement. Breaks the otherwise-cyclic dependency between layout and
//! style.
-use legacy::{IntegerAttribute, LengthAttribute, UnsignedIntegerAttribute};
+use legacy::{IntegerAttribute, LengthAttribute, SimpleColorAttribute, UnsignedIntegerAttribute};
use selectors::AttrSelector;
-use servo_util::str::LengthOrPercentageOrAuto;
+use servo_util::str::{LengthOrPercentageOrAuto, SimpleColor};
use string_cache::{Atom, Namespace};
pub trait TNode<'a, E: TElement<'a>> : Clone + Copy {
@@ -60,4 +60,5 @@ pub trait TElementAttributes : Copy {
fn get_length_attribute(self, attribute: LengthAttribute) -> LengthOrPercentageOrAuto;
fn get_integer_attribute(self, attribute: IntegerAttribute) -> Option<i32>;
fn get_unsigned_integer_attribute(self, attribute: UnsignedIntegerAttribute) -> Option<u32>;
+ fn get_simple_color_attribute(self, attribute: SimpleColorAttribute) -> Option<SimpleColor>;
}
diff --git a/components/style/selector_matching.rs b/components/style/selector_matching.rs
index b1fbd5042e8..12df5e2f35c 100644
--- a/components/style/selector_matching.rs
+++ b/components/style/selector_matching.rs
@@ -802,8 +802,8 @@ pub fn common_style_affecting_attributes() -> [CommonStyleAffectingAttributeInfo
/// Attributes that, if present, disable style sharing. All legacy HTML attributes must be in
/// either this list or `common_style_affecting_attributes`. See the comment in
/// `synthesize_presentational_hints_for_legacy_attributes`.
-pub fn rare_style_affecting_attributes() -> [Atom, ..1] {
- [ atom!("border") ]
+pub fn rare_style_affecting_attributes() -> [Atom, ..2] {
+ [ atom!("bgcolor"), atom!("border") ]
}
/// Determines whether the given element matches the given single selector.
diff --git a/components/util/Cargo.toml b/components/util/Cargo.toml
index 29fc71d25a5..331fd2fb840 100644
--- a/components/util/Cargo.toml
+++ b/components/util/Cargo.toml
@@ -7,6 +7,9 @@ authors = ["The Servo Project Developers"]
name = "util"
path = "lib.rs"
+[dependencies.cssparser]
+git = "https://github.com/servo/rust-cssparser"
+
[dependencies.geom]
git = "https://github.com/servo/rust-geom"
diff --git a/components/util/lib.rs b/components/util/lib.rs
index f556dda6eb9..b0e4cff8c62 100644
--- a/components/util/lib.rs
+++ b/components/util/lib.rs
@@ -13,6 +13,7 @@ extern crate log;
extern crate alloc;
extern crate collections;
+extern crate cssparser;
extern crate geom;
extern crate getopts;
extern crate layers;
diff --git a/components/util/str.rs b/components/util/str.rs
index 0428d0db5b2..ebc494c2642 100644
--- a/components/util/str.rs
+++ b/components/util/str.rs
@@ -4,6 +4,8 @@
use geometry::Au;
+use cssparser::{mod, RGBAColor};
+use std::ascii::AsciiExt;
use std::from_str::FromStr;
use std::iter::Filter;
use std::str::{CharEq, CharSplits};
@@ -184,6 +186,137 @@ pub fn parse_length(mut value: &str) -> LengthOrPercentageOrAuto {
}
}
+/// A "simple color" per HTML5 § 2.4.6.
+#[deriving(Show)]
+pub struct SimpleColor {
+ /// The red component of the color, [0, 255].
+ pub red: u8,
+ /// The green component of the color, [0, 255].
+ pub green: u8,
+ /// The blue component of the color, [0, 255].
+ pub blue: u8,
+}
+
+/// Parses a legacy color per HTML5 § 2.4.6. If unparseable, `Err` is returned.
+pub fn parse_legacy_color(mut input: &str) -> Result<SimpleColor,()> {
+ // Steps 1 and 2.
+ if input.len() == 0 {
+ return Err(())
+ }
+
+ // Step 3.
+ input = input.trim_left_chars(Whitespace).trim_right_chars(Whitespace);
+
+ // Step 4.
+ if input.eq_ignore_ascii_case("transparent") {
+ return Err(())
+ }
+
+ // Step 5.
+ match cssparser::parse_color_keyword(input) {
+ Ok(RGBAColor(rgba)) => {
+ return Ok(SimpleColor {
+ red: (rgba.red * 255.0) as u8,
+ green: (rgba.green * 255.0) as u8,
+ blue: (rgba.blue * 255.0) as u8,
+ })
+ }
+ _ => {}
+ }
+
+ // Step 6.
+ if input.len() == 4 {
+ match (input.char_at(0),
+ hex(input.char_at(1)),
+ hex(input.char_at(2)),
+ hex(input.char_at(3))) {
+ ('#', Ok(r), Ok(g), Ok(b)) => {
+ return Ok(SimpleColor {
+ red: r * 17,
+ green: g * 17,
+ blue: b * 17,
+ })
+ }
+ _ => {}
+ }
+ }
+
+ // Step 7.
+ let mut new_input = String::new();
+ for ch in input.chars() {
+ if ch as u32 > 0xffff {
+ new_input.push_str("00")
+ } else {
+ new_input.push(ch)
+ }
+ }
+ let mut input = new_input.as_slice();
+
+ // Step 8.
+ if input.len() > 128 {
+ input = input.slice_to(128)
+ }
+
+ // Step 9.
+ if input.char_at(0) == '#' {
+ input = input.slice_from(1)
+ }
+
+ // Step 10.
+ let mut new_input = Vec::new();
+ for ch in input.chars() {
+ if hex(ch).is_ok() {
+ new_input.push(ch as u8)
+ } else {
+ new_input.push(b'0')
+ }
+ }
+ let mut input = new_input;
+
+ // Step 11.
+ while input.len() == 0 || (input.len() % 3) != 0 {
+ input.push(b'0')
+ }
+
+ // Step 12.
+ let mut length = input.len() / 3;
+ let (mut red, mut green, mut blue) = (input.slice_to(length),
+ input.slice(length, length * 2),
+ input.slice_from(length * 2));
+
+ // Step 13.
+ if length > 8 {
+ red = red.slice_from(length - 8);
+ green = green.slice_from(length - 8);
+ blue = blue.slice_from(length - 8);
+ length = 8
+ }
+
+ // Step 14.
+ while length > 2 && red[0] == b'0' && green[0] == b'0' && blue[0] == b'0' {
+ red = red.slice_from(1);
+ green = green.slice_from(1);
+ blue = blue.slice_from(1);
+ length -= 1
+ }
+
+ // Steps 15-20.
+ return Ok(SimpleColor {
+ red: (hex(red[0] as char).unwrap() << 4) | hex(red[1] as char).unwrap(),
+ green: (hex(green[0] as char).unwrap() << 4) | hex(green[1] as char).unwrap(),
+ blue: (hex(blue[0] as char).unwrap() << 4) | hex(blue[1] as char).unwrap(),
+ });
+
+ fn hex(ch: char) -> Result<u8,()> {
+ match ch {
+ '0'...'9' => Ok((ch as u8) - b'0'),
+ 'a'...'f' => Ok((ch as u8) - b'a' + 10),
+ 'A'...'F' => Ok((ch as u8) - b'A' + 10),
+ _ => Err(()),
+ }
+ }
+}
+
#[deriving(Clone, Eq, PartialEq, Hash, Show)]
pub struct LowercaseString {
diff --git a/ports/cef/Cargo.lock b/ports/cef/Cargo.lock
index 442926ffa84..460ffbd04df 100644
--- a/ports/cef/Cargo.lock
+++ b/ports/cef/Cargo.lock
@@ -118,7 +118,7 @@ dependencies = [
[[package]]
name = "cssparser"
version = "0.1.0"
-source = "git+https://github.com/servo/rust-cssparser#cbbfd66f794bd019bbdeaefc88b29eff455b62e5"
+source = "git+https://github.com/servo/rust-cssparser#3f98f1308b769b5d61efc6c133ac520df2b074ac"
dependencies = [
"encoding 0.2.0 (git+https://github.com/lifthrasiir/rust-encoding)",
]
diff --git a/ports/gonk/Cargo.lock b/ports/gonk/Cargo.lock
index 2641812ade7..9a81bc9a406 100644
--- a/ports/gonk/Cargo.lock
+++ b/ports/gonk/Cargo.lock
@@ -101,7 +101,7 @@ dependencies = [
[[package]]
name = "cssparser"
version = "0.1.0"
-source = "git+https://github.com/servo/rust-cssparser#cbbfd66f794bd019bbdeaefc88b29eff455b62e5"
+source = "git+https://github.com/servo/rust-cssparser#3f98f1308b769b5d61efc6c133ac520df2b074ac"
dependencies = [
"encoding 0.2.0 (git+https://github.com/lifthrasiir/rust-encoding)",
]
diff --git a/tests/ref/basic.list b/tests/ref/basic.list
index 980350b5d9a..a31d6009b74 100644
--- a/tests/ref/basic.list
+++ b/tests/ref/basic.list
@@ -209,4 +209,5 @@ fragment=top != ../html/acid2.html acid2_ref.html
== box_shadow_inset_parsing_a.html box_shadow_inset_parsing_ref.html
!= list_style_type_a.html list_style_type_ref.html
== list_style_position_a.html list_style_position_ref.html
+== legacy_td_bgcolor_attribute_a.html legacy_td_bgcolor_attribute_ref.html
== legacy_table_border_attribute_a.html legacy_table_border_attribute_ref.html
diff --git a/tests/ref/legacy_td_bgcolor_attribute_a.html b/tests/ref/legacy_td_bgcolor_attribute_a.html
new file mode 100644
index 00000000000..d565feadacd
--- /dev/null
+++ b/tests/ref/legacy_td_bgcolor_attribute_a.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<body>
+<table border=0 cellspacing=0 cellpadding=0>
+ <tr><td bgcolor=chucknorris width=100>&nbsp;</td></tr>
+ <tr><td bgcolor=ChuckNorris width=100>&nbsp;</td></tr>
+ <tr><td bgcolor=sick width=100>&nbsp;</td></tr>
+ <tr><td bgcolor=crap width=100>&nbsp;</td></tr>
+ <tr><td bgcolor=LuckBeALadyTonight width=100>&nbsp;</td></tr>
+ <tr><td bgcolor=#abc width=100>&nbsp;</td></tr>
+ <tr><td bgcolor=#123456 width=100>&nbsp;</td></tr>
+ <tr><td bgcolor=#abacab width=100>&nbsp;</td></tr>
+ <tr><td bgcolor=#AbaCab width=100>&nbsp;</td></tr>
+ <tr><td bgcolor=#ABACAB width=100>&nbsp;</td></tr>
+ <tr><td bgcolor=transparent width=100>&nbsp;</td></tr>
+ <tr><td bgcolor=gold width=100>&nbsp;</td></tr>
+</table>
+</body>
+</html>
+
diff --git a/tests/ref/legacy_td_bgcolor_attribute_ref.html b/tests/ref/legacy_td_bgcolor_attribute_ref.html
new file mode 100644
index 00000000000..88038dd685b
--- /dev/null
+++ b/tests/ref/legacy_td_bgcolor_attribute_ref.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html>
+<body>
+<table border=0 cellspacing=0 cellpadding=0>
+ <tr><td style="background: #c00000" width=100>&nbsp;</td></tr>
+ <tr><td style="background: #c00000" width=100>&nbsp;</td></tr>
+ <tr><td style="background: #00c000" width=100>&nbsp;</td></tr>
+ <tr><td style="background: #c0a000" width=100>&nbsp;</td></tr>
+ <tr><td style="background: #00a000" width=100>&nbsp;</td></tr>
+ <tr><td style="background: #aabbcc" width=100>&nbsp;</td></tr>
+ <tr><td style="background: #123456" width=100>&nbsp;</td></tr>
+ <tr><td style="background: #abacab" width=100>&nbsp;</td></tr>
+ <tr><td style="background: #abacab" width=100>&nbsp;</td></tr>
+ <tr><td style="background: #abacab" width=100>&nbsp;</td></tr>
+ <tr><td width=100>&nbsp;</td></tr>
+ <tr><td style="background: gold" width=100>&nbsp;</td></tr>
+</table>
+</body>
+</html>
+
+