aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/element.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/script/dom/element.rs')
-rw-r--r--components/script/dom/element.rs60
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);