mirror of
https://github.com/servo/servo.git
synced 2025-06-09 17:13:24 +00:00
Remove some PropertyDeclaration cloning.
This commit is contained in:
parent
d2bd070dc3
commit
06ba62b012
4 changed files with 63 additions and 48 deletions
|
@ -21,6 +21,7 @@ use style::properties::PropertyDeclaration;
|
||||||
|
|
||||||
use std::ascii::AsciiExt;
|
use std::ascii::AsciiExt;
|
||||||
use std::borrow::ToOwned;
|
use std::borrow::ToOwned;
|
||||||
|
use std::cell::Ref;
|
||||||
|
|
||||||
// http://dev.w3.org/csswg/cssom/#the-cssstyledeclaration-interface
|
// http://dev.w3.org/csswg/cssom/#the-cssstyledeclaration-interface
|
||||||
#[dom_struct]
|
#[dom_struct]
|
||||||
|
@ -50,7 +51,7 @@ macro_rules! css_properties(
|
||||||
);
|
);
|
||||||
);
|
);
|
||||||
|
|
||||||
fn serialize_list(list: &Vec<PropertyDeclaration>) -> DOMString {
|
fn serialize_list(list: &[Ref<PropertyDeclaration>]) -> DOMString {
|
||||||
list.iter().fold(String::new(), |accum, ref declaration| {
|
list.iter().fold(String::new(), |accum, ref declaration| {
|
||||||
accum + &declaration.value() + " "
|
accum + &declaration.value() + " "
|
||||||
})
|
})
|
||||||
|
@ -78,25 +79,24 @@ impl CSSStyleDeclaration {
|
||||||
}
|
}
|
||||||
|
|
||||||
trait PrivateCSSStyleDeclarationHelpers {
|
trait PrivateCSSStyleDeclarationHelpers {
|
||||||
fn get_declaration(self, property: &Atom) -> Option<PropertyDeclaration>;
|
fn get_declaration(&self, property: &Atom) -> Option<Ref<PropertyDeclaration>>;
|
||||||
fn get_important_declaration(self, property: &Atom) -> Option<PropertyDeclaration>;
|
fn get_important_declaration(&self, property: &Atom) -> Option<Ref<PropertyDeclaration>>;
|
||||||
fn get_computed_style(self, property: &Atom) -> Option<DOMString>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> PrivateCSSStyleDeclarationHelpers for &'a CSSStyleDeclaration {
|
impl PrivateCSSStyleDeclarationHelpers for HTMLElement {
|
||||||
fn get_declaration(self, property: &Atom) -> Option<PropertyDeclaration> {
|
fn get_declaration(&self, property: &Atom) -> Option<Ref<PropertyDeclaration>> {
|
||||||
let owner = self.owner.root();
|
let element = ElementCast::from_ref(self);
|
||||||
let element = ElementCast::from_ref(owner.r());
|
element.get_inline_style_declaration(property)
|
||||||
element.get_inline_style_declaration(property).map(|decl| decl.clone())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_important_declaration(self, property: &Atom) -> Option<PropertyDeclaration> {
|
fn get_important_declaration(&self, property: &Atom) -> Option<Ref<PropertyDeclaration>> {
|
||||||
let owner = self.owner.root();
|
let element = ElementCast::from_ref(self);
|
||||||
let element = ElementCast::from_ref(owner.r());
|
element.get_important_inline_style_declaration(property)
|
||||||
element.get_important_inline_style_declaration(property).map(|decl| decl.clone())
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn get_computed_style(self, property: &Atom) -> Option<DOMString> {
|
impl CSSStyleDeclaration {
|
||||||
|
fn get_computed_style(&self, property: &Atom) -> Option<DOMString> {
|
||||||
let owner = self.owner.root();
|
let owner = self.owner.root();
|
||||||
let node = NodeCast::from_ref(owner.r());
|
let node = NodeCast::from_ref(owner.r());
|
||||||
if !node.is_in_doc() {
|
if !node.is_in_doc() {
|
||||||
|
@ -144,6 +144,8 @@ impl<'a> CSSStyleDeclarationMethods for &'a CSSStyleDeclaration {
|
||||||
|
|
||||||
// https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-getpropertyvalue
|
// https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-getpropertyvalue
|
||||||
fn GetPropertyValue(self, property: DOMString) -> DOMString {
|
fn GetPropertyValue(self, property: DOMString) -> DOMString {
|
||||||
|
let owner = self.owner.root();
|
||||||
|
|
||||||
// Step 1
|
// Step 1
|
||||||
let property = Atom::from_slice(&property.to_ascii_lowercase());
|
let property = Atom::from_slice(&property.to_ascii_lowercase());
|
||||||
|
|
||||||
|
@ -161,7 +163,7 @@ impl<'a> CSSStyleDeclarationMethods for &'a CSSStyleDeclaration {
|
||||||
// Step 2.2
|
// Step 2.2
|
||||||
for longhand in longhand_properties.iter() {
|
for longhand in longhand_properties.iter() {
|
||||||
// Step 2.2.1
|
// Step 2.2.1
|
||||||
let declaration = self.get_declaration(&Atom::from_slice(&longhand));
|
let declaration = owner.get_declaration(&Atom::from_slice(&longhand));
|
||||||
|
|
||||||
// Step 2.2.2 & 2.2.3
|
// Step 2.2.2 & 2.2.3
|
||||||
match declaration {
|
match declaration {
|
||||||
|
@ -175,11 +177,12 @@ impl<'a> CSSStyleDeclarationMethods for &'a CSSStyleDeclaration {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 3 & 4
|
// Step 3 & 4
|
||||||
if let Some(ref declaration) = self.get_declaration(&property) {
|
// FIXME: redundant let binding https://github.com/rust-lang/rust/issues/22252
|
||||||
declaration.value()
|
let result = match owner.get_declaration(&property) {
|
||||||
} else {
|
Some(declaration) => declaration.value(),
|
||||||
"".to_owned()
|
None => "".to_owned(),
|
||||||
}
|
};
|
||||||
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-getpropertypriority
|
// https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-getpropertypriority
|
||||||
|
@ -198,8 +201,12 @@ impl<'a> CSSStyleDeclarationMethods for &'a CSSStyleDeclaration {
|
||||||
return "important".to_owned();
|
return "important".to_owned();
|
||||||
}
|
}
|
||||||
// Step 3
|
// Step 3
|
||||||
} else if self.get_important_declaration(&property).is_some() {
|
} else {
|
||||||
return "important".to_owned();
|
// FIXME: extra let binding https://github.com/rust-lang/rust/issues/22323
|
||||||
|
let owner = self.owner.root();
|
||||||
|
if owner.get_important_declaration(&property).is_some() {
|
||||||
|
return "important".to_owned();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 4
|
// Step 4
|
||||||
|
|
|
@ -584,8 +584,8 @@ pub trait ElementHelpers<'a> {
|
||||||
fn remove_inline_style_property(self, property: &str);
|
fn remove_inline_style_property(self, property: &str);
|
||||||
fn update_inline_style(self, property_decl: PropertyDeclaration, style_priority: StylePriority);
|
fn update_inline_style(self, property_decl: PropertyDeclaration, style_priority: StylePriority);
|
||||||
fn set_inline_style_property_priority(self, properties: &[&str], style_priority: StylePriority);
|
fn set_inline_style_property_priority(self, properties: &[&str], style_priority: StylePriority);
|
||||||
fn get_inline_style_declaration(self, property: &Atom) -> Option<PropertyDeclaration>;
|
fn get_inline_style_declaration(self, property: &Atom) -> Option<Ref<'a, PropertyDeclaration>>;
|
||||||
fn get_important_inline_style_declaration(self, property: &Atom) -> Option<PropertyDeclaration>;
|
fn get_important_inline_style_declaration(self, property: &Atom) -> Option<Ref<'a, PropertyDeclaration>>;
|
||||||
fn serialize(self, traversal_scope: TraversalScope) -> Fallible<DOMString>;
|
fn serialize(self, traversal_scope: TraversalScope) -> Fallible<DOMString>;
|
||||||
fn get_root_element(self) -> Root<Element>;
|
fn get_root_element(self) -> Root<Element>;
|
||||||
fn lookup_prefix(self, namespace: Namespace) -> Option<DOMString>;
|
fn lookup_prefix(self, namespace: Namespace) -> Option<DOMString>;
|
||||||
|
@ -660,7 +660,7 @@ impl<'a> ElementHelpers<'a> for &'a Element {
|
||||||
.iter()
|
.iter()
|
||||||
.position(|decl| decl.name() == property);
|
.position(|decl| decl.name() == property);
|
||||||
if let Some(index) = index {
|
if let Some(index) = index {
|
||||||
Arc::make_unique(&mut declarations.normal).remove(index);
|
Arc::get_mut(&mut declarations.normal).unwrap().remove(index);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -668,7 +668,7 @@ impl<'a> ElementHelpers<'a> for &'a Element {
|
||||||
.iter()
|
.iter()
|
||||||
.position(|decl| decl.name() == property);
|
.position(|decl| decl.name() == property);
|
||||||
if let Some(index) = index {
|
if let Some(index) = index {
|
||||||
Arc::make_unique(&mut declarations.important).remove(index);
|
Arc::get_mut(&mut declarations.important).unwrap().remove(index);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -678,10 +678,14 @@ impl<'a> ElementHelpers<'a> for &'a Element {
|
||||||
let mut inline_declarations = self.style_attribute().borrow_mut();
|
let mut inline_declarations = self.style_attribute().borrow_mut();
|
||||||
if let &mut Some(ref mut declarations) = &mut *inline_declarations {
|
if let &mut Some(ref mut declarations) = &mut *inline_declarations {
|
||||||
let existing_declarations = if style_priority == StylePriority::Important {
|
let existing_declarations = if style_priority == StylePriority::Important {
|
||||||
Arc::make_unique(&mut declarations.important)
|
&mut declarations.important
|
||||||
} else {
|
} else {
|
||||||
Arc::make_unique(&mut declarations.normal)
|
&mut declarations.normal
|
||||||
};
|
};
|
||||||
|
// Element is the only owner of the Arc’s for its style attribute,
|
||||||
|
// except during selector matching.
|
||||||
|
// But selector matching does not run concurrently with script.
|
||||||
|
let existing_declarations = Arc::get_mut(existing_declarations).unwrap();
|
||||||
|
|
||||||
for declaration in existing_declarations.iter_mut() {
|
for declaration in existing_declarations.iter_mut() {
|
||||||
if declaration.name() == property_decl.name() {
|
if declaration.name() == property_decl.name() {
|
||||||
|
@ -713,8 +717,11 @@ impl<'a> ElementHelpers<'a> for &'a Element {
|
||||||
} else {
|
} else {
|
||||||
(&mut declarations.normal, &mut declarations.important)
|
(&mut declarations.normal, &mut declarations.important)
|
||||||
};
|
};
|
||||||
let from = Arc::make_unique(from);
|
// Element is the only owner of the Arc’s for its style attribute,
|
||||||
let to = Arc::make_unique(to);
|
// except during selector matching.
|
||||||
|
// But selector matching does not run concurrently with script.
|
||||||
|
let from = Arc::get_mut(from).unwrap();
|
||||||
|
let to = Arc::get_mut(to).unwrap();
|
||||||
let mut new_from = Vec::new();
|
let mut new_from = Vec::new();
|
||||||
for declaration in from.drain(..) {
|
for declaration in from.drain(..) {
|
||||||
if properties.contains(&declaration.name()) {
|
if properties.contains(&declaration.name()) {
|
||||||
|
@ -727,24 +734,24 @@ impl<'a> ElementHelpers<'a> for &'a Element {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_inline_style_declaration(self, property: &Atom) -> Option<PropertyDeclaration> {
|
fn get_inline_style_declaration(self, property: &Atom) -> Option<Ref<'a, PropertyDeclaration>> {
|
||||||
let inline_declarations = self.style_attribute.borrow();
|
Ref::filter_map(self.style_attribute.borrow(), |inline_declarations| {
|
||||||
inline_declarations.as_ref().and_then(|declarations| {
|
inline_declarations.as_ref().and_then(|declarations| {
|
||||||
declarations.normal
|
declarations.normal
|
||||||
.iter()
|
.iter()
|
||||||
.chain(declarations.important.iter())
|
.chain(declarations.important.iter())
|
||||||
.find(|decl| decl.matches(&property))
|
.find(|decl| decl.matches(&property))
|
||||||
.map(|decl| decl.clone())
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_important_inline_style_declaration(self, property: &Atom) -> Option<PropertyDeclaration> {
|
fn get_important_inline_style_declaration(self, property: &Atom) -> Option<Ref<'a, PropertyDeclaration>> {
|
||||||
let inline_declarations = self.style_attribute.borrow();
|
Ref::filter_map(self.style_attribute.borrow(), |inline_declarations| {
|
||||||
inline_declarations.as_ref().and_then(|declarations| {
|
inline_declarations.as_ref().and_then(|declarations| {
|
||||||
declarations.important
|
declarations.important
|
||||||
.iter()
|
.iter()
|
||||||
.find(|decl| decl.matches(&property))
|
.find(|decl| decl.matches(&property))
|
||||||
.map(|decl| decl.clone())
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#![feature(borrow_state)]
|
#![feature(borrow_state)]
|
||||||
#![feature(box_raw)]
|
#![feature(box_raw)]
|
||||||
#![feature(box_syntax)]
|
#![feature(box_syntax)]
|
||||||
|
#![feature(cell_extras)]
|
||||||
#![feature(core)]
|
#![feature(core)]
|
||||||
#![feature(core_intrinsics)]
|
#![feature(core_intrinsics)]
|
||||||
#![feature(custom_attribute)]
|
#![feature(custom_attribute)]
|
||||||
|
|
|
@ -5583,9 +5583,9 @@ pub fn parse_property_declaration_list(context: &ParserContext, input: &mut Pars
|
||||||
match declaration {
|
match declaration {
|
||||||
Ok((results, important)) => {
|
Ok((results, important)) => {
|
||||||
if important {
|
if important {
|
||||||
important_declarations.push_all(&results);
|
important_declarations.extend(results);
|
||||||
} else {
|
} else {
|
||||||
normal_declarations.push_all(&results);
|
normal_declarations.extend(results);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(range) => {
|
Err(range) => {
|
||||||
|
@ -5669,7 +5669,7 @@ impl<T: ToCss> DeclaredValue<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, PartialEq)]
|
#[derive(PartialEq)]
|
||||||
pub enum PropertyDeclaration {
|
pub enum PropertyDeclaration {
|
||||||
% for property in LONGHANDS:
|
% for property in LONGHANDS:
|
||||||
${property.camel_case}(DeclaredValue<longhands::${property.ident}::SpecifiedValue>),
|
${property.camel_case}(DeclaredValue<longhands::${property.ident}::SpecifiedValue>),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue