Remove @pointers from Stylesheet to make it Sendable

… at the cost some extra copying.

This fixes #1081.
This commit is contained in:
Simon Sapin 2013-10-18 14:25:11 +01:00
parent e30a950e40
commit acb11343ce
4 changed files with 24 additions and 16 deletions

View file

@ -5,7 +5,6 @@
// This file is a Mako template: http://www.makotemplates.org/ // This file is a Mako template: http://www.makotemplates.org/
use std::ascii::StrAsciiExt; use std::ascii::StrAsciiExt;
use std::at_vec;
pub use std::iterator; pub use std::iterator;
pub use cssparser::*; pub use cssparser::*;
pub use errors::{ErrorLoggerIterator, log_css_error}; pub use errors::{ErrorLoggerIterator, log_css_error};
@ -810,8 +809,8 @@ pub mod shorthands {
pub struct PropertyDeclarationBlock { pub struct PropertyDeclarationBlock {
important: @[PropertyDeclaration], important: ~[PropertyDeclaration],
normal: @[PropertyDeclaration], normal: ~[PropertyDeclaration],
} }
@ -837,9 +836,8 @@ pub fn parse_property_declaration_list<I: Iterator<Node>>(input: I) -> PropertyD
} }
} }
PropertyDeclarationBlock { PropertyDeclarationBlock {
// TODO avoid copying? important: important,
important: at_vec::to_managed_move(important), normal: normal,
normal: at_vec::to_managed_move(normal),
} }
} }
@ -872,6 +870,7 @@ pub enum DeclaredValue<T> {
CSSWideKeyword(CSSWideKeyword), CSSWideKeyword(CSSWideKeyword),
} }
#[deriving(Clone)]
pub enum PropertyDeclaration { pub enum PropertyDeclaration {
% for property in LONGHANDS: % for property in LONGHANDS:
${property.ident}_declaration(DeclaredValue<longhands::${property.ident}::SpecifiedValue>), ${property.ident}_declaration(DeclaredValue<longhands::${property.ident}::SpecifiedValue>),
@ -961,7 +960,7 @@ fn get_initial_values() -> ComputedValues {
// Most specific/important declarations last // Most specific/important declarations last
pub fn cascade(applicable_declarations: &[@[PropertyDeclaration]], pub fn cascade(applicable_declarations: &[~[PropertyDeclaration]],
parent_style: Option< &ComputedValues>) parent_style: Option< &ComputedValues>)
-> ComputedValues { -> ComputedValues {
let initial_keep_alive; let initial_keep_alive;

View file

@ -2,6 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use std::at_vec;
use std::ascii::StrAsciiExt; use std::ascii::StrAsciiExt;
use extra::sort::tim_sort; use extra::sort::tim_sort;
@ -50,9 +51,10 @@ impl Stylist {
if style_rule.declarations.$priority.len() > 0 { if style_rule.declarations.$priority.len() > 0 {
$flag = true; $flag = true;
for selector in style_rule.selectors.iter() { for selector in style_rule.selectors.iter() {
// TODO: avoid copying?
rules.$priority.push(Rule { rules.$priority.push(Rule {
selector: *selector, selector: @(*selector).clone(),
declarations: style_rule.declarations.$priority, declarations:at_vec::to_managed(style_rule.declarations.$priority),
}) })
} }
} }
@ -99,10 +101,12 @@ impl Stylist {
// Style attributes have author origin but higher specificity than style rules. // Style attributes have author origin but higher specificity than style rules.
append!(self.author_rules.normal); append!(self.author_rules.normal);
style_attribute.map(|sa| applicable_declarations.push(sa.normal)); // TODO: avoid copying?
style_attribute.map(|sa| applicable_declarations.push(at_vec::to_managed(sa.normal)));
append!(self.author_rules.important); append!(self.author_rules.important);
style_attribute.map(|sa| applicable_declarations.push(sa.important)); // TODO: avoid copying?
style_attribute.map(|sa| applicable_declarations.push(at_vec::to_managed(sa.important)));
append!(self.user_rules.important); append!(self.user_rules.important);
append!(self.ua_rules.important); append!(self.ua_rules.important);

View file

@ -8,6 +8,7 @@ use cssparser::*;
use namespaces::NamespaceMap; use namespaces::NamespaceMap;
#[deriving(Clone)]
pub struct Selector { pub struct Selector {
compound_selectors: CompoundSelector, compound_selectors: CompoundSelector,
pseudo_element: Option<PseudoElement>, pseudo_element: Option<PseudoElement>,
@ -17,7 +18,7 @@ pub struct Selector {
pub static STYLE_ATTRIBUTE_SPECIFICITY: u32 = 1 << 31; pub static STYLE_ATTRIBUTE_SPECIFICITY: u32 = 1 << 31;
#[deriving(Eq)] #[deriving(Eq, Clone)]
pub enum PseudoElement { pub enum PseudoElement {
Before, Before,
After, After,
@ -26,11 +27,13 @@ pub enum PseudoElement {
} }
#[deriving(Clone)]
pub struct CompoundSelector { pub struct CompoundSelector {
simple_selectors: ~[SimpleSelector], simple_selectors: ~[SimpleSelector],
next: Option<(~CompoundSelector, Combinator)>, // c.next is left of c next: Option<(~CompoundSelector, Combinator)>, // c.next is left of c
} }
#[deriving(Eq, Clone)]
pub enum Combinator { pub enum Combinator {
Child, // > Child, // >
Descendant, // space Descendant, // space
@ -38,6 +41,7 @@ pub enum Combinator {
LaterSibling, // ~ LaterSibling, // ~
} }
#[deriving(Clone)]
pub enum SimpleSelector { pub enum SimpleSelector {
IDSelector(~str), IDSelector(~str),
ClassSelector(~str), ClassSelector(~str),
@ -62,6 +66,7 @@ pub enum SimpleSelector {
// ... // ...
} }
#[deriving(Clone)]
pub struct AttrSelector { pub struct AttrSelector {
name: ~str, name: ~str,
namespace: Option<~str>, namespace: Option<~str>,
@ -73,7 +78,7 @@ type Iter = iterator::Peekable<ComponentValue, vec::MoveIterator<ComponentValue>
// None means invalid selector // None means invalid selector
pub fn parse_selector_list(input: ~[ComponentValue], namespaces: &NamespaceMap) pub fn parse_selector_list(input: ~[ComponentValue], namespaces: &NamespaceMap)
-> Option<~[@Selector]> { -> Option<~[Selector]> {
let iter = &mut input.move_iter().peekable(); let iter = &mut input.move_iter().peekable();
let first = match parse_selector(iter, namespaces) { let first = match parse_selector(iter, namespaces) {
None => return None, None => return None,
@ -99,7 +104,7 @@ pub fn parse_selector_list(input: ~[ComponentValue], namespaces: &NamespaceMap)
// None means invalid selector // None means invalid selector
fn parse_selector(iter: &mut Iter, namespaces: &NamespaceMap) fn parse_selector(iter: &mut Iter, namespaces: &NamespaceMap)
-> Option<@Selector> { -> Option<Selector> {
let (first, pseudo_element) = match parse_simple_selectors(iter, namespaces) { let (first, pseudo_element) = match parse_simple_selectors(iter, namespaces) {
None => return None, None => return None,
Some(result) => result Some(result) => result
@ -130,7 +135,7 @@ fn parse_selector(iter: &mut Iter, namespaces: &NamespaceMap)
} }
} }
} }
Some(@Selector { Some(Selector {
specificity: compute_specificity(&compound, &pseudo_element), specificity: compute_specificity(&compound, &pseudo_element),
compound_selectors: compound, compound_selectors: compound,
pseudo_element: pseudo_element, pseudo_element: pseudo_element,

View file

@ -27,7 +27,7 @@ pub enum CSSRule {
pub struct StyleRule { pub struct StyleRule {
selectors: ~[@selectors::Selector], selectors: ~[selectors::Selector],
declarations: properties::PropertyDeclarationBlock, declarations: properties::PropertyDeclarationBlock,
} }