mirror of
https://github.com/servo/servo.git
synced 2025-08-04 13:10:20 +01:00
Implement setting element style properties. Improve serialization to return initial values when unspecified.
This commit is contained in:
parent
505e1855a3
commit
6f8a9b6d46
6 changed files with 218 additions and 20 deletions
|
@ -3,16 +3,20 @@
|
||||||
* 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::codegen::InheritTypes::{NodeCast, ElementCast};
|
||||||
use dom::bindings::error::{ErrorResult, Fallible};
|
use dom::bindings::error::{ErrorResult, Fallible};
|
||||||
use dom::bindings::js::{JS, JSRef, OptionalRootedRootable};
|
use dom::bindings::js::{JS, JSRef, OptionalRootedRootable};
|
||||||
use dom::bindings::utils::{Reflectable, Reflector};
|
use dom::bindings::utils::{Reflectable, Reflector};
|
||||||
|
use dom::document::DocumentHelpers;
|
||||||
use dom::element::{Element, ElementHelpers};
|
use dom::element::{Element, ElementHelpers};
|
||||||
use dom::htmlelement::HTMLElement;
|
use dom::htmlelement::HTMLElement;
|
||||||
|
use dom::node::{document_from_node, NodeDamage, Node};
|
||||||
use servo_util::str::DOMString;
|
use servo_util::str::DOMString;
|
||||||
use string_cache::atom::Atom;
|
use string_cache::Atom;
|
||||||
use style::longhands_from_shorthand;
|
use style::{is_supported_property, longhands_from_shorthand, parse_style_attribute};
|
||||||
use style::PropertyDeclaration;
|
use style::PropertyDeclaration;
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
use std::ascii::AsciiExt;
|
use std::ascii::AsciiExt;
|
||||||
|
|
||||||
#[dom_struct]
|
#[dom_struct]
|
||||||
|
@ -31,7 +35,7 @@ fn serialize_list(list: &Vec<PropertyDeclaration>) -> DOMString {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_value(declaration: &PropertyDeclaration) -> DOMString {
|
fn serialize_value(declaration: &PropertyDeclaration) -> DOMString {
|
||||||
declaration.value().unwrap()
|
declaration.value()
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CSSStyleDeclaration {
|
impl CSSStyleDeclaration {
|
||||||
|
@ -51,15 +55,7 @@ impl<'a> PrivateCSSStyleDeclarationHelpers for JSRef<'a, CSSStyleDeclaration> {
|
||||||
fn get_declaration(self, property: &Atom) -> Option<PropertyDeclaration> {
|
fn get_declaration(self, property: &Atom) -> Option<PropertyDeclaration> {
|
||||||
self.owner.root().and_then(|owner| {
|
self.owner.root().and_then(|owner| {
|
||||||
let element: JSRef<Element> = ElementCast::from_ref(*owner);
|
let element: JSRef<Element> = ElementCast::from_ref(*owner);
|
||||||
let inline_declarations = element.style_attribute().borrow();
|
element.get_inline_style_declaration(property).map(|decl| decl.clone())
|
||||||
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
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -131,7 +127,60 @@ impl<'a> CSSStyleDeclarationMethods for JSRef<'a, CSSStyleDeclaration> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn SetPropertyValue(self, _property: DOMString, _value: DOMString) -> ErrorResult {
|
fn SetPropertyValue(self, property: DOMString, value: DOMString) -> ErrorResult {
|
||||||
|
// 1. If the readonly flag is set, throw a NoModificationAllowedError exception
|
||||||
|
// and terminate these steps.
|
||||||
|
//TODO
|
||||||
|
|
||||||
|
// 2. Let property be property converted to ASCII lowercase.
|
||||||
|
let property = Atom::from_slice(property.as_slice().to_ascii_lower().as_slice());
|
||||||
|
|
||||||
|
// 3. If property is not a case-sensitive match for a supported CSS property,
|
||||||
|
// terminate this algorithm.
|
||||||
|
if !is_supported_property(property.as_slice()) {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. If value is the empty string, invoke removeProperty() with property as argument
|
||||||
|
// and terminate this algorithm.
|
||||||
|
if value.is_empty() {
|
||||||
|
//TODO: self.RemoveProperty(property)
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. Let component value list be the result of parsing value for property property.
|
||||||
|
let mut synthesized_declaration = property.as_slice().to_string();
|
||||||
|
synthesized_declaration.push_str(": ");
|
||||||
|
synthesized_declaration.push_str(value.as_slice());
|
||||||
|
//XXXjdm need page url
|
||||||
|
let decl_block = parse_style_attribute(synthesized_declaration.as_slice(),
|
||||||
|
&Url::parse("http://localhost").unwrap());
|
||||||
|
|
||||||
|
// 6. If component value list is null terminate these steps.
|
||||||
|
if decl_block.normal.len() == 0 {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
let owner = self.owner.root();
|
||||||
|
let element: JSRef<Element> = ElementCast::from_ref(**owner.as_ref().unwrap());
|
||||||
|
|
||||||
|
assert!(decl_block.important.len() == 0);
|
||||||
|
for decl in decl_block.normal.iter() {
|
||||||
|
// 7. If property is a shorthand property, then for each longhand property
|
||||||
|
// longhand that property maps to, in canonical order, set the CSS
|
||||||
|
// declaration value longhand to the appropriate value(s) from component
|
||||||
|
// value list, and with the list of declarations being the declarations.
|
||||||
|
|
||||||
|
// 8. Otherwise, set the CSS declaration value property to the
|
||||||
|
// value component value list, and with the list of declarations
|
||||||
|
// being the declarations.
|
||||||
|
|
||||||
|
element.update_inline_style(decl.clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
let document = document_from_node(element).root();
|
||||||
|
let node: JSRef<Node> = NodeCast::from_ref(element);
|
||||||
|
document.content_changed(node, NodeDamage::NodeStyleDamaged);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -60,6 +60,7 @@ use std::ascii::AsciiExt;
|
||||||
use std::cell::{Ref, RefMut};
|
use std::cell::{Ref, RefMut};
|
||||||
use std::default::Default;
|
use std::default::Default;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
use std::sync::Arc;
|
||||||
use string_cache::{Atom, Namespace, QualName};
|
use string_cache::{Atom, Namespace, QualName};
|
||||||
use url::UrlParser;
|
use url::UrlParser;
|
||||||
|
|
||||||
|
@ -465,6 +466,8 @@ pub trait ElementHelpers<'a> {
|
||||||
fn style_attribute(self) -> &'a DOMRefCell<Option<style::PropertyDeclarationBlock>>;
|
fn style_attribute(self) -> &'a DOMRefCell<Option<style::PropertyDeclarationBlock>>;
|
||||||
fn summarize(self) -> Vec<AttrInfo>;
|
fn summarize(self) -> Vec<AttrInfo>;
|
||||||
fn is_void(self) -> bool;
|
fn is_void(self) -> bool;
|
||||||
|
fn update_inline_style(self, property_decl: style::PropertyDeclaration);
|
||||||
|
fn get_inline_style_declaration(self, property: &Atom) -> Option<style::PropertyDeclaration>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ElementHelpers<'a> for JSRef<'a, Element> {
|
impl<'a> ElementHelpers<'a> for JSRef<'a, Element> {
|
||||||
|
@ -522,6 +525,40 @@ impl<'a> ElementHelpers<'a> for JSRef<'a, Element> {
|
||||||
_ => false
|
_ => false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn update_inline_style(self, property_decl: style::PropertyDeclaration) {
|
||||||
|
let mut inline_declarations = self.style_attribute.borrow_mut();
|
||||||
|
let exists = inline_declarations.is_some();
|
||||||
|
if exists {
|
||||||
|
let declarations = inline_declarations.as_mut().unwrap();
|
||||||
|
for declaration in declarations.normal.make_unique()
|
||||||
|
.iter_mut()
|
||||||
|
.chain(declarations.important.make_unique().iter_mut()) {
|
||||||
|
if declaration.name().as_slice() == property_decl.name().as_slice() {
|
||||||
|
*declaration = property_decl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
declarations.normal.make_unique().push(property_decl);
|
||||||
|
} else {
|
||||||
|
*inline_declarations = Some(style::PropertyDeclarationBlock {
|
||||||
|
important: Arc::new(vec!()),
|
||||||
|
normal: Arc::new(vec!(property_decl)),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_inline_style_declaration(self, property: &Atom) -> Option<style::PropertyDeclaration> {
|
||||||
|
let mut inline_declarations = self.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
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait AttributeHandlers {
|
pub trait AttributeHandlers {
|
||||||
|
|
|
@ -43,6 +43,7 @@ pub use selector_matching::{matches, matches_simple_selector, common_style_affec
|
||||||
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, longhands_from_shorthand};
|
pub use properties::{cascade, cascade_anonymous, computed, longhands_from_shorthand};
|
||||||
|
pub use properties::is_supported_property;
|
||||||
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};
|
||||||
|
|
|
@ -650,6 +650,15 @@ pub mod computed {
|
||||||
Percentage(CSSFloat),
|
Percentage(CSSFloat),
|
||||||
Auto,
|
Auto,
|
||||||
}
|
}
|
||||||
|
impl fmt::Show for LengthOrPercentageOrAuto {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
&LengthOrPercentageOrAuto::Length(length) => write!(f, "{}", length),
|
||||||
|
&LengthOrPercentageOrAuto::Percentage(percentage) => write!(f, "{}%", percentage),
|
||||||
|
&LengthOrPercentageOrAuto::Auto => write!(f, "auto"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
pub fn compute_LengthOrPercentageOrAuto(value: specified::LengthOrPercentageOrAuto,
|
pub fn compute_LengthOrPercentageOrAuto(value: specified::LengthOrPercentageOrAuto,
|
||||||
context: &Context) -> LengthOrPercentageOrAuto {
|
context: &Context) -> LengthOrPercentageOrAuto {
|
||||||
|
@ -669,6 +678,15 @@ pub mod computed {
|
||||||
Percentage(CSSFloat),
|
Percentage(CSSFloat),
|
||||||
None,
|
None,
|
||||||
}
|
}
|
||||||
|
impl fmt::Show for LengthOrPercentageOrNone {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
&LengthOrPercentageOrNone::Length(length) => write!(f, "{}", length),
|
||||||
|
&LengthOrPercentageOrNone::Percentage(percentage) => write!(f, "{}%", percentage),
|
||||||
|
&LengthOrPercentageOrNone::None => write!(f, "none"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
pub fn compute_LengthOrPercentageOrNone(value: specified::LengthOrPercentageOrNone,
|
pub fn compute_LengthOrPercentageOrNone(value: specified::LengthOrPercentageOrNone,
|
||||||
context: &Context) -> LengthOrPercentageOrNone {
|
context: &Context) -> LengthOrPercentageOrNone {
|
||||||
|
@ -689,6 +707,15 @@ pub mod computed {
|
||||||
LinearGradient(LinearGradient),
|
LinearGradient(LinearGradient),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl fmt::Show for Image {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
&Image::Url(ref url) => write!(f, "url({})", url),
|
||||||
|
&Image::LinearGradient(ref grad) => write!(f, "linear-gradient({})", grad),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Computed values for a CSS linear gradient.
|
/// Computed values for a CSS linear gradient.
|
||||||
#[deriving(Clone, PartialEq)]
|
#[deriving(Clone, PartialEq)]
|
||||||
pub struct LinearGradient {
|
pub struct LinearGradient {
|
||||||
|
@ -699,6 +726,16 @@ pub mod computed {
|
||||||
pub stops: Vec<ColorStop>,
|
pub stops: Vec<ColorStop>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl fmt::Show for LinearGradient {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
let _ = write!(f, "{}", self.angle_or_corner);
|
||||||
|
for stop in self.stops.iter() {
|
||||||
|
let _ = write!(f, ", {}", stop);
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Computed values for one color stop in a linear gradient.
|
/// Computed values for one color stop in a linear gradient.
|
||||||
#[deriving(Clone, PartialEq)]
|
#[deriving(Clone, PartialEq)]
|
||||||
pub struct ColorStop {
|
pub struct ColorStop {
|
||||||
|
@ -710,6 +747,16 @@ pub mod computed {
|
||||||
pub position: Option<LengthOrPercentage>,
|
pub position: Option<LengthOrPercentage>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl fmt::Show for ColorStop {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
let _ = write!(f, "{}", self.color);
|
||||||
|
self.position.map(|pos| {
|
||||||
|
let _ = write!(f, " {}", pos);
|
||||||
|
});
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl LinearGradient {
|
impl LinearGradient {
|
||||||
pub fn compute(value: specified::LinearGradient, context: &Context) -> LinearGradient {
|
pub fn compute(value: specified::LinearGradient, context: &Context) -> LinearGradient {
|
||||||
let specified::LinearGradient {
|
let specified::LinearGradient {
|
||||||
|
|
|
@ -593,12 +593,22 @@ pub mod longhands {
|
||||||
}
|
}
|
||||||
pub mod computed_value {
|
pub mod computed_value {
|
||||||
use super::super::{Au, CSSFloat};
|
use super::super::{Au, CSSFloat};
|
||||||
|
use std::fmt;
|
||||||
#[deriving(PartialEq, Clone)]
|
#[deriving(PartialEq, Clone)]
|
||||||
pub enum T {
|
pub enum T {
|
||||||
Normal,
|
Normal,
|
||||||
Length(Au),
|
Length(Au),
|
||||||
Number(CSSFloat),
|
Number(CSSFloat),
|
||||||
}
|
}
|
||||||
|
impl fmt::Show for T {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
&T::Normal => write!(f, "normal"),
|
||||||
|
&T::Length(length) => write!(f, "{}%", length),
|
||||||
|
&T::Number(number) => write!(f, "{}", number),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_initial_value() -> computed_value::T { T::Normal }
|
pub fn get_initial_value() -> computed_value::T { T::Normal }
|
||||||
|
@ -656,6 +666,7 @@ pub mod longhands {
|
||||||
}
|
}
|
||||||
pub mod computed_value {
|
pub mod computed_value {
|
||||||
use super::super::{Au, CSSFloat};
|
use super::super::{Au, CSSFloat};
|
||||||
|
use std::fmt;
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
#[deriving(PartialEq, Clone)]
|
#[deriving(PartialEq, Clone)]
|
||||||
pub enum T {
|
pub enum T {
|
||||||
|
@ -665,6 +676,17 @@ pub mod longhands {
|
||||||
Length(Au),
|
Length(Au),
|
||||||
Percentage(CSSFloat),
|
Percentage(CSSFloat),
|
||||||
}
|
}
|
||||||
|
impl fmt::Show for T {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
% for keyword in vertical_align_keywords:
|
||||||
|
&T::${to_rust_ident(keyword)} => write!(f, "${keyword}"),
|
||||||
|
% endfor
|
||||||
|
&T::Length(length) => write!(f, "{}", length),
|
||||||
|
&T::Percentage(number) => write!(f, "{}%", number),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_initial_value() -> computed_value::T { T::baseline }
|
pub fn get_initial_value() -> computed_value::T { T::baseline }
|
||||||
|
@ -1143,12 +1165,22 @@ pub mod longhands {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub mod computed_value {
|
pub mod computed_value {
|
||||||
|
use std::fmt;
|
||||||
#[deriving(PartialEq, Clone)]
|
#[deriving(PartialEq, Clone)]
|
||||||
pub enum T {
|
pub enum T {
|
||||||
% for weight in range(100, 901, 100):
|
% for weight in range(100, 901, 100):
|
||||||
Weight${weight},
|
Weight${weight},
|
||||||
% endfor
|
% endfor
|
||||||
}
|
}
|
||||||
|
impl fmt::Show for T {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
% for weight in range(100, 901, 100):
|
||||||
|
&T::Weight${weight} => write!(f, "{}", ${weight}i),
|
||||||
|
% endfor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
impl T {
|
impl T {
|
||||||
pub fn is_bold(self) -> bool {
|
pub fn is_bold(self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
|
@ -1672,6 +1704,7 @@ pub mod longhands {
|
||||||
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;
|
||||||
|
use std::fmt;
|
||||||
|
|
||||||
pub type T = Vec<BoxShadow>;
|
pub type T = Vec<BoxShadow>;
|
||||||
|
|
||||||
|
@ -1684,6 +1717,17 @@ pub mod longhands {
|
||||||
pub color: computed::CSSColor,
|
pub color: computed::CSSColor,
|
||||||
pub inset: bool,
|
pub inset: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl fmt::Show for BoxShadow {
|
||||||
|
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, self.color);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -2456,7 +2500,8 @@ impl<T: Show> DeclaredValue<T> {
|
||||||
pub fn specified_value(&self) -> Option<String> {
|
pub fn specified_value(&self) -> Option<String> {
|
||||||
match self {
|
match self {
|
||||||
&DeclaredValue::SpecifiedValue(ref inner) => Some(format!("{}", inner)),
|
&DeclaredValue::SpecifiedValue(ref inner) => Some(format!("{}", inner)),
|
||||||
_ => None,
|
&DeclaredValue::Initial => None,
|
||||||
|
&DeclaredValue::Inherit => Some("inherit".to_string()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2488,14 +2533,16 @@ impl PropertyDeclaration {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn value(&self) -> Option<String> {
|
pub fn value(&self) -> String {
|
||||||
match self {
|
match self {
|
||||||
% for property in LONGHANDS:
|
% for property in LONGHANDS:
|
||||||
% if property.derived_from is None:
|
% if property.derived_from is None:
|
||||||
&PropertyDeclaration::${property.camel_case}Declaration(ref value) => value.specified_value(),
|
&PropertyDeclaration::${property.camel_case}Declaration(ref value) =>
|
||||||
|
value.specified_value()
|
||||||
|
.unwrap_or_else(|| format!("{}", longhands::${property.ident}::get_initial_value())),
|
||||||
% endif
|
% endif
|
||||||
% endfor
|
% endfor
|
||||||
_ => None,
|
decl => panic!("unsupported property declaration: {}", decl.name()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3144,6 +3191,18 @@ pub fn cascade_anonymous(parent_style: &ComputedValues) -> ComputedValues {
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_supported_property(property: &str) -> bool {
|
||||||
|
match property {
|
||||||
|
% for property in SHORTHANDS:
|
||||||
|
"${property.name}" => true,
|
||||||
|
% endfor
|
||||||
|
% for property in LONGHANDS:
|
||||||
|
"${property.name}" => true,
|
||||||
|
% endfor
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn longhands_from_shorthand(shorthand: &str) -> Option<Vec<String>> {
|
pub fn longhands_from_shorthand(shorthand: &str) -> Option<Vec<String>> {
|
||||||
match shorthand {
|
match shorthand {
|
||||||
% for property in SHORTHANDS:
|
% for property in SHORTHANDS:
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
<div id="test" style="display: block; background-color: black; background-position: top left;"></div>
|
<div id="test" style="display: block; background-color: black; background-position: top left;">test text!</div>
|
||||||
<script>
|
<script>
|
||||||
alert(document.getElementById('test').style.display);
|
var id = document.getElementById('test');
|
||||||
|
/*alert(id.style.display);
|
||||||
|
id.style.display = 'none';
|
||||||
|
alert(id.style.display);*/
|
||||||
|
|
||||||
|
id.style.background = "black";
|
||||||
alert(document.getElementById('test').style.background);
|
alert(document.getElementById('test').style.background);
|
||||||
alert(document.getElementById('test').style.backgroundColor);
|
alert(document.getElementById('test').style.backgroundColor);
|
||||||
alert(document.getElementById('test').style.backgroundPosition);
|
alert(document.getElementById('test').style.backgroundPosition);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue