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 "web/WebDevToolsFrontendImpl.h" 33 34 #include "bindings/core/v8/ScriptController.h" 35 #include "bindings/core/v8/V8InspectorFrontendHost.h" 36 #include "core/frame/LocalFrame.h" 37 #include "core/inspector/InspectorController.h" 38 #include "core/inspector/InspectorFrontendHost.h" 39 #include "core/page/Page.h" 40 #include "public/platform/WebString.h" 41 #include "public/web/WebDevToolsFrontendClient.h" 42 #include "web/WebViewImpl.h" 43 44 namespace blink { 45 46 WebDevToolsFrontend* WebDevToolsFrontend::create( 47 WebView* view, 48 WebDevToolsFrontendClient* client, 49 const WebString& applicationLocale) 50 { 51 return new WebDevToolsFrontendImpl(toWebViewImpl(view), client); 52 } 53 54 WebDevToolsFrontendImpl::WebDevToolsFrontendImpl( 55 WebViewImpl* webViewImpl, 56 WebDevToolsFrontendClient* client) 57 : m_webViewImpl(webViewImpl) 58 , m_client(client) 59 { 60 m_webViewImpl->page()->inspectorController().setInspectorFrontendClient(this); 61 } 62 63 WebDevToolsFrontendImpl::~WebDevToolsFrontendImpl() 64 { 65 ASSERT(!m_frontendHost); 66 } 67 68 void WebDevToolsFrontendImpl::dispose() 69 { 70 if (m_frontendHost) { 71 m_frontendHost->disconnectClient(); 72 m_frontendHost = nullptr; 73 } 74 m_client = 0; 75 } 76 77 void WebDevToolsFrontendImpl::windowObjectCleared() 78 { 79 v8::Isolate* isolate = v8::Isolate::GetCurrent(); 80 Page* page = m_webViewImpl->page(); 81 ASSERT(page->mainFrame()); 82 ScriptState* scriptState = ScriptState::forMainWorld(page->deprecatedLocalMainFrame()); 83 ScriptState::Scope scope(scriptState); 84 85 if (m_frontendHost) 86 m_frontendHost->disconnectClient(); 87 m_frontendHost = InspectorFrontendHost::create(this, page); 88 v8::Handle<v8::Object> global = scriptState->context()->Global(); 89 v8::Handle<v8::Value> frontendHostObj = toV8(m_frontendHost.get(), global, scriptState->isolate()); 90 91 global->Set(v8::String::NewFromUtf8(isolate, "InspectorFrontendHost"), frontendHostObj); 92 ScriptController* scriptController = page->mainFrame() ? &page->deprecatedLocalMainFrame()->script() : 0; 93 if (scriptController) { 94 String installAdditionalAPI = 95 "" // Wrap messages that go to embedder. 96 "(function(host, methodEntries) {" 97 " host._lastCallId = 0;" 98 " host._callbacks = [];" 99 " host.embedderMessageAck = function(id, error)" 100 " {" 101 " var callback = host._callbacks[id];" 102 " delete host._callbacks[id];" 103 " if (callback)" 104 " callback(error);" 105 " };" 106 " function dispatch(methodName, argumentCount)" 107 " {" 108 " var callId = ++host._lastCallId;" 109 " var argsArray = Array.prototype.slice.call(arguments, 2);" 110 " var callback = argsArray[argsArray.length - 1];" 111 " if (typeof callback === \"function\") {" 112 " argsArray.pop();" 113 " host._callbacks[callId] = callback;" 114 " }" 115 " var message = { \"id\": callId, \"method\": methodName };" 116 " argsArray = argsArray.slice(0, argumentCount);" 117 " if (argsArray.length)" 118 " message.params = argsArray;" 119 " host.sendMessageToEmbedder(JSON.stringify(message));" 120 " };" 121 " methodEntries.forEach(function(methodEntry) { host[methodEntry[0]] = dispatch.bind(null, methodEntry[0], methodEntry[1]); });" 122 "})(InspectorFrontendHost," 123 " [['addFileSystem', 0]," 124 " ['append', 2]," 125 " ['bringToFront', 0]," 126 " ['closeWindow', 0]," 127 " ['indexPath', 2]," 128 " ['inspectElementCompleted', 0]," 129 " ['inspectedURLChanged', 1]," 130 " ['moveWindowBy', 2]," 131 " ['openInNewTab', 1]," 132 " ['openUrlOnRemoteDeviceAndInspect', 2]," 133 " ['removeFileSystem', 1]," 134 " ['requestFileSystems', 0]," 135 " ['resetZoom', 0]," 136 " ['save', 3]," 137 " ['searchInPath', 3]," 138 " ['setDeviceCountUpdatesEnabled', 1]," 139 " ['setDevicesUpdatesEnabled', 1]," 140 " ['setWhitelistedShortcuts', 1]," 141 " ['setContentsResizingStrategy', 2]," 142 " ['setInspectedPageBounds', 1]," 143 " ['setIsDocked', 1]," 144 " ['stopIndexing', 1]," 145 " ['zoomIn', 0]," 146 " ['zoomOut', 0]]);" 147 "" 148 "" // Support for legacy front-ends (<M34). Do not add items here. 149 "InspectorFrontendHost.requestSetDockSide = function(dockSide)" 150 "{" 151 " InspectorFrontendHost.setIsDocked(dockSide !== \"undocked\");" 152 "};" 153 "InspectorFrontendHost.supportsFileSystems = function() { return true; };" 154 "" 155 "" // Support for legacy front-ends (<M28). Do not add items here. 156 "InspectorFrontendHost.canInspectWorkers = function() { return true; };" 157 "InspectorFrontendHost.canSaveAs = function() { return true; };" 158 "InspectorFrontendHost.canSave = function() { return true; };" 159 "InspectorFrontendHost.loaded = function() {};" 160 "InspectorFrontendHost.hiddenPanels = function() { return ""; };" 161 "InspectorFrontendHost.localizedStringsURL = function() { return ""; };" 162 "InspectorFrontendHost.close = function(url) { };"; 163 scriptController->executeScriptInMainWorld(installAdditionalAPI, ScriptController::ExecuteScriptWhenScriptsDisabled); 164 } 165 } 166 167 void WebDevToolsFrontendImpl::sendMessageToBackend(const String& message) 168 { 169 if (m_client) 170 m_client->sendMessageToBackend(message); 171 } 172 173 void WebDevToolsFrontendImpl::sendMessageToEmbedder(const String& message) 174 { 175 if (m_client) 176 m_client->sendMessageToEmbedder(message); 177 } 178 179 bool WebDevToolsFrontendImpl::isUnderTest() 180 { 181 return m_client ? m_client->isUnderTest() : false; 182 } 183 184 } // namespace blink 185