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

@ -164,13 +164,14 @@ impl ElementSnapshot for GeckoElementSnapshot {
}
#[inline]
fn has_class(&self, name: &Atom) -> bool {
fn has_class(&self, name: &Atom, case_sensitivity: CaseSensitivity) -> bool {
if !self.has_any(Flags::MaybeClass) {
return false;
}
snapshot_helpers::has_class(self.as_ptr(),
name,
case_sensitivity,
bindings::Gecko_SnapshotClassOrClassList)
}

View file

@ -4,7 +4,10 @@
//! Element an snapshot common logic.
use CaseSensitivityExt;
use gecko_bindings::structs::nsIAtom;
use gecko_string_cache::WeakAtom;
use selectors::attr::CaseSensitivity;
use std::{ptr, slice};
use string_cache::Atom;
@ -16,6 +19,7 @@ pub type ClassOrClassList<T> = unsafe extern fn (T, *mut *mut nsIAtom, *mut *mut
/// element has the class that `name` represents.
pub fn has_class<T>(item: T,
name: &Atom,
case_sensitivity: CaseSensitivity,
getter: ClassOrClassList<T>) -> bool
{
unsafe {
@ -24,10 +28,10 @@ pub fn has_class<T>(item: T,
let length = getter(item, &mut class, &mut list);
match length {
0 => false,
1 => name.as_ptr() == class,
1 => case_sensitivity.eq_atom(name, WeakAtom::new(class)),
n => {
let classes = slice::from_raw_parts(list, n as usize);
classes.iter().any(|ptr| name.as_ptr() == *ptr)
classes.iter().any(|ptr| case_sensitivity.eq_atom(name, WeakAtom::new(*ptr)))
}
}
}

View file

@ -14,6 +14,7 @@
//! style system it's kind of pointless in the Stylo case, and only Servo forces
//! the separation between the style system implementation and everything else.
use CaseSensitivityExt;
use app_units::Au;
use applicable_declarations::ApplicableDeclarationBlock;
use atomic_refcell::AtomicRefCell;
@ -744,6 +745,23 @@ impl<'le> TElement for GeckoElement<'le> {
}
}
fn get_id(&self) -> Option<Atom> {
if !self.has_id() {
return None
}
let ptr = unsafe {
bindings::Gecko_AtomAttrValue(self.0,
atom!("id").as_ptr())
};
if ptr.is_null() {
None
} else {
Some(Atom::from(ptr))
}
}
fn each_class<F>(&self, callback: F)
where F: FnMut(&Atom)
{
@ -1574,30 +1592,22 @@ impl<'le> ::selectors::Element for GeckoElement<'le> {
self.get_state().intersects(NonTSPseudoClass::AnyLink.state_flag())
}
fn get_id(&self) -> Option<Atom> {
if !self.has_id() {
return None;
}
let ptr = unsafe {
bindings::Gecko_AtomAttrValue(self.0,
atom!("id").as_ptr())
};
if ptr.is_null() {
None
} else {
Some(Atom::from(ptr))
}
fn in_quirks_mode_document(&self) -> bool {
self.as_node().owner_doc().mCompatMode == structs::nsCompatibility::eCompatibility_NavQuirks
}
fn has_class(&self, name: &Atom) -> bool {
fn has_id(&self, id: &Atom, case_sensitivity: CaseSensitivity) -> bool {
self.get_id().map_or(false, |atom| case_sensitivity.eq_atom(&atom, id))
}
fn has_class(&self, name: &Atom, case_sensitivity: CaseSensitivity) -> bool {
if !self.may_have_class() {
return false;
}
snapshot_helpers::has_class(self.0,
name,
case_sensitivity,
Gecko_ClassOrClassList)
}