mirror of
https://github.com/servo/servo.git
synced 2025-08-05 05:30:08 +01:00
Auto merge of #13134 - servo:archery, r=emilio
Add lots of Arc’s in style, and prepare for using DOMRefCell <!-- Please describe your changes on the following line: --> `DOMRefCell` usage is not there year because of thread-safety questions, but I have this much already that I’d like to land before it bitrots. r? @emilio --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: --> - [x] `./mach build -d` does not report any errors - [x] `./mach test-tidy` does not report any errors - [ ] These changes fix #__ (github issue number if applicable). <!-- Either: --> - [ ] There are tests for these changes OR - [x] These changes do not require new tests because refactor <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/13134) <!-- Reviewable:end -->
This commit is contained in:
commit
bbfe38e35f
29 changed files with 487 additions and 246 deletions
|
@ -53,6 +53,8 @@ fn is_unrooted_ty(cx: &LateContext, ty: &ty::TyS, in_new_function: bool) -> bool
|
||||||
false
|
false
|
||||||
} else if match_def_path(cx, did.did, &["core", "cell", "Ref"])
|
} else if match_def_path(cx, did.did, &["core", "cell", "Ref"])
|
||||||
|| match_def_path(cx, did.did, &["core", "cell", "RefMut"])
|
|| match_def_path(cx, did.did, &["core", "cell", "RefMut"])
|
||||||
|
|| match_def_path(cx, did.did, &["style", "refcell", "Ref"])
|
||||||
|
|| match_def_path(cx, did.did, &["style", "refcell", "RefMut"])
|
||||||
|| match_def_path(cx, did.did, &["core", "slice", "Iter"])
|
|| match_def_path(cx, did.did, &["core", "slice", "Iter"])
|
||||||
|| match_def_path(cx, did.did, &["std", "collections", "hash", "map", "OccupiedEntry"])
|
|| match_def_path(cx, did.did, &["std", "collections", "hash", "map", "OccupiedEntry"])
|
||||||
|| match_def_path(cx, did.did, &["std", "collections", "hash", "map", "VacantEntry"]) {
|
|| match_def_path(cx, did.did, &["std", "collections", "hash", "map", "VacantEntry"]) {
|
||||||
|
|
|
@ -56,7 +56,6 @@ plugins = {path = "../plugins"}
|
||||||
profile_traits = {path = "../profile_traits"}
|
profile_traits = {path = "../profile_traits"}
|
||||||
rand = "0.3"
|
rand = "0.3"
|
||||||
range = {path = "../range"}
|
range = {path = "../range"}
|
||||||
ref_filter_map = "1.0"
|
|
||||||
ref_slice = "1.0"
|
ref_slice = "1.0"
|
||||||
regex = "0.1.43"
|
regex = "0.1.43"
|
||||||
rustc-serialize = "0.3"
|
rustc-serialize = "0.3"
|
||||||
|
|
|
@ -15,10 +15,10 @@ use dom::element::{AttributeMutation, Element};
|
||||||
use dom::virtualmethods::vtable_for;
|
use dom::virtualmethods::vtable_for;
|
||||||
use dom::window::Window;
|
use dom::window::Window;
|
||||||
use std::borrow::ToOwned;
|
use std::borrow::ToOwned;
|
||||||
use std::cell::Ref;
|
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use string_cache::{Atom, Namespace};
|
use string_cache::{Atom, Namespace};
|
||||||
use style::attr::{AttrIdentifier, AttrValue};
|
use style::attr::{AttrIdentifier, AttrValue};
|
||||||
|
use style::refcell::Ref;
|
||||||
|
|
||||||
// https://dom.spec.whatwg.org/#interface-attr
|
// https://dom.spec.whatwg.org/#interface-attr
|
||||||
#[dom_struct]
|
#[dom_struct]
|
||||||
|
|
|
@ -128,8 +128,9 @@
|
||||||
//! return `Err()` from the method with the appropriate [error value]
|
//! return `Err()` from the method with the appropriate [error value]
|
||||||
//! (error/enum.Error.html).
|
//! (error/enum.Error.html).
|
||||||
|
|
||||||
|
pub use style::domrefcell as cell;
|
||||||
|
|
||||||
pub mod callback;
|
pub mod callback;
|
||||||
pub mod cell;
|
|
||||||
pub mod conversions;
|
pub mod conversions;
|
||||||
pub mod error;
|
pub mod error;
|
||||||
pub mod global;
|
pub mod global;
|
||||||
|
|
|
@ -88,6 +88,7 @@ use std::sync::mpsc::{Receiver, Sender};
|
||||||
use std::time::SystemTime;
|
use std::time::SystemTime;
|
||||||
use string_cache::{Atom, Namespace, QualName};
|
use string_cache::{Atom, Namespace, QualName};
|
||||||
use style::attr::{AttrIdentifier, AttrValue, LengthOrPercentageOrAuto};
|
use style::attr::{AttrIdentifier, AttrValue, LengthOrPercentageOrAuto};
|
||||||
|
use style::domrefcell::DOMRefCell;
|
||||||
use style::element_state::*;
|
use style::element_state::*;
|
||||||
use style::properties::PropertyDeclarationBlock;
|
use style::properties::PropertyDeclarationBlock;
|
||||||
use style::selector_impl::{PseudoElement, ElementSnapshot};
|
use style::selector_impl::{PseudoElement, ElementSnapshot};
|
||||||
|
@ -172,6 +173,13 @@ impl<T: JSTraceable> JSTraceable for UnsafeCell<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T: JSTraceable> JSTraceable for DOMRefCell<T> {
|
||||||
|
fn trace(&self, trc: *mut JSTracer) {
|
||||||
|
unsafe {
|
||||||
|
(*self).borrow_for_gc_trace().trace(trc)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl JSTraceable for Heap<*mut JSObject> {
|
impl JSTraceable for Heap<*mut JSObject> {
|
||||||
fn trace(&self, trc: *mut JSTracer) {
|
fn trace(&self, trc: *mut JSTracer) {
|
||||||
|
|
|
@ -19,7 +19,7 @@ use dom::element::Element;
|
||||||
use dom::node::{Node, NodeDamage};
|
use dom::node::{Node, NodeDamage};
|
||||||
use dom::processinginstruction::ProcessingInstruction;
|
use dom::processinginstruction::ProcessingInstruction;
|
||||||
use dom::text::Text;
|
use dom::text::Text;
|
||||||
use std::cell::Ref;
|
use style::refcell::Ref;
|
||||||
use util::opts;
|
use util::opts;
|
||||||
|
|
||||||
// https://dom.spec.whatwg.org/#characterdata
|
// https://dom.spec.whatwg.org/#characterdata
|
||||||
|
|
|
@ -14,12 +14,13 @@ use dom::element::Element;
|
||||||
use dom::node::{Node, NodeDamage, window_from_node};
|
use dom::node::{Node, NodeDamage, window_from_node};
|
||||||
use dom::window::Window;
|
use dom::window::Window;
|
||||||
use std::ascii::AsciiExt;
|
use std::ascii::AsciiExt;
|
||||||
use std::cell::Ref;
|
|
||||||
use std::slice;
|
use std::slice;
|
||||||
|
use std::sync::Arc;
|
||||||
use string_cache::Atom;
|
use string_cache::Atom;
|
||||||
use style::parser::ParserContextExtraData;
|
use style::parser::ParserContextExtraData;
|
||||||
use style::properties::{PropertyDeclaration, Shorthand, Importance};
|
use style::properties::{PropertyDeclaration, Shorthand, Importance};
|
||||||
use style::properties::{is_supported_property, parse_one_declaration, parse_style_attribute};
|
use style::properties::{is_supported_property, parse_one_declaration, parse_style_attribute};
|
||||||
|
use style::refcell::Ref;
|
||||||
use style::selector_impl::PseudoElement;
|
use style::selector_impl::PseudoElement;
|
||||||
|
|
||||||
// http://dev.w3.org/csswg/cssom/#the-cssstyledeclaration-interface
|
// http://dev.w3.org/csswg/cssom/#the-cssstyledeclaration-interface
|
||||||
|
@ -365,7 +366,7 @@ impl CSSStyleDeclarationMethods for CSSStyleDeclaration {
|
||||||
*element.style_attribute().borrow_mut() = if decl_block.declarations.is_empty() {
|
*element.style_attribute().borrow_mut() = if decl_block.declarations.is_empty() {
|
||||||
None // Step 2
|
None // Step 2
|
||||||
} else {
|
} else {
|
||||||
Some(decl_block)
|
Some(Arc::new(decl_block))
|
||||||
};
|
};
|
||||||
element.sync_property_with_attrs_style();
|
element.sync_property_with_attrs_style();
|
||||||
let node = element.upcast::<Node>();
|
let node = element.upcast::<Node>();
|
||||||
|
|
|
@ -111,7 +111,7 @@ use script_traits::{TouchEventType, TouchId};
|
||||||
use std::ascii::AsciiExt;
|
use std::ascii::AsciiExt;
|
||||||
use std::borrow::ToOwned;
|
use std::borrow::ToOwned;
|
||||||
use std::boxed::FnBox;
|
use std::boxed::FnBox;
|
||||||
use std::cell::{Cell, Ref, RefMut};
|
use std::cell::Cell;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::collections::hash_map::Entry::{Occupied, Vacant};
|
use std::collections::hash_map::Entry::{Occupied, Vacant};
|
||||||
use std::default::Default;
|
use std::default::Default;
|
||||||
|
@ -122,6 +122,7 @@ use std::sync::Arc;
|
||||||
use string_cache::{Atom, QualName};
|
use string_cache::{Atom, QualName};
|
||||||
use style::attr::AttrValue;
|
use style::attr::AttrValue;
|
||||||
use style::context::ReflowGoal;
|
use style::context::ReflowGoal;
|
||||||
|
use style::refcell::{Ref, RefMut};
|
||||||
use style::selector_impl::ElementSnapshot;
|
use style::selector_impl::ElementSnapshot;
|
||||||
use style::str::{split_html_space_chars, str_join};
|
use style::str::{split_html_space_chars, str_join};
|
||||||
use style::stylesheets::Stylesheet;
|
use style::stylesheets::Stylesheet;
|
||||||
|
|
|
@ -70,13 +70,12 @@ use html5ever::serialize::SerializeOpts;
|
||||||
use html5ever::serialize::TraversalScope;
|
use html5ever::serialize::TraversalScope;
|
||||||
use html5ever::serialize::TraversalScope::{ChildrenOnly, IncludeNode};
|
use html5ever::serialize::TraversalScope::{ChildrenOnly, IncludeNode};
|
||||||
use html5ever::tree_builder::{LimitedQuirks, NoQuirks, Quirks};
|
use html5ever::tree_builder::{LimitedQuirks, NoQuirks, Quirks};
|
||||||
use ref_filter_map::ref_filter_map;
|
|
||||||
use selectors::matching::{ElementFlags, matches};
|
use selectors::matching::{ElementFlags, matches};
|
||||||
use selectors::matching::{HAS_SLOW_SELECTOR, HAS_EDGE_CHILD_SELECTOR, HAS_SLOW_SELECTOR_LATER_SIBLINGS};
|
use selectors::matching::{HAS_SLOW_SELECTOR, HAS_EDGE_CHILD_SELECTOR, HAS_SLOW_SELECTOR_LATER_SIBLINGS};
|
||||||
use selectors::parser::{AttrSelector, NamespaceConstraint, parse_author_origin_selector_list_from_str};
|
use selectors::parser::{AttrSelector, NamespaceConstraint, parse_author_origin_selector_list_from_str};
|
||||||
use std::ascii::AsciiExt;
|
use std::ascii::AsciiExt;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::cell::{Cell, Ref};
|
use std::cell::Cell;
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
use std::default::Default;
|
use std::default::Default;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
@ -90,6 +89,7 @@ use style::parser::ParserContextExtraData;
|
||||||
use style::properties::longhands::{self, background_image, border_spacing, font_family, overflow_x, font_size};
|
use style::properties::longhands::{self, background_image, border_spacing, font_family, overflow_x, font_size};
|
||||||
use style::properties::{DeclaredValue, Importance};
|
use style::properties::{DeclaredValue, Importance};
|
||||||
use style::properties::{PropertyDeclaration, PropertyDeclarationBlock, parse_style_attribute};
|
use style::properties::{PropertyDeclaration, PropertyDeclarationBlock, parse_style_attribute};
|
||||||
|
use style::refcell::Ref;
|
||||||
use style::selector_impl::{NonTSPseudoClass, ServoSelectorImpl};
|
use style::selector_impl::{NonTSPseudoClass, ServoSelectorImpl};
|
||||||
use style::selector_matching::DeclarationBlock;
|
use style::selector_matching::DeclarationBlock;
|
||||||
use style::sink::Push;
|
use style::sink::Push;
|
||||||
|
@ -109,7 +109,7 @@ pub struct Element {
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
attrs: DOMRefCell<Vec<JS<Attr>>>,
|
attrs: DOMRefCell<Vec<JS<Attr>>>,
|
||||||
id_attribute: DOMRefCell<Option<Atom>>,
|
id_attribute: DOMRefCell<Option<Atom>>,
|
||||||
style_attribute: DOMRefCell<Option<PropertyDeclarationBlock>>,
|
style_attribute: DOMRefCell<Option<Arc<PropertyDeclarationBlock>>>,
|
||||||
attr_list: MutNullableHeap<JS<NamedNodeMap>>,
|
attr_list: MutNullableHeap<JS<NamedNodeMap>>,
|
||||||
class_list: MutNullableHeap<JS<DOMTokenList>>,
|
class_list: MutNullableHeap<JS<DOMTokenList>>,
|
||||||
state: Cell<ElementState>,
|
state: Cell<ElementState>,
|
||||||
|
@ -297,7 +297,7 @@ pub trait LayoutElementHelpers {
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
unsafe fn html_element_in_html_document_for_layout(&self) -> bool;
|
unsafe fn html_element_in_html_document_for_layout(&self) -> bool;
|
||||||
fn id_attribute(&self) -> *const Option<Atom>;
|
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 local_name(&self) -> &Atom;
|
||||||
fn namespace(&self) -> &Namespace;
|
fn namespace(&self) -> &Namespace;
|
||||||
fn get_checked_state_for_layout(&self) -> bool;
|
fn get_checked_state_for_layout(&self) -> bool;
|
||||||
|
@ -329,7 +329,10 @@ impl LayoutElementHelpers for LayoutJS<Element> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_declaration(rule: PropertyDeclaration) -> DeclarationBlock {
|
fn from_declaration(rule: PropertyDeclaration) -> DeclarationBlock {
|
||||||
DeclarationBlock::from_declarations(
|
DeclarationBlock::from_declarations(
|
||||||
Arc::new(vec![(rule, Importance::Normal)]),
|
Arc::new(PropertyDeclarationBlock {
|
||||||
|
declarations: vec![(rule, Importance::Normal)],
|
||||||
|
important_count: 0,
|
||||||
|
}),
|
||||||
Importance::Normal)
|
Importance::Normal)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -615,7 +618,7 @@ impl LayoutElementHelpers for LayoutJS<Element> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
fn style_attribute(&self) -> *const Option<PropertyDeclarationBlock> {
|
fn style_attribute(&self) -> *const Option<Arc<PropertyDeclarationBlock>> {
|
||||||
unsafe {
|
unsafe {
|
||||||
(*self.unsafe_get()).style_attribute.borrow_for_layout()
|
(*self.unsafe_get()).style_attribute.borrow_for_layout()
|
||||||
}
|
}
|
||||||
|
@ -704,7 +707,7 @@ impl Element {
|
||||||
self.attrs.borrow()
|
self.attrs.borrow()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn style_attribute(&self) -> &DOMRefCell<Option<PropertyDeclarationBlock>> {
|
pub fn style_attribute(&self) -> &DOMRefCell<Option<Arc<PropertyDeclarationBlock>>> {
|
||||||
&self.style_attribute
|
&self.style_attribute
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -774,7 +777,8 @@ impl Element {
|
||||||
matching
|
matching
|
||||||
});
|
});
|
||||||
if let Some(index) = index {
|
if let Some(index) = index {
|
||||||
Arc::make_mut(&mut declarations.declarations).remove(index);
|
let declarations = Arc::make_mut(declarations);
|
||||||
|
declarations.declarations.remove(index);
|
||||||
if importance.unwrap().important() {
|
if importance.unwrap().important() {
|
||||||
declarations.important_count -= 1;
|
declarations.important_count -= 1;
|
||||||
}
|
}
|
||||||
|
@ -796,7 +800,8 @@ impl Element {
|
||||||
{
|
{
|
||||||
// Usually, the reference count will be 1 here. But transitions could make it greater
|
// Usually, the reference count will be 1 here. But transitions could make it greater
|
||||||
// than that.
|
// than that.
|
||||||
let existing_declarations = Arc::make_mut(&mut declaration_block.declarations);
|
let declaration_block = Arc::make_mut(declaration_block);
|
||||||
|
let existing_declarations = &mut declaration_block.declarations;
|
||||||
|
|
||||||
'outer: for incoming_declaration in declarations {
|
'outer: for incoming_declaration in declarations {
|
||||||
for existing_declaration in &mut *existing_declarations {
|
for existing_declaration in &mut *existing_declarations {
|
||||||
|
@ -829,10 +834,10 @@ impl Element {
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
|
||||||
*inline_declarations = Some(PropertyDeclarationBlock {
|
*inline_declarations = Some(Arc::new(PropertyDeclarationBlock {
|
||||||
declarations: Arc::new(declarations.into_iter().map(|d| (d, importance)).collect()),
|
declarations: declarations.into_iter().map(|d| (d, importance)).collect(),
|
||||||
important_count: important_count,
|
important_count: important_count,
|
||||||
});
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
update(self, declarations, importance);
|
update(self, declarations, importance);
|
||||||
|
@ -847,7 +852,8 @@ impl Element {
|
||||||
if let &mut Some(ref mut block) = &mut *inline_declarations {
|
if let &mut Some(ref mut block) = &mut *inline_declarations {
|
||||||
// Usually, the reference counts of `from` and `to` will be 1 here. But transitions
|
// Usually, the reference counts of `from` and `to` will be 1 here. But transitions
|
||||||
// could make them greater than that.
|
// could make them greater than that.
|
||||||
let declarations = Arc::make_mut(&mut block.declarations);
|
let block = Arc::make_mut(block);
|
||||||
|
let declarations = &mut block.declarations;
|
||||||
for &mut (ref declaration, ref mut importance) in declarations {
|
for &mut (ref declaration, ref mut importance) in declarations {
|
||||||
if properties.iter().any(|p| declaration.name() == **p) {
|
if properties.iter().any(|p| declaration.name() == **p) {
|
||||||
match (*importance, new_importance) {
|
match (*importance, new_importance) {
|
||||||
|
@ -871,7 +877,7 @@ impl Element {
|
||||||
pub fn get_inline_style_declaration(&self,
|
pub fn get_inline_style_declaration(&self,
|
||||||
property: &Atom)
|
property: &Atom)
|
||||||
-> Option<Ref<(PropertyDeclaration, Importance)>> {
|
-> Option<Ref<(PropertyDeclaration, Importance)>> {
|
||||||
ref_filter_map(self.style_attribute.borrow(), |inline_declarations| {
|
Ref::filter_map(self.style_attribute.borrow(), |inline_declarations| {
|
||||||
inline_declarations.as_ref().and_then(|declarations| {
|
inline_declarations.as_ref().and_then(|declarations| {
|
||||||
declarations.declarations
|
declarations.declarations
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -2102,8 +2108,11 @@ impl VirtualMethods for Element {
|
||||||
*self.style_attribute.borrow_mut() =
|
*self.style_attribute.borrow_mut() =
|
||||||
mutation.new_value(attr).map(|value| {
|
mutation.new_value(attr).map(|value| {
|
||||||
let win = window_from_node(self);
|
let win = window_from_node(self);
|
||||||
parse_style_attribute(&value, &doc.base_url(), win.css_error_reporter(),
|
Arc::new(parse_style_attribute(
|
||||||
ParserContextExtraData::default())
|
&value,
|
||||||
|
&doc.base_url(),
|
||||||
|
win.css_error_reporter(),
|
||||||
|
ParserContextExtraData::default()))
|
||||||
});
|
});
|
||||||
if node.is_in_doc() {
|
if node.is_in_doc() {
|
||||||
node.dirty(NodeDamage::NodeStyleDamaged);
|
node.dirty(NodeDamage::NodeStyleDamaged);
|
||||||
|
|
|
@ -79,7 +79,7 @@ impl HTMLMetaElement {
|
||||||
if !content.is_empty() {
|
if !content.is_empty() {
|
||||||
if let Some(translated_rule) = ViewportRule::from_meta(&**content) {
|
if let Some(translated_rule) = ViewportRule::from_meta(&**content) {
|
||||||
*self.stylesheet.borrow_mut() = Some(Arc::new(Stylesheet {
|
*self.stylesheet.borrow_mut() = Some(Arc::new(Stylesheet {
|
||||||
rules: vec![CSSRule::Viewport(translated_rule)],
|
rules: vec![CSSRule::Viewport(Arc::new(translated_rule))],
|
||||||
origin: Origin::Author,
|
origin: Origin::Author,
|
||||||
media: None,
|
media: None,
|
||||||
// Viewport constraints are always recomputed on resize; they don't need to
|
// Viewport constraints are always recomputed on resize; they don't need to
|
||||||
|
|
|
@ -459,9 +459,9 @@ impl<'le> TElement for ServoLayoutElement<'le> {
|
||||||
ServoLayoutNode::from_layout_js(self.element.upcast())
|
ServoLayoutNode::from_layout_js(self.element.upcast())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn style_attribute(&self) -> &Option<PropertyDeclarationBlock> {
|
fn style_attribute(&self) -> Option<&Arc<PropertyDeclarationBlock>> {
|
||||||
unsafe {
|
unsafe {
|
||||||
&*self.element.style_attribute()
|
(*self.element.style_attribute()).as_ref()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
#![feature(slice_patterns)]
|
#![feature(slice_patterns)]
|
||||||
#![feature(stmt_expr_attributes)]
|
#![feature(stmt_expr_attributes)]
|
||||||
#![feature(question_mark)]
|
#![feature(question_mark)]
|
||||||
#![feature(try_borrow)]
|
|
||||||
#![feature(try_from)]
|
#![feature(try_from)]
|
||||||
|
|
||||||
#![deny(unsafe_code)]
|
#![deny(unsafe_code)]
|
||||||
|
@ -69,7 +68,6 @@ extern crate phf;
|
||||||
extern crate profile_traits;
|
extern crate profile_traits;
|
||||||
extern crate rand;
|
extern crate rand;
|
||||||
extern crate range;
|
extern crate range;
|
||||||
extern crate ref_filter_map;
|
|
||||||
extern crate ref_slice;
|
extern crate ref_slice;
|
||||||
extern crate regex;
|
extern crate regex;
|
||||||
extern crate rustc_serialize;
|
extern crate rustc_serialize;
|
||||||
|
|
7
components/servo/Cargo.lock
generated
7
components/servo/Cargo.lock
generated
|
@ -1839,11 +1839,6 @@ dependencies = [
|
||||||
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "ref_filter_map"
|
|
||||||
version = "1.0.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ref_slice"
|
name = "ref_slice"
|
||||||
version = "1.0.0"
|
version = "1.0.0"
|
||||||
|
@ -1929,7 +1924,6 @@ dependencies = [
|
||||||
"profile_traits 0.0.1",
|
"profile_traits 0.0.1",
|
||||||
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"range 0.0.1",
|
"range 0.0.1",
|
||||||
"ref_filter_map 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"ref_slice 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ref_slice 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"regex 0.1.73 (registry+https://github.com/rust-lang/crates.io-index)",
|
"regex 0.1.73 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -2866,7 +2860,6 @@ dependencies = [
|
||||||
"checksum quickersort 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e952ea7699262481636004bc4ab8afaccf2bc13f91b79d1aee6617bd8fc39651"
|
"checksum quickersort 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e952ea7699262481636004bc4ab8afaccf2bc13f91b79d1aee6617bd8fc39651"
|
||||||
"checksum rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "2791d88c6defac799c3f20d74f094ca33b9332612d9aef9078519c82e4fe04a5"
|
"checksum rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "2791d88c6defac799c3f20d74f094ca33b9332612d9aef9078519c82e4fe04a5"
|
||||||
"checksum rayon 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8e501871917624668fe601ad12a730450414f9b0b64722a898b040ce3ae1b0fa"
|
"checksum rayon 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8e501871917624668fe601ad12a730450414f9b0b64722a898b040ce3ae1b0fa"
|
||||||
"checksum ref_filter_map 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2b5ceb840e4009da4841ed22a15eb49f64fdd00a2138945c5beacf506b2fb5ed"
|
|
||||||
"checksum ref_slice 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "24c91f8f8903c37f0525112df98ef53b1985abca5702972e5e00854cd874baf2"
|
"checksum ref_slice 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "24c91f8f8903c37f0525112df98ef53b1985abca5702972e5e00854cd874baf2"
|
||||||
"checksum regex 0.1.73 (registry+https://github.com/rust-lang/crates.io-index)" = "56b7ee9f764ecf412c6e2fff779bca4b22980517ae335a21aeaf4e32625a5df2"
|
"checksum regex 0.1.73 (registry+https://github.com/rust-lang/crates.io-index)" = "56b7ee9f764ecf412c6e2fff779bca4b22980517ae335a21aeaf4e32625a5df2"
|
||||||
"checksum regex-syntax 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "31040aad7470ad9d8c46302dcffba337bb4289ca5da2e3cd6e37b64109a85199"
|
"checksum regex-syntax 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "31040aad7470ad9d8c46302dcffba337bb4289ca5da2e3cd6e37b64109a85199"
|
||||||
|
|
|
@ -195,7 +195,7 @@ pub trait TElement : PartialEq + Debug + Sized + Copy + Clone + ElementExt + Pre
|
||||||
|
|
||||||
fn as_node(&self) -> Self::ConcreteNode;
|
fn as_node(&self) -> Self::ConcreteNode;
|
||||||
|
|
||||||
fn style_attribute(&self) -> &Option<PropertyDeclarationBlock>;
|
fn style_attribute(&self) -> Option<&Arc<PropertyDeclarationBlock>>;
|
||||||
|
|
||||||
fn get_state(&self) -> ElementState;
|
fn get_state(&self) -> ElementState;
|
||||||
|
|
||||||
|
|
|
@ -4,17 +4,15 @@
|
||||||
|
|
||||||
//! A shareable mutable container for the DOM.
|
//! A shareable mutable container for the DOM.
|
||||||
|
|
||||||
use dom::bindings::trace::JSTraceable;
|
use refcell::{BorrowError, BorrowMutError, Ref, RefCell, RefMut};
|
||||||
use js::jsapi::JSTracer;
|
use thread_state;
|
||||||
use std::cell::{BorrowError, BorrowMutError, Ref, RefCell, RefMut};
|
|
||||||
use style::thread_state;
|
|
||||||
use style::thread_state::SCRIPT;
|
|
||||||
|
|
||||||
/// A mutable field in the DOM.
|
/// A mutable field in the DOM.
|
||||||
///
|
///
|
||||||
/// This extends the API of `core::cell::RefCell` to allow unsafe access in
|
/// This extends the API of `core::cell::RefCell` to allow unsafe access in
|
||||||
/// certain situations, with dynamic checking in debug builds.
|
/// certain situations, with dynamic checking in debug builds.
|
||||||
#[derive(Clone, HeapSizeOf)]
|
#[derive(Clone)]
|
||||||
|
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||||
pub struct DOMRefCell<T> {
|
pub struct DOMRefCell<T> {
|
||||||
value: RefCell<T>,
|
value: RefCell<T>,
|
||||||
}
|
}
|
||||||
|
@ -48,7 +46,7 @@ impl<T> DOMRefCell<T> {
|
||||||
///
|
///
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
pub unsafe fn borrow_for_script_deallocation(&self) -> &mut T {
|
pub unsafe fn borrow_for_script_deallocation(&self) -> &mut T {
|
||||||
debug_assert!(thread_state::get().contains(SCRIPT));
|
debug_assert!(thread_state::get().contains(thread_state::SCRIPT));
|
||||||
&mut *self.value.as_ptr()
|
&mut *self.value.as_ptr()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,14 +58,6 @@ impl<T> DOMRefCell<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: JSTraceable> JSTraceable for DOMRefCell<T> {
|
|
||||||
fn trace(&self, trc: *mut JSTracer) {
|
|
||||||
unsafe {
|
|
||||||
(*self).borrow_for_gc_trace().trace(trc)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Functionality duplicated with `core::cell::RefCell`
|
// Functionality duplicated with `core::cell::RefCell`
|
||||||
// ===================================================
|
// ===================================================
|
||||||
impl<T> DOMRefCell<T> {
|
impl<T> DOMRefCell<T> {
|
|
@ -7,7 +7,7 @@ use cssparser::{DeclarationListParser, DeclarationParser};
|
||||||
use parser::{ParserContext, log_css_error};
|
use parser::{ParserContext, log_css_error};
|
||||||
use properties::PropertyDeclarationParseResult;
|
use properties::PropertyDeclarationParseResult;
|
||||||
use properties::animated_properties::TransitionProperty;
|
use properties::animated_properties::TransitionProperty;
|
||||||
use properties::{PropertyDeclaration, Importance};
|
use properties::{PropertyDeclaration, PropertyDeclarationBlock, Importance};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
/// A number from 1 to 100, indicating the percentage of the animation where
|
/// 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`.
|
/// so the second value of these tuples is always `Importance::Normal`.
|
||||||
/// But including them enables `compute_style_for_animation_step` to create a `DeclarationBlock`
|
/// 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<_>`.
|
/// 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
|
/// 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))]
|
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||||
pub enum KeyframesStepValue {
|
pub enum KeyframesStepValue {
|
||||||
/// See `Keyframe::declarations`’s docs about the presence of `Importance`.
|
/// See `Keyframe::declarations`’s docs about the presence of `Importance`.
|
||||||
Declarations(Arc<Vec<(PropertyDeclaration, Importance)>>),
|
Declarations(Arc<PropertyDeclarationBlock>),
|
||||||
ComputedValues,
|
ComputedValues,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,8 +113,8 @@ impl KeyframesStep {
|
||||||
fn new(percentage: KeyframePercentage,
|
fn new(percentage: KeyframePercentage,
|
||||||
value: KeyframesStepValue) -> Self {
|
value: KeyframesStepValue) -> Self {
|
||||||
let declared_timing_function = match value {
|
let declared_timing_function = match value {
|
||||||
KeyframesStepValue::Declarations(ref declarations) => {
|
KeyframesStepValue::Declarations(ref block) => {
|
||||||
declarations.iter().any(|&(ref prop_decl, _)| {
|
block.declarations.iter().any(|&(ref prop_decl, _)| {
|
||||||
match *prop_decl {
|
match *prop_decl {
|
||||||
PropertyDeclaration::AnimationTimingFunction(..) => true,
|
PropertyDeclaration::AnimationTimingFunction(..) => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
|
@ -154,7 +154,7 @@ fn get_animated_properties(keyframe: &Keyframe) -> Vec<TransitionProperty> {
|
||||||
let mut ret = vec![];
|
let mut ret = vec![];
|
||||||
// NB: declarations are already deduplicated, so we don't have to check for
|
// NB: declarations are already deduplicated, so we don't have to check for
|
||||||
// it here.
|
// 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) {
|
if let Some(property) = TransitionProperty::from_declaration(declaration) {
|
||||||
ret.push(property);
|
ret.push(property);
|
||||||
}
|
}
|
||||||
|
@ -164,7 +164,7 @@ fn get_animated_properties(keyframe: &Keyframe) -> Vec<TransitionProperty> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl KeyframesAnimation {
|
impl KeyframesAnimation {
|
||||||
pub fn from_keyframes(keyframes: &[Keyframe]) -> Option<Self> {
|
pub fn from_keyframes(keyframes: &[Arc<Keyframe>]) -> Option<Self> {
|
||||||
if keyframes.is_empty() {
|
if keyframes.is_empty() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
@ -179,7 +179,7 @@ impl KeyframesAnimation {
|
||||||
for keyframe in keyframes {
|
for keyframe in keyframes {
|
||||||
for percentage in keyframe.selector.0.iter() {
|
for percentage in keyframe.selector.0.iter() {
|
||||||
steps.push(KeyframesStep::new(*percentage,
|
steps.push(KeyframesStep::new(*percentage,
|
||||||
KeyframesStepValue::Declarations(keyframe.declarations.clone())));
|
KeyframesStepValue::Declarations(keyframe.block.clone())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -216,7 +216,7 @@ struct KeyframeListParser<'a> {
|
||||||
context: &'a ParserContext<'a>,
|
context: &'a ParserContext<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_keyframe_list(context: &ParserContext, input: &mut Parser) -> Vec<Keyframe> {
|
pub fn parse_keyframe_list(context: &ParserContext, input: &mut Parser) -> Vec<Arc<Keyframe>> {
|
||||||
RuleListParser::new_for_nested_rule(input, KeyframeListParser { context: context })
|
RuleListParser::new_for_nested_rule(input, KeyframeListParser { context: context })
|
||||||
.filter_map(Result::ok)
|
.filter_map(Result::ok)
|
||||||
.collect()
|
.collect()
|
||||||
|
@ -225,12 +225,12 @@ pub fn parse_keyframe_list(context: &ParserContext, input: &mut Parser) -> Vec<K
|
||||||
enum Void {}
|
enum Void {}
|
||||||
impl<'a> AtRuleParser for KeyframeListParser<'a> {
|
impl<'a> AtRuleParser for KeyframeListParser<'a> {
|
||||||
type Prelude = Void;
|
type Prelude = Void;
|
||||||
type AtRule = Keyframe;
|
type AtRule = Arc<Keyframe>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> QualifiedRuleParser for KeyframeListParser<'a> {
|
impl<'a> QualifiedRuleParser for KeyframeListParser<'a> {
|
||||||
type Prelude = KeyframeSelector;
|
type Prelude = KeyframeSelector;
|
||||||
type QualifiedRule = Keyframe;
|
type QualifiedRule = Arc<Keyframe>;
|
||||||
|
|
||||||
fn parse_prelude(&self, input: &mut Parser) -> Result<Self::Prelude, ()> {
|
fn parse_prelude(&self, input: &mut Parser) -> Result<Self::Prelude, ()> {
|
||||||
let start = input.position();
|
let start = input.position();
|
||||||
|
@ -263,10 +263,13 @@ impl<'a> QualifiedRuleParser for KeyframeListParser<'a> {
|
||||||
}
|
}
|
||||||
// `parse_important` is not called here, `!important` is not allowed in keyframe blocks.
|
// `parse_important` is not called here, `!important` is not allowed in keyframe blocks.
|
||||||
}
|
}
|
||||||
Ok(Keyframe {
|
Ok(Arc::new(Keyframe {
|
||||||
selector: prelude,
|
selector: prelude,
|
||||||
declarations: Arc::new(declarations),
|
block: Arc::new(PropertyDeclarationBlock {
|
||||||
})
|
declarations: declarations,
|
||||||
|
important_count: 0,
|
||||||
|
}),
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -81,6 +81,7 @@ pub mod context;
|
||||||
pub mod custom_properties;
|
pub mod custom_properties;
|
||||||
pub mod data;
|
pub mod data;
|
||||||
pub mod dom;
|
pub mod dom;
|
||||||
|
pub mod domrefcell;
|
||||||
pub mod element_state;
|
pub mod element_state;
|
||||||
pub mod error_reporting;
|
pub mod error_reporting;
|
||||||
pub mod font_face;
|
pub mod font_face;
|
||||||
|
|
|
@ -14,7 +14,7 @@ use context::{StyleContext, SharedStyleContext};
|
||||||
use data::PrivateStyleData;
|
use data::PrivateStyleData;
|
||||||
use dom::{TElement, TNode, TRestyleDamage, UnsafeNode};
|
use dom::{TElement, TNode, TRestyleDamage, UnsafeNode};
|
||||||
use properties::longhands::display::computed_value as display;
|
use properties::longhands::display::computed_value as display;
|
||||||
use properties::{ComputedValues, cascade};
|
use properties::{ComputedValues, cascade, PropertyDeclarationBlock};
|
||||||
use selector_impl::{TheSelectorImpl, PseudoElement};
|
use selector_impl::{TheSelectorImpl, PseudoElement};
|
||||||
use selector_matching::{DeclarationBlock, Stylist};
|
use selector_matching::{DeclarationBlock, Stylist};
|
||||||
use selectors::bloom::BloomFilter;
|
use selectors::bloom::BloomFilter;
|
||||||
|
@ -139,7 +139,7 @@ impl<'a> Hash for ApplicableDeclarationsCacheQuery<'a> {
|
||||||
for declaration in self.declarations {
|
for declaration in self.declarations {
|
||||||
// Each declaration contians an Arc, which is a stable
|
// Each declaration contians an Arc, which is a stable
|
||||||
// pointer; we use that for hashing and equality.
|
// 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);
|
ptr.hash(state);
|
||||||
declaration.importance.hash(state);
|
declaration.importance.hash(state);
|
||||||
}
|
}
|
||||||
|
@ -651,7 +651,7 @@ pub trait ElementMatchMethods : TElement {
|
||||||
applicable_declarations: &mut ApplicableDeclarations)
|
applicable_declarations: &mut ApplicableDeclarations)
|
||||||
-> StyleRelations {
|
-> StyleRelations {
|
||||||
use traversal::relations_are_shareable;
|
use traversal::relations_are_shareable;
|
||||||
let style_attribute = self.style_attribute().as_ref();
|
let style_attribute = self.style_attribute();
|
||||||
|
|
||||||
let mut relations =
|
let mut relations =
|
||||||
stylist.push_applicable_declarations(self,
|
stylist.push_applicable_declarations(self,
|
||||||
|
|
|
@ -282,16 +282,36 @@ impl Importance {
|
||||||
|
|
||||||
/// Overridden declarations are skipped.
|
/// Overridden declarations are skipped.
|
||||||
// FIXME (https://github.com/servo/servo/issues/3426)
|
// FIXME (https://github.com/servo/servo/issues/3426)
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||||
pub struct PropertyDeclarationBlock {
|
pub struct PropertyDeclarationBlock {
|
||||||
#[cfg_attr(feature = "servo", ignore_heap_size_of = "#7038")]
|
#[cfg_attr(feature = "servo", ignore_heap_size_of = "#7038")]
|
||||||
pub declarations: Arc<Vec<(PropertyDeclaration, Importance)>>,
|
pub declarations: Vec<(PropertyDeclaration, Importance)>,
|
||||||
|
|
||||||
/// The number of entries in `self.declaration` with `Importance::Important`
|
/// The number of entries in `self.declaration` with `Importance::Important`
|
||||||
pub important_count: u32,
|
pub important_count: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl PropertyDeclarationBlock {
|
||||||
|
/// Returns wheather this block contains any declaration with `!important`.
|
||||||
|
///
|
||||||
|
/// This is based on the `important_count` counter,
|
||||||
|
/// which should be maintained whenever `declarations` is changed.
|
||||||
|
// FIXME: make fields private and maintain it here in methods?
|
||||||
|
pub fn any_important(&self) -> bool {
|
||||||
|
self.important_count > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns wheather this block contains any declaration without `!important`.
|
||||||
|
///
|
||||||
|
/// This is based on the `important_count` counter,
|
||||||
|
/// which should be maintained whenever `declarations` is changed.
|
||||||
|
// FIXME: make fields private and maintain it here in methods?
|
||||||
|
pub fn any_normal(&self) -> bool {
|
||||||
|
self.declarations.len() > self.important_count as usize
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl ToCss for PropertyDeclarationBlock {
|
impl ToCss for PropertyDeclarationBlock {
|
||||||
// https://drafts.csswg.org/cssom/#serialize-a-css-declaration-block
|
// https://drafts.csswg.org/cssom/#serialize-a-css-declaration-block
|
||||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
||||||
|
@ -567,7 +587,7 @@ pub fn parse_property_declaration_list(context: &ParserContext, input: &mut Pars
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let mut block = PropertyDeclarationBlock {
|
let mut block = PropertyDeclarationBlock {
|
||||||
declarations: Arc::new(declarations),
|
declarations: declarations,
|
||||||
important_count: important_count,
|
important_count: important_count,
|
||||||
};
|
};
|
||||||
deduplicate_property_declarations(&mut block);
|
deduplicate_property_declarations(&mut block);
|
||||||
|
@ -583,8 +603,7 @@ fn deduplicate_property_declarations(block: &mut PropertyDeclarationBlock) {
|
||||||
let mut seen_custom_normal = Vec::new();
|
let mut seen_custom_normal = Vec::new();
|
||||||
let mut seen_custom_important = Vec::new();
|
let mut seen_custom_important = Vec::new();
|
||||||
|
|
||||||
let declarations = Arc::get_mut(&mut block.declarations).unwrap();
|
for (declaration, importance) in block.declarations.drain(..).rev() {
|
||||||
for (declaration, importance) in declarations.drain(..).rev() {
|
|
||||||
match declaration {
|
match declaration {
|
||||||
% for property in data.longhands:
|
% for property in data.longhands:
|
||||||
PropertyDeclaration::${property.camel_case}(..) => {
|
PropertyDeclaration::${property.camel_case}(..) => {
|
||||||
|
@ -636,7 +655,7 @@ fn deduplicate_property_declarations(block: &mut PropertyDeclarationBlock) {
|
||||||
deduplicated.push((declaration, importance))
|
deduplicated.push((declaration, importance))
|
||||||
}
|
}
|
||||||
deduplicated.reverse();
|
deduplicated.reverse();
|
||||||
*declarations = deduplicated;
|
block.declarations = deduplicated;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
|
@ -15,8 +15,11 @@
|
||||||
|
|
||||||
#![allow(unsafe_code)]
|
#![allow(unsafe_code)]
|
||||||
|
|
||||||
|
#[cfg(feature = "servo")] use heapsize::HeapSizeOf;
|
||||||
use std::cell::{UnsafeCell, Cell};
|
use std::cell::{UnsafeCell, Cell};
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
|
use std::fmt::{self, Debug, Display};
|
||||||
|
use std::marker::PhantomData;
|
||||||
use std::ops::{Deref, DerefMut};
|
use std::ops::{Deref, DerefMut};
|
||||||
|
|
||||||
/// A fork of std::cell::RefCell that makes `as_unsafe_cell` usable on stable Rust.
|
/// A fork of std::cell::RefCell that makes `as_unsafe_cell` usable on stable Rust.
|
||||||
|
@ -28,7 +31,13 @@ pub struct RefCell<T: ?Sized> {
|
||||||
borrow: Cell<BorrowFlag>,
|
borrow: Cell<BorrowFlag>,
|
||||||
value: UnsafeCell<T>,
|
value: UnsafeCell<T>,
|
||||||
}
|
}
|
||||||
type BorrowFlag = usize;
|
|
||||||
|
#[cfg(feature = "servo")]
|
||||||
|
impl<T: HeapSizeOf> HeapSizeOf for RefCell<T> {
|
||||||
|
fn heap_size_of_children(&self) -> usize {
|
||||||
|
self.borrow().heap_size_of_children()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// An enumeration of values returned from the `state` method on a `RefCell<T>`.
|
/// An enumeration of values returned from the `state` method on a `RefCell<T>`.
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
||||||
|
@ -41,8 +50,43 @@ pub enum BorrowState {
|
||||||
Unused,
|
Unused,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// An error returned by [`RefCell::try_borrow`](struct.RefCell.html#method.try_borrow).
|
||||||
|
pub struct BorrowError<'a, T: 'a + ?Sized> {
|
||||||
|
marker: PhantomData<&'a RefCell<T>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, T: ?Sized> Debug for BorrowError<'a, T> {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
f.debug_struct("BorrowError").finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, T: ?Sized> Display for BorrowError<'a, T> {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
Display::fmt("already mutably borrowed", f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// An error returned by [`RefCell::try_borrow_mut`](struct.RefCell.html#method.try_borrow_mut).
|
||||||
|
pub struct BorrowMutError<'a, T: 'a + ?Sized> {
|
||||||
|
marker: PhantomData<&'a RefCell<T>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, T: ?Sized> Debug for BorrowMutError<'a, T> {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
f.debug_struct("BorrowMutError").finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, T: ?Sized> Display for BorrowMutError<'a, T> {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
Display::fmt("already borrowed", f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Values [1, MAX-1] represent the number of `Ref` active
|
// Values [1, MAX-1] represent the number of `Ref` active
|
||||||
// (will not outgrow its range since `usize` is the size of the address space)
|
// (will not outgrow its range since `usize` is the size of the address space)
|
||||||
|
type BorrowFlag = usize;
|
||||||
const UNUSED: BorrowFlag = 0;
|
const UNUSED: BorrowFlag = 0;
|
||||||
const WRITING: BorrowFlag = !0;
|
const WRITING: BorrowFlag = !0;
|
||||||
|
|
||||||
|
@ -90,6 +134,22 @@ impl<T: ?Sized> RefCell<T> {
|
||||||
///
|
///
|
||||||
/// The returned value can be dispatched on to determine if a call to
|
/// The returned value can be dispatched on to determine if a call to
|
||||||
/// `borrow` or `borrow_mut` would succeed.
|
/// `borrow` or `borrow_mut` would succeed.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// #![feature(borrow_state)]
|
||||||
|
///
|
||||||
|
/// use std::cell::{BorrowState, RefCell};
|
||||||
|
///
|
||||||
|
/// let c = RefCell::new(5);
|
||||||
|
///
|
||||||
|
/// match c.borrow_state() {
|
||||||
|
/// BorrowState::Writing => println!("Cannot be borrowed"),
|
||||||
|
/// BorrowState::Reading => println!("Cannot be borrowed mutably"),
|
||||||
|
/// BorrowState::Unused => println!("Can be borrowed (mutably as well)"),
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn borrow_state(&self) -> BorrowState {
|
pub fn borrow_state(&self) -> BorrowState {
|
||||||
match self.borrow.get() {
|
match self.borrow.get() {
|
||||||
|
@ -106,7 +166,8 @@ impl<T: ?Sized> RefCell<T> {
|
||||||
///
|
///
|
||||||
/// # Panics
|
/// # Panics
|
||||||
///
|
///
|
||||||
/// Panics if the value is currently mutably borrowed.
|
/// Panics if the value is currently mutably borrowed. For a non-panicking variant, use
|
||||||
|
/// [`try_borrow`](#method.try_borrow).
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
|
@ -136,12 +197,44 @@ impl<T: ?Sized> RefCell<T> {
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn borrow(&self) -> Ref<T> {
|
pub fn borrow(&self) -> Ref<T> {
|
||||||
|
self.try_borrow().expect("already mutably borrowed")
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Immutably borrows the wrapped value, returning an error if the value is currently mutably
|
||||||
|
/// borrowed.
|
||||||
|
///
|
||||||
|
/// The borrow lasts until the returned `Ref` exits scope. Multiple immutable borrows can be
|
||||||
|
/// taken out at the same time.
|
||||||
|
///
|
||||||
|
/// This is the non-panicking variant of [`borrow`](#method.borrow).
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// #![feature(try_borrow)]
|
||||||
|
///
|
||||||
|
/// use std::cell::RefCell;
|
||||||
|
///
|
||||||
|
/// let c = RefCell::new(5);
|
||||||
|
///
|
||||||
|
/// {
|
||||||
|
/// let m = c.borrow_mut();
|
||||||
|
/// assert!(c.try_borrow().is_err());
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// {
|
||||||
|
/// let m = c.borrow();
|
||||||
|
/// assert!(c.try_borrow().is_ok());
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
#[inline]
|
||||||
|
pub fn try_borrow(&self) -> Result<Ref<T>, BorrowError<T>> {
|
||||||
match BorrowRef::new(&self.borrow) {
|
match BorrowRef::new(&self.borrow) {
|
||||||
Some(b) => Ref {
|
Some(b) => Ok(Ref {
|
||||||
value: unsafe { &*self.value.get() },
|
value: unsafe { &*self.value.get() },
|
||||||
borrow: b,
|
borrow: b,
|
||||||
},
|
}),
|
||||||
None => panic!("RefCell<T> already mutably borrowed"),
|
None => Err(BorrowError { marker: PhantomData }),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,7 +245,8 @@ impl<T: ?Sized> RefCell<T> {
|
||||||
///
|
///
|
||||||
/// # Panics
|
/// # Panics
|
||||||
///
|
///
|
||||||
/// Panics if the value is currently borrowed.
|
/// Panics if the value is currently borrowed. For a non-panicking variant, use
|
||||||
|
/// [`try_borrow_mut`](#method.try_borrow_mut).
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
|
@ -183,12 +277,40 @@ impl<T: ?Sized> RefCell<T> {
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn borrow_mut(&self) -> RefMut<T> {
|
pub fn borrow_mut(&self) -> RefMut<T> {
|
||||||
|
self.try_borrow_mut().expect("already borrowed")
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Mutably borrows the wrapped value, returning an error if the value is currently borrowed.
|
||||||
|
///
|
||||||
|
/// The borrow lasts until the returned `RefMut` exits scope. The value cannot be borrowed
|
||||||
|
/// while this borrow is active.
|
||||||
|
///
|
||||||
|
/// This is the non-panicking variant of [`borrow_mut`](#method.borrow_mut).
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// #![feature(try_borrow)]
|
||||||
|
///
|
||||||
|
/// use std::cell::RefCell;
|
||||||
|
///
|
||||||
|
/// let c = RefCell::new(5);
|
||||||
|
///
|
||||||
|
/// {
|
||||||
|
/// let m = c.borrow();
|
||||||
|
/// assert!(c.try_borrow_mut().is_err());
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// assert!(c.try_borrow_mut().is_ok());
|
||||||
|
/// ```
|
||||||
|
#[inline]
|
||||||
|
pub fn try_borrow_mut(&self) -> Result<RefMut<T>, BorrowMutError<T>> {
|
||||||
match BorrowRefMut::new(&self.borrow) {
|
match BorrowRefMut::new(&self.borrow) {
|
||||||
Some(b) => RefMut {
|
Some(b) => Ok(RefMut {
|
||||||
value: unsafe { &mut *self.value.get() },
|
value: unsafe { &mut *self.value.get() },
|
||||||
borrow: b,
|
borrow: b,
|
||||||
},
|
}),
|
||||||
None => panic!("RefCell<T> already borrowed"),
|
None => Err(BorrowMutError { marker: PhantomData }),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -197,15 +319,53 @@ impl<T: ?Sized> RefCell<T> {
|
||||||
/// This can be used to circumvent `RefCell`'s safety checks.
|
/// This can be used to circumvent `RefCell`'s safety checks.
|
||||||
///
|
///
|
||||||
/// This function is `unsafe` because `UnsafeCell`'s field is public.
|
/// This function is `unsafe` because `UnsafeCell`'s field is public.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// #![feature(as_unsafe_cell)]
|
||||||
|
///
|
||||||
|
/// use std::cell::RefCell;
|
||||||
|
///
|
||||||
|
/// let c = RefCell::new(5);
|
||||||
|
/// let c = unsafe { c.as_unsafe_cell() };
|
||||||
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn as_unsafe_cell(&self) -> &UnsafeCell<T> {
|
pub unsafe fn as_unsafe_cell(&self) -> &UnsafeCell<T> {
|
||||||
&self.value
|
&self.value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns a raw pointer to the underlying data in this cell.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use std::cell::RefCell;
|
||||||
|
///
|
||||||
|
/// let c = RefCell::new(5);
|
||||||
|
///
|
||||||
|
/// let ptr = c.as_ptr();
|
||||||
|
/// ```
|
||||||
|
#[inline]
|
||||||
|
pub fn as_ptr(&self) -> *mut T {
|
||||||
|
self.value.get()
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns a mutable reference to the underlying data.
|
/// Returns a mutable reference to the underlying data.
|
||||||
///
|
///
|
||||||
/// This call borrows `RefCell` mutably (at compile-time) so there is no
|
/// This call borrows `RefCell` mutably (at compile-time) so there is no
|
||||||
/// need for dynamic checks.
|
/// need for dynamic checks.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use std::cell::RefCell;
|
||||||
|
///
|
||||||
|
/// let mut c = RefCell::new(5);
|
||||||
|
/// *c.get_mut() += 1;
|
||||||
|
///
|
||||||
|
/// assert_eq!(c, RefCell::new(6));
|
||||||
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_mut(&mut self) -> &mut T {
|
pub fn get_mut(&mut self) -> &mut T {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -375,6 +535,18 @@ impl<'b, T: ?Sized> Ref<'b, T> {
|
||||||
borrow: orig.borrow,
|
borrow: orig.borrow,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn filter_map<U: ?Sized, F>(orig: Ref<'b, T>, f: F) -> Option<Ref<'b, U>>
|
||||||
|
where F: FnOnce(&T) -> Option<&U>
|
||||||
|
{
|
||||||
|
f(orig.value).map(move |new_value| {
|
||||||
|
Ref {
|
||||||
|
value: new_value,
|
||||||
|
borrow: orig.borrow,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'b, T: ?Sized> RefMut<'b, T> {
|
impl<'b, T: ?Sized> RefMut<'b, T> {
|
||||||
|
@ -461,3 +633,35 @@ impl<'b, T: ?Sized> DerefMut for RefMut<'b, T> {
|
||||||
self.value
|
self.value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Imported from src/libcore/fmt/mod.rs
|
||||||
|
|
||||||
|
impl<T: ?Sized + Debug> Debug for RefCell<T> {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
match self.borrow_state() {
|
||||||
|
BorrowState::Unused | BorrowState::Reading => {
|
||||||
|
f.debug_struct("RefCell")
|
||||||
|
.field("value", &self.borrow())
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
BorrowState::Writing => {
|
||||||
|
f.debug_struct("RefCell")
|
||||||
|
.field("value", &"<borrowed>")
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'b, T: ?Sized + Debug> Debug for Ref<'b, T> {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
Debug::fmt(&**self, f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'b, T: ?Sized + Debug> Debug for RefMut<'b, T> {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
Debug::fmt(&*(self.deref()), f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -165,28 +165,26 @@ impl Stylist {
|
||||||
// Take apart the StyleRule into individual Rules and insert
|
// Take apart the StyleRule into individual Rules and insert
|
||||||
// them into the SelectorMap of that priority.
|
// them into the SelectorMap of that priority.
|
||||||
macro_rules! append(
|
macro_rules! append(
|
||||||
($style_rule: ident, $priority: ident, $importance: expr, $count: expr) => {
|
($style_rule: ident, $priority: ident, $importance: expr) => {
|
||||||
if $count > 0 {
|
for selector in &$style_rule.selectors {
|
||||||
for selector in &$style_rule.selectors {
|
let map = if let Some(ref pseudo) = selector.pseudo_element {
|
||||||
let map = if let Some(ref pseudo) = selector.pseudo_element {
|
self.pseudos_map
|
||||||
self.pseudos_map
|
.entry(pseudo.clone())
|
||||||
.entry(pseudo.clone())
|
.or_insert_with(PerPseudoElementSelectorMap::new)
|
||||||
.or_insert_with(PerPseudoElementSelectorMap::new)
|
.borrow_for_origin(&stylesheet.origin)
|
||||||
.borrow_for_origin(&stylesheet.origin)
|
} else {
|
||||||
} else {
|
self.element_map.borrow_for_origin(&stylesheet.origin)
|
||||||
self.element_map.borrow_for_origin(&stylesheet.origin)
|
};
|
||||||
};
|
|
||||||
|
|
||||||
map.$priority.insert(Rule {
|
map.$priority.insert(Rule {
|
||||||
selector: selector.complex_selector.clone(),
|
selector: selector.complex_selector.clone(),
|
||||||
declarations: DeclarationBlock {
|
declarations: DeclarationBlock {
|
||||||
specificity: selector.specificity,
|
specificity: selector.specificity,
|
||||||
mixed_declarations: $style_rule.declarations.declarations.clone(),
|
mixed_declarations: $style_rule.declarations.clone(),
|
||||||
importance: $importance,
|
importance: $importance,
|
||||||
source_order: rules_source_order,
|
source_order: rules_source_order,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
);
|
);
|
||||||
|
@ -194,10 +192,8 @@ impl Stylist {
|
||||||
for rule in stylesheet.effective_rules(&self.device) {
|
for rule in stylesheet.effective_rules(&self.device) {
|
||||||
match *rule {
|
match *rule {
|
||||||
CSSRule::Style(ref style_rule) => {
|
CSSRule::Style(ref style_rule) => {
|
||||||
let important_count = style_rule.declarations.important_count;
|
append!(style_rule, normal, Importance::Normal);
|
||||||
let normal_count = style_rule.declarations.declarations.len() as u32 - important_count;
|
append!(style_rule, important, Importance::Important);
|
||||||
append!(style_rule, normal, Importance::Normal, normal_count);
|
|
||||||
append!(style_rule, important, Importance::Important, important_count);
|
|
||||||
rules_source_order += 1;
|
rules_source_order += 1;
|
||||||
|
|
||||||
for selector in &style_rule.selectors {
|
for selector in &style_rule.selectors {
|
||||||
|
@ -346,7 +342,7 @@ impl Stylist {
|
||||||
&self,
|
&self,
|
||||||
element: &E,
|
element: &E,
|
||||||
parent_bf: Option<&BloomFilter>,
|
parent_bf: Option<&BloomFilter>,
|
||||||
style_attribute: Option<&PropertyDeclarationBlock>,
|
style_attribute: Option<&Arc<PropertyDeclarationBlock>>,
|
||||||
pseudo_element: Option<&PseudoElement>,
|
pseudo_element: Option<&PseudoElement>,
|
||||||
applicable_declarations: &mut V) -> StyleRelations
|
applicable_declarations: &mut V) -> StyleRelations
|
||||||
where E: Element<Impl=TheSelectorImpl> +
|
where E: Element<Impl=TheSelectorImpl> +
|
||||||
|
@ -373,7 +369,8 @@ impl Stylist {
|
||||||
map.user_agent.normal.get_all_matching_rules(element,
|
map.user_agent.normal.get_all_matching_rules(element,
|
||||||
parent_bf,
|
parent_bf,
|
||||||
applicable_declarations,
|
applicable_declarations,
|
||||||
&mut relations);
|
&mut relations,
|
||||||
|
Importance::Normal);
|
||||||
debug!("UA normal: {:?}", relations);
|
debug!("UA normal: {:?}", relations);
|
||||||
|
|
||||||
// Step 2: Presentational hints.
|
// Step 2: Presentational hints.
|
||||||
|
@ -389,23 +386,23 @@ impl Stylist {
|
||||||
map.user.normal.get_all_matching_rules(element,
|
map.user.normal.get_all_matching_rules(element,
|
||||||
parent_bf,
|
parent_bf,
|
||||||
applicable_declarations,
|
applicable_declarations,
|
||||||
&mut relations);
|
&mut relations,
|
||||||
|
Importance::Normal);
|
||||||
debug!("user normal: {:?}", relations);
|
debug!("user normal: {:?}", relations);
|
||||||
map.author.normal.get_all_matching_rules(element,
|
map.author.normal.get_all_matching_rules(element,
|
||||||
parent_bf,
|
parent_bf,
|
||||||
applicable_declarations,
|
applicable_declarations,
|
||||||
&mut relations);
|
&mut relations,
|
||||||
|
Importance::Normal);
|
||||||
debug!("author normal: {:?}", relations);
|
debug!("author normal: {:?}", relations);
|
||||||
|
|
||||||
// Step 4: Normal style attributes.
|
// 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 {
|
if sa.any_normal() {
|
||||||
relations |= AFFECTED_BY_STYLE_ATTRIBUTE;
|
relations |= AFFECTED_BY_STYLE_ATTRIBUTE;
|
||||||
Push::push(
|
Push::push(
|
||||||
applicable_declarations,
|
applicable_declarations,
|
||||||
DeclarationBlock::from_declarations(
|
DeclarationBlock::from_declarations(sa.clone(), Importance::Normal));
|
||||||
sa.declarations.clone(),
|
|
||||||
Importance::Normal));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -415,19 +412,18 @@ impl Stylist {
|
||||||
map.author.important.get_all_matching_rules(element,
|
map.author.important.get_all_matching_rules(element,
|
||||||
parent_bf,
|
parent_bf,
|
||||||
applicable_declarations,
|
applicable_declarations,
|
||||||
&mut relations);
|
&mut relations,
|
||||||
|
Importance::Important);
|
||||||
|
|
||||||
debug!("author important: {:?}", relations);
|
debug!("author important: {:?}", relations);
|
||||||
|
|
||||||
// Step 6: `!important` style attributes.
|
// Step 6: `!important` style attributes.
|
||||||
if let Some(ref sa) = style_attribute {
|
if let Some(sa) = style_attribute {
|
||||||
if sa.important_count > 0 {
|
if sa.any_important() {
|
||||||
relations |= AFFECTED_BY_STYLE_ATTRIBUTE;
|
relations |= AFFECTED_BY_STYLE_ATTRIBUTE;
|
||||||
Push::push(
|
Push::push(
|
||||||
applicable_declarations,
|
applicable_declarations,
|
||||||
DeclarationBlock::from_declarations(
|
DeclarationBlock::from_declarations(sa.clone(), Importance::Important));
|
||||||
sa.declarations.clone(),
|
|
||||||
Importance::Important));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -437,14 +433,16 @@ impl Stylist {
|
||||||
map.user.important.get_all_matching_rules(element,
|
map.user.important.get_all_matching_rules(element,
|
||||||
parent_bf,
|
parent_bf,
|
||||||
applicable_declarations,
|
applicable_declarations,
|
||||||
&mut relations);
|
&mut relations,
|
||||||
|
Importance::Important);
|
||||||
|
|
||||||
debug!("user important: {:?}", relations);
|
debug!("user important: {:?}", relations);
|
||||||
|
|
||||||
map.user_agent.important.get_all_matching_rules(element,
|
map.user_agent.important.get_all_matching_rules(element,
|
||||||
parent_bf,
|
parent_bf,
|
||||||
applicable_declarations,
|
applicable_declarations,
|
||||||
&mut relations);
|
&mut relations,
|
||||||
|
Importance::Important);
|
||||||
|
|
||||||
debug!("UA important: {:?}", relations);
|
debug!("UA important: {:?}", relations);
|
||||||
|
|
||||||
|
@ -651,7 +649,8 @@ impl SelectorMap {
|
||||||
element: &E,
|
element: &E,
|
||||||
parent_bf: Option<&BloomFilter>,
|
parent_bf: Option<&BloomFilter>,
|
||||||
matching_rules_list: &mut V,
|
matching_rules_list: &mut V,
|
||||||
relations: &mut StyleRelations)
|
relations: &mut StyleRelations,
|
||||||
|
importance: Importance)
|
||||||
where E: Element<Impl=TheSelectorImpl>,
|
where E: Element<Impl=TheSelectorImpl>,
|
||||||
V: VecLike<DeclarationBlock>
|
V: VecLike<DeclarationBlock>
|
||||||
{
|
{
|
||||||
|
@ -667,7 +666,8 @@ impl SelectorMap {
|
||||||
&self.id_hash,
|
&self.id_hash,
|
||||||
&id,
|
&id,
|
||||||
matching_rules_list,
|
matching_rules_list,
|
||||||
relations)
|
relations,
|
||||||
|
importance)
|
||||||
}
|
}
|
||||||
|
|
||||||
element.each_class(|class| {
|
element.each_class(|class| {
|
||||||
|
@ -676,7 +676,8 @@ impl SelectorMap {
|
||||||
&self.class_hash,
|
&self.class_hash,
|
||||||
class,
|
class,
|
||||||
matching_rules_list,
|
matching_rules_list,
|
||||||
relations);
|
relations,
|
||||||
|
importance);
|
||||||
});
|
});
|
||||||
|
|
||||||
let local_name_hash = if element.is_html_element_in_html_document() {
|
let local_name_hash = if element.is_html_element_in_html_document() {
|
||||||
|
@ -689,13 +690,15 @@ impl SelectorMap {
|
||||||
local_name_hash,
|
local_name_hash,
|
||||||
element.get_local_name(),
|
element.get_local_name(),
|
||||||
matching_rules_list,
|
matching_rules_list,
|
||||||
relations);
|
relations,
|
||||||
|
importance);
|
||||||
|
|
||||||
SelectorMap::get_matching_rules(element,
|
SelectorMap::get_matching_rules(element,
|
||||||
parent_bf,
|
parent_bf,
|
||||||
&self.other_rules,
|
&self.other_rules,
|
||||||
matching_rules_list,
|
matching_rules_list,
|
||||||
relations);
|
relations,
|
||||||
|
importance);
|
||||||
|
|
||||||
// Sort only the rules we just added.
|
// Sort only the rules we just added.
|
||||||
sort_by_key(&mut matching_rules_list[init_len..],
|
sort_by_key(&mut matching_rules_list[init_len..],
|
||||||
|
@ -731,7 +734,8 @@ impl SelectorMap {
|
||||||
hash: &FnvHashMap<Str, Vec<Rule>>,
|
hash: &FnvHashMap<Str, Vec<Rule>>,
|
||||||
key: &BorrowedStr,
|
key: &BorrowedStr,
|
||||||
matching_rules: &mut Vector,
|
matching_rules: &mut Vector,
|
||||||
relations: &mut StyleRelations)
|
relations: &mut StyleRelations,
|
||||||
|
importance: Importance)
|
||||||
where E: Element<Impl=TheSelectorImpl>,
|
where E: Element<Impl=TheSelectorImpl>,
|
||||||
Str: Borrow<BorrowedStr> + Eq + Hash,
|
Str: Borrow<BorrowedStr> + Eq + Hash,
|
||||||
BorrowedStr: Eq + Hash,
|
BorrowedStr: Eq + Hash,
|
||||||
|
@ -742,7 +746,8 @@ impl SelectorMap {
|
||||||
parent_bf,
|
parent_bf,
|
||||||
rules,
|
rules,
|
||||||
matching_rules,
|
matching_rules,
|
||||||
relations)
|
relations,
|
||||||
|
importance)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -751,12 +756,20 @@ impl SelectorMap {
|
||||||
parent_bf: Option<&BloomFilter>,
|
parent_bf: Option<&BloomFilter>,
|
||||||
rules: &[Rule],
|
rules: &[Rule],
|
||||||
matching_rules: &mut V,
|
matching_rules: &mut V,
|
||||||
relations: &mut StyleRelations)
|
relations: &mut StyleRelations,
|
||||||
|
importance: Importance)
|
||||||
where E: Element<Impl=TheSelectorImpl>,
|
where E: Element<Impl=TheSelectorImpl>,
|
||||||
V: VecLike<DeclarationBlock>
|
V: VecLike<DeclarationBlock>
|
||||||
{
|
{
|
||||||
for rule in rules.iter() {
|
for rule in rules.iter() {
|
||||||
if matches_complex_selector(&*rule.selector,
|
let block = &rule.declarations.mixed_declarations;
|
||||||
|
let any_declaration_for_importance = if importance.important() {
|
||||||
|
block.any_important()
|
||||||
|
} else {
|
||||||
|
block.any_normal()
|
||||||
|
};
|
||||||
|
if any_declaration_for_importance &&
|
||||||
|
matches_complex_selector(&*rule.selector,
|
||||||
element, parent_bf, relations) {
|
element, parent_bf, relations) {
|
||||||
matching_rules.push(rule.declarations.clone());
|
matching_rules.push(rule.declarations.clone());
|
||||||
}
|
}
|
||||||
|
@ -845,7 +858,7 @@ pub struct Rule {
|
||||||
pub struct DeclarationBlock {
|
pub struct DeclarationBlock {
|
||||||
/// Contains declarations of either importance, but only those of self.importance are relevant.
|
/// Contains declarations of either importance, but only those of self.importance are relevant.
|
||||||
/// Use DeclarationBlock::iter
|
/// Use DeclarationBlock::iter
|
||||||
pub mixed_declarations: Arc<Vec<(PropertyDeclaration, Importance)>>,
|
pub mixed_declarations: Arc<PropertyDeclarationBlock>,
|
||||||
pub importance: Importance,
|
pub importance: Importance,
|
||||||
pub source_order: usize,
|
pub source_order: usize,
|
||||||
pub specificity: u32,
|
pub specificity: u32,
|
||||||
|
@ -853,7 +866,7 @@ pub struct DeclarationBlock {
|
||||||
|
|
||||||
impl DeclarationBlock {
|
impl DeclarationBlock {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_declarations(declarations: Arc<Vec<(PropertyDeclaration, Importance)>>,
|
pub fn from_declarations(declarations: Arc<PropertyDeclarationBlock>,
|
||||||
importance: Importance)
|
importance: Importance)
|
||||||
-> Self {
|
-> Self {
|
||||||
DeclarationBlock {
|
DeclarationBlock {
|
||||||
|
@ -866,7 +879,7 @@ impl DeclarationBlock {
|
||||||
|
|
||||||
pub fn iter(&self) -> DeclarationBlockIter {
|
pub fn iter(&self) -> DeclarationBlockIter {
|
||||||
DeclarationBlockIter {
|
DeclarationBlockIter {
|
||||||
iter: self.mixed_declarations.iter(),
|
iter: self.mixed_declarations.declarations.iter(),
|
||||||
importance: self.importance,
|
importance: self.importance,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ use smallvec::SmallVec;
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::iter::Iterator;
|
use std::iter::Iterator;
|
||||||
use std::slice;
|
use std::slice;
|
||||||
|
use std::sync::Arc;
|
||||||
use string_cache::{Atom, Namespace};
|
use string_cache::{Atom, Namespace};
|
||||||
use url::Url;
|
use url::Url;
|
||||||
use viewport::ViewportRule;
|
use viewport::ViewportRule;
|
||||||
|
@ -64,31 +65,37 @@ pub struct UserAgentStylesheets {
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||||
pub enum CSSRule {
|
pub enum CSSRule {
|
||||||
Charset(String),
|
// No Charset here, CSSCharsetRule has been removed from CSSOM
|
||||||
Namespace {
|
// https://drafts.csswg.org/cssom/#changes-from-5-december-2013
|
||||||
/// `None` for the default Namespace
|
|
||||||
prefix: Option<Atom>,
|
Namespace(Arc<NamespaceRule>),
|
||||||
url: Namespace,
|
Style(Arc<StyleRule>),
|
||||||
},
|
Media(Arc<MediaRule>),
|
||||||
Style(StyleRule),
|
FontFace(Arc<FontFaceRule>),
|
||||||
Media(MediaRule),
|
Viewport(Arc<ViewportRule>),
|
||||||
FontFace(FontFaceRule),
|
Keyframes(Arc<KeyframesRule>),
|
||||||
Viewport(ViewportRule),
|
|
||||||
Keyframes(KeyframesRule),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq)]
|
||||||
|
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||||
|
pub struct NamespaceRule {
|
||||||
|
/// `None` for the default Namespace
|
||||||
|
pub prefix: Option<Atom>,
|
||||||
|
pub url: Namespace,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||||
pub struct KeyframesRule {
|
pub struct KeyframesRule {
|
||||||
pub name: Atom,
|
pub name: Atom,
|
||||||
pub keyframes: Vec<Keyframe>,
|
pub keyframes: Vec<Arc<Keyframe>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||||
pub struct MediaRule {
|
pub struct MediaRule {
|
||||||
pub media_queries: MediaQueryList,
|
pub media_queries: Arc<MediaQueryList>,
|
||||||
pub rules: Vec<CSSRule>,
|
pub rules: Vec<CSSRule>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,7 +111,7 @@ impl MediaRule {
|
||||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||||
pub struct StyleRule {
|
pub struct StyleRule {
|
||||||
pub selectors: Vec<Selector<TheSelectorImpl>>,
|
pub selectors: Vec<Selector<TheSelectorImpl>>,
|
||||||
pub declarations: PropertyDeclarationBlock,
|
pub declarations: Arc<PropertyDeclarationBlock>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -154,13 +161,13 @@ impl Stylesheet {
|
||||||
while let Some(result) = iter.next() {
|
while let Some(result) = iter.next() {
|
||||||
match result {
|
match result {
|
||||||
Ok(rule) => {
|
Ok(rule) => {
|
||||||
if let CSSRule::Namespace { ref prefix, ref url } = rule {
|
if let CSSRule::Namespace(ref rule) = rule {
|
||||||
if let Some(prefix) = prefix.as_ref() {
|
if let Some(ref prefix) = rule.prefix {
|
||||||
iter.parser.context.selector_context.namespace_prefixes.insert(
|
iter.parser.context.selector_context.namespace_prefixes.insert(
|
||||||
prefix.clone(), url.clone());
|
prefix.clone(), rule.url.clone());
|
||||||
} else {
|
} else {
|
||||||
iter.parser.context.selector_context.default_namespace =
|
iter.parser.context.selector_context.default_namespace =
|
||||||
Some(url.clone());
|
Some(rule.url.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -408,7 +415,7 @@ enum AtRulePrelude {
|
||||||
/// A @font-face rule prelude.
|
/// A @font-face rule prelude.
|
||||||
FontFace,
|
FontFace,
|
||||||
/// A @media rule prelude, with its media queries.
|
/// A @media rule prelude, with its media queries.
|
||||||
Media(MediaQueryList),
|
Media(Arc<MediaQueryList>),
|
||||||
/// A @viewport rule prelude.
|
/// A @viewport rule prelude.
|
||||||
Viewport,
|
Viewport,
|
||||||
/// A @keyframes rule, with its animation name.
|
/// A @keyframes rule, with its animation name.
|
||||||
|
@ -423,16 +430,6 @@ impl<'a> AtRuleParser for TopLevelRuleParser<'a> {
|
||||||
fn parse_prelude(&self, name: &str, input: &mut Parser)
|
fn parse_prelude(&self, name: &str, input: &mut Parser)
|
||||||
-> Result<AtRuleType<AtRulePrelude, CSSRule>, ()> {
|
-> Result<AtRuleType<AtRulePrelude, CSSRule>, ()> {
|
||||||
match_ignore_ascii_case! { name,
|
match_ignore_ascii_case! { name,
|
||||||
"charset" => {
|
|
||||||
if self.state.get() <= State::Start {
|
|
||||||
// Valid @charset rules are just ignored
|
|
||||||
self.state.set(State::Imports);
|
|
||||||
let charset = try!(input.expect_string()).into_owned();
|
|
||||||
return Ok(AtRuleType::WithoutBlock(CSSRule::Charset(charset)))
|
|
||||||
} else {
|
|
||||||
return Err(()) // "@charset must be the first rule"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"import" => {
|
"import" => {
|
||||||
if self.state.get() <= State::Imports {
|
if self.state.get() <= State::Imports {
|
||||||
self.state.set(State::Imports);
|
self.state.set(State::Imports);
|
||||||
|
@ -448,14 +445,17 @@ impl<'a> AtRuleParser for TopLevelRuleParser<'a> {
|
||||||
|
|
||||||
let prefix = input.try(|input| input.expect_ident()).ok().map(|p| p.into());
|
let prefix = input.try(|input| input.expect_ident()).ok().map(|p| p.into());
|
||||||
let url = Namespace(Atom::from(try!(input.expect_url_or_string())));
|
let url = Namespace(Atom::from(try!(input.expect_url_or_string())));
|
||||||
return Ok(AtRuleType::WithoutBlock(CSSRule::Namespace {
|
return Ok(AtRuleType::WithoutBlock(CSSRule::Namespace(Arc::new(NamespaceRule {
|
||||||
prefix: prefix,
|
prefix: prefix,
|
||||||
url: url,
|
url: url,
|
||||||
}))
|
}))))
|
||||||
} else {
|
} else {
|
||||||
return Err(()) // "@namespace must be before any rule but @charset and @import"
|
return Err(()) // "@namespace must be before any rule but @charset and @import"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
// @charset is removed by rust-cssparser if it’s the first rule in the stylesheet
|
||||||
|
// anything left is invalid.
|
||||||
|
"charset" => return Err(()), // (insert appropriate error message)
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -502,7 +502,7 @@ impl<'a, 'b> AtRuleParser for NestedRuleParser<'a, 'b> {
|
||||||
match_ignore_ascii_case! { name,
|
match_ignore_ascii_case! { name,
|
||||||
"media" => {
|
"media" => {
|
||||||
let media_queries = parse_media_query_list(input);
|
let media_queries = parse_media_query_list(input);
|
||||||
Ok(AtRuleType::WithBlock(AtRulePrelude::Media(media_queries)))
|
Ok(AtRuleType::WithBlock(AtRulePrelude::Media(Arc::new(media_queries))))
|
||||||
},
|
},
|
||||||
"font-face" => {
|
"font-face" => {
|
||||||
Ok(AtRuleType::WithBlock(AtRulePrelude::FontFace))
|
Ok(AtRuleType::WithBlock(AtRulePrelude::FontFace))
|
||||||
|
@ -530,22 +530,22 @@ impl<'a, 'b> AtRuleParser for NestedRuleParser<'a, 'b> {
|
||||||
fn parse_block(&self, prelude: AtRulePrelude, input: &mut Parser) -> Result<CSSRule, ()> {
|
fn parse_block(&self, prelude: AtRulePrelude, input: &mut Parser) -> Result<CSSRule, ()> {
|
||||||
match prelude {
|
match prelude {
|
||||||
AtRulePrelude::FontFace => {
|
AtRulePrelude::FontFace => {
|
||||||
parse_font_face_block(self.context, input).map(CSSRule::FontFace)
|
Ok(CSSRule::FontFace(Arc::new(try!(parse_font_face_block(self.context, input)))))
|
||||||
}
|
}
|
||||||
AtRulePrelude::Media(media_queries) => {
|
AtRulePrelude::Media(media_queries) => {
|
||||||
Ok(CSSRule::Media(MediaRule {
|
Ok(CSSRule::Media(Arc::new(MediaRule {
|
||||||
media_queries: media_queries,
|
media_queries: media_queries,
|
||||||
rules: parse_nested_rules(self.context, input),
|
rules: parse_nested_rules(self.context, input),
|
||||||
}))
|
})))
|
||||||
}
|
}
|
||||||
AtRulePrelude::Viewport => {
|
AtRulePrelude::Viewport => {
|
||||||
ViewportRule::parse(input, self.context).map(CSSRule::Viewport)
|
Ok(CSSRule::Viewport(Arc::new(try!(ViewportRule::parse(input, self.context)))))
|
||||||
}
|
}
|
||||||
AtRulePrelude::Keyframes(name) => {
|
AtRulePrelude::Keyframes(name) => {
|
||||||
Ok(CSSRule::Keyframes(KeyframesRule {
|
Ok(CSSRule::Keyframes(Arc::new(KeyframesRule {
|
||||||
name: name,
|
name: name,
|
||||||
keyframes: parse_keyframe_list(&self.context, input),
|
keyframes: parse_keyframe_list(&self.context, input),
|
||||||
}))
|
})))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -560,9 +560,9 @@ impl<'a, 'b> QualifiedRuleParser for NestedRuleParser<'a, 'b> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_block(&self, prelude: Vec<Selector<TheSelectorImpl>>, input: &mut Parser) -> Result<CSSRule, ()> {
|
fn parse_block(&self, prelude: Vec<Selector<TheSelectorImpl>>, input: &mut Parser) -> Result<CSSRule, ()> {
|
||||||
Ok(CSSRule::Style(StyleRule {
|
Ok(CSSRule::Style(Arc::new(StyleRule {
|
||||||
selectors: prelude,
|
selectors: prelude,
|
||||||
declarations: parse_property_declaration_list(self.context, input)
|
declarations: Arc::new(parse_property_declaration_list(self.context, input))
|
||||||
}))
|
})))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
7
ports/cef/Cargo.lock
generated
7
ports/cef/Cargo.lock
generated
|
@ -1691,11 +1691,6 @@ dependencies = [
|
||||||
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "ref_filter_map"
|
|
||||||
version = "1.0.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ref_slice"
|
name = "ref_slice"
|
||||||
version = "1.0.0"
|
version = "1.0.0"
|
||||||
|
@ -1781,7 +1776,6 @@ dependencies = [
|
||||||
"profile_traits 0.0.1",
|
"profile_traits 0.0.1",
|
||||||
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"range 0.0.1",
|
"range 0.0.1",
|
||||||
"ref_filter_map 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"ref_slice 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ref_slice 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"regex 0.1.73 (registry+https://github.com/rust-lang/crates.io-index)",
|
"regex 0.1.73 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -2720,7 +2714,6 @@ dependencies = [
|
||||||
"checksum quickersort 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e952ea7699262481636004bc4ab8afaccf2bc13f91b79d1aee6617bd8fc39651"
|
"checksum quickersort 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e952ea7699262481636004bc4ab8afaccf2bc13f91b79d1aee6617bd8fc39651"
|
||||||
"checksum rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "2791d88c6defac799c3f20d74f094ca33b9332612d9aef9078519c82e4fe04a5"
|
"checksum rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "2791d88c6defac799c3f20d74f094ca33b9332612d9aef9078519c82e4fe04a5"
|
||||||
"checksum rayon 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8e501871917624668fe601ad12a730450414f9b0b64722a898b040ce3ae1b0fa"
|
"checksum rayon 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8e501871917624668fe601ad12a730450414f9b0b64722a898b040ce3ae1b0fa"
|
||||||
"checksum ref_filter_map 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2b5ceb840e4009da4841ed22a15eb49f64fdd00a2138945c5beacf506b2fb5ed"
|
|
||||||
"checksum ref_slice 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "24c91f8f8903c37f0525112df98ef53b1985abca5702972e5e00854cd874baf2"
|
"checksum ref_slice 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "24c91f8f8903c37f0525112df98ef53b1985abca5702972e5e00854cd874baf2"
|
||||||
"checksum regex 0.1.73 (registry+https://github.com/rust-lang/crates.io-index)" = "56b7ee9f764ecf412c6e2fff779bca4b22980517ae335a21aeaf4e32625a5df2"
|
"checksum regex 0.1.73 (registry+https://github.com/rust-lang/crates.io-index)" = "56b7ee9f764ecf412c6e2fff779bca4b22980517ae335a21aeaf4e32625a5df2"
|
||||||
"checksum regex-syntax 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "31040aad7470ad9d8c46302dcffba337bb4289ca5da2e3cd6e37b64109a85199"
|
"checksum regex-syntax 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "31040aad7470ad9d8c46302dcffba337bb4289ca5da2e3cd6e37b64109a85199"
|
||||||
|
|
|
@ -356,7 +356,7 @@ pub extern "C" fn Servo_StyleSet_Drop(data: *mut RawServoStyleSet) -> () {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct GeckoDeclarationBlock {
|
pub struct GeckoDeclarationBlock {
|
||||||
pub declarations: Option<PropertyDeclarationBlock>,
|
pub declarations: Option<Arc<PropertyDeclarationBlock>>,
|
||||||
// XXX The following two fields are made atomic to work around the
|
// XXX The following two fields are made atomic to work around the
|
||||||
// ownership system so that they can be changed inside a shared
|
// ownership system so that they can be changed inside a shared
|
||||||
// instance. It wouldn't provide safety as Rust usually promises,
|
// instance. It wouldn't provide safety as Rust usually promises,
|
||||||
|
@ -377,7 +377,7 @@ pub extern "C" fn Servo_ParseStyleAttribute(bytes: *const u8, length: u32,
|
||||||
-> ServoDeclarationBlockStrong {
|
-> ServoDeclarationBlockStrong {
|
||||||
let value = unsafe { from_utf8_unchecked(slice::from_raw_parts(bytes, length as usize)) };
|
let value = unsafe { from_utf8_unchecked(slice::from_raw_parts(bytes, length as usize)) };
|
||||||
GeckoDeclarationBlock::from_arc(Arc::new(GeckoDeclarationBlock {
|
GeckoDeclarationBlock::from_arc(Arc::new(GeckoDeclarationBlock {
|
||||||
declarations: GeckoElement::parse_style_attribute(value),
|
declarations: GeckoElement::parse_style_attribute(value).map(Arc::new),
|
||||||
cache: AtomicPtr::new(cache),
|
cache: AtomicPtr::new(cache),
|
||||||
immutable: AtomicBool::new(false),
|
immutable: AtomicBool::new(false),
|
||||||
}))
|
}))
|
||||||
|
|
|
@ -35,7 +35,6 @@ use snapshot::GeckoElementSnapshot;
|
||||||
use snapshot_helpers;
|
use snapshot_helpers;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::mem::transmute;
|
|
||||||
use std::ops::BitOr;
|
use std::ops::BitOr;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
@ -462,8 +461,6 @@ lazy_static! {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
static NO_STYLE_ATTRIBUTE: Option<PropertyDeclarationBlock> = None;
|
|
||||||
|
|
||||||
impl<'le> TElement for GeckoElement<'le> {
|
impl<'le> TElement for GeckoElement<'le> {
|
||||||
type ConcreteNode = GeckoNode<'le>;
|
type ConcreteNode = GeckoNode<'le>;
|
||||||
type ConcreteDocument = GeckoDocument<'le>;
|
type ConcreteDocument = GeckoDocument<'le>;
|
||||||
|
@ -472,14 +469,16 @@ impl<'le> TElement for GeckoElement<'le> {
|
||||||
unsafe { GeckoNode::from_raw(self.element as *mut RawGeckoNode) }
|
unsafe { GeckoNode::from_raw(self.element as *mut RawGeckoNode) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn style_attribute(&self) -> &Option<PropertyDeclarationBlock> {
|
fn style_attribute(&self) -> Option<&Arc<PropertyDeclarationBlock>> {
|
||||||
let declarations = unsafe { Gecko_GetServoDeclarationBlock(self.element) };
|
let declarations = unsafe { Gecko_GetServoDeclarationBlock(self.element) };
|
||||||
if declarations.is_null() {
|
if declarations.is_null() {
|
||||||
&NO_STYLE_ATTRIBUTE
|
None
|
||||||
} else {
|
} else {
|
||||||
GeckoDeclarationBlock::with(declarations, |declarations| {
|
let opt_ptr = GeckoDeclarationBlock::with(declarations, |declarations| {
|
||||||
unsafe { transmute(&declarations.declarations) }
|
// Use a raw pointer to extend the lifetime
|
||||||
})
|
declarations.declarations.as_ref().map(|r| r as *const Arc<_>)
|
||||||
|
});
|
||||||
|
opt_ptr.map(|ptr| unsafe { &*ptr })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,10 +40,10 @@ macro_rules! sizeof_checker (
|
||||||
// Update the sizes here
|
// Update the sizes here
|
||||||
sizeof_checker!(size_event_target, EventTarget, 40);
|
sizeof_checker!(size_event_target, EventTarget, 40);
|
||||||
sizeof_checker!(size_node, Node, 152);
|
sizeof_checker!(size_node, Node, 152);
|
||||||
sizeof_checker!(size_element, Element, 328);
|
sizeof_checker!(size_element, Element, 320);
|
||||||
sizeof_checker!(size_htmlelement, HTMLElement, 344);
|
sizeof_checker!(size_htmlelement, HTMLElement, 336);
|
||||||
sizeof_checker!(size_div, HTMLDivElement, 344);
|
sizeof_checker!(size_div, HTMLDivElement, 336);
|
||||||
sizeof_checker!(size_span, HTMLSpanElement, 344);
|
sizeof_checker!(size_span, HTMLSpanElement, 336);
|
||||||
sizeof_checker!(size_text, Text, 184);
|
sizeof_checker!(size_text, Text, 184);
|
||||||
sizeof_checker!(size_characterdata, CharacterData, 184);
|
sizeof_checker!(size_characterdata, CharacterData, 184);
|
||||||
sizeof_checker!(size_servothreadsafelayoutnode, ServoThreadSafeLayoutNode, 16);
|
sizeof_checker!(size_servothreadsafelayoutnode, ServoThreadSafeLayoutNode, 16);
|
||||||
|
|
|
@ -45,8 +45,7 @@ fn property_declaration_block_should_serialize_correctly() {
|
||||||
];
|
];
|
||||||
|
|
||||||
let block = PropertyDeclarationBlock {
|
let block = PropertyDeclarationBlock {
|
||||||
declarations: Arc::new(declarations),
|
declarations: declarations,
|
||||||
|
|
||||||
important_count: 0,
|
important_count: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -63,8 +62,7 @@ mod shorthand_serialization {
|
||||||
|
|
||||||
pub fn shorthand_properties_to_string(properties: Vec<PropertyDeclaration>) -> String {
|
pub fn shorthand_properties_to_string(properties: Vec<PropertyDeclaration>) -> String {
|
||||||
let block = PropertyDeclarationBlock {
|
let block = PropertyDeclarationBlock {
|
||||||
declarations: Arc::new(properties.into_iter().map(|d| (d, Importance::Normal)).collect()),
|
declarations: properties.into_iter().map(|d| (d, Importance::Normal)).collect(),
|
||||||
|
|
||||||
important_count: 0,
|
important_count: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ use cssparser::Parser;
|
||||||
use selectors::parser::{LocalName, ParserContext, parse_selector_list};
|
use selectors::parser::{LocalName, ParserContext, parse_selector_list};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use string_cache::Atom;
|
use string_cache::Atom;
|
||||||
use style::properties::Importance;
|
use style::properties::{Importance, PropertyDeclarationBlock};
|
||||||
use style::selector_matching::{DeclarationBlock, Rule, SelectorMap};
|
use style::selector_matching::{DeclarationBlock, Rule, SelectorMap};
|
||||||
|
|
||||||
/// Helper method to get some Rules from selector strings.
|
/// Helper method to get some Rules from selector strings.
|
||||||
|
@ -19,7 +19,10 @@ fn get_mock_rules(css_selectors: &[&str]) -> Vec<Vec<Rule>> {
|
||||||
Rule {
|
Rule {
|
||||||
selector: s.complex_selector.clone(),
|
selector: s.complex_selector.clone(),
|
||||||
declarations: DeclarationBlock {
|
declarations: DeclarationBlock {
|
||||||
mixed_declarations: Arc::new(Vec::new()),
|
mixed_declarations: Arc::new(PropertyDeclarationBlock {
|
||||||
|
declarations: Vec::new(),
|
||||||
|
important_count: 0,
|
||||||
|
}),
|
||||||
importance: Importance::Normal,
|
importance: Importance::Normal,
|
||||||
specificity: s.specificity,
|
specificity: s.specificity,
|
||||||
source_order: i,
|
source_order: i,
|
||||||
|
|
|
@ -15,7 +15,7 @@ use style::parser::ParserContextExtraData;
|
||||||
use style::properties::{PropertyDeclaration, PropertyDeclarationBlock, DeclaredValue, longhands};
|
use style::properties::{PropertyDeclaration, PropertyDeclarationBlock, DeclaredValue, longhands};
|
||||||
use style::properties::Importance;
|
use style::properties::Importance;
|
||||||
use style::properties::longhands::animation_play_state;
|
use style::properties::longhands::animation_play_state;
|
||||||
use style::stylesheets::{Stylesheet, CSSRule, StyleRule, KeyframesRule, Origin};
|
use style::stylesheets::{Stylesheet, NamespaceRule, CSSRule, StyleRule, KeyframesRule, Origin};
|
||||||
use style::values::specified::{LengthOrPercentageOrAuto, Percentage};
|
use style::values::specified::{LengthOrPercentageOrAuto, Percentage};
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
|
@ -65,11 +65,11 @@ fn test_parse_stylesheet() {
|
||||||
media: None,
|
media: None,
|
||||||
dirty_on_viewport_size_change: false,
|
dirty_on_viewport_size_change: false,
|
||||||
rules: vec![
|
rules: vec![
|
||||||
CSSRule::Namespace {
|
CSSRule::Namespace(Arc::new(NamespaceRule {
|
||||||
prefix: None,
|
prefix: None,
|
||||||
url: NsAtom(Atom::from("http://www.w3.org/1999/xhtml"))
|
url: NsAtom(Atom::from("http://www.w3.org/1999/xhtml"))
|
||||||
},
|
})),
|
||||||
CSSRule::Style(StyleRule {
|
CSSRule::Style(Arc::new(StyleRule {
|
||||||
selectors: vec![
|
selectors: vec![
|
||||||
Selector {
|
Selector {
|
||||||
complex_selector: Arc::new(ComplexSelector {
|
complex_selector: Arc::new(ComplexSelector {
|
||||||
|
@ -97,18 +97,18 @@ fn test_parse_stylesheet() {
|
||||||
specificity: (0 << 20) + (1 << 10) + (1 << 0),
|
specificity: (0 << 20) + (1 << 10) + (1 << 0),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
declarations: PropertyDeclarationBlock {
|
declarations: Arc::new(PropertyDeclarationBlock {
|
||||||
declarations: Arc::new(vec![
|
declarations: vec![
|
||||||
(PropertyDeclaration::Display(DeclaredValue::Value(
|
(PropertyDeclaration::Display(DeclaredValue::Value(
|
||||||
longhands::display::SpecifiedValue::none)),
|
longhands::display::SpecifiedValue::none)),
|
||||||
Importance::Important),
|
Importance::Important),
|
||||||
(PropertyDeclaration::Custom(Atom::from("a"), DeclaredValue::Inherit),
|
(PropertyDeclaration::Custom(Atom::from("a"), DeclaredValue::Inherit),
|
||||||
Importance::Important),
|
Importance::Important),
|
||||||
]),
|
],
|
||||||
important_count: 2,
|
important_count: 2,
|
||||||
},
|
}),
|
||||||
}),
|
})),
|
||||||
CSSRule::Style(StyleRule {
|
CSSRule::Style(Arc::new(StyleRule {
|
||||||
selectors: vec![
|
selectors: vec![
|
||||||
Selector {
|
Selector {
|
||||||
complex_selector: Arc::new(ComplexSelector {
|
complex_selector: Arc::new(ComplexSelector {
|
||||||
|
@ -145,16 +145,16 @@ fn test_parse_stylesheet() {
|
||||||
specificity: (0 << 20) + (0 << 10) + (1 << 0),
|
specificity: (0 << 20) + (0 << 10) + (1 << 0),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
declarations: PropertyDeclarationBlock {
|
declarations: Arc::new(PropertyDeclarationBlock {
|
||||||
declarations: Arc::new(vec![
|
declarations: vec![
|
||||||
(PropertyDeclaration::Display(DeclaredValue::Value(
|
(PropertyDeclaration::Display(DeclaredValue::Value(
|
||||||
longhands::display::SpecifiedValue::block)),
|
longhands::display::SpecifiedValue::block)),
|
||||||
Importance::Normal),
|
Importance::Normal),
|
||||||
]),
|
],
|
||||||
important_count: 0,
|
important_count: 0,
|
||||||
},
|
}),
|
||||||
}),
|
})),
|
||||||
CSSRule::Style(StyleRule {
|
CSSRule::Style(Arc::new(StyleRule {
|
||||||
selectors: vec![
|
selectors: vec![
|
||||||
Selector {
|
Selector {
|
||||||
complex_selector: Arc::new(ComplexSelector {
|
complex_selector: Arc::new(ComplexSelector {
|
||||||
|
@ -180,8 +180,8 @@ fn test_parse_stylesheet() {
|
||||||
specificity: (1 << 20) + (1 << 10) + (0 << 0),
|
specificity: (1 << 20) + (1 << 10) + (0 << 0),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
declarations: PropertyDeclarationBlock {
|
declarations: Arc::new(PropertyDeclarationBlock {
|
||||||
declarations: Arc::new(vec![
|
declarations: vec![
|
||||||
(PropertyDeclaration::BackgroundColor(DeclaredValue::Value(
|
(PropertyDeclaration::BackgroundColor(DeclaredValue::Value(
|
||||||
longhands::background_color::SpecifiedValue {
|
longhands::background_color::SpecifiedValue {
|
||||||
authored: Some("blue".to_owned()),
|
authored: Some("blue".to_owned()),
|
||||||
|
@ -226,37 +226,43 @@ fn test_parse_stylesheet() {
|
||||||
vec![longhands::background_clip::single_value
|
vec![longhands::background_clip::single_value
|
||||||
::get_initial_specified_value()]))),
|
::get_initial_specified_value()]))),
|
||||||
Importance::Normal),
|
Importance::Normal),
|
||||||
]),
|
],
|
||||||
important_count: 0,
|
important_count: 0,
|
||||||
},
|
}),
|
||||||
}),
|
})),
|
||||||
CSSRule::Keyframes(KeyframesRule {
|
CSSRule::Keyframes(Arc::new(KeyframesRule {
|
||||||
name: "foo".into(),
|
name: "foo".into(),
|
||||||
keyframes: vec![
|
keyframes: vec![
|
||||||
Keyframe {
|
Arc::new(Keyframe {
|
||||||
selector: KeyframeSelector::new_for_unit_testing(
|
selector: KeyframeSelector::new_for_unit_testing(
|
||||||
vec![KeyframePercentage::new(0.)]),
|
vec![KeyframePercentage::new(0.)]),
|
||||||
declarations: Arc::new(vec![
|
block: Arc::new(PropertyDeclarationBlock {
|
||||||
(PropertyDeclaration::Width(DeclaredValue::Value(
|
declarations: vec![
|
||||||
LengthOrPercentageOrAuto::Percentage(Percentage(0.)))),
|
(PropertyDeclaration::Width(DeclaredValue::Value(
|
||||||
Importance::Normal),
|
LengthOrPercentageOrAuto::Percentage(Percentage(0.)))),
|
||||||
]),
|
Importance::Normal),
|
||||||
},
|
],
|
||||||
Keyframe {
|
important_count: 0,
|
||||||
|
})
|
||||||
|
}),
|
||||||
|
Arc::new(Keyframe {
|
||||||
selector: KeyframeSelector::new_for_unit_testing(
|
selector: KeyframeSelector::new_for_unit_testing(
|
||||||
vec![KeyframePercentage::new(1.)]),
|
vec![KeyframePercentage::new(1.)]),
|
||||||
declarations: Arc::new(vec![
|
block: Arc::new(PropertyDeclarationBlock {
|
||||||
(PropertyDeclaration::Width(DeclaredValue::Value(
|
declarations: vec![
|
||||||
LengthOrPercentageOrAuto::Percentage(Percentage(1.)))),
|
(PropertyDeclaration::Width(DeclaredValue::Value(
|
||||||
Importance::Normal),
|
LengthOrPercentageOrAuto::Percentage(Percentage(1.)))),
|
||||||
(PropertyDeclaration::AnimationPlayState(DeclaredValue::Value(
|
Importance::Normal),
|
||||||
animation_play_state::SpecifiedValue(
|
(PropertyDeclaration::AnimationPlayState(DeclaredValue::Value(
|
||||||
vec![animation_play_state::SingleSpecifiedValue::running]))),
|
animation_play_state::SpecifiedValue(
|
||||||
Importance::Normal),
|
vec![animation_play_state::SingleSpecifiedValue::running]))),
|
||||||
]),
|
Importance::Normal),
|
||||||
},
|
],
|
||||||
|
important_count: 0,
|
||||||
|
}),
|
||||||
|
}),
|
||||||
]
|
]
|
||||||
})
|
}))
|
||||||
|
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue