aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBobby Holley <bobbyholley@gmail.com>2017-06-12 11:13:04 -0700
committerBobby Holley <bobbyholley@gmail.com>2017-06-12 12:13:21 -0700
commita98fff1af85f377787cff046bce07c1a93e79f9e (patch)
tree1776f4c41faa932e657a3396f3a778294e0a7f46
parent0caad2ffdc0879c12474a500d41f87697e8cfa5c (diff)
downloadservo-a98fff1af85f377787cff046bce07c1a93e79f9e.tar.gz
servo-a98fff1af85f377787cff046bce07c1a93e79f9e.zip
Hoist ApplicableDeclaration{Block,List} into a separate file.
MozReview-Commit-ID: EXnAzfyoZ1e
-rw-r--r--components/script/dom/element.rs2
-rw-r--r--components/script/layout_wrapper.rs2
-rw-r--r--components/style/applicable_declarations.rs137
-rw-r--r--components/style/dom.rs2
-rw-r--r--components/style/gecko/wrapper.rs2
-rw-r--r--components/style/lib.rs1
-rw-r--r--components/style/matching.rs3
-rw-r--r--components/style/rule_tree/mod.rs4
-rw-r--r--components/style/selector_map.rs3
-rw-r--r--components/style/sharing/mod.rs3
-rw-r--r--components/style/stylist.rs130
-rw-r--r--tests/unit/stylo/size_of.rs2
12 files changed, 161 insertions, 130 deletions
diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs
index 3d7b0676fb8..957eadb53e4 100644
--- a/components/script/dom/element.rs
+++ b/components/script/dom/element.rs
@@ -97,6 +97,7 @@ use std::convert::TryFrom;
use std::default::Default;
use std::fmt;
use std::rc::Rc;
+use style::applicable_declarations::ApplicableDeclarationBlock;
use style::attr::{AttrValue, LengthOrPercentageOrAuto};
use style::context::{QuirksMode, ReflowGoal};
use style::element_state::*;
@@ -109,7 +110,6 @@ use style::selector_parser::extended_filtering;
use style::shared_lock::{SharedRwLock, Locked};
use style::sink::Push;
use style::stylearc::Arc;
-use style::stylist::ApplicableDeclarationBlock;
use style::thread_state;
use style::values::{CSSFloat, Either};
use style::values::specified;
diff --git a/components/script/layout_wrapper.rs b/components/script/layout_wrapper.rs
index 15589619e17..916b9f5a329 100644
--- a/components/script/layout_wrapper.rs
+++ b/components/script/layout_wrapper.rs
@@ -61,6 +61,7 @@ use std::marker::PhantomData;
use std::mem::transmute;
use std::sync::atomic::Ordering;
use style;
+use style::applicable_declarations::ApplicableDeclarationBlock;
use style::attr::AttrValue;
use style::computed_values::display;
use style::context::{QuirksMode, SharedStyleContext};
@@ -76,7 +77,6 @@ use style::shared_lock::{SharedRwLock as StyleSharedRwLock, Locked as StyleLocke
use style::sink::Push;
use style::str::is_whitespace;
use style::stylearc::Arc;
-use style::stylist::ApplicableDeclarationBlock;
#[derive(Copy, Clone)]
pub struct ServoLayoutNode<'a> {
diff --git a/components/style/applicable_declarations.rs b/components/style/applicable_declarations.rs
new file mode 100644
index 00000000000..17cf13f7f4d
--- /dev/null
+++ b/components/style/applicable_declarations.rs
@@ -0,0 +1,137 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * 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/. */
+
+//! Applicable declarations management.
+
+use properties::PropertyDeclarationBlock;
+use rule_tree::{CascadeLevel, StyleSource};
+use shared_lock::Locked;
+use smallvec::SmallVec;
+use std::fmt::{Debug, self};
+use std::mem;
+use stylearc::Arc;
+
+/// List of applicable declarations. This is a transient structure that shuttles
+/// declarations between selector matching and inserting into the rule tree, and
+/// therefore we want to avoid heap-allocation where possible.
+///
+/// In measurements on wikipedia, we pretty much never have more than 8 applicable
+/// declarations, so we could consider making this 8 entries instead of 16.
+/// However, it may depend a lot on workload, and stack space is cheap.
+pub type ApplicableDeclarationList = SmallVec<[ApplicableDeclarationBlock; 16]>;
+
+/// Blink uses 18 bits to store source order, and does not check overflow [1].
+/// That's a limit that could be reached in realistic webpages, so we use
+/// 24 bits and enforce defined behavior in the overflow case.
+///
+/// Note that the value of 24 is also hard-coded into the level() accessor,
+/// which does a byte-aligned load of the 4th byte. If you change this value
+/// you'll need to change that as well.
+///
+/// [1] https://cs.chromium.org/chromium/src/third_party/WebKit/Source/core/css/
+/// RuleSet.h?l=128&rcl=90140ab80b84d0f889abc253410f44ed54ae04f3
+const SOURCE_ORDER_BITS: usize = 24;
+const SOURCE_ORDER_MASK: u32 = (1 << SOURCE_ORDER_BITS) - 1;
+const SOURCE_ORDER_MAX: u32 = SOURCE_ORDER_MASK;
+
+/// Stores the source order of a block and the cascade level it belongs to.
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
+#[derive(Copy, Clone, Eq, PartialEq)]
+struct SourceOrderAndCascadeLevel(u32);
+
+impl SourceOrderAndCascadeLevel {
+ fn new(source_order: u32, cascade_level: CascadeLevel) -> SourceOrderAndCascadeLevel {
+ let mut bits = ::std::cmp::min(source_order, SOURCE_ORDER_MAX);
+ bits |= (cascade_level as u8 as u32) << SOURCE_ORDER_BITS;
+ SourceOrderAndCascadeLevel(bits)
+ }
+
+ fn order(&self) -> u32 {
+ self.0 & SOURCE_ORDER_MASK
+ }
+
+ fn level(&self) -> CascadeLevel {
+ unsafe {
+ // Transmute rather than shifting so that we're sure the compiler
+ // emits a simple byte-aligned load.
+ let as_bytes: [u8; 4] = mem::transmute(self.0);
+ CascadeLevel::from_byte(as_bytes[3])
+ }
+ }
+}
+
+impl Debug for SourceOrderAndCascadeLevel {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.debug_struct("SourceOrderAndCascadeLevel")
+ .field("order", &self.order())
+ .field("level", &self.level())
+ .finish()
+ }
+}
+
+/// A property declaration together with its precedence among rules of equal
+/// specificity so that we can sort them.
+///
+/// This represents the declarations in a given declaration block for a given
+/// importance.
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
+#[derive(Debug, Clone, PartialEq)]
+pub struct ApplicableDeclarationBlock {
+ /// The style source, either a style rule, or a property declaration block.
+ #[cfg_attr(feature = "servo", ignore_heap_size_of = "Arc")]
+ pub source: StyleSource,
+ /// The source order of the block, and the cascade level it belongs to.
+ order_and_level: SourceOrderAndCascadeLevel,
+ /// The specificity of the selector this block is represented by.
+ pub specificity: u32,
+}
+
+impl ApplicableDeclarationBlock {
+ /// Constructs an applicable declaration block from a given property
+ /// declaration block and importance.
+ #[inline]
+ pub fn from_declarations(declarations: Arc<Locked<PropertyDeclarationBlock>>,
+ level: CascadeLevel)
+ -> Self {
+ ApplicableDeclarationBlock {
+ source: StyleSource::Declarations(declarations),
+ order_and_level: SourceOrderAndCascadeLevel::new(0, level),
+ specificity: 0,
+ }
+ }
+
+ /// Constructs an applicable declaration block from the given components
+ #[inline]
+ pub fn new(source: StyleSource,
+ order: u32,
+ level: CascadeLevel,
+ specificity: u32) -> Self {
+ ApplicableDeclarationBlock {
+ source: source,
+ order_and_level: SourceOrderAndCascadeLevel::new(order, level),
+ specificity: specificity,
+ }
+
+ }
+
+ /// Returns the source order of the block.
+ #[inline]
+ pub fn source_order(&self) -> u32 {
+ self.order_and_level.order()
+ }
+
+ /// Returns the cascade level of the block.
+ #[inline]
+ pub fn level(&self) -> CascadeLevel {
+ self.order_and_level.level()
+ }
+
+ /// Convenience method to consume self and return the source alongside the
+ /// level.
+ #[inline]
+ pub fn order_and_level(self) -> (StyleSource, CascadeLevel) {
+ let level = self.level();
+ (self.source, level)
+ }
+}
diff --git a/components/style/dom.rs b/components/style/dom.rs
index aef401dc43e..bbb4b279bf3 100644
--- a/components/style/dom.rs
+++ b/components/style/dom.rs
@@ -8,6 +8,7 @@
#![deny(missing_docs)]
use {Atom, Namespace, LocalName};
+use applicable_declarations::ApplicableDeclarationBlock;
use atomic_refcell::{AtomicRef, AtomicRefCell, AtomicRefMut};
#[cfg(feature = "gecko")] use context::UpdateAnimationsTasks;
use data::ElementData;
@@ -29,7 +30,6 @@ use std::fmt::Debug;
use std::hash::Hash;
use std::ops::Deref;
use stylearc::Arc;
-use stylist::ApplicableDeclarationBlock;
use thread_state;
pub use style_traits::UnsafeNode;
diff --git a/components/style/gecko/wrapper.rs b/components/style/gecko/wrapper.rs
index 0ceb2c82a1b..64068a875f6 100644
--- a/components/style/gecko/wrapper.rs
+++ b/components/style/gecko/wrapper.rs
@@ -15,6 +15,7 @@
//! the separation between the style system implementation and everything else.
use app_units::Au;
+use applicable_declarations::ApplicableDeclarationBlock;
use atomic_refcell::AtomicRefCell;
use context::{QuirksMode, SharedStyleContext, UpdateAnimationsTasks};
use data::ElementData;
@@ -87,7 +88,6 @@ use std::ptr;
use string_cache::{Atom, Namespace, WeakAtom, WeakNamespace};
use stylearc::Arc;
use stylesheets::UrlExtraData;
-use stylist::ApplicableDeclarationBlock;
/// A simple wrapper over a non-null Gecko node (`nsINode`) pointer.
///
diff --git a/components/style/lib.rs b/components/style/lib.rs
index 0cde26b37f0..66cde1211d3 100644
--- a/components/style/lib.rs
+++ b/components/style/lib.rs
@@ -91,6 +91,7 @@ extern crate unicode_segmentation;
mod macros;
pub mod animation;
+pub mod applicable_declarations;
#[allow(missing_docs)] // TODO.
#[cfg(feature = "servo")] pub mod attr;
pub mod bezier;
diff --git a/components/style/matching.rs b/components/style/matching.rs
index 00eaba9b63e..d93eec27026 100644
--- a/components/style/matching.rs
+++ b/components/style/matching.rs
@@ -7,6 +7,7 @@
#![allow(unsafe_code)]
#![deny(missing_docs)]
+use applicable_declarations::ApplicableDeclarationList;
use cascade_info::CascadeInfo;
use context::{SelectorFlagsMap, SharedStyleContext, StyleContext};
use data::{ComputedStyle, ElementData, RestyleData};
@@ -25,7 +26,7 @@ use selectors::matching::{ElementSelectorFlags, MatchingContext, MatchingMode, S
use selectors::matching::{VisitedHandlingMode, AFFECTED_BY_PSEUDO_ELEMENTS};
use sharing::StyleSharingBehavior;
use stylearc::Arc;
-use stylist::{ApplicableDeclarationList, RuleInclusion};
+use stylist::RuleInclusion;
/// The way a style should be inherited.
enum InheritMode {
diff --git a/components/style/rule_tree/mod.rs b/components/style/rule_tree/mod.rs
index 66e5bd214f0..c1a3b2b69d5 100644
--- a/components/style/rule_tree/mod.rs
+++ b/components/style/rule_tree/mod.rs
@@ -6,6 +6,7 @@
//! The rule tree.
+use applicable_declarations::ApplicableDeclarationList;
#[cfg(feature = "servo")]
use heapsize::HeapSizeOf;
use properties::{AnimationRules, Importance, LonghandIdSet, PropertyDeclarationBlock};
@@ -17,7 +18,6 @@ use std::ptr;
use std::sync::atomic::{AtomicPtr, AtomicUsize, Ordering};
use stylearc::{Arc, NonZeroPtrMut};
use stylesheets::StyleRule;
-use stylist::ApplicableDeclarationList;
use thread_state;
/// The rule tree, the structure servo uses to preserve the results of selector
@@ -230,7 +230,7 @@ impl RuleTree {
guards: &StylesheetGuards)
-> StrongRuleNode
{
- let rules = applicable_declarations.drain().map(|d| d.source_and_level());
+ let rules = applicable_declarations.drain().map(|d| d.order_and_level());
let rule_node = self.insert_ordered_rules_with_important(rules, guards);
rule_node
}
diff --git a/components/style/selector_map.rs b/components/style/selector_map.rs
index 8bb9eeb8e31..6a5733877a2 100644
--- a/components/style/selector_map.rs
+++ b/components/style/selector_map.rs
@@ -6,6 +6,7 @@
//! name, ids and hash.
use {Atom, LocalName};
+use applicable_declarations::ApplicableDeclarationBlock;
use dom::TElement;
use fnv::FnvHashMap;
use pdqsort::sort_by;
@@ -18,7 +19,7 @@ use smallvec::VecLike;
use std::borrow::Borrow;
use std::collections::HashMap;
use std::hash::Hash;
-use stylist::{ApplicableDeclarationBlock, Rule};
+use stylist::Rule;
/// A trait to abstract over a given selector map entry.
pub trait SelectorMapEntry : Sized + Clone {
diff --git a/components/style/sharing/mod.rs b/components/style/sharing/mod.rs
index 3c17f576156..5971eb34367 100644
--- a/components/style/sharing/mod.rs
+++ b/components/style/sharing/mod.rs
@@ -65,6 +65,7 @@
//! elements makes sense.
use Atom;
+use applicable_declarations::ApplicableDeclarationBlock;
use bit_vec::BitVec;
use bloom::StyleBloom;
use cache::{LRUCache, LRUCacheMutIterator};
@@ -78,7 +79,7 @@ use selectors::matching::{ElementSelectorFlags, VisitedHandlingMode, StyleRelati
use smallvec::SmallVec;
use std::mem;
use std::ops::Deref;
-use stylist::{ApplicableDeclarationBlock, Stylist};
+use stylist::Stylist;
mod checks;
diff --git a/components/style/stylist.rs b/components/style/stylist.rs
index ecda82f269e..321e417a428 100644
--- a/components/style/stylist.rs
+++ b/components/style/stylist.rs
@@ -5,6 +5,7 @@
//! Selector matching.
use {Atom, LocalName, Namespace};
+use applicable_declarations::{ApplicableDeclarationBlock, ApplicableDeclarationList};
use bit_vec::BitVec;
use context::{QuirksMode, SharedStyleContext};
use data::ComputedStyle;
@@ -33,11 +34,10 @@ use selectors::parser::{SelectorIter, SelectorMethods};
use selectors::visitor::SelectorVisitor;
use shared_lock::{Locked, SharedRwLockReadGuard, StylesheetGuards};
use sink::Push;
-use smallvec::{SmallVec, VecLike};
-use std::fmt::{Debug, self};
+use smallvec::VecLike;
+use std::fmt::Debug;
#[cfg(feature = "servo")]
use std::marker::PhantomData;
-use std::mem;
use style_traits::viewport::ViewportConstraints;
use stylearc::Arc;
#[cfg(feature = "gecko")]
@@ -50,15 +50,6 @@ use thread_state;
pub use ::fnv::FnvHashMap;
-/// List of applicable declaration. This is a transient structure that shuttles
-/// declarations between selector matching and inserting into the rule tree, and
-/// therefore we want to avoid heap-allocation where possible.
-///
-/// In measurements on wikipedia, we pretty much never have more than 8 applicable
-/// declarations, so we could consider making this 8 entries instead of 16.
-/// However, it may depend a lot on workload, and stack space is cheap.
-pub type ApplicableDeclarationList = SmallVec<[ApplicableDeclarationBlock; 16]>;
-
/// This structure holds all the selectors and device characteristics
/// for a given document. The selectors are converted into `Rule`s
/// (defined in rust-selectors), and introduced in a `SelectorMap`
@@ -756,7 +747,7 @@ impl Stylist {
let rule_node =
self.rule_tree.insert_ordered_rules_with_important(
- declarations.into_iter().map(|a| a.source_and_level()),
+ declarations.into_iter().map(|a| a.order_and_level()),
guards);
if rule_node == self.rule_tree.root() {
None
@@ -1208,7 +1199,7 @@ impl Stylist {
CascadeLevel::StyleAttributeNormal)
];
let rule_node =
- self.rule_tree.insert_ordered_rules(v.into_iter().map(|a| a.source_and_level()));
+ self.rule_tree.insert_ordered_rules(v.into_iter().map(|a| a.order_and_level()));
// This currently ignores visited styles. It appears to be used for
// font styles in <canvas> via Servo_StyleSet_ResolveForDeclarations.
@@ -1529,11 +1520,11 @@ impl Rule {
pub fn to_applicable_declaration_block(&self,
level: CascadeLevel)
-> ApplicableDeclarationBlock {
- ApplicableDeclarationBlock {
- source: StyleSource::Style(self.style_rule.clone()),
- source_and_level: SourceOrderAndCascadeLevel::new(self.source_order, level),
- specificity: self.specificity(),
- }
+ let source = StyleSource::Style(self.style_rule.clone());
+ ApplicableDeclarationBlock::new(source,
+ self.source_order,
+ level,
+ self.specificity())
}
/// Creates a new Rule.
@@ -1551,104 +1542,3 @@ impl Rule {
}
}
}
-
-/// Blink uses 18 bits to store source order, and does not check overflow [1].
-/// That's a limit that could be reached in realistic webpages, so we use
-/// 24 bits and enforce defined behavior in the overflow case.
-///
-/// Note that the value of 24 is also hard-coded into the level() accessor,
-/// which does a byte-aligned load of the 4th byte. If you change this value
-/// you'll need to change that as well.
-///
-/// [1] https://cs.chromium.org/chromium/src/third_party/WebKit/Source/core/css/
-/// RuleSet.h?l=128&rcl=90140ab80b84d0f889abc253410f44ed54ae04f3
-const SOURCE_ORDER_BITS: usize = 24;
-const SOURCE_ORDER_MASK: u32 = (1 << SOURCE_ORDER_BITS) - 1;
-const SOURCE_ORDER_MAX: u32 = SOURCE_ORDER_MASK;
-
-/// Stores the source order of a block and the cascade level it belongs to.
-#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
-#[derive(Copy, Clone, Eq, PartialEq)]
-struct SourceOrderAndCascadeLevel(u32);
-
-impl SourceOrderAndCascadeLevel {
- fn new(source_order: u32, cascade_level: CascadeLevel) -> SourceOrderAndCascadeLevel {
- let mut bits = ::std::cmp::min(source_order, SOURCE_ORDER_MAX);
- bits |= (cascade_level as u8 as u32) << SOURCE_ORDER_BITS;
- SourceOrderAndCascadeLevel(bits)
- }
-
- fn order(&self) -> u32 {
- self.0 & SOURCE_ORDER_MASK
- }
-
- fn level(&self) -> CascadeLevel {
- unsafe {
- // Transmute rather than shifting so that we're sure the compiler
- // emits a simple byte-aligned load.
- let as_bytes: [u8; 4] = mem::transmute(self.0);
- CascadeLevel::from_byte(as_bytes[3])
- }
- }
-}
-
-impl Debug for SourceOrderAndCascadeLevel {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- f.debug_struct("SourceOrderAndCascadeLevel")
- .field("order", &self.order())
- .field("level", &self.level())
- .finish()
- }
-}
-
-/// A property declaration together with its precedence among rules of equal
-/// specificity so that we can sort them.
-///
-/// This represents the declarations in a given declaration block for a given
-/// importance.
-#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
-#[derive(Debug, Clone, PartialEq)]
-pub struct ApplicableDeclarationBlock {
- /// The style source, either a style rule, or a property declaration block.
- #[cfg_attr(feature = "servo", ignore_heap_size_of = "Arc")]
- pub source: StyleSource,
- /// The source order of the block, and the cascade level it belongs to.
- source_and_level: SourceOrderAndCascadeLevel,
- /// The specificity of the selector this block is represented by.
- pub specificity: u32,
-}
-
-impl ApplicableDeclarationBlock {
- /// Constructs an applicable declaration block from a given property
- /// declaration block and importance.
- #[inline]
- pub fn from_declarations(declarations: Arc<Locked<PropertyDeclarationBlock>>,
- level: CascadeLevel)
- -> Self {
- ApplicableDeclarationBlock {
- source: StyleSource::Declarations(declarations),
- source_and_level: SourceOrderAndCascadeLevel::new(0, level),
- specificity: 0,
- }
- }
-
- /// Returns the source order of the block.
- #[inline]
- pub fn source_order(&self) -> u32 {
- self.source_and_level.order()
- }
-
- /// Returns the cascade level of the block.
- #[inline]
- pub fn level(&self) -> CascadeLevel {
- self.source_and_level.level()
- }
-
- /// Convenience method to consume self and return the source alongside the
- /// level.
- #[inline]
- pub fn source_and_level(self) -> (StyleSource, CascadeLevel) {
- let level = self.level();
- (self.source, level)
- }
-}
diff --git a/tests/unit/stylo/size_of.rs b/tests/unit/stylo/size_of.rs
index 6c90f53ffe6..72acb2c2d5f 100644
--- a/tests/unit/stylo/size_of.rs
+++ b/tests/unit/stylo/size_of.rs
@@ -6,11 +6,11 @@ use selectors::gecko_like_types as dummies;
use servo_arc::Arc;
use std::mem::{size_of, align_of};
use style;
+use style::applicable_declarations::ApplicableDeclarationBlock;
use style::data::{ComputedStyle, ElementData, ElementStyles};
use style::gecko::selector_parser as real;
use style::properties::ComputedValues;
use style::rule_tree::StrongRuleNode;
-use style::stylist::ApplicableDeclarationBlock;
#[test]
fn size_of_selectors_dummy_types() {