mirror of
https://github.com/servo/servo.git
synced 2025-06-24 17:14:33 +01:00
Use Arc<PropertyDeclarationBlock> everwhere it’s appropriate.
This commit is contained in:
parent
c50e6add4a
commit
acc38aa8c2
13 changed files with 85 additions and 68 deletions
|
@ -15,6 +15,7 @@ use dom::node::{Node, NodeDamage, window_from_node};
|
|||
use dom::window::Window;
|
||||
use std::ascii::AsciiExt;
|
||||
use std::slice;
|
||||
use std::sync::Arc;
|
||||
use string_cache::Atom;
|
||||
use style::parser::ParserContextExtraData;
|
||||
use style::properties::{PropertyDeclaration, Shorthand, Importance};
|
||||
|
@ -367,7 +368,7 @@ impl CSSStyleDeclarationMethods for CSSStyleDeclaration {
|
|||
*element.style_attribute().borrow_mut() = if decl_block.declarations.is_empty() {
|
||||
None // Step 2
|
||||
} else {
|
||||
Some(decl_block)
|
||||
Some(Arc::new(decl_block))
|
||||
};
|
||||
element.sync_property_with_attrs_style();
|
||||
let node = element.upcast::<Node>();
|
||||
|
|
|
@ -109,7 +109,7 @@ pub struct Element {
|
|||
prefix: Option<DOMString>,
|
||||
attrs: DOMRefCell<Vec<JS<Attr>>>,
|
||||
id_attribute: DOMRefCell<Option<Atom>>,
|
||||
style_attribute: DOMRefCell<Option<PropertyDeclarationBlock>>,
|
||||
style_attribute: DOMRefCell<Option<Arc<PropertyDeclarationBlock>>>,
|
||||
attr_list: MutNullableHeap<JS<NamedNodeMap>>,
|
||||
class_list: MutNullableHeap<JS<DOMTokenList>>,
|
||||
state: Cell<ElementState>,
|
||||
|
@ -297,7 +297,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<PropertyDeclarationBlock>;
|
||||
fn style_attribute(&self) -> *const Option<Arc<PropertyDeclarationBlock>>;
|
||||
fn local_name(&self) -> &Atom;
|
||||
fn namespace(&self) -> &Namespace;
|
||||
fn get_checked_state_for_layout(&self) -> bool;
|
||||
|
@ -329,7 +329,10 @@ impl LayoutElementHelpers for LayoutJS<Element> {
|
|||
#[inline]
|
||||
fn from_declaration(rule: PropertyDeclaration) -> DeclarationBlock {
|
||||
DeclarationBlock::from_declarations(
|
||||
Arc::new(vec![(rule, Importance::Normal)]),
|
||||
Arc::new(PropertyDeclarationBlock {
|
||||
declarations: Arc::new(vec![(rule, Importance::Normal)]),
|
||||
important_count: 0,
|
||||
}),
|
||||
Importance::Normal)
|
||||
}
|
||||
|
||||
|
@ -615,7 +618,7 @@ impl LayoutElementHelpers for LayoutJS<Element> {
|
|||
}
|
||||
|
||||
#[allow(unsafe_code)]
|
||||
fn style_attribute(&self) -> *const Option<PropertyDeclarationBlock> {
|
||||
fn style_attribute(&self) -> *const Option<Arc<PropertyDeclarationBlock>> {
|
||||
unsafe {
|
||||
(*self.unsafe_get()).style_attribute.borrow_for_layout()
|
||||
}
|
||||
|
@ -704,7 +707,7 @@ impl Element {
|
|||
self.attrs.borrow()
|
||||
}
|
||||
|
||||
pub fn style_attribute(&self) -> &DOMRefCell<Option<PropertyDeclarationBlock>> {
|
||||
pub fn style_attribute(&self) -> &DOMRefCell<Option<Arc<PropertyDeclarationBlock>>> {
|
||||
&self.style_attribute
|
||||
}
|
||||
|
||||
|
@ -774,6 +777,7 @@ impl Element {
|
|||
matching
|
||||
});
|
||||
if let Some(index) = index {
|
||||
let declarations = Arc::make_mut(declarations);
|
||||
Arc::make_mut(&mut declarations.declarations).remove(index);
|
||||
if importance.unwrap().important() {
|
||||
declarations.important_count -= 1;
|
||||
|
@ -796,6 +800,7 @@ impl Element {
|
|||
{
|
||||
// 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 existing_declarations = Arc::make_mut(&mut declaration_block.declarations);
|
||||
|
||||
'outer: for incoming_declaration in declarations {
|
||||
|
@ -829,10 +834,10 @@ impl Element {
|
|||
0
|
||||
};
|
||||
|
||||
*inline_declarations = Some(PropertyDeclarationBlock {
|
||||
*inline_declarations = Some(Arc::new(PropertyDeclarationBlock {
|
||||
declarations: Arc::new(declarations.into_iter().map(|d| (d, importance)).collect()),
|
||||
important_count: important_count,
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
update(self, declarations, importance);
|
||||
|
@ -847,6 +852,7 @@ impl Element {
|
|||
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 declarations = Arc::make_mut(&mut block.declarations);
|
||||
for &mut (ref declaration, ref mut importance) in declarations {
|
||||
if properties.iter().any(|p| declaration.name() == **p) {
|
||||
|
@ -2102,8 +2108,11 @@ impl VirtualMethods for Element {
|
|||
*self.style_attribute.borrow_mut() =
|
||||
mutation.new_value(attr).map(|value| {
|
||||
let win = window_from_node(self);
|
||||
parse_style_attribute(&value, &doc.base_url(), win.css_error_reporter(),
|
||||
ParserContextExtraData::default())
|
||||
Arc::new(parse_style_attribute(
|
||||
&value,
|
||||
&doc.base_url(),
|
||||
win.css_error_reporter(),
|
||||
ParserContextExtraData::default()))
|
||||
});
|
||||
if node.is_in_doc() {
|
||||
node.dirty(NodeDamage::NodeStyleDamaged);
|
||||
|
|
|
@ -451,9 +451,9 @@ impl<'le> TElement for ServoLayoutElement<'le> {
|
|||
ServoLayoutNode::from_layout_js(self.element.upcast())
|
||||
}
|
||||
|
||||
fn style_attribute(&self) -> &Option<PropertyDeclarationBlock> {
|
||||
fn style_attribute(&self) -> Option<&Arc<PropertyDeclarationBlock>> {
|
||||
unsafe {
|
||||
&*self.element.style_attribute()
|
||||
(*self.element.style_attribute()).as_ref()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -192,7 +192,7 @@ pub trait TElement : PartialEq + Debug + Sized + Copy + Clone + ElementExt + Pre
|
|||
|
||||
fn as_node(&self) -> Self::ConcreteNode;
|
||||
|
||||
fn style_attribute(&self) -> &Option<PropertyDeclarationBlock>;
|
||||
fn style_attribute(&self) -> Option<&Arc<PropertyDeclarationBlock>>;
|
||||
|
||||
fn get_state(&self) -> ElementState;
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ use cssparser::{DeclarationListParser, DeclarationParser};
|
|||
use parser::{ParserContext, log_css_error};
|
||||
use properties::PropertyDeclarationParseResult;
|
||||
use properties::animated_properties::TransitionProperty;
|
||||
use properties::{PropertyDeclaration, Importance};
|
||||
use properties::{PropertyDeclaration, PropertyDeclarationBlock, Importance};
|
||||
use std::sync::Arc;
|
||||
|
||||
/// A number from 1 to 100, indicating the percentage of the animation where
|
||||
|
@ -77,7 +77,7 @@ pub struct Keyframe {
|
|||
/// so the second value of these tuples is always `Importance::Normal`.
|
||||
/// But including them enables `compute_style_for_animation_step` to create a `DeclarationBlock`
|
||||
/// by cloning an `Arc<_>` (incrementing a reference count) rather than re-creating a `Vec<_>`.
|
||||
pub declarations: Arc<Vec<(PropertyDeclaration, Importance)>>,
|
||||
pub block: Arc<PropertyDeclarationBlock>,
|
||||
}
|
||||
|
||||
/// A keyframes step value. This can be a synthetised keyframes animation, that
|
||||
|
@ -88,7 +88,7 @@ pub struct Keyframe {
|
|||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
pub enum KeyframesStepValue {
|
||||
/// See `Keyframe::declarations`’s docs about the presence of `Importance`.
|
||||
Declarations(Arc<Vec<(PropertyDeclaration, Importance)>>),
|
||||
Declarations(Arc<PropertyDeclarationBlock>),
|
||||
ComputedValues,
|
||||
}
|
||||
|
||||
|
@ -113,8 +113,8 @@ impl KeyframesStep {
|
|||
fn new(percentage: KeyframePercentage,
|
||||
value: KeyframesStepValue) -> Self {
|
||||
let declared_timing_function = match value {
|
||||
KeyframesStepValue::Declarations(ref declarations) => {
|
||||
declarations.iter().any(|&(ref prop_decl, _)| {
|
||||
KeyframesStepValue::Declarations(ref block) => {
|
||||
block.declarations.iter().any(|&(ref prop_decl, _)| {
|
||||
match *prop_decl {
|
||||
PropertyDeclaration::AnimationTimingFunction(..) => true,
|
||||
_ => false,
|
||||
|
@ -154,7 +154,7 @@ fn get_animated_properties(keyframe: &Keyframe) -> Vec<TransitionProperty> {
|
|||
let mut ret = vec![];
|
||||
// NB: declarations are already deduplicated, so we don't have to check for
|
||||
// it here.
|
||||
for &(ref declaration, _) in keyframe.declarations.iter() {
|
||||
for &(ref declaration, _) in keyframe.block.declarations.iter() {
|
||||
if let Some(property) = TransitionProperty::from_declaration(declaration) {
|
||||
ret.push(property);
|
||||
}
|
||||
|
@ -179,7 +179,7 @@ impl KeyframesAnimation {
|
|||
for keyframe in keyframes {
|
||||
for percentage in keyframe.selector.0.iter() {
|
||||
steps.push(KeyframesStep::new(*percentage,
|
||||
KeyframesStepValue::Declarations(keyframe.declarations.clone())));
|
||||
KeyframesStepValue::Declarations(keyframe.block.clone())));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -265,7 +265,10 @@ impl<'a> QualifiedRuleParser for KeyframeListParser<'a> {
|
|||
}
|
||||
Ok(Arc::new(Keyframe {
|
||||
selector: prelude,
|
||||
declarations: Arc::new(declarations),
|
||||
block: Arc::new(PropertyDeclarationBlock {
|
||||
declarations: Arc::new(declarations),
|
||||
important_count: 0,
|
||||
}),
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ use context::{StyleContext, SharedStyleContext};
|
|||
use data::PrivateStyleData;
|
||||
use dom::{TElement, TNode, TRestyleDamage, UnsafeNode};
|
||||
use properties::longhands::display::computed_value as display;
|
||||
use properties::{ComputedValues, cascade};
|
||||
use properties::{ComputedValues, cascade, PropertyDeclarationBlock};
|
||||
use selector_impl::{TheSelectorImpl, PseudoElement};
|
||||
use selector_matching::{DeclarationBlock, Stylist};
|
||||
use selectors::bloom::BloomFilter;
|
||||
|
@ -139,7 +139,7 @@ impl<'a> Hash for ApplicableDeclarationsCacheQuery<'a> {
|
|||
for declaration in self.declarations {
|
||||
// Each declaration contians an Arc, which is a stable
|
||||
// pointer; we use that for hashing and equality.
|
||||
let ptr: *const Vec<_> = &*declaration.mixed_declarations;
|
||||
let ptr: *const PropertyDeclarationBlock = &*declaration.mixed_declarations;
|
||||
ptr.hash(state);
|
||||
declaration.importance.hash(state);
|
||||
}
|
||||
|
@ -651,7 +651,7 @@ pub trait ElementMatchMethods : TElement {
|
|||
applicable_declarations: &mut ApplicableDeclarations)
|
||||
-> StyleRelations {
|
||||
use traversal::relations_are_shareable;
|
||||
let style_attribute = self.style_attribute().as_ref();
|
||||
let style_attribute = self.style_attribute();
|
||||
|
||||
let mut relations =
|
||||
stylist.push_applicable_declarations(self,
|
||||
|
|
|
@ -282,7 +282,7 @@ impl Importance {
|
|||
|
||||
/// Overridden declarations are skipped.
|
||||
// FIXME (https://github.com/servo/servo/issues/3426)
|
||||
#[derive(Debug, PartialEq)]
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
pub struct PropertyDeclarationBlock {
|
||||
#[cfg_attr(feature = "servo", ignore_heap_size_of = "#7038")]
|
||||
|
|
|
@ -181,7 +181,7 @@ impl Stylist {
|
|||
selector: selector.complex_selector.clone(),
|
||||
declarations: DeclarationBlock {
|
||||
specificity: selector.specificity,
|
||||
mixed_declarations: $style_rule.declarations.declarations.clone(),
|
||||
mixed_declarations: $style_rule.declarations.clone(),
|
||||
importance: $importance,
|
||||
source_order: rules_source_order,
|
||||
},
|
||||
|
@ -346,7 +346,7 @@ impl Stylist {
|
|||
&self,
|
||||
element: &E,
|
||||
parent_bf: Option<&BloomFilter>,
|
||||
style_attribute: Option<&PropertyDeclarationBlock>,
|
||||
style_attribute: Option<&Arc<PropertyDeclarationBlock>>,
|
||||
pseudo_element: Option<&PseudoElement>,
|
||||
applicable_declarations: &mut V) -> StyleRelations
|
||||
where E: Element<Impl=TheSelectorImpl> +
|
||||
|
@ -398,14 +398,12 @@ impl Stylist {
|
|||
debug!("author normal: {:?}", relations);
|
||||
|
||||
// Step 4: Normal style attributes.
|
||||
if let Some(ref sa) = style_attribute {
|
||||
if let Some(sa) = style_attribute {
|
||||
if sa.declarations.len() as u32 - sa.important_count > 0 {
|
||||
relations |= AFFECTED_BY_STYLE_ATTRIBUTE;
|
||||
Push::push(
|
||||
applicable_declarations,
|
||||
DeclarationBlock::from_declarations(
|
||||
sa.declarations.clone(),
|
||||
Importance::Normal));
|
||||
DeclarationBlock::from_declarations(sa.clone(), Importance::Normal));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -420,14 +418,12 @@ impl Stylist {
|
|||
debug!("author important: {:?}", relations);
|
||||
|
||||
// Step 6: `!important` style attributes.
|
||||
if let Some(ref sa) = style_attribute {
|
||||
if let Some(sa) = style_attribute {
|
||||
if sa.important_count > 0 {
|
||||
relations |= AFFECTED_BY_STYLE_ATTRIBUTE;
|
||||
Push::push(
|
||||
applicable_declarations,
|
||||
DeclarationBlock::from_declarations(
|
||||
sa.declarations.clone(),
|
||||
Importance::Important));
|
||||
DeclarationBlock::from_declarations(sa.clone(), Importance::Important));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -845,7 +841,7 @@ pub struct Rule {
|
|||
pub struct DeclarationBlock {
|
||||
/// Contains declarations of either importance, but only those of self.importance are relevant.
|
||||
/// Use DeclarationBlock::iter
|
||||
pub mixed_declarations: Arc<Vec<(PropertyDeclaration, Importance)>>,
|
||||
pub mixed_declarations: Arc<PropertyDeclarationBlock>,
|
||||
pub importance: Importance,
|
||||
pub source_order: usize,
|
||||
pub specificity: u32,
|
||||
|
@ -853,7 +849,7 @@ pub struct DeclarationBlock {
|
|||
|
||||
impl DeclarationBlock {
|
||||
#[inline]
|
||||
pub fn from_declarations(declarations: Arc<Vec<(PropertyDeclaration, Importance)>>,
|
||||
pub fn from_declarations(declarations: Arc<PropertyDeclarationBlock>,
|
||||
importance: Importance)
|
||||
-> Self {
|
||||
DeclarationBlock {
|
||||
|
@ -866,7 +862,7 @@ impl DeclarationBlock {
|
|||
|
||||
pub fn iter(&self) -> DeclarationBlockIter {
|
||||
DeclarationBlockIter {
|
||||
iter: self.mixed_declarations.iter(),
|
||||
iter: self.mixed_declarations.declarations.iter(),
|
||||
importance: self.importance,
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue