mirror of
https://github.com/servo/servo.git
synced 2025-08-03 12:40:06 +01:00
Implement something like CSS value serialization. Fetch actual inline style declarations from owning elements.
This commit is contained in:
parent
2e14b653bf
commit
505e1855a3
8 changed files with 375 additions and 55 deletions
|
@ -10,6 +10,7 @@ use dom::bindings::global;
|
||||||
use dom::bindings::js::{JSRef, Temporary};
|
use dom::bindings::js::{JSRef, Temporary};
|
||||||
use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object};
|
use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object};
|
||||||
use dom::cssstyledeclaration::CSSStyleDeclaration;
|
use dom::cssstyledeclaration::CSSStyleDeclaration;
|
||||||
|
use dom::htmlelement::HTMLElement;
|
||||||
use dom::window::Window;
|
use dom::window::Window;
|
||||||
use servo_util::str::DOMString;
|
use servo_util::str::DOMString;
|
||||||
|
|
||||||
|
@ -37,15 +38,15 @@ macro_rules! css_setter(
|
||||||
)
|
)
|
||||||
|
|
||||||
impl CSS2Properties {
|
impl CSS2Properties {
|
||||||
fn new_inherited() -> CSS2Properties {
|
fn new_inherited(owner: JSRef<HTMLElement>) -> CSS2Properties {
|
||||||
CSS2Properties {
|
CSS2Properties {
|
||||||
cssstyledeclaration: CSSStyleDeclaration::new_inherited(),
|
cssstyledeclaration: CSSStyleDeclaration::new_inherited(Some(owner)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new(global: &JSRef<Window>) -> Temporary<CSS2Properties> {
|
pub fn new(global: JSRef<Window>, owner: JSRef<HTMLElement>) -> Temporary<CSS2Properties> {
|
||||||
reflect_dom_object(box CSS2Properties::new_inherited(),
|
reflect_dom_object(box CSS2Properties::new_inherited(owner),
|
||||||
global::Window(*global),
|
global::Window(global),
|
||||||
CSS2PropertiesBinding::Wrap)
|
CSS2PropertiesBinding::Wrap)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,55 +3,67 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use dom::bindings::codegen::Bindings::CSSStyleDeclarationBinding::CSSStyleDeclarationMethods;
|
use dom::bindings::codegen::Bindings::CSSStyleDeclarationBinding::CSSStyleDeclarationMethods;
|
||||||
|
use dom::bindings::codegen::InheritTypes::ElementCast;
|
||||||
use dom::bindings::error::{ErrorResult, Fallible};
|
use dom::bindings::error::{ErrorResult, Fallible};
|
||||||
use dom::bindings::js::JSRef;
|
use dom::bindings::js::{JS, JSRef, OptionalRootedRootable};
|
||||||
use dom::bindings::utils::{Reflectable, Reflector};
|
use dom::bindings::utils::{Reflectable, Reflector};
|
||||||
|
use dom::element::{Element, ElementHelpers};
|
||||||
|
use dom::htmlelement::HTMLElement;
|
||||||
use servo_util::str::DOMString;
|
use servo_util::str::DOMString;
|
||||||
use string_cache::atom::Atom;
|
use string_cache::atom::Atom;
|
||||||
|
use style::longhands_from_shorthand;
|
||||||
|
use style::PropertyDeclaration;
|
||||||
use std::ascii::AsciiExt;
|
use std::ascii::AsciiExt;
|
||||||
|
|
||||||
#[dom_struct]
|
#[dom_struct]
|
||||||
pub struct CSSStyleDeclaration {
|
pub struct CSSStyleDeclaration {
|
||||||
reflector_: Reflector,
|
reflector_: Reflector,
|
||||||
|
owner: Option<JS<HTMLElement>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_longhands_from_shorthand(shorthand: &Atom) -> Vec<Atom> {
|
fn serialize_list(list: &Vec<PropertyDeclaration>) -> DOMString {
|
||||||
match shorthand.as_slice() {
|
let mut result = String::new();
|
||||||
"background" =>
|
|
||||||
vec!(Atom::from_slice("background-color"), Atom::from_slice("background-position"),
|
|
||||||
Atom::from_slice("background-attachment"), Atom::from_slice("background-image"),
|
|
||||||
Atom::from_slice("background-repeat")),
|
|
||||||
_ => vec!(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type Declaration = int;
|
|
||||||
|
|
||||||
fn serialize_list(property: String, list: Vec<Declaration>) -> DOMString {
|
|
||||||
let mut result = property;
|
|
||||||
result.push_str(": ");
|
|
||||||
for declaration in list.iter() {
|
for declaration in list.iter() {
|
||||||
result.push_str(serialize_declaration(declaration).as_slice());
|
result.push_str(serialize_value(declaration).as_slice());
|
||||||
|
result.push_str(" ");
|
||||||
}
|
}
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_declaration(_declaration: &Declaration) -> DOMString {
|
fn serialize_value(declaration: &PropertyDeclaration) -> DOMString {
|
||||||
"".to_string()
|
declaration.value().unwrap()
|
||||||
}
|
|
||||||
|
|
||||||
fn get_declaration(_property: &Atom) -> Option<Declaration> {
|
|
||||||
None
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CSSStyleDeclaration {
|
impl CSSStyleDeclaration {
|
||||||
pub fn new_inherited() -> CSSStyleDeclaration {
|
pub fn new_inherited(owner: Option<JSRef<HTMLElement>>) -> CSSStyleDeclaration {
|
||||||
CSSStyleDeclaration {
|
CSSStyleDeclaration {
|
||||||
reflector_: Reflector::new()
|
reflector_: Reflector::new(),
|
||||||
|
owner: owner.map(|owner| JS::from_rooted(owner)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trait PrivateCSSStyleDeclarationHelpers {
|
||||||
|
fn get_declaration(self, property: &Atom) -> Option<PropertyDeclaration>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> PrivateCSSStyleDeclarationHelpers for JSRef<'a, CSSStyleDeclaration> {
|
||||||
|
fn get_declaration(self, property: &Atom) -> Option<PropertyDeclaration> {
|
||||||
|
self.owner.root().and_then(|owner| {
|
||||||
|
let element: JSRef<Element> = ElementCast::from_ref(*owner);
|
||||||
|
let inline_declarations = element.style_attribute().borrow();
|
||||||
|
inline_declarations.as_ref().and_then(|declarations| {
|
||||||
|
for declaration in declarations.normal.iter().chain(declarations.important.iter()) {
|
||||||
|
if declaration.matches(property.as_slice()) {
|
||||||
|
return Some(declaration.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a> CSSStyleDeclarationMethods for JSRef<'a, CSSStyleDeclaration> {
|
impl<'a> CSSStyleDeclarationMethods for JSRef<'a, CSSStyleDeclaration> {
|
||||||
fn CssText(self) -> DOMString {
|
fn CssText(self) -> DOMString {
|
||||||
"".to_string()
|
"".to_string()
|
||||||
|
@ -75,39 +87,38 @@ impl<'a> CSSStyleDeclarationMethods for JSRef<'a, CSSStyleDeclaration> {
|
||||||
let property = Atom::from_slice(property.as_slice().to_ascii_lower().as_slice());
|
let property = Atom::from_slice(property.as_slice().to_ascii_lower().as_slice());
|
||||||
|
|
||||||
// 2. If property is a shorthand property, then follow these substeps:
|
// 2. If property is a shorthand property, then follow these substeps:
|
||||||
let longhand_properties = get_longhands_from_shorthand(&property);
|
let longhand_properties = longhands_from_shorthand(property.as_slice());
|
||||||
if !longhand_properties.is_empty() {
|
if longhand_properties.is_some() {
|
||||||
// 1. Let list be a new empty array.
|
// 1. Let list be a new empty array.
|
||||||
let mut list = vec!();
|
let mut list = vec!();
|
||||||
|
|
||||||
// 2. For each longhand property longhand that property maps to, in canonical order,
|
// 2. For each longhand property longhand that property maps to, in canonical order,
|
||||||
// follow these substeps:
|
// follow these substeps:
|
||||||
for longhand in longhand_properties.iter() {
|
for longhand in longhand_properties.unwrap().iter() {
|
||||||
// 1. If longhand is a case-sensitive match for a property name of a
|
// 1. If longhand is a case-sensitive match for a property name of a
|
||||||
// CSS declaration in the declarations, let declaration be that CSS
|
// CSS declaration in the declarations, let declaration be that CSS
|
||||||
// declaration, or null otherwise.
|
// declaration, or null otherwise.
|
||||||
let declaration = get_declaration(longhand);
|
let declaration = self.get_declaration(&Atom::from_slice(longhand.as_slice()));
|
||||||
|
|
||||||
// 2. If declaration is null, return the empty string and terminate these
|
// 2. If declaration is null, return the empty string and terminate these
|
||||||
// steps.
|
// steps.
|
||||||
if declaration.is_none() {
|
//XXXjdm ambiguous? this suggests that if we're missing a longhand we return nothing at all.
|
||||||
return "".to_string();
|
if declaration.is_some() {
|
||||||
|
// 3. Append the declaration to list.
|
||||||
|
list.push(declaration.unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. Append the declaration to list.
|
|
||||||
list.push(declaration.unwrap());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. Return the serialization of list and terminate these steps.
|
// 3. Return the serialization of list and terminate these steps.
|
||||||
return serialize_list(property.as_slice().to_string(), list);
|
return serialize_list(&list);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. If property is a case-sensitive match for a property name of a CSS declaration
|
// 3. If property is a case-sensitive match for a property name of a CSS declaration
|
||||||
// in the declarations, return the result of invoking serialize a CSS value of that
|
// in the declarations, return the result of invoking serialize a CSS value of that
|
||||||
// declaration and terminate these steps.
|
// declaration and terminate these steps.
|
||||||
// 4. Return the empty string.
|
// 4. Return the empty string.
|
||||||
let declaration = get_declaration(&property);
|
let declaration = self.get_declaration(&property);
|
||||||
declaration.as_ref().map(|declaration| serialize_declaration(declaration))
|
declaration.as_ref().map(|declaration| serialize_value(declaration))
|
||||||
.unwrap_or("".to_string())
|
.unwrap_or("".to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -73,8 +73,8 @@ impl<'a> PrivateHTMLElementHelpers for JSRef<'a, HTMLElement> {
|
||||||
impl<'a> HTMLElementMethods for JSRef<'a, HTMLElement> {
|
impl<'a> HTMLElementMethods for JSRef<'a, HTMLElement> {
|
||||||
fn Style(self) -> Temporary<CSSStyleDeclaration> {
|
fn Style(self) -> Temporary<CSSStyleDeclaration> {
|
||||||
if self.style_decl.get().is_none() {
|
if self.style_decl.get().is_none() {
|
||||||
let global = window_from_node(self);
|
let global = window_from_node(self).root();
|
||||||
let style_props = CSS2Properties::new(&*global.root()).root();
|
let style_props = CSS2Properties::new(*global, self).root();
|
||||||
let style_decl: JSRef<CSSStyleDeclaration> = CSSStyleDeclarationCast::from_ref(*style_props);
|
let style_decl: JSRef<CSSStyleDeclaration> = CSSStyleDeclarationCast::from_ref(*style_props);
|
||||||
self.style_decl.assign(Some(style_decl));
|
self.style_decl.assign(Some(style_decl));
|
||||||
}
|
}
|
||||||
|
|
|
@ -194,7 +194,7 @@ pub struct SharedLayoutData {
|
||||||
/// Encapsulates the abstract layout data.
|
/// Encapsulates the abstract layout data.
|
||||||
pub struct LayoutData {
|
pub struct LayoutData {
|
||||||
chan: Option<LayoutChan>,
|
chan: Option<LayoutChan>,
|
||||||
_shared_data: SharedLayoutData,
|
pub shared_data: SharedLayoutData,
|
||||||
_data: *const (),
|
_data: *const (),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
#![comment = "The Servo Parallel Browser Project"]
|
#![comment = "The Servo Parallel Browser Project"]
|
||||||
#![license = "MPL"]
|
#![license = "MPL"]
|
||||||
|
|
||||||
#![feature(globs, macro_rules)]
|
#![feature(globs, macro_rules, if_let)]
|
||||||
|
|
||||||
#![deny(unused_imports)]
|
#![deny(unused_imports)]
|
||||||
#![deny(unused_variables)]
|
#![deny(unused_variables)]
|
||||||
|
@ -42,7 +42,7 @@ pub use selector_matching::{CommonStyleAffectingAttributeInfo, CommonStyleAffect
|
||||||
pub use selector_matching::{matches, matches_simple_selector, common_style_affecting_attributes};
|
pub use selector_matching::{matches, matches_simple_selector, common_style_affecting_attributes};
|
||||||
pub use selector_matching::{rare_style_affecting_attributes};
|
pub use selector_matching::{rare_style_affecting_attributes};
|
||||||
pub use selector_matching::{RECOMMENDED_SELECTOR_BLOOM_FILTER_SIZE, SELECTOR_WHITESPACE};
|
pub use selector_matching::{RECOMMENDED_SELECTOR_BLOOM_FILTER_SIZE, SELECTOR_WHITESPACE};
|
||||||
pub use properties::{cascade, cascade_anonymous, computed};
|
pub use properties::{cascade, cascade_anonymous, computed, longhands_from_shorthand};
|
||||||
pub use properties::{PropertyDeclaration, ComputedValues, computed_values, style_structs};
|
pub use properties::{PropertyDeclaration, ComputedValues, computed_values, style_structs};
|
||||||
pub use properties::{PropertyDeclarationBlock, parse_style_attribute}; // Style attributes
|
pub use properties::{PropertyDeclarationBlock, parse_style_attribute}; // Style attributes
|
||||||
pub use properties::{CSSFloat, DeclaredValue, PropertyDeclarationParseResult};
|
pub use properties::{CSSFloat, DeclaredValue, PropertyDeclarationParseResult};
|
||||||
|
|
|
@ -13,6 +13,7 @@ pub type CSSFloat = f64;
|
||||||
pub mod specified {
|
pub mod specified {
|
||||||
use std::ascii::AsciiExt;
|
use std::ascii::AsciiExt;
|
||||||
use std::f64::consts::PI;
|
use std::f64::consts::PI;
|
||||||
|
use std::fmt::{Formatter, FormatError, Show};
|
||||||
use url::Url;
|
use url::Url;
|
||||||
use cssparser::ast;
|
use cssparser::ast;
|
||||||
use cssparser::ast::*;
|
use cssparser::ast::*;
|
||||||
|
@ -20,7 +21,7 @@ pub mod specified {
|
||||||
use super::{Au, CSSFloat};
|
use super::{Au, CSSFloat};
|
||||||
pub use cssparser::Color as CSSColor;
|
pub use cssparser::Color as CSSColor;
|
||||||
|
|
||||||
#[deriving(Clone, Show)]
|
#[deriving(Clone)]
|
||||||
pub enum Length {
|
pub enum Length {
|
||||||
Au(Au), // application units
|
Au(Au), // application units
|
||||||
Em(CSSFloat),
|
Em(CSSFloat),
|
||||||
|
@ -40,6 +41,17 @@ pub mod specified {
|
||||||
// Vmin(CSSFloat),
|
// Vmin(CSSFloat),
|
||||||
// Vmax(CSSFloat),
|
// Vmax(CSSFloat),
|
||||||
}
|
}
|
||||||
|
impl Show for Length {
|
||||||
|
fn fmt(&self, f: &mut Formatter) -> Result<(), FormatError> {
|
||||||
|
match self {
|
||||||
|
&Length::Au(length) => write!(f, "{}", length),
|
||||||
|
&Length::Em(length) => write!(f, "{}em", length),
|
||||||
|
&Length::Ex(length) => write!(f, "{}ex", length),
|
||||||
|
&Length::Rem(length) => write!(f, "{}rem", length),
|
||||||
|
&Length::ServoCharacterWidth(_) => panic!("internal CSS values should never be serialized"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
const AU_PER_PX: CSSFloat = 60.;
|
const AU_PER_PX: CSSFloat = 60.;
|
||||||
const AU_PER_IN: CSSFloat = AU_PER_PX * 96.;
|
const AU_PER_IN: CSSFloat = AU_PER_PX * 96.;
|
||||||
const AU_PER_CM: CSSFloat = AU_PER_IN / 2.54;
|
const AU_PER_CM: CSSFloat = AU_PER_IN / 2.54;
|
||||||
|
@ -83,12 +95,19 @@ pub mod specified {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[deriving(Clone, Show)]
|
#[deriving(Clone)]
|
||||||
pub enum LengthOrPercentage {
|
pub enum LengthOrPercentage {
|
||||||
Length(Length),
|
Length(Length),
|
||||||
Percentage(CSSFloat), // [0 .. 100%] maps to [0.0 .. 1.0]
|
Percentage(CSSFloat), // [0 .. 100%] maps to [0.0 .. 1.0]
|
||||||
}
|
}
|
||||||
|
impl Show for LengthOrPercentage {
|
||||||
|
fn fmt(&self, f: &mut Formatter) -> Result<(), FormatError> {
|
||||||
|
match self {
|
||||||
|
&LengthOrPercentage::Length(length) => write!(f, "{}", length),
|
||||||
|
&LengthOrPercentage::Percentage(percentage) => write!(f, "{}%", percentage),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
impl LengthOrPercentage {
|
impl LengthOrPercentage {
|
||||||
fn parse_internal(input: &ComponentValue, negative_ok: bool)
|
fn parse_internal(input: &ComponentValue, negative_ok: bool)
|
||||||
-> Result<LengthOrPercentage, ()> {
|
-> Result<LengthOrPercentage, ()> {
|
||||||
|
@ -120,6 +139,15 @@ pub mod specified {
|
||||||
Percentage(CSSFloat), // [0 .. 100%] maps to [0.0 .. 1.0]
|
Percentage(CSSFloat), // [0 .. 100%] maps to [0.0 .. 1.0]
|
||||||
Auto,
|
Auto,
|
||||||
}
|
}
|
||||||
|
impl Show for LengthOrPercentageOrAuto {
|
||||||
|
fn fmt(&self, f: &mut Formatter) -> Result<(), FormatError> {
|
||||||
|
match self {
|
||||||
|
&LengthOrPercentageOrAuto::Length(length) => write!(f, "{}", length),
|
||||||
|
&LengthOrPercentageOrAuto::Percentage(percentage) => write!(f, "{}%", percentage),
|
||||||
|
&LengthOrPercentageOrAuto::Auto => write!(f, "auto"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
impl LengthOrPercentageOrAuto {
|
impl LengthOrPercentageOrAuto {
|
||||||
fn parse_internal(input: &ComponentValue, negative_ok: bool)
|
fn parse_internal(input: &ComponentValue, negative_ok: bool)
|
||||||
-> Result<LengthOrPercentageOrAuto, ()> {
|
-> Result<LengthOrPercentageOrAuto, ()> {
|
||||||
|
@ -151,6 +179,15 @@ pub mod specified {
|
||||||
Percentage(CSSFloat), // [0 .. 100%] maps to [0.0 .. 1.0]
|
Percentage(CSSFloat), // [0 .. 100%] maps to [0.0 .. 1.0]
|
||||||
None,
|
None,
|
||||||
}
|
}
|
||||||
|
impl Show for LengthOrPercentageOrNone {
|
||||||
|
fn fmt(&self, f: &mut Formatter) -> Result<(), FormatError> {
|
||||||
|
match self {
|
||||||
|
&LengthOrPercentageOrNone::Length(length) => write!(f, "{}", length),
|
||||||
|
&LengthOrPercentageOrNone::Percentage(percentage) => write!(f, "{}%", percentage),
|
||||||
|
&LengthOrPercentageOrNone::None => write!(f, "none"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
impl LengthOrPercentageOrNone {
|
impl LengthOrPercentageOrNone {
|
||||||
fn parse_internal(input: &ComponentValue, negative_ok: bool)
|
fn parse_internal(input: &ComponentValue, negative_ok: bool)
|
||||||
-> Result<LengthOrPercentageOrNone, ()> {
|
-> Result<LengthOrPercentageOrNone, ()> {
|
||||||
|
@ -219,6 +256,13 @@ pub mod specified {
|
||||||
#[deriving(Clone, PartialEq, PartialOrd)]
|
#[deriving(Clone, PartialEq, PartialOrd)]
|
||||||
pub struct Angle(pub CSSFloat);
|
pub struct Angle(pub CSSFloat);
|
||||||
|
|
||||||
|
impl Show for Angle {
|
||||||
|
fn fmt(&self, f: &mut Formatter) -> Result<(), FormatError> {
|
||||||
|
let Angle(value) = *self;
|
||||||
|
write!(f, "{}", value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Angle {
|
impl Angle {
|
||||||
pub fn radians(self) -> f64 {
|
pub fn radians(self) -> f64 {
|
||||||
let Angle(radians) = self;
|
let Angle(radians) = self;
|
||||||
|
@ -253,6 +297,15 @@ pub mod specified {
|
||||||
LinearGradient(LinearGradient),
|
LinearGradient(LinearGradient),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Show for Image {
|
||||||
|
fn fmt(&self, f: &mut Formatter) -> Result<(), FormatError> {
|
||||||
|
match self {
|
||||||
|
&Image::Url(ref url) => write!(f, "url({})", url),
|
||||||
|
&Image::LinearGradient(ref grad) => write!(f, "linear-gradient({})", grad),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Image {
|
impl Image {
|
||||||
pub fn from_component_value(component_value: &ComponentValue, base_url: &Url)
|
pub fn from_component_value(component_value: &ComponentValue, base_url: &Url)
|
||||||
-> Result<Image,()> {
|
-> Result<Image,()> {
|
||||||
|
@ -296,6 +349,16 @@ pub mod specified {
|
||||||
pub stops: Vec<ColorStop>,
|
pub stops: Vec<ColorStop>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Show for LinearGradient {
|
||||||
|
fn fmt(&self, f: &mut Formatter) -> Result<(), FormatError> {
|
||||||
|
let _ = write!(f, "{}", self.angle_or_corner);
|
||||||
|
for stop in self.stops.iter() {
|
||||||
|
let _ = write!(f, ", {}", stop);
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Specified values for an angle or a corner in a linear gradient.
|
/// Specified values for an angle or a corner in a linear gradient.
|
||||||
#[deriving(Clone, PartialEq)]
|
#[deriving(Clone, PartialEq)]
|
||||||
pub enum AngleOrCorner {
|
pub enum AngleOrCorner {
|
||||||
|
@ -303,6 +366,15 @@ pub mod specified {
|
||||||
Corner(HorizontalDirection, VerticalDirection),
|
Corner(HorizontalDirection, VerticalDirection),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Show for AngleOrCorner {
|
||||||
|
fn fmt(&self, f: &mut Formatter) -> Result<(), FormatError> {
|
||||||
|
match self {
|
||||||
|
&AngleOrCorner::Angle(angle) => write!(f, "{}", angle),
|
||||||
|
&AngleOrCorner::Corner(horiz, vert) => write!(f, "to {} {}", horiz, vert),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Specified values for one color stop in a linear gradient.
|
/// Specified values for one color stop in a linear gradient.
|
||||||
#[deriving(Clone)]
|
#[deriving(Clone)]
|
||||||
pub struct ColorStop {
|
pub struct ColorStop {
|
||||||
|
@ -314,18 +386,46 @@ pub mod specified {
|
||||||
pub position: Option<LengthOrPercentage>,
|
pub position: Option<LengthOrPercentage>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Show for ColorStop {
|
||||||
|
fn fmt(&self, f: &mut Formatter) -> Result<(), FormatError> {
|
||||||
|
let _ = write!(f, "{}", self.color);
|
||||||
|
self.position.map(|pos| {
|
||||||
|
let _ = write!(f, " {}", pos);
|
||||||
|
});
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[deriving(Clone, PartialEq)]
|
#[deriving(Clone, PartialEq)]
|
||||||
pub enum HorizontalDirection {
|
pub enum HorizontalDirection {
|
||||||
Left,
|
Left,
|
||||||
Right,
|
Right,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Show for HorizontalDirection {
|
||||||
|
fn fmt(&self, f: &mut Formatter) -> Result<(), FormatError> {
|
||||||
|
match self {
|
||||||
|
&HorizontalDirection::Left => write!(f, "left"),
|
||||||
|
&HorizontalDirection::Right => write!(f, "right"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[deriving(Clone, PartialEq)]
|
#[deriving(Clone, PartialEq)]
|
||||||
pub enum VerticalDirection {
|
pub enum VerticalDirection {
|
||||||
Top,
|
Top,
|
||||||
Bottom,
|
Bottom,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Show for VerticalDirection {
|
||||||
|
fn fmt(&self, f: &mut Formatter) -> Result<(), FormatError> {
|
||||||
|
match self {
|
||||||
|
&VerticalDirection::Top => write!(f, "top"),
|
||||||
|
&VerticalDirection::Bottom => write!(f, "bottom"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn parse_color_stop(source: ParserIter) -> Result<ColorStop,()> {
|
fn parse_color_stop(source: ParserIter) -> Result<ColorStop,()> {
|
||||||
let color = match source.next() {
|
let color = match source.next() {
|
||||||
Some(color) => try!(CSSColor::parse(color)),
|
Some(color) => try!(CSSColor::parse(color)),
|
||||||
|
@ -466,6 +566,7 @@ pub mod computed {
|
||||||
pub use super::super::longhands::computed_as_specified as compute_CSSColor;
|
pub use super::super::longhands::computed_as_specified as compute_CSSColor;
|
||||||
use super::*;
|
use super::*;
|
||||||
use super::super::longhands;
|
use super::super::longhands;
|
||||||
|
use std::fmt;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
pub struct Context {
|
pub struct Context {
|
||||||
|
@ -518,11 +619,19 @@ pub mod computed {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[deriving(PartialEq, Clone, Show)]
|
#[deriving(PartialEq, Clone)]
|
||||||
pub enum LengthOrPercentage {
|
pub enum LengthOrPercentage {
|
||||||
Length(Au),
|
Length(Au),
|
||||||
Percentage(CSSFloat),
|
Percentage(CSSFloat),
|
||||||
}
|
}
|
||||||
|
impl fmt::Show for LengthOrPercentage {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
&LengthOrPercentage::Length(length) => write!(f, "{}", length),
|
||||||
|
&LengthOrPercentage::Percentage(percentage) => write!(f, "{}%", percentage),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
pub fn compute_LengthOrPercentage(value: specified::LengthOrPercentage, context: &Context)
|
pub fn compute_LengthOrPercentage(value: specified::LengthOrPercentage, context: &Context)
|
||||||
|
@ -535,7 +644,7 @@ pub mod computed {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[deriving(PartialEq, Clone, Show)]
|
#[deriving(PartialEq, Clone)]
|
||||||
pub enum LengthOrPercentageOrAuto {
|
pub enum LengthOrPercentageOrAuto {
|
||||||
Length(Au),
|
Length(Au),
|
||||||
Percentage(CSSFloat),
|
Percentage(CSSFloat),
|
||||||
|
@ -554,7 +663,7 @@ pub mod computed {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[deriving(PartialEq, Clone, Show)]
|
#[deriving(PartialEq, Clone)]
|
||||||
pub enum LengthOrPercentageOrNone {
|
pub enum LengthOrPercentageOrNone {
|
||||||
Length(Au),
|
Length(Au),
|
||||||
Percentage(CSSFloat),
|
Percentage(CSSFloat),
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
// This file is a Mako template: http://www.makotemplates.org/
|
// This file is a Mako template: http://www.makotemplates.org/
|
||||||
|
|
||||||
pub use std::ascii::AsciiExt;
|
pub use std::ascii::AsciiExt;
|
||||||
|
use std::fmt::Show;
|
||||||
|
|
||||||
use servo_util::logical_geometry::{WritingMode, LogicalMargin};
|
use servo_util::logical_geometry::{WritingMode, LogicalMargin};
|
||||||
use sync::Arc;
|
use sync::Arc;
|
||||||
|
@ -159,13 +160,23 @@ pub mod longhands {
|
||||||
<%self:single_component_value name="${name}" experimental="${experimental}">
|
<%self:single_component_value name="${name}" experimental="${experimental}">
|
||||||
${caller.body()}
|
${caller.body()}
|
||||||
pub mod computed_value {
|
pub mod computed_value {
|
||||||
|
use std::fmt;
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
#[deriving(PartialEq, Clone, FromPrimitive, Show)]
|
#[deriving(PartialEq, Clone, FromPrimitive)]
|
||||||
pub enum T {
|
pub enum T {
|
||||||
% for value in values.split():
|
% for value in values.split():
|
||||||
${to_rust_ident(value)},
|
${to_rust_ident(value)},
|
||||||
% endfor
|
% endfor
|
||||||
}
|
}
|
||||||
|
impl fmt::Show for T {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
% for value in values.split():
|
||||||
|
&T::${to_rust_ident(value)} => write!(f, "${value}"),
|
||||||
|
% endfor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
pub type SpecifiedValue = computed_value::T;
|
pub type SpecifiedValue = computed_value::T;
|
||||||
#[inline] pub fn get_initial_value() -> computed_value::T {
|
#[inline] pub fn get_initial_value() -> computed_value::T {
|
||||||
|
@ -455,11 +466,20 @@ pub mod longhands {
|
||||||
pub use super::computed_as_specified as to_computed_value;
|
pub use super::computed_as_specified as to_computed_value;
|
||||||
pub type SpecifiedValue = computed_value::T;
|
pub type SpecifiedValue = computed_value::T;
|
||||||
pub mod computed_value {
|
pub mod computed_value {
|
||||||
|
use std::fmt;
|
||||||
#[deriving(PartialEq, Clone)]
|
#[deriving(PartialEq, Clone)]
|
||||||
pub enum T {
|
pub enum T {
|
||||||
Auto,
|
Auto,
|
||||||
Number(i32),
|
Number(i32),
|
||||||
}
|
}
|
||||||
|
impl fmt::Show for T {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
&T::Auto => write!(f, "auto"),
|
||||||
|
&T::Number(number) => write!(f, "{}", number),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl T {
|
impl T {
|
||||||
pub fn number_or_zero(self) -> i32 {
|
pub fn number_or_zero(self) -> i32 {
|
||||||
|
@ -538,6 +558,7 @@ pub mod longhands {
|
||||||
${switch_to_style_struct("InheritedBox")}
|
${switch_to_style_struct("InheritedBox")}
|
||||||
|
|
||||||
<%self:single_component_value name="line-height">
|
<%self:single_component_value name="line-height">
|
||||||
|
use std::fmt;
|
||||||
#[deriving(Clone)]
|
#[deriving(Clone)]
|
||||||
pub enum SpecifiedValue {
|
pub enum SpecifiedValue {
|
||||||
Normal,
|
Normal,
|
||||||
|
@ -545,6 +566,15 @@ pub mod longhands {
|
||||||
Number(CSSFloat),
|
Number(CSSFloat),
|
||||||
// percentage are the same as em.
|
// percentage are the same as em.
|
||||||
}
|
}
|
||||||
|
impl fmt::Show for SpecifiedValue {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
&SpecifiedValue::Normal => write!(f, "normal"),
|
||||||
|
&SpecifiedValue::Length(length) => write!(f, "{}%", length),
|
||||||
|
&SpecifiedValue::Number(number) => write!(f, "{}", number),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
/// normal | <number> | <length> | <percentage>
|
/// normal | <number> | <length> | <percentage>
|
||||||
pub fn from_component_value(input: &ComponentValue, _base_url: &Url)
|
pub fn from_component_value(input: &ComponentValue, _base_url: &Url)
|
||||||
-> Result<SpecifiedValue, ()> {
|
-> Result<SpecifiedValue, ()> {
|
||||||
|
@ -586,6 +616,7 @@ pub mod longhands {
|
||||||
${switch_to_style_struct("Box")}
|
${switch_to_style_struct("Box")}
|
||||||
|
|
||||||
<%self:single_component_value name="vertical-align">
|
<%self:single_component_value name="vertical-align">
|
||||||
|
use std::fmt;
|
||||||
<% vertical_align_keywords = (
|
<% vertical_align_keywords = (
|
||||||
"baseline sub super top text-top middle bottom text-bottom".split()) %>
|
"baseline sub super top text-top middle bottom text-bottom".split()) %>
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
|
@ -596,6 +627,16 @@ pub mod longhands {
|
||||||
% endfor
|
% endfor
|
||||||
LengthOrPercentage(specified::LengthOrPercentage),
|
LengthOrPercentage(specified::LengthOrPercentage),
|
||||||
}
|
}
|
||||||
|
impl fmt::Show for SpecifiedValue {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
% for keyword in vertical_align_keywords:
|
||||||
|
&SpecifiedValue::${to_rust_ident(keyword)} => write!(f, "${keyword}"),
|
||||||
|
% endfor
|
||||||
|
&SpecifiedValue::LengthOrPercentage(lop) => write!(f, "{}", lop),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
/// baseline | sub | super | top | text-top | middle | bottom | text-bottom
|
/// baseline | sub | super | top | text-top | middle | bottom | text-bottom
|
||||||
/// | <percentage> | <length>
|
/// | <percentage> | <length>
|
||||||
pub fn from_component_value(input: &ComponentValue, _base_url: &Url)
|
pub fn from_component_value(input: &ComponentValue, _base_url: &Url)
|
||||||
|
@ -660,10 +701,18 @@ pub mod longhands {
|
||||||
<%self:longhand name="content">
|
<%self:longhand name="content">
|
||||||
pub use super::computed_as_specified as to_computed_value;
|
pub use super::computed_as_specified as to_computed_value;
|
||||||
pub mod computed_value {
|
pub mod computed_value {
|
||||||
|
use std::fmt;
|
||||||
#[deriving(PartialEq, Clone)]
|
#[deriving(PartialEq, Clone)]
|
||||||
pub enum ContentItem {
|
pub enum ContentItem {
|
||||||
StringContent(String),
|
StringContent(String),
|
||||||
}
|
}
|
||||||
|
impl fmt::Show for ContentItem {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
&ContentItem::StringContent(ref s) => write!(f, "{}", s),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
#[deriving(PartialEq, Clone)]
|
#[deriving(PartialEq, Clone)]
|
||||||
pub enum T {
|
pub enum T {
|
||||||
|
@ -671,6 +720,20 @@ pub mod longhands {
|
||||||
none,
|
none,
|
||||||
Content(Vec<ContentItem>),
|
Content(Vec<ContentItem>),
|
||||||
}
|
}
|
||||||
|
impl fmt::Show for T {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
&T::normal => write!(f, "normal"),
|
||||||
|
&T::none => write!(f, "none"),
|
||||||
|
&T::Content(ref content) => {
|
||||||
|
for c in content.iter() {
|
||||||
|
let _ = write!(f, "{} ", c);
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
pub type SpecifiedValue = computed_value::T;
|
pub type SpecifiedValue = computed_value::T;
|
||||||
#[inline] pub fn get_initial_value() -> computed_value::T { T::normal }
|
#[inline] pub fn get_initial_value() -> computed_value::T { T::normal }
|
||||||
|
@ -784,14 +847,24 @@ pub mod longhands {
|
||||||
</%self:single_component_value>
|
</%self:single_component_value>
|
||||||
|
|
||||||
<%self:longhand name="background-position">
|
<%self:longhand name="background-position">
|
||||||
|
use std::fmt;
|
||||||
|
|
||||||
pub mod computed_value {
|
pub mod computed_value {
|
||||||
use super::super::super::common_types::computed::LengthOrPercentage;
|
use super::super::super::common_types::computed::LengthOrPercentage;
|
||||||
|
use std::fmt;
|
||||||
|
|
||||||
#[deriving(PartialEq, Clone)]
|
#[deriving(PartialEq, Clone)]
|
||||||
pub struct T {
|
pub struct T {
|
||||||
pub horizontal: LengthOrPercentage,
|
pub horizontal: LengthOrPercentage,
|
||||||
pub vertical: LengthOrPercentage,
|
pub vertical: LengthOrPercentage,
|
||||||
}
|
}
|
||||||
|
impl fmt::Show for T {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
let _ = write!(f, "{}", self.horizontal);
|
||||||
|
let _ = write!(f, "{}", self.vertical);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[deriving(Clone)]
|
#[deriving(Clone)]
|
||||||
|
@ -799,6 +872,13 @@ pub mod longhands {
|
||||||
pub horizontal: specified::LengthOrPercentage,
|
pub horizontal: specified::LengthOrPercentage,
|
||||||
pub vertical: specified::LengthOrPercentage,
|
pub vertical: specified::LengthOrPercentage,
|
||||||
}
|
}
|
||||||
|
impl fmt::Show for SpecifiedValue {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
let _ = write!(f, "{}", self.horizontal);
|
||||||
|
let _ = write!(f, "{}", self.vertical);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl SpecifiedValue {
|
impl SpecifiedValue {
|
||||||
fn new(first: specified::PositionComponent, second: specified::PositionComponent)
|
fn new(first: specified::PositionComponent, second: specified::PositionComponent)
|
||||||
|
@ -927,6 +1007,7 @@ pub mod longhands {
|
||||||
<%self:longhand name="font-family">
|
<%self:longhand name="font-family">
|
||||||
pub use super::computed_as_specified as to_computed_value;
|
pub use super::computed_as_specified as to_computed_value;
|
||||||
pub mod computed_value {
|
pub mod computed_value {
|
||||||
|
use std::fmt;
|
||||||
#[deriving(PartialEq, Clone)]
|
#[deriving(PartialEq, Clone)]
|
||||||
pub enum FontFamily {
|
pub enum FontFamily {
|
||||||
FamilyName(String),
|
FamilyName(String),
|
||||||
|
@ -944,7 +1025,22 @@ pub mod longhands {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl fmt::Show for FontFamily {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
&FontFamily::FamilyName(ref name) => write!(f, "{}", name),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
pub type T = Vec<FontFamily>;
|
pub type T = Vec<FontFamily>;
|
||||||
|
/*impl fmt::Show for T {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
for font in self.iter() {
|
||||||
|
write!(f, "{} ", font);
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}*/
|
||||||
}
|
}
|
||||||
pub type SpecifiedValue = computed_value::T;
|
pub type SpecifiedValue = computed_value::T;
|
||||||
|
|
||||||
|
@ -998,6 +1094,7 @@ pub mod longhands {
|
||||||
${single_keyword("font-variant", "normal small-caps")}
|
${single_keyword("font-variant", "normal small-caps")}
|
||||||
|
|
||||||
<%self:single_component_value name="font-weight">
|
<%self:single_component_value name="font-weight">
|
||||||
|
use std::fmt;
|
||||||
#[deriving(Clone)]
|
#[deriving(Clone)]
|
||||||
pub enum SpecifiedValue {
|
pub enum SpecifiedValue {
|
||||||
Bolder,
|
Bolder,
|
||||||
|
@ -1006,6 +1103,17 @@ pub mod longhands {
|
||||||
SpecifiedWeight${weight},
|
SpecifiedWeight${weight},
|
||||||
% endfor
|
% endfor
|
||||||
}
|
}
|
||||||
|
impl fmt::Show for SpecifiedValue {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
&SpecifiedValue::Bolder => write!(f, "bolder"),
|
||||||
|
&SpecifiedValue::Lighter => write!(f, "lighter"),
|
||||||
|
% for weight in range(100, 901, 100):
|
||||||
|
&SpecifiedValue::SpecifiedWeight${weight} => write!(f, "{}", ${weight}i),
|
||||||
|
% endfor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
/// normal | bold | bolder | lighter | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900
|
/// normal | bold | bolder | lighter | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900
|
||||||
pub fn from_component_value(input: &ComponentValue, _base_url: &Url)
|
pub fn from_component_value(input: &ComponentValue, _base_url: &Url)
|
||||||
-> Result<SpecifiedValue, ()> {
|
-> Result<SpecifiedValue, ()> {
|
||||||
|
@ -1193,6 +1301,7 @@ pub mod longhands {
|
||||||
|
|
||||||
<%self:longhand name="text-decoration">
|
<%self:longhand name="text-decoration">
|
||||||
pub use super::computed_as_specified as to_computed_value;
|
pub use super::computed_as_specified as to_computed_value;
|
||||||
|
use std::fmt;
|
||||||
#[deriving(PartialEq, Clone)]
|
#[deriving(PartialEq, Clone)]
|
||||||
pub struct SpecifiedValue {
|
pub struct SpecifiedValue {
|
||||||
pub underline: bool,
|
pub underline: bool,
|
||||||
|
@ -1201,6 +1310,20 @@ pub mod longhands {
|
||||||
// 'blink' is accepted in the parser but ignored.
|
// 'blink' is accepted in the parser but ignored.
|
||||||
// Just not blinking the text is a conforming implementation per CSS 2.1.
|
// Just not blinking the text is a conforming implementation per CSS 2.1.
|
||||||
}
|
}
|
||||||
|
impl fmt::Show for SpecifiedValue {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
if self.underline {
|
||||||
|
let _ = write!(f, "underline ");
|
||||||
|
}
|
||||||
|
if self.overline {
|
||||||
|
let _ = write!(f, "overline ");
|
||||||
|
}
|
||||||
|
if self.line_through {
|
||||||
|
let _ = write!(f, "line-through ");
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
pub mod computed_value {
|
pub mod computed_value {
|
||||||
pub type T = super::SpecifiedValue;
|
pub type T = super::SpecifiedValue;
|
||||||
#[allow(non_upper_case_globals)]
|
#[allow(non_upper_case_globals)]
|
||||||
|
@ -1518,6 +1641,7 @@ pub mod longhands {
|
||||||
|
|
||||||
<%self:longhand name="box-shadow">
|
<%self:longhand name="box-shadow">
|
||||||
use cssparser;
|
use cssparser;
|
||||||
|
use std::fmt;
|
||||||
|
|
||||||
pub type SpecifiedValue = Vec<SpecifiedBoxShadow>;
|
pub type SpecifiedValue = Vec<SpecifiedBoxShadow>;
|
||||||
|
|
||||||
|
@ -1531,6 +1655,20 @@ pub mod longhands {
|
||||||
pub inset: bool,
|
pub inset: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl fmt::Show for SpecifiedBoxShadow {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
if self.inset {
|
||||||
|
let _ = write!(f, "inset ");
|
||||||
|
}
|
||||||
|
let _ = write!(f, "{} {} {} {}", self.offset_x, self.offset_y,
|
||||||
|
self.blur_radius, self.spread_radius);
|
||||||
|
if let Some(ref color) = self.color {
|
||||||
|
let _ = write!(f, "{}", color);
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub mod computed_value {
|
pub mod computed_value {
|
||||||
use super::super::Au;
|
use super::super::Au;
|
||||||
use super::super::super::computed;
|
use super::super::super::computed;
|
||||||
|
@ -2314,6 +2452,15 @@ pub enum DeclaredValue<T> {
|
||||||
// depending on whether the property is inherited.
|
// depending on whether the property is inherited.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T: Show> DeclaredValue<T> {
|
||||||
|
pub fn specified_value(&self) -> Option<String> {
|
||||||
|
match self {
|
||||||
|
&DeclaredValue::SpecifiedValue(ref inner) => Some(format!("{}", inner)),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[deriving(Clone)]
|
#[deriving(Clone)]
|
||||||
pub enum PropertyDeclaration {
|
pub enum PropertyDeclaration {
|
||||||
% for property in LONGHANDS:
|
% for property in LONGHANDS:
|
||||||
|
@ -2329,8 +2476,41 @@ pub enum PropertyDeclarationParseResult {
|
||||||
ValidOrIgnoredDeclaration,
|
ValidOrIgnoredDeclaration,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl PropertyDeclaration {
|
impl PropertyDeclaration {
|
||||||
|
pub fn name(&self) -> String {
|
||||||
|
match self {
|
||||||
|
% for property in LONGHANDS:
|
||||||
|
% if property.derived_from is None:
|
||||||
|
&PropertyDeclaration::${property.camel_case}Declaration(..) => "${property.name}".to_string(),
|
||||||
|
% endif
|
||||||
|
% endfor
|
||||||
|
_ => "".to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn value(&self) -> Option<String> {
|
||||||
|
match self {
|
||||||
|
% for property in LONGHANDS:
|
||||||
|
% if property.derived_from is None:
|
||||||
|
&PropertyDeclaration::${property.camel_case}Declaration(ref value) => value.specified_value(),
|
||||||
|
% endif
|
||||||
|
% endfor
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn matches(&self, name: &str) -> bool {
|
||||||
|
let name_lower = name.as_slice().to_ascii_lower();
|
||||||
|
match (self, name_lower.as_slice()) {
|
||||||
|
% for property in LONGHANDS:
|
||||||
|
% if property.derived_from is None:
|
||||||
|
(&PropertyDeclaration::${property.camel_case}Declaration(..), "${property.name}") => true,
|
||||||
|
% endif
|
||||||
|
% endfor
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn parse(name: &str, value: &[ComponentValue],
|
pub fn parse(name: &str, value: &[ComponentValue],
|
||||||
result_list: &mut Vec<PropertyDeclaration>,
|
result_list: &mut Vec<PropertyDeclaration>,
|
||||||
base_url: &Url,
|
base_url: &Url,
|
||||||
|
@ -2964,6 +3144,18 @@ pub fn cascade_anonymous(parent_style: &ComputedValues) -> ComputedValues {
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn longhands_from_shorthand(shorthand: &str) -> Option<Vec<String>> {
|
||||||
|
match shorthand {
|
||||||
|
% for property in SHORTHANDS:
|
||||||
|
"${property.name}" => Some(vec!(
|
||||||
|
% for sub in property.sub_properties:
|
||||||
|
"${sub.name}".to_string(),
|
||||||
|
% endfor
|
||||||
|
)),
|
||||||
|
% endfor
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Only re-export the types for computed values.
|
// Only re-export the types for computed values.
|
||||||
pub mod computed_values {
|
pub mod computed_values {
|
||||||
|
|
7
tests/html/test_style.html
Normal file
7
tests/html/test_style.html
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
<div id="test" style="display: block; background-color: black; background-position: top left;"></div>
|
||||||
|
<script>
|
||||||
|
alert(document.getElementById('test').style.display);
|
||||||
|
alert(document.getElementById('test').style.background);
|
||||||
|
alert(document.getElementById('test').style.backgroundColor);
|
||||||
|
alert(document.getElementById('test').style.backgroundPosition);
|
||||||
|
</script>
|
Loading…
Add table
Add a link
Reference in a new issue