mirror of
https://github.com/servo/servo.git
synced 2025-08-01 19:50:30 +01:00
style: Define a CascadeLevel enum, and make the rule tree operate on it.
We'll use this level to know where to stop replacing nodes in the tree.
This commit is contained in:
parent
31ecc9b692
commit
314f2ce714
6 changed files with 144 additions and 64 deletions
|
@ -105,6 +105,7 @@ use style::properties::{DeclaredValue, Importance};
|
|||
use style::properties::{PropertyDeclaration, PropertyDeclarationBlock, parse_style_attribute};
|
||||
use style::properties::longhands::{background_image, border_spacing, font_family, font_size, overflow_x};
|
||||
use style::restyle_hints::RESTYLE_SELF;
|
||||
use style::rule_tree::CascadeLevel;
|
||||
use style::selector_parser::{NonTSPseudoClass, RestyleDamage, SelectorImpl, SelectorParser};
|
||||
use style::sink::Push;
|
||||
use style::stylist::ApplicableDeclarationBlock;
|
||||
|
@ -380,7 +381,7 @@ impl LayoutElementHelpers for LayoutJS<Element> {
|
|||
declarations: vec![(declaration, Importance::Normal)],
|
||||
important_count: 0,
|
||||
})),
|
||||
Importance::Normal)
|
||||
CascadeLevel::PresHints)
|
||||
}
|
||||
|
||||
let bgcolor = if let Some(this) = self.downcast::<HTMLBodyElement>() {
|
||||
|
|
|
@ -573,7 +573,7 @@ fn compute_rule_node<E: TElement>(context: &StyleContext<E>,
|
|||
applicable_declarations: &mut Vec<ApplicableDeclarationBlock>)
|
||||
-> StrongRuleNode
|
||||
{
|
||||
let rules = applicable_declarations.drain(..).map(|d| (d.source, d.importance));
|
||||
let rules = applicable_declarations.drain(..).map(|d| (d.source, d.level));
|
||||
let rule_node = context.shared.stylist.rule_tree.insert_ordered_rules(rules);
|
||||
rule_node
|
||||
}
|
||||
|
@ -583,10 +583,14 @@ impl<E: TElement> PrivateMatchMethods for E {}
|
|||
/// The public API that elements expose for selector matching.
|
||||
pub trait MatchMethods : TElement {
|
||||
/// Runs selector matching of this element, and returns the result.
|
||||
fn match_element(&self, context: &StyleContext<Self>, parent_bf: Option<&BloomFilter>)
|
||||
fn match_element(&self,
|
||||
context: &StyleContext<Self>,
|
||||
parent_bf: Option<&BloomFilter>)
|
||||
-> MatchResults
|
||||
{
|
||||
let mut applicable_declarations: Vec<ApplicableDeclarationBlock> = Vec::with_capacity(16);
|
||||
let mut applicable_declarations =
|
||||
Vec::<ApplicableDeclarationBlock>::with_capacity(16);
|
||||
|
||||
let stylist = &context.shared.stylist;
|
||||
let style_attribute = self.style_attribute();
|
||||
let animation_rules = self.get_animation_rules(None);
|
||||
|
@ -609,7 +613,7 @@ pub trait MatchMethods : TElement {
|
|||
let pseudo_animation_rules = self.get_animation_rules(Some(&pseudo));
|
||||
stylist.push_applicable_declarations(self, parent_bf, None,
|
||||
pseudo_animation_rules,
|
||||
Some(&pseudo.clone()),
|
||||
Some(&pseudo),
|
||||
&mut applicable_declarations,
|
||||
MatchingReason::ForStyling);
|
||||
|
||||
|
|
|
@ -151,11 +151,11 @@ impl RuleTree {
|
|||
/// Insert the given rules, that must be in proper order by specifity, and
|
||||
/// return the corresponding rule node representing the last inserted one.
|
||||
pub fn insert_ordered_rules<'a, I>(&self, iter: I) -> StrongRuleNode
|
||||
where I: Iterator<Item=(StyleSource, Importance)>,
|
||||
where I: Iterator<Item=(StyleSource, CascadeLevel)>,
|
||||
{
|
||||
let mut current = self.root.clone();
|
||||
for (source, importance) in iter {
|
||||
current = current.ensure_child(self.root.downgrade(), source, importance);
|
||||
for (source, level) in iter {
|
||||
current = current.ensure_child(self.root.downgrade(), source, level);
|
||||
}
|
||||
current
|
||||
}
|
||||
|
@ -176,6 +176,66 @@ impl RuleTree {
|
|||
/// where it likely did not result from a rigorous performance analysis.)
|
||||
const RULE_TREE_GC_INTERVAL: usize = 300;
|
||||
|
||||
/// The cascade level these rules are relevant at, as per[1].
|
||||
///
|
||||
/// The order of variants declared here is significant, and must be in
|
||||
/// _ascending_ order of precedence.
|
||||
///
|
||||
/// [1]: https://drafts.csswg.org/css-cascade/#cascade-origin
|
||||
#[repr(u8)]
|
||||
#[derive(Eq, PartialEq, Copy, Clone, Debug)]
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
pub enum CascadeLevel {
|
||||
/// Normal User-Agent rules.
|
||||
UANormal = 0,
|
||||
/// Presentational hints.
|
||||
PresHints,
|
||||
/// User normal rules.
|
||||
UserNormal,
|
||||
/// Author normal rules.
|
||||
AuthorNormal,
|
||||
/// Style attribute normal rules.
|
||||
StyleAttributeNormal,
|
||||
/// CSS animations and script-generated animations.
|
||||
Animations,
|
||||
/// Author-supplied important rules.
|
||||
AuthorImportant,
|
||||
/// Style attribute important rules.
|
||||
StyleAttributeImportant,
|
||||
/// User important rules.
|
||||
UserImportant,
|
||||
/// User-agent important rules.
|
||||
UAImportant,
|
||||
/// Transitions
|
||||
Transitions,
|
||||
}
|
||||
|
||||
impl CascadeLevel {
|
||||
/// Returns whether this cascade level represents important rules of some
|
||||
/// sort.
|
||||
#[inline]
|
||||
pub fn is_important(&self) -> bool {
|
||||
match *self {
|
||||
CascadeLevel::AuthorImportant |
|
||||
CascadeLevel::StyleAttributeImportant |
|
||||
CascadeLevel::UserImportant |
|
||||
CascadeLevel::UAImportant => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the importance relevant for this rule. Pretty similar to
|
||||
/// `is_important`.
|
||||
#[inline]
|
||||
pub fn importance(&self) -> Importance {
|
||||
if self.is_important() {
|
||||
Importance::Important
|
||||
} else {
|
||||
Importance::Normal
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct RuleNode {
|
||||
/// The root node. Only the root has no root pointer, for obvious reasons.
|
||||
root: Option<WeakRuleNode>,
|
||||
|
@ -187,9 +247,8 @@ struct RuleNode {
|
|||
/// or a raw property declaration block (like the style attribute).
|
||||
source: Option<StyleSource>,
|
||||
|
||||
/// The importance of the declarations relevant in the style rule,
|
||||
/// meaningless in the root node.
|
||||
importance: Importance,
|
||||
/// The cascade level this rule is positioned at.
|
||||
cascade_level: CascadeLevel,
|
||||
|
||||
refcount: AtomicUsize,
|
||||
first_child: AtomicPtr<RuleNode>,
|
||||
|
@ -215,13 +274,13 @@ impl RuleNode {
|
|||
fn new(root: WeakRuleNode,
|
||||
parent: StrongRuleNode,
|
||||
source: StyleSource,
|
||||
importance: Importance) -> Self {
|
||||
cascade_level: CascadeLevel) -> Self {
|
||||
debug_assert!(root.upgrade().parent().is_none());
|
||||
RuleNode {
|
||||
root: Some(root),
|
||||
parent: Some(parent),
|
||||
source: Some(source),
|
||||
importance: importance,
|
||||
cascade_level: cascade_level,
|
||||
refcount: AtomicUsize::new(1),
|
||||
first_child: AtomicPtr::new(ptr::null_mut()),
|
||||
next_sibling: AtomicPtr::new(ptr::null_mut()),
|
||||
|
@ -236,7 +295,7 @@ impl RuleNode {
|
|||
root: None,
|
||||
parent: None,
|
||||
source: None,
|
||||
importance: Importance::Normal,
|
||||
cascade_level: CascadeLevel::UANormal,
|
||||
refcount: AtomicUsize::new(1),
|
||||
first_child: AtomicPtr::new(ptr::null_mut()),
|
||||
next_sibling: AtomicPtr::new(ptr::null_mut()),
|
||||
|
@ -385,10 +444,10 @@ impl StrongRuleNode {
|
|||
fn ensure_child(&self,
|
||||
root: WeakRuleNode,
|
||||
source: StyleSource,
|
||||
importance: Importance) -> StrongRuleNode {
|
||||
cascade_level: CascadeLevel) -> StrongRuleNode {
|
||||
let mut last = None;
|
||||
for child in self.get().iter_children() {
|
||||
if child .get().importance == importance &&
|
||||
if child .get().cascade_level == cascade_level &&
|
||||
child.get().source.as_ref().unwrap().ptr_equals(&source) {
|
||||
return child;
|
||||
}
|
||||
|
@ -398,7 +457,7 @@ impl StrongRuleNode {
|
|||
let mut node = Box::new(RuleNode::new(root,
|
||||
self.clone(),
|
||||
source.clone(),
|
||||
importance));
|
||||
cascade_level));
|
||||
let new_ptr: *mut RuleNode = &mut *node;
|
||||
|
||||
loop {
|
||||
|
@ -462,7 +521,7 @@ impl StrongRuleNode {
|
|||
|
||||
/// Get the importance that this rule node represents.
|
||||
pub fn importance(&self) -> Importance {
|
||||
self.get().importance
|
||||
self.get().cascade_level.importance()
|
||||
}
|
||||
|
||||
/// Get an iterator for this rule node and its ancestors.
|
||||
|
|
|
@ -14,10 +14,10 @@ use keyframes::KeyframesAnimation;
|
|||
use media_queries::Device;
|
||||
use parking_lot::RwLock;
|
||||
use pdqsort::sort_by;
|
||||
use properties::{self, CascadeFlags, ComputedValues, INHERIT_ALL, Importance};
|
||||
use properties::{PropertyDeclaration, PropertyDeclarationBlock};
|
||||
use properties::{self, CascadeFlags, ComputedValues, INHERIT_ALL};
|
||||
use properties::PropertyDeclarationBlock;
|
||||
use restyle_hints::{RestyleHint, DependencySet};
|
||||
use rule_tree::{RuleTree, StrongRuleNode, StyleSource};
|
||||
use rule_tree::{CascadeLevel, RuleTree, StrongRuleNode, StyleSource};
|
||||
use selector_parser::{ElementExt, SelectorImpl, PseudoElement, Snapshot};
|
||||
use selectors::Element;
|
||||
use selectors::bloom::BloomFilter;
|
||||
|
@ -31,7 +31,6 @@ use std::borrow::Borrow;
|
|||
use std::collections::HashMap;
|
||||
use std::fmt;
|
||||
use std::hash::Hash;
|
||||
use std::slice;
|
||||
use std::sync::Arc;
|
||||
use style_traits::viewport::ViewportConstraints;
|
||||
use stylesheets::{CssRule, Origin, StyleRule, Stylesheet, UserAgentStylesheets};
|
||||
|
@ -215,7 +214,9 @@ impl Stylist {
|
|||
// extra field, and avoid this precomputation entirely.
|
||||
if let Some(map) = self.pseudos_map.remove(&pseudo) {
|
||||
let mut declarations = vec![];
|
||||
map.user_agent.get_universal_rules(&mut declarations);
|
||||
map.user_agent.get_universal_rules(&mut declarations,
|
||||
CascadeLevel::UANormal,
|
||||
CascadeLevel::UAImportant);
|
||||
self.precomputed_pseudo_element_decls.insert(pseudo, declarations);
|
||||
}
|
||||
});
|
||||
|
@ -311,7 +312,7 @@ impl Stylist {
|
|||
// FIXME(emilio): When we've taken rid of the cascade we can just
|
||||
// use into_iter.
|
||||
self.rule_tree.insert_ordered_rules(
|
||||
declarations.into_iter().map(|a| (a.source.clone(), a.importance)))
|
||||
declarations.into_iter().map(|a| (a.source.clone(), a.level)))
|
||||
}
|
||||
None => self.rule_tree.root(),
|
||||
};
|
||||
|
@ -394,7 +395,7 @@ impl Stylist {
|
|||
|
||||
let rule_node =
|
||||
self.rule_tree.insert_ordered_rules(
|
||||
declarations.into_iter().map(|a| (a.source, a.importance)));
|
||||
declarations.into_iter().map(|a| (a.source, a.level)));
|
||||
|
||||
let computed =
|
||||
properties::cascade(self.device.au_viewport_size(),
|
||||
|
@ -527,13 +528,18 @@ impl Stylist {
|
|||
applicable_declarations,
|
||||
&mut relations,
|
||||
reason,
|
||||
Importance::Normal);
|
||||
CascadeLevel::UANormal);
|
||||
debug!("UA normal: {:?}", relations);
|
||||
|
||||
// Step 2: Presentational hints.
|
||||
let length = applicable_declarations.len();
|
||||
let length_before_preshints = applicable_declarations.len();
|
||||
element.synthesize_presentational_hints_for_legacy_attributes(applicable_declarations);
|
||||
if applicable_declarations.len() != length {
|
||||
if applicable_declarations.len() != length_before_preshints {
|
||||
if cfg!(debug_assertions) {
|
||||
for declaration in &applicable_declarations[length_before_preshints..] {
|
||||
assert_eq!(declaration.level, CascadeLevel::PresHints);
|
||||
}
|
||||
}
|
||||
// Never share style for elements with preshints
|
||||
relations |= AFFECTED_BY_PRESENTATIONAL_HINTS;
|
||||
}
|
||||
|
@ -546,14 +552,14 @@ impl Stylist {
|
|||
applicable_declarations,
|
||||
&mut relations,
|
||||
reason,
|
||||
Importance::Normal);
|
||||
CascadeLevel::UserNormal);
|
||||
debug!("user normal: {:?}", relations);
|
||||
map.author.get_all_matching_rules(element,
|
||||
parent_bf,
|
||||
applicable_declarations,
|
||||
&mut relations,
|
||||
reason,
|
||||
Importance::Normal);
|
||||
CascadeLevel::AuthorNormal);
|
||||
debug!("author normal: {:?}", relations);
|
||||
|
||||
// Step 4: Normal style attributes.
|
||||
|
@ -562,7 +568,8 @@ impl Stylist {
|
|||
relations |= AFFECTED_BY_STYLE_ATTRIBUTE;
|
||||
Push::push(
|
||||
applicable_declarations,
|
||||
ApplicableDeclarationBlock::from_declarations(sa.clone(), Importance::Normal));
|
||||
ApplicableDeclarationBlock::from_declarations(sa.clone(),
|
||||
CascadeLevel::StyleAttributeNormal));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -575,7 +582,8 @@ impl Stylist {
|
|||
relations |= AFFECTED_BY_ANIMATIONS;
|
||||
Push::push(
|
||||
applicable_declarations,
|
||||
ApplicableDeclarationBlock::from_declarations(anim.clone(), Importance::Normal));
|
||||
ApplicableDeclarationBlock::from_declarations(anim.clone(),
|
||||
CascadeLevel::Animations));
|
||||
}
|
||||
debug!("animation: {:?}", relations);
|
||||
|
||||
|
@ -585,7 +593,7 @@ impl Stylist {
|
|||
applicable_declarations,
|
||||
&mut relations,
|
||||
reason,
|
||||
Importance::Important);
|
||||
CascadeLevel::AuthorImportant);
|
||||
|
||||
debug!("author important: {:?}", relations);
|
||||
|
||||
|
@ -595,7 +603,8 @@ impl Stylist {
|
|||
relations |= AFFECTED_BY_STYLE_ATTRIBUTE;
|
||||
Push::push(
|
||||
applicable_declarations,
|
||||
ApplicableDeclarationBlock::from_declarations(sa.clone(), Importance::Important));
|
||||
ApplicableDeclarationBlock::from_declarations(sa.clone(),
|
||||
CascadeLevel::StyleAttributeImportant));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -607,7 +616,7 @@ impl Stylist {
|
|||
applicable_declarations,
|
||||
&mut relations,
|
||||
reason,
|
||||
Importance::Important);
|
||||
CascadeLevel::UserImportant);
|
||||
|
||||
debug!("user important: {:?}", relations);
|
||||
} else {
|
||||
|
@ -620,7 +629,7 @@ impl Stylist {
|
|||
applicable_declarations,
|
||||
&mut relations,
|
||||
reason,
|
||||
Importance::Important);
|
||||
CascadeLevel::UAImportant);
|
||||
|
||||
debug!("UA important: {:?}", relations);
|
||||
|
||||
|
@ -630,7 +639,7 @@ impl Stylist {
|
|||
relations |= AFFECTED_BY_TRANSITIONS;
|
||||
Push::push(
|
||||
applicable_declarations,
|
||||
ApplicableDeclarationBlock::from_declarations(anim.clone(), Importance::Normal));
|
||||
ApplicableDeclarationBlock::from_declarations(anim.clone(), CascadeLevel::Transitions));
|
||||
}
|
||||
debug!("transition: {:?}", relations);
|
||||
|
||||
|
@ -858,7 +867,7 @@ impl SelectorMap {
|
|||
matching_rules_list: &mut V,
|
||||
relations: &mut StyleRelations,
|
||||
reason: MatchingReason,
|
||||
importance: Importance)
|
||||
cascade_level: CascadeLevel)
|
||||
where E: Element<Impl=SelectorImpl>,
|
||||
V: VecLike<ApplicableDeclarationBlock>
|
||||
{
|
||||
|
@ -876,7 +885,7 @@ impl SelectorMap {
|
|||
matching_rules_list,
|
||||
relations,
|
||||
reason,
|
||||
importance)
|
||||
cascade_level)
|
||||
}
|
||||
|
||||
element.each_class(|class| {
|
||||
|
@ -887,7 +896,7 @@ impl SelectorMap {
|
|||
matching_rules_list,
|
||||
relations,
|
||||
reason,
|
||||
importance);
|
||||
cascade_level);
|
||||
});
|
||||
|
||||
let local_name_hash = if element.is_html_element_in_html_document() {
|
||||
|
@ -902,7 +911,7 @@ impl SelectorMap {
|
|||
matching_rules_list,
|
||||
relations,
|
||||
reason,
|
||||
importance);
|
||||
cascade_level);
|
||||
|
||||
SelectorMap::get_matching_rules(element,
|
||||
parent_bf,
|
||||
|
@ -910,7 +919,7 @@ impl SelectorMap {
|
|||
matching_rules_list,
|
||||
relations,
|
||||
reason,
|
||||
importance);
|
||||
cascade_level);
|
||||
|
||||
// Sort only the rules we just added.
|
||||
sort_by_key(&mut matching_rules_list[init_len..],
|
||||
|
@ -918,11 +927,15 @@ impl SelectorMap {
|
|||
}
|
||||
|
||||
/// Append to `rule_list` all universal Rules (rules with selector `*|*`) in
|
||||
/// `self` sorted by specifity and source order.
|
||||
/// `self` sorted by specificity and source order.
|
||||
pub fn get_universal_rules<V>(&self,
|
||||
matching_rules_list: &mut V)
|
||||
matching_rules_list: &mut V,
|
||||
cascade_level: CascadeLevel,
|
||||
important_cascade_level: CascadeLevel)
|
||||
where V: VecLike<ApplicableDeclarationBlock>
|
||||
{
|
||||
debug_assert!(!cascade_level.is_important());
|
||||
debug_assert!(important_cascade_level.is_important());
|
||||
if self.empty {
|
||||
return
|
||||
}
|
||||
|
@ -936,11 +949,11 @@ impl SelectorMap {
|
|||
let block = guard.block.read();
|
||||
if block.any_normal() {
|
||||
matching_rules_list.push(
|
||||
rule.to_applicable_declaration_block(Importance::Normal));
|
||||
rule.to_applicable_declaration_block(cascade_level));
|
||||
}
|
||||
if block.any_important() {
|
||||
matching_rules_list.push(
|
||||
rule.to_applicable_declaration_block(Importance::Important));
|
||||
rule.to_applicable_declaration_block(important_cascade_level));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -957,7 +970,7 @@ impl SelectorMap {
|
|||
matching_rules: &mut Vector,
|
||||
relations: &mut StyleRelations,
|
||||
reason: MatchingReason,
|
||||
importance: Importance)
|
||||
cascade_level: CascadeLevel)
|
||||
where E: Element<Impl=SelectorImpl>,
|
||||
Str: Borrow<BorrowedStr> + Eq + Hash,
|
||||
BorrowedStr: Eq + Hash,
|
||||
|
@ -970,7 +983,7 @@ impl SelectorMap {
|
|||
matching_rules,
|
||||
relations,
|
||||
reason,
|
||||
importance)
|
||||
cascade_level)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -981,14 +994,14 @@ impl SelectorMap {
|
|||
matching_rules: &mut V,
|
||||
relations: &mut StyleRelations,
|
||||
reason: MatchingReason,
|
||||
importance: Importance)
|
||||
cascade_level: CascadeLevel)
|
||||
where E: Element<Impl=SelectorImpl>,
|
||||
V: VecLike<ApplicableDeclarationBlock>
|
||||
{
|
||||
for rule in rules.iter() {
|
||||
let guard = rule.style_rule.read();
|
||||
let block = guard.block.read();
|
||||
let any_declaration_for_importance = if importance.important() {
|
||||
let any_declaration_for_importance = if cascade_level.is_important() {
|
||||
block.any_important()
|
||||
} else {
|
||||
block.any_normal()
|
||||
|
@ -997,7 +1010,7 @@ impl SelectorMap {
|
|||
matches_complex_selector(&*rule.selector, element, parent_bf,
|
||||
relations, reason) {
|
||||
matching_rules.push(
|
||||
rule.to_applicable_declaration_block(importance));
|
||||
rule.to_applicable_declaration_block(cascade_level));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1093,10 +1106,10 @@ pub struct Rule {
|
|||
}
|
||||
|
||||
impl Rule {
|
||||
fn to_applicable_declaration_block(&self, importance: Importance) -> ApplicableDeclarationBlock {
|
||||
fn to_applicable_declaration_block(&self, level: CascadeLevel) -> ApplicableDeclarationBlock {
|
||||
ApplicableDeclarationBlock {
|
||||
source: StyleSource::Style(self.style_rule.clone()),
|
||||
importance: importance,
|
||||
level: level,
|
||||
source_order: self.source_order,
|
||||
specificity: self.specificity,
|
||||
}
|
||||
|
@ -1114,8 +1127,8 @@ 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 importance of this declaration block.
|
||||
pub importance: Importance,
|
||||
/// The cascade level this applicable declaration block is in.
|
||||
pub level: CascadeLevel,
|
||||
/// The source order of this block.
|
||||
pub source_order: usize,
|
||||
/// The specificity of the selector this block is represented by.
|
||||
|
@ -1127,13 +1140,13 @@ impl ApplicableDeclarationBlock {
|
|||
/// declaration block and importance.
|
||||
#[inline]
|
||||
pub fn from_declarations(declarations: Arc<RwLock<PropertyDeclarationBlock>>,
|
||||
importance: Importance)
|
||||
level: CascadeLevel)
|
||||
-> Self {
|
||||
ApplicableDeclarationBlock {
|
||||
source: StyleSource::Declarations(declarations),
|
||||
level: level,
|
||||
source_order: 0,
|
||||
specificity: 0,
|
||||
importance: importance,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ use style::error_reporting::ParseErrorReporter;
|
|||
use style::media_queries::MediaList;
|
||||
use style::parser::ParserContextExtraData;
|
||||
use style::properties::{longhands, DeclaredValue, Importance, PropertyDeclaration, PropertyDeclarationBlock};
|
||||
use style::rule_tree::{RuleTree, StrongRuleNode, StyleSource};
|
||||
use style::rule_tree::{CascadeLevel, RuleTree, StrongRuleNode, StyleSource};
|
||||
use style::stylesheets::{Origin, Stylesheet, CssRule};
|
||||
use test::{self, Bencher};
|
||||
|
||||
|
@ -40,7 +40,7 @@ impl<'a> Drop for AutoGCRuleTree<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn parse_rules(css: &str) -> Vec<(StyleSource, Importance)> {
|
||||
fn parse_rules(css: &str) -> Vec<(StyleSource, CascadeLevel)> {
|
||||
let s = Stylesheet::from_str(css,
|
||||
ServoUrl::parse("http://localhost").unwrap(),
|
||||
Origin::Author,
|
||||
|
@ -57,15 +57,15 @@ fn parse_rules(css: &str) -> Vec<(StyleSource, Importance)> {
|
|||
_ => None,
|
||||
}
|
||||
}).cloned().map(StyleSource::Style).map(|s| {
|
||||
(s, Importance::Normal)
|
||||
(s, CascadeLevel::UserNormal)
|
||||
}).collect()
|
||||
}
|
||||
|
||||
fn test_insertion(rule_tree: &RuleTree, rules: Vec<(StyleSource, Importance)>) -> StrongRuleNode {
|
||||
fn test_insertion(rule_tree: &RuleTree, rules: Vec<(StyleSource, CascadeLevel)>) -> StrongRuleNode {
|
||||
rule_tree.insert_ordered_rules(rules.into_iter())
|
||||
}
|
||||
|
||||
fn test_insertion_style_attribute(rule_tree: &RuleTree, rules: &[(StyleSource, Importance)]) -> StrongRuleNode {
|
||||
fn test_insertion_style_attribute(rule_tree: &RuleTree, rules: &[(StyleSource, CascadeLevel)]) -> StrongRuleNode {
|
||||
let mut rules = rules.to_vec();
|
||||
rules.push((StyleSource::Declarations(Arc::new(RwLock::new(PropertyDeclarationBlock {
|
||||
declarations: vec![
|
||||
|
@ -74,7 +74,7 @@ fn test_insertion_style_attribute(rule_tree: &RuleTree, rules: &[(StyleSource, I
|
|||
Importance::Normal),
|
||||
],
|
||||
important_count: 0,
|
||||
}))), Importance::Normal));
|
||||
}))), CascadeLevel::UserNormal));
|
||||
test_insertion(rule_tree, rules)
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ use servo_atoms::Atom;
|
|||
use std::sync::Arc;
|
||||
use style::properties::{PropertyDeclarationBlock, PropertyDeclaration, DeclaredValue};
|
||||
use style::properties::{longhands, Importance};
|
||||
use style::rule_tree::CascadeLevel;
|
||||
use style::selector_parser::SelectorParser;
|
||||
use style::stylesheets::StyleRule;
|
||||
use style::stylist::{Rule, SelectorMap};
|
||||
|
@ -113,7 +114,9 @@ fn test_get_universal_rules() {
|
|||
let map = get_mock_map(&["*|*", "#foo > *|*", ".klass", "#id"]);
|
||||
let mut decls = vec![];
|
||||
|
||||
map.get_universal_rules(&mut decls);
|
||||
map.get_universal_rules(&mut decls,
|
||||
CascadeLevel::UserNormal,
|
||||
CascadeLevel::UserImportant);
|
||||
|
||||
assert_eq!(decls.len(), 1);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue