summaryrefslogtreecommitdiffstats
path: root/WebCore/inspector/InspectorController.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/inspector/InspectorController.cpp')
-rw-r--r--WebCore/inspector/InspectorController.cpp670
1 files changed, 357 insertions, 313 deletions
diff --git a/WebCore/inspector/InspectorController.cpp b/WebCore/inspector/InspectorController.cpp
index b487ad8..c54ee5b 100644
--- a/WebCore/inspector/InspectorController.cpp
+++ b/WebCore/inspector/InspectorController.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
* Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com>
*
* Redistribution and use in source and binary forms, with or without
@@ -32,7 +32,6 @@
#if ENABLE(INSPECTOR)
-#include "CString.h"
#include "CachedResource.h"
#include "Chrome.h"
#include "Console.h"
@@ -57,12 +56,12 @@
#include "InjectedScriptHost.h"
#include "InspectorBackend.h"
#include "InspectorClient.h"
-#include "InspectorDOMAgent.h"
+#include "InspectorFrontendClient.h"
#include "InspectorDOMStorageResource.h"
#include "InspectorDatabaseResource.h"
#include "InspectorFrontend.h"
-#include "InspectorFrontendHost.h"
#include "InspectorResource.h"
+#include "InspectorWorkerResource.h"
#include "InspectorTimelineAgent.h"
#include "Page.h"
#include "ProgressTracker.h"
@@ -70,18 +69,20 @@
#include "RenderInline.h"
#include "ResourceRequest.h"
#include "ResourceResponse.h"
+#include "ScriptBreakpoint.h"
#include "ScriptCallStack.h"
-#include "ScriptDebugServer.h"
#include "ScriptFunctionCall.h"
#include "ScriptObject.h"
#include "ScriptProfile.h"
#include "ScriptProfiler.h"
+#include "ScriptSourceCode.h"
#include "ScriptString.h"
#include "SecurityOrigin.h"
#include "Settings.h"
#include "SharedBuffer.h"
#include "TextEncoding.h"
#include "TextIterator.h"
+#include <wtf/text/CString.h>
#include <wtf/CurrentTime.h>
#include <wtf/ListHashSet.h>
#include <wtf/RefCounted.h>
@@ -96,17 +97,17 @@
#include "StorageArea.h"
#endif
-#if ENABLE(JAVASCRIPT_DEBUGGER) && USE(JSC)
-#include "JSJavaScriptCallFrame.h"
-#include "JavaScriptCallFrame.h"
-#include "JavaScriptDebugServer.h"
-#include "JavaScriptProfile.h"
-
+#if ENABLE(JAVASCRIPT_DEBUGGER)
+#include "ScriptDebugServer.h"
+#if USE(JSC)
#include <runtime/JSLock.h>
#include <runtime/UString.h>
-
-using namespace JSC;
+#include "JSScriptProfile.h"
+#else
+#include "V8ScriptProfile.h"
+#endif
#endif
+
using namespace std;
namespace WebCore {
@@ -118,7 +119,18 @@ static const char* const debuggerEnabledSettingName = "debuggerEnabled";
static const char* const profilerEnabledSettingName = "profilerEnabled";
static const char* const inspectorAttachedHeightName = "inspectorAttachedHeight";
static const char* const lastActivePanelSettingName = "lastActivePanel";
-const char* const InspectorController::FrontendSettingsSettingName = "frontendSettings";
+
+const String& InspectorController::frontendSettingsSettingName()
+{
+ DEFINE_STATIC_LOCAL(String, settingName, ("frontendSettings"));
+ return settingName;
+}
+
+const String& InspectorController::inspectorStartsAttachedSettingName()
+{
+ DEFINE_STATIC_LOCAL(String, settingName, ("inspectorStartsAttached"));
+ return settingName;
+}
static const unsigned defaultAttachedHeight = 300;
static const float minimumAttachedHeight = 250.0f;
@@ -131,10 +143,8 @@ static unsigned s_inspectorControllerCount;
InspectorController::InspectorController(Page* page, InspectorClient* client)
: m_inspectedPage(page)
, m_client(client)
- , m_page(0)
+ , m_openingFrontend(false)
, m_expiredConsoleMessageCount(0)
- , m_frontendScriptState(0)
- , m_windowVisible(false)
, m_showAfterVisible(CurrentPanel)
, m_groupLevel(0)
, m_searchingForNode(false)
@@ -142,9 +152,8 @@ InspectorController::InspectorController(Page* page, InspectorClient* client)
, m_resourceTrackingEnabled(false)
, m_resourceTrackingSettingsLoaded(false)
, m_inspectorBackend(InspectorBackend::create(this))
- , m_inspectorFrontendHost(InspectorFrontendHost::create(this, client))
, m_injectedScriptHost(InjectedScriptHost::create(this))
-#if ENABLE(JAVASCRIPT_DEBUGGER) && USE(JSC)
+#if ENABLE(JAVASCRIPT_DEBUGGER)
, m_debuggerEnabled(false)
, m_attachDebuggerWhenShown(false)
#endif
@@ -165,9 +174,7 @@ InspectorController::~InspectorController()
{
// These should have been cleared in inspectedPageDestroyed().
ASSERT(!m_client);
- ASSERT(!m_frontendScriptState);
ASSERT(!m_inspectedPage);
- ASSERT(!m_page || (m_page && !m_page->parentInspectorController()));
deleteAllValues(m_frameResources);
deleteAllValues(m_consoleMessages);
@@ -178,18 +185,14 @@ InspectorController::~InspectorController()
releaseDOMAgent();
m_inspectorBackend->disconnectController();
- m_inspectorFrontendHost->disconnectController();
m_injectedScriptHost->disconnectController();
}
void InspectorController::inspectedPageDestroyed()
{
- close();
+ if (m_frontend)
+ m_frontend->inspectedPageDestroyed();
- if (m_frontendScriptState) {
- ScriptGlobalObject::remove(m_frontendScriptState, "InspectorBackend");
- ScriptGlobalObject::remove(m_frontendScriptState, "InspectorFrontendHost");
- }
ASSERT(m_inspectedPage);
m_inspectedPage = 0;
@@ -222,20 +225,9 @@ void InspectorController::setSetting(const String& key, const String& value)
m_client->storeSetting(key, value);
}
-// Trying to inspect something in a frame with JavaScript disabled would later lead to
-// crashes trying to create JavaScript wrappers. Some day we could fix this issue, but
-// for now prevent crashes here by never targeting a node in such a frame.
-static bool canPassNodeToJavaScript(Node* node)
-{
- if (!node)
- return false;
- Frame* frame = node->document()->frame();
- return frame && frame->script()->canExecuteScripts();
-}
-
void InspectorController::inspect(Node* node)
{
- if (!canPassNodeToJavaScript(node) || !enabled())
+ if (!enabled())
return;
show();
@@ -284,48 +276,7 @@ void InspectorController::hideHighlight()
bool InspectorController::windowVisible()
{
- return m_windowVisible;
-}
-
-void InspectorController::setWindowVisible(bool visible, bool attached)
-{
- if (visible == m_windowVisible || !m_frontend)
- return;
-
- m_windowVisible = visible;
-
- if (m_windowVisible) {
- setAttachedWindow(attached);
- populateScriptObjects();
-
- if (m_showAfterVisible == CurrentPanel) {
- String lastActivePanelSetting = setting(lastActivePanelSettingName);
- m_showAfterVisible = specialPanelForJSName(lastActivePanelSetting);
- }
-
- if (m_nodeToFocus)
- focusNode();
-#if ENABLE(JAVASCRIPT_DEBUGGER) && USE(JSC)
- if (m_attachDebuggerWhenShown)
- enableDebugger();
-#endif
- showPanel(m_showAfterVisible);
- } else {
-#if ENABLE(JAVASCRIPT_DEBUGGER) && USE(JSC)
- // If the window is being closed with the debugger enabled,
- // remember this state to re-enable debugger on the next window
- // opening.
- bool debuggerWasEnabled = m_debuggerEnabled;
- disableDebugger();
- if (debuggerWasEnabled)
- m_attachDebuggerWhenShown = true;
-#endif
- if (m_searchingForNode)
- toggleSearchForNodeInPage();
- resetScriptObjects();
- stopTimelineProfiler();
- }
- m_showAfterVisible = CurrentPanel;
+ return m_frontend;
}
void InspectorController::addMessageToConsole(MessageSource source, MessageType type, MessageLevel level, ScriptCallStack* callStack)
@@ -352,16 +303,16 @@ void InspectorController::addConsoleMessage(ScriptState* scriptState, ConsoleMes
if (m_previousMessage && m_previousMessage->isEqual(scriptState, consoleMessage)) {
m_previousMessage->incrementCount();
delete consoleMessage;
- if (windowVisible())
+ if (m_frontend)
m_previousMessage->updateRepeatCountInConsole(m_frontend.get());
} else {
m_previousMessage = consoleMessage;
m_consoleMessages.append(consoleMessage);
- if (windowVisible())
- m_previousMessage->addToConsole(m_frontend.get());
+ if (m_frontend)
+ m_previousMessage->addToFrontend(m_frontend.get(), m_injectedScriptHost.get());
}
- if (!windowVisible() && m_consoleMessages.size() >= maximumConsoleMessages) {
+ if (!m_frontend && m_consoleMessages.size() >= maximumConsoleMessages) {
m_expiredConsoleMessageCount += expireConsoleMessagesStep;
for (size_t i = 0; i < expireConsoleMessagesStep; ++i)
delete m_consoleMessages[i];
@@ -406,127 +357,79 @@ void InspectorController::markTimeline(const String& message)
timelineAgent()->didMarkTimeline(message);
}
-static unsigned constrainedAttachedWindowHeight(unsigned preferredHeight, unsigned totalWindowHeight)
-{
- return roundf(max(minimumAttachedHeight, min<float>(preferredHeight, totalWindowHeight * maximumAttachedHeightRatio)));
-}
-
-void InspectorController::attachWindow()
-{
- if (!enabled())
- return;
-
- unsigned inspectedPageHeight = m_inspectedPage->mainFrame()->view()->visibleHeight();
-
- m_client->attachWindow();
-
- String attachedHeight = setting(inspectorAttachedHeightName);
- bool success = true;
- int height = attachedHeight.toInt(&success);
- unsigned preferredHeight = success ? height : defaultAttachedHeight;
-
- // We need to constrain the window height here in case the user has resized the inspected page's window so that
- // the user's preferred height would be too big to display.
- m_client->setAttachedWindowHeight(constrainedAttachedWindowHeight(preferredHeight, inspectedPageHeight));
-}
-
-void InspectorController::detachWindow()
-{
- if (!enabled())
- return;
- m_client->detachWindow();
-}
-
-void InspectorController::setAttachedWindow(bool attached)
-{
- if (!enabled() || !m_frontend)
- return;
-
- m_frontend->setAttachedWindow(attached);
-}
-
-void InspectorController::setAttachedWindowHeight(unsigned height)
-{
- if (!enabled())
- return;
-
- unsigned totalHeight = m_page->mainFrame()->view()->visibleHeight() + m_inspectedPage->mainFrame()->view()->visibleHeight();
- unsigned attachedHeight = constrainedAttachedWindowHeight(height, totalHeight);
-
- setSetting(inspectorAttachedHeightName, String::number(attachedHeight));
-
- m_client->setAttachedWindowHeight(attachedHeight);
-}
-
void InspectorController::storeLastActivePanel(const String& panelName)
{
setSetting(lastActivePanelSettingName, panelName);
}
-void InspectorController::toggleSearchForNodeInPage()
-{
- if (!enabled())
- return;
-
- m_searchingForNode = !m_searchingForNode;
- if (!m_searchingForNode)
- hideHighlight();
-}
-
void InspectorController::mouseDidMoveOverElement(const HitTestResult& result, unsigned)
{
if (!enabled() || !m_searchingForNode)
return;
Node* node = result.innerNode();
+ while (node && node->nodeType() == Node::TEXT_NODE)
+ node = node->parentNode();
if (node)
highlight(node);
}
-void InspectorController::handleMousePressOnNode(Node* node)
+void InspectorController::handleMousePress()
{
if (!enabled())
return;
ASSERT(m_searchingForNode);
- ASSERT(node);
- if (!node)
+ if (!m_highlightedNode)
return;
- // inspect() will implicitly call ElementsPanel's focusedNodeChanged() and the hover feedback will be stopped there.
- inspect(node);
+ RefPtr<Node> node = m_highlightedNode;
+ setSearchingForNode(false);
+ inspect(node.get());
+}
+
+void InspectorController::setInspectorFrontendClient(PassOwnPtr<InspectorFrontendClient> client)
+{
+ ASSERT(!m_inspectorFrontendClient);
+ m_inspectorFrontendClient = client;
}
void InspectorController::inspectedWindowScriptObjectCleared(Frame* frame)
{
+ // If the page is supposed to serve as InspectorFrontend notify inspetor frontend
+ // client that it's cleared so that the client can expose inspector bindings.
+ if (m_inspectorFrontendClient && frame == m_inspectedPage->mainFrame())
+ m_inspectorFrontendClient->windowObjectCleared();
+
if (!enabled() || !m_frontend || frame != m_inspectedPage->mainFrame())
return;
m_injectedScriptHost->discardInjectedScripts();
}
-void InspectorController::windowScriptObjectAvailable()
+void InspectorController::setSearchingForNode(bool enabled)
{
- if (!m_page || !enabled())
+ if (m_searchingForNode == enabled)
return;
-
- // Grant the inspector the ability to script the inspected page.
- m_page->mainFrame()->document()->securityOrigin()->grantUniversalAccess();
- m_frontendScriptState = scriptStateFromPage(debuggerWorld(), m_page);
- ScriptGlobalObject::set(m_frontendScriptState, "InspectorBackend", m_inspectorBackend.get());
- ScriptGlobalObject::set(m_frontendScriptState, "InspectorFrontendHost", m_inspectorFrontendHost.get());
+ m_searchingForNode = enabled;
+ if (!m_searchingForNode)
+ hideHighlight();
+ if (m_frontend) {
+ if (enabled)
+ m_frontend->searchingForNodeWasEnabled();
+ else
+ m_frontend->searchingForNodeWasDisabled();
+ }
}
-void InspectorController::scriptObjectReady()
+void InspectorController::setFrontend(PassOwnPtr<InspectorFrontend> frontend)
{
- ASSERT(m_frontendScriptState);
- if (!m_frontendScriptState)
- return;
-
- ScriptObject webInspectorObj;
- if (!ScriptGlobalObject::get(m_frontendScriptState, "WebInspector", webInspectorObj))
- return;
- setFrontendProxyObject(m_frontendScriptState, webInspectorObj);
-
+ ASSERT(frontend);
+ m_openingFrontend = false;
+ m_frontend = frontend;
+ releaseDOMAgent();
+ m_domAgent = InspectorDOMAgent::create(m_frontend.get());
+ if (m_timelineAgent)
+ m_timelineAgent->resetFrontendProxyObject(m_frontend.get());
#if ENABLE(JAVASCRIPT_DEBUGGER) && USE(JSC)
String debuggerEnabled = setting(debuggerEnabledSettingName);
if (debuggerEnabled == "true")
@@ -536,41 +439,39 @@ void InspectorController::scriptObjectReady()
enableProfiler();
#endif
- // Make sure our window is visible now that the page loaded
- showWindow();
-
- m_client->inspectorWindowObjectCleared();
-}
+ // Initialize Web Inspector title.
+ m_frontend->inspectedURLChanged(m_inspectedPage->mainFrame()->loader()->url().string());
-void InspectorController::setFrontendProxyObject(ScriptState* scriptState, ScriptObject webInspectorObj, ScriptObject)
-{
- m_frontendScriptState = scriptState;
- m_frontend.set(new InspectorFrontend(this, webInspectorObj));
- releaseDOMAgent();
- m_domAgent = InspectorDOMAgent::create(m_frontend.get());
- if (m_timelineAgent)
- m_timelineAgent->resetFrontendProxyObject(m_frontend.get());
+ populateScriptObjects();
+
+ if (m_showAfterVisible == CurrentPanel) {
+ String lastActivePanelSetting = setting(lastActivePanelSettingName);
+ m_showAfterVisible = specialPanelForJSName(lastActivePanelSetting);
+ }
+
+ if (m_nodeToFocus)
+ focusNode();
+#if ENABLE(JAVASCRIPT_DEBUGGER)
+ if (m_attachDebuggerWhenShown)
+ enableDebugger();
+#endif
+ showPanel(m_showAfterVisible);
}
void InspectorController::show()
{
if (!enabled())
return;
-
- if (!m_page) {
- if (m_frontend)
- return; // We are using custom frontend - no need to create page.
- m_page = m_client->createPage();
- if (!m_page)
- return;
- m_page->setParentInspectorController(this);
-
- // showWindow() will be called after the page loads in scriptObjectReady()
+ if (m_openingFrontend)
return;
+
+ if (m_frontend)
+ m_frontend->bringToFront();
+ else {
+ m_openingFrontend = true;
+ m_client->openInspectorFrontend(this);
}
-
- showWindow();
}
void InspectorController::showPanel(SpecialPanels panel)
@@ -593,49 +494,40 @@ void InspectorController::showPanel(SpecialPanels panel)
void InspectorController::close()
{
- if (!enabled())
+ if (!m_frontend)
return;
-
-#if ENABLE(JAVASCRIPT_DEBUGGER) && USE(JSC)
- stopUserInitiatedProfiling();
- disableDebugger();
-#endif
- closeWindow();
-
- releaseDOMAgent();
- m_frontend.set(0);
- m_timelineAgent = 0;
- m_frontendScriptState = 0;
- if (m_page) {
- if (!m_page->mainFrame() || !m_page->mainFrame()->loader() || !m_page->mainFrame()->loader()->isLoading()) {
- m_page->setParentInspectorController(0);
- m_page = 0;
- }
- }
+ m_frontend->close();
}
-void InspectorController::showWindow()
+void InspectorController::disconnectFrontend()
{
- ASSERT(enabled());
+ if (!m_frontend)
+ return;
+ m_frontend.clear();
- unsigned inspectedPageHeight = m_inspectedPage->mainFrame()->view()->visibleHeight();
+#if ENABLE(JAVASCRIPT_DEBUGGER)
+ // If the window is being closed with the debugger enabled,
+ // remember this state to re-enable debugger on the next window
+ // opening.
+ bool debuggerWasEnabled = m_debuggerEnabled;
+ disableDebugger();
+ if (debuggerWasEnabled)
+ m_attachDebuggerWhenShown = true;
+#endif
+ setSearchingForNode(false);
+ unbindAllResources();
+ stopTimelineProfiler();
- m_client->showWindow();
+ m_showAfterVisible = CurrentPanel;
- String attachedHeight = setting(inspectorAttachedHeightName);
- bool success = true;
- int height = attachedHeight.toInt(&success);
- unsigned preferredHeight = success ? height : defaultAttachedHeight;
+ hideHighlight();
- // This call might not go through (if the window starts out detached), but if the window is initially created attached,
- // InspectorController::attachWindow is never called, so we need to make sure to set the attachedWindowHeight.
- // FIXME: Clean up code so we only have to call setAttachedWindowHeight in InspectorController::attachWindow
- m_client->setAttachedWindowHeight(constrainedAttachedWindowHeight(preferredHeight, inspectedPageHeight));
-}
+#if ENABLE(JAVASCRIPT_DEBUGGER)
+ stopUserInitiatedProfiling();
+#endif
-void InspectorController::closeWindow()
-{
- m_client->closeWindow();
+ releaseDOMAgent();
+ m_timelineAgent.clear();
}
void InspectorController::releaseDOMAgent()
@@ -644,7 +536,7 @@ void InspectorController::releaseDOMAgent()
// no references to the DOM agent from the DOM tree.
if (m_domAgent)
m_domAgent->reset();
- m_domAgent = 0;
+ m_domAgent.clear();
}
void InspectorController::populateScriptObjects()
@@ -653,7 +545,20 @@ void InspectorController::populateScriptObjects()
if (!m_frontend)
return;
- m_frontend->populateFrontendSettings(setting(FrontendSettingsSettingName));
+ m_frontend->populateFrontendSettings(setting(frontendSettingsSettingName()));
+
+ if (m_resourceTrackingEnabled)
+ m_frontend->resourceTrackingWasEnabled();
+
+ if (m_searchingForNode)
+ m_frontend->searchingForNodeWasEnabled();
+ else
+ m_frontend->searchingForNodeWasDisabled();
+
+#if ENABLE(JAVASCRIPT_DEBUGGER)
+ if (m_profilerEnabled)
+ m_frontend->profilerWasEnabled();
+#endif
ResourcesMap::iterator resourcesEnd = m_resources.end();
for (ResourcesMap::iterator it = m_resources.begin(); it != resourcesEnd; ++it)
@@ -665,8 +570,12 @@ void InspectorController::populateScriptObjects()
m_frontend->updateConsoleMessageExpiredCount(m_expiredConsoleMessageCount);
unsigned messageCount = m_consoleMessages.size();
for (unsigned i = 0; i < messageCount; ++i)
- m_consoleMessages[i]->addToConsole(m_frontend.get());
+ m_consoleMessages[i]->addToFrontend(m_frontend.get(), m_injectedScriptHost.get());
+#if ENABLE(JAVASCRIPT_DEBUGGER)
+ if (m_debuggerEnabled)
+ m_frontend->updatePauseOnExceptionsState(ScriptDebugServer::shared().pauseOnExceptionsState());
+#endif
#if ENABLE(DATABASE)
DatabaseResourcesMap::iterator databasesEnd = m_databaseResources.end();
for (DatabaseResourcesMap::iterator it = m_databaseResources.begin(); it != databasesEnd; ++it)
@@ -677,6 +586,11 @@ void InspectorController::populateScriptObjects()
for (DOMStorageResourcesMap::iterator it = m_domStorageResources.begin(); it != domStorageEnd; ++it)
it->second->bind(m_frontend.get());
#endif
+#if ENABLE(WORKERS)
+ WorkersMap::iterator workersEnd = m_workers.end();
+ for (WorkersMap::iterator it = m_workers.begin(); it != workersEnd; ++it)
+ m_frontend->didCreateWorker(*it->second);
+#endif
m_frontend->populateInterface();
@@ -686,15 +600,12 @@ void InspectorController::populateScriptObjects()
m_pendingEvaluateTestCommands.clear();
}
-void InspectorController::resetScriptObjects()
+void InspectorController::unbindAllResources()
{
- if (!m_frontend)
- return;
-
- ResourcesMap::iterator resourcesEnd = m_resources.end();
- for (ResourcesMap::iterator it = m_resources.begin(); it != resourcesEnd; ++it)
- it->second->releaseScriptObject(m_frontend.get(), false);
-
+ ResourcesMap::iterator resourcesEnd = m_resources.end();
+ for (ResourcesMap::iterator it = m_resources.begin(); it != resourcesEnd; ++it)
+ it->second->releaseScriptObject(0);
+
#if ENABLE(DATABASE)
DatabaseResourcesMap::iterator databasesEnd = m_databaseResources.end();
for (DatabaseResourcesMap::iterator it = m_databaseResources.begin(); it != databasesEnd; ++it)
@@ -705,12 +616,8 @@ void InspectorController::resetScriptObjects()
for (DOMStorageResourcesMap::iterator it = m_domStorageResources.begin(); it != domStorageEnd; ++it)
it->second->unbind();
#endif
-
if (m_timelineAgent)
m_timelineAgent->reset();
-
- m_frontend->reset();
- m_domAgent->reset();
}
void InspectorController::pruneResources(ResourcesMap* resourceMap, DocumentLoader* loaderToKeep)
@@ -726,8 +633,8 @@ void InspectorController::pruneResources(ResourcesMap* resourceMap, DocumentLoad
if (!loaderToKeep || !resource->isSameLoader(loaderToKeep)) {
removeResource(resource);
- if (windowVisible())
- resource->releaseScriptObject(m_frontend.get(), true);
+ if (m_frontend)
+ resource->releaseScriptObject(m_frontend.get());
}
}
}
@@ -740,13 +647,17 @@ void InspectorController::didCommitLoad(DocumentLoader* loader)
ASSERT(m_inspectedPage);
if (loader->frame() == m_inspectedPage->mainFrame()) {
- m_client->inspectedURLChanged(loader->url().string());
+ if (m_frontend)
+ m_frontend->inspectedURLChanged(loader->url().string());
m_injectedScriptHost->discardInjectedScripts();
clearConsoleMessages();
m_times.clear();
m_counts.clear();
+#if ENABLE(JAVASCRIPT_DEBUGGER)
+ m_sourceIDToURL.clear();
+#endif
#if ENABLE(JAVASCRIPT_DEBUGGER) && USE(JSC)
m_profiles.clear();
m_currentUserInitiatedProfileNumber = 1;
@@ -754,8 +665,13 @@ void InspectorController::didCommitLoad(DocumentLoader* loader)
#endif
// resetScriptObjects should be called before database and DOM storage
// resources are cleared so that it has a chance to unbind them.
- resetScriptObjects();
-
+ if (m_frontend) {
+ m_frontend->reset();
+ m_domAgent->reset();
+ }
+#if ENABLE(WORKERS)
+ m_workers.clear();
+#endif
#if ENABLE(DATABASE)
m_databaseResources.clear();
#endif
@@ -769,8 +685,7 @@ void InspectorController::didCommitLoad(DocumentLoader* loader)
// We don't add the main resource until its load is committed. This is
// needed to keep the load for a user-entered URL from showing up in the
// list of resources for the page they are navigating away from.
- if (windowVisible())
- m_mainResource->updateScriptObject(m_frontend.get());
+ m_mainResource->updateScriptObject(m_frontend.get());
} else {
// Pages loaded from the page cache are committed before
// m_mainResource is the right resource for this load, so we
@@ -778,16 +693,22 @@ void InspectorController::didCommitLoad(DocumentLoader* loader)
// identifierForInitialRequest.
m_mainResource = 0;
}
- if (windowVisible()) {
- m_frontend->didCommitLoad();
- m_domAgent->setDocument(m_inspectedPage->mainFrame()->document());
- }
+ m_frontend->didCommitLoad();
+ m_domAgent->setDocument(m_inspectedPage->mainFrame()->document());
}
}
for (Frame* frame = loader->frame(); frame; frame = frame->tree()->traverseNext(loader->frame()))
if (ResourcesMap* resourceMap = m_frameResources.get(frame))
pruneResources(resourceMap, loader);
+
+ if (m_scriptsToEvaluateOnLoad.size()) {
+ ScriptState* scriptState = mainWorldScriptState(loader->frame());
+ for (Vector<String>::iterator it = m_scriptsToEvaluateOnLoad.begin();
+ it != m_scriptsToEvaluateOnLoad.end(); ++it) {
+ m_injectedScriptHost->injectScript(*it, scriptState);
+ }
+ }
}
void InspectorController::frameDetachedFromParent(Frame* frame)
@@ -874,7 +795,7 @@ void InspectorController::didLoadResourceFromMemoryCache(DocumentLoader* loader,
addResource(resource.get());
- if (windowVisible())
+ if (m_frontend)
resource->updateScriptObject(m_frontend.get());
}
@@ -898,7 +819,7 @@ void InspectorController::identifierForInitialRequest(unsigned long identifier,
addResource(resource.get());
- if (windowVisible() && loader->frameLoader()->isLoadingFromCachedPage() && resource == m_mainResource)
+ if (m_frontend && loader->frameLoader()->isLoadingFromCachedPage() && resource == m_mainResource)
resource->updateScriptObject(m_frontend.get());
}
@@ -909,7 +830,9 @@ void InspectorController::mainResourceFiredDOMContentEvent(DocumentLoader* loade
if (m_mainResource) {
m_mainResource->markDOMContentEventTime();
- if (windowVisible())
+ if (m_timelineAgent)
+ m_timelineAgent->didMarkDOMContentEvent();
+ if (m_frontend)
m_mainResource->updateScriptObject(m_frontend.get());
}
}
@@ -921,7 +844,9 @@ void InspectorController::mainResourceFiredLoadEvent(DocumentLoader* loader, con
if (m_mainResource) {
m_mainResource->markLoadEventTime();
- if (windowVisible())
+ if (m_timelineAgent)
+ m_timelineAgent->didMarkLoadEvent();
+ if (m_frontend)
m_mainResource->updateScriptObject(m_frontend.get());
}
}
@@ -961,15 +886,12 @@ void InspectorController::willSendRequest(unsigned long identifier, const Resour
resource->startTiming();
resource->updateRequest(request);
- if (resource != m_mainResource && windowVisible())
+ if (resource != m_mainResource && m_frontend)
resource->updateScriptObject(m_frontend.get());
}
void InspectorController::didReceiveResponse(unsigned long identifier, const ResourceResponse& response)
{
- if (m_timelineAgent)
- m_timelineAgent->didReceiveResourceResponse(identifier, response);
-
RefPtr<InspectorResource> resource = getTrackedResource(identifier);
if (!resource)
return;
@@ -977,7 +899,7 @@ void InspectorController::didReceiveResponse(unsigned long identifier, const Res
resource->updateResponse(response);
resource->markResponseReceivedTime();
- if (resource != m_mainResource && windowVisible())
+ if (resource != m_mainResource && m_frontend)
resource->updateScriptObject(m_frontend.get());
}
@@ -989,7 +911,7 @@ void InspectorController::didReceiveContentLength(unsigned long identifier, int
resource->addLength(lengthReceived);
- if (resource != m_mainResource && windowVisible())
+ if (resource != m_mainResource && m_frontend)
resource->updateScriptObject(m_frontend.get());
}
@@ -1004,7 +926,8 @@ void InspectorController::didFinishLoading(unsigned long identifier)
resource->endTiming();
- if (resource != m_mainResource && windowVisible())
+ // No need to mute this event for main resource since it happens after did commit load.
+ if (m_frontend)
resource->updateScriptObject(m_frontend.get());
}
@@ -1020,7 +943,8 @@ void InspectorController::didFailLoading(unsigned long identifier, const Resourc
resource->markFailed();
resource->endTiming();
- if (resource != m_mainResource && windowVisible())
+ // No need to mute this event for main resource since it happens after did commit load.
+ if (m_frontend)
resource->updateScriptObject(m_frontend.get());
}
@@ -1033,9 +957,9 @@ void InspectorController::resourceRetrievedByXMLHttpRequest(unsigned long identi
if (!resource)
return;
- resource->setXMLHttpResponseText(sourceString);
+ resource->setOverrideContent(sourceString, InspectorResource::XHR);
- if (windowVisible())
+ if (m_frontend)
resource->updateScriptObject(m_frontend.get());
}
@@ -1048,11 +972,9 @@ void InspectorController::scriptImported(unsigned long identifier, const String&
if (!resource)
return;
- // FIXME: imported script and XHR response are currently viewed as the same
- // thing by the Inspector. They should be made into distinct types.
- resource->setXMLHttpResponseText(ScriptString(sourceString));
+ resource->setOverrideContent(ScriptString(sourceString), InspectorResource::Script);
- if (windowVisible())
+ if (m_frontend)
resource->updateScriptObject(m_frontend.get());
}
@@ -1073,7 +995,7 @@ void InspectorController::enableResourceTracking(bool always, bool reload)
m_frontend->resourceTrackingWasEnabled();
if (reload)
- m_inspectedPage->mainFrame()->loader()->reload();
+ m_inspectedPage->mainFrame()->redirectScheduler()->scheduleRefresh(true);
}
void InspectorController::disableResourceTracking(bool always)
@@ -1127,6 +1049,71 @@ void InspectorController::stopTimelineProfiler()
m_frontend->timelineProfilerWasStopped();
}
+#if ENABLE(WORKERS)
+class PostWorkerNotificationToFrontendTask : public ScriptExecutionContext::Task {
+public:
+ static PassOwnPtr<PostWorkerNotificationToFrontendTask> create(PassRefPtr<InspectorWorkerResource> worker, InspectorController::WorkerAction action)
+ {
+ return new PostWorkerNotificationToFrontendTask(worker, action);
+ }
+
+private:
+ PostWorkerNotificationToFrontendTask(PassRefPtr<InspectorWorkerResource> worker, InspectorController::WorkerAction action)
+ : m_worker(worker)
+ , m_action(action)
+ {
+ }
+
+ virtual void performTask(ScriptExecutionContext* scriptContext)
+ {
+ if (InspectorController* inspector = scriptContext->inspectorController())
+ inspector->postWorkerNotificationToFrontend(*m_worker, m_action);
+ }
+
+private:
+ RefPtr<InspectorWorkerResource> m_worker;
+ InspectorController::WorkerAction m_action;
+};
+
+void InspectorController::postWorkerNotificationToFrontend(const InspectorWorkerResource& worker, InspectorController::WorkerAction action)
+{
+ if (!m_frontend)
+ return;
+ switch (action) {
+ case InspectorController::WorkerCreated:
+ m_frontend->didCreateWorker(worker);
+ break;
+ case InspectorController::WorkerDestroyed:
+ m_frontend->didDestroyWorker(worker);
+ break;
+ }
+}
+
+void InspectorController::didCreateWorker(intptr_t id, const String& url, bool isSharedWorker)
+{
+ if (!enabled())
+ return;
+
+ RefPtr<InspectorWorkerResource> workerResource(InspectorWorkerResource::create(id, url, isSharedWorker));
+ m_workers.set(id, workerResource);
+ if (m_inspectedPage && m_frontend)
+ m_inspectedPage->mainFrame()->document()->postTask(PostWorkerNotificationToFrontendTask::create(workerResource, InspectorController::WorkerCreated));
+}
+
+void InspectorController::didDestroyWorker(intptr_t id)
+{
+ if (!enabled())
+ return;
+
+ WorkersMap::iterator workerResource = m_workers.find(id);
+ if (workerResource == m_workers.end())
+ return;
+ if (m_inspectedPage && m_frontend)
+ m_inspectedPage->mainFrame()->document()->postTask(PostWorkerNotificationToFrontendTask::create(workerResource->second, InspectorController::WorkerDestroyed));
+ m_workers.remove(workerResource);
+}
+#endif // ENABLE(WORKERS)
+
#if ENABLE(DATABASE)
void InspectorController::selectDatabase(Database* database)
{
@@ -1141,7 +1128,7 @@ void InspectorController::selectDatabase(Database* database)
}
}
-Database* InspectorController::databaseForId(int databaseId)
+Database* InspectorController::databaseForId(long databaseId)
{
DatabaseResourcesMap::iterator it = m_databaseResources.find(databaseId);
if (it == m_databaseResources.end())
@@ -1159,7 +1146,7 @@ void InspectorController::didOpenDatabase(Database* database, const String& doma
m_databaseResources.set(resource->id(), resource);
// Resources are only bound while visible.
- if (windowVisible())
+ if (m_frontend)
resource->bind(m_frontend.get());
}
#endif
@@ -1252,7 +1239,7 @@ void InspectorController::didUseDOMStorage(StorageArea* storageArea, bool isLoca
m_domStorageResources.set(resource->id(), resource);
// Resources are only bound while visible.
- if (windowVisible())
+ if (m_frontend)
resource->bind(m_frontend.get());
}
@@ -1263,8 +1250,9 @@ void InspectorController::selectDOMStorage(Storage* storage)
return;
Frame* frame = storage->frame();
- bool isLocalStorage = (frame->domWindow()->localStorage() == storage);
- int storageResourceId = 0;
+ ExceptionCode ec = 0;
+ bool isLocalStorage = (frame->domWindow()->localStorage(ec) == storage && !ec);
+ long storageResourceId = 0;
DOMStorageResourcesMap::iterator domStorageEnd = m_domStorageResources.end();
for (DOMStorageResourcesMap::iterator it = m_domStorageResources.begin(); it != domStorageEnd; ++it) {
if (it->second->isSameHostAndType(frame, isLocalStorage)) {
@@ -1276,7 +1264,7 @@ void InspectorController::selectDOMStorage(Storage* storage)
m_frontend->selectDOMStorage(storageResourceId);
}
-void InspectorController::getDOMStorageEntries(int callId, int storageId)
+void InspectorController::getDOMStorageEntries(long callId, long storageId)
{
if (!m_frontend)
return;
@@ -1327,7 +1315,7 @@ void InspectorController::removeDOMStorageItem(long callId, long storageId, cons
m_frontend->didRemoveDOMStorageItem(callId, success);
}
-InspectorDOMStorageResource* InspectorController::getDOMStorageResourceForId(int storageId)
+InspectorDOMStorageResource* InspectorController::getDOMStorageResourceForId(long storageId)
{
DOMStorageResourcesMap::iterator it = m_domStorageResources.find(storageId);
if (it == m_domStorageResources.end())
@@ -1336,16 +1324,6 @@ InspectorDOMStorageResource* InspectorController::getDOMStorageResourceForId(int
}
#endif
-void InspectorController::moveWindowBy(float x, float y) const
-{
- if (!m_page || !enabled())
- return;
-
- FloatRect frameRect = m_page->chrome()->windowRect();
- frameRect.move(x, y);
- m_page->chrome()->setWindowRect(frameRect);
-}
-
#if ENABLE(JAVASCRIPT_DEBUGGER)
void InspectorController::addProfile(PassRefPtr<ScriptProfile> prpProfile, unsigned lineNumber, const String& sourceURL)
{
@@ -1357,7 +1335,7 @@ void InspectorController::addProfile(PassRefPtr<ScriptProfile> prpProfile, unsig
if (m_frontend) {
#if USE(JSC)
- JSLock lock(SilenceAssertionsOnly);
+ JSC::JSLock lock(JSC::SilenceAssertionsOnly);
#endif
m_frontend->addProfileHeader(createProfileHeader(*profile));
}
@@ -1369,7 +1347,12 @@ void InspectorController::addProfileFinishedMessageToConsole(PassRefPtr<ScriptPr
{
RefPtr<ScriptProfile> profile = prpProfile;
- String message = String::format("Profile \"webkit-profile://%s/%s#%d\" finished.", CPUProfileType, encodeWithURLEscapeSequences(profile->title()).utf8().data(), profile->uid());
+#if USE(JSC)
+ String title = ustringToString(profile->title());
+#else
+ String title = profile->title();
+#endif
+ String message = String::format("Profile \"webkit-profile://%s/%s#%d\" finished.", CPUProfileType, encodeWithURLEscapeSequences(title).utf8().data(), profile->uid());
addMessageToConsole(JSMessageSource, LogMessageType, LogMessageLevel, message, lineNumber, sourceURL);
}
@@ -1396,16 +1379,24 @@ void InspectorController::getProfile(long callId, unsigned uid)
if (!m_frontend)
return;
ProfilesMap::iterator it = m_profiles.find(uid);
-#if USE(JSC)
if (it != m_profiles.end())
- m_frontend->didGetProfile(callId, toJS(m_frontendScriptState, it->second.get()));
+#if USE(JSC)
+ m_frontend->didGetProfile(callId, toJS(m_frontend->scriptState(), it->second.get()));
+#else
+ m_frontend->didGetProfile(callId, toV8(it->second.get()));
#endif
}
ScriptObject InspectorController::createProfileHeader(const ScriptProfile& profile)
{
+#if USE(JSC)
+ String title = ustringToString(profile.title());
+#else
+ String title = profile.title();
+#endif
+
ScriptObject header = m_frontend->newScriptObject();
- header.set("title", profile.title());
+ header.set("title", title);
header.set("uid", profile.uid());
header.set("typeId", String(CPUProfileType));
return header;
@@ -1431,7 +1422,7 @@ void InspectorController::startUserInitiatedProfiling(Timer<InspectorController>
if (!profilerEnabled()) {
enableProfiler(false, true);
- ScriptDebugServer::recompileAllJSFunctions();
+ ScriptDebugServer::shared().recompileAllJSFunctions();
}
m_recordingUserInitiatedProfile = true;
@@ -1439,7 +1430,7 @@ void InspectorController::startUserInitiatedProfiling(Timer<InspectorController>
String title = getCurrentUserInitiatedProfileName(true);
#if USE(JSC)
- ExecState* scriptState = toJSDOMWindow(m_inspectedPage->mainFrame(), debuggerWorld())->globalExec();
+ JSC::ExecState* scriptState = toJSDOMWindow(m_inspectedPage->mainFrame(), debuggerWorld())->globalExec();
#else
ScriptState* scriptState = 0;
#endif
@@ -1460,7 +1451,7 @@ void InspectorController::stopUserInitiatedProfiling()
String title = getCurrentUserInitiatedProfileName();
#if USE(JSC)
- ExecState* scriptState = toJSDOMWindow(m_inspectedPage->mainFrame(), debuggerWorld())->globalExec();
+ JSC::ExecState* scriptState = toJSDOMWindow(m_inspectedPage->mainFrame(), debuggerWorld())->globalExec();
#else
ScriptState* scriptState = 0;
#endif
@@ -1489,7 +1480,7 @@ void InspectorController::enableProfiler(bool always, bool skipRecompile)
m_profilerEnabled = true;
if (!skipRecompile)
- ScriptDebugServer::recompileAllJSFunctionsSoon();
+ ScriptDebugServer::shared().recompileAllJSFunctionsSoon();
if (m_frontend)
m_frontend->profilerWasEnabled();
@@ -1505,14 +1496,14 @@ void InspectorController::disableProfiler(bool always)
m_profilerEnabled = false;
- ScriptDebugServer::recompileAllJSFunctionsSoon();
+ ScriptDebugServer::shared().recompileAllJSFunctionsSoon();
if (m_frontend)
m_frontend->profilerWasDisabled();
}
#endif
-#if ENABLE(JAVASCRIPT_DEBUGGER) && USE(JSC)
+#if ENABLE(JAVASCRIPT_DEBUGGER)
void InspectorController::enableDebuggerFromFrontend(bool always)
{
if (always)
@@ -1520,8 +1511,8 @@ void InspectorController::enableDebuggerFromFrontend(bool always)
ASSERT(m_inspectedPage);
- JavaScriptDebugServer::shared().addListener(this, m_inspectedPage);
- JavaScriptDebugServer::shared().clearBreakpoints();
+ ScriptDebugServer::shared().addListener(this, m_inspectedPage);
+ ScriptDebugServer::shared().clearBreakpoints();
m_debuggerEnabled = true;
m_frontend->debuggerWasEnabled();
@@ -1535,7 +1526,7 @@ void InspectorController::enableDebugger()
if (m_debuggerEnabled)
return;
- if (!m_frontendScriptState || !m_frontend)
+ if (!m_frontend)
m_attachDebuggerWhenShown = true;
else {
m_frontend->attachDebuggerWhenShown();
@@ -1553,7 +1544,7 @@ void InspectorController::disableDebugger(bool always)
ASSERT(m_inspectedPage);
- JavaScriptDebugServer::shared().removeListener(this, m_inspectedPage);
+ ScriptDebugServer::shared().removeListener(this, m_inspectedPage);
m_debuggerEnabled = false;
m_attachDebuggerWhenShown = false;
@@ -1566,25 +1557,66 @@ void InspectorController::resumeDebugger()
{
if (!m_debuggerEnabled)
return;
- JavaScriptDebugServer::shared().continueProgram();
+ ScriptDebugServer::shared().continueProgram();
+}
+
+void InspectorController::setBreakpoint(const String& sourceID, unsigned lineNumber, bool enabled, const String& condition)
+{
+ ScriptBreakpoint breakpoint(enabled, condition);
+ ScriptDebugServer::shared().setBreakpoint(sourceID, lineNumber, breakpoint);
+ String url = m_sourceIDToURL.get(sourceID);
+ if (url.isEmpty())
+ return;
+
+ HashMap<String, SourceBreakpoints>::iterator it = m_stickyBreakpoints.find(url);
+ if (it == m_stickyBreakpoints.end())
+ it = m_stickyBreakpoints.set(url, SourceBreakpoints()).first;
+ it->second.set(lineNumber, breakpoint);
+}
+
+void InspectorController::removeBreakpoint(const String& sourceID, unsigned lineNumber)
+{
+ ScriptDebugServer::shared().removeBreakpoint(sourceID, lineNumber);
+
+ String url = m_sourceIDToURL.get(sourceID);
+ if (url.isEmpty())
+ return;
+
+ HashMap<String, SourceBreakpoints>::iterator it = m_stickyBreakpoints.find(url);
+ if (it != m_stickyBreakpoints.end())
+ it->second.remove(lineNumber);
}
// JavaScriptDebugListener functions
-void InspectorController::didParseSource(ExecState*, const SourceCode& source)
+void InspectorController::didParseSource(const String& sourceID, const String& url, const String& data, int firstLine)
{
- m_frontend->parsedScriptSource(source);
+ m_frontend->parsedScriptSource(sourceID, url, data, firstLine);
+
+ if (url.isEmpty())
+ return;
+
+ HashMap<String, SourceBreakpoints>::iterator it = m_stickyBreakpoints.find(url);
+ if (it != m_stickyBreakpoints.end()) {
+ for (SourceBreakpoints::iterator breakpointIt = it->second.begin(); breakpointIt != it->second.end(); ++breakpointIt) {
+ if (firstLine <= breakpointIt->first) {
+ ScriptDebugServer::shared().setBreakpoint(sourceID, breakpointIt->first, breakpointIt->second);
+ m_frontend->restoredBreakpoint(sourceID, url, breakpointIt->first, breakpointIt->second.enabled, breakpointIt->second.condition);
+ }
+ }
+ }
+
+ m_sourceIDToURL.set(sourceID, url);
}
-void InspectorController::failedToParseSource(ExecState*, const SourceCode& source, int errorLine, const UString& errorMessage)
+void InspectorController::failedToParseSource(const String& url, const String& data, int firstLine, int errorLine, const String& errorMessage)
{
- m_frontend->failedToParseScriptSource(source, errorLine, errorMessage);
+ m_frontend->failedToParseScriptSource(url, data, firstLine, errorLine, errorMessage);
}
void InspectorController::didPause()
{
- JavaScriptCallFrame* callFrame = m_injectedScriptHost->currentCallFrame();
- ScriptState* scriptState = callFrame->scopeChain()->globalObject->globalExec();
+ ScriptState* scriptState = ScriptDebugServer::shared().currentCallFrameState();
ASSERT(scriptState);
InjectedScript injectedScript = m_injectedScriptHost->injectedScriptFor(scriptState);
RefPtr<SerializedScriptValue> callFrames = injectedScript.callFrames();
@@ -1809,6 +1841,8 @@ InspectorController::SpecialPanels InspectorController::specialPanelForJSName(co
return ProfilesPanel;
if (panelName == "storage" || panelName == "databases")
return StoragePanel;
+ if (panelName == "audits")
+ return AuditsPanel;
if (panelName == "console")
return ConsolePanel;
return ElementsPanel;
@@ -1845,6 +1879,16 @@ InjectedScript InspectorController::injectedScriptForNodeId(long id)
return InjectedScript();
}
+void InspectorController::addScriptToEvaluateOnLoad(const String& source)
+{
+ m_scriptsToEvaluateOnLoad.append(source);
+}
+
+void InspectorController::removeAllScriptsToEvaluateOnLoad()
+{
+ m_scriptsToEvaluateOnLoad.clear();
+}
+
} // namespace WebCore
#endif // ENABLE(INSPECTOR)