mirror of
https://github.com/servo/servo.git
synced 2025-08-01 11:40:30 +01:00
Look for relevant links while matching
Adjust the matching process to look for a "relevant link" while matching. A "relevant link" is the element being matched if it is a link or the nearest ancestor link. Matching for links now depends on the `VisitedHandlingMode`, which determines whether all links match as if they are unvisited (the default) or if the relevant link matches as visited (and all others remain unvisited). If a relevant link is ever found for any selector, track this as part of the `MatchingContext` object. This is used in the next patch to determine if an additional match and cascade should be performed to compute the styles when visited. MozReview-Commit-ID: 3xUbRo7vpuD
This commit is contained in:
parent
8ae546f7ea
commit
e3a256803d
8 changed files with 197 additions and 55 deletions
|
@ -87,8 +87,9 @@ use ref_filter_map::ref_filter_map;
|
|||
use script_layout_interface::message::ReflowQueryType;
|
||||
use script_thread::Runnable;
|
||||
use selectors::attr::{AttrSelectorOperation, NamespaceConstraint};
|
||||
use selectors::matching::{ElementSelectorFlags, MatchingContext, MatchingMode, matches_selector_list};
|
||||
use selectors::matching::{ElementSelectorFlags, MatchingContext, MatchingMode};
|
||||
use selectors::matching::{HAS_EDGE_CHILD_SELECTOR, HAS_SLOW_SELECTOR, HAS_SLOW_SELECTOR_LATER_SIBLINGS};
|
||||
use selectors::matching::{RelevantLinkStatus, matches_selector_list};
|
||||
use servo_atoms::Atom;
|
||||
use std::ascii::AsciiExt;
|
||||
use std::borrow::Cow;
|
||||
|
@ -2429,6 +2430,7 @@ impl<'a> ::selectors::Element for Root<Element> {
|
|||
fn match_non_ts_pseudo_class<F>(&self,
|
||||
pseudo_class: &NonTSPseudoClass,
|
||||
_: &mut MatchingContext,
|
||||
_: &RelevantLinkStatus,
|
||||
_: &mut F)
|
||||
-> bool
|
||||
where F: FnMut(&Self, ElementSelectorFlags),
|
||||
|
@ -2478,6 +2480,20 @@ impl<'a> ::selectors::Element for Root<Element> {
|
|||
}
|
||||
}
|
||||
|
||||
fn is_link(&self) -> bool {
|
||||
// FIXME: This is HTML only.
|
||||
let node = self.upcast::<Node>();
|
||||
match node.type_id() {
|
||||
// https://html.spec.whatwg.org/multipage/#selector-link
|
||||
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLAnchorElement)) |
|
||||
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLAreaElement)) |
|
||||
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLLinkElement)) => {
|
||||
self.has_attribute(&local_name!("href"))
|
||||
},
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn get_id(&self) -> Option<Atom> {
|
||||
self.id_attribute.borrow().clone()
|
||||
}
|
||||
|
@ -2592,20 +2608,6 @@ impl Element {
|
|||
}
|
||||
}
|
||||
|
||||
fn is_link(&self) -> bool {
|
||||
// FIXME: This is HTML only.
|
||||
let node = self.upcast::<Node>();
|
||||
match node.type_id() {
|
||||
// https://html.spec.whatwg.org/multipage/#selector-link
|
||||
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLAnchorElement)) |
|
||||
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLAreaElement)) |
|
||||
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLLinkElement)) => {
|
||||
self.has_attribute(&local_name!("href"))
|
||||
},
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Please call this method *only* for real click events
|
||||
///
|
||||
/// https://html.spec.whatwg.org/multipage/#run-authentic-click-activation-steps
|
||||
|
|
|
@ -51,7 +51,7 @@ use script_layout_interface::{OpaqueStyleAndLayoutData, PartialPersistentLayoutD
|
|||
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::matching::{ElementSelectorFlags, MatchingContext};
|
||||
use selectors::matching::{ElementSelectorFlags, MatchingContext, RelevantLinkStatus};
|
||||
use servo_atoms::Atom;
|
||||
use servo_url::ServoUrl;
|
||||
use std::fmt;
|
||||
|
@ -680,6 +680,7 @@ impl<'le> ::selectors::Element for ServoLayoutElement<'le> {
|
|||
fn match_non_ts_pseudo_class<F>(&self,
|
||||
pseudo_class: &NonTSPseudoClass,
|
||||
_: &mut MatchingContext,
|
||||
_: &RelevantLinkStatus,
|
||||
_: &mut F)
|
||||
-> bool
|
||||
where F: FnMut(&Self, ElementSelectorFlags),
|
||||
|
@ -687,16 +688,7 @@ impl<'le> ::selectors::Element for ServoLayoutElement<'le> {
|
|||
match *pseudo_class {
|
||||
// https://github.com/servo/servo/issues/8718
|
||||
NonTSPseudoClass::Link |
|
||||
NonTSPseudoClass::AnyLink => unsafe {
|
||||
match self.as_node().script_type_id() {
|
||||
// https://html.spec.whatwg.org/multipage/#selector-link
|
||||
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLAnchorElement)) |
|
||||
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLAreaElement)) |
|
||||
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLLinkElement)) =>
|
||||
(*self.element.unsafe_get()).get_attr_val_for_layout(&ns!(), &local_name!("href")).is_some(),
|
||||
_ => false,
|
||||
}
|
||||
},
|
||||
NonTSPseudoClass::AnyLink => self.is_link(),
|
||||
NonTSPseudoClass::Visited => false,
|
||||
|
||||
// FIXME(#15746): This is wrong, we need to instead use extended filtering as per RFC4647
|
||||
|
@ -731,6 +723,20 @@ impl<'le> ::selectors::Element for ServoLayoutElement<'le> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_link(&self) -> bool {
|
||||
unsafe {
|
||||
match self.as_node().script_type_id() {
|
||||
// https://html.spec.whatwg.org/multipage/#selector-link
|
||||
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLAnchorElement)) |
|
||||
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLAreaElement)) |
|
||||
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLLinkElement)) =>
|
||||
(*self.element.unsafe_get()).get_attr_val_for_layout(&ns!(), &local_name!("href")).is_some(),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn get_id(&self) -> Option<Atom> {
|
||||
unsafe {
|
||||
|
@ -1187,6 +1193,7 @@ impl<'le> ::selectors::Element for ServoThreadSafeLayoutElement<'le> {
|
|||
fn match_non_ts_pseudo_class<F>(&self,
|
||||
_: &NonTSPseudoClass,
|
||||
_: &mut MatchingContext,
|
||||
_: &RelevantLinkStatus,
|
||||
_: &mut F)
|
||||
-> bool
|
||||
where F: FnMut(&Self, ElementSelectorFlags),
|
||||
|
@ -1196,6 +1203,11 @@ impl<'le> ::selectors::Element for ServoThreadSafeLayoutElement<'le> {
|
|||
false
|
||||
}
|
||||
|
||||
fn is_link(&self) -> bool {
|
||||
warn!("ServoThreadSafeLayoutElement::is_link called");
|
||||
false
|
||||
}
|
||||
|
||||
fn get_id(&self) -> Option<Atom> {
|
||||
debug!("ServoThreadSafeLayoutElement::get_id called");
|
||||
None
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue