1 /*
2 * Copyright (C) 2011 Google Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
14 * its contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #include "third_party/blink/renderer/core/inspector/inspector_overlay_agent.h"
30
31 #include <algorithm>
32 #include <memory>
33 #include <utility>
34
35 #include "base/auto_reset.h"
36 #include "build/build_config.h"
37 #include "cc/layers/picture_layer.h"
38 #include "third_party/blink/public/platform/platform.h"
39 #include "third_party/blink/public/platform/task_type.h"
40 #include "third_party/blink/public/platform/web_data.h"
41 #include "third_party/blink/public/resources/grit/inspector_overlay_resources_map.h"
42 #include "third_party/blink/public/web/web_widget_client.h"
43 #include "third_party/blink/renderer/bindings/core/v8/script_source_code.h"
44 #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
45 #include "third_party/blink/renderer/bindings/core/v8/v8_inspector_overlay_host.h"
46 #include "third_party/blink/renderer/core/display_lock/display_lock_utilities.h"
47 #include "third_party/blink/renderer/core/dom/dom_node_ids.h"
48 #include "third_party/blink/renderer/core/dom/node.h"
49 #include "third_party/blink/renderer/core/dom/static_node_list.h"
50 #include "third_party/blink/renderer/core/events/web_input_event_conversion.h"
51 #include "third_party/blink/renderer/core/exported/web_view_impl.h"
52 #include "third_party/blink/renderer/core/frame/frame_overlay.h"
53 #include "third_party/blink/renderer/core/frame/local_frame.h"
54 #include "third_party/blink/renderer/core/frame/local_frame_client.h"
55 #include "third_party/blink/renderer/core/frame/local_frame_view.h"
56 #include "third_party/blink/renderer/core/frame/root_frame_viewport.h"
57 #include "third_party/blink/renderer/core/frame/settings.h"
58 #include "third_party/blink/renderer/core/frame/visual_viewport.h"
59 #include "third_party/blink/renderer/core/frame/web_frame_widget_base.h"
60 #include "third_party/blink/renderer/core/frame/web_local_frame_impl.h"
61 #include "third_party/blink/renderer/core/html/html_frame_owner_element.h"
62 #include "third_party/blink/renderer/core/input/event_handler.h"
63 #include "third_party/blink/renderer/core/inspector/identifiers_factory.h"
64 #include "third_party/blink/renderer/core/inspector/inspect_tools.h"
65 #include "third_party/blink/renderer/core/inspector/inspected_frames.h"
66 #include "third_party/blink/renderer/core/inspector/inspector_css_agent.h"
67 #include "third_party/blink/renderer/core/inspector/inspector_dom_agent.h"
68 #include "third_party/blink/renderer/core/inspector/inspector_overlay_host.h"
69 #include "third_party/blink/renderer/core/layout/layout_view.h"
70 #include "third_party/blink/renderer/core/loader/empty_clients.h"
71 #include "third_party/blink/renderer/core/loader/frame_load_request.h"
72 #include "third_party/blink/renderer/core/page/chrome_client.h"
73 #include "third_party/blink/renderer/core/page/page.h"
74 #include "third_party/blink/renderer/core/script/classic_script.h"
75 #include "third_party/blink/renderer/platform/bindings/script_forbidden_scope.h"
76 #include "third_party/blink/renderer/platform/data_resource_helper.h"
77 #include "third_party/blink/renderer/platform/graphics/color.h"
78 #include "third_party/blink/renderer/platform/graphics/graphics_context.h"
79 #include "third_party/blink/renderer/platform/graphics/paint/cull_rect.h"
80 #include "third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h"
81 #include "third_party/blink/renderer/platform/graphics/paint/foreign_layer_display_item.h"
82 #include "third_party/blink/renderer/platform/graphics/paint/paint_record_builder.h"
83 #include "third_party/blink/renderer/platform/heap/heap.h"
84 #include "third_party/blink/renderer/platform/keyboard_codes.h"
85 #include "third_party/inspector_protocol/crdtp/json.h"
86 #include "v8/include/v8.h"
87
88 using crdtp::SpanFrom;
89 using crdtp::json::ConvertCBORToJSON;
90
91 namespace blink {
92
93 using protocol::Maybe;
94 using protocol::Response;
95
96 namespace {
97
ParseQuad(std::unique_ptr<protocol::Array<double>> quad_array,FloatQuad * quad)98 bool ParseQuad(std::unique_ptr<protocol::Array<double>> quad_array,
99 FloatQuad* quad) {
100 const size_t kCoordinatesInQuad = 8;
101 if (!quad_array || quad_array->size() != kCoordinatesInQuad)
102 return false;
103 quad->SetP1(FloatPoint((*quad_array)[0], (*quad_array)[1]));
104 quad->SetP2(FloatPoint((*quad_array)[2], (*quad_array)[3]));
105 quad->SetP3(FloatPoint((*quad_array)[4], (*quad_array)[5]));
106 quad->SetP4(FloatPoint((*quad_array)[6], (*quad_array)[7]));
107 return true;
108 }
109
110 } // namespace
111
112 // OverlayNames ----------------------------------------------------------------
113 const char* OverlayNames::OVERLAY_HIGHLIGHT = "highlight";
114 const char* OverlayNames::OVERLAY_HIGHLIGHT_GRID = "highlightGrid";
115 const char* OverlayNames::OVERLAY_SOURCE_ORDER = "sourceOrder";
116 const char* OverlayNames::OVERLAY_DISTANCES = "distances";
117 const char* OverlayNames::OVERLAY_VIEWPORT_SIZE = "viewportSize";
118 const char* OverlayNames::OVERLAY_SCREENSHOT = "screenshot";
119 const char* OverlayNames::OVERLAY_PAUSED = "paused";
120
121 // InspectTool -----------------------------------------------------------------
HandleInputEvent(LocalFrameView * frame_view,const WebInputEvent & input_event,bool * swallow_next_mouse_up)122 bool InspectTool::HandleInputEvent(LocalFrameView* frame_view,
123 const WebInputEvent& input_event,
124 bool* swallow_next_mouse_up) {
125 if (input_event.GetType() == WebInputEvent::Type::kGestureTap) {
126 // We only have a use for gesture tap.
127 WebGestureEvent transformed_event = TransformWebGestureEvent(
128 frame_view, static_cast<const WebGestureEvent&>(input_event));
129 return HandleGestureTapEvent(transformed_event);
130 }
131
132 if (WebInputEvent::IsMouseEventType(input_event.GetType())) {
133 WebMouseEvent transformed_event = TransformWebMouseEvent(
134 frame_view, static_cast<const WebMouseEvent&>(input_event));
135 return HandleMouseEvent(transformed_event, swallow_next_mouse_up);
136 }
137
138 if (WebInputEvent::IsPointerEventType(input_event.GetType())) {
139 WebPointerEvent transformed_event = TransformWebPointerEvent(
140 frame_view, static_cast<const WebPointerEvent&>(input_event));
141 return HandlePointerEvent(transformed_event);
142 }
143
144 if (WebInputEvent::IsKeyboardEventType(input_event.GetType())) {
145 return HandleKeyboardEvent(
146 static_cast<const WebKeyboardEvent&>(input_event));
147 }
148
149 return false;
150 }
151
HandleMouseEvent(const WebMouseEvent & mouse_event,bool * swallow_next_mouse_up)152 bool InspectTool::HandleMouseEvent(const WebMouseEvent& mouse_event,
153 bool* swallow_next_mouse_up) {
154 if (mouse_event.GetType() == WebInputEvent::Type::kMouseMove)
155 return HandleMouseMove(mouse_event);
156
157 if (mouse_event.GetType() == WebInputEvent::Type::kMouseDown)
158 return HandleMouseDown(mouse_event, swallow_next_mouse_up);
159
160 if (mouse_event.GetType() == WebInputEvent::Type::kMouseUp)
161 return HandleMouseUp(mouse_event);
162
163 return false;
164 }
165
HandleMouseDown(const WebMouseEvent &,bool * swallow_next_mouse_up)166 bool InspectTool::HandleMouseDown(const WebMouseEvent&,
167 bool* swallow_next_mouse_up) {
168 return false;
169 }
170
HandleMouseUp(const WebMouseEvent &)171 bool InspectTool::HandleMouseUp(const WebMouseEvent&) {
172 return false;
173 }
174
HandleMouseMove(const WebMouseEvent &)175 bool InspectTool::HandleMouseMove(const WebMouseEvent&) {
176 return false;
177 }
178
HandleGestureTapEvent(const WebGestureEvent &)179 bool InspectTool::HandleGestureTapEvent(const WebGestureEvent&) {
180 return false;
181 }
182
HandlePointerEvent(const WebPointerEvent &)183 bool InspectTool::HandlePointerEvent(const WebPointerEvent&) {
184 return false;
185 }
186
HandleKeyboardEvent(const WebKeyboardEvent &)187 bool InspectTool::HandleKeyboardEvent(const WebKeyboardEvent&) {
188 return false;
189 }
190
ForwardEventsToOverlay()191 bool InspectTool::ForwardEventsToOverlay() {
192 return true;
193 }
194
SupportsPersistentOverlays()195 bool InspectTool::SupportsPersistentOverlays() {
196 return false;
197 }
198
HideOnMouseMove()199 bool InspectTool::HideOnMouseMove() {
200 return false;
201 }
202
HideOnHideHighlight()203 bool InspectTool::HideOnHideHighlight() {
204 return false;
205 }
206
Trace(Visitor * visitor) const207 void InspectTool::Trace(Visitor* visitor) const {
208 visitor->Trace(overlay_);
209 }
210
211 // Hinge -----------------------------------------------------------------------
212
Hinge(FloatQuad quad,Color content_color,Color outline_color,InspectorOverlayAgent * overlay)213 Hinge::Hinge(FloatQuad quad,
214 Color content_color,
215 Color outline_color,
216 InspectorOverlayAgent* overlay)
217 : quad_(quad),
218 content_color_(content_color),
219 outline_color_(outline_color),
220 overlay_(overlay) {}
221
GetOverlayName()222 String Hinge::GetOverlayName() {
223 // TODO (soxia): In the future, we should make the hinge working properly
224 // with tools using different resources.
225 return OverlayNames::OVERLAY_HIGHLIGHT;
226 }
227
Trace(Visitor * visitor) const228 void Hinge::Trace(Visitor* visitor) const {
229 visitor->Trace(overlay_);
230 }
231
Draw(float scale)232 void Hinge::Draw(float scale) {
233 // scaling is applied at the drawHighlight code.
234 InspectorHighlight highlight(1.f);
235 highlight.AppendQuad(quad_, content_color_, outline_color_);
236 overlay_->EvaluateInOverlay("drawHighlight", highlight.AsProtocolValue());
237 }
238
239 // InspectorOverlayAgent -------------------------------------------------------
240
241 class InspectorOverlayAgent::InspectorPageOverlayDelegate final
242 : public FrameOverlay::Delegate,
243 public cc::ContentLayerClient {
244 public:
InspectorPageOverlayDelegate(InspectorOverlayAgent & overlay)245 explicit InspectorPageOverlayDelegate(InspectorOverlayAgent& overlay)
246 : overlay_(&overlay) {
247 if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
248 layer_ = cc::PictureLayer::Create(this);
249 layer_->SetIsDrawable(true);
250 layer_->SetHitTestable(false);
251 }
252 }
~InspectorPageOverlayDelegate()253 ~InspectorPageOverlayDelegate() override {
254 if (layer_)
255 layer_->ClearClient();
256 }
257
PaintFrameOverlay(const FrameOverlay & frame_overlay,GraphicsContext & graphics_context,const IntSize & size) const258 void PaintFrameOverlay(const FrameOverlay& frame_overlay,
259 GraphicsContext& graphics_context,
260 const IntSize& size) const override {
261 if (!overlay_->IsVisible())
262 return;
263
264 overlay_->PaintOverlayPage();
265
266 if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
267 layer_->SetBounds(gfx::Size(size));
268 DEFINE_STATIC_LOCAL(LiteralDebugNameClient, debug_name_client,
269 ("InspectorOverlay"));
270 RecordForeignLayer(graphics_context, debug_name_client,
271 DisplayItem::kForeignLayerDevToolsOverlay, layer_,
272 IntPoint(), &PropertyTreeState::Root());
273 return;
274 }
275
276 frame_overlay.Invalidate();
277 DrawingRecorder recorder(graphics_context, frame_overlay,
278 DisplayItem::kFrameOverlay,
279 IntRect(IntPoint(), size));
280 // The overlay frame is has a standalone paint property tree. Paint it in
281 // its root space into a paint record, then draw the record into the proper
282 // target space in the overlaid frame.
283 PaintRecordBuilder paint_record_builder(nullptr, &graphics_context);
284 overlay_->OverlayMainFrame()->View()->PaintOutsideOfLifecycle(
285 paint_record_builder.Context(), kGlobalPaintNormalPhase);
286 graphics_context.DrawRecord(paint_record_builder.EndRecording());
287 }
288
Invalidate()289 void Invalidate() override {
290 if (layer_)
291 layer_->SetNeedsDisplay();
292 }
293
GetLayer() const294 const cc::Layer* GetLayer() const { return layer_.get(); }
295
296 private:
297 // cc::ContentLayerClient implementation
PaintableRegion()298 gfx::Rect PaintableRegion() override { return gfx::Rect(layer_->bounds()); }
FillsBoundsCompletely() const299 bool FillsBoundsCompletely() const override { return false; }
300
PaintContentsToDisplayList()301 scoped_refptr<cc::DisplayItemList> PaintContentsToDisplayList() override {
302 auto display_list = base::MakeRefCounted<cc::DisplayItemList>();
303 display_list->StartPaint();
304 display_list->push<cc::DrawRecordOp>(
305 overlay_->OverlayMainFrame()->View()->GetPaintRecord());
306 display_list->EndPaintOfUnpaired(PaintableRegion());
307 display_list->Finalize();
308 return display_list;
309 }
310
311 Persistent<InspectorOverlayAgent> overlay_;
312 // For CompositeAfterPaint.
313 scoped_refptr<cc::PictureLayer> layer_;
314 };
315
316 class InspectorOverlayAgent::InspectorOverlayChromeClient final
317 : public EmptyChromeClient {
318 public:
InspectorOverlayChromeClient(ChromeClient & client,InspectorOverlayAgent & overlay)319 InspectorOverlayChromeClient(ChromeClient& client,
320 InspectorOverlayAgent& overlay)
321 : client_(&client), overlay_(&overlay) {}
322
Trace(Visitor * visitor) const323 void Trace(Visitor* visitor) const override {
324 visitor->Trace(client_);
325 visitor->Trace(overlay_);
326 EmptyChromeClient::Trace(visitor);
327 }
328
SetCursor(const ui::Cursor & cursor,LocalFrame * local_root)329 void SetCursor(const ui::Cursor& cursor, LocalFrame* local_root) override {
330 client_->SetCursorOverridden(false);
331 client_->SetCursor(cursor, overlay_->GetFrame());
332 client_->SetCursorOverridden(true);
333 }
334
SetToolTip(LocalFrame & frame,const String & tooltip,TextDirection direction)335 void SetToolTip(LocalFrame& frame,
336 const String& tooltip,
337 TextDirection direction) override {
338 DCHECK_EQ(&frame, overlay_->OverlayMainFrame());
339 client_->SetToolTip(*overlay_->GetFrame(), tooltip, direction);
340 }
341
342 private:
343 Member<ChromeClient> client_;
344 Member<InspectorOverlayAgent> overlay_;
345 };
346
InspectorOverlayAgent(WebLocalFrameImpl * frame_impl,InspectedFrames * inspected_frames,v8_inspector::V8InspectorSession * v8_session,InspectorDOMAgent * dom_agent)347 InspectorOverlayAgent::InspectorOverlayAgent(
348 WebLocalFrameImpl* frame_impl,
349 InspectedFrames* inspected_frames,
350 v8_inspector::V8InspectorSession* v8_session,
351 InspectorDOMAgent* dom_agent)
352 : frame_impl_(frame_impl),
353 inspected_frames_(inspected_frames),
354 resize_timer_active_(false),
355 resize_timer_(
356 frame_impl->GetFrame()->GetTaskRunner(TaskType::kInternalInspector),
357 this,
358 &InspectorOverlayAgent::OnResizeTimer),
359 disposed_(false),
360 v8_session_(v8_session),
361 dom_agent_(dom_agent),
362 swallow_next_mouse_up_(false),
363 backend_node_id_to_inspect_(0),
364 enabled_(&agent_state_, false),
365 show_ad_highlights_(&agent_state_, false),
366 show_debug_borders_(&agent_state_, false),
367 show_fps_counter_(&agent_state_, false),
368 show_paint_rects_(&agent_state_, false),
369 show_layout_shift_regions_(&agent_state_, false),
370 show_scroll_bottleneck_rects_(&agent_state_, false),
371 show_hit_test_borders_(&agent_state_, false),
372 show_size_on_resize_(&agent_state_, false),
373 paused_in_debugger_message_(&agent_state_, String()),
374 inspect_mode_(&agent_state_, protocol::Overlay::InspectModeEnum::None),
375 inspect_mode_protocol_config_(&agent_state_, std::vector<uint8_t>()) {}
376
~InspectorOverlayAgent()377 InspectorOverlayAgent::~InspectorOverlayAgent() {
378 DCHECK(!overlay_page_ && !inspect_tool_ && !hinge_ && !persistent_tool_);
379 }
380
Trace(Visitor * visitor) const381 void InspectorOverlayAgent::Trace(Visitor* visitor) const {
382 visitor->Trace(frame_impl_);
383 visitor->Trace(inspected_frames_);
384 visitor->Trace(overlay_page_);
385 visitor->Trace(overlay_chrome_client_);
386 visitor->Trace(overlay_host_);
387 visitor->Trace(dom_agent_);
388 visitor->Trace(inspect_tool_);
389 visitor->Trace(persistent_tool_);
390 visitor->Trace(hinge_);
391 visitor->Trace(document_to_ax_context_);
392 InspectorBaseAgent::Trace(visitor);
393 }
394
Restore()395 void InspectorOverlayAgent::Restore() {
396 if (enabled_.Get())
397 enable();
398 setShowAdHighlights(show_ad_highlights_.Get());
399 setShowDebugBorders(show_debug_borders_.Get());
400 setShowFPSCounter(show_fps_counter_.Get());
401 setShowPaintRects(show_paint_rects_.Get());
402 setShowLayoutShiftRegions(show_layout_shift_regions_.Get());
403 setShowScrollBottleneckRects(show_scroll_bottleneck_rects_.Get());
404 setShowHitTestBorders(show_hit_test_borders_.Get());
405 setShowViewportSizeOnResize(show_size_on_resize_.Get());
406 PickTheRightTool();
407 }
408
Dispose()409 void InspectorOverlayAgent::Dispose() {
410 InspectorBaseAgent::Dispose();
411 disposed_ = true;
412 }
413
enable()414 Response InspectorOverlayAgent::enable() {
415 if (!dom_agent_->Enabled())
416 return Response::ServerError("DOM should be enabled first");
417 enabled_.Set(true);
418 if (backend_node_id_to_inspect_) {
419 GetFrontend()->inspectNodeRequested(
420 static_cast<int>(backend_node_id_to_inspect_));
421 }
422 backend_node_id_to_inspect_ = 0;
423 SetNeedsUnbufferedInput(true);
424 return Response::Success();
425 }
426
EnsureAXContext(Node * node)427 void InspectorOverlayAgent::EnsureAXContext(Node* node) {
428 Document& document = node->GetDocument();
429 if (!document_to_ax_context_.Contains(&document)) {
430 auto context = std::make_unique<AXContext>(document);
431 document_to_ax_context_.Set(&document, std::move(context));
432 }
433 }
434
disable()435 Response InspectorOverlayAgent::disable() {
436 enabled_.Clear();
437 setShowAdHighlights(false);
438 setShowDebugBorders(false);
439 setShowFPSCounter(false);
440 setShowPaintRects(false);
441 setShowLayoutShiftRegions(false);
442 setShowScrollBottleneckRects(false);
443 setShowHitTestBorders(false);
444 setShowViewportSizeOnResize(false);
445 paused_in_debugger_message_.Clear();
446 inspect_mode_.Set(protocol::Overlay::InspectModeEnum::None);
447 inspect_mode_protocol_config_.Set(std::vector<uint8_t>());
448 if (overlay_page_) {
449 overlay_page_->WillBeDestroyed();
450 overlay_page_.Clear();
451 overlay_chrome_client_.Clear();
452 overlay_host_->ClearDelegate();
453 overlay_host_.Clear();
454 }
455 resize_timer_.Stop();
456 resize_timer_active_ = false;
457 frame_overlay_.reset();
458 persistent_tool_ = nullptr;
459 PickTheRightTool();
460 SetNeedsUnbufferedInput(false);
461 document_to_ax_context_.clear();
462 return Response::Success();
463 }
464
setShowAdHighlights(bool show)465 Response InspectorOverlayAgent::setShowAdHighlights(bool show) {
466 show_ad_highlights_.Set(show);
467 frame_impl_->ViewImpl()->GetPage()->GetSettings().SetHighlightAds(show);
468 return Response::Success();
469 }
470
setShowDebugBorders(bool show)471 Response InspectorOverlayAgent::setShowDebugBorders(bool show) {
472 show_debug_borders_.Set(show);
473 if (show) {
474 Response response = CompositingEnabled();
475 if (!response.IsSuccess())
476 return response;
477 }
478 WebFrameWidget* widget = frame_impl_->LocalRoot()->FrameWidget();
479 WebFrameWidgetBase* widget_impl = static_cast<WebFrameWidgetBase*>(widget);
480 // While a frame is being detached the inspector will shutdown and
481 // turn off debug overlays, but the WebFrameWidget is already gone.
482 if (widget_impl) {
483 cc::LayerTreeDebugState debug_state = widget_impl->GetLayerTreeDebugState();
484 if (show)
485 debug_state.show_debug_borders.set();
486 else
487 debug_state.show_debug_borders.reset();
488 widget_impl->SetLayerTreeDebugState(debug_state);
489 }
490 return Response::Success();
491 }
492
setShowFPSCounter(bool show)493 Response InspectorOverlayAgent::setShowFPSCounter(bool show) {
494 show_fps_counter_.Set(show);
495 if (show) {
496 Response response = CompositingEnabled();
497 if (!response.IsSuccess())
498 return response;
499 }
500 WebFrameWidget* widget = frame_impl_->LocalRoot()->FrameWidget();
501 WebFrameWidgetBase* widget_impl = static_cast<WebFrameWidgetBase*>(widget);
502 // While a frame is being detached the inspector will shutdown and
503 // turn off debug overlays, but the WebFrameWidget is already gone.
504 if (widget_impl) {
505 cc::LayerTreeDebugState debug_state = widget_impl->GetLayerTreeDebugState();
506 debug_state.show_fps_counter = show;
507 widget_impl->SetLayerTreeDebugState(debug_state);
508 }
509 return Response::Success();
510 }
511
setShowPaintRects(bool show)512 Response InspectorOverlayAgent::setShowPaintRects(bool show) {
513 show_paint_rects_.Set(show);
514 if (show) {
515 Response response = CompositingEnabled();
516 if (!response.IsSuccess())
517 return response;
518 }
519 WebFrameWidget* widget = frame_impl_->LocalRoot()->FrameWidget();
520 WebFrameWidgetBase* widget_impl = static_cast<WebFrameWidgetBase*>(widget);
521 // While a frame is being detached the inspector will shutdown and
522 // turn off debug overlays, but the WebFrameWidget is already gone.
523 if (widget_impl) {
524 cc::LayerTreeDebugState debug_state = widget_impl->GetLayerTreeDebugState();
525 debug_state.show_paint_rects = show;
526 widget_impl->SetLayerTreeDebugState(debug_state);
527 }
528 if (!show && frame_impl_->GetFrameView())
529 frame_impl_->GetFrameView()->Invalidate();
530 return Response::Success();
531 }
532
setShowLayoutShiftRegions(bool show)533 Response InspectorOverlayAgent::setShowLayoutShiftRegions(bool show) {
534 show_layout_shift_regions_.Set(show);
535 if (show) {
536 Response response = CompositingEnabled();
537 if (!response.IsSuccess())
538 return response;
539 }
540 WebFrameWidget* widget = frame_impl_->LocalRoot()->FrameWidget();
541 WebFrameWidgetBase* widget_impl = static_cast<WebFrameWidgetBase*>(widget);
542 // While a frame is being detached the inspector will shutdown and
543 // turn off debug overlays, but the WebFrameWidget is already gone.
544 if (widget_impl) {
545 cc::LayerTreeDebugState debug_state = widget_impl->GetLayerTreeDebugState();
546 debug_state.show_layout_shift_regions = show;
547 widget_impl->SetLayerTreeDebugState(debug_state);
548 }
549
550 if (!show && frame_impl_->GetFrameView())
551 frame_impl_->GetFrameView()->Invalidate();
552 return Response::Success();
553 }
554
setShowScrollBottleneckRects(bool show)555 Response InspectorOverlayAgent::setShowScrollBottleneckRects(bool show) {
556 show_scroll_bottleneck_rects_.Set(show);
557 if (show) {
558 Response response = CompositingEnabled();
559 if (!response.IsSuccess())
560 return response;
561 }
562 WebFrameWidget* widget = frame_impl_->LocalRoot()->FrameWidget();
563 WebFrameWidgetBase* widget_impl = static_cast<WebFrameWidgetBase*>(widget);
564 // While a frame is being detached the inspector will shutdown and
565 // turn off debug overlays, but the WebFrameWidget is already gone.
566 if (widget_impl) {
567 cc::LayerTreeDebugState debug_state = widget_impl->GetLayerTreeDebugState();
568 debug_state.show_touch_event_handler_rects = show;
569 debug_state.show_wheel_event_handler_rects = show;
570 debug_state.show_non_fast_scrollable_rects = show;
571 debug_state.show_main_thread_scrolling_reason_rects = show;
572 widget_impl->SetLayerTreeDebugState(debug_state);
573 }
574
575 return Response::Success();
576 }
577
setShowHitTestBorders(bool show)578 Response InspectorOverlayAgent::setShowHitTestBorders(bool show) {
579 show_hit_test_borders_.Set(show);
580 if (show) {
581 Response response = CompositingEnabled();
582 if (!response.IsSuccess())
583 return response;
584 }
585 WebFrameWidget* widget = frame_impl_->LocalRoot()->FrameWidget();
586 WebFrameWidgetBase* widget_impl = static_cast<WebFrameWidgetBase*>(widget);
587 // While a frame is being detached the inspector will shutdown and
588 // turn off debug overlays, but the WebFrameWidget is already gone.
589 if (widget_impl) {
590 cc::LayerTreeDebugState debug_state = widget_impl->GetLayerTreeDebugState();
591 debug_state.show_hit_test_borders = show;
592 widget_impl->SetLayerTreeDebugState(debug_state);
593 }
594 return Response::Success();
595 }
596
setShowViewportSizeOnResize(bool show)597 Response InspectorOverlayAgent::setShowViewportSizeOnResize(bool show) {
598 show_size_on_resize_.Set(show);
599 return Response::Success();
600 }
601
setPausedInDebuggerMessage(Maybe<String> message)602 Response InspectorOverlayAgent::setPausedInDebuggerMessage(
603 Maybe<String> message) {
604 paused_in_debugger_message_.Set(message.fromMaybe(String()));
605 PickTheRightTool();
606 return Response::Success();
607 }
608
highlightRect(int x,int y,int width,int height,Maybe<protocol::DOM::RGBA> color,Maybe<protocol::DOM::RGBA> outline_color)609 Response InspectorOverlayAgent::highlightRect(
610 int x,
611 int y,
612 int width,
613 int height,
614 Maybe<protocol::DOM::RGBA> color,
615 Maybe<protocol::DOM::RGBA> outline_color) {
616 std::unique_ptr<FloatQuad> quad =
617 std::make_unique<FloatQuad>(FloatRect(x, y, width, height));
618 return SetInspectTool(MakeGarbageCollected<QuadHighlightTool>(
619 this, GetFrontend(), std::move(quad),
620 InspectorDOMAgent::ParseColor(color.fromMaybe(nullptr)),
621 InspectorDOMAgent::ParseColor(outline_color.fromMaybe(nullptr))));
622 }
623
highlightQuad(std::unique_ptr<protocol::Array<double>> quad_array,Maybe<protocol::DOM::RGBA> color,Maybe<protocol::DOM::RGBA> outline_color)624 Response InspectorOverlayAgent::highlightQuad(
625 std::unique_ptr<protocol::Array<double>> quad_array,
626 Maybe<protocol::DOM::RGBA> color,
627 Maybe<protocol::DOM::RGBA> outline_color) {
628 std::unique_ptr<FloatQuad> quad = std::make_unique<FloatQuad>();
629 if (!ParseQuad(std::move(quad_array), quad.get()))
630 return Response::ServerError("Invalid Quad format");
631 return SetInspectTool(MakeGarbageCollected<QuadHighlightTool>(
632 this, GetFrontend(), std::move(quad),
633 InspectorDOMAgent::ParseColor(color.fromMaybe(nullptr)),
634 InspectorDOMAgent::ParseColor(outline_color.fromMaybe(nullptr))));
635 }
636
setShowHinge(protocol::Maybe<protocol::Overlay::HingeConfig> tool_config)637 Response InspectorOverlayAgent::setShowHinge(
638 protocol::Maybe<protocol::Overlay::HingeConfig> tool_config) {
639 // Hide the hinge when called without a configuration.
640 if (!tool_config.isJust()) {
641 hinge_ = nullptr;
642 if (!inspect_tool_)
643 DisableFrameOverlay();
644 ScheduleUpdate();
645 return Response::Success();
646 }
647
648 // Create a hinge
649 protocol::Overlay::HingeConfig* config = tool_config.fromJust();
650 protocol::DOM::Rect* rect = config->getRect();
651 int x = rect->getX();
652 int y = rect->getY();
653 int width = rect->getWidth();
654 int height = rect->getHeight();
655 if (x < 0 || y < 0 || width < 0 || height < 0)
656 return Response::InvalidParams("Invalid hinge rectangle.");
657
658 // Use default color if a content color is not provided.
659 Color content_color =
660 config->hasContentColor()
661 ? InspectorDOMAgent::ParseColor(config->getContentColor(nullptr))
662 : Color(38, 38, 38);
663 // outlineColor uses a kTransparent default from ParseColor if not provided.
664 Color outline_color =
665 InspectorDOMAgent::ParseColor(config->getOutlineColor(nullptr));
666
667 DCHECK(frame_impl_->GetFrameView() && GetFrame());
668
669 FloatQuad quad(FloatRect(x, y, width, height));
670 hinge_ =
671 MakeGarbageCollected<Hinge>(quad, content_color, outline_color, this);
672
673 LoadOverlayPageResource();
674 EvaluateInOverlay("setOverlay", hinge_->GetOverlayName());
675 EnsureEnableFrameOverlay();
676
677 ScheduleUpdate();
678
679 return Response::Success();
680 }
681
highlightNode(std::unique_ptr<protocol::Overlay::HighlightConfig> highlight_inspector_object,Maybe<int> node_id,Maybe<int> backend_node_id,Maybe<String> object_id,Maybe<String> selector_list)682 Response InspectorOverlayAgent::highlightNode(
683 std::unique_ptr<protocol::Overlay::HighlightConfig>
684 highlight_inspector_object,
685 Maybe<int> node_id,
686 Maybe<int> backend_node_id,
687 Maybe<String> object_id,
688 Maybe<String> selector_list) {
689 Node* node = nullptr;
690 Response response =
691 dom_agent_->AssertNode(node_id, backend_node_id, object_id, node);
692 if (!response.IsSuccess())
693 return response;
694
695 std::unique_ptr<InspectorHighlightConfig> highlight_config;
696 response = HighlightConfigFromInspectorObject(
697 std::move(highlight_inspector_object), &highlight_config);
698 if (!response.IsSuccess())
699 return response;
700
701 return SetInspectTool(MakeGarbageCollected<NodeHighlightTool>(
702 this, GetFrontend(), node, selector_list.fromMaybe(String()),
703 std::move(highlight_config)));
704 }
705
setShowGridOverlays(std::unique_ptr<protocol::Array<protocol::Overlay::GridNodeHighlightConfig>> grid_node_highlight_configs)706 Response InspectorOverlayAgent::setShowGridOverlays(
707 std::unique_ptr<protocol::Array<protocol::Overlay::GridNodeHighlightConfig>>
708 grid_node_highlight_configs) {
709 persistent_tool_ = nullptr;
710
711 if (grid_node_highlight_configs->size()) {
712 GridHighlightTool* grid_tool =
713 MakeGarbageCollected<GridHighlightTool>(this, GetFrontend());
714 for (std::unique_ptr<protocol::Overlay::GridNodeHighlightConfig>& config :
715 *grid_node_highlight_configs) {
716 Node* node = nullptr;
717 Response response = dom_agent_->AssertNode(config->getNodeId(), node);
718 if (!response.IsSuccess())
719 return response;
720 grid_tool->AddGridConfig(node,
721 InspectorOverlayAgent::ToGridHighlightConfig(
722 config->getGridHighlightConfig()));
723 }
724 persistent_tool_ = grid_tool;
725 }
726
727 PickTheRightTool();
728
729 return Response::Success();
730 }
731
highlightSourceOrder(std::unique_ptr<protocol::Overlay::SourceOrderConfig> source_order_inspector_object,Maybe<int> node_id,Maybe<int> backend_node_id,Maybe<String> object_id)732 Response InspectorOverlayAgent::highlightSourceOrder(
733 std::unique_ptr<protocol::Overlay::SourceOrderConfig>
734 source_order_inspector_object,
735 Maybe<int> node_id,
736 Maybe<int> backend_node_id,
737 Maybe<String> object_id) {
738 Node* node = nullptr;
739 Response response =
740 dom_agent_->AssertNode(node_id, backend_node_id, object_id, node);
741 if (!response.IsSuccess())
742 return response;
743
744 InspectorSourceOrderConfig config = SourceOrderConfigFromInspectorObject(
745 std::move(source_order_inspector_object));
746 std::unique_ptr<InspectorSourceOrderConfig> source_order_config =
747 std::make_unique<InspectorSourceOrderConfig>(config);
748
749 return SetInspectTool(MakeGarbageCollected<SourceOrderTool>(
750 this, GetFrontend(), node, std::move(source_order_config)));
751 }
752
highlightFrame(const String & frame_id,Maybe<protocol::DOM::RGBA> color,Maybe<protocol::DOM::RGBA> outline_color)753 Response InspectorOverlayAgent::highlightFrame(
754 const String& frame_id,
755 Maybe<protocol::DOM::RGBA> color,
756 Maybe<protocol::DOM::RGBA> outline_color) {
757 LocalFrame* frame =
758 IdentifiersFactory::FrameById(inspected_frames_, frame_id);
759 // FIXME: Inspector doesn't currently work cross process.
760 if (!frame)
761 return Response::ServerError("Invalid frame id");
762 if (!frame->DeprecatedLocalOwner()) {
763 PickTheRightTool();
764 return Response::Success();
765 }
766
767 std::unique_ptr<InspectorHighlightConfig> highlight_config =
768 std::make_unique<InspectorHighlightConfig>();
769 highlight_config->show_info = true; // Always show tooltips for frames.
770 highlight_config->content =
771 InspectorDOMAgent::ParseColor(color.fromMaybe(nullptr));
772 highlight_config->content_outline =
773 InspectorDOMAgent::ParseColor(outline_color.fromMaybe(nullptr));
774
775 return SetInspectTool(MakeGarbageCollected<NodeHighlightTool>(
776 this, GetFrontend(), frame->DeprecatedLocalOwner(), String(),
777 std::move(highlight_config)));
778 }
779
hideHighlight()780 Response InspectorOverlayAgent::hideHighlight() {
781 if (inspect_tool_ && inspect_tool_->HideOnHideHighlight())
782 PickTheRightTool();
783
784 return Response::Success();
785 }
786
getHighlightObjectForTest(int node_id,Maybe<bool> include_distance,Maybe<bool> include_style,Maybe<String> colorFormat,Maybe<bool> show_accessibility_info,std::unique_ptr<protocol::DictionaryValue> * result)787 Response InspectorOverlayAgent::getHighlightObjectForTest(
788 int node_id,
789 Maybe<bool> include_distance,
790 Maybe<bool> include_style,
791 Maybe<String> colorFormat,
792 Maybe<bool> show_accessibility_info,
793 std::unique_ptr<protocol::DictionaryValue>* result) {
794 Node* node = nullptr;
795 Response response = dom_agent_->AssertNode(node_id, node);
796 if (!response.IsSuccess())
797 return response;
798
799 auto config = std::make_unique<InspectorHighlightConfig>(
800 InspectorHighlight::DefaultConfig());
801 config->show_styles = include_style.fromMaybe(false);
802 config->show_accessibility_info = show_accessibility_info.fromMaybe(true);
803 String format = colorFormat.fromMaybe("hex");
804 namespace ColorFormatEnum = protocol::Overlay::ColorFormatEnum;
805 if (format == ColorFormatEnum::Hsl) {
806 config->color_format = ColorFormat::HSL;
807 } else if (format == ColorFormatEnum::Rgb) {
808 config->color_format = ColorFormat::RGB;
809 } else {
810 config->color_format = ColorFormat::HEX;
811 }
812
813 NodeHighlightTool tool(this, GetFrontend(), node, "" /* selector_list */,
814 std::move(config));
815 *result = tool.GetNodeInspectorHighlightAsJson(
816 true /* append_element_info */, include_distance.fromMaybe(false));
817 return Response::Success();
818 }
819
getGridHighlightObjectsForTest(std::unique_ptr<protocol::Array<int>> node_ids,std::unique_ptr<protocol::DictionaryValue> * highlights)820 Response InspectorOverlayAgent::getGridHighlightObjectsForTest(
821 std::unique_ptr<protocol::Array<int>> node_ids,
822 std::unique_ptr<protocol::DictionaryValue>* highlights) {
823 GridHighlightTool grid_highlight_tool(this, GetFrontend());
824 for (const int node_id : *node_ids) {
825 Node* node = nullptr;
826 Response response = dom_agent_->AssertNode(node_id, node);
827 if (!response.IsSuccess())
828 return response;
829 grid_highlight_tool.AddGridConfig(
830 node, std::make_unique<InspectorGridHighlightConfig>(
831 InspectorHighlight::DefaultGridConfig()));
832 }
833 *highlights = grid_highlight_tool.GetGridInspectorHighlightsAsJson();
834 return Response::Success();
835 }
836
getSourceOrderHighlightObjectForTest(int node_id,std::unique_ptr<protocol::DictionaryValue> * result)837 Response InspectorOverlayAgent::getSourceOrderHighlightObjectForTest(
838 int node_id,
839 std::unique_ptr<protocol::DictionaryValue>* result) {
840 Node* node = nullptr;
841 Response response = dom_agent_->AssertNode(node_id, node);
842 if (!response.IsSuccess())
843 return response;
844
845 auto config = std::make_unique<InspectorSourceOrderConfig>(
846 InspectorSourceOrderHighlight::DefaultConfig());
847
848 SourceOrderTool tool(this, GetFrontend(), node, std::move(config));
849 *result = tool.GetNodeInspectorSourceOrderHighlightAsJson();
850 return Response::Success();
851 }
852
UpdatePrePaint()853 void InspectorOverlayAgent::UpdatePrePaint() {
854 if (frame_overlay_)
855 frame_overlay_->UpdatePrePaint();
856 }
857
PaintOverlay(GraphicsContext & context)858 void InspectorOverlayAgent::PaintOverlay(GraphicsContext& context) {
859 DCHECK(RuntimeEnabledFeatures::CompositeAfterPaintEnabled());
860 if (frame_overlay_)
861 frame_overlay_->Paint(context);
862 }
863
IsInspectorLayer(const cc::Layer * layer) const864 bool InspectorOverlayAgent::IsInspectorLayer(const cc::Layer* layer) const {
865 if (!frame_overlay_)
866 return false;
867 if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
868 return layer == static_cast<const InspectorPageOverlayDelegate*>(
869 frame_overlay_->GetDelegate())
870 ->GetLayer();
871 }
872 return layer == &frame_overlay_->GetGraphicsLayer()->CcLayer();
873 }
874
GetFrame() const875 LocalFrame* InspectorOverlayAgent::GetFrame() const {
876 return frame_impl_->GetFrame();
877 }
878
DispatchBufferedTouchEvents()879 void InspectorOverlayAgent::DispatchBufferedTouchEvents() {
880 if (!inspect_tool_)
881 return;
882 OverlayMainFrame()->GetEventHandler().DispatchBufferedTouchEvents();
883 }
884
HandleInputEvent(const WebInputEvent & input_event)885 WebInputEventResult InspectorOverlayAgent::HandleInputEvent(
886 const WebInputEvent& input_event) {
887 if (!enabled_.Get())
888 return WebInputEventResult::kNotHandled;
889
890 if (input_event.GetType() == WebInputEvent::Type::kMouseUp &&
891 swallow_next_mouse_up_) {
892 swallow_next_mouse_up_ = false;
893 return WebInputEventResult::kHandledSuppressed;
894 }
895
896 LocalFrame* frame = GetFrame();
897 if (!frame || !frame->View() || !frame->ContentLayoutObject() ||
898 !inspect_tool_)
899 return WebInputEventResult::kNotHandled;
900
901 bool handled = inspect_tool_->HandleInputEvent(
902 frame_impl_->GetFrameView(), input_event, &swallow_next_mouse_up_);
903
904 if (handled) {
905 ScheduleUpdate();
906 return WebInputEventResult::kHandledSuppressed;
907 }
908
909 if (inspect_tool_->ForwardEventsToOverlay()) {
910 WebInputEventResult result = HandleInputEventInOverlay(input_event);
911 if (result != WebInputEventResult::kNotHandled) {
912 ScheduleUpdate();
913 return result;
914 }
915 }
916
917 // Exit tool upon unhandled Esc.
918 if (input_event.GetType() == WebInputEvent::Type::kRawKeyDown) {
919 const WebKeyboardEvent& keyboard_event =
920 static_cast<const WebKeyboardEvent&>(input_event);
921 if (keyboard_event.windows_key_code == VKEY_ESCAPE) {
922 GetFrontend()->inspectModeCanceled();
923 return WebInputEventResult::kNotHandled;
924 }
925 }
926
927 if (input_event.GetType() == WebInputEvent::Type::kMouseMove &&
928 inspect_tool_->HideOnMouseMove()) {
929 PickTheRightTool();
930 }
931
932 return WebInputEventResult::kNotHandled;
933 }
934
HandleInputEventInOverlay(const WebInputEvent & input_event)935 WebInputEventResult InspectorOverlayAgent::HandleInputEventInOverlay(
936 const WebInputEvent& input_event) {
937 if (input_event.GetType() == WebInputEvent::Type::kGestureTap) {
938 return OverlayMainFrame()->GetEventHandler().HandleGestureEvent(
939 static_cast<const WebGestureEvent&>(input_event));
940 }
941
942 if (WebInputEvent::IsMouseEventType(input_event.GetType())) {
943 WebMouseEvent mouse_event = static_cast<const WebMouseEvent&>(input_event);
944 if (mouse_event.GetType() == WebInputEvent::Type::kMouseMove) {
945 return OverlayMainFrame()->GetEventHandler().HandleMouseMoveEvent(
946 mouse_event, {}, {});
947 }
948 if (mouse_event.GetType() == WebInputEvent::Type::kMouseDown) {
949 return OverlayMainFrame()->GetEventHandler().HandleMousePressEvent(
950 mouse_event);
951 }
952 if (mouse_event.GetType() == WebInputEvent::Type::kMouseUp) {
953 return OverlayMainFrame()->GetEventHandler().HandleMouseReleaseEvent(
954 mouse_event);
955 }
956 return WebInputEventResult::kNotHandled;
957 }
958
959 if (WebInputEvent::IsPointerEventType(input_event.GetType())) {
960 return OverlayMainFrame()->GetEventHandler().HandlePointerEvent(
961 static_cast<const WebPointerEvent&>(input_event),
962 Vector<WebPointerEvent>(), Vector<WebPointerEvent>());
963 }
964
965 if (WebInputEvent::IsKeyboardEventType(input_event.GetType())) {
966 return OverlayMainFrame()->GetEventHandler().KeyEvent(
967 static_cast<const WebKeyboardEvent&>(input_event));
968 }
969
970 if (input_event.GetType() == WebInputEvent::Type::kMouseWheel) {
971 return OverlayMainFrame()->GetEventHandler().HandleWheelEvent(
972 static_cast<const WebMouseWheelEvent&>(input_event));
973 }
974
975 return WebInputEventResult::kNotHandled;
976 }
977
ScheduleUpdate()978 void InspectorOverlayAgent::ScheduleUpdate() {
979 if (IsVisible()) {
980 GetFrame()->GetPage()->GetChromeClient().ScheduleAnimation(
981 GetFrame()->View());
982 }
983 }
984
PaintOverlayPage()985 void InspectorOverlayAgent::PaintOverlayPage() {
986 DCHECK(overlay_page_);
987
988 LocalFrameView* view = frame_impl_->GetFrameView();
989 LocalFrame* frame = GetFrame();
990 if (!view || !frame)
991 return;
992
993 LocalFrame* overlay_frame = OverlayMainFrame();
994 // To make overlay render the same size text with any emulation scale,
995 // compensate the emulation scale using page scale.
996 float emulation_scale =
997 frame->GetPage()->GetChromeClient().InputEventsScaleForEmulation();
998 IntSize viewport_size = frame->GetPage()->GetVisualViewport().Size();
999 viewport_size.Scale(emulation_scale);
1000 overlay_page_->GetVisualViewport().SetSize(viewport_size);
1001 overlay_page_->SetDefaultPageScaleLimits(1 / emulation_scale,
1002 1 / emulation_scale);
1003 overlay_page_->GetVisualViewport().SetScale(1 / emulation_scale);
1004 overlay_frame->SetPageZoomFactor(WindowToViewportScale());
1005 overlay_frame->View()->Resize(viewport_size);
1006
1007 Reset(viewport_size);
1008
1009 float scale = WindowToViewportScale();
1010
1011 if (inspect_tool_) {
1012 inspect_tool_->Draw(scale);
1013 if (persistent_tool_ && inspect_tool_->SupportsPersistentOverlays())
1014 persistent_tool_->Draw(scale);
1015 }
1016
1017 if (hinge_)
1018 hinge_->Draw(scale);
1019
1020 OverlayMainFrame()->View()->UpdateAllLifecyclePhases(
1021 DocumentUpdateReason::kInspector);
1022 }
1023
BuildObjectForSize(const IntSize & size)1024 static std::unique_ptr<protocol::DictionaryValue> BuildObjectForSize(
1025 const IntSize& size) {
1026 std::unique_ptr<protocol::DictionaryValue> result =
1027 protocol::DictionaryValue::create();
1028 result->setInteger("width", size.Width());
1029 result->setInteger("height", size.Height());
1030 return result;
1031 }
1032
WindowToViewportScale() const1033 float InspectorOverlayAgent::WindowToViewportScale() const {
1034 LocalFrame* frame = GetFrame();
1035 if (!frame)
1036 return 1.0f;
1037 return frame->GetPage()->GetChromeClient().WindowToViewportScalar(frame,
1038 1.0f);
1039 }
1040
LoadOverlayPageResource()1041 void InspectorOverlayAgent::LoadOverlayPageResource() {
1042 if (overlay_page_)
1043 return;
1044
1045 ScriptForbiddenScope::AllowUserAgentScript allow_script;
1046
1047 Page::PageClients page_clients;
1048 FillWithEmptyClients(page_clients);
1049 DCHECK(!overlay_chrome_client_);
1050 overlay_chrome_client_ = MakeGarbageCollected<InspectorOverlayChromeClient>(
1051 GetFrame()->GetPage()->GetChromeClient(), *this);
1052 page_clients.chrome_client = overlay_chrome_client_.Get();
1053 overlay_page_ = Page::CreateNonOrdinary(page_clients);
1054 overlay_host_ = MakeGarbageCollected<InspectorOverlayHost>(this);
1055
1056 Settings& settings = GetFrame()->GetPage()->GetSettings();
1057 Settings& overlay_settings = overlay_page_->GetSettings();
1058
1059 overlay_settings.GetGenericFontFamilySettings().UpdateStandard(
1060 settings.GetGenericFontFamilySettings().Standard());
1061 overlay_settings.GetGenericFontFamilySettings().UpdateFixed(
1062 settings.GetGenericFontFamilySettings().Fixed());
1063 overlay_settings.GetGenericFontFamilySettings().UpdateSerif(
1064 settings.GetGenericFontFamilySettings().Serif());
1065 overlay_settings.GetGenericFontFamilySettings().UpdateSansSerif(
1066 settings.GetGenericFontFamilySettings().SansSerif());
1067 overlay_settings.GetGenericFontFamilySettings().UpdateCursive(
1068 settings.GetGenericFontFamilySettings().Cursive());
1069 overlay_settings.GetGenericFontFamilySettings().UpdateFantasy(
1070 settings.GetGenericFontFamilySettings().Fantasy());
1071 overlay_settings.GetGenericFontFamilySettings().UpdatePictograph(
1072 settings.GetGenericFontFamilySettings().Pictograph());
1073 overlay_settings.SetMinimumFontSize(settings.GetMinimumFontSize());
1074 overlay_settings.SetMinimumLogicalFontSize(
1075 settings.GetMinimumLogicalFontSize());
1076 overlay_settings.SetScriptEnabled(true);
1077 overlay_settings.SetPluginsEnabled(false);
1078 overlay_settings.SetLoadsImagesAutomatically(true);
1079
1080 DEFINE_STATIC_LOCAL(Persistent<LocalFrameClient>, dummy_local_frame_client,
1081 (MakeGarbageCollected<EmptyLocalFrameClient>()));
1082 auto* frame = MakeGarbageCollected<LocalFrame>(
1083 dummy_local_frame_client, *overlay_page_, nullptr, nullptr, nullptr,
1084 FrameInsertType::kInsertInConstructor, base::UnguessableToken::Create(),
1085 nullptr, nullptr, /* policy_container */ nullptr);
1086 frame->SetView(MakeGarbageCollected<LocalFrameView>(*frame));
1087 frame->Init(nullptr);
1088 frame->View()->SetCanHaveScrollbars(false);
1089 frame->View()->SetBaseBackgroundColor(Color::kTransparent);
1090
1091 scoped_refptr<SharedBuffer> data = SharedBuffer::Create();
1092
1093 data->Append("<script>", static_cast<size_t>(8));
1094 data->Append(UncompressResourceAsBinary(IDR_INSPECT_TOOL_MAIN_JS));
1095 data->Append("</script>", static_cast<size_t>(9));
1096
1097 frame->ForceSynchronousDocumentInstall("text/html", data);
1098
1099 v8::Isolate* isolate = ToIsolate(frame);
1100 ScriptState* script_state = ToScriptStateForMainWorld(frame);
1101 DCHECK(script_state);
1102 ScriptState::Scope scope(script_state);
1103 v8::Local<v8::Object> global = script_state->GetContext()->Global();
1104 v8::Local<v8::Value> overlay_host_obj =
1105 ToV8(overlay_host_.Get(), global, isolate);
1106 DCHECK(!overlay_host_obj.IsEmpty());
1107 global
1108 ->Set(script_state->GetContext(),
1109 V8AtomicString(isolate, "InspectorOverlayHost"), overlay_host_obj)
1110 .ToChecked();
1111
1112 #if defined(OS_WIN)
1113 EvaluateInOverlay("setPlatform", "windows");
1114 #elif defined(OS_MAC)
1115 EvaluateInOverlay("setPlatform", "mac");
1116 #elif defined(OS_POSIX)
1117 EvaluateInOverlay("setPlatform", "linux");
1118 #else
1119 EvaluateInOverlay("setPlatform", "other");
1120 #endif
1121 }
1122
OverlayMainFrame()1123 LocalFrame* InspectorOverlayAgent::OverlayMainFrame() {
1124 DCHECK(overlay_page_);
1125 return To<LocalFrame>(overlay_page_->MainFrame());
1126 }
1127
Reset(const IntSize & viewport_size)1128 void InspectorOverlayAgent::Reset(const IntSize& viewport_size) {
1129 std::unique_ptr<protocol::DictionaryValue> reset_data =
1130 protocol::DictionaryValue::create();
1131 reset_data->setDouble("deviceScaleFactor",
1132 GetFrame()->GetPage()->DeviceScaleFactorDeprecated());
1133 reset_data->setDouble(
1134 "emulationScaleFactor",
1135 GetFrame()->GetPage()->GetChromeClient().InputEventsScaleForEmulation());
1136 reset_data->setDouble("pageScaleFactor",
1137 GetFrame()->GetPage()->GetVisualViewport().Scale());
1138
1139 IntRect viewport_in_screen =
1140 GetFrame()->GetPage()->GetChromeClient().ViewportToScreen(
1141 IntRect(IntPoint(), viewport_size), GetFrame()->View());
1142 reset_data->setObject("viewportSize",
1143 BuildObjectForSize(viewport_in_screen.Size()));
1144
1145 // The zoom factor in the overlay frame already has been multiplied by the
1146 // window to viewport scale (aka device scale factor), so cancel it.
1147 reset_data->setDouble("pageZoomFactor",
1148 GetFrame()->PageZoomFactor() / WindowToViewportScale());
1149
1150 // TODO(szager): These values have been zero since root layer scrolling
1151 // landed. Probably they should be derived from
1152 // LocalFrameView::LayoutViewport(); but I have no idea who the consumers
1153 // of these values are, so I'm leaving them zero pending investigation.
1154 reset_data->setInteger("scrollX", 0);
1155 reset_data->setInteger("scrollY", 0);
1156 EvaluateInOverlay("reset", std::move(reset_data));
1157 }
1158
EvaluateInOverlay(const String & method,const String & argument)1159 void InspectorOverlayAgent::EvaluateInOverlay(const String& method,
1160 const String& argument) {
1161 ScriptForbiddenScope::AllowUserAgentScript allow_script;
1162 std::unique_ptr<protocol::ListValue> command = protocol::ListValue::create();
1163 command->pushValue(protocol::StringValue::create(method));
1164 command->pushValue(protocol::StringValue::create(argument));
1165 std::vector<uint8_t> json;
1166 ConvertCBORToJSON(SpanFrom(command->Serialize()), &json);
1167 ClassicScript::CreateUnspecifiedScript(
1168 ScriptSourceCode(
1169 "dispatch(" +
1170 String(reinterpret_cast<const char*>(json.data()), json.size()) +
1171 ")",
1172 ScriptSourceLocationType::kInspector))
1173 ->RunScript(To<LocalFrame>(OverlayMainFrame())->DomWindow(),
1174 ScriptController::kExecuteScriptWhenScriptsDisabled);
1175 }
1176
EvaluateInOverlay(const String & method,std::unique_ptr<protocol::Value> argument)1177 void InspectorOverlayAgent::EvaluateInOverlay(
1178 const String& method,
1179 std::unique_ptr<protocol::Value> argument) {
1180 ScriptForbiddenScope::AllowUserAgentScript allow_script;
1181 std::unique_ptr<protocol::ListValue> command = protocol::ListValue::create();
1182 command->pushValue(protocol::StringValue::create(method));
1183 command->pushValue(std::move(argument));
1184 std::vector<uint8_t> json;
1185 ConvertCBORToJSON(SpanFrom(command->Serialize()), &json);
1186 ClassicScript::CreateUnspecifiedScript(
1187 ScriptSourceCode(
1188 "dispatch(" +
1189 String(reinterpret_cast<const char*>(json.data()), json.size()) +
1190 ")",
1191 ScriptSourceLocationType::kInspector))
1192 ->RunScript(To<LocalFrame>(OverlayMainFrame())->DomWindow(),
1193 ScriptController::kExecuteScriptWhenScriptsDisabled);
1194 }
1195
EvaluateInOverlayForTest(const String & script)1196 String InspectorOverlayAgent::EvaluateInOverlayForTest(const String& script) {
1197 ScriptForbiddenScope::AllowUserAgentScript allow_script;
1198 v8::HandleScope handle_scope(ToIsolate(OverlayMainFrame()));
1199 v8::Local<v8::Value> string =
1200 ClassicScript::CreateUnspecifiedScript(
1201 ScriptSourceCode(script, ScriptSourceLocationType::kInspector))
1202 ->RunScriptAndReturnValue(
1203 To<LocalFrame>(OverlayMainFrame())->DomWindow(),
1204 ScriptController::kExecuteScriptWhenScriptsDisabled);
1205 return ToCoreStringWithUndefinedOrNullCheck(string);
1206 }
1207
OnResizeTimer(TimerBase *)1208 void InspectorOverlayAgent::OnResizeTimer(TimerBase*) {
1209 if (resize_timer_active_) {
1210 // Restore the original tool.
1211 PickTheRightTool();
1212 return;
1213 }
1214
1215 // Show the resize tool.
1216 SetInspectTool(MakeGarbageCollected<ShowViewSizeTool>(this, GetFrontend()));
1217 resize_timer_active_ = true;
1218 resize_timer_.Stop();
1219 resize_timer_.StartOneShot(base::TimeDelta::FromSeconds(1), FROM_HERE);
1220 }
1221
Dispatch(const String & message)1222 void InspectorOverlayAgent::Dispatch(const String& message) {
1223 inspect_tool_->Dispatch(message);
1224 }
1225
PageLayoutInvalidated(bool resized)1226 void InspectorOverlayAgent::PageLayoutInvalidated(bool resized) {
1227 if (resized && show_size_on_resize_.Get()) {
1228 resize_timer_active_ = false;
1229 // Handle the resize in the next cycle to decouple overlay page rebuild from
1230 // the main page layout to avoid document lifecycle issues caused by
1231 // Microtask::PerformCheckpoint() called when we rebuild the overlay page.
1232 resize_timer_.Stop();
1233 resize_timer_.StartOneShot(base::TimeDelta::FromSeconds(0), FROM_HERE);
1234 return;
1235 }
1236 ScheduleUpdate();
1237 }
1238
CompositingEnabled()1239 Response InspectorOverlayAgent::CompositingEnabled() {
1240 bool main_frame = frame_impl_->ViewImpl() && !frame_impl_->Parent();
1241 if (!main_frame || !frame_impl_->ViewImpl()
1242 ->GetPage()
1243 ->GetSettings()
1244 .GetAcceleratedCompositingEnabled())
1245 return Response::ServerError("Compositing mode is not supported");
1246 return Response::Success();
1247 }
1248
InSomeInspectMode()1249 bool InspectorOverlayAgent::InSomeInspectMode() {
1250 return inspect_mode_.Get() != protocol::Overlay::InspectModeEnum::None;
1251 }
1252
Inspect(Node * inspected_node)1253 void InspectorOverlayAgent::Inspect(Node* inspected_node) {
1254 if (!inspected_node)
1255 return;
1256
1257 Node* node = inspected_node;
1258 while (node && !node->IsElementNode() && !node->IsDocumentNode() &&
1259 !node->IsDocumentFragment())
1260 node = node->ParentOrShadowHostNode();
1261 if (!node)
1262 return;
1263
1264 DOMNodeId backend_node_id = DOMNodeIds::IdForNode(node);
1265 if (!enabled_.Get()) {
1266 backend_node_id_to_inspect_ = backend_node_id;
1267 return;
1268 }
1269
1270 GetFrontend()->inspectNodeRequested(IdentifiersFactory::IntIdForNode(node));
1271 }
1272
setInspectMode(const String & mode,Maybe<protocol::Overlay::HighlightConfig> highlight_inspector_object)1273 Response InspectorOverlayAgent::setInspectMode(
1274 const String& mode,
1275 Maybe<protocol::Overlay::HighlightConfig> highlight_inspector_object) {
1276 if (mode != protocol::Overlay::InspectModeEnum::None &&
1277 mode != protocol::Overlay::InspectModeEnum::SearchForNode &&
1278 mode != protocol::Overlay::InspectModeEnum::SearchForUAShadowDOM &&
1279 mode != protocol::Overlay::InspectModeEnum::CaptureAreaScreenshot &&
1280 mode != protocol::Overlay::InspectModeEnum::ShowDistances) {
1281 return Response::ServerError(
1282 String("Unknown mode \"" + mode + "\" was provided.").Utf8());
1283 }
1284
1285 std::vector<uint8_t> serialized_config;
1286 if (highlight_inspector_object.isJust()) {
1287 highlight_inspector_object.fromJust()->AppendSerialized(&serialized_config);
1288 }
1289 std::unique_ptr<InspectorHighlightConfig> config;
1290 Response response = HighlightConfigFromInspectorObject(
1291 std::move(highlight_inspector_object), &config);
1292 if (!response.IsSuccess())
1293 return response;
1294 inspect_mode_.Set(mode);
1295 inspect_mode_protocol_config_.Set(serialized_config);
1296 PickTheRightTool();
1297 return Response::Success();
1298 }
1299
PickTheRightTool()1300 void InspectorOverlayAgent::PickTheRightTool() {
1301 InspectTool* inspect_tool = nullptr;
1302
1303 String inspect_mode = inspect_mode_.Get();
1304 if (inspect_mode == protocol::Overlay::InspectModeEnum::SearchForNode ||
1305 inspect_mode ==
1306 protocol::Overlay::InspectModeEnum::SearchForUAShadowDOM) {
1307 inspect_tool = MakeGarbageCollected<SearchingForNodeTool>(
1308 this, GetFrontend(), dom_agent_,
1309 inspect_mode ==
1310 protocol::Overlay::InspectModeEnum::SearchForUAShadowDOM,
1311 inspect_mode_protocol_config_.Get());
1312 } else if (inspect_mode ==
1313 protocol::Overlay::InspectModeEnum::CaptureAreaScreenshot) {
1314 inspect_tool = MakeGarbageCollected<ScreenshotTool>(this, GetFrontend());
1315 } else if (inspect_mode ==
1316 protocol::Overlay::InspectModeEnum::ShowDistances) {
1317 inspect_tool =
1318 MakeGarbageCollected<NearbyDistanceTool>(this, GetFrontend());
1319 } else if (!paused_in_debugger_message_.Get().IsNull()) {
1320 inspect_tool = MakeGarbageCollected<PausedInDebuggerTool>(
1321 this, GetFrontend(), v8_session_, paused_in_debugger_message_.Get());
1322 } else if (persistent_tool_) {
1323 inspect_tool = persistent_tool_;
1324 }
1325
1326 SetInspectTool(inspect_tool);
1327 }
1328
DisableFrameOverlay()1329 void InspectorOverlayAgent::DisableFrameOverlay() {
1330 if (IsVisible() || !frame_overlay_)
1331 return;
1332
1333 frame_overlay_.reset();
1334 auto& client = GetFrame()->GetPage()->GetChromeClient();
1335 client.SetCursorOverridden(false);
1336 client.SetCursor(PointerCursor(), GetFrame());
1337
1338 if (auto* frame_view = frame_impl_->GetFrameView())
1339 frame_view->SetPaintArtifactCompositorNeedsUpdate();
1340 }
1341
EnsureEnableFrameOverlay()1342 void InspectorOverlayAgent::EnsureEnableFrameOverlay() {
1343 if (frame_overlay_)
1344 return;
1345
1346 frame_overlay_ = std::make_unique<FrameOverlay>(
1347 GetFrame(), std::make_unique<InspectorPageOverlayDelegate>(*this));
1348 }
1349
ClearInspectTool()1350 void InspectorOverlayAgent::ClearInspectTool() {
1351 inspect_tool_ = nullptr;
1352 if (!hinge_)
1353 DisableFrameOverlay();
1354 }
1355
SetInspectTool(InspectTool * inspect_tool)1356 Response InspectorOverlayAgent::SetInspectTool(InspectTool* inspect_tool) {
1357 ClearInspectTool();
1358
1359 if (!inspect_tool)
1360 return Response::Success();
1361
1362 if (!enabled_.Get()) {
1363 return Response::InvalidRequest(
1364 "Overlay must be enabled before a tool can be shown");
1365 }
1366
1367 LocalFrameView* view = frame_impl_->GetFrameView();
1368 LocalFrame* frame = GetFrame();
1369 if (!view || !frame)
1370 return Response::InternalError();
1371
1372 inspect_tool_ = inspect_tool;
1373 // If the tool supports persistent overlays, the resources of the persistent
1374 // tool will be included into the JS resource.
1375 LoadOverlayPageResource();
1376 EvaluateInOverlay("setOverlay", inspect_tool->GetOverlayName());
1377 EnsureEnableFrameOverlay();
1378 ScheduleUpdate();
1379 return Response::Success();
1380 }
1381
1382 InspectorSourceOrderConfig
SourceOrderConfigFromInspectorObject(std::unique_ptr<protocol::Overlay::SourceOrderConfig> source_order_inspector_object)1383 InspectorOverlayAgent::SourceOrderConfigFromInspectorObject(
1384 std::unique_ptr<protocol::Overlay::SourceOrderConfig>
1385 source_order_inspector_object) {
1386 InspectorSourceOrderConfig source_order_config = InspectorSourceOrderConfig();
1387 source_order_config.parent_outline_color = InspectorDOMAgent::ParseColor(
1388 source_order_inspector_object->getParentOutlineColor());
1389 source_order_config.child_outline_color = InspectorDOMAgent::ParseColor(
1390 source_order_inspector_object->getChildOutlineColor());
1391
1392 return source_order_config;
1393 }
1394
HighlightConfigFromInspectorObject(Maybe<protocol::Overlay::HighlightConfig> highlight_inspector_object,std::unique_ptr<InspectorHighlightConfig> * out_config)1395 Response InspectorOverlayAgent::HighlightConfigFromInspectorObject(
1396 Maybe<protocol::Overlay::HighlightConfig> highlight_inspector_object,
1397 std::unique_ptr<InspectorHighlightConfig>* out_config) {
1398 if (!highlight_inspector_object.isJust()) {
1399 return Response::ServerError(
1400 "Internal error: highlight configuration parameter is missing");
1401 }
1402 protocol::Overlay::HighlightConfig* config =
1403 highlight_inspector_object.fromJust();
1404
1405 namespace ColorFormatEnum = protocol::Overlay::ColorFormatEnum;
1406
1407 String format = config->getColorFormat("hex");
1408
1409 if (format != ColorFormatEnum::Rgb && format != ColorFormatEnum::Hex &&
1410 format != ColorFormatEnum::Hsl) {
1411 return Response::InvalidParams("Unknown color format");
1412 }
1413
1414 *out_config = InspectorOverlayAgent::ToHighlightConfig(config);
1415 return Response::Success();
1416 }
1417
1418 // static
1419 std::unique_ptr<InspectorGridHighlightConfig>
ToGridHighlightConfig(protocol::Overlay::GridHighlightConfig * config)1420 InspectorOverlayAgent::ToGridHighlightConfig(
1421 protocol::Overlay::GridHighlightConfig* config) {
1422 if (!config) {
1423 return nullptr;
1424 }
1425 std::unique_ptr<InspectorGridHighlightConfig> highlight_config =
1426 std::make_unique<InspectorGridHighlightConfig>();
1427 highlight_config->show_positive_line_numbers =
1428 config->getShowPositiveLineNumbers(false);
1429 highlight_config->show_negative_line_numbers =
1430 config->getShowNegativeLineNumbers(false);
1431 highlight_config->show_area_names = config->getShowAreaNames(false);
1432 highlight_config->show_line_names = config->getShowLineNames(false);
1433 highlight_config->show_grid_extension_lines =
1434 config->getShowGridExtensionLines(false);
1435 highlight_config->grid_border_dash = config->getGridBorderDash(false);
1436
1437 // cellBorderDash is deprecated. We only use it if defined and none of the new
1438 // properties are.
1439 bool hasLegacyBorderDash = !config->hasRowLineDash() &&
1440 !config->hasColumnLineDash() &&
1441 config->hasCellBorderDash();
1442 highlight_config->row_line_dash = hasLegacyBorderDash
1443 ? config->getCellBorderDash(false)
1444 : config->getRowLineDash(false);
1445 highlight_config->column_line_dash = hasLegacyBorderDash
1446 ? config->getCellBorderDash(false)
1447 : config->getColumnLineDash(false);
1448
1449 highlight_config->show_track_sizes = config->getShowTrackSizes(false);
1450 highlight_config->grid_color =
1451 InspectorDOMAgent::ParseColor(config->getGridBorderColor(nullptr));
1452
1453 // cellBorderColor is deprecated. We only use it if defined and none of the
1454 // new properties are.
1455 bool hasLegacyBorderColors = !config->hasRowLineColor() &&
1456 !config->hasColumnLineColor() &&
1457 config->hasCellBorderColor();
1458 highlight_config->row_line_color =
1459 hasLegacyBorderColors
1460 ? InspectorDOMAgent::ParseColor(config->getCellBorderColor(nullptr))
1461 : InspectorDOMAgent::ParseColor(config->getRowLineColor(nullptr));
1462 highlight_config->column_line_color =
1463 hasLegacyBorderColors
1464 ? InspectorDOMAgent::ParseColor(config->getCellBorderColor(nullptr))
1465 : InspectorDOMAgent::ParseColor(config->getColumnLineColor(nullptr));
1466
1467 highlight_config->row_gap_color =
1468 InspectorDOMAgent::ParseColor(config->getRowGapColor(nullptr));
1469 highlight_config->column_gap_color =
1470 InspectorDOMAgent::ParseColor(config->getColumnGapColor(nullptr));
1471 highlight_config->row_hatch_color =
1472 InspectorDOMAgent::ParseColor(config->getRowHatchColor(nullptr));
1473 highlight_config->column_hatch_color =
1474 InspectorDOMAgent::ParseColor(config->getColumnHatchColor(nullptr));
1475 highlight_config->area_border_color =
1476 InspectorDOMAgent::ParseColor(config->getAreaBorderColor(nullptr));
1477 highlight_config->grid_background_color =
1478 InspectorDOMAgent::ParseColor(config->getGridBackgroundColor(nullptr));
1479 return highlight_config;
1480 }
1481
1482 // static
1483 std::unique_ptr<InspectorFlexContainerHighlightConfig>
ToFlexContainerHighlightConfig(protocol::Overlay::FlexContainerHighlightConfig * config)1484 InspectorOverlayAgent::ToFlexContainerHighlightConfig(
1485 protocol::Overlay::FlexContainerHighlightConfig* config) {
1486 if (!config) {
1487 return nullptr;
1488 }
1489 std::unique_ptr<InspectorFlexContainerHighlightConfig> highlight_config =
1490 std::make_unique<InspectorFlexContainerHighlightConfig>();
1491 highlight_config->container_border =
1492 InspectorOverlayAgent::ToLineStyle(config->getContainerBorder(nullptr));
1493 highlight_config->line_separator =
1494 InspectorOverlayAgent::ToLineStyle(config->getLineSeparator(nullptr));
1495 highlight_config->item_separator =
1496 InspectorOverlayAgent::ToLineStyle(config->getItemSeparator(nullptr));
1497
1498 return highlight_config;
1499 }
1500
1501 // static
ToLineStyle(protocol::Overlay::LineStyle * config)1502 std::unique_ptr<LineStyle> InspectorOverlayAgent::ToLineStyle(
1503 protocol::Overlay::LineStyle* config) {
1504 if (!config) {
1505 return nullptr;
1506 }
1507 std::unique_ptr<LineStyle> line_style = std::make_unique<LineStyle>();
1508 line_style->color = InspectorDOMAgent::ParseColor(config->getColor(nullptr));
1509 line_style->pattern = config->getPattern("solid");
1510
1511 return line_style;
1512 }
1513
1514 // static
1515 std::unique_ptr<InspectorHighlightConfig>
ToHighlightConfig(protocol::Overlay::HighlightConfig * config)1516 InspectorOverlayAgent::ToHighlightConfig(
1517 protocol::Overlay::HighlightConfig* config) {
1518 std::unique_ptr<InspectorHighlightConfig> highlight_config =
1519 std::make_unique<InspectorHighlightConfig>();
1520 highlight_config->show_info = config->getShowInfo(false);
1521 highlight_config->show_accessibility_info =
1522 config->getShowAccessibilityInfo(true);
1523 highlight_config->show_styles = config->getShowStyles(false);
1524 highlight_config->show_rulers = config->getShowRulers(false);
1525 highlight_config->show_extension_lines = config->getShowExtensionLines(false);
1526 highlight_config->content =
1527 InspectorDOMAgent::ParseColor(config->getContentColor(nullptr));
1528 highlight_config->padding =
1529 InspectorDOMAgent::ParseColor(config->getPaddingColor(nullptr));
1530 highlight_config->border =
1531 InspectorDOMAgent::ParseColor(config->getBorderColor(nullptr));
1532 highlight_config->margin =
1533 InspectorDOMAgent::ParseColor(config->getMarginColor(nullptr));
1534 highlight_config->event_target =
1535 InspectorDOMAgent::ParseColor(config->getEventTargetColor(nullptr));
1536 highlight_config->shape =
1537 InspectorDOMAgent::ParseColor(config->getShapeColor(nullptr));
1538 highlight_config->shape_margin =
1539 InspectorDOMAgent::ParseColor(config->getShapeMarginColor(nullptr));
1540 highlight_config->css_grid =
1541 InspectorDOMAgent::ParseColor(config->getCssGridColor(nullptr));
1542
1543 namespace ColorFormatEnum = protocol::Overlay::ColorFormatEnum;
1544
1545 String format = config->getColorFormat("hex");
1546
1547 if (format == ColorFormatEnum::Hsl) {
1548 highlight_config->color_format = ColorFormat::HSL;
1549 } else if (format == ColorFormatEnum::Rgb) {
1550 highlight_config->color_format = ColorFormat::RGB;
1551 } else {
1552 highlight_config->color_format = ColorFormat::HEX;
1553 }
1554
1555 highlight_config->grid_highlight_config =
1556 InspectorOverlayAgent::ToGridHighlightConfig(
1557 config->getGridHighlightConfig(nullptr));
1558
1559 highlight_config->flex_container_highlight_config =
1560 InspectorOverlayAgent::ToFlexContainerHighlightConfig(
1561 config->getFlexContainerHighlightConfig(nullptr));
1562 return highlight_config;
1563 }
1564
SetNeedsUnbufferedInput(bool unbuffered)1565 void InspectorOverlayAgent::SetNeedsUnbufferedInput(bool unbuffered) {
1566 LocalFrame* frame = GetFrame();
1567 if (frame) {
1568 frame->GetPage()->GetChromeClient().SetNeedsUnbufferedInputForDebugger(
1569 frame, unbuffered);
1570 }
1571 }
1572
1573 } // namespace blink
1574