1/* 2 * Copyright (C) 2010 Apple 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 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' 14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS 17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 23 * THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#include "config.h" 27#include "WebInspector.h" 28 29#if ENABLE(INSPECTOR) 30#include "WebFrame.h" 31#include "WebInspectorFrontendClient.h" 32#include "WebInspectorProxyMessages.h" 33#include "WebPage.h" 34#include "WebPageCreationParameters.h" 35#include "WebProcess.h" 36#include <WebCore/InspectorController.h> 37#include <WebCore/InspectorFrontendClient.h> 38#include <WebCore/MainFrame.h> 39#include <WebCore/Page.h> 40#include <WebCore/ScriptController.h> 41#include <inspector/InspectorAgentBase.h> 42#include <bindings/ScriptValue.h> 43#include <wtf/text/StringConcatenate.h> 44 45using namespace WebCore; 46 47namespace WebKit { 48 49PassRefPtr<WebInspector> WebInspector::create(WebPage* page, InspectorFrontendChannel* frontendChannel) 50{ 51 return adoptRef(new WebInspector(page, frontendChannel)); 52} 53 54WebInspector::WebInspector(WebPage* page, InspectorFrontendChannel* frontendChannel) 55 : m_page(page) 56 , m_inspectorPage(nullptr) 57 , m_frontendClient(nullptr) 58 , m_frontendChannel(frontendChannel) 59#if PLATFORM(COCOA) 60 , m_hasLocalizedStringsURL(false) 61#endif 62#if ENABLE(INSPECTOR_SERVER) 63 , m_remoteFrontendConnected(false) 64#endif 65{ 66} 67 68// Called from WebInspectorClient 69WebPage* WebInspector::createInspectorPage() 70{ 71 if (!m_page) 72 return nullptr; 73 74 ASSERT(!m_inspectorPage); 75 ASSERT(!m_frontendClient); 76 77 uint64_t inspectorPageID = 0; 78 WebPageCreationParameters parameters; 79 80 if (!WebProcess::shared().parentProcessConnection()->sendSync(Messages::WebInspectorProxy::CreateInspectorPage(), 81 Messages::WebInspectorProxy::CreateInspectorPage::Reply(inspectorPageID, parameters), 82 m_page->pageID(), std::chrono::milliseconds::max())) { 83 return nullptr; 84 } 85 86 if (!inspectorPageID) 87 return nullptr; 88 89 WebProcess::shared().createWebPage(inspectorPageID, parameters); 90 m_inspectorPage = WebProcess::shared().webPage(inspectorPageID); 91 ASSERT(m_inspectorPage); 92 93 auto frontendClient = std::make_unique<WebInspectorFrontendClient>(m_page, m_inspectorPage); 94 m_frontendClient = frontendClient.get(); 95 m_inspectorPage->corePage()->inspectorController().setInspectorFrontendClient(WTF::move(frontendClient)); 96 return m_inspectorPage; 97} 98 99WebPage* WebInspector::createInspectorPageForTest() 100{ 101 if (!m_page) 102 return nullptr; 103 104 ASSERT(!m_inspectorPage); 105 ASSERT(!m_frontendClient); 106 107 uint64_t inspectorPageID = 0; 108 WebPageCreationParameters parameters; 109 110 if (!WebProcess::shared().parentProcessConnection()->sendSync(Messages::WebInspectorProxy::CreateInspectorPageForTest(), 111 Messages::WebInspectorProxy::CreateInspectorPageForTest::Reply(inspectorPageID, parameters), 112 m_page->pageID(), std::chrono::milliseconds::max())) { 113 return nullptr; 114 } 115 116 if (!inspectorPageID) 117 return nullptr; 118 119 WebProcess::shared().createWebPage(inspectorPageID, parameters); 120 m_inspectorPage = WebProcess::shared().webPage(inspectorPageID); 121 ASSERT(m_inspectorPage); 122 123 auto frontendClient = std::make_unique<WebInspectorFrontendClient>(m_page, m_inspectorPage); 124 m_frontendClient = frontendClient.get(); 125 m_inspectorPage->corePage()->inspectorController().setInspectorFrontendClient(WTF::move(frontendClient)); 126 return m_inspectorPage; 127} 128 129void WebInspector::destroyInspectorPage() 130{ 131 m_inspectorPage = nullptr; 132 m_frontendClient = nullptr; 133 m_frontendChannel = nullptr; 134} 135 136// Called from WebInspectorFrontendClient 137void WebInspector::didClose() 138{ 139 WebProcess::shared().parentProcessConnection()->send(Messages::WebInspectorProxy::DidClose(), m_page->pageID()); 140 destroyInspectorPage(); 141} 142 143void WebInspector::bringToFront() 144{ 145 WebProcess::shared().parentProcessConnection()->send(Messages::WebInspectorProxy::BringToFront(), m_page->pageID()); 146} 147 148void WebInspector::inspectedURLChanged(const String& urlString) 149{ 150 WebProcess::shared().parentProcessConnection()->send(Messages::WebInspectorProxy::InspectedURLChanged(urlString), m_page->pageID()); 151} 152 153void WebInspector::save(const String& filename, const String& content, bool base64Encoded, bool forceSaveAs) 154{ 155 WebProcess::shared().parentProcessConnection()->send(Messages::WebInspectorProxy::Save(filename, content, base64Encoded, forceSaveAs), m_page->pageID()); 156} 157 158void WebInspector::append(const String& filename, const String& content) 159{ 160 WebProcess::shared().parentProcessConnection()->send(Messages::WebInspectorProxy::Append(filename, content), m_page->pageID()); 161} 162 163void WebInspector::attachBottom() 164{ 165 WebProcess::shared().parentProcessConnection()->send(Messages::WebInspectorProxy::AttachBottom(), m_page->pageID()); 166} 167 168void WebInspector::attachRight() 169{ 170 WebProcess::shared().parentProcessConnection()->send(Messages::WebInspectorProxy::AttachRight(), m_page->pageID()); 171} 172 173void WebInspector::detach() 174{ 175 WebProcess::shared().parentProcessConnection()->send(Messages::WebInspectorProxy::Detach(), m_page->pageID()); 176} 177 178void WebInspector::setAttachedWindowHeight(unsigned height) 179{ 180 WebProcess::shared().parentProcessConnection()->send(Messages::WebInspectorProxy::SetAttachedWindowHeight(height), m_page->pageID()); 181} 182 183void WebInspector::setAttachedWindowWidth(unsigned width) 184{ 185 WebProcess::shared().parentProcessConnection()->send(Messages::WebInspectorProxy::SetAttachedWindowWidth(width), m_page->pageID()); 186} 187 188void WebInspector::setToolbarHeight(unsigned height) 189{ 190 WebProcess::shared().parentProcessConnection()->send(Messages::WebInspectorProxy::SetToolbarHeight(height), m_page->pageID()); 191} 192 193// Called by WebInspector messages 194void WebInspector::show() 195{ 196 m_page->corePage()->inspectorController().show(); 197} 198 199void WebInspector::close() 200{ 201 m_page->corePage()->inspectorController().close(); 202} 203 204void WebInspector::didSave(const String& url) 205{ 206 ASSERT(m_inspectorPage); 207 m_inspectorPage->corePage()->mainFrame().script().executeScript(makeString("InspectorFrontendAPI.savedURL(\"", url, "\")")); 208} 209 210void WebInspector::didAppend(const String& url) 211{ 212 ASSERT(m_inspectorPage); 213 m_inspectorPage->corePage()->mainFrame().script().executeScript(makeString("InspectorFrontendAPI.appendedToURL(\"", url, "\")")); 214} 215 216void WebInspector::attachedBottom() 217{ 218 if (m_frontendClient) 219 m_frontendClient->setAttachedWindow(InspectorFrontendClient::DOCKED_TO_BOTTOM); 220} 221 222void WebInspector::attachedRight() 223{ 224 if (m_frontendClient) 225 m_frontendClient->setAttachedWindow(InspectorFrontendClient::DOCKED_TO_RIGHT); 226} 227 228void WebInspector::detached() 229{ 230 if (m_frontendClient) 231 m_frontendClient->setAttachedWindow(InspectorFrontendClient::UNDOCKED); 232} 233 234void WebInspector::evaluateScriptForTest(const String& script) 235{ 236 m_page->corePage()->inspectorController().evaluateForTestInFrontend(script); 237} 238 239void WebInspector::showConsole() 240{ 241 m_page->corePage()->inspectorController().show(); 242 if (m_frontendClient) 243 m_frontendClient->showConsole(); 244} 245 246void WebInspector::showResources() 247{ 248 m_page->corePage()->inspectorController().show(); 249 if (m_frontendClient) 250 m_frontendClient->showResources(); 251} 252 253void WebInspector::showMainResourceForFrame(uint64_t frameID) 254{ 255 WebFrame* frame = WebProcess::shared().webFrame(frameID); 256 if (!frame) 257 return; 258 259 m_page->corePage()->inspectorController().show(); 260 if (m_frontendClient) 261 m_frontendClient->showMainResourceForFrame(frame->coreFrame()); 262} 263 264void WebInspector::startJavaScriptDebugging() 265{ 266 m_page->corePage()->inspectorController().show(); 267 if (m_frontendClient) 268 m_frontendClient->setDebuggingEnabled(true); 269} 270 271void WebInspector::stopJavaScriptDebugging() 272{ 273 m_page->corePage()->inspectorController().show(); 274 if (m_frontendClient) 275 m_frontendClient->setDebuggingEnabled(false); 276} 277 278void WebInspector::setJavaScriptProfilingEnabled(bool enabled) 279{ 280 // No longer supported. 281} 282 283void WebInspector::startJavaScriptProfiling() 284{ 285 // No longer supported. 286} 287 288void WebInspector::stopJavaScriptProfiling() 289{ 290 // No longer supported. 291} 292 293void WebInspector::startPageProfiling() 294{ 295 m_page->corePage()->inspectorController().show(); 296 if (m_frontendClient) 297 m_frontendClient->setTimelineProfilingEnabled(true); 298} 299 300void WebInspector::stopPageProfiling() 301{ 302 m_page->corePage()->inspectorController().show(); 303 if (m_frontendClient) 304 m_frontendClient->setTimelineProfilingEnabled(false); 305} 306 307void WebInspector::updateDockingAvailability() 308{ 309 if (!m_frontendClient) 310 return; 311 312 bool canAttachWindow = m_frontendClient->canAttachWindow(); 313 WebProcess::shared().parentProcessConnection()->send(Messages::WebInspectorProxy::AttachAvailabilityChanged(canAttachWindow), m_page->pageID()); 314 m_frontendClient->setDockingUnavailable(!canAttachWindow); 315} 316 317#if ENABLE(INSPECTOR_SERVER) 318void WebInspector::sendMessageToRemoteFrontend(const String& message) 319{ 320 ASSERT(m_remoteFrontendConnected); 321 WebProcess::shared().parentProcessConnection()->send(Messages::WebInspectorProxy::SendMessageToRemoteFrontend(message), m_page->pageID()); 322} 323 324void WebInspector::dispatchMessageFromRemoteFrontend(const String& message) 325{ 326 m_page->corePage()->inspectorController().dispatchMessageFromFrontend(message); 327} 328 329void WebInspector::remoteFrontendConnected() 330{ 331 ASSERT(!m_remoteFrontendConnected); 332 // Switching between in-process and remote inspectors isn't supported yet. 333 ASSERT(!m_inspectorPage); 334 335 m_page->corePage()->inspectorController().connectFrontend(m_frontendChannel); 336 m_remoteFrontendConnected = true; 337} 338 339void WebInspector::remoteFrontendDisconnected() 340{ 341 ASSERT(m_remoteFrontendConnected); 342 m_page->corePage()->inspectorController().disconnectFrontend(Inspector::InspectorDisconnectReason::InspectorDestroyed); 343 m_remoteFrontendConnected = false; 344} 345#endif 346 347} // namespace WebKit 348 349#endif // ENABLE(INSPECTOR) 350