Home | History | Annotate | Download | only in inspector
      1 /*
      2  * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
      3  * Copyright (C) 2008 Matt Lilek <webkit (at) mattlilek.com>
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions
      7  * are met:
      8  *
      9  * 1.  Redistributions of source code must retain the above copyright
     10  *     notice, this list of conditions and the following disclaimer.
     11  * 2.  Redistributions in binary form must reproduce the above copyright
     12  *     notice, this list of conditions and the following disclaimer in the
     13  *     documentation and/or other materials provided with the distribution.
     14  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
     15  *     its contributors may be used to endorse or promote products derived
     16  *     from this software without specific prior written permission.
     17  *
     18  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
     19  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     20  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     21  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
     22  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     23  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     24  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
     25  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     28  */
     29 
     30 #include "config.h"
     31 #include "InspectorFrontendHost.h"
     32 
     33 #if ENABLE(INSPECTOR)
     34 
     35 #include "ContextMenu.h"
     36 #include "ContextMenuItem.h"
     37 #include "ContextMenuController.h"
     38 #include "ContextMenuProvider.h"
     39 #include "Element.h"
     40 #include "Frame.h"
     41 #include "FrameLoader.h"
     42 #include "HitTestResult.h"
     43 #include "HTMLFrameOwnerElement.h"
     44 #include "InspectorAgent.h"
     45 #include "InspectorController.h"
     46 #include "InspectorFrontendClient.h"
     47 #include "Page.h"
     48 #include "Pasteboard.h"
     49 #include "ScriptFunctionCall.h"
     50 
     51 #include <wtf/RefPtr.h>
     52 #include <wtf/StdLibExtras.h>
     53 
     54 using namespace std;
     55 
     56 namespace WebCore {
     57 
     58 #if ENABLE(CONTEXT_MENUS)
     59 class FrontendMenuProvider : public ContextMenuProvider {
     60 public:
     61     static PassRefPtr<FrontendMenuProvider> create(InspectorFrontendHost* frontendHost, ScriptObject webInspector, const Vector<ContextMenuItem*>& items)
     62     {
     63         return adoptRef(new FrontendMenuProvider(frontendHost, webInspector, items));
     64     }
     65 
     66     void disconnect()
     67     {
     68         m_webInspector = ScriptObject();
     69         m_frontendHost = 0;
     70     }
     71 
     72 private:
     73     FrontendMenuProvider(InspectorFrontendHost* frontendHost, ScriptObject webInspector,  const Vector<ContextMenuItem*>& items)
     74         : m_frontendHost(frontendHost)
     75         , m_webInspector(webInspector)
     76         , m_items(items)
     77     {
     78     }
     79 
     80     virtual ~FrontendMenuProvider()
     81     {
     82         contextMenuCleared();
     83     }
     84 
     85     virtual void populateContextMenu(ContextMenu* menu)
     86     {
     87         for (size_t i = 0; i < m_items.size(); ++i)
     88             menu->appendItem(*m_items[i]);
     89     }
     90 
     91     virtual void contextMenuItemSelected(ContextMenuItem* item)
     92     {
     93         if (m_frontendHost) {
     94             int itemNumber = item->action() - ContextMenuItemBaseCustomTag;
     95 
     96             ScriptFunctionCall function(m_webInspector, "contextMenuItemSelected");
     97             function.appendArgument(itemNumber);
     98             function.call();
     99         }
    100     }
    101 
    102     virtual void contextMenuCleared()
    103     {
    104         if (m_frontendHost) {
    105             ScriptFunctionCall function(m_webInspector, "contextMenuCleared");
    106             function.call();
    107 
    108             m_frontendHost->m_menuProvider = 0;
    109         }
    110         deleteAllValues(m_items);
    111         m_items.clear();
    112     }
    113 
    114     InspectorFrontendHost* m_frontendHost;
    115     ScriptObject m_webInspector;
    116     Vector<ContextMenuItem*> m_items;
    117 };
    118 #endif
    119 
    120 InspectorFrontendHost::InspectorFrontendHost(InspectorFrontendClient* client, Page* frontendPage)
    121     : m_client(client)
    122     , m_frontendPage(frontendPage)
    123 #if ENABLE(CONTEXT_MENUS)
    124     , m_menuProvider(0)
    125 #endif
    126 {
    127 }
    128 
    129 InspectorFrontendHost::~InspectorFrontendHost()
    130 {
    131     ASSERT(!m_client);
    132 }
    133 
    134 void InspectorFrontendHost::disconnectClient()
    135 {
    136     m_client = 0;
    137 #if ENABLE(CONTEXT_MENUS)
    138     if (m_menuProvider)
    139         m_menuProvider->disconnect();
    140 #endif
    141     m_frontendPage = 0;
    142 }
    143 
    144 void InspectorFrontendHost::loaded()
    145 {
    146     if (m_client)
    147         m_client->frontendLoaded();
    148 }
    149 
    150 void InspectorFrontendHost::requestAttachWindow()
    151 {
    152     if (m_client)
    153         m_client->requestAttachWindow();
    154 }
    155 
    156 void InspectorFrontendHost::requestDetachWindow()
    157 {
    158     if (m_client)
    159         m_client->requestDetachWindow();
    160 }
    161 
    162 void InspectorFrontendHost::closeWindow()
    163 {
    164     if (m_client) {
    165         m_client->closeWindow();
    166         disconnectClient(); // Disconnect from client.
    167     }
    168 }
    169 
    170 void InspectorFrontendHost::disconnectFromBackend()
    171 {
    172     if (m_client) {
    173         m_client->disconnectFromBackend();
    174         disconnectClient(); // Disconnect from client.
    175     }
    176 }
    177 
    178 void InspectorFrontendHost::bringToFront()
    179 {
    180     if (m_client)
    181         m_client->bringToFront();
    182 }
    183 
    184 void InspectorFrontendHost::inspectedURLChanged(const String& newURL)
    185 {
    186     if (m_client)
    187         m_client->inspectedURLChanged(newURL);
    188 }
    189 
    190 void InspectorFrontendHost::setAttachedWindowHeight(unsigned height)
    191 {
    192     if (m_client)
    193         m_client->changeAttachedWindowHeight(height);
    194 }
    195 
    196 void InspectorFrontendHost::moveWindowBy(float x, float y) const
    197 {
    198     if (m_client)
    199         m_client->moveWindowBy(x, y);
    200 }
    201 
    202 void InspectorFrontendHost::setExtensionAPI(const String& script)
    203 {
    204     ASSERT(m_frontendPage->inspectorController());
    205     m_frontendPage->inspectorController()->setInspectorExtensionAPI(script);
    206 }
    207 
    208 String InspectorFrontendHost::localizedStringsURL()
    209 {
    210     return m_client->localizedStringsURL();
    211 }
    212 
    213 String InspectorFrontendHost::hiddenPanels()
    214 {
    215     return m_client->hiddenPanels();
    216 }
    217 
    218 void InspectorFrontendHost::copyText(const String& text)
    219 {
    220     Pasteboard::generalPasteboard()->writePlainText(text);
    221 }
    222 
    223 void InspectorFrontendHost::saveSessionSetting(const String& key, const String& value)
    224 {
    225     if (m_client)
    226         m_client->saveSessionSetting(key, value);
    227 }
    228 
    229 String InspectorFrontendHost::loadSessionSetting(const String& key)
    230 {
    231     String value;
    232     if (m_client)
    233         m_client->loadSessionSetting(key, &value);
    234     return value;
    235 }
    236 
    237 void InspectorFrontendHost::sendMessageToBackend(const String& message)
    238 {
    239     if (m_client)
    240         m_client->sendMessageToBackend(message);
    241 }
    242 
    243 #if ENABLE(CONTEXT_MENUS)
    244 void InspectorFrontendHost::showContextMenu(Event* event, const Vector<ContextMenuItem*>& items)
    245 {
    246     ASSERT(m_frontendPage);
    247     ScriptState* frontendScriptState = scriptStateFromPage(debuggerWorld(), m_frontendPage);
    248     ScriptObject webInspectorObj;
    249     if (!ScriptGlobalObject::get(frontendScriptState, "WebInspector", webInspectorObj)) {
    250         ASSERT_NOT_REACHED();
    251         return;
    252     }
    253     RefPtr<FrontendMenuProvider> menuProvider = FrontendMenuProvider::create(this, webInspectorObj, items);
    254     ContextMenuController* menuController = m_frontendPage->contextMenuController();
    255     menuController->showContextMenu(event, menuProvider);
    256     m_menuProvider = menuProvider.get();
    257 }
    258 #endif
    259 
    260 } // namespace WebCore
    261 
    262 #endif // ENABLE(INSPECTOR)
    263