aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/layout_dom/document.rs
diff options
context:
space:
mode:
authorMartin Robinson <mrobinson@igalia.com>2023-05-02 08:35:33 +0200
committerMartin Robinson <mrobinson@igalia.com>2023-05-05 17:16:38 +0200
commit2d31d4301d66bce4678af848e80905a35b9c02aa (patch)
treed6386d2c0984ea74b733e3393a187aff6065ad1f /components/script/layout_dom/document.rs
parentab0d462c83b6a13d64f664e09276d6c8decb5a02 (diff)
downloadservo-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.rs114
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,
+ }
+ }
+}