mirror of
https://github.com/servo/servo.git
synced 2025-08-05 21:50:18 +01:00
Support CSS-wide keywords in custom properties
This commit is contained in:
parent
65d4ecaa39
commit
3fcd8938f3
2 changed files with 47 additions and 22 deletions
|
@ -3,6 +3,7 @@
|
||||||
* 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 cssparser::{Parser, Token};
|
use cssparser::{Parser, Token};
|
||||||
|
use properties::DeclaredValue;
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use string_cache::Atom;
|
use string_cache::Atom;
|
||||||
|
@ -111,19 +112,33 @@ fn parse_var_function<'i, 't>(input: &mut Parser<'i, 't>, references: &mut HashS
|
||||||
|
|
||||||
/// Add one custom property declaration to a map,
|
/// Add one custom property declaration to a map,
|
||||||
/// unless another with the same name was already there.
|
/// unless another with the same name was already there.
|
||||||
pub fn cascade(custom_properties: &mut Option<Map>, inherited_custom_properties: &Option<Arc<Map>>,
|
pub fn cascade<'a>(custom_properties: &mut Option<Map>,
|
||||||
name: &Atom, value: &Value) {
|
inherited_custom_properties: &Option<Arc<Map>>,
|
||||||
let map = match *custom_properties {
|
seen: &mut HashSet<&'a Atom>,
|
||||||
Some(ref mut map) => map,
|
name: &'a Atom,
|
||||||
None => {
|
value: &DeclaredValue<Value>) {
|
||||||
*custom_properties = Some(match *inherited_custom_properties {
|
let was_not_already_present = seen.insert(name);
|
||||||
Some(ref arc) => (**arc).clone(),
|
if was_not_already_present {
|
||||||
None => HashMap::new(),
|
let map = match *custom_properties {
|
||||||
});
|
Some(ref mut map) => map,
|
||||||
custom_properties.as_mut().unwrap()
|
None => {
|
||||||
|
*custom_properties = Some(match *inherited_custom_properties {
|
||||||
|
Some(ref arc) => (**arc).clone(),
|
||||||
|
None => HashMap::new(),
|
||||||
|
});
|
||||||
|
custom_properties.as_mut().unwrap()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
match *value {
|
||||||
|
DeclaredValue::SpecifiedValue(ref value) => {
|
||||||
|
map.insert(name.clone(), value.clone());
|
||||||
|
}
|
||||||
|
DeclaredValue::Initial => {
|
||||||
|
map.remove(name);
|
||||||
|
}
|
||||||
|
DeclaredValue::Inherit => {} // The inherited value is what we already have.
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
map.entry(name.clone()).or_insert(value.clone());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// If any custom property declarations where found for this element (`custom_properties.is_some()`)
|
/// If any custom property declarations where found for this element (`custom_properties.is_some()`)
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
use std::ascii::AsciiExt;
|
use std::ascii::AsciiExt;
|
||||||
use std::borrow::ToOwned;
|
use std::borrow::ToOwned;
|
||||||
|
use std::collections::HashSet;
|
||||||
use std::default::Default;
|
use std::default::Default;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
@ -5684,7 +5685,7 @@ pub enum PropertyDeclaration {
|
||||||
${property.camel_case}(DeclaredValue<longhands::${property.ident}::SpecifiedValue>),
|
${property.camel_case}(DeclaredValue<longhands::${property.ident}::SpecifiedValue>),
|
||||||
% endfor
|
% endfor
|
||||||
/// Name (atom) does not include the `--` prefix.
|
/// Name (atom) does not include the `--` prefix.
|
||||||
Custom(Atom, ::custom_properties::Value),
|
Custom(Atom, DeclaredValue<::custom_properties::Value>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -5736,13 +5737,18 @@ impl PropertyDeclaration {
|
||||||
pub fn parse(name: &str, context: &ParserContext, input: &mut Parser,
|
pub fn parse(name: &str, context: &ParserContext, input: &mut Parser,
|
||||||
result_list: &mut Vec<PropertyDeclaration>) -> PropertyDeclarationParseResult {
|
result_list: &mut Vec<PropertyDeclaration>) -> PropertyDeclarationParseResult {
|
||||||
if name.starts_with("--") {
|
if name.starts_with("--") {
|
||||||
if let Ok(value) = ::custom_properties::parse(input) {
|
let value = match input.try(CSSWideKeyword::parse) {
|
||||||
let name = Atom::from_slice(&name[2..]);
|
Ok(CSSWideKeyword::UnsetKeyword) | // Custom properties are alawys inherited
|
||||||
result_list.push(PropertyDeclaration::Custom(name, value));
|
Ok(CSSWideKeyword::InheritKeyword) => DeclaredValue::Inherit,
|
||||||
return PropertyDeclarationParseResult::ValidOrIgnoredDeclaration;
|
Ok(CSSWideKeyword::InitialKeyword) => DeclaredValue::Initial,
|
||||||
} else {
|
Err(()) => match ::custom_properties::parse(input) {
|
||||||
return PropertyDeclarationParseResult::InvalidValue;
|
Ok(value) => DeclaredValue::SpecifiedValue(value),
|
||||||
}
|
Err(()) => return PropertyDeclarationParseResult::InvalidValue,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let name = Atom::from_slice(&name[2..]);
|
||||||
|
result_list.push(PropertyDeclaration::Custom(name, value));
|
||||||
|
return PropertyDeclarationParseResult::ValidOrIgnoredDeclaration;
|
||||||
}
|
}
|
||||||
match_ignore_ascii_case! { name,
|
match_ignore_ascii_case! { name,
|
||||||
% for property in LONGHANDS:
|
% for property in LONGHANDS:
|
||||||
|
@ -6097,6 +6103,7 @@ fn cascade_with_cached_declarations(
|
||||||
let mut custom_properties = None;
|
let mut custom_properties = None;
|
||||||
|
|
||||||
let mut seen = PropertyBitField::new();
|
let mut seen = PropertyBitField::new();
|
||||||
|
let mut seen_custom = HashSet::new();
|
||||||
// Declaration blocks are stored in increasing precedence order,
|
// Declaration blocks are stored in increasing precedence order,
|
||||||
// we want them in decreasing order here.
|
// we want them in decreasing order here.
|
||||||
for sub_list in applicable_declarations.iter().rev() {
|
for sub_list in applicable_declarations.iter().rev() {
|
||||||
|
@ -6158,7 +6165,8 @@ fn cascade_with_cached_declarations(
|
||||||
% endfor
|
% endfor
|
||||||
PropertyDeclaration::Custom(ref name, ref value) => {
|
PropertyDeclaration::Custom(ref name, ref value) => {
|
||||||
::custom_properties::cascade(
|
::custom_properties::cascade(
|
||||||
&mut custom_properties, &parent_style.custom_properties, name, value)
|
&mut custom_properties, &parent_style.custom_properties,
|
||||||
|
&mut seen_custom, name, value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6390,13 +6398,15 @@ pub fn cascade(viewport_size: Size2D<Au>,
|
||||||
// of compiled code! To improve i-cache behavior, we outline the individual functions and use
|
// of compiled code! To improve i-cache behavior, we outline the individual functions and use
|
||||||
// virtual dispatch instead.
|
// virtual dispatch instead.
|
||||||
CASCADE_PROPERTY.with(|cascade_property| {
|
CASCADE_PROPERTY.with(|cascade_property| {
|
||||||
|
let mut seen_custom = HashSet::new();
|
||||||
for sub_list in applicable_declarations.iter().rev() {
|
for sub_list in applicable_declarations.iter().rev() {
|
||||||
// Declarations are already stored in reverse order.
|
// Declarations are already stored in reverse order.
|
||||||
for declaration in sub_list.declarations.iter() {
|
for declaration in sub_list.declarations.iter() {
|
||||||
match *declaration {
|
match *declaration {
|
||||||
PropertyDeclaration::Custom(ref name, ref value) => {
|
PropertyDeclaration::Custom(ref name, ref value) => {
|
||||||
::custom_properties::cascade(
|
::custom_properties::cascade(
|
||||||
&mut custom_properties, &inherited_style.custom_properties, name, value)
|
&mut custom_properties, &inherited_style.custom_properties,
|
||||||
|
&mut seen_custom, name, value)
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
let discriminant = unsafe {
|
let discriminant = unsafe {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue