mirror of
https://github.com/servo/servo.git
synced 2025-08-05 21:50:18 +01:00
Shrink selectors::Component, add case-insensitive for other attr selectors
* https://bugzilla.mozilla.org/show_bug.cgi?id=1364148 * https://bugzilla.mozilla.org/show_bug.cgi?id=1364162
This commit is contained in:
parent
83c7824fda
commit
9376abdd2c
15 changed files with 377 additions and 357 deletions
|
@ -2,10 +2,10 @@
|
|||
* 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::{AttrSelectorOperation, AttrSelectorOperator, CaseSensitivity};
|
||||
use attr::{AttrSelectorOperation, NamespaceConstraint};
|
||||
use bloom::BloomFilter;
|
||||
use parser::{Combinator, ComplexSelector, Component, LocalName, NamespaceConstraint};
|
||||
use parser::{Selector, SelectorInner, SelectorIter, SelectorImpl, AttrSelector};
|
||||
use parser::{Combinator, ComplexSelector, Component, LocalName};
|
||||
use parser::{Selector, SelectorInner, SelectorIter, SelectorImpl};
|
||||
use std::borrow::Borrow;
|
||||
use tree::Element;
|
||||
|
||||
|
@ -387,8 +387,7 @@ fn matches_simple_selector<E, F>(
|
|||
element.match_pseudo_element(pseudo, context)
|
||||
}
|
||||
Component::LocalName(LocalName { ref name, ref lower_name }) => {
|
||||
let name = if element.is_html_element_in_html_document() { lower_name } else { name };
|
||||
element.get_local_name() == name.borrow()
|
||||
element.get_local_name() == select_name(element, name, lower_name).borrow()
|
||||
}
|
||||
Component::ExplicitUniversalType |
|
||||
Component::ExplicitAnyNamespace => {
|
||||
|
@ -399,9 +398,8 @@ fn matches_simple_selector<E, F>(
|
|||
element.get_namespace() == url.borrow()
|
||||
}
|
||||
Component::ExplicitNoNamespace => {
|
||||
// Rust type’s default, not default namespace
|
||||
let empty_string = <E::Impl as SelectorImpl>::NamespaceUrl::default();
|
||||
element.get_namespace() == empty_string.borrow()
|
||||
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) => {
|
||||
|
@ -411,63 +409,58 @@ fn matches_simple_selector<E, F>(
|
|||
Component::Class(ref class) => {
|
||||
element.has_class(class)
|
||||
}
|
||||
Component::AttrExists(ref attr) => {
|
||||
let (ns, n) = unpack_attr_selector(element, attr);
|
||||
element.attr_matches(ns, n, &AttrSelectorOperation::Exists)
|
||||
Component::AttributeInNoNamespaceExists { ref local_name, ref local_name_lower } => {
|
||||
element.attr_matches(
|
||||
&NamespaceConstraint::Specific(&::parser::namespace_empty_string::<E::Impl>()),
|
||||
select_name(element, local_name, local_name_lower),
|
||||
&AttrSelectorOperation::Exists
|
||||
)
|
||||
}
|
||||
Component::AttrEqual(ref attr, ref value, case_sensitivity) => {
|
||||
let (ns, n) = unpack_attr_selector(element, attr);
|
||||
element.attr_matches(ns, n, &AttrSelectorOperation::WithValue {
|
||||
operator: AttrSelectorOperator::Equal,
|
||||
case_sensitivity: case_sensitivity,
|
||||
expected_value: value
|
||||
})
|
||||
Component::AttributeInNoNamespace {
|
||||
ref local_name,
|
||||
ref local_name_lower,
|
||||
ref value,
|
||||
operator,
|
||||
case_sensitivity,
|
||||
never_matches,
|
||||
} => {
|
||||
if never_matches {
|
||||
false
|
||||
} else {
|
||||
element.attr_matches(
|
||||
&NamespaceConstraint::Specific(&::parser::namespace_empty_string::<E::Impl>()),
|
||||
select_name(element, local_name, local_name_lower),
|
||||
&AttrSelectorOperation::WithValue {
|
||||
operator: operator,
|
||||
case_sensitivity: case_sensitivity,
|
||||
expected_value: value,
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
Component::AttrIncludes(ref attr, ref value) => {
|
||||
let (ns, n) = unpack_attr_selector(element, attr);
|
||||
element.attr_matches(ns, n, &AttrSelectorOperation::WithValue {
|
||||
operator: AttrSelectorOperator::Includes,
|
||||
case_sensitivity: CaseSensitivity::CaseSensitive,
|
||||
expected_value: value
|
||||
})
|
||||
}
|
||||
Component::AttrDashMatch(ref attr, ref value) => {
|
||||
let (ns, n) = unpack_attr_selector(element, attr);
|
||||
element.attr_matches(ns, n, &AttrSelectorOperation::WithValue {
|
||||
operator: AttrSelectorOperator::DashMatch,
|
||||
case_sensitivity: CaseSensitivity::CaseSensitive,
|
||||
expected_value: value
|
||||
})
|
||||
}
|
||||
Component::AttrPrefixMatch(ref attr, ref value) => {
|
||||
let (ns, n) = unpack_attr_selector(element, attr);
|
||||
element.attr_matches(ns, n, &AttrSelectorOperation::WithValue {
|
||||
operator: AttrSelectorOperator::Prefix,
|
||||
case_sensitivity: CaseSensitivity::CaseSensitive,
|
||||
expected_value: value
|
||||
})
|
||||
}
|
||||
Component::AttrSubstringMatch(ref attr, ref value) => {
|
||||
let (ns, n) = unpack_attr_selector(element, attr);
|
||||
element.attr_matches(ns, n, &AttrSelectorOperation::WithValue {
|
||||
operator: AttrSelectorOperator::Substring,
|
||||
case_sensitivity: CaseSensitivity::CaseSensitive,
|
||||
expected_value: value
|
||||
})
|
||||
}
|
||||
Component::AttrSuffixMatch(ref attr, ref value) => {
|
||||
let (ns, n) = unpack_attr_selector(element, attr);
|
||||
element.attr_matches(ns, n, &AttrSelectorOperation::WithValue {
|
||||
operator: AttrSelectorOperator::Suffix,
|
||||
case_sensitivity: CaseSensitivity::CaseSensitive,
|
||||
expected_value: value
|
||||
})
|
||||
}
|
||||
Component::AttrIncludesNeverMatch(..) |
|
||||
Component::AttrPrefixNeverMatch(..) |
|
||||
Component::AttrSubstringNeverMatch(..) |
|
||||
Component::AttrSuffixNeverMatch(..) => {
|
||||
false
|
||||
Component::AttributeOther(ref attr_sel) => {
|
||||
if attr_sel.never_matches {
|
||||
return false
|
||||
} else {
|
||||
element.attr_matches(
|
||||
&attr_sel.namespace(),
|
||||
select_name(element, &attr_sel.local_name, &attr_sel.local_name_lower),
|
||||
&match attr_sel.operation {
|
||||
AttrSelectorOperation::Exists => AttrSelectorOperation::Exists,
|
||||
AttrSelectorOperation::WithValue {
|
||||
operator,
|
||||
case_sensitivity,
|
||||
ref expected_value,
|
||||
} => {
|
||||
AttrSelectorOperation::WithValue {
|
||||
operator: operator,
|
||||
case_sensitivity: case_sensitivity,
|
||||
expected_value: expected_value,
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
Component::NonTSPseudoClass(ref pc) => {
|
||||
element.match_non_ts_pseudo_class(pc, context, flags_setter)
|
||||
|
@ -519,16 +512,15 @@ fn matches_simple_selector<E, F>(
|
|||
}
|
||||
}
|
||||
|
||||
fn unpack_attr_selector<'a, E>(element: &E, attr: &'a AttrSelector<E::Impl>)
|
||||
-> (&'a NamespaceConstraint<E::Impl>,
|
||||
&'a <E::Impl as SelectorImpl>::LocalName)
|
||||
fn select_name<'a, E>(element: &E, local_name: &'a <E::Impl as SelectorImpl>::LocalName,
|
||||
local_name_lower: &'a <E::Impl as SelectorImpl>::LocalName)
|
||||
-> &'a <E::Impl as SelectorImpl>::LocalName
|
||||
where E: Element {
|
||||
let name = if element.is_html_element_in_html_document() {
|
||||
&attr.lower_name
|
||||
if element.is_html_element_in_html_document() {
|
||||
local_name_lower
|
||||
} else {
|
||||
&attr.name
|
||||
};
|
||||
(&attr.namespace, name)
|
||||
local_name
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue