diff options
40 files changed, 339 insertions, 249 deletions
diff --git a/components/layout/Cargo.toml b/components/layout/Cargo.toml index fb006dd59ac..4d9c5d02a48 100644 --- a/components/layout/Cargo.toml +++ b/components/layout/Cargo.toml @@ -61,7 +61,7 @@ fnv = "1.0" bitflags = "0.3" rustc-serialize = "0.3" libc = "0.2" -selectors = "0.2" +selectors = "0.4.1" smallvec = "0.1" string_cache = "0.2" euclid = {version = "0.4", features = ["plugins"]} diff --git a/components/layout/lib.rs b/components/layout/lib.rs index 7b9caa88313..cf0d2f18ea1 100644 --- a/components/layout/lib.rs +++ b/components/layout/lib.rs @@ -45,7 +45,7 @@ extern crate profile_traits; extern crate rustc_serialize; extern crate script; extern crate script_traits; -#[macro_use(state_pseudo_classes)] extern crate selectors; +extern crate selectors; extern crate serde; extern crate serde_json; extern crate smallvec; diff --git a/components/layout/query.rs b/components/layout/query.rs index ab28e6c49d8..84d3071defb 100644 --- a/components/layout/query.rs +++ b/components/layout/query.rs @@ -19,7 +19,6 @@ use script::layout_interface::{ContentBoxResponse, ContentBoxesResponse, NodeGeo use script::layout_interface::{HitTestResponse, LayoutRPC, MouseOverResponse, OffsetParentResponse}; use script::layout_interface::{ResolvedStyleResponse, ScriptLayoutChan}; use script_traits::LayoutMsg as ConstellationMsg; -use selectors::parser::PseudoElement; use sequential; use std::ops::Deref; use std::sync::{Arc, Mutex}; @@ -27,6 +26,7 @@ use string_cache::Atom; use style::computed_values; use style::properties::longhands::{display, position}; use style::properties::style_structs; +use style::selector_impl::PseudoElement; use style::values::AuExtensionMethods; use util::cursor::Cursor; use util::logical_geometry::WritingMode; diff --git a/components/layout/wrapper.rs b/components/layout/wrapper.rs index cf02c66ed63..1c8f1ee1d8e 100644 --- a/components/layout/wrapper.rs +++ b/components/layout/wrapper.rs @@ -55,7 +55,6 @@ use script::dom::text::Text; use script::layout_interface::TrustedNodeAddress; use selectors::matching::DeclarationBlock; use selectors::parser::{AttrSelector, NamespaceConstraint}; -use selectors::states::*; use smallvec::VecLike; use std::borrow::ToOwned; use std::cell::{Ref, RefCell, RefMut}; @@ -67,9 +66,11 @@ use style::computed_values::content::ContentItem; use style::computed_values::{content, display}; use style::data::PrivateStyleData; use style::dom::{TDocument, TElement, TNode, UnsafeNode}; +use style::element_state::*; use style::properties::ComputedValues; use style::properties::{PropertyDeclaration, PropertyDeclarationBlock}; use style::restyle_hints::ElementSnapshot; +use style::selector_impl::{NonTSPseudoClass, ServoSelectorImpl}; use url::Url; use util::str::{is_whitespace, search_index}; @@ -452,17 +453,9 @@ fn as_element<'le>(node: LayoutJS<Node>) -> Option<ServoLayoutElement<'le>> { node.downcast().map(ServoLayoutElement::from_layout_js) } -macro_rules! state_getter { - ($( - $(#[$Flag_attr: meta])* - state $css: expr => $variant: ident / $method: ident / - $flag: ident = $value: expr, - )+) => { - $( fn $method(&self) -> bool { self.element.get_state_for_layout().contains($flag) } )+ - } -} - impl<'le> ::selectors::Element for ServoLayoutElement<'le> { + type Impl = ServoSelectorImpl; + fn parent_element(&self) -> Option<ServoLayoutElement<'le>> { unsafe { self.element.upcast().parent_node_ref().and_then(as_element) @@ -531,34 +524,40 @@ impl<'le> ::selectors::Element for ServoLayoutElement<'le> { self.element.namespace() } - fn is_link(&self) -> bool { - // FIXME: This is HTML only. - let node = self.as_node(); - match node.type_id() { - // https://html.spec.whatwg.org/multipage/#selector-link - NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLAnchorElement)) | - NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLAreaElement)) | - NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLLinkElement)) => { - unsafe { - (*self.element.unsafe_get()).get_attr_val_for_layout(&ns!(), &atom!("href")).is_some() + fn match_non_ts_pseudo_class(&self, pseudo_class: NonTSPseudoClass) -> bool { + match pseudo_class { + // https://github.com/servo/servo/issues/8718 + NonTSPseudoClass::Link | + NonTSPseudoClass::AnyLink => unsafe { + match self.as_node().type_id() { + // https://html.spec.whatwg.org/multipage/#selector-link + NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLAnchorElement)) | + NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLAreaElement)) | + NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLLinkElement)) => + (*self.element.unsafe_get()).get_attr_val_for_layout(&ns!(), &atom!("href")).is_some(), + _ => false, } - } - _ => false, - } - } + }, + NonTSPseudoClass::Visited => false, - #[inline] - fn is_unvisited_link(&self) -> bool { - self.is_link() - } + NonTSPseudoClass::ServoNonZeroBorder => unsafe { + match (*self.element.unsafe_get()).get_attr_for_layout(&ns!(), &atom!("border")) { + None | Some(&AttrValue::UInt(_, 0)) => false, + _ => true, + } + }, - #[inline] - fn is_visited_link(&self) -> bool { - false + NonTSPseudoClass::Active | + NonTSPseudoClass::Focus | + NonTSPseudoClass::Hover | + NonTSPseudoClass::Enabled | + NonTSPseudoClass::Disabled | + NonTSPseudoClass::Checked | + NonTSPseudoClass::Indeterminate => + self.element.get_state_for_layout().contains(pseudo_class.state_flag()) + } } - state_pseudo_classes!(state_getter); - #[inline] fn get_id(&self) -> Option<Atom> { unsafe { @@ -576,27 +575,14 @@ impl<'le> ::selectors::Element for ServoLayoutElement<'le> { #[inline(always)] fn each_class<F>(&self, mut callback: F) where F: FnMut(&Atom) { unsafe { - match self.element.get_classes_for_layout() { - None => {} - Some(ref classes) => { - for class in *classes { - callback(class) - } + if let Some(ref classes) = self.element.get_classes_for_layout() { + for class in *classes { + callback(class) } } } } - #[inline] - fn has_servo_nonzero_border(&self) -> bool { - unsafe { - match (*self.element.unsafe_get()).get_attr_for_layout(&ns!(), &atom!("border")) { - None | Some(&AttrValue::UInt(_, 0)) => false, - _ => true, - } - } - } - fn match_attr<F>(&self, attr: &AttrSelector, test: F) -> bool where F: Fn(&str) -> bool { let name = if self.is_html_element_in_html_document() { &attr.lower_name diff --git a/components/script/Cargo.toml b/components/script/Cargo.toml index c3754adf3fe..a6f8bc2f0c6 100644 --- a/components/script/Cargo.toml +++ b/components/script/Cargo.toml @@ -79,7 +79,7 @@ websocket = "0.14.0" uuid = "0.1.16" smallvec = "0.1" html5ever = { version = "0.4", features = ["unstable"] } -selectors = "0.2" +selectors = "0.4.1" string_cache = { version = "0.2", features = ["unstable"] } euclid = {version = "0.4", features = ["plugins"]} rand = "0.3" diff --git a/components/script/dom/bindings/trace.rs b/components/script/dom/bindings/trace.rs index e62bd5d9583..1362731339a 100644 --- a/components/script/dom/bindings/trace.rs +++ b/components/script/dom/bindings/trace.rs @@ -65,8 +65,6 @@ use profile_traits::mem::ProfilerChan as MemProfilerChan; use profile_traits::time::ProfilerChan as TimeProfilerChan; use script_thread::ScriptChan; use script_traits::{LayoutMsg, ScriptMsg, TimerEventId, TimerSource, UntrustedNodeAddress}; -use selectors::parser::PseudoElement; -use selectors::states::*; use serde::{Deserialize, Serialize}; use smallvec::SmallVec; use std::boxed::FnBox; @@ -84,8 +82,10 @@ use std::sync::atomic::AtomicBool; use std::sync::mpsc::{Receiver, Sender}; use string_cache::{Atom, Namespace, QualName}; use style::attr::{AttrIdentifier, AttrValue}; +use style::element_state::*; use style::properties::PropertyDeclarationBlock; use style::restyle_hints::ElementSnapshot; +use style::selector_impl::PseudoElement; use style::values::specified::Length; use url::Url; use util::str::{DOMString, LengthOrPercentageOrAuto}; diff --git a/components/script/dom/cssstyledeclaration.rs b/components/script/dom/cssstyledeclaration.rs index 479d2e00f95..f6683f9eae5 100644 --- a/components/script/dom/cssstyledeclaration.rs +++ b/components/script/dom/cssstyledeclaration.rs @@ -11,7 +11,6 @@ use dom::bindings::reflector::{Reflector, reflect_dom_object}; use dom::element::{Element, StylePriority}; use dom::node::{Node, NodeDamage, document_from_node, window_from_node}; use dom::window::Window; -use selectors::parser::PseudoElement; use std::ascii::AsciiExt; use std::borrow::ToOwned; use std::cell::Ref; @@ -19,6 +18,7 @@ use string_cache::Atom; use style::error_reporting::ParseErrorReporter; use style::properties::{PropertyDeclaration, Shorthand}; use style::properties::{is_supported_property, parse_one_declaration}; +use style::selector_impl::PseudoElement; use util::str::{DOMString, str_join}; // http://dev.w3.org/csswg/cssom/#the-cssstyledeclaration-interface diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs index 66cad82dbb8..d093380b008 100644 --- a/components/script/dom/element.rs +++ b/components/script/dom/element.rs @@ -68,7 +68,6 @@ use html5ever::tree_builder::{LimitedQuirks, NoQuirks, Quirks}; use selectors::matching::{DeclarationBlock, matches}; use selectors::matching::{common_style_affecting_attributes, rare_style_affecting_attributes}; use selectors::parser::{AttrSelector, NamespaceConstraint, parse_author_origin_selector_list_from_str}; -use selectors::states::*; use smallvec::VecLike; use std::ascii::AsciiExt; use std::borrow::Cow; @@ -77,10 +76,12 @@ use std::default::Default; use std::mem; use std::sync::Arc; use string_cache::{Atom, Namespace, QualName}; +use style::element_state::*; use style::error_reporting::ParseErrorReporter; use style::properties::DeclaredValue; use style::properties::longhands::{self, background_image, border_spacing, font_family, font_size}; use style::properties::{PropertyDeclaration, PropertyDeclarationBlock, parse_style_attribute}; +use style::selector_impl::{NonTSPseudoClass, ServoSelectorImpl}; use style::values::CSSFloat; use style::values::specified::{self, CSSColor, CSSRGBA, LengthOrPercentage}; use util::mem::HeapSizeOf; @@ -1689,17 +1690,9 @@ impl VirtualMethods for Element { } } -macro_rules! state_getter { - ($( - $(#[$Flag_attr: meta])* - state $css: expr => $variant: ident / $method: ident / - $flag: ident = $value: expr, - )+) => { - $( fn $method(&self) -> bool { Element::get_state(self).contains($flag) } )+ - } -} - impl<'a> ::selectors::Element for Root<Element> { + type Impl = ServoSelectorImpl; + fn parent_element(&self) -> Option<Root<Element>> { self.upcast::<Node>().GetParentElement() } @@ -1734,46 +1727,52 @@ impl<'a> ::selectors::Element for Root<Element> { }) } - fn is_link(&self) -> bool { - // FIXME: This is HTML only. - let node = self.upcast::<Node>(); - match node.type_id() { - // https://html.spec.whatwg.org/multipage/#selector-link - NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLAnchorElement)) | - NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLAreaElement)) | - NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLLinkElement)) => { - self.has_attribute(&atom!("href")) - }, - _ => false, - } - } - - #[inline] - fn is_unvisited_link(&self) -> bool { - self.is_link() - } - - #[inline] - fn is_visited_link(&self) -> bool { - // https://github.com/servo/servo/issues/8718 - false - } - fn get_local_name(&self) -> &Atom { self.local_name() } + fn get_namespace(&self) -> &Namespace { self.namespace() } - state_pseudo_classes!(state_getter); + fn match_non_ts_pseudo_class(&self, pseudo_class: NonTSPseudoClass) -> bool { + match pseudo_class { + // https://github.com/servo/servo/issues/8718 + NonTSPseudoClass::Link | + NonTSPseudoClass::AnyLink => self.is_link(), + NonTSPseudoClass::Visited => false, + + NonTSPseudoClass::ServoNonZeroBorder => { + match self.downcast::<HTMLTableElement>() { + None => false, + Some(this) => { + match this.get_border() { + None | Some(0) => false, + Some(_) => true, + } + } + } + }, + + NonTSPseudoClass::Active | + NonTSPseudoClass::Focus | + NonTSPseudoClass::Hover | + NonTSPseudoClass::Enabled | + NonTSPseudoClass::Disabled | + NonTSPseudoClass::Checked | + NonTSPseudoClass::Indeterminate => + Element::get_state(self).contains(pseudo_class.state_flag()), + } + } fn get_id(&self) -> Option<Atom> { self.id_attribute.borrow().clone() } + fn has_class(&self, name: &Atom) -> bool { Element::has_class(&**self, name) } + fn each_class<F>(&self, mut callback: F) where F: FnMut(&Atom) { @@ -1785,17 +1784,6 @@ impl<'a> ::selectors::Element for Root<Element> { } } } - fn has_servo_nonzero_border(&self) -> bool { - match self.downcast::<HTMLTableElement>() { - None => false, - Some(this) => { - match this.get_border() { - None | Some(0) => false, - Some(_) => true, - } - } - } - } fn match_attr<F>(&self, attr: &AttrSelector, test: F) -> bool where F: Fn(&str) -> bool @@ -1886,6 +1874,20 @@ impl Element { } } + fn is_link(&self) -> bool { + // FIXME: This is HTML only. + let node = self.upcast::<Node>(); + match node.type_id() { + // https://html.spec.whatwg.org/multipage/#selector-link + NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLAnchorElement)) | + NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLAreaElement)) | + NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLLinkElement)) => { + self.has_attribute(&atom!("href")) + }, + _ => false, + } + } + /// Please call this method *only* for real click events /// /// https://html.spec.whatwg.org/multipage/#run-authentic-click-activation-steps diff --git a/components/script/dom/htmlbuttonelement.rs b/components/script/dom/htmlbuttonelement.rs index 5a8ffaf0df6..31d4b0a8740 100644 --- a/components/script/dom/htmlbuttonelement.rs +++ b/components/script/dom/htmlbuttonelement.rs @@ -20,10 +20,10 @@ use dom::node::{Node, UnbindContext, document_from_node, window_from_node}; use dom::nodelist::NodeList; use dom::validitystate::ValidityState; use dom::virtualmethods::VirtualMethods; -use selectors::states::*; use std::ascii::AsciiExt; use std::cell::Cell; use string_cache::Atom; +use style::element_state::*; use util::str::DOMString; #[derive(JSTraceable, PartialEq, Copy, Clone)] diff --git a/components/script/dom/htmlelement.rs b/components/script/dom/htmlelement.rs index f0348c27b76..ce5d9a1f27a 100644 --- a/components/script/dom/htmlelement.rs +++ b/components/script/dom/htmlelement.rs @@ -30,13 +30,13 @@ use dom::node::{Node, SEQUENTIALLY_FOCUSABLE}; use dom::node::{document_from_node, window_from_node}; use dom::nodelist::NodeList; use dom::virtualmethods::VirtualMethods; -use selectors::states::*; use std::ascii::AsciiExt; use std::borrow::ToOwned; use std::default::Default; use std::intrinsics; use std::rc::Rc; use string_cache::Atom; +use style::element_state::*; use util::str::DOMString; #[dom_struct] diff --git a/components/script/dom/htmlfieldsetelement.rs b/components/script/dom/htmlfieldsetelement.rs index 009f9f93282..0390d9aa599 100644 --- a/components/script/dom/htmlfieldsetelement.rs +++ b/components/script/dom/htmlfieldsetelement.rs @@ -16,8 +16,8 @@ use dom::htmllegendelement::HTMLLegendElement; use dom::node::{Node, window_from_node}; use dom::validitystate::ValidityState; use dom::virtualmethods::VirtualMethods; -use selectors::states::*; use string_cache::Atom; +use style::element_state::*; use util::str::DOMString; #[dom_struct] diff --git a/components/script/dom/htmlinputelement.rs b/components/script/dom/htmlinputelement.rs index 368285f8a9f..e7116b5d8ce 100644 --- a/components/script/dom/htmlinputelement.rs +++ b/components/script/dom/htmlinputelement.rs @@ -32,10 +32,10 @@ use msg::constellation_msg::ConstellationChan; use script_thread::ScriptThreadEventCategory::InputEvent; use script_thread::{CommonScriptMsg, Runnable}; use script_traits::ScriptMsg as ConstellationMsg; -use selectors::states::*; use std::borrow::ToOwned; use std::cell::Cell; use string_cache::Atom; +use style::element_state::*; use textinput::KeyReaction::{DispatchInput, Nothing, RedrawSelection, TriggerDefaultAction}; use textinput::Lines::Single; use textinput::TextInput; diff --git a/components/script/dom/htmloptgroupelement.rs b/components/script/dom/htmloptgroupelement.rs index b0624d426f9..a554377ea7a 100644 --- a/components/script/dom/htmloptgroupelement.rs +++ b/components/script/dom/htmloptgroupelement.rs @@ -13,8 +13,8 @@ use dom::htmlelement::HTMLElement; use dom::htmloptionelement::HTMLOptionElement; use dom::node::Node; use dom::virtualmethods::VirtualMethods; -use selectors::states::*; use string_cache::Atom; +use style::element_state::*; use util::str::DOMString; #[dom_struct] diff --git a/components/script/dom/htmloptionelement.rs b/components/script/dom/htmloptionelement.rs index 3e6019384ab..cd521702a34 100644 --- a/components/script/dom/htmloptionelement.rs +++ b/components/script/dom/htmloptionelement.rs @@ -18,9 +18,9 @@ use dom::htmlselectelement::HTMLSelectElement; use dom::node::{Node, UnbindContext}; use dom::text::Text; use dom::virtualmethods::VirtualMethods; -use selectors::states::*; use std::cell::Cell; use string_cache::Atom; +use style::element_state::*; use util::str::{DOMString, split_html_space_chars, str_join}; #[dom_struct] diff --git a/components/script/dom/htmlselectelement.rs b/components/script/dom/htmlselectelement.rs index 6db068d6da2..1b5ddb22183 100644 --- a/components/script/dom/htmlselectelement.rs +++ b/components/script/dom/htmlselectelement.rs @@ -20,8 +20,8 @@ use dom::node::{Node, UnbindContext, window_from_node}; use dom::nodelist::NodeList; use dom::validitystate::ValidityState; use dom::virtualmethods::VirtualMethods; -use selectors::states::*; use string_cache::Atom; +use style::element_state::*; use util::str::DOMString; #[dom_struct] diff --git a/components/script/dom/htmltextareaelement.rs b/components/script/dom/htmltextareaelement.rs index 95f1438f6e3..dfcfdc77f73 100644 --- a/components/script/dom/htmltextareaelement.rs +++ b/components/script/dom/htmltextareaelement.rs @@ -26,9 +26,9 @@ use dom::nodelist::NodeList; use dom::virtualmethods::VirtualMethods; use msg::constellation_msg::ConstellationChan; use script_traits::ScriptMsg as ConstellationMsg; -use selectors::states::*; use std::cell::Cell; use string_cache::Atom; +use style::element_state::*; use textinput::{KeyReaction, Lines, TextInput}; use util::str::DOMString; diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs index 33dadfe527b..9c4e52b495d 100644 --- a/components/script/dom/node.rs +++ b/components/script/dom/node.rs @@ -63,6 +63,7 @@ use std::default::Default; use std::iter::{self, FilterMap, Peekable}; use std::mem; use string_cache::{Atom, Namespace, QualName}; +use style::selector_impl::ServoSelectorImpl; use util::str::DOMString; use util::thread_state; use uuid::Uuid; @@ -291,12 +292,12 @@ impl Node { } pub struct QuerySelectorIterator { - selectors: Vec<Selector>, + selectors: Vec<Selector<ServoSelectorImpl>>, iterator: TreeIterator, } impl<'a> QuerySelectorIterator { - fn new(iter: TreeIterator, selectors: Vec<Selector>) + fn new(iter: TreeIterator, selectors: Vec<Selector<ServoSelectorImpl>>) -> QuerySelectorIterator { QuerySelectorIterator { selectors: selectors, diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs index 2ca2090e547..c8ea1d9f0f8 100644 --- a/components/script/dom/window.rs +++ b/components/script/dom/window.rs @@ -58,7 +58,6 @@ use script_thread::{HistoryTraversalThreadSource, FileReadingThreadSource, Senda use script_thread::{ScriptChan, ScriptPort, MainThreadScriptChan, MainThreadScriptMsg, RunnableWrapper}; use script_traits::{DocumentState, MsDuration, ScriptToCompositorMsg, TimerEvent, TimerEventId}; use script_traits::{MozBrowserEvent, ScriptMsg as ConstellationMsg, TimerEventRequest, TimerSource}; -use selectors::parser::PseudoElement; use std::ascii::AsciiExt; use std::borrow::ToOwned; use std::cell::Cell; @@ -74,6 +73,7 @@ use std::sync::mpsc::{Sender, channel}; use string_cache::Atom; use style::context::ReflowGoal; use style::error_reporting::ParseErrorReporter; +use style::selector_impl::PseudoElement; use time; use timers::{ActiveTimers, IsInterval, ScheduledCallback, TimerCallback, TimerHandle}; use url::Url; diff --git a/components/script/layout_interface.rs b/components/script/layout_interface.rs index 7c555efcca6..c759b358e79 100644 --- a/components/script/layout_interface.rs +++ b/components/script/layout_interface.rs @@ -18,12 +18,12 @@ use net_traits::image_cache_thread::ImageCacheThread; use profile_traits::mem::ReportsChan; use script_traits::{ConstellationControlMsg, LayoutControlMsg, LayoutMsg as ConstellationMsg}; use script_traits::{OpaqueScriptLayoutChannel, UntrustedNodeAddress}; -use selectors::parser::PseudoElement; use std::any::Any; use std::sync::Arc; use std::sync::mpsc::{Receiver, Sender, channel}; use string_cache::Atom; use style::context::ReflowGoal; +use style::selector_impl::PseudoElement; use style::stylesheets::Stylesheet; use url::Url; use util::ipc::OptionalOpaqueIpcSender; diff --git a/components/script/lib.rs b/components/script/lib.rs index a776fe2d484..6365c03c5b7 100644 --- a/components/script/lib.rs +++ b/components/script/lib.rs @@ -60,7 +60,7 @@ extern crate rand; extern crate ref_slice; extern crate rustc_serialize; extern crate script_traits; -#[macro_use(state_pseudo_classes)] extern crate selectors; +extern crate selectors; extern crate serde; extern crate smallvec; #[macro_use(atom, ns)] extern crate string_cache; diff --git a/components/servo/Cargo.lock b/components/servo/Cargo.lock index 1124ec68945..bc6734ab33d 100644 --- a/components/servo/Cargo.lock +++ b/components/servo/Cargo.lock @@ -971,7 +971,7 @@ dependencies = [ "rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", "script 0.0.1", "script_traits 0.0.1", - "selectors 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "selectors 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde_macros 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1530,7 +1530,7 @@ dependencies = [ "ref_slice 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", "script_traits 0.0.1", - "selectors 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "selectors 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "string_cache 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1579,7 +1579,7 @@ dependencies = [ [[package]] name = "selectors" -version = "0.2.3" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1782,7 +1782,7 @@ dependencies = [ "num 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "plugins 0.0.1", "rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", - "selectors 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "selectors 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde_macros 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1802,7 +1802,7 @@ dependencies = [ "euclid 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "msg 0.0.1", "plugins 0.0.1", - "selectors 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "selectors 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "string_cache 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", "style 0.0.1", "style_traits 0.0.1", @@ -1821,7 +1821,7 @@ dependencies = [ "num 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "plugins 0.0.1", "rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", - "selectors 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "selectors 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde_macros 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "url 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1977,7 +1977,7 @@ dependencies = [ "plugins 0.0.1", "rand 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", - "selectors 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "selectors 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde_macros 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/components/style/Cargo.toml b/components/style/Cargo.toml index 0fa4d69caa4..77463e3e6d8 100644 --- a/components/style/Cargo.toml +++ b/components/style/Cargo.toml @@ -29,7 +29,7 @@ matches = "0.1" bitflags = "0.3" num = "0.1.24" lazy_static = "0.1.10" -selectors = { version = "0.2", features = ["unstable"] } +selectors = { version = "0.4.1", features = ["unstable"] } smallvec = "0.1" string_cache = "0.2" euclid = {version = "0.4", features = ["plugins"]} diff --git a/components/style/dom.rs b/components/style/dom.rs index ce538f1b21f..9b0ce59167d 100644 --- a/components/style/dom.rs +++ b/components/style/dom.rs @@ -5,10 +5,11 @@ #![allow(unsafe_code)] use data::PrivateStyleData; +use element_state::ElementState; use properties::{ComputedValues, PropertyDeclaration, PropertyDeclarationBlock}; use restyle_hints::{ElementSnapshot, RESTYLE_DESCENDANTS, RESTYLE_LATER_SIBLINGS, RESTYLE_SELF, RestyleHint}; +use selector_impl::ServoSelectorImpl; use selectors::matching::DeclarationBlock; -use selectors::states::ElementState; use smallvec::VecLike; use std::cell::{Ref, RefMut}; use std::marker::PhantomData; @@ -185,7 +186,7 @@ pub trait TDocument<'ld> : Sized + Copy + Clone { fn drain_modified_elements(&self) -> Vec<(Self::ConcreteElement, ElementSnapshot)>; } -pub trait TElement<'le> : Sized + Copy + Clone + ::selectors::Element { +pub trait TElement<'le> : Sized + Copy + Clone + ::selectors::Element<Impl=ServoSelectorImpl> { type ConcreteNode: TNode<'le, ConcreteElement = Self, ConcreteDocument = Self::ConcreteDocument>; type ConcreteDocument: TDocument<'le, ConcreteNode = Self::ConcreteNode, ConcreteElement = Self>; diff --git a/components/style/element_state.rs b/components/style/element_state.rs new file mode 100644 index 00000000000..41846085fc8 --- /dev/null +++ b/components/style/element_state.rs @@ -0,0 +1,31 @@ +/* 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/. */ + +bitflags! { + #[doc = "Event-based element states."] + #[derive(HeapSizeOf)] + flags ElementState: u8 { + #[doc = "The mouse is down on this element. \ + https://html.spec.whatwg.org/multipage/#selector-active \ + FIXME(#7333): set/unset this when appropriate"] + const IN_ACTIVE_STATE = 0x01, + #[doc = "This element has focus. \ + https://html.spec.whatwg.org/multipage/#selector-focus"] + const IN_FOCUS_STATE = 0x02, + #[doc = "The mouse is hovering over this element. \ + https://html.spec.whatwg.org/multipage/#selector-hover"] + const IN_HOVER_STATE = 0x04, + #[doc = "Content is enabled (and can be disabled). \ + http://www.whatwg.org/html/#selector-enabled"] + const IN_ENABLED_STATE = 0x08, + #[doc = "Content is disabled. \ + http://www.whatwg.org/html/#selector-disabled"] + const IN_DISABLED_STATE = 0x10, + #[doc = "Content is checked. \ + https://html.spec.whatwg.org/multipage/#selector-checked"] + const IN_CHECKED_STATE = 0x20, + #[doc = "https://html.spec.whatwg.org/multipage/#selector-indeterminate"] + const IN_INDETERMINATE_STATE = 0x40, + } +} diff --git a/components/style/lib.rs b/components/style/lib.rs index f9e26d670c0..dee1d51efc6 100644 --- a/components/style/lib.rs +++ b/components/style/lib.rs @@ -34,7 +34,7 @@ extern crate log; extern crate matches; extern crate num; extern crate rustc_serialize; -#[macro_use(state_pseudo_classes)] extern crate selectors; +extern crate selectors; extern crate serde; extern crate smallvec; #[macro_use(atom, ns)] extern crate string_cache; @@ -50,6 +50,7 @@ pub mod context; mod custom_properties; pub mod data; pub mod dom; +pub mod element_state; pub mod error_reporting; pub mod font_face; pub mod matching; @@ -57,6 +58,7 @@ pub mod media_queries; pub mod parallel; pub mod parser; pub mod restyle_hints; +pub mod selector_impl; pub mod selector_matching; pub mod sequential; pub mod stylesheets; diff --git a/components/style/matching.rs b/components/style/matching.rs index ea25d518a99..0e7ee4b6453 100644 --- a/components/style/matching.rs +++ b/components/style/matching.rs @@ -9,12 +9,12 @@ use context::SharedStyleContext; use data::PrivateStyleData; use dom::{TElement, TNode, TRestyleDamage}; use properties::{ComputedValues, PropertyDeclaration, cascade}; +use selector_impl::{NonTSPseudoClass, PseudoElement}; use selector_matching::{DeclarationBlock, Stylist}; use selectors::Element; use selectors::bloom::BloomFilter; use selectors::matching::{CommonStyleAffectingAttributeMode, CommonStyleAffectingAttributes}; use selectors::matching::{common_style_affecting_attributes, rare_style_affecting_attributes}; -use selectors::parser::PseudoElement; use smallvec::SmallVec; use std::hash::{Hash, Hasher}; use std::slice::Iter; @@ -246,7 +246,7 @@ impl StyleSharingCandidate { local_name: element.get_local_name().clone(), class: element.get_attr(&ns!(), &atom!("class")) .map(|string| string.to_owned()), - link: element.is_link(), + link: element.match_non_ts_pseudo_class(NonTSPseudoClass::AnyLink), namespace: (*element.get_namespace()).clone(), common_style_affecting_attributes: create_common_style_affecting_attributes_from_element::<'le, E>(&element) @@ -314,7 +314,7 @@ impl StyleSharingCandidate { } } - if element.is_link() != self.link { + if element.match_non_ts_pseudo_class(NonTSPseudoClass::AnyLink) != self.link { return false } diff --git a/components/style/restyle_hints.rs b/components/style/restyle_hints.rs index e1b1b477201..1eaccff91e0 100644 --- a/components/style/restyle_hints.rs +++ b/components/style/restyle_hints.rs @@ -3,10 +3,11 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use attr::{AttrIdentifier, AttrValue}; +use element_state::*; +use selector_impl::{NonTSPseudoClass, ServoSelectorImpl}; use selectors::Element; use selectors::matching::matches_compound_selector; use selectors::parser::{AttrSelector, Combinator, CompoundSelector, NamespaceConstraint, SimpleSelector}; -use selectors::states::*; use std::clone::Clone; use std::sync::Arc; use string_cache::{Atom, Namespace}; @@ -92,24 +93,20 @@ impl<'a, E> ElementWrapper<'a, E> where E: Element { } } -macro_rules! snapshot_state_accessors { - ($( - $(#[$Flag_attr: meta])* - state $css: expr => $variant: ident / $method: ident / - $flag: ident = $value: expr, - )+) => { $( fn $method(&self) -> bool { - match self.snapshot.state { - Some(s) => s.contains($flag), - None => self.element.$method() +impl<'a, E> Element for ElementWrapper<'a, E> where E: Element<Impl=ServoSelectorImpl> { + type Impl = E::Impl; + + fn match_non_ts_pseudo_class(&self, pseudo_class: NonTSPseudoClass) -> bool { + let flag = pseudo_class.state_flag(); + if flag == ElementState::empty() { + self.element.match_non_ts_pseudo_class(pseudo_class) + } else { + match self.snapshot.state { + Some(s) => s.contains(pseudo_class.state_flag()), + None => self.element.match_non_ts_pseudo_class(pseudo_class) + } } - } )+ } -} - -impl<'a, E> Element for ElementWrapper<'a, E> where E: Element { - - // Implement the state accessors on Element to use the snapshot state if it exists. - state_pseudo_classes!(snapshot_state_accessors); fn parent_element(&self) -> Option<Self> { self.element.parent_element().map(ElementWrapper::new) @@ -168,15 +165,6 @@ impl<'a, E> Element for ElementWrapper<'a, E> where E: Element { fn is_root(&self) -> bool { self.element.is_root() } - fn is_link(&self) -> bool { - self.element.is_link() - } - fn is_visited_link(&self) -> bool { - self.element.is_visited_link() - } - fn is_unvisited_link(&self) -> bool { - self.element.is_unvisited_link() - } fn each_class<F>(&self, mut callback: F) where F: FnMut(&Atom) { match self.snapshot.attrs { Some(_) => { @@ -189,24 +177,14 @@ impl<'a, E> Element for ElementWrapper<'a, E> where E: Element { } } -macro_rules! gen_selector_to_state { - ($( - $(#[$Flag_attr: meta])* - state $css: expr => $variant: ident / $method: ident / - $flag: ident = $value: expr, - )+) => { - fn selector_to_state(sel: &SimpleSelector) -> ElementState { - match *sel { - $( SimpleSelector::$variant => $flag, )+ - _ => ElementState::empty(), - } - } +fn selector_to_state(sel: &SimpleSelector<ServoSelectorImpl>) -> ElementState { + match *sel { + SimpleSelector::NonTSPseudoClass(ref pc) => pc.state_flag(), + _ => ElementState::empty(), } } -state_pseudo_classes!(gen_selector_to_state); - -fn is_attr_selector(sel: &SimpleSelector) -> bool { +fn is_attr_selector(sel: &SimpleSelector<ServoSelectorImpl>) -> bool { match *sel { SimpleSelector::ID(_) | SimpleSelector::Class(_) | @@ -272,7 +250,7 @@ impl Sensitivities { // elements in the document. #[derive(Debug)] struct Dependency { - selector: Arc<CompoundSelector>, + selector: Arc<CompoundSelector<ServoSelectorImpl>>, combinator: Option<Combinator>, sensitivities: Sensitivities, } @@ -288,7 +266,8 @@ impl DependencySet { } pub fn compute_hint<E>(&self, el: &E, snapshot: &ElementSnapshot, current_state: ElementState) - -> RestyleHint where E: Element, E: Clone { + -> RestyleHint + where E: Element<Impl=ServoSelectorImpl> + Clone { let state_changes = snapshot.state.map_or(ElementState::empty(), |old_state| current_state ^ old_state); let attrs_changed = snapshot.attrs.is_some(); let mut hint = RestyleHint::empty(); @@ -308,7 +287,7 @@ impl DependencySet { hint } - pub fn note_selector(&mut self, selector: Arc<CompoundSelector>) { + pub fn note_selector(&mut self, selector: Arc<CompoundSelector<ServoSelectorImpl>>) { let mut cur = selector; let mut combinator: Option<Combinator> = None; loop { diff --git a/components/style/selector_impl.rs b/components/style/selector_impl.rs new file mode 100644 index 00000000000..74f2bcde91b --- /dev/null +++ b/components/style/selector_impl.rs @@ -0,0 +1,91 @@ +/* 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/. */ +use element_state::ElementState; +use selectors::parser::{ParserContext, SelectorImpl}; + +#[derive(Clone, Debug, PartialEq, HeapSizeOf)] +pub enum PseudoElement { + Before, + After, +} + +#[derive(Clone, Debug, PartialEq, HeapSizeOf)] +pub enum NonTSPseudoClass { + AnyLink, + Link, + Visited, + Active, + Focus, + Hover, + Enabled, + Disabled, + Checked, + Indeterminate, + ServoNonZeroBorder, +} + +impl NonTSPseudoClass { + pub fn state_flag(&self) -> ElementState { + use element_state::*; + use self::NonTSPseudoClass::*; + match *self { + Active => IN_ACTIVE_STATE, + Focus => IN_FOCUS_STATE, + Hover => IN_HOVER_STATE, + Enabled => IN_ENABLED_STATE, + Disabled => IN_DISABLED_STATE, + Checked => IN_CHECKED_STATE, + Indeterminate => IN_INDETERMINATE_STATE, + + AnyLink | + Link | + Visited | + ServoNonZeroBorder => ElementState::empty(), + } + } +} + +#[derive(Clone, Debug, PartialEq, HeapSizeOf)] +pub struct ServoSelectorImpl; + +impl SelectorImpl for ServoSelectorImpl { + type PseudoElement = PseudoElement; + type NonTSPseudoClass = NonTSPseudoClass; + + fn parse_non_ts_pseudo_class(context: &ParserContext, + name: &str) -> Result<NonTSPseudoClass, ()> { + use self::NonTSPseudoClass::*; + let pseudo_class = match_ignore_ascii_case! { name, + "any-link" => AnyLink, + "link" => Link, + "visited" => Visited, + "active" => Active, + "focus" => Focus, + "hover" => Hover, + "enabled" => Enabled, + "disabled" => Disabled, + "checked" => Checked, + "indeterminate" => Indeterminate, + "-servo-nonzero-border" => { + if !context.in_user_agent_stylesheet { + return Err(()); + } + ServoNonZeroBorder + }, + _ => return Err(()) + }; + + Ok(pseudo_class) + } + + fn parse_pseudo_element(_context: &ParserContext, + name: &str) -> Result<PseudoElement, ()> { + use self::PseudoElement::*; + match_ignore_ascii_case! { name, + "before" => Ok(Before), + "after" => Ok(After), + _ => Err(()) + } + } +} diff --git a/components/style/selector_matching.rs b/components/style/selector_matching.rs index 27b1bdde118..6fe34195b90 100644 --- a/components/style/selector_matching.rs +++ b/components/style/selector_matching.rs @@ -6,16 +6,16 @@ #![allow(unsafe_code)] use dom::TElement; +use element_state::*; use error_reporting::{ParseErrorReporter, StdoutErrorReporter}; use media_queries::{Device, MediaType}; use properties::{PropertyDeclaration, PropertyDeclarationBlock}; use restyle_hints::{ElementSnapshot, RestyleHint, DependencySet}; +use selector_impl::{PseudoElement, ServoSelectorImpl}; use selectors::Element; use selectors::bloom::BloomFilter; use selectors::matching::DeclarationBlock as GenericDeclarationBlock; use selectors::matching::{Rule, SelectorMap}; -use selectors::parser::PseudoElement; -use selectors::states::*; use smallvec::VecLike; use std::process; use std::sync::Arc; @@ -216,7 +216,7 @@ impl Stylist { // more expensive than getting it directly from the caller. current_state: ElementState) -> RestyleHint - where E: Element + Clone { + where E: Element<Impl=ServoSelectorImpl> + Clone { self.state_deps.compute_hint(element, snapshot, current_state) } @@ -337,8 +337,8 @@ impl Stylist { } struct PerOriginSelectorMap { - normal: SelectorMap<Vec<PropertyDeclaration>>, - important: SelectorMap<Vec<PropertyDeclaration>>, + normal: SelectorMap<Vec<PropertyDeclaration>, ServoSelectorImpl>, + important: SelectorMap<Vec<PropertyDeclaration>, ServoSelectorImpl>, } impl PerOriginSelectorMap { diff --git a/components/style/stylesheets.rs b/components/style/stylesheets.rs index d8121b2fa6c..ce21cf68522 100644 --- a/components/style/stylesheets.rs +++ b/components/style/stylesheets.rs @@ -10,6 +10,7 @@ use font_face::{FontFaceRule, parse_font_face_block}; use media_queries::{Device, MediaQueryList, parse_media_query_list}; use parser::{ParserContext, log_css_error}; use properties::{PropertyDeclarationBlock, parse_property_declaration_list}; +use selector_impl::ServoSelectorImpl; use selectors::parser::{Selector, parse_selector_list}; use smallvec::SmallVec; use std::ascii::AsciiExt; @@ -74,7 +75,7 @@ impl MediaRule { #[derive(Debug, HeapSizeOf, PartialEq)] pub struct StyleRule { - pub selectors: Vec<Selector>, + pub selectors: Vec<Selector<ServoSelectorImpl>>, pub declarations: PropertyDeclarationBlock, } @@ -408,17 +409,17 @@ impl<'a> AtRuleParser for TopLevelRuleParser<'a> { impl<'a> QualifiedRuleParser for TopLevelRuleParser<'a> { - type Prelude = Vec<Selector>; + type Prelude = Vec<Selector<ServoSelectorImpl>>; type QualifiedRule = CSSRule; #[inline] - fn parse_prelude(&self, input: &mut Parser) -> Result<Vec<Selector>, ()> { + fn parse_prelude(&self, input: &mut Parser) -> Result<Vec<Selector<ServoSelectorImpl>>, ()> { self.state.set(State::Body); QualifiedRuleParser::parse_prelude(&NestedRuleParser { context: &self.context }, input) } #[inline] - fn parse_block(&self, prelude: Vec<Selector>, input: &mut Parser) -> Result<CSSRule, ()> { + fn parse_block(&self, prelude: Vec<Selector<ServoSelectorImpl>>, input: &mut Parser) -> Result<CSSRule, ()> { QualifiedRuleParser::parse_block(&NestedRuleParser { context: &self.context }, prelude, input) } @@ -475,14 +476,14 @@ impl<'a, 'b> AtRuleParser for NestedRuleParser<'a, 'b> { impl<'a, 'b> QualifiedRuleParser for NestedRuleParser<'a, 'b> { - type Prelude = Vec<Selector>; + type Prelude = Vec<Selector<ServoSelectorImpl>>; type QualifiedRule = CSSRule; - fn parse_prelude(&self, input: &mut Parser) -> Result<Vec<Selector>, ()> { + fn parse_prelude(&self, input: &mut Parser) -> Result<Vec<Selector<ServoSelectorImpl>>, ()> { parse_selector_list(&self.context.selector_context, input) } - fn parse_block(&self, prelude: Vec<Selector>, input: &mut Parser) -> Result<CSSRule, ()> { + fn parse_block(&self, prelude: Vec<Selector<ServoSelectorImpl>>, input: &mut Parser) -> Result<CSSRule, ()> { Ok(CSSRule::Style(StyleRule { selectors: prelude, declarations: parse_property_declaration_list(self.context, input) diff --git a/components/style_traits/Cargo.toml b/components/style_traits/Cargo.toml index 0fca4738abe..a3b771a5583 100644 --- a/components/style_traits/Cargo.toml +++ b/components/style_traits/Cargo.toml @@ -20,7 +20,7 @@ log = "0.3" lazy_static = "0.1.10" num = "0.1.24" rustc-serialize = "0.3" -selectors = "0.2" +selectors = "0.4.1" serde = "0.6" serde_macros = "0.6" url = "0.5.2" diff --git a/components/util/Cargo.toml b/components/util/Cargo.toml index bd26fcf7626..f111aa0e0ca 100644 --- a/components/util/Cargo.toml +++ b/components/util/Cargo.toml @@ -57,7 +57,7 @@ smallvec = "0.1" num_cpus = "0.2.2" num = "0.1.24" euclid = {version = "0.4", features = ["plugins"]} -selectors = "0.2.3" +selectors = "0.4.1" serde = "0.6" serde_macros = "0.6" string_cache = "0.2" diff --git a/components/util/mem.rs b/components/util/mem.rs index 6bfd910096a..b5654b24123 100644 --- a/components/util/mem.rs +++ b/components/util/mem.rs @@ -16,8 +16,7 @@ use libc::{c_void, size_t}; use logical_geometry::WritingMode; use rand::OsRng; use range::Range; -use selectors::parser::{Combinator, CompoundSelector, PseudoElement, Selector, SimpleSelector}; -use selectors::states::ElementState; +use selectors::parser::{Combinator, CompoundSelector, Selector, SimpleSelector, SelectorImpl}; use std::cell::{Cell, RefCell}; use std::collections::{HashMap, LinkedList}; use std::hash::{BuildHasher, Hash}; @@ -308,7 +307,9 @@ impl HeapSizeOf for () { } } -impl HeapSizeOf for Selector { +impl<T: SelectorImpl> HeapSizeOf for Selector<T> + where T::NonTSPseudoClass: HeapSizeOf, + T::PseudoElement: HeapSizeOf { fn heap_size_of_children(&self) -> usize { let &Selector { ref compound_selectors, ref pseudo_element, ref specificity } = self; compound_selectors.heap_size_of_children() + pseudo_element.heap_size_of_children() + @@ -316,23 +317,27 @@ impl HeapSizeOf for Selector { } } -impl HeapSizeOf for CompoundSelector { +impl<T: SelectorImpl> HeapSizeOf for CompoundSelector<T> + where T::NonTSPseudoClass: HeapSizeOf { fn heap_size_of_children(&self) -> usize { let &CompoundSelector { ref simple_selectors, ref next } = self; simple_selectors.heap_size_of_children() + next.heap_size_of_children() } } -impl HeapSizeOf for SimpleSelector { +impl<T: SelectorImpl> HeapSizeOf for SimpleSelector<T> + where T::NonTSPseudoClass: HeapSizeOf { fn heap_size_of_children(&self) -> usize { match *self { SimpleSelector::Negation(ref vec) => vec.heap_size_of_children(), SimpleSelector::AttrIncludes(_, ref str) | SimpleSelector::AttrPrefixMatch(_, ref str) | SimpleSelector::AttrSubstringMatch(_, ref str) | SimpleSelector::AttrSuffixMatch(_, ref str) - => str.heap_size_of_children(), + => str.heap_size_of_children(), SimpleSelector::AttrEqual(_, ref str, _) => str.heap_size_of_children(), - SimpleSelector::AttrDashMatch(_, ref first, ref second) => first.heap_size_of_children() - + second.heap_size_of_children(), + SimpleSelector::AttrDashMatch(_, ref first, ref second) + => first.heap_size_of_children() + second.heap_size_of_children(), + SimpleSelector::NonTSPseudoClass(ref pseudo_class) + => pseudo_class.heap_size_of_children(), // All other types come down to Atom, enum or i32, all 0 _ => 0 } @@ -351,5 +356,5 @@ known_heap_size!(0, Au, WritingMode, CSSParserColor, RGBA, Cursor, Matrix4, Qual known_heap_size!(0, PagePx, ViewportPx, OsRng); known_heap_size!(0, TokenSerializationType, LengthOrPercentageOrAuto); -known_heap_size!(0, ElementState, Combinator, PseudoElement, str); +known_heap_size!(0, Combinator, str); known_heap_size!(0, Uuid); diff --git a/ports/cef/Cargo.lock b/ports/cef/Cargo.lock index e11201e784e..eae654cc75f 100644 --- a/ports/cef/Cargo.lock +++ b/ports/cef/Cargo.lock @@ -930,7 +930,7 @@ dependencies = [ "rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", "script 0.0.1", "script_traits 0.0.1", - "selectors 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "selectors 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde_macros 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1454,7 +1454,7 @@ dependencies = [ "ref_slice 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", "script_traits 0.0.1", - "selectors 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "selectors 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "string_cache 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1494,7 +1494,7 @@ dependencies = [ [[package]] name = "selectors" -version = "0.2.3" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1732,7 +1732,7 @@ dependencies = [ "num 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "plugins 0.0.1", "rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", - "selectors 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "selectors 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde_macros 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1754,7 +1754,7 @@ dependencies = [ "num 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "plugins 0.0.1", "rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", - "selectors 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "selectors 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde_macros 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "url 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1910,7 +1910,7 @@ dependencies = [ "plugins 0.0.1", "rand 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", - "selectors 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "selectors 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde_macros 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/ports/geckolib/Cargo.lock b/ports/geckolib/Cargo.lock index 212a4a4eacf..2c53fea82c3 100644 --- a/ports/geckolib/Cargo.lock +++ b/ports/geckolib/Cargo.lock @@ -9,7 +9,7 @@ dependencies = [ "libc 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", - "selectors 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "selectors 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "string_cache 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", "style 0.0.1", @@ -312,7 +312,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "selectors" -version = "0.2.3" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -383,7 +383,7 @@ dependencies = [ "num 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "plugins 0.0.1", "rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", - "selectors 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "selectors 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde_macros 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -405,7 +405,7 @@ dependencies = [ "num 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "plugins 0.0.1", "rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", - "selectors 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "selectors 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde_macros 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "url 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -465,7 +465,7 @@ dependencies = [ "plugins 0.0.1", "rand 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", - "selectors 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "selectors 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde_macros 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/ports/geckolib/Cargo.toml b/ports/geckolib/Cargo.toml index fbf00f3c706..5624d3ff7f8 100644 --- a/ports/geckolib/Cargo.toml +++ b/ports/geckolib/Cargo.toml @@ -16,7 +16,7 @@ euclid = {version = "0.4", features = ["plugins"]} libc = "0.2" log = "0.3" num_cpus = "0.2.2" -selectors = "0.2" +selectors = "0.4.1" smallvec = "0.1" string_cache = "0.2" url = "0.5.2" diff --git a/ports/geckolib/lib.rs b/ports/geckolib/lib.rs index 64be8072437..d1548b7fd94 100644 --- a/ports/geckolib/lib.rs +++ b/ports/geckolib/lib.rs @@ -13,7 +13,6 @@ extern crate cssparser; extern crate euclid; extern crate libc; extern crate num_cpus; -#[macro_use(state_pseudo_classes)] extern crate selectors; extern crate smallvec; #[macro_use(atom, ns)] diff --git a/ports/geckolib/wrapper.rs b/ports/geckolib/wrapper.rs index a4d97c8a17c..41b2b3ab1bc 100644 --- a/ports/geckolib/wrapper.rs +++ b/ports/geckolib/wrapper.rs @@ -17,7 +17,6 @@ use bindings::{ServoNodeData}; use libc::uintptr_t; use selectors::matching::DeclarationBlock; use selectors::parser::{AttrSelector, NamespaceConstraint}; -use selectors::states::*; use smallvec::VecLike; use std::cell::{Ref, RefCell, RefMut}; use std::marker::PhantomData; @@ -28,12 +27,14 @@ use std::sync::Arc; use string_cache::{Atom, Namespace}; use style::data::PrivateStyleData; use style::dom::{OpaqueNode, TDocument, TElement, TNode, TRestyleDamage, UnsafeNode}; +use style::element_state::ElementState; #[allow(unused_imports)] // Used in commented-out code. use style::error_reporting::StdoutErrorReporter; use style::properties::{ComputedValues, PropertyDeclaration, PropertyDeclarationBlock}; #[allow(unused_imports)] // Used in commented-out code. use style::properties::{parse_style_attribute}; use style::restyle_hints::ElementSnapshot; +use style::selector_impl::{NonTSPseudoClass, ServoSelectorImpl}; #[allow(unused_imports)] // Used in commented-out code. use url::Url; @@ -351,17 +352,9 @@ impl<'le> TElement<'le> for GeckoElement<'le> { } } -macro_rules! state_getter { - ($( - $(#[$Flag_attr: meta])* - state $css: expr => $variant: ident / $method: ident / - $flag: ident = $value: expr, - )+) => { - $( fn $method(&self) -> bool { self.get_state().contains($flag) } )+ - } -} - impl<'le> ::selectors::Element for GeckoElement<'le> { + type Impl = ServoSelectorImpl; + fn parent_element(&self) -> Option<Self> { unimplemented!() } @@ -412,26 +405,29 @@ impl<'le> ::selectors::Element for GeckoElement<'le> { */ } - fn is_link(&self) -> bool { - unsafe { - Gecko_IsLink(self.element) != 0 - } - } + fn match_non_ts_pseudo_class(&self, pseudo_class: NonTSPseudoClass) -> bool { + match pseudo_class { + // https://github.com/servo/servo/issues/8718 + NonTSPseudoClass::Link => unsafe { Gecko_IsLink(self.element) != 0 }, + NonTSPseudoClass::AnyLink => unsafe { Gecko_IsUnvisitedLink(self.element) != 0 }, + NonTSPseudoClass::Visited => unsafe { Gecko_IsVisitedLink(self.element) != 0 }, - fn is_unvisited_link(&self) -> bool { - unsafe { - Gecko_IsUnvisitedLink(self.element) != 0 - } - } + NonTSPseudoClass::ServoNonZeroBorder => { + unimplemented!() + }, - fn is_visited_link(&self) -> bool { - unsafe { - Gecko_IsVisitedLink(self.element) != 0 + NonTSPseudoClass::Active | + NonTSPseudoClass::Focus | + NonTSPseudoClass::Hover | + NonTSPseudoClass::Enabled | + NonTSPseudoClass::Disabled | + NonTSPseudoClass::Checked | + NonTSPseudoClass::Indeterminate => { + self.get_state().contains(pseudo_class.state_flag()) + }, } } - state_pseudo_classes!(state_getter); - fn get_id(&self) -> Option<Atom> { // FIXME(bholley): Servo caches the id atom directly on the element to // make this blazing fast. Assuming that was a measured optimization, doing @@ -452,10 +448,6 @@ impl<'le> ::selectors::Element for GeckoElement<'le> { } } - fn has_servo_nonzero_border(&self) -> bool { - unimplemented!() - } - fn match_attr<F>(&self, attr: &AttrSelector, test: F) -> bool where F: Fn(&str) -> bool { // FIXME(bholley): This is copy-pasted from the servo wrapper's version. // We should find a way to share it. diff --git a/ports/gonk/Cargo.lock b/ports/gonk/Cargo.lock index 959c23dd47f..b7faf344c1f 100644 --- a/ports/gonk/Cargo.lock +++ b/ports/gonk/Cargo.lock @@ -901,7 +901,7 @@ dependencies = [ "rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", "script 0.0.1", "script_traits 0.0.1", - "selectors 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "selectors 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde_macros 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1425,7 +1425,7 @@ dependencies = [ "ref_slice 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", "script_traits 0.0.1", - "selectors 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "selectors 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "string_cache 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1465,7 +1465,7 @@ dependencies = [ [[package]] name = "selectors" -version = "0.2.3" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1701,7 +1701,7 @@ dependencies = [ "num 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "plugins 0.0.1", "rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", - "selectors 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "selectors 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde_macros 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1723,7 +1723,7 @@ dependencies = [ "num 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "plugins 0.0.1", "rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", - "selectors 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "selectors 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde_macros 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "url 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1879,7 +1879,7 @@ dependencies = [ "plugins 0.0.1", "rand 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", - "selectors 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "selectors 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde_macros 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/tests/unit/style/Cargo.toml b/tests/unit/style/Cargo.toml index 7e2c2b08c55..525f1114706 100644 --- a/tests/unit/style/Cargo.toml +++ b/tests/unit/style/Cargo.toml @@ -27,6 +27,6 @@ path = "../../../components/util" app_units = {version = "0.1", features = ["plugins"]} url = "0.5.2" cssparser = "0.5" -selectors = "0.2" +selectors = "0.4.1" string_cache = "0.2" euclid = {version = "0.4", features = ["plugins"]} |