diff --git a/components/script/dom/webidls/CSSStyleDeclaration.webidl b/components/script/dom/webidls/CSSStyleDeclaration.webidl index aebe2b5f7c6..efe1d57b038 100644 --- a/components/script/dom/webidls/CSSStyleDeclaration.webidl +++ b/components/script/dom/webidls/CSSStyleDeclaration.webidl @@ -33,6 +33,8 @@ interface CSSStyleDeclaration { }; partial interface CSSStyleDeclaration { + [SetterThrows, TreatNullAs=EmptyString] attribute DOMString all; + [SetterThrows, TreatNullAs=EmptyString] attribute DOMString background; [SetterThrows, TreatNullAs=EmptyString] attribute DOMString backgroundColor; [SetterThrows, TreatNullAs=EmptyString] attribute DOMString background-color; diff --git a/components/style/properties/data.py b/components/style/properties/data.py index 157ad551f62..83e91e020b4 100644 --- a/components/style/properties/data.py +++ b/components/style/properties/data.py @@ -280,3 +280,6 @@ class PropertiesData(object): self.add_prefixed_aliases(shorthand) self.shorthands.append(shorthand) return shorthand + + def shorthands_except_all(self): + return [s for s in self.shorthands if s.name != "all"] diff --git a/components/style/properties/properties.mako.rs b/components/style/properties/properties.mako.rs index 15a75c8d02d..bdbb09bdfcc 100644 --- a/components/style/properties/properties.mako.rs +++ b/components/style/properties/properties.mako.rs @@ -165,6 +165,45 @@ pub mod shorthands { <%include file="/shorthand/position.mako.rs" /> <%include file="/shorthand/inherited_svg.mako.rs" /> <%include file="/shorthand/text.mako.rs" /> + + // We don't defined the 'all' shorthand using the regular helpers:shorthand + // mechanism, since it causes some very large types to be generated. + <% data.declare_shorthand("all", + [p.name for p in data.longhands if p.name not in ['direction', 'unicode-bidi']], + spec="https://drafts.csswg.org/css-cascade-3/#all-shorthand") %> + pub mod all { + use cssparser::Parser; + use parser::ParserContext; + use properties::{ParsedDeclaration, ShorthandId, UnparsedValue}; + use std::sync::Arc; + + pub fn parse(context: &ParserContext, input: &mut Parser) -> Result { + // This function is like the parse() that is generated by + // helpers:shorthand, but since the only values for the 'all' + // shorthand when not just a single CSS-wide keyword is one + // with variable references, we can make this function a + // little simpler. + // + // FIXME(heycam) Try to share code with the helpers:shorthand + // definition. + input.look_for_var_functions(); + let start = input.position(); + while let Ok(_) = input.next() {} // Look for var() + if input.seen_var_functions() { + input.reset(start); + let (first_token_type, css) = try!( + ::custom_properties::parse_non_custom_with_var(input)); + Ok(ParsedDeclaration::AllWithVariables(Arc::new(UnparsedValue { + css: css.into_owned(), + first_token_type: first_token_type, + url_data: context.url_data.clone(), + from_shorthand: Some(ShorthandId::All), + }))) + } else { + Err(()) + } + } + } } /// A module with all the code related to animated properties. @@ -337,7 +376,12 @@ impl PropertyDeclarationIdSet { longhands::${property.ident} ::parse_specified(&context, input).map(DeclaredValueOwned::Value) } - % for shorthand in data.shorthands: + Some(ShorthandId::All) => { + // No need to parse the 'all' shorthand as anything other than a CSS-wide + // keyword, after variable substitution. + Err(()) + } + % for shorthand in data.shorthands_except_all(): % if property in shorthand.sub_properties: Some(ShorthandId::${shorthand.camel_case}) => { shorthands::${shorthand.ident}::parse_value(&context, input) @@ -543,7 +587,14 @@ impl ShorthandId { I: Iterator, { match *self { - % for property in data.shorthands: + ShorthandId::All => { + // No need to try to serialize the declarations as the 'all' + // shorthand, since it only accepts CSS-wide keywords (and + // variable references), which will be handled in + // get_shorthand_appendable_value. + Err(fmt::Error) + } + % for property in data.shorthands_except_all(): ShorthandId::${property.camel_case} => { match shorthands::${property.ident}::LonghandsToSerialize::from_iter(declarations) { Ok(longhands) => longhands.to_css(dest), @@ -868,8 +919,14 @@ impl PropertyId { /// Includes shorthands before expansion pub enum ParsedDeclaration { % for shorthand in data.shorthands: + % if shorthand.name == "all": + // No need for an All(shorthands::all::Longhands) case, since we can + // never have any values for 'all' other than the CSS-wide keywords + // and values with variable references. + % else: /// ${shorthand.name} ${shorthand.camel_case}(shorthands::${shorthand.ident}::Longhands), + % endif /// ${shorthand.name} with a CSS-wide keyword ${shorthand.camel_case}CSSWideKeyword(CSSWideKeyword), @@ -910,6 +967,7 @@ impl ParsedDeclaration { overwrite_more_important: bool) -> bool { match self { % for shorthand in data.shorthands: + % if shorthand.name != "all": ParsedDeclaration::${shorthand.camel_case}( shorthands::${shorthand.ident}::Longhands { % for sub_property in shorthand.sub_properties: @@ -933,6 +991,7 @@ impl ParsedDeclaration { % endfor changed }, + % endif ParsedDeclaration::${shorthand.camel_case}CSSWideKeyword(keyword) => { let mut changed = false; % for sub_property in shorthand.sub_properties: