diff options
Diffstat (limited to 'Source/WebCore/inspector/InspectorOverlay.cpp')
-rw-r--r-- | Source/WebCore/inspector/InspectorOverlay.cpp | 733 |
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(®ion, 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) |