summaryrefslogtreecommitdiffstats
path: root/WebCore/inspector
diff options
context:
space:
mode:
authorBen Murdoch <benm@google.com>2010-06-15 19:36:43 +0100
committerBen Murdoch <benm@google.com>2010-06-16 14:52:28 +0100
commit545e470e52f0ac6a3a072bf559c796b42c6066b6 (patch)
treec0c14763654d84d37577dde512c3d3b4699a9e86 /WebCore/inspector
parent719298a66237d38ea5c05f1547123ad8aacbc237 (diff)
downloadexternal_webkit-545e470e52f0ac6a3a072bf559c796b42c6066b6.zip
external_webkit-545e470e52f0ac6a3a072bf559c796b42c6066b6.tar.gz
external_webkit-545e470e52f0ac6a3a072bf559c796b42c6066b6.tar.bz2
Merge webkit.org at r61121: Initial merge by git.
Change-Id: Icd6db395c62285be384d137164d95d7466c98760
Diffstat (limited to 'WebCore/inspector')
-rw-r--r--WebCore/inspector/InjectedScriptHost.cpp6
-rw-r--r--WebCore/inspector/InjectedScriptHost.h1
-rw-r--r--WebCore/inspector/InjectedScriptHost.idl1
-rw-r--r--WebCore/inspector/InspectorBackend.cpp32
-rw-r--r--WebCore/inspector/InspectorBackend.h12
-rw-r--r--WebCore/inspector/InspectorBackend.idl9
-rw-r--r--WebCore/inspector/InspectorClient.h2
-rw-r--r--WebCore/inspector/InspectorController.cpp132
-rw-r--r--WebCore/inspector/InspectorController.h17
-rw-r--r--WebCore/inspector/InspectorDOMAgent.cpp253
-rw-r--r--WebCore/inspector/InspectorDOMAgent.h15
-rw-r--r--WebCore/inspector/InspectorFrontend.cpp45
-rw-r--r--WebCore/inspector/InspectorFrontend.h20
-rw-r--r--WebCore/inspector/InspectorFrontendClientLocal.cpp2
-rw-r--r--WebCore/inspector/InspectorResource.cpp1
-rw-r--r--WebCore/inspector/InspectorTimelineAgent.h4
-rw-r--r--WebCore/inspector/InspectorValues.cpp531
-rw-r--r--WebCore/inspector/InspectorValues.h51
-rw-r--r--WebCore/inspector/ScriptDebugListener.h7
-rw-r--r--WebCore/inspector/front-end/Breakpoint.js0
-rw-r--r--WebCore/inspector/front-end/BreakpointManager.js22
-rw-r--r--WebCore/inspector/front-end/CSSStyleModel.js111
-rw-r--r--WebCore/inspector/front-end/ConsoleView.js6
-rw-r--r--WebCore/inspector/front-end/ElementsPanel.js11
-rw-r--r--WebCore/inspector/front-end/EventListenersSidebarPane.js8
-rw-r--r--WebCore/inspector/front-end/HAREntry.js135
-rw-r--r--WebCore/inspector/front-end/InjectedScript.js280
-rw-r--r--WebCore/inspector/front-end/InjectedScriptAccess.js11
-rw-r--r--WebCore/inspector/front-end/InspectorBackendStub.js24
-rw-r--r--WebCore/inspector/front-end/KeyboardShortcut.js28
-rw-r--r--WebCore/inspector/front-end/Resource.js81
-rw-r--r--WebCore/inspector/front-end/ResourceView.js54
-rw-r--r--WebCore/inspector/front-end/ResourcesPanel.js10
-rw-r--r--WebCore/inspector/front-end/Script.js13
-rw-r--r--WebCore/inspector/front-end/ScriptView.js30
-rw-r--r--WebCore/inspector/front-end/ScriptsPanel.js36
-rw-r--r--WebCore/inspector/front-end/Settings.js47
-rw-r--r--WebCore/inspector/front-end/SourceFrame.js8
-rw-r--r--WebCore/inspector/front-end/SourceView.js19
-rw-r--r--WebCore/inspector/front-end/StylesSidebarPane.js100
-rw-r--r--WebCore/inspector/front-end/TextPrompt.js2
-rw-r--r--WebCore/inspector/front-end/TextViewer.js8
-rw-r--r--WebCore/inspector/front-end/TimelinePanel.js2
-rw-r--r--WebCore/inspector/front-end/WatchExpressionsSidebarPane.js8
-rw-r--r--WebCore/inspector/front-end/WebKit.qrc2
-rw-r--r--WebCore/inspector/front-end/inspector.css7
-rw-r--r--WebCore/inspector/front-end/inspector.html2
-rw-r--r--WebCore/inspector/front-end/inspector.js18
-rw-r--r--WebCore/inspector/front-end/utilities.js9
49 files changed, 1701 insertions, 532 deletions
diff --git a/WebCore/inspector/InjectedScriptHost.cpp b/WebCore/inspector/InjectedScriptHost.cpp
index c58073d..4c3c7ae 100644
--- a/WebCore/inspector/InjectedScriptHost.cpp
+++ b/WebCore/inspector/InjectedScriptHost.cpp
@@ -110,12 +110,6 @@ long InjectedScriptHost::pushNodePathToFrontend(Node* node, bool withChildren, b
return id;
}
-void InjectedScriptHost::addNodesToSearchResult(const String& nodeIds)
-{
- if (InspectorFrontend* frontend = inspectorFrontend())
- frontend->addNodesToSearchResult(nodeIds);
-}
-
long InjectedScriptHost::pushNodeByPathToFrontend(const String& path)
{
InspectorDOMAgent* domAgent = inspectorDOMAgent();
diff --git a/WebCore/inspector/InjectedScriptHost.h b/WebCore/inspector/InjectedScriptHost.h
index beffc9d..66cf41e 100644
--- a/WebCore/inspector/InjectedScriptHost.h
+++ b/WebCore/inspector/InjectedScriptHost.h
@@ -69,7 +69,6 @@ public:
Node* nodeForId(long nodeId);
long pushNodePathToFrontend(Node* node, bool withChildren, bool selectInUI);
- void addNodesToSearchResult(const String& nodeIds);
long pushNodeByPathToFrontend(const String& path);
#if ENABLE(DATABASE)
diff --git a/WebCore/inspector/InjectedScriptHost.idl b/WebCore/inspector/InjectedScriptHost.idl
index 8b24157..5a4ce19 100644
--- a/WebCore/inspector/InjectedScriptHost.idl
+++ b/WebCore/inspector/InjectedScriptHost.idl
@@ -38,7 +38,6 @@ module core {
[Custom] DOMObject nodeForId(in long nodeId);
[Custom] int pushNodePathToFrontend(in DOMObject node, in boolean withChildren, in boolean selectInUI);
- void addNodesToSearchResult(in DOMString nodeIds);
long pushNodeByPathToFrontend(in DOMString path);
#if defined(ENABLE_JAVASCRIPT_DEBUGGER) && ENABLE_JAVASCRIPT_DEBUGGER
diff --git a/WebCore/inspector/InspectorBackend.cpp b/WebCore/inspector/InspectorBackend.cpp
index 36f41b8..1eedda1 100644
--- a/WebCore/inspector/InspectorBackend.cpp
+++ b/WebCore/inspector/InspectorBackend.cpp
@@ -79,12 +79,18 @@ InspectorBackend::~InspectorBackend()
{
}
-void InspectorBackend::saveFrontendSettings(const String& settings)
+void InspectorBackend::saveApplicationSettings(const String& settings)
{
if (m_inspectorController)
m_inspectorController->setSetting(InspectorController::frontendSettingsSettingName(), settings);
}
+void InspectorBackend::saveSessionSettings(const String& settings)
+{
+ if (m_inspectorController)
+ m_inspectorController->setSessionSettings(settings);
+}
+
void InspectorBackend::storeLastActivePanel(const String& panelName)
{
if (m_inspectorController)
@@ -215,9 +221,17 @@ void InspectorBackend::setPauseOnExceptionsState(long pauseState)
frontend->updatePauseOnExceptionsState(ScriptDebugServer::shared().pauseOnExceptionsState());
}
-#endif
+void InspectorBackend::editScriptSource(long callId, const String& sourceID, const String& newContent)
+{
+ if (m_inspectorController)
+ m_inspectorController->editScriptSource(callId, sourceID, newContent);
+}
-#if ENABLE(JAVASCRIPT_DEBUGGER)
+void InspectorBackend::getScriptSource(long callId, const String& sourceID)
+{
+ if (m_inspectorController)
+ m_inspectorController->getScriptSource(callId, sourceID);
+}
void InspectorBackend::enableProfiler(bool always)
{
@@ -351,6 +365,18 @@ void InspectorBackend::changeTagName(long callId, long nodeId, const AtomicStrin
domAgent->changeTagName(callId, nodeId, tagName, expanded);
}
+void InspectorBackend::performSearch(const String& query, bool runSynchronously)
+{
+ if (InspectorDOMAgent* domAgent = inspectorDOMAgent())
+ domAgent->performSearch(query, runSynchronously);
+}
+
+void InspectorBackend::searchCanceled()
+{
+ if (InspectorDOMAgent* domAgent = inspectorDOMAgent())
+ domAgent->searchCanceled();
+}
+
void InspectorBackend::getStyles(long callId, long nodeId, bool authorOnly)
{
if (InspectorDOMAgent* domAgent = inspectorDOMAgent())
diff --git a/WebCore/inspector/InspectorBackend.h b/WebCore/inspector/InspectorBackend.h
index 0eb8e4c..61d73b8 100644
--- a/WebCore/inspector/InspectorBackend.h
+++ b/WebCore/inspector/InspectorBackend.h
@@ -57,7 +57,8 @@ public:
InspectorController* inspectorController() { return m_inspectorController; }
void disconnectController() { m_inspectorController = 0; }
- void saveFrontendSettings(const String&);
+ void saveApplicationSettings(const String&);
+ void saveSessionSettings(const String&);
void storeLastActivePanel(const String& panelName);
@@ -84,12 +85,15 @@ public:
void pauseInDebugger();
void resumeDebugger();
- void setPauseOnExceptionsState(long pauseState);
-
void stepOverStatementInDebugger();
void stepIntoStatementInDebugger();
void stepOutOfFunctionInDebugger();
+ void setPauseOnExceptionsState(long pauseState);
+
+ void editScriptSource(long callId, const String& sourceID, const String& newContent);
+ void getScriptSource(long callId, const String& sourceID);
+
void enableProfiler(bool always);
void disableProfiler(bool always);
@@ -116,6 +120,8 @@ public:
void copyNode(long nodeId);
void removeNode(long callId, long nodeId);
void changeTagName(long callId, long nodeId, const AtomicString& tagName, bool expanded);
+ void performSearch(const String& query, bool runSynchronously);
+ void searchCanceled();
void getStyles(long callId, long nodeId, bool authOnly);
void getAllStyles(long callId);
diff --git a/WebCore/inspector/InspectorBackend.idl b/WebCore/inspector/InspectorBackend.idl
index e8cfdb9..c0078ee 100644
--- a/WebCore/inspector/InspectorBackend.idl
+++ b/WebCore/inspector/InspectorBackend.idl
@@ -34,7 +34,8 @@ module core {
interface [Conditional=INSPECTOR] InspectorBackend {
void storeLastActivePanel(in DOMString panelName);
- void saveFrontendSettings(in DOMString settings);
+ void saveApplicationSettings(in DOMString settings);
+ void saveSessionSettings(in DOMString settings);
void enableSearchingForNode();
void disableSearchingForNode();
@@ -65,6 +66,9 @@ module core {
void setPauseOnExceptionsState(in long pauseOnExceptionsState);
+ void editScriptSource(in long callId, in DOMString sourceID, in DOMString newContent);
+ void getScriptSource(in long callId, in DOMString sourceID);
+
void enableProfiler(in boolean always);
void disableProfiler(in boolean always);
@@ -91,6 +95,9 @@ module core {
void copyNode(in long nodeId);
void removeNode(in long callId, in long nodeId);
void changeTagName(in long callId, in long nodeId, in DOMString newTagName, in boolean expanded);
+ void performSearch(in DOMString query, in boolean runSynchronously);
+ void searchCanceled();
+
void highlightDOMNode(in long nodeId);
void hideDOMNodeHighlight();
diff --git a/WebCore/inspector/InspectorClient.h b/WebCore/inspector/InspectorClient.h
index 841c15e..2ce3a09 100644
--- a/WebCore/inspector/InspectorClient.h
+++ b/WebCore/inspector/InspectorClient.h
@@ -48,6 +48,8 @@ public:
virtual void populateSetting(const String& key, String* value) = 0;
virtual void storeSetting(const String& key, const String& value) = 0;
+
+ virtual bool sendMessageToFrontend(const String& message) = 0;
};
} // namespace WebCore
diff --git a/WebCore/inspector/InspectorController.cpp b/WebCore/inspector/InspectorController.cpp
index f38f8d0..7916cd0 100644
--- a/WebCore/inspector/InspectorController.cpp
+++ b/WebCore/inspector/InspectorController.cpp
@@ -24,7 +24,7 @@
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
@@ -148,6 +148,7 @@ InspectorController::InspectorController(Page* page, InspectorClient* client)
, m_cssStore(new InspectorCSSStore(this))
, m_expiredConsoleMessageCount(0)
, m_showAfterVisible(CurrentPanel)
+ , m_sessionSettings(InspectorObject::create())
, m_groupLevel(0)
, m_searchingForNode(false)
, m_previousMessage(0)
@@ -158,8 +159,7 @@ InspectorController::InspectorController(Page* page, InspectorClient* client)
#if ENABLE(JAVASCRIPT_DEBUGGER)
, m_debuggerEnabled(false)
, m_attachDebuggerWhenShown(false)
-#endif
-#if ENABLE(JAVASCRIPT_DEBUGGER)
+ , m_pausedScriptState(0)
, m_profilerEnabled(!WTF_USE_JSC)
, m_recordingUserInitiatedProfile(false)
, m_currentUserInitiatedProfileNumber(-1)
@@ -230,6 +230,11 @@ void InspectorController::setSetting(const String& key, const String& value)
m_client->storeSetting(key, value);
}
+void InspectorController::setSessionSettings(const String& settingsJSON)
+{
+ m_sessionSettings = InspectorValue::readJSON(settingsJSON);
+}
+
void InspectorController::inspect(Node* node)
{
if (!enabled())
@@ -426,22 +431,27 @@ void InspectorController::setSearchingForNode(bool enabled)
}
}
-void InspectorController::setFrontend(PassOwnPtr<InspectorFrontend> frontend)
+void InspectorController::connectFrontend(const ScriptObject& webInspector)
{
- ASSERT(frontend);
m_openingFrontend = false;
- m_frontend = frontend;
+ m_frontend = new InspectorFrontend(webInspector, m_client);
releaseDOMAgent();
m_domAgent = InspectorDOMAgent::create(m_cssStore.get(), 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")
- enableDebugger();
- String profilerEnabled = setting(profilerEnabledSettingName);
- if (profilerEnabled == "true")
- enableProfiler();
+#if ENABLE(JAVASCRIPT_DEBUGGER)
+ if (ScriptDebugServer::shared().isDebuggerAlwaysEnabled()) {
+ // FIXME (40364): This will force pushing script sources to frontend even if script
+ // panel is inactive.
+ enableDebuggerFromFrontend(false);
+ } else {
+ String debuggerEnabled = setting(debuggerEnabledSettingName);
+ if (debuggerEnabled == "true")
+ enableDebugger();
+ String profilerEnabled = setting(profilerEnabledSettingName);
+ if (profilerEnabled == "true")
+ enableProfiler();
+ }
#endif
// Initialize Web Inspector title.
@@ -550,7 +560,7 @@ void InspectorController::populateScriptObjects()
if (!m_frontend)
return;
- m_frontend->populateFrontendSettings(setting(frontendSettingsSettingName()));
+ m_frontend->populateApplicationSettings(setting(frontendSettingsSettingName()));
if (m_resourceTrackingEnabled)
m_frontend->resourceTrackingWasEnabled();
@@ -597,6 +607,7 @@ void InspectorController::populateScriptObjects()
m_frontend->didCreateWorker(*it->second);
#endif
+ m_frontend->populateSessionSettings(m_sessionSettings->toJSONString());
m_frontend->populateInterface();
// Dispatch pending frontend commands
@@ -662,6 +673,7 @@ void InspectorController::didCommitLoad(DocumentLoader* loader)
m_counts.clear();
#if ENABLE(JAVASCRIPT_DEBUGGER)
m_sourceIDToURL.clear();
+ m_scriptIDToContent.clear();
#endif
#if ENABLE(JAVASCRIPT_DEBUGGER) && USE(JSC)
m_profiles.clear();
@@ -673,6 +685,7 @@ void InspectorController::didCommitLoad(DocumentLoader* loader)
unbindAllResources();
m_cssStore->reset();
+ m_sessionSettings = InspectorObject::create();
if (m_frontend) {
m_frontend->reset();
m_domAgent->reset();
@@ -875,6 +888,9 @@ bool InspectorController::isMainResourceLoader(DocumentLoader* loader, const KUR
void InspectorController::willSendRequest(unsigned long identifier, const ResourceRequest& request, const ResourceResponse& redirectResponse)
{
+ if (!enabled())
+ return;
+
bool isMainResource = (m_mainResource && m_mainResource->identifier() == identifier);
if (m_timelineAgent)
m_timelineAgent->willSendResourceRequest(identifier, isMainResource, request);
@@ -884,20 +900,24 @@ void InspectorController::willSendRequest(unsigned long identifier, const Resour
return;
if (!redirectResponse.isNull()) {
- resource->markResponseReceivedTime();
- resource->endTiming();
- resource->updateResponse(redirectResponse);
-
- // We always store last redirect by the original id key. Rest of the redirects are stored within the last one.
- unsigned long id = m_inspectedPage->progress()->createUniqueIdentifier();
- RefPtr<InspectorResource> withRedirect = resource->appendRedirect(id, request.url());
- removeResource(resource.get());
- addResource(withRedirect.get());
- if (isMainResource) {
- m_mainResource = withRedirect;
- withRedirect->markMainResource();
+ // Redirect may have empty URL and we'd like to not crash with invalid HashMap entry.
+ // See http/tests/misc/will-send-request-returns-null-on-redirect.html
+ if (!request.url().isEmpty()) {
+ resource->markResponseReceivedTime();
+ resource->endTiming();
+ resource->updateResponse(redirectResponse);
+
+ // We always store last redirect by the original id key. Rest of the redirects are stored within the last one.
+ unsigned long id = m_inspectedPage->progress()->createUniqueIdentifier();
+ RefPtr<InspectorResource> withRedirect = resource->appendRedirect(id, request.url());
+ removeResource(resource.get());
+ addResource(withRedirect.get());
+ if (isMainResource) {
+ m_mainResource = withRedirect;
+ withRedirect->markMainResource();
+ }
+ resource = withRedirect;
}
- resource = withRedirect;
}
resource->startTiming();
@@ -909,6 +929,9 @@ void InspectorController::willSendRequest(unsigned long identifier, const Resour
void InspectorController::didReceiveResponse(unsigned long identifier, const ResourceResponse& response)
{
+ if (!enabled())
+ return;
+
if (RefPtr<InspectorResource> resource = getTrackedResource(identifier)) {
resource->updateResponse(response);
resource->markResponseReceivedTime();
@@ -926,6 +949,9 @@ void InspectorController::didReceiveResponse(unsigned long identifier, const Res
void InspectorController::didReceiveContentLength(unsigned long identifier, int lengthReceived)
{
+ if (!enabled())
+ return;
+
RefPtr<InspectorResource> resource = getTrackedResource(identifier);
if (!resource)
return;
@@ -938,6 +964,9 @@ void InspectorController::didReceiveContentLength(unsigned long identifier, int
void InspectorController::didFinishLoading(unsigned long identifier)
{
+ if (!enabled())
+ return;
+
if (m_timelineAgent)
m_timelineAgent->didFinishLoadingResource(identifier, false);
@@ -954,6 +983,9 @@ void InspectorController::didFinishLoading(unsigned long identifier)
void InspectorController::didFailLoading(unsigned long identifier, const ResourceError& error)
{
+ if (!enabled())
+ return;
+
if (m_timelineAgent)
m_timelineAgent->didFinishLoadingResource(identifier, true);
@@ -1498,6 +1530,8 @@ void InspectorController::stopUserInitiatedProfiling()
#if USE(JSC)
JSC::ExecState* scriptState = toJSDOMWindow(m_inspectedPage->mainFrame(), debuggerWorld())->globalExec();
#else
+ // Use null script state to avoid filtering by context security token.
+ // All functions from all iframes should be visible from Inspector UI.
ScriptState* scriptState = 0;
#endif
RefPtr<ScriptProfile> profile = ScriptProfiler::stop(scriptState, title);
@@ -1593,11 +1627,30 @@ void InspectorController::disableDebugger(bool always)
m_debuggerEnabled = false;
m_attachDebuggerWhenShown = false;
+ m_pausedScriptState = 0;
if (m_frontend)
m_frontend->debuggerWasDisabled();
}
+void InspectorController::editScriptSource(long callId, const String& sourceID, const String& newContent)
+{
+ String result;
+ bool success = ScriptDebugServer::shared().editScriptSource(sourceID, newContent, result);
+ RefPtr<SerializedScriptValue> callFrames;
+ if (success)
+ callFrames = currentCallFrames();
+ m_frontend->didEditScriptSource(callId, success, result, callFrames.get());
+}
+
+void InspectorController::getScriptSource(long callId, const String& sourceID)
+{
+ if (!m_frontend)
+ return;
+ String scriptSource = m_scriptIDToContent.get(sourceID);
+ m_frontend->didGetScriptSource(callId, scriptSource);
+}
+
void InspectorController::resumeDebugger()
{
if (!m_debuggerEnabled)
@@ -1605,6 +1658,18 @@ void InspectorController::resumeDebugger()
ScriptDebugServer::shared().continueProgram();
}
+PassRefPtr<SerializedScriptValue> InspectorController::currentCallFrames()
+{
+ if (!m_pausedScriptState)
+ return 0;
+ InjectedScript injectedScript = m_injectedScriptHost->injectedScriptFor(m_pausedScriptState);
+ if (injectedScript.hasNoValue()) {
+ ASSERT_NOT_REACHED();
+ return 0;
+ }
+ return injectedScript.callFrames();
+}
+
void InspectorController::setBreakpoint(const String& sourceID, unsigned lineNumber, bool enabled, const String& condition)
{
ScriptBreakpoint breakpoint(enabled, condition);
@@ -1634,9 +1699,10 @@ void InspectorController::removeBreakpoint(const String& sourceID, unsigned line
// JavaScriptDebugListener functions
-void InspectorController::didParseSource(const String& sourceID, const String& url, const String& data, int firstLine)
+void InspectorController::didParseSource(const String& sourceID, const String& url, const String& data, int firstLine, ScriptWorldType worldType)
{
- m_frontend->parsedScriptSource(sourceID, url, data, firstLine);
+ // Don't send script content to the front end until it's really needed.
+ m_frontend->parsedScriptSource(sourceID, url, "", firstLine, worldType);
if (url.isEmpty())
return;
@@ -1652,6 +1718,7 @@ void InspectorController::didParseSource(const String& sourceID, const String& u
}
m_sourceIDToURL.set(sourceID, url);
+ m_scriptIDToContent.set(sourceID, data);
}
void InspectorController::failedToParseSource(const String& url, const String& data, int firstLine, int errorLine, const String& errorMessage)
@@ -1661,14 +1728,15 @@ void InspectorController::failedToParseSource(const String& url, const String& d
void InspectorController::didPause(ScriptState* scriptState)
{
- ASSERT(scriptState);
- InjectedScript injectedScript = m_injectedScriptHost->injectedScriptFor(scriptState);
- RefPtr<SerializedScriptValue> callFrames = injectedScript.callFrames();
+ ASSERT(scriptState && !m_pausedScriptState);
+ m_pausedScriptState = scriptState;
+ RefPtr<SerializedScriptValue> callFrames = currentCallFrames();
m_frontend->pausedScript(callFrames.get());
}
void InspectorController::didContinue()
{
+ m_pausedScriptState = 0;
m_frontend->resumedScript();
}
diff --git a/WebCore/inspector/InspectorController.h b/WebCore/inspector/InspectorController.h
index a2c8a77..af36383 100644
--- a/WebCore/inspector/InspectorController.h
+++ b/WebCore/inspector/InspectorController.h
@@ -32,6 +32,7 @@
#include "Console.h"
#include "Cookie.h"
#include "InspectorDOMAgent.h"
+#include "InspectorValues.h"
#include "PlatformString.h"
#include "ScriptArray.h"
#include "ScriptBreakpoint.h"
@@ -126,6 +127,7 @@ public:
String setting(const String& key) const;
void setSetting(const String& key, const String& value);
+ void setSessionSettings(const String&);
void inspect(Node*);
void highlight(Node*);
@@ -134,6 +136,11 @@ public:
void show();
void showPanel(SpecialPanels);
void close();
+
+ // We are in transition from JS transport via webInspector to native
+ // transport via InspectorClient. After migration, webInspector parameter should
+ // be removed.
+ void connectFrontend(const ScriptObject& webInspector);
void disconnectFrontend();
void addMessageToConsole(MessageSource, MessageType, MessageLevel, ScriptCallStack*);
@@ -151,7 +158,6 @@ public:
void inspectedWindowScriptObjectCleared(Frame*);
bool windowVisible();
- void setFrontend(PassOwnPtr<InspectorFrontend>);
void didCommitLoad(DocumentLoader*);
void frameDetachedFromParent(Frame*);
@@ -241,9 +247,13 @@ public:
void disableDebugger(bool always = false);
bool debuggerEnabled() const { return m_debuggerEnabled; }
+ void editScriptSource(long callId, const String& sourceID, const String& newContent);
+ void getScriptSource(long callId, const String& sourceID);
+
void resumeDebugger();
+ PassRefPtr<SerializedScriptValue> currentCallFrames();
- virtual void didParseSource(const String& sourceID, const String& url, const String& data, int firstLine);
+ virtual void didParseSource(const String& sourceID, const String& url, const String& data, int firstLine, ScriptWorldType);
virtual void failedToParseSource(const String& url, const String& data, int firstLine, int errorLine, const String& errorMessage);
virtual void didPause(ScriptState*);
virtual void didContinue();
@@ -340,6 +350,7 @@ private:
#endif
SpecialPanels m_showAfterVisible;
RefPtr<Node> m_highlightedNode;
+ RefPtr<InspectorValue> m_sessionSettings;
unsigned m_groupLevel;
bool m_searchingForNode;
ConsoleMessage* m_previousMessage;
@@ -356,7 +367,9 @@ private:
#if ENABLE(JAVASCRIPT_DEBUGGER)
bool m_debuggerEnabled;
bool m_attachDebuggerWhenShown;
+ ScriptState* m_pausedScriptState;
HashMap<String, String> m_sourceIDToURL;
+ HashMap<String, String> m_scriptIDToContent;
HashMap<String, SourceBreakpoints> m_stickyBreakpoints;
bool m_profilerEnabled;
diff --git a/WebCore/inspector/InspectorDOMAgent.cpp b/WebCore/inspector/InspectorDOMAgent.cpp
index 338dc33..b152dc3 100644
--- a/WebCore/inspector/InspectorDOMAgent.cpp
+++ b/WebCore/inspector/InspectorDOMAgent.cpp
@@ -51,6 +51,8 @@
#include "EventListener.h"
#include "EventNames.h"
#include "EventTarget.h"
+#include "Frame.h"
+#include "FrameTree.h"
#include "HTMLFrameOwnerElement.h"
#include "InspectorFrontend.h"
#include "markup.h"
@@ -65,18 +67,141 @@
#include "StyleSheetList.h"
#include "Text.h"
+#if ENABLE(XPATH)
+#include "XPathResult.h"
+#endif
+
#include <wtf/text/CString.h>
#include <wtf/HashSet.h>
+#include <wtf/ListHashSet.h>
#include <wtf/OwnPtr.h>
#include <wtf/Vector.h>
namespace WebCore {
+class MatchJob {
+public:
+ virtual void match(ListHashSet<Node*>& resultCollector) = 0;
+ virtual ~MatchJob() { }
+
+protected:
+ MatchJob(Document* document, const String& query)
+ : m_document(document)
+ , m_query(query) { }
+
+ void addNodesToResults(PassRefPtr<NodeList> nodes, ListHashSet<Node*>& resultCollector)
+ {
+ for (unsigned i = 0; nodes && i < nodes->length(); ++i)
+ resultCollector.add(nodes->item(i));
+ }
+
+ RefPtr<Document> m_document;
+ String m_query;
+};
+
+namespace {
+
+class MatchExactIdJob : public WebCore::MatchJob {
+public:
+ MatchExactIdJob(Document* document, const String& query) : WebCore::MatchJob(document, query) { }
+ virtual ~MatchExactIdJob() { }
+
+protected:
+ virtual void match(ListHashSet<Node*>& resultCollector)
+ {
+ if (m_query.isEmpty())
+ return;
+
+ Element* element = m_document->getElementById(m_query);
+ if (element)
+ resultCollector.add(element);
+ }
+};
+
+class MatchExactClassNamesJob : public WebCore::MatchJob {
+public:
+ MatchExactClassNamesJob(Document* document, const String& query) : WebCore::MatchJob(document, query) { }
+ virtual ~MatchExactClassNamesJob() { }
+
+ virtual void match(ListHashSet<Node*>& resultCollector)
+ {
+ if (!m_query.isEmpty())
+ addNodesToResults(m_document->getElementsByClassName(m_query), resultCollector);
+ }
+};
+
+class MatchExactTagNamesJob : public WebCore::MatchJob {
+public:
+ MatchExactTagNamesJob(Document* document, const String& query) : WebCore::MatchJob(document, query) { }
+ virtual ~MatchExactTagNamesJob() { }
+
+ virtual void match(ListHashSet<Node*>& resultCollector)
+ {
+ if (!m_query.isEmpty())
+ addNodesToResults(m_document->getElementsByName(m_query), resultCollector);
+ }
+};
+
+class MatchQuerySelectorAllJob : public WebCore::MatchJob {
+public:
+ MatchQuerySelectorAllJob(Document* document, const String& query) : WebCore::MatchJob(document, query) { }
+ virtual ~MatchQuerySelectorAllJob() { }
+
+ virtual void match(ListHashSet<Node*>& resultCollector)
+ {
+ if (m_query.isEmpty())
+ return;
+
+ ExceptionCode ec = 0;
+ RefPtr<NodeList> list = m_document->querySelectorAll(m_query, ec);
+ if (!ec)
+ addNodesToResults(list, resultCollector);
+ }
+};
+
+class MatchXPathJob : public WebCore::MatchJob {
+public:
+ MatchXPathJob(Document* document, const String& query) : WebCore::MatchJob(document, query) { }
+ virtual ~MatchXPathJob() { }
+
+ virtual void match(ListHashSet<Node*>& resultCollector)
+ {
+#if ENABLE(XPATH)
+ if (m_query.isEmpty())
+ return;
+
+ ExceptionCode ec = 0;
+ RefPtr<XPathResult> result = m_document->evaluate(m_query, m_document.get(), 0, XPathResult::ORDERED_NODE_SNAPSHOT_TYPE, 0, ec);
+ if (ec || !result)
+ return;
+
+ unsigned long size = result->snapshotLength(ec);
+ for (unsigned long i = 0; !ec && i < size; ++i) {
+ Node* node = result->snapshotItem(i, ec);
+ if (!ec)
+ resultCollector.add(node);
+ }
+#endif
+ }
+};
+
+class MatchPlainTextJob : public MatchXPathJob {
+public:
+ MatchPlainTextJob(Document* document, const String& query) : MatchXPathJob(document, query)
+ {
+ m_query = "//text()[contains(., '" + m_query + "')] | //comment()[contains(., '" + m_query + "')]";
+ }
+ virtual ~MatchPlainTextJob() { }
+};
+
+}
+
InspectorDOMAgent::InspectorDOMAgent(InspectorCSSStore* cssStore, InspectorFrontend* frontend)
: EventListener(InspectorDOMAgentType)
, m_cssStore(cssStore)
, m_frontend(frontend)
, m_lastNodeId(1)
+ , m_matchJobsTimer(this, &InspectorDOMAgent::onMatchJobsTimer)
{
}
@@ -87,6 +212,7 @@ InspectorDOMAgent::~InspectorDOMAgent()
void InspectorDOMAgent::reset()
{
+ searchCanceled();
discardBindings();
ListHashSet<RefPtr<Document> > copy = m_documents;
@@ -506,6 +632,103 @@ void InspectorDOMAgent::getEventListenersForNode(long callId, long nodeId)
m_frontend->didGetEventListenersForNode(callId, nodeId, listenersArray);
}
+void InspectorDOMAgent::performSearch(const String& whitespaceTrimmedQuery, bool runSynchronously)
+{
+ // FIXME: Few things are missing here:
+ // 1) Search works with node granularity - number of matches within node is not calculated.
+ // 2) There is no need to push all search results to the front-end at a time, pushing next / previous result
+ // is sufficient.
+
+ int queryLength = whitespaceTrimmedQuery.length();
+ bool startTagFound = !whitespaceTrimmedQuery.find('<');
+ bool endTagFound = whitespaceTrimmedQuery.reverseFind('>') + 1 == queryLength;
+
+ String tagNameQuery = whitespaceTrimmedQuery;
+ if (startTagFound || endTagFound)
+ tagNameQuery = tagNameQuery.substring(startTagFound ? 1 : 0, endTagFound ? queryLength - 1 : queryLength);
+ if (!Document::isValidName(tagNameQuery))
+ tagNameQuery = "";
+
+ String attributeNameQuery = whitespaceTrimmedQuery;
+ if (!Document::isValidName(attributeNameQuery))
+ attributeNameQuery = "";
+
+ String escapedQuery = whitespaceTrimmedQuery;
+ escapedQuery.replace("'", "\\'");
+ String escapedTagNameQuery = tagNameQuery;
+ escapedTagNameQuery.replace("'", "\\'");
+
+ // Clear pending jobs.
+ searchCanceled();
+
+ // Find all frames, iframes and object elements to search their documents.
+ for (Frame* frame = mainFrameDocument()->frame(); frame; frame = frame->tree()->traverseNext()) {
+ Document* document = frame->document();
+ if (!document)
+ continue;
+
+ if (!tagNameQuery.isEmpty() && startTagFound && endTagFound) {
+ m_pendingMatchJobs.append(new MatchExactTagNamesJob(document, tagNameQuery));
+ m_pendingMatchJobs.append(new MatchPlainTextJob(document, escapedQuery));
+ continue;
+ }
+
+ if (!tagNameQuery.isEmpty() && startTagFound) {
+ m_pendingMatchJobs.append(new MatchXPathJob(document, "//*[starts-with(name(), '" + escapedTagNameQuery + "')]"));
+ m_pendingMatchJobs.append(new MatchPlainTextJob(document, escapedQuery));
+ continue;
+ }
+
+ if (!tagNameQuery.isEmpty() && endTagFound) {
+ // FIXME: we should have a matchEndOfTagNames search function if endTagFound is true but not startTagFound.
+ // This requires ends-with() support in XPath, WebKit only supports starts-with() and contains().
+ m_pendingMatchJobs.append(new MatchXPathJob(document, "//*[contains(name(), '" + escapedTagNameQuery + "')]"));
+ m_pendingMatchJobs.append(new MatchPlainTextJob(document, escapedQuery));
+ continue;
+ }
+
+ bool matchesEveryNode = whitespaceTrimmedQuery == "//*" || whitespaceTrimmedQuery == "*";
+ if (matchesEveryNode) {
+ // These queries will match every node. Matching everything isn't useful and can be slow for large pages,
+ // so limit the search functions list to plain text and attribute matching for these.
+ m_pendingMatchJobs.append(new MatchXPathJob(document, "//*[contains(@*, '" + escapedQuery + "')]"));
+ m_pendingMatchJobs.append(new MatchPlainTextJob(document, escapedQuery));
+ continue;
+ }
+
+ m_pendingMatchJobs.append(new MatchExactIdJob(document, whitespaceTrimmedQuery));
+ m_pendingMatchJobs.append(new MatchExactClassNamesJob(document, whitespaceTrimmedQuery));
+ m_pendingMatchJobs.append(new MatchExactTagNamesJob(document, tagNameQuery));
+ m_pendingMatchJobs.append(new MatchQuerySelectorAllJob(document, "[" + attributeNameQuery + "]"));
+ m_pendingMatchJobs.append(new MatchQuerySelectorAllJob(document, whitespaceTrimmedQuery));
+ m_pendingMatchJobs.append(new MatchXPathJob(document, "//*[contains(@*, '" + escapedQuery + "')]"));
+ if (!tagNameQuery.isEmpty())
+ m_pendingMatchJobs.append(new MatchXPathJob(document, "//*[contains(name(), '" + escapedTagNameQuery + "')]"));
+ m_pendingMatchJobs.append(new MatchPlainTextJob(document, escapedQuery));
+ m_pendingMatchJobs.append(new MatchXPathJob(document, whitespaceTrimmedQuery));
+ }
+
+ if (runSynchronously) {
+ // For tests.
+ ListHashSet<Node*> resultCollector;
+ for (Deque<MatchJob*>::iterator it = m_pendingMatchJobs.begin(); it != m_pendingMatchJobs.end(); ++it)
+ (*it)->match(resultCollector);
+ reportNodesAsSearchResults(resultCollector);
+ searchCanceled();
+ return;
+ }
+ m_matchJobsTimer.startOneShot(0);
+}
+
+void InspectorDOMAgent::searchCanceled()
+{
+ if (m_matchJobsTimer.isActive())
+ m_matchJobsTimer.stop();
+ deleteAllValues(m_pendingMatchJobs);
+ m_pendingMatchJobs.clear();
+ m_searchResults.clear();
+}
+
String InspectorDOMAgent::documentURLString(Document* document) const
{
if (!document || document->url().isNull())
@@ -1330,6 +1553,36 @@ CSSStyleSheet* InspectorDOMAgent::getParentStyleSheet(CSSStyleDeclaration* style
return parentStyleSheet;
}
+void InspectorDOMAgent::onMatchJobsTimer(Timer<InspectorDOMAgent>*)
+{
+ if (!m_pendingMatchJobs.size()) {
+ searchCanceled();
+ return;
+ }
+
+ ListHashSet<Node*> resultCollector;
+ MatchJob* job = m_pendingMatchJobs.takeFirst();
+ job->match(resultCollector);
+ delete job;
+
+ reportNodesAsSearchResults(resultCollector);
+
+ m_matchJobsTimer.startOneShot(0.025);
+}
+
+void InspectorDOMAgent::reportNodesAsSearchResults(ListHashSet<Node*>& resultCollector)
+{
+ ScriptArray nodeIds = m_frontend->newScriptArray();
+ int index = 0;
+ for (ListHashSet<Node*>::iterator it = resultCollector.begin(); it != resultCollector.end(); ++it) {
+ if (m_searchResults.contains(*it))
+ continue;
+ m_searchResults.add(*it);
+ nodeIds.set(index++, static_cast<long long>(pushNodePathToFrontend(*it)));
+ }
+ m_frontend->addNodesToSearchResult(nodeIds);
+}
+
} // namespace WebCore
#endif // ENABLE(INSPECTOR)
diff --git a/WebCore/inspector/InspectorDOMAgent.h b/WebCore/inspector/InspectorDOMAgent.h
index f8925b5..a962569 100644
--- a/WebCore/inspector/InspectorDOMAgent.h
+++ b/WebCore/inspector/InspectorDOMAgent.h
@@ -31,13 +31,17 @@
#define InspectorDOMAgent_h
#include "AtomicString.h"
+#include "Document.h"
#include "EventListener.h"
#include "EventTarget.h"
#include "InspectorCSSStore.h"
+#include "NodeList.h"
#include "ScriptArray.h"
#include "ScriptObject.h"
#include "ScriptState.h"
+#include "Timer.h"
+#include <wtf/Deque.h>
#include <wtf/ListHashSet.h>
#include <wtf/HashMap.h>
#include <wtf/HashSet.h>
@@ -53,8 +57,8 @@ namespace WebCore {
class CSSStyleSheet;
class Element;
class Event;
- class Document;
class InspectorFrontend;
+ class MatchJob;
class NameNodeMap;
class Node;
class Page;
@@ -101,6 +105,8 @@ namespace WebCore {
void changeTagName(long callId, long nodeId, const AtomicString& tagName, bool expanded);
void setTextNodeValue(long callId, long nodeId, const String& value);
void getEventListenersForNode(long callId, long nodeId);
+ void performSearch(const String& whitespaceTrimmedQuery, bool runSynchronously);
+ void searchCanceled();
// Methods called from the frontend for CSS styles inspection.
void getStyles(long callId, long nodeId, bool authorOnly);
@@ -165,6 +171,9 @@ namespace WebCore {
String documentURLString(Document* document) const;
InspectorCSSStore* cssStore() { return m_cssStore; }
+ void onMatchJobsTimer(Timer<InspectorDOMAgent>*);
+ void reportNodesAsSearchResults(ListHashSet<Node*>& resultCollector);
+
ScriptObject buildObjectForStyle(CSSStyleDeclaration*, bool bind);
void populateObjectWithStyleProperties(CSSStyleDeclaration*, ScriptObject& result);
ScriptArray buildArrayForDisabledStyleProperties(DisabledStyleDeclaration*);
@@ -188,9 +197,11 @@ namespace WebCore {
HashSet<long> m_childrenRequested;
long m_lastNodeId;
ListHashSet<RefPtr<Document> > m_documents;
+ Deque<MatchJob*> m_pendingMatchJobs;
+ Timer<InspectorDOMAgent> m_matchJobsTimer;
+ HashSet<RefPtr<Node> > m_searchResults;
};
-
} // namespace WebCore
#endif // !defined(InspectorDOMAgent_h)
diff --git a/WebCore/inspector/InspectorFrontend.cpp b/WebCore/inspector/InspectorFrontend.cpp
index fb66cad..c9aa730 100644
--- a/WebCore/inspector/InspectorFrontend.cpp
+++ b/WebCore/inspector/InspectorFrontend.cpp
@@ -36,6 +36,7 @@
#include "Frame.h"
#include "InjectedScript.h"
#include "InjectedScriptHost.h"
+#include "InspectorClient.h"
#include "InspectorController.h"
#include "InspectorWorkerResource.h"
#include "Node.h"
@@ -49,8 +50,9 @@
namespace WebCore {
-InspectorFrontend::InspectorFrontend(ScriptObject webInspector)
+InspectorFrontend::InspectorFrontend(ScriptObject webInspector, InspectorClient* inspectorClient)
: m_webInspector(webInspector)
+ , m_inspectorClient(inspectorClient)
{
}
@@ -86,10 +88,18 @@ void InspectorFrontend::didCommitLoad()
callSimpleFunction("didCommitLoad");
}
-void InspectorFrontend::populateFrontendSettings(const String& settings)
+void InspectorFrontend::populateApplicationSettings(const String& settings)
{
ScriptFunctionCall function(m_webInspector, "dispatch");
- function.appendArgument("populateFrontendSettings");
+ function.appendArgument("populateApplicationSettings");
+ function.appendArgument(settings);
+ function.call();
+}
+
+void InspectorFrontend::populateSessionSettings(const String& settings)
+{
+ ScriptFunctionCall function(m_webInspector, "dispatch");
+ function.appendArgument("populateSessionSettings");
function.appendArgument(settings);
function.call();
}
@@ -305,7 +315,7 @@ void InspectorFrontend::debuggerWasDisabled()
callSimpleFunction("debuggerWasDisabled");
}
-void InspectorFrontend::parsedScriptSource(const String& sourceID, const String& url, const String& data, int firstLine)
+void InspectorFrontend::parsedScriptSource(const String& sourceID, const String& url, const String& data, int firstLine, int scriptWorldType)
{
ScriptFunctionCall function(m_webInspector, "dispatch");
function.appendArgument("parsedScriptSource");
@@ -313,6 +323,7 @@ void InspectorFrontend::parsedScriptSource(const String& sourceID, const String&
function.appendArgument(url);
function.appendArgument(data);
function.appendArgument(firstLine);
+ function.appendArgument(scriptWorldType);
function.call();
}
@@ -354,6 +365,30 @@ void InspectorFrontend::resumedScript()
callSimpleFunction("resumedScript");
}
+void InspectorFrontend::didEditScriptSource(long callId, bool success, const String& result, SerializedScriptValue* newCallFrames)
+{
+ ScriptFunctionCall function(m_webInspector, "dispatch");
+ function.appendArgument("didEditScriptSource");
+ function.appendArgument(callId);
+ function.appendArgument(success);
+ function.appendArgument(result);
+ if (success && newCallFrames) {
+ ScriptValue newCallFramesValue = ScriptValue::deserialize(scriptState(), newCallFrames);
+ ASSERT(!newCallFramesValue .hasNoValue());
+ function.appendArgument(newCallFramesValue);
+ }
+ function.call();
+}
+
+void InspectorFrontend::didGetScriptSource(long callId, const String& result)
+{
+ ScriptFunctionCall function(m_webInspector, "dispatch");
+ function.appendArgument("didGetScriptSource");
+ function.appendArgument(callId);
+ function.appendArgument(result);
+ function.call();
+}
+
void InspectorFrontend::profilerWasEnabled()
{
callSimpleFunction("profilerWasEnabled");
@@ -738,7 +773,7 @@ void InspectorFrontend::updateDOMStorage(long storageId)
}
#endif
-void InspectorFrontend::addNodesToSearchResult(const String& nodeIds)
+void InspectorFrontend::addNodesToSearchResult(const ScriptArray& nodeIds)
{
ScriptFunctionCall function(m_webInspector, "dispatch");
function.appendArgument("addNodesToSearchResult");
diff --git a/WebCore/inspector/InspectorFrontend.h b/WebCore/inspector/InspectorFrontend.h
index fa752aa..1762014 100644
--- a/WebCore/inspector/InspectorFrontend.h
+++ b/WebCore/inspector/InspectorFrontend.h
@@ -30,6 +30,7 @@
#ifndef InspectorFrontend_h
#define InspectorFrontend_h
+#include "InspectorValues.h"
#include "ScriptArray.h"
#include "ScriptObject.h"
#include "ScriptState.h"
@@ -39,16 +40,20 @@ namespace WebCore {
class ConsoleMessage;
class Database;
class Frame;
+ class InspectorClient;
class InspectorResource;
+ class InspectorWorkerResource;
class Node;
class ScriptString;
class SerializedScriptValue;
class Storage;
- class InspectorWorkerResource;
class InspectorFrontend : public Noncopyable {
public:
- InspectorFrontend(ScriptObject webInspector);
+ // We are in transition from JS transport via webInspector to native
+ // transport via inspectorClient. After migration, webInspector parameter should
+ // be removed.
+ InspectorFrontend(ScriptObject webInspector, InspectorClient* inspectorClient);
~InspectorFrontend();
void close();
@@ -59,7 +64,8 @@ namespace WebCore {
void didCommitLoad();
- void populateFrontendSettings(const String& settings);
+ void populateApplicationSettings(const String& settings);
+ void populateSessionSettings(const String& settings);
void updateConsoleMessageExpiredCount(unsigned count);
void addConsoleMessage(const ScriptObject& messageObj, const Vector<ScriptString>& frames, const Vector<RefPtr<SerializedScriptValue> >& arguments, const String& message);
@@ -92,12 +98,15 @@ namespace WebCore {
void debuggerWasEnabled();
void debuggerWasDisabled();
- void parsedScriptSource(const String& sourceID, const String& url, const String& data, int firstLine);
+ void parsedScriptSource(const String& sourceID, const String& url, const String& data, int firstLine, int scriptWorldType);
void restoredBreakpoint(const String& sourceID, const String& url, int line, bool enabled, const String& condition);
void failedToParseScriptSource(const String& url, const String& data, int firstLine, int errorLine, const String& errorMessage);
void pausedScript(SerializedScriptValue* callFrames);
void resumedScript();
+ void didEditScriptSource(long callId, bool success, const String& result, SerializedScriptValue* newCallFrames);
+ void didGetScriptSource(long callId, const String& result);
+
void profilerWasEnabled();
void profilerWasDisabled();
void addProfileHeader(const ScriptValue& profile);
@@ -158,7 +167,7 @@ namespace WebCore {
void didGetCookies(long callId, const ScriptArray& cookies, const String& cookiesString);
void didDispatchOnInjectedScript(long callId, SerializedScriptValue* result, bool isException);
- void addNodesToSearchResult(const String& nodeIds);
+ void addNodesToSearchResult(const ScriptArray& nodeIds);
void contextMenuItemSelected(int itemId);
void contextMenuCleared();
@@ -169,6 +178,7 @@ namespace WebCore {
private:
void callSimpleFunction(const String& functionName);
ScriptObject m_webInspector;
+ InspectorClient* m_inspectorClient;
};
} // namespace WebCore
diff --git a/WebCore/inspector/InspectorFrontendClientLocal.cpp b/WebCore/inspector/InspectorFrontendClientLocal.cpp
index 18c52da..188566f 100644
--- a/WebCore/inspector/InspectorFrontendClientLocal.cpp
+++ b/WebCore/inspector/InspectorFrontendClientLocal.cpp
@@ -89,7 +89,7 @@ void InspectorFrontendClientLocal::frontendLoaded()
ASSERT_NOT_REACHED();
return;
}
- m_inspectorController->setFrontend(new InspectorFrontend(webInspectorObj));
+ m_inspectorController->connectFrontend(webInspectorObj);
}
void InspectorFrontendClientLocal::requestAttachWindow()
diff --git a/WebCore/inspector/InspectorResource.cpp b/WebCore/inspector/InspectorResource.cpp
index 999b8d6..f0e391d 100644
--- a/WebCore/inspector/InspectorResource.cpp
+++ b/WebCore/inspector/InspectorResource.cpp
@@ -169,7 +169,6 @@ void InspectorResource::updateScriptObject(InspectorFrontend* frontend)
jsonObject.set("expectedContentLength", m_expectedContentLength);
jsonObject.set("statusCode", m_responseStatusCode);
jsonObject.set("statusText", m_responseStatusText);
- jsonObject.set("suggestedFilename", m_suggestedFilename);
ScriptObject responseHeaders = frontend->newScriptObject();
populateHeadersObject(&responseHeaders, m_responseHeaderFields);
jsonObject.set("responseHeaders", responseHeaders);
diff --git a/WebCore/inspector/InspectorTimelineAgent.h b/WebCore/inspector/InspectorTimelineAgent.h
index 4c5b939..fe334be 100644
--- a/WebCore/inspector/InspectorTimelineAgent.h
+++ b/WebCore/inspector/InspectorTimelineAgent.h
@@ -97,9 +97,11 @@ public:
void willPaint(const IntRect&);
void didPaint();
+ // FIXME: |length| should be passed in didWrite instead willWrite
+ // as the parser can not know how much it will process until it tries.
void willWriteHTML(unsigned int length, unsigned int startLine);
void didWriteHTML(unsigned int endLine);
-
+
void didInstallTimer(int timerId, int timeout, bool singleShot);
void didRemoveTimer(int timerId);
void willFireTimer(int timerId);
diff --git a/WebCore/inspector/InspectorValues.cpp b/WebCore/inspector/InspectorValues.cpp
index f59e900..5c7d0c8 100644
--- a/WebCore/inspector/InspectorValues.cpp
+++ b/WebCore/inspector/InspectorValues.cpp
@@ -35,6 +35,407 @@
namespace WebCore {
+namespace {
+
+static const int stackLimit = 1000;
+
+enum Token {
+ OBJECT_BEGIN,
+ OBJECT_END,
+ ARRAY_BEGIN,
+ ARRAY_END,
+ STRING,
+ NUMBER,
+ BOOL_TRUE,
+ BOOL_FALSE,
+ NULL_TOKEN,
+ LIST_SEPARATOR,
+ OBJECT_PAIR_SEPARATOR,
+ INVALID_TOKEN,
+};
+
+const char* const nullString = "null";
+const char* const trueString = "true";
+const char* const falseString = "false";
+
+bool parseConstToken(const UChar* start, const UChar* end, const UChar** tokenEnd, const char* token)
+{
+ while (start < end && *token != '\0' && *start++ == *token++) { }
+ if (*token != '\0')
+ return false;
+ *tokenEnd = start;
+ return true;
+}
+
+bool readInt(const UChar* start, const UChar* end, const UChar** tokenEnd, bool canHaveLeadingZeros)
+{
+ if (start == end)
+ return false;
+ bool haveLeadingZero = '0' == *start;
+ int length = 0;
+ while (start < end && '0' <= *start && *start <= '9') {
+ ++start;
+ ++length;
+ }
+ if (!length)
+ return false;
+ if (!canHaveLeadingZeros && length > 1 && haveLeadingZero)
+ return false;
+ *tokenEnd = start;
+ return true;
+}
+
+bool parseNumberToken(const UChar* start, const UChar* end, const UChar** tokenEnd)
+{
+ // We just grab the number here. We validate the size in DecodeNumber.
+ // According to RFC4627, a valid number is: [minus] int [frac] [exp]
+ if (start == end)
+ return false;
+ UChar c = *start;
+ if ('-' == c)
+ ++start;
+
+ if (!readInt(start, end, &start, false))
+ return false;
+ if (start == end) {
+ *tokenEnd = start;
+ return true;
+ }
+
+ // Optional fraction part
+ c = *start;
+ if ('.' == c) {
+ ++start;
+ if (!readInt(start, end, &start, true))
+ return false;
+ if (start == end) {
+ *tokenEnd = start;
+ return true;
+ }
+ c = *start;
+ }
+
+ // Optional exponent part
+ if ('e' == c || 'E' == c) {
+ ++start;
+ if (start == end)
+ return false;
+ c = *start;
+ if ('-' == c || '+' == c) {
+ ++start;
+ if (start == end)
+ return false;
+ }
+ if (!readInt(start, end, &start, true))
+ return false;
+ }
+
+ *tokenEnd = start;
+ return true;
+}
+
+bool readHexDigits(const UChar* start, const UChar* end, const UChar** tokenEnd, int digits)
+{
+ if (end - start < digits)
+ return false;
+ for (int i = 0; i < digits; ++i) {
+ UChar c = *start++;
+ if (!(('0' <= c && c <= '9') || ('a' <= c && c <= 'f') || ('A' <= c && c <= 'F')))
+ return false;
+ }
+ *tokenEnd = start;
+ return true;
+}
+
+bool parseStringToken(const UChar* start, const UChar* end, const UChar** tokenEnd)
+{
+ while (start < end) {
+ UChar c = *start++;
+ if ('\\' == c) {
+ c = *start++;
+ // Make sure the escaped char is valid.
+ switch (c) {
+ case 'x':
+ if (!readHexDigits(start, end, &start, 2))
+ return false;
+ break;
+ case 'u':
+ if (!readHexDigits(start, end, &start, 4))
+ return false;
+ break;
+ case '\\':
+ case '/':
+ case 'b':
+ case 'f':
+ case 'n':
+ case 'r':
+ case 't':
+ case 'v':
+ case '"':
+ break;
+ default:
+ return false;
+ }
+ } else if ('"' == c) {
+ *tokenEnd = start;
+ return true;
+ }
+ }
+ return false;
+}
+
+Token parseToken(const UChar* start, const UChar* end, const UChar** tokenEnd)
+{
+ if (start == end)
+ return INVALID_TOKEN;
+
+ switch (*start) {
+ case 'n':
+ if (parseConstToken(start, end, tokenEnd, nullString))
+ return NULL_TOKEN;
+ break;
+ case 't':
+ if (parseConstToken(start, end, tokenEnd, trueString))
+ return BOOL_TRUE;
+ break;
+ case 'f':
+ if (parseConstToken(start, end, tokenEnd, falseString))
+ return BOOL_FALSE;
+ break;
+ case '[':
+ *tokenEnd = start + 1;
+ return ARRAY_BEGIN;
+ case ']':
+ *tokenEnd = start + 1;
+ return ARRAY_END;
+ case ',':
+ *tokenEnd = start + 1;
+ return LIST_SEPARATOR;
+ case '{':
+ *tokenEnd = start + 1;
+ return OBJECT_BEGIN;
+ case '}':
+ *tokenEnd = start + 1;
+ return OBJECT_END;
+ case ':':
+ *tokenEnd = start + 1;
+ return OBJECT_PAIR_SEPARATOR;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ case '-':
+ if (parseNumberToken(start, end, tokenEnd))
+ return NUMBER;
+ break;
+ case '"':
+ if (parseStringToken(start + 1, end, tokenEnd))
+ return STRING;
+ break;
+ }
+ return INVALID_TOKEN;
+}
+
+inline int hexToInt(UChar c)
+{
+ if ('0' <= c && c <= '9')
+ return c - '0';
+ if ('A' <= c && c <= 'F')
+ return c - 'A' + 10;
+ if ('a' <= c && c <= 'f')
+ return c - 'a' + 10;
+ ASSERT_NOT_REACHED();
+ return 0;
+}
+
+bool decodeString(const UChar* start, const UChar* end, Vector<UChar>* output)
+{
+ while (start < end) {
+ UChar c = *start++;
+ if ('\\' != c) {
+ output->append(c);
+ continue;
+ }
+ c = *start++;
+ switch (c) {
+ case '"':
+ case '/':
+ case '\\':
+ break;
+ case 'b':
+ c = '\b';
+ break;
+ case 'f':
+ c = '\f';
+ break;
+ case 'n':
+ c = '\n';
+ break;
+ case 'r':
+ c = '\r';
+ break;
+ case 't':
+ c = '\t';
+ break;
+ case 'v':
+ c = '\v';
+ break;
+ case 'x':
+ c = (hexToInt(*start) << 4) +
+ hexToInt(*(start + 1));
+ start += 2;
+ break;
+ case 'u':
+ c = (hexToInt(*start) << 12) +
+ (hexToInt(*(start + 1)) << 8) +
+ (hexToInt(*(start + 2)) << 4) +
+ hexToInt(*(start + 3));
+ start += 4;
+ break;
+ default:
+ return false;
+ }
+ output->append(c);
+ }
+ return true;
+}
+
+bool decodeString(const UChar* start, const UChar* end, String* output)
+{
+ if (start == end) {
+ *output = "";
+ return true;
+ }
+ if (start > end)
+ return false;
+ Vector<UChar> buffer;
+ buffer.reserveCapacity(end - start);
+ if (!decodeString(start, end, &buffer))
+ return false;
+ *output = String(buffer.data(), buffer.size());
+ return true;
+}
+
+PassRefPtr<InspectorValue> buildValue(const UChar* start, const UChar* end, const UChar** valueTokenEnd, int depth)
+{
+ if (depth > stackLimit)
+ return 0;
+
+ RefPtr<InspectorValue> result;
+ const UChar* tokenEnd;
+ Token token = parseToken(start, end, &tokenEnd);
+ switch (token) {
+ case INVALID_TOKEN:
+ return 0;
+ case NULL_TOKEN:
+ result = InspectorValue::null();
+ break;
+ case BOOL_TRUE:
+ result = InspectorBasicValue::create(true);
+ break;
+ case BOOL_FALSE:
+ result = InspectorBasicValue::create(false);
+ break;
+ case NUMBER: {
+ bool ok;
+ double value = charactersToDouble(start, tokenEnd - start, &ok);
+ if (!ok)
+ return 0;
+ result = InspectorBasicValue::create(value);
+ break;
+ }
+ case STRING: {
+ String value;
+ bool ok = decodeString(start + 1, tokenEnd - 1, &value);
+ if (!ok)
+ return 0;
+ result = InspectorString::create(value);
+ break;
+ }
+ case ARRAY_BEGIN: {
+ RefPtr<InspectorArray> array = InspectorArray::create();
+ start = tokenEnd;
+ token = parseToken(start, end, &tokenEnd);
+ while (token != ARRAY_END) {
+ RefPtr<InspectorValue> arrayNode = buildValue(start, end, &tokenEnd, depth + 1);
+ if (!arrayNode)
+ return 0;
+ array->push(arrayNode);
+
+ // After a list value, we expect a comma or the end of the list.
+ start = tokenEnd;
+ token = parseToken(start, end, &tokenEnd);
+ if (token == LIST_SEPARATOR) {
+ start = tokenEnd;
+ token = parseToken(start, end, &tokenEnd);
+ if (token == ARRAY_END)
+ return 0;
+ } else if (token != ARRAY_END) {
+ // Unexpected value after list value. Bail out.
+ return 0;
+ }
+ }
+ if (token != ARRAY_END)
+ return 0;
+ result = array.release();
+ break;
+ }
+ case OBJECT_BEGIN: {
+ RefPtr<InspectorObject> object = InspectorObject::create();
+ start = tokenEnd;
+ token = parseToken(start, end, &tokenEnd);
+ while (token != OBJECT_END) {
+ if (token != STRING)
+ return 0;
+ String key;
+ if (!decodeString(start + 1, tokenEnd - 1, &key))
+ return 0;
+ start = tokenEnd;
+
+ token = parseToken(start, end, &tokenEnd);
+ if (token != OBJECT_PAIR_SEPARATOR)
+ return 0;
+ start = tokenEnd;
+
+ RefPtr<InspectorValue> value = buildValue(start, end, &tokenEnd, depth + 1);
+ if (!value)
+ return 0;
+ object->set(key, value);
+ start = tokenEnd;
+
+ // After a key/value pair, we expect a comma or the end of the
+ // object.
+ token = parseToken(start, end, &tokenEnd);
+ if (token == LIST_SEPARATOR) {
+ start = tokenEnd;
+ token = parseToken(start, end, &tokenEnd);
+ if (token == OBJECT_END)
+ return 0;
+ } else if (token != OBJECT_END) {
+ // Unexpected value after last object value. Bail out.
+ return 0;
+ }
+ }
+ if (token != OBJECT_END)
+ return 0;
+ result = object.release();
+ break;
+ }
+
+ default:
+ // We got a token that's not a value.
+ return 0;
+ }
+ *valueTokenEnd = tokenEnd;
+ return result.release();
+}
+
inline bool escapeChar(UChar c, Vector<UChar>* dst)
{
switch (c) {
@@ -71,6 +472,44 @@ inline void doubleQuoteString(const String& str, Vector<UChar>* dst)
dst->append('"');
}
+} // anonymous namespace
+
+bool InspectorValue::asBool(bool*) const
+{
+ return false;
+}
+
+bool InspectorValue::asNumber(double*) const
+{
+ return false;
+}
+
+bool InspectorValue::asString(String*) const
+{
+ return false;
+}
+
+PassRefPtr<InspectorObject> InspectorValue::asObject()
+{
+ return 0;
+}
+
+PassRefPtr<InspectorArray> InspectorValue::asArray()
+{
+ return 0;
+}
+
+PassRefPtr<InspectorValue> InspectorValue::readJSON(const String& json)
+{
+ const UChar* start = json.characters();
+ const UChar* end = json.characters() + json.length();
+ const UChar *tokenEnd;
+ RefPtr<InspectorValue> value = buildValue(start, end, &tokenEnd, 0);
+ if (!value || tokenEnd != end)
+ return 0;
+ return value.release();
+}
+
String InspectorValue::toJSONString() const
{
Vector<UChar> result;
@@ -82,7 +521,23 @@ String InspectorValue::toJSONString() const
void InspectorValue::writeJSON(Vector<UChar>* output) const
{
ASSERT(m_type == TypeNull);
- output->append("null", 4);
+ output->append(nullString, 4);
+}
+
+bool InspectorBasicValue::asBool(bool* output) const
+{
+ if (type() != TypeBoolean)
+ return false;
+ *output = m_boolValue;
+ return true;
+}
+
+bool InspectorBasicValue::asNumber(double* output) const
+{
+ if (type() != TypeDouble)
+ return false;
+ *output = m_doubleValue;
+ return true;
}
void InspectorBasicValue::writeJSON(Vector<UChar>* output) const
@@ -90,26 +545,87 @@ void InspectorBasicValue::writeJSON(Vector<UChar>* output) const
ASSERT(type() == TypeBoolean || type() == TypeDouble);
if (type() == TypeBoolean) {
if (m_boolValue)
- output->append("true", 4);
+ output->append(trueString, 4);
else
- output->append("false", 5);
+ output->append(falseString, 5);
} else if (type() == TypeDouble) {
String value = String::format("%f", m_doubleValue);
output->append(value.characters(), value.length());
}
}
+bool InspectorString::asString(String* output) const
+{
+ *output = m_stringValue;
+ return true;
+}
+
void InspectorString::writeJSON(Vector<UChar>* output) const
{
ASSERT(type() == TypeString);
doubleQuoteString(m_stringValue, output);
}
+PassRefPtr<InspectorObject> InspectorObject::asObject()
+{
+ return this;
+}
+
+bool InspectorObject::getBool(const String& name, bool* output) const
+{
+ RefPtr<InspectorValue> value = get(name);
+ if (!value)
+ return false;
+ return value->asBool(output);
+}
+
+bool InspectorObject::getNumber(const String& name, double* output) const
+{
+ RefPtr<InspectorValue> value = get(name);
+ if (!value)
+ return false;
+ return value->asNumber(output);
+}
+
+bool InspectorObject::getString(const String& name, String* output) const
+{
+ RefPtr<InspectorValue> value = get(name);
+ if (!value)
+ return false;
+ return value->asString(output);
+}
+
+PassRefPtr<InspectorObject> InspectorObject::getObject(const String& name) const
+{
+ PassRefPtr<InspectorValue> value = get(name);
+ if (!value)
+ return false;
+ return value->asObject();
+}
+
+PassRefPtr<InspectorArray> InspectorObject::getArray(const String& name) const
+{
+ PassRefPtr<InspectorValue> value = get(name);
+ if (!value)
+ return false;
+ return value->asArray();
+}
+
+PassRefPtr<InspectorValue> InspectorObject::get(const String& name) const
+{
+ Dictionary::const_iterator it = m_data.find(name);
+ if (it == m_data.end())
+ return 0;
+ return it->second;
+}
+
void InspectorObject::writeJSON(Vector<UChar>* output) const
{
output->append('{');
- for (Dictionary::const_iterator it = m_data.begin(); it != m_data.end(); ++it) {
- if (it != m_data.begin())
+ for (size_t i = 0; i < m_order.size(); ++i) {
+ Dictionary::const_iterator it = m_data.find(m_order[i]);
+ ASSERT(it != m_data.end());
+ if (i)
output->append(',');
doubleQuoteString(it->first, output);
output->append(':');
@@ -118,6 +634,11 @@ void InspectorObject::writeJSON(Vector<UChar>* output) const
output->append('}');
}
+PassRefPtr<InspectorArray> InspectorArray::asArray()
+{
+ return this;
+}
+
void InspectorArray::writeJSON(Vector<UChar>* output) const
{
output->append('[');
diff --git a/WebCore/inspector/InspectorValues.h b/WebCore/inspector/InspectorValues.h
index a60bb2c..b9920c4 100644
--- a/WebCore/inspector/InspectorValues.h
+++ b/WebCore/inspector/InspectorValues.h
@@ -42,6 +42,8 @@
namespace WebCore {
+class InspectorArray;
+class InspectorObject;
class String;
class InspectorValue : public RefCounted<InspectorValue> {
@@ -65,6 +67,14 @@ public:
Type type() const { return m_type; }
+ virtual bool asBool(bool* output) const;
+ virtual bool asNumber(double* output) const;
+ virtual bool asString(String* output) const;
+ virtual PassRefPtr<InspectorObject> asObject();
+ virtual PassRefPtr<InspectorArray> asArray();
+
+ static PassRefPtr<InspectorValue> readJSON(const String& json);
+
String toJSONString() const;
virtual void writeJSON(Vector<UChar>* output) const;
@@ -93,6 +103,9 @@ public:
return adoptRef(new InspectorBasicValue(value));
}
+ virtual bool asBool(bool* output) const;
+ virtual bool asNumber(double* output) const;
+
virtual void writeJSON(Vector<UChar>* output) const;
private:
@@ -117,6 +130,9 @@ public:
{
return adoptRef(new InspectorString(value));
}
+
+ virtual bool asString(String* output) const;
+
virtual void writeJSON(Vector<UChar>* output) const;
private:
@@ -127,6 +143,13 @@ private:
};
class InspectorObject : public InspectorValue {
+private:
+ typedef HashMap<String, RefPtr<InspectorValue> > Dictionary;
+
+public:
+ typedef Dictionary::iterator iterator;
+ typedef Dictionary::const_iterator const_iterator;
+
public:
static PassRefPtr<InspectorObject> create()
{
@@ -134,17 +157,31 @@ public:
}
~InspectorObject() { }
+ virtual PassRefPtr<InspectorObject> asObject();
+
void setBool(const String& name, bool);
void setNumber(const String& name, double);
void setString(const String& name, const String&);
void set(const String& name, PassRefPtr<InspectorValue>);
+ bool getBool(const String& name, bool* output) const;
+ bool getNumber(const String& name, double* output) const;
+ bool getString(const String& name, String* output) const;
+ PassRefPtr<InspectorObject> getObject(const String& name) const;
+ PassRefPtr<InspectorArray> getArray(const String& name) const;
+ PassRefPtr<InspectorValue> get(const String& name) const;
+
virtual void writeJSON(Vector<UChar>* output) const;
+ iterator begin() { return m_data.begin(); }
+ iterator end() { return m_data.end(); }
+ const_iterator begin() const { return m_data.begin(); }
+ const_iterator end() const { return m_data.end(); }
+
private:
InspectorObject() : InspectorValue(TypeObject) { }
- typedef HashMap<String, RefPtr<InspectorValue> > Dictionary;
Dictionary m_data;
+ Vector<String> m_order;
};
class InspectorArray : public InspectorValue {
@@ -155,6 +192,8 @@ public:
}
~InspectorArray() { }
+ virtual PassRefPtr<InspectorArray> asArray();
+
void pushBool(bool);
void pushNumber(double);
void pushString(const String&);
@@ -170,22 +209,23 @@ private:
inline void InspectorObject::setBool(const String& name, bool value)
{
- m_data.set(name, InspectorBasicValue::create(value));
+ set(name, InspectorBasicValue::create(value));
}
inline void InspectorObject::setNumber(const String& name, double value)
{
- m_data.set(name, InspectorBasicValue::create(value));
+ set(name, InspectorBasicValue::create(value));
}
inline void InspectorObject::setString(const String& name, const String& value)
{
- m_data.set(name, InspectorString::create(value));
+ set(name, InspectorString::create(value));
}
inline void InspectorObject::set(const String& name, PassRefPtr<InspectorValue> value)
{
- m_data.set(name, value);
+ if (m_data.set(name, value).second)
+ m_order.append(name);
}
inline void InspectorArray::pushBool(bool value)
@@ -212,4 +252,3 @@ inline void InspectorArray::push(PassRefPtr<InspectorValue> value)
#endif // ENABLE(INSPECTOR)
#endif // !defined(InspectorValues_h)
-
diff --git a/WebCore/inspector/ScriptDebugListener.h b/WebCore/inspector/ScriptDebugListener.h
index c669f5e..539b000 100644
--- a/WebCore/inspector/ScriptDebugListener.h
+++ b/WebCore/inspector/ScriptDebugListener.h
@@ -38,11 +38,16 @@ namespace WebCore {
class String;
+enum ScriptWorldType {
+MAIN_WORLD = 0,
+EXTENSIONS_WORLD
+};
+
class ScriptDebugListener {
public:
virtual ~ScriptDebugListener() { }
- virtual void didParseSource(const String& sourceID, const String& url, const String& data, int firstLine) = 0;
+ virtual void didParseSource(const String& sourceID, const String& url, const String& data, int firstLine, ScriptWorldType) = 0;
virtual void failedToParseSource(const String& url, const String& data, int firstLine, int errorLine, const String& errorMessage) = 0;
virtual void didPause(ScriptState*) = 0;
virtual void didContinue() = 0;
diff --git a/WebCore/inspector/front-end/Breakpoint.js b/WebCore/inspector/front-end/Breakpoint.js
deleted file mode 100644
index e69de29..0000000
--- a/WebCore/inspector/front-end/Breakpoint.js
+++ /dev/null
diff --git a/WebCore/inspector/front-end/BreakpointManager.js b/WebCore/inspector/front-end/BreakpointManager.js
index c277fb1..3ccccac 100644
--- a/WebCore/inspector/front-end/BreakpointManager.js
+++ b/WebCore/inspector/front-end/BreakpointManager.js
@@ -30,11 +30,32 @@ WebInspector.BreakpointManager = function()
}
WebInspector.BreakpointManager.prototype = {
+ setOneTimeBreakpoint: function(sourceID, line)
+ {
+ var breakpoint = new WebInspector.Breakpoint(this, sourceID, undefined, line, true, undefined);
+ if (this._breakpoints[breakpoint.id])
+ return;
+ if (this._oneTimeBreakpoint)
+ this._removeBreakpointFromBackend(this._oneTimeBreakpoint);
+ this._oneTimeBreakpoint = breakpoint;
+ this._saveBreakpointOnBackend(breakpoint);
+ },
+
+ removeOneTimeBreakpoint: function()
+ {
+ if (this._oneTimeBreakpoint) {
+ this._removeBreakpointFromBackend(this._oneTimeBreakpoint);
+ delete this._oneTimeBreakpoint;
+ }
+ },
+
addBreakpoint: function(sourceID, sourceURL, line, enabled, condition)
{
var breakpoint = new WebInspector.Breakpoint(this, sourceID, sourceURL, line, enabled, condition);
if (this._breakpoints[breakpoint.id])
return;
+ if (this._oneTimeBreakpoint && (this._oneTimeBreakpoint.id == breakpoint.id))
+ delete this._oneTimeBreakpoint;
this._breakpoints[breakpoint.id] = breakpoint;
this._saveBreakpointOnBackend(breakpoint);
this.dispatchEventToListeners("breakpoint-added", breakpoint);
@@ -72,6 +93,7 @@ WebInspector.BreakpointManager.prototype = {
reset: function()
{
this._breakpoints = {};
+ delete this._oneTimeBreakpoint;
},
_saveBreakpointOnBackend: function(breakpoint)
diff --git a/WebCore/inspector/front-end/CSSStyleModel.js b/WebCore/inspector/front-end/CSSStyleModel.js
new file mode 100644
index 0000000..66a20ce
--- /dev/null
+++ b/WebCore/inspector/front-end/CSSStyleModel.js
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+WebInspector.CSSStyleModel = function()
+{
+}
+
+WebInspector.CSSStyleModel.prototype = {
+ getStylesAsync: function(nodeId, authOnly, userCallback)
+ {
+ InspectorBackend.getStyles(WebInspector.Callback.wrap(userCallback), nodeId, authOnly);
+ },
+
+ getComputedStyleAsync: function(nodeId, userCallback)
+ {
+ InspectorBackend.getComputedStyle(WebInspector.Callback.wrap(userCallback), nodeId);
+ },
+
+ setRuleSelector: function(ruleId, newContent, nodeId, successCallback, failureCallback)
+ {
+ function callback(newRulePayload, doesAffectSelectedNode)
+ {
+ if (!newRulePayload)
+ failureCallback();
+ else
+ successCallback(WebInspector.CSSStyleDeclaration.parseRule(newRulePayload), doesAffectSelectedNode);
+ }
+
+ InspectorBackend.setRuleSelector(WebInspector.Callback.wrap(callback), ruleId, newContent, nodeId);
+ },
+
+ addRule: function(nodeId, newContent, successCallback, failureCallback)
+ {
+ function callback(rule, doesAffectSelectedNode)
+ {
+ if (!rule) {
+ // Invalid syntax for a selector
+ failureCallback();
+ } else {
+ var styleRule = WebInspector.CSSStyleDeclaration.parseRule(rule);
+ styleRule.rule = rule;
+ successCallback(styleRule, doesAffectSelectedNode);
+ }
+ }
+
+ InspectorBackend.addRule(WebInspector.Callback.wrap(callback), newContent, nodeId);
+ },
+
+ toggleStyleEnabled: function(styleId, propertyName, disabled, userCallback)
+ {
+ function callback(newPayload)
+ {
+ if (!newPayload) {
+ userCallback(null);
+ return;
+ }
+
+ var newStyle = WebInspector.CSSStyleDeclaration.parseStyle(newPayload);
+ userCallback(newStyle);
+ }
+
+ InspectorBackend.toggleStyleEnabled(WebInspector.Callback.wrap(callback), styleId, propertyName, disabled);
+ },
+
+ setCSSText: function(styleId, cssText)
+ {
+ InspectorBackend.setStyleText(WebInspector.Callback.wrap(null), styleId, cssText);
+ },
+
+ applyStyleText: function(styleId, styleText, propertyName, successCallback, failureCallback)
+ {
+ function callback(success, newPayload, changedProperties)
+ {
+ if (!success)
+ failureCallback();
+ else {
+ var newStyle = newPayload ? WebInspector.CSSStyleDeclaration.parseStyle(newPayload) : null;
+ successCallback(newStyle, changedProperties);
+ }
+ }
+
+ InspectorBackend.applyStyleText(WebInspector.Callback.wrap(callback), styleId, styleText, propertyName);
+ }
+}
diff --git a/WebCore/inspector/front-end/ConsoleView.js b/WebCore/inspector/front-end/ConsoleView.js
index 8521cb3..d1f347b 100644
--- a/WebCore/inspector/front-end/ConsoleView.js
+++ b/WebCore/inspector/front-end/ConsoleView.js
@@ -48,7 +48,7 @@ WebInspector.ConsoleView = function(drawer)
this.promptElement.className = "source-code";
this.promptElement.addEventListener("keydown", this._promptKeyDown.bind(this), true);
this.prompt = new WebInspector.TextPrompt(this.promptElement, this.completions.bind(this), ExpressionStopCharacters + ".");
- WebInspector.settings.addEventListener("loaded", this._settingsLoaded, this);
+ WebInspector.applicationSettings.addEventListener("loaded", this._settingsLoaded, this);
this.topGroup = new WebInspector.ConsoleGroup(null, 0);
this.messagesElement.insertBefore(this.topGroup.element, this.promptElement);
@@ -104,7 +104,7 @@ WebInspector.ConsoleView = function(drawer)
WebInspector.ConsoleView.prototype = {
_settingsLoaded: function()
{
- this.prompt.history = WebInspector.settings.consoleHistory;
+ this.prompt.history = WebInspector.applicationSettings.consoleHistory;
},
_updateFilter: function(e)
@@ -536,7 +536,7 @@ WebInspector.ConsoleView.prototype = {
self.prompt.historyOffset = 0;
self.prompt.text = "";
- WebInspector.settings.consoleHistory = self.prompt.history.slice(-30);
+ WebInspector.applicationSettings.consoleHistory = self.prompt.history.slice(-30);
self.addMessage(new WebInspector.ConsoleCommandResult(result, exception, commandMessage));
}
diff --git a/WebCore/inspector/front-end/ElementsPanel.js b/WebCore/inspector/front-end/ElementsPanel.js
index c853440..55ba82d 100644
--- a/WebCore/inspector/front-end/ElementsPanel.js
+++ b/WebCore/inspector/front-end/ElementsPanel.js
@@ -240,7 +240,7 @@ WebInspector.ElementsPanel.prototype = {
this._currentSearchResultIndex = 0;
this._searchResults = [];
- InjectedScriptAccess.getDefault().searchCanceled(function() {});
+ InspectorBackend.searchCanceled();
},
performSearch: function(query)
@@ -256,7 +256,7 @@ WebInspector.ElementsPanel.prototype = {
this._matchesCountUpdateTimeout = null;
this._searchQuery = query;
- InjectedScriptAccess.getDefault().performSearch(whitespaceTrimmedQuery, false, function() {});
+ InspectorBackend.performSearch(whitespaceTrimmedQuery);
},
searchingForNodeWasEnabled: function()
@@ -288,12 +288,11 @@ WebInspector.ElementsPanel.prototype = {
addNodesToSearchResult: function(nodeIds)
{
- if (!nodeIds)
+ if (!nodeIds.length)
return;
- var nodeIdsArray = nodeIds.split(",");
- for (var i = 0; i < nodeIdsArray.length; ++i) {
- var nodeId = nodeIdsArray[i];
+ for (var i = 0; i < nodeIds.length; ++i) {
+ var nodeId = nodeIds[i];
var node = WebInspector.domAgent.nodeForId(nodeId);
if (!node)
continue;
diff --git a/WebCore/inspector/front-end/EventListenersSidebarPane.js b/WebCore/inspector/front-end/EventListenersSidebarPane.js
index 045d29b..6798845 100644
--- a/WebCore/inspector/front-end/EventListenersSidebarPane.js
+++ b/WebCore/inspector/front-end/EventListenersSidebarPane.js
@@ -46,7 +46,7 @@ WebInspector.EventListenersSidebarPane = function()
option.label = WebInspector.UIString("Selected Node Only");
this.settingsSelectElement.appendChild(option);
- WebInspector.settings.addEventListener("loaded", this._settingsLoaded, this);
+ WebInspector.applicationSettings.addEventListener("loaded", this._settingsLoaded, this);
this.settingsSelectElement.addEventListener("click", function(event) { event.stopPropagation() }, false);
this.settingsSelectElement.addEventListener("change", this._changeSetting.bind(this), false);
@@ -56,7 +56,7 @@ WebInspector.EventListenersSidebarPane = function()
WebInspector.EventListenersSidebarPane.prototype = {
_settingsLoaded: function()
{
- var filter = WebInspector.settings.eventListenersFilter;
+ var filter = WebInspector.applicationSettings.eventListenersFilter;
if (filter === "all")
this.settingsSelectElement[0].selected = true;
if (filter === "selected")
@@ -112,7 +112,7 @@ WebInspector.EventListenersSidebarPane.prototype = {
_changeSetting: function(event)
{
var selectedOption = this.settingsSelectElement[this.settingsSelectElement.selectedIndex];
- WebInspector.settings.eventListenersFilter = selectedOption.value;
+ WebInspector.applicationSettings.eventListenersFilter = selectedOption.value;
for (var i = 0; i < this.sections.length; ++i)
this.sections[i].update();
@@ -142,7 +142,7 @@ WebInspector.EventListenersSection.prototype = {
{
// A Filtered Array simplifies when to create connectors
var filteredEventListeners = this.eventListeners;
- if (WebInspector.settings.eventListenersFilter === "selected") {
+ if (WebInspector.applicationSettings.eventListenersFilter === "selected") {
filteredEventListeners = [];
for (var i = 0; i < this.eventListeners.length; ++i) {
var eventListener = this.eventListeners[i];
diff --git a/WebCore/inspector/front-end/HAREntry.js b/WebCore/inspector/front-end/HAREntry.js
new file mode 100644
index 0000000..c06e64f
--- /dev/null
+++ b/WebCore/inspector/front-end/HAREntry.js
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// See http://groups.google.com/group/http-archive-specification/web/har-1-2-spec
+// for HAR specification.
+
+WebInspector.HAREntry = function(resource)
+{
+ this._resource = resource;
+}
+
+WebInspector.HAREntry.prototype = {
+ build: function()
+ {
+ return {
+ pageref: this._resource.documentURL,
+ startedDateTime: new Date(this._resource.startTime * 1000),
+ time: this._toMilliseconds(this._resource.duration),
+ request: this._buildRequest(),
+ response: this._buildResponse(),
+ // cache: {...}, -- Not supproted yet.
+ timings: this._buildTimings()
+ };
+ },
+
+ _buildRequest: function()
+ {
+ var res = {
+ method: this._resource.requestMethod,
+ url: this._resource.url,
+ // httpVersion: "HTTP/1.1" -- Not available.
+ // cookies: [] -- Not available.
+ headers: this._buildHeaders(this._resource.requestHeaders),
+ headersSize: -1, // Not available.
+ bodySize: -1 // Not available.
+ };
+ if (this._resource.queryParameters)
+ res.queryString = this._buildParameters(this._resource.queryParameters);
+ if (this._resource.requestFormData)
+ res.postData = this._buildPostData();
+ return res;
+ },
+
+ _buildResponse: function()
+ {
+ return {
+ status: this._resource.statusCode,
+ statusText: this._resource.statusText,
+ // "httpVersion": "HTTP/1.1" -- Not available.
+ // "cookies": [], -- Not available.
+ headers: this._buildHeaders(this._resource.responseHeaders),
+ content: this._buildContent(),
+ redirectURL: this._resource.responseHeaderValue("Location") || "",
+ headersSize: -1, // Not available.
+ bodySize: this._resource.resourceSize
+ };
+ },
+
+ _buildContent: function()
+ {
+ return {
+ size: this._resource.resourceSize,
+ // compression: 0, -- Not available.
+ mimeType: this._resource.mimeType,
+ // text: -- Not available.
+ };
+ },
+
+ _buildTimings: function()
+ {
+ return {
+ blocked: -1, // Not available.
+ dns: -1, // Not available.
+ connect: -1, // Not available.
+ send: -1, // Not available.
+ wait: this._toMilliseconds(this._resource.latency),
+ receive: this._toMilliseconds(this._resource.receiveDuration),
+ ssl: -1 // Not available.
+ };
+ },
+
+ _buildHeaders: function(headers)
+ {
+ var result = [];
+ for (var name in headers)
+ result.push({ name: name, value: headers[name] });
+ return result;
+ },
+
+ _buildPostData: function()
+ {
+ return {
+ mimeType: this._resource.requestHeaderValue("Content-Type"),
+ params: this._buildParameters(this._resource.formParameters),
+ text: this._resource.requestFormData
+ };
+ },
+
+ _buildParameters: function(parameters)
+ {
+ return parameters.slice();
+ },
+
+ _toMilliseconds: function(time)
+ {
+ return time === -1 ? -1 : Math.round(time * 1000);
+ }
+};
diff --git a/WebCore/inspector/front-end/InjectedScript.js b/WebCore/inspector/front-end/InjectedScript.js
index e3be6a3..e62a916 100644
--- a/WebCore/inspector/front-end/InjectedScript.js
+++ b/WebCore/inspector/front-end/InjectedScript.js
@@ -83,8 +83,6 @@ InjectedScript.releaseWrapperObjectGroup = function(objectGroupName) {
// Called from within InspectorController on the 'inspected page' side.
InjectedScript.reset = function()
{
- InjectedScript._searchResults = [];
- InjectedScript._includedInSearchResultsPropertyName = "__includedInInspectorSearchResults";
}
InjectedScript.reset();
@@ -211,7 +209,7 @@ InjectedScript.setPropertyValue = function(objectProxy, propertyName, expression
return true;
} catch(e) {
try {
- var result = inspectedWindow.eval("\"" + InjectedScript._escapeCharacters(expression, "\"") + "\"");
+ var result = inspectedWindow.eval("\"" + expression.replace(/"/g, "\\\"") + "\"");
object[propertyName] = result;
return true;
} catch(e) {
@@ -355,247 +353,6 @@ InjectedScript.getNodeId = function(node)
return InjectedScriptHost.pushNodePathToFrontend(node, false, false);
}
-InjectedScript.performSearch = function(whitespaceTrimmedQuery, runSynchronously)
-{
- // FIXME: Few things are missing here:
- // 1) Search works with node granularity - number of matches within node is not calculated.
- // 2) Search does not work outside main documents' domain - we need to use specific InjectedScript instances
- // for other domains.
- // 3) There is no need to push all search results to the front-end at a time, pushing next / previous result
- // is sufficient.
- var tagNameQuery = whitespaceTrimmedQuery;
- var attributeNameQuery = whitespaceTrimmedQuery;
- var startTagFound = (tagNameQuery.indexOf("<") === 0);
- var endTagFound = (tagNameQuery.lastIndexOf(">") === (tagNameQuery.length - 1));
-
- if (startTagFound || endTagFound) {
- var tagNameQueryLength = tagNameQuery.length;
- tagNameQuery = tagNameQuery.substring((startTagFound ? 1 : 0), (endTagFound ? (tagNameQueryLength - 1) : tagNameQueryLength));
- }
-
- // Check the tagNameQuery is it is a possibly valid tag name.
- if (!/^[a-zA-Z0-9\-_:]+$/.test(tagNameQuery))
- tagNameQuery = null;
-
- // Check the attributeNameQuery is it is a possibly valid tag name.
- if (!/^[a-zA-Z0-9\-_:]+$/.test(attributeNameQuery))
- attributeNameQuery = null;
-
- const escapedQuery = InjectedScript._escapeCharacters(whitespaceTrimmedQuery, "'");
- const escapedTagNameQuery = (tagNameQuery ? InjectedScript._escapeCharacters(tagNameQuery, "'") : null);
- const escapedWhitespaceTrimmedQuery = InjectedScript._escapeCharacters(whitespaceTrimmedQuery, "'");
- const searchResultsProperty = InjectedScript._includedInSearchResultsPropertyName;
-
- function addNodesToResults(nodes, length, getItem)
- {
- if (!length)
- return;
-
- var nodeIds = [];
- for (var i = 0; i < length; ++i) {
- var node = getItem.call(nodes, i);
- // Skip this node if it already has the property.
- if (searchResultsProperty in node)
- continue;
-
- if (!InjectedScript._searchResults.length) {
- InjectedScript._currentSearchResultIndex = 0;
- }
-
- node[searchResultsProperty] = true;
- InjectedScript._searchResults.push(node);
- var nodeId = InjectedScriptHost.pushNodePathToFrontend(node, false, false);
- nodeIds.push(nodeId);
- }
- InjectedScriptHost.addNodesToSearchResult(nodeIds.join(","));
- }
-
- function matchExactItems(doc)
- {
- matchExactId.call(this, doc);
- matchExactClassNames.call(this, doc);
- matchExactTagNames.call(this, doc);
- matchExactAttributeNames.call(this, doc);
- }
-
- function matchExactId(doc)
- {
- const result = doc.__proto__.getElementById.call(doc, whitespaceTrimmedQuery);
- addNodesToResults.call(this, result, (result ? 1 : 0), function() { return this });
- }
-
- function matchExactClassNames(doc)
- {
- const result = doc.__proto__.getElementsByClassName.call(doc, whitespaceTrimmedQuery);
- addNodesToResults.call(this, result, result.length, result.item);
- }
-
- function matchExactTagNames(doc)
- {
- if (!tagNameQuery)
- return;
- const result = doc.__proto__.getElementsByTagName.call(doc, tagNameQuery);
- addNodesToResults.call(this, result, result.length, result.item);
- }
-
- function matchExactAttributeNames(doc)
- {
- if (!attributeNameQuery)
- return;
- const result = doc.__proto__.querySelectorAll.call(doc, "[" + attributeNameQuery + "]");
- addNodesToResults.call(this, result, result.length, result.item);
- }
-
- function matchPartialTagNames(doc)
- {
- if (!tagNameQuery)
- return;
- const result = doc.__proto__.evaluate.call(doc, "//*[contains(name(), '" + escapedTagNameQuery + "')]", doc, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE);
- addNodesToResults.call(this, result, result.snapshotLength, result.snapshotItem);
- }
-
- function matchStartOfTagNames(doc)
- {
- if (!tagNameQuery)
- return;
- const result = doc.__proto__.evaluate.call(doc, "//*[starts-with(name(), '" + escapedTagNameQuery + "')]", doc, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE);
- addNodesToResults.call(this, result, result.snapshotLength, result.snapshotItem);
- }
-
- function matchPartialTagNamesAndAttributeValues(doc)
- {
- if (!tagNameQuery) {
- matchPartialAttributeValues.call(this, doc);
- return;
- }
-
- const result = doc.__proto__.evaluate.call(doc, "//*[contains(name(), '" + escapedTagNameQuery + "') or contains(@*, '" + escapedQuery + "')]", doc, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE);
- addNodesToResults.call(this, result, result.snapshotLength, result.snapshotItem);
- }
-
- function matchPartialAttributeValues(doc)
- {
- const result = doc.__proto__.evaluate.call(doc, "//*[contains(@*, '" + escapedQuery + "')]", doc, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE);
- addNodesToResults.call(this, result, result.snapshotLength, result.snapshotItem);
- }
-
- function matchStyleSelector(doc)
- {
- const result = doc.__proto__.querySelectorAll.call(doc, whitespaceTrimmedQuery);
- addNodesToResults.call(this, result, result.length, result.item);
- }
-
- function matchPlainText(doc)
- {
- const result = doc.__proto__.evaluate.call(doc, "//text()[contains(., '" + escapedQuery + "')] | //comment()[contains(., '" + escapedQuery + "')]", doc, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE);
- addNodesToResults.call(this, result, result.snapshotLength, result.snapshotItem);
- }
-
- function matchXPathQuery(doc)
- {
- const result = doc.__proto__.evaluate.call(doc, whitespaceTrimmedQuery, doc, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE);
- addNodesToResults.call(this, result, result.snapshotLength, result.snapshotItem);
- }
-
- function finishedSearching()
- {
- // Remove the searchResultsProperty now that the search is finished.
- for (var i = 0; i < InjectedScript._searchResults.length; ++i)
- delete InjectedScript._searchResults[i][searchResultsProperty];
- }
-
- const mainFrameDocument = inspectedWindow.document;
- const searchDocuments = [mainFrameDocument];
- var searchFunctions;
- if (tagNameQuery && startTagFound && endTagFound)
- searchFunctions = [matchExactTagNames, matchPlainText];
- else if (tagNameQuery && startTagFound)
- searchFunctions = [matchStartOfTagNames, matchPlainText];
- else if (tagNameQuery && endTagFound) {
- // FIXME: we should have a matchEndOfTagNames search function if endTagFound is true but not startTagFound.
- // This requires ends-with() support in XPath, WebKit only supports starts-with() and contains().
- searchFunctions = [matchPartialTagNames, matchPlainText];
- } else if (whitespaceTrimmedQuery === "//*" || whitespaceTrimmedQuery === "*") {
- // These queries will match every node. Matching everything isn't useful and can be slow for large pages,
- // so limit the search functions list to plain text and attribute matching.
- searchFunctions = [matchPartialAttributeValues, matchPlainText];
- } else
- searchFunctions = [matchExactItems, matchStyleSelector, matchPartialTagNamesAndAttributeValues, matchPlainText, matchXPathQuery];
-
- // Find all frames, iframes and object elements to search their documents.
- const subdocumentResult = mainFrameDocument.querySelectorAll("iframe, frame, object");
-
- for (var i = 0; i < subdocumentResult.length; ++i) {
- var element = subdocumentResult.item(i);
- if (element.contentDocument)
- searchDocuments.push(element.contentDocument);
- }
-
- const panel = InjectedScript;
- var documentIndex = 0;
- var searchFunctionIndex = 0;
- var chunkIntervalIdentifier = null;
-
- // Split up the work into chunks so we don't block the UI thread while processing.
-
- function processChunk()
- {
- var searchDocument = searchDocuments[documentIndex];
- var searchFunction = searchFunctions[searchFunctionIndex];
-
- if (++searchFunctionIndex > searchFunctions.length) {
- searchFunction = searchFunctions[0];
- searchFunctionIndex = 0;
-
- if (++documentIndex > searchDocuments.length) {
- if (panel._currentSearchChunkIntervalIdentifier === chunkIntervalIdentifier)
- delete panel._currentSearchChunkIntervalIdentifier;
- clearInterval(chunkIntervalIdentifier);
- finishedSearching.call(panel);
- return false;
- }
-
- searchDocument = searchDocuments[documentIndex];
- }
-
- try {
- searchFunction.call(panel, searchDocument);
- } catch(err) {
- // ignore any exceptions. the query might be malformed, but we allow that.
- }
- return true;
- }
-
- if (runSynchronously)
- while (processChunk()) {}
- else {
- processChunk();
- chunkIntervalIdentifier = setInterval(processChunk, 25);
- InjectedScript._currentSearchChunkIntervalIdentifier = chunkIntervalIdentifier;
- }
- return true;
-}
-
-InjectedScript.searchCanceled = function()
-{
- if (InjectedScript._searchResults) {
- const searchResultsProperty = InjectedScript._includedInSearchResultsPropertyName;
- for (var i = 0; i < this._searchResults.length; ++i) {
- var node = this._searchResults[i];
-
- // Remove the searchResultsProperty since there might be an unfinished search.
- delete node[searchResultsProperty];
- }
- }
-
- if (InjectedScript._currentSearchChunkIntervalIdentifier) {
- clearInterval(InjectedScript._currentSearchChunkIntervalIdentifier);
- delete InjectedScript._currentSearchChunkIntervalIdentifier;
- }
- InjectedScript._searchResults = [];
- return true;
-}
-
InjectedScript.openInInspectedWindow = function(url)
{
// Don't call window.open on wrapper - popup blocker mutes it.
@@ -1017,38 +774,15 @@ InjectedScript._className = function(obj)
// Both of the methods below result in "Object" names on the foreign engine bindings.
// I gave up and am using a check below to distinguish between the egine bingings.
- if (typeof Document === "object") {
- // JSC
+ if (jsEngine == "JSC") {
var str = inspectedWindow.Object ? inspectedWindow.Object.prototype.toString.call(obj) : InjectedScript._toString(obj);
return str.replace(/^\[object (.*)\]$/i, "$1");
+ } else {
+ // V8
+ if (typeof obj !== "object")
+ return "null";
+ return obj.constructor.name || "Object";
}
- // V8
- if (typeof obj !== "object")
- return "null";
- return obj.constructor.name;
-}
-
-InjectedScript._escapeCharacters = function(str, chars)
-{
- var foundChar = false;
- for (var i = 0; i < chars.length; ++i) {
- if (str.indexOf(chars.charAt(i)) !== -1) {
- foundChar = true;
- break;
- }
- }
-
- if (!foundChar)
- return str;
-
- var result = "";
- for (var i = 0; i < str.length; ++i) {
- if (chars.indexOf(str.charAt(i)) !== -1)
- result += "\\";
- result += str.charAt(i);
- }
-
- return result;
}
return InjectedScript;
diff --git a/WebCore/inspector/front-end/InjectedScriptAccess.js b/WebCore/inspector/front-end/InjectedScriptAccess.js
index 2558267..c388213 100644
--- a/WebCore/inspector/front-end/InjectedScriptAccess.js
+++ b/WebCore/inspector/front-end/InjectedScriptAccess.js
@@ -71,29 +71,18 @@ InjectedScriptAccess._installHandler = function(methodName, async)
// - Make sure last parameter of all the InjectedSriptAccess.* calls is a callback function.
// We keep these sorted.
InjectedScriptAccess._installHandler("addInspectedNode");
-InjectedScriptAccess._installHandler("addStyleSelector");
-InjectedScriptAccess._installHandler("applyStyleRuleText");
-InjectedScriptAccess._installHandler("applyStyleText");
InjectedScriptAccess._installHandler("clearConsoleMessages");
InjectedScriptAccess._installHandler("evaluate");
InjectedScriptAccess._installHandler("evaluateInCallFrame");
InjectedScriptAccess._installHandler("getCompletions");
-InjectedScriptAccess._installHandler("getComputedStyle");
-InjectedScriptAccess._installHandler("getInlineStyle");
InjectedScriptAccess._installHandler("getNodePropertyValue");
InjectedScriptAccess._installHandler("getProperties");
InjectedScriptAccess._installHandler("getPrototypes");
-InjectedScriptAccess._installHandler("getStyles");
InjectedScriptAccess._installHandler("openInInspectedWindow");
-InjectedScriptAccess._installHandler("performSearch");
InjectedScriptAccess._installHandler("pushNodeToFrontend");
InjectedScriptAccess._installHandler("nodeByPath");
-InjectedScriptAccess._installHandler("searchCanceled");
InjectedScriptAccess._installHandler("setOuterHTML");
InjectedScriptAccess._installHandler("setPropertyValue");
-InjectedScriptAccess._installHandler("setStyleProperty");
-InjectedScriptAccess._installHandler("setStyleText");
-InjectedScriptAccess._installHandler("toggleStyleEnabled");
InjectedScriptAccess._installHandler("evaluateOnSelf");
// Some methods can't run synchronously even on the injected script side (such as DB transactions).
diff --git a/WebCore/inspector/front-end/InspectorBackendStub.js b/WebCore/inspector/front-end/InspectorBackendStub.js
index 4670af1..492bf87 100644
--- a/WebCore/inspector/front-end/InspectorBackendStub.js
+++ b/WebCore/inspector/front-end/InspectorBackendStub.js
@@ -185,6 +185,16 @@ WebInspector.InspectorBackendStub.prototype = {
WebInspector.updatePauseOnExceptionsState(value);
},
+ editScriptSource: function()
+ {
+ WebInspector.didEditScriptSource(callId, false);
+ },
+
+ getScriptSource: function(callId, sourceID)
+ {
+ WebInspector.didGetScriptSource(callId, null);
+ },
+
resumeDebugger: function()
{
},
@@ -237,7 +247,11 @@ WebInspector.InspectorBackendStub.prototype = {
{
},
- saveFrontendSettings: function()
+ saveApplicationSettings: function()
+ {
+ },
+
+ saveSessionSettings: function()
{
},
@@ -259,6 +273,14 @@ WebInspector.InspectorBackendStub.prototype = {
removeAllScriptsToEvaluateOnLoad: function()
{
+ },
+
+ performSearch: function()
+ {
+ },
+
+ searchCanceled: function()
+ {
}
}
diff --git a/WebCore/inspector/front-end/KeyboardShortcut.js b/WebCore/inspector/front-end/KeyboardShortcut.js
index 4e7c88a..2bcf3d1 100644
--- a/WebCore/inspector/front-end/KeyboardShortcut.js
+++ b/WebCore/inspector/front-end/KeyboardShortcut.js
@@ -50,14 +50,14 @@ WebInspector.KeyboardShortcut.Modifiers = {
WebInspector.KeyboardShortcut.Keys = {
Backspace: { code: 8, name: "\u21a4" },
- Tab: { code: 9, name: "<Tab>" },
- Enter: { code: 13, name: "<Enter>" },
- Esc: { code: 27, name: "<Esc>" },
+ Tab: { code: 9, name: { mac: "\u21e5", other: "<Tab>" } },
+ Enter: { code: 13, name: { mac: "\u21a9", other: "<Enter>" } },
+ Esc: { code: 27, name: { mac: "\u238b", other: "<Esc>" } },
Space: { code: 32, name: "<Space>" },
- PageUp: { code: 33, name: "<PageUp>" }, // also NUM_NORTH_EAST
- PageDown: { code: 34, name: "<PageDown>" }, // also NUM_SOUTH_EAST
- End: { code: 35, name: "<End>" }, // also NUM_SOUTH_WEST
- Home: { code: 36, name: "<Home>" }, // also NUM_NORTH_WEST
+ PageUp: { code: 33, name: { mac: "\u21de", other: "<PageUp>" } }, // also NUM_NORTH_EAST
+ PageDown: { code: 34, name: { mac: "\u21df", other: "<PageDown>" } }, // also NUM_SOUTH_EAST
+ End: { code: 35, name: { mac: "\u2197", other: "<End>" } }, // also NUM_SOUTH_WEST
+ Home: { code: 36, name: { mac: "\u2196", other: "<Home>" } }, // also NUM_NORTH_WEST
Left: { code: 37, name: "\u2190" }, // also NUM_WEST
Up: { code: 38, name: "\u2191" }, // also NUM_NORTH
Right: { code: 39, name: "\u2192" }, // also NUM_EAST
@@ -130,7 +130,16 @@ WebInspector.KeyboardShortcut.makeDescriptor = function(key, optModifiers)
WebInspector.KeyboardShortcut.shortcutToString = function(key, modifiers)
{
- return WebInspector.KeyboardShortcut._modifiersToString(modifiers) + (typeof key === "string" ? key.toUpperCase() : key.name);
+ return WebInspector.KeyboardShortcut._modifiersToString(modifiers) + WebInspector.KeyboardShortcut._keyName(key);
+}
+
+WebInspector.KeyboardShortcut._keyName = function(key)
+{
+ if (typeof key === "string")
+ return key.toUpperCase();
+ if (typeof key.name === "string")
+ return key.name;
+ return key.name[WebInspector.platform] || key.name.other;
}
WebInspector.KeyboardShortcut._makeKeyFromCodeAndModifiers = function(keyCode, modifiers)
@@ -143,11 +152,12 @@ WebInspector.KeyboardShortcut._modifiersToString = function(modifiers)
const cmdKey = "\u2318";
const optKey = "\u2325";
const shiftKey = "\u21e7";
+ const ctrlKey = "\u2303";
var isMac = WebInspector.isMac();
var res = "";
if (modifiers & WebInspector.KeyboardShortcut.Modifiers.Ctrl)
- res += "<Ctrl> + ";
+ res += isMac ? ctrlKey : "<Ctrl> + ";
if (modifiers & WebInspector.KeyboardShortcut.Modifiers.Alt)
res += isMac ? optKey : "<Alt> + ";
if (modifiers & WebInspector.KeyboardShortcut.Modifiers.Shift)
diff --git a/WebCore/inspector/front-end/Resource.js b/WebCore/inspector/front-end/Resource.js
index 279e3af..2ae23a0 100644
--- a/WebCore/inspector/front-end/Resource.js
+++ b/WebCore/inspector/front-end/Resource.js
@@ -33,7 +33,6 @@ WebInspector.Resource = function(identifier, url)
this._startTime = -1;
this._endTime = -1;
this._requestMethod = "";
- this._requestFormData = "";
this._category = WebInspector.resourceCategories.other;
}
@@ -88,7 +87,7 @@ WebInspector.Resource.prototype = {
var oldURL = this._url;
this._url = x;
-
+ delete this._parsedQueryParameters;
// FIXME: We should make the WebInspector object listen for the "url changed" event.
// Then resourceURLChanged can be removed.
WebInspector.resourceURLChanged(this, oldURL);
@@ -215,6 +214,13 @@ WebInspector.Resource.prototype = {
return this._responseReceivedTime - this._startTime;
},
+ get receiveDuration()
+ {
+ if (this._endTime === -1 || this._responseReceivedTime === -1)
+ return -1;
+ return this._endTime - this._responseReceivedTime;
+ },
+
get resourceSize()
{
return this._resourceSize || 0;
@@ -384,6 +390,22 @@ WebInspector.Resource.prototype = {
return this._sortedRequestHeaders;
},
+ requestHeaderValue: function(headerName)
+ {
+ return this._headerValue(this.requestHeaders, headerName);
+ },
+
+ get requestFormData()
+ {
+ return this._requestFormData;
+ },
+
+ set requestFormData(x)
+ {
+ this._requestFormData = x;
+ delete this._parsedFormParameters;
+ },
+
get responseHeaders()
{
if (this._responseHeaders === undefined)
@@ -415,6 +437,61 @@ WebInspector.Resource.prototype = {
return this._sortedResponseHeaders;
},
+ responseHeaderValue: function(headerName)
+ {
+ return this._headerValue(this.responseHeaders, headerName);
+ },
+
+ get queryParameters()
+ {
+ if (this._parsedQueryParameters)
+ return this._parsedQueryParameters;
+ var queryString = this.url.split("?", 2)[1];
+ if (!queryString)
+ return;
+ this._parsedQueryParameters = this._parseParameters(queryString);
+ return this._parsedQueryParameters;
+ },
+
+ get formParameters()
+ {
+ if (this._parsedFormParameters)
+ return this._parsedFormParameters;
+ if (!this.requestFormData)
+ return;
+ var requestContentType = this.requestHeaderValue("Content-Type");
+ if (!requestContentType || !requestContentType.match(/^application\/x-www-form-urlencoded\s*(;.*)?$/i))
+ return;
+ this._parsedFormParameters = this._parseParameters(this.requestFormData);
+ return this._parsedFormParameters;
+ },
+
+ _parseParameters: function(queryString)
+ {
+ function parseNameValue(pair)
+ {
+ var parameter = {};
+ var splitPair = pair.split("=", 2);
+
+ parameter.name = splitPair[0];
+ if (splitPair.length === 1)
+ parameter.value = "";
+ else
+ parameter.value = splitPair[1];
+ return parameter;
+ }
+ return queryString.split("&").map(parseNameValue);
+ },
+
+ _headerValue: function(headers, headerName)
+ {
+ headerName = headerName.toLowerCase();
+ for (var header in headers) {
+ if (header.toLowerCase() === headerName)
+ return headers[header];
+ }
+ },
+
get scripts()
{
if (!("_scripts" in this))
diff --git a/WebCore/inspector/front-end/ResourceView.js b/WebCore/inspector/front-end/ResourceView.js
index ffcb9b9..bfd1576 100644
--- a/WebCore/inspector/front-end/ResourceView.js
+++ b/WebCore/inspector/front-end/ResourceView.js
@@ -143,7 +143,7 @@ WebInspector.ResourceView.prototype = {
_selectTab: function()
{
if (this._headersVisible) {
- if (!this.hasContentTab() || WebInspector.settings.resourceViewTab === "headers")
+ if (!this.hasContentTab() || WebInspector.applicationSettings.resourceViewTab === "headers")
this._selectHeadersTab();
else
this.selectContentTab();
@@ -154,14 +154,14 @@ WebInspector.ResourceView.prototype = {
_selectHeadersTab: function(updatePrefs)
{
if (updatePrefs)
- WebInspector.settings.resourceViewTab = "headers";
+ WebInspector.applicationSettings.resourceViewTab = "headers";
this.tabbedPane.selectTabById("headers");
},
selectContentTab: function(updatePrefs)
{
if (updatePrefs)
- WebInspector.settings.resourceViewTab = "content";
+ WebInspector.applicationSettings.resourceViewTab = "content";
this._innerSelectContentTab();
},
@@ -187,17 +187,10 @@ WebInspector.ResourceView.prototype = {
_refreshQueryString: function()
{
- var url = this.resource.url;
- var hasQueryString = url.indexOf("?") >= 0;
-
- if (!hasQueryString) {
- this.queryStringTreeElement.hidden = true;
- return;
- }
-
- this.queryStringTreeElement.hidden = false;
- var parmString = url.split("?", 2)[1];
- this._refreshParms(WebInspector.UIString("Query String Parameters"), parmString, this.queryStringTreeElement);
+ var queryParameters = this.resource.queryParameters;
+ this.queryStringTreeElement.hidden = !queryParameters;
+ if (queryParameters)
+ this._refreshParms(WebInspector.UIString("Query String Parameters"), queryParameters, this.queryStringTreeElement);
},
_refreshFormData: function()
@@ -205,21 +198,17 @@ WebInspector.ResourceView.prototype = {
this.formDataTreeElement.hidden = true;
this.requestPayloadTreeElement.hidden = true;
- var isFormData = this.resource.requestFormData;
- if (!isFormData)
+ var formData = this.resource.requestFormData;
+ if (!formData)
return;
- var isFormEncoded = false;
- var requestContentType = this._getHeaderValue(this.resource.requestHeaders, "Content-Type");
- if (requestContentType && requestContentType.match(/^application\/x-www-form-urlencoded\s*(;.*)?$/i))
- isFormEncoded = true;
-
- if (isFormEncoded) {
+ var formParameters = this.resource.formParameters;
+ if (formParameters) {
this.formDataTreeElement.hidden = false;
- this._refreshParms(WebInspector.UIString("Form Data"), this.resource.requestFormData, this.formDataTreeElement);
+ this._refreshParms(WebInspector.UIString("Form Data"), formParameters, this.formDataTreeElement);
} else {
this.requestPayloadTreeElement.hidden = false;
- this._refreshRequestPayload(this.resource.requestFormData);
+ this._refreshRequestPayload(formData);
}
},
@@ -233,24 +222,15 @@ WebInspector.ResourceView.prototype = {
this.requestPayloadTreeElement.appendChild(parmTreeElement);
},
- _refreshParms: function(title, parmString, parmsTreeElement)
+ _refreshParms: function(title, parms, parmsTreeElement)
{
- var parms = parmString.split("&");
- for (var i = 0; i < parms.length; ++i) {
- var parm = parms[i];
- parm = parm.split("=", 2);
- if (parm.length == 1)
- parm.push("");
- parms[i] = parm;
- }
-
parmsTreeElement.removeChildren();
parmsTreeElement.title = title + "<span class=\"header-count\">" + WebInspector.UIString(" (%d)", parms.length) + "</span>";
for (var i = 0; i < parms.length; ++i) {
- var key = parms[i][0];
- var value = parms[i][1];
+ var name = parms[i].name;
+ var value = parms[i].value;
var errorDecoding = false;
if (this._decodeRequestParameters) {
@@ -269,7 +249,7 @@ WebInspector.ResourceView.prototype = {
if (errorDecoding)
valueEscaped += " <span class=\"error-message\">" + WebInspector.UIString("(unable to decode value)").escapeHTML() + "</span>";
- var title = "<div class=\"header-name\">" + key.escapeHTML() + ":</div>";
+ var title = "<div class=\"header-name\">" + name.escapeHTML() + ":</div>";
title += "<div class=\"header-value source-code\">" + valueEscaped + "</div>";
var parmTreeElement = new TreeElement(title, null, false);
diff --git a/WebCore/inspector/front-end/ResourcesPanel.js b/WebCore/inspector/front-end/ResourcesPanel.js
index b2dfa15..ef6aa26 100644
--- a/WebCore/inspector/front-end/ResourcesPanel.js
+++ b/WebCore/inspector/front-end/ResourcesPanel.js
@@ -151,7 +151,7 @@ WebInspector.ResourcesPanel.prototype = {
{
this.largerResourcesButton = new WebInspector.StatusBarButton(WebInspector.UIString("Use small resource rows."), "resources-larger-resources-status-bar-item");
- WebInspector.settings.addEventListener("loaded", this._settingsLoaded, this);
+ WebInspector.applicationSettings.addEventListener("loaded", this._settingsLoaded, this);
this.largerResourcesButton.addEventListener("click", this._toggleLargerResources.bind(this), false);
this.sortingSelectElement = document.createElement("select");
this.sortingSelectElement.className = "status-bar-item";
@@ -160,9 +160,9 @@ WebInspector.ResourcesPanel.prototype = {
_settingsLoaded: function()
{
- this.largerResourcesButton.toggled = WebInspector.settings.resourcesLargeRows;
- if (!WebInspector.settings.resourcesLargeRows)
- this._setLargerResources(WebInspector.settings.resourcesLargeRows);
+ this.largerResourcesButton.toggled = WebInspector.applicationSettings.resourcesLargeRows;
+ if (!WebInspector.applicationSettings.resourcesLargeRows)
+ this._setLargerResources(WebInspector.applicationSettings.resourcesLargeRows);
},
get mainResourceLoadTime()
@@ -637,7 +637,7 @@ WebInspector.ResourcesPanel.prototype = {
if (!this.itemsTreeElement._childrenListNode)
return;
- WebInspector.settings.resourcesLargeRows = !WebInspector.settings.resourcesLargeRows;
+ WebInspector.applicationSettings.resourcesLargeRows = !WebInspector.applicationSettings.resourcesLargeRows;
this._setLargerResources(this.itemsTreeElement.smallChildren);
},
diff --git a/WebCore/inspector/front-end/Script.js b/WebCore/inspector/front-end/Script.js
index 79004f3..42d6850 100644
--- a/WebCore/inspector/front-end/Script.js
+++ b/WebCore/inspector/front-end/Script.js
@@ -23,7 +23,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-WebInspector.Script = function(sourceID, sourceURL, source, startingLine, errorLine, errorMessage)
+WebInspector.Script = function(sourceID, sourceURL, source, startingLine, errorLine, errorMessage, worldType)
{
this.sourceID = sourceID;
this.sourceURL = sourceURL;
@@ -31,6 +31,7 @@ WebInspector.Script = function(sourceID, sourceURL, source, startingLine, errorL
this.startingLine = startingLine;
this.errorLine = errorLine;
this.errorMessage = errorMessage;
+ this.worldType = worldType;
// if no URL, look for "//@ sourceURL=" decorator
// note that this sourceURL comment decorator is behavior that FireBug added
@@ -46,6 +47,16 @@ WebInspector.Script = function(sourceID, sourceURL, source, startingLine, errorL
}
}
+WebInspector.Script.WorldType = {
+ MAIN_WORLD: 0,
+ EXTENSIONS_WORLD: 1
+}
+
+WebInspector.Script.WorldType = {
+ MAIN_WORLD: 0,
+ EXTENSIONS_WORLD: 1
+}
+
WebInspector.Script.prototype = {
get linesCount()
{
diff --git a/WebCore/inspector/front-end/ScriptView.js b/WebCore/inspector/front-end/ScriptView.js
index 1a24211..fb0bb4b 100644
--- a/WebCore/inspector/front-end/ScriptView.js
+++ b/WebCore/inspector/front-end/ScriptView.js
@@ -34,7 +34,7 @@ WebInspector.ScriptView = function(script)
this._frameNeedsSetup = true;
this._sourceFrameSetup = false;
var canEditScripts = WebInspector.panels.scripts.canEditScripts();
- this.sourceFrame = new WebInspector.SourceFrame(this.element, this._addBreakpoint.bind(this), this._removeBreakpoint.bind(this), canEditScripts ? this._editLine.bind(this) : null);
+ this.sourceFrame = new WebInspector.SourceFrame(this.element, this._addBreakpoint.bind(this), this._removeBreakpoint.bind(this), canEditScripts ? this._editLine.bind(this) : null, this._continueToLine.bind(this));
}
WebInspector.ScriptView.prototype = {
@@ -50,12 +50,28 @@ WebInspector.ScriptView.prototype = {
{
if (!this._frameNeedsSetup)
return;
+ delete this._frameNeedsSetup;
this.attach();
+ if (this.script.source)
+ this._sourceFrameSetupFinished();
+ else {
+ var callbackId = WebInspector.Callback.wrap(this._didGetScriptSource.bind(this))
+ InspectorBackend.getScriptSource(callbackId, this.script.sourceID);
+ }
+ },
+
+ _didGetScriptSource: function(source)
+ {
+ this.script.source = source || WebInspector.UIString("<source is not available>");
+ this._sourceFrameSetupFinished();
+ },
+
+ _sourceFrameSetupFinished: function()
+ {
this.sourceFrame.setContent("text/javascript", this._prependWhitespace(this.script.source));
this._sourceFrameSetup = true;
- delete this._frameNeedsSetup;
},
_prependWhitespace: function(content) {
@@ -71,6 +87,13 @@ WebInspector.ScriptView.prototype = {
document.getElementById("script-resource-views").appendChild(this.element);
},
+ _continueToLine: function(line)
+ {
+ var scriptsPanel = WebInspector.panels.scripts;
+ if (scriptsPanel)
+ scriptsPanel.continueToLine(this.script.sourceID, line);
+ },
+
_addBreakpoint: function(line)
{
WebInspector.breakpointManager.addBreakpoint(this.script.sourceID, this.script.sourceURL, line, true, "");
@@ -99,10 +122,11 @@ WebInspector.ScriptView.prototype = {
showingFirstSearchResult: WebInspector.SourceView.prototype.showingFirstSearchResult,
showingLastSearchResult: WebInspector.SourceView.prototype.showingLastSearchResult,
_jumpToSearchResult: WebInspector.SourceView.prototype._jumpToSearchResult,
- _sourceFrameSetupFinished: WebInspector.SourceView.prototype._sourceFrameSetupFinished,
_removeBreakpoint: WebInspector.SourceView.prototype._removeBreakpoint,
_editLine: WebInspector.SourceView.prototype._editLine,
resize: WebInspector.SourceView.prototype.resize
}
WebInspector.ScriptView.prototype.__proto__ = WebInspector.View.prototype;
+
+WebInspector.didGetScriptSource = WebInspector.Callback.processCallback;
diff --git a/WebCore/inspector/front-end/ScriptsPanel.js b/WebCore/inspector/front-end/ScriptsPanel.js
index 755daff..4504d57 100644
--- a/WebCore/inspector/front-end/ScriptsPanel.js
+++ b/WebCore/inspector/front-end/ScriptsPanel.js
@@ -241,9 +241,9 @@ WebInspector.ScriptsPanel.prototype = {
return this.toggleBreakpointsButton.toggled;
},
- addScript: function(sourceID, sourceURL, source, startingLine, errorLine, errorMessage)
+ addScript: function(sourceID, sourceURL, source, startingLine, errorLine, errorMessage, scriptWorldType)
{
- var script = new WebInspector.Script(sourceID, sourceURL, source, startingLine, errorLine, errorMessage);
+ var script = new WebInspector.Script(sourceID, sourceURL, source, startingLine, errorLine, errorMessage, scriptWorldType);
this._sourceIDMap[sourceID] = script;
var resource = WebInspector.resourceURLMap[sourceURL];
@@ -264,6 +264,13 @@ WebInspector.ScriptsPanel.prototype = {
this._addScriptToFilesMenu(script);
},
+ continueToLine: function(sourceID, line)
+ {
+ WebInspector.breakpointManager.setOneTimeBreakpoint(sourceID, line);
+ if (this.paused)
+ this._togglePause();
+ },
+
_resourceLoadingFinished: function(e)
{
var resource = e.target;
@@ -334,10 +341,10 @@ WebInspector.ScriptsPanel.prototype = {
canEditScripts: function()
{
- return !!InspectorBackend.editScriptSource;
+ return Preferences.canEditScriptSource;
},
- editScriptSource: function(sourceID, newContent, line, linesCountToShift, callback)
+ editScriptSource: function(sourceID, newContent, line, linesCountToShift, commitEditingCallback, cancelEditingCallback)
{
if (!this.canEditScripts())
return;
@@ -347,12 +354,19 @@ WebInspector.ScriptsPanel.prototype = {
for (var i = 0; i < breakpoints.length; ++i)
WebInspector.breakpointManager.removeBreakpoint(breakpoints[i]);
- function mycallback(newBody)
+ function mycallback(success, newBodyOrErrorMessage, callFrames)
{
- callback(newBody);
+ if (success) {
+ commitEditingCallback(newBodyOrErrorMessage);
+ if (callFrames && callFrames.length)
+ this.debuggerPaused(callFrames);
+ } else {
+ cancelEditingCallback();
+ WebInspector.log(newBodyOrErrorMessage, WebInspector.ConsoleMessage.MessageLevel.Warning);
+ }
for (var i = 0; i < breakpoints.length; ++i) {
var breakpoint = breakpoints[i];
- if (breakpoint.line >= line)
+ if (success && breakpoint.line >= line)
breakpoint.line += linesCountToShift;
WebInspector.breakpointManager.addBreakpoint(breakpoint);
}
@@ -400,6 +414,7 @@ WebInspector.ScriptsPanel.prototype = {
debuggerPaused: function(callFrames)
{
+ WebInspector.breakpointManager.removeOneTimeBreakpoint();
this._paused = true;
this._waitingToPause = false;
this._stepping = false;
@@ -624,7 +639,7 @@ WebInspector.ScriptsPanel.prototype = {
var url = scriptOrResource.url || scriptOrResource.sourceURL;
if (url && !options.initialLoad)
- WebInspector.settings.lastViewedScriptFile = url;
+ WebInspector.applicationSettings.lastViewedScriptFile = url;
if (!options.fromBackForwardAction) {
var oldIndex = this._currentBackForwardIndex;
@@ -725,10 +740,13 @@ WebInspector.ScriptsPanel.prototype = {
else {
// if not first item, check to see if this was the last viewed
var url = option.representedObject.url || option.representedObject.sourceURL;
- var lastURL = WebInspector.settings.lastViewedScriptFile;
+ var lastURL = WebInspector.applicationSettings.lastViewedScriptFile;
if (url && url === lastURL)
this._showScriptOrResource(option.representedObject, {initialLoad: true});
}
+
+ if (script.worldType === WebInspector.Script.WorldType.EXTENSIONS_WORLD)
+ script.filesSelectOption.addStyleClass("extension-script");
},
_clearCurrentExecutionLine: function()
diff --git a/WebCore/inspector/front-end/Settings.js b/WebCore/inspector/front-end/Settings.js
index b9b5f75..c7fc5a9 100644
--- a/WebCore/inspector/front-end/Settings.js
+++ b/WebCore/inspector/front-end/Settings.js
@@ -30,6 +30,7 @@
var Preferences = {
+ canEditScriptSource: false,
maxInlineTextChildLength: 80,
minConsoleHeight: 75,
minSidebarWidth: 100,
@@ -44,16 +45,39 @@ var Preferences = {
auditsPanelEnabled: true
}
-WebInspector.populateFrontendSettings = function(settingsString)
+WebInspector.populateApplicationSettings = function(settingsString)
{
- WebInspector.settings._load(settingsString);
+ WebInspector.applicationSettings._load(settingsString);
+ WebInspector.applicationSettings._installSetting("eventListenersFilter", "event-listeners-filter", "all");
+ WebInspector.applicationSettings._installSetting("colorFormat", "color-format", "hex");
+ WebInspector.applicationSettings._installSetting("resourcesLargeRows", "resources-large-rows", true);
+ WebInspector.applicationSettings._installSetting("watchExpressions", "watch-expressions", []);
+ WebInspector.applicationSettings._installSetting("lastViewedScriptFile", "last-viewed-script-file");
+ WebInspector.applicationSettings._installSetting("showInheritedComputedStyleProperties", "show-inherited-computed-style-properties", false);
+ WebInspector.applicationSettings._installSetting("showUserAgentStyles", "show-user-agent-styles", true);
+ WebInspector.applicationSettings._installSetting("resourceViewTab", "resource-view-tab", "content");
+ WebInspector.applicationSettings._installSetting("consoleHistory", "console-history", []);
+ WebInspector.applicationSettings.dispatchEventToListeners("loaded");
}
-WebInspector.Settings = function()
+WebInspector.populateSessionSettings = function(settingsString)
{
+ WebInspector.sessionSettings._load(settingsString);
+ WebInspector.sessionSettings.dispatchEventToListeners("loaded");
+}
+
+WebInspector.Settings = function(sessionScope)
+{
+ this._sessionScope = sessionScope;
}
WebInspector.Settings.prototype = {
+ reset: function()
+ {
+ this._store = {};
+ this.dispatchEventToListeners("loaded");
+ },
+
_load: function(settingsString)
{
try {
@@ -62,17 +86,6 @@ WebInspector.Settings.prototype = {
// May fail;
this._store = {};
}
-
- this._installSetting("eventListenersFilter", "event-listeners-filter", "all");
- this._installSetting("colorFormat", "color-format", "hex");
- this._installSetting("resourcesLargeRows", "resources-large-rows", true);
- this._installSetting("watchExpressions", "watch-expressions", []);
- this._installSetting("lastViewedScriptFile", "last-viewed-script-file");
- this._installSetting("showInheritedComputedStyleProperties", "show-inherited-computed-style-properties", false);
- this._installSetting("showUserAgentStyles", "show-user-agent-styles", true);
- this._installSetting("resourceViewTab", "resource-view-tab", "content");
- this._installSetting("consoleHistory", "console-history", []);
- this.dispatchEventToListeners("loaded");
},
_installSetting: function(name, propertyName, defaultValue)
@@ -93,7 +106,11 @@ WebInspector.Settings.prototype = {
{
this._store[propertyName] = newValue;
try {
- InspectorBackend.saveFrontendSettings(JSON.stringify(this._store));
+ var store = JSON.stringify(this._store);
+ if (this._sessionScope)
+ InspectorBackend.saveSessionSettings(store);
+ else
+ InspectorBackend.saveApplicationSettings(store);
} catch (e) {
// May fail;
}
diff --git a/WebCore/inspector/front-end/SourceFrame.js b/WebCore/inspector/front-end/SourceFrame.js
index 5e529ae..f221086 100644
--- a/WebCore/inspector/front-end/SourceFrame.js
+++ b/WebCore/inspector/front-end/SourceFrame.js
@@ -28,7 +28,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-WebInspector.SourceFrame = function(parentElement, addBreakpointDelegate, removeBreakpointDelegate, editDelegate)
+WebInspector.SourceFrame = function(parentElement, addBreakpointDelegate, removeBreakpointDelegate, editDelegate, continueToHereDelegate)
{
this._parentElement = parentElement;
@@ -42,6 +42,7 @@ WebInspector.SourceFrame = function(parentElement, addBreakpointDelegate, remove
this._loaded = false;
+ this._continueToHereDelegate = continueToHereDelegate;
this._addBreakpointDelegate = addBreakpointDelegate;
this._removeBreakpointDelegate = removeBreakpointDelegate;
this._editDelegate = editDelegate;
@@ -409,9 +410,14 @@ WebInspector.SourceFrame.prototype = {
return;
var row = target.parentElement;
+ if (!WebInspector.panels.scripts)
+ return;
+
var lineNumber = row.lineNumber;
var contextMenu = new WebInspector.ContextMenu();
+ contextMenu.appendItem(WebInspector.UIString("Continue to Here"), this._continueToHereDelegate.bind(this, lineNumber + 1));
+
var breakpoint = this._textModel.getAttribute(lineNumber, "breakpoint");
if (!breakpoint) {
// This row doesn't have a breakpoint: We want to show Add Breakpoint and Add and Edit Breakpoint.
diff --git a/WebCore/inspector/front-end/SourceView.js b/WebCore/inspector/front-end/SourceView.js
index f01c241..e4d7fed 100644
--- a/WebCore/inspector/front-end/SourceView.js
+++ b/WebCore/inspector/front-end/SourceView.js
@@ -32,8 +32,8 @@ WebInspector.SourceView = function(resource)
this.element.addStyleClass("source");
- var canEditScripts = WebInspector.panels.scripts.canEditScripts() && resource.type === WebInspector.Resource.Type.Script;
- this.sourceFrame = new WebInspector.SourceFrame(this.contentElement, this._addBreakpoint.bind(this), this._removeBreakpoint.bind(this), canEditScripts ? this._editLine.bind(this) : null);
+ var canEditScripts = WebInspector.panels.scripts && WebInspector.panels.scripts.canEditScripts() && resource.type === WebInspector.Resource.Type.Script;
+ this.sourceFrame = new WebInspector.SourceFrame(this.contentElement, this._addBreakpoint.bind(this), this._removeBreakpoint.bind(this), canEditScripts ? this._editLine.bind(this) : null, this._continueToLine.bind(this));
resource.addEventListener("finished", this._resourceLoadingFinished, this);
this._frameNeedsSetup = true;
}
@@ -115,6 +115,15 @@ WebInspector.SourceView.prototype = {
this.resource.removeEventListener("finished", this._resourceLoadingFinished, this);
},
+ _continueToLine: function(line)
+ {
+ var scriptsPanel = WebInspector.panels.scripts;
+ if (scriptsPanel) {
+ var sourceID = this._sourceIDForLine(line);
+ scriptsPanel.continueToLine(sourceID, line);
+ }
+ },
+
_addBreakpoint: function(line)
{
var sourceID = this._sourceIDForLine(line);
@@ -126,7 +135,7 @@ WebInspector.SourceView.prototype = {
WebInspector.breakpointManager.removeBreakpoint(breakpoint);
},
- _editLine: function(line, newContent)
+ _editLine: function(line, newContent, cancelEditingCallback)
{
var lines = [];
var textModel = this.sourceFrame.textModel;
@@ -138,7 +147,7 @@ WebInspector.SourceView.prototype = {
}
var linesCountToShift = newContent.split("\n").length - 1;
- WebInspector.panels.scripts.editScriptSource(this._sourceIDForLine(line), lines.join("\n"), line, linesCountToShift, this._editLineComplete.bind(this));
+ WebInspector.panels.scripts.editScriptSource(this._sourceIDForLine(line), lines.join("\n"), line, linesCountToShift, this._editLineComplete.bind(this), cancelEditingCallback);
},
_editLineComplete: function(newBody)
@@ -202,7 +211,7 @@ WebInspector.SourceView.prototype = {
this.localContentElement = document.createElement("div");
this.localContentElement.className = "resource-view-content";
this.tabbedPane.appendTab("local", WebInspector.UIString("Local"), this.localContentElement, this.selectLocalContentTab.bind(this));
- this.localSourceFrame = new WebInspector.SourceFrame(this.localContentElement, this._addBreakpoint.bind(this), this._removeBreakpoint.bind(this));
+ this.localSourceFrame = new WebInspector.SourceFrame(this.localContentElement, this._addBreakpoint.bind(this), this._removeBreakpoint.bind(this), null, this._continueToLine.bind(this));
}
this.localSourceFrame.setContent(mimeType, content, "");
},
diff --git a/WebCore/inspector/front-end/StylesSidebarPane.js b/WebCore/inspector/front-end/StylesSidebarPane.js
index 35d25d4..18b7f0f 100644
--- a/WebCore/inspector/front-end/StylesSidebarPane.js
+++ b/WebCore/inspector/front-end/StylesSidebarPane.js
@@ -60,7 +60,7 @@ WebInspector.StylesSidebarPane = function(computedStylePane)
this.settingsSelectElement.addEventListener("click", function(event) { event.stopPropagation() }, false);
this.settingsSelectElement.addEventListener("change", this._changeSetting.bind(this), false);
- WebInspector.settings.addEventListener("loaded", this._settingsLoaded, this);
+ WebInspector.applicationSettings.addEventListener("loaded", this._settingsLoaded, this);
this.titleElement.appendChild(this.settingsSelectElement);
this._computedStylePane = computedStylePane;
@@ -96,7 +96,7 @@ WebInspector.StylesSidebarPane.PseudoIdNames = [
WebInspector.StylesSidebarPane.prototype = {
_settingsLoaded: function()
{
- var format = WebInspector.settings.colorFormat;
+ var format = WebInspector.applicationSettings.colorFormat;
if (format === "hex")
this.settingsSelectElement[0].selected = true;
if (format === "rgb")
@@ -133,22 +133,22 @@ WebInspector.StylesSidebarPane.prototype = {
return;
}
- function getStylesCallback(styles)
+ function stylesCallback(styles)
{
if (styles)
this._rebuildUpdate(node, styles);
}
- function getComputedStyleCallback(computedStyle)
+ function computedStyleCallback(computedStyle)
{
if (computedStyle)
this._refreshUpdate(node, computedStyle, editedSection);
};
if (refresh)
- InspectorBackend.getComputedStyle(WebInspector.Callback.wrap(getComputedStyleCallback.bind(this)), node.id);
+ WebInspector.cssModel.getComputedStyleAsync(node.id, computedStyleCallback.bind(this));
else
- InspectorBackend.getStyles(WebInspector.Callback.wrap(getStylesCallback.bind(this)), node.id, !WebInspector.settings.showUserAgentStyles);
+ WebInspector.cssModel.getStylesAsync(node.id, !WebInspector.applicationSettings.showUserAgentStyles, stylesCallback.bind(this));
},
_refreshUpdate: function(node, computedStyle, editedSection)
@@ -466,7 +466,7 @@ WebInspector.StylesSidebarPane.prototype = {
{
for (var i = 0; i < properties.length; ++i) {
var property = properties[i];
- // Does this style contain non-overriden inherited property?
+ // Does this style contain non-overridden inherited property?
if (property.name in WebInspector.StylesSidebarPane.InheritedProperties)
return true;
}
@@ -482,7 +482,7 @@ WebInspector.StylesSidebarPane.prototype = {
// Select the correct color format setting again, since it needs to be selected.
var selectedIndex = 0;
for (var i = 0; i < options.length; ++i) {
- if (options[i].value === WebInspector.settings.colorFormat) {
+ if (options[i].value === WebInspector.applicationSettings.colorFormat) {
selectedIndex = i;
break;
}
@@ -494,7 +494,7 @@ WebInspector.StylesSidebarPane.prototype = {
_changeColorFormat: function(event)
{
var selectedOption = this.settingsSelectElement[this.settingsSelectElement.selectedIndex];
- WebInspector.settings.colorFormat = selectedOption.value;
+ WebInspector.applicationSettings.colorFormat = selectedOption.value;
for (var pseudoId in this.sections) {
var sections = this.sections[pseudoId];
@@ -581,18 +581,18 @@ WebInspector.ComputedStyleSidebarPane = function()
function settingsLoaded()
{
- if (WebInspector.settings.showInheritedComputedStyleProperties) {
+ if (WebInspector.applicationSettings.showInheritedComputedStyleProperties) {
this.bodyElement.addStyleClass("show-inherited");
showInheritedCheckbox.checked = true;
}
}
- WebInspector.settings.addEventListener("loaded", settingsLoaded.bind(this));
+ WebInspector.applicationSettings.addEventListener("loaded", settingsLoaded.bind(this));
function showInheritedToggleFunction(event)
{
- WebInspector.settings.showInheritedComputedStyleProperties = showInheritedCheckbox.checked;
- if (WebInspector.settings.showInheritedComputedStyleProperties)
+ WebInspector.applicationSettings.showInheritedComputedStyleProperties = showInheritedCheckbox.checked;
+ if (WebInspector.applicationSettings.showInheritedComputedStyleProperties)
this.bodyElement.addStyleClass("show-inherited");
else
this.bodyElement.removeStyleClass("show-inherited");
@@ -600,7 +600,7 @@ WebInspector.ComputedStyleSidebarPane = function()
showInheritedCheckbox.addEventListener(showInheritedToggleFunction.bind(this));
}
-
+
WebInspector.ComputedStyleSidebarPane.prototype.__proto__ = WebInspector.SidebarPane.prototype;
WebInspector.StylePropertiesSection = function(styleRule, subtitle, computedStyle, usedProperties, editable, isInherited, isFirstSection)
@@ -882,14 +882,9 @@ WebInspector.StylePropertiesSection.prototype = {
return moveToNextIfNeeded.call(this);
var self = this;
- function callback(newRulePayload, doesAffectSelectedNode)
- {
- if (!newRulePayload) {
- // Invalid Syntax for a Selector
- moveToNextIfNeeded.call(self);
- return;
- }
+ function successCallback(newRule, doesAffectSelectedNode)
+ {
if (!doesAffectSelectedNode) {
self.noAffect = true;
self.element.addStyleClass("no-affect");
@@ -898,7 +893,6 @@ WebInspector.StylePropertiesSection.prototype = {
self.element.removeStyleClass("no-affect");
}
- var newRule = WebInspector.CSSStyleDeclaration.parseRule(newRulePayload);
self.rule = newRule;
self.styleRule = { section: self, style: newRule.style, selectorText: newRule.selectorText, parentStyleSheet: newRule.parentStyleSheet, rule: newRule };
@@ -912,7 +906,7 @@ WebInspector.StylePropertiesSection.prototype = {
moveToNextIfNeeded.call(self);
}
- InspectorBackend.setRuleSelector(WebInspector.Callback.wrap(callback), this.rule.id, newContent, this.pane.node.id);
+ WebInspector.cssModel.setRuleSelector(this.rule.id, newContent, this.pane.node.id, successCallback, moveToNextIfNeeded.bind(this));
},
editingSelectorCancelled: function()
@@ -939,17 +933,8 @@ WebInspector.BlankStylePropertiesSection.prototype = {
editingSelectorCommitted: function(element, newContent, oldContent, context)
{
var self = this;
- function callback(rule, doesSelectorAffectSelectedNode)
+ function successCallback(styleRule, doesSelectorAffectSelectedNode)
{
- if (!rule) {
- // Invalid Syntax for a Selector
- self.editingSelectorCancelled();
- return;
- }
-
- var styleRule = WebInspector.CSSStyleDeclaration.parseRule(rule);
- styleRule.rule = rule;
-
self.makeNormal(styleRule);
if (!doesSelectorAffectSelectedNode) {
@@ -963,7 +948,7 @@ WebInspector.BlankStylePropertiesSection.prototype = {
self.addNewBlankProperty().startEditing();
}
- InspectorBackend.addRule(WebInspector.Callback.wrap(callback), newContent, this.pane.node.id);
+ WebInspector.cssModel.addRule(this.pane.node.id, newContent, successCallback, this.editingSelectorCancelled.bind(this));
},
editingSelectorCancelled: function()
@@ -1137,9 +1122,9 @@ WebInspector.StylePropertyTreeElement.prototype = {
var format;
if (Preferences.showColorNicknames && color.nickname)
format = "nickname";
- else if (WebInspector.settings.colorFormat === "rgb")
+ else if (WebInspector.applicationSettings.colorFormat === "rgb")
format = (color.simple ? "rgb" : "rgba");
- else if (WebInspector.settings.colorFormat === "hsl")
+ else if (WebInspector.applicationSettings.colorFormat === "hsl")
format = (color.simple ? "hsl" : "hsla");
else if (color.simple)
format = (color.hasShortHex() ? "shorthex" : "hex");
@@ -1220,6 +1205,9 @@ WebInspector.StylePropertyTreeElement.prototype = {
this.listItemElement.removeChildren();
+ if (!this.treeOutline)
+ return;
+
// Append the checkbox for root elements of an editable section.
if (this.treeOutline.section && this.treeOutline.section.editable && this.parent.root)
this.listItemElement.appendChild(enabledCheckboxElement);
@@ -1254,12 +1242,12 @@ WebInspector.StylePropertyTreeElement.prototype = {
var disabled = !event.target.checked;
var self = this;
- function callback(newPayload)
+ function callback(newStyle)
{
- if (!newPayload)
+ if (!newStyle)
return;
- self.style = WebInspector.CSSStyleDeclaration.parseStyle(newPayload);
+ self.style = newStyle;
self._styleRule.style = self.style;
// Set the disabled property here, since the code above replies on it not changing
@@ -1272,7 +1260,7 @@ WebInspector.StylePropertyTreeElement.prototype = {
self.updateAll(true);
}
- InspectorBackend.toggleStyleEnabled(WebInspector.Callback.wrap(callback), this.style.id, this.name, disabled);
+ WebInspector.cssModel.toggleStyleEnabled(this.style.id, this.name, disabled, callback);
},
updateState: function()
@@ -1434,7 +1422,7 @@ WebInspector.StylePropertyTreeElement.prototype = {
} else {
// Restore the original CSS text before applying user changes. This is needed to prevent
// new properties from sticking around if the user adds one, then removes it.
- InspectorBackend.setStyleText(WebInspector.Callback.wrap(null), this.style.id, this.originalCSSText);
+ WebInspector.cssModel.setCSSText(this.style.id, this.originalCSSText);
}
this.applyStyleText(this.listItemElement.textContent);
@@ -1454,7 +1442,7 @@ WebInspector.StylePropertyTreeElement.prototype = {
if (this._newProperty)
this.treeOutline.removeChild(this);
else if (this.originalCSSText) {
- InspectorBackend.setStyleText(WebInspector.Callback.wrap(null), this.style.id, this.originalCSSText);
+ WebInspector.cssModel.setCSSText(this.style.id, this.originalCSSText);
if (this.treeOutline.section && this.treeOutline.section.pane)
this.treeOutline.section.pane.dispatchEventToListeners("style edited");
@@ -1541,28 +1529,29 @@ WebInspector.StylePropertyTreeElement.prototype = {
}
var self = this;
- function callback(success, newPayload, changedProperties)
+
+ function failureCallback()
{
- if (!success) {
- // The user typed something, but it didn't parse. Just abort and restore
- // the original title for this property. If this was a new attribute and
- // we couldn't parse, then just remove it.
- if (self._newProperty) {
- self.parent.removeChild(self);
- return;
- }
- if (updateInterface)
- self.updateTitle();
+ // The user typed something, but it didn't parse. Just abort and restore
+ // the original title for this property. If this was a new attribute and
+ // we couldn't parse, then just remove it.
+ if (self._newProperty) {
+ self.parent.removeChild(self);
return;
}
+ if (updateInterface)
+ self.updateTitle();
+ }
+ function successCallback(newStyle, changedProperties)
+ {
elementsPanel.removeStyleChange(section.identifier, self.style, self.name);
if (!styleTextLength) {
// Do remove ourselves from UI when the property removal is confirmed.
self.parent.removeChild(self);
} else {
- self.style = WebInspector.CSSStyleDeclaration.parseStyle(newPayload);
+ self.style = newStyle;
for (var i = 0; i < changedProperties.length; ++i)
elementsPanel.addStyleChange(section.identifier, self.style, changedProperties[i]);
self._styleRule.style = self.style;
@@ -1574,7 +1563,8 @@ WebInspector.StylePropertyTreeElement.prototype = {
if (updateInterface)
self.updateAll(true);
}
- InspectorBackend.applyStyleText(WebInspector.Callback.wrap(callback), this.style.id, styleText, this.name);
+
+ WebInspector.cssModel.applyStyleText(this.style.id, styleText, this.name, successCallback, failureCallback);
}
}
diff --git a/WebCore/inspector/front-end/TextPrompt.js b/WebCore/inspector/front-end/TextPrompt.js
index 2bbe075..b6bcd52 100644
--- a/WebCore/inspector/front-end/TextPrompt.js
+++ b/WebCore/inspector/front-end/TextPrompt.js
@@ -242,7 +242,7 @@ WebInspector.TextPrompt.prototype = {
wordPrefixLength = commonPrefix.length;
if (selection.isCollapsed)
- var completionText = completions[1];
+ var completionText = completions[0];
else {
var currentText = fullWordRange.toString();
diff --git a/WebCore/inspector/front-end/TextViewer.js b/WebCore/inspector/front-end/TextViewer.js
index cd06072..4709a59 100644
--- a/WebCore/inspector/front-end/TextViewer.js
+++ b/WebCore/inspector/front-end/TextViewer.js
@@ -260,12 +260,14 @@ WebInspector.TextViewer.prototype = {
return; // Do not trigger editing from line numbers.
var oldContent = lineRow.lastChild.innerHTML;
- this._editingLine = WebInspector.startEditing(lineRow.lastChild, this._commitEditingLine.bind(this, lineRow.lineNumber, lineRow.lastChild), this._cancelEditingLine.bind(this, lineRow.lastChild, oldContent), null, true);
+ var cancelEditingCallback = this._cancelEditingLine.bind(this, lineRow.lastChild, oldContent);
+ var commitEditingCallback = this._commitEditingLine.bind(this, lineRow.lineNumber, lineRow.lastChild, cancelEditingCallback);
+ this._editingLine = WebInspector.startEditing(lineRow.lastChild, commitEditingCallback, cancelEditingCallback, null, true);
},
- _commitEditingLine: function(lineNumber, element)
+ _commitEditingLine: function(lineNumber, element, cancelEditingCallback)
{
- this._editCallback(lineNumber, element.textContent)
+ this._editCallback(lineNumber, element.textContent, cancelEditingCallback);
delete this._editingLine;
},
diff --git a/WebCore/inspector/front-end/TimelinePanel.js b/WebCore/inspector/front-end/TimelinePanel.js
index b9f0814..29efd79 100644
--- a/WebCore/inspector/front-end/TimelinePanel.js
+++ b/WebCore/inspector/front-end/TimelinePanel.js
@@ -940,7 +940,7 @@ WebInspector.TimelinePanel.FormattedRecord.prototype = {
case recordTypes.TimerRemove:
contentHelper._appendTextRow(WebInspector.UIString("Timer ID"), this.data.timerId);
if (typeof this.timeout === "number") {
- contentHelper._appendTextRow(WebInspector.UIString("Timeout"), this.timeout);
+ contentHelper._appendTextRow(WebInspector.UIString("Timeout"), Number.secondsToString(this.timeout / 1000, WebInspector.UIString));
contentHelper._appendTextRow(WebInspector.UIString("Repeats"), !this.singleShot);
}
if (typeof this.callSiteScriptLine === "number")
diff --git a/WebCore/inspector/front-end/WatchExpressionsSidebarPane.js b/WebCore/inspector/front-end/WatchExpressionsSidebarPane.js
index 3655d68..b530ab6 100644
--- a/WebCore/inspector/front-end/WatchExpressionsSidebarPane.js
+++ b/WebCore/inspector/front-end/WatchExpressionsSidebarPane.js
@@ -31,7 +31,7 @@
WebInspector.WatchExpressionsSidebarPane = function()
{
WebInspector.SidebarPane.call(this, WebInspector.UIString("Watch Expressions"));
- WebInspector.settings.addEventListener("loaded", this._settingsLoaded, this);
+ WebInspector.applicationSettings.addEventListener("loaded", this._settingsLoaded, this);
}
WebInspector.WatchExpressionsSidebarPane.prototype = {
@@ -39,7 +39,7 @@ WebInspector.WatchExpressionsSidebarPane.prototype = {
{
this.bodyElement.removeChildren();
- this.expanded = WebInspector.settings.watchExpressions.length > 0;
+ this.expanded = WebInspector.applicationSettings.watchExpressions.length > 0;
this.section = new WebInspector.WatchExpressionsSection();
this.bodyElement.appendChild(this.section.element);
@@ -77,7 +77,7 @@ WebInspector.WatchExpressionsSection = function()
WebInspector.ObjectPropertiesSection.call(this);
- this.watchExpressions = WebInspector.settings.watchExpressions;
+ this.watchExpressions = WebInspector.applicationSettings.watchExpressions;
this.headerElement.className = "hidden";
this.editable = true;
@@ -195,7 +195,7 @@ WebInspector.WatchExpressionsSection.prototype = {
if (this.watchExpressions[i])
toSave.push(this.watchExpressions[i]);
- WebInspector.settings.watchExpressions = toSave;
+ WebInspector.applicationSettings.watchExpressions = toSave;
return toSave.length;
}
}
diff --git a/WebCore/inspector/front-end/WebKit.qrc b/WebCore/inspector/front-end/WebKit.qrc
index e93bf2c..fd84586 100644
--- a/WebCore/inspector/front-end/WebKit.qrc
+++ b/WebCore/inspector/front-end/WebKit.qrc
@@ -19,6 +19,7 @@
<file>ConsoleView.js</file>
<file>ContextMenu.js</file>
<file>CookieItemsView.js</file>
+ <file>CSSStyleModel.js</file>
<file>Database.js</file>
<file>DatabaseQueryView.js</file>
<file>DatabaseTableView.js</file>
@@ -32,6 +33,7 @@
<file>ElementsTreeOutline.js</file>
<file>EventListenersSidebarPane.js</file>
<file>FontView.js</file>
+ <file>HAREntry.js</file>
<file>HelpScreen.js</file>
<file>ImageView.js</file>
<file>InjectedFakeWorker.js</file>
diff --git a/WebCore/inspector/front-end/inspector.css b/WebCore/inspector/front-end/inspector.css
index ef34f2c..52b85bc 100644
--- a/WebCore/inspector/front-end/inspector.css
+++ b/WebCore/inspector/front-end/inspector.css
@@ -2351,6 +2351,10 @@ button.enable-toggle-status-bar-item.toggled-on .glyph {
max-width: 250px;
}
+#scripts-files option.extension-script {
+ color: rgb(70, 134, 240);
+}
+
#scripts-functions {
max-width: 150px;
}
@@ -3976,7 +3980,6 @@ ol.breakpoint-list {
.styles-selector {
cursor: text;
- -webkit-user-select: text;
}
.workers-list {
@@ -4004,6 +4007,7 @@ a.worker-item {
white-space: nowrap;
-webkit-background-origin: padding;
-webkit-background-clip: padding;
+ -webkit-user-select: text;
}
.styles-section:not(.first-styles-section) {
@@ -4058,7 +4062,6 @@ a.worker-item {
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
- -webkit-user-select: text;
cursor: auto;
}
diff --git a/WebCore/inspector/front-end/inspector.html b/WebCore/inspector/front-end/inspector.html
index 75b31eb..4c51634 100644
--- a/WebCore/inspector/front-end/inspector.html
+++ b/WebCore/inspector/front-end/inspector.html
@@ -41,6 +41,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<script type="text/javascript" src="InspectorFrontendHostStub.js"></script>
<script type="text/javascript" src="Object.js"></script>
<script type="text/javascript" src="Settings.js"></script>
+ <script type="text/javascript" src="CSSStyleModel.js"></script>
<script type="text/javascript" src="Checkbox.js"></script>
<script type="text/javascript" src="ContextMenu.js"></script>
<script type="text/javascript" src="KeyboardShortcut.js"></script>
@@ -127,6 +128,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<script type="text/javascript" src="TestController.js"></script>
<script type="text/javascript" src="HelpScreen.js"></script>
<script type="text/javascript" src="ShortcutsHelp.js"></script>
+ <script type="text/javascript" src="HAREntry.js"></script>
</head>
<body class="detached">
<div id="toolbar">
diff --git a/WebCore/inspector/front-end/inspector.js b/WebCore/inspector/front-end/inspector.js
index 8c25be5..e8108af 100644
--- a/WebCore/inspector/front-end/inspector.js
+++ b/WebCore/inspector/front-end/inspector.js
@@ -440,7 +440,8 @@ WebInspector.loaded = function()
var port = WebInspector.port;
document.body.addStyleClass("port-" + port);
- this.settings = new WebInspector.Settings();
+ this.applicationSettings = new WebInspector.Settings(false);
+ this.sessionSettings = new WebInspector.Settings(true);
this._registerShortcuts();
// set order of some sections explicitly
@@ -466,6 +467,7 @@ WebInspector.loaded = function()
};
this.breakpointManager = new WebInspector.BreakpointManager();
+ this.cssModel = new WebInspector.CSSStyleModel();
this.panels = {};
this._createPanels();
@@ -571,6 +573,13 @@ WebInspector.dispatch = function() {
setTimeout(delayDispatch, 0);
}
+WebInspector.dispatchMessageFromBackend = function(arguments)
+{
+ var methodName = arguments.shift();
+ WebInspector[methodName].apply(this, arguments);
+}
+
+
WebInspector.windowResize = function(event)
{
if (this.currentPanel)
@@ -696,7 +705,7 @@ WebInspector._registerShortcuts = function()
shortcut.shortcutToString("[", shortcut.Modifiers.CtrlOrMeta)
];
section.addRelatedKeys(keys, WebInspector.UIString("Next/previous panel"));
- section.addKey(shortcut.Keys.Esc.name, WebInspector.UIString("Toggle console"));
+ section.addKey(shortcut.shortcutToString(shortcut.Keys.Esc), WebInspector.UIString("Toggle console"));
section.addKey(shortcut.shortcutToString("f", shortcut.Modifiers.CtrlOrMeta), WebInspector.UIString("Search"));
keys = [
shortcut.shortcutToString("g", shortcut.Modifiers.CtrlOrMeta),
@@ -1318,9 +1327,9 @@ WebInspector.profilerWasDisabled = function()
this.panels.profiles.profilerWasDisabled();
}
-WebInspector.parsedScriptSource = function(sourceID, sourceURL, source, startingLine)
+WebInspector.parsedScriptSource = function(sourceID, sourceURL, source, startingLine, scriptWorldType)
{
- this.panels.scripts.addScript(sourceID, sourceURL, source, startingLine);
+ this.panels.scripts.addScript(sourceID, sourceURL, source, startingLine, undefined, undefined, scriptWorldType);
}
WebInspector.restoredBreakpoint = function(sourceID, sourceURL, line, enabled, condition)
@@ -1360,6 +1369,7 @@ WebInspector.reset = function()
panel.reset();
}
+ this.sessionSettings.reset();
this.breakpointManager.reset();
for (var category in this.resourceCategories)
diff --git a/WebCore/inspector/front-end/utilities.js b/WebCore/inspector/front-end/utilities.js
index 9ad1c10..bb19dbd 100644
--- a/WebCore/inspector/front-end/utilities.js
+++ b/WebCore/inspector/front-end/utilities.js
@@ -55,7 +55,14 @@ Function.prototype.bind = function(thisObject)
{
var func = this;
var args = Array.prototype.slice.call(arguments, 1);
- return function() { return func.apply(thisObject, args.concat(Array.prototype.slice.call(arguments, 0))) };
+ function bound()
+ {
+ return func.apply(thisObject, args.concat(Array.prototype.slice.call(arguments, 0)));
+ }
+ bound.toString = function() {
+ return "bound: " + func;
+ };
+ return bound;
}
Node.prototype.rangeOfWord = function(offset, stopCharacters, stayWithinNode, direction)