summaryrefslogtreecommitdiffstats
path: root/third_party/WebKit/Source/core/layout/TracedLayoutObject.cpp
blob: 5a1b2b9540551fa1e49509b6aa92c9ccfba66141 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "core/layout/TracedLayoutObject.h"

#include "core/layout/LayoutInline.h"
#include "core/layout/LayoutTableCell.h"
#include "core/layout/LayoutText.h"
#include "core/layout/LayoutView.h"
#include <inttypes.h>

namespace blink {

namespace {

void dumpToTracedValue(const LayoutObject& object, bool traceGeometry, TracedValue* tracedValue)
{
    tracedValue->setString("address", String::format("%" PRIxPTR, reinterpret_cast<uintptr_t>(&object)));
    tracedValue->setString("name", object.name());
    if (Node* node = object.node()) {
        tracedValue->setString("tag", node->nodeName());
        if (node->isElementNode()) {
            Element& element = toElement(*node);
            if (element.hasID())
                tracedValue->setString("htmlId", element.getIdAttribute());
            if (element.hasClass()) {
                tracedValue->beginArray("classNames");
                for (size_t i = 0; i < element.classNames().size(); ++i)
                    tracedValue->pushString(element.classNames()[i]);
                tracedValue->endArray();
            }
        }
    }

    // FIXME: When the fixmes in LayoutTreeAsText::writeLayoutObject() are
    // fixed, deduplicate it with this.
    if (traceGeometry) {
        tracedValue->setDouble("absX", object.absoluteBoundingBoxRect().x());
        tracedValue->setDouble("absY", object.absoluteBoundingBoxRect().y());
        LayoutRect rect;
        if (object.isText())
            rect = LayoutRect(toLayoutText(object).linesBoundingBox());
        else if (object.isLayoutInline())
            rect = LayoutRect(toLayoutInline(object).linesBoundingBox());
        else if (object.isBox())
            rect = toLayoutBox(&object)->frameRect();
        tracedValue->setDouble("relX", rect.x());
        tracedValue->setDouble("relY", rect.y());
        tracedValue->setDouble("width", rect.width());
        tracedValue->setDouble("height", rect.height());
    } else {
        tracedValue->setDouble("absX", 0);
        tracedValue->setDouble("absY", 0);
        tracedValue->setDouble("relX", 0);
        tracedValue->setDouble("relY", 0);
        tracedValue->setDouble("width", 0);
        tracedValue->setDouble("height", 0);
    }

    if (object.isOutOfFlowPositioned())
        tracedValue->setBoolean("positioned", object.isOutOfFlowPositioned());
    if (object.selfNeedsLayout())
        tracedValue->setBoolean("selfNeeds", object.selfNeedsLayout());
    if (object.needsPositionedMovementLayout())
        tracedValue->setBoolean("positionedMovement", object.needsPositionedMovementLayout());
    if (object.normalChildNeedsLayout())
        tracedValue->setBoolean("childNeeds", object.normalChildNeedsLayout());
    if (object.posChildNeedsLayout())
        tracedValue->setBoolean("posChildNeeds", object.posChildNeedsLayout());
    if (object.isTableCell()) {
        const LayoutTableCell& c = toLayoutTableCell(object);
        tracedValue->setDouble("row", c.rowIndex());
        tracedValue->setDouble("col", c.absoluteColumnIndex());
        if (c.rowSpan() != 1)
            tracedValue->setDouble("rowSpan", c.rowSpan());
        if (c.colSpan() != 1)
            tracedValue->setDouble("colSpan", c.colSpan());
    }
    if (object.isAnonymous())
        tracedValue->setBoolean("anonymous", object.isAnonymous());
    if (object.isRelPositioned())
        tracedValue->setBoolean("relativePositioned", object.isRelPositioned());
    if (object.isStickyPositioned())
        tracedValue->setBoolean("stickyPositioned", object.isStickyPositioned());
    if (object.isFloating())
        tracedValue->setBoolean("float", object.isFloating());

    if (object.slowFirstChild()) {
        tracedValue->beginArray("children");
        for (LayoutObject* child = object.slowFirstChild(); child; child = child->nextSibling()) {
            tracedValue->beginDictionary();
            dumpToTracedValue(*child, traceGeometry, tracedValue);
            tracedValue->endDictionary();
        }
        tracedValue->endArray();
    }
}

} // namespace

PassOwnPtr<TracedValue> TracedLayoutObject::create(const LayoutView& view, bool traceGeometry)
{
    OwnPtr<TracedValue> tracedValue = TracedValue::create();
    dumpToTracedValue(view, traceGeometry, tracedValue.get());
    return tracedValue.release();
}

} // namespace blink