Torne (Richard Coles) | 5c87bf8 | 2012-11-14 11:46:17 +0000 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2010 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 are |
| 6 | * met: |
| 7 | * |
| 8 | * * Redistributions of source code must retain the above copyright |
| 9 | * notice, this list of conditions and the following disclaimer. |
| 10 | * * Redistributions in binary form must reproduce the above |
| 11 | * copyright notice, this list of conditions and the following disclaimer |
| 12 | * in the documentation and/or other materials provided with the |
| 13 | * distribution. |
| 14 | * * Neither the name of Google Inc. nor the names of its |
| 15 | * contributors may be used to endorse or promote products derived from |
| 16 | * this software without specific prior written permission. |
| 17 | * |
| 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| 21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| 22 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| 23 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 24 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 25 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 26 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 29 | */ |
| 30 | |
| 31 | #include "config.h" |
| 32 | #include "WebDevToolsFrontendImpl.h" |
| 33 | |
Torne (Richard Coles) | 5c87bf8 | 2012-11-14 11:46:17 +0000 | [diff] [blame] | 34 | #include "InspectorFrontendClientImpl.h" |
Torne (Richard Coles) | 5c87bf8 | 2012-11-14 11:46:17 +0000 | [diff] [blame] | 35 | #include "V8InspectorFrontendHost.h" |
| 36 | #include "V8MouseEvent.h" |
| 37 | #include "V8Node.h" |
Torne (Richard Coles) | 5c87bf8 | 2012-11-14 11:46:17 +0000 | [diff] [blame] | 38 | #include "WebDevToolsFrontendClient.h" |
| 39 | #include "WebFrameImpl.h" |
| 40 | #include "WebScriptSource.h" |
| 41 | #include "WebViewImpl.h" |
Torne (Richard Coles) | 53e740f | 2013-05-09 18:38:43 +0100 | [diff] [blame] | 42 | #include "bindings/v8/ScriptController.h" |
| 43 | #include "bindings/v8/V8Binding.h" |
| 44 | #include "bindings/v8/V8DOMWrapper.h" |
Torne (Richard Coles) | 0938029 | 2014-02-21 12:17:33 +0000 | [diff] [blame] | 45 | #include "core/clipboard/Pasteboard.h" |
Torne (Richard Coles) | 53e740f | 2013-05-09 18:38:43 +0100 | [diff] [blame] | 46 | #include "core/dom/Document.h" |
Torne (Richard Coles) | 53e740f | 2013-05-09 18:38:43 +0100 | [diff] [blame] | 47 | #include "core/dom/Node.h" |
Torne (Richard Coles) | 0938029 | 2014-02-21 12:17:33 +0000 | [diff] [blame] | 48 | #include "core/events/Event.h" |
Torne (Richard Coles) | 53e740f | 2013-05-09 18:38:43 +0100 | [diff] [blame] | 49 | #include "core/inspector/InspectorController.h" |
| 50 | #include "core/inspector/InspectorFrontendHost.h" |
| 51 | #include "core/page/ContextMenuController.h" |
Torne (Richard Coles) | 1e20218 | 2013-10-18 15:46:42 +0100 | [diff] [blame] | 52 | #include "core/frame/DOMWindow.h" |
Torne (Richard Coles) | d5428f3 | 2014-03-18 10:21:16 +0000 | [diff] [blame] | 53 | #include "core/frame/LocalFrame.h" |
Torne (Richard Coles) | 53e740f | 2013-05-09 18:38:43 +0100 | [diff] [blame] | 54 | #include "core/page/Page.h" |
Torne (Richard Coles) | 0938029 | 2014-02-21 12:17:33 +0000 | [diff] [blame] | 55 | #include "core/frame/Settings.h" |
Torne (Richard Coles) | 51b2906 | 2013-11-28 11:56:03 +0000 | [diff] [blame] | 56 | #include "platform/ContextMenuItem.h" |
| 57 | #include "platform/weborigin/SecurityOrigin.h" |
Torne (Richard Coles) | 5267f70 | 2013-06-11 10:57:24 +0100 | [diff] [blame] | 58 | #include "wtf/OwnPtr.h" |
Torne (Richard Coles) | 5c87bf8 | 2012-11-14 11:46:17 +0000 | [diff] [blame] | 59 | |
| 60 | using namespace WebCore; |
| 61 | |
Torne (Richard Coles) | 51b2906 | 2013-11-28 11:56:03 +0000 | [diff] [blame] | 62 | namespace blink { |
Torne (Richard Coles) | 5c87bf8 | 2012-11-14 11:46:17 +0000 | [diff] [blame] | 63 | |
Torne (Richard Coles) | 5267f70 | 2013-06-11 10:57:24 +0100 | [diff] [blame] | 64 | class WebDevToolsFrontendImpl::InspectorFrontendResumeObserver : public ActiveDOMObject { |
| 65 | WTF_MAKE_NONCOPYABLE(InspectorFrontendResumeObserver); |
| 66 | public: |
| 67 | InspectorFrontendResumeObserver(WebDevToolsFrontendImpl* webDevToolsFrontendImpl, Document* document) |
| 68 | : ActiveDOMObject(document) |
| 69 | , m_webDevToolsFrontendImpl(webDevToolsFrontendImpl) |
| 70 | { |
| 71 | suspendIfNeeded(); |
| 72 | } |
| 73 | |
| 74 | private: |
Torne (Richard Coles) | 5267f70 | 2013-06-11 10:57:24 +0100 | [diff] [blame] | 75 | virtual void resume() OVERRIDE |
| 76 | { |
| 77 | m_webDevToolsFrontendImpl->resume(); |
| 78 | } |
| 79 | |
| 80 | WebDevToolsFrontendImpl* m_webDevToolsFrontendImpl; |
| 81 | }; |
| 82 | |
Torne (Richard Coles) | 5c87bf8 | 2012-11-14 11:46:17 +0000 | [diff] [blame] | 83 | WebDevToolsFrontend* WebDevToolsFrontend::create( |
| 84 | WebView* view, |
| 85 | WebDevToolsFrontendClient* client, |
| 86 | const WebString& applicationLocale) |
| 87 | { |
Torne (Richard Coles) | c0e19a6 | 2013-08-30 15:15:11 +0100 | [diff] [blame] | 88 | return new WebDevToolsFrontendImpl(toWebViewImpl(view), client, applicationLocale); |
Torne (Richard Coles) | 5c87bf8 | 2012-11-14 11:46:17 +0000 | [diff] [blame] | 89 | } |
| 90 | |
| 91 | WebDevToolsFrontendImpl::WebDevToolsFrontendImpl( |
| 92 | WebViewImpl* webViewImpl, |
| 93 | WebDevToolsFrontendClient* client, |
| 94 | const String& applicationLocale) |
| 95 | : m_webViewImpl(webViewImpl) |
| 96 | , m_client(client) |
| 97 | , m_applicationLocale(applicationLocale) |
Torne (Richard Coles) | 5267f70 | 2013-06-11 10:57:24 +0100 | [diff] [blame] | 98 | , m_inspectorFrontendDispatchTimer(this, &WebDevToolsFrontendImpl::maybeDispatch) |
Torne (Richard Coles) | 5c87bf8 | 2012-11-14 11:46:17 +0000 | [diff] [blame] | 99 | { |
Torne (Richard Coles) | e1f1df5 | 2013-08-23 16:39:30 +0100 | [diff] [blame] | 100 | m_webViewImpl->page()->inspectorController().setInspectorFrontendClient(adoptPtr(new InspectorFrontendClientImpl(m_webViewImpl->page(), m_client, this))); |
Torne (Richard Coles) | 5c87bf8 | 2012-11-14 11:46:17 +0000 | [diff] [blame] | 101 | } |
| 102 | |
| 103 | WebDevToolsFrontendImpl::~WebDevToolsFrontendImpl() |
| 104 | { |
| 105 | } |
| 106 | |
| 107 | void WebDevToolsFrontendImpl::dispatchOnInspectorFrontend(const WebString& message) |
| 108 | { |
Torne (Richard Coles) | 5267f70 | 2013-06-11 10:57:24 +0100 | [diff] [blame] | 109 | m_messages.append(message); |
| 110 | maybeDispatch(0); |
| 111 | } |
| 112 | |
| 113 | void WebDevToolsFrontendImpl::resume() |
| 114 | { |
| 115 | // We should call maybeDispatch asynchronously here because we are not allowed to update activeDOMObjects list in |
Torne (Richard Coles) | 1e20218 | 2013-10-18 15:46:42 +0100 | [diff] [blame] | 116 | // resume (See ExecutionContext::resumeActiveDOMObjects). |
Torne (Richard Coles) | 5267f70 | 2013-06-11 10:57:24 +0100 | [diff] [blame] | 117 | if (!m_inspectorFrontendDispatchTimer.isActive()) |
Torne (Richard Coles) | d5428f3 | 2014-03-18 10:21:16 +0000 | [diff] [blame] | 118 | m_inspectorFrontendDispatchTimer.startOneShot(0, FROM_HERE); |
Torne (Richard Coles) | 5267f70 | 2013-06-11 10:57:24 +0100 | [diff] [blame] | 119 | } |
| 120 | |
| 121 | void WebDevToolsFrontendImpl::maybeDispatch(WebCore::Timer<WebDevToolsFrontendImpl>*) |
| 122 | { |
| 123 | while (!m_messages.isEmpty()) { |
| 124 | Document* document = m_webViewImpl->page()->mainFrame()->document(); |
| 125 | if (document->activeDOMObjectsAreSuspended()) { |
| 126 | m_inspectorFrontendResumeObserver = adoptPtr(new InspectorFrontendResumeObserver(this, document)); |
| 127 | return; |
| 128 | } |
| 129 | m_inspectorFrontendResumeObserver.clear(); |
| 130 | doDispatchOnInspectorFrontend(m_messages.takeFirst()); |
| 131 | } |
| 132 | } |
| 133 | |
| 134 | void WebDevToolsFrontendImpl::doDispatchOnInspectorFrontend(const WebString& message) |
| 135 | { |
Torne (Richard Coles) | 5c87bf8 | 2012-11-14 11:46:17 +0000 | [diff] [blame] | 136 | WebFrameImpl* frame = m_webViewImpl->mainFrameImpl(); |
Torne (Richard Coles) | 8abfc58 | 2013-09-12 12:10:38 +0100 | [diff] [blame] | 137 | if (!frame->frame()) |
| 138 | return; |
Torne (Richard Coles) | 9bbd2f5 | 2013-09-19 22:37:05 +0100 | [diff] [blame] | 139 | v8::Isolate* isolate = toIsolate(frame->frame()); |
Torne (Richard Coles) | 8abfc58 | 2013-09-12 12:10:38 +0100 | [diff] [blame] | 140 | v8::HandleScope scope(isolate); |
Torne (Richard Coles) | 0938029 | 2014-02-21 12:17:33 +0000 | [diff] [blame] | 141 | v8::Handle<v8::Context> frameContext = toV8Context(isolate, frame->frame(), DOMWrapperWorld::mainWorld()); |
| 142 | if (frameContext.IsEmpty()) |
| 143 | return; |
Torne (Richard Coles) | 5c87bf8 | 2012-11-14 11:46:17 +0000 | [diff] [blame] | 144 | v8::Context::Scope contextScope(frameContext); |
Torne (Richard Coles) | a854de0 | 2013-12-18 16:25:25 +0000 | [diff] [blame] | 145 | v8::Handle<v8::Value> inspectorFrontendApiValue = frameContext->Global()->Get(v8::String::NewFromUtf8(isolate, "InspectorFrontendAPI")); |
Torne (Richard Coles) | 5c87bf8 | 2012-11-14 11:46:17 +0000 | [diff] [blame] | 146 | if (!inspectorFrontendApiValue->IsObject()) |
| 147 | return; |
Torne (Richard Coles) | c0e19a6 | 2013-08-30 15:15:11 +0100 | [diff] [blame] | 148 | v8::Handle<v8::Object> dispatcherObject = v8::Handle<v8::Object>::Cast(inspectorFrontendApiValue); |
Torne (Richard Coles) | a854de0 | 2013-12-18 16:25:25 +0000 | [diff] [blame] | 149 | v8::Handle<v8::Value> dispatchFunction = dispatcherObject->Get(v8::String::NewFromUtf8(isolate, "dispatchMessage")); |
Torne (Richard Coles) | c0e19a6 | 2013-08-30 15:15:11 +0100 | [diff] [blame] | 150 | // The frame might have navigated away from the front-end page (which is still weird), |
| 151 | // OR the older version of frontend might have a dispatch method in a different place. |
| 152 | // FIXME(kaznacheev): Remove when Chrome for Android M18 is retired. |
| 153 | if (!dispatchFunction->IsFunction()) { |
Torne (Richard Coles) | a854de0 | 2013-12-18 16:25:25 +0000 | [diff] [blame] | 154 | v8::Handle<v8::Value> inspectorBackendApiValue = frameContext->Global()->Get(v8::String::NewFromUtf8(isolate, "InspectorBackend")); |
Torne (Richard Coles) | c0e19a6 | 2013-08-30 15:15:11 +0100 | [diff] [blame] | 155 | if (!inspectorBackendApiValue->IsObject()) |
| 156 | return; |
| 157 | dispatcherObject = v8::Handle<v8::Object>::Cast(inspectorBackendApiValue); |
Torne (Richard Coles) | a854de0 | 2013-12-18 16:25:25 +0000 | [diff] [blame] | 158 | dispatchFunction = dispatcherObject->Get(v8::String::NewFromUtf8(isolate, "dispatch")); |
Torne (Richard Coles) | c0e19a6 | 2013-08-30 15:15:11 +0100 | [diff] [blame] | 159 | if (!dispatchFunction->IsFunction()) |
| 160 | return; |
| 161 | } |
Torne (Richard Coles) | 5c87bf8 | 2012-11-14 11:46:17 +0000 | [diff] [blame] | 162 | v8::Handle<v8::Function> function = v8::Handle<v8::Function>::Cast(dispatchFunction); |
| 163 | Vector< v8::Handle<v8::Value> > args; |
Torne (Richard Coles) | a854de0 | 2013-12-18 16:25:25 +0000 | [diff] [blame] | 164 | args.append(v8String(isolate, message)); |
Torne (Richard Coles) | 5c87bf8 | 2012-11-14 11:46:17 +0000 | [diff] [blame] | 165 | v8::TryCatch tryCatch; |
| 166 | tryCatch.SetVerbose(true); |
Torne (Richard Coles) | 1e20218 | 2013-10-18 15:46:42 +0100 | [diff] [blame] | 167 | ScriptController::callFunction(frame->frame()->document(), function, dispatcherObject, args.size(), args.data(), isolate); |
Torne (Richard Coles) | 5c87bf8 | 2012-11-14 11:46:17 +0000 | [diff] [blame] | 168 | } |
| 169 | |
Torne (Richard Coles) | 51b2906 | 2013-11-28 11:56:03 +0000 | [diff] [blame] | 170 | } // namespace blink |