OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2011 Google Inc. All rights reserved. | 2 * Copyright (C) 2011 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * | 7 * |
8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
57 #include "platform/graphics/GraphicsContextStateSaver.h" | 57 #include "platform/graphics/GraphicsContextStateSaver.h" |
58 #include "public/platform/Platform.h" | 58 #include "public/platform/Platform.h" |
59 #include "public/platform/WebData.h" | 59 #include "public/platform/WebData.h" |
60 #include "wtf/text/StringBuilder.h" | 60 #include "wtf/text/StringBuilder.h" |
61 #include <v8.h> | 61 #include <v8.h> |
62 | 62 |
63 namespace blink { | 63 namespace blink { |
64 | 64 |
65 namespace { | 65 namespace { |
66 | 66 |
67 struct PathApplyInfo { | 67 class PathBuilder { |
68 FrameView* view; | 68 WTF_MAKE_NONCOPYABLE(PathBuilder); |
69 TypeBuilder::Array<JSONValue>* array; | 69 public: |
70 RenderObject* renderer; | 70 PathBuilder() : m_path(TypeBuilder::Array<JSONValue>::create()) { } |
71 const ShapeOutsideInfo* shapeOutsideInfo; | 71 virtual ~PathBuilder() { } |
| 72 |
| 73 PassRefPtr<TypeBuilder::Array<JSONValue> > path() const { return m_path; } |
| 74 void appendPath(const Path& path) |
| 75 { |
| 76 path.apply(this, &PathBuilder::appendPathElement); |
| 77 } |
| 78 |
| 79 protected: |
| 80 virtual FloatPoint translatePoint(const FloatPoint& point) { return point; } |
| 81 |
| 82 private: |
| 83 static void appendPathElement(void* pathBuilder, const PathElement* pathElem
ent) |
| 84 { |
| 85 static_cast<PathBuilder*>(pathBuilder)->appendPathElement(pathElement); |
| 86 } |
| 87 |
| 88 void appendPathElement(const PathElement*); |
| 89 void appendPathCommandAndPoints(const char* command, const FloatPoint points
[], size_t length); |
| 90 |
| 91 RefPtr<TypeBuilder::Array<JSONValue> > m_path; |
| 92 }; |
| 93 |
| 94 class ShapePathBuilder : public PathBuilder { |
| 95 public: |
| 96 ShapePathBuilder(FrameView& view, RenderObject& renderer, const ShapeOutside
Info& shapeOutsideInfo) |
| 97 : m_view(view) |
| 98 , m_renderer(renderer) |
| 99 , m_shapeOutsideInfo(shapeOutsideInfo) { } |
| 100 |
| 101 static PassRefPtr<TypeBuilder::Array<JSONValue> > buildPath(FrameView& view,
RenderObject& renderer, const ShapeOutsideInfo& shapeOutsideInfo, const Path& p
ath) |
| 102 { |
| 103 ShapePathBuilder builder(view, renderer, shapeOutsideInfo); |
| 104 builder.appendPath(path); |
| 105 return builder.path(); |
| 106 } |
| 107 |
| 108 protected: |
| 109 virtual FloatPoint translatePoint(const FloatPoint& point) |
| 110 { |
| 111 FloatPoint rendererPoint = m_shapeOutsideInfo.shapeToRendererPoint(point
); |
| 112 return m_view.contentsToRootView(roundedIntPoint(m_renderer.localToAbsol
ute(rendererPoint))); |
| 113 } |
| 114 |
| 115 private: |
| 116 FrameView& m_view; |
| 117 RenderObject& m_renderer; |
| 118 const ShapeOutsideInfo& m_shapeOutsideInfo; |
72 }; | 119 }; |
73 | 120 |
74 class InspectorOverlayChromeClient FINAL: public EmptyChromeClient { | 121 class InspectorOverlayChromeClient FINAL: public EmptyChromeClient { |
75 public: | 122 public: |
76 InspectorOverlayChromeClient(ChromeClient& client, InspectorOverlay* overlay
) | 123 InspectorOverlayChromeClient(ChromeClient& client, InspectorOverlay* overlay
) |
77 : m_client(client) | 124 : m_client(client) |
78 , m_overlay(overlay) | 125 , m_overlay(overlay) |
79 { } | 126 { } |
80 | 127 |
81 virtual void setCursor(const Cursor& cursor) OVERRIDE | 128 virtual void setCursor(const Cursor& cursor) OVERRIDE |
(...skipping 14 matching lines...) Expand all Loading... |
96 virtual void invalidateContentsForSlowScroll(const IntRect&) OVERRIDE | 143 virtual void invalidateContentsForSlowScroll(const IntRect&) OVERRIDE |
97 { | 144 { |
98 m_overlay->invalidate(); | 145 m_overlay->invalidate(); |
99 } | 146 } |
100 | 147 |
101 private: | 148 private: |
102 ChromeClient& m_client; | 149 ChromeClient& m_client; |
103 InspectorOverlay* m_overlay; | 150 InspectorOverlay* m_overlay; |
104 }; | 151 }; |
105 | 152 |
106 Path quadToPath(const FloatQuad& quad) | 153 static Path quadToPath(const FloatQuad& quad) |
107 { | 154 { |
108 Path quadPath; | 155 Path quadPath; |
109 quadPath.moveTo(quad.p1()); | 156 quadPath.moveTo(quad.p1()); |
110 quadPath.addLineTo(quad.p2()); | 157 quadPath.addLineTo(quad.p2()); |
111 quadPath.addLineTo(quad.p3()); | 158 quadPath.addLineTo(quad.p3()); |
112 quadPath.addLineTo(quad.p4()); | 159 quadPath.addLineTo(quad.p4()); |
113 quadPath.closeSubpath(); | 160 quadPath.closeSubpath(); |
114 return quadPath; | 161 return quadPath; |
115 } | 162 } |
116 | 163 |
(...skipping 14 matching lines...) Expand all Loading... |
131 context->strokePath(quadPath); | 178 context->strokePath(quadPath); |
132 | 179 |
133 context->restore(); | 180 context->restore(); |
134 } | 181 } |
135 | 182 |
136 // Now do the fill | 183 // Now do the fill |
137 context->setFillColor(fillColor); | 184 context->setFillColor(fillColor); |
138 context->fillPath(quadPath); | 185 context->fillPath(quadPath); |
139 } | 186 } |
140 | 187 |
| 188 class Highlight { |
| 189 public: |
| 190 Highlight() |
| 191 : m_showRulers(false) |
| 192 , m_showExtensionLines(false) |
| 193 , m_highlightPaths(JSONArray::create()) |
| 194 { } |
| 195 |
| 196 void setDataFromConfig(const HighlightConfig& highlightConfig) |
| 197 { |
| 198 m_showRulers = highlightConfig.showRulers; |
| 199 m_showExtensionLines = highlightConfig.showExtensionLines; |
| 200 } |
| 201 |
| 202 void setElementInfo(PassRefPtr<JSONObject> elementInfo) |
| 203 { |
| 204 m_elementInfo = elementInfo; |
| 205 } |
| 206 |
| 207 void appendQuad(const FloatQuad& quad, const Color& fillColor, const Color&
outlineColor = Color::transparent) |
| 208 { |
| 209 Path path = quadToPath(quad); |
| 210 PathBuilder builder; |
| 211 builder.appendPath(path); |
| 212 appendPath(builder.path(), fillColor, outlineColor); |
| 213 } |
| 214 |
| 215 void appendPath(PassRefPtr<JSONArrayBase> path, const Color& fillColor, cons
t Color& outlineColor) |
| 216 { |
| 217 RefPtr<JSONObject> object = JSONObject::create(); |
| 218 object->setValue("path", path); |
| 219 object->setString("fillColor", fillColor.serialized()); |
| 220 if (outlineColor != Color::transparent) |
| 221 object->setString("outlineColor", outlineColor.serialized()); |
| 222 m_highlightPaths->pushObject(object.release()); |
| 223 } |
| 224 |
| 225 PassRefPtr<JSONObject> asJSONObject() const |
| 226 { |
| 227 RefPtr<JSONObject> object = JSONObject::create(); |
| 228 object->setArray("paths", m_highlightPaths); |
| 229 object->setBoolean("showRulers", m_showRulers); |
| 230 object->setBoolean("showExtensionLines", m_showExtensionLines); |
| 231 if (m_elementInfo) |
| 232 object->setObject("elementInfo", m_elementInfo); |
| 233 return object.release(); |
| 234 } |
| 235 |
| 236 private: |
| 237 bool m_showRulers; |
| 238 bool m_showExtensionLines; |
| 239 RefPtr<JSONObject> m_elementInfo; |
| 240 RefPtr<JSONArray> m_highlightPaths; |
| 241 }; |
| 242 |
141 static void contentsQuadToScreen(const FrameView* view, FloatQuad& quad) | 243 static void contentsQuadToScreen(const FrameView* view, FloatQuad& quad) |
142 { | 244 { |
143 quad.setP1(view->contentsToRootView(roundedIntPoint(quad.p1()))); | 245 quad.setP1(view->contentsToRootView(roundedIntPoint(quad.p1()))); |
144 quad.setP2(view->contentsToRootView(roundedIntPoint(quad.p2()))); | 246 quad.setP2(view->contentsToRootView(roundedIntPoint(quad.p2()))); |
145 quad.setP3(view->contentsToRootView(roundedIntPoint(quad.p3()))); | 247 quad.setP3(view->contentsToRootView(roundedIntPoint(quad.p3()))); |
146 quad.setP4(view->contentsToRootView(roundedIntPoint(quad.p4()))); | 248 quad.setP4(view->contentsToRootView(roundedIntPoint(quad.p4()))); |
147 } | 249 } |
148 | 250 |
149 static bool buildNodeQuads(Node* node, Vector<FloatQuad>& quads) | 251 static bool buildNodeQuads(RenderObject* renderer, FloatQuad* content, FloatQuad
* padding, FloatQuad* border, FloatQuad* margin) |
150 { | 252 { |
151 RenderObject* renderer = node->renderer(); | 253 FrameView* containingView = renderer->frameView(); |
152 LocalFrame* containingFrame = node->document().frame(); | 254 if (!containingView) |
153 | |
154 if (!renderer || !containingFrame) | |
155 return false; | 255 return false; |
156 | |
157 FrameView* containingView = containingFrame->view(); | |
158 | |
159 // RenderSVGRoot should be highlighted through the isBox() code path, all ot
her SVG elements should just dump their absoluteQuads(). | |
160 if (renderer->node() && renderer->node()->isSVGElement() && !renderer->isSVG
Root()) { | |
161 renderer->absoluteQuads(quads); | |
162 for (size_t i = 0; i < quads.size(); ++i) | |
163 contentsQuadToScreen(containingView, quads[i]); | |
164 return false; | |
165 } | |
166 | |
167 if (!renderer->isBox() && !renderer->isRenderInline()) | 256 if (!renderer->isBox() && !renderer->isRenderInline()) |
168 return false; | 257 return false; |
169 | 258 |
170 LayoutRect contentBox; | 259 LayoutRect contentBox; |
171 LayoutRect paddingBox; | 260 LayoutRect paddingBox; |
172 LayoutRect borderBox; | 261 LayoutRect borderBox; |
173 LayoutRect marginBox; | 262 LayoutRect marginBox; |
174 | 263 |
175 if (renderer->isBox()) { | 264 if (renderer->isBox()) { |
176 RenderBox* renderBox = toRenderBox(renderer); | 265 RenderBox* renderBox = toRenderBox(renderer); |
(...skipping 16 matching lines...) Expand all Loading... |
193 borderBox = renderInline->linesBoundingBox(); | 282 borderBox = renderInline->linesBoundingBox(); |
194 paddingBox = LayoutRect(borderBox.x() + renderInline->borderLeft(), bord
erBox.y() + renderInline->borderTop(), | 283 paddingBox = LayoutRect(borderBox.x() + renderInline->borderLeft(), bord
erBox.y() + renderInline->borderTop(), |
195 borderBox.width() - renderInline->borderLeft() - renderInline->borde
rRight(), borderBox.height() - renderInline->borderTop() - renderInline->borderB
ottom()); | 284 borderBox.width() - renderInline->borderLeft() - renderInline->borde
rRight(), borderBox.height() - renderInline->borderTop() - renderInline->borderB
ottom()); |
196 contentBox = LayoutRect(paddingBox.x() + renderInline->paddingLeft(), pa
ddingBox.y() + renderInline->paddingTop(), | 285 contentBox = LayoutRect(paddingBox.x() + renderInline->paddingLeft(), pa
ddingBox.y() + renderInline->paddingTop(), |
197 paddingBox.width() - renderInline->paddingLeft() - renderInline->pad
dingRight(), paddingBox.height() - renderInline->paddingTop() - renderInline->pa
ddingBottom()); | 286 paddingBox.width() - renderInline->paddingLeft() - renderInline->pad
dingRight(), paddingBox.height() - renderInline->paddingTop() - renderInline->pa
ddingBottom()); |
198 // Ignore marginTop and marginBottom for inlines. | 287 // Ignore marginTop and marginBottom for inlines. |
199 marginBox = LayoutRect(borderBox.x() - renderInline->marginLeft(), borde
rBox.y(), | 288 marginBox = LayoutRect(borderBox.x() - renderInline->marginLeft(), borde
rBox.y(), |
200 borderBox.width() + renderInline->marginWidth(), borderBox.height())
; | 289 borderBox.width() + renderInline->marginWidth(), borderBox.height())
; |
201 } | 290 } |
202 | 291 |
203 FloatQuad absContentQuad = renderer->localToAbsoluteQuad(FloatRect(contentBo
x)); | 292 *content = renderer->localToAbsoluteQuad(FloatRect(contentBox)); |
204 FloatQuad absPaddingQuad = renderer->localToAbsoluteQuad(FloatRect(paddingBo
x)); | 293 *padding = renderer->localToAbsoluteQuad(FloatRect(paddingBox)); |
205 FloatQuad absBorderQuad = renderer->localToAbsoluteQuad(FloatRect(borderBox)
); | 294 *border = renderer->localToAbsoluteQuad(FloatRect(borderBox)); |
206 FloatQuad absMarginQuad = renderer->localToAbsoluteQuad(FloatRect(marginBox)
); | 295 *margin = renderer->localToAbsoluteQuad(FloatRect(marginBox)); |
207 | 296 |
208 contentsQuadToScreen(containingView, absContentQuad); | 297 contentsQuadToScreen(containingView, *content); |
209 contentsQuadToScreen(containingView, absPaddingQuad); | 298 contentsQuadToScreen(containingView, *padding); |
210 contentsQuadToScreen(containingView, absBorderQuad); | 299 contentsQuadToScreen(containingView, *border); |
211 contentsQuadToScreen(containingView, absMarginQuad); | 300 contentsQuadToScreen(containingView, *margin); |
212 | |
213 quads.append(absMarginQuad); | |
214 quads.append(absBorderQuad); | |
215 quads.append(absPaddingQuad); | |
216 quads.append(absContentQuad); | |
217 | 301 |
218 return true; | 302 return true; |
219 } | 303 } |
220 | 304 |
221 static void buildNodeHighlight(Node* node, const HighlightConfig& highlightConfi
g, Highlight* highlight) | 305 static void buildNodeHighlight(Node& node, const HighlightConfig& highlightConfi
g, Highlight* highlight) |
222 { | 306 { |
223 RenderObject* renderer = node->renderer(); | 307 RenderObject* renderer = node.renderer(); |
224 LocalFrame* containingFrame = node->document().frame(); | 308 if (!renderer) |
225 | |
226 if (!renderer || !containingFrame) | |
227 return; | 309 return; |
228 | 310 |
229 highlight->setDataFromConfig(highlightConfig); | 311 highlight->setDataFromConfig(highlightConfig); |
230 | 312 |
231 // RenderSVGRoot should be highlighted through the isBox() code path, all ot
her SVG elements should just dump their absoluteQuads(). | 313 // RenderSVGRoot should be highlighted through the isBox() code path, all ot
her SVG elements should just dump their absoluteQuads(). |
232 if (renderer->node() && renderer->node()->isSVGElement() && !renderer->isSVG
Root()) | 314 if (renderer->node() && renderer->node()->isSVGElement() && !renderer->isSVG
Root()) { |
233 highlight->type = HighlightTypeRects; | 315 Vector<FloatQuad> quads; |
234 else if (renderer->isBox() || renderer->isRenderInline()) | 316 renderer->absoluteQuads(quads); |
235 highlight->type = HighlightTypeNode; | 317 for (size_t i = 0; i < quads.size(); ++i) |
236 buildNodeQuads(node, highlight->quads); | 318 highlight->appendQuad(quads[i], highlightConfig.content, highlightCo
nfig.contentOutline); |
237 } | 319 return; |
| 320 } |
238 | 321 |
239 static void buildQuadHighlight(Page* page, const FloatQuad& quad, const Highligh
tConfig& highlightConfig, Highlight *highlight) | 322 FloatQuad content, padding, border, margin; |
240 { | 323 if (!buildNodeQuads(renderer, &content, &padding, &border, &margin)) |
241 if (!page) | |
242 return; | 324 return; |
243 highlight->setDataFromConfig(highlightConfig); | 325 highlight->appendQuad(content, highlightConfig.content, highlightConfig.cont
entOutline); |
244 highlight->type = HighlightTypeRects; | 326 highlight->appendQuad(padding, highlightConfig.padding); |
245 highlight->quads.append(quad); | 327 highlight->appendQuad(border, highlightConfig.border); |
| 328 highlight->appendQuad(margin, highlightConfig.margin); |
246 } | 329 } |
247 | 330 |
248 } // anonymous namespace | 331 } // anonymous namespace |
249 | 332 |
250 InspectorOverlay::InspectorOverlay(Page* page, InspectorClient* client) | 333 InspectorOverlay::InspectorOverlay(Page* page, InspectorClient* client) |
251 : m_page(page) | 334 : m_page(page) |
252 , m_client(client) | 335 , m_client(client) |
253 , m_inspectModeEnabled(false) | 336 , m_inspectModeEnabled(false) |
254 , m_overlayHost(InspectorOverlayHost::create()) | 337 , m_overlayHost(InspectorOverlayHost::create()) |
255 , m_drawViewSize(false) | 338 , m_drawViewSize(false) |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
432 m_timer.stop(); | 515 m_timer.stop(); |
433 m_highlightNode.clear(); | 516 m_highlightNode.clear(); |
434 m_eventTargetNode.clear(); | 517 m_eventTargetNode.clear(); |
435 m_highlightQuad.clear(); | 518 m_highlightQuad.clear(); |
436 m_pausedInDebuggerMessage = String(); | 519 m_pausedInDebuggerMessage = String(); |
437 m_drawViewSize = false; | 520 m_drawViewSize = false; |
438 m_drawViewSizeWithGrid = false; | 521 m_drawViewSizeWithGrid = false; |
439 update(); | 522 update(); |
440 } | 523 } |
441 | 524 |
442 static PassRefPtr<JSONObject> buildObjectForPoint(const FloatPoint& point) | |
443 { | |
444 RefPtr<JSONObject> object = JSONObject::create(); | |
445 object->setNumber("x", point.x()); | |
446 object->setNumber("y", point.y()); | |
447 return object.release(); | |
448 } | |
449 | |
450 static PassRefPtr<JSONArray> buildArrayForQuad(const FloatQuad& quad) | |
451 { | |
452 RefPtr<JSONArray> array = JSONArray::create(); | |
453 array->pushObject(buildObjectForPoint(quad.p1())); | |
454 array->pushObject(buildObjectForPoint(quad.p2())); | |
455 array->pushObject(buildObjectForPoint(quad.p3())); | |
456 array->pushObject(buildObjectForPoint(quad.p4())); | |
457 return array.release(); | |
458 } | |
459 | |
460 static PassRefPtr<JSONObject> buildObjectForHighlight(const Highlight& highlight
) | |
461 { | |
462 RefPtr<JSONObject> object = JSONObject::create(); | |
463 RefPtr<JSONArray> array = JSONArray::create(); | |
464 for (size_t i = 0; i < highlight.quads.size(); ++i) | |
465 array->pushArray(buildArrayForQuad(highlight.quads[i])); | |
466 object->setArray("quads", array.release()); | |
467 object->setBoolean("showRulers", highlight.showRulers); | |
468 object->setBoolean("showExtensionLines", highlight.showExtensionLines); | |
469 object->setString("contentColor", highlight.contentColor.serialized()); | |
470 object->setString("contentOutlineColor", highlight.contentOutlineColor.seria
lized()); | |
471 object->setString("paddingColor", highlight.paddingColor.serialized()); | |
472 object->setString("borderColor", highlight.borderColor.serialized()); | |
473 object->setString("marginColor", highlight.marginColor.serialized()); | |
474 object->setString("eventTargetColor", highlight.eventTargetColor.serialized(
)); | |
475 return object.release(); | |
476 } | |
477 | |
478 static PassRefPtr<JSONObject> buildObjectForSize(const IntSize& size) | 525 static PassRefPtr<JSONObject> buildObjectForSize(const IntSize& size) |
479 { | 526 { |
480 RefPtr<JSONObject> result = JSONObject::create(); | 527 RefPtr<JSONObject> result = JSONObject::create(); |
481 result->setNumber("width", size.width()); | 528 result->setNumber("width", size.width()); |
482 result->setNumber("height", size.height()); | 529 result->setNumber("height", size.height()); |
483 return result.release(); | 530 return result.release(); |
484 } | 531 } |
485 | 532 |
486 // CSS shapes | 533 void PathBuilder::appendPathCommandAndPoints(const char* command, const FloatPoi
nt points[], size_t length) |
487 static void appendPathCommandAndPoints(PathApplyInfo* info, const String& comman
d, const FloatPoint points[], unsigned length) | |
488 { | 534 { |
489 FloatPoint point; | 535 m_path->addItem(JSONString::create(command)); |
490 info->array->addItem(JSONString::create(command)); | 536 for (size_t i = 0; i < length; i++) { |
491 for (unsigned i = 0; i < length; i++) { | 537 FloatPoint point = translatePoint(points[i]); |
492 point = info->shapeOutsideInfo->shapeToRendererPoint(points[i]); | 538 m_path->addItem(JSONBasicValue::create(point.x())); |
493 point = info->view->contentsToRootView(roundedIntPoint(info->renderer->l
ocalToAbsolute(point))); | 539 m_path->addItem(JSONBasicValue::create(point.y())); |
494 info->array->addItem(JSONBasicValue::create(point.x())); | |
495 info->array->addItem(JSONBasicValue::create(point.y())); | |
496 } | 540 } |
497 } | 541 } |
498 | 542 |
499 static void appendPathSegment(void* info, const PathElement* pathElement) | 543 void PathBuilder::appendPathElement(const PathElement* pathElement) |
500 { | 544 { |
501 PathApplyInfo* pathApplyInfo = static_cast<PathApplyInfo*>(info); | |
502 FloatPoint point; | |
503 switch (pathElement->type) { | 545 switch (pathElement->type) { |
504 // The points member will contain 1 value. | 546 // The points member will contain 1 value. |
505 case PathElementMoveToPoint: | 547 case PathElementMoveToPoint: |
506 appendPathCommandAndPoints(pathApplyInfo, "M", pathElement->points, 1); | 548 appendPathCommandAndPoints("M", pathElement->points, 1); |
507 break; | 549 break; |
508 // The points member will contain 1 value. | 550 // The points member will contain 1 value. |
509 case PathElementAddLineToPoint: | 551 case PathElementAddLineToPoint: |
510 appendPathCommandAndPoints(pathApplyInfo, "L", pathElement->points, 1); | 552 appendPathCommandAndPoints("L", pathElement->points, 1); |
511 break; | 553 break; |
512 // The points member will contain 3 values. | 554 // The points member will contain 3 values. |
513 case PathElementAddCurveToPoint: | 555 case PathElementAddCurveToPoint: |
514 appendPathCommandAndPoints(pathApplyInfo, "C", pathElement->points, 3); | 556 appendPathCommandAndPoints("C", pathElement->points, 3); |
515 break; | 557 break; |
516 // The points member will contain 2 values. | 558 // The points member will contain 2 values. |
517 case PathElementAddQuadCurveToPoint: | 559 case PathElementAddQuadCurveToPoint: |
518 appendPathCommandAndPoints(pathApplyInfo, "Q", pathElement->points, 2); | 560 appendPathCommandAndPoints("Q", pathElement->points, 2); |
519 break; | 561 break; |
520 // The points member will contain no values. | 562 // The points member will contain no values. |
521 case PathElementCloseSubpath: | 563 case PathElementCloseSubpath: |
522 appendPathCommandAndPoints(pathApplyInfo, "Z", 0, 0); | 564 appendPathCommandAndPoints("Z", 0, 0); |
523 break; | 565 break; |
524 } | 566 } |
525 } | 567 } |
526 | 568 |
527 static RefPtr<TypeBuilder::Array<double> > buildArrayForQuadTypeBuilder(const Fl
oatQuad& quad) | 569 static RefPtr<TypeBuilder::Array<double> > buildArrayForQuad(const FloatQuad& qu
ad) |
528 { | 570 { |
529 RefPtr<TypeBuilder::Array<double> > array = TypeBuilder::Array<double>::crea
te(); | 571 RefPtr<TypeBuilder::Array<double> > array = TypeBuilder::Array<double>::crea
te(); |
530 array->addItem(quad.p1().x()); | 572 array->addItem(quad.p1().x()); |
531 array->addItem(quad.p1().y()); | 573 array->addItem(quad.p1().y()); |
532 array->addItem(quad.p2().x()); | 574 array->addItem(quad.p2().x()); |
533 array->addItem(quad.p2().y()); | 575 array->addItem(quad.p2().y()); |
534 array->addItem(quad.p3().x()); | 576 array->addItem(quad.p3().x()); |
535 array->addItem(quad.p3().y()); | 577 array->addItem(quad.p3().y()); |
536 array->addItem(quad.p4().x()); | 578 array->addItem(quad.p4().x()); |
537 array->addItem(quad.p4().y()); | 579 array->addItem(quad.p4().y()); |
538 return array.release(); | 580 return array.release(); |
539 } | 581 } |
540 | 582 |
541 PassRefPtr<TypeBuilder::DOM::ShapeOutsideInfo> InspectorOverlay::buildObjectForS
hapeOutside(Node* node) | 583 static const ShapeOutsideInfo* shapeOutsideInfoForNode(Node* node, Shape::Displa
yPaths* paths, FloatQuad* bounds) |
542 { | 584 { |
543 RenderObject* renderer = node->renderer(); | 585 RenderObject* renderer = node->renderer(); |
544 if (!renderer || !renderer->isBox() || !toRenderBox(renderer)->shapeOutsideI
nfo()) | 586 if (!renderer || !renderer->isBox() || !toRenderBox(renderer)->shapeOutsideI
nfo()) |
545 return nullptr; | 587 return 0; |
546 | 588 |
547 LocalFrame* containingFrame = node->document().frame(); | 589 FrameView* containingView = node->document().view(); |
548 RenderBox* renderBox = toRenderBox(renderer); | 590 RenderBox* renderBox = toRenderBox(renderer); |
549 const ShapeOutsideInfo* shapeOutsideInfo = renderBox->shapeOutsideInfo(); | 591 const ShapeOutsideInfo* shapeOutsideInfo = renderBox->shapeOutsideInfo(); |
550 | 592 |
| 593 shapeOutsideInfo->computedShape().buildDisplayPaths(*paths); |
| 594 |
551 LayoutRect shapeBounds = shapeOutsideInfo->computedShapePhysicalBoundingBox(
); | 595 LayoutRect shapeBounds = shapeOutsideInfo->computedShapePhysicalBoundingBox(
); |
552 FloatQuad shapeQuad = renderBox->localToAbsoluteQuad(FloatRect(shapeBounds))
; | 596 *bounds = renderBox->localToAbsoluteQuad(FloatRect(shapeBounds)); |
553 FrameView* containingView = containingFrame->view(); | 597 contentsQuadToScreen(containingView, *bounds); |
554 contentsQuadToScreen(containingView, shapeQuad); | |
555 | 598 |
556 Shape::DisplayPaths paths; | 599 return shapeOutsideInfo; |
557 shapeOutsideInfo->computedShape().buildDisplayPaths(paths); | |
558 RefPtr<TypeBuilder::Array<JSONValue> > shapePath = TypeBuilder::Array<JSONVa
lue>::create(); | |
559 RefPtr<TypeBuilder::Array<JSONValue> > marginShapePath = TypeBuilder::Array<
JSONValue>::create(); | |
560 | |
561 if (paths.shape.length()) { | |
562 PathApplyInfo info; | |
563 info.view = containingView; | |
564 info.array = shapePath.get(); | |
565 info.renderer = renderBox; | |
566 info.shapeOutsideInfo = shapeOutsideInfo; | |
567 paths.shape.apply(&info, &appendPathSegment); | |
568 | |
569 if (paths.marginShape.length()) { | |
570 info.array = marginShapePath.get(); | |
571 paths.marginShape.apply(&info, &appendPathSegment); | |
572 } | |
573 } | |
574 RefPtr<TypeBuilder::DOM::ShapeOutsideInfo> shapeTypeBuilder = TypeBuilder::D
OM::ShapeOutsideInfo::create() | |
575 .setBounds(buildArrayForQuadTypeBuilder(shapeQuad)) | |
576 .setShape(shapePath) | |
577 .setMarginShape(marginShapePath); | |
578 | |
579 return shapeTypeBuilder.release(); | |
580 } | 600 } |
581 | 601 |
582 static void setElementInfo(RefPtr<JSONObject>& highlightObject, RefPtr<JSONObjec
t>& shapeObject, Node* node) | 602 static void appendPathsForShapeOutside(Highlight& highlight, const HighlightConf
ig& config, Node* node) |
| 603 { |
| 604 Shape::DisplayPaths paths; |
| 605 FloatQuad boundsQuad; |
| 606 |
| 607 const ShapeOutsideInfo* shapeOutsideInfo = shapeOutsideInfoForNode(node, &pa
ths, &boundsQuad); |
| 608 if (!shapeOutsideInfo) |
| 609 return; |
| 610 |
| 611 if (!paths.shape.length()) { |
| 612 highlight.appendQuad(boundsQuad, config.shape); |
| 613 return; |
| 614 } |
| 615 |
| 616 highlight.appendPath(ShapePathBuilder::buildPath(*node->document().view(), *
node->renderer(), *shapeOutsideInfo, paths.shape), config.shape, Color::transpar
ent); |
| 617 if (paths.marginShape.length()) |
| 618 highlight.appendPath(ShapePathBuilder::buildPath(*node->document().view(
), *node->renderer(), *shapeOutsideInfo, paths.marginShape), config.shapeMargin,
Color::transparent); |
| 619 } |
| 620 |
| 621 PassRefPtr<JSONObject> buildElementInfo(Element* element) |
583 { | 622 { |
584 RefPtr<JSONObject> elementInfo = JSONObject::create(); | 623 RefPtr<JSONObject> elementInfo = JSONObject::create(); |
585 Element* element = toElement(node); | |
586 Element* realElement = element; | 624 Element* realElement = element; |
587 PseudoElement* pseudoElement = 0; | 625 PseudoElement* pseudoElement = 0; |
588 if (element->isPseudoElement()) { | 626 if (element->isPseudoElement()) { |
589 pseudoElement = toPseudoElement(element); | 627 pseudoElement = toPseudoElement(element); |
590 realElement = element->parentOrShadowHostElement(); | 628 realElement = element->parentOrShadowHostElement(); |
591 } | 629 } |
592 bool isXHTML = realElement->document().isXHTMLDocument(); | 630 bool isXHTML = realElement->document().isXHTMLDocument(); |
593 elementInfo->setString("tagName", isXHTML ? realElement->nodeName() : realEl
ement->nodeName().lower()); | 631 elementInfo->setString("tagName", isXHTML ? realElement->nodeName() : realEl
ement->nodeName().lower()); |
594 elementInfo->setString("idValue", realElement->getIdAttribute()); | 632 elementInfo->setString("idValue", realElement->getIdAttribute()); |
595 StringBuilder classNames; | 633 StringBuilder classNames; |
(...skipping 11 matching lines...) Expand all Loading... |
607 } | 645 } |
608 if (pseudoElement) { | 646 if (pseudoElement) { |
609 if (pseudoElement->pseudoId() == BEFORE) | 647 if (pseudoElement->pseudoId() == BEFORE) |
610 classNames.append("::before"); | 648 classNames.append("::before"); |
611 else if (pseudoElement->pseudoId() == AFTER) | 649 else if (pseudoElement->pseudoId() == AFTER) |
612 classNames.append("::after"); | 650 classNames.append("::after"); |
613 } | 651 } |
614 if (!classNames.isEmpty()) | 652 if (!classNames.isEmpty()) |
615 elementInfo->setString("className", classNames.toString()); | 653 elementInfo->setString("className", classNames.toString()); |
616 | 654 |
617 RenderObject* renderer = node->renderer(); | 655 RenderObject* renderer = element->renderer(); |
618 LocalFrame* containingFrame = node->document().frame(); | 656 FrameView* containingView = element->document().view(); |
619 FrameView* containingView = containingFrame->view(); | 657 if (!renderer || !containingView) |
| 658 return elementInfo; |
| 659 |
620 IntRect boundingBox = pixelSnappedIntRect(containingView->contentsToRootView
(renderer->absoluteBoundingBoxRect())); | 660 IntRect boundingBox = pixelSnappedIntRect(containingView->contentsToRootView
(renderer->absoluteBoundingBoxRect())); |
621 RenderBoxModelObject* modelObject = renderer->isBoxModelObject() ? toRenderB
oxModelObject(renderer) : 0; | 661 RenderBoxModelObject* modelObject = renderer->isBoxModelObject() ? toRenderB
oxModelObject(renderer) : 0; |
622 elementInfo->setString("nodeWidth", String::number(modelObject ? adjustForAb
soluteZoom(modelObject->pixelSnappedOffsetWidth(), modelObject) : boundingBox.wi
dth())); | 662 elementInfo->setString("nodeWidth", String::number(modelObject ? adjustForAb
soluteZoom(modelObject->pixelSnappedOffsetWidth(), modelObject) : boundingBox.wi
dth())); |
623 elementInfo->setString("nodeHeight", String::number(modelObject ? adjustForA
bsoluteZoom(modelObject->pixelSnappedOffsetHeight(), modelObject) : boundingBox.
height())); | 663 elementInfo->setString("nodeHeight", String::number(modelObject ? adjustForA
bsoluteZoom(modelObject->pixelSnappedOffsetHeight(), modelObject) : boundingBox.
height())); |
624 if (renderer->isBox() && shapeObject) | 664 |
625 elementInfo->setObject("shapeOutsideInfo", shapeObject.release()); | 665 return elementInfo; |
626 highlightObject->setObject("elementInfo", elementInfo.release()); | |
627 } | 666 } |
628 | 667 |
629 void InspectorOverlay::drawNodeHighlight() | 668 void InspectorOverlay::drawNodeHighlight() |
630 { | 669 { |
631 if (!m_highlightNode) | 670 if (!m_highlightNode) |
632 return; | 671 return; |
633 | 672 |
634 Highlight highlight; | 673 Highlight highlight; |
635 buildNodeHighlight(m_highlightNode.get(), m_nodeHighlightConfig, &highlight)
; | 674 appendPathsForShapeOutside(highlight, m_nodeHighlightConfig, m_highlightNode
.get()); |
636 if (m_eventTargetNode) { | 675 buildNodeHighlight(*m_highlightNode, m_nodeHighlightConfig, &highlight); |
637 Highlight eventTargetHighlight; | 676 |
638 buildNodeHighlight(m_eventTargetNode.get(), m_nodeHighlightConfig, &even
tTargetHighlight); | 677 if (m_eventTargetNode && m_eventTargetNode->renderer()) { |
639 highlight.quads.append(eventTargetHighlight.quads[1]); // Add border fro
m eventTargetNode to highlight. | 678 FloatQuad border, unused; |
| 679 if (buildNodeQuads(m_eventTargetNode->renderer(), &unused, &unused, &bor
der, &unused)) |
| 680 highlight.appendQuad(border, m_nodeHighlightConfig.eventTarget); |
640 } | 681 } |
641 RefPtr<JSONObject> highlightObject = buildObjectForHighlight(highlight); | |
642 | 682 |
643 Node* node = m_highlightNode.get(); | 683 if (m_highlightNode->isElementNode() && !m_omitTooltip && m_nodeHighlightCon
fig.showInfo && m_highlightNode->renderer() && m_highlightNode->document().frame
()) |
644 RefPtr<TypeBuilder::DOM::ShapeOutsideInfo> shapeObject = buildObjectForShape
Outside(node); | 684 highlight.setElementInfo(buildElementInfo(toElement(m_highlightNode.get(
)))); |
645 RefPtr<JSONObject> shapeObjectJSON = shapeObject ? shapeObject->asObject() :
nullptr; | 685 |
646 if (node->isElementNode() && !m_omitTooltip && m_nodeHighlightConfig.showInf
o && node->renderer() && node->document().frame()) | 686 evaluateInOverlay("drawHighlight", highlight.asJSONObject()); |
647 setElementInfo(highlightObject, shapeObjectJSON, node); | |
648 evaluateInOverlay("drawNodeHighlight", highlightObject); | |
649 } | 687 } |
650 | 688 |
651 void InspectorOverlay::drawQuadHighlight() | 689 void InspectorOverlay::drawQuadHighlight() |
652 { | 690 { |
653 if (!m_highlightQuad) | 691 if (!m_highlightQuad) |
654 return; | 692 return; |
655 | 693 |
656 Highlight highlight; | 694 Highlight highlight; |
657 buildQuadHighlight(m_page, *m_highlightQuad, m_quadHighlightConfig, &highlig
ht); | 695 highlight.appendQuad(*m_highlightQuad, m_quadHighlightConfig.content, m_quad
HighlightConfig.contentOutline); |
658 evaluateInOverlay("drawQuadHighlight", buildObjectForHighlight(highlight)); | 696 evaluateInOverlay("drawHighlight", highlight.asJSONObject()); |
659 } | 697 } |
660 | 698 |
661 void InspectorOverlay::drawPausedInDebuggerMessage() | 699 void InspectorOverlay::drawPausedInDebuggerMessage() |
662 { | 700 { |
663 if (!m_pausedInDebuggerMessage.isNull()) | 701 if (!m_pausedInDebuggerMessage.isNull()) |
664 evaluateInOverlay("drawPausedInDebuggerMessage", m_pausedInDebuggerMessa
ge); | 702 evaluateInOverlay("drawPausedInDebuggerMessage", m_pausedInDebuggerMessa
ge); |
665 } | 703 } |
666 | 704 |
667 void InspectorOverlay::drawViewSize() | 705 void InspectorOverlay::drawViewSize() |
668 { | 706 { |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
762 command->pushValue(argument); | 800 command->pushValue(argument); |
763 toLocalFrame(overlayPage()->mainFrame())->script().executeScriptInMainWorld(
"dispatch(" + command->toJSONString() + ")", ScriptController::ExecuteScriptWhen
ScriptsDisabled); | 801 toLocalFrame(overlayPage()->mainFrame())->script().executeScriptInMainWorld(
"dispatch(" + command->toJSONString() + ")", ScriptController::ExecuteScriptWhen
ScriptsDisabled); |
764 } | 802 } |
765 | 803 |
766 void InspectorOverlay::onTimer(Timer<InspectorOverlay>*) | 804 void InspectorOverlay::onTimer(Timer<InspectorOverlay>*) |
767 { | 805 { |
768 m_drawViewSize = false; | 806 m_drawViewSize = false; |
769 update(); | 807 update(); |
770 } | 808 } |
771 | 809 |
772 bool InspectorOverlay::getBoxModel(Node* node, Vector<FloatQuad>* quads) | 810 bool InspectorOverlay::getBoxModel(Node* node, RefPtr<TypeBuilder::DOM::BoxModel
>& model) |
773 { | 811 { |
774 return buildNodeQuads(node, *quads); | 812 RenderObject* renderer = node->renderer(); |
| 813 FrameView* view = node->document().view(); |
| 814 if (!renderer || !view) |
| 815 return false; |
| 816 |
| 817 FloatQuad content, padding, border, margin; |
| 818 if (!buildNodeQuads(node->renderer(), &content, &padding, &border, &margin)) |
| 819 return false; |
| 820 |
| 821 IntRect boundingBox = pixelSnappedIntRect(view->contentsToRootView(renderer-
>absoluteBoundingBoxRect())); |
| 822 RenderBoxModelObject* modelObject = renderer->isBoxModelObject() ? toRenderB
oxModelObject(renderer) : 0; |
| 823 |
| 824 model = TypeBuilder::DOM::BoxModel::create() |
| 825 .setContent(buildArrayForQuad(content)) |
| 826 .setPadding(buildArrayForQuad(padding)) |
| 827 .setBorder(buildArrayForQuad(border)) |
| 828 .setMargin(buildArrayForQuad(margin)) |
| 829 .setWidth(modelObject ? adjustForAbsoluteZoom(modelObject->pixelSnappedO
ffsetWidth(), modelObject) : boundingBox.width()) |
| 830 .setHeight(modelObject ? adjustForAbsoluteZoom(modelObject->pixelSnapped
OffsetHeight(), modelObject) : boundingBox.height()); |
| 831 |
| 832 Shape::DisplayPaths paths; |
| 833 FloatQuad boundsQuad; |
| 834 if (const ShapeOutsideInfo* shapeOutsideInfo = shapeOutsideInfoForNode(node,
&paths, &boundsQuad)) { |
| 835 RefPtr<TypeBuilder::DOM::ShapeOutsideInfo> shapeTypeBuilder = TypeBuilde
r::DOM::ShapeOutsideInfo::create() |
| 836 .setBounds(buildArrayForQuad(boundsQuad)) |
| 837 .setShape(ShapePathBuilder::buildPath(*view, *renderer, *shapeOutsid
eInfo, paths.shape)) |
| 838 .setMarginShape(ShapePathBuilder::buildPath(*view, *renderer, *shape
OutsideInfo, paths.marginShape)); |
| 839 model->setShapeOutside(shapeTypeBuilder); |
| 840 } |
| 841 |
| 842 return true; |
775 } | 843 } |
776 | 844 |
777 void InspectorOverlay::freePage() | 845 void InspectorOverlay::freePage() |
778 { | 846 { |
779 if (m_overlayPage) { | 847 if (m_overlayPage) { |
780 m_overlayPage->willBeDestroyed(); | 848 m_overlayPage->willBeDestroyed(); |
781 m_overlayPage.clear(); | 849 m_overlayPage.clear(); |
782 } | 850 } |
783 m_overlayChromeClient.clear(); | 851 m_overlayChromeClient.clear(); |
784 m_timer.stop(); | 852 m_timer.stop(); |
785 | 853 |
786 // This will clear internal structures and issue update to the client. Safe
to call last. | 854 // This will clear internal structures and issue update to the client. Safe
to call last. |
787 hideHighlight(); | 855 hideHighlight(); |
788 } | 856 } |
789 | 857 |
790 void InspectorOverlay::startedRecordingProfile() | 858 void InspectorOverlay::startedRecordingProfile() |
791 { | 859 { |
792 if (!m_activeProfilerCount++) | 860 if (!m_activeProfilerCount++) |
793 freePage(); | 861 freePage(); |
794 } | 862 } |
795 | 863 |
796 } // namespace blink | 864 } // namespace blink |
OLD | NEW |