| Index: Source/core/inspector/InspectorOverlay.cpp
|
| diff --git a/Source/core/inspector/InspectorOverlay.cpp b/Source/core/inspector/InspectorOverlay.cpp
|
| index 522204b02d4aaeead087fe736ea53120844822af..419167e8b53792c9f94817315636b2c83b838c82 100644
|
| --- a/Source/core/inspector/InspectorOverlay.cpp
|
| +++ b/Source/core/inspector/InspectorOverlay.cpp
|
| @@ -59,6 +59,14 @@ namespace WebCore {
|
|
|
| namespace {
|
|
|
| +struct PathApplyInfo {
|
| + FrameView* rootView;
|
| + FrameView* view;
|
| + TypeBuilder::Array<JSONValue>* array;
|
| + RenderObject* renderer;
|
| + const ShapeOutsideInfo* shapeOutsideInfo;
|
| +};
|
| +
|
| class InspectorOverlayChromeClient FINAL: public EmptyChromeClient {
|
| public:
|
| InspectorOverlayChromeClient(ChromeClient& client, InspectorOverlay* overlay)
|
| @@ -483,7 +491,105 @@ static PassRefPtr<JSONObject> buildObjectForSize(const IntSize& size)
|
| return result.release();
|
| }
|
|
|
| -static void setElementInfo(RefPtr<JSONObject>& highlightObject, Node* node)
|
| +// CSS shapes
|
| +static void appendPathCommandAndPoints(PathApplyInfo* info, const String& command, const FloatPoint points[], unsigned length)
|
| +{
|
| + FloatPoint point;
|
| + info->array->addItem(JSONString::create(command));
|
| + for (unsigned i = 0; i < length; i++) {
|
| + point = info->shapeOutsideInfo->shapeToRendererPoint(points[i]);
|
| + point = info->view->contentsToRootView(roundedIntPoint(info->renderer->localToAbsolute(point))) + info->rootView->scrollOffset();
|
| + info->array->addItem(JSONBasicValue::create(point.x()));
|
| + info->array->addItem(JSONBasicValue::create(point.y()));
|
| + }
|
| +}
|
| +
|
| +static void appendPathSegment(void* info, const PathElement* pathElement)
|
| +{
|
| + PathApplyInfo* pathApplyInfo = static_cast<PathApplyInfo*>(info);
|
| + FloatPoint point;
|
| + switch (pathElement->type) {
|
| + // The points member will contain 1 value.
|
| + case PathElementMoveToPoint:
|
| + appendPathCommandAndPoints(pathApplyInfo, "M", pathElement->points, 1);
|
| + break;
|
| + // The points member will contain 1 value.
|
| + case PathElementAddLineToPoint:
|
| + appendPathCommandAndPoints(pathApplyInfo, "L", pathElement->points, 1);
|
| + break;
|
| + // The points member will contain 3 values.
|
| + case PathElementAddCurveToPoint:
|
| + appendPathCommandAndPoints(pathApplyInfo, "C", pathElement->points, 3);
|
| + break;
|
| + // The points member will contain 2 values.
|
| + case PathElementAddQuadCurveToPoint:
|
| + appendPathCommandAndPoints(pathApplyInfo, "Q", pathElement->points, 2);
|
| + break;
|
| + // The points member will contain no values.
|
| + case PathElementCloseSubpath:
|
| + appendPathCommandAndPoints(pathApplyInfo, "Z", 0, 0);
|
| + break;
|
| + }
|
| +}
|
| +
|
| +static RefPtr<TypeBuilder::Array<double> > buildArrayForQuadTypeBuilder(const FloatQuad& quad)
|
| +{
|
| + RefPtr<TypeBuilder::Array<double> > array = TypeBuilder::Array<double>::create();
|
| + array->addItem(quad.p1().x());
|
| + array->addItem(quad.p1().y());
|
| + array->addItem(quad.p2().x());
|
| + array->addItem(quad.p2().y());
|
| + array->addItem(quad.p3().x());
|
| + array->addItem(quad.p3().y());
|
| + array->addItem(quad.p4().x());
|
| + array->addItem(quad.p4().y());
|
| + return array.release();
|
| +}
|
| +
|
| +PassRefPtr<TypeBuilder::DOM::ShapeOutsideInfo> InspectorOverlay::buildObjectForShapeOutside(Node* node)
|
| +{
|
| + RenderObject* renderer = node->renderer();
|
| + if (!renderer || !renderer->isBox() || !toRenderBox(renderer)->shapeOutsideInfo())
|
| + return nullptr;
|
| +
|
| + LocalFrame* containingFrame = node->document().frame();
|
| + RenderBox* renderBox = toRenderBox(renderer);
|
| + const ShapeOutsideInfo* shapeOutsideInfo = renderBox->shapeOutsideInfo();
|
| +
|
| + LayoutRect shapeBounds = shapeOutsideInfo->computedShapePhysicalBoundingBox();
|
| + FloatQuad shapeQuad = renderBox->localToAbsoluteQuad(FloatRect(shapeBounds));
|
| + FrameView* mainView = containingFrame->page()->mainFrame()->view();
|
| + FrameView* containingView = containingFrame->view();
|
| + contentsQuadToPage(mainView, containingView, shapeQuad);
|
| +
|
| + Shape::DisplayPaths paths;
|
| + shapeOutsideInfo->computedShape().buildDisplayPaths(paths);
|
| + RefPtr<TypeBuilder::Array<JSONValue> > shapePath = TypeBuilder::Array<JSONValue>::create();
|
| + RefPtr<TypeBuilder::Array<JSONValue> > marginShapePath = TypeBuilder::Array<JSONValue>::create();
|
| +
|
| + if (paths.shape.length()) {
|
| + PathApplyInfo info;
|
| + info.rootView = mainView;
|
| + info.view = containingView;
|
| + info.array = shapePath.get();
|
| + info.renderer = renderBox;
|
| + info.shapeOutsideInfo = shapeOutsideInfo;
|
| + paths.shape.apply(&info, &appendPathSegment);
|
| +
|
| + if (paths.marginShape.length()) {
|
| + info.array = marginShapePath.get();
|
| + paths.marginShape.apply(&info, &appendPathSegment);
|
| + }
|
| + }
|
| + RefPtr<TypeBuilder::DOM::ShapeOutsideInfo> shapeTypeBuilder = TypeBuilder::DOM::ShapeOutsideInfo::create()
|
| + .setBounds(buildArrayForQuadTypeBuilder(shapeQuad))
|
| + .setShape(shapePath)
|
| + .setMarginShape(marginShapePath);
|
| +
|
| + return shapeTypeBuilder.release();
|
| +}
|
| +
|
| +static void setElementInfo(RefPtr<JSONObject>& highlightObject, RefPtr<JSONObject>& shapeObject, Node* node)
|
| {
|
| RefPtr<JSONObject> elementInfo = JSONObject::create();
|
| Element* element = toElement(node);
|
| @@ -525,6 +631,8 @@ static void setElementInfo(RefPtr<JSONObject>& highlightObject, Node* node)
|
| RenderBoxModelObject* modelObject = renderer->isBoxModelObject() ? toRenderBoxModelObject(renderer) : 0;
|
| 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->isBox() && shapeObject)
|
| + elementInfo->setObject("shapeOutsideInfo", shapeObject.release());
|
| highlightObject->setObject("elementInfo", elementInfo.release());
|
| }
|
|
|
| @@ -543,8 +651,10 @@ void InspectorOverlay::drawNodeHighlight()
|
| RefPtr<JSONObject> highlightObject = buildObjectForHighlight(highlight);
|
|
|
| Node* node = m_highlightNode.get();
|
| + RefPtr<TypeBuilder::DOM::ShapeOutsideInfo> shapeObject = buildObjectForShapeOutside(node);
|
| + RefPtr<JSONObject> shapeObjectJSON = shapeObject ? shapeObject->asObject() : nullptr;
|
| if (node->isElementNode() && !m_omitTooltip && m_nodeHighlightConfig.showInfo && node->renderer() && node->document().frame())
|
| - setElementInfo(highlightObject, node);
|
| + setElementInfo(highlightObject, shapeObjectJSON, node);
|
| evaluateInOverlay("drawNodeHighlight", highlightObject);
|
| }
|
|
|
|
|