[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):
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@231141 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index f37324f..a9717c7 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,5 +1,40 @@
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.
https://bugs.webkit.org/show_bug.cgi?id=185036
diff --git a/Source/WebCore/Sources.txt b/Source/WebCore/Sources.txt
index 4bac2c0..73c1351 100644
--- a/Source/WebCore/Sources.txt
+++ b/Source/WebCore/Sources.txt
@@ -1229,6 +1229,7 @@
layout/layouttree/LayoutContainer.cpp
layout/layouttree/LayoutInlineBox.cpp
layout/layouttree/LayoutInlineContainer.cpp
+layout/layouttree/LayoutTreeBuilder.cpp
loader/ContentFilter.cpp
loader/CookieJar.cpp
diff --git a/Source/WebCore/WebCore.xcodeproj/project.pbxproj b/Source/WebCore/WebCore.xcodeproj/project.pbxproj
index f27ed18..36a443f 100644
--- a/Source/WebCore/WebCore.xcodeproj/project.pbxproj
+++ b/Source/WebCore/WebCore.xcodeproj/project.pbxproj
@@ -5719,6 +5719,8 @@
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>"; };
@@ -15669,6 +15671,8 @@
1199FA4E208E3899002358CC /* LayoutInlineContainer.cpp */,
1199FA4D208E3899002358CC /* LayoutInlineContainer.h */,
11100FC72092764C0081AA6C /* LayoutIterator.h */,
+ 11100FD5209514DE0081AA6C /* LayoutTreeBuilder.cpp */,
+ 11100FD7209514DF0081AA6C /* LayoutTreeBuilder.h */,
);
path = layouttree;
sourceTree = "<group>";
@@ -31018,8 +31022,7 @@
1C09D0501E31C32900725F18 /* libPAL.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
- name = libPAL.a;
- path = lib.a;
+ path = libPAL.a;
remoteRef = 1C09D04F1E31C32900725F18 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
diff --git a/Source/WebCore/layout/FormattingState.cpp b/Source/WebCore/layout/FormattingState.cpp
index 0e28e85..ff691a7 100644
--- a/Source/WebCore/layout/FormattingState.cpp
+++ b/Source/WebCore/layout/FormattingState.cpp
@@ -40,6 +40,10 @@
{
}
+FormattingState::~FormattingState()
+{
+}
+
}
}
#endif
diff --git a/Source/WebCore/layout/FormattingState.h b/Source/WebCore/layout/FormattingState.h
index 698b3c7..10c3a42 100644
--- a/Source/WebCore/layout/FormattingState.h
+++ b/Source/WebCore/layout/FormattingState.h
@@ -41,6 +41,7 @@
WTF_MAKE_ISO_ALLOCATED(FormattingState);
public:
FormattingState(Ref<FloatingState>&&);
+ virtual ~FormattingState();
FloatingState& floatingState() const { return m_floatingState; }
diff --git a/Source/WebCore/layout/LayoutContext.h b/Source/WebCore/layout/LayoutContext.h
index 5768bd2..a99b15f 100644
--- a/Source/WebCore/layout/LayoutContext.h
+++ b/Source/WebCore/layout/LayoutContext.h
@@ -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 @@
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.
diff --git a/Source/WebCore/layout/blockformatting/BlockFormattingState.cpp b/Source/WebCore/layout/blockformatting/BlockFormattingState.cpp
index 95a8a0b..c951eee 100644
--- a/Source/WebCore/layout/blockformatting/BlockFormattingState.cpp
+++ b/Source/WebCore/layout/blockformatting/BlockFormattingState.cpp
@@ -40,6 +40,10 @@
{
}
+BlockFormattingState::~BlockFormattingState()
+{
+}
+
}
}
#endif
diff --git a/Source/WebCore/layout/blockformatting/BlockFormattingState.h b/Source/WebCore/layout/blockformatting/BlockFormattingState.h
index 6202310..44e5d83 100644
--- a/Source/WebCore/layout/blockformatting/BlockFormattingState.h
+++ b/Source/WebCore/layout/blockformatting/BlockFormattingState.h
@@ -39,6 +39,7 @@
WTF_MAKE_ISO_ALLOCATED(BlockFormattingState);
public:
BlockFormattingState(Ref<FloatingState>&&);
+ virtual ~BlockFormattingState();
};
}
diff --git a/Source/WebCore/layout/inlineformatting/InlineFormattingState.cpp b/Source/WebCore/layout/inlineformatting/InlineFormattingState.cpp
index 99970d1..721d829 100644
--- a/Source/WebCore/layout/inlineformatting/InlineFormattingState.cpp
+++ b/Source/WebCore/layout/inlineformatting/InlineFormattingState.cpp
@@ -40,6 +40,10 @@
{
}
+InlineFormattingState::~InlineFormattingState()
+{
+}
+
}
}
#endif
diff --git a/Source/WebCore/layout/inlineformatting/InlineFormattingState.h b/Source/WebCore/layout/inlineformatting/InlineFormattingState.h
index c7b5d7b..5623dd9 100644
--- a/Source/WebCore/layout/inlineformatting/InlineFormattingState.h
+++ b/Source/WebCore/layout/inlineformatting/InlineFormattingState.h
@@ -39,6 +39,7 @@
WTF_MAKE_ISO_ALLOCATED(InlineFormattingState);
public:
InlineFormattingState(Ref<FloatingState>&&);
+ virtual ~InlineFormattingState();
};
}
diff --git a/Source/WebCore/layout/layouttree/LayoutBlockContainer.h b/Source/WebCore/layout/layouttree/LayoutBlockContainer.h
index 98c41a3..dade706 100644
--- a/Source/WebCore/layout/layouttree/LayoutBlockContainer.h
+++ b/Source/WebCore/layout/layouttree/LayoutBlockContainer.h
@@ -39,9 +39,13 @@
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);
+
};
}
diff --git a/Source/WebCore/layout/layouttree/LayoutBox.h b/Source/WebCore/layout/layouttree/LayoutBox.h
index 8aa330d..5c4563c 100644
--- a/Source/WebCore/layout/layouttree/LayoutBox.h
+++ b/Source/WebCore/layout/layouttree/LayoutBox.h
@@ -42,9 +42,7 @@
WTF_MAKE_ISO_ALLOCATED(Box);
public:
friend class TreeBuilder;
- typedef unsigned BaseTypeFlags;
- Box(RenderStyle&&, BaseTypeFlags);
virtual ~Box();
bool establishesFormattingContext() const;
@@ -83,6 +81,7 @@
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 @@
InlineBoxFlag = 1 << 2,
InlineContainerFlag = 1 << 3
};
+ Box(RenderStyle&&, BaseTypeFlags);
bool isOverflowVisible() const;
@@ -114,7 +114,7 @@
Box* m_previousSibling { nullptr };
Box* m_nextSibling { nullptr };
- unsigned m_baseTypeFlags : 3;
+ unsigned m_baseTypeFlags : 4;
unsigned m_isAnonymous : 1;
};
diff --git a/Source/WebCore/layout/layouttree/LayoutContainer.h b/Source/WebCore/layout/layouttree/LayoutContainer.h
index dacd6b4..6ba89ae 100644
--- a/Source/WebCore/layout/layouttree/LayoutContainer.h
+++ b/Source/WebCore/layout/layouttree/LayoutContainer.h
@@ -42,8 +42,6 @@
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 @@
const Vector<WeakPtr<Box>>& outOfFlowDescendants() { return m_outOfFlowDescendants; }
+protected:
+ Container(RenderStyle&&, BaseTypeFlags);
+
private:
void setFirstChild(Box&);
void setLastChild(Box&);
diff --git a/Source/WebCore/layout/layouttree/LayoutInlineContainer.h b/Source/WebCore/layout/layouttree/LayoutInlineContainer.h
index a93a690..aaa21d5 100644
--- a/Source/WebCore/layout/layouttree/LayoutInlineContainer.h
+++ b/Source/WebCore/layout/layouttree/LayoutInlineContainer.h
@@ -39,7 +39,10 @@
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
index 0000000..e785269
--- /dev/null
+++ b/Source/WebCore/layout/layouttree/LayoutTreeBuilder.cpp
@@ -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
index 0000000..c3b87b9
--- /dev/null
+++ b/Source/WebCore/layout/layouttree/LayoutTreeBuilder.h
@@ -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
diff --git a/Source/WebCore/page/mac/PageMac.mm b/Source/WebCore/page/mac/PageMac.mm
index aa030c5..edf1810 100644
--- a/Source/WebCore/page/mac/PageMac.mm
+++ b/Source/WebCore/page/mac/PageMac.mm
@@ -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 @@
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
}