mirror of
https://github.com/servo/servo.git
synced 2025-08-05 05:30:08 +01:00
layout: Small vector optimize CSS selector matching
This commit is contained in:
parent
beb9b9bd92
commit
61b030552e
3 changed files with 36 additions and 25 deletions
|
@ -10,6 +10,7 @@ use layout::util::LayoutDataAccess;
|
|||
use layout::wrapper::LayoutNode;
|
||||
|
||||
use extra::arc::Arc;
|
||||
use servo_util::smallvec::SmallVec;
|
||||
use style::{TNode, Stylist, cascade};
|
||||
use style::{Before, After};
|
||||
|
||||
|
@ -33,12 +34,22 @@ impl<'ln> MatchMethods for LayoutNode<'ln> {
|
|||
let mut layout_data_ref = self.mutate_layout_data();
|
||||
match *layout_data_ref.get() {
|
||||
Some(ref mut layout_data) => {
|
||||
layout_data.data.applicable_declarations = stylist.get_applicable_declarations(
|
||||
self, style_attribute, None);
|
||||
layout_data.data.before_applicable_declarations = stylist.get_applicable_declarations(
|
||||
self, None, Some(Before));
|
||||
layout_data.data.after_applicable_declarations = stylist.get_applicable_declarations(
|
||||
self, None, Some(After));
|
||||
stylist.get_applicable_declarations(self,
|
||||
style_attribute,
|
||||
None,
|
||||
&mut layout_data.data.applicable_declarations);
|
||||
stylist.get_applicable_declarations(self,
|
||||
None,
|
||||
Some(Before),
|
||||
&mut layout_data
|
||||
.data
|
||||
.before_applicable_declarations);
|
||||
stylist.get_applicable_declarations(self,
|
||||
None,
|
||||
Some(After),
|
||||
&mut layout_data
|
||||
.data
|
||||
.after_applicable_declarations);
|
||||
}
|
||||
None => fail!("no layout data")
|
||||
}
|
||||
|
@ -79,7 +90,8 @@ impl<'ln> MatchMethods for LayoutNode<'ln> {
|
|||
let computed_values = {
|
||||
let layout_data_ref = self.borrow_layout_data();
|
||||
let layout_data = layout_data_ref.get().as_ref().unwrap();
|
||||
Arc::new(cascade(layout_data.data.$applicable_declarations, parent_style))
|
||||
Arc::new(cascade(layout_data.data.$applicable_declarations.as_slice(),
|
||||
parent_style))
|
||||
};
|
||||
|
||||
let mut layout_data_ref = self.mutate_layout_data();
|
||||
|
|
|
@ -11,6 +11,7 @@ use script::dom::bindings::utils::Reflectable;
|
|||
use script::dom::node::AbstractNode;
|
||||
use script::layout_interface::{LayoutChan, UntrustedNodeAddress};
|
||||
use servo_util::range::Range;
|
||||
use servo_util::smallvec::{SmallVec0, SmallVec16};
|
||||
use std::cast;
|
||||
use std::cell::{Ref, RefMut};
|
||||
use std::iter::Enumerate;
|
||||
|
@ -129,11 +130,11 @@ impl ElementMapping {
|
|||
/// Data that layout associates with a node.
|
||||
pub struct PrivateLayoutData {
|
||||
/// The results of CSS matching for this node.
|
||||
before_applicable_declarations: ~[Arc<~[PropertyDeclaration]>],
|
||||
applicable_declarations: SmallVec16<Arc<~[PropertyDeclaration]>>,
|
||||
|
||||
applicable_declarations: ~[Arc<~[PropertyDeclaration]>],
|
||||
before_applicable_declarations: SmallVec0<Arc<~[PropertyDeclaration]>>,
|
||||
|
||||
after_applicable_declarations: ~[Arc<~[PropertyDeclaration]>],
|
||||
after_applicable_declarations: SmallVec0<Arc<~[PropertyDeclaration]>>,
|
||||
|
||||
/// The results of CSS styling for this node.
|
||||
before_style: Option<Arc<ComputedValues>>,
|
||||
|
@ -154,9 +155,9 @@ impl PrivateLayoutData {
|
|||
/// Creates new layout data.
|
||||
pub fn new() -> PrivateLayoutData {
|
||||
PrivateLayoutData {
|
||||
applicable_declarations: ~[],
|
||||
before_applicable_declarations: ~[],
|
||||
after_applicable_declarations: ~[],
|
||||
applicable_declarations: SmallVec16::new(),
|
||||
before_applicable_declarations: SmallVec0::new(),
|
||||
after_applicable_declarations: SmallVec0::new(),
|
||||
before_style: None,
|
||||
style: None,
|
||||
after_style: None,
|
||||
|
|
|
@ -9,6 +9,7 @@ use std::str;
|
|||
use std::to_bytes;
|
||||
|
||||
use servo_util::namespace;
|
||||
use servo_util::smallvec::{SmallVec, SmallVec16};
|
||||
use servo_util::sort;
|
||||
|
||||
use media_queries::{Device, Screen};
|
||||
|
@ -106,7 +107,7 @@ impl SelectorMap {
|
|||
N:TNode<E>>(
|
||||
&self,
|
||||
node: &N,
|
||||
matching_rules_list: &mut ~[Rule]) {
|
||||
matching_rules_list: &mut SmallVec16<Rule>) {
|
||||
if self.empty {
|
||||
return
|
||||
}
|
||||
|
@ -156,7 +157,7 @@ impl SelectorMap {
|
|||
node: &N,
|
||||
hash: &HashMap<~str,~[Rule]>,
|
||||
key: &str,
|
||||
matching_rules: &mut ~[Rule]) {
|
||||
matching_rules: &mut SmallVec16<Rule>) {
|
||||
match hash.find_equiv(&key) {
|
||||
Some(rules) => {
|
||||
SelectorMap::get_matching_rules(node, *rules, matching_rules)
|
||||
|
@ -170,7 +171,7 @@ impl SelectorMap {
|
|||
node: &N,
|
||||
hash: &HashMap<~str,~[Rule]>,
|
||||
key: &str,
|
||||
matching_rules: &mut ~[Rule]) {
|
||||
matching_rules: &mut SmallVec16<Rule>) {
|
||||
match hash.find_equiv(&LowercaseAsciiString(key)) {
|
||||
Some(rules) => {
|
||||
SelectorMap::get_matching_rules(node, *rules, matching_rules)
|
||||
|
@ -184,7 +185,7 @@ impl SelectorMap {
|
|||
N:TNode<E>>(
|
||||
node: &N,
|
||||
rules: &[Rule],
|
||||
matching_rules: &mut ~[Rule]) {
|
||||
matching_rules: &mut SmallVec16<Rule>) {
|
||||
for rule in rules.iter() {
|
||||
if matches_compound_selector(rule.selector.get(), node) {
|
||||
// TODO(pradeep): Is the cloning inefficient?
|
||||
|
@ -358,12 +359,13 @@ impl Stylist {
|
|||
/// Returns the applicable CSS declarations for the given element. This corresponds to
|
||||
/// `ElementRuleCollector` in WebKit.
|
||||
pub fn get_applicable_declarations<E:TElement,
|
||||
N:TNode<E>>(
|
||||
N:TNode<E>,
|
||||
V:SmallVec<Arc<~[PropertyDeclaration]>>>(
|
||||
&self,
|
||||
element: &N,
|
||||
style_attribute: Option<&PropertyDeclarationBlock>,
|
||||
pseudo_element: Option<PseudoElement>)
|
||||
-> ~[Arc<~[PropertyDeclaration]>] {
|
||||
pseudo_element: Option<PseudoElement>,
|
||||
applicable_declarations: &mut V) {
|
||||
assert!(element.is_element());
|
||||
assert!(style_attribute.is_none() || pseudo_element.is_none(),
|
||||
"Style attributes do not apply to pseudo-elements");
|
||||
|
@ -387,8 +389,7 @@ impl Stylist {
|
|||
// we have the indices straight at the end.
|
||||
let mut rule_map_indices = [ 0, ..6 ];
|
||||
|
||||
// TODO(pcwalton): Small vector optimization.
|
||||
let mut matching_rules_list = ~[];
|
||||
let mut matching_rules_list = SmallVec16::new();
|
||||
|
||||
for (i, rule_map) in rule_map_list.iter().enumerate() {
|
||||
rule_map_indices[i] = matching_rules_list.len();
|
||||
|
@ -406,7 +407,6 @@ impl Stylist {
|
|||
});
|
||||
|
||||
// Gather up all rules.
|
||||
let mut applicable_declarations = ~[];
|
||||
let mut i = 0;
|
||||
|
||||
// Step 1: Normal rules.
|
||||
|
@ -432,8 +432,6 @@ impl Stylist {
|
|||
applicable_declarations.push(declaration_iter.next().unwrap());
|
||||
i += 1
|
||||
}
|
||||
|
||||
applicable_declarations
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue