mirror of
https://github.com/servo/servo.git
synced 2025-08-05 13:40:08 +01:00
Introduce enums for identifying CSS properties.
* `LonghandId` and `ShorthandId` are C-like enums * `Atom` is used for the name of custom properties. * `PropertyDeclarationId` is the identifier for `PropertyDeclaration`, after parsing and shorthand expansion. (Longhand or custom property.) * `PropertyId` represents any CSS property, e.g. in CSSOM. (Longhand, shorthand, or custom.) Using these instead of strings avoids some memory allocations and copies.
This commit is contained in:
parent
97344b150d
commit
137e30b825
10 changed files with 334 additions and 278 deletions
|
@ -286,6 +286,12 @@ impl Into<Vec<u8>> for DOMString {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> Into<Cow<'a, str>> for DOMString {
|
||||
fn into(self) -> Cow<'a, str> {
|
||||
self.0.into()
|
||||
}
|
||||
}
|
||||
|
||||
impl Extend<char> for DOMString {
|
||||
fn extend<I>(&mut self, iterable: I) where I: IntoIterator<Item=char> {
|
||||
self.0.extend(iterable)
|
||||
|
|
|
@ -16,8 +16,8 @@ use servo_atoms::Atom;
|
|||
use std::ascii::AsciiExt;
|
||||
use std::sync::Arc;
|
||||
use style::parser::ParserContextExtraData;
|
||||
use style::properties::{Shorthand, Importance, PropertyDeclarationBlock};
|
||||
use style::properties::{is_supported_property, parse_one_declaration, parse_style_attribute};
|
||||
use style::properties::{Importance, PropertyDeclarationBlock, PropertyId};
|
||||
use style::properties::{parse_one_declaration, parse_style_attribute};
|
||||
use style::selector_parser::PseudoElement;
|
||||
use style_traits::ToCss;
|
||||
|
||||
|
@ -111,6 +111,13 @@ impl CSSStyleDeclarationMethods for CSSStyleDeclaration {
|
|||
return self.get_computed_style(&property).unwrap_or(DOMString::new());
|
||||
}
|
||||
|
||||
let id = if let Ok(id) = PropertyId::parse(property.into()) {
|
||||
id
|
||||
} else {
|
||||
// Unkwown property
|
||||
return DOMString::new()
|
||||
};
|
||||
|
||||
let style_attribute = self.owner.style_attribute().borrow();
|
||||
let style_attribute = if let Some(ref lock) = *style_attribute {
|
||||
lock.read()
|
||||
|
@ -120,12 +127,19 @@ impl CSSStyleDeclarationMethods for CSSStyleDeclaration {
|
|||
};
|
||||
|
||||
let mut string = String::new();
|
||||
style_attribute.property_value_to_css(&property, &mut string).unwrap();
|
||||
style_attribute.property_value_to_css(&id, &mut string).unwrap();
|
||||
DOMString::from(string)
|
||||
}
|
||||
|
||||
// https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-getpropertypriority
|
||||
fn GetPropertyPriority(&self, property: DOMString) -> DOMString {
|
||||
let id = if let Ok(id) = PropertyId::parse(property.into()) {
|
||||
id
|
||||
} else {
|
||||
// Unkwown property
|
||||
return DOMString::new()
|
||||
};
|
||||
|
||||
let style_attribute = self.owner.style_attribute().borrow();
|
||||
let style_attribute = if let Some(ref lock) = *style_attribute {
|
||||
lock.read()
|
||||
|
@ -134,7 +148,7 @@ impl CSSStyleDeclarationMethods for CSSStyleDeclaration {
|
|||
return DOMString::new()
|
||||
};
|
||||
|
||||
if style_attribute.property_priority(&property).important() {
|
||||
if style_attribute.property_priority(&id).important() {
|
||||
DOMString::from("important")
|
||||
} else {
|
||||
// Step 4
|
||||
|
@ -154,9 +168,13 @@ impl CSSStyleDeclarationMethods for CSSStyleDeclaration {
|
|||
}
|
||||
|
||||
// Step 3
|
||||
if !is_supported_property(&property) {
|
||||
return Ok(());
|
||||
}
|
||||
// FIXME: give ownership on `property` here when parse_one_declaration can take &PropertyId
|
||||
let id = if let Ok(id) = PropertyId::parse((&*property).into()) {
|
||||
id
|
||||
} else {
|
||||
// Unkwown property
|
||||
return Ok(())
|
||||
};
|
||||
|
||||
let mut style_attribute = self.owner.style_attribute().borrow_mut();
|
||||
|
||||
|
@ -171,7 +189,7 @@ impl CSSStyleDeclarationMethods for CSSStyleDeclaration {
|
|||
return Ok(())
|
||||
};
|
||||
|
||||
style_attribute.remove_property(&property);
|
||||
style_attribute.remove_property(&id);
|
||||
empty = style_attribute.declarations.is_empty()
|
||||
}
|
||||
if empty {
|
||||
|
@ -237,9 +255,12 @@ impl CSSStyleDeclarationMethods for CSSStyleDeclaration {
|
|||
}
|
||||
|
||||
// Step 2 & 3
|
||||
if !is_supported_property(&property) {
|
||||
return Ok(());
|
||||
}
|
||||
let id = if let Ok(id) = PropertyId::parse(property.into()) {
|
||||
id
|
||||
} else {
|
||||
// Unkwown property
|
||||
return Ok(())
|
||||
};
|
||||
|
||||
// Step 4
|
||||
let importance = match &*priority {
|
||||
|
@ -253,10 +274,7 @@ impl CSSStyleDeclarationMethods for CSSStyleDeclaration {
|
|||
let mut style_attribute = lock.write();
|
||||
|
||||
// Step 5 & 6
|
||||
match Shorthand::from_name(&property) {
|
||||
Some(shorthand) => style_attribute.set_importance(shorthand.longhands(), importance),
|
||||
None => style_attribute.set_importance(&[&*property], importance),
|
||||
}
|
||||
style_attribute.set_importance(&id, importance);
|
||||
|
||||
self.owner.set_style_attr(style_attribute.to_css_string());
|
||||
let node = self.owner.upcast::<Node>();
|
||||
|
@ -277,6 +295,13 @@ impl CSSStyleDeclarationMethods for CSSStyleDeclaration {
|
|||
return Err(Error::NoModificationAllowed);
|
||||
}
|
||||
|
||||
let id = if let Ok(id) = PropertyId::parse(property.into()) {
|
||||
id
|
||||
} else {
|
||||
// Unkwown property, cannot be there to remove.
|
||||
return Ok(DOMString::new())
|
||||
};
|
||||
|
||||
let mut style_attribute = self.owner.style_attribute().borrow_mut();
|
||||
let mut string = String::new();
|
||||
let empty;
|
||||
|
@ -289,10 +314,10 @@ impl CSSStyleDeclarationMethods for CSSStyleDeclaration {
|
|||
};
|
||||
|
||||
// Step 3
|
||||
style_attribute.property_value_to_css(&property, &mut string).unwrap();
|
||||
style_attribute.property_value_to_css(&id, &mut string).unwrap();
|
||||
|
||||
// Step 4 & 5
|
||||
style_attribute.remove_property(&property);
|
||||
style_attribute.remove_property(&id);
|
||||
self.owner.set_style_attr(style_attribute.to_css_string());
|
||||
empty = style_attribute.declarations.is_empty()
|
||||
}
|
||||
|
|
|
@ -9,10 +9,9 @@ use gecko_bindings::bindings::Gecko_Atomize;
|
|||
use gecko_bindings::bindings::Gecko_ReleaseAtom;
|
||||
use gecko_bindings::structs::nsIAtom;
|
||||
use heapsize::HeapSizeOf;
|
||||
use std::ascii::AsciiExt;
|
||||
use std::borrow::{Cow, Borrow};
|
||||
use std::char::{self, DecodeUtf16};
|
||||
use std::fmt;
|
||||
use std::fmt::{self, Write};
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::iter::Cloned;
|
||||
use std::mem;
|
||||
|
@ -111,14 +110,6 @@ impl WeakAtom {
|
|||
cb(&owned)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn eq_str_ignore_ascii_case(&self, s: &str) -> bool {
|
||||
self.chars().map(|r| match r {
|
||||
Ok(c) => c.to_ascii_lowercase() as u32,
|
||||
Err(e) => e.unpaired_surrogate() as u32,
|
||||
}).eq(s.chars().map(|c| c.to_ascii_lowercase() as u32))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn to_string(&self) -> String {
|
||||
String::from_utf16(self.as_slice()).unwrap()
|
||||
|
@ -154,7 +145,7 @@ impl fmt::Debug for WeakAtom {
|
|||
impl fmt::Display for WeakAtom {
|
||||
fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result {
|
||||
for c in self.chars() {
|
||||
try!(write!(w, "{}", c.unwrap_or(char::REPLACEMENT_CHARACTER)))
|
||||
try!(w.write_char(c.unwrap_or(char::REPLACEMENT_CHARACTER)))
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -7,7 +7,6 @@ use cssparser::{Parser, AtRuleParser, DeclarationParser, Delimiter};
|
|||
use error_reporting::ParseErrorReporter;
|
||||
use parser::{ParserContext, ParserContextExtraData, log_css_error};
|
||||
use servo_url::ServoUrl;
|
||||
use std::ascii::AsciiExt;
|
||||
use std::boxed::Box as StdBox;
|
||||
use std::fmt;
|
||||
use style_traits::ToCss;
|
||||
|
@ -65,28 +64,28 @@ impl PropertyDeclarationBlock {
|
|||
self.declarations.len() > self.important_count as usize
|
||||
}
|
||||
|
||||
pub fn get(&self, property_name: &str) -> Option< &(PropertyDeclaration, Importance)> {
|
||||
self.declarations.iter().find(|&&(ref decl, _)| decl.matches(property_name))
|
||||
pub fn get(&self, property: PropertyDeclarationId) -> Option< &(PropertyDeclaration, Importance)> {
|
||||
self.declarations.iter().find(|&&(ref decl, _)| decl.id() == property)
|
||||
}
|
||||
|
||||
/// Find the value of the given property in this block and serialize it
|
||||
///
|
||||
/// https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-getpropertyvalue
|
||||
pub fn property_value_to_css<W>(&self, property_name: &str, dest: &mut W) -> fmt::Result
|
||||
pub fn property_value_to_css<W>(&self, property: &PropertyId, dest: &mut W) -> fmt::Result
|
||||
where W: fmt::Write {
|
||||
// Step 1
|
||||
let property = property_name.to_ascii_lowercase();
|
||||
// Step 1: done when parsing a string to PropertyId
|
||||
|
||||
// Step 2
|
||||
if let Some(shorthand) = Shorthand::from_name(&property) {
|
||||
match property.as_shorthand() {
|
||||
Ok(shorthand) => {
|
||||
// Step 2.1
|
||||
let mut list = Vec::new();
|
||||
let mut important_count = 0;
|
||||
|
||||
// Step 2.2
|
||||
for longhand in shorthand.longhands() {
|
||||
for &longhand in shorthand.longhands() {
|
||||
// Step 2.2.1
|
||||
let declaration = self.get(longhand);
|
||||
let declaration = self.get(PropertyDeclarationId::Longhand(longhand));
|
||||
|
||||
// Step 2.2.2 & 2.2.3
|
||||
match declaration {
|
||||
|
@ -112,10 +111,10 @@ impl PropertyDeclarationBlock {
|
|||
// so we treat this as a normal-importance property
|
||||
let importance = Importance::Normal;
|
||||
let appendable_value = shorthand.get_shorthand_appendable_value(list).unwrap();
|
||||
return append_declaration_value(dest, appendable_value, importance)
|
||||
append_declaration_value(dest, appendable_value, importance)
|
||||
}
|
||||
|
||||
if let Some(&(ref value, _importance)) = self.get(property_name) {
|
||||
Err(longhand_or_custom) => {
|
||||
if let Some(&(ref value, _importance)) = self.get(longhand_or_custom) {
|
||||
// Step 3
|
||||
value.to_css(dest)
|
||||
} else {
|
||||
|
@ -123,32 +122,36 @@ impl PropertyDeclarationBlock {
|
|||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-getpropertypriority
|
||||
pub fn property_priority(&self, property_name: &str) -> Importance {
|
||||
// Step 1
|
||||
let property = property_name.to_ascii_lowercase();
|
||||
pub fn property_priority(&self, property: &PropertyId) -> Importance {
|
||||
// Step 1: done when parsing a string to PropertyId
|
||||
|
||||
// Step 2
|
||||
if let Some(shorthand) = Shorthand::from_name(&property) {
|
||||
match property.as_shorthand() {
|
||||
Ok(shorthand) => {
|
||||
// Step 2.1 & 2.2 & 2.3
|
||||
if shorthand.longhands().iter().all(|l| {
|
||||
self.get(l).map_or(false, |&(_, importance)| importance.important())
|
||||
if shorthand.longhands().iter().all(|&l| {
|
||||
self.get(PropertyDeclarationId::Longhand(l))
|
||||
.map_or(false, |&(_, importance)| importance.important())
|
||||
}) {
|
||||
Importance::Important
|
||||
} else {
|
||||
Importance::Normal
|
||||
}
|
||||
} else {
|
||||
}
|
||||
Err(longhand_or_custom) => {
|
||||
// Step 3
|
||||
self.get(&property).map_or(Importance::Normal, |&(_, importance)| importance)
|
||||
self.get(longhand_or_custom).map_or(Importance::Normal, |&(_, importance)| importance)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_parsed_declaration(&mut self, declaration: PropertyDeclaration,
|
||||
importance: Importance) {
|
||||
pub fn set_parsed_declaration(&mut self, declaration: PropertyDeclaration, importance: Importance) {
|
||||
for slot in &mut *self.declarations {
|
||||
if slot.0.name() == declaration.name() {
|
||||
if slot.0.id() == declaration.id() {
|
||||
match (slot.1, importance) {
|
||||
(Importance::Normal, Importance::Important) => {
|
||||
self.important_count += 1;
|
||||
|
@ -169,9 +172,9 @@ impl PropertyDeclarationBlock {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn set_importance(&mut self, property_names: &[&str], new_importance: Importance) {
|
||||
pub fn set_importance(&mut self, property: &PropertyId, new_importance: Importance) {
|
||||
for &mut (ref declaration, ref mut importance) in &mut self.declarations {
|
||||
if property_names.iter().any(|p| declaration.matches(p)) {
|
||||
if declaration.id().is_or_is_longhand_of(property) {
|
||||
match (*importance, new_importance) {
|
||||
(Importance::Normal, Importance::Important) => {
|
||||
self.important_count += 1;
|
||||
|
@ -187,44 +190,34 @@ impl PropertyDeclarationBlock {
|
|||
}
|
||||
|
||||
/// https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-removeproperty
|
||||
pub fn remove_property(&mut self, property_name: &str) {
|
||||
// Step 2
|
||||
let property = property_name.to_ascii_lowercase();
|
||||
|
||||
match Shorthand::from_name(&property) {
|
||||
// Step 4
|
||||
Some(shorthand) => self.remove_longhands(shorthand.longhands()),
|
||||
// Step 5
|
||||
None => self.remove_longhands(&[&*property]),
|
||||
}
|
||||
}
|
||||
|
||||
fn remove_longhands(&mut self, names: &[&str]) {
|
||||
pub fn remove_property(&mut self, property: &PropertyId) {
|
||||
let important_count = &mut self.important_count;
|
||||
self.declarations.retain(|&(ref declaration, importance)| {
|
||||
let retain = !names.iter().any(|n| declaration.matches(n));
|
||||
if !retain && importance.important() {
|
||||
let remove = declaration.id().is_or_is_longhand_of(property);
|
||||
if remove && importance.important() {
|
||||
*important_count -= 1
|
||||
}
|
||||
retain
|
||||
!remove
|
||||
})
|
||||
}
|
||||
|
||||
/// Take a declaration block known to contain a single property and serialize it.
|
||||
pub fn single_value_to_css<W>(&self, property_name: &str, dest: &mut W) -> fmt::Result
|
||||
pub fn single_value_to_css<W>(&self, property: &PropertyId, dest: &mut W) -> fmt::Result
|
||||
where W: fmt::Write {
|
||||
match self.declarations.len() {
|
||||
0 => Err(fmt::Error),
|
||||
1 if self.declarations[0].0.name().eq_str_ignore_ascii_case(property_name) => {
|
||||
match property.as_shorthand() {
|
||||
Err(_longhand_or_custom) => {
|
||||
if self.declarations.len() == 1 {
|
||||
self.declarations[0].0.to_css(dest)
|
||||
} else {
|
||||
Err(fmt::Error)
|
||||
}
|
||||
_ => {
|
||||
}
|
||||
Ok(shorthand) => {
|
||||
// we use this function because a closure won't be `Clone`
|
||||
fn get_declaration(dec: &(PropertyDeclaration, Importance))
|
||||
-> &PropertyDeclaration {
|
||||
&dec.0
|
||||
}
|
||||
let shorthand = try!(Shorthand::from_name(property_name).ok_or(fmt::Error));
|
||||
if !self.declarations.iter().all(|decl| decl.0.shorthands().contains(&shorthand)) {
|
||||
return Err(fmt::Error)
|
||||
}
|
||||
|
@ -254,7 +247,7 @@ impl ToCss for PropertyDeclarationBlock {
|
|||
// Step 3
|
||||
for &(ref declaration, importance) in &*self.declarations {
|
||||
// Step 3.1
|
||||
let property = declaration.name();
|
||||
let property = declaration.id();
|
||||
|
||||
// Step 3.2
|
||||
if already_serialized.contains(&property) {
|
||||
|
@ -266,11 +259,11 @@ impl ToCss for PropertyDeclarationBlock {
|
|||
if !shorthands.is_empty() {
|
||||
// Step 3.3.1
|
||||
let mut longhands = self.declarations.iter()
|
||||
.filter(|d| !already_serialized.contains(&d.0.name()))
|
||||
.filter(|d| !already_serialized.contains(&d.0.id()))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
// Step 3.3.2
|
||||
for shorthand in shorthands {
|
||||
for &shorthand in shorthands {
|
||||
let properties = shorthand.longhands();
|
||||
|
||||
// Substep 2 & 3
|
||||
|
@ -278,8 +271,7 @@ impl ToCss for PropertyDeclarationBlock {
|
|||
let mut important_count = 0;
|
||||
|
||||
for &&(ref longhand, longhand_importance) in longhands.iter() {
|
||||
let longhand_name = longhand.name();
|
||||
if properties.iter().any(|p| &longhand_name == *p) {
|
||||
if longhand.id().is_longhand_of(shorthand) {
|
||||
current_longhands.push(longhand);
|
||||
if longhand_importance.important() {
|
||||
important_count += 1;
|
||||
|
@ -325,7 +317,7 @@ impl ToCss for PropertyDeclarationBlock {
|
|||
|
||||
for current_longhand in current_longhands {
|
||||
// Substep 9
|
||||
already_serialized.push(current_longhand.name());
|
||||
already_serialized.push(current_longhand.id());
|
||||
let index_to_remove = longhands.iter().position(|l| l.0 == *current_longhand);
|
||||
if let Some(index) = index_to_remove {
|
||||
// Substep 10
|
||||
|
@ -348,9 +340,9 @@ impl ToCss for PropertyDeclarationBlock {
|
|||
// "error: unable to infer enough type information about `_`;
|
||||
// type annotations or generic parameter binding required [E0282]"
|
||||
// Use the same type as earlier call to reuse generated code.
|
||||
try!(append_serialization::<W, Cloned<slice::Iter< &PropertyDeclaration>>>(
|
||||
try!(append_serialization::<W, Cloned<slice::Iter< &PropertyDeclaration>>, _>(
|
||||
dest,
|
||||
&property.to_string(),
|
||||
&property,
|
||||
AppendableValue::Declaration(declaration),
|
||||
importance,
|
||||
&mut is_first_serialization));
|
||||
|
@ -367,7 +359,7 @@ impl ToCss for PropertyDeclarationBlock {
|
|||
pub enum AppendableValue<'a, I>
|
||||
where I: Iterator<Item=&'a PropertyDeclaration> {
|
||||
Declaration(&'a PropertyDeclaration),
|
||||
DeclarationsForShorthand(Shorthand, I),
|
||||
DeclarationsForShorthand(ShorthandId, I),
|
||||
Css(&'a str)
|
||||
}
|
||||
|
||||
|
@ -407,13 +399,15 @@ pub fn append_declaration_value<'a, W, I>
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn append_serialization<'a, W, I>(dest: &mut W,
|
||||
property_name: &str,
|
||||
pub fn append_serialization<'a, W, I, N>(dest: &mut W,
|
||||
property_name: &N,
|
||||
appendable_value: AppendableValue<'a, I>,
|
||||
importance: Importance,
|
||||
is_first_serialization: &mut bool)
|
||||
-> fmt::Result
|
||||
where W: fmt::Write, I: Iterator<Item=&'a PropertyDeclaration> {
|
||||
where W: fmt::Write,
|
||||
I: Iterator<Item=&'a PropertyDeclaration>,
|
||||
N: ToCss {
|
||||
try!(handle_first_serialization(dest, is_first_serialization));
|
||||
|
||||
// Overflow does not behave like a normal shorthand. When overflow-x and overflow-y are not of equal
|
||||
|
@ -422,7 +416,8 @@ pub fn append_serialization<'a, W, I>(dest: &mut W,
|
|||
return append_declaration_value(dest, appendable_value, importance);
|
||||
}
|
||||
|
||||
try!(write!(dest, "{}:", property_name));
|
||||
try!(property_name.to_css(dest));
|
||||
try!(dest.write_char(':'));
|
||||
|
||||
// for normal parsed values, add a space between key: and value
|
||||
match &appendable_value {
|
||||
|
|
|
@ -68,7 +68,7 @@
|
|||
pub mod single_value {
|
||||
use cssparser::Parser;
|
||||
use parser::{Parse, ParserContext, ParserContextExtraData};
|
||||
use properties::{CSSWideKeyword, DeclaredValue, Shorthand};
|
||||
use properties::{CSSWideKeyword, DeclaredValue, ShorthandId};
|
||||
use values::computed::{Context, ToComputedValue};
|
||||
use values::{computed, specified};
|
||||
${caller.body()}
|
||||
|
@ -182,7 +182,7 @@
|
|||
% if not property.derived_from:
|
||||
use cssparser::Parser;
|
||||
use parser::{Parse, ParserContext, ParserContextExtraData};
|
||||
use properties::{CSSWideKeyword, DeclaredValue, Shorthand};
|
||||
use properties::{CSSWideKeyword, DeclaredValue, ShorthandId};
|
||||
% endif
|
||||
use values::{Auto, Either, None_, Normal};
|
||||
use cascade_info::CascadeInfo;
|
||||
|
@ -380,7 +380,7 @@
|
|||
#[allow(unused_imports)]
|
||||
use cssparser::Parser;
|
||||
use parser::ParserContext;
|
||||
use properties::{longhands, PropertyDeclaration, DeclaredValue, Shorthand};
|
||||
use properties::{longhands, PropertyDeclaration, DeclaredValue, ShorthandId};
|
||||
use std::fmt;
|
||||
use style_traits::ToCss;
|
||||
|
||||
|
@ -500,7 +500,7 @@
|
|||
css: css.clone().into_owned(),
|
||||
first_token_type: first_token_type,
|
||||
base_url: context.base_url.clone(),
|
||||
from_shorthand: Some(Shorthand::${shorthand.camel_case}),
|
||||
from_shorthand: Some(ShorthandId::${shorthand.camel_case}),
|
||||
}
|
||||
));
|
||||
% endfor
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
<%namespace name="helpers" file="/helpers.mako.rs" />
|
||||
|
||||
use std::ascii::AsciiExt;
|
||||
use std::borrow::Cow;
|
||||
use std::boxed::Box as StdBox;
|
||||
use std::collections::HashSet;
|
||||
use std::fmt::{self, Write};
|
||||
|
@ -40,6 +40,12 @@ use rule_tree::StrongRuleNode;
|
|||
use self::property_bit_field::PropertyBitField;
|
||||
pub use self::declaration_block::*;
|
||||
|
||||
#[cfg(feature = "gecko")]
|
||||
#[macro_export]
|
||||
macro_rules! property_name {
|
||||
($s: tt) => { atom!($s) }
|
||||
}
|
||||
|
||||
<%!
|
||||
from data import Method, Keyword, to_rust_ident
|
||||
import os.path
|
||||
|
@ -242,7 +248,7 @@ mod property_bit_field {
|
|||
css: &String,
|
||||
first_token_type: TokenSerializationType,
|
||||
base_url: &ServoUrl,
|
||||
from_shorthand: Option<Shorthand>,
|
||||
from_shorthand: Option<ShorthandId>,
|
||||
custom_properties: &Option<Arc<::custom_properties::ComputedValuesMap>>,
|
||||
f: F,
|
||||
error_reporter: &mut StdBox<ParseErrorReporter + Send>,
|
||||
|
@ -265,7 +271,7 @@ mod property_bit_field {
|
|||
}
|
||||
% for shorthand in data.shorthands:
|
||||
% if property in shorthand.sub_properties:
|
||||
Some(Shorthand::${shorthand.camel_case}) => {
|
||||
Some(ShorthandId::${shorthand.camel_case}) => {
|
||||
shorthands::${shorthand.ident}::parse_value(&context, input)
|
||||
.map(|result| match result.${property.ident} {
|
||||
Some(value) => DeclaredValue::Value(value),
|
||||
|
@ -378,41 +384,76 @@ impl Parse for CSSWideKeyword {
|
|||
|
||||
#[derive(Clone, Copy, Eq, PartialEq, Debug)]
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
pub enum Shorthand {
|
||||
pub enum LonghandId {
|
||||
% for i, property in enumerate(data.longhands):
|
||||
${property.camel_case} = ${i},
|
||||
% endfor
|
||||
}
|
||||
|
||||
impl LonghandId {
|
||||
pub fn from_ascii_lowercase_name(name: &str) -> Result<Self, ()> {
|
||||
// FIXME: use rust-phf?
|
||||
match name {
|
||||
% for property in data.longhands:
|
||||
"${property.name}" => Ok(LonghandId::${property.camel_case}),
|
||||
% endfor
|
||||
_ => Err(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn name(&self) -> &'static str {
|
||||
match *self {
|
||||
% for property in data.longhands:
|
||||
LonghandId::${property.camel_case} => "${property.name}",
|
||||
% endfor
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Eq, PartialEq, Debug)]
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
pub enum ShorthandId {
|
||||
% for property in data.shorthands:
|
||||
${property.camel_case},
|
||||
% endfor
|
||||
}
|
||||
|
||||
impl Shorthand {
|
||||
pub fn from_name(name: &str) -> Option<Shorthand> {
|
||||
match_ignore_ascii_case! { name,
|
||||
impl ToCss for ShorthandId {
|
||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
||||
dest.write_str(self.name())
|
||||
}
|
||||
}
|
||||
|
||||
impl ShorthandId {
|
||||
pub fn from_ascii_lowercase_name(name: &str) -> Result<Self, ()> {
|
||||
// FIXME: use rust-phf?
|
||||
match name {
|
||||
% for property in data.shorthands:
|
||||
"${property.name}" => Some(Shorthand::${property.camel_case}),
|
||||
"${property.name}" => Ok(ShorthandId::${property.camel_case}),
|
||||
% endfor
|
||||
_ => None
|
||||
_ => Err(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn name(&self) -> &'static str {
|
||||
match *self {
|
||||
% for property in data.shorthands:
|
||||
Shorthand::${property.camel_case} => "${property.name}",
|
||||
ShorthandId::${property.camel_case} => "${property.name}",
|
||||
% endfor
|
||||
}
|
||||
}
|
||||
|
||||
pub fn longhands(&self) -> &'static [&'static str] {
|
||||
pub fn longhands(&self) -> &'static [LonghandId] {
|
||||
% for property in data.shorthands:
|
||||
static ${property.ident.upper()}: &'static [&'static str] = &[
|
||||
static ${property.ident.upper()}: &'static [LonghandId] = &[
|
||||
% for sub in property.sub_properties:
|
||||
"${sub.name}",
|
||||
LonghandId::${sub.camel_case},
|
||||
% endfor
|
||||
];
|
||||
% endfor
|
||||
match *self {
|
||||
% for property in data.shorthands:
|
||||
Shorthand::${property.camel_case} => ${property.ident.upper()},
|
||||
ShorthandId::${property.camel_case} => ${property.ident.upper()},
|
||||
% endfor
|
||||
}
|
||||
}
|
||||
|
@ -421,7 +462,7 @@ impl Shorthand {
|
|||
where W: fmt::Write, I: Iterator<Item=&'a PropertyDeclaration> {
|
||||
match *self {
|
||||
% for property in data.shorthands:
|
||||
Shorthand::${property.camel_case} => {
|
||||
ShorthandId::${property.camel_case} => {
|
||||
match shorthands::${property.ident}::LonghandsToSerialize::from_iter(declarations) {
|
||||
Ok(longhands) => longhands.to_css(dest),
|
||||
Err(_) => Err(fmt::Error)
|
||||
|
@ -443,11 +484,9 @@ impl Shorthand {
|
|||
match self.get_shorthand_appendable_value(declarations) {
|
||||
None => Ok(false),
|
||||
Some(appendable_value) => {
|
||||
let property_name = self.name();
|
||||
|
||||
append_serialization(
|
||||
dest,
|
||||
property_name,
|
||||
&self,
|
||||
appendable_value,
|
||||
importance,
|
||||
is_first_serialization
|
||||
|
@ -496,7 +535,7 @@ pub enum DeclaredValue<T> {
|
|||
css: String,
|
||||
first_token_type: TokenSerializationType,
|
||||
base_url: ServoUrl,
|
||||
from_shorthand: Option<Shorthand>,
|
||||
from_shorthand: Option<ShorthandId>,
|
||||
},
|
||||
Initial,
|
||||
Inherit,
|
||||
|
@ -533,6 +572,88 @@ impl<T: ToCss> ToCss for DeclaredValue<T> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Clone)]
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
pub enum PropertyDeclarationId<'a> {
|
||||
Longhand(LonghandId),
|
||||
Custom(&'a ::custom_properties::Name),
|
||||
}
|
||||
|
||||
impl<'a> ToCss for PropertyDeclarationId<'a> {
|
||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
||||
match *self {
|
||||
PropertyDeclarationId::Longhand(id) => dest.write_str(id.name()),
|
||||
PropertyDeclarationId::Custom(name) => write!(dest, "--{}", name),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> PropertyDeclarationId<'a> {
|
||||
pub fn is_or_is_longhand_of(&self, other: &PropertyId) -> bool {
|
||||
match *self {
|
||||
PropertyDeclarationId::Longhand(id) => {
|
||||
match *other {
|
||||
PropertyId::Longhand(other_id) => id == other_id,
|
||||
PropertyId::Shorthand(shorthand) => shorthand.longhands().contains(&id),
|
||||
PropertyId::Custom(_) => false,
|
||||
}
|
||||
}
|
||||
PropertyDeclarationId::Custom(name) => {
|
||||
matches!(*other, PropertyId::Custom(ref other_name) if name == other_name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_longhand_of(&self, shorthand: ShorthandId) -> bool {
|
||||
match *self {
|
||||
PropertyDeclarationId::Longhand(ref id) => shorthand.longhands().contains(id),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Eq, PartialEq, Clone)]
|
||||
pub enum PropertyId {
|
||||
Longhand(LonghandId),
|
||||
Shorthand(ShorthandId),
|
||||
Custom(::custom_properties::Name),
|
||||
}
|
||||
|
||||
impl ToCss for PropertyId {
|
||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
||||
match *self {
|
||||
PropertyId::Longhand(id) => dest.write_str(id.name()),
|
||||
PropertyId::Shorthand(id) => dest.write_str(id.name()),
|
||||
PropertyId::Custom(ref name) => write!(dest, "--{}", name),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PropertyId {
|
||||
/// Returns Err(()) for unknown non-custom properties
|
||||
pub fn parse(s: Cow<str>) -> Result<Self, ()> {
|
||||
if let Ok(name) = ::custom_properties::parse_name(&s) {
|
||||
return Ok(PropertyId::Custom(::custom_properties::Name::from(name)))
|
||||
}
|
||||
let lower_case = ::str::cow_into_ascii_lowercase(s);
|
||||
if let Ok(id) = LonghandId::from_ascii_lowercase_name(&lower_case) {
|
||||
Ok(PropertyId::Longhand(id))
|
||||
} else if let Ok(id) = ShorthandId::from_ascii_lowercase_name(&lower_case) {
|
||||
Ok(PropertyId::Shorthand(id))
|
||||
} else {
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_shorthand(&self) -> Result<ShorthandId, PropertyDeclarationId> {
|
||||
match *self {
|
||||
PropertyId::Shorthand(id) => Ok(id),
|
||||
PropertyId::Longhand(id) => Err(PropertyDeclarationId::Longhand(id)),
|
||||
PropertyId::Custom(ref name) => Err(PropertyDeclarationId::Custom(name)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Clone)]
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
pub enum PropertyDeclaration {
|
||||
|
@ -566,51 +687,10 @@ pub enum PropertyDeclarationParseResult {
|
|||
ValidOrIgnoredDeclaration,
|
||||
}
|
||||
|
||||
#[derive(Eq, PartialEq, Clone)]
|
||||
pub enum PropertyDeclarationName {
|
||||
Longhand(&'static str),
|
||||
Custom(::custom_properties::Name),
|
||||
Internal
|
||||
}
|
||||
|
||||
impl PropertyDeclarationName {
|
||||
pub fn eq_str_ignore_ascii_case(&self, other: &str) -> bool {
|
||||
match *self {
|
||||
PropertyDeclarationName::Longhand(s) => s.eq_ignore_ascii_case(other),
|
||||
PropertyDeclarationName::Custom(ref n) => n.eq_str_ignore_ascii_case(other),
|
||||
PropertyDeclarationName::Internal => false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq<str> for PropertyDeclarationName {
|
||||
fn eq(&self, other: &str) -> bool {
|
||||
match *self {
|
||||
PropertyDeclarationName::Longhand(n) => n == other,
|
||||
PropertyDeclarationName::Custom(ref n) => {
|
||||
n.with_str(|s| ::custom_properties::parse_name(other) == Ok(s))
|
||||
}
|
||||
PropertyDeclarationName::Internal => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for PropertyDeclarationName {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
PropertyDeclarationName::Longhand(n) => f.write_str(n),
|
||||
PropertyDeclarationName::Custom(ref n) => {
|
||||
try!(f.write_str("--"));
|
||||
n.with_str(|s| f.write_str(s))
|
||||
}
|
||||
PropertyDeclarationName::Internal => Ok(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for PropertyDeclaration {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
try!(write!(f, "{}: ", self.name()));
|
||||
try!(self.id().to_css(f));
|
||||
try!(f.write_str(": "));
|
||||
match *self {
|
||||
% for property in data.longhands:
|
||||
% if not property.derived_from:
|
||||
|
@ -643,45 +723,20 @@ impl ToCss for PropertyDeclaration {
|
|||
}
|
||||
|
||||
impl PropertyDeclaration {
|
||||
pub fn name(&self) -> PropertyDeclarationName {
|
||||
pub fn id(&self) -> PropertyDeclarationId {
|
||||
match *self {
|
||||
% for property in data.longhands:
|
||||
PropertyDeclaration::${property.camel_case}(..) =>
|
||||
% if not property.derived_from:
|
||||
PropertyDeclarationName::Longhand("${property.name}"),
|
||||
% else:
|
||||
PropertyDeclarationName::Internal,
|
||||
% endif
|
||||
PropertyDeclaration::${property.camel_case}(..) => {
|
||||
PropertyDeclarationId::Longhand(LonghandId::${property.camel_case})
|
||||
}
|
||||
% endfor
|
||||
PropertyDeclaration::Custom(ref name, _) => {
|
||||
PropertyDeclarationName::Custom(name.clone())
|
||||
PropertyDeclarationId::Custom(name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn discriminant_value(&self) -> usize {
|
||||
match *self {
|
||||
% for i, property in enumerate(data.longhands):
|
||||
PropertyDeclaration::${property.camel_case}(..) => ${i},
|
||||
% endfor
|
||||
PropertyDeclaration::Custom(..) => ${len(data.longhands)}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn value(&self) -> String {
|
||||
let mut value = String::new();
|
||||
if let Err(_) = self.to_css(&mut value) {
|
||||
panic!("unsupported property declaration: {}", self.name());
|
||||
}
|
||||
|
||||
value
|
||||
}
|
||||
|
||||
/// If this is a pending-substitution value from the given shorthand, return that value
|
||||
// Extra space here because < seems to be removed by Mako when immediately followed by &.
|
||||
// ↓
|
||||
pub fn with_variables_from_shorthand(&self, shorthand: Shorthand) -> Option< &str> {
|
||||
pub fn with_variables_from_shorthand(&self, shorthand: ShorthandId) -> Option< &str> {
|
||||
match *self {
|
||||
% for property in data.longhands:
|
||||
PropertyDeclaration::${property.camel_case}(ref value) => match *value {
|
||||
|
@ -727,22 +782,6 @@ impl PropertyDeclaration {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn matches(&self, name: &str) -> bool {
|
||||
match *self {
|
||||
% for property in data.longhands:
|
||||
PropertyDeclaration::${property.camel_case}(..) =>
|
||||
% if not property.derived_from:
|
||||
name.eq_ignore_ascii_case("${property.name}"),
|
||||
% else:
|
||||
false,
|
||||
% endif
|
||||
% endfor
|
||||
PropertyDeclaration::Custom(ref declaration_name, _) => {
|
||||
declaration_name.with_str(|s| ::custom_properties::parse_name(name) == Ok(s))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The `in_keyframe_block` parameter controls this:
|
||||
///
|
||||
/// https://drafts.csswg.org/css-animations/#keyframes
|
||||
|
@ -858,7 +897,7 @@ impl PropertyDeclaration {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn shorthands(&self) -> &'static [Shorthand] {
|
||||
pub fn shorthands(&self) -> &'static [ShorthandId] {
|
||||
// first generate longhand to shorthands lookup map
|
||||
<%
|
||||
longhand_to_shorthand_map = {}
|
||||
|
@ -875,9 +914,9 @@ impl PropertyDeclaration {
|
|||
|
||||
// based on lookup results for each longhand, create result arrays
|
||||
% for property in data.longhands:
|
||||
static ${property.ident.upper()}: &'static [Shorthand] = &[
|
||||
static ${property.ident.upper()}: &'static [ShorthandId] = &[
|
||||
% for shorthand in longhand_to_shorthand_map.get(property.ident, []):
|
||||
Shorthand::${shorthand},
|
||||
ShorthandId::${shorthand},
|
||||
% endfor
|
||||
];
|
||||
% endfor
|
||||
|
@ -1576,9 +1615,11 @@ pub fn apply_declarations<'a, F, I>(viewport_size: Size2D<Au>,
|
|||
ComputedValues::do_cascade_property(|cascade_property| {
|
||||
% for category_to_cascade_now in ["early", "other"]:
|
||||
for declaration in iter_declarations() {
|
||||
if let PropertyDeclaration::Custom(..) = *declaration {
|
||||
continue
|
||||
}
|
||||
let longhand_id = match declaration.id() {
|
||||
PropertyDeclarationId::Longhand(id) => id,
|
||||
PropertyDeclarationId::Custom(..) => continue,
|
||||
};
|
||||
|
||||
// The computed value of some properties depends on the
|
||||
// (sometimes computed) value of *other* properties.
|
||||
//
|
||||
|
@ -1610,7 +1651,7 @@ pub fn apply_declarations<'a, F, I>(viewport_size: Size2D<Au>,
|
|||
continue
|
||||
}
|
||||
|
||||
let discriminant = declaration.discriminant_value();
|
||||
let discriminant = longhand_id as usize;
|
||||
(cascade_property[discriminant])(declaration,
|
||||
inherited_style,
|
||||
&mut context,
|
||||
|
@ -1948,16 +1989,6 @@ pub fn modify_style_for_inline_absolute_hypothetical_fragment(style: &mut Arc<Co
|
|||
}
|
||||
}
|
||||
|
||||
// FIXME: https://github.com/w3c/csswg-drafts/issues/580
|
||||
pub fn is_supported_property(property: &str) -> bool {
|
||||
match_ignore_ascii_case! { property,
|
||||
% for property in data.shorthands + data.longhands:
|
||||
"${property.name}" => true,
|
||||
% endfor
|
||||
_ => property.starts_with("--")
|
||||
}
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! css_properties_accessors {
|
||||
($macro_name: ident) => {
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* 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 properties::{AppendableValue, DeclaredValue, PropertyDeclaration, Shorthand};
|
||||
use properties::{AppendableValue, DeclaredValue, PropertyDeclaration, ShorthandId};
|
||||
use style_traits::ToCss;
|
||||
use values::specified::{BorderStyle, CSSColor};
|
||||
use std::fmt;
|
||||
|
@ -88,7 +88,7 @@ fn serialize_directional_border<W, I>(dest: &mut W,
|
|||
pub fn is_overflow_shorthand<'a, I>(appendable_value: &AppendableValue<'a, I>) -> bool
|
||||
where I: Iterator<Item=&'a PropertyDeclaration> {
|
||||
if let AppendableValue::DeclarationsForShorthand(shorthand, _) = *appendable_value {
|
||||
if let Shorthand::Overflow = shorthand {
|
||||
if let ShorthandId::Overflow = shorthand {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,6 +50,7 @@ use style::parallel;
|
|||
use style::parser::{ParserContext, ParserContextExtraData};
|
||||
use style::properties::{CascadeFlags, ComputedValues, Importance, PropertyDeclaration};
|
||||
use style::properties::{PropertyDeclarationParseResult, PropertyDeclarationBlock};
|
||||
use style::properties::{PropertyId, LonghandId, ShorthandId};
|
||||
use style::properties::{apply_declarations, parse_one_declaration};
|
||||
use style::restyle_hints::RestyleHint;
|
||||
use style::selector_parser::PseudoElementCascadeType;
|
||||
|
@ -610,7 +611,7 @@ pub extern "C" fn Servo_DeclarationBlock_SerializeOneValue(
|
|||
buffer: *mut nsAString)
|
||||
{
|
||||
let declarations = RwLock::<PropertyDeclarationBlock>::as_arc(&declarations);
|
||||
let property = get_property_name_from_atom(property, is_custom);
|
||||
let property = get_property_id_from_atom(property, is_custom);
|
||||
let mut string = String::new();
|
||||
let rv = declarations.read().single_value_to_css(&property, &mut string);
|
||||
debug_assert!(rv.is_ok());
|
||||
|
@ -630,23 +631,28 @@ pub extern "C" fn Servo_DeclarationBlock_GetNthProperty(declarations: RawServoDe
|
|||
let declarations = RwLock::<PropertyDeclarationBlock>::as_arc(&declarations);
|
||||
if let Some(&(ref decl, _)) = declarations.read().declarations.get(index as usize) {
|
||||
let result = unsafe { result.as_mut().unwrap() };
|
||||
write!(result, "{}", decl.name()).unwrap();
|
||||
decl.id().to_css(result).unwrap();
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME Methods of PropertyDeclarationBlock should take atoms directly.
|
||||
// This function is just a temporary workaround before that finishes.
|
||||
fn get_property_name_from_atom(atom: *mut nsIAtom, is_custom: bool) -> String {
|
||||
fn get_property_id_from_atom(atom: *mut nsIAtom, is_custom: bool) -> PropertyId {
|
||||
let atom = Atom::from(atom);
|
||||
if !is_custom {
|
||||
atom.to_string()
|
||||
// FIXME: can we do this mapping without going through a UTF-8 string?
|
||||
// Maybe even from nsCSSPropertyID directly?
|
||||
let s = atom.to_string();
|
||||
if let Ok(id) = LonghandId::from_ascii_lowercase_name(&s) {
|
||||
PropertyId::Longhand(id)
|
||||
} else if let Ok(id) = ShorthandId::from_ascii_lowercase_name(&s) {
|
||||
PropertyId::Shorthand(id)
|
||||
} else {
|
||||
let mut result = String::with_capacity(atom.len() as usize + 2);
|
||||
write!(result, "--{}", atom).unwrap();
|
||||
result
|
||||
panic!("got unknown property name {:?} from Gecko", s)
|
||||
}
|
||||
} else {
|
||||
PropertyId::Custom(atom)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -655,7 +661,7 @@ pub extern "C" fn Servo_DeclarationBlock_GetPropertyValue(declarations: RawServo
|
|||
property: *mut nsIAtom, is_custom: bool,
|
||||
value: *mut nsAString) {
|
||||
let declarations = RwLock::<PropertyDeclarationBlock>::as_arc(&declarations);
|
||||
let property = get_property_name_from_atom(property, is_custom);
|
||||
let property = get_property_id_from_atom(property, is_custom);
|
||||
declarations.read().property_value_to_css(&property, unsafe { value.as_mut().unwrap() }).unwrap();
|
||||
}
|
||||
|
||||
|
@ -663,7 +669,7 @@ pub extern "C" fn Servo_DeclarationBlock_GetPropertyValue(declarations: RawServo
|
|||
pub extern "C" fn Servo_DeclarationBlock_GetPropertyIsImportant(declarations: RawServoDeclarationBlockBorrowed,
|
||||
property: *mut nsIAtom, is_custom: bool) -> bool {
|
||||
let declarations = RwLock::<PropertyDeclarationBlock>::as_arc(&declarations);
|
||||
let property = get_property_name_from_atom(property, is_custom);
|
||||
let property = get_property_id_from_atom(property, is_custom);
|
||||
declarations.read().property_priority(&property).important()
|
||||
}
|
||||
|
||||
|
@ -671,12 +677,12 @@ pub extern "C" fn Servo_DeclarationBlock_GetPropertyIsImportant(declarations: Ra
|
|||
pub extern "C" fn Servo_DeclarationBlock_SetProperty(declarations: RawServoDeclarationBlockBorrowed,
|
||||
property: *mut nsIAtom, is_custom: bool,
|
||||
value: *mut nsACString, is_important: bool) -> bool {
|
||||
let property = get_property_name_from_atom(property, is_custom);
|
||||
let property = get_property_id_from_atom(property, is_custom);
|
||||
let value = unsafe { value.as_ref().unwrap().as_str_unchecked() };
|
||||
// FIXME Needs real URL and ParserContextExtraData.
|
||||
let base_url = &*DUMMY_BASE_URL;
|
||||
let extra_data = ParserContextExtraData::default();
|
||||
if let Ok(decls) = parse_one_declaration(&property, value, &base_url,
|
||||
if let Ok(decls) = parse_one_declaration(&property.to_css_string(), value, &base_url,
|
||||
Box::new(StdoutErrorReporter), extra_data) {
|
||||
let mut declarations = RwLock::<PropertyDeclarationBlock>::as_arc(&declarations).write();
|
||||
let importance = if is_important { Importance::Important } else { Importance::Normal };
|
||||
|
@ -693,7 +699,7 @@ pub extern "C" fn Servo_DeclarationBlock_SetProperty(declarations: RawServoDecla
|
|||
pub extern "C" fn Servo_DeclarationBlock_RemoveProperty(declarations: RawServoDeclarationBlockBorrowed,
|
||||
property: *mut nsIAtom, is_custom: bool) {
|
||||
let declarations = RwLock::<PropertyDeclarationBlock>::as_arc(&declarations);
|
||||
let property = get_property_name_from_atom(property, is_custom);
|
||||
let property = get_property_id_from_atom(property, is_custom);
|
||||
declarations.write().remove_property(&property);
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
pub use std::sync::Arc;
|
||||
pub use style::computed_values::display::T::inline_block;
|
||||
pub use style::properties::{DeclaredValue, PropertyDeclaration, PropertyDeclarationBlock, Importance};
|
||||
pub use style::properties::{DeclaredValue, PropertyDeclaration, PropertyDeclarationBlock, Importance, PropertyId};
|
||||
pub use style::values::specified::{BorderStyle, BorderWidth, CSSColor, Length};
|
||||
pub use style::values::specified::{LengthOrPercentage, LengthOrPercentageOrAuto, LengthOrPercentageOrAutoOrContent};
|
||||
pub use style::properties::longhands::outline_color::computed_value::T as ComputedColor;
|
||||
|
@ -1027,7 +1027,8 @@ mod shorthand_serialization {
|
|||
|
||||
let mut s = String::new();
|
||||
|
||||
let x = block.single_value_to_css("scroll-snap-type", &mut s);
|
||||
let id = PropertyId::parse("scroll-snap-type".into()).unwrap();
|
||||
let x = block.single_value_to_css(&id, &mut s);
|
||||
|
||||
assert_eq!(x.is_ok(), true);
|
||||
assert_eq!(s, "");
|
||||
|
@ -1049,7 +1050,8 @@ mod shorthand_serialization {
|
|||
|
||||
let mut s = String::new();
|
||||
|
||||
let x = block.single_value_to_css("scroll-snap-type", &mut s);
|
||||
let id = PropertyId::parse("scroll-snap-type".into()).unwrap();
|
||||
let x = block.single_value_to_css(&id, &mut s);
|
||||
|
||||
assert_eq!(x.is_ok(), true);
|
||||
assert_eq!(s, "mandatory");
|
||||
|
|
|
@ -16,8 +16,8 @@ use std::sync::atomic::AtomicBool;
|
|||
use style::error_reporting::ParseErrorReporter;
|
||||
use style::keyframes::{Keyframe, KeyframeSelector, KeyframePercentage};
|
||||
use style::parser::ParserContextExtraData;
|
||||
use style::properties::{PropertyDeclaration, PropertyDeclarationBlock, DeclaredValue, longhands};
|
||||
use style::properties::Importance;
|
||||
use style::properties::{PropertyDeclaration, PropertyDeclarationBlock, DeclaredValue, longhands};
|
||||
use style::properties::longhands::animation_play_state;
|
||||
use style::stylesheets::{Origin, Namespaces};
|
||||
use style::stylesheets::{Stylesheet, NamespaceRule, CssRule, CssRules, StyleRule, KeyframesRule};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue