tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

tree.rs (6347B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
      4 
      5 //! Traits that nodes must implement. Breaks the otherwise-cyclic dependency
      6 //! between layout and style.
      7 
      8 use crate::attr::{AttrSelectorOperation, CaseSensitivity, NamespaceConstraint};
      9 use crate::bloom::BloomFilter;
     10 use crate::matching::{ElementSelectorFlags, MatchingContext};
     11 use crate::parser::SelectorImpl;
     12 use std::fmt::Debug;
     13 use std::ptr::NonNull;
     14 
     15 /// Opaque representation of an Element, for identity comparisons.
     16 #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
     17 pub struct OpaqueElement(NonNull<()>);
     18 
     19 unsafe impl Send for OpaqueElement {}
     20 // This should be safe given that we do not provide a way to recover
     21 // the original reference.
     22 unsafe impl Sync for OpaqueElement {}
     23 
     24 impl OpaqueElement {
     25    /// Creates a new OpaqueElement from an arbitrarily-typed pointer.
     26    pub fn new<T>(ptr: &T) -> Self {
     27        unsafe {
     28            OpaqueElement(NonNull::new_unchecked(
     29                ptr as *const T as *const () as *mut (),
     30            ))
     31        }
     32    }
     33 
     34    /// Creates a new OpaqueElement from a type-erased non-null pointer
     35    pub fn from_non_null_ptr(ptr: NonNull<()>) -> Self {
     36        Self(ptr)
     37    }
     38 
     39    /// Returns a const ptr to the contained reference. Unsafe especially
     40    /// since Element can be recovered and potentially-mutated.
     41    pub unsafe fn as_const_ptr<T>(&self) -> *const T {
     42        self.0.as_ptr() as *const T
     43    }
     44 }
     45 
     46 pub trait Element: Sized + Clone + Debug {
     47    type Impl: SelectorImpl;
     48 
     49    /// Converts self into an opaque representation.
     50    fn opaque(&self) -> OpaqueElement;
     51 
     52    fn parent_element(&self) -> Option<Self>;
     53 
     54    /// Whether the parent node of this element is a shadow root.
     55    fn parent_node_is_shadow_root(&self) -> bool;
     56 
     57    /// The host of the containing shadow root, if any.
     58    fn containing_shadow_host(&self) -> Option<Self>;
     59 
     60    /// The parent of a given pseudo-element, after matching a pseudo-element
     61    /// selector.
     62    ///
     63    /// This is guaranteed to be called in a pseudo-element.
     64    fn pseudo_element_originating_element(&self) -> Option<Self> {
     65        debug_assert!(self.is_pseudo_element());
     66        self.parent_element()
     67    }
     68 
     69    /// Whether we're matching on a pseudo-element.
     70    fn is_pseudo_element(&self) -> bool;
     71 
     72    /// Skips non-element nodes
     73    fn prev_sibling_element(&self) -> Option<Self>;
     74 
     75    /// Skips non-element nodes
     76    fn next_sibling_element(&self) -> Option<Self>;
     77 
     78    /// Skips non-element nodes
     79    fn first_element_child(&self) -> Option<Self>;
     80 
     81    fn is_html_element_in_html_document(&self) -> bool;
     82 
     83    fn has_local_name(&self, local_name: &<Self::Impl as SelectorImpl>::BorrowedLocalName) -> bool;
     84 
     85    /// Empty string for no namespace
     86    fn has_namespace(&self, ns: &<Self::Impl as SelectorImpl>::BorrowedNamespaceUrl) -> bool;
     87 
     88    /// Whether this element and the `other` element have the same local name and namespace.
     89    fn is_same_type(&self, other: &Self) -> bool;
     90 
     91    fn attr_matches(
     92        &self,
     93        ns: &NamespaceConstraint<&<Self::Impl as SelectorImpl>::NamespaceUrl>,
     94        local_name: &<Self::Impl as SelectorImpl>::LocalName,
     95        operation: &AttrSelectorOperation<&<Self::Impl as SelectorImpl>::AttrValue>,
     96    ) -> bool;
     97 
     98    fn has_attr_in_no_namespace(
     99        &self,
    100        local_name: &<Self::Impl as SelectorImpl>::LocalName,
    101    ) -> bool {
    102        self.attr_matches(
    103            &NamespaceConstraint::Specific(&crate::parser::namespace_empty_string::<Self::Impl>()),
    104            local_name,
    105            &AttrSelectorOperation::Exists,
    106        )
    107    }
    108 
    109    fn match_non_ts_pseudo_class(
    110        &self,
    111        pc: &<Self::Impl as SelectorImpl>::NonTSPseudoClass,
    112        context: &mut MatchingContext<Self::Impl>,
    113    ) -> bool;
    114 
    115    fn match_pseudo_element(
    116        &self,
    117        pe: &<Self::Impl as SelectorImpl>::PseudoElement,
    118        context: &mut MatchingContext<Self::Impl>,
    119    ) -> bool;
    120 
    121    /// Sets selector flags on the elemnt itself or the parent, depending on the
    122    /// flags, which indicate what kind of work may need to be performed when
    123    /// DOM state changes.
    124    fn apply_selector_flags(&self, flags: ElementSelectorFlags);
    125 
    126    /// Whether this element is a `link`.
    127    fn is_link(&self) -> bool;
    128 
    129    /// Returns whether the element is an HTML <slot> element.
    130    fn is_html_slot_element(&self) -> bool;
    131 
    132    /// Returns the assigned <slot> element this element is assigned to.
    133    ///
    134    /// Necessary for the `::slotted` pseudo-class.
    135    fn assigned_slot(&self) -> Option<Self> {
    136        None
    137    }
    138 
    139    fn has_id(
    140        &self,
    141        id: &<Self::Impl as SelectorImpl>::Identifier,
    142        case_sensitivity: CaseSensitivity,
    143    ) -> bool;
    144 
    145    fn has_class(
    146        &self,
    147        name: &<Self::Impl as SelectorImpl>::Identifier,
    148        case_sensitivity: CaseSensitivity,
    149    ) -> bool;
    150 
    151    fn has_custom_state(&self, name: &<Self::Impl as SelectorImpl>::Identifier) -> bool;
    152 
    153    /// Returns the mapping from the `exportparts` attribute in the reverse
    154    /// direction, that is, in an outer-tree -> inner-tree direction.
    155    fn imported_part(
    156        &self,
    157        name: &<Self::Impl as SelectorImpl>::Identifier,
    158    ) -> Option<<Self::Impl as SelectorImpl>::Identifier>;
    159 
    160    fn is_part(&self, name: &<Self::Impl as SelectorImpl>::Identifier) -> bool;
    161 
    162    /// Returns whether this element matches `:empty`.
    163    ///
    164    /// That is, whether it does not contain any child element or any non-zero-length text node.
    165    /// See http://dev.w3.org/csswg/selectors-3/#empty-pseudo
    166    fn is_empty(&self) -> bool;
    167 
    168    /// Returns whether this element matches `:root`,
    169    /// i.e. whether it is the root element of a document.
    170    ///
    171    /// Note: this can be false even if `.parent_element()` is `None`
    172    /// if the parent node is a `DocumentFragment`.
    173    fn is_root(&self) -> bool;
    174 
    175    /// Returns whether this element should ignore matching nth child
    176    /// selector.
    177    fn ignores_nth_child_selectors(&self) -> bool {
    178        false
    179    }
    180 
    181    /// Add hashes unique to this element to the given filter, returning true
    182    /// if any got added.
    183    fn add_element_unique_hashes(&self, filter: &mut BloomFilter) -> bool;
    184 }