servo: Merge #17165 - support matching :-moz-browser-frame and :-moz-table-border-nonzero against snapshots (from heycam:pseudo-other); r=emilio

From https://bugzilla.mozilla.org/show_bug.cgi?id=1365159.

Source-Repo: https://github.com/servo/servo
Source-Revision: 6ce567b776292bec2e9dd3489a8f29fa89970c9e

--HG--
extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear
extra : subtree_revision : f2fd9b32085a7dd0299b7de9fd9bf1f68fbd52a6
This commit is contained in:
Cameron McCormack 2017-06-05 22:09:56 -07:00
Родитель 819ccfd2e4
Коммит 6de5b55b7b
7 изменённых файлов: 4416 добавлений и 4470 удалений

Просмотреть файл

@ -786,6 +786,8 @@ cfg_if! {
pub static nsGkAtoms_field: *mut nsIAtom;
#[link_name = "_ZN9nsGkAtoms8fieldsetE"]
pub static nsGkAtoms_fieldset: *mut nsIAtom;
#[link_name = "_ZN9nsGkAtoms4fileE"]
pub static nsGkAtoms_file: *mut nsIAtom;
#[link_name = "_ZN9nsGkAtoms10figcaptionE"]
pub static nsGkAtoms_figcaption: *mut nsIAtom;
#[link_name = "_ZN9nsGkAtoms6figureE"]
@ -3938,6 +3940,14 @@ cfg_if! {
pub static nsGkAtoms_ondevicechange: *mut nsIAtom;
#[link_name = "_ZN9nsGkAtoms33mozinputrangeignorepreventdefaultE"]
pub static nsGkAtoms_mozinputrangeignorepreventdefault: *mut nsIAtom;
#[link_name = "_ZN9nsGkAtoms13moz_extensionE"]
pub static nsGkAtoms_moz_extension: *mut nsIAtom;
#[link_name = "_ZN9nsGkAtoms18all_urlsPermissionE"]
pub static nsGkAtoms_all_urlsPermission: *mut nsIAtom;
#[link_name = "_ZN9nsGkAtoms4httpE"]
pub static nsGkAtoms_http: *mut nsIAtom;
#[link_name = "_ZN9nsGkAtoms5httpsE"]
pub static nsGkAtoms_https: *mut nsIAtom;
#[link_name = "_ZN9nsGkAtoms12cdataTagNameE"]
pub static nsGkAtoms_cdataTagName: *mut nsIAtom;
#[link_name = "_ZN9nsGkAtoms14commentTagNameE"]
@ -5809,6 +5819,8 @@ cfg_if! {
pub static nsGkAtoms_field: *mut nsIAtom;
#[link_name = "?fieldset@nsGkAtoms@@2PEAVnsIAtom@@EA"]
pub static nsGkAtoms_fieldset: *mut nsIAtom;
#[link_name = "?file@nsGkAtoms@@2PEAVnsIAtom@@EA"]
pub static nsGkAtoms_file: *mut nsIAtom;
#[link_name = "?figcaption@nsGkAtoms@@2PEAVnsIAtom@@EA"]
pub static nsGkAtoms_figcaption: *mut nsIAtom;
#[link_name = "?figure@nsGkAtoms@@2PEAVnsIAtom@@EA"]
@ -8961,6 +8973,14 @@ cfg_if! {
pub static nsGkAtoms_ondevicechange: *mut nsIAtom;
#[link_name = "?mozinputrangeignorepreventdefault@nsGkAtoms@@2PEAVnsIAtom@@EA"]
pub static nsGkAtoms_mozinputrangeignorepreventdefault: *mut nsIAtom;
#[link_name = "?moz_extension@nsGkAtoms@@2PEAVnsIAtom@@EA"]
pub static nsGkAtoms_moz_extension: *mut nsIAtom;
#[link_name = "?all_urlsPermission@nsGkAtoms@@2PEAVnsIAtom@@EA"]
pub static nsGkAtoms_all_urlsPermission: *mut nsIAtom;
#[link_name = "?http@nsGkAtoms@@2PEAVnsIAtom@@EA"]
pub static nsGkAtoms_http: *mut nsIAtom;
#[link_name = "?https@nsGkAtoms@@2PEAVnsIAtom@@EA"]
pub static nsGkAtoms_https: *mut nsIAtom;
#[link_name = "?cdataTagName@nsGkAtoms@@2PEAVnsIAtom@@EA"]
pub static nsGkAtoms_cdataTagName: *mut nsIAtom;
#[link_name = "?commentTagName@nsGkAtoms@@2PEAVnsIAtom@@EA"]
@ -10832,6 +10852,8 @@ cfg_if! {
pub static nsGkAtoms_field: *mut nsIAtom;
#[link_name = "\x01?fieldset@nsGkAtoms@@2PAVnsIAtom@@A"]
pub static nsGkAtoms_fieldset: *mut nsIAtom;
#[link_name = "\x01?file@nsGkAtoms@@2PAVnsIAtom@@A"]
pub static nsGkAtoms_file: *mut nsIAtom;
#[link_name = "\x01?figcaption@nsGkAtoms@@2PAVnsIAtom@@A"]
pub static nsGkAtoms_figcaption: *mut nsIAtom;
#[link_name = "\x01?figure@nsGkAtoms@@2PAVnsIAtom@@A"]
@ -13984,6 +14006,14 @@ cfg_if! {
pub static nsGkAtoms_ondevicechange: *mut nsIAtom;
#[link_name = "\x01?mozinputrangeignorepreventdefault@nsGkAtoms@@2PAVnsIAtom@@A"]
pub static nsGkAtoms_mozinputrangeignorepreventdefault: *mut nsIAtom;
#[link_name = "\x01?moz_extension@nsGkAtoms@@2PAVnsIAtom@@A"]
pub static nsGkAtoms_moz_extension: *mut nsIAtom;
#[link_name = "\x01?all_urlsPermission@nsGkAtoms@@2PAVnsIAtom@@A"]
pub static nsGkAtoms_all_urlsPermission: *mut nsIAtom;
#[link_name = "\x01?http@nsGkAtoms@@2PAVnsIAtom@@A"]
pub static nsGkAtoms_http: *mut nsIAtom;
#[link_name = "\x01?https@nsGkAtoms@@2PAVnsIAtom@@A"]
pub static nsGkAtoms_https: *mut nsIAtom;
#[link_name = "\x01?cdataTagName@nsGkAtoms@@2PAVnsIAtom@@A"]
pub static nsGkAtoms_cdataTagName: *mut nsIAtom;
#[link_name = "\x01?commentTagName@nsGkAtoms@@2PAVnsIAtom@@A"]
@ -15858,6 +15888,8 @@ macro_rules! atom {
{ unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_field as *mut _) } };
("fieldset") =>
{ unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_fieldset as *mut _) } };
("file") =>
{ unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_file as *mut _) } };
("figcaption") =>
{ unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_figcaption as *mut _) } };
("figure") =>
@ -19010,6 +19042,14 @@ macro_rules! atom {
{ unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_ondevicechange as *mut _) } };
("mozinputrangeignorepreventdefault") =>
{ unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_mozinputrangeignorepreventdefault as *mut _) } };
("moz-extension") =>
{ unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_moz_extension as *mut _) } };
("<all_urls>") =>
{ unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_all_urlsPermission as *mut _) } };
("http") =>
{ unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_http as *mut _) } };
("https") =>
{ unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_https as *mut _) } };
("#cdata-section") =>
{ unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_cdataTagName as *mut _) } };
("#comment") =>

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -206,6 +206,14 @@ impl NonTSPseudoClass {
}
apply_non_ts_list!(pseudo_class_geckotype)
}
/// Returns true if the evaluation of the pseudo-class depends on the
/// element's attributes.
pub fn is_attr_based(&self) -> bool {
matches!(*self,
NonTSPseudoClass::MozTableBorderNonzero |
NonTSPseudoClass::MozBrowserFrame)
}
}
/// The dummy struct we use to implement our selector parsing.

Просмотреть файл

@ -55,6 +55,13 @@ impl GeckoElementSnapshot {
self
}
/// Returns true if the snapshot has stored state for pseudo-classes
/// that depend on things other than `ElementState`.
#[inline]
pub fn has_other_pseudo_class_state(&self) -> bool {
self.has_any(Flags::OtherPseudoClassState)
}
/// selectors::Element::attr_matches
pub fn attr_matches(&self,
ns: &NamespaceConstraint<&Namespace>,

Просмотреть файл

@ -636,30 +636,27 @@ impl<'a, E> Element for ElementWrapper<'a, E>
-> bool
where F: FnMut(&Self, ElementSelectorFlags),
{
// :moz-any is quite special, because we need to keep matching as a
// snapshot.
// Some pseudo-classes need special handling to evaluate them against
// the snapshot.
match *pseudo_class {
#[cfg(feature = "gecko")]
{
NonTSPseudoClass::MozAny(ref selectors) => {
use selectors::matching::matches_complex_selector;
if let NonTSPseudoClass::MozAny(ref selectors) = *pseudo_class {
return selectors.iter().any(|s| {
matches_complex_selector(s, 0, self, context, _setter)
})
}
}
// :dir needs special handling. It's implemented in terms of state
// flags, but which state flag it maps to depends on the argument to
// :dir. That means we can't just add its state flags to the
// NonTSPseudoClass, because if we added all of them there, and tested
// via intersects() here, we'd get incorrect behavior for :not(:dir())
// cases.
// :dir is implemented in terms of state flags, but which state flag
// it maps to depends on the argument to :dir. That means we can't
// just add its state flags to the NonTSPseudoClass, because if we
// added all of them there, and tested via intersects() here, we'd
// get incorrect behavior for :not(:dir()) cases.
//
// FIXME(bz): How can I set this up so once Servo adds :dir() support we
// don't forget to update this code?
// FIXME(bz): How can I set this up so once Servo adds :dir()
// support we don't forget to update this code?
#[cfg(feature = "gecko")]
{
if let NonTSPseudoClass::Dir(ref s) = *pseudo_class {
NonTSPseudoClass::Dir(ref s) => {
let selector_flag = dir_selector_to_state(s);
if selector_flag.is_empty() {
// :dir() with some random argument; does not match.
@ -671,16 +668,36 @@ impl<'a, E> Element for ElementWrapper<'a, E>
};
return state.contains(selector_flag);
}
}
// For :link and :visited, we don't actually want to test the element
// state directly. Instead, we use the `relevant_link` to determine if
// they match.
if *pseudo_class == NonTSPseudoClass::Link {
return relevant_link.is_unvisited(self, context)
NonTSPseudoClass::Link => {
return relevant_link.is_unvisited(self, context);
}
if *pseudo_class == NonTSPseudoClass::Visited {
return relevant_link.is_visited(self, context)
NonTSPseudoClass::Visited => {
return relevant_link.is_visited(self, context);
}
#[cfg(feature = "gecko")]
NonTSPseudoClass::MozTableBorderNonzero => {
if let Some(snapshot) = self.snapshot() {
if snapshot.has_other_pseudo_class_state() {
return snapshot.mIsTableBorderNonzero();
}
}
}
#[cfg(feature = "gecko")]
NonTSPseudoClass::MozBrowserFrame => {
if let Some(snapshot) = self.snapshot() {
if snapshot.has_other_pseudo_class_state() {
return snapshot.mIsMozBrowserFrame();
}
}
}
_ => {}
}
let flag = pseudo_class.state_flag();
@ -808,24 +825,25 @@ fn selector_to_state(sel: &Component<SelectorImpl>) -> ElementState {
}
}
fn is_attr_selector(sel: &Component<SelectorImpl>) -> bool {
fn is_attr_based_selector(sel: &Component<SelectorImpl>) -> bool {
match *sel {
Component::ID(_) |
Component::Class(_) |
Component::AttributeInNoNamespaceExists { .. } |
Component::AttributeInNoNamespace { .. } |
Component::AttributeOther(_) => true,
Component::NonTSPseudoClass(ref pc) => pc.is_attr_based(),
_ => false,
}
}
#[derive(Clone, Debug)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
/// The aspects of an selector which are sensitive.
/// The characteristics that a selector is sensitive to.
pub struct Sensitivities {
/// The states which are sensitive.
/// The states which the selector is sensitive to.
pub states: ElementState,
/// Whether attributes are sensitive.
/// Whether the selector is sensitive to attributes.
pub attrs: bool,
}
@ -903,7 +921,7 @@ impl SelectorVisitor for SensitivitiesVisitor {
type Impl = SelectorImpl;
fn visit_simple_selector(&mut self, s: &Component<SelectorImpl>) -> bool {
self.sensitivities.states.insert(selector_to_state(s));
self.sensitivities.attrs |= is_attr_selector(s);
self.sensitivities.attrs |= is_attr_based_selector(s);
true
}
}

Просмотреть файл

@ -268,6 +268,12 @@ impl NonTSPseudoClass {
pub fn needs_cache_revalidation(&self) -> bool {
self.state_flag().is_empty()
}
/// Returns true if the evaluation of the pseudo-class depends on the
/// element's attributes.
pub fn is_attr_based(&self) -> bool {
false
}
}
/// The abstract struct we implement the selector parser implementation on top