mirror of
https://github.com/servo/servo.git
synced 2025-07-13 02:13:40 +01:00
This fixes a couple fuzz bugs and prevents special-casing <svg:use> even more in bug 1431255. Unfortunately not as many hacks went away as I'd have hoped, since we still need to match document rules, see the linked SVGWG issues. But blocks_ancestor_combinators goes away, which is nice since it's on a very hot path. Bug: 1450250 Reviewed-by: heycam Differential Revision: https://phabricator.services.mozilla.com/D2154 MozReview-Commit-ID: C4mthjoSNFh
132 lines
4.2 KiB
Rust
132 lines
4.2 KiB
Rust
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* 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/. */
|
|
|
|
//! Traits that nodes must implement. Breaks the otherwise-cyclic dependency
|
|
//! between layout and style.
|
|
|
|
use attr::{AttrSelectorOperation, CaseSensitivity, NamespaceConstraint};
|
|
use matching::{ElementSelectorFlags, MatchingContext};
|
|
use parser::SelectorImpl;
|
|
use servo_arc::NonZeroPtrMut;
|
|
use std::fmt::Debug;
|
|
|
|
/// Opaque representation of an Element, for identity comparisons. We use
|
|
/// NonZeroPtrMut to get the NonZero optimization.
|
|
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
|
|
pub struct OpaqueElement(NonZeroPtrMut<()>);
|
|
|
|
impl OpaqueElement {
|
|
/// Creates a new OpaqueElement from an arbitrarily-typed pointer.
|
|
pub fn new<T>(ptr: *const T) -> Self {
|
|
OpaqueElement(NonZeroPtrMut::new(ptr as *const () as *mut ()))
|
|
}
|
|
}
|
|
|
|
pub trait Element: Sized + Clone + Debug {
|
|
type Impl: SelectorImpl;
|
|
|
|
/// Converts self into an opaque representation.
|
|
fn opaque(&self) -> OpaqueElement;
|
|
|
|
fn parent_element(&self) -> Option<Self>;
|
|
|
|
/// Whether the parent node of this element is a shadow root.
|
|
fn parent_node_is_shadow_root(&self) -> bool;
|
|
|
|
/// The host of the containing shadow root, if any.
|
|
fn containing_shadow_host(&self) -> Option<Self>;
|
|
|
|
/// The parent of a given pseudo-element, after matching a pseudo-element
|
|
/// selector.
|
|
///
|
|
/// This is guaranteed to be called in a pseudo-element.
|
|
fn pseudo_element_originating_element(&self) -> Option<Self> {
|
|
self.parent_element()
|
|
}
|
|
|
|
/// Skips non-element nodes
|
|
fn first_child_element(&self) -> Option<Self>;
|
|
|
|
/// Skips non-element nodes
|
|
fn last_child_element(&self) -> Option<Self>;
|
|
|
|
/// Skips non-element nodes
|
|
fn prev_sibling_element(&self) -> Option<Self>;
|
|
|
|
/// Skips non-element nodes
|
|
fn next_sibling_element(&self) -> Option<Self>;
|
|
|
|
fn is_html_element_in_html_document(&self) -> bool;
|
|
|
|
fn local_name(&self) -> &<Self::Impl as SelectorImpl>::BorrowedLocalName;
|
|
|
|
/// Empty string for no namespace
|
|
fn namespace(&self) -> &<Self::Impl as SelectorImpl>::BorrowedNamespaceUrl;
|
|
|
|
fn attr_matches(
|
|
&self,
|
|
ns: &NamespaceConstraint<&<Self::Impl as SelectorImpl>::NamespaceUrl>,
|
|
local_name: &<Self::Impl as SelectorImpl>::LocalName,
|
|
operation: &AttrSelectorOperation<&<Self::Impl as SelectorImpl>::AttrValue>,
|
|
) -> bool;
|
|
|
|
fn match_non_ts_pseudo_class<F>(
|
|
&self,
|
|
pc: &<Self::Impl as SelectorImpl>::NonTSPseudoClass,
|
|
context: &mut MatchingContext<Self::Impl>,
|
|
flags_setter: &mut F,
|
|
) -> bool
|
|
where
|
|
F: FnMut(&Self, ElementSelectorFlags);
|
|
|
|
fn match_pseudo_element(
|
|
&self,
|
|
pe: &<Self::Impl as SelectorImpl>::PseudoElement,
|
|
context: &mut MatchingContext<Self::Impl>,
|
|
) -> bool;
|
|
|
|
/// Whether this element is a `link`.
|
|
fn is_link(&self) -> bool;
|
|
|
|
/// Returns whether the element is an HTML <slot> element.
|
|
fn is_html_slot_element(&self) -> bool;
|
|
|
|
/// Returns the assigned <slot> element this element is assigned to.
|
|
///
|
|
/// Necessary for the `::slotted` pseudo-class.
|
|
fn assigned_slot(&self) -> Option<Self> {
|
|
None
|
|
}
|
|
|
|
fn has_id(
|
|
&self,
|
|
id: &<Self::Impl as SelectorImpl>::Identifier,
|
|
case_sensitivity: CaseSensitivity,
|
|
) -> bool;
|
|
|
|
fn has_class(
|
|
&self,
|
|
name: &<Self::Impl as SelectorImpl>::ClassName,
|
|
case_sensitivity: CaseSensitivity,
|
|
) -> bool;
|
|
|
|
/// Returns whether this element matches `:empty`.
|
|
///
|
|
/// That is, whether it does not contain any child element or any non-zero-length text node.
|
|
/// See http://dev.w3.org/csswg/selectors-3/#empty-pseudo
|
|
fn is_empty(&self) -> bool;
|
|
|
|
/// Returns whether this element matches `:root`,
|
|
/// i.e. whether it is the root element of a document.
|
|
///
|
|
/// Note: this can be false even if `.parent_element()` is `None`
|
|
/// if the parent node is a `DocumentFragment`.
|
|
fn is_root(&self) -> bool;
|
|
|
|
/// Returns whether this element should ignore matching nth child
|
|
/// selector.
|
|
fn ignores_nth_child_selectors(&self) -> bool {
|
|
false
|
|
}
|
|
}
|