Move ServoSelectorImpl to a dedicated module.

This commit is contained in:
Simon Sapin 2016-07-19 16:17:02 +02:00
parent 2f967893f3
commit b2a7e44373
7 changed files with 269 additions and 249 deletions

View file

@ -5,13 +5,21 @@
//! The pseudo-classes and pseudo-elements supported by the style system.
use element_state::ElementState;
use properties::{self, ServoComputedValues};
use selector_matching::{USER_OR_USER_AGENT_STYLESHEETS, QUIRKS_MODE_STYLESHEET};
use properties;
use selectors::Element;
use selectors::parser::{ParserContext, SelectorImpl};
use selectors::parser::SelectorImpl;
use std::fmt::Debug;
use stylesheets::Stylesheet;
#[cfg(feature = "servo")]
pub use servo_selector_impl::ServoSelectorImpl;
#[cfg(feature = "servo")]
pub use servo_selector_impl::{ServoSelectorImpl as TheSelectorImpl, PseudoElement, NonTSPseudoClass};
#[cfg(feature = "gecko")]
pub use gecko_selector_impl::{GeckoSelectorImpl as TheSelectorImpl, PseudoElement, NonTSPseudoClass};
/// This function determines if a pseudo-element is eagerly cascaded or not.
///
/// Eagerly cascaded pseudo-elements are "normal" pseudo-elements (i.e.
@ -101,186 +109,3 @@ pub trait SelectorImplExt : SelectorImpl + Clone + Debug + Sized + 'static {
fn get_quirks_mode_stylesheet() -> Option<&'static Stylesheet<Self>>;
}
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub enum PseudoElement {
Before,
After,
Selection,
DetailsSummary,
DetailsContent,
}
impl PseudoElement {
#[inline]
pub fn is_before_or_after(&self) -> bool {
match *self {
PseudoElement::Before |
PseudoElement::After => true,
_ => false,
}
}
#[inline]
pub fn cascade_type(&self) -> PseudoElementCascadeType {
match *self {
PseudoElement::Before |
PseudoElement::After |
PseudoElement::Selection => PseudoElementCascadeType::Eager,
PseudoElement::DetailsSummary => PseudoElementCascadeType::Lazy,
PseudoElement::DetailsContent => PseudoElementCascadeType::Precomputed,
}
}
}
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub enum NonTSPseudoClass {
AnyLink,
Link,
Visited,
Active,
Focus,
Hover,
Enabled,
Disabled,
Checked,
Indeterminate,
ServoNonZeroBorder,
ReadWrite,
ReadOnly,
PlaceholderShown,
}
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,
ReadOnly | ReadWrite => IN_READ_WRITE_STATE,
PlaceholderShown => IN_PLACEHOLDER_SHOWN_STATE,
AnyLink |
Link |
Visited |
ServoNonZeroBorder => ElementState::empty(),
}
}
}
#[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub struct ServoSelectorImpl;
impl SelectorImpl for ServoSelectorImpl {
type AttrString = String;
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,
"read-write" => ReadWrite,
"read-only" => ReadOnly,
"placeholder-shown" => PlaceholderShown,
"-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::*;
let pseudo_element = match_ignore_ascii_case! { name,
"before" => Before,
"after" => After,
"selection" => Selection,
"-servo-details-summary" => {
if !context.in_user_agent_stylesheet {
return Err(())
}
DetailsSummary
},
"-servo-details-content" => {
if !context.in_user_agent_stylesheet {
return Err(())
}
DetailsContent
},
_ => return Err(())
};
Ok(pseudo_element)
}
}
impl SelectorImplExt for ServoSelectorImpl {
type ComputedValues = ServoComputedValues;
#[inline]
fn pseudo_element_cascade_type(pseudo: &PseudoElement) -> PseudoElementCascadeType {
pseudo.cascade_type()
}
#[inline]
fn each_pseudo_element<F>(mut fun: F)
where F: FnMut(PseudoElement) {
fun(PseudoElement::Before);
fun(PseudoElement::After);
fun(PseudoElement::DetailsContent);
fun(PseudoElement::DetailsSummary);
fun(PseudoElement::Selection);
}
#[inline]
fn pseudo_class_state_flag(pc: &NonTSPseudoClass) -> ElementState {
pc.state_flag()
}
#[inline]
fn pseudo_is_before_or_after(pseudo: &PseudoElement) -> bool {
pseudo.is_before_or_after()
}
#[inline]
fn get_user_or_user_agent_stylesheets() -> &'static [Stylesheet<Self>] {
&*USER_OR_USER_AGENT_STYLESHEETS
}
#[inline]
fn get_quirks_mode_stylesheet() -> Option<&'static Stylesheet<Self>> {
Some(&*QUIRKS_MODE_STYLESHEET)
}
}
impl<E: Element<Impl=ServoSelectorImpl, AttrString=String>> ElementExt for E {
fn is_link(&self) -> bool {
self.match_non_ts_pseudo_class(NonTSPseudoClass::AnyLink)
}
}