Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(277)

Side by Side Diff: third_party/WebKit/Source/web/InspectorOverlayAgent.cpp

Issue 2826833002: Revert of [DevTools] Consolidate overlay-related functionality in Overlay domain (Closed)
Patch Set: Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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 "web/InspectorOverlayAgent.h"
30
31 #include <memory>
32
33 #include "bindings/core/v8/ScriptController.h"
34 #include "bindings/core/v8/ScriptSourceCode.h"
35 #include "bindings/core/v8/V8Binding.h"
36 #include "bindings/core/v8/V8InspectorOverlayHost.h"
37 #include "core/dom/DOMNodeIds.h"
38 #include "core/dom/Node.h"
39 #include "core/dom/StaticNodeList.h"
40 #include "core/dom/TaskRunnerHelper.h"
41 #include "core/frame/FrameView.h"
42 #include "core/frame/LocalFrame.h"
43 #include "core/frame/LocalFrameClient.h"
44 #include "core/frame/Settings.h"
45 #include "core/frame/VisualViewport.h"
46 #include "core/html/HTMLFrameOwnerElement.h"
47 #include "core/input/EventHandler.h"
48 #include "core/inspector/IdentifiersFactory.h"
49 #include "core/inspector/InspectedFrames.h"
50 #include "core/inspector/InspectorDOMAgent.h"
51 #include "core/inspector/InspectorOverlayHost.h"
52 #include "core/layout/api/LayoutViewItem.h"
53 #include "core/loader/EmptyClients.h"
54 #include "core/loader/FrameLoadRequest.h"
55 #include "core/page/ChromeClient.h"
56 #include "core/page/Page.h"
57 #include "platform/ScriptForbiddenScope.h"
58 #include "platform/graphics/Color.h"
59 #include "platform/graphics/GraphicsContext.h"
60 #include "platform/graphics/paint/CullRect.h"
61 #include "platform/wtf/AutoReset.h"
62 #include "public/platform/Platform.h"
63 #include "public/platform/WebData.h"
64 #include "v8/include/v8.h"
65 #include "web/ChromeClientImpl.h"
66 #include "web/PageOverlay.h"
67 #include "web/WebInputEventConversion.h"
68 #include "web/WebLocalFrameImpl.h"
69 #include "web/WebViewImpl.h"
70
71 namespace blink {
72
73 using protocol::Maybe;
74 using protocol::Response;
75
76 namespace {
77
78 namespace OverlayAgentState {
79 static const char kEnabled[] = "enabled";
80 static const char kShowDebugBorders[] = "showDebugBorders";
81 static const char kShowFPSCounter[] = "showFPSCounter";
82 static const char kShowPaintRects[] = "showPaintRects";
83 static const char kShowScrollBottleneckRects[] = "showScrollBottleneckRects";
84 static const char kShowSizeOnResize[] = "showSizeOnResize";
85 static const char kSuspended[] = "suspended";
86 static const char kPausedInDebuggerMessage[] = "pausedInDebuggerMessage";
87 }
88
89 Node* HoveredNodeForPoint(LocalFrame* frame,
90 const IntPoint& point_in_root_frame,
91 bool ignore_pointer_events_none) {
92 HitTestRequest::HitTestRequestType hit_type =
93 HitTestRequest::kMove | HitTestRequest::kReadOnly |
94 HitTestRequest::kAllowChildFrameContent;
95 if (ignore_pointer_events_none)
96 hit_type |= HitTestRequest::kIgnorePointerEventsNone;
97 HitTestRequest request(hit_type);
98 HitTestResult result(request,
99 frame->View()->RootFrameToContents(point_in_root_frame));
100 frame->ContentLayoutItem().HitTest(result);
101 Node* node = result.InnerPossiblyPseudoNode();
102 while (node && node->getNodeType() == Node::kTextNode)
103 node = node->parentNode();
104 return node;
105 }
106
107 Node* HoveredNodeForEvent(LocalFrame* frame,
108 const WebGestureEvent& event,
109 bool ignore_pointer_events_none) {
110 return HoveredNodeForPoint(frame,
111 RoundedIntPoint(event.PositionInRootFrame()),
112 ignore_pointer_events_none);
113 }
114
115 Node* HoveredNodeForEvent(LocalFrame* frame,
116 const WebMouseEvent& event,
117 bool ignore_pointer_events_none) {
118 return HoveredNodeForPoint(frame,
119 RoundedIntPoint(event.PositionInRootFrame()),
120 ignore_pointer_events_none);
121 }
122
123 Node* HoveredNodeForEvent(LocalFrame* frame,
124 const WebTouchEvent& event,
125 bool ignore_pointer_events_none) {
126 if (!event.touches_length)
127 return nullptr;
128 WebTouchPoint transformed_point = event.TouchPointInRootFrame(0);
129 return HoveredNodeForPoint(frame, RoundedIntPoint(transformed_point.position),
130 ignore_pointer_events_none);
131 }
132
133 bool ParseQuad(std::unique_ptr<protocol::Array<double>> quad_array,
134 FloatQuad* quad) {
135 const size_t kCoordinatesInQuad = 8;
136 if (!quad_array || quad_array->length() != kCoordinatesInQuad)
137 return false;
138 quad->SetP1(FloatPoint(quad_array->get(0), quad_array->get(1)));
139 quad->SetP2(FloatPoint(quad_array->get(2), quad_array->get(3)));
140 quad->SetP3(FloatPoint(quad_array->get(4), quad_array->get(5)));
141 quad->SetP4(FloatPoint(quad_array->get(6), quad_array->get(7)));
142 return true;
143 }
144
145 } // namespace
146
147 class InspectorOverlayAgent::InspectorPageOverlayDelegate final
148 : public PageOverlay::Delegate {
149 public:
150 explicit InspectorPageOverlayDelegate(InspectorOverlayAgent& overlay)
151 : overlay_(&overlay) {}
152
153 void PaintPageOverlay(const PageOverlay&,
154 GraphicsContext& graphics_context,
155 const WebSize& web_view_size) const override {
156 if (overlay_->IsEmpty())
157 return;
158
159 FrameView* view = overlay_->OverlayMainFrame()->View();
160 DCHECK(!view->NeedsLayout());
161 view->Paint(graphics_context,
162 CullRect(IntRect(0, 0, view->Width(), view->Height())));
163 }
164
165 private:
166 Persistent<InspectorOverlayAgent> overlay_;
167 };
168
169 class InspectorOverlayAgent::InspectorOverlayChromeClient final
170 : public EmptyChromeClient {
171 public:
172 static InspectorOverlayChromeClient* Create(ChromeClient& client,
173 InspectorOverlayAgent& overlay) {
174 return new InspectorOverlayChromeClient(client, overlay);
175 }
176
177 DEFINE_INLINE_VIRTUAL_TRACE() {
178 visitor->Trace(client_);
179 visitor->Trace(overlay_);
180 EmptyChromeClient::Trace(visitor);
181 }
182
183 void SetCursor(const Cursor& cursor, LocalFrame* local_root) override {
184 ToChromeClientImpl(client_)->SetCursorOverridden(false);
185 ToChromeClientImpl(client_)->SetCursor(cursor,
186 overlay_->frame_impl_->GetFrame());
187 ToChromeClientImpl(client_)->SetCursorOverridden(false);
188 }
189
190 void SetToolTip(LocalFrame& frame,
191 const String& tooltip,
192 TextDirection direction) override {
193 DCHECK_EQ(&frame, overlay_->OverlayMainFrame());
194 client_->SetToolTip(*overlay_->frame_impl_->GetFrame(), tooltip, direction);
195 }
196
197 void InvalidateRect(const IntRect&) override { overlay_->Invalidate(); }
198
199 void ScheduleAnimation(FrameViewBase* frame_view_base) override {
200 if (overlay_->in_layout_)
201 return;
202
203 client_->ScheduleAnimation(frame_view_base);
204 }
205
206 private:
207 InspectorOverlayChromeClient(ChromeClient& client,
208 InspectorOverlayAgent& overlay)
209 : client_(&client), overlay_(&overlay) {}
210
211 Member<ChromeClient> client_;
212 Member<InspectorOverlayAgent> overlay_;
213 };
214
215 InspectorOverlayAgent::InspectorOverlayAgent(
216 WebLocalFrameImpl* frame_impl,
217 InspectedFrames* inspected_frames,
218 v8_inspector::V8InspectorSession* v8_session,
219 InspectorDOMAgent* dom_agent)
220 : frame_impl_(frame_impl),
221 inspected_frames_(inspected_frames),
222 enabled_(false),
223 overlay_host_(new InspectorOverlayHost(this)),
224 draw_view_size_(false),
225 resize_timer_active_(false),
226 omit_tooltip_(false),
227 timer_(TaskRunnerHelper::Get(TaskType::kUnspecedTimer,
228 frame_impl->GetFrame()),
229 this,
230 &InspectorOverlayAgent::OnTimer),
231 suspended_(false),
232 show_reloading_blanket_(false),
233 in_layout_(false),
234 needs_update_(false),
235 v8_session_(v8_session),
236 dom_agent_(dom_agent),
237 swallow_next_mouse_up_(false),
238 inspect_mode_(kNotSearching),
239 backend_node_id_to_inspect_(0) {}
240
241 InspectorOverlayAgent::~InspectorOverlayAgent() {
242 DCHECK(!overlay_page_);
243 }
244
245 DEFINE_TRACE(InspectorOverlayAgent) {
246 visitor->Trace(frame_impl_);
247 visitor->Trace(inspected_frames_);
248 visitor->Trace(highlight_node_);
249 visitor->Trace(event_target_node_);
250 visitor->Trace(overlay_page_);
251 visitor->Trace(overlay_chrome_client_);
252 visitor->Trace(overlay_host_);
253 visitor->Trace(dom_agent_);
254 visitor->Trace(hovered_node_for_inspect_mode_);
255 InspectorBaseAgent::Trace(visitor);
256 }
257
258 void InspectorOverlayAgent::Restore() {
259 if (state_->booleanProperty(OverlayAgentState::kEnabled, false))
260 enabled_ = true;
261 setShowDebugBorders(
262 state_->booleanProperty(OverlayAgentState::kShowDebugBorders, false));
263 setShowFPSCounter(
264 state_->booleanProperty(OverlayAgentState::kShowFPSCounter, false));
265 setShowPaintRects(
266 state_->booleanProperty(OverlayAgentState::kShowPaintRects, false));
267 setShowScrollBottleneckRects(state_->booleanProperty(
268 OverlayAgentState::kShowScrollBottleneckRects, false));
269 setShowViewportSizeOnResize(
270 state_->booleanProperty(OverlayAgentState::kShowSizeOnResize, false));
271 String message;
272 state_->getString(OverlayAgentState::kPausedInDebuggerMessage, &message);
273 setPausedInDebuggerMessage(message);
274 setSuspended(state_->booleanProperty(OverlayAgentState::kSuspended, false));
275 }
276
277 Response InspectorOverlayAgent::enable() {
278 if (!dom_agent_->Enabled())
279 return Response::Error("DOM should be enabled first");
280 state_->setBoolean(OverlayAgentState::kEnabled, true);
281 enabled_ = true;
282 if (backend_node_id_to_inspect_)
283 GetFrontend()->inspectNodeRequested(backend_node_id_to_inspect_);
284 backend_node_id_to_inspect_ = 0;
285 return Response::OK();
286 }
287
288 Response InspectorOverlayAgent::disable() {
289 state_->setBoolean(OverlayAgentState::kEnabled, false);
290 enabled_ = false;
291 setShowDebugBorders(false);
292 setShowFPSCounter(false);
293 setShowPaintRects(false);
294 setShowScrollBottleneckRects(false);
295 setShowViewportSizeOnResize(false);
296 setPausedInDebuggerMessage(String());
297 setSuspended(false);
298 SetSearchingForNode(kNotSearching,
299 Maybe<protocol::Overlay::HighlightConfig>());
300 return Response::OK();
301 }
302
303 Response InspectorOverlayAgent::setShowDebugBorders(bool show) {
304 state_->setBoolean(OverlayAgentState::kShowDebugBorders, show);
305 if (show) {
306 Response response = CompositingEnabled();
307 if (!response.isSuccess())
308 return response;
309 }
310 frame_impl_->ViewImpl()->SetShowDebugBorders(show);
311 return Response::OK();
312 }
313
314 Response InspectorOverlayAgent::setShowFPSCounter(bool show) {
315 state_->setBoolean(OverlayAgentState::kShowFPSCounter, show);
316 if (show) {
317 Response response = CompositingEnabled();
318 if (!response.isSuccess())
319 return response;
320 }
321 frame_impl_->ViewImpl()->SetShowFPSCounter(show);
322 return Response::OK();
323 }
324
325 Response InspectorOverlayAgent::setShowPaintRects(bool show) {
326 state_->setBoolean(OverlayAgentState::kShowPaintRects, show);
327 if (show) {
328 Response response = CompositingEnabled();
329 if (!response.isSuccess())
330 return response;
331 }
332 frame_impl_->ViewImpl()->SetShowPaintRects(show);
333 if (!show && frame_impl_->GetFrameView())
334 frame_impl_->GetFrameView()->Invalidate();
335 return Response::OK();
336 }
337
338 Response InspectorOverlayAgent::setShowScrollBottleneckRects(bool show) {
339 state_->setBoolean(OverlayAgentState::kShowScrollBottleneckRects, show);
340 if (show) {
341 Response response = CompositingEnabled();
342 if (!response.isSuccess())
343 return response;
344 }
345 frame_impl_->ViewImpl()->SetShowScrollBottleneckRects(show);
346 return Response::OK();
347 }
348
349 Response InspectorOverlayAgent::setShowViewportSizeOnResize(bool show) {
350 state_->setBoolean(OverlayAgentState::kShowSizeOnResize, show);
351 draw_view_size_ = show;
352 return Response::OK();
353 }
354
355 Response InspectorOverlayAgent::setPausedInDebuggerMessage(
356 Maybe<String> message) {
357 String just_message = message.fromMaybe(String());
358 state_->setString(OverlayAgentState::kPausedInDebuggerMessage, just_message);
359 paused_in_debugger_message_ = just_message;
360 ScheduleUpdate();
361 return Response::OK();
362 }
363
364 Response InspectorOverlayAgent::setSuspended(bool suspended) {
365 state_->setBoolean(OverlayAgentState::kSuspended, suspended);
366 if (suspended && !suspended_ && !show_reloading_blanket_)
367 ClearInternal();
368 suspended_ = suspended;
369 return Response::OK();
370 }
371
372 Response InspectorOverlayAgent::setInspectMode(
373 const String& mode,
374 Maybe<protocol::Overlay::HighlightConfig> highlight_config) {
375 SearchMode search_mode;
376 if (mode == protocol::Overlay::InspectModeEnum::SearchForNode) {
377 search_mode = kSearchingForNormal;
378 } else if (mode == protocol::Overlay::InspectModeEnum::SearchForUAShadowDOM) {
379 search_mode = kSearchingForUAShadow;
380 } else if (mode == protocol::Overlay::InspectModeEnum::None) {
381 search_mode = kNotSearching;
382 } else {
383 return Response::Error(
384 String("Unknown mode \"" + mode + "\" was provided."));
385 }
386
387 if (search_mode != kNotSearching) {
388 Response response = dom_agent_->PushDocumentUponHandlelessOperation();
389 if (!response.isSuccess())
390 return response;
391 }
392
393 return SetSearchingForNode(search_mode, std::move(highlight_config));
394 }
395
396 Response InspectorOverlayAgent::highlightRect(
397 int x,
398 int y,
399 int width,
400 int height,
401 Maybe<protocol::DOM::RGBA> color,
402 Maybe<protocol::DOM::RGBA> outline_color) {
403 std::unique_ptr<FloatQuad> quad =
404 WTF::WrapUnique(new FloatQuad(FloatRect(x, y, width, height)));
405 InnerHighlightQuad(std::move(quad), std::move(color),
406 std::move(outline_color));
407 return Response::OK();
408 }
409
410 Response InspectorOverlayAgent::highlightQuad(
411 std::unique_ptr<protocol::Array<double>> quad_array,
412 Maybe<protocol::DOM::RGBA> color,
413 Maybe<protocol::DOM::RGBA> outline_color) {
414 std::unique_ptr<FloatQuad> quad = WTF::MakeUnique<FloatQuad>();
415 if (!ParseQuad(std::move(quad_array), quad.get()))
416 return Response::Error("Invalid Quad format");
417 InnerHighlightQuad(std::move(quad), std::move(color),
418 std::move(outline_color));
419 return Response::OK();
420 }
421
422 Response InspectorOverlayAgent::highlightNode(
423 std::unique_ptr<protocol::Overlay::HighlightConfig>
424 highlight_inspector_object,
425 Maybe<int> node_id,
426 Maybe<int> backend_node_id,
427 Maybe<String> object_id) {
428 Node* node = nullptr;
429 Response response;
430 if (node_id.isJust()) {
431 response = dom_agent_->AssertNode(node_id.fromJust(), node);
432 } else if (backend_node_id.isJust()) {
433 node = DOMNodeIds::NodeForId(backend_node_id.fromJust());
434 response = !node ? Response::Error("No node found for given backend id")
435 : Response::OK();
436 } else if (object_id.isJust()) {
437 response = dom_agent_->NodeForRemoteObjectId(object_id.fromJust(), node);
438 } else {
439 response = Response::Error(
440 "Either nodeId, backendNodeId or objectId must be specified");
441 }
442
443 if (!response.isSuccess())
444 return response;
445
446 std::unique_ptr<InspectorHighlightConfig> highlight_config;
447 response = HighlightConfigFromInspectorObject(
448 std::move(highlight_inspector_object), &highlight_config);
449 if (!response.isSuccess())
450 return response;
451
452 InnerHighlightNode(node, nullptr, *highlight_config, false);
453 return Response::OK();
454 }
455
456 Response InspectorOverlayAgent::highlightFrame(
457 const String& frame_id,
458 Maybe<protocol::DOM::RGBA> color,
459 Maybe<protocol::DOM::RGBA> outline_color) {
460 LocalFrame* frame =
461 IdentifiersFactory::FrameById(inspected_frames_, frame_id);
462 // FIXME: Inspector doesn't currently work cross process.
463 if (frame && frame->DeprecatedLocalOwner()) {
464 std::unique_ptr<InspectorHighlightConfig> highlight_config =
465 WTF::MakeUnique<InspectorHighlightConfig>();
466 highlight_config->show_info = true; // Always show tooltips for frames.
467 highlight_config->content =
468 InspectorDOMAgent::ParseColor(color.fromMaybe(nullptr));
469 highlight_config->content_outline =
470 InspectorDOMAgent::ParseColor(outline_color.fromMaybe(nullptr));
471 InnerHighlightNode(frame->DeprecatedLocalOwner(), nullptr,
472 *highlight_config, false);
473 }
474 return Response::OK();
475 }
476
477 Response InspectorOverlayAgent::hideHighlight() {
478 InnerHideHighlight();
479 return Response::OK();
480 }
481
482 Response InspectorOverlayAgent::getHighlightObjectForTest(
483 int node_id,
484 std::unique_ptr<protocol::DictionaryValue>* result) {
485 Node* node = nullptr;
486 Response response = dom_agent_->AssertNode(node_id, node);
487 if (!response.isSuccess())
488 return response;
489 InspectorHighlight highlight(node, InspectorHighlight::DefaultConfig(), true);
490 *result = highlight.AsProtocolValue();
491 return Response::OK();
492 }
493
494 void InspectorOverlayAgent::Invalidate() {
495 if (!page_overlay_) {
496 page_overlay_ = PageOverlay::Create(
497 frame_impl_, WTF::WrapUnique(new InspectorPageOverlayDelegate(*this)));
498 }
499
500 page_overlay_->Update();
501 }
502
503 void InspectorOverlayAgent::UpdateAllLifecyclePhases() {
504 if (IsEmpty())
505 return;
506
507 AutoReset<bool> scoped(&in_layout_, true);
508 if (needs_update_) {
509 needs_update_ = false;
510 RebuildOverlayPage();
511 }
512 OverlayMainFrame()->View()->UpdateAllLifecyclePhases();
513 }
514
515 bool InspectorOverlayAgent::HandleInputEvent(const WebInputEvent& input_event) {
516 bool handled = false;
517
518 if (IsEmpty())
519 return false;
520
521 if (input_event.GetType() == WebInputEvent::kGestureTap) {
522 // We only have a use for gesture tap.
523 WebGestureEvent transformed_event = TransformWebGestureEvent(
524 frame_impl_->GetFrameView(),
525 static_cast<const WebGestureEvent&>(input_event));
526 handled = HandleGestureEvent(transformed_event);
527 if (handled)
528 return true;
529
530 OverlayMainFrame()->GetEventHandler().HandleGestureEvent(transformed_event);
531 }
532 if (WebInputEvent::IsMouseEventType(input_event.GetType())) {
533 WebMouseEvent mouse_event =
534 TransformWebMouseEvent(frame_impl_->GetFrameView(),
535 static_cast<const WebMouseEvent&>(input_event));
536
537 if (mouse_event.GetType() == WebInputEvent::kMouseMove)
538 handled = HandleMouseMove(mouse_event);
539 else if (mouse_event.GetType() == WebInputEvent::kMouseDown)
540 handled = HandleMouseDown();
541 else if (mouse_event.GetType() == WebInputEvent::kMouseUp)
542 handled = HandleMouseUp();
543
544 if (handled)
545 return true;
546
547 if (mouse_event.GetType() == WebInputEvent::kMouseMove) {
548 handled = OverlayMainFrame()->GetEventHandler().HandleMouseMoveEvent(
549 mouse_event, TransformWebMouseEventVector(
550 frame_impl_->GetFrameView(),
551 std::vector<const WebInputEvent*>())) !=
552 WebInputEventResult::kNotHandled;
553 }
554 if (mouse_event.GetType() == WebInputEvent::kMouseDown) {
555 handled = OverlayMainFrame()->GetEventHandler().HandleMousePressEvent(
556 mouse_event) != WebInputEventResult::kNotHandled;
557 }
558 if (mouse_event.GetType() == WebInputEvent::kMouseUp) {
559 handled = OverlayMainFrame()->GetEventHandler().HandleMouseReleaseEvent(
560 mouse_event) != WebInputEventResult::kNotHandled;
561 }
562 }
563
564 if (WebInputEvent::IsTouchEventType(input_event.GetType())) {
565 WebTouchEvent transformed_event =
566 TransformWebTouchEvent(frame_impl_->GetFrameView(),
567 static_cast<const WebTouchEvent&>(input_event));
568 handled = HandleTouchEvent(transformed_event);
569 if (handled)
570 return true;
571 OverlayMainFrame()->GetEventHandler().HandleTouchEvent(
572 transformed_event, Vector<WebTouchEvent>());
573 }
574 if (WebInputEvent::IsKeyboardEventType(input_event.GetType())) {
575 OverlayMainFrame()->GetEventHandler().KeyEvent(
576 static_cast<const WebKeyboardEvent&>(input_event));
577 }
578
579 if (input_event.GetType() == WebInputEvent::kMouseWheel) {
580 WebMouseWheelEvent transformed_event = TransformWebMouseWheelEvent(
581 frame_impl_->GetFrameView(),
582 static_cast<const WebMouseWheelEvent&>(input_event));
583 handled = OverlayMainFrame()->GetEventHandler().HandleWheelEvent(
584 transformed_event) != WebInputEventResult::kNotHandled;
585 }
586
587 return handled;
588 }
589
590 void InspectorOverlayAgent::ShowReloadingBlanket() {
591 show_reloading_blanket_ = true;
592 ScheduleUpdate();
593 }
594
595 void InspectorOverlayAgent::HideReloadingBlanket() {
596 if (!show_reloading_blanket_)
597 return;
598 show_reloading_blanket_ = false;
599 if (suspended_)
600 ClearInternal();
601 else
602 ScheduleUpdate();
603 }
604
605 void InspectorOverlayAgent::InnerHideHighlight() {
606 highlight_node_.Clear();
607 event_target_node_.Clear();
608 highlight_quad_.reset();
609 ScheduleUpdate();
610 }
611
612 void InspectorOverlayAgent::InnerHighlightNode(
613 Node* node,
614 Node* event_target,
615 const InspectorHighlightConfig& highlight_config,
616 bool omit_tooltip) {
617 node_highlight_config_ = highlight_config;
618 highlight_node_ = node;
619 event_target_node_ = event_target;
620 omit_tooltip_ = omit_tooltip;
621 ScheduleUpdate();
622 }
623
624 void InspectorOverlayAgent::InnerHighlightQuad(
625 std::unique_ptr<FloatQuad> quad,
626 Maybe<protocol::DOM::RGBA> color,
627 Maybe<protocol::DOM::RGBA> outline_color) {
628 quad_content_color_ = InspectorDOMAgent::ParseColor(color.fromMaybe(nullptr));
629 quad_content_outline_color_ =
630 InspectorDOMAgent::ParseColor(outline_color.fromMaybe(nullptr));
631 highlight_quad_ = std::move(quad);
632 omit_tooltip_ = false;
633 ScheduleUpdate();
634 }
635
636 bool InspectorOverlayAgent::IsEmpty() {
637 if (show_reloading_blanket_)
638 return false;
639 if (suspended_)
640 return true;
641 bool has_visible_elements = highlight_node_ || event_target_node_ ||
642 highlight_quad_ ||
643 (resize_timer_active_ && draw_view_size_) ||
644 !paused_in_debugger_message_.IsNull();
645 return !has_visible_elements && inspect_mode_ == kNotSearching;
646 }
647
648 void InspectorOverlayAgent::ScheduleUpdate() {
649 if (IsEmpty()) {
650 if (page_overlay_)
651 page_overlay_.reset();
652 return;
653 }
654 needs_update_ = true;
655 FrameView* view = frame_impl_->GetFrameView();
656 LocalFrame* frame = frame_impl_->GetFrame();
657 if (view && frame)
658 frame->GetPage()->GetChromeClient().ScheduleAnimation(view);
659 }
660
661 void InspectorOverlayAgent::RebuildOverlayPage() {
662 FrameView* view = frame_impl_->GetFrameView();
663 LocalFrame* frame = frame_impl_->GetFrame();
664 if (!view || !frame)
665 return;
666
667 IntRect visible_rect_in_document =
668 view->GetScrollableArea()->VisibleContentRect();
669 IntSize viewport_size = frame->GetPage()->GetVisualViewport().Size();
670 OverlayMainFrame()->View()->Resize(viewport_size);
671 OverlayPage()->GetVisualViewport().SetSize(viewport_size);
672 OverlayMainFrame()->SetPageZoomFactor(WindowToViewportScale());
673
674 Reset(viewport_size, visible_rect_in_document.Location());
675
676 if (show_reloading_blanket_) {
677 EvaluateInOverlay("showReloadingBlanket", "");
678 return;
679 }
680 DrawNodeHighlight();
681 DrawQuadHighlight();
682 DrawPausedInDebuggerMessage();
683 DrawViewSize();
684 }
685
686 static std::unique_ptr<protocol::DictionaryValue> BuildObjectForSize(
687 const IntSize& size) {
688 std::unique_ptr<protocol::DictionaryValue> result =
689 protocol::DictionaryValue::create();
690 result->setInteger("width", size.Width());
691 result->setInteger("height", size.Height());
692 return result;
693 }
694
695 void InspectorOverlayAgent::DrawNodeHighlight() {
696 if (!highlight_node_)
697 return;
698
699 String selectors = node_highlight_config_.selector_list;
700 StaticElementList* elements = nullptr;
701 DummyExceptionStateForTesting exception_state;
702 ContainerNode* query_base = highlight_node_->ContainingShadowRoot();
703 if (!query_base)
704 query_base = highlight_node_->ownerDocument();
705 if (selectors.length()) {
706 elements =
707 query_base->QuerySelectorAll(AtomicString(selectors), exception_state);
708 }
709 if (elements && !exception_state.HadException()) {
710 for (unsigned i = 0; i < elements->length(); ++i) {
711 Element* element = elements->item(i);
712 InspectorHighlight highlight(element, node_highlight_config_, false);
713 std::unique_ptr<protocol::DictionaryValue> highlight_json =
714 highlight.AsProtocolValue();
715 EvaluateInOverlay("drawHighlight", std::move(highlight_json));
716 }
717 }
718
719 bool append_element_info =
720 highlight_node_->IsElementNode() && !omit_tooltip_ &&
721 node_highlight_config_.show_info && highlight_node_->GetLayoutObject() &&
722 highlight_node_->GetDocument().GetFrame();
723 InspectorHighlight highlight(highlight_node_.Get(), node_highlight_config_,
724 append_element_info);
725 if (event_target_node_) {
726 highlight.AppendEventTargetQuads(event_target_node_.Get(),
727 node_highlight_config_);
728 }
729
730 std::unique_ptr<protocol::DictionaryValue> highlight_json =
731 highlight.AsProtocolValue();
732 EvaluateInOverlay("drawHighlight", std::move(highlight_json));
733 }
734
735 void InspectorOverlayAgent::DrawQuadHighlight() {
736 if (!highlight_quad_)
737 return;
738
739 InspectorHighlight highlight(WindowToViewportScale());
740 highlight.AppendQuad(*highlight_quad_, quad_content_color_,
741 quad_content_outline_color_);
742 EvaluateInOverlay("drawHighlight", highlight.AsProtocolValue());
743 }
744
745 void InspectorOverlayAgent::DrawPausedInDebuggerMessage() {
746 if (inspect_mode_ == kNotSearching && !paused_in_debugger_message_.IsNull()) {
747 EvaluateInOverlay("drawPausedInDebuggerMessage",
748 paused_in_debugger_message_);
749 }
750 }
751
752 void InspectorOverlayAgent::DrawViewSize() {
753 if (resize_timer_active_ && draw_view_size_)
754 EvaluateInOverlay("drawViewSize", "");
755 }
756
757 float InspectorOverlayAgent::WindowToViewportScale() const {
758 LocalFrame* frame = frame_impl_->GetFrame();
759 if (!frame)
760 return 1.0f;
761 return frame->GetPage()->GetChromeClient().WindowToViewportScalar(1.0f);
762 }
763
764 Page* InspectorOverlayAgent::OverlayPage() {
765 if (overlay_page_)
766 return overlay_page_.Get();
767
768 ScriptForbiddenScope::AllowUserAgentScript allow_script;
769
770 DEFINE_STATIC_LOCAL(LocalFrameClient, dummy_local_frame_client,
771 (EmptyLocalFrameClient::Create()));
772 Page::PageClients page_clients;
773 FillWithEmptyClients(page_clients);
774 DCHECK(!overlay_chrome_client_);
775 overlay_chrome_client_ = InspectorOverlayChromeClient::Create(
776 frame_impl_->GetFrame()->GetPage()->GetChromeClient(), *this);
777 page_clients.chrome_client = overlay_chrome_client_.Get();
778 overlay_page_ = Page::Create(page_clients);
779
780 Settings& settings = frame_impl_->GetFrame()->GetPage()->GetSettings();
781 Settings& overlay_settings = overlay_page_->GetSettings();
782
783 overlay_settings.GetGenericFontFamilySettings().UpdateStandard(
784 settings.GetGenericFontFamilySettings().Standard());
785 overlay_settings.GetGenericFontFamilySettings().UpdateSerif(
786 settings.GetGenericFontFamilySettings().Serif());
787 overlay_settings.GetGenericFontFamilySettings().UpdateSansSerif(
788 settings.GetGenericFontFamilySettings().SansSerif());
789 overlay_settings.GetGenericFontFamilySettings().UpdateCursive(
790 settings.GetGenericFontFamilySettings().Cursive());
791 overlay_settings.GetGenericFontFamilySettings().UpdateFantasy(
792 settings.GetGenericFontFamilySettings().Fantasy());
793 overlay_settings.GetGenericFontFamilySettings().UpdatePictograph(
794 settings.GetGenericFontFamilySettings().Pictograph());
795 overlay_settings.SetMinimumFontSize(settings.GetMinimumFontSize());
796 overlay_settings.SetMinimumLogicalFontSize(
797 settings.GetMinimumLogicalFontSize());
798 overlay_settings.SetScriptEnabled(true);
799 overlay_settings.SetPluginsEnabled(false);
800 overlay_settings.SetLoadsImagesAutomatically(true);
801 // FIXME: http://crbug.com/363843. Inspector should probably create its
802 // own graphics layers and attach them to the tree rather than going
803 // through some non-composited paint function.
804 overlay_settings.SetAcceleratedCompositingEnabled(false);
805
806 LocalFrame* frame =
807 LocalFrame::Create(&dummy_local_frame_client, *overlay_page_, 0);
808 frame->SetView(FrameView::Create(*frame));
809 frame->Init();
810 FrameLoader& loader = frame->Loader();
811 frame->View()->SetCanHaveScrollbars(false);
812 frame->View()->SetBaseBackgroundColor(Color::kTransparent);
813
814 const WebData& overlay_page_html_resource =
815 Platform::Current()->LoadResource("InspectorOverlayPage.html");
816 loader.Load(
817 FrameLoadRequest(0, ResourceRequest(BlankURL()),
818 SubstituteData(overlay_page_html_resource, "text/html",
819 "UTF-8", KURL(), kForceSynchronousLoad)));
820 v8::Isolate* isolate = ToIsolate(frame);
821 ScriptState* script_state = ToScriptStateForMainWorld(frame);
822 DCHECK(script_state);
823 ScriptState::Scope scope(script_state);
824 v8::Local<v8::Object> global = script_state->GetContext()->Global();
825 v8::Local<v8::Value> overlay_host_obj =
826 ToV8(overlay_host_.Get(), global, isolate);
827 DCHECK(!overlay_host_obj.IsEmpty());
828 global
829 ->Set(script_state->GetContext(),
830 V8AtomicString(isolate, "InspectorOverlayHost"), overlay_host_obj)
831 .ToChecked();
832
833 #if OS(WIN)
834 EvaluateInOverlay("setPlatform", "windows");
835 #elif OS(MACOSX)
836 EvaluateInOverlay("setPlatform", "mac");
837 #elif OS(POSIX)
838 EvaluateInOverlay("setPlatform", "linux");
839 #endif
840
841 return overlay_page_.Get();
842 }
843
844 LocalFrame* InspectorOverlayAgent::OverlayMainFrame() {
845 return ToLocalFrame(OverlayPage()->MainFrame());
846 }
847
848 void InspectorOverlayAgent::Reset(const IntSize& viewport_size,
849 const IntPoint& document_scroll_offset) {
850 std::unique_ptr<protocol::DictionaryValue> reset_data =
851 protocol::DictionaryValue::create();
852 reset_data->setDouble(
853 "deviceScaleFactor",
854 frame_impl_->GetFrame()->GetPage()->DeviceScaleFactorDeprecated());
855 reset_data->setDouble(
856 "pageScaleFactor",
857 frame_impl_->GetFrame()->GetPage()->GetVisualViewport().Scale());
858
859 IntRect viewport_in_screen =
860 frame_impl_->GetFrame()->GetPage()->GetChromeClient().ViewportToScreen(
861 IntRect(IntPoint(), viewport_size), frame_impl_->GetFrame()->View());
862 reset_data->setObject("viewportSize",
863 BuildObjectForSize(viewport_in_screen.Size()));
864
865 // The zoom factor in the overlay frame already has been multiplied by the
866 // window to viewport scale (aka device scale factor), so cancel it.
867 reset_data->setDouble(
868 "pageZoomFactor",
869 frame_impl_->GetFrame()->PageZoomFactor() / WindowToViewportScale());
870
871 reset_data->setInteger("scrollX", document_scroll_offset.X());
872 reset_data->setInteger("scrollY", document_scroll_offset.Y());
873 EvaluateInOverlay("reset", std::move(reset_data));
874 }
875
876 void InspectorOverlayAgent::EvaluateInOverlay(const String& method,
877 const String& argument) {
878 ScriptForbiddenScope::AllowUserAgentScript allow_script;
879 std::unique_ptr<protocol::ListValue> command = protocol::ListValue::create();
880 command->pushValue(protocol::StringValue::create(method));
881 command->pushValue(protocol::StringValue::create(argument));
882 ToLocalFrame(OverlayPage()->MainFrame())
883 ->GetScriptController()
884 .ExecuteScriptInMainWorld(
885 "dispatch(" + command->serialize() + ")",
886 ScriptController::kExecuteScriptWhenScriptsDisabled);
887 }
888
889 void InspectorOverlayAgent::EvaluateInOverlay(
890 const String& method,
891 std::unique_ptr<protocol::Value> argument) {
892 ScriptForbiddenScope::AllowUserAgentScript allow_script;
893 std::unique_ptr<protocol::ListValue> command = protocol::ListValue::create();
894 command->pushValue(protocol::StringValue::create(method));
895 command->pushValue(std::move(argument));
896 ToLocalFrame(OverlayPage()->MainFrame())
897 ->GetScriptController()
898 .ExecuteScriptInMainWorld(
899 "dispatch(" + command->serialize() + ")",
900 ScriptController::kExecuteScriptWhenScriptsDisabled);
901 }
902
903 String InspectorOverlayAgent::EvaluateInOverlayForTest(const String& script) {
904 ScriptForbiddenScope::AllowUserAgentScript allow_script;
905 v8::HandleScope handle_scope(ToIsolate(OverlayMainFrame()));
906 v8::Local<v8::Value> string =
907 ToLocalFrame(OverlayPage()->MainFrame())
908 ->GetScriptController()
909 .ExecuteScriptInMainWorldAndReturnValue(
910 ScriptSourceCode(script),
911 ScriptController::kExecuteScriptWhenScriptsDisabled);
912 return ToCoreStringWithUndefinedOrNullCheck(string);
913 }
914
915 void InspectorOverlayAgent::OnTimer(TimerBase*) {
916 resize_timer_active_ = false;
917 ScheduleUpdate();
918 }
919
920 void InspectorOverlayAgent::ClearInternal() {
921 if (overlay_page_) {
922 overlay_page_->WillBeDestroyed();
923 overlay_page_.Clear();
924 overlay_chrome_client_.Clear();
925 }
926 resize_timer_active_ = false;
927 paused_in_debugger_message_ = String();
928 inspect_mode_ = kNotSearching;
929 timer_.Stop();
930 InnerHideHighlight();
931 }
932
933 void InspectorOverlayAgent::OverlayResumed() {
934 if (v8_session_)
935 v8_session_->resume();
936 }
937
938 void InspectorOverlayAgent::OverlaySteppedOver() {
939 if (v8_session_)
940 v8_session_->stepOver();
941 }
942
943 void InspectorOverlayAgent::PageLayoutInvalidated(bool resized) {
944 if (resized && draw_view_size_) {
945 resize_timer_active_ = true;
946 timer_.StartOneShot(1, BLINK_FROM_HERE);
947 }
948 ScheduleUpdate();
949 }
950
951 bool InspectorOverlayAgent::HandleMouseMove(const WebMouseEvent& event) {
952 if (!ShouldSearchForNode())
953 return false;
954
955 LocalFrame* frame = frame_impl_->GetFrame();
956 if (!frame || !frame->View() || frame->ContentLayoutItem().IsNull())
957 return false;
958 Node* node = HoveredNodeForEvent(
959 frame, event, event.GetModifiers() & WebInputEvent::kShiftKey);
960
961 // Do not highlight within user agent shadow root unless requested.
962 if (inspect_mode_ != kSearchingForUAShadow) {
963 ShadowRoot* shadow_root = InspectorDOMAgent::UserAgentShadowRoot(node);
964 if (shadow_root)
965 node = &shadow_root->host();
966 }
967
968 // Shadow roots don't have boxes - use host element instead.
969 if (node && node->IsShadowRoot())
970 node = node->ParentOrShadowHostNode();
971
972 if (!node)
973 return true;
974
975 if (node->IsFrameOwnerElement()) {
976 HTMLFrameOwnerElement* frame_owner = ToHTMLFrameOwnerElement(node);
977 if (frame_owner->ContentFrame() &&
978 !frame_owner->ContentFrame()->IsLocalFrame()) {
979 // Do not consume event so that remote frame can handle it.
980 InnerHideHighlight();
981 hovered_node_for_inspect_mode_.Clear();
982 return false;
983 }
984 }
985
986 Node* event_target = (event.GetModifiers() & WebInputEvent::kShiftKey)
987 ? HoveredNodeForEvent(frame, event, false)
988 : nullptr;
989 if (event_target == node)
990 event_target = nullptr;
991
992 if (node && inspect_mode_highlight_config_) {
993 hovered_node_for_inspect_mode_ = node;
994 NodeHighlightRequested(node);
995 bool omit_tooltip = event.GetModifiers() &
996 (WebInputEvent::kControlKey | WebInputEvent::kMetaKey);
997 InnerHighlightNode(node, event_target, *inspect_mode_highlight_config_,
998 omit_tooltip);
999 }
1000 return true;
1001 }
1002
1003 bool InspectorOverlayAgent::HandleMouseDown() {
1004 swallow_next_mouse_up_ = false;
1005 if (!ShouldSearchForNode())
1006 return false;
1007
1008 if (hovered_node_for_inspect_mode_) {
1009 swallow_next_mouse_up_ = true;
1010 Inspect(hovered_node_for_inspect_mode_.Get());
1011 hovered_node_for_inspect_mode_.Clear();
1012 return true;
1013 }
1014 return false;
1015 }
1016
1017 bool InspectorOverlayAgent::HandleMouseUp() {
1018 if (swallow_next_mouse_up_) {
1019 swallow_next_mouse_up_ = false;
1020 return true;
1021 }
1022 return false;
1023 }
1024
1025 bool InspectorOverlayAgent::HandleGestureEvent(const WebGestureEvent& event) {
1026 if (!ShouldSearchForNode() || event.GetType() != WebInputEvent::kGestureTap)
1027 return false;
1028 Node* node = HoveredNodeForEvent(frame_impl_->GetFrame(), event, false);
1029 if (node && inspect_mode_highlight_config_) {
1030 InnerHighlightNode(node, nullptr, *inspect_mode_highlight_config_, false);
1031 Inspect(node);
1032 return true;
1033 }
1034 return false;
1035 }
1036
1037 bool InspectorOverlayAgent::HandleTouchEvent(const WebTouchEvent& event) {
1038 if (!ShouldSearchForNode())
1039 return false;
1040 Node* node = HoveredNodeForEvent(frame_impl_->GetFrame(), event, false);
1041 if (node && inspect_mode_highlight_config_) {
1042 InnerHighlightNode(node, nullptr, *inspect_mode_highlight_config_, false);
1043 Inspect(node);
1044 return true;
1045 }
1046 return false;
1047 }
1048
1049 Response InspectorOverlayAgent::CompositingEnabled() {
1050 bool main_frame = frame_impl_->ViewImpl() && !frame_impl_->Parent();
1051 if (!main_frame || !frame_impl_->ViewImpl()
1052 ->GetPage()
1053 ->GetSettings()
1054 .GetAcceleratedCompositingEnabled())
1055 return Response::Error("Compositing mode is not supported");
1056 return Response::OK();
1057 }
1058
1059 bool InspectorOverlayAgent::ShouldSearchForNode() {
1060 return inspect_mode_ != kNotSearching;
1061 }
1062
1063 void InspectorOverlayAgent::Inspect(Node* inspected_node) {
1064 if (!inspected_node)
1065 return;
1066
1067 Node* node = inspected_node;
1068 while (node && !node->IsElementNode() && !node->IsDocumentNode() &&
1069 !node->IsDocumentFragment())
1070 node = node->ParentOrShadowHostNode();
1071 if (!node)
1072 return;
1073
1074 int backend_node_id = DOMNodeIds::IdForNode(node);
1075 if (!enabled_) {
1076 backend_node_id_to_inspect_ = backend_node_id;
1077 return;
1078 }
1079
1080 GetFrontend()->inspectNodeRequested(backend_node_id);
1081 }
1082
1083 void InspectorOverlayAgent::NodeHighlightRequested(Node* node) {
1084 if (!enabled_)
1085 return;
1086
1087 while (node && !node->IsElementNode() && !node->IsDocumentNode() &&
1088 !node->IsDocumentFragment())
1089 node = node->ParentOrShadowHostNode();
1090
1091 if (!node)
1092 return;
1093
1094 int node_id = dom_agent_->PushNodePathToFrontend(node);
1095 GetFrontend()->nodeHighlightRequested(node_id);
1096 }
1097
1098 Response InspectorOverlayAgent::SetSearchingForNode(
1099 SearchMode search_mode,
1100 Maybe<protocol::Overlay::HighlightConfig> highlight_inspector_object) {
1101 if (search_mode == kNotSearching) {
1102 inspect_mode_ = search_mode;
1103 ScheduleUpdate();
1104 hovered_node_for_inspect_mode_.Clear();
1105 InnerHideHighlight();
1106 return Response::OK();
1107 }
1108
1109 std::unique_ptr<InspectorHighlightConfig> config;
1110 Response response = HighlightConfigFromInspectorObject(
1111 std::move(highlight_inspector_object), &config);
1112 if (!response.isSuccess())
1113 return response;
1114 inspect_mode_ = search_mode;
1115 inspect_mode_highlight_config_ = std::move(config);
1116 ScheduleUpdate();
1117 return Response::OK();
1118 }
1119
1120 Response InspectorOverlayAgent::HighlightConfigFromInspectorObject(
1121 Maybe<protocol::Overlay::HighlightConfig> highlight_inspector_object,
1122 std::unique_ptr<InspectorHighlightConfig>* out_config) {
1123 if (!highlight_inspector_object.isJust()) {
1124 return Response::Error(
1125 "Internal error: highlight configuration parameter is missing");
1126 }
1127
1128 protocol::Overlay::HighlightConfig* config =
1129 highlight_inspector_object.fromJust();
1130 std::unique_ptr<InspectorHighlightConfig> highlight_config =
1131 WTF::MakeUnique<InspectorHighlightConfig>();
1132 highlight_config->show_info = config->getShowInfo(false);
1133 highlight_config->show_rulers = config->getShowRulers(false);
1134 highlight_config->show_extension_lines = config->getShowExtensionLines(false);
1135 highlight_config->display_as_material = config->getDisplayAsMaterial(false);
1136 highlight_config->content =
1137 InspectorDOMAgent::ParseColor(config->getContentColor(nullptr));
1138 highlight_config->padding =
1139 InspectorDOMAgent::ParseColor(config->getPaddingColor(nullptr));
1140 highlight_config->border =
1141 InspectorDOMAgent::ParseColor(config->getBorderColor(nullptr));
1142 highlight_config->margin =
1143 InspectorDOMAgent::ParseColor(config->getMarginColor(nullptr));
1144 highlight_config->event_target =
1145 InspectorDOMAgent::ParseColor(config->getEventTargetColor(nullptr));
1146 highlight_config->shape =
1147 InspectorDOMAgent::ParseColor(config->getShapeColor(nullptr));
1148 highlight_config->shape_margin =
1149 InspectorDOMAgent::ParseColor(config->getShapeMarginColor(nullptr));
1150 highlight_config->selector_list = config->getSelectorList("");
1151
1152 *out_config = std::move(highlight_config);
1153 return Response::OK();
1154 }
1155
1156 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/web/InspectorOverlayAgent.h ('k') | third_party/WebKit/Source/web/InspectorRenderingAgent.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698