summaryrefslogtreecommitdiff
path: root/Source/WebCore/rendering/RenderTreeAsText.cpp
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
commit1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch)
tree46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WebCore/rendering/RenderTreeAsText.cpp
parent32761a6cee1d0dee366b885b7b9c777e67885688 (diff)
downloadWebKitGtk-tarball-master.tar.gz
Diffstat (limited to 'Source/WebCore/rendering/RenderTreeAsText.cpp')
-rw-r--r--Source/WebCore/rendering/RenderTreeAsText.cpp336
1 files changed, 173 insertions, 163 deletions
diff --git a/Source/WebCore/rendering/RenderTreeAsText.cpp b/Source/WebCore/rendering/RenderTreeAsText.cpp
index d866bc64d..d7d37aa54 100644
--- a/Source/WebCore/rendering/RenderTreeAsText.cpp
+++ b/Source/WebCore/rendering/RenderTreeAsText.cpp
@@ -10,10 +10,10 @@
* 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 COMPUTER, INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``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 COMPUTER, INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* 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
@@ -26,6 +26,7 @@
#include "config.h"
#include "RenderTreeAsText.h"
+#include "ClipRect.h"
#include "Document.h"
#include "FlowThreadController.h"
#include "Frame.h"
@@ -33,7 +34,9 @@
#include "FrameView.h"
#include "HTMLElement.h"
#include "HTMLNames.h"
+#include "HTMLSpanElement.h"
#include "InlineTextBox.h"
+#include "Logging.h"
#include "PrintContext.h"
#include "PseudoElement.h"
#include "RenderBlockFlow.h"
@@ -43,35 +46,35 @@
#include "RenderInline.h"
#include "RenderIterator.h"
#include "RenderLayer.h"
+#include "RenderLayerBacking.h"
#include "RenderLineBreak.h"
#include "RenderListItem.h"
#include "RenderListMarker.h"
#include "RenderNamedFlowFragment.h"
#include "RenderNamedFlowThread.h"
#include "RenderRegion.h"
+#include "RenderSVGContainer.h"
+#include "RenderSVGGradientStop.h"
+#include "RenderSVGImage.h"
+#include "RenderSVGInlineText.h"
+#include "RenderSVGPath.h"
+#include "RenderSVGResourceContainer.h"
+#include "RenderSVGRoot.h"
+#include "RenderSVGText.h"
#include "RenderTableCell.h"
#include "RenderView.h"
#include "RenderWidget.h"
+#include "SVGRenderTreeAsText.h"
#include "ShadowRoot.h"
#include "SimpleLineLayoutResolver.h"
#include "StyleProperties.h"
+#include "TextStream.h"
#include <wtf/HexNumber.h>
#include <wtf/Vector.h>
#include <wtf/unicode/CharacterNames.h>
-#if ENABLE(SVG)
-#include "RenderSVGContainer.h"
-#include "RenderSVGGradientStop.h"
-#include "RenderSVGImage.h"
-#include "RenderSVGInlineText.h"
-#include "RenderSVGPath.h"
-#include "RenderSVGRoot.h"
-#include "RenderSVGText.h"
-#include "SVGRenderTreeAsText.h"
-#endif
-
-#if USE(ACCELERATED_COMPOSITING)
-#include "RenderLayerBacking.h"
+#if PLATFORM(MAC)
+#include "ScrollbarThemeMac.h"
#endif
namespace WebCore {
@@ -129,21 +132,21 @@ static String getTagName(Node* n)
static bool isEmptyOrUnstyledAppleStyleSpan(const Node* node)
{
- if (!node || !node->isHTMLElement() || !node->hasTagName(spanTag))
+ if (!is<HTMLSpanElement>(node))
return false;
- const HTMLElement* elem = toHTMLElement(node);
- if (elem->getAttribute(classAttr) != "Apple-style-span")
+ const HTMLElement& element = downcast<HTMLSpanElement>(*node);
+ if (element.getAttribute(classAttr) != "Apple-style-span")
return false;
if (!node->hasChildNodes())
return true;
- const StyleProperties* inlineStyleDecl = elem->inlineStyle();
+ const StyleProperties* inlineStyleDecl = element.inlineStyle();
return (!inlineStyleDecl || inlineStyleDecl->isEmpty());
}
-String quoteAndEscapeNonPrintables(const String& s)
+String quoteAndEscapeNonPrintables(StringView s)
{
StringBuilder result;
result.append('"');
@@ -201,51 +204,44 @@ void RenderTreeAsText::writeRenderObject(TextStream& ts, const RenderObject& o,
bool adjustForTableCells = cb ? cb->isTableCell() : false;
LayoutRect r;
- if (o.isText()) {
+ if (is<RenderText>(o)) {
// FIXME: Would be better to dump the bounding box x and y rather than the first run's x and y, but that would involve updating
// many test results.
- const RenderText& text = toRenderText(o);
- IntRect linesBox = text.linesBoundingBox();
- if (text.simpleLineLayout()) {
- int y = linesBox.y();
- if (text.containingBlock()->isTableCell())
- y -= toRenderTableCell(o.containingBlock())->intrinsicPaddingBefore();
- r = IntRect(linesBox.x(), y, linesBox.width(), linesBox.height());
- } else
- r = IntRect(text.firstRunX(), text.firstRunY(), linesBox.width(), linesBox.height());
- if (adjustForTableCells && !text.firstTextBox())
+ const RenderText& text = downcast<RenderText>(o);
+ r = IntRect(text.firstRunLocation(), text.linesBoundingBox().size());
+ if (!text.firstTextBox() && !text.simpleLineLayout())
adjustForTableCells = false;
} else if (o.isBR()) {
- const RenderLineBreak& br = toRenderLineBreak(o);
+ const RenderLineBreak& br = downcast<RenderLineBreak>(o);
IntRect linesBox = br.linesBoundingBox();
r = IntRect(linesBox.x(), linesBox.y(), linesBox.width(), linesBox.height());
if (!br.inlineBoxWrapper())
adjustForTableCells = false;
- } else if (o.isRenderInline()) {
- const RenderInline& inlineFlow = toRenderInline(o);
+ } else if (is<RenderInline>(o)) {
+ const RenderInline& inlineFlow = downcast<RenderInline>(o);
// FIXME: Would be better not to just dump 0, 0 as the x and y here.
r = IntRect(0, 0, inlineFlow.linesBoundingBox().width(), inlineFlow.linesBoundingBox().height());
adjustForTableCells = false;
- } else if (o.isTableCell()) {
+ } else if (is<RenderTableCell>(o)) {
// FIXME: Deliberately dump the "inner" box of table cells, since that is what current results reflect. We'd like
// to clean up the results to dump both the outer box and the intrinsic padding so that both bits of information are
// captured by the results.
- const RenderTableCell& cell = *toRenderTableCell(&o);
+ const RenderTableCell& cell = downcast<RenderTableCell>(o);
r = LayoutRect(cell.x(), cell.y() + cell.intrinsicPaddingBefore(), cell.width(), cell.height() - cell.intrinsicPaddingBefore() - cell.intrinsicPaddingAfter());
- } else if (o.isBox())
- r = toRenderBox(o).frameRect();
+ } else if (is<RenderBox>(o))
+ r = downcast<RenderBox>(o).frameRect();
// FIXME: Temporary in order to ensure compatibility with existing layout test results.
if (adjustForTableCells)
- r.move(0, -toRenderTableCell(o.containingBlock())->intrinsicPaddingBefore());
+ r.move(0, -downcast<RenderTableCell>(*o.containingBlock()).intrinsicPaddingBefore());
// FIXME: Convert layout test results to report sub-pixel values, in the meantime using enclosingIntRect
// for consistency with old results.
ts << " " << enclosingIntRect(r);
- if (!o.isText()) {
- if (o.isFileUploadControl())
- ts << " " << quoteAndEscapeNonPrintables(toRenderFileUploadControl(&o)->fileTextValue());
+ if (!is<RenderText>(o)) {
+ if (is<RenderFileUploadControl>(o))
+ ts << " " << quoteAndEscapeNonPrintables(downcast<RenderFileUploadControl>(o).fileTextValue());
if (o.parent()) {
Color color = o.style().visitedDependentColor(CSSPropertyColor);
@@ -272,10 +268,10 @@ void RenderTreeAsText::writeRenderObject(TextStream& ts, const RenderObject& o,
ts << " [textStrokeWidth=" << o.style().textStrokeWidth() << "]";
}
- if (!o.isBoxModelObject() || o.isLineBreak())
+ if (!is<RenderBoxModelObject>(o) || is<RenderLineBreak>(o))
return;
- const RenderBoxModelObject& box = toRenderBoxModelObject(o);
+ const RenderBoxModelObject& box = downcast<RenderBoxModelObject>(o);
if (box.borderTop() || box.borderRight() || box.borderBottom() || box.borderLeft()) {
ts << " [border:";
@@ -354,15 +350,14 @@ void RenderTreeAsText::writeRenderObject(TextStream& ts, const RenderObject& o,
#endif
}
- if (o.isTableCell()) {
- const RenderTableCell& c = *toRenderTableCell(&o);
+ if (is<RenderTableCell>(o)) {
+ const RenderTableCell& c = downcast<RenderTableCell>(o);
ts << " [r=" << c.rowIndex() << " c=" << c.col() << " rs=" << c.rowSpan() << " cs=" << c.colSpan() << "]";
}
-#if ENABLE(DETAILS_ELEMENT)
- if (o.isDetailsMarker()) {
+ if (is<RenderDetailsMarker>(o)) {
ts << ": ";
- switch (toRenderDetailsMarker(o).orientation()) {
+ switch (downcast<RenderDetailsMarker>(o).orientation()) {
case RenderDetailsMarker::Left:
ts << "left";
break;
@@ -377,10 +372,9 @@ void RenderTreeAsText::writeRenderObject(TextStream& ts, const RenderObject& o,
break;
}
}
-#endif
- if (o.isListMarker()) {
- String text = toRenderListMarker(o).text();
+ if (is<RenderListMarker>(o)) {
+ String text = downcast<RenderListMarker>(o).text();
if (!text.isEmpty()) {
if (text.length() != 1)
text = quoteAndEscapeNonPrintables(text);
@@ -403,8 +397,13 @@ void RenderTreeAsText::writeRenderObject(TextStream& ts, const RenderObject& o,
}
}
+ writeDebugInfo(ts, o, behavior);
+}
+
+void writeDebugInfo(TextStream& ts, const RenderObject& object, RenderAsTextBehavior behavior)
+{
if (behavior & RenderAsTextShowIDAndClass) {
- if (Element* element = o.node() && o.node()->isElementNode() ? toElement(o.node()) : 0) {
+ if (Element* element = is<Element>(object.node()) ? downcast<Element>(object.node()) : nullptr) {
if (element->hasID())
ts << " id=\"" + element->getIdAttribute() + "\"";
@@ -419,33 +418,33 @@ void RenderTreeAsText::writeRenderObject(TextStream& ts, const RenderObject& o,
}
}
}
-
+
if (behavior & RenderAsTextShowLayoutState) {
- bool needsLayout = o.selfNeedsLayout() || o.needsPositionedMovementLayout() || o.posChildNeedsLayout() || o.normalChildNeedsLayout();
+ bool needsLayout = object.selfNeedsLayout() || object.needsPositionedMovementLayout() || object.posChildNeedsLayout() || object.normalChildNeedsLayout();
if (needsLayout)
ts << " (needs layout:";
bool havePrevious = false;
- if (o.selfNeedsLayout()) {
+ if (object.selfNeedsLayout()) {
ts << " self";
havePrevious = true;
}
- if (o.needsPositionedMovementLayout()) {
+ if (object.needsPositionedMovementLayout()) {
if (havePrevious)
ts << ",";
havePrevious = true;
ts << " positioned movement";
}
- if (o.normalChildNeedsLayout()) {
+ if (object.normalChildNeedsLayout()) {
if (havePrevious)
ts << ",";
havePrevious = true;
ts << " child";
}
- if (o.posChildNeedsLayout()) {
+ if (object.posChildNeedsLayout()) {
if (havePrevious)
ts << ",";
ts << " positioned child";
@@ -454,9 +453,9 @@ void RenderTreeAsText::writeRenderObject(TextStream& ts, const RenderObject& o,
if (needsLayout)
ts << ")";
}
-
- if (behavior & RenderAsTextShowOverflow && o.isBox()) {
- const RenderBox& box = toRenderBox(o);
+
+ if (behavior & RenderAsTextShowOverflow && is<RenderBox>(object)) {
+ const auto& box = downcast<RenderBox>(object);
if (box.hasRenderOverflow()) {
LayoutRect layoutOverflow = box.layoutOverflowRect();
ts << " (layout overflow " << layoutOverflow.x().toInt() << "," << layoutOverflow.y().toInt() << " " << layoutOverflow.width().toInt() << "x" << layoutOverflow.height().toInt() << ")";
@@ -478,8 +477,8 @@ static void writeTextRun(TextStream& ts, const RenderText& o, const InlineTextBo
int logicalWidth = ceilf(run.left() + run.logicalWidth()) - x;
// FIXME: Table cell adjustment is temporary until results can be updated.
- if (o.containingBlock()->isTableCell())
- y -= toRenderTableCell(o.containingBlock())->intrinsicPaddingBefore();
+ if (is<RenderTableCell>(*o.containingBlock()))
+ y -= floorToInt(downcast<RenderTableCell>(*o.containingBlock()).intrinsicPaddingBefore());
ts << "text run at (" << x << "," << y << ") width " << logicalWidth;
if (!run.isLeftToRightDirection() || run.dirOverride()) {
@@ -490,102 +489,100 @@ static void writeTextRun(TextStream& ts, const RenderText& o, const InlineTextBo
ts << ": "
<< quoteAndEscapeNonPrintables(String(o.text()).substring(run.start(), run.len()));
if (run.hasHyphen())
- ts << " + hyphen string " << quoteAndEscapeNonPrintables(o.style().hyphenString());
+ ts << " + hyphen string " << quoteAndEscapeNonPrintables(o.style().hyphenString().string());
ts << "\n";
}
-static void writeSimpleLine(TextStream& ts, const RenderText& o, const LayoutRect& rect, const String& text)
+static void writeSimpleLine(TextStream& ts, const RenderText& renderText, const SimpleLineLayout::RunResolver::Run& run)
{
+ auto rect = run.rect();
int x = rect.x();
int y = rect.y();
int logicalWidth = ceilf(rect.x() + rect.width()) - x;
- if (o.containingBlock()->isTableCell())
- y -= toRenderTableCell(o.containingBlock())->intrinsicPaddingBefore();
-
+ if (is<RenderTableCell>(*renderText.containingBlock()))
+ y -= floorToInt(downcast<RenderTableCell>(*renderText.containingBlock()).intrinsicPaddingBefore());
+
ts << "text run at (" << x << "," << y << ") width " << logicalWidth;
- ts << ": "
- << quoteAndEscapeNonPrintables(text);
+ ts << ": " << quoteAndEscapeNonPrintables(run.text());
+ if (run.hasHyphen())
+ ts << " + hyphen string " << quoteAndEscapeNonPrintables(renderText.style().hyphenString().string());
ts << "\n";
}
void write(TextStream& ts, const RenderObject& o, int indent, RenderAsTextBehavior behavior)
{
-#if ENABLE(SVG)
- if (o.isSVGShape()) {
- write(ts, *toRenderSVGShape(&o), indent);
+ if (is<RenderSVGShape>(o)) {
+ write(ts, downcast<RenderSVGShape>(o), indent, behavior);
return;
}
- if (o.isSVGGradientStop()) {
- writeSVGGradientStop(ts, *toRenderSVGGradientStop(&o), indent);
+ if (is<RenderSVGGradientStop>(o)) {
+ writeSVGGradientStop(ts, downcast<RenderSVGGradientStop>(o), indent, behavior);
return;
}
- if (o.isSVGResourceContainer()) {
- writeSVGResourceContainer(ts, o, indent);
+ if (is<RenderSVGResourceContainer>(o)) {
+ writeSVGResourceContainer(ts, downcast<RenderSVGResourceContainer>(o), indent, behavior);
return;
}
- if (o.isSVGContainer()) {
- writeSVGContainer(ts, o, indent);
+ if (is<RenderSVGContainer>(o)) {
+ writeSVGContainer(ts, downcast<RenderSVGContainer>(o), indent, behavior);
return;
}
- if (o.isSVGRoot()) {
- write(ts, *toRenderSVGRoot(&o), indent);
+ if (is<RenderSVGRoot>(o)) {
+ write(ts, downcast<RenderSVGRoot>(o), indent, behavior);
return;
}
- if (o.isSVGText()) {
- writeSVGText(ts, *toRenderSVGText(&o), indent);
+ if (is<RenderSVGText>(o)) {
+ writeSVGText(ts, downcast<RenderSVGText>(o), indent, behavior);
return;
}
- if (o.isSVGInlineText()) {
- writeSVGInlineText(ts, toRenderSVGInlineText(o), indent);
+ if (is<RenderSVGInlineText>(o)) {
+ writeSVGInlineText(ts, downcast<RenderSVGInlineText>(o), indent, behavior);
return;
}
- if (o.isSVGImage()) {
- writeSVGImage(ts, *toRenderSVGImage(&o), indent);
+ if (is<RenderSVGImage>(o)) {
+ writeSVGImage(ts, downcast<RenderSVGImage>(o), indent, behavior);
return;
}
-#endif
writeIndent(ts, indent);
RenderTreeAsText::writeRenderObject(ts, o, behavior);
ts << "\n";
- if (o.isText()) {
- auto& text = toRenderText(o);
+ if (is<RenderText>(o)) {
+ auto& text = downcast<RenderText>(o);
if (auto layout = text.simpleLineLayout()) {
ASSERT(!text.firstTextBox());
- auto resolver = runResolver(toRenderBlockFlow(*text.parent()), *layout);
- for (auto it = resolver.begin(), end = resolver.end(); it != end; ++it) {
- auto run = *it;
+ auto resolver = runResolver(downcast<RenderBlockFlow>(*text.parent()), *layout);
+ for (const auto& run : resolver.rangeForRenderer(text)) {
writeIndent(ts, indent + 1);
- writeSimpleLine(ts, text, run.rect(), run.text());
+ writeSimpleLine(ts, text, run);
}
} else {
- for (auto box = text.firstTextBox(); box; box = box->nextTextBox()) {
+ for (auto* box = text.firstTextBox(); box; box = box->nextTextBox()) {
writeIndent(ts, indent + 1);
writeTextRun(ts, text, *box);
}
}
} else {
- for (RenderObject* child = toRenderElement(o).firstChild(); child; child = child->nextSibling()) {
- if (child->hasLayer())
+ for (auto& child : childrenOfType<RenderObject>(downcast<RenderElement>(o))) {
+ if (child.hasLayer())
continue;
- write(ts, *child, indent + 1, behavior);
+ write(ts, child, indent + 1, behavior);
}
}
- if (o.isWidget()) {
- Widget* widget = toRenderWidget(&o)->widget();
- if (widget && widget->isFrameView()) {
- FrameView* view = toFrameView(widget);
- if (RenderView* root = view->frame().contentRenderer()) {
+ if (is<RenderWidget>(o)) {
+ Widget* widget = downcast<RenderWidget>(o).widget();
+ if (is<FrameView>(widget)) {
+ FrameView& view = downcast<FrameView>(*widget);
+ if (RenderView* root = view.frame().contentRenderer()) {
if (!(behavior & RenderAsTextDontUpdateLayout))
- view->layout();
- RenderLayer* l = root->layer();
- if (l)
- writeLayers(ts, l, l, l->rect(), indent + 1, behavior);
+ view.layout();
+ if (RenderLayer* layer = root->layer())
+ writeLayers(ts, layer, layer, layer->rect(), indent + 1, behavior);
}
}
}
@@ -597,21 +594,19 @@ enum LayerPaintPhase {
LayerPaintPhaseForeground = 1
};
-static void write(TextStream& ts, RenderLayer& l,
- const LayoutRect& layerBounds, const LayoutRect& backgroundClipRect, const LayoutRect& clipRect, const LayoutRect& outlineClipRect,
- LayerPaintPhase paintPhase = LayerPaintPhaseAll, int indent = 0, RenderAsTextBehavior behavior = RenderAsTextBehaviorNormal)
+static void write(TextStream& ts, const RenderLayer& layer, const LayoutRect& layerBounds, const LayoutRect& backgroundClipRect, const LayoutRect& clipRect,
+ LayerPaintPhase paintPhase = LayerPaintPhaseAll, int indent = 0, RenderAsTextBehavior behavior = RenderAsTextBehaviorNormal)
{
- IntRect adjustedLayoutBounds = pixelSnappedIntRect(layerBounds);
- IntRect adjustedBackgroundClipRect = pixelSnappedIntRect(backgroundClipRect);
- IntRect adjustedClipRect = pixelSnappedIntRect(clipRect);
- IntRect adjustedOutlineClipRect = pixelSnappedIntRect(outlineClipRect);
+ IntRect adjustedLayoutBounds = snappedIntRect(layerBounds);
+ IntRect adjustedBackgroundClipRect = snappedIntRect(backgroundClipRect);
+ IntRect adjustedClipRect = snappedIntRect(clipRect);
writeIndent(ts, indent);
ts << "layer ";
if (behavior & RenderAsTextShowAddresses)
- ts << static_cast<const void*>(&l) << " ";
+ ts << static_cast<const void*>(&layer) << " ";
ts << adjustedLayoutBounds;
@@ -620,39 +615,50 @@ static void write(TextStream& ts, RenderLayer& l,
ts << " backgroundClip " << adjustedBackgroundClipRect;
if (!adjustedClipRect.contains(adjustedLayoutBounds))
ts << " clip " << adjustedClipRect;
- if (!adjustedOutlineClipRect.contains(adjustedLayoutBounds))
- ts << " outlineClip " << adjustedOutlineClipRect;
}
- if (l.renderer().hasOverflowClip()) {
- if (l.scrollXOffset())
- ts << " scrollX " << l.scrollXOffset();
- if (l.scrollYOffset())
- ts << " scrollY " << l.scrollYOffset();
- if (l.renderBox() && l.renderBox()->pixelSnappedClientWidth() != l.scrollWidth())
- ts << " scrollWidth " << l.scrollWidth();
- if (l.renderBox() && l.renderBox()->pixelSnappedClientHeight() != l.scrollHeight())
- ts << " scrollHeight " << l.scrollHeight();
+ if (layer.renderer().hasOverflowClip()) {
+ if (layer.scrollOffset().x())
+ ts << " scrollX " << layer.scrollOffset().x();
+ if (layer.scrollOffset().y())
+ ts << " scrollY " << layer.scrollOffset().y();
+ if (layer.renderBox() && roundToInt(layer.renderBox()->clientWidth()) != layer.scrollWidth())
+ ts << " scrollWidth " << layer.scrollWidth();
+ if (layer.renderBox() && roundToInt(layer.renderBox()->clientHeight()) != layer.scrollHeight())
+ ts << " scrollHeight " << layer.scrollHeight();
+#if PLATFORM(MAC)
+ ScrollbarTheme& scrollbarTheme = ScrollbarTheme::theme();
+ if (!scrollbarTheme.isMockTheme() && layer.hasVerticalScrollbar()) {
+ ScrollbarThemeMac& macTheme = *static_cast<ScrollbarThemeMac*>(&scrollbarTheme);
+ if (macTheme.isLayoutDirectionRTL(*layer.verticalScrollbar()))
+ ts << " scrollbarHasRTLLayoutDirection";
+ }
+#endif
}
if (paintPhase == LayerPaintPhaseBackground)
ts << " layerType: background only";
else if (paintPhase == LayerPaintPhaseForeground)
ts << " layerType: foreground only";
-
-#if USE(ACCELERATED_COMPOSITING)
+
if (behavior & RenderAsTextShowCompositedLayers) {
- if (l.isComposited())
- ts << " (composited, bounds=" << l.backing()->compositedBounds() << ", drawsContent=" << l.backing()->graphicsLayer()->drawsContent() << ", paints into ancestor=" << l.backing()->paintsIntoCompositedAncestor() << ")";
+ if (layer.isComposited()) {
+ ts << " (composited, bounds=" << layer.backing()->compositedBounds() << ", drawsContent=" << layer.backing()->graphicsLayer()->drawsContent()
+ << ", paints into ancestor=" << layer.backing()->paintsIntoCompositedAncestor() << ")";
+ }
}
-#else
- UNUSED_PARAM(behavior);
+
+#if ENABLE(CSS_COMPOSITING)
+ if (layer.isolatesBlending())
+ ts << " isolatesBlending";
+ if (layer.hasBlendMode())
+ ts << " blendMode: " << compositeOperatorName(CompositeSourceOver, layer.blendMode());
#endif
ts << "\n";
if (paintPhase != LayerPaintPhaseBackground)
- write(ts, l.renderer(), indent + 1, behavior);
+ write(ts, layer.renderer(), indent + 1, behavior);
}
static void writeRenderRegionList(const RenderRegionList& flowThreadRegionList, TextStream& ts, int indent)
@@ -663,8 +669,8 @@ static void writeRenderRegionList(const RenderRegionList& flowThreadRegionList,
Element* generatingElement = renderRegion->generatingElement();
if (generatingElement) {
- bool isRenderNamedFlowFragment = renderRegion->isRenderNamedFlowFragment();
- if (isRenderNamedFlowFragment && toRenderNamedFlowFragment(renderRegion)->hasCustomRegionStyle())
+ bool isRenderNamedFlowFragment = is<RenderNamedFlowFragment>(*renderRegion);
+ if (isRenderNamedFlowFragment && downcast<RenderNamedFlowFragment>(*renderRegion).hasCustomRegionStyle())
ts << " region style: 1";
if (renderRegion->hasAutoLogicalHeight())
ts << " hasAutoLogicalHeight";
@@ -678,15 +684,16 @@ static void writeRenderRegionList(const RenderRegionList& flowThreadRegionList,
RenderElement* renderElementForRegion = isRenderNamedFlowFragment ? renderRegion->parent() : renderRegion;
if (renderElementForRegion->isPseudoElement()) {
if (renderElementForRegion->element()->isBeforePseudoElement())
- tagName.append("::before");
+ tagName.appendLiteral("::before");
else if (renderElementForRegion->element()->isAfterPseudoElement())
- tagName.append("::after");
+ tagName.appendLiteral("::after");
}
ts << " {" << tagName.toString() << "}";
- if (generatingElement->hasID())
- ts << " #" << generatingElement->idForStyleResolution();
+ auto& generatingElementId = generatingElement->idForStyleResolution();
+ if (!generatingElementId.isNull())
+ ts << " #" << generatingElementId;
if (isRenderNamedFlowFragment)
ts << ")";
@@ -746,22 +753,23 @@ static void writeLayers(TextStream& ts, const RenderLayer* rootLayer, RenderLaye
if (rootLayer == l) {
paintDirtyRect.setWidth(std::max<LayoutUnit>(paintDirtyRect.width(), rootLayer->renderBox()->layoutOverflowRect().maxX()));
paintDirtyRect.setHeight(std::max<LayoutUnit>(paintDirtyRect.height(), rootLayer->renderBox()->layoutOverflowRect().maxY()));
- l->setSize(l->size().expandedTo(pixelSnappedIntSize(maxLayoutOverflow(l->renderBox()), LayoutPoint(0, 0))));
+ l->setSize(l->size().expandedTo(snappedIntSize(maxLayoutOverflow(l->renderBox()), LayoutPoint(0, 0))));
}
// Calculate the clip rects we should use.
LayoutRect layerBounds;
- ClipRect damageRect, clipRectToApply, outlineRect;
- l->calculateRects(RenderLayer::ClipRectsContext(rootLayer, 0, TemporaryClipRects), paintDirtyRect, layerBounds, damageRect, clipRectToApply, outlineRect);
+ ClipRect damageRect;
+ ClipRect clipRectToApply;
+ l->calculateRects(RenderLayer::ClipRectsContext(rootLayer, TemporaryClipRects), paintDirtyRect, layerBounds, damageRect, clipRectToApply, l->offsetFromAncestor(rootLayer));
// Ensure our lists are up-to-date.
l->updateLayerListsIfNeeded();
- bool shouldPaint = (behavior & RenderAsTextShowAllLayers) ? true : l->intersectsDamageRect(layerBounds, damageRect.rect(), rootLayer);
+ bool shouldPaint = (behavior & RenderAsTextShowAllLayers) ? true : l->intersectsDamageRect(layerBounds, damageRect.rect(), rootLayer, l->offsetFromAncestor(rootLayer));
Vector<RenderLayer*>* negList = l->negZOrderList();
bool paintsBackgroundSeparately = negList && negList->size() > 0;
if (shouldPaint && paintsBackgroundSeparately)
- write(ts, *l, layerBounds, damageRect.rect(), clipRectToApply.rect(), outlineRect.rect(), LayerPaintPhaseBackground, indent, behavior);
+ write(ts, *l, layerBounds, damageRect.rect(), clipRectToApply.rect(), LayerPaintPhaseBackground, indent, behavior);
if (negList) {
int currIndent = indent;
@@ -775,7 +783,7 @@ static void writeLayers(TextStream& ts, const RenderLayer* rootLayer, RenderLaye
}
if (shouldPaint)
- write(ts, *l, layerBounds, damageRect.rect(), clipRectToApply.rect(), outlineRect.rect(), paintsBackgroundSeparately ? LayerPaintPhaseForeground : LayerPaintPhaseAll, indent, behavior);
+ write(ts, *l, layerBounds, damageRect.rect(), clipRectToApply.rect(), paintsBackgroundSeparately ? LayerPaintPhaseForeground : LayerPaintPhaseAll, indent, behavior);
if (Vector<RenderLayer*>* normalFlowList = l->normalFlowList()) {
int currIndent = indent;
@@ -813,15 +821,15 @@ static void writeLayers(TextStream& ts, const RenderLayer* rootLayer, RenderLaye
// Altough the RenderFlowThread requires a layer, it is not collected by its parent,
// so we have to treat it as a special case.
- if (l->renderer().isRenderView())
- writeRenderNamedFlowThreads(ts, toRenderView(l->renderer()), rootLayer, paintDirtyRect, indent, behavior);
+ if (is<RenderView>(l->renderer()))
+ writeRenderNamedFlowThreads(ts, downcast<RenderView>(l->renderer()), rootLayer, paintDirtyRect, indent, behavior);
}
static String nodePosition(Node* node)
{
StringBuilder result;
- Element* body = node->document().body();
+ auto* body = node->document().bodyOrFrameset();
Node* parent;
for (Node* n = node; n; n = parent) {
parent = n->parentOrShadowHostNode();
@@ -839,7 +847,7 @@ static String nodePosition(Node* node)
result.append('}');
} else {
result.appendLiteral("child ");
- result.appendNumber(n->nodeIndex());
+ result.appendNumber(n->computeNodeIndex());
result.appendLiteral(" {");
result.append(getTagName(n));
result.append('}');
@@ -873,10 +881,12 @@ static void writeSelection(TextStream& ts, const RenderObject* renderer)
static String externalRepresentation(RenderBox* renderer, RenderAsTextBehavior behavior)
{
- TextStream ts;
+ TextStream ts(TextStream::LineMode::MultipleLine, TextStream::Formatting::SVGStyleRect | TextStream::Formatting::LayoutUnitsAsIntegers);
if (!renderer->hasLayer())
return ts.release();
-
+
+ LOG(Layout, "externalRepresentation: dumping layer tree");
+
RenderLayer* layer = renderer->layer();
writeLayers(ts, layer, layer, layer->rect(), 0, behavior);
writeSelection(ts, renderer);
@@ -885,30 +895,30 @@ static String externalRepresentation(RenderBox* renderer, RenderAsTextBehavior b
String externalRepresentation(Frame* frame, RenderAsTextBehavior behavior)
{
- RenderObject* renderer = frame->contentRenderer();
- if (!renderer || !renderer->isBox())
+ RenderView* renderer = frame->contentRenderer();
+ if (!renderer)
return String();
PrintContext printContext(frame);
if (behavior & RenderAsTextPrintingMode)
- printContext.begin(toRenderBox(renderer)->width());
+ printContext.begin(renderer->width());
if (!(behavior & RenderAsTextDontUpdateLayout))
frame->document()->updateLayout();
- return externalRepresentation(toRenderBox(renderer), behavior);
+ return externalRepresentation(renderer, behavior);
}
String externalRepresentation(Element* element, RenderAsTextBehavior behavior)
{
- RenderObject* renderer = element->renderer();
- if (!renderer || !renderer->isBox())
+ RenderElement* renderer = element->renderer();
+ if (!is<RenderBox>(renderer))
return String();
// Doesn't support printing mode.
ASSERT(!(behavior & RenderAsTextPrintingMode));
if (!(behavior & RenderAsTextDontUpdateLayout))
element->document().updateLayout();
- return externalRepresentation(toRenderBox(renderer), behavior | RenderAsTextShowAllLayers);
+ return externalRepresentation(downcast<RenderBox>(renderer), behavior | RenderAsTextShowAllLayers);
}
static void writeCounterValuesFromChildren(TextStream& stream, const RenderElement* parent, bool& isFirstCounter)
@@ -929,7 +939,7 @@ String counterValueForElement(Element* element)
// Make sure the element is not freed during the layout.
RefPtr<Element> elementRef(element);
element->document().updateLayout();
- TextStream stream;
+ TextStream stream(TextStream::LineMode::MultipleLine, TextStream::Formatting::SVGStyleRect | TextStream::Formatting::LayoutUnitsAsIntegers);
bool isFirstCounter = true;
// The counter renderers should be children of :before or :after pseudo-elements.
if (PseudoElement* before = element->beforePseudoElement())
@@ -945,11 +955,11 @@ String markerTextForListItem(Element* element)
RefPtr<Element> elementRef(element);
element->document().updateLayout();
- RenderObject* renderer = element->renderer();
- if (!renderer || !renderer->isListItem())
+ RenderElement* renderer = element->renderer();
+ if (!is<RenderListItem>(renderer))
return String();
- return toRenderListItem(renderer)->markerText();
+ return downcast<RenderListItem>(*renderer).markerText();
}
} // namespace WebCore