diff options
author | Martin Robinson <mrobinson@igalia.com> | 2023-05-02 08:35:33 +0200 |
---|---|---|
committer | Martin Robinson <mrobinson@igalia.com> | 2023-05-05 17:16:38 +0200 |
commit | 2d31d4301d66bce4678af848e80905a35b9c02aa (patch) | |
tree | d6386d2c0984ea74b733e3393a187aff6065ad1f /components/script/layout_dom/document.rs | |
parent | ab0d462c83b6a13d64f664e09276d6c8decb5a02 (diff) | |
download | servo-2d31d4301d66bce4678af848e80905a35b9c02aa.tar.gz servo-2d31d4301d66bce4678af848e80905a35b9c02aa.zip |
Eliminate duplicate Layout DOM wrappers
There are duplicate sets of Layout DOM wrappers: one for Layout 2013 and
one for Layout 2020. As part of cleaning up and simplifying the
wrappers, this change parameterizes them on the specific layout data
they contain. This allows them to be shared again. In addition, various
small cleanups are included.
Fixes #29691.
Diffstat (limited to 'components/script/layout_dom/document.rs')
-rw-r--r-- | components/script/layout_dom/document.rs | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/components/script/layout_dom/document.rs b/components/script/layout_dom/document.rs new file mode 100644 index 00000000000..e723f731cab --- /dev/null +++ b/components/script/layout_dom/document.rs @@ -0,0 +1,114 @@ +/* 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 https://mozilla.org/MPL/2.0/. */ + +use crate::dom::bindings::root::LayoutDom; +use crate::dom::document::{Document, LayoutDocumentHelpers}; +use crate::dom::node::{LayoutNodeHelpers, Node, NodeFlags}; +use crate::layout_dom::ServoLayoutElement; +use crate::layout_dom::ServoLayoutNode; +use crate::layout_dom::ServoShadowRoot; +use script_layout_interface::wrapper_traits::LayoutDataTrait; +use selectors::matching::QuirksMode; +use std::marker::PhantomData; +use style::dom::{TDocument, TNode}; +use style::media_queries::Device; +use style::shared_lock::{ + SharedRwLock as StyleSharedRwLock, SharedRwLockReadGuard as StyleSharedRwLockReadGuard, +}; + +// A wrapper around documents that ensures ayout can only ever access safe properties. +pub struct ServoLayoutDocument<'dom, LayoutDataType: LayoutDataTrait> { + /// The wrapped private DOM Document + document: LayoutDom<'dom, Document>, + + /// A PhantomData that is used to track the type of the stored layout data. + phantom: PhantomData<LayoutDataType>, +} + +impl<'dom, LayoutDataType: LayoutDataTrait> Clone for ServoLayoutDocument<'dom, LayoutDataType> { + fn clone(&self) -> Self { + *self + } +} +impl<'dom, LayoutDataType: LayoutDataTrait> Copy for ServoLayoutDocument<'dom, LayoutDataType> {} + +impl<'ld, LayoutDataType: LayoutDataTrait> ::style::dom::TDocument + for ServoLayoutDocument<'ld, LayoutDataType> +{ + type ConcreteNode = ServoLayoutNode<'ld, LayoutDataType>; + + fn as_node(&self) -> Self::ConcreteNode { + ServoLayoutNode::from_layout_js(self.document.upcast()) + } + + fn quirks_mode(&self) -> QuirksMode { + self.document.quirks_mode() + } + + fn is_html_document(&self) -> bool { + self.document.is_html_document_for_layout() + } + + fn shared_lock(&self) -> &StyleSharedRwLock { + self.document.style_shared_lock() + } +} + +impl<'ld, LayoutDataType: LayoutDataTrait> ServoLayoutDocument<'ld, LayoutDataType> { + pub fn root_element(&self) -> Option<ServoLayoutElement<'ld, LayoutDataType>> { + self.as_node() + .dom_children() + .flat_map(|n| n.as_element()) + .next() + } + + pub fn needs_paint_from_layout(&self) { + unsafe { self.document.needs_paint_from_layout() } + } + + pub fn will_paint(&self) { + unsafe { self.document.will_paint() } + } + + pub fn style_shared_lock(&self) -> &StyleSharedRwLock { + self.document.style_shared_lock() + } + + pub fn shadow_roots(&self) -> Vec<ServoShadowRoot<LayoutDataType>> { + unsafe { + self.document + .shadow_roots() + .iter() + .map(|sr| { + debug_assert!(sr.upcast::<Node>().get_flag(NodeFlags::IS_CONNECTED)); + ServoShadowRoot::from_layout_js(*sr) + }) + .collect() + } + } + + pub fn flush_shadow_roots_stylesheets( + &self, + device: &Device, + quirks_mode: QuirksMode, + guard: &StyleSharedRwLockReadGuard, + ) { + unsafe { + if !self.document.shadow_roots_styles_changed() { + return; + } + self.document.flush_shadow_roots_stylesheets(); + for shadow_root in self.shadow_roots() { + shadow_root.flush_stylesheets(device, quirks_mode, guard); + } + } + } + + pub fn from_layout_js(doc: LayoutDom<'ld, Document>) -> Self { + ServoLayoutDocument { + document: doc, + phantom: PhantomData, + } + } +} |