lazily compute normalized name of psuedo selector

This commit is contained in:
Connor Skees 2020-07-07 14:48:02 -04:00
parent 1ae9cdbb23
commit 4379e1e3b7
4 changed files with 14 additions and 15 deletions

View File

@ -600,7 +600,7 @@ fn first_if_root(queue: &mut VecDeque<ComplexSelectorComponent>) -> Option<Compo
fn has_root(compound: &CompoundSelector) -> bool {
compound.components.iter().any(|simple| {
if let SimpleSelector::Pseudo(pseudo) = simple {
pseudo.is_class && &*pseudo.normalized_name == "root"
pseudo.is_class && pseudo.normalized_name() == "root"
} else {
false
}

View File

@ -598,7 +598,7 @@ impl Extender {
// writing. We can keep them if either the original selector had a complex
// selector, or the result of extending has only complex selectors, because
// either way we aren't breaking anything that isn't already broken.
let mut complexes = if &*pseudo.normalized_name == "not"
let mut complexes = if pseudo.normalized_name() == "not"
&& !pseudo
.selector
.clone()
@ -644,7 +644,7 @@ impl Extender {
return vec![complex];
}
match &*pseudo.normalized_name {
match pseudo.normalized_name() {
"not" => {
// In theory, if there's a `:not` nested within another `:not`, the
// inner `:not`'s contents should be unified with the return value.
@ -652,7 +652,7 @@ impl Extender {
// become `.foo:not(.bar)`. However, this is a narrow edge case and
// supporting it properly would make this code and the code calling it
// a lot more complicated, so it's not supported for now.
if &*inner_pseudo.normalized_name == "matches" {
if inner_pseudo.normalized_name() == "matches" {
inner_pseudo.selector.clone().unwrap().components
} else {
Vec::new()
@ -684,7 +684,7 @@ impl Extender {
// Older browsers support `:not`, but only with a single complex selector.
// In order to support those browsers, we break up the contents of a `:not`
// unless it originally contained a selector list.
if &*pseudo.normalized_name == "not"
if pseudo.normalized_name() == "not"
&& pseudo.selector.clone().unwrap().components.len() == 1
{
let result = complexes

View File

@ -295,8 +295,6 @@ impl<'a, 'b> SelectorParser<'a, 'b> {
Some(Token { kind: '(', .. }) => self.parser.toks.next(),
_ => {
return Ok(SimpleSelector::Pseudo(Pseudo {
// todo: we can store the reference to this
normalized_name: unvendor(&name.node).to_string().into_boxed_str(),
is_class: !element && !is_fake_pseudo_element(&name),
name: name.node,
selector: None,
@ -353,7 +351,6 @@ impl<'a, 'b> SelectorParser<'a, 'b> {
}
Ok(SimpleSelector::Pseudo(Pseudo {
normalized_name: unvendor(&name.node).to_string().into_boxed_str(),
is_class: !element && !is_fake_pseudo_element(&name),
name: name.node,
selector,

View File

@ -5,7 +5,7 @@ use std::{
use codemap::Span;
use crate::error::SassResult;
use crate::{common::unvendor, error::SassResult};
use super::{
Attribute, ComplexSelector, ComplexSelectorComponent, CompoundSelector, Namespace,
@ -353,11 +353,11 @@ impl SimpleSelector {
}
if let SimpleSelector::Pseudo(Pseudo {
selector: Some(sel),
normalized_name,
name,
..
}) = their_simple
{
if SUBSELECTOR_PSEUDOS.contains(&&**normalized_name) {
if SUBSELECTOR_PSEUDOS.contains(&unvendor(&name)) {
return sel.components.iter().all(|complex| {
if complex.components.len() != 1 {
return false;
@ -384,9 +384,6 @@ pub(crate) struct Pseudo {
/// The name of this selector.
pub name: String,
/// Like `name`, but without any vendor prefixes.
pub normalized_name: Box<str>,
/// Whether this is a pseudo-class selector.
///
/// If this is false, this is a pseudo-element selector
@ -489,7 +486,7 @@ impl Pseudo {
parents: Option<Vec<ComplexSelectorComponent>>,
) -> bool {
debug_assert!(self.selector.is_some());
match &*self.normalized_name {
match self.normalized_name() {
"matches" | "any" => {
let pseudos = selector_pseudos_named(compound.clone(), &self.name, true);
pseudos.iter().any(move |pseudo2| {
@ -647,6 +644,11 @@ impl Pseudo {
Specificity { min, max }
}
}
/// Like `name`, but without any vendor prefixes.
pub fn normalized_name(&self) -> &str {
unvendor(&self.name)
}
}
/// Returns all pseudo selectors in `compound` that have a selector argument,