ID and class selectors are ASCII case-insensitive in quirks mode.

https://bugzilla.mozilla.org/show_bug.cgi?id=1363778
This commit is contained in:
Simon Sapin 2017-06-07 19:07:07 +02:00
parent 524fcac191
commit 5bccf98aa4
22 changed files with 313 additions and 191 deletions

View file

@ -127,7 +127,7 @@ pub static SELECTOR_WHITESPACE: &'static [char] = &[' ', '\t', '\n', '\r', '\x0C
#[derive(Eq, PartialEq, Clone, Copy, Debug)]
pub enum ParsedCaseSensitivity {
CaseSensitive, // Selectors spec says language-defined, but HTML says sensitive.
CaseSensitive,
AsciiCaseInsensitive,
AsciiCaseInsensitiveIfInHtmlElementInHtmlDocument,
}
@ -150,7 +150,7 @@ impl ParsedCaseSensitivity {
#[derive(Eq, PartialEq, Clone, Copy, Debug)]
pub enum CaseSensitivity {
CaseSensitive, // Selectors spec says language-defined, but HTML says sensitive.
CaseSensitive,
AsciiCaseInsensitive,
}

View file

@ -2,7 +2,7 @@
* 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 attr::{ParsedAttrSelectorOperation, AttrSelectorOperation, NamespaceConstraint};
use attr::{ParsedAttrSelectorOperation, AttrSelectorOperation, NamespaceConstraint, CaseSensitivity};
use bloom::{BLOOM_HASH_MASK, BloomFilter};
use parser::{AncestorHashes, Combinator, Component, LocalName};
use parser::{Selector, SelectorImpl, SelectorIter, SelectorList};
@ -666,12 +666,21 @@ fn matches_simple_selector<E, F>(
let ns = ::parser::namespace_empty_string::<E::Impl>();
element.get_namespace() == ns.borrow()
}
// TODO: case-sensitivity depends on the document type and quirks mode
Component::ID(ref id) => {
element.get_id().map_or(false, |attr| attr == *id)
let case_sensitivity = if element.in_quirks_mode_document() {
CaseSensitivity::AsciiCaseInsensitive
} else {
CaseSensitivity::CaseSensitive
};
element.has_id(id, case_sensitivity)
}
Component::Class(ref class) => {
element.has_class(class)
let case_sensitivity = if element.in_quirks_mode_document() {
CaseSensitivity::AsciiCaseInsensitive
} else {
CaseSensitivity::CaseSensitive
};
element.has_class(class, case_sensitivity)
}
Component::AttributeInNoNamespaceExists { ref local_name, ref local_name_lower } => {
let is_html = element.is_html_element_in_html_document();

View file

@ -1385,7 +1385,10 @@ fn parse_attribute_flags<'i, 't, E>(input: &mut CssParser<'i, 't>)
-> Result<ParsedCaseSensitivity,
ParseError<'i, SelectorParseError<'i, E>>> {
match input.next() {
Err(_) => Ok(ParsedCaseSensitivity::CaseSensitive),
Err(_) => {
// Selectors spec says language-defined, but HTML says sensitive.
Ok(ParsedCaseSensitivity::CaseSensitive)
}
Ok(Token::Ident(ref value)) if value.eq_ignore_ascii_case("i") => {
Ok(ParsedCaseSensitivity::AsciiCaseInsensitive)
}

View file

@ -5,7 +5,7 @@
//! Traits that nodes must implement. Breaks the otherwise-cyclic dependency
//! between layout and style.
use attr::{AttrSelectorOperation, NamespaceConstraint};
use attr::{AttrSelectorOperation, NamespaceConstraint, CaseSensitivity};
use matching::{ElementSelectorFlags, LocalMatchingContext, MatchingContext, RelevantLinkStatus};
use parser::SelectorImpl;
use std::fmt::Debug;
@ -63,9 +63,20 @@ pub trait Element: Sized + Debug {
/// Whether this element is a `link`.
fn is_link(&self) -> bool;
fn get_id(&self) -> Option<<Self::Impl as SelectorImpl>::Identifier>;
/// Whether this element is in a document that is in quirks mode.
///
/// https://dom.spec.whatwg.org/#concept-document-quirks
fn in_quirks_mode_document(&self) -> bool;
fn has_class(&self, name: &<Self::Impl as SelectorImpl>::ClassName) -> bool;
fn has_id(&self,
id: &<Self::Impl as SelectorImpl>::Identifier,
case_sensitivity: CaseSensitivity)
-> bool;
fn has_class(&self,
name: &<Self::Impl as SelectorImpl>::ClassName,
case_sensitivity: CaseSensitivity)
-> bool;
/// Returns whether this element matches `:empty`.
///