diff options
author | Simon Sapin <simon.sapin@exyr.org> | 2017-06-07 19:07:07 +0200 |
---|---|---|
committer | Simon Sapin <simon.sapin@exyr.org> | 2017-06-12 23:33:53 +0200 |
commit | 5bccf98aa4925264b7fe0c5e996ab5de13d02f3a (patch) | |
tree | b21f0d1cdc9aeda8a336119a01e495a88f8769aa /components/script | |
parent | 524fcac19155c69f8f2ea1683b411a8ef0ee149b (diff) | |
download | servo-5bccf98aa4925264b7fe0c5e996ab5de13d02f3a.tar.gz servo-5bccf98aa4925264b7fe0c5e996ab5de13d02f3a.zip |
ID and class selectors are ASCII case-insensitive in quirks mode.
https://bugzilla.mozilla.org/show_bug.cgi?id=1363778
Diffstat (limited to 'components/script')
-rw-r--r-- | components/script/dom/element.rs | 43 | ||||
-rw-r--r-- | components/script/dom/htmlcollection.rs | 11 | ||||
-rw-r--r-- | components/script/dom/window.rs | 4 | ||||
-rw-r--r-- | components/script/layout_wrapper.rs | 39 |
4 files changed, 66 insertions, 31 deletions
diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs index 957eadb53e4..ce848be5e17 100644 --- a/components/script/dom/element.rs +++ b/components/script/dom/element.rs @@ -85,7 +85,7 @@ use net_traits::request::CorsSettings; use ref_filter_map::ref_filter_map; use script_layout_interface::message::ReflowQueryType; use script_thread::Runnable; -use selectors::attr::{AttrSelectorOperation, NamespaceConstraint}; +use selectors::attr::{AttrSelectorOperation, NamespaceConstraint, CaseSensitivity}; use selectors::matching::{ElementSelectorFlags, LocalMatchingContext, MatchingContext, MatchingMode}; use selectors::matching::{HAS_EDGE_CHILD_SELECTOR, HAS_SLOW_SELECTOR, HAS_SLOW_SELECTOR_LATER_SIBLINGS}; use selectors::matching::{RelevantLinkStatus, matches_selector_list}; @@ -97,6 +97,7 @@ use std::convert::TryFrom; use std::default::Default; use std::fmt; use std::rc::Rc; +use style::CaseSensitivityExt; use style::applicable_declarations::ApplicableDeclarationBlock; use style::attr::{AttrValue, LengthOrPercentageOrAuto}; use style::context::{QuirksMode, ReflowGoal}; @@ -345,7 +346,9 @@ impl RawLayoutElementHelpers for Element { pub trait LayoutElementHelpers { #[allow(unsafe_code)] - unsafe fn has_class_for_layout(&self, name: &Atom) -> bool; + unsafe fn in_quirks_mode_document_for_layout(&self) -> bool; + #[allow(unsafe_code)] + unsafe fn has_class_for_layout(&self, name: &Atom, case_sensitivity: CaseSensitivity) -> bool; #[allow(unsafe_code)] unsafe fn get_classes_for_layout(&self) -> Option<&'static [Atom]>; @@ -373,9 +376,15 @@ pub trait LayoutElementHelpers { impl LayoutElementHelpers for LayoutJS<Element> { #[allow(unsafe_code)] #[inline] - unsafe fn has_class_for_layout(&self, name: &Atom) -> bool { + unsafe fn in_quirks_mode_document_for_layout(&self) -> bool { + self.upcast::<Node>().owner_doc_for_layout().quirks_mode() == QuirksMode::Quirks + } + + #[allow(unsafe_code)] + #[inline] + unsafe fn has_class_for_layout(&self, name: &Atom, case_sensitivity: CaseSensitivity) -> bool { get_attr_for_layout(&*self.unsafe_get(), &ns!(), &local_name!("class")).map_or(false, |attr| { - attr.value_tokens_forever().unwrap().iter().any(|atom| atom == name) + attr.value_tokens_forever().unwrap().iter().any(|atom| case_sensitivity.eq_atom(atom, name)) }) } @@ -1158,16 +1167,10 @@ impl Element { }) } - pub fn has_class(&self, name: &Atom) -> bool { - let quirks_mode = document_from_node(self).quirks_mode(); - let is_equal = |lhs: &Atom, rhs: &Atom| { - match quirks_mode { - QuirksMode::NoQuirks | QuirksMode::LimitedQuirks => lhs == rhs, - QuirksMode::Quirks => lhs.eq_ignore_ascii_case(&rhs), - } - }; - self.get_attribute(&ns!(), &local_name!("class")) - .map_or(false, |attr| attr.value().as_tokens().iter().any(|atom| is_equal(name, atom))) + pub fn has_class(&self, name: &Atom, case_sensitivity: CaseSensitivity) -> bool { + self.get_attribute(&ns!(), &local_name!("class")).map_or(false, |attr| { + attr.value().as_tokens().iter().any(|atom| case_sensitivity.eq_atom(name, atom)) + }) } pub fn set_atomic_attribute(&self, local_name: &LocalName, value: DOMString) { @@ -2503,12 +2506,16 @@ impl<'a> ::selectors::Element for Root<Element> { } } - fn get_id(&self) -> Option<Atom> { - self.id_attribute.borrow().clone() + fn has_id(&self, id: &Atom, case_sensitivity: CaseSensitivity) -> bool { + self.id_attribute.borrow().as_ref().map_or(false, |atom| case_sensitivity.eq_atom(id, atom)) + } + + fn has_class(&self, name: &Atom, case_sensitivity: CaseSensitivity) -> bool { + Element::has_class(&**self, name, case_sensitivity) } - fn has_class(&self, name: &Atom) -> bool { - Element::has_class(&**self, name) + fn in_quirks_mode_document(&self) -> bool { + document_from_node(&**self).quirks_mode() == QuirksMode::Quirks } fn is_html_element_in_html_document(&self) -> bool { diff --git a/components/script/dom/htmlcollection.rs b/components/script/dom/htmlcollection.rs index aff4125a29f..7c3cad306c4 100644 --- a/components/script/dom/htmlcollection.rs +++ b/components/script/dom/htmlcollection.rs @@ -11,12 +11,14 @@ use dom::bindings::str::DOMString; use dom::bindings::trace::JSTraceable; use dom::bindings::xmlname::namespace_from_domstring; use dom::element::Element; -use dom::node::Node; +use dom::node::{Node, document_from_node}; use dom::window::Window; use dom_struct::dom_struct; use html5ever::{LocalName, QualName}; +use selectors::attr::CaseSensitivity; use servo_atoms::Atom; use std::cell::Cell; +use style::context::QuirksMode; use style::str::split_html_space_chars; pub trait CollectionFilter : JSTraceable { @@ -199,7 +201,12 @@ impl HTMLCollection { } impl CollectionFilter for ClassNameFilter { fn filter(&self, elem: &Element, _root: &Node) -> bool { - self.classes.iter().all(|class| elem.has_class(class)) + let case_sensitivity = match document_from_node(elem).quirks_mode() { + QuirksMode::NoQuirks | + QuirksMode::LimitedQuirks => CaseSensitivity::CaseSensitive, + QuirksMode::Quirks => CaseSensitivity::AsciiCaseInsensitive, + }; + self.classes.iter().all(|class| elem.has_class(class, case_sensitivity)) } } let filter = ClassNameFilter { diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs index bcc5a749d33..6e89024887a 100644 --- a/components/script/dom/window.rs +++ b/components/script/dom/window.rs @@ -84,7 +84,7 @@ use script_traits::{ConstellationControlMsg, DocumentState, LoadData, MozBrowser use script_traits::{ScriptMsg as ConstellationMsg, ScrollState, TimerEvent, TimerEventId}; use script_traits::{TimerSchedulerMsg, UntrustedNodeAddress, WindowSizeData, WindowSizeType}; use script_traits::webdriver_msg::{WebDriverJSError, WebDriverJSResult}; -use servo_atoms::Atom; +use selectors::attr::CaseSensitivity; use servo_config::opts; use servo_config::prefs::PREFS; use servo_geometry::{f32_rect_to_au_rect, max_rect}; @@ -1365,7 +1365,7 @@ impl Window { // See http://testthewebforward.org/docs/reftests.html let html_element = document.GetDocumentElement(); let reftest_wait = html_element.map_or(false, |elem| { - elem.has_class(&Atom::from("reftest-wait")) + elem.has_class(&atom!("reftest-wait"), CaseSensitivity::CaseSensitive) }); let ready_state = document.ReadyState(); diff --git a/components/script/layout_wrapper.rs b/components/script/layout_wrapper.rs index 916b9f5a329..7b4b450c63e 100644 --- a/components/script/layout_wrapper.rs +++ b/components/script/layout_wrapper.rs @@ -49,7 +49,7 @@ use script_layout_interface::{HTMLCanvasData, LayoutNodeType, SVGSVGData, Truste use script_layout_interface::{OpaqueStyleAndLayoutData, StyleData}; use script_layout_interface::wrapper_traits::{DangerousThreadSafeLayoutNode, GetLayoutData, LayoutNode}; use script_layout_interface::wrapper_traits::{PseudoElementType, ThreadSafeLayoutElement, ThreadSafeLayoutNode}; -use selectors::attr::{AttrSelectorOperation, NamespaceConstraint}; +use selectors::attr::{AttrSelectorOperation, NamespaceConstraint, CaseSensitivity}; use selectors::matching::{ElementSelectorFlags, LocalMatchingContext, MatchingContext, RelevantLinkStatus}; use selectors::matching::VisitedHandlingMode; use servo_atoms::Atom; @@ -61,6 +61,7 @@ use std::marker::PhantomData; use std::mem::transmute; use std::sync::atomic::Ordering; use style; +use style::CaseSensitivityExt; use style::applicable_declarations::ApplicableDeclarationBlock; use style::attr::AttrValue; use style::computed_values::display; @@ -414,6 +415,13 @@ impl<'le> TElement for ServoLayoutElement<'le> { self.get_attr(namespace, attr).is_some() } + #[inline] + fn get_id(&self) -> Option<Atom> { + unsafe { + (*self.element.id_attribute()).clone() + } + } + #[inline(always)] fn each_class<F>(&self, mut callback: F) where F: FnMut(&Atom) { unsafe { @@ -779,16 +787,24 @@ impl<'le> ::selectors::Element for ServoLayoutElement<'le> { } #[inline] - fn get_id(&self) -> Option<Atom> { + fn has_id(&self, id: &Atom, case_sensitivity: CaseSensitivity) -> bool { unsafe { - (*self.element.id_attribute()).clone() + (*self.element.id_attribute()) + .as_ref() + .map_or(false, |atom| case_sensitivity.eq_atom(atom, id)) } } #[inline] - fn has_class(&self, name: &Atom) -> bool { + fn has_class(&self, name: &Atom, case_sensitivity: CaseSensitivity) -> bool { unsafe { - self.element.has_class_for_layout(name) + self.element.has_class_for_layout(name, case_sensitivity) + } + } + + fn in_quirks_mode_document(&self) -> bool { + unsafe { + self.element.in_quirks_mode_document_for_layout() } } @@ -1194,6 +1210,11 @@ impl<'le> ::selectors::Element for ServoThreadSafeLayoutElement<'le> { true } + fn in_quirks_mode_document(&self) -> bool { + debug!("ServoThreadSafeLayoutElement::in_quirks_mode_document called"); + false + } + #[inline] fn get_local_name(&self) -> &LocalName { self.element.get_local_name() @@ -1249,12 +1270,12 @@ impl<'le> ::selectors::Element for ServoThreadSafeLayoutElement<'le> { false } - fn get_id(&self) -> Option<Atom> { - debug!("ServoThreadSafeLayoutElement::get_id called"); - None + fn has_id(&self, _id: &Atom, _case_sensitivity: CaseSensitivity) -> bool { + debug!("ServoThreadSafeLayoutElement::has_id called"); + false } - fn has_class(&self, _name: &Atom) -> bool { + fn has_class(&self, _name: &Atom, _case_sensitivity: CaseSensitivity) -> bool { debug!("ServoThreadSafeLayoutElement::has_class called"); false } |