summaryrefslogtreecommitdiffstats
path: root/chromium/third_party/WebKit/Source/web/WebDevToolsAgentImpl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/WebKit/Source/web/WebDevToolsAgentImpl.cpp')
-rw-r--r--chromium/third_party/WebKit/Source/web/WebDevToolsAgentImpl.cpp768
1 files changed, 768 insertions, 0 deletions
diff --git a/chromium/third_party/WebKit/Source/web/WebDevToolsAgentImpl.cpp b/chromium/third_party/WebKit/Source/web/WebDevToolsAgentImpl.cpp
new file mode 100644
index 00000000000..3ea57461e1f
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/web/WebDevToolsAgentImpl.cpp
@@ -0,0 +1,768 @@
+/*
+ * Copyright (C) 2010-2011 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WebDevToolsAgentImpl.h"
+
+#include "InspectorBackendDispatcher.h"
+#include "InspectorFrontend.h"
+#include "InspectorProtocolVersion.h"
+#include "WebDataSource.h"
+#include "WebDevToolsAgentClient.h"
+#include "WebFrameImpl.h"
+#include "WebInputEventConversion.h"
+#include "WebMemoryUsageInfo.h"
+#include "WebViewClient.h"
+#include "WebViewImpl.h"
+#include "bindings/v8/PageScriptDebugServer.h"
+#include "bindings/v8/ScriptController.h"
+#include "bindings/v8/V8Binding.h"
+#include "bindings/v8/V8Utilities.h"
+#include "core/dom/ExceptionCode.h"
+#include "core/fetch/MemoryCache.h"
+#include "core/inspector/InjectedScriptHost.h"
+#include "core/inspector/InspectorController.h"
+#include "core/page/Frame.h"
+#include "core/page/FrameView.h"
+#include "core/page/Page.h"
+#include "core/page/PageGroup.h"
+#include "core/platform/JSONValues.h"
+#include "core/platform/graphics/GraphicsContext.h"
+#include "core/platform/network/ResourceError.h"
+#include "core/platform/network/ResourceRequest.h"
+#include "core/platform/network/ResourceResponse.h"
+#include "core/rendering/RenderView.h"
+#include "public/platform/Platform.h"
+#include "public/platform/WebRect.h"
+#include "public/platform/WebString.h"
+#include "public/platform/WebURL.h"
+#include "public/platform/WebURLError.h"
+#include "public/platform/WebURLRequest.h"
+#include "public/platform/WebURLResponse.h"
+#include "wtf/CurrentTime.h"
+#include "wtf/MathExtras.h"
+#include "wtf/Noncopyable.h"
+#include "wtf/OwnPtr.h"
+#include "wtf/text/WTFString.h"
+
+using namespace WebCore;
+using namespace std;
+
+namespace OverlayZOrders {
+// Use 99 as a big z-order number so that highlight is above other overlays.
+static const int highlight = 99;
+}
+
+namespace WebKit {
+
+class ClientMessageLoopAdapter : public PageScriptDebugServer::ClientMessageLoop {
+public:
+ static void ensureClientMessageLoopCreated(WebDevToolsAgentClient* client)
+ {
+ if (s_instance)
+ return;
+ OwnPtr<ClientMessageLoopAdapter> instance = adoptPtr(new ClientMessageLoopAdapter(adoptPtr(client->createClientMessageLoop())));
+ s_instance = instance.get();
+ PageScriptDebugServer::shared().setClientMessageLoop(instance.release());
+ }
+
+ static void inspectedViewClosed(WebViewImpl* view)
+ {
+ if (s_instance)
+ s_instance->m_frozenViews.remove(view);
+ }
+
+ static void didNavigate()
+ {
+ // Release render thread if necessary.
+ if (s_instance && s_instance->m_running)
+ PageScriptDebugServer::shared().continueProgram();
+ }
+
+private:
+ ClientMessageLoopAdapter(PassOwnPtr<WebKit::WebDevToolsAgentClient::WebKitClientMessageLoop> messageLoop)
+ : m_running(false)
+ , m_messageLoop(messageLoop) { }
+
+
+ virtual void run(Page* page)
+ {
+ if (m_running)
+ return;
+ m_running = true;
+
+ Vector<WebViewImpl*> views;
+
+ // 1. Disable input events.
+ HashSet<Page*>::const_iterator end = page->group().pages().end();
+ for (HashSet<Page*>::const_iterator it = page->group().pages().begin(); it != end; ++it) {
+ WebViewImpl* view = WebViewImpl::fromPage(*it);
+ if (!view)
+ continue;
+ m_frozenViews.add(view);
+ views.append(view);
+ view->setIgnoreInputEvents(true);
+ }
+
+ // 2. Disable active objects
+ WebView::willEnterModalLoop();
+
+ // 3. Process messages until quitNow is called.
+ m_messageLoop->run();
+
+ // 4. Resume active objects
+ WebView::didExitModalLoop();
+
+ // 5. Resume input events.
+ for (Vector<WebViewImpl*>::iterator it = views.begin(); it != views.end(); ++it) {
+ if (m_frozenViews.contains(*it)) {
+ // The view was not closed during the dispatch.
+ (*it)->setIgnoreInputEvents(false);
+ }
+ }
+
+ // 6. All views have been resumed, clear the set.
+ m_frozenViews.clear();
+
+ m_running = false;
+ }
+
+ virtual void quitNow()
+ {
+ m_messageLoop->quitNow();
+ }
+
+ bool m_running;
+ OwnPtr<WebKit::WebDevToolsAgentClient::WebKitClientMessageLoop> m_messageLoop;
+ typedef HashSet<WebViewImpl*> FrozenViewsSet;
+ FrozenViewsSet m_frozenViews;
+ // FIXME: The ownership model for s_instance is somewhat complicated. Can we make this simpler?
+ static ClientMessageLoopAdapter* s_instance;
+};
+
+ClientMessageLoopAdapter* ClientMessageLoopAdapter::s_instance = 0;
+
+class DebuggerTask : public PageScriptDebugServer::Task {
+public:
+ DebuggerTask(PassOwnPtr<WebDevToolsAgent::MessageDescriptor> descriptor)
+ : m_descriptor(descriptor)
+ {
+ }
+
+ virtual ~DebuggerTask() { }
+ virtual void run()
+ {
+ if (WebDevToolsAgent* webagent = m_descriptor->agent())
+ webagent->dispatchOnInspectorBackend(m_descriptor->message());
+ }
+
+private:
+ OwnPtr<WebDevToolsAgent::MessageDescriptor> m_descriptor;
+};
+
+class DeviceMetricsSupport {
+public:
+ DeviceMetricsSupport(WebViewImpl* webView)
+ : m_webView(webView)
+ , m_fitWindow(false)
+ , m_originalZoomFactor(0)
+ {
+ }
+
+ ~DeviceMetricsSupport()
+ {
+ restore();
+ }
+
+ void setDeviceMetrics(int width, int height, float textZoomFactor, bool fitWindow)
+ {
+ WebCore::FrameView* view = frameView();
+ if (!view)
+ return;
+
+ m_emulatedFrameSize = WebSize(width, height);
+ m_fitWindow = fitWindow;
+ m_originalZoomFactor = 0;
+ m_webView->setEmulatedTextZoomFactor(textZoomFactor);
+ applySizeOverrideInternal(view, FitWindowAllowed);
+ autoZoomPageToFitWidth(view->frame());
+
+ m_webView->sendResizeEventAndRepaint();
+ }
+
+ void autoZoomPageToFitWidthOnNavigation(Frame* frame)
+ {
+ FrameView* frameView = frame->view();
+ applySizeOverrideInternal(frameView, FitWindowNotAllowed);
+ m_originalZoomFactor = 0;
+ applySizeOverrideInternal(frameView, FitWindowAllowed);
+ autoZoomPageToFitWidth(frame);
+ }
+
+ void autoZoomPageToFitWidth(Frame* frame)
+ {
+ if (!frame)
+ return;
+
+ frame->setTextZoomFactor(m_webView->emulatedTextZoomFactor());
+ ensureOriginalZoomFactor(frame->view());
+ Document* document = frame->document();
+ float numerator = document->renderView() ? document->renderView()->viewWidth() : frame->view()->contentsWidth();
+ float factor = m_originalZoomFactor * (numerator / m_emulatedFrameSize.width);
+ frame->setPageAndTextZoomFactors(factor, m_webView->emulatedTextZoomFactor());
+ document->styleResolverChanged(RecalcStyleImmediately);
+ document->updateLayout();
+ }
+
+ void webViewResized()
+ {
+ if (!m_fitWindow)
+ return;
+
+ applySizeOverrideIfNecessary();
+ autoZoomPageToFitWidth(m_webView->mainFrameImpl()->frame());
+ }
+
+ void applySizeOverrideIfNecessary()
+ {
+ FrameView* view = frameView();
+ if (!view)
+ return;
+
+ applySizeOverrideInternal(view, FitWindowAllowed);
+ }
+
+private:
+ enum FitWindowFlag { FitWindowAllowed, FitWindowNotAllowed };
+
+ void ensureOriginalZoomFactor(FrameView* frameView)
+ {
+ if (m_originalZoomFactor)
+ return;
+
+ m_webView->setPageScaleFactor(1, WebPoint());
+ m_webView->setZoomLevel(false, 0);
+ WebSize scaledEmulatedSize = scaledEmulatedFrameSize(frameView);
+ double denominator = frameView->contentsWidth();
+ if (!denominator)
+ denominator = 1;
+ m_originalZoomFactor = static_cast<double>(scaledEmulatedSize.width) / denominator;
+ }
+
+ void restore()
+ {
+ WebCore::FrameView* view = frameView();
+ if (!view)
+ return;
+
+ m_webView->setZoomLevel(false, 0);
+ m_webView->setEmulatedTextZoomFactor(1);
+ view->setHorizontalScrollbarLock(false);
+ view->setVerticalScrollbarLock(false);
+ view->setScrollbarModes(ScrollbarAuto, ScrollbarAuto, false, false);
+ view->setFrameRect(IntRect(IntPoint(), IntSize(m_webView->size())));
+ m_webView->sendResizeEventAndRepaint();
+ }
+
+ WebSize scaledEmulatedFrameSize(FrameView* frameView)
+ {
+ if (!m_fitWindow)
+ return m_emulatedFrameSize;
+
+ WebSize scrollbarDimensions = forcedScrollbarDimensions(frameView);
+
+ int overrideWidth = m_emulatedFrameSize.width;
+ int overrideHeight = m_emulatedFrameSize.height;
+
+ WebSize webViewSize = m_webView->size();
+ int availableViewWidth = max(webViewSize.width - scrollbarDimensions.width, 1);
+ int availableViewHeight = max(webViewSize.height - scrollbarDimensions.height, 1);
+
+ double widthRatio = static_cast<double>(overrideWidth) / availableViewWidth;
+ double heightRatio = static_cast<double>(overrideHeight) / availableViewHeight;
+ double dimensionRatio = max(widthRatio, heightRatio);
+ overrideWidth = static_cast<int>(ceil(static_cast<double>(overrideWidth) / dimensionRatio));
+ overrideHeight = static_cast<int>(ceil(static_cast<double>(overrideHeight) / dimensionRatio));
+
+ return WebSize(overrideWidth, overrideHeight);
+ }
+
+ WebSize forcedScrollbarDimensions(FrameView* frameView)
+ {
+ frameView->setScrollbarModes(ScrollbarAlwaysOn, ScrollbarAlwaysOn, true, true);
+
+ int verticalScrollbarWidth = 0;
+ int horizontalScrollbarHeight = 0;
+ if (Scrollbar* verticalBar = frameView->verticalScrollbar())
+ verticalScrollbarWidth = !verticalBar->isOverlayScrollbar() ? verticalBar->width() : 0;
+ if (Scrollbar* horizontalBar = frameView->horizontalScrollbar())
+ horizontalScrollbarHeight = !horizontalBar->isOverlayScrollbar() ? horizontalBar->height() : 0;
+ return WebSize(verticalScrollbarWidth, horizontalScrollbarHeight);
+ }
+
+ void applySizeOverrideInternal(FrameView* frameView, FitWindowFlag fitWindowFlag)
+ {
+ WebSize scrollbarDimensions = forcedScrollbarDimensions(frameView);
+
+ WebSize effectiveEmulatedSize = (fitWindowFlag == FitWindowAllowed) ? scaledEmulatedFrameSize(frameView) : m_emulatedFrameSize;
+ int overrideWidth = effectiveEmulatedSize.width + scrollbarDimensions.width;
+ int overrideHeight = effectiveEmulatedSize.height + scrollbarDimensions.height;
+
+ if (IntSize(overrideWidth, overrideHeight) != frameView->size())
+ frameView->resize(overrideWidth, overrideHeight);
+
+ Document* doc = frameView->frame()->document();
+ doc->styleResolverChanged(RecalcStyleImmediately);
+ doc->updateLayout();
+ }
+
+ WebCore::FrameView* frameView()
+ {
+ return m_webView->mainFrameImpl() ? m_webView->mainFrameImpl()->frameView() : 0;
+ }
+
+ WebViewImpl* m_webView;
+ WebSize m_emulatedFrameSize;
+ bool m_fitWindow;
+ double m_originalZoomFactor;
+};
+
+WebDevToolsAgentImpl::WebDevToolsAgentImpl(
+ WebViewImpl* webViewImpl,
+ WebDevToolsAgentClient* client)
+ : m_hostId(client->hostIdentifier())
+ , m_client(client)
+ , m_webViewImpl(webViewImpl)
+ , m_attached(false)
+{
+ ASSERT(m_hostId > 0);
+ ClientMessageLoopAdapter::ensureClientMessageLoopCreated(m_client);
+}
+
+WebDevToolsAgentImpl::~WebDevToolsAgentImpl()
+{
+ ClientMessageLoopAdapter::inspectedViewClosed(m_webViewImpl);
+ if (m_attached)
+ WebKit::Platform::current()->currentThread()->removeTaskObserver(this);
+}
+
+void WebDevToolsAgentImpl::attach()
+{
+ if (m_attached)
+ return;
+
+ inspectorController()->connectFrontend(this);
+ inspectorController()->webViewResized(m_webViewImpl->size());
+ WebKit::Platform::current()->currentThread()->addTaskObserver(this);
+ m_attached = true;
+}
+
+void WebDevToolsAgentImpl::reattach(const WebString& savedState)
+{
+ if (m_attached)
+ return;
+
+ inspectorController()->reuseFrontend(this, savedState);
+ WebKit::Platform::current()->currentThread()->addTaskObserver(this);
+ m_attached = true;
+}
+
+void WebDevToolsAgentImpl::detach()
+{
+ WebKit::Platform::current()->currentThread()->removeTaskObserver(this);
+
+ // Prevent controller from sending messages to the frontend.
+ InspectorController* ic = inspectorController();
+ ic->disconnectFrontend();
+ ic->hideHighlight();
+ m_attached = false;
+}
+
+void WebDevToolsAgentImpl::didNavigate()
+{
+ ClientMessageLoopAdapter::didNavigate();
+}
+
+void WebDevToolsAgentImpl::didBeginFrame()
+{
+ if (InspectorController* ic = inspectorController())
+ ic->didBeginFrame();
+}
+
+void WebDevToolsAgentImpl::didCancelFrame()
+{
+ if (InspectorController* ic = inspectorController())
+ ic->didCancelFrame();
+}
+
+void WebDevToolsAgentImpl::willComposite()
+{
+ if (InspectorController* ic = inspectorController())
+ ic->willComposite();
+}
+
+void WebDevToolsAgentImpl::didComposite()
+{
+ if (InspectorController* ic = inspectorController())
+ ic->didComposite();
+}
+
+void WebDevToolsAgentImpl::didCreateScriptContext(WebFrameImpl* webframe, int worldId)
+{
+ // Skip non main world contexts.
+ if (worldId)
+ return;
+ if (WebCore::Frame* frame = webframe->frame())
+ frame->script()->setContextDebugId(m_hostId);
+}
+
+void WebDevToolsAgentImpl::mainFrameViewCreated(WebFrameImpl* webFrame)
+{
+ if (m_metricsSupport)
+ m_metricsSupport->applySizeOverrideIfNecessary();
+}
+
+bool WebDevToolsAgentImpl::metricsOverridden()
+{
+ return !!m_metricsSupport;
+}
+
+void WebDevToolsAgentImpl::webViewResized(const WebSize& size)
+{
+ if (m_metricsSupport)
+ m_metricsSupport->webViewResized();
+ if (InspectorController* ic = inspectorController())
+ ic->webViewResized(m_metricsSupport ? IntSize(size.width, size.height) : IntSize());
+}
+
+bool WebDevToolsAgentImpl::handleInputEvent(WebCore::Page* page, const WebInputEvent& inputEvent)
+{
+ if (!m_attached)
+ return false;
+
+ InspectorController* ic = inspectorController();
+ if (!ic)
+ return false;
+
+ if (WebInputEvent::isGestureEventType(inputEvent.type) && inputEvent.type == WebInputEvent::GestureTap) {
+ // Only let GestureTab in (we only need it and we know PlatformGestureEventBuilder supports it).
+ PlatformGestureEvent gestureEvent = PlatformGestureEventBuilder(page->mainFrame()->view(), *static_cast<const WebGestureEvent*>(&inputEvent));
+ return ic->handleGestureEvent(page->mainFrame(), gestureEvent);
+ }
+ if (WebInputEvent::isMouseEventType(inputEvent.type) && inputEvent.type != WebInputEvent::MouseEnter) {
+ // PlatformMouseEventBuilder does not work with MouseEnter type, so we filter it out manually.
+ PlatformMouseEvent mouseEvent = PlatformMouseEventBuilder(page->mainFrame()->view(), *static_cast<const WebMouseEvent*>(&inputEvent));
+ return ic->handleMouseEvent(page->mainFrame(), mouseEvent);
+ }
+ if (WebInputEvent::isTouchEventType(inputEvent.type)) {
+ PlatformTouchEvent touchEvent = PlatformTouchEventBuilder(page->mainFrame()->view(), *static_cast<const WebTouchEvent*>(&inputEvent));
+ return ic->handleTouchEvent(page->mainFrame(), touchEvent);
+ }
+ return false;
+}
+
+void WebDevToolsAgentImpl::overrideDeviceMetrics(int width, int height, float fontScaleFactor, bool fitWindow)
+{
+ if (!width && !height) {
+ if (m_metricsSupport)
+ m_metricsSupport.clear();
+ if (InspectorController* ic = inspectorController())
+ ic->webViewResized(IntSize());
+ return;
+ }
+
+ if (!m_metricsSupport)
+ m_metricsSupport = adoptPtr(new DeviceMetricsSupport(m_webViewImpl));
+
+ m_metricsSupport->setDeviceMetrics(width, height, fontScaleFactor, fitWindow);
+ if (InspectorController* ic = inspectorController()) {
+ WebSize size = m_webViewImpl->size();
+ ic->webViewResized(IntSize(size.width, size.height));
+ }
+}
+
+void WebDevToolsAgentImpl::autoZoomPageToFitWidth()
+{
+ if (m_metricsSupport)
+ m_metricsSupport->autoZoomPageToFitWidthOnNavigation(m_webViewImpl->mainFrameImpl()->frame());
+}
+
+void WebDevToolsAgentImpl::getAllocatedObjects(HashSet<const void*>& set)
+{
+ class CountingVisitor : public WebDevToolsAgentClient::AllocatedObjectVisitor {
+ public:
+ CountingVisitor() : m_totalObjectsCount(0)
+ {
+ }
+
+ virtual bool visitObject(const void* ptr)
+ {
+ ++m_totalObjectsCount;
+ return true;
+ }
+ size_t totalObjectsCount() const
+ {
+ return m_totalObjectsCount;
+ }
+
+ private:
+ size_t m_totalObjectsCount;
+ };
+
+ CountingVisitor counter;
+ m_client->visitAllocatedObjects(&counter);
+
+ class PointerCollector : public WebDevToolsAgentClient::AllocatedObjectVisitor {
+ public:
+ explicit PointerCollector(size_t maxObjectsCount)
+ : m_maxObjectsCount(maxObjectsCount)
+ , m_index(0)
+ , m_success(true)
+ , m_pointers(new const void*[maxObjectsCount])
+ {
+ }
+ virtual ~PointerCollector()
+ {
+ delete[] m_pointers;
+ }
+ virtual bool visitObject(const void* ptr)
+ {
+ if (m_index == m_maxObjectsCount) {
+ m_success = false;
+ return false;
+ }
+ m_pointers[m_index++] = ptr;
+ return true;
+ }
+
+ bool success() const { return m_success; }
+
+ void copyTo(HashSet<const void*>& set)
+ {
+ for (size_t i = 0; i < m_index; i++)
+ set.add(m_pointers[i]);
+ }
+
+ private:
+ const size_t m_maxObjectsCount;
+ size_t m_index;
+ bool m_success;
+ const void** m_pointers;
+ };
+
+ // Double size to allow room for all objects that may have been allocated
+ // since we counted them.
+ size_t estimatedMaxObjectsCount = counter.totalObjectsCount() * 2;
+ while (true) {
+ PointerCollector collector(estimatedMaxObjectsCount);
+ m_client->visitAllocatedObjects(&collector);
+ if (collector.success()) {
+ collector.copyTo(set);
+ break;
+ }
+ estimatedMaxObjectsCount *= 2;
+ }
+}
+
+void WebDevToolsAgentImpl::dumpUncountedAllocatedObjects(const HashMap<const void*, size_t>& map)
+{
+ class InstrumentedObjectSizeProvider : public WebDevToolsAgentClient::InstrumentedObjectSizeProvider {
+ public:
+ InstrumentedObjectSizeProvider(const HashMap<const void*, size_t>& map) : m_map(map) { }
+ virtual size_t objectSize(const void* ptr) const
+ {
+ HashMap<const void*, size_t>::const_iterator i = m_map.find(ptr);
+ return i == m_map.end() ? 0 : i->value;
+ }
+
+ private:
+ const HashMap<const void*, size_t>& m_map;
+ };
+
+ InstrumentedObjectSizeProvider provider(map);
+ m_client->dumpUncountedAllocatedObjects(&provider);
+}
+
+void WebDevToolsAgentImpl::setTraceEventCallback(TraceEventCallback callback)
+{
+ m_client->setTraceEventCallback(callback);
+}
+
+void WebDevToolsAgentImpl::dispatchKeyEvent(const PlatformKeyboardEvent& event)
+{
+ WebKeyboardEvent webEvent = WebKeyboardEventBuilder(event);
+ if (!webEvent.keyIdentifier[0] && webEvent.type != WebInputEvent::Char)
+ webEvent.setKeyIdentifierFromWindowsKeyCode();
+ m_webViewImpl->handleInputEvent(webEvent);
+}
+
+void WebDevToolsAgentImpl::dispatchMouseEvent(const PlatformMouseEvent& event)
+{
+ WebMouseEvent webEvent = WebMouseEventBuilder(m_webViewImpl->mainFrameImpl()->frameView(), event);
+ m_webViewImpl->handleInputEvent(webEvent);
+}
+
+void WebDevToolsAgentImpl::dispatchOnInspectorBackend(const WebString& message)
+{
+ inspectorController()->dispatchMessageFromFrontend(message);
+}
+
+void WebDevToolsAgentImpl::inspectElementAt(const WebPoint& point)
+{
+ m_webViewImpl->inspectElementAt(point);
+}
+
+InspectorController* WebDevToolsAgentImpl::inspectorController()
+{
+ if (Page* page = m_webViewImpl->page())
+ return page->inspectorController();
+ return 0;
+}
+
+Frame* WebDevToolsAgentImpl::mainFrame()
+{
+ if (Page* page = m_webViewImpl->page())
+ return page->mainFrame();
+ return 0;
+}
+
+// WebPageOverlay
+void WebDevToolsAgentImpl::paintPageOverlay(WebCanvas* canvas)
+{
+ InspectorController* ic = inspectorController();
+ if (ic) {
+ GraphicsContext context(canvas);
+ context.setCertainlyOpaque(false);
+ ic->drawHighlight(context);
+ }
+}
+
+void WebDevToolsAgentImpl::highlight()
+{
+ m_webViewImpl->addPageOverlay(this, OverlayZOrders::highlight);
+}
+
+void WebDevToolsAgentImpl::hideHighlight()
+{
+ m_webViewImpl->removePageOverlay(this);
+}
+
+bool WebDevToolsAgentImpl::sendMessageToFrontend(const String& message)
+{
+ WebDevToolsAgentImpl* devToolsAgent = static_cast<WebDevToolsAgentImpl*>(m_webViewImpl->devToolsAgent());
+ if (!devToolsAgent)
+ return false;
+ m_client->sendMessageToInspectorFrontend(message);
+ return true;
+}
+
+void WebDevToolsAgentImpl::updateInspectorStateCookie(const String& state)
+{
+ m_client->saveAgentRuntimeState(state);
+}
+
+void WebDevToolsAgentImpl::clearBrowserCache()
+{
+ m_client->clearBrowserCache();
+}
+
+void WebDevToolsAgentImpl::clearBrowserCookies()
+{
+ m_client->clearBrowserCookies();
+}
+
+void WebDevToolsAgentImpl::setProcessId(long processId)
+{
+ inspectorController()->setProcessId(processId);
+}
+
+void WebDevToolsAgentImpl::setLayerTreeId(int layerTreeId)
+{
+ inspectorController()->setLayerTreeId(layerTreeId);
+}
+
+void WebDevToolsAgentImpl::evaluateInWebInspector(long callId, const WebString& script)
+{
+ InspectorController* ic = inspectorController();
+ ic->evaluateForTestInFrontend(callId, script);
+}
+
+void WebDevToolsAgentImpl::willProcessTask()
+{
+ if (InspectorController* ic = inspectorController())
+ ic->willProcessTask();
+}
+
+void WebDevToolsAgentImpl::didProcessTask()
+{
+ if (InspectorController* ic = inspectorController())
+ ic->didProcessTask();
+}
+
+WebString WebDevToolsAgent::inspectorProtocolVersion()
+{
+ return WebCore::inspectorProtocolVersion();
+}
+
+bool WebDevToolsAgent::supportsInspectorProtocolVersion(const WebString& version)
+{
+ return WebCore::supportsInspectorProtocolVersion(version);
+}
+
+void WebDevToolsAgent::interruptAndDispatch(MessageDescriptor* rawDescriptor)
+{
+ // rawDescriptor can't be a PassOwnPtr because interruptAndDispatch is a WebKit API function.
+ OwnPtr<MessageDescriptor> descriptor = adoptPtr(rawDescriptor);
+ OwnPtr<DebuggerTask> task = adoptPtr(new DebuggerTask(descriptor.release()));
+ PageScriptDebugServer::interruptAndRun(task.release(), v8::Isolate::GetCurrent());
+}
+
+bool WebDevToolsAgent::shouldInterruptForMessage(const WebString& message)
+{
+ String commandName;
+ if (!InspectorBackendDispatcher::getCommandName(message, &commandName))
+ return false;
+ return commandName == InspectorBackendDispatcher::commandNames[InspectorBackendDispatcher::kDebugger_pauseCmd]
+ || commandName == InspectorBackendDispatcher::commandNames[InspectorBackendDispatcher::kDebugger_setBreakpointCmd]
+ || commandName == InspectorBackendDispatcher::commandNames[InspectorBackendDispatcher::kDebugger_setBreakpointByUrlCmd]
+ || commandName == InspectorBackendDispatcher::commandNames[InspectorBackendDispatcher::kDebugger_removeBreakpointCmd]
+ || commandName == InspectorBackendDispatcher::commandNames[InspectorBackendDispatcher::kDebugger_setBreakpointsActiveCmd]
+ || commandName == InspectorBackendDispatcher::commandNames[InspectorBackendDispatcher::kProfiler_startCmd]
+ || commandName == InspectorBackendDispatcher::commandNames[InspectorBackendDispatcher::kProfiler_stopCmd]
+ || commandName == InspectorBackendDispatcher::commandNames[InspectorBackendDispatcher::kProfiler_getCPUProfileCmd]
+ || commandName == InspectorBackendDispatcher::commandNames[InspectorBackendDispatcher::kHeapProfiler_getHeapSnapshotCmd];
+}
+
+void WebDevToolsAgent::processPendingMessages()
+{
+ PageScriptDebugServer::shared().runPendingTasks();
+}
+
+} // namespace WebKit