[LFC] Add LayoutTreeBuilder class to generate the layout tree
authorzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 28 Apr 2018 23:13:04 +0000 (23:13 +0000)
committerzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 28 Apr 2018 23:13:04 +0000 (23:13 +0000)
https://bugs.webkit.org/show_bug.cgi?id=185108

Reviewed by Antti Koivisto.

This is for testing purposes.

* WebCore.xcodeproj/project.pbxproj:
* layout/FormattingState.cpp:
(WebCore::Layout::FormattingState::~FormattingState):
* layout/FormattingState.h:
* layout/LayoutContext.h:
* layout/blockformatting/BlockFormattingState.cpp:
(WebCore::Layout::BlockFormattingState::~BlockFormattingState):
* layout/blockformatting/BlockFormattingState.h:
* layout/inlineformatting/InlineFormattingState.cpp:
(WebCore::Layout::InlineFormattingState::~InlineFormattingState):
* layout/inlineformatting/InlineFormattingState.h:
* layout/layouttree/LayoutBlockContainer.h:
* layout/layouttree/LayoutBox.h:
* layout/layouttree/LayoutContainer.h:
* layout/layouttree/LayoutInlineContainer.h:
* layout/layouttree/LayoutTreeBuilder.cpp: Added.
(WebCore::Layout::TreeBuilder::createLayoutTree):
(WebCore::Layout::TreeBuilder::createSubTree):
(WebCore::Layout::outputLayoutBox):
(WebCore::Layout::outputLayoutTree):
(WebCore::Layout::TreeBuilder::showLayoutTree):
(WebCore::Layout::printLayoutTreeForLiveDocuments):
* layout/layouttree/LayoutTreeBuilder.h: Copied from Source/WebCore/layout/layouttree/LayoutBlockContainer.h.
* page/mac/PageMac.mm:
(WebCore::Page::platformInitialize):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@231141 268f45cc-cd09-0410-ab3c-d52691b4dbfc

17 files changed:
Source/WebCore/ChangeLog
Source/WebCore/Sources.txt
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/layout/FormattingState.cpp
Source/WebCore/layout/FormattingState.h
Source/WebCore/layout/LayoutContext.h
Source/WebCore/layout/blockformatting/BlockFormattingState.cpp
Source/WebCore/layout/blockformatting/BlockFormattingState.h
Source/WebCore/layout/inlineformatting/InlineFormattingState.cpp
Source/WebCore/layout/inlineformatting/InlineFormattingState.h
Source/WebCore/layout/layouttree/LayoutBlockContainer.h
Source/WebCore/layout/layouttree/LayoutBox.h
Source/WebCore/layout/layouttree/LayoutContainer.h
Source/WebCore/layout/layouttree/LayoutInlineContainer.h
Source/WebCore/layout/layouttree/LayoutTreeBuilder.cpp [new file with mode: 0644]
Source/WebCore/layout/layouttree/LayoutTreeBuilder.h [new file with mode: 0644]
Source/WebCore/page/mac/PageMac.mm

index f37324fcfe2dfd5d8a3729742c3a45466a750cac..a9717c7e5088cd9207ceb416b4e236a9bdfeb962 100644 (file)
@@ -1,3 +1,38 @@
+2018-04-28  Zalan Bujtas  <zalan@apple.com>
+
+        [LFC] Add LayoutTreeBuilder class to generate the layout tree
+        https://bugs.webkit.org/show_bug.cgi?id=185108
+
+        Reviewed by Antti Koivisto.
+
+        This is for testing purposes.
+
+        * WebCore.xcodeproj/project.pbxproj:
+        * layout/FormattingState.cpp:
+        (WebCore::Layout::FormattingState::~FormattingState):
+        * layout/FormattingState.h:
+        * layout/LayoutContext.h:
+        * layout/blockformatting/BlockFormattingState.cpp:
+        (WebCore::Layout::BlockFormattingState::~BlockFormattingState):
+        * layout/blockformatting/BlockFormattingState.h:
+        * layout/inlineformatting/InlineFormattingState.cpp:
+        (WebCore::Layout::InlineFormattingState::~InlineFormattingState):
+        * layout/inlineformatting/InlineFormattingState.h:
+        * layout/layouttree/LayoutBlockContainer.h:
+        * layout/layouttree/LayoutBox.h:
+        * layout/layouttree/LayoutContainer.h:
+        * layout/layouttree/LayoutInlineContainer.h:
+        * layout/layouttree/LayoutTreeBuilder.cpp: Added.
+        (WebCore::Layout::TreeBuilder::createLayoutTree):
+        (WebCore::Layout::TreeBuilder::createSubTree):
+        (WebCore::Layout::outputLayoutBox):
+        (WebCore::Layout::outputLayoutTree):
+        (WebCore::Layout::TreeBuilder::showLayoutTree):
+        (WebCore::Layout::printLayoutTreeForLiveDocuments):
+        * layout/layouttree/LayoutTreeBuilder.h: Copied from Source/WebCore/layout/layouttree/LayoutBlockContainer.h.
+        * page/mac/PageMac.mm:
+        (WebCore::Page::platformInitialize):
+
 2018-04-28  Zalan Bujtas  <zalan@apple.com>
 
         [LFC] Implement BlockMarginCollapse functions.
index 4bac2c085edfff80476488b9297ba709685bc9aa..73c1351580084451bb70f9465d7f8457edc7474b 100644 (file)
@@ -1229,6 +1229,7 @@ layout/layouttree/LayoutBox.cpp
 layout/layouttree/LayoutContainer.cpp
 layout/layouttree/LayoutInlineBox.cpp
 layout/layouttree/LayoutInlineContainer.cpp
+layout/layouttree/LayoutTreeBuilder.cpp
 
 loader/ContentFilter.cpp
 loader/CookieJar.cpp
index f27ed18c3cac79f1d650732bf1fe455c0016fa31..36a443fb492e2e99a07d4b85f66d2c37c21c4083 100644 (file)
                11100FC72092764C0081AA6C /* LayoutIterator.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LayoutIterator.h; sourceTree = "<group>"; };
                11100FC920927CBC0081AA6C /* LayoutChildIterator.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LayoutChildIterator.h; sourceTree = "<group>"; };
                11100FCA2092868D0081AA6C /* LayoutAncestorIterator.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LayoutAncestorIterator.h; sourceTree = "<group>"; };
+               11100FD5209514DE0081AA6C /* LayoutTreeBuilder.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = LayoutTreeBuilder.cpp; sourceTree = "<group>"; };
+               11100FD7209514DF0081AA6C /* LayoutTreeBuilder.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LayoutTreeBuilder.h; sourceTree = "<group>"; };
                112B34D01E60B8A700BB310A /* SimpleLineLayoutPagination.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SimpleLineLayoutPagination.cpp; sourceTree = "<group>"; };
                112B34D41E60B98300BB310A /* SimpleLineLayoutPagination.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SimpleLineLayoutPagination.h; sourceTree = "<group>"; };
                113409D7203E038000C66915 /* RenderTreeBuilderContinuation.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = RenderTreeBuilderContinuation.cpp; sourceTree = "<group>"; };
                                1199FA4E208E3899002358CC /* LayoutInlineContainer.cpp */,
                                1199FA4D208E3899002358CC /* LayoutInlineContainer.h */,
                                11100FC72092764C0081AA6C /* LayoutIterator.h */,
+                               11100FD5209514DE0081AA6C /* LayoutTreeBuilder.cpp */,
+                               11100FD7209514DF0081AA6C /* LayoutTreeBuilder.h */,
                        );
                        path = layouttree;
                        sourceTree = "<group>";
                1C09D0501E31C32900725F18 /* libPAL.a */ = {
                        isa = PBXReferenceProxy;
                        fileType = archive.ar;
-                       name = libPAL.a;
-                       path = lib.a;
+                       path = libPAL.a;
                        remoteRef = 1C09D04F1E31C32900725F18 /* PBXContainerItemProxy */;
                        sourceTree = BUILT_PRODUCTS_DIR;
                };
index 0e28e8569a949e775f5adcbcfee54f4c2f08f82a..ff691a7036c622fe9b3727f3af4d43482611599b 100644 (file)
@@ -40,6 +40,10 @@ FormattingState::FormattingState(Ref<FloatingState>&& floatingState)
 {
 }
 
+FormattingState::~FormattingState()
+{
+}
+
 }
 }
 #endif
index 698b3c7f2cbc51dc502dfaa548a6b6d6db71ee5e..10c3a4278a97244d5587853cef8995c7e6f6fcd6 100644 (file)
@@ -41,6 +41,7 @@ class FormattingState {
     WTF_MAKE_ISO_ALLOCATED(FormattingState);
 public:
     FormattingState(Ref<FloatingState>&&);
+    virtual ~FormattingState();
 
     FloatingState& floatingState() const { return m_floatingState; }
 
index 5768bd2fe465ca2337abcd5f029bcffc1c28f4a4..a99b15f7f89476cd19cbbe5a55f3215268f784a4 100644 (file)
@@ -27,6 +27,8 @@
 
 #if ENABLE(LAYOUT_FORMATTING_CONTEXT)
 
+#include "FormattingContext.h"
+#include "FormattingState.h"
 #include "LayoutBox.h"
 #include <wtf/IsoMalloc.h>
 
@@ -38,8 +40,6 @@ class Box;
 
 namespace Layout {
 
-class FormattingContext;
-class FormattingState;
 class StyleDiff;
 
 // LayoutContext is the entry point for layout. It takes a (formatting root)container which acts as the root of the layout context.
index 95a8a0bd3f4aafc44193075a3c853ce18ac33749..c951eee36c901fa0bc6451e27280a15d01708260 100644 (file)
@@ -40,6 +40,10 @@ BlockFormattingState::BlockFormattingState(Ref<FloatingState>&& floatingState)
 {
 }
 
+BlockFormattingState::~BlockFormattingState()
+{
+}
+
 }
 }
 #endif
index 6202310888461f38c704e60a959d855e54813232..44e5d83c5c05a4fb2b17aea39e425b0707c70710 100644 (file)
@@ -39,6 +39,7 @@ class BlockFormattingState : public FormattingState {
     WTF_MAKE_ISO_ALLOCATED(BlockFormattingState);
 public:
     BlockFormattingState(Ref<FloatingState>&&);
+    virtual ~BlockFormattingState();
 };
 
 }
index 99970d1d8ca85cbb58c10a1bcc6f4562365666bb..721d8294fa8561d0a0382d54935a502ded4c1887 100644 (file)
@@ -40,6 +40,10 @@ InlineFormattingState::InlineFormattingState(Ref<FloatingState>&& floatingState)
 {
 }
 
+InlineFormattingState::~InlineFormattingState()
+{
+}
+
 }
 }
 #endif
index c7b5d7b3296f7b2b325ae481490ffc63e0ed25cd..5623dd98649ec1137bd414ebe0ddb7d10936584e 100644 (file)
@@ -39,6 +39,7 @@ class InlineFormattingState : public FormattingState {
     WTF_MAKE_ISO_ALLOCATED(InlineFormattingState);
 public:
     InlineFormattingState(Ref<FloatingState>&&);
+    virtual ~InlineFormattingState();
 };
 
 }
index 98c41a3d769f504cc7b54e601d77dfad3d2cbc95..dade7060eadd09b3d9e3628ada6f886fb60fd095 100644 (file)
@@ -39,9 +39,13 @@ namespace Layout {
 class BlockContainer : public Container {
     WTF_MAKE_ISO_ALLOCATED(BlockContainer);
 public:
-    BlockContainer(RenderStyle&&, BaseTypeFlags);
+    friend class TreeBuilder;
 
     bool establishesInlineFormattingContext() const final;
+
+protected:
+    BlockContainer(RenderStyle&&, BaseTypeFlags = BlockContainerFlag);
+
 };
 
 }
index 8aa330ddd232aac08cd63fc16c814fc5f1077e26..5c4563c642525ea0d82bf2774cdf5d5014932e9f 100644 (file)
@@ -42,9 +42,7 @@ class Box {
     WTF_MAKE_ISO_ALLOCATED(Box);
 public:
     friend class TreeBuilder;
-    typedef unsigned BaseTypeFlags;
 
-    Box(RenderStyle&&, BaseTypeFlags);
     virtual ~Box();
 
     bool establishesFormattingContext() const;
@@ -83,6 +81,7 @@ public:
     const Box* previousInFlowSibling() const;
     const Box* previousInFlowOrFloatingSibling() const;
 
+    typedef unsigned BaseTypeFlags;
     bool isContainer() const { return m_baseTypeFlags & ContainerFlag; }
     bool isBlockContainer() const { return m_baseTypeFlags & BlockContainerFlag; }
     bool isInlineBox() const { return m_baseTypeFlags & InlineBoxFlag; }
@@ -98,6 +97,7 @@ protected:
         InlineBoxFlag         = 1 << 2,
         InlineContainerFlag   = 1 << 3
     };
+    Box(RenderStyle&&, BaseTypeFlags);
 
     bool isOverflowVisible() const;
 
@@ -114,7 +114,7 @@ private:
     Box* m_previousSibling { nullptr };
     Box* m_nextSibling { nullptr };
 
-    unsigned m_baseTypeFlags : 3;
+    unsigned m_baseTypeFlags : 4;
     unsigned m_isAnonymous : 1;
 
 };
index dacd6b4e70bb172e80642a1346e56bfdeb710597..6ba89ae73276ce1d96ebf70c8b6f8abb13480b3c 100644 (file)
@@ -42,8 +42,6 @@ class Container : public Box {
 public:
     friend class TreeBuilder;
 
-    Container(RenderStyle&&, BaseTypeFlags);
-
     const Box* firstChild() const { return m_firstChild; }
     const Box* firstInFlowChild() const;
     const Box* firstInFlowOrFloatingChild() const;
@@ -57,6 +55,9 @@ public:
 
     const Vector<WeakPtr<Box>>& outOfFlowDescendants() { return m_outOfFlowDescendants; }
 
+protected:
+    Container(RenderStyle&&, BaseTypeFlags);
+
 private:
     void setFirstChild(Box&);
     void setLastChild(Box&);
index a93a690778687f2bd5b59bf85b2517b44508c964..aaa21d5aba906b5a958017ebba516406da6fa371 100644 (file)
@@ -39,7 +39,10 @@ namespace Layout {
 class InlineContainer : public Container {
     WTF_MAKE_ISO_ALLOCATED(InlineContainer);
 public:
-    InlineContainer(RenderStyle&&, BaseTypeFlags);
+    friend class TreeBuilder;
+
+protected:
+    InlineContainer(RenderStyle&&, BaseTypeFlags = InlineContainerFlag);
 };
 
 }
diff --git a/Source/WebCore/layout/layouttree/LayoutTreeBuilder.cpp b/Source/WebCore/layout/layouttree/LayoutTreeBuilder.cpp
new file mode 100644 (file)
index 0000000..e785269
--- /dev/null
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "LayoutTreeBuilder.h"
+
+#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
+
+#include "LayoutBlockContainer.h"
+#include "LayoutChildIterator.h"
+#include "LayoutContainer.h"
+#include "LayoutInlineBox.h"
+#include "LayoutInlineContainer.h"
+#include "RenderBlock.h"
+#include "RenderChildIterator.h"
+#include "RenderElement.h"
+#include "RenderInline.h"
+#include "RenderStyle.h"
+#include "RenderView.h"
+#include <wtf/text/TextStream.h>
+
+namespace WebCore {
+namespace Layout {
+
+std::unique_ptr<Container> TreeBuilder::createLayoutTree(const RenderView& renderView)
+{
+    std::unique_ptr<Container> initialContainingBlock(new BlockContainer(RenderStyle::clone(renderView.style())));
+    TreeBuilder::createSubTree(renderView, *initialContainingBlock);
+    return initialContainingBlock;
+}
+
+void TreeBuilder::createSubTree(const RenderElement& rootRenderer, Container& rootContainer)
+{
+    // Skip RenderText (and some others) for now.
+    for (auto& child : childrenOfType<RenderElement>(rootRenderer)) {
+        Box* box = nullptr;
+        if (is<RenderBlock>(child)) {
+            box = new BlockContainer(RenderStyle::clone(child.style()));
+            createSubTree(child, downcast<Container>(*box));
+        } else if (is<RenderInline>(child)) {
+            box = new InlineContainer(RenderStyle::clone(child.style()));
+            createSubTree(child, downcast<Container>(*box));
+        } else
+            ASSERT_NOT_REACHED();
+
+        if (!rootContainer.hasChild()) {
+            rootContainer.setFirstChild(*box);
+            rootContainer.setLastChild(*box);
+        } else {
+            auto* lastChild = const_cast<Box*>(rootContainer.lastChild());
+            box->setPreviousSibling(*lastChild);
+            lastChild->setNextSibling(*box);
+            rootContainer.setLastChild(*box);
+        }
+        box->setParent(rootContainer);
+    }
+}
+
+#if ENABLE(TREE_DEBUGGING)
+static void outputLayoutBox(TextStream& stream, const Box& layoutBox, unsigned depth)
+{
+    unsigned printedCharacters = 0;
+    while (++printedCharacters <= depth * 2)
+        stream << " ";
+
+    if (is<InlineContainer>(layoutBox))
+        stream << "inline container";
+    else if (is<InlineBox>(layoutBox))
+        stream << "inline box";
+    else if (is<BlockContainer>(layoutBox)) {
+        if (!layoutBox.parent())
+            stream << "initial ";
+        stream << "block container";
+    } else
+        stream << "box";
+    stream << " at [0 0] size [0 0]";
+    stream << " object [" << &layoutBox << "]";
+
+    stream.nextLine();
+}
+
+static void outputLayoutTree(TextStream& stream, const Container& rootContainer, unsigned depth)
+{
+    for (auto& child : childrenOfType<Box>(rootContainer)) {
+        outputLayoutBox(stream, child, depth);
+        if (is<Container>(child))
+            outputLayoutTree(stream, downcast<Container>(child), depth + 1);
+    }
+}
+
+void TreeBuilder::showLayoutTree(const Container& layoutBox)
+{
+    TextStream stream(TextStream::LineMode::MultipleLine, TextStream::Formatting::SVGStyleRect);
+    outputLayoutBox(stream, layoutBox, 0);
+    outputLayoutTree(stream, layoutBox, 1);
+    WTFLogAlways("%s", stream.release().utf8().data());
+}
+
+void printLayoutTreeForLiveDocuments()
+{
+    for (const auto* document : Document::allDocuments()) {
+        if (!document->renderView())
+            continue;
+        if (document->frame() && document->frame()->isMainFrame())
+            fprintf(stderr, "----------------------main frame--------------------------\n");
+        fprintf(stderr, "%s\n", document->url().string().utf8().data());
+        Layout::TreeBuilder::showLayoutTree(*TreeBuilder::createLayoutTree(*document->renderView()));
+    }
+}
+#endif
+
+}
+}
+
+#endif
diff --git a/Source/WebCore/layout/layouttree/LayoutTreeBuilder.h b/Source/WebCore/layout/layouttree/LayoutTreeBuilder.h
new file mode 100644 (file)
index 0000000..c3b87b9
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
+
+namespace WebCore {
+
+class RenderElement;
+class RenderView;
+
+namespace Layout {
+
+class Container;
+
+class TreeBuilder {
+public:
+    static std::unique_ptr<Container> createLayoutTree(const RenderView&);
+    static void showLayoutTree(const Container&);
+
+private:
+    static void createSubTree(const RenderElement& rootRenderer, Container& rootContainer);
+};
+
+#if ENABLE(TREE_DEBUGGING)
+void printLayoutTreeForLiveDocuments();
+#endif
+
+}
+}
+
+#endif
index aa030c54617ff0eb3a81324dc9451d29cf2e5922..edf18107e2004eed48c3b1293a31cbe174e22543 100644 (file)
@@ -33,6 +33,7 @@
 #import "Frame.h"
 #import "FrameLoader.h"
 #import "FrameTree.h"
+#import "LayoutTreeBuilder.h"
 #import "Logging.h"
 #import "RenderObject.h"
 #import <pal/Logging.h>
@@ -56,6 +57,9 @@ void Page::platformInitialize()
     std::call_once(onceFlag, [] {
         PAL::registerNotifyCallback("com.apple.WebKit.showRenderTree", printRenderTreeForLiveDocuments);
         PAL::registerNotifyCallback("com.apple.WebKit.showLayerTree", printLayerTreeForLiveDocuments);
+#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
+        PAL::registerNotifyCallback("com.apple.WebKit.showLayoutTree", Layout::printLayoutTreeForLiveDocuments);
+#endif
     });
 #endif
 }