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
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.
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"
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();
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();
94 return hoveredNodeForPoint(frame
, roundedIntPoint(points
[0].pos()), ignorePointerEventsNone
);
98 class InspectorOverlayImpl::InspectorPageOverlayDelegate final
: public PageOverlay::Delegate
{
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())
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()));
122 RawPtrWillBeMember
<InspectorOverlayImpl
> m_overlay
;
126 class InspectorOverlayImpl::InspectorOverlayChromeClient final
: public EmptyChromeClient
{
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
)
163 m_client
->scheduleAnimation();
167 InspectorOverlayChromeClient(ChromeClient
& client
, InspectorOverlayImpl
& overlay
)
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
)
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()
222 m_pageOverlay
= PageOverlay::create(m_webViewImpl
, new InspectorPageOverlayDelegate(*this));
224 m_pageOverlay
->update();
227 void InspectorOverlayImpl::layout()
232 TemporaryChange
<bool> scoped(m_inLayout
, true);
234 m_needsUpdate
= false;
235 rebuildOverlayPage();
237 overlayMainFrame()->view()->updateAllLifecyclePhases();
240 bool InspectorOverlayImpl::handleInputEvent(const WebInputEvent
& inputEvent
)
242 bool handled
= 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
);
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();
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
);
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
);
296 void InspectorOverlayImpl::setPausedInDebuggerMessage(const String
* message
)
298 m_pausedInDebuggerMessage
= message
? *message
: String();
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);
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
;
328 void InspectorOverlayImpl::setInspectMode(InspectorDOMAgent::SearchMode searchMode
, PassOwnPtr
<InspectorHighlightConfig
> highlightConfig
)
331 overlayClearSelection(true);
333 m_inspectMode
= searchMode
;
336 if (searchMode
!= InspectorDOMAgent::NotSearching
) {
337 m_inspectModeHighlightConfig
= highlightConfig
;
339 m_hoveredNodeForInspectMode
.clear();
344 void InspectorOverlayImpl::highlightQuad(PassOwnPtr
<FloatQuad
> quad
, const InspectorHighlightConfig
& highlightConfig
)
346 m_quadHighlightConfig
= highlightConfig
;
347 m_highlightQuad
= quad
;
348 m_omitTooltip
= false;
352 bool InspectorOverlayImpl::isEmpty()
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()
364 m_pageOverlay
.clear();
367 m_needsUpdate
= true;
368 m_webViewImpl
->page()->chromeClient().scheduleAnimation();
371 void InspectorOverlayImpl::rebuildOverlayPage()
373 FrameView
* view
= m_webViewImpl
->mainFrameImpl()->frameView();
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());
385 drawPausedInDebuggerMessage();
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
)
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
)
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()
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()));
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
));
492 evaluateInOverlay("setPlatform", "windows");
494 evaluateInOverlay("setPlatform", "mac");
496 evaluateInOverlay("setPlatform", "linux");
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;
542 void InspectorOverlayImpl::clear()
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
;
556 void InspectorOverlayImpl::overlayResumed()
558 if (m_debuggerAgent
) {
560 m_debuggerAgent
->resume(&error
);
564 void InspectorOverlayImpl::overlaySteppedOver()
566 if (m_debuggerAgent
) {
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();
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
++)
634 void InspectorOverlayImpl::profilingStopped()
639 void InspectorOverlayImpl::pageLayoutInvalidated(bool resized
)
641 if (resized
&& m_drawViewSize
) {
642 m_resizeTimerActive
= true;
643 m_timer
.startOneShot(1, FROM_HERE
);
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())
659 LocalFrame
* frame
= m_webViewImpl
->mainFrameImpl()->frame();
660 if (!frame
->view() || !frame
->contentLayoutObject())
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
);
668 node
= shadowRoot
->host();
671 // Shadow roots don't have boxes - use host element instead.
672 if (node
&& node
->isShadowRoot())
673 node
= node
->parentOrShadowHostNode();
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());
689 bool InspectorOverlayImpl::handleMousePress()
691 if (!shouldSearchForNode())
694 if (m_hoveredNodeForInspectMode
) {
695 inspect(m_hoveredNodeForInspectMode
.get());
696 m_hoveredNodeForInspectMode
.clear();
702 bool InspectorOverlayImpl::handleGestureEvent(const PlatformGestureEvent
& event
)
704 if (!shouldSearchForNode() || event
.type() != PlatformEvent::GestureTap
)
706 Node
* node
= hoveredNodeForEvent(m_webViewImpl
->mainFrameImpl()->frame(), event
, false);
707 if (node
&& m_inspectModeHighlightConfig
) {
708 highlightNode(node
, *m_inspectModeHighlightConfig
, false);
715 bool InspectorOverlayImpl::handleTouchEvent(const PlatformTouchEvent
& event
)
717 if (!shouldSearchForNode())
719 Node
* node
= hoveredNodeForEvent(m_webViewImpl
->mainFrameImpl()->frame(), event
, false);
720 if (node
&& m_inspectModeHighlightConfig
) {
721 highlightNode(node
, *m_inspectModeHighlightConfig
, false);
728 bool InspectorOverlayImpl::shouldSearchForNode()
730 return m_inspectMode
!= InspectorDOMAgent::NotSearching
&& !m_layoutEditor
;
733 void InspectorOverlayImpl::inspect(Node
* node
)
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);