1 /*
2 * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
3 * Copyright (C) 2008 Matt Lilek <webkit@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:
create(InspectorFrontendHost * frontendHost,ScriptObject webInspector,const Vector<ContextMenuItem * > & items)61 static PassRefPtr<FrontendMenuProvider> create(InspectorFrontendHost* frontendHost, ScriptObject webInspector, const Vector<ContextMenuItem*>& items)
62 {
63 return adoptRef(new FrontendMenuProvider(frontendHost, webInspector, items));
64 }
65
disconnect()66 void disconnect()
67 {
68 m_webInspector = ScriptObject();
69 m_frontendHost = 0;
70 }
71
72 private:
FrontendMenuProvider(InspectorFrontendHost * frontendHost,ScriptObject webInspector,const Vector<ContextMenuItem * > & items)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
~FrontendMenuProvider()80 virtual ~FrontendMenuProvider()
81 {
82 contextMenuCleared();
83 }
84
populateContextMenu(ContextMenu * menu)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
contextMenuItemSelected(ContextMenuItem * item)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
contextMenuCleared()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
InspectorFrontendHost(InspectorFrontendClient * client,Page * frontendPage)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
~InspectorFrontendHost()129 InspectorFrontendHost::~InspectorFrontendHost()
130 {
131 ASSERT(!m_client);
132 }
133
disconnectClient()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
loaded()144 void InspectorFrontendHost::loaded()
145 {
146 if (m_client)
147 m_client->frontendLoaded();
148 }
149
requestAttachWindow()150 void InspectorFrontendHost::requestAttachWindow()
151 {
152 if (m_client)
153 m_client->requestAttachWindow();
154 }
155
requestDetachWindow()156 void InspectorFrontendHost::requestDetachWindow()
157 {
158 if (m_client)
159 m_client->requestDetachWindow();
160 }
161
closeWindow()162 void InspectorFrontendHost::closeWindow()
163 {
164 if (m_client) {
165 m_client->closeWindow();
166 disconnectClient(); // Disconnect from client.
167 }
168 }
169
disconnectFromBackend()170 void InspectorFrontendHost::disconnectFromBackend()
171 {
172 if (m_client) {
173 m_client->disconnectFromBackend();
174 disconnectClient(); // Disconnect from client.
175 }
176 }
177
bringToFront()178 void InspectorFrontendHost::bringToFront()
179 {
180 if (m_client)
181 m_client->bringToFront();
182 }
183
inspectedURLChanged(const String & newURL)184 void InspectorFrontendHost::inspectedURLChanged(const String& newURL)
185 {
186 if (m_client)
187 m_client->inspectedURLChanged(newURL);
188 }
189
setAttachedWindowHeight(unsigned height)190 void InspectorFrontendHost::setAttachedWindowHeight(unsigned height)
191 {
192 if (m_client)
193 m_client->changeAttachedWindowHeight(height);
194 }
195
moveWindowBy(float x,float y) const196 void InspectorFrontendHost::moveWindowBy(float x, float y) const
197 {
198 if (m_client)
199 m_client->moveWindowBy(x, y);
200 }
201
setExtensionAPI(const String & script)202 void InspectorFrontendHost::setExtensionAPI(const String& script)
203 {
204 ASSERT(m_frontendPage->inspectorController());
205 m_frontendPage->inspectorController()->setInspectorExtensionAPI(script);
206 }
207
localizedStringsURL()208 String InspectorFrontendHost::localizedStringsURL()
209 {
210 return m_client->localizedStringsURL();
211 }
212
hiddenPanels()213 String InspectorFrontendHost::hiddenPanels()
214 {
215 return m_client->hiddenPanels();
216 }
217
copyText(const String & text)218 void InspectorFrontendHost::copyText(const String& text)
219 {
220 Pasteboard::generalPasteboard()->writePlainText(text);
221 }
222
saveSessionSetting(const String & key,const String & value)223 void InspectorFrontendHost::saveSessionSetting(const String& key, const String& value)
224 {
225 if (m_client)
226 m_client->saveSessionSetting(key, value);
227 }
228
loadSessionSetting(const String & key)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
sendMessageToBackend(const String & message)237 void InspectorFrontendHost::sendMessageToBackend(const String& message)
238 {
239 if (m_client)
240 m_client->sendMessageToBackend(message);
241 }
242
243 #if ENABLE(CONTEXT_MENUS)
showContextMenu(Event * event,const Vector<ContextMenuItem * > & items)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