summaryrefslogtreecommitdiff
path: root/Source/WebCore/inspector/InspectorOverlay.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/inspector/InspectorOverlay.cpp')
-rw-r--r--Source/WebCore/inspector/InspectorOverlay.cpp733
1 files changed, 434 insertions, 299 deletions
diff --git a/Source/WebCore/inspector/InspectorOverlay.cpp b/Source/WebCore/inspector/InspectorOverlay.cpp
index f334f456d..a873c174d 100644
--- a/Source/WebCore/inspector/InspectorOverlay.cpp
+++ b/Source/WebCore/inspector/InspectorOverlay.cpp
@@ -10,7 +10,7 @@
* 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.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * 3. Neither the name of Apple Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
@@ -27,22 +27,23 @@
*/
#include "config.h"
-
-#if ENABLE(INSPECTOR)
-
#include "InspectorOverlay.h"
#include "DocumentLoader.h"
+#include "EditorClient.h"
#include "Element.h"
#include "EmptyClients.h"
#include "FrameView.h"
#include "GraphicsContext.h"
#include "InspectorClient.h"
#include "InspectorOverlayPage.h"
+#include "LibWebRTCProvider.h"
#include "MainFrame.h"
#include "Node.h"
#include "Page.h"
+#include "PageConfiguration.h"
#include "PolygonShape.h"
+#include "PseudoElement.h"
#include "RectangleShape.h"
#include "RenderBoxModelObject.h"
#include "RenderElement.h"
@@ -55,120 +56,86 @@
#include "ScriptController.h"
#include "ScriptSourceCode.h"
#include "Settings.h"
+#include "SocketProvider.h"
#include "StyledElement.h"
-#include <bindings/ScriptValue.h>
+#include <inspector/InspectorProtocolObjects.h>
#include <inspector/InspectorValues.h>
-#include <wtf/text/StringBuilder.h>
using namespace Inspector;
namespace WebCore {
-namespace {
-
-Path quadToPath(const FloatQuad& quad)
-{
- Path quadPath;
- quadPath.moveTo(quad.p1());
- quadPath.addLineTo(quad.p2());
- quadPath.addLineTo(quad.p3());
- quadPath.addLineTo(quad.p4());
- quadPath.closeSubpath();
- return quadPath;
-}
-
-void drawOutlinedQuad(GraphicsContext* context, const FloatQuad& quad, const Color& fillColor, const Color& outlineColor)
+static void contentsQuadToCoordinateSystem(const FrameView* mainView, const FrameView* view, FloatQuad& quad, InspectorOverlay::CoordinateSystem coordinateSystem)
{
- static const int outlineThickness = 2;
-
- Path quadPath = quadToPath(quad);
-
- // Clip out the quad, then draw with a 2px stroke to get a pixel
- // of outline (because inflating a quad is hard)
- {
- context->save();
- context->clipOut(quadPath);
-
- context->setStrokeThickness(outlineThickness);
- context->setStrokeColor(outlineColor, ColorSpaceDeviceRGB);
- context->strokePath(quadPath);
-
- context->restore();
- }
+ quad.setP1(view->contentsToRootView(roundedIntPoint(quad.p1())));
+ quad.setP2(view->contentsToRootView(roundedIntPoint(quad.p2())));
+ quad.setP3(view->contentsToRootView(roundedIntPoint(quad.p3())));
+ quad.setP4(view->contentsToRootView(roundedIntPoint(quad.p4())));
- // Now do the fill
- context->setFillColor(fillColor, ColorSpaceDeviceRGB);
- context->fillPath(quadPath);
+ if (coordinateSystem == InspectorOverlay::CoordinateSystem::View)
+ quad += toIntSize(mainView->scrollPosition());
}
static void contentsQuadToPage(const FrameView* mainView, const FrameView* view, FloatQuad& quad)
{
- quad.setP1(view->contentsToRootView(roundedIntPoint(quad.p1())));
- quad.setP2(view->contentsToRootView(roundedIntPoint(quad.p2())));
- quad.setP3(view->contentsToRootView(roundedIntPoint(quad.p3())));
- quad.setP4(view->contentsToRootView(roundedIntPoint(quad.p4())));
- quad += mainView->scrollOffset();
+ contentsQuadToCoordinateSystem(mainView, view, quad, InspectorOverlay::CoordinateSystem::View);
}
-static void buildRendererHighlight(RenderObject* renderer, RenderRegion* region, const HighlightConfig& highlightConfig, Highlight* highlight)
+static void buildRendererHighlight(RenderObject* renderer, RenderRegion* region, const HighlightConfig& highlightConfig, Highlight& highlight, InspectorOverlay::CoordinateSystem coordinateSystem)
{
Frame* containingFrame = renderer->document().frame();
if (!containingFrame)
return;
- highlight->setDataFromConfig(highlightConfig);
+ highlight.setDataFromConfig(highlightConfig);
FrameView* containingView = containingFrame->view();
FrameView* mainView = containingFrame->page()->mainFrame().view();
// RenderSVGRoot should be highlighted through the isBox() code path, all other SVG elements should just dump their absoluteQuads().
-#if ENABLE(SVG)
bool isSVGRenderer = renderer->node() && renderer->node()->isSVGElement() && !renderer->isSVGRoot();
-#else
- bool isSVGRenderer = false;
-#endif
if (isSVGRenderer) {
- highlight->type = HighlightTypeRects;
- renderer->absoluteQuads(highlight->quads);
- for (size_t i = 0; i < highlight->quads.size(); ++i)
- contentsQuadToPage(mainView, containingView, highlight->quads[i]);
- } else if (renderer->isBox() || renderer->isRenderInline()) {
+ highlight.type = HighlightType::Rects;
+ renderer->absoluteQuads(highlight.quads);
+ for (auto& quad : highlight.quads)
+ contentsQuadToCoordinateSystem(mainView, containingView, quad, coordinateSystem);
+ } else if (is<RenderBox>(*renderer) || is<RenderInline>(*renderer)) {
LayoutRect contentBox;
LayoutRect paddingBox;
LayoutRect borderBox;
LayoutRect marginBox;
- if (renderer->isBox()) {
- RenderBox* renderBox = toRenderBox(renderer);
+ if (is<RenderBox>(*renderer)) {
+ auto& renderBox = downcast<RenderBox>(*renderer);
- LayoutBoxExtent margins(renderBox->marginTop(), renderBox->marginRight(), renderBox->marginBottom(), renderBox->marginLeft());
+ LayoutBoxExtent margins(renderBox.marginTop(), renderBox.marginRight(), renderBox.marginBottom(), renderBox.marginLeft());
- if (!renderBox->isOutOfFlowPositioned() && region) {
+ if (!renderBox.isOutOfFlowPositioned() && region) {
RenderBox::LogicalExtentComputedValues computedValues;
- renderBox->computeLogicalWidthInRegion(computedValues, region);
- margins.mutableLogicalLeft(renderBox->style().writingMode()) = computedValues.m_margins.m_start;
- margins.mutableLogicalRight(renderBox->style().writingMode()) = computedValues.m_margins.m_end;
+ renderBox.computeLogicalWidthInRegion(computedValues, region);
+ margins.start(renderBox.style().writingMode()) = computedValues.m_margins.m_start;
+ margins.end(renderBox.style().writingMode()) = computedValues.m_margins.m_end;
}
- paddingBox = renderBox->clientBoxRectInRegion(region);
- contentBox = LayoutRect(paddingBox.x() + renderBox->paddingLeft(), paddingBox.y() + renderBox->paddingTop(),
- paddingBox.width() - renderBox->paddingLeft() - renderBox->paddingRight(), paddingBox.height() - renderBox->paddingTop() - renderBox->paddingBottom());
- borderBox = LayoutRect(paddingBox.x() - renderBox->borderLeft(), paddingBox.y() - renderBox->borderTop(),
- paddingBox.width() + renderBox->borderLeft() + renderBox->borderRight(), paddingBox.height() + renderBox->borderTop() + renderBox->borderBottom());
+ paddingBox = renderBox.clientBoxRectInRegion(region);
+ contentBox = LayoutRect(paddingBox.x() + renderBox.paddingLeft(), paddingBox.y() + renderBox.paddingTop(),
+ paddingBox.width() - renderBox.paddingLeft() - renderBox.paddingRight(), paddingBox.height() - renderBox.paddingTop() - renderBox.paddingBottom());
+ borderBox = LayoutRect(paddingBox.x() - renderBox.borderLeft(), paddingBox.y() - renderBox.borderTop(),
+ paddingBox.width() + renderBox.borderLeft() + renderBox.borderRight(), paddingBox.height() + renderBox.borderTop() + renderBox.borderBottom());
marginBox = LayoutRect(borderBox.x() - margins.left(), borderBox.y() - margins.top(),
borderBox.width() + margins.left() + margins.right(), borderBox.height() + margins.top() + margins.bottom());
} else {
- RenderInline* renderInline = toRenderInline(renderer);
+ auto& renderInline = downcast<RenderInline>(*renderer);
// RenderInline's bounding box includes paddings and borders, excludes margins.
- borderBox = renderInline->linesBoundingBox();
- paddingBox = LayoutRect(borderBox.x() + renderInline->borderLeft(), borderBox.y() + renderInline->borderTop(),
- borderBox.width() - renderInline->borderLeft() - renderInline->borderRight(), borderBox.height() - renderInline->borderTop() - renderInline->borderBottom());
- contentBox = LayoutRect(paddingBox.x() + renderInline->paddingLeft(), paddingBox.y() + renderInline->paddingTop(),
- paddingBox.width() - renderInline->paddingLeft() - renderInline->paddingRight(), paddingBox.height() - renderInline->paddingTop() - renderInline->paddingBottom());
+ borderBox = renderInline.linesBoundingBox();
+ paddingBox = LayoutRect(borderBox.x() + renderInline.borderLeft(), borderBox.y() + renderInline.borderTop(),
+ borderBox.width() - renderInline.borderLeft() - renderInline.borderRight(), borderBox.height() - renderInline.borderTop() - renderInline.borderBottom());
+ contentBox = LayoutRect(paddingBox.x() + renderInline.paddingLeft(), paddingBox.y() + renderInline.paddingTop(),
+ paddingBox.width() - renderInline.paddingLeft() - renderInline.paddingRight(), paddingBox.height() - renderInline.paddingTop() - renderInline.paddingBottom());
// Ignore marginTop and marginBottom for inlines.
- marginBox = LayoutRect(borderBox.x() - renderInline->marginLeft(), borderBox.y(),
- borderBox.width() + renderInline->marginWidth(), borderBox.height());
+ marginBox = LayoutRect(borderBox.x() - renderInline.marginLeft(), borderBox.y(),
+ borderBox.width() + renderInline.horizontalMarginExtent(), borderBox.height());
}
FloatQuad absContentQuad;
@@ -207,39 +174,39 @@ static void buildRendererHighlight(RenderObject* renderer, RenderRegion* region,
absMarginQuad = renderer->localToAbsoluteQuad(FloatRect(marginBox));
}
- contentsQuadToPage(mainView, containingView, absContentQuad);
- contentsQuadToPage(mainView, containingView, absPaddingQuad);
- contentsQuadToPage(mainView, containingView, absBorderQuad);
- contentsQuadToPage(mainView, containingView, absMarginQuad);
+ contentsQuadToCoordinateSystem(mainView, containingView, absContentQuad, coordinateSystem);
+ contentsQuadToCoordinateSystem(mainView, containingView, absPaddingQuad, coordinateSystem);
+ contentsQuadToCoordinateSystem(mainView, containingView, absBorderQuad, coordinateSystem);
+ contentsQuadToCoordinateSystem(mainView, containingView, absMarginQuad, coordinateSystem);
- highlight->type = HighlightTypeNode;
- highlight->quads.append(absMarginQuad);
- highlight->quads.append(absBorderQuad);
- highlight->quads.append(absPaddingQuad);
- highlight->quads.append(absContentQuad);
+ highlight.type = HighlightType::Node;
+ highlight.quads.append(absMarginQuad);
+ highlight.quads.append(absBorderQuad);
+ highlight.quads.append(absPaddingQuad);
+ highlight.quads.append(absContentQuad);
}
}
-static void buildNodeHighlight(Node* node, RenderRegion* region, const HighlightConfig& highlightConfig, Highlight* highlight)
+static void buildNodeHighlight(Node& node, RenderRegion* region, const HighlightConfig& highlightConfig, Highlight& highlight, InspectorOverlay::CoordinateSystem coordinateSystem)
{
- RenderObject* renderer = node->renderer();
+ RenderObject* renderer = node.renderer();
if (!renderer)
return;
- buildRendererHighlight(renderer, region, highlightConfig, highlight);
+
+ buildRendererHighlight(renderer, region, highlightConfig, highlight, coordinateSystem);
}
-static void buildQuadHighlight(const FloatQuad& quad, const HighlightConfig& highlightConfig, Highlight *highlight)
+static void buildQuadHighlight(const FloatQuad& quad, const HighlightConfig& highlightConfig, Highlight& highlight)
{
- highlight->setDataFromConfig(highlightConfig);
- highlight->type = HighlightTypeRects;
- highlight->quads.append(quad);
+ highlight.setDataFromConfig(highlightConfig);
+ highlight.type = HighlightType::Rects;
+ highlight.quads.append(quad);
}
-} // anonymous namespace
-
InspectorOverlay::InspectorOverlay(Page& page, InspectorClient* client)
: m_page(page)
, m_client(client)
+ , m_paintRectUpdateTimer(*this, &InspectorOverlay::updatePaintRectsTimerFired)
{
}
@@ -249,29 +216,33 @@ InspectorOverlay::~InspectorOverlay()
void InspectorOverlay::paint(GraphicsContext& context)
{
- if (m_pausedInDebuggerMessage.isNull() && !m_highlightNode && !m_highlightQuad && m_size.isEmpty())
+ if (!shouldShowOverlay())
return;
+
GraphicsContextStateSaver stateSaver(context);
FrameView* view = overlayPage()->mainFrame().view();
view->updateLayoutAndStyleIfNeededRecursive();
- view->paint(&context, IntRect(0, 0, view->width(), view->height()));
+ view->paint(context, IntRect(0, 0, view->width(), view->height()));
}
-void InspectorOverlay::drawOutline(GraphicsContext* context, const LayoutRect& rect, const Color& color)
+void InspectorOverlay::getHighlight(Highlight& highlight, InspectorOverlay::CoordinateSystem coordinateSystem) const
{
- FloatRect outlineRect = rect;
- drawOutlinedQuad(context, outlineRect, Color(), color);
-}
-
-void InspectorOverlay::getHighlight(Highlight* highlight) const
-{
- if (!m_highlightNode && !m_highlightQuad)
+ if (!m_highlightNode && !m_highlightQuad && !m_highlightNodeList)
return;
- highlight->type = HighlightTypeRects;
+ highlight.type = HighlightType::Rects;
if (m_highlightNode)
- buildNodeHighlight(m_highlightNode.get(), nullptr, m_nodeHighlightConfig, highlight);
- else
+ buildNodeHighlight(*m_highlightNode, nullptr, m_nodeHighlightConfig, highlight, coordinateSystem);
+ else if (m_highlightNodeList) {
+ highlight.setDataFromConfig(m_nodeHighlightConfig);
+ for (unsigned i = 0; i < m_highlightNodeList->length(); ++i) {
+ Highlight nodeHighlight;
+ buildNodeHighlight(*(m_highlightNodeList->item(i)), nullptr, m_nodeHighlightConfig, nodeHighlight, coordinateSystem);
+ if (nodeHighlight.type == HighlightType::Node)
+ highlight.quads.appendVector(nodeHighlight.quads);
+ }
+ highlight.type = HighlightType::NodeList;
+ } else
buildQuadHighlight(*m_highlightQuad, m_quadHighlightConfig, highlight);
}
@@ -283,8 +254,17 @@ void InspectorOverlay::setPausedInDebuggerMessage(const String* message)
void InspectorOverlay::hideHighlight()
{
- m_highlightNode.clear();
- m_highlightQuad.clear();
+ m_highlightNode = nullptr;
+ m_highlightNodeList = nullptr;
+ m_highlightQuad = nullptr;
+ update();
+}
+
+void InspectorOverlay::highlightNodeList(RefPtr<NodeList>&& nodes, const HighlightConfig& highlightConfig)
+{
+ m_nodeHighlightConfig = highlightConfig;
+ m_highlightNodeList = WTFMove(nodes);
+ m_highlightNode = nullptr;
update();
}
@@ -292,16 +272,17 @@ void InspectorOverlay::highlightNode(Node* node, const HighlightConfig& highligh
{
m_nodeHighlightConfig = highlightConfig;
m_highlightNode = node;
+ m_highlightNodeList = nullptr;
update();
}
-void InspectorOverlay::highlightQuad(PassOwnPtr<FloatQuad> quad, const HighlightConfig& highlightConfig)
+void InspectorOverlay::highlightQuad(std::unique_ptr<FloatQuad> quad, const HighlightConfig& highlightConfig)
{
- if (m_quadHighlightConfig.usePageCoordinates)
- *quad -= m_page.mainFrame().view()->scrollOffset();
+ if (highlightConfig.usePageCoordinates)
+ *quad -= toIntSize(m_page.mainFrame().view()->scrollPosition());
m_quadHighlightConfig = highlightConfig;
- m_highlightQuad = quad;
+ m_highlightQuad = WTFMove(quad);
update();
}
@@ -315,9 +296,26 @@ void InspectorOverlay::didSetSearchingForNode(bool enabled)
m_client->didSetSearchingForNode(enabled);
}
+void InspectorOverlay::setIndicating(bool indicating)
+{
+ m_indicating = indicating;
+
+ if (m_indicating)
+ evaluateInOverlay(ASCIILiteral("showPageIndication"));
+ else
+ evaluateInOverlay(ASCIILiteral("hidePageIndication"));
+
+ update();
+}
+
+bool InspectorOverlay::shouldShowOverlay() const
+{
+ return m_highlightNode || m_highlightNodeList || m_highlightQuad || m_indicating || m_showingPaintRects || !m_pausedInDebuggerMessage.isNull();
+}
+
void InspectorOverlay::update()
{
- if (!m_highlightNode && !m_highlightQuad && m_pausedInDebuggerMessage.isNull() && m_size.isEmpty()) {
+ if (!shouldShowOverlay()) {
m_client->hideHighlight();
return;
}
@@ -327,80 +325,88 @@ void InspectorOverlay::update()
return;
FrameView* overlayView = overlayPage()->mainFrame().view();
- IntSize viewportSize = view->visibleContentRect().size();
- IntSize frameViewFullSize = view->visibleContentRectIncludingScrollbars().size();
- IntSize size = m_size.isEmpty() ? frameViewFullSize : m_size;
- overlayPage()->setPageScaleFactor(m_page.pageScaleFactor(), IntPoint());
- size.scale(m_page.pageScaleFactor());
- overlayView->resize(size);
+ IntSize viewportSize = view->sizeForVisibleContent();
+ IntSize frameViewFullSize = view->sizeForVisibleContent(ScrollableArea::IncludeScrollbars);
+ overlayView->resize(frameViewFullSize);
// Clear canvas and paint things.
- reset(viewportSize, m_size.isEmpty() ? IntSize() : frameViewFullSize);
+ // FIXME: Remove extra parameter?
+ reset(viewportSize, IntSize());
// Include scrollbars to avoid masking them by the gutter.
drawGutter();
drawNodeHighlight();
drawQuadHighlight();
drawPausedInDebuggerMessage();
+ drawPaintRects();
// Position DOM elements.
overlayPage()->mainFrame().document()->recalcStyle(Style::Force);
if (overlayView->needsLayout())
overlayView->layout();
- // Kick paint.
- m_client->highlight();
+ forcePaint();
}
-static PassRefPtr<InspectorObject> buildObjectForPoint(const FloatPoint& point)
+static Ref<Inspector::Protocol::OverlayTypes::Point> buildObjectForPoint(const FloatPoint& point)
{
- RefPtr<InspectorObject> object = InspectorObject::create();
- object->setNumber("x", point.x());
- object->setNumber("y", point.y());
- return object.release();
+ return Inspector::Protocol::OverlayTypes::Point::create()
+ .setX(point.x())
+ .setY(point.y())
+ .release();
}
-static PassRefPtr<InspectorArray> buildArrayForQuad(const FloatQuad& quad)
+static Ref<Inspector::Protocol::OverlayTypes::Rect> buildObjectForRect(const FloatRect& rect)
{
- RefPtr<InspectorArray> array = InspectorArray::create();
- array->pushObject(buildObjectForPoint(quad.p1()));
- array->pushObject(buildObjectForPoint(quad.p2()));
- array->pushObject(buildObjectForPoint(quad.p3()));
- array->pushObject(buildObjectForPoint(quad.p4()));
- return array.release();
+ return Inspector::Protocol::OverlayTypes::Rect::create()
+ .setX(rect.x())
+ .setY(rect.y())
+ .setWidth(rect.width())
+ .setHeight(rect.height())
+ .release();
}
-static PassRefPtr<InspectorObject> buildObjectForHighlight(const Highlight& highlight)
+static Ref<Inspector::Protocol::OverlayTypes::Quad> buildArrayForQuad(const FloatQuad& quad)
{
- RefPtr<InspectorObject> object = InspectorObject::create();
- RefPtr<InspectorArray> array = InspectorArray::create();
- for (size_t i = 0; i < highlight.quads.size(); ++i)
- array->pushArray(buildArrayForQuad(highlight.quads[i]));
- object->setArray("quads", array.release());
- object->setBoolean("showRulers", highlight.showRulers);
- object->setString("contentColor", highlight.contentColor.serialized());
- object->setString("contentOutlineColor", highlight.contentOutlineColor.serialized());
- object->setString("paddingColor", highlight.paddingColor.serialized());
- object->setString("borderColor", highlight.borderColor.serialized());
- object->setString("marginColor", highlight.marginColor.serialized());
- return object.release();
+ auto array = Inspector::Protocol::OverlayTypes::Quad::create();
+ array->addItem(buildObjectForPoint(quad.p1()));
+ array->addItem(buildObjectForPoint(quad.p2()));
+ array->addItem(buildObjectForPoint(quad.p3()));
+ array->addItem(buildObjectForPoint(quad.p4()));
+ return array;
}
-static PassRefPtr<InspectorObject> buildObjectForRegionHighlight(FrameView* mainView, RenderRegion* region)
+static Ref<Inspector::Protocol::OverlayTypes::FragmentHighlightData> buildObjectForHighlight(const Highlight& highlight)
+{
+ auto arrayOfQuads = Inspector::Protocol::Array<Inspector::Protocol::OverlayTypes::Quad>::create();
+ for (auto& quad : highlight.quads)
+ arrayOfQuads->addItem(buildArrayForQuad(quad));
+
+ return Inspector::Protocol::OverlayTypes::FragmentHighlightData::create()
+ .setQuads(WTFMove(arrayOfQuads))
+ .setContentColor(highlight.contentColor.serialized())
+ .setContentOutlineColor(highlight.contentOutlineColor.serialized())
+ .setPaddingColor(highlight.paddingColor.serialized())
+ .setBorderColor(highlight.borderColor.serialized())
+ .setMarginColor(highlight.marginColor.serialized())
+ .release();
+}
+
+static RefPtr<Inspector::Protocol::OverlayTypes::Region> buildObjectForRegion(FrameView* mainView, RenderRegion* region)
{
FrameView* containingView = region->frame().view();
if (!containingView)
return nullptr;
- RenderBlockFlow* regionContainer = toRenderBlockFlow(region->parent());
- LayoutRect borderBox = regionContainer->borderBoxRect();
- borderBox.setWidth(borderBox.width() + regionContainer->verticalScrollbarWidth());
- borderBox.setHeight(borderBox.height() + regionContainer->horizontalScrollbarHeight());
+ RenderBlockFlow& regionContainer = downcast<RenderBlockFlow>(*region->parent());
+ LayoutRect borderBox = regionContainer.borderBoxRect();
+ borderBox.setWidth(borderBox.width() + regionContainer.verticalScrollbarWidth());
+ borderBox.setHeight(borderBox.height() + regionContainer.horizontalScrollbarHeight());
// Create incoming and outgoing boxes that we use to chain the regions toghether.
const LayoutSize linkBoxSize(10, 10);
const LayoutSize linkBoxMidpoint(linkBoxSize.width() / 2, linkBoxSize.height() / 2);
-
+
LayoutRect incomingRectBox = LayoutRect(borderBox.location() - linkBoxMidpoint, linkBoxSize);
LayoutRect outgoingRectBox = LayoutRect(borderBox.location() - linkBoxMidpoint + borderBox.size(), linkBoxSize);
@@ -410,55 +416,53 @@ static PassRefPtr<InspectorObject> buildObjectForRegionHighlight(FrameView* main
incomingRectBox.move(0, linkBoxVerticalOffset);
outgoingRectBox.move(0, -linkBoxVerticalOffset);
- FloatQuad borderRectQuad = regionContainer->localToAbsoluteQuad(FloatRect(borderBox));
- FloatQuad incomingRectQuad = regionContainer->localToAbsoluteQuad(FloatRect(incomingRectBox));
- FloatQuad outgoingRectQuad = regionContainer->localToAbsoluteQuad(FloatRect(outgoingRectBox));
+ FloatQuad borderRectQuad = regionContainer.localToAbsoluteQuad(FloatRect(borderBox));
+ FloatQuad incomingRectQuad = regionContainer.localToAbsoluteQuad(FloatRect(incomingRectBox));
+ FloatQuad outgoingRectQuad = regionContainer.localToAbsoluteQuad(FloatRect(outgoingRectBox));
contentsQuadToPage(mainView, containingView, borderRectQuad);
contentsQuadToPage(mainView, containingView, incomingRectQuad);
contentsQuadToPage(mainView, containingView, outgoingRectQuad);
- RefPtr<InspectorObject> regionObject = InspectorObject::create();
-
- regionObject->setArray("borderQuad", buildArrayForQuad(borderRectQuad));
- regionObject->setArray("incomingQuad", buildArrayForQuad(incomingRectQuad));
- regionObject->setArray("outgoingQuad", buildArrayForQuad(outgoingRectQuad));
-
- return regionObject.release();
+ return Inspector::Protocol::OverlayTypes::Region::create()
+ .setBorderQuad(buildArrayForQuad(borderRectQuad))
+ .setIncomingQuad(buildArrayForQuad(incomingRectQuad))
+ .setOutgoingQuad(buildArrayForQuad(outgoingRectQuad))
+ .release();
}
-static PassRefPtr<InspectorArray> buildObjectForCSSRegionsHighlight(RenderRegion* region, RenderFlowThread* flowThread)
+static Ref<Inspector::Protocol::Array<Inspector::Protocol::OverlayTypes::Region>> buildObjectForFlowRegions(RenderRegion* region, RenderFlowThread* flowThread)
{
FrameView* mainFrameView = region->document().page()->mainFrame().view();
- RefPtr<InspectorArray> array = InspectorArray::create();
+ auto arrayOfRegions = Inspector::Protocol::Array<Inspector::Protocol::OverlayTypes::Region>::create();
const RenderRegionList& regionList = flowThread->renderRegionList();
for (auto& iterRegion : regionList) {
if (!iterRegion->isValid())
continue;
- RefPtr<InspectorObject> regionHighlightObject = buildObjectForRegionHighlight(mainFrameView, iterRegion);
- if (!regionHighlightObject)
+ RefPtr<Inspector::Protocol::OverlayTypes::Region> regionObject = buildObjectForRegion(mainFrameView, iterRegion);
+ if (!regionObject)
continue;
if (region == iterRegion) {
// Let the script know that this is the currently highlighted node.
- regionHighlightObject->setBoolean("isHighlighted", true);
+ regionObject->setIsHighlighted(true);
}
- array->pushObject(regionHighlightObject.release());
+ arrayOfRegions->addItem(WTFMove(regionObject));
}
- return array.release();
+ return arrayOfRegions;
}
-static PassRefPtr<InspectorObject> buildObjectForSize(const IntSize& size)
+static Ref<Inspector::Protocol::OverlayTypes::Size> buildObjectForSize(const IntSize& size)
{
- RefPtr<InspectorObject> result = InspectorObject::create();
- result->setNumber("width", size.width());
- result->setNumber("height", size.height());
- return result.release();
+ return Inspector::Protocol::OverlayTypes::Size::create()
+ .setWidth(size.width())
+ .setHeight(size.height())
+ .release();
}
-static PassRefPtr<InspectorObject> buildObjectForCSSRegionContentClip(RenderRegion* region)
+static RefPtr<Inspector::Protocol::OverlayTypes::Quad> buildQuadObjectForCSSRegionContentClip(RenderRegion* region)
{
Frame* containingFrame = region->document().frame();
if (!containingFrame)
@@ -478,104 +482,161 @@ static PassRefPtr<InspectorObject> buildObjectForCSSRegionContentClip(RenderRegi
FloatQuad clipQuad = region->localToAbsoluteQuad(FloatRect(flippedRegionRect));
contentsQuadToPage(mainView, containingView, clipQuad);
- RefPtr<InspectorObject> regionObject = InspectorObject::create();
- regionObject->setArray("quad", buildArrayForQuad(clipQuad));
- return regionObject.release();
+ return buildArrayForQuad(clipQuad);
+}
+
+void InspectorOverlay::setShowingPaintRects(bool showingPaintRects)
+{
+ if (m_showingPaintRects == showingPaintRects)
+ return;
+
+ m_showingPaintRects = showingPaintRects;
+ if (!m_showingPaintRects) {
+ m_paintRects.clear();
+ m_paintRectUpdateTimer.stop();
+ drawPaintRects();
+ forcePaint();
+ }
+}
+
+void InspectorOverlay::showPaintRect(const FloatRect& rect)
+{
+ if (!m_showingPaintRects)
+ return;
+
+ IntRect rootRect = m_page.mainFrame().view()->contentsToRootView(enclosingIntRect(rect));
+
+ const auto removeDelay = 250ms;
+
+ std::chrono::steady_clock::time_point removeTime = std::chrono::steady_clock::now() + removeDelay;
+ m_paintRects.append(TimeRectPair(removeTime, rootRect));
+
+ if (!m_paintRectUpdateTimer.isActive()) {
+ const double paintRectsUpdateIntervalSeconds = 0.032;
+ m_paintRectUpdateTimer.startRepeating(paintRectsUpdateIntervalSeconds);
+ }
+
+ drawPaintRects();
+ forcePaint();
+}
+
+void InspectorOverlay::updatePaintRectsTimerFired()
+{
+ std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now();
+ bool rectsChanged = false;
+ while (!m_paintRects.isEmpty() && m_paintRects.first().first < now) {
+ m_paintRects.removeFirst();
+ rectsChanged = true;
+ }
+
+ if (m_paintRects.isEmpty())
+ m_paintRectUpdateTimer.stop();
+
+ if (rectsChanged) {
+ drawPaintRects();
+ forcePaint();
+ }
+}
+
+void InspectorOverlay::drawPaintRects()
+{
+ auto arrayOfRects = Inspector::Protocol::Array<Inspector::Protocol::OverlayTypes::Rect>::create();
+ for (const auto& pair : m_paintRects)
+ arrayOfRects->addItem(buildObjectForRect(pair.second));
+
+ evaluateInOverlay(ASCIILiteral("updatePaintRects"), WTFMove(arrayOfRects));
}
void InspectorOverlay::drawGutter()
{
- evaluateInOverlay("drawGutter", "");
+ evaluateInOverlay(ASCIILiteral("drawGutter"));
}
-static PassRefPtr<InspectorArray> buildObjectForRendererFragments(RenderObject* renderer, const HighlightConfig& config)
+static RefPtr<Inspector::Protocol::Array<Inspector::Protocol::OverlayTypes::FragmentHighlightData>> buildArrayForRendererFragments(RenderObject* renderer, const HighlightConfig& config)
{
- RefPtr<InspectorArray> fragmentsArray = InspectorArray::create();
+ auto arrayOfFragments = Inspector::Protocol::Array<Inspector::Protocol::OverlayTypes::FragmentHighlightData>::create();
RenderFlowThread* containingFlowThread = renderer->flowThreadContainingBlock();
if (!containingFlowThread) {
Highlight highlight;
- buildRendererHighlight(renderer, nullptr, config, &highlight);
- fragmentsArray->pushObject(buildObjectForHighlight(highlight));
+ buildRendererHighlight(renderer, nullptr, config, highlight, InspectorOverlay::CoordinateSystem::View);
+ arrayOfFragments->addItem(buildObjectForHighlight(highlight));
} else {
- RenderBox* enclosingBox = renderer->enclosingBox();
RenderRegion* startRegion = nullptr;
RenderRegion* endRegion = nullptr;
- containingFlowThread->getRegionRangeForBox(enclosingBox, startRegion, endRegion);
- if (!startRegion) {
+ if (!containingFlowThread->getRegionRangeForBox(&renderer->enclosingBox(), startRegion, endRegion)) {
// The flow has no visible regions. The renderer is not visible on screen.
return nullptr;
}
+
const RenderRegionList& regionList = containingFlowThread->renderRegionList();
for (RenderRegionList::const_iterator iter = regionList.find(startRegion); iter != regionList.end(); ++iter) {
RenderRegion* region = *iter;
if (region->isValid()) {
// Compute the highlight of the fragment inside the current region.
Highlight highlight;
- buildRendererHighlight(renderer, region, config, &highlight);
- RefPtr<InspectorObject> fragmentObject = buildObjectForHighlight(highlight);
+ buildRendererHighlight(renderer, region, config, highlight, InspectorOverlay::CoordinateSystem::View);
+ Ref<Inspector::Protocol::OverlayTypes::FragmentHighlightData> fragmentHighlight = buildObjectForHighlight(highlight);
// Compute the clipping area of the region.
- fragmentObject->setObject("region", buildObjectForCSSRegionContentClip(region));
- fragmentsArray->pushObject(fragmentObject.release());
+ fragmentHighlight->setRegionClippingArea(buildQuadObjectForCSSRegionContentClip(region));
+ arrayOfFragments->addItem(WTFMove(fragmentHighlight));
}
if (region == endRegion)
break;
}
}
- return fragmentsArray.release();
+ return WTFMove(arrayOfFragments);
}
-#if ENABLE(CSS_SHAPES)
static FloatPoint localPointToRoot(RenderObject* renderer, const FrameView* mainView, const FrameView* view, const FloatPoint& point)
{
FloatPoint result = renderer->localToAbsolute(point);
result = view->contentsToRootView(roundedIntPoint(result));
- result += mainView->scrollOffset();
+ result += toIntSize(mainView->scrollPosition());
return result;
}
struct PathApplyInfo {
FrameView* rootView;
FrameView* view;
- InspectorArray* array;
+ Inspector::Protocol::OverlayTypes::DisplayPath* pathArray;
RenderObject* renderer;
const ShapeOutsideInfo* shapeOutsideInfo;
};
-static void appendPathCommandAndPoints(PathApplyInfo* info, const String& command, const FloatPoint points[], unsigned length)
+static void appendPathCommandAndPoints(PathApplyInfo& info, const String& command, const FloatPoint points[], unsigned length)
{
FloatPoint point;
- info->array->pushString(command);
+ info.pathArray->addItem(command);
for (unsigned i = 0; i < length; i++) {
- point = info->shapeOutsideInfo->shapeToRendererPoint(points[i]);
- point = localPointToRoot(info->renderer, info->rootView, info->view, point);
- info->array->pushNumber(point.x());
- info->array->pushNumber(point.y());
+ point = info.shapeOutsideInfo->shapeToRendererPoint(points[i]);
+ point = localPointToRoot(info.renderer, info.rootView, info.view, point);
+ info.pathArray->addItem(point.x());
+ info.pathArray->addItem(point.y());
}
}
-static void appendPathSegment(void* info, const PathElement* pathElement)
+static void appendPathSegment(PathApplyInfo& pathApplyInfo, const PathElement& pathElement)
{
- PathApplyInfo* pathApplyInfo = static_cast<PathApplyInfo*>(info);
FloatPoint point;
- switch (pathElement->type) {
+ switch (pathElement.type) {
// The points member will contain 1 value.
case PathElementMoveToPoint:
- appendPathCommandAndPoints(pathApplyInfo, ASCIILiteral("M"), pathElement->points, 1);
+ appendPathCommandAndPoints(pathApplyInfo, ASCIILiteral("M"), pathElement.points, 1);
break;
// The points member will contain 1 value.
case PathElementAddLineToPoint:
- appendPathCommandAndPoints(pathApplyInfo, ASCIILiteral("L"), pathElement->points, 1);
+ appendPathCommandAndPoints(pathApplyInfo, ASCIILiteral("L"), pathElement.points, 1);
break;
// The points member will contain 3 values.
case PathElementAddCurveToPoint:
- appendPathCommandAndPoints(pathApplyInfo, ASCIILiteral("C"), pathElement->points, 3);
+ appendPathCommandAndPoints(pathApplyInfo, ASCIILiteral("C"), pathElement.points, 3);
break;
// The points member will contain 2 values.
case PathElementAddQuadCurveToPoint:
- appendPathCommandAndPoints(pathApplyInfo, ASCIILiteral("Q"), pathElement->points, 2);
+ appendPathCommandAndPoints(pathApplyInfo, ASCIILiteral("Q"), pathElement.points, 2);
break;
// The points member will contain no values.
case PathElementCloseSubpath:
@@ -584,149 +645,198 @@ static void appendPathSegment(void* info, const PathElement* pathElement)
}
}
-static PassRefPtr<InspectorObject> buildObjectForShapeOutside(Frame* containingFrame, RenderBox* renderer)
+static RefPtr<Inspector::Protocol::OverlayTypes::ShapeOutsideData> buildObjectForShapeOutside(Frame* containingFrame, RenderBox* renderer)
{
const ShapeOutsideInfo* shapeOutsideInfo = renderer->shapeOutsideInfo();
if (!shapeOutsideInfo)
return nullptr;
- RefPtr<InspectorObject> shapeObject = InspectorObject::create();
LayoutRect shapeBounds = shapeOutsideInfo->computedShapePhysicalBoundingBox();
FloatQuad shapeQuad = renderer->localToAbsoluteQuad(FloatRect(shapeBounds));
contentsQuadToPage(containingFrame->page()->mainFrame().view(), containingFrame->view(), shapeQuad);
- shapeObject->setArray(ASCIILiteral("bounds"), buildArrayForQuad(shapeQuad));
+
+ auto shapeObject = Inspector::Protocol::OverlayTypes::ShapeOutsideData::create()
+ .setBounds(buildArrayForQuad(shapeQuad))
+ .release();
Shape::DisplayPaths paths;
shapeOutsideInfo->computedShape().buildDisplayPaths(paths);
if (paths.shape.length()) {
- RefPtr<InspectorArray> shapePath = InspectorArray::create();
+ auto shapePath = Inspector::Protocol::OverlayTypes::DisplayPath::create();
PathApplyInfo info;
info.rootView = containingFrame->page()->mainFrame().view();
info.view = containingFrame->view();
- info.array = shapePath.get();
+ info.pathArray = &shapePath.get();
info.renderer = renderer;
info.shapeOutsideInfo = shapeOutsideInfo;
- paths.shape.apply(&info, &appendPathSegment);
+ paths.shape.apply([&info](const PathElement& pathElement) {
+ appendPathSegment(info, pathElement);
+ });
- shapeObject->setArray(ASCIILiteral("shape"), shapePath.release());
+ shapeObject->setShape(shapePath.copyRef());
if (paths.marginShape.length()) {
- shapePath = InspectorArray::create();
- info.array = shapePath.get();
+ auto marginShapePath = Inspector::Protocol::OverlayTypes::DisplayPath::create();
+ info.pathArray = &marginShapePath.get();
- paths.marginShape.apply(&info, &appendPathSegment);
+ paths.marginShape.apply([&info](const PathElement& pathElement) {
+ appendPathSegment(info, pathElement);
+ });
- shapeObject->setArray(ASCIILiteral("marginShape"), shapePath.release());
+ shapeObject->setMarginShape(marginShapePath.copyRef());
}
}
- return shapeObject.release();
+ return WTFMove(shapeObject);
}
-#endif
-static PassRefPtr<InspectorObject> buildObjectForElementInfo(Node* node)
+static RefPtr<Inspector::Protocol::OverlayTypes::ElementData> buildObjectForElementData(Node* node, HighlightType type)
{
- if (!node->isElementNode() || !node->document().frame())
+ if (!is<Element>(node) || !node->document().frame())
return nullptr;
- RefPtr<InspectorObject> elementInfo = InspectorObject::create();
-
- Element* element = toElement(node);
- bool isXHTML = element->document().isXHTMLDocument();
- elementInfo->setString("tagName", isXHTML ? element->nodeName() : element->nodeName().lower());
- elementInfo->setString("idValue", element->getIdAttribute());
- HashSet<AtomicString> usedClassNames;
- if (element->hasClass() && element->isStyledElement()) {
- StringBuilder classNames;
- const SpaceSplitString& classNamesString = toStyledElement(element)->classNames();
- size_t classNameCount = classNamesString.size();
- for (size_t i = 0; i < classNameCount; ++i) {
+ Element* effectiveElement = downcast<Element>(node);
+ if (node->isPseudoElement()) {
+ Element* hostElement = downcast<PseudoElement>(*node).hostElement();
+ if (!hostElement)
+ return nullptr;
+ effectiveElement = hostElement;
+ }
+
+ Element& element = *effectiveElement;
+ bool isXHTML = element.document().isXHTMLDocument();
+ auto elementData = Inspector::Protocol::OverlayTypes::ElementData::create()
+ .setTagName(isXHTML ? element.nodeName() : element.nodeName().convertToASCIILowercase())
+ .setIdValue(element.getIdAttribute())
+ .release();
+
+ if (element.hasClass() && is<StyledElement>(element)) {
+ auto classes = Inspector::Protocol::Array<String>::create();
+ HashSet<AtomicString> usedClassNames;
+ const SpaceSplitString& classNamesString = downcast<StyledElement>(element).classNames();
+ for (size_t i = 0; i < classNamesString.size(); ++i) {
const AtomicString& className = classNamesString[i];
if (usedClassNames.contains(className))
continue;
+
usedClassNames.add(className);
- classNames.append('.');
- classNames.append(className);
+ classes->addItem(className);
}
- elementInfo->setString("className", classNames.toString());
+ elementData->setClasses(WTFMove(classes));
+ }
+
+ if (node->isPseudoElement()) {
+ if (node->pseudoId() == BEFORE)
+ elementData->setPseudoElement("before");
+ else if (node->pseudoId() == AFTER)
+ elementData->setPseudoElement("after");
}
- RenderElement* renderer = element->renderer();
+ RenderElement* renderer = element.renderer();
+ if (!renderer)
+ return nullptr;
+
Frame* containingFrame = node->document().frame();
FrameView* containingView = containingFrame->view();
- IntRect boundingBox = pixelSnappedIntRect(containingView->contentsToRootView(renderer->absoluteBoundingBoxRect()));
- RenderBoxModelObject* modelObject = renderer->isBoxModelObject() ? toRenderBoxModelObject(renderer) : nullptr;
- elementInfo->setString("nodeWidth", String::number(modelObject ? adjustForAbsoluteZoom(modelObject->pixelSnappedOffsetWidth(), *modelObject) : boundingBox.width()));
- elementInfo->setString("nodeHeight", String::number(modelObject ? adjustForAbsoluteZoom(modelObject->pixelSnappedOffsetHeight(), *modelObject) : boundingBox.height()));
-
- if (renderer->isRenderNamedFlowFragmentContainer()) {
- RenderNamedFlowFragment* region = toRenderBlockFlow(renderer)->renderNamedFlowFragment();
- RenderFlowThread* flowThread = region->flowThread();
- if (flowThread && flowThread->isRenderNamedFlowThread()) {
- RefPtr<InspectorObject> regionFlowInfo = InspectorObject::create();
- regionFlowInfo->setString("name", toRenderNamedFlowThread(flowThread)->flowThreadName());
- regionFlowInfo->setArray("regions", buildObjectForCSSRegionsHighlight(region, flowThread));
- elementInfo->setObject("regionFlowInfo", regionFlowInfo.release());
+ IntRect boundingBox = snappedIntRect(containingView->contentsToRootView(renderer->absoluteBoundingBoxRect()));
+ RenderBoxModelObject* modelObject = is<RenderBoxModelObject>(*renderer) ? downcast<RenderBoxModelObject>(renderer) : nullptr;
+ auto sizeObject = Inspector::Protocol::OverlayTypes::Size::create()
+ .setWidth(modelObject ? adjustForAbsoluteZoom(roundToInt(modelObject->offsetWidth()), *modelObject) : boundingBox.width())
+ .setHeight(modelObject ? adjustForAbsoluteZoom(roundToInt(modelObject->offsetHeight()), *modelObject) : boundingBox.height())
+ .release();
+ elementData->setSize(WTFMove(sizeObject));
+
+ if (type != HighlightType::NodeList && renderer->isRenderNamedFlowFragmentContainer()) {
+ RenderNamedFlowFragment& region = *downcast<RenderBlockFlow>(*renderer).renderNamedFlowFragment();
+ if (region.isValid()) {
+ RenderFlowThread* flowThread = region.flowThread();
+ auto regionFlowData = Inspector::Protocol::OverlayTypes::RegionFlowData::create()
+ .setName(downcast<RenderNamedFlowThread>(*flowThread).flowThreadName())
+ .setRegions(buildObjectForFlowRegions(&region, flowThread))
+ .release();
+ elementData->setRegionFlowData(WTFMove(regionFlowData));
}
}
RenderFlowThread* containingFlowThread = renderer->flowThreadContainingBlock();
- if (containingFlowThread && containingFlowThread->isRenderNamedFlowThread()) {
- RefPtr<InspectorObject> contentFlowInfo = InspectorObject::create();
- contentFlowInfo->setString("name", toRenderNamedFlowThread(containingFlowThread)->flowThreadName());
- elementInfo->setObject("contentFlowInfo", contentFlowInfo.release());
+ if (is<RenderNamedFlowThread>(containingFlowThread)) {
+ auto contentFlowData = Inspector::Protocol::OverlayTypes::ContentFlowData::create()
+ .setName(downcast<RenderNamedFlowThread>(*containingFlowThread).flowThreadName())
+ .release();
+
+ elementData->setContentFlowData(WTFMove(contentFlowData));
}
-#if ENABLE(CSS_SHAPES)
- if (renderer->isBox()) {
- RenderBox* renderBox = toRenderBox(renderer);
- if (RefPtr<InspectorObject> shapeObject = buildObjectForShapeOutside(containingFrame, renderBox))
- elementInfo->setObject("shapeOutsideInfo", shapeObject.release());
+ if (is<RenderBox>(*renderer)) {
+ auto& renderBox = downcast<RenderBox>(*renderer);
+ if (RefPtr<Inspector::Protocol::OverlayTypes::ShapeOutsideData> shapeObject = buildObjectForShapeOutside(containingFrame, &renderBox))
+ elementData->setShapeOutsideData(WTFMove(shapeObject));
+ }
+
+ // Need to enable AX to get the computed role.
+ if (!WebCore::AXObjectCache::accessibilityEnabled())
+ WebCore::AXObjectCache::enableAccessibility();
+
+ if (AXObjectCache* axObjectCache = node->document().axObjectCache()) {
+ if (AccessibilityObject* axObject = axObjectCache->getOrCreate(node))
+ elementData->setRole(axObject->computedRoleString());
}
-#endif
- return elementInfo.release();
+ return WTFMove(elementData);
}
-PassRefPtr<InspectorObject> InspectorOverlay::buildObjectForHighlightedNode() const
+RefPtr<Inspector::Protocol::OverlayTypes::NodeHighlightData> InspectorOverlay::buildHighlightObjectForNode(Node* node, HighlightType type) const
{
- if (!m_highlightNode)
+ if (!node)
return nullptr;
- Node* node = m_highlightNode.get();
RenderObject* renderer = node->renderer();
if (!renderer)
return nullptr;
- RefPtr<InspectorArray> highlightFragments = buildObjectForRendererFragments(renderer, m_nodeHighlightConfig);
- if (!highlightFragments)
+ RefPtr<Inspector::Protocol::Array<Inspector::Protocol::OverlayTypes::FragmentHighlightData>> arrayOfFragmentHighlights = buildArrayForRendererFragments(renderer, m_nodeHighlightConfig);
+ if (!arrayOfFragmentHighlights)
return nullptr;
- RefPtr<InspectorObject> highlightObject = InspectorObject::create();
-
// The main view's scroll offset is shared across all quads.
FrameView* mainView = m_page.mainFrame().view();
- highlightObject->setObject("scroll", buildObjectForPoint(!mainView->delegatesScrolling() ? mainView->visibleContentRect().location() : FloatPoint()));
- highlightObject->setArray("fragments", highlightFragments.release());
+ auto nodeHighlightObject = Inspector::Protocol::OverlayTypes::NodeHighlightData::create()
+ .setScrollOffset(buildObjectForPoint(!mainView->delegatesScrolling() ? mainView->visibleContentRect().location() : FloatPoint()))
+ .setFragments(WTFMove(arrayOfFragmentHighlights))
+ .release();
if (m_nodeHighlightConfig.showInfo) {
- RefPtr<InspectorObject> elementInfo = buildObjectForElementInfo(node);
- if (elementInfo)
- highlightObject->setObject("elementInfo", elementInfo.release());
+ if (RefPtr<Inspector::Protocol::OverlayTypes::ElementData> elementData = buildObjectForElementData(node, type))
+ nodeHighlightObject->setElementData(WTFMove(elementData));
}
-
- return highlightObject.release();
+
+ return WTFMove(nodeHighlightObject);
+}
+
+Ref<Inspector::Protocol::Array<Inspector::Protocol::OverlayTypes::NodeHighlightData>> InspectorOverlay::buildObjectForHighlightedNodes() const
+{
+ auto highlights = Inspector::Protocol::Array<Inspector::Protocol::OverlayTypes::NodeHighlightData>::create();
+
+ if (m_highlightNode) {
+ if (RefPtr<Inspector::Protocol::OverlayTypes::NodeHighlightData> nodeHighlightData = buildHighlightObjectForNode(m_highlightNode.get(), HighlightType::Node))
+ highlights->addItem(WTFMove(nodeHighlightData));
+ } else if (m_highlightNodeList) {
+ for (unsigned i = 0; i < m_highlightNodeList->length(); ++i) {
+ if (RefPtr<Inspector::Protocol::OverlayTypes::NodeHighlightData> nodeHighlightData = buildHighlightObjectForNode(m_highlightNodeList->item(i), HighlightType::NodeList))
+ highlights->addItem(WTFMove(nodeHighlightData));
+ }
+ }
+
+ return highlights;
}
void InspectorOverlay::drawNodeHighlight()
{
- RefPtr<InspectorObject> highlightObject = buildObjectForHighlightedNode();
- if (!highlightObject)
- return;
- evaluateInOverlay("drawNodeHighlight", highlightObject);
+ if (m_highlightNode || m_highlightNodeList)
+ evaluateInOverlay("drawNodeHighlight", buildObjectForHighlightedNodes());
}
void InspectorOverlay::drawQuadHighlight()
@@ -735,7 +845,7 @@ void InspectorOverlay::drawQuadHighlight()
return;
Highlight highlight;
- buildQuadHighlight(*m_highlightQuad, m_quadHighlightConfig, &highlight);
+ buildQuadHighlight(*m_highlightQuad, m_quadHighlightConfig, highlight);
evaluateInOverlay("drawQuadHighlight", buildObjectForHighlight(highlight));
}
@@ -750,9 +860,14 @@ Page* InspectorOverlay::overlayPage()
if (m_overlayPage)
return m_overlayPage.get();
- Page::PageClients pageClients;
- fillWithEmptyClients(pageClients);
- m_overlayPage = adoptPtr(new Page(pageClients));
+ PageConfiguration pageConfiguration(
+ createEmptyEditorClient(),
+ SocketProvider::create(),
+ makeUniqueRef<LibWebRTCProvider>()
+ );
+ fillWithEmptyClients(pageConfiguration);
+ m_overlayPage = std::make_unique<Page>(WTFMove(pageConfiguration));
+ m_overlayPage->setDeviceScaleFactor(m_page.deviceScaleFactor());
Settings& settings = m_page.settings();
Settings& overlaySettings = m_overlayPage->settings();
@@ -792,36 +907,56 @@ Page* InspectorOverlay::overlayPage()
return m_overlayPage.get();
}
+void InspectorOverlay::forcePaint()
+{
+ // This overlay page is very weird and doesn't automatically paint. We have to force paints manually.
+ m_client->highlight();
+}
+
void InspectorOverlay::reset(const IntSize& viewportSize, const IntSize& frameViewFullSize)
{
- RefPtr<InspectorObject> resetData = InspectorObject::create();
- resetData->setNumber("deviceScaleFactor", m_page.deviceScaleFactor());
- resetData->setObject("viewportSize", buildObjectForSize(viewportSize));
- resetData->setObject("frameViewFullSize", buildObjectForSize(frameViewFullSize));
- evaluateInOverlay("reset", resetData.release());
+ auto configObject = Inspector::Protocol::OverlayTypes::OverlayConfiguration::create()
+ .setDeviceScaleFactor(m_page.deviceScaleFactor())
+ .setViewportSize(buildObjectForSize(viewportSize))
+ .setFrameViewFullSize(buildObjectForSize(frameViewFullSize))
+ .release();
+ evaluateInOverlay("reset", WTFMove(configObject));
+}
+
+static void evaluateCommandInOverlay(Page* page, Ref<InspectorArray>&& command)
+{
+ page->mainFrame().script().evaluate(ScriptSourceCode(makeString("dispatch(", command->toJSONString(), ')')));
+}
+
+void InspectorOverlay::evaluateInOverlay(const String& method)
+{
+ Ref<InspectorArray> command = InspectorArray::create();
+ command->pushString(method);
+
+ evaluateCommandInOverlay(overlayPage(), WTFMove(command));
}
void InspectorOverlay::evaluateInOverlay(const String& method, const String& argument)
{
- RefPtr<InspectorArray> command = InspectorArray::create();
+ Ref<InspectorArray> command = InspectorArray::create();
command->pushString(method);
command->pushString(argument);
- overlayPage()->mainFrame().script().evaluate(ScriptSourceCode(makeString("dispatch(", command->toJSONString(), ")")));
+
+ evaluateCommandInOverlay(overlayPage(), WTFMove(command));
}
-void InspectorOverlay::evaluateInOverlay(const String& method, PassRefPtr<InspectorValue> argument)
+void InspectorOverlay::evaluateInOverlay(const String& method, RefPtr<InspectorValue>&& argument)
{
- RefPtr<InspectorArray> command = InspectorArray::create();
+ Ref<InspectorArray> command = InspectorArray::create();
command->pushString(method);
- command->pushValue(argument);
- overlayPage()->mainFrame().script().evaluate(ScriptSourceCode(makeString("dispatch(", command->toJSONString(), ")")));
+ command->pushValue(WTFMove(argument));
+
+ evaluateCommandInOverlay(overlayPage(), WTFMove(command));
}
void InspectorOverlay::freePage()
{
- m_overlayPage.clear();
+ m_overlayPage = nullptr;
}
} // namespace WebCore
-
-#endif // ENABLE(INSPECTOR)