diff options
Diffstat (limited to 'components/script/dom/element.rs')
-rw-r--r-- | components/script/dom/element.rs | 60 |
1 files changed, 29 insertions, 31 deletions
diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs index 838da981524..5e00cb71c75 100644 --- a/components/script/dom/element.rs +++ b/components/script/dom/element.rs @@ -70,12 +70,13 @@ use html5ever::serialize::SerializeOpts; use html5ever::serialize::TraversalScope; use html5ever::serialize::TraversalScope::{ChildrenOnly, IncludeNode}; use html5ever::tree_builder::{LimitedQuirks, NoQuirks, Quirks}; +use parking_lot::RwLock; use selectors::matching::{ElementFlags, MatchingReason, matches}; use selectors::matching::{HAS_EDGE_CHILD_SELECTOR, HAS_SLOW_SELECTOR, HAS_SLOW_SELECTOR_LATER_SIBLINGS}; use selectors::parser::{AttrSelector, NamespaceConstraint, parse_author_origin_selector_list_from_str}; use std::ascii::AsciiExt; use std::borrow::Cow; -use std::cell::Cell; +use std::cell::{Cell, Ref}; use std::convert::TryFrom; use std::default::Default; use std::fmt; @@ -89,7 +90,6 @@ use style::parser::ParserContextExtraData; use style::properties::{DeclaredValue, Importance}; use style::properties::{PropertyDeclaration, PropertyDeclarationBlock, parse_style_attribute}; use style::properties::longhands::{self, background_image, border_spacing, font_family, font_size, overflow_x}; -use style::refcell::Ref; use style::selector_impl::{NonTSPseudoClass, ServoSelectorImpl}; use style::selector_matching::ApplicableDeclarationBlock; use style::sink::Push; @@ -109,7 +109,8 @@ pub struct Element { prefix: Option<DOMString>, attrs: DOMRefCell<Vec<JS<Attr>>>, id_attribute: DOMRefCell<Option<Atom>>, - style_attribute: DOMRefCell<Option<Arc<PropertyDeclarationBlock>>>, + #[ignore_heap_size_of = "Arc"] + style_attribute: DOMRefCell<Option<Arc<RwLock<PropertyDeclarationBlock>>>>, attr_list: MutNullableHeap<JS<NamedNodeMap>>, class_list: MutNullableHeap<JS<DOMTokenList>>, state: Cell<ElementState>, @@ -297,7 +298,7 @@ pub trait LayoutElementHelpers { #[allow(unsafe_code)] unsafe fn html_element_in_html_document_for_layout(&self) -> bool; fn id_attribute(&self) -> *const Option<Atom>; - fn style_attribute(&self) -> *const Option<Arc<PropertyDeclarationBlock>>; + fn style_attribute(&self) -> *const Option<Arc<RwLock<PropertyDeclarationBlock>>>; fn local_name(&self) -> &Atom; fn namespace(&self) -> &Namespace; fn get_checked_state_for_layout(&self) -> bool; @@ -329,10 +330,10 @@ impl LayoutElementHelpers for LayoutJS<Element> { #[inline] fn from_declaration(rule: PropertyDeclaration) -> ApplicableDeclarationBlock { ApplicableDeclarationBlock::from_declarations( - Arc::new(PropertyDeclarationBlock { + Arc::new(RwLock::new(PropertyDeclarationBlock { declarations: vec![(rule, Importance::Normal)], important_count: 0, - }), + })), Importance::Normal) } @@ -618,7 +619,7 @@ impl LayoutElementHelpers for LayoutJS<Element> { } #[allow(unsafe_code)] - fn style_attribute(&self) -> *const Option<Arc<PropertyDeclarationBlock>> { + fn style_attribute(&self) -> *const Option<Arc<RwLock<PropertyDeclarationBlock>>> { unsafe { (*self.unsafe_get()).style_attribute.borrow_for_layout() } @@ -707,7 +708,7 @@ impl Element { self.attrs.borrow() } - pub fn style_attribute(&self) -> &DOMRefCell<Option<Arc<PropertyDeclarationBlock>>> { + pub fn style_attribute(&self) -> &DOMRefCell<Option<Arc<RwLock<PropertyDeclarationBlock>>>> { &self.style_attribute } @@ -737,7 +738,7 @@ impl Element { // therefore, it should not trigger subsequent mutation events pub fn sync_property_with_attrs_style(&self) { let style_str = if let &Some(ref declarations) = &*self.style_attribute().borrow() { - declarations.to_css_string() + declarations.read().to_css_string() } else { String::new() }; @@ -769,7 +770,7 @@ impl Element { let mut inline_declarations = element.style_attribute.borrow_mut(); if let &mut Some(ref mut declarations) = &mut *inline_declarations { let mut importance = None; - let index = declarations.declarations.iter().position(|&(ref decl, i)| { + let index = declarations.read().declarations.iter().position(|&(ref decl, i)| { let matching = decl.matches(property); if matching { importance = Some(i) @@ -777,7 +778,7 @@ impl Element { matching }); if let Some(index) = index { - let declarations = Arc::make_mut(declarations); + let mut declarations = declarations.write(); declarations.declarations.remove(index); if importance.unwrap().important() { declarations.important_count -= 1; @@ -798,9 +799,8 @@ impl Element { let mut inline_declarations = element.style_attribute().borrow_mut(); if let &mut Some(ref mut declaration_block) = &mut *inline_declarations { { - // Usually, the reference count will be 1 here. But transitions could make it greater - // than that. - let declaration_block = Arc::make_mut(declaration_block); + let mut declaration_block = declaration_block.write(); + let declaration_block = &mut *declaration_block; let existing_declarations = &mut declaration_block.declarations; 'outer: for incoming_declaration in declarations { @@ -834,10 +834,10 @@ impl Element { 0 }; - *inline_declarations = Some(Arc::new(PropertyDeclarationBlock { + *inline_declarations = Some(Arc::new(RwLock::new(PropertyDeclarationBlock { declarations: declarations.into_iter().map(|d| (d, importance)).collect(), important_count: important_count, - })); + }))); } update(self, declarations, importance); @@ -850,9 +850,8 @@ impl Element { { let mut inline_declarations = self.style_attribute().borrow_mut(); if let &mut Some(ref mut block) = &mut *inline_declarations { - // Usually, the reference counts of `from` and `to` will be 1 here. But transitions - // could make them greater than that. - let block = Arc::make_mut(block); + let mut block = block.write(); + let block = &mut *block; let declarations = &mut block.declarations; for &mut (ref declaration, ref mut importance) in declarations { if properties.iter().any(|p| declaration.name() == **p) { @@ -874,16 +873,15 @@ impl Element { self.sync_property_with_attrs_style(); } - pub fn get_inline_style_declaration(&self, - property: &Atom) - -> Option<Ref<(PropertyDeclaration, Importance)>> { - Ref::filter_map(self.style_attribute.borrow(), |inline_declarations| { - inline_declarations.as_ref().and_then(|declarations| { - declarations.declarations - .iter() - .find(|&&(ref decl, _)| decl.matches(&property)) - }) - }) + pub fn get_inline_style_declaration<F, R>(&self, property: &str, f: F) -> R + where F: FnOnce(Option<&(PropertyDeclaration, Importance)>) -> R { + let style_attr = self.style_attribute.borrow(); + if let Some(ref block) = *style_attr { + let block = block.read(); + f(block.get(property)) + } else { + f(None) + } } pub fn serialize(&self, traversal_scope: TraversalScope) -> Fallible<DOMString> { @@ -2129,11 +2127,11 @@ impl VirtualMethods for Element { *self.style_attribute.borrow_mut() = mutation.new_value(attr).map(|value| { let win = window_from_node(self); - Arc::new(parse_style_attribute( + Arc::new(RwLock::new(parse_style_attribute( &value, &doc.base_url(), win.css_error_reporter(), - ParserContextExtraData::default())) + ParserContextExtraData::default()))) }); if node.is_in_doc() { node.dirty(NodeDamage::NodeStyleDamaged); |