diff options
Diffstat (limited to 'components/script')
-rw-r--r-- | components/script/Cargo.toml | 3 | ||||
-rw-r--r-- | components/script/dom/attr.rs | 2 | ||||
-rw-r--r-- | components/script/dom/bindings/cell.rs | 139 | ||||
-rw-r--r-- | components/script/dom/bindings/mod.rs | 3 | ||||
-rw-r--r-- | components/script/dom/bindings/trace.rs | 8 | ||||
-rw-r--r-- | components/script/dom/characterdata.rs | 2 | ||||
-rw-r--r-- | components/script/dom/cssstyledeclaration.rs | 5 | ||||
-rw-r--r-- | components/script/dom/document.rs | 3 | ||||
-rw-r--r-- | components/script/dom/element.rs | 47 | ||||
-rw-r--r-- | components/script/dom/htmlmetaelement.rs | 2 | ||||
-rw-r--r-- | components/script/dom/node.rs | 6 | ||||
-rw-r--r-- | components/script/layout_wrapper.rs | 4 | ||||
-rw-r--r-- | components/script/lib.rs | 2 |
13 files changed, 52 insertions, 174 deletions
diff --git a/components/script/Cargo.toml b/components/script/Cargo.toml index 30aab73f112..3e8e216c986 100644 --- a/components/script/Cargo.toml +++ b/components/script/Cargo.toml @@ -56,13 +56,12 @@ plugins = {path = "../plugins"} profile_traits = {path = "../profile_traits"} rand = "0.3" range = {path = "../range"} -ref_filter_map = "1.0" ref_slice = "1.0" regex = "0.1.43" rustc-serialize = "0.3" script_layout_interface = {path = "../script_layout_interface"} script_traits = {path = "../script_traits"} -selectors = {version = "0.12", features = ["heap_size"]} +selectors = {version = "0.13", features = ["heap_size"]} serde = "0.8" smallvec = "0.1" string_cache = {version = "0.2.26", features = ["heap_size", "unstable"]} diff --git a/components/script/dom/attr.rs b/components/script/dom/attr.rs index d5a00e6c1fa..36de48a1f9b 100644 --- a/components/script/dom/attr.rs +++ b/components/script/dom/attr.rs @@ -15,10 +15,10 @@ use dom::element::{AttributeMutation, Element}; use dom::virtualmethods::vtable_for; use dom::window::Window; use std::borrow::ToOwned; -use std::cell::Ref; use std::mem; use string_cache::{Atom, Namespace}; use style::attr::{AttrIdentifier, AttrValue}; +use style::refcell::Ref; // https://dom.spec.whatwg.org/#interface-attr #[dom_struct] diff --git a/components/script/dom/bindings/cell.rs b/components/script/dom/bindings/cell.rs deleted file mode 100644 index d1b40af5b1a..00000000000 --- a/components/script/dom/bindings/cell.rs +++ /dev/null @@ -1,139 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -//! A shareable mutable container for the DOM. - -use dom::bindings::trace::JSTraceable; -use js::jsapi::JSTracer; -use std::cell::{BorrowError, BorrowMutError, Ref, RefCell, RefMut}; -use style::thread_state; -use style::thread_state::SCRIPT; - -/// A mutable field in the DOM. -/// -/// This extends the API of `core::cell::RefCell` to allow unsafe access in -/// certain situations, with dynamic checking in debug builds. -#[derive(Clone, HeapSizeOf)] -pub struct DOMRefCell<T> { - value: RefCell<T>, -} - -// Functionality specific to Servo's `DOMRefCell` type -// =================================================== - -impl<T> DOMRefCell<T> { - /// Return a reference to the contents. - /// - /// For use in the layout thread only. - #[allow(unsafe_code)] - pub unsafe fn borrow_for_layout(&self) -> &T { - debug_assert!(thread_state::get().is_layout()); - &*self.value.as_ptr() - } - - /// Borrow the contents for the purpose of GC tracing. - /// - /// This succeeds even if the object is mutably borrowed, - /// so you have to be careful in trace code! - #[allow(unsafe_code)] - pub unsafe fn borrow_for_gc_trace(&self) -> &T { - // FIXME: IN_GC isn't reliable enough - doesn't catch minor GCs - // https://github.com/servo/servo/issues/6389 - // debug_assert!(thread_state::get().contains(SCRIPT | IN_GC)); - &*self.value.as_ptr() - } - - /// Borrow the contents for the purpose of script deallocation. - /// - #[allow(unsafe_code)] - pub unsafe fn borrow_for_script_deallocation(&self) -> &mut T { - debug_assert!(thread_state::get().contains(SCRIPT)); - &mut *self.value.as_ptr() - } - - /// Version of the above that we use during restyle while the script thread - /// is blocked. - pub fn borrow_mut_for_layout(&self) -> RefMut<T> { - debug_assert!(thread_state::get().is_layout()); - self.value.borrow_mut() - } -} - -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` -// =================================================== -impl<T> DOMRefCell<T> { - /// Create a new `DOMRefCell` containing `value`. - pub fn new(value: T) -> DOMRefCell<T> { - DOMRefCell { - value: RefCell::new(value), - } - } - - - /// Immutably borrows the wrapped value. - /// - /// The borrow lasts until the returned `Ref` exits scope. Multiple - /// immutable borrows can be taken out at the same time. - /// - /// # Panics - /// - /// Panics if this is called off the script thread. - /// - /// Panics if the value is currently mutably borrowed. - pub fn borrow(&self) -> Ref<T> { - self.try_borrow().expect("DOMRefCell<T> already mutably borrowed") - } - - /// Mutably borrows the wrapped value. - /// - /// The borrow lasts until the returned `RefMut` exits scope. The value - /// cannot be borrowed while this borrow is active. - /// - /// # Panics - /// - /// Panics if this is called off the script thread. - /// - /// Panics if the value is currently borrowed. - pub fn borrow_mut(&self) -> RefMut<T> { - self.try_borrow_mut().expect("DOMRefCell<T> already borrowed") - } - - /// Attempts to immutably borrow the wrapped value. - /// - /// The borrow lasts until the returned `Ref` exits scope. Multiple - /// immutable borrows can be taken out at the same time. - /// - /// Returns `None` if the value is currently mutably borrowed. - /// - /// # Panics - /// - /// Panics if this is called off the script thread. - pub fn try_borrow(&self) -> Result<Ref<T>, BorrowError<T>> { - debug_assert!(thread_state::get().is_script()); - self.value.try_borrow() - } - - /// Mutably borrows the wrapped value. - /// - /// The borrow lasts until the returned `RefMut` exits scope. The value - /// cannot be borrowed while this borrow is active. - /// - /// Returns `None` if the value is currently borrowed. - /// - /// # Panics - /// - /// Panics if this is called off the script thread. - pub fn try_borrow_mut(&self) -> Result<RefMut<T>, BorrowMutError<T>> { - debug_assert!(thread_state::get().is_script()); - self.value.try_borrow_mut() - } -} diff --git a/components/script/dom/bindings/mod.rs b/components/script/dom/bindings/mod.rs index 439016ee15b..02d5c9c8bef 100644 --- a/components/script/dom/bindings/mod.rs +++ b/components/script/dom/bindings/mod.rs @@ -128,8 +128,9 @@ //! return `Err()` from the method with the appropriate [error value] //! (error/enum.Error.html). +pub use style::domrefcell as cell; + pub mod callback; -pub mod cell; pub mod conversions; pub mod error; pub mod global; diff --git a/components/script/dom/bindings/trace.rs b/components/script/dom/bindings/trace.rs index d6969f38d6c..507e19e4bcb 100644 --- a/components/script/dom/bindings/trace.rs +++ b/components/script/dom/bindings/trace.rs @@ -88,6 +88,7 @@ use std::sync::mpsc::{Receiver, Sender}; use std::time::SystemTime; use string_cache::{Atom, Namespace, QualName}; use style::attr::{AttrIdentifier, AttrValue, LengthOrPercentageOrAuto}; +use style::domrefcell::DOMRefCell; use style::element_state::*; use style::properties::PropertyDeclarationBlock; 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> { fn trace(&self, trc: *mut JSTracer) { diff --git a/components/script/dom/characterdata.rs b/components/script/dom/characterdata.rs index 01f11e3ac50..979e9a70434 100644 --- a/components/script/dom/characterdata.rs +++ b/components/script/dom/characterdata.rs @@ -19,7 +19,7 @@ use dom::element::Element; use dom::node::{Node, NodeDamage}; use dom::processinginstruction::ProcessingInstruction; use dom::text::Text; -use std::cell::Ref; +use style::refcell::Ref; use util::opts; // https://dom.spec.whatwg.org/#characterdata diff --git a/components/script/dom/cssstyledeclaration.rs b/components/script/dom/cssstyledeclaration.rs index 0335a7498c0..c048446d813 100644 --- a/components/script/dom/cssstyledeclaration.rs +++ b/components/script/dom/cssstyledeclaration.rs @@ -14,12 +14,13 @@ use dom::element::Element; use dom::node::{Node, NodeDamage, window_from_node}; use dom::window::Window; use std::ascii::AsciiExt; -use std::cell::Ref; use std::slice; +use std::sync::Arc; use string_cache::Atom; use style::parser::ParserContextExtraData; use style::properties::{PropertyDeclaration, Shorthand, Importance}; use style::properties::{is_supported_property, parse_one_declaration, parse_style_attribute}; +use style::refcell::Ref; use style::selector_impl::PseudoElement; // 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() { None // Step 2 } else { - Some(decl_block) + Some(Arc::new(decl_block)) }; element.sync_property_with_attrs_style(); let node = element.upcast::<Node>(); diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index f6f06e7d851..4322e348c92 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -111,7 +111,7 @@ use script_traits::{TouchEventType, TouchId}; use std::ascii::AsciiExt; use std::borrow::ToOwned; use std::boxed::FnBox; -use std::cell::{Cell, Ref, RefMut}; +use std::cell::Cell; use std::collections::HashMap; use std::collections::hash_map::Entry::{Occupied, Vacant}; use std::default::Default; @@ -122,6 +122,7 @@ use std::sync::Arc; use string_cache::{Atom, QualName}; use style::attr::AttrValue; use style::context::ReflowGoal; +use style::refcell::{Ref, RefMut}; use style::selector_impl::ElementSnapshot; use style::str::{split_html_space_chars, str_join}; use style::stylesheets::Stylesheet; diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs index 2d57ddab4d6..193fb16b937 100644 --- a/components/script/dom/element.rs +++ b/components/script/dom/element.rs @@ -70,13 +70,12 @@ use html5ever::serialize::SerializeOpts; use html5ever::serialize::TraversalScope; use html5ever::serialize::TraversalScope::{ChildrenOnly, IncludeNode}; use html5ever::tree_builder::{LimitedQuirks, NoQuirks, Quirks}; -use ref_filter_map::ref_filter_map; -use selectors::matching::{ElementFlags, matches}; +use selectors::matching::{ElementFlags, MatchingReason, matches}; 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 std::ascii::AsciiExt; use std::borrow::Cow; -use std::cell::{Cell, Ref}; +use std::cell::Cell; use std::convert::TryFrom; use std::default::Default; 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::{DeclaredValue, Importance}; use style::properties::{PropertyDeclaration, PropertyDeclarationBlock, parse_style_attribute}; +use style::refcell::Ref; use style::selector_impl::{NonTSPseudoClass, ServoSelectorImpl}; use style::selector_matching::DeclarationBlock; use style::sink::Push; @@ -109,7 +109,7 @@ pub struct Element { prefix: Option<DOMString>, attrs: DOMRefCell<Vec<JS<Attr>>>, id_attribute: DOMRefCell<Option<Atom>>, - style_attribute: DOMRefCell<Option<PropertyDeclarationBlock>>, + style_attribute: DOMRefCell<Option<Arc<PropertyDeclarationBlock>>>, attr_list: MutNullableHeap<JS<NamedNodeMap>>, class_list: MutNullableHeap<JS<DOMTokenList>>, state: Cell<ElementState>, @@ -297,7 +297,7 @@ pub trait LayoutElementHelpers { #[allow(unsafe_code)] unsafe fn html_element_in_html_document_for_layout(&self) -> bool; 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 namespace(&self) -> &Namespace; fn get_checked_state_for_layout(&self) -> bool; @@ -329,7 +329,10 @@ impl LayoutElementHelpers for LayoutJS<Element> { #[inline] fn from_declaration(rule: PropertyDeclaration) -> DeclarationBlock { DeclarationBlock::from_declarations( - Arc::new(vec![(rule, Importance::Normal)]), + Arc::new(PropertyDeclarationBlock { + declarations: vec![(rule, Importance::Normal)], + important_count: 0, + }), Importance::Normal) } @@ -615,7 +618,7 @@ impl LayoutElementHelpers for LayoutJS<Element> { } #[allow(unsafe_code)] - fn style_attribute(&self) -> *const Option<PropertyDeclarationBlock> { + fn style_attribute(&self) -> *const Option<Arc<PropertyDeclarationBlock>> { unsafe { (*self.unsafe_get()).style_attribute.borrow_for_layout() } @@ -704,7 +707,7 @@ impl Element { self.attrs.borrow() } - pub fn style_attribute(&self) -> &DOMRefCell<Option<PropertyDeclarationBlock>> { + pub fn style_attribute(&self) -> &DOMRefCell<Option<Arc<PropertyDeclarationBlock>>> { &self.style_attribute } @@ -774,7 +777,8 @@ impl Element { matching }); 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() { declarations.important_count -= 1; } @@ -796,7 +800,8 @@ impl Element { { // Usually, the reference count will be 1 here. But transitions could make it greater // 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 { for existing_declaration in &mut *existing_declarations { @@ -829,10 +834,10 @@ impl Element { 0 }; - *inline_declarations = Some(PropertyDeclarationBlock { - declarations: Arc::new(declarations.into_iter().map(|d| (d, importance)).collect()), + *inline_declarations = Some(Arc::new(PropertyDeclarationBlock { + declarations: declarations.into_iter().map(|d| (d, importance)).collect(), important_count: important_count, - }); + })); } update(self, declarations, importance); @@ -847,7 +852,8 @@ impl Element { if let &mut Some(ref mut block) = &mut *inline_declarations { // Usually, the reference counts of `from` and `to` will be 1 here. But transitions // 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 { if properties.iter().any(|p| declaration.name() == **p) { match (*importance, new_importance) { @@ -871,7 +877,7 @@ impl Element { pub fn get_inline_style_declaration(&self, property: &Atom) -> 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| { declarations.declarations .iter() @@ -2000,7 +2006,7 @@ impl ElementMethods for Element { match parse_author_origin_selector_list_from_str(&selectors) { Err(()) => Err(Error::Syntax), Ok(ref selectors) => { - Ok(matches(selectors, &Root::from_ref(self), None)) + Ok(matches(selectors, &Root::from_ref(self), None, MatchingReason::Other)) } } } @@ -2018,7 +2024,7 @@ impl ElementMethods for Element { let root = self.upcast::<Node>(); for element in root.inclusive_ancestors() { if let Some(element) = Root::downcast::<Element>(element) { - if matches(selectors, &element, None) { + if matches(selectors, &element, None, MatchingReason::Other) { return Ok(Some(element)); } } @@ -2102,8 +2108,11 @@ impl VirtualMethods for Element { *self.style_attribute.borrow_mut() = mutation.new_value(attr).map(|value| { let win = window_from_node(self); - parse_style_attribute(&value, &doc.base_url(), win.css_error_reporter(), - ParserContextExtraData::default()) + Arc::new(parse_style_attribute( + &value, + &doc.base_url(), + win.css_error_reporter(), + ParserContextExtraData::default())) }); if node.is_in_doc() { node.dirty(NodeDamage::NodeStyleDamaged); diff --git a/components/script/dom/htmlmetaelement.rs b/components/script/dom/htmlmetaelement.rs index b8c2cd423fa..e6f86f41d86 100644 --- a/components/script/dom/htmlmetaelement.rs +++ b/components/script/dom/htmlmetaelement.rs @@ -79,7 +79,7 @@ impl HTMLMetaElement { if !content.is_empty() { if let Some(translated_rule) = ViewportRule::from_meta(&**content) { *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, media: None, // Viewport constraints are always recomputed on resize; they don't need to diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs index 49aa8242b34..555c7719fb1 100644 --- a/components/script/dom/node.rs +++ b/components/script/dom/node.rs @@ -63,7 +63,7 @@ use script_layout_interface::message::Msg; use script_layout_interface::{HTMLCanvasData, OpaqueStyleAndLayoutData}; use script_layout_interface::{LayoutNodeType, LayoutElementType, TrustedNodeAddress}; use script_traits::UntrustedNodeAddress; -use selectors::matching::matches; +use selectors::matching::{MatchingReason, matches}; use selectors::parser::Selector; use selectors::parser::parse_author_origin_selector_list_from_str; use std::borrow::ToOwned; @@ -319,7 +319,7 @@ impl<'a> Iterator for QuerySelectorIterator { // (instead of passing `None`)? Probably. self.iterator.by_ref().filter_map(|node| { if let Some(element) = Root::downcast(node) { - if matches(selectors, &element, None) { + if matches(selectors, &element, None, MatchingReason::Other) { return Some(Root::upcast(element)); } } @@ -711,7 +711,7 @@ impl Node { // Step 3. Ok(ref selectors) => { Ok(self.traverse_preorder().filter_map(Root::downcast).find(|element| { - matches(selectors, element, None) + matches(selectors, element, None, MatchingReason::Other) })) } } diff --git a/components/script/layout_wrapper.rs b/components/script/layout_wrapper.rs index 4edd821ad0b..a7f0a5019f3 100644 --- a/components/script/layout_wrapper.rs +++ b/components/script/layout_wrapper.rs @@ -459,9 +459,9 @@ impl<'le> TElement for ServoLayoutElement<'le> { ServoLayoutNode::from_layout_js(self.element.upcast()) } - fn style_attribute(&self) -> &Option<PropertyDeclarationBlock> { + fn style_attribute(&self) -> Option<&Arc<PropertyDeclarationBlock>> { unsafe { - &*self.element.style_attribute() + (*self.element.style_attribute()).as_ref() } } diff --git a/components/script/lib.rs b/components/script/lib.rs index ff3715de24c..910706f4a1a 100644 --- a/components/script/lib.rs +++ b/components/script/lib.rs @@ -17,7 +17,6 @@ #![feature(slice_patterns)] #![feature(stmt_expr_attributes)] #![feature(question_mark)] -#![feature(try_borrow)] #![feature(try_from)] #![deny(unsafe_code)] @@ -69,7 +68,6 @@ extern crate phf; extern crate profile_traits; extern crate rand; extern crate range; -extern crate ref_filter_map; extern crate ref_slice; extern crate regex; extern crate rustc_serialize; |