Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / third_party / WebKit / Source / web / InspectorOverlayImpl.cpp
blob445213eb9c34fbf79e44f15c982c377ed767d7cb
1 /*
2 * Copyright (C) 2011 Google Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
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.
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.
29 #include "config.h"
30 #include "web/InspectorOverlayImpl.h"
32 #include "bindings/core/v8/ScriptController.h"
33 #include "bindings/core/v8/V8InspectorOverlayHost.h"
34 #include "core/dom/Node.h"
35 #include "core/frame/FrameHost.h"
36 #include "core/frame/FrameView.h"
37 #include "core/frame/LocalFrame.h"
38 #include "core/frame/Settings.h"
39 #include "core/input/EventHandler.h"
40 #include "core/inspector/InspectorCSSAgent.h"
41 #include "core/inspector/InspectorDebuggerAgent.h"
42 #include "core/inspector/InspectorOverlayHost.h"
43 #include "core/inspector/LayoutEditor.h"
44 #include "core/layout/LayoutView.h"
45 #include "core/loader/EmptyClients.h"
46 #include "core/loader/FrameLoadRequest.h"
47 #include "core/page/ChromeClient.h"
48 #include "core/page/Page.h"
49 #include "platform/JSONValues.h"
50 #include "platform/ScriptForbiddenScope.h"
51 #include "platform/graphics/GraphicsContext.h"
52 #include "public/platform/Platform.h"
53 #include "public/platform/WebData.h"
54 #include "web/PageOverlay.h"
55 #include "web/WebGraphicsContextImpl.h"
56 #include "web/WebInputEventConversion.h"
57 #include "web/WebLocalFrameImpl.h"
58 #include "web/WebViewImpl.h"
59 #include <v8.h>
61 namespace blink {
63 namespace {
65 Node* hoveredNodeForPoint(LocalFrame* frame, const IntPoint& pointInRootFrame, bool ignorePointerEventsNone)
67 HitTestRequest::HitTestRequestType hitType = HitTestRequest::Move | HitTestRequest::ReadOnly | HitTestRequest::AllowChildFrameContent;
68 if (ignorePointerEventsNone)
69 hitType |= HitTestRequest::IgnorePointerEventsNone;
70 HitTestRequest request(hitType);
71 HitTestResult result(request, frame->view()->rootFrameToContents(pointInRootFrame));
72 frame->contentLayoutObject()->hitTest(result);
73 Node* node = result.innerPossiblyPseudoNode();
74 while (node && node->nodeType() == Node::TEXT_NODE)
75 node = node->parentNode();
76 return node;
79 Node* hoveredNodeForEvent(LocalFrame* frame, const PlatformGestureEvent& event, bool ignorePointerEventsNone)
81 return hoveredNodeForPoint(frame, event.position(), ignorePointerEventsNone);
84 Node* hoveredNodeForEvent(LocalFrame* frame, const PlatformMouseEvent& event, bool ignorePointerEventsNone)
86 return hoveredNodeForPoint(frame, event.position(), ignorePointerEventsNone);
89 Node* hoveredNodeForEvent(LocalFrame* frame, const PlatformTouchEvent& event, bool ignorePointerEventsNone)
91 const Vector<PlatformTouchPoint>& points = event.touchPoints();
92 if (!points.size())
93 return nullptr;
94 return hoveredNodeForPoint(frame, roundedIntPoint(points[0].pos()), ignorePointerEventsNone);
96 } // namespace
98 class InspectorOverlayImpl::InspectorPageOverlayDelegate final : public PageOverlay::Delegate {
99 public:
100 explicit InspectorPageOverlayDelegate(InspectorOverlayImpl& overlay)
101 : m_overlay(&overlay)
104 DEFINE_INLINE_VIRTUAL_TRACE()
106 visitor->trace(m_overlay);
107 PageOverlay::Delegate::trace(visitor);
110 void paintPageOverlay(WebGraphicsContext* context, const WebSize& webViewSize)
112 if (m_overlay->isEmpty())
113 return;
115 GraphicsContext& graphicsContext = toWebGraphicsContextImpl(context)->graphicsContext();
116 FrameView* view = m_overlay->overlayMainFrame()->view();
117 ASSERT(!view->needsLayout());
118 view->paint(&graphicsContext, IntRect(0, 0, view->width(), view->height()));
121 private:
122 RawPtrWillBeMember<InspectorOverlayImpl> m_overlay;
126 class InspectorOverlayImpl::InspectorOverlayChromeClient final : public EmptyChromeClient {
127 public:
128 static PassOwnPtrWillBeRawPtr<InspectorOverlayChromeClient> create(ChromeClient& client, InspectorOverlayImpl& overlay)
130 return adoptPtrWillBeNoop(new InspectorOverlayChromeClient(client, overlay));
133 DEFINE_INLINE_VIRTUAL_TRACE()
135 visitor->trace(m_client);
136 visitor->trace(m_overlay);
137 EmptyChromeClient::trace(visitor);
140 void setCursor(const Cursor& cursor) override
142 toChromeClientImpl(m_client)->setCursorOverridden(false);
143 toChromeClientImpl(m_client)->setCursor(cursor);
144 bool overrideCursor = m_overlay->m_layoutEditor;
145 toChromeClientImpl(m_client)->setCursorOverridden(overrideCursor);
148 void setToolTip(const String& tooltip, TextDirection direction) override
150 m_client->setToolTip(tooltip, direction);
153 void invalidateRect(const IntRect&) override
155 m_overlay->invalidate();
158 void scheduleAnimation() override
160 if (m_overlay->m_inLayout)
161 return;
163 m_client->scheduleAnimation();
166 private:
167 InspectorOverlayChromeClient(ChromeClient& client, InspectorOverlayImpl& overlay)
168 : m_client(&client)
169 , m_overlay(&overlay)
172 RawPtrWillBeMember<ChromeClient> m_client;
173 RawPtrWillBeMember<InspectorOverlayImpl> m_overlay;
177 InspectorOverlayImpl::InspectorOverlayImpl(WebViewImpl* webViewImpl)
178 : m_webViewImpl(webViewImpl)
179 , m_overlayHost(InspectorOverlayHost::create())
180 , m_drawViewSize(false)
181 , m_drawViewSizeWithGrid(false)
182 , m_resizeTimerActive(false)
183 , m_omitTooltip(false)
184 , m_timer(this, &InspectorOverlayImpl::onTimer)
185 , m_suspendCount(0)
186 , m_inLayout(false)
187 , m_needsUpdate(false)
188 , m_inspectMode(InspectorDOMAgent::NotSearching)
192 InspectorOverlayImpl::~InspectorOverlayImpl()
194 ASSERT(!m_overlayPage);
197 DEFINE_TRACE(InspectorOverlayImpl)
199 visitor->trace(m_highlightNode);
200 visitor->trace(m_eventTargetNode);
201 visitor->trace(m_overlayPage);
202 visitor->trace(m_overlayChromeClient);
203 visitor->trace(m_overlayHost);
204 visitor->trace(m_debuggerAgent);
205 visitor->trace(m_domAgent);
206 visitor->trace(m_cssAgent);
207 visitor->trace(m_layoutEditor);
208 visitor->trace(m_hoveredNodeForInspectMode);
211 void InspectorOverlayImpl::init(InspectorCSSAgent* cssAgent, InspectorDebuggerAgent* debuggerAgent, InspectorDOMAgent* domAgent)
213 m_debuggerAgent = debuggerAgent;
214 m_domAgent = domAgent;
215 m_cssAgent = cssAgent;
216 m_overlayHost->setListener(this);
219 void InspectorOverlayImpl::invalidate()
221 if (!m_pageOverlay)
222 m_pageOverlay = PageOverlay::create(m_webViewImpl, new InspectorPageOverlayDelegate(*this));
224 m_pageOverlay->update();
227 void InspectorOverlayImpl::layout()
229 if (isEmpty())
230 return;
232 TemporaryChange<bool> scoped(m_inLayout, true);
233 if (m_needsUpdate) {
234 m_needsUpdate = false;
235 rebuildOverlayPage();
237 overlayMainFrame()->view()->updateAllLifecyclePhases();
240 bool InspectorOverlayImpl::handleInputEvent(const WebInputEvent& inputEvent)
242 bool handled = false;
244 if (isEmpty())
245 return false;
247 if (WebInputEvent::isGestureEventType(inputEvent.type) && inputEvent.type == WebInputEvent::GestureTap) {
248 // Only let GestureTab in (we only need it and we know PlatformGestureEventBuilder supports it).
249 PlatformGestureEvent gestureEvent = PlatformGestureEventBuilder(m_webViewImpl->mainFrameImpl()->frameView(), static_cast<const WebGestureEvent&>(inputEvent));
250 handled = handleGestureEvent(gestureEvent);
251 if (handled)
252 return true;
254 overlayMainFrame()->eventHandler().handleGestureEvent(gestureEvent);
256 if (WebInputEvent::isMouseEventType(inputEvent.type) && inputEvent.type != WebInputEvent::MouseEnter) {
257 // PlatformMouseEventBuilder does not work with MouseEnter type, so we filter it out manually.
258 PlatformMouseEvent mouseEvent = PlatformMouseEventBuilder(m_webViewImpl->mainFrameImpl()->frameView(), static_cast<const WebMouseEvent&>(inputEvent));
260 if (mouseEvent.type() == PlatformEvent::MouseMoved)
261 handled = handleMouseMove(mouseEvent);
262 else if (mouseEvent.type() == PlatformEvent::MousePressed)
263 handled = handleMousePress();
265 if (handled)
266 return true;
268 if (mouseEvent.type() == PlatformEvent::MouseMoved)
269 handled = overlayMainFrame()->eventHandler().handleMouseMoveEvent(mouseEvent);
270 if (mouseEvent.type() == PlatformEvent::MousePressed)
271 handled = overlayMainFrame()->eventHandler().handleMousePressEvent(mouseEvent);
272 if (mouseEvent.type() == PlatformEvent::MouseReleased)
273 handled = overlayMainFrame()->eventHandler().handleMouseReleaseEvent(mouseEvent);
276 if (WebInputEvent::isTouchEventType(inputEvent.type)) {
277 PlatformTouchEvent touchEvent = PlatformTouchEventBuilder(m_webViewImpl->mainFrameImpl()->frameView(), static_cast<const WebTouchEvent&>(inputEvent));
278 handled = handleTouchEvent(touchEvent);
279 if (handled)
280 return true;
281 overlayMainFrame()->eventHandler().handleTouchEvent(touchEvent);
283 if (WebInputEvent::isKeyboardEventType(inputEvent.type)) {
284 PlatformKeyboardEvent keyboardEvent = PlatformKeyboardEventBuilder(static_cast<const WebKeyboardEvent&>(inputEvent));
285 overlayMainFrame()->eventHandler().keyEvent(keyboardEvent);
288 if (inputEvent.type == WebInputEvent::MouseWheel) {
289 PlatformWheelEvent wheelEvent = PlatformWheelEventBuilder(m_webViewImpl->mainFrameImpl()->frameView(), static_cast<const WebMouseWheelEvent&>(inputEvent));
290 handled = overlayMainFrame()->eventHandler().handleWheelEvent(wheelEvent);
293 return handled;
296 void InspectorOverlayImpl::setPausedInDebuggerMessage(const String* message)
298 m_pausedInDebuggerMessage = message ? *message : String();
299 scheduleUpdate();
302 void InspectorOverlayImpl::hideHighlight()
304 m_highlightNode.clear();
305 m_eventTargetNode.clear();
306 m_highlightQuad.clear();
308 if (m_layoutEditor && m_inspectModeHighlightConfig)
309 highlightNode(m_layoutEditor->element(), *m_inspectModeHighlightConfig, false);
310 else
311 scheduleUpdate();
314 void InspectorOverlayImpl::highlightNode(Node* node, const InspectorHighlightConfig& highlightConfig, bool omitTooltip)
316 highlightNode(node, nullptr, highlightConfig, omitTooltip);
319 void InspectorOverlayImpl::highlightNode(Node* node, Node* eventTarget, const InspectorHighlightConfig& highlightConfig, bool omitTooltip)
321 m_nodeHighlightConfig = highlightConfig;
322 m_highlightNode = node;
323 m_eventTargetNode = eventTarget;
324 m_omitTooltip = omitTooltip;
325 scheduleUpdate();
328 void InspectorOverlayImpl::setInspectMode(InspectorDOMAgent::SearchMode searchMode, PassOwnPtr<InspectorHighlightConfig> highlightConfig)
330 if (m_layoutEditor)
331 overlayClearSelection(true);
333 m_inspectMode = searchMode;
334 scheduleUpdate();
336 if (searchMode != InspectorDOMAgent::NotSearching) {
337 m_inspectModeHighlightConfig = highlightConfig;
338 } else {
339 m_hoveredNodeForInspectMode.clear();
340 hideHighlight();
344 void InspectorOverlayImpl::highlightQuad(PassOwnPtr<FloatQuad> quad, const InspectorHighlightConfig& highlightConfig)
346 m_quadHighlightConfig = highlightConfig;
347 m_highlightQuad = quad;
348 m_omitTooltip = false;
349 scheduleUpdate();
352 bool InspectorOverlayImpl::isEmpty()
354 if (m_suspendCount)
355 return true;
356 bool hasVisibleElements = m_highlightNode || m_eventTargetNode || m_highlightQuad || (m_resizeTimerActive && m_drawViewSize) || !m_pausedInDebuggerMessage.isNull();
357 return !hasVisibleElements && m_inspectMode == InspectorDOMAgent::NotSearching;
360 void InspectorOverlayImpl::scheduleUpdate()
362 if (isEmpty()) {
363 if (m_pageOverlay)
364 m_pageOverlay.clear();
365 return;
367 m_needsUpdate = true;
368 m_webViewImpl->page()->chromeClient().scheduleAnimation();
371 void InspectorOverlayImpl::rebuildOverlayPage()
373 FrameView* view = m_webViewImpl->mainFrameImpl()->frameView();
374 if (!view)
375 return;
377 IntRect visibleRectInDocument = view->scrollableArea()->visibleContentRect();
378 IntSize viewportSize = m_webViewImpl->page()->frameHost().visualViewport().size();
379 toLocalFrame(overlayPage()->mainFrame())->view()->resize(viewportSize);
380 overlayPage()->frameHost().visualViewport().setSize(viewportSize);
381 reset(viewportSize, visibleRectInDocument.location());
383 drawNodeHighlight();
384 drawQuadHighlight();
385 drawPausedInDebuggerMessage();
386 drawViewSize();
389 static PassRefPtr<JSONObject> buildObjectForSize(const IntSize& size)
391 RefPtr<JSONObject> result = JSONObject::create();
392 result->setNumber("width", size.width());
393 result->setNumber("height", size.height());
394 return result.release();
397 void InspectorOverlayImpl::drawNodeHighlight()
399 if (!m_highlightNode)
400 return;
402 bool appendElementInfo = m_highlightNode->isElementNode() && !m_omitTooltip && m_nodeHighlightConfig.showInfo && m_highlightNode->layoutObject() && m_highlightNode->document().frame();
403 InspectorHighlight highlight(m_highlightNode.get(), m_nodeHighlightConfig, appendElementInfo);
404 if (m_eventTargetNode)
405 highlight.appendEventTargetQuads(m_eventTargetNode.get(), m_nodeHighlightConfig);
407 RefPtr<JSONObject> highlightJSON = highlight.asJSONObject();
408 evaluateInOverlay("drawHighlight", highlightJSON.release());
409 if (m_layoutEditor && m_highlightNode == m_layoutEditor->element()) {
410 RefPtr<JSONObject> layoutEditorInfo = m_layoutEditor->buildJSONInfo();
411 if (layoutEditorInfo)
412 evaluateInOverlay("showLayoutEditor", layoutEditorInfo.release());
416 void InspectorOverlayImpl::drawQuadHighlight()
418 if (!m_highlightQuad)
419 return;
421 InspectorHighlight highlight;
422 highlight.appendQuad(*m_highlightQuad, m_quadHighlightConfig.content, m_quadHighlightConfig.contentOutline);
423 evaluateInOverlay("drawHighlight", highlight.asJSONObject());
426 void InspectorOverlayImpl::drawPausedInDebuggerMessage()
428 if (m_inspectMode == InspectorDOMAgent::NotSearching && !m_pausedInDebuggerMessage.isNull())
429 evaluateInOverlay("drawPausedInDebuggerMessage", m_pausedInDebuggerMessage);
432 void InspectorOverlayImpl::drawViewSize()
434 if (m_resizeTimerActive && m_drawViewSize)
435 evaluateInOverlay("drawViewSize", m_drawViewSizeWithGrid ? "true" : "false");
438 Page* InspectorOverlayImpl::overlayPage()
440 if (m_overlayPage)
441 return m_overlayPage.get();
443 ScriptForbiddenScope::AllowUserAgentScript allowScript;
445 DEFINE_STATIC_LOCAL(OwnPtrWillBePersistent<FrameLoaderClient>, dummyFrameLoaderClient, (EmptyFrameLoaderClient::create()));
446 Page::PageClients pageClients;
447 fillWithEmptyClients(pageClients);
448 ASSERT(!m_overlayChromeClient);
449 m_overlayChromeClient = InspectorOverlayChromeClient::create(m_webViewImpl->page()->chromeClient(), *this);
450 pageClients.chromeClient = m_overlayChromeClient.get();
451 m_overlayPage = adoptPtrWillBeNoop(new Page(pageClients));
453 Settings& settings = m_webViewImpl->page()->settings();
454 Settings& overlaySettings = m_overlayPage->settings();
456 overlaySettings.genericFontFamilySettings().updateStandard(settings.genericFontFamilySettings().standard());
457 overlaySettings.genericFontFamilySettings().updateSerif(settings.genericFontFamilySettings().serif());
458 overlaySettings.genericFontFamilySettings().updateSansSerif(settings.genericFontFamilySettings().sansSerif());
459 overlaySettings.genericFontFamilySettings().updateCursive(settings.genericFontFamilySettings().cursive());
460 overlaySettings.genericFontFamilySettings().updateFantasy(settings.genericFontFamilySettings().fantasy());
461 overlaySettings.genericFontFamilySettings().updatePictograph(settings.genericFontFamilySettings().pictograph());
462 overlaySettings.setMinimumFontSize(settings.minimumFontSize());
463 overlaySettings.setMinimumLogicalFontSize(settings.minimumLogicalFontSize());
464 overlaySettings.setScriptEnabled(true);
465 overlaySettings.setPluginsEnabled(false);
466 overlaySettings.setLoadsImagesAutomatically(true);
467 // FIXME: http://crbug.com/363843. Inspector should probably create its
468 // own graphics layers and attach them to the tree rather than going
469 // through some non-composited paint function.
470 overlaySettings.setAcceleratedCompositingEnabled(false);
472 RefPtrWillBeRawPtr<LocalFrame> frame = LocalFrame::create(dummyFrameLoaderClient.get(), &m_overlayPage->frameHost(), 0);
473 frame->setView(FrameView::create(frame.get()));
474 frame->init();
475 FrameLoader& loader = frame->loader();
476 frame->view()->setCanHaveScrollbars(false);
477 frame->view()->setTransparent(true);
479 const WebData& overlayPageHTMLResource = Platform::current()->loadResource("InspectorOverlayPage.html");
480 RefPtr<SharedBuffer> data = SharedBuffer::create(overlayPageHTMLResource.data(), overlayPageHTMLResource.size());
481 loader.load(FrameLoadRequest(0, blankURL(), SubstituteData(data, "text/html", "UTF-8", KURL(), ForceSynchronousLoad)));
482 v8::Isolate* isolate = toIsolate(frame.get());
483 ScriptState* scriptState = ScriptState::forMainWorld(frame.get());
484 ASSERT(scriptState->contextIsValid());
485 ScriptState::Scope scope(scriptState);
486 v8::Local<v8::Object> global = scriptState->context()->Global();
487 v8::Local<v8::Value> overlayHostObj = toV8(m_overlayHost.get(), global, isolate);
488 ASSERT(!overlayHostObj.IsEmpty());
489 v8CallOrCrash(global->Set(scriptState->context(), v8AtomicString(isolate, "InspectorOverlayHost"), overlayHostObj));
491 #if OS(WIN)
492 evaluateInOverlay("setPlatform", "windows");
493 #elif OS(MACOSX)
494 evaluateInOverlay("setPlatform", "mac");
495 #elif OS(POSIX)
496 evaluateInOverlay("setPlatform", "linux");
497 #endif
499 return m_overlayPage.get();
502 LocalFrame* InspectorOverlayImpl::overlayMainFrame()
504 return toLocalFrame(overlayPage()->mainFrame());
507 void InspectorOverlayImpl::reset(const IntSize& viewportSize, const IntPoint& documentScrollOffset)
509 RefPtr<JSONObject> resetData = JSONObject::create();
510 resetData->setNumber("deviceScaleFactor", m_webViewImpl->page()->deviceScaleFactor());
511 resetData->setObject("viewportSize", buildObjectForSize(viewportSize));
512 resetData->setNumber("pageZoomFactor", m_webViewImpl->mainFrameImpl()->frame()->pageZoomFactor());
513 resetData->setNumber("scrollX", documentScrollOffset.x());
514 resetData->setNumber("scrollY", documentScrollOffset.y());
515 evaluateInOverlay("reset", resetData.release());
518 void InspectorOverlayImpl::evaluateInOverlay(const String& method, const String& argument)
520 ScriptForbiddenScope::AllowUserAgentScript allowScript;
521 RefPtr<JSONArray> command = JSONArray::create();
522 command->pushString(method);
523 command->pushString(argument);
524 toLocalFrame(overlayPage()->mainFrame())->script().executeScriptInMainWorld("dispatch(" + command->toJSONString() + ")", ScriptController::ExecuteScriptWhenScriptsDisabled);
527 void InspectorOverlayImpl::evaluateInOverlay(const String& method, PassRefPtr<JSONValue> argument)
529 ScriptForbiddenScope::AllowUserAgentScript allowScript;
530 RefPtr<JSONArray> command = JSONArray::create();
531 command->pushString(method);
532 command->pushValue(argument);
533 toLocalFrame(overlayPage()->mainFrame())->script().executeScriptInMainWorld("dispatch(" + command->toJSONString() + ")", ScriptController::ExecuteScriptWhenScriptsDisabled);
536 void InspectorOverlayImpl::onTimer(Timer<InspectorOverlayImpl>*)
538 m_resizeTimerActive = false;
539 scheduleUpdate();
542 void InspectorOverlayImpl::clear()
544 if (m_overlayPage) {
545 m_overlayPage->willBeDestroyed();
546 m_overlayPage.clear();
547 m_overlayChromeClient.clear();
549 m_resizeTimerActive = false;
550 m_pausedInDebuggerMessage = String();
551 m_inspectMode = InspectorDOMAgent::NotSearching;
552 m_timer.stop();
553 hideHighlight();
556 void InspectorOverlayImpl::overlayResumed()
558 if (m_debuggerAgent) {
559 ErrorString error;
560 m_debuggerAgent->resume(&error);
564 void InspectorOverlayImpl::overlaySteppedOver()
566 if (m_debuggerAgent) {
567 ErrorString error;
568 m_debuggerAgent->stepOver(&error);
572 void InspectorOverlayImpl::overlayStartedPropertyChange(const String& property)
574 ASSERT(m_layoutEditor);
575 m_layoutEditor->overlayStartedPropertyChange(property);
578 void InspectorOverlayImpl::overlayPropertyChanged(float value)
580 ASSERT(m_layoutEditor);
581 m_layoutEditor->overlayPropertyChanged(value);
584 void InspectorOverlayImpl::overlayEndedPropertyChange()
586 ASSERT(m_layoutEditor);
587 m_layoutEditor->overlayEndedPropertyChange();
590 void InspectorOverlayImpl::overlayNextSelector()
592 ASSERT(m_layoutEditor);
593 m_layoutEditor->nextSelector();
596 void InspectorOverlayImpl::overlayPreviousSelector()
598 ASSERT(m_layoutEditor);
599 m_layoutEditor->previousSelector();
602 String InspectorOverlayImpl::overlayCurrentSelectorInfo()
604 ASSERT(m_layoutEditor);
605 return m_layoutEditor->currentSelectorInfo();
608 void InspectorOverlayImpl::overlayClearSelection(bool commitChanges)
610 ASSERT(m_layoutEditor);
611 m_hoveredNodeForInspectMode = m_layoutEditor->element();
613 if (commitChanges)
614 m_layoutEditor->commitChanges();
616 if (m_layoutEditor) {
617 m_layoutEditor->dispose();
618 m_layoutEditor.clear();
621 if (m_inspectModeHighlightConfig)
622 highlightNode(m_hoveredNodeForInspectMode.get(), *m_inspectModeHighlightConfig, false);
624 toChromeClientImpl(m_webViewImpl->page()->chromeClient()).setCursorOverridden(false);
625 toChromeClientImpl(m_webViewImpl->page()->chromeClient()).setCursor(pointerCursor());
628 void InspectorOverlayImpl::profilingStarted()
630 if (!m_suspendCount++)
631 clear();
634 void InspectorOverlayImpl::profilingStopped()
636 --m_suspendCount;
639 void InspectorOverlayImpl::pageLayoutInvalidated(bool resized)
641 if (resized && m_drawViewSize) {
642 m_resizeTimerActive = true;
643 m_timer.startOneShot(1, FROM_HERE);
645 scheduleUpdate();
648 void InspectorOverlayImpl::setShowViewportSizeOnResize(bool show, bool showGrid)
650 m_drawViewSize = show;
651 m_drawViewSizeWithGrid = showGrid;
654 bool InspectorOverlayImpl::handleMouseMove(const PlatformMouseEvent& event)
656 if (!shouldSearchForNode())
657 return false;
659 LocalFrame* frame = m_webViewImpl->mainFrameImpl()->frame();
660 if (!frame->view() || !frame->contentLayoutObject())
661 return false;
662 Node* node = hoveredNodeForEvent(frame, event, event.shiftKey());
664 // Do not highlight within user agent shadow root unless requested.
665 if (m_inspectMode != InspectorDOMAgent::SearchingForUAShadow) {
666 ShadowRoot* shadowRoot = InspectorDOMAgent::userAgentShadowRoot(node);
667 if (shadowRoot)
668 node = shadowRoot->host();
671 // Shadow roots don't have boxes - use host element instead.
672 if (node && node->isShadowRoot())
673 node = node->parentOrShadowHostNode();
675 if (!node)
676 return true;
678 Node* eventTarget = event.shiftKey() ? hoveredNodeForEvent(m_webViewImpl->mainFrameImpl()->frame(), event, false) : nullptr;
679 if (eventTarget == node)
680 eventTarget = nullptr;
682 if (node && m_inspectModeHighlightConfig) {
683 m_hoveredNodeForInspectMode = node;
684 highlightNode(node, eventTarget, *m_inspectModeHighlightConfig, event.ctrlKey() || event.metaKey());
686 return true;
689 bool InspectorOverlayImpl::handleMousePress()
691 if (!shouldSearchForNode())
692 return false;
694 if (m_hoveredNodeForInspectMode) {
695 inspect(m_hoveredNodeForInspectMode.get());
696 m_hoveredNodeForInspectMode.clear();
697 return true;
699 return false;
702 bool InspectorOverlayImpl::handleGestureEvent(const PlatformGestureEvent& event)
704 if (!shouldSearchForNode() || event.type() != PlatformEvent::GestureTap)
705 return false;
706 Node* node = hoveredNodeForEvent(m_webViewImpl->mainFrameImpl()->frame(), event, false);
707 if (node && m_inspectModeHighlightConfig) {
708 highlightNode(node, *m_inspectModeHighlightConfig, false);
709 inspect(node);
710 return true;
712 return false;
715 bool InspectorOverlayImpl::handleTouchEvent(const PlatformTouchEvent& event)
717 if (!shouldSearchForNode())
718 return false;
719 Node* node = hoveredNodeForEvent(m_webViewImpl->mainFrameImpl()->frame(), event, false);
720 if (node && m_inspectModeHighlightConfig) {
721 highlightNode(node, *m_inspectModeHighlightConfig, false);
722 inspect(node);
723 return true;
725 return false;
728 bool InspectorOverlayImpl::shouldSearchForNode()
730 return m_inspectMode != InspectorDOMAgent::NotSearching && !m_layoutEditor;
733 void InspectorOverlayImpl::inspect(Node* node)
735 if (m_domAgent)
736 m_domAgent->inspect(node);
738 if (node && node->isElementNode() && m_inspectMode == InspectorDOMAgent::ShowLayoutEditor && !m_layoutEditor) {
739 m_layoutEditor = LayoutEditor::create(toElement(node), m_cssAgent, m_domAgent);
740 toChromeClientImpl(m_webViewImpl->page()->chromeClient()).setCursorOverridden(true);
741 highlightNode(node, *m_inspectModeHighlightConfig, false);
745 } // namespace blink