Home | History | Annotate | Download | only in web
      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