summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/inspector
diff options
context:
space:
mode:
authorBen Murdoch <benm@google.com>2011-05-16 16:25:10 +0100
committerBen Murdoch <benm@google.com>2011-05-23 18:54:14 +0100
commitab9e7a118cf1ea2e3a93dce683b2ded3e7291ddb (patch)
treedb769fadd053248f85db67434a5b275224defef7 /Source/WebCore/inspector
parent52e2557aeb8477967e97fd24f20f8f407a10fa15 (diff)
downloadexternal_webkit-ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddb.zip
external_webkit-ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddb.tar.gz
external_webkit-ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddb.tar.bz2
Merge WebKit at r76408: Initial merge by git.
Change-Id: I5b91decbd693ccbf5c1b8354b37cd68cc9a1ea53
Diffstat (limited to 'Source/WebCore/inspector')
-rw-r--r--Source/WebCore/inspector/CodeGeneratorInspector.pm80
-rw-r--r--Source/WebCore/inspector/ConsoleMessage.h3
-rw-r--r--Source/WebCore/inspector/InjectedScript.cpp117
-rw-r--r--Source/WebCore/inspector/InjectedScript.h19
-rw-r--r--Source/WebCore/inspector/InjectedScriptHost.cpp44
-rw-r--r--Source/WebCore/inspector/InjectedScriptHost.h6
-rw-r--r--Source/WebCore/inspector/InjectedScriptSource.js124
-rw-r--r--Source/WebCore/inspector/Inspector.idl49
-rw-r--r--Source/WebCore/inspector/InspectorApplicationCacheAgent.h3
-rw-r--r--Source/WebCore/inspector/InspectorBrowserDebuggerAgent.cpp117
-rw-r--r--Source/WebCore/inspector/InspectorBrowserDebuggerAgent.h11
-rw-r--r--Source/WebCore/inspector/InspectorCSSAgent.cpp15
-rw-r--r--Source/WebCore/inspector/InspectorConsoleAgent.cpp24
-rw-r--r--Source/WebCore/inspector/InspectorConsoleAgent.h7
-rw-r--r--Source/WebCore/inspector/InspectorController.cpp178
-rw-r--r--Source/WebCore/inspector/InspectorController.h84
-rw-r--r--Source/WebCore/inspector/InspectorDOMAgent.cpp52
-rw-r--r--Source/WebCore/inspector/InspectorDOMAgent.h308
-rw-r--r--Source/WebCore/inspector/InspectorDebuggerAgent.cpp15
-rw-r--r--Source/WebCore/inspector/InspectorDebuggerAgent.h11
-rw-r--r--Source/WebCore/inspector/InspectorFrontendClientLocal.h3
-rw-r--r--Source/WebCore/inspector/InspectorInstrumentation.cpp63
-rw-r--r--Source/WebCore/inspector/InspectorInstrumentation.h33
-rw-r--r--Source/WebCore/inspector/InspectorProfilerAgent.cpp11
-rw-r--r--Source/WebCore/inspector/InspectorProfilerAgent.h4
-rw-r--r--Source/WebCore/inspector/InspectorResourceAgent.cpp13
-rw-r--r--Source/WebCore/inspector/InspectorResourceAgent.h12
-rw-r--r--Source/WebCore/inspector/InspectorRuntimeAgent.cpp83
-rw-r--r--Source/WebCore/inspector/InspectorRuntimeAgent.h75
-rw-r--r--Source/WebCore/inspector/InspectorState.cpp45
-rw-r--r--Source/WebCore/inspector/InspectorState.h29
-rw-r--r--Source/WebCore/inspector/InspectorTimelineAgent.h3
-rw-r--r--Source/WebCore/inspector/InspectorValues.cpp8
-rw-r--r--Source/WebCore/inspector/InspectorValues.h1
-rw-r--r--Source/WebCore/inspector/JavaScriptCallFrame.idl1
-rw-r--r--Source/WebCore/inspector/front-end/AuditLauncherView.js58
-rw-r--r--Source/WebCore/inspector/front-end/AuditRules.js8
-rw-r--r--Source/WebCore/inspector/front-end/AuditsPanel.js15
-rw-r--r--Source/WebCore/inspector/front-end/Breakpoint.js43
-rw-r--r--Source/WebCore/inspector/front-end/BreakpointManager.js4
-rw-r--r--Source/WebCore/inspector/front-end/BreakpointsSidebarPane.js218
-rw-r--r--Source/WebCore/inspector/front-end/CSSCompletions.js2
-rwxr-xr-xSource/WebCore/inspector/front-end/CSSKeywordCompletions.js438
-rw-r--r--Source/WebCore/inspector/front-end/ConsoleView.js51
-rw-r--r--Source/WebCore/inspector/front-end/DebuggerModel.js87
-rw-r--r--Source/WebCore/inspector/front-end/ElementsTreeOutline.js3
-rw-r--r--Source/WebCore/inspector/front-end/ExtensionAPI.js3
-rw-r--r--Source/WebCore/inspector/front-end/ExtensionPanel.js2
-rw-r--r--Source/WebCore/inspector/front-end/ExtensionServer.js18
-rw-r--r--Source/WebCore/inspector/front-end/InjectedScriptAccess.js96
-rw-r--r--Source/WebCore/inspector/front-end/NetworkManager.js42
-rw-r--r--Source/WebCore/inspector/front-end/NetworkPanel.js27
-rw-r--r--Source/WebCore/inspector/front-end/PropertiesSidebarPane.js14
-rw-r--r--Source/WebCore/inspector/front-end/RemoteObject.js8
-rw-r--r--Source/WebCore/inspector/front-end/Resource.js12
-rw-r--r--Source/WebCore/inspector/front-end/ResourcesPanel.js5
-rw-r--r--Source/WebCore/inspector/front-end/Script.js6
-rw-r--r--Source/WebCore/inspector/front-end/ScriptFormatter.js134
-rw-r--r--Source/WebCore/inspector/front-end/ScriptFormatterWorker.js64
-rw-r--r--Source/WebCore/inspector/front-end/ScriptView.js2
-rw-r--r--Source/WebCore/inspector/front-end/ScriptsPanel.js121
-rw-r--r--Source/WebCore/inspector/front-end/Settings.js1
-rw-r--r--Source/WebCore/inspector/front-end/SourceFrame.js203
-rw-r--r--Source/WebCore/inspector/front-end/SourceView.js4
-rw-r--r--Source/WebCore/inspector/front-end/StylesSidebarPane.js184
-rw-r--r--Source/WebCore/inspector/front-end/TextPrompt.js55
-rw-r--r--Source/WebCore/inspector/front-end/TextViewer.js57
-rw-r--r--Source/WebCore/inspector/front-end/UglifyJS/parse-js.js1233
-rwxr-xr-xSource/WebCore/inspector/front-end/UglifyJS/process.js1560
-rw-r--r--Source/WebCore/inspector/front-end/WebKit.qrc6
-rw-r--r--Source/WebCore/inspector/front-end/inspector.css4
-rw-r--r--Source/WebCore/inspector/front-end/inspector.html3
-rw-r--r--Source/WebCore/inspector/front-end/inspector.js23
-rw-r--r--Source/WebCore/inspector/front-end/utilities.js16
74 files changed, 5246 insertions, 1235 deletions
diff --git a/Source/WebCore/inspector/CodeGeneratorInspector.pm b/Source/WebCore/inspector/CodeGeneratorInspector.pm
index b7be15e..e215a91 100644
--- a/Source/WebCore/inspector/CodeGeneratorInspector.pm
+++ b/Source/WebCore/inspector/CodeGeneratorInspector.pm
@@ -13,61 +13,70 @@ my %typeTransform;
$typeTransform{"ApplicationCache"} = {
"forward" => "InspectorApplicationCacheAgent",
"header" => "InspectorApplicationCacheAgent.h",
- "domainAccessor" => "m_inspectorController->m_applicationCacheAgent",
+ "domainAccessor" => "m_inspectorAgent->applicationCacheAgent()",
};
$typeTransform{"CSS"} = {
"forward" => "InspectorCSSAgent",
"header" => "InspectorCSSAgent.h",
- "domainAccessor" => "m_inspectorController->m_cssAgent",
+ "domainAccessor" => "m_inspectorAgent->cssAgent()",
};
$typeTransform{"Console"} = {
"forward" => "InspectorConsoleAgent",
"header" => "InspectorConsoleAgent.h",
- "domainAccessor" => "m_inspectorController->m_consoleAgent",
+ "domainAccessor" => "m_inspectorAgent->consoleAgent()",
};
$typeTransform{"Debugger"} = {
"forward" => "InspectorDebuggerAgent",
"header" => "InspectorDebuggerAgent.h",
- "domainAccessor" => "m_inspectorController->m_debuggerAgent",
+ "domainAccessor" => "m_inspectorAgent->debuggerAgent()",
};
$typeTransform{"BrowserDebugger"} = {
"forward" => "InspectorBrowserDebuggerAgent",
"header" => "InspectorBrowserDebuggerAgent.h",
- "domainAccessor" => "m_inspectorController->m_browserDebuggerAgent",
+ "domainAccessor" => "m_inspectorAgent->browserDebuggerAgent()",
};
$typeTransform{"Database"} = {
"forward" => "InspectorDatabaseAgent",
"header" => "InspectorDatabaseAgent.h",
- "domainAccessor" => "m_inspectorController->m_databaseAgent",
+ "domainAccessor" => "m_inspectorAgent->databaseAgent()",
};
$typeTransform{"DOM"} = {
"forward" => "InspectorDOMAgent",
"header" => "InspectorDOMAgent.h",
- "domainAccessor" => "m_inspectorController->m_domAgent",
+ "domainAccessor" => "m_inspectorAgent->domAgent()",
};
$typeTransform{"DOMStorage"} = {
"forward" => "InspectorDOMStorageAgent",
"header" => "InspectorDOMStorageAgent.h",
- "domainAccessor" => "m_inspectorController->m_domStorageAgent",
+ "domainAccessor" => "m_inspectorAgent->domStorageAgent()",
};
$typeTransform{"FileSystem"} = {
"forward" => "InspectorFileSystemAgent",
"header" => "InspectorFileSystemAgent.h",
- "domainAccessor" => "m_inspectorController->m_fileSystemAgent",
+ "domainAccessor" => "m_inspectorAgent->fileSystemAgent()",
+};
+$typeTransform{"InjectedScript"} = {
+ "forwardHeader" => "InjectedScriptHost.h",
+ "domainAccessor" => "m_inspectorAgent->injectedScriptAgent()",
};
$typeTransform{"Inspector"} = {
- "forwardHeader" => "InspectorController.h",
- "domainAccessor" => "m_inspectorController",
+ "forwardHeader" => "InspectorController.h", # FIXME: Temporary solution until extracting the real InspectorAgent from InspectorController.
+ "domainAccessor" => "m_inspectorAgent",
};
$typeTransform{"Network"} = {
"forward" => "InspectorResourceAgent",
"header" => "InspectorResourceAgent.h",
- "domainAccessor" => "m_inspectorController->m_resourceAgent",
+ "domainAccessor" => "m_inspectorAgent->resourceAgent()",
};
$typeTransform{"Profiler"} = {
"forward" => "InspectorProfilerAgent",
"header" => "InspectorProfilerAgent.h",
- "domainAccessor" => "m_inspectorController->m_profilerAgent",
+ "domainAccessor" => "m_inspectorAgent->profilerAgent()",
+};
+$typeTransform{"Runtime"} = {
+ "forward" => "InspectorRuntimeAgent",
+ "header" => "InspectorRuntimeAgent.h",
+ "domainAccessor" => "m_inspectorAgent->runtimeAgent()",
};
$typeTransform{"Frontend"} = {
@@ -87,7 +96,8 @@ $typeTransform{"Object"} = {
"defaultValue" => "InspectorObject::create()",
"forward" => "InspectorObject",
"header" => "InspectorValues.h",
- "JSONType" => "Object"
+ "JSONType" => "Object",
+ "JSType" => "object"
};
$typeTransform{"Array"} = {
"param" => "PassRefPtr<InspectorArray>",
@@ -95,7 +105,8 @@ $typeTransform{"Array"} = {
"defaultValue" => "InspectorArray::create()",
"forward" => "InspectorArray",
"header" => "InspectorValues.h",
- "JSONType" => "Array"
+ "JSONType" => "Array",
+ "JSType" => "object"
};
$typeTransform{"Value"} = {
"param" => "PassRefPtr<InspectorValue>",
@@ -103,16 +114,18 @@ $typeTransform{"Value"} = {
"defaultValue" => "InspectorValue::null()",
"forward" => "InspectorValue",
"header" => "InspectorValues.h",
- "JSONType" => "Value"
+ "JSONType" => "Value",
+ "JSType" => ""
};
$typeTransform{"String"} = {
"param" => "const String&",
"variable" => "String",
"return" => "String",
"defaultValue" => "\"\"",
- "forwardHeader" => "wtf/Forward.h",
+ "forwardHeader" => "PlatformString.h",
"header" => "PlatformString.h",
- "JSONType" => "String"
+ "JSONType" => "String",
+ "JSType" => "string"
};
$typeTransform{"long"} = {
"param" => "long",
@@ -120,7 +133,8 @@ $typeTransform{"long"} = {
"defaultValue" => "0",
"forward" => "",
"header" => "",
- "JSONType" => "Number"
+ "JSONType" => "Number",
+ "JSType" => "number"
};
$typeTransform{"int"} = {
"param" => "int",
@@ -129,6 +143,7 @@ $typeTransform{"int"} = {
"forward" => "",
"header" => "",
"JSONType" => "Number",
+ "JSType" => "number"
};
$typeTransform{"unsigned long"} = {
"param" => "unsigned long",
@@ -136,7 +151,8 @@ $typeTransform{"unsigned long"} = {
"defaultValue" => "0u",
"forward" => "",
"header" => "",
- "JSONType" => "Number"
+ "JSONType" => "Number",
+ "JSType" => "number"
};
$typeTransform{"unsigned int"} = {
"param" => "unsigned int",
@@ -144,7 +160,8 @@ $typeTransform{"unsigned int"} = {
"defaultValue" => "0u",
"forward" => "",
"header" => "",
- "JSONType" => "Number"
+ "JSONType" => "Number",
+ "JSType" => "number"
};
$typeTransform{"double"} = {
"param" => "double",
@@ -152,7 +169,8 @@ $typeTransform{"double"} = {
"defaultValue" => "0.0",
"forward" => "",
"header" => "",
- "JSONType" => "Number"
+ "JSONType" => "Number",
+ "JSType" => "number"
};
$typeTransform{"boolean"} = {
"param" => "bool",
@@ -160,7 +178,8 @@ $typeTransform{"boolean"} = {
"defaultValue" => "false",
"forward" => "",
"header" => "",
- "JSONType" => "Boolean"
+ "JSONType" => "Boolean",
+ "JSType" => "boolean"
};
$typeTransform{"void"} = {
"forward" => "",
@@ -250,12 +269,13 @@ sub GenerateInterface
$backendClassName = $className . "BackendDispatcher";
$backendJSStubName = $className . "BackendStub";
my @backendHead;
- push(@backendHead, " ${backendClassName}(InspectorController* inspectorController) : m_inspectorController(inspectorController) { }");
+ push(@backendHead, " typedef InspectorController InspectorAgent;"); # FIXME: Temporary substitution until extracting InspectorAgent from InspectorController.
+ push(@backendHead, " ${backendClassName}(InspectorAgent* inspectorAgent) : m_inspectorAgent(inspectorAgent) { }");
push(@backendHead, " void reportProtocolError(const long callId, const String& errorText) const;");
push(@backendHead, " void dispatch(const String& message);");
push(@backendHead, " static bool getCommandName(const String& message, String* result);");
$backendConstructor = join("\n", @backendHead);
- $backendFooter = " InspectorController* m_inspectorController;";
+ $backendFooter = " InspectorAgent* m_inspectorAgent;";
$backendTypes{"Inspector"} = 1;
$backendTypes{"InspectorClient"} = 1;
$backendTypes{"PassRefPtr"} = 1;
@@ -392,7 +412,7 @@ sub generateBackendFunction
}
push(@function, " // use InspectorFrontend as a marker of WebInspector availability");
- push(@function, " if ((callId || protocolErrors->length()) && m_inspectorController->hasFrontend()) {");
+ push(@function, " if ((callId || protocolErrors->length()) && m_inspectorAgent->hasFrontend()) {");
push(@function, " RefPtr<InspectorObject> responseMessage = InspectorObject::create();");
push(@function, " responseMessage->setNumber(\"seq\", callId);");
push(@function, " responseMessage->setString(\"domain\", \"$domain\");");
@@ -407,7 +427,7 @@ sub generateBackendFunction
push(@function, " responseMessage->setObject(\"data\", responseData);");
push(@function, " }");
}
- push(@function, " m_inspectorController->inspectorClient()->sendMessageToFrontend(responseMessage->toJSONString());");
+ push(@function, " m_inspectorAgent->inspectorClient()->sendMessageToFrontend(responseMessage->toJSONString());");
push(@function, " }");
@@ -428,7 +448,7 @@ void ${backendClassName}::reportProtocolError(const long callId, const String& e
RefPtr<InspectorArray> errors = InspectorArray::create();
errors->pushString(errorText);
message->setArray("errors", errors);
- m_inspectorController->inspectorClient()->sendMessageToFrontend(message->toJSONString());
+ m_inspectorAgent->inspectorClient()->sendMessageToFrontend(message->toJSONString());
}
EOF
return split("\n", $reportProtocolError);
@@ -567,7 +587,7 @@ sub generateBackendStubJS
foreach my $function (@backendFunctions) {
my $name = $function->signature->name;
my $domain = $function->signature->extendedAttributes->{"domain"};
- my $argumentNames = join(",", map("\"" . $_->name . "\": \"" . lc($typeTransform{$_->type}->{"JSONType"}) . "\"", grep($_->direction eq "in", @{$function->parameters})));
+ my $argumentNames = join(",", map("\"" . $_->name . "\": \"" . $typeTransform{$_->type}->{"JSType"} . "\"", grep($_->direction eq "in", @{$function->parameters})));
push(@JSStubs, " this._registerDelegate('{" .
"\"seq\": 0, " .
"\"domain\": \"$domain\", " .
@@ -625,7 +645,7 @@ InspectorBackendStub.prototype = {
return;
}
var value = args.shift();
- if (typeof value !== request.arguments[key]) {
+ if (request.arguments[key] && typeof value !== request.arguments[key]) {
console.error("Protocol Error: Invalid type of argument '%s' for 'InspectorBackend.%s' call. It should be '%s' but it is '%s'.", key, request.command, request.arguments[key], typeof value);
return;
}
diff --git a/Source/WebCore/inspector/ConsoleMessage.h b/Source/WebCore/inspector/ConsoleMessage.h
index 310aa8e..7c3348b 100644
--- a/Source/WebCore/inspector/ConsoleMessage.h
+++ b/Source/WebCore/inspector/ConsoleMessage.h
@@ -46,7 +46,8 @@ class ScriptCallFrame;
class ScriptCallStack;
class ScriptValue;
-class ConsoleMessage : public Noncopyable {
+class ConsoleMessage {
+ WTF_MAKE_NONCOPYABLE(ConsoleMessage); WTF_MAKE_FAST_ALLOCATED;
public:
ConsoleMessage(MessageSource, MessageType, MessageLevel, const String& m, unsigned li, const String& u);
ConsoleMessage(MessageSource, MessageType, MessageLevel, const String& m, PassRefPtr<ScriptArguments>, PassRefPtr<ScriptCallStack>);
diff --git a/Source/WebCore/inspector/InjectedScript.cpp b/Source/WebCore/inspector/InjectedScript.cpp
index 3f4d819..1969f34 100644
--- a/Source/WebCore/inspector/InjectedScript.cpp
+++ b/Source/WebCore/inspector/InjectedScript.cpp
@@ -44,21 +44,94 @@ InjectedScript::InjectedScript(ScriptObject injectedScriptObject)
{
}
-void InjectedScript::dispatch(const String& methodName, const String& arguments, RefPtr<InspectorValue>* result, bool* hadException)
+void InjectedScript::evaluate(const String& expression, const String& objectGroup, RefPtr<InspectorValue>* result)
{
- ASSERT(!hasNoValue());
- if (!canAccessInspectedWindow()) {
- *hadException = true;
- return;
- }
+ ScriptFunctionCall function(m_injectedScriptObject, "evaluate");
+ function.appendArgument(expression);
+ function.appendArgument(objectGroup);
+ makeCall(function, result);
+}
- ScriptFunctionCall function(m_injectedScriptObject, "dispatch");
- function.appendArgument(methodName);
- function.appendArgument(arguments);
- *hadException = false;
- ScriptValue resultValue = function.call(*hadException);
- if (!*hadException)
- *result = resultValue.toInspectorValue(m_injectedScriptObject.scriptState());
+void InjectedScript::evaluateOnCallFrame(PassRefPtr<InspectorObject> callFrameId, const String& expression, const String& objectGroup, RefPtr<InspectorValue>* result)
+{
+ ScriptFunctionCall function(m_injectedScriptObject, "evaluateOnCallFrame");
+ function.appendArgument(callFrameId->toJSONString());
+ function.appendArgument(expression);
+ function.appendArgument(objectGroup);
+ makeCall(function, result);
+}
+
+void InjectedScript::evaluateOnSelf(const String& functionBody, PassRefPtr<InspectorArray> argumentsArray, RefPtr<InspectorValue>* result)
+{
+ ScriptFunctionCall function(m_injectedScriptObject, "evaluateOnSelf");
+ function.appendArgument(functionBody);
+ function.appendArgument(argumentsArray->toJSONString());
+ makeCall(function, result);
+}
+
+void InjectedScript::getCompletions(const String& expression, bool includeInspectorCommandLineAPI, RefPtr<InspectorValue>* result)
+{
+ ScriptFunctionCall function(m_injectedScriptObject, "getCompletions");
+ function.appendArgument(expression);
+ function.appendArgument(includeInspectorCommandLineAPI);
+ makeCall(function, result);
+}
+
+void InjectedScript::getCompletionsOnCallFrame(PassRefPtr<InspectorObject> callFrameId, const String& expression, bool includeInspectorCommandLineAPI, RefPtr<InspectorValue>* result)
+{
+ ScriptFunctionCall function(m_injectedScriptObject, "getCompletionsOnCallFrame");
+ function.appendArgument(callFrameId->toJSONString());
+ function.appendArgument(expression);
+ function.appendArgument(includeInspectorCommandLineAPI);
+ makeCall(function, result);
+}
+
+void InjectedScript::getProperties(PassRefPtr<InspectorObject> objectId, bool ignoreHasOwnProperty, bool abbreviate, RefPtr<InspectorValue>* result)
+{
+ ScriptFunctionCall function(m_injectedScriptObject, "getProperties");
+ String objectIdString = objectId->toJSONString();
+ function.appendArgument(objectIdString);
+ function.appendArgument(ignoreHasOwnProperty);
+ function.appendArgument(abbreviate);
+ makeCall(function, result);
+}
+
+void InjectedScript::pushNodeToFrontend(PassRefPtr<InspectorObject> objectId, RefPtr<InspectorValue>* result)
+{
+ ScriptFunctionCall function(m_injectedScriptObject, "pushNodeToFrontend");
+ function.appendArgument(objectId->toJSONString());
+ makeCall(function, result);
+}
+
+void InjectedScript::resolveNode(long nodeId, RefPtr<InspectorValue>* result)
+{
+ ScriptFunctionCall function(m_injectedScriptObject, "resolveNode");
+ function.appendArgument(nodeId);
+ makeCall(function, result);
+}
+
+void InjectedScript::getNodeProperties(long nodeId, PassRefPtr<InspectorArray> propertiesArray, RefPtr<InspectorValue>* result)
+{
+ ScriptFunctionCall function(m_injectedScriptObject, "getNodeProperties");
+ function.appendArgument(nodeId);
+ function.appendArgument(propertiesArray->toJSONString());
+ makeCall(function, result);
+}
+
+void InjectedScript::getNodePrototypes(long nodeId, RefPtr<InspectorValue>* result)
+{
+ ScriptFunctionCall function(m_injectedScriptObject, "getNodePrototypes");
+ function.appendArgument(nodeId);
+ makeCall(function, result);
+}
+
+void InjectedScript::setPropertyValue(PassRefPtr<InspectorObject> objectId, const String& propertyName, const String& expression, RefPtr<InspectorValue>* result)
+{
+ ScriptFunctionCall function(m_injectedScriptObject, "getNodeProperties");
+ function.appendArgument(objectId->toJSONString());
+ function.appendArgument(propertyName);
+ function.appendArgument(expression);
+ makeCall(function, result);
}
#if ENABLE(JAVASCRIPT_DEBUGGER)
@@ -91,11 +164,29 @@ void InjectedScript::releaseWrapperObjectGroup(const String& objectGroup)
releaseFunction.appendArgument(objectGroup);
releaseFunction.call();
}
+
bool InjectedScript::canAccessInspectedWindow()
{
return InjectedScriptHost::canAccessInspectedWindow(m_injectedScriptObject.scriptState());
}
+void InjectedScript::makeCall(ScriptFunctionCall& function, RefPtr<InspectorValue>* result)
+{
+ if (hasNoValue() || !canAccessInspectedWindow()) {
+ *result = InspectorValue::null();
+ return;
+ }
+
+ bool hadException = false;
+ ScriptValue resultValue = function.call(hadException);
+
+ ASSERT(!hadException);
+ if (!hadException)
+ *result = resultValue.toInspectorValue(m_injectedScriptObject.scriptState());
+ else
+ *result = InspectorValue::null();
+}
+
} // namespace WebCore
#endif // ENABLE(INSPECTOR)
diff --git a/Source/WebCore/inspector/InjectedScript.h b/Source/WebCore/inspector/InjectedScript.h
index f80cfb4..0a3f24b 100644
--- a/Source/WebCore/inspector/InjectedScript.h
+++ b/Source/WebCore/inspector/InjectedScript.h
@@ -36,10 +36,12 @@
#include <wtf/Forward.h>
#include <wtf/Noncopyable.h>
#include <wtf/PassRefPtr.h>
+#include <wtf/RefPtr.h>
namespace WebCore {
class InspectorValue;
+class ScriptFunctionCall;
class InjectedScript {
public:
@@ -48,10 +50,22 @@ public:
bool hasNoValue() const { return m_injectedScriptObject.hasNoValue(); }
- void dispatch(const String& methodName, const String& arguments, RefPtr<InspectorValue>* result, bool* hadException);
+ void evaluate(const String& expression, const String& objectGroup, RefPtr<InspectorValue>* result);
+ void evaluateOnCallFrame(PassRefPtr<InspectorObject> callFrameId, const String& expression, const String& objectGroup, RefPtr<InspectorValue>* result);
+ void evaluateOnSelf(const String& functionBody, PassRefPtr<InspectorArray> argumentsArray, RefPtr<InspectorValue>* result);
+ void getCompletions(const String& expression, bool includeInspectorCommandLineAPI, RefPtr<InspectorValue>* result);
+ void getCompletionsOnCallFrame(PassRefPtr<InspectorObject> callFrameId, const String& expression, bool includeInspectorCommandLineAPI, RefPtr<InspectorValue>* result);
+ void getProperties(PassRefPtr<InspectorObject> objectId, bool ignoreHasOwnProperty, bool abbreviate, RefPtr<InspectorValue>* result);
+ void pushNodeToFrontend(PassRefPtr<InspectorObject> objectId, RefPtr<InspectorValue>* result);
+ void resolveNode(long nodeId, RefPtr<InspectorValue>* result);
+ void getNodeProperties(long nodeId, PassRefPtr<InspectorArray> propertiesArray, RefPtr<InspectorValue>* result);
+ void getNodePrototypes(long nodeId, RefPtr<InspectorValue>* result);
+ void setPropertyValue(PassRefPtr<InspectorObject> objectId, const String& propertyName, const String& expression, RefPtr<InspectorValue>* result);
+
#if ENABLE(JAVASCRIPT_DEBUGGER)
PassRefPtr<InspectorValue> callFrames();
#endif
+
PassRefPtr<InspectorValue> wrapForConsole(ScriptValue);
void releaseWrapperObjectGroup(const String&);
ScriptState* scriptState() const { return m_injectedScriptObject.scriptState(); }
@@ -60,6 +74,9 @@ private:
friend InjectedScript InjectedScriptHost::injectedScriptFor(ScriptState*);
explicit InjectedScript(ScriptObject);
bool canAccessInspectedWindow();
+
+ void makeCall(ScriptFunctionCall&, RefPtr<InspectorValue>* result);
+
ScriptObject m_injectedScriptObject;
};
diff --git a/Source/WebCore/inspector/InjectedScriptHost.cpp b/Source/WebCore/inspector/InjectedScriptHost.cpp
index 3fd70e4..d67adaf 100644
--- a/Source/WebCore/inspector/InjectedScriptHost.cpp
+++ b/Source/WebCore/inspector/InjectedScriptHost.cpp
@@ -30,22 +30,21 @@
#include "config.h"
#include "InjectedScriptHost.h"
-#include "InjectedScriptSource.h"
-#include "InspectorDatabaseAgent.h"
-#include "InspectorDOMStorageAgent.h"
#if ENABLE(INSPECTOR)
-
#include "Element.h"
#include "Frame.h"
#include "FrameLoader.h"
#include "HTMLFrameOwnerElement.h"
#include "InjectedScript.h"
+#include "InjectedScriptSource.h"
#include "InspectorClient.h"
#include "InspectorConsoleAgent.h"
#include "InspectorController.h"
#include "InspectorDOMAgent.h"
+#include "InspectorDOMStorageAgent.h"
+#include "InspectorDatabaseAgent.h"
#include "InspectorFrontend.h"
#include "Pasteboard.h"
@@ -81,6 +80,13 @@ InjectedScriptHost::~InjectedScriptHost()
{
}
+void InjectedScriptHost::evaluateOnSelf(const String& functionBody, PassRefPtr<InspectorArray> argumentsArray, RefPtr<InspectorValue>* result)
+{
+ InjectedScript injectedScript = injectedScriptForMainFrame();
+ if (!injectedScript.hasNoValue())
+ injectedScript.evaluateOnSelf(functionBody, argumentsArray, result);
+}
+
void InjectedScriptHost::clearConsoleMessages()
{
if (m_inspectorController)
@@ -124,23 +130,23 @@ long InjectedScriptHost::inspectedNode(unsigned long num)
#if ENABLE(DATABASE)
Database* InjectedScriptHost::databaseForId(long databaseId)
{
- if (m_inspectorController && m_inspectorController->m_databaseAgent)
- return m_inspectorController->m_databaseAgent->databaseForId(databaseId);
+ if (m_inspectorController && m_inspectorController->databaseAgent())
+ return m_inspectorController->databaseAgent()->databaseForId(databaseId);
return 0;
}
void InjectedScriptHost::selectDatabase(Database* database)
{
- if (m_inspectorController && m_inspectorController->m_databaseAgent)
- m_inspectorController->m_databaseAgent->selectDatabase(database);
+ if (m_inspectorController && m_inspectorController->databaseAgent())
+ m_inspectorController->databaseAgent()->selectDatabase(database);
}
#endif
#if ENABLE(DOM_STORAGE)
void InjectedScriptHost::selectDOMStorage(Storage* storage)
{
- if (m_inspectorController && m_inspectorController->m_domStorageAgent)
- m_inspectorController->m_domStorageAgent->selectDOMStorage(storage);
+ if (m_inspectorController && m_inspectorController->domStorageAgent())
+ m_inspectorController->domStorageAgent()->selectDOMStorage(storage);
}
#endif
@@ -149,6 +155,20 @@ InjectedScript InjectedScriptHost::injectedScriptForId(long id)
return m_idToInjectedScript.get(id);
}
+InjectedScript InjectedScriptHost::injectedScriptForObjectId(InspectorObject* objectId)
+{
+ long injectedScriptId = 0;
+ bool success = objectId->getNumber("injectedScriptId", &injectedScriptId);
+ if (success)
+ return injectedScriptForId(injectedScriptId);
+ return InjectedScript();
+}
+
+InjectedScript InjectedScriptHost::injectedScriptForMainFrame()
+{
+ return injectedScriptFor(mainWorldScriptState(m_inspectorController->inspectedPage()->mainFrame()));
+}
+
void InjectedScriptHost::discardInjectedScripts()
{
IdToInjectedScriptMap::iterator end = m_idToInjectedScript.end();
@@ -174,14 +194,14 @@ InspectorDOMAgent* InjectedScriptHost::inspectorDOMAgent()
{
if (!m_inspectorController)
return 0;
- return m_inspectorController->m_domAgent.get();
+ return m_inspectorController->domAgent();
}
InspectorFrontend* InjectedScriptHost::frontend()
{
if (!m_inspectorController)
return 0;
- return m_inspectorController->m_frontend.get();
+ return m_inspectorController->frontend();
}
String InjectedScriptHost::injectedScriptSource()
diff --git a/Source/WebCore/inspector/InjectedScriptHost.h b/Source/WebCore/inspector/InjectedScriptHost.h
index e9c09aa..108f118 100644
--- a/Source/WebCore/inspector/InjectedScriptHost.h
+++ b/Source/WebCore/inspector/InjectedScriptHost.h
@@ -44,6 +44,7 @@ class Database;
class InjectedScript;
class InspectorDOMAgent;
class InspectorFrontend;
+class InspectorObject;
class Node;
class ScriptObject;
class Storage;
@@ -58,6 +59,9 @@ public:
~InjectedScriptHost();
+ // Part of the protocol.
+ void evaluateOnSelf(const String& functionBody, PassRefPtr<InspectorArray> argumentsArray, RefPtr<InspectorValue>* result);
+
InspectorController* inspectorController() { return m_inspectorController; }
void disconnectController() { m_inspectorController = 0; }
@@ -84,6 +88,8 @@ public:
pair<long, ScriptObject> injectScript(const String& source, ScriptState*);
InjectedScript injectedScriptFor(ScriptState*);
InjectedScript injectedScriptForId(long);
+ InjectedScript injectedScriptForObjectId(InspectorObject* objectId);
+ InjectedScript injectedScriptForMainFrame();
void discardInjectedScripts();
void releaseWrapperObjectGroup(long injectedScriptId, const String& objectGroup);
diff --git a/Source/WebCore/inspector/InjectedScriptSource.js b/Source/WebCore/inspector/InjectedScriptSource.js
index 90797fb..3aa24a6 100644
--- a/Source/WebCore/inspector/InjectedScriptSource.js
+++ b/Source/WebCore/inspector/InjectedScriptSource.js
@@ -60,7 +60,9 @@ InjectedScript.prototype = {
this._objectGroups[objectGroupName] = group;
}
group.push(id);
- objectId = this._serializeObjectId(id, objectGroupName);
+ objectId = { injectedScriptId: injectedScriptId,
+ id: id,
+ groupName: objectGroupName };
}
return InjectedScript.RemoteObject.fromObject(object, objectId, abbreviate);
} catch (e) {
@@ -68,18 +70,9 @@ InjectedScript.prototype = {
}
},
- _serializeObjectId: function(id, groupName)
- {
- return injectedScriptId + ":" + id + ":" + groupName;
- },
-
_parseObjectId: function(objectId)
{
- var tokens = objectId.split(":");
- var parsedObjectId = {};
- parsedObjectId.id = parseInt(tokens[1]);
- parsedObjectId.groupName = tokens[2];
- return parsedObjectId;
+ return eval("(" + objectId + ")");
},
releaseWrapperObjectGroup: function(objectGroupName)
@@ -103,26 +96,11 @@ InjectedScript.prototype = {
return result;
},
- getPrototypes: function(nodeId)
- {
- this.releaseWrapperObjectGroup("prototypes");
- var node = this._nodeForId(nodeId);
- if (!node)
- return false;
-
- var result = [];
- var prototype = node;
- do {
- result.push(this._wrapObject(prototype, "prototypes"));
- prototype = prototype.__proto__;
- } while (prototype)
- return result;
- },
-
getProperties: function(objectId, ignoreHasOwnProperty, abbreviate)
{
var parsedObjectId = this._parseObjectId(objectId);
var object = this._objectForId(parsedObjectId);
+
if (!this._isDefined(object))
return false;
var properties = [];
@@ -208,29 +186,14 @@ InjectedScript.prototype = {
return Object.keys(propertyNameSet);
},
- getCompletions: function(expression, includeInspectorCommandLineAPI, callFrameId)
+ getCompletions: function(expression, includeInspectorCommandLineAPI)
{
var props = {};
try {
- var expressionResult;
- // Evaluate on call frame if call frame id is available.
- if (typeof callFrameId === "number") {
- var callFrame = this._callFrameForId(callFrameId);
- if (!callFrame)
- return props;
- if (expression)
- expressionResult = this._evaluateOn(callFrame.evaluate, callFrame, expression, true);
- else {
- // Evaluate into properties in scope of the selected call frame.
- var scopeChain = callFrame.scopeChain;
- for (var i = 0; i < scopeChain.length; ++i)
- this._populatePropertyNames(scopeChain[i], props);
- }
- } else {
- if (!expression)
- expression = "this";
- expressionResult = this._evaluateOn(inspectedWindow.eval, inspectedWindow, expression, false);
- }
+ if (!expression)
+ expression = "this";
+ var expressionResult = this._evaluateOn(inspectedWindow.eval, inspectedWindow, expression, false);
+
if (typeof expressionResult === "object")
this._populatePropertyNames(expressionResult, props);
@@ -243,6 +206,34 @@ InjectedScript.prototype = {
return props;
},
+ getCompletionsOnCallFrame: function(callFrameId, expression, includeInspectorCommandLineAPI)
+ {
+ var props = {};
+ try {
+ var callFrame = this._callFrameForId(callFrameId);
+ if (!callFrame)
+ return props;
+
+ if (expression) {
+ var expressionResult = this._evaluateOn(callFrame.evaluate, callFrame, expression, true);
+ if (typeof expressionResult === "object")
+ this._populatePropertyNames(expressionResult, props);
+ } else {
+ // Evaluate into properties in scope of the selected call frame.
+ var scopeChain = callFrame.scopeChain;
+ for (var i = 0; i < scopeChain.length; ++i)
+ this._populatePropertyNames(scopeChain[i], props);
+ }
+
+ if (includeInspectorCommandLineAPI) {
+ for (var prop in this._commandLineAPI)
+ props[prop] = true;
+ }
+ } catch(e) {
+ }
+ return props;
+ },
+
evaluate: function(expression, objectGroup)
{
return this._evaluateAndWrap(inspectedWindow.eval, inspectedWindow, expression, objectGroup, false);
@@ -300,7 +291,7 @@ InjectedScript.prototype = {
return result;
},
- evaluateInCallFrame: function(callFrameId, code, objectGroup)
+ evaluateOnCallFrame: function(callFrameId, code, objectGroup)
{
var callFrame = this._callFrameForId(callFrameId);
if (!callFrame)
@@ -308,10 +299,12 @@ InjectedScript.prototype = {
return this._evaluateAndWrap(callFrame.evaluate, callFrame, code, objectGroup, true);
},
- _callFrameForId: function(id)
+ _callFrameForId: function(callFrameId)
{
+ var parsedCallFrameId = eval("(" + callFrameId + ")");
+ var ordinal = parsedCallFrameId.ordinal;
var callFrame = InjectedScriptHost.currentCallFrame();
- while (--id >= 0 && callFrame)
+ while (--ordinal >= 0 && callFrame)
callFrame = callFrame.caller;
return callFrame;
},
@@ -323,9 +316,9 @@ InjectedScript.prototype = {
return InjectedScriptHost.nodeForId(nodeId);
},
- _objectForId: function(parsedObjectId)
+ _objectForId: function(objectId)
{
- return this._idToWrappedObject[parsedObjectId.id];
+ return this._idToWrappedObject[objectId.id];
},
resolveNode: function(nodeId)
@@ -342,12 +335,29 @@ InjectedScript.prototype = {
var node = this._nodeForId(nodeId);
if (!node)
return false;
+ properties = eval("(" + properties + ")");
var result = {};
for (var i = 0; i < properties.length; ++i)
result[properties[i]] = node[properties[i]];
return result;
},
+ getNodePrototypes: function(nodeId)
+ {
+ this.releaseWrapperObjectGroup("prototypes");
+ var node = this._nodeForId(nodeId);
+ if (!node)
+ return false;
+
+ var result = [];
+ var prototype = node;
+ do {
+ result.push(this._wrapObject(prototype, "prototypes"));
+ prototype = prototype.__proto__;
+ } while (prototype)
+ return result;
+ },
+
pushNodeToFrontend: function(objectId)
{
var parsedObjectId = this._parseObjectId(objectId);
@@ -359,8 +369,8 @@ InjectedScript.prototype = {
evaluateOnSelf: function(funcBody, args)
{
- var func = window.eval("(" + funcBody + ")");
- return func.apply(this, args || []);
+ var func = eval("(" + funcBody + ")");
+ return func.apply(this, eval("(" + args + ")") || []);
},
_isDefined: function(object)
@@ -536,15 +546,15 @@ InjectedScript.RemoteObject.fromObject = function(object, objectId, abbreviate)
}
}
-InjectedScript.CallFrameProxy = function(id, callFrame)
+InjectedScript.CallFrameProxy = function(ordinal, callFrame)
{
- this.id = id;
+ this.id = { ordinal: ordinal, injectedScriptId: injectedScriptId };
this.type = callFrame.type;
this.functionName = (this.type === "function" ? callFrame.functionName : "");
this.sourceID = callFrame.sourceID;
this.line = callFrame.line;
+ this.column = callFrame.column;
this.scopeChain = this._wrapScopeChain(callFrame);
- this.worldId = injectedScriptId;
}
InjectedScript.CallFrameProxy.prototype = {
diff --git a/Source/WebCore/inspector/Inspector.idl b/Source/WebCore/inspector/Inspector.idl
index 6c2cc2e..79b33f6 100644
--- a/Source/WebCore/inspector/Inspector.idl
+++ b/Source/WebCore/inspector/Inspector.idl
@@ -36,13 +36,8 @@ module core {
// generic Inspector's methods
///////////////////////////////////////////////////////////////////////
- // HUGE FIXME: we need to expose InjectedScript methods here. Or document InjectedScript capabilities.
- [domain=Inspector] void dispatchOnInjectedScript(in long injectedScriptId, in String methodName, in String arguments, out Value result, out boolean isException);
[domain=Inspector] void addScriptToEvaluateOnLoad(in String scriptSource);
[domain=Inspector] void removeAllScriptsToEvaluateOnLoad();
- [domain=Inspector] void releaseWrapperObjectGroup(in long injectedScriptId, in String objectGroup);
- [domain=Inspector] void getInspectorState(out Object state);
- [domain=Inspector] void setMonitoringXHREnabled(in boolean enable, out boolean newState);
[domain=Inspector] void reloadPage();
[domain=Inspector] void populateScriptObjects();
@@ -73,6 +68,22 @@ module core {
[domain=Inspector] void deleteCookie(in String cookieName, in String domain);
///////////////////////////////////////////////////////////////////////
+ // Runtime
+ ///////////////////////////////////////////////////////////////////////
+
+ [domain=Runtime] void evaluate(in String expression, in String objectGroup, out Value result);
+ [domain=Runtime] void getCompletions(in String expression, in boolean includeInspectorCommandLineAPI, out Value result);
+ [domain=Runtime] void getProperties(in Object objectId, in boolean ignoreHasOwnProperty, in boolean abbreviate, out Value result);
+ [domain=Runtime] void setPropertyValue(in Object objectId, in String propertyName, in String expression, out Value result);
+ [domain=Runtime] void releaseWrapperObjectGroup(in long injectedScriptId, in String objectGroup);
+
+ ///////////////////////////////////////////////////////////////////////
+ // Injected Script
+ ///////////////////////////////////////////////////////////////////////
+
+ [domain=InjectedScript] void evaluateOnSelf(in String functionBody, in Array argumentsArray, out Value result);
+
+ ///////////////////////////////////////////////////////////////////////
// Console API
///////////////////////////////////////////////////////////////////////
@@ -82,6 +93,8 @@ module core {
[notify, domain=Console] void updateConsoleMessageRepeatCount(out unsigned long count);
[domain=Console] void clearConsoleMessages();
[notify, domain=Console] void consoleMessagesCleared();
+ [domain=Console] void setMonitoringXHREnabled(in boolean enabled);
+ [notify, domain=Console] void monitoringXHRStateChanged(out boolean enabled);
///////////////////////////////////////////////////////////////////////
// Network API
@@ -89,8 +102,8 @@ module core {
[domain=Network] void cachedResources(out Object resources);
[domain=Network] void resourceContent(in unsigned long frameId, in String url, in boolean base64Encode, out String content);
- [notify, domain=Network] void frameDetachedFromParent(out unsigned long frameId);
+ [notify, domain=Network] void frameDetachedFromParent(out unsigned long frameId);
[notify, domain=Network] void identifierForInitialRequest(out long identifier, out String url, out Object loader, out Value callStack);
[notify, domain=Network] void willSendRequest(out long identifier, out double time, out Object request, out Object redirectResponse);
[notify, domain=Network] void markResourceAsCached(out long identifier);
@@ -112,10 +125,11 @@ module core {
// Database API
///////////////////////////////////////////////////////////////////////
- [notify, domain=Database] void addDatabase(out Object database);
- [notify, domain=Database] void selectDatabase(out int databaseId);
[domain=Database] void getDatabaseTableNames(in long databaseId, out Array tableNames);
[domain=Database] void executeSQL(in long databaseId, in String query, out boolean success, out long transactionId);
+
+ [notify, domain=Database] void addDatabase(out Object database);
+ [notify, domain=Database] void selectDatabase(out int databaseId);
[notify, domain=Database] void sqlTransactionSucceeded(out long transactionId, out Value columnNames, out Value values);
[notify, domain=Database] void sqlTransactionFailed(out long transactionId, out Value sqlError);
#endif
@@ -177,6 +191,10 @@ module core {
[domain=DOM] void performSearch(in String query, in boolean runSynchronously);
[domain=DOM] void searchCanceled();
[domain=DOM] void pushNodeByPathToFrontend(in String path, out long nodeId);
+ [domain=DOM] void resolveNode(in long nodeId, out Value result);
+ [domain=DOM] void getNodeProperties(in long nodeId, in Array propertiesArray, out Value result);
+ [domain=DOM] void getNodePrototypes(in long nodeId, out Value result);
+ [domain=DOM] void pushNodeToFrontend(in Object objectId, out Value result);
[notify, domain=DOM] void setDocument(out Value root); // FIXME: should be requested from the front-end as getDocument.
[notify, domain=DOM] void attributesUpdated(out long id, out Array attributes);
@@ -224,12 +242,12 @@ module core {
[domain=Inspector] void enableDebugger(in boolean always);
[domain=Inspector] void disableDebugger(in boolean always);
- [domain=Inspector] void setStickyBreakpoints(in Object breakpoints);
+ [domain=Inspector] void setAllBrowserBreakpoints(in Object breakpoints);
[notify, domain=Debugger] void debuggerWasEnabled();
[notify, domain=Debugger] void debuggerWasDisabled();
- [notify, domain=Debugger] void parsedScriptSource(out String sourceID, out String url, out int lineOffset, out int columnOffset, out int scriptWorldType);
+ [notify, domain=Debugger] void parsedScriptSource(out String sourceID, out String url, out int lineOffset, out int columnOffset, out int length, out int scriptWorldType);
[notify, domain=Debugger] void failedToParseScriptSource(out String url, out String data, out int firstLine, out int errorLine, out String errorMessage);
[domain=Debugger] void activateBreakpoints();
@@ -251,13 +269,16 @@ module core {
[domain=Debugger] void pause();
[notify, domain=Debugger] void pausedScript(out Object details);
[domain=Debugger] void resume();
- [notify, domain=Debugger] void resumedScript(); // FIXME: Make this out parameter fo resume if possible.
-
- [domain=Debugger] void setPauseOnExceptionsState(in long pauseOnExceptionsState, out long newState);
+ [notify, domain=Debugger] void resumedScript(); // FIXME: Make this out parameter of resume if possible.
[domain=Debugger] void editScriptSource(in String sourceID, in String newContent, out boolean success, out String result, out Value newCallFrames);
[domain=Debugger] void getScriptSource(in String sourceID, out String scriptSource);
+ [domain=Debugger] void setPauseOnExceptionsState(in long pauseOnExceptionsState, out long newState);
+
+ [domain=Debugger] void evaluateOnCallFrame(in Object callFrameId, in String expression, in String objectGroup, out Value result);
+ [domain=Debugger] void getCompletionsOnCallFrame(in Object callFrameId, in String expression, in boolean includeInspectorCommandLineAPI, out Value result);
+
[notify, domain=Debugger] void breakpointResolved(out String breakpointId, out String sourceID, out unsigned int lineNumber, out String condition, out boolean enabled, out unsigned int originalLineNumber);
#if defined(ENABLE_WORKERS) && ENABLE_WORKERS
@@ -269,7 +290,7 @@ module core {
// Profiler API
///////////////////////////////////////////////////////////////////////
- [domain=Inspector] void enableProfiler(in boolean always); // FIXME: preferrable with Inspector domain, dispatched on backend.
+ [domain=Inspector] void enableProfiler(in boolean always);
[domain=Inspector] void disableProfiler(in boolean always);
[notify, domain=Profiler] void profilerWasEnabled();
[notify, domain=Profiler] void profilerWasDisabled();
diff --git a/Source/WebCore/inspector/InspectorApplicationCacheAgent.h b/Source/WebCore/inspector/InspectorApplicationCacheAgent.h
index 3d9e494..ac0acbf 100644
--- a/Source/WebCore/inspector/InspectorApplicationCacheAgent.h
+++ b/Source/WebCore/inspector/InspectorApplicationCacheAgent.h
@@ -41,7 +41,8 @@ class InspectorObject;
class InspectorValue;
class ResourceResponse;
-class InspectorApplicationCacheAgent : public Noncopyable {
+class InspectorApplicationCacheAgent {
+ WTF_MAKE_NONCOPYABLE(InspectorApplicationCacheAgent); WTF_MAKE_FAST_ALLOCATED;
public:
InspectorApplicationCacheAgent(InspectorController* inspectorController, InspectorFrontend* frontend);
~InspectorApplicationCacheAgent() { }
diff --git a/Source/WebCore/inspector/InspectorBrowserDebuggerAgent.cpp b/Source/WebCore/inspector/InspectorBrowserDebuggerAgent.cpp
index a33bacc..023dc49 100644
--- a/Source/WebCore/inspector/InspectorBrowserDebuggerAgent.cpp
+++ b/Source/WebCore/inspector/InspectorBrowserDebuggerAgent.cpp
@@ -71,9 +71,71 @@ InspectorBrowserDebuggerAgent::~InspectorBrowserDebuggerAgent()
{
}
+void InspectorBrowserDebuggerAgent::inspectedURLChanged(const KURL& url)
+{
+ m_eventListenerBreakpoints.clear();
+ m_XHRBreakpoints.clear();
+ m_hasXHRBreakpointWithEmptyURL = false;
+
+ RefPtr<InspectorObject> allBreakpoints = m_inspectorController->state()->getObject(InspectorState::browserBreakpoints);
+ KURL urlCopy = url;
+ urlCopy.removeFragmentIdentifier();
+ RefPtr<InspectorArray> breakpoints = allBreakpoints->getArray(urlCopy);
+ if (!breakpoints)
+ return;
+ for (unsigned i = 0; i < breakpoints->length(); ++i)
+ restoreStickyBreakpoint(breakpoints->get(i)->asObject());
+}
+
+void InspectorBrowserDebuggerAgent::restoreStickyBreakpoint(PassRefPtr<InspectorObject> breakpoint)
+{
+ DEFINE_STATIC_LOCAL(String, eventListenerBreakpointType, ("EventListener"));
+ DEFINE_STATIC_LOCAL(String, javaScriptBreakpointType, ("JS"));
+ DEFINE_STATIC_LOCAL(String, xhrBreakpointType, ("XHR"));
+
+ if (!breakpoint)
+ return;
+ String type;
+ if (!breakpoint->getString("type", &type))
+ return;
+ bool enabled;
+ if (!breakpoint->getBoolean("enabled", &enabled))
+ return;
+ RefPtr<InspectorObject> condition = breakpoint->getObject("condition");
+ if (!condition)
+ return;
+
+ if (type == eventListenerBreakpointType) {
+ if (!enabled)
+ return;
+ String eventName;
+ if (!condition->getString("eventName", &eventName))
+ return;
+ setEventListenerBreakpoint(eventName);
+ } else if (type == javaScriptBreakpointType && m_inspectorController->debuggerAgent()) {
+ String url;
+ if (!condition->getString("url", &url))
+ return;
+ double lineNumber;
+ if (!condition->getNumber("lineNumber", &lineNumber))
+ return;
+ String javaScriptCondition;
+ if (!condition->getString("condition", &javaScriptCondition))
+ return;
+ m_inspectorController->debuggerAgent()->setStickyBreakpoint(url, static_cast<unsigned>(lineNumber), javaScriptCondition, enabled);
+ } else if (type == xhrBreakpointType) {
+ if (!enabled)
+ return;
+ String url;
+ if (!condition->getString("url", &url))
+ return;
+ setXHRBreakpoint(url);
+ }
+}
+
void InspectorBrowserDebuggerAgent::discardBindings()
{
- m_breakpoints.clear();
+ m_domBreakpoints.clear();
}
void InspectorBrowserDebuggerAgent::setEventListenerBreakpoint(const String& eventName)
@@ -88,8 +150,8 @@ void InspectorBrowserDebuggerAgent::removeEventListenerBreakpoint(const String&
void InspectorBrowserDebuggerAgent::didInsertDOMNode(Node* node)
{
- if (m_breakpoints.size()) {
- uint32_t mask = m_breakpoints.get(InspectorDOMAgent::innerParentNode(node));
+ if (m_domBreakpoints.size()) {
+ uint32_t mask = m_domBreakpoints.get(InspectorDOMAgent::innerParentNode(node));
uint32_t inheritableTypesMask = (mask | (mask >> domBreakpointDerivedTypeShift)) & inheritableDOMBreakpointTypesMask;
if (inheritableTypesMask)
updateSubtreeBreakpoints(node, inheritableTypesMask, true);
@@ -98,16 +160,16 @@ void InspectorBrowserDebuggerAgent::didInsertDOMNode(Node* node)
void InspectorBrowserDebuggerAgent::didRemoveDOMNode(Node* node)
{
- if (m_breakpoints.size()) {
+ if (m_domBreakpoints.size()) {
// Remove subtree breakpoints.
- m_breakpoints.remove(node);
+ m_domBreakpoints.remove(node);
Vector<Node*> stack(1, InspectorDOMAgent::innerFirstChild(node));
do {
Node* node = stack.last();
stack.removeLast();
if (!node)
continue;
- m_breakpoints.remove(node);
+ m_domBreakpoints.remove(node);
stack.append(InspectorDOMAgent::innerFirstChild(node));
stack.append(InspectorDOMAgent::innerNextSibling(node));
} while (!stack.isEmpty());
@@ -116,12 +178,12 @@ void InspectorBrowserDebuggerAgent::didRemoveDOMNode(Node* node)
void InspectorBrowserDebuggerAgent::setDOMBreakpoint(long nodeId, long type)
{
- Node* node = m_inspectorController->m_domAgent->nodeForId(nodeId);
+ Node* node = m_inspectorController->domAgent()->nodeForId(nodeId);
if (!node)
return;
uint32_t rootBit = 1 << type;
- m_breakpoints.set(node, m_breakpoints.get(node) | rootBit);
+ m_domBreakpoints.set(node, m_domBreakpoints.get(node) | rootBit);
if (rootBit & inheritableDOMBreakpointTypesMask) {
for (Node* child = InspectorDOMAgent::innerFirstChild(node); child; child = InspectorDOMAgent::innerNextSibling(child))
updateSubtreeBreakpoints(child, rootBit, true);
@@ -130,16 +192,16 @@ void InspectorBrowserDebuggerAgent::setDOMBreakpoint(long nodeId, long type)
void InspectorBrowserDebuggerAgent::removeDOMBreakpoint(long nodeId, long type)
{
- Node* node = m_inspectorController->m_domAgent->nodeForId(nodeId);
+ Node* node = m_inspectorController->domAgent()->nodeForId(nodeId);
if (!node)
return;
uint32_t rootBit = 1 << type;
- uint32_t mask = m_breakpoints.get(node) & ~rootBit;
+ uint32_t mask = m_domBreakpoints.get(node) & ~rootBit;
if (mask)
- m_breakpoints.set(node, mask);
+ m_domBreakpoints.set(node, mask);
else
- m_breakpoints.remove(node);
+ m_domBreakpoints.remove(node);
if ((rootBit & inheritableDOMBreakpointTypesMask) && !(mask & (rootBit << domBreakpointDerivedTypeShift))) {
for (Node* child = InspectorDOMAgent::innerFirstChild(node); child; child = InspectorDOMAgent::innerNextSibling(child))
@@ -149,7 +211,7 @@ void InspectorBrowserDebuggerAgent::removeDOMBreakpoint(long nodeId, long type)
void InspectorBrowserDebuggerAgent::willInsertDOMNode(Node*, Node* parent)
{
- InspectorDebuggerAgent* debuggerAgent = m_inspectorController->m_debuggerAgent.get();
+ InspectorDebuggerAgent* debuggerAgent = m_inspectorController->debuggerAgent();
if (!debuggerAgent)
return;
@@ -163,7 +225,7 @@ void InspectorBrowserDebuggerAgent::willInsertDOMNode(Node*, Node* parent)
void InspectorBrowserDebuggerAgent::willRemoveDOMNode(Node* node)
{
- InspectorDebuggerAgent* debuggerAgent = m_inspectorController->m_debuggerAgent.get();
+ InspectorDebuggerAgent* debuggerAgent = m_inspectorController->debuggerAgent();
if (!debuggerAgent)
return;
@@ -182,7 +244,7 @@ void InspectorBrowserDebuggerAgent::willRemoveDOMNode(Node* node)
void InspectorBrowserDebuggerAgent::willModifyDOMAttr(Element* element)
{
- InspectorDebuggerAgent* debuggerAgent = m_inspectorController->m_debuggerAgent.get();
+ InspectorDebuggerAgent* debuggerAgent = m_inspectorController->debuggerAgent();
if (!debuggerAgent)
return;
@@ -202,7 +264,7 @@ void InspectorBrowserDebuggerAgent::descriptionForDOMEvent(Node* target, long br
if ((1 << breakpointType) & inheritableDOMBreakpointTypesMask) {
// For inheritable breakpoint types, target node isn't always the same as the node that owns a breakpoint.
// Target node may be unknown to frontend, so we need to push it first.
- long targetNodeId = m_inspectorController->m_domAgent->pushNodePathToFrontend(target);
+ long targetNodeId = m_inspectorController->domAgent()->pushNodePathToFrontend(target);
ASSERT(targetNodeId);
description->setNumber("targetNodeId", targetNodeId);
@@ -210,7 +272,7 @@ void InspectorBrowserDebuggerAgent::descriptionForDOMEvent(Node* target, long br
if (!insertion)
breakpointOwner = InspectorDOMAgent::innerParentNode(target);
ASSERT(breakpointOwner);
- while (!(m_breakpoints.get(breakpointOwner) & (1 << breakpointType))) {
+ while (!(m_domBreakpoints.get(breakpointOwner) & (1 << breakpointType))) {
breakpointOwner = InspectorDOMAgent::innerParentNode(breakpointOwner);
ASSERT(breakpointOwner);
}
@@ -219,7 +281,7 @@ void InspectorBrowserDebuggerAgent::descriptionForDOMEvent(Node* target, long br
description->setBoolean("insertion", insertion);
}
- long breakpointOwnerNodeId = m_inspectorController->m_domAgent->pushNodePathToFrontend(breakpointOwner);
+ long breakpointOwnerNodeId = m_inspectorController->domAgent()->pushNodePathToFrontend(breakpointOwner);
ASSERT(breakpointOwnerNodeId);
description->setNumber("nodeId", breakpointOwnerNodeId);
description->setNumber("type", breakpointType);
@@ -229,18 +291,18 @@ bool InspectorBrowserDebuggerAgent::hasBreakpoint(Node* node, long type)
{
uint32_t rootBit = 1 << type;
uint32_t derivedBit = rootBit << domBreakpointDerivedTypeShift;
- return m_breakpoints.get(node) & (rootBit | derivedBit);
+ return m_domBreakpoints.get(node) & (rootBit | derivedBit);
}
void InspectorBrowserDebuggerAgent::updateSubtreeBreakpoints(Node* node, uint32_t rootMask, bool set)
{
- uint32_t oldMask = m_breakpoints.get(node);
+ uint32_t oldMask = m_domBreakpoints.get(node);
uint32_t derivedMask = rootMask << domBreakpointDerivedTypeShift;
uint32_t newMask = set ? oldMask | derivedMask : oldMask & ~derivedMask;
if (newMask)
- m_breakpoints.set(node, newMask);
+ m_domBreakpoints.set(node, newMask);
else
- m_breakpoints.remove(node);
+ m_domBreakpoints.remove(node);
uint32_t newRootMask = rootMask & ~newMask;
if (!newRootMask)
@@ -252,7 +314,7 @@ void InspectorBrowserDebuggerAgent::updateSubtreeBreakpoints(Node* node, uint32_
void InspectorBrowserDebuggerAgent::pauseOnNativeEventIfNeeded(const String& categoryType, const String& eventName, bool synchronous)
{
- InspectorDebuggerAgent* debuggerAgent = m_inspectorController->m_debuggerAgent.get();
+ InspectorDebuggerAgent* debuggerAgent = m_inspectorController->debuggerAgent();
if (!debuggerAgent)
return;
@@ -287,7 +349,7 @@ void InspectorBrowserDebuggerAgent::removeXHRBreakpoint(const String& url)
void InspectorBrowserDebuggerAgent::willSendXMLHttpRequest(const String& url)
{
- InspectorDebuggerAgent* debuggerAgent = m_inspectorController->m_debuggerAgent.get();
+ InspectorDebuggerAgent* debuggerAgent = m_inspectorController->debuggerAgent();
if (!debuggerAgent)
return;
@@ -313,13 +375,6 @@ void InspectorBrowserDebuggerAgent::willSendXMLHttpRequest(const String& url)
debuggerAgent->breakProgram(NativeBreakpointDebuggerEventType, eventData.release());
}
-void InspectorBrowserDebuggerAgent::clearForPageNavigation()
-{
- m_eventListenerBreakpoints.clear();
- m_XHRBreakpoints.clear();
- m_hasXHRBreakpointWithEmptyURL = false;
-}
-
} // namespace WebCore
#endif // ENABLE(INSPECTOR) && ENABLE(JAVASCRIPT_DEBUGGER)
diff --git a/Source/WebCore/inspector/InspectorBrowserDebuggerAgent.h b/Source/WebCore/inspector/InspectorBrowserDebuggerAgent.h
index 537bda1..0ffa85c 100644
--- a/Source/WebCore/inspector/InspectorBrowserDebuggerAgent.h
+++ b/Source/WebCore/inspector/InspectorBrowserDebuggerAgent.h
@@ -46,9 +46,11 @@ namespace WebCore {
class Element;
class InspectorController;
class InspectorObject;
+class KURL;
class Node;
-class InspectorBrowserDebuggerAgent : public Noncopyable {
+class InspectorBrowserDebuggerAgent {
+ WTF_MAKE_NONCOPYABLE(InspectorBrowserDebuggerAgent);
public:
static PassOwnPtr<InspectorBrowserDebuggerAgent> create(InspectorController* inspectorController)
{
@@ -57,6 +59,8 @@ public:
virtual ~InspectorBrowserDebuggerAgent();
+ void inspectedURLChanged(const KURL&);
+
// BrowserDebugger API for InspectorFrontend
void setXHRBreakpoint(const String& url);
void removeXHRBreakpoint(const String& url);
@@ -74,17 +78,18 @@ public:
void willSendXMLHttpRequest(const String& url);
void pauseOnNativeEventIfNeeded(const String& categoryType, const String& eventName, bool synchronous);
- void clearForPageNavigation();
private:
InspectorBrowserDebuggerAgent(InspectorController*);
+ void restoreStickyBreakpoint(PassRefPtr<InspectorObject> breakpoint);
+
void descriptionForDOMEvent(Node* target, long breakpointType, bool insertion, InspectorObject* description);
void updateSubtreeBreakpoints(Node*, uint32_t rootMask, bool set);
bool hasBreakpoint(Node*, long type);
void discardBindings();
InspectorController* m_inspectorController;
- HashMap<Node*, uint32_t> m_breakpoints;
+ HashMap<Node*, uint32_t> m_domBreakpoints;
HashSet<String> m_eventListenerBreakpoints;
HashSet<String> m_XHRBreakpoints;
bool m_hasXHRBreakpointWithEmptyURL;
diff --git a/Source/WebCore/inspector/InspectorCSSAgent.cpp b/Source/WebCore/inspector/InspectorCSSAgent.cpp
index 725a26d..bacf741 100644
--- a/Source/WebCore/inspector/InspectorCSSAgent.cpp
+++ b/Source/WebCore/inspector/InspectorCSSAgent.cpp
@@ -349,6 +349,8 @@ void InspectorCSSAgent::addRule2(const long contextNodeId, const String& selecto
return;
InspectorStyleSheet* inspectorStyleSheet = viaInspectorStyleSheet(node->document(), true);
+ if (!inspectorStyleSheet)
+ return;
CSSStyleRule* newRule = inspectorStyleSheet->addRule(selector);
if (!newRule)
return;
@@ -447,8 +449,17 @@ InspectorStyleSheet* InspectorCSSAgent::viaInspectorStyleSheet(Document* documen
RefPtr<Element> styleElement = document->createElement("style", ec);
if (!ec)
styleElement->setAttribute("type", "text/css", ec);
- if (!ec)
- document->head()->appendChild(styleElement, ec);
+ if (!ec) {
+ ContainerNode* targetNode;
+ // HEAD is absent in ImageDocuments, for example.
+ if (document->head())
+ targetNode = document->head();
+ else if (document->body())
+ targetNode = document->body();
+ else
+ return 0;
+ targetNode->appendChild(styleElement, ec);
+ }
if (ec)
return 0;
StyleSheetList* styleSheets = document->styleSheets();
diff --git a/Source/WebCore/inspector/InspectorConsoleAgent.cpp b/Source/WebCore/inspector/InspectorConsoleAgent.cpp
index a543cb2..2c837f3 100644
--- a/Source/WebCore/inspector/InspectorConsoleAgent.cpp
+++ b/Source/WebCore/inspector/InspectorConsoleAgent.cpp
@@ -33,6 +33,7 @@
#include "InspectorController.h"
#include "InspectorDOMAgent.h"
#include "InspectorFrontend.h"
+#include "InspectorSettings.h"
#include "InspectorState.h"
#include "ResourceError.h"
#include "ResourceResponse.h"
@@ -49,9 +50,8 @@ namespace WebCore {
static const unsigned maximumConsoleMessages = 1000;
static const unsigned expireConsoleMessagesStep = 100;
-InspectorConsoleAgent::InspectorConsoleAgent(InspectorController* inspectorController, InspectorState* state)
+InspectorConsoleAgent::InspectorConsoleAgent(InspectorController* inspectorController)
: m_inspectorController(inspectorController)
- , m_state(state)
, m_frontend(0)
, m_previousMessage(0)
, m_expiredConsoleMessageCount(0)
@@ -165,7 +165,7 @@ void InspectorConsoleAgent::resourceRetrievedByXMLHttpRequest(const String& url,
{
if (!m_inspectorController->enabled())
return;
- if (m_state->getBoolean(InspectorState::monitoringXHR))
+ if (m_inspectorController->state()->getBoolean(InspectorState::monitoringXHR))
addMessageToConsole(JSMessageSource, LogMessageType, LogMessageLevel, "XHR finished loading: \"" + url + "\".", sendLineNumber, sendURL);
}
@@ -191,11 +191,21 @@ void InspectorConsoleAgent::didFailLoading(unsigned long identifier, const Resou
addConsoleMessage(new ConsoleMessage(OtherMessageSource, NetworkErrorMessageType, ErrorMessageLevel, message, error.failingURL(), identifier));
}
+void InspectorConsoleAgent::setMonitoringXHREnabled(bool enabled)
+{
+ m_inspectorController->state()->setBoolean(InspectorState::monitoringXHR, enabled);
+ m_inspectorController->settings()->setBoolean(InspectorSettings::MonitoringXHREnabled, enabled);
+ if (m_frontend)
+ m_frontend->monitoringXHRStateChanged(enabled);
+}
+
void InspectorConsoleAgent::setConsoleMessagesEnabled(bool enabled)
{
- m_state->setBoolean(InspectorState::consoleMessagesEnabled, enabled);
- if (!m_inspectorController->enabled())
+ m_inspectorController->state()->setBoolean(InspectorState::consoleMessagesEnabled, enabled);
+ if (!enabled || !m_frontend)
return;
+
+ m_frontend->monitoringXHRStateChanged(m_inspectorController->state()->getBoolean(InspectorState::monitoringXHR));
if (m_expiredConsoleMessageCount)
m_frontend->updateConsoleMessageExpiredCount(m_expiredConsoleMessageCount);
unsigned messageCount = m_consoleMessages.size();
@@ -210,12 +220,12 @@ void InspectorConsoleAgent::addConsoleMessage(PassOwnPtr<ConsoleMessage> console
if (m_previousMessage && m_previousMessage->isEqual(consoleMessage.get())) {
m_previousMessage->incrementCount();
- if (m_state->getBoolean(InspectorState::consoleMessagesEnabled) && m_frontend)
+ if (m_inspectorController->state()->getBoolean(InspectorState::consoleMessagesEnabled) && m_frontend)
m_previousMessage->updateRepeatCountInConsole(m_frontend);
} else {
m_previousMessage = consoleMessage.get();
m_consoleMessages.append(consoleMessage);
- if (m_state->getBoolean(InspectorState::consoleMessagesEnabled) && m_frontend)
+ if (m_inspectorController->state()->getBoolean(InspectorState::consoleMessagesEnabled) && m_frontend)
m_previousMessage->addToFrontend(m_frontend, m_inspectorController->injectedScriptHost());
}
diff --git a/Source/WebCore/inspector/InspectorConsoleAgent.h b/Source/WebCore/inspector/InspectorConsoleAgent.h
index 97fcb3f..411f709 100644
--- a/Source/WebCore/inspector/InspectorConsoleAgent.h
+++ b/Source/WebCore/inspector/InspectorConsoleAgent.h
@@ -46,9 +46,10 @@ class ScriptArguments;
class ScriptCallStack;
class ScriptProfile;
-class InspectorConsoleAgent : public Noncopyable {
+class InspectorConsoleAgent {
+ WTF_MAKE_NONCOPYABLE(InspectorConsoleAgent);
public:
- InspectorConsoleAgent(InspectorController*, InspectorState*);
+ InspectorConsoleAgent(InspectorController*);
~InspectorConsoleAgent();
void setConsoleMessagesEnabled(bool enabled, bool* newState);
@@ -70,13 +71,13 @@ public:
void addProfileFinishedMessageToConsole(PassRefPtr<ScriptProfile>, unsigned lineNumber, const String& sourceURL);
void addStartProfilingMessageToConsole(const String& title, unsigned lineNumber, const String& sourceURL);
#endif
+ void setMonitoringXHREnabled(bool enabled);
private:
void setConsoleMessagesEnabled(bool);
void addConsoleMessage(PassOwnPtr<ConsoleMessage>);
InspectorController* m_inspectorController;
- InspectorState* m_state;
InspectorFrontend* m_frontend;
ConsoleMessage* m_previousMessage;
Vector<OwnPtr<ConsoleMessage> > m_consoleMessages;
diff --git a/Source/WebCore/inspector/InspectorController.cpp b/Source/WebCore/inspector/InspectorController.cpp
index 5a139b6..8533a5f 100644
--- a/Source/WebCore/inspector/InspectorController.cpp
+++ b/Source/WebCore/inspector/InspectorController.cpp
@@ -70,6 +70,7 @@
#include "InspectorInstrumentation.h"
#include "InspectorProfilerAgent.h"
#include "InspectorResourceAgent.h"
+#include "InspectorRuntimeAgent.h"
#include "InspectorSettings.h"
#include "InspectorState.h"
#include "InspectorTimelineAgent.h"
@@ -95,6 +96,7 @@
#include "SharedBuffer.h"
#include "TextEncoding.h"
#include "TextIterator.h"
+#include "TextRun.h"
#include "UserGestureIndicator.h"
#include "WindowFeatures.h"
#include <wtf/text/StringConcatenate.h>
@@ -140,7 +142,7 @@ InspectorController::InspectorController(Page* page, InspectorClient* client)
, m_state(new InspectorState(client))
, m_inspectorBackendDispatcher(new InspectorBackendDispatcher(this))
, m_injectedScriptHost(InjectedScriptHost::create(this))
- , m_consoleAgent(new InspectorConsoleAgent(this, m_state.get()))
+ , m_consoleAgent(new InspectorConsoleAgent(this))
#if ENABLE(JAVASCRIPT_DEBUGGER)
, m_attachDebuggerWhenShown(false)
, m_profilerAgent(InspectorProfilerAgent::create(this))
@@ -156,10 +158,6 @@ InspectorController::~InspectorController()
ASSERT(!m_client);
ASSERT(!m_inspectedPage);
ASSERT(!m_highlightedNode);
-
- releaseFrontendLifetimeAgents();
-
- m_injectedScriptHost->disconnectController();
}
void InspectorController::inspectedPageDestroyed()
@@ -177,6 +175,9 @@ void InspectorController::inspectedPageDestroyed()
ASSERT(m_inspectedPage);
m_inspectedPage = 0;
+ releaseFrontendLifetimeAgents();
+ m_injectedScriptHost->disconnectController();
+
m_client->inspectorDestroyed();
m_client = 0;
}
@@ -213,15 +214,6 @@ bool InspectorController::searchingForNodeInPage() const
return m_state->getBoolean(InspectorState::searchingForNode);
}
-void InspectorController::getInspectorState(RefPtr<InspectorObject>* state)
-{
-#if ENABLE(JAVASCRIPT_DEBUGGER)
- if (m_debuggerAgent)
- m_state->setLong(InspectorState::pauseOnExceptionsState, m_debuggerAgent->pauseOnExceptionsState());
-#endif
- *state = m_state->generateStateObjectForFrontend();
-}
-
void InspectorController::restoreInspectorStateFromCookie(const String& inspectorStateCookie)
{
m_state->restoreFromInspectorCookie(inspectorStateCookie);
@@ -229,11 +221,13 @@ void InspectorController::restoreInspectorStateFromCookie(const String& inspecto
if (!m_frontend) {
connectFrontend();
m_frontend->frontendReused();
- m_frontend->inspectedURLChanged(m_inspectedPage->mainFrame()->loader()->url().string());
+ m_frontend->inspectedURLChanged(inspectedURL().string());
m_domAgent->setDocument(m_inspectedPage->mainFrame()->document());
pushDataCollectedOffline();
}
+ m_resourceAgent = InspectorResourceAgent::restore(m_inspectedPage, m_state.get(), m_frontend.get());
+
if (m_state->getBoolean(InspectorState::timelineProfilerEnabled))
startTimelineProfiler();
@@ -381,21 +375,13 @@ void InspectorController::setSearchingForNode(bool enabled, bool* newState)
setSearchingForNode(enabled);
}
-void InspectorController::setMonitoringXHREnabled(bool enabled, bool* newState)
-{
- *newState = enabled;
- m_state->setBoolean(InspectorState::monitoringXHR, enabled);
- m_settings->setBoolean(InspectorSettings::MonitoringXHREnabled, enabled);
-}
-
void InspectorController::connectFrontend()
{
m_openingFrontend = false;
releaseFrontendLifetimeAgents();
m_frontend = new InspectorFrontend(m_client);
- m_domAgent = InspectorDOMAgent::create(m_frontend.get());
- m_resourceAgent = InspectorResourceAgent::create(m_inspectedPage, m_frontend.get());
-
+ m_domAgent = InspectorDOMAgent::create(m_injectedScriptHost.get(), m_frontend.get());
+ m_runtimeAgent = InspectorRuntimeAgent::create(m_injectedScriptHost.get());
m_cssAgent->setDOMAgent(m_domAgent.get());
#if ENABLE(DATABASE)
@@ -412,7 +398,7 @@ void InspectorController::connectFrontend()
m_consoleAgent->setFrontend(m_frontend.get());
// Initialize Web Inspector title.
- m_frontend->inspectedURLChanged(m_inspectedPage->mainFrame()->loader()->url().string());
+ m_frontend->inspectedURLChanged(inspectedURL().string());
#if ENABLE(OFFLINE_WEB_APPLICATIONS)
m_applicationCacheAgent = new InspectorApplicationCacheAgent(this, m_frontend.get());
@@ -501,9 +487,17 @@ void InspectorController::disconnectFrontend()
m_extraHeaders.clear();
}
+InspectorResourceAgent* InspectorController::resourceAgent()
+{
+ if (!m_resourceAgent && m_frontend)
+ m_resourceAgent = InspectorResourceAgent::create(m_inspectedPage, m_state.get(), m_frontend.get());
+ return m_resourceAgent.get();
+}
+
void InspectorController::releaseFrontendLifetimeAgents()
{
m_resourceAgent.clear();
+ m_runtimeAgent.clear();
// This should be invoked prior to m_domAgent destruction.
m_cssAgent->setDOMAgent(0);
@@ -607,7 +601,7 @@ void InspectorController::restoreProfiler(ProfilerRestoreAction action)
if (!ScriptProfiler::isProfilerAlwaysEnabled() && m_settings->getBoolean(InspectorSettings::ProfilerAlwaysEnabled))
enableProfiler();
if (action == ProfilerRestoreResetAgent)
- m_profilerAgent->resetState();
+ m_profilerAgent->resetFrontendProfiles();
#endif
}
@@ -648,8 +642,7 @@ void InspectorController::didCommitLoad(DocumentLoader* loader)
if (m_debuggerAgent) {
m_debuggerAgent->clearForPageNavigation();
if (m_browserDebuggerAgent)
- m_browserDebuggerAgent->clearForPageNavigation();
- restoreStickyBreakpoints();
+ m_browserDebuggerAgent->inspectedURLChanged(inspectedURL());
}
#endif
@@ -988,23 +981,11 @@ void InspectorController::didCloseWebSocket(unsigned long identifier)
#endif // ENABLE(WEB_SOCKETS)
#if ENABLE(JAVASCRIPT_DEBUGGER)
-void InspectorController::addProfile(PassRefPtr<ScriptProfile> prpProfile, unsigned lineNumber, const String& sourceURL)
-{
- if (!enabled())
- return;
- m_profilerAgent->addProfile(prpProfile, lineNumber, sourceURL);
-}
-
bool InspectorController::isRecordingUserInitiatedProfile() const
{
return m_profilerAgent->isRecordingUserInitiatedProfile();
}
-String InspectorController::getCurrentUserInitiatedProfileName(bool incrementProfileNumber)
-{
- return m_profilerAgent->getCurrentUserInitiatedProfileName(incrementProfileNumber);
-}
-
void InspectorController::startUserInitiatedProfiling()
{
if (!enabled())
@@ -1067,7 +1048,7 @@ void InspectorController::enableDebugger(bool always)
m_debuggerAgent = InspectorDebuggerAgent::create(this, m_frontend.get());
m_browserDebuggerAgent = InspectorBrowserDebuggerAgent::create(this);
- restoreStickyBreakpoints();
+ m_browserDebuggerAgent->inspectedURLChanged(inspectedURL());
m_frontend->debuggerWasEnabled();
}
@@ -1097,95 +1078,12 @@ void InspectorController::resume()
m_debuggerAgent->resume();
}
-void InspectorController::setStickyBreakpoints(PassRefPtr<InspectorObject> breakpoints)
+void InspectorController::setAllBrowserBreakpoints(PassRefPtr<InspectorObject> breakpoints)
{
- m_state->setObject(InspectorState::stickyBreakpoints, breakpoints);
-}
-
-void InspectorController::restoreStickyBreakpoints()
-{
- RefPtr<InspectorObject> allBreakpoints = m_state->getObject(InspectorState::stickyBreakpoints);
- KURL url = m_inspectedPage->mainFrame()->loader()->url();
- url.removeFragmentIdentifier();
- RefPtr<InspectorArray> breakpoints = allBreakpoints->getArray(url);
- if (!breakpoints)
- return;
- for (unsigned i = 0; i < breakpoints->length(); ++i)
- restoreStickyBreakpoint(breakpoints->get(i)->asObject());
-}
-
-void InspectorController::restoreStickyBreakpoint(PassRefPtr<InspectorObject> breakpoint)
-{
- DEFINE_STATIC_LOCAL(String, eventListenerBreakpointType, ("EventListener"));
- DEFINE_STATIC_LOCAL(String, javaScriptBreakpointType, ("JS"));
- DEFINE_STATIC_LOCAL(String, xhrBreakpointType, ("XHR"));
-
- if (!breakpoint)
- return;
- String type;
- if (!breakpoint->getString("type", &type))
- return;
- bool enabled;
- if (!breakpoint->getBoolean("enabled", &enabled))
- return;
- RefPtr<InspectorObject> condition = breakpoint->getObject("condition");
- if (!condition)
- return;
-
- if (type == eventListenerBreakpointType && m_browserDebuggerAgent) {
- if (!enabled)
- return;
- String eventName;
- if (!condition->getString("eventName", &eventName))
- return;
- m_browserDebuggerAgent->setEventListenerBreakpoint(eventName);
- } else if (type == javaScriptBreakpointType && m_debuggerAgent) {
- String url;
- if (!condition->getString("url", &url))
- return;
- double lineNumber;
- if (!condition->getNumber("lineNumber", &lineNumber))
- return;
- String javaScriptCondition;
- if (!condition->getString("condition", &javaScriptCondition))
- return;
- m_debuggerAgent->setStickyBreakpoint(url, static_cast<unsigned>(lineNumber), javaScriptCondition, enabled);
- } else if (type == xhrBreakpointType && m_browserDebuggerAgent) {
- if (!enabled)
- return;
- String url;
- if (!condition->getString("url", &url))
- return;
- m_browserDebuggerAgent->setXHRBreakpoint(url);
- }
+ m_state->setObject(InspectorState::browserBreakpoints, breakpoints);
}
#endif
-void InspectorController::dispatchOnInjectedScript(long injectedScriptId, const String& methodName, const String& arguments, RefPtr<InspectorValue>* result, bool* hadException)
-{
- if (!m_frontend)
- return;
-
- // FIXME: explicitly pass injectedScriptId along with node id to the frontend.
- bool injectedScriptIdIsNodeId = injectedScriptId <= 0;
-
- InjectedScript injectedScript;
- if (injectedScriptIdIsNodeId)
- injectedScript = injectedScriptForNodeId(-injectedScriptId);
- else
- injectedScript = injectedScriptHost()->injectedScriptForId(injectedScriptId);
-
- if (injectedScript.hasNoValue())
- return;
-
- injectedScript.dispatch(methodName, arguments, result, hadException);
-}
-
-void InspectorController::releaseWrapperObjectGroup(long injectedScriptId, const String& objectGroup)
-{
- injectedScriptHost()->releaseWrapperObjectGroup(injectedScriptId, objectGroup);
-}
-
void InspectorController::evaluateForTestInFrontend(long callId, const String& script)
{
if (m_frontend)
@@ -1468,27 +1366,6 @@ void InspectorController::openInInspectedWindow(const String& url)
newFrame->loader()->changeLocation(mainFrame->document()->securityOrigin(), newFrame->loader()->completeURL(url), "", false, false);
}
-InjectedScript InspectorController::injectedScriptForNodeId(long id)
-{
-
- Frame* frame = 0;
- if (id) {
- ASSERT(m_domAgent);
- Node* node = m_domAgent->nodeForId(id);
- if (node) {
- Document* document = node->ownerDocument();
- if (document)
- frame = document->frame();
- }
- } else
- frame = m_inspectedPage->mainFrame();
-
- if (frame)
- return m_injectedScriptHost->injectedScriptFor(mainWorldScriptState(frame));
-
- return InjectedScript();
-}
-
void InspectorController::addScriptToEvaluateOnLoad(const String& source)
{
m_scriptsToEvaluateOnLoad.append(source);
@@ -1504,6 +1381,11 @@ void InspectorController::setInspectorExtensionAPI(const String& source)
m_inspectorExtensionAPI = source;
}
+KURL InspectorController::inspectedURL() const
+{
+ return m_inspectedPage->mainFrame()->loader()->url();
+}
+
void InspectorController::reloadPage()
{
// FIXME: Why do we set the user gesture indicator here?
diff --git a/Source/WebCore/inspector/InspectorController.h b/Source/WebCore/inspector/InspectorController.h
index 9cddc56..90a0300 100644
--- a/Source/WebCore/inspector/InspectorController.h
+++ b/Source/WebCore/inspector/InspectorController.h
@@ -72,6 +72,7 @@ class InspectorFrontendClient;
class InspectorObject;
class InspectorProfilerAgent;
class InspectorResourceAgent;
+class InspectorRuntimeAgent;
class InspectorSettings;
class InspectorState;
class InspectorStorageAgent;
@@ -104,7 +105,8 @@ class WebSocketHandshakeRequest;
class WebSocketHandshakeResponse;
#endif
-class InspectorController : public Noncopyable {
+class InspectorController {
+ WTF_MAKE_NONCOPYABLE(InspectorController); WTF_MAKE_FAST_ALLOCATED;
public:
static const char* const ConsolePanel;
static const char* const ElementsPanel;
@@ -123,6 +125,7 @@ public:
bool enabled() const;
Page* inspectedPage() const { return m_inspectedPage; }
+ KURL inspectedURL() const;
void reloadPage();
void restoreInspectorStateFromCookie(const String& inspectorCookie);
@@ -143,9 +146,35 @@ public:
void connectFrontend();
void reuseFrontend();
void disconnectFrontend();
+ InspectorFrontend* frontend() const { return m_frontend.get(); }
+
+ InspectorResourceAgent* resourceAgent();
+
+ InspectorController* inspectorAgent() { return this; }
+ InspectorConsoleAgent* consoleAgent() { return m_consoleAgent.get(); }
+ InspectorCSSAgent* cssAgent() { return m_cssAgent.get(); }
+ InspectorDOMAgent* domAgent() { return m_domAgent.get(); }
+ InjectedScriptHost* injectedScriptAgent() { return m_injectedScriptHost.get(); }
+ InspectorRuntimeAgent* runtimeAgent() { return m_runtimeAgent.get(); }
+ InspectorTimelineAgent* timelineAgent() { return m_timelineAgent.get(); }
+#if ENABLE(DATABASE)
+ InspectorDatabaseAgent* databaseAgent() { return m_databaseAgent.get(); }
+#endif
+#if ENABLE(DOM_STORAGE)
+ InspectorDOMStorageAgent* domStorageAgent() { return m_domStorageAgent.get(); }
+#endif
+#if ENABLE(FILE_SYSTEM)
+ InspectorFileSystemAgent* fileSystemAgent() { return m_fileSystemAgent.get(); }
+#endif
+#if ENABLE(JAVASCRIPT_DEBUGGER)
+ InspectorBrowserDebuggerAgent* browserDebuggerAgent() const { return m_browserDebuggerAgent.get(); }
+ InspectorDebuggerAgent* debuggerAgent() const { return m_debuggerAgent.get(); }
+ InspectorProfilerAgent* profilerAgent() const { return m_profilerAgent.get(); }
+#endif
+#if ENABLE(OFFLINE_WEB_APPLICATIONS)
+ InspectorApplicationCacheAgent* applicationCacheAgent() { return m_applicationCacheAgent.get(); }
+#endif
- InspectorConsoleAgent* consoleAgent() const { return m_consoleAgent.get(); }
- InspectorDOMAgent* domAgent() const { return m_domAgent.get(); }
bool searchingForNodeInPage() const;
void mouseDidMoveOverElement(const HitTestResult&, unsigned modifierFlags);
@@ -162,15 +191,10 @@ public:
void startTimelineProfiler();
void stopTimelineProfiler();
- InspectorTimelineAgent* timelineAgent() { return m_timelineAgent.get(); }
void getCookies(RefPtr<InspectorArray>* cookies, WTF::String* cookiesString);
void deleteCookie(const String& cookieName, const String& domain);
-#if ENABLE(OFFLINE_WEB_APPLICATIONS)
- InspectorApplicationCacheAgent* applicationCacheAgent() { return m_applicationCacheAgent.get(); }
-#endif
-
void mainResourceFiredLoadEvent(DocumentLoader*, const KURL&);
void mainResourceFiredDOMContentEvent(DocumentLoader*, const KURL&);
@@ -204,9 +228,7 @@ public:
void drawElementTitle(GraphicsContext&, const IntRect& boundingBox, const FloatRect& overlayRect, WebCore::Settings*) const;
#if ENABLE(JAVASCRIPT_DEBUGGER)
- void addProfile(PassRefPtr<ScriptProfile>, unsigned lineNumber, const String& sourceURL);
bool isRecordingUserInitiatedProfile() const;
- String getCurrentUserInitiatedProfileName(bool incrementProfileNumber = false);
void startProfiling() { startUserInitiatedProfiling(); }
void startUserInitiatedProfiling();
void stopProfiling() { stopUserInitiatedProfiling(); }
@@ -221,19 +243,12 @@ public:
bool debuggerEnabled() const { return m_debuggerAgent; }
void resume();
- void setStickyBreakpoints(PassRefPtr<InspectorObject> breakpoints);
+ void setAllBrowserBreakpoints(PassRefPtr<InspectorObject>);
#endif
- void setInjectedScriptSource(const String& source);
- void dispatchOnInjectedScript(long injectedScriptId, const String& methodName, const String& arguments, RefPtr<InspectorValue>* result, bool* hadException);
-
// Generic code called from custom implementations.
- void releaseWrapperObjectGroup(long injectedScriptId, const String& objectGroup);
-
void evaluateForTestInFrontend(long testCallId, const String& script);
- InjectedScript injectedScriptForNodeId(long id);
-
void addScriptToEvaluateOnLoad(const String& source);
void removeAllScriptsToEvaluateOnLoad();
void setInspectorExtensionAPI(const String& source);
@@ -243,20 +258,22 @@ public:
void setInspectorAttachedHeight(long height);
long inspectorAttachedHeight() const;
-private:
- friend class InspectorBackend;
- friend class InspectorBackendDispatcher;
- friend class InspectorBrowserDebuggerAgent;
- friend class InspectorInstrumentation;
- friend class InjectedScriptHost;
+ InspectorState* state() { return m_state.get(); }
+ InspectorSettings* settings() { return m_settings.get(); }
- void willSendRequest(ResourceRequest&);
+ // InspectorAgent API
+ void getInspectorState(RefPtr<InspectorObject>* state);
+ void setMonitoringXHREnabled(bool enabled, bool* newState);
+ void populateScriptObjects();
+ // Following are used from InspectorBackend and internally.
+ void setSearchingForNode(bool enabled, bool* newState);
+ void didEvaluateForTestInFrontend(long callId, const String& jsonResult);
+ // InspectorInstrumentation API
void ensureSettingsLoaded();
+ void willSendRequest(ResourceRequest&);
- void getInspectorState(RefPtr<InspectorObject>* state);
-
- void populateScriptObjects();
+private:
void pushDataCollectedOffline();
void restoreDebugger();
enum ProfilerRestoreAction {
@@ -267,27 +284,18 @@ private:
void unbindAllResources();
void setSearchingForNode(bool enabled);
- // Following are used from InspectorBackend and internally.
- void setSearchingForNode(bool enabled, bool* newState);
-
- void setMonitoringXHREnabled(bool enabled, bool* newState);
void releaseFrontendLifetimeAgents();
#if ENABLE(JAVASCRIPT_DEBUGGER)
void toggleRecordButton(bool);
- void restoreStickyBreakpoints();
- void restoreStickyBreakpoint(PassRefPtr<InspectorObject> breakpoint);
#endif
PassRefPtr<InspectorObject> buildObjectForCookie(const Cookie&);
PassRefPtr<InspectorArray> buildArrayForCookies(ListHashSet<Cookie>&);
void focusNode();
-
bool isMainResourceLoader(DocumentLoader* loader, const KURL& requestUrl);
- void didEvaluateForTestInFrontend(long callId, const String& jsonResult);
-
Page* m_inspectedPage;
InspectorClient* m_client;
OwnPtr<InspectorFrontendClient> m_inspectorFrontendClient;
@@ -318,6 +326,7 @@ private:
RefPtr<Node> m_nodeToFocus;
RefPtr<InspectorResourceAgent> m_resourceAgent;
+ OwnPtr<InspectorRuntimeAgent> m_runtimeAgent;
#if ENABLE(DATABASE)
typedef HashMap<int, RefPtr<InspectorDatabaseResource> > DatabaseResourcesMap;
@@ -341,7 +350,6 @@ private:
bool m_attachDebuggerWhenShown;
OwnPtr<InspectorDebuggerAgent> m_debuggerAgent;
OwnPtr<InspectorBrowserDebuggerAgent> m_browserDebuggerAgent;
-
OwnPtr<InspectorProfilerAgent> m_profilerAgent;
#endif
OwnPtr<HTTPHeaderMap> m_extraHeaders;
diff --git a/Source/WebCore/inspector/InspectorDOMAgent.cpp b/Source/WebCore/inspector/InspectorDOMAgent.cpp
index 19ae30d..6e10f09 100644
--- a/Source/WebCore/inspector/InspectorDOMAgent.cpp
+++ b/Source/WebCore/inspector/InspectorDOMAgent.cpp
@@ -59,6 +59,7 @@
#include "FrameTree.h"
#include "HTMLElement.h"
#include "HTMLFrameOwnerElement.h"
+#include "InjectedScriptHost.h"
#include "InspectorFrontend.h"
#include "MutationEvent.h"
#include "Node.h"
@@ -206,8 +207,9 @@ public:
}
-InspectorDOMAgent::InspectorDOMAgent(InspectorFrontend* frontend)
+InspectorDOMAgent::InspectorDOMAgent(InjectedScriptHost* injectedScriptHost, InspectorFrontend* frontend)
: EventListener(InspectorDOMAgentType)
+ , m_injectedScriptHost(injectedScriptHost)
, m_frontend(frontend)
, m_domListener(0)
, m_lastNodeId(1)
@@ -758,6 +760,34 @@ void InspectorDOMAgent::searchCanceled()
m_searchResults.clear();
}
+void InspectorDOMAgent::resolveNode(long nodeId, RefPtr<InspectorValue>* result)
+{
+ InjectedScript injectedScript = injectedScriptForNodeId(nodeId);
+ if (!injectedScript.hasNoValue())
+ injectedScript.resolveNode(nodeId, result);
+}
+
+void InspectorDOMAgent::getNodeProperties(long nodeId, PassRefPtr<InspectorArray> propertiesArray, RefPtr<InspectorValue>* result)
+{
+ InjectedScript injectedScript = injectedScriptForNodeId(nodeId);
+ if (!injectedScript.hasNoValue())
+ injectedScript.getNodeProperties(nodeId, propertiesArray, result);
+}
+
+void InspectorDOMAgent::getNodePrototypes(long nodeId, RefPtr<InspectorValue>* result)
+{
+ InjectedScript injectedScript = injectedScriptForNodeId(nodeId);
+ if (!injectedScript.hasNoValue())
+ injectedScript.getNodePrototypes(nodeId, result);
+}
+
+void InspectorDOMAgent::pushNodeToFrontend(PassRefPtr<InspectorObject> objectId, RefPtr<InspectorValue>* result)
+{
+ InjectedScript injectedScript = m_injectedScriptHost->injectedScriptForObjectId(objectId.get());
+ if (!injectedScript.hasNoValue())
+ injectedScript.pushNodeToFrontend(objectId, result);
+}
+
String InspectorDOMAgent::documentURLString(Document* document) const
{
if (!document || document->url().isNull())
@@ -1112,6 +1142,26 @@ void InspectorDOMAgent::pushNodeByPathToFrontend(const String& path, long* nodeI
*nodeId = pushNodePathToFrontend(node);
}
+InjectedScript InspectorDOMAgent::injectedScriptForNodeId(long nodeId)
+{
+ Frame* frame = 0;
+ if (nodeId) {
+ Node* node = nodeForId(nodeId);
+ if (node) {
+ Document* document = node->ownerDocument();
+ if (document)
+ frame = document->frame();
+ }
+ } else
+ frame = mainFrameDocument()->frame();
+
+ if (frame)
+ return m_injectedScriptHost->injectedScriptFor(mainWorldScriptState(frame));
+
+ return InjectedScript();
+}
+
+
} // namespace WebCore
#endif // ENABLE(INSPECTOR)
diff --git a/Source/WebCore/inspector/InspectorDOMAgent.h b/Source/WebCore/inspector/InspectorDOMAgent.h
index 97175fe..e4edf5d 100644
--- a/Source/WebCore/inspector/InspectorDOMAgent.h
+++ b/Source/WebCore/inspector/InspectorDOMAgent.h
@@ -32,6 +32,8 @@
#include "EventListener.h"
#include "EventTarget.h"
+#include "InjectedScript.h"
+#include "InjectedScriptHost.h"
#include "InspectorValues.h"
#include "NodeList.h"
#include "Timer.h"
@@ -45,164 +47,168 @@
#include <wtf/text/AtomicString.h>
namespace WebCore {
- class ContainerNode;
- class CSSRule;
- class CSSRuleList;
- class CSSStyleDeclaration;
- class CSSStyleRule;
- class CSSStyleSheet;
- class CharacterData;
- class Document;
- class Element;
- class Event;
- class InspectorDOMAgent;
- class InspectorFrontend;
- class MatchJob;
- class NameNodeMap;
- class Node;
- class Page;
+class ContainerNode;
+class CSSRule;
+class CSSRuleList;
+class CSSStyleDeclaration;
+class CSSStyleRule;
+class CSSStyleSheet;
+class CharacterData;
+class Document;
+class Element;
+class Event;
+class InspectorDOMAgent;
+class InspectorFrontend;
+class MatchJob;
+class NameNodeMap;
+class Node;
+class Page;
#if ENABLE(INSPECTOR)
- struct EventListenerInfo {
- EventListenerInfo(Node* node, const AtomicString& eventType, const EventListenerVector& eventListenerVector)
- : node(node)
- , eventType(eventType)
- , eventListenerVector(eventListenerVector)
+struct EventListenerInfo {
+ EventListenerInfo(Node* node, const AtomicString& eventType, const EventListenerVector& eventListenerVector)
+ : node(node)
+ , eventType(eventType)
+ , eventListenerVector(eventListenerVector)
+ {
+ }
+
+ Node* node;
+ const AtomicString eventType;
+ const EventListenerVector eventListenerVector;
+};
+
+class InspectorDOMAgent : public EventListener {
+public:
+ struct DOMListener {
+ virtual ~DOMListener()
{
}
-
- Node* node;
- const AtomicString eventType;
- const EventListenerVector eventListenerVector;
- };
-
- class InspectorDOMAgent : public EventListener {
- public:
- struct DOMListener {
- virtual ~DOMListener()
- {
- }
- virtual void didRemoveDocument(Document*) = 0;
- virtual void didRemoveDOMNode(Node*) = 0;
- virtual void didModifyDOMAttr(Element*) = 0;
- };
-
- static PassRefPtr<InspectorDOMAgent> create(InspectorFrontend* frontend)
- {
- return adoptRef(new InspectorDOMAgent(frontend));
- }
-
- static const InspectorDOMAgent* cast(const EventListener* listener)
- {
- return listener->type() == InspectorDOMAgentType
- ? static_cast<const InspectorDOMAgent*>(listener)
- : 0;
- }
-
- InspectorDOMAgent(InspectorFrontend* frontend);
- ~InspectorDOMAgent();
-
- void reset();
-
- virtual bool operator==(const EventListener& other);
-
- // Methods called from the frontend for DOM nodes inspection.
- void getChildNodes(long nodeId);
- void setAttribute(long elementId, const String& name, const String& value, bool* success);
- void removeAttribute(long elementId, const String& name, bool* success);
- void removeNode(long nodeId, long* outNodeId);
- void changeTagName(long nodeId, const String& tagName, long* newId);
- void getOuterHTML(long nodeId, WTF::String* outerHTML);
- void setOuterHTML(long nodeId, const String& outerHTML, long* newId);
- void setTextNodeValue(long nodeId, const String& value, bool* success);
- void getEventListenersForNode(long nodeId, long* outNodeId, RefPtr<InspectorArray>* listenersArray);
- void addInspectedNode(long nodeId);
- void performSearch(const String& whitespaceTrimmedQuery, bool runSynchronously);
- void searchCanceled();
- bool shouldBreakOnNodeInsertion(Node* node, Node* parent, PassRefPtr<InspectorObject> details);
- bool shouldBreakOnNodeRemoval(Node* node, PassRefPtr<InspectorObject> details);
- bool shouldBreakOnAttributeModification(Element* element, PassRefPtr<InspectorObject> details);
-
- // Methods called from the InspectorInstrumentation.
- void setDocument(Document* document);
- void releaseDanglingNodes();
-
- void didInsertDOMNode(Node*);
- void didRemoveDOMNode(Node*);
- void didModifyDOMAttr(Element*);
- void characterDataModified(CharacterData*);
-
- Node* nodeForId(long nodeId);
- long pushNodePathToFrontend(Node* node);
- void pushChildNodesToFrontend(long nodeId);
- void pushNodeByPathToFrontend(const String& path, long* nodeId);
- long inspectedNode(unsigned long num);
- void copyNode(long nodeId);
- const ListHashSet<RefPtr<Document> >& documents() { return m_documents; }
- void setDOMListener(DOMListener*);
-
- String documentURLString(Document* document) const;
-
- // We represent embedded doms as a part of the same hierarchy. Hence we treat children of frame owners differently.
- // We also skip whitespace text nodes conditionally. Following methods encapsulate these specifics.
- static Node* innerFirstChild(Node*);
- static Node* innerNextSibling(Node*);
- static Node* innerPreviousSibling(Node*);
- static unsigned innerChildNodeCount(Node*);
- static Node* innerParentNode(Node*);
- static bool isWhitespace(Node*);
-
- private:
- void startListeningFrameDocument(Node* frameOwnerNode);
- void startListening(Document* document);
- void stopListening(Document* document);
-
- virtual void handleEvent(ScriptExecutionContext*, Event* event);
-
- // Node-related methods.
- typedef HashMap<RefPtr<Node>, long> NodeToIdMap;
- long bind(Node* node, NodeToIdMap* nodesMap);
- void unbind(Node* node, NodeToIdMap* nodesMap);
-
- bool pushDocumentToFrontend();
-
- bool hasBreakpoint(Node* node, long type);
- void updateSubtreeBreakpoints(Node* root, uint32_t rootMask, bool value);
- void descriptionForDOMEvent(Node* target, long breakpointType, bool insertion, PassRefPtr<InspectorObject> description);
-
- PassRefPtr<InspectorObject> buildObjectForNode(Node* node, int depth, NodeToIdMap* nodesMap);
- PassRefPtr<InspectorArray> buildArrayForElementAttributes(Element* element);
- PassRefPtr<InspectorArray> buildArrayForContainerChildren(Node* container, int depth, NodeToIdMap* nodesMap);
- PassRefPtr<InspectorObject> buildObjectForEventListener(const RegisteredEventListener& registeredEventListener, const AtomicString& eventType, Node* node);
-
- Document* mainFrameDocument() const;
-
- void onMatchJobsTimer(Timer<InspectorDOMAgent>*);
- void reportNodesAsSearchResults(ListHashSet<Node*>& resultCollector);
-
- Node* nodeForPath(const String& path);
- PassRefPtr<InspectorArray> toArray(const Vector<String>& data);
-
- void discardBindings();
-
- InspectorFrontend* m_frontend;
- DOMListener* m_domListener;
- NodeToIdMap m_documentNodeToIdMap;
- // Owns node mappings for dangling nodes.
- Vector<NodeToIdMap*> m_danglingNodeToIdMaps;
- HashMap<long, Node*> m_idToNode;
- HashMap<long, NodeToIdMap*> m_idToNodesMap;
- 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;
- Vector<long> m_inspectedNodes;
+ virtual void didRemoveDocument(Document*) = 0;
+ virtual void didRemoveDOMNode(Node*) = 0;
+ virtual void didModifyDOMAttr(Element*) = 0;
};
-#endif
+ static PassRefPtr<InspectorDOMAgent> create(InjectedScriptHost* injectedScriptHost, InspectorFrontend* frontend)
+ {
+ return adoptRef(new InspectorDOMAgent(injectedScriptHost, frontend));
+ }
+
+ static const InspectorDOMAgent* cast(const EventListener* listener)
+ {
+ return listener->type() == InspectorDOMAgentType
+ ? static_cast<const InspectorDOMAgent*>(listener)
+ : 0;
+ }
+
+ InspectorDOMAgent(InjectedScriptHost*, InspectorFrontend*);
+ ~InspectorDOMAgent();
+
+ void reset();
+
+ virtual bool operator==(const EventListener& other);
+
+ // Methods called from the frontend for DOM nodes inspection.
+ void getChildNodes(long nodeId);
+ void setAttribute(long elementId, const String& name, const String& value, bool* success);
+ void removeAttribute(long elementId, const String& name, bool* success);
+ void removeNode(long nodeId, long* outNodeId);
+ void changeTagName(long nodeId, const String& tagName, long* newId);
+ void getOuterHTML(long nodeId, WTF::String* outerHTML);
+ void setOuterHTML(long nodeId, const String& outerHTML, long* newId);
+ void setTextNodeValue(long nodeId, const String& value, bool* success);
+ void getEventListenersForNode(long nodeId, long* outNodeId, RefPtr<InspectorArray>* listenersArray);
+ void addInspectedNode(long nodeId);
+ void performSearch(const String& whitespaceTrimmedQuery, bool runSynchronously);
+ void searchCanceled();
+ void resolveNode(long nodeId, RefPtr<InspectorValue>* result);
+ void getNodeProperties(long nodeId, PassRefPtr<InspectorArray> propertiesArray, RefPtr<InspectorValue>* result);
+ void getNodePrototypes(long nodeId, RefPtr<InspectorValue>* result);
+ void pushNodeToFrontend(PassRefPtr<InspectorObject> objectId, RefPtr<InspectorValue>* result);
+
+ // Methods called from the InspectorInstrumentation.
+ void setDocument(Document*);
+ void releaseDanglingNodes();
+
+ void didInsertDOMNode(Node*);
+ void didRemoveDOMNode(Node*);
+ void didModifyDOMAttr(Element*);
+ void characterDataModified(CharacterData*);
+
+ Node* nodeForId(long nodeId);
+ long pushNodePathToFrontend(Node*);
+ void pushChildNodesToFrontend(long nodeId);
+ void pushNodeByPathToFrontend(const String& path, long* nodeId);
+ long inspectedNode(unsigned long num);
+ void copyNode(long nodeId);
+ const ListHashSet<RefPtr<Document> >& documents() { return m_documents; }
+ void setDOMListener(DOMListener*);
+
+ String documentURLString(Document*) const;
+
+ // We represent embedded doms as a part of the same hierarchy. Hence we treat children of frame owners differently.
+ // We also skip whitespace text nodes conditionally. Following methods encapsulate these specifics.
+ static Node* innerFirstChild(Node*);
+ static Node* innerNextSibling(Node*);
+ static Node* innerPreviousSibling(Node*);
+ static unsigned innerChildNodeCount(Node*);
+ static Node* innerParentNode(Node*);
+ static bool isWhitespace(Node*);
+
+private:
+ void startListeningFrameDocument(Node* frameOwnerNode);
+ void startListening(Document*);
+ void stopListening(Document*);
+
+ virtual void handleEvent(ScriptExecutionContext*, Event*);
+
+ // Node-related methods.
+ typedef HashMap<RefPtr<Node>, long> NodeToIdMap;
+ long bind(Node*, NodeToIdMap*);
+ void unbind(Node*, NodeToIdMap*);
+
+ bool pushDocumentToFrontend();
+
+ bool hasBreakpoint(Node*, long type);
+ void updateSubtreeBreakpoints(Node* root, uint32_t rootMask, bool value);
+ void descriptionForDOMEvent(Node* target, long breakpointType, bool insertion, PassRefPtr<InspectorObject> description);
+
+ PassRefPtr<InspectorObject> buildObjectForNode(Node*, int depth, NodeToIdMap*);
+ PassRefPtr<InspectorArray> buildArrayForElementAttributes(Element*);
+ PassRefPtr<InspectorArray> buildArrayForContainerChildren(Node* container, int depth, NodeToIdMap* nodesMap);
+ PassRefPtr<InspectorObject> buildObjectForEventListener(const RegisteredEventListener&, const AtomicString& eventType, Node*);
+
+ Document* mainFrameDocument() const;
+
+ void onMatchJobsTimer(Timer<InspectorDOMAgent>*);
+ void reportNodesAsSearchResults(ListHashSet<Node*>& resultCollector);
+
+ Node* nodeForPath(const String& path);
+ PassRefPtr<InspectorArray> toArray(const Vector<String>& data);
+
+ void discardBindings();
+
+ InjectedScript injectedScriptForNodeId(long nodeId);
+
+ InjectedScriptHost* m_injectedScriptHost;
+ InspectorFrontend* m_frontend;
+ DOMListener* m_domListener;
+ NodeToIdMap m_documentNodeToIdMap;
+ // Owns node mappings for dangling nodes.
+ Vector<NodeToIdMap*> m_danglingNodeToIdMaps;
+ HashMap<long, Node*> m_idToNode;
+ HashMap<long, NodeToIdMap*> m_idToNodesMap;
+ 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;
+ Vector<long> m_inspectedNodes;
+};
+
+#endif // ENABLE(INSPECTOR)
} // namespace WebCore
diff --git a/Source/WebCore/inspector/InspectorDebuggerAgent.cpp b/Source/WebCore/inspector/InspectorDebuggerAgent.cpp
index 82c250a..acfbb6e 100644
--- a/Source/WebCore/inspector/InspectorDebuggerAgent.cpp
+++ b/Source/WebCore/inspector/InspectorDebuggerAgent.cpp
@@ -173,9 +173,18 @@ void InspectorDebuggerAgent::setPauseOnExceptionsState(long pauseState, long* ne
*newState = ScriptDebugServer::shared().pauseOnExceptionsState();
}
-long InspectorDebuggerAgent::pauseOnExceptionsState()
+void InspectorDebuggerAgent::evaluateOnCallFrame(PassRefPtr<InspectorObject> callFrameId, const String& expression, const String& objectGroup, RefPtr<InspectorValue>* result)
{
- return ScriptDebugServer::shared().pauseOnExceptionsState();
+ InjectedScript injectedScript = m_inspectorController->injectedScriptHost()->injectedScriptForObjectId(callFrameId.get());
+ if (!injectedScript.hasNoValue())
+ injectedScript.evaluateOnCallFrame(callFrameId, expression, objectGroup, result);
+}
+
+void InspectorDebuggerAgent::getCompletionsOnCallFrame(PassRefPtr<InspectorObject> callFrameId, const String& expression, bool includeInspectorCommandLineAPI, RefPtr<InspectorValue>* result)
+{
+ InjectedScript injectedScript = m_inspectorController->injectedScriptHost()->injectedScriptForObjectId(callFrameId.get());
+ if (!injectedScript.hasNoValue())
+ injectedScript.getCompletionsOnCallFrame(callFrameId, expression, includeInspectorCommandLineAPI, result);
}
void InspectorDebuggerAgent::clearForPageNavigation()
@@ -202,7 +211,7 @@ PassRefPtr<InspectorValue> InspectorDebuggerAgent::currentCallFrames()
void InspectorDebuggerAgent::didParseSource(const String& sourceID, const String& url, const String& data, int lineOffset, int columnOffset, ScriptWorldType worldType)
{
// Don't send script content to the front end until it's really needed.
- m_frontend->parsedScriptSource(sourceID, url, lineOffset, columnOffset, worldType);
+ m_frontend->parsedScriptSource(sourceID, url, lineOffset, columnOffset, data.length(), worldType);
m_scriptIDToContent.set(sourceID, data);
diff --git a/Source/WebCore/inspector/InspectorDebuggerAgent.h b/Source/WebCore/inspector/InspectorDebuggerAgent.h
index 07d2ab9..4cb9f9c 100644
--- a/Source/WebCore/inspector/InspectorDebuggerAgent.h
+++ b/Source/WebCore/inspector/InspectorDebuggerAgent.h
@@ -31,6 +31,7 @@
#define InspectorDebuggerAgent_h
#if ENABLE(JAVASCRIPT_DEBUGGER) && ENABLE(INSPECTOR)
+#include "InjectedScript.h"
#include "ScriptDebugListener.h"
#include "ScriptState.h"
#include <wtf/Forward.h>
@@ -52,22 +53,22 @@ enum DebuggerEventType {
NativeBreakpointDebuggerEventType
};
-class InspectorDebuggerAgent : public ScriptDebugListener, public Noncopyable {
+class InspectorDebuggerAgent : public ScriptDebugListener {
+ WTF_MAKE_NONCOPYABLE(InspectorDebuggerAgent); WTF_MAKE_FAST_ALLOCATED;
public:
static PassOwnPtr<InspectorDebuggerAgent> create(InspectorController*, InspectorFrontend*);
virtual ~InspectorDebuggerAgent();
static bool isDebuggerAlwaysEnabled();
+ // Part of the protocol.
void activateBreakpoints();
void deactivateBreakpoints();
void setStickyBreakpoint(const String& url, unsigned lineNumber, const String& condition, bool enabled);
void setBreakpoint(const String& sourceID, unsigned lineNumber, const String& condition, bool enabled, String* breakpointId, unsigned int* actualLineNumber);
void removeBreakpoint(const String& breakpointId);
-
void editScriptSource(const String& sourceID, const String& newContent, bool* success, String* result, RefPtr<InspectorValue>* newCallFrames);
void getScriptSource(const String& sourceID, String* scriptSource);
-
void schedulePauseOnNextStatement(DebuggerEventType type, PassRefPtr<InspectorValue> data);
void cancelPauseOnNextStatement();
void breakProgram(DebuggerEventType type, PassRefPtr<InspectorValue> data);
@@ -76,9 +77,9 @@ public:
void stepOver();
void stepInto();
void stepOut();
-
void setPauseOnExceptionsState(long pauseState, long* newState);
- long pauseOnExceptionsState();
+ void evaluateOnCallFrame(PassRefPtr<InspectorObject> callFrameId, const String& expression, const String& objectGroup, RefPtr<InspectorValue>* result);
+ void getCompletionsOnCallFrame(PassRefPtr<InspectorObject> callFrameId, const String& expression, bool includeInspectorCommandLineAPI, RefPtr<InspectorValue>* result);
void clearForPageNavigation();
diff --git a/Source/WebCore/inspector/InspectorFrontendClientLocal.h b/Source/WebCore/inspector/InspectorFrontendClientLocal.h
index 9dcaa5a..19f6ad1 100644
--- a/Source/WebCore/inspector/InspectorFrontendClientLocal.h
+++ b/Source/WebCore/inspector/InspectorFrontendClientLocal.h
@@ -41,7 +41,8 @@ class InspectorController;
class InspectorFrontendHost;
class Page;
-class InspectorFrontendClientLocal : public InspectorFrontendClient, public Noncopyable {
+class InspectorFrontendClientLocal : public InspectorFrontendClient {
+ WTF_MAKE_NONCOPYABLE(InspectorFrontendClientLocal); WTF_MAKE_FAST_ALLOCATED;
public:
InspectorFrontendClientLocal(InspectorController*, Page*);
virtual ~InspectorFrontendClientLocal();
diff --git a/Source/WebCore/inspector/InspectorInstrumentation.cpp b/Source/WebCore/inspector/InspectorInstrumentation.cpp
index aa941df..9ae97be 100644
--- a/Source/WebCore/inspector/InspectorInstrumentation.cpp
+++ b/Source/WebCore/inspector/InspectorInstrumentation.cpp
@@ -93,17 +93,17 @@ void InspectorInstrumentation::inspectedPageDestroyedImpl(InspectorController* i
void InspectorInstrumentation::willInsertDOMNodeImpl(InspectorController* inspectorController, Node* node, Node* parent)
{
#if ENABLE(JAVASCRIPT_DEBUGGER)
- if (InspectorBrowserDebuggerAgent* browserDebuggerAgent = inspectorController->m_browserDebuggerAgent.get())
+ if (InspectorBrowserDebuggerAgent* browserDebuggerAgent = inspectorController->browserDebuggerAgent())
browserDebuggerAgent->willInsertDOMNode(node, parent);
#endif
}
void InspectorInstrumentation::didInsertDOMNodeImpl(InspectorController* inspectorController, Node* node)
{
- if (InspectorDOMAgent* domAgent = inspectorController->m_domAgent.get())
+ if (InspectorDOMAgent* domAgent = inspectorController->domAgent())
domAgent->didInsertDOMNode(node);
#if ENABLE(JAVASCRIPT_DEBUGGER)
- if (InspectorBrowserDebuggerAgent* browserDebuggerAgent = inspectorController->m_browserDebuggerAgent.get())
+ if (InspectorBrowserDebuggerAgent* browserDebuggerAgent = inspectorController->browserDebuggerAgent())
browserDebuggerAgent->didInsertDOMNode(node);
#endif
}
@@ -111,7 +111,7 @@ void InspectorInstrumentation::didInsertDOMNodeImpl(InspectorController* inspect
void InspectorInstrumentation::willRemoveDOMNodeImpl(InspectorController* inspectorController, Node* node)
{
#if ENABLE(JAVASCRIPT_DEBUGGER)
- if (InspectorBrowserDebuggerAgent* browserDebuggerAgent = inspectorController->m_browserDebuggerAgent.get())
+ if (InspectorBrowserDebuggerAgent* browserDebuggerAgent = inspectorController->browserDebuggerAgent())
browserDebuggerAgent->willRemoveDOMNode(node);
#endif
}
@@ -119,24 +119,24 @@ void InspectorInstrumentation::willRemoveDOMNodeImpl(InspectorController* inspec
void InspectorInstrumentation::didRemoveDOMNodeImpl(InspectorController* inspectorController, Node* node)
{
#if ENABLE(JAVASCRIPT_DEBUGGER)
- if (InspectorBrowserDebuggerAgent* browserDebuggerAgent = inspectorController->m_browserDebuggerAgent.get())
+ if (InspectorBrowserDebuggerAgent* browserDebuggerAgent = inspectorController->browserDebuggerAgent())
browserDebuggerAgent->didRemoveDOMNode(node);
#endif
- if (InspectorDOMAgent* domAgent = inspectorController->m_domAgent.get())
+ if (InspectorDOMAgent* domAgent = inspectorController->domAgent())
domAgent->didRemoveDOMNode(node);
}
void InspectorInstrumentation::willModifyDOMAttrImpl(InspectorController* inspectorController, Element* element)
{
#if ENABLE(JAVASCRIPT_DEBUGGER)
- if (InspectorBrowserDebuggerAgent* browserDebuggerAgent = inspectorController->m_browserDebuggerAgent.get())
+ if (InspectorBrowserDebuggerAgent* browserDebuggerAgent = inspectorController->browserDebuggerAgent())
browserDebuggerAgent->willModifyDOMAttr(element);
#endif
}
void InspectorInstrumentation::didModifyDOMAttrImpl(InspectorController* inspectorController, Element* element)
{
- if (InspectorDOMAgent* domAgent = inspectorController->m_domAgent.get())
+ if (InspectorDOMAgent* domAgent = inspectorController->domAgent())
domAgent->didModifyDOMAttr(element);
}
@@ -152,14 +152,14 @@ bool InspectorInstrumentation::handleMousePressImpl(InspectorController* inspect
void InspectorInstrumentation::characterDataModifiedImpl(InspectorController* inspectorController, CharacterData* characterData)
{
- if (InspectorDOMAgent* domAgent = inspectorController->m_domAgent.get())
+ if (InspectorDOMAgent* domAgent = inspectorController->domAgent())
domAgent->characterDataModified(characterData);
}
void InspectorInstrumentation::willSendXMLHttpRequestImpl(InspectorController* inspectorController, const String& url)
{
#if ENABLE(JAVASCRIPT_DEBUGGER)
- if (InspectorBrowserDebuggerAgent* browserDebuggerAgent = inspectorController->m_browserDebuggerAgent.get())
+ if (InspectorBrowserDebuggerAgent* browserDebuggerAgent = inspectorController->browserDebuggerAgent())
browserDebuggerAgent->willSendXMLHttpRequest(url);
#endif
}
@@ -433,7 +433,7 @@ void InspectorInstrumentation::didReceiveResourceResponseImpl(const InspectorIns
InspectorController* ic = cookie.first;
if (InspectorResourceAgent* resourceAgent = retrieveResourceAgent(ic))
resourceAgent->didReceiveResponse(identifier, loader, response);
- ic->m_consoleAgent->didReceiveResponse(identifier, response);
+ ic->consoleAgent()->didReceiveResponse(identifier, response);
if (InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(cookie))
timelineAgent->didReceiveResourceResponse();
}
@@ -454,7 +454,7 @@ void InspectorInstrumentation::didFinishLoadingImpl(InspectorController* ic, uns
void InspectorInstrumentation::didFailLoadingImpl(InspectorController* ic, unsigned long identifier, const ResourceError& error)
{
- ic->m_consoleAgent->didFailLoading(identifier, error);
+ ic->consoleAgent()->didFailLoading(identifier, error);
if (InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(ic))
timelineAgent->didFinishLoadingResource(identifier, true, 0);
if (InspectorResourceAgent* resourceAgent = retrieveResourceAgent(ic))
@@ -463,7 +463,7 @@ void InspectorInstrumentation::didFailLoadingImpl(InspectorController* ic, unsig
void InspectorInstrumentation::resourceRetrievedByXMLHttpRequestImpl(InspectorController* ic, unsigned long identifier, const String& sourceString, const String& url, const String& sendURL, unsigned sendLineNumber)
{
- ic->m_consoleAgent->resourceRetrievedByXMLHttpRequest(url, sendURL, sendLineNumber);
+ ic->consoleAgent()->resourceRetrievedByXMLHttpRequest(url, sendURL, sendLineNumber);
if (InspectorResourceAgent* resourceAgent = retrieveResourceAgent(ic))
resourceAgent->setInitialContent(identifier, sourceString, "XHR");
}
@@ -549,9 +549,36 @@ void InspectorInstrumentation::consoleMarkTimelineImpl(InspectorController* insp
#if ENABLE(JAVASCRIPT_DEBUGGER)
void InspectorInstrumentation::addStartProfilingMessageToConsoleImpl(InspectorController* inspectorController, const String& title, unsigned lineNumber, const String& sourceURL)
{
- if (InspectorProfilerAgent* profilerAgent = inspectorController->m_profilerAgent.get())
+ if (InspectorProfilerAgent* profilerAgent = inspectorController->profilerAgent())
profilerAgent->addStartProfilingMessageToConsole(title, lineNumber, sourceURL);
}
+
+void InspectorInstrumentation::addProfileImpl(InspectorController* inspectorController, RefPtr<ScriptProfile> profile, ScriptCallStack* callStack)
+{
+ if (InspectorProfilerAgent* profilerAgent = inspectorController->profilerAgent()) {
+ const ScriptCallFrame& lastCaller = callStack->at(0);
+ profilerAgent->addProfile(profile, lastCaller.lineNumber(), lastCaller.sourceURL());
+ }
+}
+
+bool InspectorInstrumentation::profilerEnabledImpl(InspectorController* inspectorController)
+{
+ if (!inspectorController->enabled())
+ return false;
+
+ InspectorProfilerAgent* profilerAgent = inspectorController->profilerAgent();
+ if (!profilerAgent)
+ return false;
+
+ return profilerAgent->enabled();
+}
+
+String InspectorInstrumentation::getCurrentUserInitiatedProfileNameImpl(InspectorController* inspectorController, bool incrementProfileNumber)
+{
+ if (InspectorProfilerAgent* profilerAgent = inspectorController->profilerAgent())
+ return profilerAgent->getCurrentUserInitiatedProfileName(incrementProfileNumber);
+ return "";
+}
#endif
#if ENABLE(DATABASE)
@@ -624,7 +651,7 @@ bool InspectorInstrumentation::hasFrontend(InspectorController* inspectorControl
void InspectorInstrumentation::pauseOnNativeEventIfNeeded(InspectorController* inspectorController, const String& categoryType, const String& eventName, bool synchronous)
{
#if ENABLE(JAVASCRIPT_DEBUGGER)
- if (InspectorBrowserDebuggerAgent* browserDebuggerAgent = inspectorController->m_browserDebuggerAgent.get())
+ if (InspectorBrowserDebuggerAgent* browserDebuggerAgent = inspectorController->browserDebuggerAgent())
browserDebuggerAgent->pauseOnNativeEventIfNeeded(categoryType, eventName, synchronous);
#endif
}
@@ -632,14 +659,14 @@ void InspectorInstrumentation::pauseOnNativeEventIfNeeded(InspectorController* i
void InspectorInstrumentation::cancelPauseOnNativeEvent(InspectorController* inspectorController)
{
#if ENABLE(JAVASCRIPT_DEBUGGER)
- if (InspectorDebuggerAgent* debuggerAgent = inspectorController->m_debuggerAgent.get())
+ if (InspectorDebuggerAgent* debuggerAgent = inspectorController->debuggerAgent())
debuggerAgent->cancelPauseOnNextStatement();
#endif
}
InspectorTimelineAgent* InspectorInstrumentation::retrieveTimelineAgent(InspectorController* inspectorController)
{
- return inspectorController->m_timelineAgent.get();
+ return inspectorController->timelineAgent();
}
InspectorTimelineAgent* InspectorInstrumentation::retrieveTimelineAgent(const InspectorInstrumentationCookie& cookie)
@@ -652,7 +679,7 @@ InspectorTimelineAgent* InspectorInstrumentation::retrieveTimelineAgent(const In
InspectorResourceAgent* InspectorInstrumentation::retrieveResourceAgent(InspectorController* ic)
{
- return ic->m_resourceAgent.get();
+ return ic->resourceAgent();
}
} // namespace WebCore
diff --git a/Source/WebCore/inspector/InspectorInstrumentation.h b/Source/WebCore/inspector/InspectorInstrumentation.h
index 28867cb..7a7ee43 100644
--- a/Source/WebCore/inspector/InspectorInstrumentation.h
+++ b/Source/WebCore/inspector/InspectorInstrumentation.h
@@ -139,6 +139,9 @@ public:
#if ENABLE(JAVASCRIPT_DEBUGGER)
static void addStartProfilingMessageToConsole(Page*, const String& title, unsigned lineNumber, const String& sourceURL);
+ static void addProfile(Page*, RefPtr<ScriptProfile>, ScriptCallStack*);
+ static bool profilerEnabled(Page*);
+ static String getCurrentUserInitiatedProfileName(Page*, bool incrementProfileNumber);
#endif
#if ENABLE(DATABASE)
@@ -246,6 +249,9 @@ private:
#if ENABLE(JAVASCRIPT_DEBUGGER)
static void addStartProfilingMessageToConsoleImpl(InspectorController*, const String& title, unsigned lineNumber, const String& sourceURL);
+ static void addProfileImpl(InspectorController*, RefPtr<ScriptProfile>, ScriptCallStack*);
+ static bool profilerEnabledImpl(InspectorController*);
+ static String getCurrentUserInitiatedProfileNameImpl(InspectorController*, bool incrementProfileNumber);
#endif
#if ENABLE(DATABASE)
@@ -881,6 +887,32 @@ inline void InspectorInstrumentation::addStartProfilingMessageToConsole(Page* pa
addStartProfilingMessageToConsoleImpl(inspectorController, title, lineNumber, sourceURL);
#endif
}
+
+inline void InspectorInstrumentation::addProfile(Page* page, RefPtr<ScriptProfile> profile, ScriptCallStack* callStack)
+{
+#if ENABLE(INSPECTOR)
+ if (InspectorController* inspectorController = inspectorControllerForPage(page))
+ addProfileImpl(inspectorController, profile, callStack);
+#endif
+}
+
+inline bool InspectorInstrumentation::profilerEnabled(Page* page)
+{
+#if ENABLE(INSPECTOR)
+ if (InspectorController* inspectorController = inspectorControllerForPage(page))
+ return profilerEnabledImpl(inspectorController);
+#endif
+ return false;
+}
+
+inline String InspectorInstrumentation::getCurrentUserInitiatedProfileName(Page* page, bool incrementProfileNumber)
+{
+#if ENABLE(INSPECTOR)
+ if (InspectorController* inspectorController = inspectorControllerForPage(page))
+ return InspectorInstrumentation::getCurrentUserInitiatedProfileNameImpl(inspectorController, incrementProfileNumber);
+#endif
+ return "";
+}
#endif
#if ENABLE(INSPECTOR)
@@ -936,6 +968,7 @@ inline InspectorController* InspectorInstrumentation::inspectorControllerWithFro
}
return 0;
}
+
#endif
} // namespace WebCore
diff --git a/Source/WebCore/inspector/InspectorProfilerAgent.cpp b/Source/WebCore/inspector/InspectorProfilerAgent.cpp
index da9b67d..8c4f28f 100644
--- a/Source/WebCore/inspector/InspectorProfilerAgent.cpp
+++ b/Source/WebCore/inspector/InspectorProfilerAgent.cpp
@@ -88,6 +88,8 @@ void InspectorProfilerAgent::addProfile(PassRefPtr<ScriptProfile> prpProfile, un
void InspectorProfilerAgent::addProfileFinishedMessageToConsole(PassRefPtr<ScriptProfile> prpProfile, unsigned lineNumber, const String& sourceURL)
{
+ if (!m_frontend)
+ return;
RefPtr<ScriptProfile> profile = prpProfile;
String title = profile->title();
String message = makeString("Profile \"webkit-profile://", CPUProfileType, '/', encodeWithURLEscapeSequences(title), '#', String::number(profile->uid()), "\" finished.");
@@ -96,6 +98,8 @@ void InspectorProfilerAgent::addProfileFinishedMessageToConsole(PassRefPtr<Scrip
void InspectorProfilerAgent::addStartProfilingMessageToConsole(const String& title, unsigned lineNumber, const String& sourceURL)
{
+ if (!m_frontend)
+ return;
String message = makeString("Profile \"webkit-profile://", CPUProfileType, '/', encodeWithURLEscapeSequences(title), "#0\" started.");
m_inspectorController->consoleAgent()->addMessageToConsole(JSMessageSource, LogMessageType, LogMessageLevel, message, lineNumber, sourceURL);
}
@@ -211,7 +215,12 @@ void InspectorProfilerAgent::resetState()
m_currentUserInitiatedProfileNumber = 1;
m_nextUserInitiatedProfileNumber = 1;
m_nextUserInitiatedHeapSnapshotNumber = 1;
- if (m_frontend)
+ resetFrontendProfiles();
+}
+
+void InspectorProfilerAgent::resetFrontendProfiles()
+{
+ if (m_frontend && m_profiles.begin() == m_profiles.end())
m_frontend->resetProfiles();
}
diff --git a/Source/WebCore/inspector/InspectorProfilerAgent.h b/Source/WebCore/inspector/InspectorProfilerAgent.h
index e67848d..436ae51 100644
--- a/Source/WebCore/inspector/InspectorProfilerAgent.h
+++ b/Source/WebCore/inspector/InspectorProfilerAgent.h
@@ -47,7 +47,8 @@ class InspectorObject;
class ScriptHeapSnapshot;
class ScriptProfile;
-class InspectorProfilerAgent : public Noncopyable {
+class InspectorProfilerAgent {
+ WTF_MAKE_NONCOPYABLE(InspectorProfilerAgent); WTF_MAKE_FAST_ALLOCATED;
public:
static PassOwnPtr<InspectorProfilerAgent> create(InspectorController*);
virtual ~InspectorProfilerAgent();
@@ -65,6 +66,7 @@ public:
bool isRecordingUserInitiatedProfile() { return m_recordingUserInitiatedProfile; }
void removeProfile(const String& type, unsigned uid);
void resetState();
+ void resetFrontendProfiles();
void setFrontend(InspectorFrontend* frontend) { m_frontend = frontend; }
void startUserInitiatedProfiling();
void stopUserInitiatedProfiling(bool ignoreProfile = false);
diff --git a/Source/WebCore/inspector/InspectorResourceAgent.cpp b/Source/WebCore/inspector/InspectorResourceAgent.cpp
index 6779790..029c79d 100644
--- a/Source/WebCore/inspector/InspectorResourceAgent.cpp
+++ b/Source/WebCore/inspector/InspectorResourceAgent.cpp
@@ -45,6 +45,7 @@
#include "HTMLNames.h"
#include "HTTPHeaderMap.h"
#include "InspectorFrontend.h"
+#include "InspectorState.h"
#include "InspectorValues.h"
#include "KURL.h"
#include "Page.h"
@@ -66,6 +67,13 @@
namespace WebCore {
+PassRefPtr<InspectorResourceAgent> InspectorResourceAgent::restore(Page* page, InspectorState* state, InspectorFrontend* frontend)
+{
+ if (state->getBoolean(InspectorState::resourceAgentEnabled))
+ return create(page, state, frontend);
+ return 0;
+}
+
bool InspectorResourceAgent::resourceContent(Frame* frame, const KURL& url, String* result)
{
if (!frame)
@@ -281,6 +289,7 @@ static void populateObjectWithFrameResources(Frame* frame, PassRefPtr<InspectorO
InspectorResourceAgent::~InspectorResourceAgent()
{
+ m_state->setBoolean(InspectorState::resourceAgentEnabled, false);
}
void InspectorResourceAgent::identifierForInitialRequest(unsigned long identifier, const KURL& url, DocumentLoader* loader)
@@ -476,10 +485,12 @@ void InspectorResourceAgent::resourceContent(unsigned long id, const String& url
}
}
-InspectorResourceAgent::InspectorResourceAgent(Page* page, InspectorFrontend* frontend)
+InspectorResourceAgent::InspectorResourceAgent(Page* page, InspectorState* state, InspectorFrontend* frontend)
: m_page(page)
+ , m_state(state)
, m_frontend(frontend)
{
+ m_state->setBoolean(InspectorState::resourceAgentEnabled, true);
}
} // namespace WebCore
diff --git a/Source/WebCore/inspector/InspectorResourceAgent.h b/Source/WebCore/inspector/InspectorResourceAgent.h
index 1e77d58..6c2df24 100644
--- a/Source/WebCore/inspector/InspectorResourceAgent.h
+++ b/Source/WebCore/inspector/InspectorResourceAgent.h
@@ -49,8 +49,9 @@ class Document;
class DocumentLoader;
class Frame;
class InspectorArray;
-class InspectorObject;
class InspectorFrontend;
+class InspectorObject;
+class InspectorState;
class KURL;
class Page;
class ResourceError;
@@ -65,11 +66,13 @@ class WebSocketHandshakeResponse;
class InspectorResourceAgent : public RefCounted<InspectorResourceAgent> {
public:
- static PassRefPtr<InspectorResourceAgent> create(Page* page, InspectorFrontend* frontend)
+ static PassRefPtr<InspectorResourceAgent> create(Page* page, InspectorState* state, InspectorFrontend* frontend)
{
- return adoptRef(new InspectorResourceAgent(page, frontend));
+ return adoptRef(new InspectorResourceAgent(page, state, frontend));
}
+ static PassRefPtr<InspectorResourceAgent> restore(Page*, InspectorState*, InspectorFrontend*);
+
static bool resourceContent(Frame*, const KURL&, String* result);
static bool resourceContentBase64(Frame*, const KURL&, String* result);
static PassRefPtr<SharedBuffer> resourceData(Frame*, const KURL&, String* textEncodingName);
@@ -103,9 +106,10 @@ public:
void resourceContent(unsigned long frameID, const String& url, bool base64Encode, String* content);
private:
- InspectorResourceAgent(Page* page, InspectorFrontend* frontend);
+ InspectorResourceAgent(Page* page, InspectorState*, InspectorFrontend* frontend);
Page* m_page;
+ InspectorState* m_state;
InspectorFrontend* m_frontend;
};
diff --git a/Source/WebCore/inspector/InspectorRuntimeAgent.cpp b/Source/WebCore/inspector/InspectorRuntimeAgent.cpp
new file mode 100644
index 0000000..0502437
--- /dev/null
+++ b/Source/WebCore/inspector/InspectorRuntimeAgent.cpp
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#include "config.h"
+#include "InspectorRuntimeAgent.h"
+
+#if ENABLE(INSPECTOR)
+
+#include "InjectedScriptHost.h"
+#include "InspectorValues.h"
+
+namespace WebCore {
+
+InspectorRuntimeAgent::InspectorRuntimeAgent(InjectedScriptHost* injectedScriptHost)
+ : m_injectedScriptHost(injectedScriptHost)
+{
+}
+
+InspectorRuntimeAgent::~InspectorRuntimeAgent() { }
+
+void InspectorRuntimeAgent::evaluate(const String& expression, const String& objectGroup, RefPtr<InspectorValue>* result)
+{
+ InjectedScript injectedScript = m_injectedScriptHost->injectedScriptForMainFrame();
+ if (!injectedScript.hasNoValue())
+ injectedScript.evaluate(expression, objectGroup, result);
+}
+
+void InspectorRuntimeAgent::getCompletions(const String& expression, bool includeInspectorCommandLineAPI, RefPtr<InspectorValue>* result)
+{
+ InjectedScript injectedScript = m_injectedScriptHost->injectedScriptForMainFrame();
+ if (!injectedScript.hasNoValue())
+ injectedScript.getCompletions(expression, includeInspectorCommandLineAPI, result);
+}
+
+void InspectorRuntimeAgent::getProperties(PassRefPtr<InspectorObject> objectId, bool ignoreHasOwnProperty, bool abbreviate, RefPtr<InspectorValue>* result)
+{
+ InjectedScript injectedScript = m_injectedScriptHost->injectedScriptForObjectId(objectId.get());
+ if (!injectedScript.hasNoValue())
+ injectedScript.getProperties(objectId, ignoreHasOwnProperty, abbreviate, result);
+}
+
+void InspectorRuntimeAgent::setPropertyValue(PassRefPtr<InspectorObject> objectId, const String& propertyName, const String& expression, RefPtr<InspectorValue>* result)
+{
+ InjectedScript injectedScript = m_injectedScriptHost->injectedScriptForObjectId(objectId.get());
+ if (!injectedScript.hasNoValue())
+ injectedScript.setPropertyValue(objectId, propertyName, expression, result);
+}
+
+void InspectorRuntimeAgent::releaseWrapperObjectGroup(long injectedScriptId, const String& objectGroup)
+{
+ m_injectedScriptHost->releaseWrapperObjectGroup(injectedScriptId, objectGroup);
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(INSPECTOR)
diff --git a/Source/WebCore/inspector/InspectorRuntimeAgent.h b/Source/WebCore/inspector/InspectorRuntimeAgent.h
new file mode 100644
index 0000000..3ac2eed
--- /dev/null
+++ b/Source/WebCore/inspector/InspectorRuntimeAgent.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#ifndef InspectorRuntimeAgent_h
+#define InspectorRuntimeAgent_h
+
+#if ENABLE(INSPECTOR)
+
+#include "InjectedScript.h"
+#include "PlatformString.h"
+
+#include <wtf/Noncopyable.h>
+#include <wtf/PassOwnPtr.h>
+#include <wtf/PassRefPtr.h>
+
+namespace WebCore {
+
+class InjectedScriptHost;
+class InspectorObject;
+class InspectorValue;
+
+class InspectorRuntimeAgent {
+ WTF_MAKE_NONCOPYABLE(InspectorRuntimeAgent);
+public:
+ static PassOwnPtr<InspectorRuntimeAgent> create(InjectedScriptHost* injectedScriptHost)
+ {
+ return adoptPtr(new InspectorRuntimeAgent(injectedScriptHost));
+ }
+
+ ~InspectorRuntimeAgent();
+
+ // Part of the protocol.
+ void evaluate(const String& expression, const String& objectGroup, RefPtr<InspectorValue>* result);
+ void getCompletions(const String& expression, bool includeInspectorCommandLineAPI, RefPtr<InspectorValue>* result);
+ void getProperties(PassRefPtr<InspectorObject> objectId, bool ignoreHasOwnProperty, bool abbreviate, RefPtr<InspectorValue>* result);
+ void setPropertyValue(PassRefPtr<InspectorObject> objectId, const String& propertyName, const String& expression, RefPtr<InspectorValue>* result);
+ void releaseWrapperObjectGroup(long injectedScriptId, const String& objectGroup);
+
+private:
+ InspectorRuntimeAgent(InjectedScriptHost*);
+
+ InjectedScriptHost* m_injectedScriptHost;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(INSPECTOR)
+#endif // InspectorRuntimeAgent_h
diff --git a/Source/WebCore/inspector/InspectorState.cpp b/Source/WebCore/inspector/InspectorState.cpp
index 1b74518..dba9e4d 100644
--- a/Source/WebCore/inspector/InspectorState.cpp
+++ b/Source/WebCore/inspector/InspectorState.cpp
@@ -39,15 +39,13 @@ InspectorState::InspectorState(InspectorClient* client)
: m_client(client)
{
// Pure reload state
- registerBoolean(userInitiatedProfiling, false, String());
- registerBoolean(timelineProfilerEnabled, false, String());
- registerBoolean(searchingForNode, false, String());
- registerObject(stickyBreakpoints, String());
-
- // Should go away
- registerBoolean(consoleMessagesEnabled, false, "consoleMessagesEnabled");
- registerBoolean(monitoringXHR, false, "monitoringXHREnabled");
- registerLong(pauseOnExceptionsState, 0, "pauseOnExceptionsState");
+ registerBoolean(userInitiatedProfiling, false);
+ registerBoolean(timelineProfilerEnabled, false);
+ registerBoolean(searchingForNode, false);
+ registerObject(browserBreakpoints);
+ registerBoolean(consoleMessagesEnabled, false);
+ registerBoolean(monitoringXHR, false);
+ registerBoolean(resourceAgentEnabled, false);
}
void InspectorState::restoreFromInspectorCookie(const String& json)
@@ -70,16 +68,6 @@ void InspectorState::restoreFromInspectorCookie(const String& json)
}
}
-PassRefPtr<InspectorObject> InspectorState::generateStateObjectForFrontend()
-{
- RefPtr<InspectorObject> stateObject = InspectorObject::create();
- for (PropertyMap::iterator i = m_properties.begin(); i != m_properties.end(); ++i) {
- if (i->second.m_frontendAlias.length())
- stateObject->setValue(i->second.m_frontendAlias, i->second.m_value);
- }
- return stateObject.release();
-}
-
void InspectorState::updateCookie()
{
RefPtr<InspectorObject> cookieObject = InspectorObject::create();
@@ -139,31 +127,30 @@ void InspectorState::setObject(InspectorPropertyId id, PassRefPtr<InspectorObjec
updateCookie();
}
-void InspectorState::registerBoolean(InspectorPropertyId propertyId, bool value, const String& frontendAlias)
+void InspectorState::registerBoolean(InspectorPropertyId propertyId, bool value)
{
- m_properties.set(propertyId, Property::create(InspectorBasicValue::create(value), frontendAlias));
+ m_properties.set(propertyId, Property::create(InspectorBasicValue::create(value)));
}
-void InspectorState::registerString(InspectorPropertyId propertyId, const String& value, const String& frontendAlias)
+void InspectorState::registerString(InspectorPropertyId propertyId, const String& value)
{
- m_properties.set(propertyId, Property::create(InspectorString::create(value), frontendAlias));
+ m_properties.set(propertyId, Property::create(InspectorString::create(value)));
}
-void InspectorState::registerLong(InspectorPropertyId propertyId, long value, const String& frontendAlias)
+void InspectorState::registerLong(InspectorPropertyId propertyId, long value)
{
- m_properties.set(propertyId, Property::create(InspectorBasicValue::create((double)value), frontendAlias));
+ m_properties.set(propertyId, Property::create(InspectorBasicValue::create((double)value)));
}
-void InspectorState::registerObject(InspectorPropertyId propertyId, const String& frontendAlias)
+void InspectorState::registerObject(InspectorPropertyId propertyId)
{
- m_properties.set(propertyId, Property::create(InspectorObject::create(), frontendAlias));
+ m_properties.set(propertyId, Property::create(InspectorObject::create()));
}
-InspectorState::Property InspectorState::Property::create(PassRefPtr<InspectorValue> value, const String& frontendAlias)
+InspectorState::Property InspectorState::Property::create(PassRefPtr<InspectorValue> value)
{
Property property;
property.m_value = value;
- property.m_frontendAlias = frontendAlias;
return property;
}
diff --git a/Source/WebCore/inspector/InspectorState.h b/Source/WebCore/inspector/InspectorState.h
index 3142c92..6e12673 100644
--- a/Source/WebCore/inspector/InspectorState.h
+++ b/Source/WebCore/inspector/InspectorState.h
@@ -47,45 +47,42 @@ public:
monitoringXHR = 1,
timelineProfilerEnabled,
searchingForNode,
- pauseOnExceptionsState,
consoleMessagesEnabled,
userInitiatedProfiling,
- stickyBreakpoints,
+ browserBreakpoints,
+ resourceAgentEnabled,
lastPropertyId
};
InspectorState(InspectorClient* client);
- PassRefPtr<InspectorObject> generateStateObjectForFrontend();
void restoreFromInspectorCookie(const String& jsonString);
- String getFrontendAlias(InspectorPropertyId propertyId);
- bool getBoolean(InspectorPropertyId propertyId);
- String getString(InspectorPropertyId propertyId);
- long getLong(InspectorPropertyId propertyId);
- PassRefPtr<InspectorObject> getObject(InspectorPropertyId id);
+ bool getBoolean(InspectorPropertyId);
+ String getString(InspectorPropertyId);
+ long getLong(InspectorPropertyId);
+ PassRefPtr<InspectorObject> getObject(InspectorPropertyId);
void setBoolean(InspectorPropertyId propertyId, bool value) { setValue(propertyId, InspectorBasicValue::create(value)); }
void setString(InspectorPropertyId propertyId, const String& value) { setValue(propertyId, InspectorString::create(value)); }
void setLong(InspectorPropertyId propertyId, long value) { setValue(propertyId, InspectorBasicValue::create((double)value)); }
- void setObject(InspectorPropertyId propertyId, PassRefPtr<InspectorObject> value);
+ void setObject(InspectorPropertyId, PassRefPtr<InspectorObject> value);
private:
void updateCookie();
- void setValue(InspectorPropertyId propertyId, PassRefPtr<InspectorValue> value);
+ void setValue(InspectorPropertyId, PassRefPtr<InspectorValue>);
struct Property {
- static Property create(PassRefPtr<InspectorValue> value, const String& frontendAlias);
- String m_frontendAlias;
+ static Property create(PassRefPtr<InspectorValue> value);
RefPtr<InspectorValue> m_value;
};
typedef HashMap<long, Property> PropertyMap;
PropertyMap m_properties;
- void registerBoolean(InspectorPropertyId propertyId, bool value, const String& frontendAlias);
- void registerString(InspectorPropertyId propertyId, const String& value, const String& frontendAlias);
- void registerLong(InspectorPropertyId propertyId, long value, const String& frontendAlias);
- void registerObject(InspectorPropertyId propertyId, const String& frontendAlias);
+ void registerBoolean(InspectorPropertyId, bool value);
+ void registerString(InspectorPropertyId, const String& value);
+ void registerLong(InspectorPropertyId, long value);
+ void registerObject(InspectorPropertyId);
InspectorClient* m_client;
};
diff --git a/Source/WebCore/inspector/InspectorTimelineAgent.h b/Source/WebCore/inspector/InspectorTimelineAgent.h
index 33e2737..cae5aad 100644
--- a/Source/WebCore/inspector/InspectorTimelineAgent.h
+++ b/Source/WebCore/inspector/InspectorTimelineAgent.h
@@ -70,7 +70,8 @@ enum TimelineRecordType {
ScheduleResourceRequestTimelineRecordType = 20
};
-class InspectorTimelineAgent : ScriptGCEventListener, public Noncopyable {
+class InspectorTimelineAgent : ScriptGCEventListener {
+ WTF_MAKE_NONCOPYABLE(InspectorTimelineAgent); WTF_MAKE_FAST_ALLOCATED;
public:
InspectorTimelineAgent(InspectorFrontend* frontend);
~InspectorTimelineAgent();
diff --git a/Source/WebCore/inspector/InspectorValues.cpp b/Source/WebCore/inspector/InspectorValues.cpp
index 89e9b7c..d1b8093 100644
--- a/Source/WebCore/inspector/InspectorValues.cpp
+++ b/Source/WebCore/inspector/InspectorValues.cpp
@@ -647,6 +647,14 @@ bool InspectorObject::getBoolean(const String& name, bool* output) const
return value->asBoolean(output);
}
+bool InspectorObject::getNumber(const String& name, long* output) const
+{
+ RefPtr<InspectorValue> value = get(name);
+ if (!value)
+ return false;
+ return value->asNumber(output);
+}
+
bool InspectorObject::getNumber(const String& name, double* output) const
{
RefPtr<InspectorValue> value = get(name);
diff --git a/Source/WebCore/inspector/InspectorValues.h b/Source/WebCore/inspector/InspectorValues.h
index 391372e..843f369 100644
--- a/Source/WebCore/inspector/InspectorValues.h
+++ b/Source/WebCore/inspector/InspectorValues.h
@@ -180,6 +180,7 @@ public:
const_iterator find(const String& name) const;
bool getBoolean(const String& name, bool* output) const;
+ bool getNumber(const String& name, long* 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;
diff --git a/Source/WebCore/inspector/JavaScriptCallFrame.idl b/Source/WebCore/inspector/JavaScriptCallFrame.idl
index 225059d..db0e0a6 100644
--- a/Source/WebCore/inspector/JavaScriptCallFrame.idl
+++ b/Source/WebCore/inspector/JavaScriptCallFrame.idl
@@ -43,6 +43,7 @@ module inspector {
readonly attribute JavaScriptCallFrame caller;
readonly attribute long sourceID;
readonly attribute long line;
+ readonly attribute long column;
readonly attribute [CustomGetter] Array scopeChain;
[Custom] unsigned short scopeType(in int scopeIndex);
readonly attribute [CustomGetter] Object thisObject;
diff --git a/Source/WebCore/inspector/front-end/AuditLauncherView.js b/Source/WebCore/inspector/front-end/AuditLauncherView.js
index c140589..df16a41 100644
--- a/Source/WebCore/inspector/front-end/AuditLauncherView.js
+++ b/Source/WebCore/inspector/front-end/AuditLauncherView.js
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Google Inc. All rights reserved.
+ * Copyright (C) 2011 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
@@ -50,60 +50,38 @@ WebInspector.AuditLauncherView = function(runnerCallback)
this._headerElement.className = "no-audits";
this._headerElement.textContent = WebInspector.UIString("No audits to run");
this._contentElement.appendChild(this._headerElement);
+
+ WebInspector.networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.ResourceStarted, this._onResourceStarted, this);
+ WebInspector.networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.ResourceFinished, this._onResourceFinished, this);
}
WebInspector.AuditLauncherView.prototype = {
- get totalResources()
+ _resetResourceCount: function()
{
- return this._totalResources;
+ this._loadedResources = 0;
+ this._totalResources = 0;
},
- set totalResources(x)
+ _onResourceStarted: function(event)
{
- if (this._totalResources === x)
+ var resource = event.data;
+ // Ignore long-living WebSockets for the sake of progress indicator, as we won't be waiting them anyway.
+ if (resource.type === WebInspector.Resource.Type.WebSocket)
return;
- this._totalResources = x;
+ ++this._totalResources;
this._updateResourceProgress();
},
- get loadedResources()
- {
- return this._loadedResources;
- },
-
- set loadedResources(x)
+ _onResourceFinished: function(event)
{
- if (this._loadedResources === x)
+ var resource = event.data;
+ // See resorceStarted for details.
+ if (resource.type === WebInspector.Resource.Type.WebSocket)
return;
- this._loadedResources = x;
+ ++this._loadedResources;
this._updateResourceProgress();
},
- _resetResourceCount: function()
- {
- this.loadedResources = 0;
- this.totalResources = 0;
- },
-
- resourceStarted: function(resource)
- {
- // Ignore long-living WebSockets for the sake of progress indicator, as we won't be waiting them anyway.
- if (resource.type !== WebInspector.Resource.Type.WebSocket)
- ++this.totalResources;
- },
-
- resourceFinished: function(resource)
- {
- // See resorceStarted for details.
- if (resource.type !== WebInspector.Resource.Type.WebSocket)
- ++this.loadedResources;
- },
-
- reset: function()
- {
- this._resetResourceCount();
- },
-
addCategory: function(category)
{
if (!this._sortedCategories.length)
@@ -264,7 +242,7 @@ WebInspector.AuditLauncherView.prototype = {
this._resourceProgressContainer.addStyleClass("hidden");
} else
this._resourceProgressContainer.removeStyleClass("hidden");
- this._resourceProgressTextElement.textContent = WebInspector.UIString("Loading (%d of %d)", this.loadedResources, this.totalResources);
+ this._resourceProgressTextElement.textContent = WebInspector.UIString("Loading (%d of %d)", this._loadedResources, this._totalResources);
},
_updateButton: function()
diff --git a/Source/WebCore/inspector/front-end/AuditRules.js b/Source/WebCore/inspector/front-end/AuditRules.js
index 7aa891f..c2bbcbb 100644
--- a/Source/WebCore/inspector/front-end/AuditRules.js
+++ b/Source/WebCore/inspector/front-end/AuditRules.js
@@ -65,7 +65,7 @@ WebInspector.AuditRules.getDomainToResourcesMap = function(resources, types, nee
WebInspector.AuditRules.evaluateInTargetWindow = function(func, args, callback)
{
- InjectedScriptAccess.getDefault().evaluateOnSelf(func.toString(), args, callback);
+ InspectorBackend.evaluateOnSelf(func.toString(), args, callback);
}
@@ -721,7 +721,7 @@ WebInspector.AuditRules.ImageDimensionsRule.prototype = {
return nodeIds;
}
- WebInspector.AuditRules.evaluateInTargetWindow(pushImageNodes, null, receivedImages);
+ WebInspector.AuditRules.evaluateInTargetWindow(pushImageNodes, [], receivedImages);
}
}
@@ -797,7 +797,7 @@ WebInspector.AuditRules.CssInHeadRule.prototype = {
return found ? urlToViolationsArray : null;
}
- WebInspector.AuditRules.evaluateInTargetWindow(routine, null, evalCallback);
+ WebInspector.AuditRules.evaluateInTargetWindow(routine, [], evalCallback);
}
}
@@ -844,7 +844,7 @@ WebInspector.AuditRules.StylesScriptsOrderRule.prototype = {
return [ lateStyleUrls, cssBeforeInlineCount ];
}
- WebInspector.AuditRules.evaluateInTargetWindow(routine, null, evalCallback.bind(this));
+ WebInspector.AuditRules.evaluateInTargetWindow(routine, [], evalCallback.bind(this));
}
}
diff --git a/Source/WebCore/inspector/front-end/AuditsPanel.js b/Source/WebCore/inspector/front-end/AuditsPanel.js
index c639f47..f3cbfa7 100644
--- a/Source/WebCore/inspector/front-end/AuditsPanel.js
+++ b/Source/WebCore/inspector/front-end/AuditsPanel.js
@@ -96,16 +96,6 @@ WebInspector.AuditsPanel.prototype = {
return this._auditCategoriesById;
},
- resourceStarted: function(resource)
- {
- this._launcherView.resourceStarted(resource);
- },
-
- resourceFinished: function(resource)
- {
- this._launcherView.resourceFinished(resource);
- },
-
addCategory: function(category)
{
this.categoriesById[category.id] = category;
@@ -246,11 +236,6 @@ WebInspector.AuditsPanel.prototype = {
x.show(this.viewsContainerElement);
},
- reset: function()
- {
- this._launcherView.reset();
- },
-
attach: function()
{
WebInspector.Panel.prototype.attach.call(this);
diff --git a/Source/WebCore/inspector/front-end/Breakpoint.js b/Source/WebCore/inspector/front-end/Breakpoint.js
index e5e1768..aa600a7 100644
--- a/Source/WebCore/inspector/front-end/Breakpoint.js
+++ b/Source/WebCore/inspector/front-end/Breakpoint.js
@@ -37,7 +37,6 @@ WebInspector.Breakpoint = function(debuggerModel, breakpointId, sourceID, url, l
this.sourceID = sourceID;
this._enabled = enabled;
this._condition = condition || "";
- this._hit = false;
this._debuggerModel = debuggerModel;
}
@@ -60,52 +59,14 @@ WebInspector.Breakpoint.prototype = {
return this._condition;
},
- get hit()
+ get data()
{
- return this._hit;
- },
-
- set hit(hit)
- {
- this._hit = hit;
- this.dispatchEventToListeners("hit-state-changed");
- },
-
- click: function(event)
- {
- WebInspector.panels.scripts.showSourceLine(this.url, this.line);
- },
-
- compareTo: function(other)
- {
- if (this.url != other.url)
- return this.url < other.url ? -1 : 1;
- if (this.line != other.line)
- return this.line < other.line ? -1 : 1;
- return 0;
- },
-
- populateLabelElement: function(element)
- {
- function didGetSourceLine(text)
- {
- var displayName = this.url ? WebInspector.displayNameForURL(this.url) : WebInspector.UIString("(program)");
- var labelElement = document.createTextNode(displayName + ":" + this.line);
- element.appendChild(labelElement);
-
- var sourceTextElement = document.createElement("div");
- sourceTextElement.textContent = text;
- sourceTextElement.className = "source-text monospace";
- element.appendChild(sourceTextElement);
- }
- var script = this._debuggerModel.scriptForSourceID(this.sourceID);
- script.sourceLine(this.line, didGetSourceLine.bind(this));
+ return { id: this.id, url: this.url, sourceID: this.sourceID, lineNumber: this.line, condition: this.condition };
},
remove: function()
{
this._debuggerModel.removeBreakpoint(this.id);
- this.dispatchEventToListeners("removed");
this.removeAllListeners();
delete this._debuggerModel;
}
diff --git a/Source/WebCore/inspector/front-end/BreakpointManager.js b/Source/WebCore/inspector/front-end/BreakpointManager.js
index 67ef112..d943d5b 100644
--- a/Source/WebCore/inspector/front-end/BreakpointManager.js
+++ b/Source/WebCore/inspector/front-end/BreakpointManager.js
@@ -34,7 +34,7 @@ WebInspector.BreakpointManager = function()
var breakpoints = WebInspector.settings.findSettingForAllProjects("nativeBreakpoints");
for (var projectId in breakpoints)
this._stickyBreakpoints[projectId] = this._validateBreakpoints(breakpoints[projectId]);
- InspectorBackend.setStickyBreakpoints(this._stickyBreakpoints);
+ InspectorBackend.setAllBrowserBreakpoints(this._stickyBreakpoints);
this._breakpoints = {};
this._domBreakpointsRestored = false;
@@ -303,7 +303,7 @@ WebInspector.BreakpointManager.prototype = {
WebInspector.settings.nativeBreakpoints = breakpoints;
this._stickyBreakpoints[WebInspector.settings.projectId] = breakpoints;
- InspectorBackend.setStickyBreakpoints(this._stickyBreakpoints);
+ InspectorBackend.setAllBrowserBreakpoints(this._stickyBreakpoints);
},
_validateBreakpoints: function(persistentBreakpoints)
diff --git a/Source/WebCore/inspector/front-end/BreakpointsSidebarPane.js b/Source/WebCore/inspector/front-end/BreakpointsSidebarPane.js
index 408c5ba..b237ca2 100644
--- a/Source/WebCore/inspector/front-end/BreakpointsSidebarPane.js
+++ b/Source/WebCore/inspector/front-end/BreakpointsSidebarPane.js
@@ -23,7 +23,213 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-WebInspector.BreakpointsSidebarPane = function(title)
+WebInspector.JavaScriptBreakpointsSidebarPane = function(title)
+{
+ WebInspector.SidebarPane.call(this, WebInspector.UIString("Breakpoints"));
+
+ this.listElement = document.createElement("ol");
+ this.listElement.className = "breakpoint-list";
+
+ this.emptyElement = document.createElement("div");
+ this.emptyElement.className = "info";
+ this.emptyElement.textContent = WebInspector.UIString("No Breakpoints");
+
+ this.bodyElement.appendChild(this.emptyElement);
+
+ this._items = {};
+
+ WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.BreakpointAdded, this._breakpointAdded, this);
+ WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.BreakpointRemoved, this._breakpointRemoved, this);
+ WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.DebuggerPaused, this._debuggerPaused, this);
+ WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.DebuggerResumed, this._debuggerResumed, this);
+ WebInspector.breakpointManager.addEventListener(WebInspector.BreakpointManager.Events.ProjectChanged, this._projectChanged, this);
+}
+
+WebInspector.JavaScriptBreakpointsSidebarPane.prototype = {
+ _breakpointAdded: function(event)
+ {
+ var breakpoint = event.data;
+ var breakpointId = breakpoint.id;
+ var data = breakpoint.data;
+
+ var element = document.createElement("li");
+
+ var checkbox = document.createElement("input");
+ checkbox.className = "checkbox-elem";
+ checkbox.type = "checkbox";
+ checkbox.checked = breakpoint.enabled;
+ checkbox.addEventListener("click", this._breakpointItemCheckboxClicked.bind(this, breakpointId), false);
+ element.appendChild(checkbox);
+
+ var label = document.createElement("span");
+ element.appendChild(label);
+
+ element._data = data;
+ var currentElement = this.listElement.firstChild;
+ while (currentElement) {
+ if (currentElement._data && this._compareBreakpoints(currentElement._data, element._data) > 0)
+ break;
+ currentElement = currentElement.nextSibling;
+ }
+ this._addListElement(element, currentElement);
+
+ element.addEventListener("contextmenu", this._contextMenuEventFired.bind(this, breakpointId), true);
+
+ this._setupBreakpointElement(data, element);
+
+ var breakpointItem = {};
+ breakpointItem.data = data;
+ breakpointItem.element = element;
+ breakpointItem.checkbox = checkbox;
+ this._items[breakpointId] = breakpointItem;
+
+ if (!this.expanded)
+ this.expanded = true;
+ },
+
+ _breakpointRemoved: function(event)
+ {
+ var breakpointId = event.data;
+ var breakpointItem = this._items[breakpointId];
+ if (breakpointItem) {
+ delete this._items[breakpointId];
+ this._removeListElement(breakpointItem.element);
+ }
+ },
+
+ _breakpointEnableChanged: function(enabled, event)
+ {
+ var breakpointId = event.data;
+ var breakpointItem = this._items[breakpointId];
+ if (breakpointItem)
+ breakpointItem.checkbox.checked = enabled;
+ },
+
+ _breakpointItemCheckboxClicked: function(breakpointId, event)
+ {
+ this._setBreakpointEnabled(breakpointId, event.target.checked);
+
+ // Breakpoint element may have it's own click handler.
+ event.stopPropagation();
+ },
+
+ _contextMenuEventFired: function(breakpointId, event)
+ {
+ var contextMenu = new WebInspector.ContextMenu();
+ contextMenu.appendItem(WebInspector.UIString("Remove Breakpoint"), this._removeBreakpoint.bind(this, breakpointId));
+ contextMenu.show(event);
+ },
+
+ _debuggerPaused: function(event)
+ {
+ var breakpointId = this._breakpointIdForDebuggerPausedEvent(event.data);
+ if (!breakpointId)
+ return;
+ var breakpointItem = this._items[breakpointId];
+ if (!breakpointItem)
+ return;
+ breakpointItem.element.addStyleClass("breakpoint-hit");
+ this._lastHitBreakpointItem = breakpointItem;
+ },
+
+ _debuggerResumed: function()
+ {
+ if (this._lastHitBreakpointItem) {
+ this._lastHitBreakpointItem.element.removeStyleClass("breakpoint-hit");
+ delete this._lastHitBreakpointItem;
+ }
+ },
+
+ _addListElement: function(element, beforeElement)
+ {
+ if (beforeElement)
+ this.listElement.insertBefore(element, beforeElement);
+ else {
+ if (!this.listElement.firstChild) {
+ this.bodyElement.removeChild(this.emptyElement);
+ this.bodyElement.appendChild(this.listElement);
+ }
+ this.listElement.appendChild(element);
+ }
+ },
+
+ _removeListElement: function(element)
+ {
+ this.listElement.removeChild(element);
+ if (!this.listElement.firstChild) {
+ this.bodyElement.removeChild(this.listElement);
+ this.bodyElement.appendChild(this.emptyElement);
+ }
+ },
+
+ _projectChanged: function()
+ {
+ this.listElement.removeChildren();
+ if (this.listElement.parentElement) {
+ this.bodyElement.removeChild(this.listElement);
+ this.bodyElement.appendChild(this.emptyElement);
+ }
+ this._items = {};
+ },
+
+ _compare: function(x, y)
+ {
+ if (x !== y)
+ return x < y ? -1 : 1;
+ return 0;
+ },
+
+ _compareBreakpoints: function(b1, b2)
+ {
+ return this._compare(b1.url, b2.url) || this._compare(b1.lineNumber, b2.lineNumber);
+ },
+
+ _setupBreakpointElement: function(data, element)
+ {
+ var displayName = data.url ? WebInspector.displayNameForURL(data.url) : WebInspector.UIString("(program)");
+ var labelElement = document.createTextNode(displayName + ":" + data.lineNumber);
+ element.appendChild(labelElement);
+
+ var sourceTextElement = document.createElement("div");
+ sourceTextElement.className = "source-text monospace";
+ element.appendChild(sourceTextElement);
+
+ function didGetSourceLine(text)
+ {
+ sourceTextElement.textContent = text;
+ }
+ var script = WebInspector.debuggerModel.scriptForSourceID(data.sourceID);
+ script.sourceLine(data.lineNumber, didGetSourceLine.bind(this));
+
+ element.addStyleClass("cursor-pointer");
+ var clickHandler = WebInspector.panels.scripts.showSourceLine.bind(WebInspector.panels.scripts, data.url, data.lineNumber);
+ element.addEventListener("click", clickHandler, false);
+ },
+
+ _breakpointIdForDebuggerPausedEvent: function(details)
+ {
+ var callFrame = details.callFrames[0];
+ var breakpoint = WebInspector.debuggerModel.findBreakpoint(callFrame.sourceID, callFrame.line);
+ if (breakpoint)
+ return breakpoint.id;
+ },
+
+ _setBreakpointEnabled: function(breakpointId, enabled)
+ {
+ var breakpoint = WebInspector.debuggerModel.breakpointForId(breakpointId);
+ WebInspector.debuggerModel.removeBreakpoint(breakpointId);
+ WebInspector.debuggerModel.setBreakpoint(breakpoint.sourceID, breakpoint.line, enabled, breakpoint.condition);
+ },
+
+ _removeBreakpoint: function(breakpointId)
+ {
+ WebInspector.debuggerModel.removeBreakpoint(breakpointId);
+ }
+}
+
+WebInspector.JavaScriptBreakpointsSidebarPane.prototype.__proto__ = WebInspector.SidebarPane.prototype;
+
+WebInspector.NativeBreakpointsSidebarPane = function(title)
{
WebInspector.SidebarPane.call(this, title);
@@ -39,7 +245,7 @@ WebInspector.BreakpointsSidebarPane = function(title)
WebInspector.breakpointManager.addEventListener(WebInspector.BreakpointManager.Events.ProjectChanged, this._projectChanged, this);
}
-WebInspector.BreakpointsSidebarPane.prototype = {
+WebInspector.NativeBreakpointsSidebarPane.prototype = {
addBreakpointItem: function(breakpointItem)
{
var element = breakpointItem.element;
@@ -102,11 +308,11 @@ WebInspector.BreakpointsSidebarPane.prototype = {
}
}
-WebInspector.BreakpointsSidebarPane.prototype.__proto__ = WebInspector.SidebarPane.prototype;
+WebInspector.NativeBreakpointsSidebarPane.prototype.__proto__ = WebInspector.SidebarPane.prototype;
WebInspector.XHRBreakpointsSidebarPane = function()
{
- WebInspector.BreakpointsSidebarPane.call(this, WebInspector.UIString("XHR Breakpoints"));
+ WebInspector.NativeBreakpointsSidebarPane.call(this, WebInspector.UIString("XHR Breakpoints"));
function addButtonClicked(event)
{
@@ -123,7 +329,7 @@ WebInspector.XHRBreakpointsSidebarPane = function()
WebInspector.XHRBreakpointsSidebarPane.prototype = {
addBreakpointItem: function(breakpointItem)
{
- WebInspector.BreakpointsSidebarPane.prototype.addBreakpointItem.call(this, breakpointItem);
+ WebInspector.NativeBreakpointsSidebarPane.prototype.addBreakpointItem.call(this, breakpointItem);
breakpointItem._labelElement.addEventListener("dblclick", this._startEditingBreakpoint.bind(this, breakpointItem), false);
},
@@ -166,7 +372,7 @@ WebInspector.XHRBreakpointsSidebarPane.prototype = {
}
}
-WebInspector.XHRBreakpointsSidebarPane.prototype.__proto__ = WebInspector.BreakpointsSidebarPane.prototype;
+WebInspector.XHRBreakpointsSidebarPane.prototype.__proto__ = WebInspector.NativeBreakpointsSidebarPane.prototype;
WebInspector.BreakpointItem = function(breakpoint)
{
diff --git a/Source/WebCore/inspector/front-end/CSSCompletions.js b/Source/WebCore/inspector/front-end/CSSCompletions.js
index e8d7556..f60c297 100644
--- a/Source/WebCore/inspector/front-end/CSSCompletions.js
+++ b/Source/WebCore/inspector/front-end/CSSCompletions.js
@@ -44,7 +44,7 @@ WebInspector.CSSCompletions.prototype = {
return [];
var results = [];
- while (this._values[firstIndex].indexOf(prefix) === 0)
+ while (firstIndex < this._values.length && this._values[firstIndex].indexOf(prefix) === 0)
results.push(this._values[firstIndex++]);
return results;
},
diff --git a/Source/WebCore/inspector/front-end/CSSKeywordCompletions.js b/Source/WebCore/inspector/front-end/CSSKeywordCompletions.js
new file mode 100755
index 0000000..ac62aff
--- /dev/null
+++ b/Source/WebCore/inspector/front-end/CSSKeywordCompletions.js
@@ -0,0 +1,438 @@
+/*
+ * Copyright (C) 2011 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.CSSKeywordCompletions = {
+ forProperty: function(propertyName)
+ {
+ var acceptedKeywords = ["initial"];
+ if (propertyName in this._propertyKeywordMap)
+ acceptedKeywords = acceptedKeywords.concat(this._propertyKeywordMap[propertyName]);
+ if (propertyName in this._colorAwareProperties)
+ acceptedKeywords = acceptedKeywords.concat(WebInspector.CSSKeywordCompletions._colors);
+ if (propertyName in WebInspector.StylesSidebarPane.InheritedProperties)
+ acceptedKeywords.push("inherit");
+ return new WebInspector.CSSCompletions(acceptedKeywords);
+ }
+};
+
+WebInspector.CSSKeywordCompletions._colors = [
+ "aqua", "black", "blue", "fuchsia", "gray", "green", "lime", "maroon", "navy", "olive", "orange", "purple", "red",
+ "silver", "teal", "white", "yellow", "transparent", "currentcolor", "grey", "aliceblue", "antiquewhite",
+ "aquamarine", "azure", "beige", "bisque", "blanchedalmond", "blueviolet", "brown", "burlywood", "cadetblue",
+ "chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "cyan", "darkblue", "darkcyan",
+ "darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange",
+ "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkslategrey",
+ "darkturquoise", "darkviolet", "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "firebrick",
+ "floralwhite", "forestgreen", "gainsboro", "ghostwhite", "gold", "goldenrod", "greenyellow", "honeydew", "hotpink",
+ "indianred", "indigo", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue",
+ "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink",
+ "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "lightsteelblue", "lightyellow",
+ "limegreen", "linen", "magenta", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple", "mediumseagreen",
+ "mediumslateblue", "mediumspringgreen", "mediumturquoise", "mediumvioletred", "midnightblue", "mintcream",
+ "mistyrose", "moccasin", "navajowhite", "oldlace", "olivedrab", "orangered", "orchid", "palegoldenrod", "palegreen",
+ "paleturquoise", "palevioletred", "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue", "rosybrown",
+ "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "skyblue", "slateblue",
+ "slategray", "slategrey", "snow", "springgreen", "steelblue", "tan", "thistle", "tomato", "turquoise", "violet",
+ "wheat", "whitesmoke", "yellowgreen"
+],
+
+WebInspector.CSSKeywordCompletions._colorAwareProperties = [
+ "background", "background-color", "border", "border-color", "border-top", "border-right", "border-bottom",
+ "border-left", "border-top-color", "border-right-color", "border-bottom-color", "border-left-color", "color",
+ "outline", "outline-color", "text-line-through", "text-line-through-color", "text-overline", "text-overline-color",
+ "text-shadow", "text-underline", "text-underline-color", "-webkit-text-emphasis", "-webkit-text-emphasis-color"
+].keySet();
+
+WebInspector.CSSKeywordCompletions._propertyKeywordMap = {
+ "table-layout": [
+ "auto", "fixed"
+ ],
+ "visibility": [
+ "hidden", "visible", "collapse"
+ ],
+ "background-repeat": [
+ "repeat", "repeat-x", "repeat-y", "no-repeat", "space", "round"
+ ],
+ "text-underline": [
+ "none", "dotted", "dashed", "solid", "double", "dot-dash", "dot-dot-dash", "wave"
+ ],
+ "content": [
+ "list-item", "close-quote", "no-close-quote", "no-open-quote", "open-quote"
+ ],
+ "list-style-image": [
+ "none"
+ ],
+ "clear": [
+ "none", "left", "right", "both"
+ ],
+ "text-underline-mode": [
+ "continuous", "skip-white-space"
+ ],
+ "overflow-x": [
+ "hidden", "auto", "visible", "overlay", "scroll"
+ ],
+ "stroke-linejoin": [
+ "round", "miter", "bevel"
+ ],
+ "baseline-shift": [
+ "baseline", "sub", "super"
+ ],
+ "border-bottom-width": [
+ "medium", "thick", "thin"
+ ],
+ "marquee-speed": [
+ "normal", "slow", "fast"
+ ],
+ "margin-top-collapse": [
+ "collapse", "separate", "discard"
+ ],
+ "max-height": [
+ "none"
+ ],
+ "box-orient": [
+ "horizontal", "vertical", "inline-axis", "block-axis"
+ ],
+ "font-stretch": [
+ "normal", "wider", "narrower", "ultra-condensed", "extra-condensed", "condensed", "semi-condensed",
+ "semi-expanded", "expanded", "extra-expanded", "ultra-expanded"
+ ],
+ "-webkit-color-correction": [
+ "default", "srgb"
+ ],
+ "text-underline-style": [
+ "none", "dotted", "dashed", "solid", "double", "dot-dash", "dot-dot-dash", "wave"
+ ],
+ "text-overline-mode": [
+ "continuous", "skip-white-space"
+ ],
+ "-webkit-background-composite": [
+ "highlight", "clear", "copy", "source-over", "source-in", "source-out", "source-atop", "destination-over",
+ "destination-in", "destination-out", "destination-atop", "xor", "plus-darker", "plus-lighter"
+ ],
+ "border-left-width": [
+ "medium", "thick", "thin"
+ ],
+ "-webkit-writing-mode": [
+ "lr", "rl", "tb", "lr-tb", "rl-tb", "tb-rl", "horizontal-tb", "vertical-rl", "vertical-lr", "horizontal-bt"
+ ],
+ "text-line-through-mode": [
+ "continuous", "skip-white-space"
+ ],
+ "border-collapse": [
+ "collapse", "separate"
+ ],
+ "page-break-inside": [
+ "auto", "avoid"
+ ],
+ "border-top-width": [
+ "medium", "thick", "thin"
+ ],
+ "outline-color": [
+ "invert"
+ ],
+ "text-line-through-style": [
+ "none", "dotted", "dashed", "solid", "double", "dot-dash", "dot-dot-dash", "wave"
+ ],
+ "outline-style": [
+ "none", "hidden", "inset", "groove", "ridge", "outset", "dotted", "dashed", "solid", "double"
+ ],
+ "cursor": [
+ "none", "copy", "auto", "crosshair", "default", "pointer", "move", "vertical-text", "cell", "context-menu",
+ "alias", "progress", "no-drop", "not-allowed", "-webkit-zoom-in", "-webkit-zoom-out", "e-resize", "ne-resize",
+ "nw-resize", "n-resize", "se-resize", "sw-resize", "s-resize", "w-resize", "ew-resize", "ns-resize",
+ "nesw-resize", "nwse-resize", "col-resize", "row-resize", "text", "wait", "help", "all-scroll", "-webkit-grab",
+ "-webkit-grabbing"
+ ],
+ "border-width": [
+ "medium", "thick", "thin"
+ ],
+ "size": [
+ "a3", "a4", "a5", "b4", "b5", "landscape", "ledger", "legal", "letter", "portrait"
+ ],
+ "background-size": [
+ "contain", "cover"
+ ],
+ "direction": [
+ "ltr", "rtl"
+ ],
+ "marquee-direction": [
+ "left", "right", "auto", "reverse", "forwards", "backwards", "ahead", "up", "down"
+ ],
+ "enable-background": [
+ "accumulate", "new"
+ ],
+ "float": [
+ "none", "left", "right"
+ ],
+ "overflow-y": [
+ "hidden", "auto", "visible", "overlay", "scroll"
+ ],
+ "margin-bottom-collapse": [
+ "collapse", "separate", "discard"
+ ],
+ "box-reflect": [
+ "left", "right", "above", "below"
+ ],
+ "overflow": [
+ "hidden", "auto", "visible", "overlay", "scroll"
+ ],
+ "text-rendering": [
+ "auto", "optimizespeed", "optimizelegibility", "geometricprecision"
+ ],
+ "text-align": [
+ "-webkit-auto", "left", "right", "center", "justify", "-webkit-left", "-webkit-right", "-webkit-center"
+ ],
+ "list-style-position": [
+ "outside", "inside"
+ ],
+ "margin-bottom": [
+ "auto"
+ ],
+ "color-interpolation": [
+ "linearrgb"
+ ],
+ "background-origin": [
+ "border-box", "content-box", "padding-box"
+ ],
+ "word-wrap": [
+ "normal", "break-word"
+ ],
+ "font-weight": [
+ "normal", "bold", "bolder", "lighter", "100", "200", "300", "400", "500", "600", "700", "800", "900"
+ ],
+ "margin-before-collapse": [
+ "collapse", "separate", "discard"
+ ],
+ "text-overline-width": [
+ "normal", "medium", "auto", "thick", "thin"
+ ],
+ "text-transform": [
+ "none", "capitalize", "uppercase", "lowercase"
+ ],
+ "border-right-style": [
+ "none", "hidden", "inset", "groove", "ridge", "outset", "dotted", "dashed", "solid", "double"
+ ],
+ "border-left-style": [
+ "none", "hidden", "inset", "groove", "ridge", "outset", "dotted", "dashed", "solid", "double"
+ ],
+ "-webkit-text-emphasis": [
+ "circle", "filled", "open", "dot", "double-circle", "triangle", "sesame"
+ ],
+ "font-style": [
+ "italic", "oblique", "normal"
+ ],
+ "speak": [
+ "none", "normal", "spell-out", "digits", "literal-punctuation", "no-punctuation"
+ ],
+ "text-line-through": [
+ "none", "dotted", "dashed", "solid", "double", "dot-dash", "dot-dot-dash", "wave", "continuous",
+ "skip-white-space"
+ ],
+ "color-rendering": [
+ "auto", "optimizespeed", "optimizequality"
+ ],
+ "list-style-type": [
+ "none", "disc", "circle", "square", "decimal", "decimal-leading-zero", "arabic-indic", "binary", "bengali",
+ "cambodian", "khmer", "devanagari", "gujarati", "gurmukhi", "kannada", "lower-hexadecimal", "lao", "malayalam",
+ "mongolian", "myanmar", "octal", "oriya", "persian", "urdu", "telugu", "tibetan", "thai", "upper-hexadecimal",
+ "lower-roman", "upper-roman", "lower-greek", "lower-alpha", "lower-latin", "upper-alpha", "upper-latin", "afar",
+ "ethiopic-halehame-aa-et", "ethiopic-halehame-aa-er", "amharic", "ethiopic-halehame-am-et", "amharic-abegede",
+ "ethiopic-abegede-am-et", "cjk-earthly-branch", "cjk-heavenly-stem", "ethiopic", "ethiopic-halehame-gez",
+ "ethiopic-abegede", "ethiopic-abegede-gez", "hangul-consonant", "hangul", "lower-norwegian", "oromo",
+ "ethiopic-halehame-om-et", "sidama", "ethiopic-halehame-sid-et", "somali", "ethiopic-halehame-so-et", "tigre",
+ "ethiopic-halehame-tig", "tigrinya-er", "ethiopic-halehame-ti-er", "tigrinya-er-abegede",
+ "ethiopic-abegede-ti-er", "tigrinya-et", "ethiopic-halehame-ti-et", "tigrinya-et-abegede",
+ "ethiopic-abegede-ti-et", "upper-greek", "upper-norwegian", "asterisks", "footnotes", "hebrew", "armenian",
+ "lower-armenian", "upper-armenian", "georgian", "cjk-ideographic", "hiragana", "katakana", "hiragana-iroha",
+ "katakana-iroha"
+ ],
+ "-webkit-text-combine": [
+ "none", "horizontal"
+ ],
+ "outline": [
+ "none", "hidden", "inset", "groove", "ridge", "outset", "dotted", "dashed", "solid", "double"
+ ],
+ "font": [
+ "caption", "icon", "menu", "message-box", "small-caption", "-webkit-mini-control", "-webkit-small-control",
+ "-webkit-control", "status-bar", "italic", "oblique", "small-caps", "normal", "bold", "bolder", "lighter",
+ "100", "200", "300", "400", "500", "600", "700", "800", "900", "xx-small", "x-small", "small", "medium",
+ "large", "x-large", "xx-large", "-webkit-xxx-large", "smaller", "larger", "serif", "sans-serif", "cursive",
+ "fantasy", "monospace", "-webkit-body"
+ ],
+ "dominant-baseline": [
+ "middle", "auto", "central", "text-before-edge", "text-after-edge", "ideographic", "alphabetic", "hanging",
+ "mathematical", "use-script", "no-change", "reset-size"
+ ],
+ "display": [
+ "none", "inline", "block", "list-item", "run-in", "compact", "inline-block", "table", "inline-table",
+ "table-row-group", "table-header-group", "table-footer-group", "table-row", "table-column-group",
+ "table-column", "table-cell", "table-caption", "-webkit-box", "-webkit-inline-box", "-wap-marquee"
+ ],
+ "-webkit-text-emphasis-position": [
+ "over", "under"
+ ],
+ "image-rendering": [
+ "auto", "optimizespeed", "optimizequality"
+ ],
+ "alignment-baseline": [
+ "baseline", "middle", "auto", "before-edge", "after-edge", "central", "text-before-edge", "text-after-edge",
+ "ideographic", "alphabetic", "hanging", "mathematical"
+ ],
+ "outline-width": [
+ "medium", "thick", "thin"
+ ],
+ "text-line-through-width": [
+ "normal", "medium", "auto", "thick", "thin"
+ ],
+ "box-align": [
+ "baseline", "center", "stretch", "start", "end"
+ ],
+ "border-right-width": [
+ "medium", "thick", "thin"
+ ],
+ "border-top-style": [
+ "none", "hidden", "inset", "groove", "ridge", "outset", "dotted", "dashed", "solid", "double"
+ ],
+ "line-height": [
+ "normal"
+ ],
+ "text-overflow": [
+ "clip", "ellipsis"
+ ],
+ "box-direction": [
+ "normal", "reverse"
+ ],
+ "margin-after-collapse": [
+ "collapse", "separate", "discard"
+ ],
+ "page-break-before": [
+ "left", "right", "auto", "always", "avoid"
+ ],
+ "-webkit-hyphens": [
+ "none", "auto", "manual"
+ ],
+ "border-image": [
+ "repeat", "stretch"
+ ],
+ "text-decoration": [
+ "blink", "line-through", "overline", "underline"
+ ],
+ "position": [
+ "absolute", "fixed", "relative", "static"
+ ],
+ "font-family": [
+ "serif", "sans-serif", "cursive", "fantasy", "monospace", "-webkit-body"
+ ],
+ "text-overflow-mode": [
+ "clip", "ellipsis"
+ ],
+ "border-bottom-style": [
+ "none", "hidden", "inset", "groove", "ridge", "outset", "dotted", "dashed", "solid", "double"
+ ],
+ "unicode-bidi": [
+ "normal", "bidi-override", "embed"
+ ],
+ "clip-rule": [
+ "nonzero", "evenodd"
+ ],
+ "margin-left": [
+ "auto"
+ ],
+ "margin-top": [
+ "auto"
+ ],
+ "zoom": [
+ "document", "reset"
+ ],
+ "text-overline-style": [
+ "none", "dotted", "dashed", "solid", "double", "dot-dash", "dot-dot-dash", "wave"
+ ],
+ "max-width": [
+ "none"
+ ],
+ "empty-cells": [
+ "hide", "show"
+ ],
+ "pointer-events": [
+ "none", "all", "auto", "visible", "visiblepainted", "visiblefill", "visiblestroke", "painted", "fill", "stroke"
+ ],
+ "letter-spacing": [
+ "normal"
+ ],
+ "background-clip": [
+ "border-box", "content-box", "padding-box"
+ ],
+ "-webkit-font-smoothing": [
+ "none", "auto", "antialiased", "subpixel-antialiased"
+ ],
+ "border": [
+ "none", "hidden", "inset", "groove", "ridge", "outset", "dotted", "dashed", "solid", "double"
+ ],
+ "font-size": [
+ "xx-small", "x-small", "small", "medium", "large", "x-large", "xx-large", "-webkit-xxx-large", "smaller",
+ "larger"
+ ],
+ "font-variant": [
+ "small-caps", "normal"
+ ],
+ "vertical-align": [
+ "baseline", "middle", "sub", "super", "text-top", "text-bottom", "top", "bottom", "-webkit-baseline-middle"
+ ],
+ "marquee-style": [
+ "none", "scroll", "slide", "alternate"
+ ],
+ "white-space": [
+ "normal", "nowrap", "pre", "pre-line", "pre-wrap"
+ ],
+ "text-underline-width": [
+ "normal", "medium", "auto", "thick", "thin"
+ ],
+ "box-lines": [
+ "single", "multiple"
+ ],
+ "page-break-after": [
+ "left", "right", "auto", "always", "avoid"
+ ],
+ "clip-path": [
+ "none"
+ ],
+ "margin": [
+ "auto"
+ ],
+ "marquee-repetition": [
+ "infinite"
+ ],
+ "margin-right": [
+ "auto"
+ ],
+ "-webkit-text-emphasis-style": [
+ "circle", "filled", "open", "dot", "double-circle", "triangle", "sesame"
+ ]
+}
diff --git a/Source/WebCore/inspector/front-end/ConsoleView.js b/Source/WebCore/inspector/front-end/ConsoleView.js
index a40030e..bd08e60 100644
--- a/Source/WebCore/inspector/front-end/ConsoleView.js
+++ b/Source/WebCore/inspector/front-end/ConsoleView.js
@@ -149,6 +149,11 @@ WebInspector.ConsoleView.prototype = {
consoleMessagesCleared: function()
{
console.clearMessages();
+ },
+
+ monitoringXHRStateChanged: function(enabled)
+ {
+ console._monitoringXHREnabled = enabled;
}
}
InspectorBackend.registerDomainDispatcher("Console", dispatcher);
@@ -355,14 +360,11 @@ WebInspector.ConsoleView.prototype = {
// Collect comma separated object properties for the completion.
var includeInspectorCommandLineAPI = (!dotNotation && !bracketNotation);
- var callFrameId = WebInspector.panels.scripts.selectedCallFrameId();
var injectedScriptAccess;
- if (WebInspector.panels.scripts && WebInspector.panels.scripts.paused) {
- var selectedCallFrame = WebInspector.panels.scripts.sidebarPanes.callstack.selectedCallFrame;
- injectedScriptAccess = InjectedScriptAccess.get(selectedCallFrame.worldId);
- } else
- injectedScriptAccess = InjectedScriptAccess.getDefault();
- injectedScriptAccess.getCompletions(expressionString, includeInspectorCommandLineAPI, callFrameId, reportCompletions);
+ if (WebInspector.panels.scripts && WebInspector.panels.scripts.paused)
+ InspectorBackend.getCompletionsOnCallFrame(WebInspector.panels.scripts.selectedCallFrameId(), expressionString, includeInspectorCommandLineAPI, reportCompletions);
+ else
+ InspectorBackend.getCompletions(expressionString, includeInspectorCommandLineAPI, reportCompletions);
},
_reportCompletions: function(bestMatchOnly, completionsReadyCallback, dotNotation, bracketNotation, prefix, result, isException) {
@@ -416,14 +418,9 @@ WebInspector.ConsoleView.prototype = {
return;
}
+ var itemAction = InspectorBackend.setMonitoringXHREnabled.bind(InspectorBackend, !this._monitoringXHREnabled);
var contextMenu = new WebInspector.ContextMenu();
-
- function monitoringXHRWasChanged(newState)
- {
- WebInspector.monitoringXHREnabled = newState;
- }
- var itemAction = InspectorBackend.setMonitoringXHREnabled.bind(InspectorBackend, !WebInspector.monitoringXHREnabled, monitoringXHRWasChanged);
- contextMenu.appendCheckboxItem(WebInspector.UIString("XMLHttpRequest logging"), itemAction, WebInspector.monitoringXHREnabled);
+ contextMenu.appendCheckboxItem(WebInspector.UIString("XMLHttpRequest logging"), itemAction, this._monitoringXHREnabled);
contextMenu.appendItem(WebInspector.UIString("Clear Console"), this.requestClearMessages.bind(this));
contextMenu.show(event);
},
@@ -532,8 +529,8 @@ WebInspector.ConsoleView.prototype = {
function evalCallback(result)
{
callback(WebInspector.RemoteObject.fromPayload(result));
- };
- InjectedScriptAccess.getDefault().evaluate(expression, objectGroup, evalCallback);
+ }
+ InspectorBackend.evaluate(expression, objectGroup, evalCallback);
},
_enterKeyPressed: function(event)
@@ -681,6 +678,15 @@ WebInspector.ConsoleMessage = function(source, type, level, line, url, repeatCou
this._parameters = parameters;
this._stackTrace = stackTrace;
this._requestId = requestId;
+
+ if (stackTrace && stackTrace.length) {
+ var topCallFrame = stackTrace[0];
+ if (!this.url)
+ this.url = topCallFrame.scriptName;
+ if (!this.line)
+ this.line = topCallFrame.lineNumber;
+ }
+
this._formatMessage();
}
@@ -737,17 +743,8 @@ WebInspector.ConsoleMessage.prototype = {
this._formattedMessage = document.createElement("span");
this._formattedMessage.className = "console-message-text source-code";
- if (stackTrace && stackTrace.length) {
- var topCallFrame = stackTrace[0];
- var sourceName = topCallFrame.scriptName;
- var sourceLine = topCallFrame.lineNumber;
- } else {
- var sourceName = this.url;
- var sourceLine = this.line;
- }
-
- if (sourceName && sourceName !== "undefined") {
- var urlElement = WebInspector.linkifyResourceAsNode(sourceName, "scripts", sourceLine, "console-message-url");
+ if (this.url && this.url !== "undefined") {
+ var urlElement = WebInspector.linkifyResourceAsNode(this.url, "scripts", this.line, "console-message-url");
this._formattedMessage.appendChild(urlElement);
}
diff --git a/Source/WebCore/inspector/front-end/DebuggerModel.js b/Source/WebCore/inspector/front-end/DebuggerModel.js
index 8f5bcf7..717486c 100644
--- a/Source/WebCore/inspector/front-end/DebuggerModel.js
+++ b/Source/WebCore/inspector/front-end/DebuggerModel.js
@@ -31,6 +31,7 @@
WebInspector.DebuggerModel = function()
{
this._paused = false;
+ this._callFrames = [];
this._breakpoints = {};
this._sourceIDAndLineToBreakpointId = {};
this._scripts = {};
@@ -43,6 +44,7 @@ WebInspector.DebuggerModel.Events = {
DebuggerResumed: "debugger-resumed",
ParsedScriptSource: "parsed-script-source",
FailedToParseScriptSource: "failed-to-parse-script-source",
+ ScriptSourceChanged: "script-source-changed",
BreakpointAdded: "breakpoint-added",
BreakpointRemoved: "breakpoint-removed"
}
@@ -84,6 +86,7 @@ WebInspector.DebuggerModel.prototype = {
delete this._breakpoints[breakpointId];
delete this._sourceIDAndLineToBreakpointId[this._encodeSourceIDAndLine(breakpoint.sourceID, breakpoint.line)];
this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.BreakpointRemoved, breakpointId);
+ breakpoint.dispatchEventToListeners("removed");
},
_breakpointSetOnBackend: function(breakpointId, sourceID, lineNumber, condition, enabled, originalLineNumber, restored)
@@ -103,6 +106,11 @@ WebInspector.DebuggerModel.prototype = {
this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.BreakpointAdded, breakpoint);
},
+ breakpointForId: function(breakpointId)
+ {
+ return this._breakpoints[breakpointId];
+ },
+
queryBreakpoints: function(filter)
{
var breakpoints = [];
@@ -129,6 +137,7 @@ WebInspector.DebuggerModel.prototype = {
reset: function()
{
this._paused = false;
+ this._callFrames = [];
this._breakpoints = {};
delete this._oneTimeBreakpoint;
this._sourceIDAndLineToBreakpointId = {};
@@ -156,39 +165,81 @@ WebInspector.DebuggerModel.prototype = {
return scripts;
},
+ editScriptSource: function(sourceID, scriptSource)
+ {
+ function didEditScriptSource(success, newBodyOrErrorMessage, callFrames)
+ {
+ if (success) {
+ if (callFrames && callFrames.length)
+ this._callFrames = callFrames;
+ this._updateScriptSource(sourceID, newBodyOrErrorMessage);
+ } else
+ WebInspector.log(newBodyOrErrorMessage, WebInspector.ConsoleMessage.MessageLevel.Warning);
+ }
+ InspectorBackend.editScriptSource(sourceID, scriptSource, didEditScriptSource.bind(this));
+ },
+
+ _updateScriptSource: function(sourceID, scriptSource)
+ {
+ var script = this._scripts[sourceID];
+ var oldSource = script.source;
+ script.source = scriptSource;
+
+ // Clear and re-create breakpoints according to text diff.
+ var diff = Array.diff(oldSource.split("\n"), script.source.split("\n"));
+ for (var id in this._breakpoints) {
+ var breakpoint = this._breakpoints[id];
+ if (breakpoint.sourceID !== sourceID)
+ continue;
+ breakpoint.remove();
+ var lineNumber = breakpoint.line - 1;
+ var newLineNumber = diff.left[lineNumber].row;
+ if (newLineNumber === undefined) {
+ for (var i = lineNumber - 1; i >= 0; --i) {
+ if (diff.left[i].row === undefined)
+ continue;
+ var shiftedLineNumber = diff.left[i].row + lineNumber - i;
+ if (shiftedLineNumber < diff.right.length) {
+ var originalLineNumber = diff.right[shiftedLineNumber].row;
+ if (originalLineNumber === lineNumber || originalLineNumber === undefined)
+ newLineNumber = shiftedLineNumber;
+ }
+ break;
+ }
+ }
+ if (newLineNumber !== undefined)
+ this.setBreakpoint(sourceID, newLineNumber + 1, breakpoint.enabled, breakpoint.condition);
+ }
+
+ this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.ScriptSourceChanged, { sourceID: sourceID, oldSource: oldSource });
+ },
+
+ get callFrames()
+ {
+ return this._callFrames;
+ },
+
_pausedScript: function(details)
{
this._paused = true;
+ this._callFrames = details.callFrames;
if ("_continueToLineBreakpointId" in this) {
InspectorBackend.removeBreakpoint(this._continueToLineBreakpointId);
delete this._continueToLineBreakpointId;
}
this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.DebuggerPaused, details);
-
- if (details.eventType === WebInspector.DebuggerEventTypes.JavaScriptPause || details.eventType === WebInspector.DebuggerEventTypes.NativeBreakpoint)
- return;
-
- var breakpoint = this.findBreakpoint(details.callFrames[0].sourceID, details.callFrames[0].line);
- if (!breakpoint)
- return;
- breakpoint.hit = true;
- this._lastHitBreakpoint = breakpoint;
},
_resumedScript: function()
{
this._paused = false;
+ this._callFrames = [];
this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.DebuggerResumed);
-
- if (!this._lastHitBreakpoint)
- return;
- this._lastHitBreakpoint.hit = false;
- delete this._lastHitBreakpoint;
},
- _parsedScriptSource: function(sourceID, sourceURL, lineOffset, columnOffset, scriptWorldType)
+ _parsedScriptSource: function(sourceID, sourceURL, lineOffset, columnOffset, length, scriptWorldType)
{
- var script = new WebInspector.Script(sourceID, sourceURL, "", lineOffset, columnOffset, undefined, undefined, scriptWorldType);
+ var script = new WebInspector.Script(sourceID, sourceURL, "", lineOffset, columnOffset, length, undefined, undefined, scriptWorldType);
this._scripts[sourceID] = script;
this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.ParsedScriptSource, sourceID);
},
@@ -234,9 +285,9 @@ WebInspector.DebuggerDispatcher.prototype = {
WebInspector.panels.scripts.debuggerWasDisabled();
},
- parsedScriptSource: function(sourceID, sourceURL, lineOffset, columnOffset, scriptWorldType)
+ parsedScriptSource: function(sourceID, sourceURL, lineOffset, columnOffset, length, scriptWorldType)
{
- this._debuggerModel._parsedScriptSource(sourceID, sourceURL, lineOffset, columnOffset, scriptWorldType);
+ this._debuggerModel._parsedScriptSource(sourceID, sourceURL, lineOffset, columnOffset, length, scriptWorldType);
},
failedToParseScriptSource: function(sourceURL, source, startingLine, errorLine, errorMessage)
diff --git a/Source/WebCore/inspector/front-end/ElementsTreeOutline.js b/Source/WebCore/inspector/front-end/ElementsTreeOutline.js
index 67d34b2..722c028 100644
--- a/Source/WebCore/inspector/front-end/ElementsTreeOutline.js
+++ b/Source/WebCore/inspector/front-end/ElementsTreeOutline.js
@@ -411,8 +411,7 @@ WebInspector.ElementsTreeElement.prototype = {
else
this.tooltip = WebInspector.UIString("%d × %d pixels (Natural: %d × %d pixels)", properties.offsetWidth, properties.offsetHeight, properties.naturalWidth, properties.naturalHeight);
}
-
- InjectedScriptAccess.getForNode(node).getNodeProperties(node.id, ["naturalHeight", "naturalWidth", "offsetHeight", "offsetWidth"], setTooltip.bind(this));
+ InspectorBackend.getNodeProperties(node.id, ["naturalHeight", "naturalWidth", "offsetHeight", "offsetWidth"], setTooltip.bind(this));
},
updateSelection: function()
diff --git a/Source/WebCore/inspector/front-end/ExtensionAPI.js b/Source/WebCore/inspector/front-end/ExtensionAPI.js
index a9a2423..b10452d 100644
--- a/Source/WebCore/inspector/front-end/ExtensionAPI.js
+++ b/Source/WebCore/inspector/front-end/ExtensionAPI.js
@@ -450,8 +450,9 @@ ExtensionServerClient.prototype = {
_onCallback: function(request)
{
if (request.requestId in this._callbacks) {
- this._callbacks[request.requestId](request.result);
+ var callback = this._callbacks[request.requestId];
delete this._callbacks[request.requestId];
+ callback(request.result);
}
},
diff --git a/Source/WebCore/inspector/front-end/ExtensionPanel.js b/Source/WebCore/inspector/front-end/ExtensionPanel.js
index 4b42e68..fb98350 100644
--- a/Source/WebCore/inspector/front-end/ExtensionPanel.js
+++ b/Source/WebCore/inspector/front-end/ExtensionPanel.js
@@ -95,7 +95,7 @@ WebInspector.ExtensionWatchSidebarPane.prototype = {
setExpression: function(expression, title)
{
- InjectedScriptAccess.getDefault().evaluate(expression, this._onEvaluate.bind(this, title));
+ InspectorBackend.evaluate(expression, "extension-watch", this._onEvaluate.bind(this, title));
},
_onEvaluate: function(title, result)
diff --git a/Source/WebCore/inspector/front-end/ExtensionServer.js b/Source/WebCore/inspector/front-end/ExtensionServer.js
index 1320efb..0924106 100644
--- a/Source/WebCore/inspector/front-end/ExtensionServer.js
+++ b/Source/WebCore/inspector/front-end/ExtensionServer.js
@@ -53,7 +53,6 @@ WebInspector.ExtensionServer = function()
this._registerHandler("subscribe", this._onSubscribe.bind(this));
this._registerHandler("unsubscribe", this._onUnsubscribe.bind(this));
-
window.addEventListener("message", this._onWindowMessage.bind(this), false);
}
@@ -68,11 +67,6 @@ WebInspector.ExtensionServer.prototype = {
this._postNotification("panel-objectSelected-" + panelId, objectId);
},
- notifyResourceFinished: function(resource)
- {
- this._postNotification("resource-finished", resource.identifier, (new WebInspector.HAREntry(resource)).build());
- },
-
notifySearchAction: function(panelId, action, searchString)
{
this._postNotification("panel-search-" + panelId, action, searchString);
@@ -114,6 +108,12 @@ WebInspector.ExtensionServer.prototype = {
delete this._clientObjects[auditRun.id];
},
+ _notifyResourceFinished: function(event)
+ {
+ var resource = event.data;
+ this._postNotification("resource-finished", resource.identifier, (new WebInspector.HAREntry(resource)).build());
+ },
+
_postNotification: function(type, details)
{
var subscribers = this._subscribers[type];
@@ -272,7 +272,7 @@ WebInspector.ExtensionServer.prototype = {
var evalExpression = "JSON.stringify(eval('" +
"with (window.console._commandLineAPI) with (window) {' + unescape('" + escape(message.expression) +
"') + '}'));";
- InjectedScriptAccess.getDefault().evaluate(evalExpression, callback.bind(this));
+ InspectorBackend.evaluate(evalExpression, "none", callback.bind(this));
},
_onRevealAndSelect: function(message)
@@ -356,6 +356,9 @@ WebInspector.ExtensionServer.prototype = {
initExtensions: function()
{
+ // The networkManager is normally created after the ExtensionServer is constructed, but before initExtensions() is called.
+ WebInspector.networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.ResourceFinished, this._notifyResourceFinished, this);
+
InspectorExtensionRegistry.getExtensionsAsync();
},
@@ -393,7 +396,6 @@ WebInspector.ExtensionServer.prototype = {
"var apiPrivate = {};" +
"(" + WebInspector.commonExtensionSymbols.toString() + ")(apiPrivate);" +
"(" + WebInspector.injectedExtensionAPI.toString() + ").apply(this, arguments);" +
- "webInspector.resources.Types = " + JSON.stringify(resourceTypes) + ";" +
platformAPI +
"})";
},
diff --git a/Source/WebCore/inspector/front-end/InjectedScriptAccess.js b/Source/WebCore/inspector/front-end/InjectedScriptAccess.js
deleted file mode 100644
index cb3c2b8..0000000
--- a/Source/WebCore/inspector/front-end/InjectedScriptAccess.js
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (C) 2009 Google Inc. All rights reserved.
- * Copyright (C) 2009 Joseph Pecoraro
- *
- * 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.
- */
-
-function InjectedScriptAccess(worldId) {
- this._worldId = worldId;
-}
-
-InjectedScriptAccess.get = function(worldId)
-{
- if (typeof worldId === "number")
- return new InjectedScriptAccess(worldId);
-
- console.assert(false, "Access to injected script with no id");
-}
-
-InjectedScriptAccess.getForNode = function(node)
-{
- // FIXME: do something.
- return InjectedScriptAccess.get(-node.id);
-}
-
-InjectedScriptAccess.getForObjectId = function(objectId)
-{
- // FIXME: move to native layer.
- var tokens = objectId.split(":");
- return InjectedScriptAccess.get(parseInt(tokens[0]));
-}
-
-InjectedScriptAccess.getDefault = function()
-{
- return InjectedScriptAccess.get(0);
-}
-
-InjectedScriptAccess.prototype = {};
-
-InjectedScriptAccess._installHandler = function(methodName, async)
-{
- InjectedScriptAccess.prototype[methodName] = function()
- {
- var allArgs = Array.prototype.slice.call(arguments);
- var callback = allArgs[allArgs.length - 1];
- var argsString = JSON.stringify(Array.prototype.slice.call(allArgs, 0, allArgs.length - 1));
-
- function myCallback(result, isException)
- {
- if (!isException)
- callback(result);
- else
- WebInspector.console.addMessage(WebInspector.ConsoleMessage.createTextMessage("Error dispatching: " + methodName));
- }
- InspectorBackend.dispatchOnInjectedScript(this._worldId, methodName, argsString, myCallback);
- };
-}
-
-// InjectedScriptAccess message forwarding puts some constraints on the way methods are implemented and called:
-// - Make sure corresponding methods in InjectedScript return non-null and non-undefined values,
-// - Make sure last parameter of all the InjectedSriptAccess.* calls is a callback function.
-// We keep these sorted.
-InjectedScriptAccess._installHandler("evaluate");
-InjectedScriptAccess._installHandler("evaluateInCallFrame");
-InjectedScriptAccess._installHandler("evaluateOnSelf");
-InjectedScriptAccess._installHandler("getCompletions");
-InjectedScriptAccess._installHandler("getProperties");
-InjectedScriptAccess._installHandler("getPrototypes");
-InjectedScriptAccess._installHandler("pushNodeToFrontend");
-InjectedScriptAccess._installHandler("resolveNode");
-InjectedScriptAccess._installHandler("getNodeProperties");
-InjectedScriptAccess._installHandler("setPropertyValue");
diff --git a/Source/WebCore/inspector/front-end/NetworkManager.js b/Source/WebCore/inspector/front-end/NetworkManager.js
index a657377..ed4309e 100644
--- a/Source/WebCore/inspector/front-end/NetworkManager.js
+++ b/Source/WebCore/inspector/front-end/NetworkManager.js
@@ -30,6 +30,8 @@
WebInspector.NetworkManager = function(resourceTreeModel)
{
+ WebInspector.Object.call(this);
+
this._inflightResources = {};
this._resourceTreeModel = resourceTreeModel;
this._lastIdentifierForCachedResource = 0;
@@ -86,6 +88,13 @@ WebInspector.NetworkManager.updateResourceWithCachedResource = function(resource
WebInspector.NetworkManager.updateResourceWithResponse(resource, cachedResource.response);
}
+WebInspector.NetworkManager.EventTypes = {
+ ResourceStarted: "ResourceStarted",
+ ResourceUpdated: "ResourceUpdated",
+ ResourceFinished: "ResourceFinished",
+ MainResourceCommitLoad: "MainResourceCommitLoad"
+}
+
WebInspector.NetworkManager.prototype = {
reset: function()
{
@@ -119,7 +128,7 @@ WebInspector.NetworkManager.prototype = {
if (isRedirect)
this._startResource(resource);
else
- WebInspector.panels.network.refreshResource(resource);
+ this._updateResource(resource);
},
markResourceAsCached: function(identifier)
@@ -129,7 +138,7 @@ WebInspector.NetworkManager.prototype = {
return;
resource.cached = true;
- WebInspector.panels.network.refreshResource(resource);
+ this._updateResource(resource);
},
didReceiveResponse: function(identifier, time, resourceType, response)
@@ -143,7 +152,7 @@ WebInspector.NetworkManager.prototype = {
WebInspector.NetworkManager.updateResourceWithResponse(resource, response);
- WebInspector.panels.network.refreshResource(resource);
+ this._updateResource(resource);
this._resourceTreeModel.addResourceToFrame(resource.loader.frameId, resource);
},
@@ -156,7 +165,7 @@ WebInspector.NetworkManager.prototype = {
resource.resourceSize += lengthReceived;
resource.endTime = time;
- WebInspector.panels.network.refreshResource(resource);
+ this._updateResource(resource);
},
didFinishLoading: function(identifier, finishTime)
@@ -204,8 +213,7 @@ WebInspector.NetworkManager.prototype = {
resource.type = WebInspector.Resource.Type[type];
resource.setInitialContent(sourceString);
- WebInspector.panels.resources.refreshResource(resource);
- WebInspector.panels.network.refreshResource(resource);
+ this._updateResource(resource);
},
didCommitLoadForFrame: function(frame, loader)
@@ -216,7 +224,7 @@ WebInspector.NetworkManager.prototype = {
if (mainResource) {
WebInspector.mainResource = mainResource;
mainResource.isMainResource = true;
- WebInspector.panels.network.mainResourceChanged();
+ this.dispatchEventToListeners(WebInspector.NetworkManager.EventTypes.MainResourceCommitLoad, mainResource);
}
}
},
@@ -239,7 +247,7 @@ WebInspector.NetworkManager.prototype = {
resource.webSocketRequestKey3 = request.webSocketRequestKey3;
resource.startTime = time;
- WebInspector.panels.network.refreshResource(resource);
+ this._updateResource(resource);
},
didReceiveWebSocketHandshakeResponse: function(identifier, time, response)
@@ -254,7 +262,7 @@ WebInspector.NetworkManager.prototype = {
resource.webSocketChallengeResponse = response.webSocketChallengeResponse;
resource.responseReceivedTime = time;
- WebInspector.panels.network.refreshResource(resource);
+ this._updateResource(resource);
},
didCloseWebSocket: function(identifier, time)
@@ -283,20 +291,24 @@ WebInspector.NetworkManager.prototype = {
return newResource;
},
- _startResource: function(resource, skipRefresh)
+ _startResource: function(resource)
{
this._inflightResources[resource.identifier] = resource;
- WebInspector.panels.network.appendResource(resource, skipRefresh);
- WebInspector.panels.audits.resourceStarted(resource);
+ this.dispatchEventToListeners(WebInspector.NetworkManager.EventTypes.ResourceStarted, resource);
+ },
+
+ _updateResource: function(resource)
+ {
+ this.dispatchEventToListeners(WebInspector.NetworkManager.EventTypes.ResourceUpdated, resource);
},
_finishResource: function(resource, finishTime)
{
resource.endTime = finishTime;
resource.finished = true;
- WebInspector.panels.network.refreshResource(resource);
- WebInspector.panels.audits.resourceFinished(resource);
- WebInspector.extensionServer.notifyResourceFinished(resource);
+ this.dispatchEventToListeners(WebInspector.NetworkManager.EventTypes.ResourceFinished, resource);
delete this._inflightResources[resource.identifier];
}
}
+
+WebInspector.NetworkManager.prototype.__proto__ = WebInspector.Object.prototype;
diff --git a/Source/WebCore/inspector/front-end/NetworkPanel.js b/Source/WebCore/inspector/front-end/NetworkPanel.js
index 28cbd36..943ee7f 100644
--- a/Source/WebCore/inspector/front-end/NetworkPanel.js
+++ b/Source/WebCore/inspector/front-end/NetworkPanel.js
@@ -78,6 +78,11 @@ WebInspector.NetworkPanel = function()
this._filter(this._filterAllElement, false);
this._toggleGridMode();
+
+ WebInspector.networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.ResourceStarted, this._onResourceStarted, this);
+ WebInspector.networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.ResourceUpdated, this._onResourceUpdated, this);
+ WebInspector.networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.ResourceFinished, this._onResourceUpdated, this);
+ WebInspector.networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.MainResourceCommitLoad, this._onMainResourceCommitLoad, this);
}
WebInspector.NetworkPanel.prototype = {
@@ -772,7 +777,12 @@ WebInspector.NetworkPanel.prototype = {
return this._resourcesById[id];
},
- appendResource: function(resource)
+ _onResourceStarted: function(event)
+ {
+ this._appendResource(event.data);
+ },
+
+ _appendResource: function(resource)
{
this._resources.push(resource);
this._resourcesById[resource.identifier] = resource;
@@ -781,13 +791,18 @@ WebInspector.NetworkPanel.prototype = {
// Pull all the redirects of the main resource upon commit load.
if (resource.redirects) {
for (var i = 0; i < resource.redirects.length; ++i)
- this.refreshResource(resource.redirects[i]);
+ this._refreshResource(resource.redirects[i]);
}
- this.refreshResource(resource);
+ this._refreshResource(resource);
+ },
+
+ _onResourceUpdated: function(event)
+ {
+ this._refreshResource(event.data);
},
- refreshResource: function(resource)
+ _refreshResource: function(resource)
{
this._staleResources.push(resource);
this._scheduleRefresh();
@@ -811,7 +826,7 @@ WebInspector.NetworkPanel.prototype = {
this._reset();
},
- mainResourceChanged: function()
+ _onMainResourceCommitLoad: function()
{
if (this._preserveLogToggle.toggled)
return;
@@ -819,7 +834,7 @@ WebInspector.NetworkPanel.prototype = {
this._reset();
// Now resurrect the main resource along with all redirects that lead to it.
var resourcesToAppend = (WebInspector.mainResource.redirects || []).concat(WebInspector.mainResource);
- resourcesToAppend.forEach(this.appendResource, this);
+ resourcesToAppend.forEach(this._appendResource, this);
},
canShowSourceLine: function(url, line)
diff --git a/Source/WebCore/inspector/front-end/PropertiesSidebarPane.js b/Source/WebCore/inspector/front-end/PropertiesSidebarPane.js
index b9c212a..a1e37bc 100644
--- a/Source/WebCore/inspector/front-end/PropertiesSidebarPane.js
+++ b/Source/WebCore/inspector/front-end/PropertiesSidebarPane.js
@@ -42,11 +42,11 @@ WebInspector.PropertiesSidebarPane.prototype = {
return;
}
- var self = this;
- var callback = function(prototypes) {
- var body = self.bodyElement;
+ function callback(prototypes)
+ {
+ var body = this.bodyElement;
body.removeChildren();
- self.sections = [];
+ this.sections = [];
// Get array of prototype user-friendly names.
for (var i = 0; i < prototypes.length; ++i) {
@@ -55,11 +55,11 @@ WebInspector.PropertiesSidebarPane.prototype = {
if (title.match(/Prototype$/))
title = title.replace(/Prototype$/, "");
var section = new WebInspector.ObjectPropertiesSection(prototype, title);
- self.sections.push(section);
+ this.sections.push(section);
body.appendChild(section.element);
}
- };
- InjectedScriptAccess.getForNode(node).getPrototypes(node.id, callback);
+ }
+ InspectorBackend.getNodePrototypes(node.id, callback.bind(this));
}
}
diff --git a/Source/WebCore/inspector/front-end/RemoteObject.js b/Source/WebCore/inspector/front-end/RemoteObject.js
index 4d6736c..10af2e3 100644
--- a/Source/WebCore/inspector/front-end/RemoteObject.js
+++ b/Source/WebCore/inspector/front-end/RemoteObject.js
@@ -52,7 +52,7 @@ WebInspector.RemoteObject.resolveNode = function(node, callback)
{
callback(object ? WebInspector.RemoteObject.fromPayload(object) : null);
}
- InjectedScriptAccess.getForNode(node).resolveNode(node.id, mycallback);
+ InspectorBackend.resolveNode(node.id, mycallback);
}
WebInspector.RemoteObject.fromPayload = function(payload)
@@ -118,7 +118,7 @@ WebInspector.RemoteObject.prototype = {
properties[i].value = WebInspector.RemoteObject.fromPayload(properties[i].value);
callback(properties);
}
- InjectedScriptAccess.getForObjectId(this._objectId).getProperties(this._objectId, ignoreHasOwnProperty, abbreviate, remoteObjectBinder);
+ InspectorBackend.getProperties(this._objectId, !!ignoreHasOwnProperty, abbreviate, remoteObjectBinder);
},
setPropertyValue: function(name, value, callback)
@@ -127,12 +127,12 @@ WebInspector.RemoteObject.prototype = {
callback(false);
return;
}
- InjectedScriptAccess.getForObjectId(this._objectId).setPropertyValue(this._objectId, name, value, callback);
+ InspectorBackend.setPropertyValue(this._objectId, name, value, callback);
},
pushNodeToFrontend: function(callback)
{
- InjectedScriptAccess.getForObjectId(this._objectId).pushNodeToFrontend(this._objectId, callback);
+ InspectorBackend.pushNodeToFrontend(this._objectId, callback);
}
}
diff --git a/Source/WebCore/inspector/front-end/Resource.js b/Source/WebCore/inspector/front-end/Resource.js
index 7340645..00c1fb9 100644
--- a/Source/WebCore/inspector/front-end/Resource.js
+++ b/Source/WebCore/inspector/front-end/Resource.js
@@ -44,7 +44,6 @@ WebInspector.Resource.Type = {
Font: 3,
Script: 4,
XHR: 5,
- Media: 6,
WebSocket: 7,
Other: 8,
@@ -68,8 +67,6 @@ WebInspector.Resource.Type = {
return WebInspector.UIString("Script");
case this.XHR:
return WebInspector.UIString("XHR");
- case this.Media:
- return WebInspector.UIString("Media");
case this.WebSocket:
return WebInspector.UIString("WebSocket");
case this.Other:
@@ -95,8 +92,6 @@ WebInspector.Resource.Type = {
return "script";
case this.XHR:
return "xhr";
- case this.Media:
- return "media";
case this.WebSocket:
return "websocket";
case this.Other:
@@ -669,6 +664,13 @@ WebInspector.Resource.prototype = {
requestContent: function(callback)
{
+ // We do not support content retrieval for WebSockets at the moment.
+ // Since WebSockets are potentially long-living, fail requests immediately
+ // to prevent caller blocking until resource is marked as finished.
+ if (this.type === WebInspector.Resource.Type.WebSocket) {
+ callback(null, null);
+ return;
+ }
if (this._content) {
callback(this._content, this._contentEncoded);
return;
diff --git a/Source/WebCore/inspector/front-end/ResourcesPanel.js b/Source/WebCore/inspector/front-end/ResourcesPanel.js
index d96989b..7e1fcc0 100644
--- a/Source/WebCore/inspector/front-end/ResourcesPanel.js
+++ b/Source/WebCore/inspector/front-end/ResourcesPanel.js
@@ -78,6 +78,8 @@ WebInspector.ResourcesPanel = function(database)
this.sidebarElement.addEventListener("mousemove", this._onmousemove.bind(this), false);
this.sidebarElement.addEventListener("mouseout", this._onmouseout.bind(this), false);
+
+ WebInspector.networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.ResourceUpdated, this._refreshResource, this);
}
WebInspector.ResourcesPanel.prototype = {
@@ -253,8 +255,9 @@ WebInspector.ResourcesPanel.prototype = {
frameTreeElement.removeChildren();
},
- refreshResource: function(resource)
+ _refreshResource: function(event)
{
+ var resource = event.data;
// FIXME: do not add XHR in the first place based on the native instrumentation.
if (resource.type === WebInspector.Resource.Type.XHR) {
var resourceTreeElement = this._findTreeElementForResource(resource);
diff --git a/Source/WebCore/inspector/front-end/Script.js b/Source/WebCore/inspector/front-end/Script.js
index 89b2121..6e3b18d 100644
--- a/Source/WebCore/inspector/front-end/Script.js
+++ b/Source/WebCore/inspector/front-end/Script.js
@@ -23,13 +23,14 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-WebInspector.Script = function(sourceID, sourceURL, source, lineOffset, columnOffset, errorLine, errorMessage, worldType)
+WebInspector.Script = function(sourceID, sourceURL, source, lineOffset, columnOffset, length, errorLine, errorMessage, worldType)
{
this.sourceID = sourceID;
this.sourceURL = sourceURL;
this._source = source;
this.lineOffset = lineOffset;
this.columnOffset = columnOffset;
+ this.length = length;
this.errorLine = errorLine;
this.errorMessage = errorMessage;
this.worldType = worldType;
@@ -96,12 +97,15 @@ WebInspector.Script.prototype = {
get source()
{
+ if (!this._source && this.resource)
+ this._source = this.resource.content;
return this._source;
},
set source(source)
{
this._source = source;
+ delete this._lineEndings;
},
requestSource: function(callback)
diff --git a/Source/WebCore/inspector/front-end/ScriptFormatter.js b/Source/WebCore/inspector/front-end/ScriptFormatter.js
new file mode 100644
index 0000000..69ffb74
--- /dev/null
+++ b/Source/WebCore/inspector/front-end/ScriptFormatter.js
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2011 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.ScriptFormatter = function(source)
+{
+ this._originalSource = source;
+ this._originalLineEndings = source.findAll("\n");
+ this._originalLineEndings.push(source.length);
+}
+
+WebInspector.ScriptFormatter.locationToPosition = function(lineEndings, location)
+{
+ var position = location.line ? lineEndings[location.line - 1] + 1 : 0;
+ return position + location.column;
+}
+
+WebInspector.ScriptFormatter.positionToLocation = function(lineEndings, position)
+{
+ var location = {};
+ location.line = lineEndings.upperBound(position - 1);
+ if (!location.line)
+ location.column = position;
+ else
+ location.column = position - lineEndings[location.line - 1] - 1;
+ return location;
+}
+
+WebInspector.ScriptFormatter.prototype = {
+ format: function(callback)
+ {
+ var worker = new Worker("scriptFormatterWorker.js");
+ function messageHandler(event)
+ {
+ var formattedSource = event.data;
+ this._formatted = true;
+ this._formattedSource = formattedSource;
+ this._formattedLineEndings = formattedSource.findAll("\n");
+ this._formattedLineEndings.push(formattedSource.length);
+ this._buildMapping();
+ callback(formattedSource);
+ }
+ worker.onmessage = messageHandler.bind(this);
+ worker.postMessage(this._originalSource);
+ },
+
+ _buildMapping: function()
+ {
+ this._originalSymbolPositions = [];
+ this._formattedSymbolPositions = [];
+ var lastCodePosition = 0;
+ var regexp = /[\$\.\w]+|{|}|;/g;
+ while (true) {
+ var match = regexp.exec(this._formattedSource);
+ if (!match)
+ break;
+ var position = this._originalSource.indexOf(match[0], lastCodePosition);
+ if (position === -1)
+ continue;
+ this._originalSymbolPositions.push(position);
+ this._formattedSymbolPositions.push(match.index);
+ lastCodePosition = position + match[0].length;
+ }
+ this._originalSymbolPositions.push(this._originalSource.length);
+ this._formattedSymbolPositions.push(this._formattedSource.length);
+ },
+
+ originalLineNumberToFormattedLineNumber: function(originalLineNumber)
+ {
+ if (!this._formatted)
+ return originalLineNumber;
+ var originalPosition = WebInspector.ScriptFormatter.locationToPosition(this._originalLineEndings, { line: originalLineNumber, column: 0 });
+ return this.originalPositionToFormattedLineNumber(originalPosition);
+ },
+
+ formattedLineNumberToOriginalLineNumber: function(formattedLineNumber)
+ {
+ if (!this._formatted)
+ return formattedLineNumber;
+ var originalPosition = this.formattedLineNumberToOriginalPosition(formattedLineNumber);
+ return WebInspector.ScriptFormatter.positionToLocation(this._originalLineEndings, originalPosition).line;
+ },
+
+ originalPositionToFormattedLineNumber: function(originalPosition)
+ {
+ var lineEndings = this._formatted ? this._formattedLineEndings : this._originalLineEndings;
+ if (this._formatted)
+ formattedPosition = this._convertPosition(this._originalSymbolPositions, this._formattedSymbolPositions, originalPosition);
+ return WebInspector.ScriptFormatter.positionToLocation(lineEndings, formattedPosition).line;
+ },
+
+ formattedLineNumberToOriginalPosition: function(formattedLineNumber)
+ {
+ var lineEndings = this._formatted ? this._formattedLineEndings : this._originalLineEndings;
+ var formattedPosition = WebInspector.ScriptFormatter.locationToPosition(lineEndings, { line: formattedLineNumber, column: 0 });
+ if (!this._formatted)
+ return formattedPosition;
+ return this._convertPosition(this._formattedSymbolPositions, this._originalSymbolPositions, formattedPosition);
+ },
+
+ _convertPosition: function(symbolPositions1, symbolPositions2, position)
+ {
+ var index = symbolPositions1.upperBound(position);
+ if (index === symbolPositions2.length - 1)
+ return symbolPositions2[index] - 1;
+ return symbolPositions2[index];
+ }
+}
diff --git a/Source/WebCore/inspector/front-end/ScriptFormatterWorker.js b/Source/WebCore/inspector/front-end/ScriptFormatterWorker.js
new file mode 100644
index 0000000..e900317
--- /dev/null
+++ b/Source/WebCore/inspector/front-end/ScriptFormatterWorker.js
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+var parse = loadModule("parse-js.js");
+var process = loadModule("process.js");
+
+onmessage = function(event) {
+ postMessage(beautify(event.data));
+};
+
+function beautify(source)
+{
+ var ast = parse.parse(source);
+ var beautifyOptions = {
+ indent_level: 4,
+ indent_start: 0,
+ quote_keys: false,
+ space_colon: false
+ };
+ return process.gen_code(ast, beautifyOptions);
+}
+
+function loadModule(src)
+{
+ var request = new XMLHttpRequest();
+ request.open("GET", src, false);
+ request.send();
+
+ var exports = {};
+ eval(request.responseText);
+ return exports;
+}
+
+function require()
+{
+ return parse;
+}
diff --git a/Source/WebCore/inspector/front-end/ScriptView.js b/Source/WebCore/inspector/front-end/ScriptView.js
index d6c1c59..f631fcc 100644
--- a/Source/WebCore/inspector/front-end/ScriptView.js
+++ b/Source/WebCore/inspector/front-end/ScriptView.js
@@ -30,7 +30,7 @@ WebInspector.ScriptView = function(script)
this.element.addStyleClass("script-view");
var contentProvider = new WebInspector.SourceFrameContentProviderForScript(script);
- this.sourceFrame = new WebInspector.SourceFrame(this.element, contentProvider, "", WebInspector.panels.scripts.canEditScripts());
+ this.sourceFrame = new WebInspector.SourceFrame(this.element, contentProvider, "", true);
}
WebInspector.ScriptView.prototype = {
diff --git a/Source/WebCore/inspector/front-end/ScriptsPanel.js b/Source/WebCore/inspector/front-end/ScriptsPanel.js
index 32212d4..a74f80d 100644
--- a/Source/WebCore/inspector/front-end/ScriptsPanel.js
+++ b/Source/WebCore/inspector/front-end/ScriptsPanel.js
@@ -63,6 +63,15 @@ WebInspector.ScriptsPanel = function()
// FIXME: append the functions select element to the top status bar when it is implemented.
// this.topStatusBar.appendChild(this.functionsSelectElement);
+ this.formatButton = document.createElement("button");
+ this.formatButton.className = "status-bar-item";
+ this.formatButton.id = "format-script";
+ this.formatButton.title = WebInspector.UIString("Format script.");
+ this.formatButton.appendChild(document.createElement("img"));
+ this.formatButton.addEventListener("click", this._formatScript.bind(this), false);
+ if (Preferences.debugMode)
+ this.topStatusBar.appendChild(this.formatButton);
+
this.sidebarButtonsElement = document.createElement("div");
this.sidebarButtonsElement.id = "scripts-sidebar-buttons";
this.topStatusBar.appendChild(this.sidebarButtonsElement);
@@ -131,7 +140,7 @@ WebInspector.ScriptsPanel = function()
this.sidebarPanes.watchExpressions = new WebInspector.WatchExpressionsSidebarPane();
this.sidebarPanes.callstack = new WebInspector.CallStackSidebarPane();
this.sidebarPanes.scopechain = new WebInspector.ScopeChainSidebarPane();
- this.sidebarPanes.jsBreakpoints = WebInspector.createJSBreakpointsSidebarPane();
+ this.sidebarPanes.jsBreakpoints = new WebInspector.JavaScriptBreakpointsSidebarPane();
if (Preferences.nativeInstrumentationEnabled) {
this.sidebarPanes.domBreakpoints = WebInspector.createDOMBreakpointsSidebarPane();
this.sidebarPanes.xhrBreakpoints = WebInspector.createXHRBreakpointsSidebarPane();
@@ -168,8 +177,6 @@ WebInspector.ScriptsPanel = function()
this._pauseOnExceptionButton = new WebInspector.StatusBarButton("", "scripts-pause-on-exceptions-status-bar-item", 3);
this._pauseOnExceptionButton.addEventListener("click", this._togglePauseOnExceptions.bind(this), false);
- this._pauseOnExceptionButton.state = WebInspector.ScriptsPanel.PauseOnExceptionsState.DontPauseOnExceptions;
- this._pauseOnExceptionButton.title = WebInspector.UIString("Don't pause on exceptions.\nClick to Pause on all exceptions.");
this._registerShortcuts();
@@ -179,6 +186,7 @@ WebInspector.ScriptsPanel = function()
WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.ParsedScriptSource, this._parsedScriptSource, this);
WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.FailedToParseScriptSource, this._failedToParseScriptSource, this);
+ WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.ScriptSourceChanged, this._scriptSourceChanged, this);
WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.DebuggerPaused, this._debuggerPaused, this);
WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.DebuggerResumed, this._debuggerResumed, this);
}
@@ -244,6 +252,27 @@ WebInspector.ScriptsPanel.prototype = {
this._addScript(event.data);
},
+ _scriptSourceChanged: function(event)
+ {
+ var sourceID = event.data.sourceID;
+ var oldSource = event.data.oldSource;
+
+ var script = WebInspector.debuggerModel.scriptForSourceID(sourceID);
+ var oldView = script._scriptView;
+ if (oldView) {
+ script._scriptView = new WebInspector.ScriptView(script);
+ this.viewRecreated(oldView, script._scriptView);
+ }
+ if (script.resource) {
+ var revertHandle = WebInspector.debuggerModel.editScriptSource.bind(WebInspector.debuggerModel, sourceID, oldSource);
+ script.resource.setContent(script.source, revertHandle);
+ }
+
+ var callFrames = WebInspector.debuggerModel.callFrames;
+ if (callFrames.length)
+ this._debuggerPaused({ data: { callFrames: callFrames } });
+ },
+
_addScript: function(script)
{
var resource = WebInspector.resourceForURL(script.sourceURL);
@@ -279,52 +308,6 @@ WebInspector.ScriptsPanel.prototype = {
delete resource._scriptsPendingResourceLoad;
},
- canEditScripts: function()
- {
- return Preferences.canEditScriptSource;
- },
-
- editScriptSource: function(editData, revertEditingCallback, cancelEditingCallback)
- {
- if (!this.canEditScripts())
- return;
-
- // Need to clear breakpoints and re-create them later when editing source.
- var breakpoints = WebInspector.debuggerModel.queryBreakpoints(function(b) { return b.sourceID === editData.sourceID });
- for (var i = 0; i < breakpoints.length; ++i)
- breakpoints[i].remove();
-
- function mycallback(success, newBodyOrErrorMessage, callFrames)
- {
- if (success) {
- var script = WebInspector.debuggerModel.scriptForSourceID(editData.sourceID);
- script.source = newBodyOrErrorMessage;
- var oldView = script._scriptView
- if (oldView) {
- script._scriptView = new WebInspector.ScriptView(script);
- this.viewRecreated(oldView, script._scriptView);
- }
- if (script.resource)
- script.resource.setContent(newBodyOrErrorMessage, revertEditingCallback);
-
- if (callFrames && callFrames.length)
- this._debuggerPaused({ data: { callFrames: callFrames } });
- } else {
- if (cancelEditingCallback)
- cancelEditingCallback();
- WebInspector.log(newBodyOrErrorMessage, WebInspector.ConsoleMessage.MessageLevel.Warning);
- }
- for (var i = 0; i < breakpoints.length; ++i) {
- var breakpoint = breakpoints[i];
- var newLine = breakpoint.line;
- if (success && breakpoint.line >= editData.line)
- newLine += editData.linesCountToShift;
- WebInspector.debuggerModel.setBreakpoint(editData.sourceID, newLine, breakpoint.enabled, breakpoint.condition);
- }
- };
- InspectorBackend.editScriptSource(editData.sourceID, editData.content, mycallback.bind(this));
- },
-
selectedCallFrameId: function()
{
var selectedCallFrame = this.sidebarPanes.callstack.selectedCallFrame;
@@ -359,7 +342,7 @@ WebInspector.ScriptsPanel.prototype = {
if (result)
callback(WebInspector.RemoteObject.fromPayload(result));
}
- InjectedScriptAccess.get(callFrame.worldId).evaluateInCallFrame(callFrame.id, code, objectGroup, evalCallback);
+ InspectorBackend.evaluateOnCallFrame(callFrame.id, code, objectGroup, evalCallback);
},
_debuggerPaused: function(event)
@@ -392,9 +375,10 @@ WebInspector.ScriptsPanel.prototype = {
debuggerWasEnabled: function()
{
+ this._setPauseOnExceptions(WebInspector.settings.pauseOnExceptionState);
+
if (this._debuggerEnabled)
return;
-
this._debuggerEnabled = true;
this.reset(true);
},
@@ -677,7 +661,7 @@ WebInspector.ScriptsPanel.prototype = {
_clearCurrentExecutionLine: function()
{
if (this._executionSourceFrame)
- this._executionSourceFrame.executionLine = 0;
+ this._executionSourceFrame.clearExecutionLine();
delete this._executionSourceFrame;
},
@@ -699,7 +683,7 @@ WebInspector.ScriptsPanel.prototype = {
this._executionSourceFrame = this._sourceFrameForScriptOrResource(scriptOrResource);
if (this._executionSourceFrame)
- this._executionSourceFrame.executionLine = currentFrame.line;
+ this._executionSourceFrame.setExecutionLine(currentFrame.line);
},
_changeVisibleFile: function(event)
@@ -744,16 +728,21 @@ WebInspector.ScriptsPanel.prototype = {
this.resize();
},
- updatePauseOnExceptionsState: function(pauseOnExceptionsState)
+ _setPauseOnExceptions: function(pauseOnExceptionsState)
{
- if (pauseOnExceptionsState == WebInspector.ScriptsPanel.PauseOnExceptionsState.DontPauseOnExceptions)
- this._pauseOnExceptionButton.title = WebInspector.UIString("Don't pause on exceptions.\nClick to Pause on all exceptions.");
- else if (pauseOnExceptionsState == WebInspector.ScriptsPanel.PauseOnExceptionsState.PauseOnAllExceptions)
- this._pauseOnExceptionButton.title = WebInspector.UIString("Pause on all exceptions.\nClick to Pause on uncaught exceptions.");
- else if (pauseOnExceptionsState == WebInspector.ScriptsPanel.PauseOnExceptionsState.PauseOnUncaughtExceptions)
- this._pauseOnExceptionButton.title = WebInspector.UIString("Pause on uncaught exceptions.\nClick to Not pause on exceptions.");
-
- this._pauseOnExceptionButton.state = pauseOnExceptionsState;
+ function callback(pauseOnExceptionsState)
+ {
+ if (pauseOnExceptionsState == WebInspector.ScriptsPanel.PauseOnExceptionsState.DontPauseOnExceptions)
+ this._pauseOnExceptionButton.title = WebInspector.UIString("Don't pause on exceptions.\nClick to Pause on all exceptions.");
+ else if (pauseOnExceptionsState == WebInspector.ScriptsPanel.PauseOnExceptionsState.PauseOnAllExceptions)
+ this._pauseOnExceptionButton.title = WebInspector.UIString("Pause on all exceptions.\nClick to Pause on uncaught exceptions.");
+ else if (pauseOnExceptionsState == WebInspector.ScriptsPanel.PauseOnExceptionsState.PauseOnUncaughtExceptions)
+ this._pauseOnExceptionButton.title = WebInspector.UIString("Pause on uncaught exceptions.\nClick to Not pause on exceptions.");
+
+ this._pauseOnExceptionButton.state = pauseOnExceptionsState;
+ WebInspector.settings.pauseOnExceptionState = pauseOnExceptionsState;
+ }
+ InspectorBackend.setPauseOnExceptionsState(pauseOnExceptionsState, callback.bind(this));
},
_updateDebuggerButtons: function()
@@ -833,6 +822,12 @@ WebInspector.ScriptsPanel.prototype = {
this._updateBackAndForwardButtons();
},
+ _formatScript: function()
+ {
+ if (this.visibleView && this.visibleView.sourceFrame)
+ this.visibleView.sourceFrame.formatSource();
+ },
+
_enableDebugging: function()
{
if (this._debuggerEnabled)
@@ -854,7 +849,7 @@ WebInspector.ScriptsPanel.prototype = {
_togglePauseOnExceptions: function()
{
- InspectorBackend.setPauseOnExceptionsState((this._pauseOnExceptionButton.state + 1) % this._pauseOnExceptionButton.states, this.updatePauseOnExceptionsState.bind(this));
+ this._setPauseOnExceptions((this._pauseOnExceptionButton.state + 1) % this._pauseOnExceptionButton.states);
},
_togglePause: function()
diff --git a/Source/WebCore/inspector/front-end/Settings.js b/Source/WebCore/inspector/front-end/Settings.js
index bc50ce9..e26b1d7 100644
--- a/Source/WebCore/inspector/front-end/Settings.js
+++ b/Source/WebCore/inspector/front-end/Settings.js
@@ -65,6 +65,7 @@ WebInspector.Settings = function()
this.installApplicationSetting("showUserAgentStyles", true);
this.installApplicationSetting("watchExpressions", []);
this.installApplicationSetting("lastActivePanel", "elements");
+ this.installApplicationSetting("pauseOnExceptionState", WebInspector.ScriptsPanel.PauseOnExceptionsState.DontPauseOnExceptions);
this.installProjectSetting("breakpoints", {});
this.installProjectSetting("nativeBreakpoints", []);
diff --git a/Source/WebCore/inspector/front-end/SourceFrame.js b/Source/WebCore/inspector/front-end/SourceFrame.js
index af10f1e..eb89f24 100644
--- a/Source/WebCore/inspector/front-end/SourceFrame.js
+++ b/Source/WebCore/inspector/front-end/SourceFrame.js
@@ -28,12 +28,13 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-WebInspector.SourceFrame = function(parentElement, contentProvider, url, canEditScripts)
+WebInspector.SourceFrame = function(parentElement, contentProvider, url, isScript)
{
this._parentElement = parentElement;
this._contentProvider = contentProvider;
this._url = url;
- this._canEditScripts = canEditScripts;
+ this._isScript = isScript;
+
this._textModel = new WebInspector.TextEditorModel();
this._textModel.replaceTabsWithSpaces = true;
@@ -71,23 +72,6 @@ WebInspector.SourceFrame.prototype = {
}
},
- get executionLine()
- {
- return this._executionLine;
- },
-
- set executionLine(x)
- {
- if (this._executionLine === x)
- return;
-
- var previousLine = this._executionLine;
- this._executionLine = x;
-
- if (this._textViewer)
- this._updateExecutionLine(previousLine);
- },
-
markDiff: function(diffData)
{
if (this._diffLines && this._textViewer)
@@ -172,6 +156,7 @@ WebInspector.SourceFrame.prototype = {
{
this._content = content;
this._textModel.setText(null, content);
+ this._formatter = new WebInspector.ScriptFormatter(content);
this._textViewer = new WebInspector.TextViewer(this._textModel, WebInspector.platform, this._url);
var element = this._textViewer.element;
@@ -179,15 +164,13 @@ WebInspector.SourceFrame.prototype = {
element.addEventListener("mousedown", this._mouseDown.bind(this), true);
element.addEventListener("mousemove", this._mouseMove.bind(this), true);
element.addEventListener("scroll", this._scroll.bind(this), true);
+ element.addEventListener("dblclick", this._doubleClick.bind(this), true);
this._parentElement.appendChild(element);
this._textViewer.beginUpdates();
this._textViewer.mimeType = mimeType;
- this._addExistingMessagesToSource();
- this._updateExecutionLine();
- this._updateDiffDecorations();
- this._textViewer.resize();
+ this._setTextViewerDecorations();
if (this._lineNumberToReveal) {
this.revealLine(this._lineNumberToReveal);
@@ -210,15 +193,34 @@ WebInspector.SourceFrame.prototype = {
delete this._delayedFindSearchMatches;
}
+ this._textViewer.endUpdates();
+
+ WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.BreakpointAdded, this._breakpointAdded, this);
+
+ if (this._canEditScripts)
+ this._textViewer.editCallback = this._editLine.bind(this);
+ },
+
+ _setTextViewerDecorations: function()
+ {
+ this._rowMessages = {};
+ this._messageBubbles = {};
+
+ this._textViewer.beginUpdates();
+
+ this._addExistingMessagesToSource();
+ this._updateDiffDecorations();
+
+ if (this._executionLine)
+ this.setExecutionLine(this._executionLine);
+
var breakpoints = this._breakpoints();
for (var i = 0; i < breakpoints.length; ++i)
this._addBreakpoint(breakpoints[i]);
- WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.BreakpointAdded, this._breakpointAdded, this);
- this._textViewer.endUpdates();
+ this._textViewer.resize();
- if (this._canEditScripts)
- this._textViewer.editCallback = this._editLine.bind(this);
+ this._textViewer.endUpdates();
},
findSearchMatches: function(query, finishedCallback)
@@ -300,18 +302,22 @@ WebInspector.SourceFrame.prototype = {
msg._resourceMessageRepeatCountElement.textContent = WebInspector.UIString(" (repeated %d times)", msg.repeatCount);
},
- _updateExecutionLine: function(previousLine)
+ setExecutionLine: function(lineNumber)
{
- if (previousLine) {
- if (previousLine - 1 < this._textModel.linesCount)
- this._textViewer.removeDecoration(previousLine - 1, "webkit-execution-line");
- }
-
- if (!this._executionLine)
+ this._executionLine = lineNumber;
+ if (!this._textViewer)
return;
+ var textViewerLineNumber = this._formatter.originalLineNumberToFormattedLineNumber(this._executionLine - 1);
+ this._textViewer.addDecoration(textViewerLineNumber, "webkit-execution-line");
+ },
- if (this._executionLine < this._textModel.linesCount)
- this._textViewer.addDecoration(this._executionLine - 1, "webkit-execution-line");
+ clearExecutionLine: function()
+ {
+ if (!this._textViewer)
+ return;
+ var textViewerLineNumber = this._formatter.originalLineNumberToFormattedLineNumber(this._executionLine - 1);
+ this._textViewer.removeDecoration(textViewerLineNumber, "webkit-execution-line");
+ delete this._executionLine;
},
_updateDiffDecorations: function()
@@ -412,14 +418,15 @@ WebInspector.SourceFrame.prototype = {
_addBreakpoint: function(breakpoint)
{
- if (breakpoint.line > this._textModel.linesCount)
+ var textViewerLineNumber = this._formatter.originalLineNumberToFormattedLineNumber(breakpoint.line - 1);
+ if (textViewerLineNumber >= this._textModel.linesCount)
return;
breakpoint.addEventListener("enable-changed", this._breakpointChanged, this);
breakpoint.addEventListener("condition-changed", this._breakpointChanged, this);
breakpoint.addEventListener("removed", this._breakpointRemoved, this);
- this._setBreakpointDecoration(breakpoint.line, breakpoint.enabled, !!breakpoint.condition);
+ this._setBreakpointDecoration(textViewerLineNumber, breakpoint.enabled, !!breakpoint.condition);
},
_breakpointRemoved: function(event)
@@ -430,18 +437,19 @@ WebInspector.SourceFrame.prototype = {
breakpoint.removeEventListener("condition-changed", null, this);
breakpoint.removeEventListener("removed", null, this);
- this._removeBreakpointDecoration(breakpoint.line);
+ var textViewerLineNumber = this._formatter.originalLineNumberToFormattedLineNumber(breakpoint.line - 1);
+ this._removeBreakpointDecoration(textViewerLineNumber);
},
_breakpointChanged: function(event)
{
var breakpoint = event.target;
- this._setBreakpointDecoration(breakpoint.line, breakpoint.enabled, !!breakpoint.condition);
+ var textViewerLineNumber = this._formatter.originalLineNumberToFormattedLineNumber(breakpoint.line - 1);
+ this._setBreakpointDecoration(textViewerLineNumber, breakpoint.enabled, !!breakpoint.condition);
},
_setBreakpointDecoration: function(lineNumber, enabled, hasCondition)
{
- lineNumber -= 1;
this._textViewer.beginUpdates();
this._textViewer.addDecoration(lineNumber, "webkit-breakpoint");
if (enabled)
@@ -457,7 +465,6 @@ WebInspector.SourceFrame.prototype = {
_removeBreakpointDecoration: function(lineNumber)
{
- lineNumber -= 1;
this._textViewer.beginUpdates();
this._textViewer.removeDecoration(lineNumber, "webkit-breakpoint");
this._textViewer.removeDecoration(lineNumber, "webkit-breakpoint-disabled");
@@ -473,27 +480,28 @@ WebInspector.SourceFrame.prototype = {
var target = event.target.enclosingNodeOrSelfWithClass("webkit-line-number");
if (!target)
return;
- var lineNumber = target.parentElement.lineNumber + 1;
+ var textViewerLineNumber = target.parentElement.lineNumber;
+ var originalLineNumber = this._formatter.formattedLineNumberToOriginalLineNumber(textViewerLineNumber);
var contextMenu = new WebInspector.ContextMenu();
- contextMenu.appendItem(WebInspector.UIString("Continue to Here"), this._continueToLine.bind(this, lineNumber));
+ contextMenu.appendItem(WebInspector.UIString("Continue to Here"), this._continueToLine.bind(this, originalLineNumber));
- var breakpoint = this._findBreakpoint(lineNumber);
+ var breakpoint = this._findBreakpoint(originalLineNumber);
if (!breakpoint) {
// This row doesn't have a breakpoint: We want to show Add Breakpoint and Add and Edit Breakpoint.
- contextMenu.appendItem(WebInspector.UIString("Add Breakpoint"), this._setBreakpoint.bind(this, lineNumber, "", true));
+ contextMenu.appendItem(WebInspector.UIString("Add Breakpoint"), this._setBreakpoint.bind(this, originalLineNumber, "", true));
function addConditionalBreakpoint()
{
- this._setBreakpointDecoration(lineNumber, true, true);
+ this._setBreakpointDecoration(textViewerLineNumber, true, true);
function didEditBreakpointCondition(committed, condition)
{
- this._removeBreakpointDecoration(lineNumber);
+ this._removeBreakpointDecoration(textViewerLineNumber);
if (committed)
- this._setBreakpoint(lineNumber, true, condition);
+ this._setBreakpoint(originalLineNumber, true, condition);
}
- this._editBreakpointCondition(lineNumber, "", didEditBreakpointCondition.bind(this));
+ this._editBreakpointCondition(textViewerLineNumber, "", didEditBreakpointCondition.bind(this));
}
contextMenu.appendItem(WebInspector.UIString("Add Conditional Breakpoint…"), addConditionalBreakpoint.bind(this));
} else {
@@ -505,16 +513,16 @@ WebInspector.SourceFrame.prototype = {
{
if (committed) {
breakpoint.remove();
- this._setBreakpoint(breakpoint.line, breakpoint.enabled, condition);
+ this._setBreakpoint(originalLineNumber, breakpoint.enabled, condition);
}
}
- this._editBreakpointCondition(lineNumber, breakpoint.condition, didEditBreakpointCondition.bind(this));
+ this._editBreakpointCondition(textViewerLineNumber, breakpoint.condition, didEditBreakpointCondition.bind(this));
}
contextMenu.appendItem(WebInspector.UIString("Edit Breakpoint…"), editBreakpointCondition.bind(this));
function setBreakpointEnabled(enabled)
{
breakpoint.remove();
- this._setBreakpoint(breakpoint.line, enabled, breakpoint.condition);
+ this._setBreakpoint(originalLineNumber, enabled, breakpoint.condition);
}
if (breakpoint.enabled)
contextMenu.appendItem(WebInspector.UIString("Disable Breakpoint"), setBreakpointEnabled.bind(this, false));
@@ -538,15 +546,15 @@ WebInspector.SourceFrame.prototype = {
var target = event.target.enclosingNodeOrSelfWithClass("webkit-line-number");
if (!target)
return;
- var lineNumber = target.parentElement.lineNumber + 1;
+ var originalLineNumber = this._formatter.formattedLineNumberToOriginalLineNumber(target.parentElement.lineNumber);
- var breakpoint = this._findBreakpoint(lineNumber);
+ var breakpoint = this._findBreakpoint(originalLineNumber);
if (breakpoint) {
breakpoint.remove();
if (event.shiftKey)
- this._setBreakpoint(breakpoint.line, !breakpoint.enabled, breakpoint.condition);
+ this._setBreakpoint(originalLineNumber, !breakpoint.enabled, breakpoint.condition);
} else
- this._setBreakpoint(lineNumber, true, "");
+ this._setBreakpoint(originalLineNumber, true, "");
event.preventDefault();
},
@@ -710,7 +718,6 @@ WebInspector.SourceFrame.prototype = {
_editBreakpointCondition: function(lineNumber, condition, callback)
{
- lineNumber -= 1;
this._conditionElement = this._createConditionElement(lineNumber);
this._textViewer.addDecoration(lineNumber, this._conditionElement);
@@ -776,49 +783,55 @@ WebInspector.SourceFrame.prototype = {
this._textViewer.resize();
},
+ formatSource: function()
+ {
+ if (!this._formatter)
+ return;
+
+ function didFormat(source)
+ {
+ this._textModel.setText(null, source);
+ this._setTextViewerDecorations();
+ }
+ this._formatter.format(didFormat.bind(this));
+ },
+
_continueToLine: function(lineNumber)
{
var sourceID = this._sourceIDForLine(lineNumber);
if (!sourceID)
return;
- WebInspector.debuggerModel.continueToLine(sourceID, lineNumber);
+ WebInspector.debuggerModel.continueToLine(sourceID, lineNumber + 1);
},
- _editLine: function(lineNumber, newContent, cancelEditingCallback)
+ _doubleClick: function(event)
{
- lineNumber += 1;
-
- var lines = [];
- var oldLines = this._content.split('\n');
- for (var i = 0; i < oldLines.length; ++i) {
- if (i === lineNumber - 1)
- lines.push(newContent);
- else
- lines.push(oldLines[i]);
- }
+ if (!Preferences.canEditScriptSource || !this._isScript)
+ return;
- var editData = {};
- editData.sourceID = this._sourceIDForLine(lineNumber);
- editData.content = lines.join("\n");
- editData.line = lineNumber;
- editData.linesCountToShift = newContent.split("\n").length - 1;
- this._doEditLine(editData, cancelEditingCallback);
- },
+ var target = event.target.enclosingNodeOrSelfWithNodeName("TD");
+ if (!target || target.parentElement.firstChild === target)
+ return; // Do not trigger editing from line numbers.
- _revertEditLine: function(editData, contentToRevertTo)
- {
- var newEditData = {};
- newEditData.sourceID = editData.sourceID;
- newEditData.content = contentToRevertTo;
- newEditData.line = editData.line;
- newEditData.linesCountToShift = -editData.linesCountToShift;
- this._doEditLine(newEditData);
- },
+ var lineRow = target.parentElement;
+ var lineNumber = lineRow.lineNumber;
+ var sourceID = this._sourceIDForLine(lineNumber);
+ if (!sourceID)
+ return;
- _doEditLine: function(editData, cancelEditingCallback)
- {
- var revertEditingCallback = this._revertEditLine.bind(this, editData);
- WebInspector.panels.scripts.editScriptSource(editData, revertEditingCallback, cancelEditingCallback);
+ function didEditLine(newContent)
+ {
+ var lines = [];
+ var oldLines = this._content.split('\n');
+ for (var i = 0; i < oldLines.length; ++i) {
+ if (i === lineNumber)
+ lines.push(newContent);
+ else
+ lines.push(oldLines[i]);
+ }
+ WebInspector.debuggerModel.editScriptSource(sourceID, lines.join("\n"));
+ }
+ this._textViewer.editLine(lineRow, didEditLine.bind(this));
},
_setBreakpoint: function(lineNumber, enabled, condition)
@@ -826,7 +839,7 @@ WebInspector.SourceFrame.prototype = {
var sourceID = this._sourceIDForLine(lineNumber);
if (!sourceID)
return;
- WebInspector.debuggerModel.setBreakpoint(sourceID, lineNumber, enabled, condition);
+ WebInspector.debuggerModel.setBreakpoint(sourceID, lineNumber + 1, enabled, condition);
if (!WebInspector.panels.scripts.breakpointsActivated)
WebInspector.panels.scripts.toggleBreakpointsClicked();
},
@@ -840,7 +853,7 @@ WebInspector.SourceFrame.prototype = {
_findBreakpoint: function(lineNumber)
{
var sourceID = this._sourceIDForLine(lineNumber);
- return WebInspector.debuggerModel.findBreakpoint(sourceID, lineNumber);
+ return WebInspector.debuggerModel.findBreakpoint(sourceID, lineNumber + 1);
},
_sourceIDForLine: function(lineNumber)
@@ -849,9 +862,9 @@ WebInspector.SourceFrame.prototype = {
var closestStartingLine = 0;
var scripts = this._contentProvider.scripts();
for (var i = 0; i < scripts.length; ++i) {
- var startingLine = scripts[i].startingLine;
- if (startingLine <= lineNumber && startingLine >= closestStartingLine) {
- closestStartingLine = startingLine;
+ var lineOffset = scripts[i].lineOffset;
+ if (lineOffset <= lineNumber && lineOffset >= closestStartingLine) {
+ closestStartingLine = lineOffset;
sourceIDForLine = scripts[i].sourceID;
}
}
diff --git a/Source/WebCore/inspector/front-end/SourceView.js b/Source/WebCore/inspector/front-end/SourceView.js
index e78ff94..37caabb 100644
--- a/Source/WebCore/inspector/front-end/SourceView.js
+++ b/Source/WebCore/inspector/front-end/SourceView.js
@@ -33,8 +33,8 @@ WebInspector.SourceView = function(resource)
this.element.addStyleClass("source");
var contentProvider = new WebInspector.SourceFrameContentProviderForResource(resource);
- var canEditScripts = WebInspector.panels.scripts.canEditScripts() && resource.type === WebInspector.Resource.Type.Script;
- this.sourceFrame = new WebInspector.SourceFrame(this.element, contentProvider, resource.url, canEditScripts);
+ var isScript = resource.type === WebInspector.Resource.Type.Script;
+ this.sourceFrame = new WebInspector.SourceFrame(this.element, contentProvider, resource.url, isScript);
}
WebInspector.SourceView.prototype = {
diff --git a/Source/WebCore/inspector/front-end/StylesSidebarPane.js b/Source/WebCore/inspector/front-end/StylesSidebarPane.js
index d646829..9880adc 100644
--- a/Source/WebCore/inspector/front-end/StylesSidebarPane.js
+++ b/Source/WebCore/inspector/front-end/StylesSidebarPane.js
@@ -81,6 +81,8 @@ WebInspector.StylesSidebarPane = function(computedStylePane)
this.element.addEventListener("contextmenu", this._contextMenuEventFired.bind(this), true);
}
+WebInspector.StylesSidebarPane.StyleValueDelimiters = " \t\n\"':;,/()";
+
// Taken from http://www.w3.org/TR/CSS21/propidx.html.
WebInspector.StylesSidebarPane.InheritedProperties = [
"azimuth", "border-collapse", "border-spacing", "caption-side", "color", "cursor", "direction", "elevation",
@@ -1379,6 +1381,8 @@ WebInspector.StylePropertyTreeElement.prototype = {
}
this.listItemElement.removeChildren();
+ nameElement.normalize();
+ valueElement.normalize();
if (!this.treeOutline)
return;
@@ -1529,16 +1533,15 @@ WebInspector.StylePropertyTreeElement.prototype = {
var context = {
expanded: this.expanded,
hasChildren: this.hasChildren,
- keyDownListener: isEditingName ? this.editingNameKeyDown.bind(this) : this.editingValueKeyDown.bind(this),
- keyPressListener: isEditingName ? this.editingNameKeyPress.bind(this) : this.editingValueKeyPress.bind(this),
+ keyDownListener: isEditingName ? null : this.editingValueKeyDown.bind(this),
isEditingName: isEditingName,
};
// Lie about our children to prevent expanding on double click and to collapse shorthands.
this.hasChildren = false;
- selectElement.addEventListener("keydown", context.keyDownListener, false);
- selectElement.addEventListener("keypress", context.keyPressListener, false);
+ if (!isEditingName)
+ selectElement.addEventListener("keydown", context.keyDownListener, false);
if (selectElement.parentElement)
selectElement.parentElement.addStyleClass("child-editing");
selectElement.textContent = selectElement.textContent; // remove color swatch and the like
@@ -1613,76 +1616,15 @@ WebInspector.StylePropertyTreeElement.prototype = {
customFinishHandler: nameValueFinishHandler.bind(this, context, isEditingName),
pasteHandler: isEditingName ? pasteHandler.bind(this, context) : null
});
- window.getSelection().setBaseAndExtent(selectElement, 0, selectElement, 1);
- },
-
- editingNameKeyPress: function(event)
- {
- // Complete property names.
- var character = event.data.toLowerCase();
- if (character && /[a-z-]/.test(character)) {
- var selection = window.getSelection();
- var prefix = selection.anchorNode.textContent.substring(0, selection.anchorOffset);
- var property = WebInspector.cssNameCompletions.firstStartsWith(prefix + character);
- if (!selection.isCollapsed)
- selection.deleteFromDocument();
-
- this.restoreNameElement();
-
- if (property) {
- if (property !== this.nameElement.textContent)
- this.nameElement.textContent = property;
- this.nameElement.firstChild.select(prefix.length + 1);
- event.preventDefault();
- }
- }
- },
-
- editingValueKeyPress: function(event)
- {
- // FIXME: This should complete property values.
- },
-
- editingNameKeyDown: function(event)
- {
- var showNext;
- if (event.keyIdentifier === "Up")
- showNext = false;
- else if (event.keyIdentifier === "Down")
- showNext = true;
- else
- return;
-
- var selection = window.getSelection();
- if (!selection.rangeCount)
- return;
-
- var selectionRange = selection.getRangeAt(0);
- if (selectionRange.commonAncestorContainer !== this.nameElement && !selectionRange.commonAncestorContainer.isDescendant(this.nameElement))
- return;
-
- const styleValueDelimeters = " \t\n\"':;,/()";
- var wordRange = selectionRange.startContainer.rangeOfWord(selectionRange.startOffset, styleValueDelimeters, this.nameElement);
- var wordString = wordRange.toString();
- var cursorPosition = selectionRange.startOffset != selectionRange.endOffset ? selectionRange.startOffset : 0;
- var prefix = selectionRange.startContainer.textContent.substring(0, cursorPosition);
- var property;
-
- if (showNext)
- property = WebInspector.cssNameCompletions.next(wordString, prefix);
- else
- property = WebInspector.cssNameCompletions.previous(wordString, prefix);
-
- if (property) {
- this.nameElement.textContent = property;
- this.nameElement.firstChild.select(cursorPosition);
- }
- event.preventDefault();
+ this._prompt = new WebInspector.StylesSidebarPane.CSSPropertyPrompt(selectElement, isEditingName ? WebInspector.cssNameCompletions : WebInspector.CSSKeywordCompletions.forProperty(this.nameElement.textContent));
+ window.getSelection().setBaseAndExtent(selectElement, 0, selectElement, 1);
},
editingValueKeyDown: function(event)
{
+ if (event.handled)
+ return;
var arrowKeyPressed = (event.keyIdentifier === "Up" || event.keyIdentifier === "Down");
var pageKeyPressed = (event.keyIdentifier === "PageUp" || event.keyIdentifier === "PageDown");
if (!arrowKeyPressed && !pageKeyPressed)
@@ -1696,8 +1638,7 @@ WebInspector.StylePropertyTreeElement.prototype = {
if (selectionRange.commonAncestorContainer !== this.valueElement && !selectionRange.commonAncestorContainer.isDescendant(this.valueElement))
return;
- const styleValueDelimeters = " \t\n\"':;,/()";
- var wordRange = selectionRange.startContainer.rangeOfWord(selectionRange.startOffset, styleValueDelimeters, this.valueElement);
+ var wordRange = selectionRange.startContainer.rangeOfWord(selectionRange.startOffset, WebInspector.StylesSidebarPane.StyleValueDelimiters, this.valueElement);
var wordString = wordRange.toString();
var replacementString = wordString;
@@ -1739,42 +1680,45 @@ WebInspector.StylePropertyTreeElement.prototype = {
}
replacementString = prefix + number + suffix;
- } else {
- // FIXME: this should cycle through known keywords for the current property value.
- }
- var replacementTextNode = document.createTextNode(replacementString);
+ var replacementTextNode = document.createTextNode(replacementString);
- wordRange.deleteContents();
- wordRange.insertNode(replacementTextNode);
+ wordRange.deleteContents();
+ wordRange.insertNode(replacementTextNode);
- var finalSelectionRange = document.createRange();
- finalSelectionRange.setStart(replacementTextNode, 0);
- finalSelectionRange.setEnd(replacementTextNode, replacementString.length);
+ var finalSelectionRange = document.createRange();
+ finalSelectionRange.setStart(replacementTextNode, 0);
+ finalSelectionRange.setEnd(replacementTextNode, replacementString.length);
- selection.removeAllRanges();
- selection.addRange(finalSelectionRange);
+ selection.removeAllRanges();
+ selection.addRange(finalSelectionRange);
- event.preventDefault();
+ event.handled = true;
+ event.preventDefault();
- if (!("originalPropertyText" in this)) {
- // Remember the rule's original CSS text on [Page](Up|Down), so it can be restored
- // if the editing is canceled.
- this.originalPropertyText = this.property.propertyText;
- }
+ if (!("originalPropertyText" in this)) {
+ // Remember the rule's original CSS text on [Page](Up|Down), so it can be restored
+ // if the editing is canceled.
+ this.originalPropertyText = this.property.propertyText;
+ }
- // Synthesize property text disregarding any comments, custom whitespace etc.
- this.applyStyleText(this.nameElement.textContent + ": " + this.valueElement.textContent);
+ // Synthesize property text disregarding any comments, custom whitespace etc.
+ this.applyStyleText(this.nameElement.textContent + ": " + this.valueElement.textContent);
+ }
},
editingEnded: function(context)
{
+ if (this._prompt) {
+ this._prompt.removeFromElement();
+ delete this._prompt;
+ }
this.hasChildren = context.hasChildren;
if (context.expanded)
this.expand();
var editedElement = context.isEditingName ? this.nameElement : this.valueElement;
- editedElement.removeEventListener("keydown", context.keyDownListener, false);
- editedElement.removeEventListener("keypress", context.keyPressListener, false);
+ if (!context.isEditingName)
+ editedElement.removeEventListener("keydown", context.keyDownListener, false);
if (editedElement.parentElement)
editedElement.parentElement.removeStyleClass("child-editing");
@@ -1791,6 +1735,8 @@ WebInspector.StylePropertyTreeElement.prototype = {
else
this.updateTitle();
}
+
+ // This should happen last, as it clears the info necessary to restore the property value after [Page]Up/Down changes.
this.editingEnded(context);
},
@@ -1948,3 +1894,57 @@ WebInspector.StylePropertyTreeElement.prototype = {
}
WebInspector.StylePropertyTreeElement.prototype.__proto__ = TreeElement.prototype;
+
+WebInspector.StylesSidebarPane.CSSPropertyPrompt = function(element, cssCompletions)
+{
+ WebInspector.TextPrompt.call(this, element, this._buildPropertyCompletions.bind(this), WebInspector.StylesSidebarPane.StyleValueDelimiters, true);
+ this._cssCompletions = cssCompletions;
+}
+
+WebInspector.StylesSidebarPane.CSSPropertyPrompt.prototype = {
+ upKeyPressed: function(event)
+ {
+ this._handleNameOrValueUpDown(event);
+ },
+
+ downKeyPressed: function(event)
+ {
+ this._handleNameOrValueUpDown(event);
+ },
+
+ tabKeyPressed: function(event)
+ {
+ this.acceptAutoComplete();
+ },
+
+ _handleNameOrValueUpDown: function(event)
+ {
+ var reverse = event.keyIdentifier === "Up";
+ if (this.autoCompleteElement)
+ this.complete(false, reverse); // Accept the current suggestion, if any.
+ this.complete(false, reverse); // Actually increment/decrement the suggestion.
+ event.handled = true;
+ },
+
+ _buildPropertyCompletions: function(wordRange, bestMatchOnly, completionsReadyCallback)
+ {
+ var prefix = wordRange.toString().toLowerCase();
+ if (!prefix.length)
+ return;
+
+ var results;
+ if (bestMatchOnly) {
+ results = [];
+ var firstMatch = this._cssCompletions.firstStartsWith(prefix);
+ if (firstMatch)
+ results.push(firstMatch);
+ return completionsReadyCallback(results);
+ }
+
+ results = this._cssCompletions.startsWith(prefix);
+ if (results)
+ completionsReadyCallback(results);
+ }
+}
+
+WebInspector.StylesSidebarPane.CSSPropertyPrompt.prototype.__proto__ = WebInspector.TextPrompt.prototype;
diff --git a/Source/WebCore/inspector/front-end/TextPrompt.js b/Source/WebCore/inspector/front-end/TextPrompt.js
index 21a5bde..ac54d8c 100644
--- a/Source/WebCore/inspector/front-end/TextPrompt.js
+++ b/Source/WebCore/inspector/front-end/TextPrompt.js
@@ -26,15 +26,18 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-WebInspector.TextPrompt = function(element, completions, stopCharacters)
+WebInspector.TextPrompt = function(element, completions, stopCharacters, omitHistory)
{
this.element = element;
this.element.addStyleClass("text-prompt");
this.completions = completions;
this.completionStopCharacters = stopCharacters;
- this.history = [];
- this.historyOffset = 0;
- this.element.addEventListener("keydown", this._onKeyDown.bind(this), true);
+ if (!omitHistory) {
+ this.history = [];
+ this.historyOffset = 0;
+ }
+ this._boundOnKeyDown = this._onKeyDown.bind(this);
+ this.element.addEventListener("keydown", this._boundOnKeyDown, true);
}
WebInspector.TextPrompt.prototype = {
@@ -55,6 +58,12 @@ WebInspector.TextPrompt.prototype = {
this.moveCaretToEndOfPrompt();
},
+ removeFromElement: function()
+ {
+ this.clearAutoComplete(true);
+ this.element.removeEventListener("keydown", this._boundOnKeyDown, true);
+ },
+
_onKeyDown: function(event)
{
function defaultAction()
@@ -63,16 +72,20 @@ WebInspector.TextPrompt.prototype = {
this.autoCompleteSoon();
}
+ if (event.handled)
+ return;
+
var handled = false;
+
switch (event.keyIdentifier) {
case "Up":
- this._upKeyPressed(event);
+ this.upKeyPressed(event);
break;
case "Down":
- this._downKeyPressed(event);
+ this.downKeyPressed(event);
break;
case "U+0009": // Tab
- this._tabKeyPressed(event);
+ this.tabKeyPressed(event);
break;
case "Right":
case "End":
@@ -85,7 +98,7 @@ WebInspector.TextPrompt.prototype = {
case "Control":
break;
case "U+0050": // Ctrl+P = Previous
- if (WebInspector.isMac() && event.ctrlKey && !event.metaKey && !event.altKey && !event.shiftKey) {
+ if (this.history && WebInspector.isMac() && event.ctrlKey && !event.metaKey && !event.altKey && !event.shiftKey) {
handled = true;
this._moveBackInHistory();
break;
@@ -93,7 +106,7 @@ WebInspector.TextPrompt.prototype = {
defaultAction.call(this);
break;
case "U+004E": // Ctrl+N = Next
- if (WebInspector.isMac() && event.ctrlKey && !event.metaKey && !event.altKey && !event.shiftKey) {
+ if (this.history && WebInspector.isMac() && event.ctrlKey && !event.metaKey && !event.altKey && !event.shiftKey) {
handled = true;
this._moveForwardInHistory();
break;
@@ -105,7 +118,9 @@ WebInspector.TextPrompt.prototype = {
break;
}
+ handled |= event.handled;
if (handled) {
+ event.handled = true;
event.preventDefault();
event.stopPropagation();
}
@@ -376,39 +391,33 @@ WebInspector.TextPrompt.prototype = {
selection.addRange(selectionRange);
},
- _tabKeyPressed: function(event)
+ tabKeyPressed: function(event)
{
- event.preventDefault();
- event.stopPropagation();
-
+ event.handled = true;
this.complete(false, event.shiftKey);
},
- _upKeyPressed: function(event)
+ upKeyPressed: function(event)
{
if (!this.isCaretOnFirstLine())
return;
- event.preventDefault();
- event.stopPropagation();
-
+ event.handled = true;
this._moveBackInHistory();
},
- _downKeyPressed: function(event)
+ downKeyPressed: function(event)
{
if (!this.isCaretOnLastLine())
return;
- event.preventDefault();
- event.stopPropagation();
-
+ event.handled = true;
this._moveForwardInHistory();
},
_moveBackInHistory: function()
{
- if (this.historyOffset == this.history.length)
+ if (!this.history || this.historyOffset == this.history.length)
return;
this.clearAutoComplete(true);
@@ -437,7 +446,7 @@ WebInspector.TextPrompt.prototype = {
_moveForwardInHistory: function()
{
- if (this.historyOffset === 0)
+ if (!this.history || this.historyOffset === 0)
return;
this.clearAutoComplete(true);
diff --git a/Source/WebCore/inspector/front-end/TextViewer.js b/Source/WebCore/inspector/front-end/TextViewer.js
index f116dea..ea36513 100644
--- a/Source/WebCore/inspector/front-end/TextViewer.js
+++ b/Source/WebCore/inspector/front-end/TextViewer.js
@@ -43,7 +43,6 @@ WebInspector.TextViewer = function(textModel, platform, url)
this.element.addEventListener("keydown", this._handleKeyDown.bind(this), false);
this.element.addEventListener("beforecopy", this._beforeCopy.bind(this), false);
this.element.addEventListener("copy", this._copy.bind(this), false);
- this.element.addEventListener("dblclick", this._handleDoubleClick.bind(this), false);
this._url = url;
@@ -80,11 +79,6 @@ WebInspector.TextViewer.prototype = {
chunk.element.scrollIntoViewIfNeeded();
},
- set editCallback(editCallback)
- {
- this._editCallback = editCallback;
- },
-
addDecoration: function(lineNumber, decoration)
{
var chunk = this._makeLineAChunk(lineNumber);
@@ -231,20 +225,20 @@ WebInspector.TextViewer.prototype = {
scrollValue = -1;
else if (event.keyCode == WebInspector.KeyboardShortcut.Keys.Down.code)
scrollValue = 1;
-
+
if (scrollValue) {
event.preventDefault();
event.stopPropagation();
this.element.scrollByLines(scrollValue);
return;
}
-
+
scrollValue = 0;
if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Left.code)
scrollValue = -40;
else if (event.keyCode == WebInspector.KeyboardShortcut.Keys.Right.code)
scrollValue = 40;
-
+
if (scrollValue) {
event.preventDefault();
event.stopPropagation();
@@ -252,42 +246,25 @@ WebInspector.TextViewer.prototype = {
}
},
- _handleDoubleClick: function(e)
+ editLine: function(lineRow, callback)
{
- if (!this._editCallback)
- return;
-
- var cell = e.target.enclosingNodeOrSelfWithNodeName("TD");
- if (!cell)
- return;
-
- var lineRow = cell.parentElement;
- if (lineRow.firstChild === cell)
- return; // Do not trigger editing from line numbers.
-
- var oldContent = lineRow.lastChild.innerHTML;
- 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, {
+ var element = lineRow.lastChild;
+ var oldContent = element.innerHTML;
+ function finishEditing(committed, e, newContent)
+ {
+ if (committed)
+ callback(newContent);
+ element.innerHTML = oldContent;
+ delete this._editingLine;
+ }
+ this._editingLine = WebInspector.startEditing(element, {
context: null,
- commitHandler: commitEditingCallback,
- cancelHandler: cancelEditingCallback,
+ commitHandler: finishEditing.bind(this, true),
+ cancelHandler: finishEditing.bind(this, false),
multiline: true
});
},
- _commitEditingLine: function(lineNumber, element, cancelEditingCallback)
- {
- this._editCallback(lineNumber, element.textContent, cancelEditingCallback);
- delete this._editingLine;
- },
-
- _cancelEditingLine: function(element, oldContent, e)
- {
- element.innerHTML = oldContent;
- delete this._editingLine;
- },
-
_beforeCopy: function(e)
{
e.preventDefault();
@@ -786,7 +763,7 @@ WebInspector.TextChunk.prototype = {
var lineContentElement = document.createElement("td");
lineContentElement.className = "webkit-line-content";
- lineRow.appendChild(lineContentElement);
+ lineRow.appendChild(lineContentElement);
}
lineRow.lineNumber = lineNumber;
lineNumberElement.textContent = lineNumber + 1;
diff --git a/Source/WebCore/inspector/front-end/UglifyJS/parse-js.js b/Source/WebCore/inspector/front-end/UglifyJS/parse-js.js
new file mode 100644
index 0000000..a218c01
--- /dev/null
+++ b/Source/WebCore/inspector/front-end/UglifyJS/parse-js.js
@@ -0,0 +1,1233 @@
+/***********************************************************************
+
+ A JavaScript tokenizer / parser / beautifier / compressor.
+
+ This version is suitable for Node.js. With minimal changes (the
+ exports stuff) it should work on any JS platform.
+
+ This file contains the tokenizer/parser. It is a port to JavaScript
+ of parse-js [1], a JavaScript parser library written in Common Lisp
+ by Marijn Haverbeke. Thank you Marijn!
+
+ [1] http://marijn.haverbeke.nl/parse-js/
+
+ Exported functions:
+
+ - tokenizer(code) -- returns a function. Call the returned
+ function to fetch the next token.
+
+ - parse(code) -- returns an AST of the given JavaScript code.
+
+ -------------------------------- (C) ---------------------------------
+
+ Author: Mihai Bazon
+ <mihai.bazon@gmail.com>
+ http://mihai.bazon.net/blog
+
+ Distributed under the BSD license:
+
+ Copyright 2010 (c) Mihai Bazon <mihai.bazon@gmail.com>
+ Based on parse-js (http://marijn.haverbeke.nl/parse-js/).
+
+ 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.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “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 HOLDER 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.
+
+ ***********************************************************************/
+
+/* -----[ Tokenizer (constants) ]----- */
+
+var KEYWORDS = array_to_hash([
+ "break",
+ "case",
+ "catch",
+ "const",
+ "continue",
+ "default",
+ "delete",
+ "do",
+ "else",
+ "finally",
+ "for",
+ "function",
+ "if",
+ "in",
+ "instanceof",
+ "new",
+ "return",
+ "switch",
+ "throw",
+ "try",
+ "typeof",
+ "var",
+ "void",
+ "while",
+ "with"
+]);
+
+var RESERVED_WORDS = array_to_hash([
+ "abstract",
+ "boolean",
+ "byte",
+ "char",
+ "class",
+ "debugger",
+ "double",
+ "enum",
+ "export",
+ "extends",
+ "final",
+ "float",
+ "goto",
+ "implements",
+ "import",
+ "int",
+ "interface",
+ "long",
+ "native",
+ "package",
+ "private",
+ "protected",
+ "public",
+ "short",
+ "static",
+ "super",
+ "synchronized",
+ "throws",
+ "transient",
+ "volatile"
+]);
+
+var KEYWORDS_BEFORE_EXPRESSION = array_to_hash([
+ "return",
+ "new",
+ "delete",
+ "throw",
+ "else",
+ "case"
+]);
+
+var KEYWORDS_ATOM = array_to_hash([
+ "false",
+ "null",
+ "true",
+ "undefined"
+]);
+
+var OPERATOR_CHARS = array_to_hash(characters("+-*&%=<>!?|~^"));
+
+var RE_HEX_NUMBER = /^0x[0-9a-f]+$/i;
+var RE_OCT_NUMBER = /^0[0-7]+$/;
+var RE_DEC_NUMBER = /^\d*\.?\d*(?:e[+-]?\d*(?:\d\.?|\.?\d)\d*)?$/i;
+
+var OPERATORS = array_to_hash([
+ "in",
+ "instanceof",
+ "typeof",
+ "new",
+ "void",
+ "delete",
+ "++",
+ "--",
+ "+",
+ "-",
+ "!",
+ "~",
+ "&",
+ "|",
+ "^",
+ "*",
+ "/",
+ "%",
+ ">>",
+ "<<",
+ ">>>",
+ "<",
+ ">",
+ "<=",
+ ">=",
+ "==",
+ "===",
+ "!=",
+ "!==",
+ "?",
+ "=",
+ "+=",
+ "-=",
+ "/=",
+ "*=",
+ "%=",
+ ">>=",
+ "<<=",
+ ">>>=",
+ "~=",
+ "%=",
+ "|=",
+ "^=",
+ "&=",
+ "&&",
+ "||"
+]);
+
+var WHITESPACE_CHARS = array_to_hash(characters(" \n\r\t"));
+
+var PUNC_BEFORE_EXPRESSION = array_to_hash(characters("[{}(,.;:"));
+
+var PUNC_CHARS = array_to_hash(characters("[]{}(),;:"));
+
+var REGEXP_MODIFIERS = array_to_hash(characters("gmsiy"));
+
+/* -----[ Tokenizer ]----- */
+
+function is_alphanumeric_char(ch) {
+ ch = ch.charCodeAt(0);
+ return (ch >= 48 && ch <= 57) ||
+ (ch >= 65 && ch <= 90) ||
+ (ch >= 97 && ch <= 122);
+};
+
+function is_identifier_char(ch) {
+ return is_alphanumeric_char(ch) || ch == "$" || ch == "_";
+};
+
+function is_digit(ch) {
+ ch = ch.charCodeAt(0);
+ return ch >= 48 && ch <= 57;
+};
+
+function parse_js_number(num) {
+ if (RE_HEX_NUMBER.test(num)) {
+ return parseInt(num.substr(2), 16);
+ } else if (RE_OCT_NUMBER.test(num)) {
+ return parseInt(num.substr(1), 8);
+ } else if (RE_DEC_NUMBER.test(num)) {
+ return parseFloat(num);
+ }
+};
+
+function JS_Parse_Error(message, line, col, pos) {
+ this.message = message;
+ this.line = line;
+ this.col = col;
+ this.pos = pos;
+ try {
+ ({})();
+ } catch(ex) {
+ this.stack = ex.stack;
+ };
+};
+
+JS_Parse_Error.prototype.toString = function() {
+ return this.message + " (line: " + this.line + ", col: " + this.col + ", pos: " + this.pos + ")" + "\n\n" + this.stack;
+};
+
+function js_error(message, line, col, pos) {
+ throw new JS_Parse_Error(message, line, col, pos);
+};
+
+function is_token(token, type, val) {
+ return token.type == type && (val == null || token.value == val);
+};
+
+var EX_EOF = {};
+
+function tokenizer($TEXT, skip_comments) {
+
+ var S = {
+ text : $TEXT.replace(/\r\n?|[\n\u2028\u2029]/g, "\n").replace(/^\uFEFF/, ''),
+ pos : 0,
+ tokpos : 0,
+ line : 0,
+ tokline : 0,
+ col : 0,
+ tokcol : 0,
+ newline_before : false,
+ regex_allowed : false
+ };
+
+ function peek() { return S.text.charAt(S.pos); };
+
+ function next(signal_eof) {
+ var ch = S.text.charAt(S.pos++);
+ if (signal_eof && !ch)
+ throw EX_EOF;
+ if (ch == "\n") {
+ S.newline_before = true;
+ ++S.line;
+ S.col = 0;
+ } else {
+ ++S.col;
+ }
+ return ch;
+ };
+
+ function eof() {
+ return !S.peek();
+ };
+
+ function find(what, signal_eof) {
+ var pos = S.text.indexOf(what, S.pos);
+ if (signal_eof && pos == -1) throw EX_EOF;
+ return pos;
+ };
+
+ function start_token() {
+ S.tokline = S.line;
+ S.tokcol = S.col;
+ S.tokpos = S.pos;
+ };
+
+ function token(type, value) {
+ S.regex_allowed = ((type == "operator" && !HOP(UNARY_POSTFIX, value)) ||
+ (type == "keyword" && HOP(KEYWORDS_BEFORE_EXPRESSION, value)) ||
+ (type == "punc" && HOP(PUNC_BEFORE_EXPRESSION, value)));
+ var ret = {
+ type : type,
+ value : value,
+ line : S.tokline,
+ col : S.tokcol,
+ pos : S.tokpos,
+ nlb : S.newline_before
+ };
+ S.newline_before = false;
+ return ret;
+ };
+
+ function skip_whitespace() {
+ while (HOP(WHITESPACE_CHARS, peek()))
+ next();
+ };
+
+ function read_while(pred) {
+ var ret = "", ch = peek(), i = 0;
+ while (ch && pred(ch, i++)) {
+ ret += next();
+ ch = peek();
+ }
+ return ret;
+ };
+
+ function parse_error(err) {
+ js_error(err, S.tokline, S.tokcol, S.tokpos);
+ };
+
+ function read_num(prefix) {
+ var has_e = false, after_e = false, has_x = false;
+ var num = read_while(function(ch, i){
+ if (ch == "x" || ch == "X") {
+ if (has_x) return false;
+ return has_x = true;
+ }
+ if (!has_x && (ch == "E" || ch == "e")) {
+ if (has_e) return false;
+ return has_e = after_e = true;
+ }
+ if (ch == "-") {
+ if (after_e || (i == 0 && !prefix)) return true;
+ return false;
+ }
+ if (ch == "+") return after_e;
+ after_e = false;
+ return is_alphanumeric_char(ch) || ch == ".";
+ });
+ if (prefix)
+ num = prefix + num;
+ var valid = parse_js_number(num);
+ if (!isNaN(valid)) {
+ return token("num", valid);
+ } else {
+ parse_error("Invalid syntax: " + num);
+ }
+ };
+
+ function read_escaped_char() {
+ var ch = next(true);
+ switch (ch) {
+ case "n" : return "\n";
+ case "r" : return "\r";
+ case "t" : return "\t";
+ case "b" : return "\b";
+ case "v" : return "\v";
+ case "f" : return "\f";
+ case "0" : return "\0";
+ case "x" : return String.fromCharCode(hex_bytes(2));
+ case "u" : return String.fromCharCode(hex_bytes(4));
+ default : return ch;
+ }
+ };
+
+ function hex_bytes(n) {
+ var num = 0;
+ for (; n > 0; --n) {
+ var digit = parseInt(next(true), 16);
+ if (isNaN(digit))
+ parse_error("Invalid hex-character pattern in string");
+ num = (num << 4) | digit;
+ }
+ return num;
+ };
+
+ function read_string() {
+ return with_eof_error("Unterminated string constant", function(){
+ var quote = next(), ret = "";
+ for (;;) {
+ var ch = next(true);
+ if (ch == "\\") ch = read_escaped_char();
+ else if (ch == quote) break;
+ ret += ch;
+ }
+ return token("string", ret);
+ });
+ };
+
+ function read_line_comment() {
+ next();
+ var i = find("\n"), ret;
+ if (i == -1) {
+ ret = S.text.substr(S.pos);
+ S.pos = S.text.length;
+ } else {
+ ret = S.text.substring(S.pos, i);
+ S.pos = i;
+ }
+ return token("comment1", ret);
+ };
+
+ function read_multiline_comment() {
+ next();
+ return with_eof_error("Unterminated multiline comment", function(){
+ var i = find("*/", true),
+ text = S.text.substring(S.pos, i),
+ tok = token("comment2", text);
+ S.pos = i + 2;
+ S.newline_before = text.indexOf("\n") >= 0;
+ return tok;
+ });
+ };
+
+ function read_regexp() {
+ return with_eof_error("Unterminated regular expression", function(){
+ var prev_backslash = false, regexp = "", ch, in_class = false;
+ while ((ch = next(true))) if (prev_backslash) {
+ regexp += "\\" + ch;
+ prev_backslash = false;
+ } else if (ch == "[") {
+ in_class = true;
+ regexp += ch;
+ } else if (ch == "]" && in_class) {
+ in_class = false;
+ regexp += ch;
+ } else if (ch == "/" && !in_class) {
+ break;
+ } else if (ch == "\\") {
+ prev_backslash = true;
+ } else {
+ regexp += ch;
+ }
+ var mods = read_while(function(ch){
+ return HOP(REGEXP_MODIFIERS, ch);
+ });
+ return token("regexp", [ regexp, mods ]);
+ });
+ };
+
+ function read_operator(prefix) {
+ function grow(op) {
+ var bigger = op + peek();
+ if (HOP(OPERATORS, bigger)) {
+ next();
+ return grow(bigger);
+ } else {
+ return op;
+ }
+ };
+ return token("operator", grow(prefix || next()));
+ };
+
+ var handle_slash = skip_comments ? function() {
+ next();
+ var regex_allowed = S.regex_allowed;
+ switch (peek()) {
+ case "/": read_line_comment(); S.regex_allowed = regex_allowed; return next_token();
+ case "*": read_multiline_comment(); S.regex_allowed = regex_allowed; return next_token();
+ }
+ return S.regex_allowed ? read_regexp() : read_operator("/");
+ } : function() {
+ next();
+ switch (peek()) {
+ case "/": return read_line_comment();
+ case "*": return read_multiline_comment();
+ }
+ return S.regex_allowed ? read_regexp() : read_operator("/");
+ };
+
+ function handle_dot() {
+ next();
+ return is_digit(peek())
+ ? read_num(".")
+ : token("punc", ".");
+ };
+
+ function read_word() {
+ var word = read_while(is_identifier_char);
+ return !HOP(KEYWORDS, word)
+ ? token("name", word)
+ : HOP(OPERATORS, word)
+ ? token("operator", word)
+ : HOP(KEYWORDS_ATOM, word)
+ ? token("atom", word)
+ : token("keyword", word);
+ };
+
+ function with_eof_error(eof_error, cont) {
+ try {
+ return cont();
+ } catch(ex) {
+ if (ex === EX_EOF) parse_error(eof_error);
+ else throw ex;
+ }
+ };
+
+ function next_token(force_regexp) {
+ if (force_regexp)
+ return read_regexp();
+ skip_whitespace();
+ start_token();
+ var ch = peek();
+ if (!ch) return token("eof");
+ if (is_digit(ch)) return read_num();
+ if (ch == '"' || ch == "'") return read_string();
+ if (HOP(PUNC_CHARS, ch)) return token("punc", next());
+ if (ch == ".") return handle_dot();
+ if (ch == "/") return handle_slash();
+ if (HOP(OPERATOR_CHARS, ch)) return read_operator();
+ if (is_identifier_char(ch)) return read_word();
+ parse_error("Unexpected character '" + ch + "'");
+ };
+
+ next_token.context = function(nc) {
+ if (nc) S = nc;
+ return S;
+ };
+
+ return next_token;
+
+};
+
+/* -----[ Parser (constants) ]----- */
+
+var UNARY_PREFIX = array_to_hash([
+ "typeof",
+ "void",
+ "delete",
+ "--",
+ "++",
+ "!",
+ "~",
+ "-",
+ "+"
+]);
+
+var UNARY_POSTFIX = array_to_hash([ "--", "++" ]);
+
+var ASSIGNMENT = (function(a, ret, i){
+ while (i < a.length) {
+ ret[a[i]] = a[i].substr(0, a[i].length - 1);
+ i++;
+ }
+ return ret;
+})(
+ ["+=", "-=", "/=", "*=", "%=", ">>=", "<<=", ">>>=", "~=", "%=", "|=", "^=", "&="],
+ { "=": true },
+ 0
+);
+
+var PRECEDENCE = (function(a, ret){
+ for (var i = 0, n = 1; i < a.length; ++i, ++n) {
+ var b = a[i];
+ for (var j = 0; j < b.length; ++j) {
+ ret[b[j]] = n;
+ }
+ }
+ return ret;
+})(
+ [
+ ["||"],
+ ["&&"],
+ ["|"],
+ ["^"],
+ ["&"],
+ ["==", "===", "!=", "!=="],
+ ["<", ">", "<=", ">=", "in", "instanceof"],
+ [">>", "<<", ">>>"],
+ ["+", "-"],
+ ["*", "/", "%"]
+ ],
+ {}
+);
+
+var STATEMENTS_WITH_LABELS = array_to_hash([ "for", "do", "while", "switch" ]);
+
+var ATOMIC_START_TOKEN = array_to_hash([ "atom", "num", "string", "regexp", "name" ]);
+
+/* -----[ Parser ]----- */
+
+function NodeWithToken(str, start, end) {
+ this.name = str;
+ this.start = start;
+ this.end = end;
+};
+
+NodeWithToken.prototype.toString = function() { return this.name; };
+
+function parse($TEXT, strict_mode, embed_tokens) {
+
+ var S = {
+ input: tokenizer($TEXT, true),
+ token: null,
+ prev: null,
+ peeked: null,
+ in_function: 0,
+ in_loop: 0,
+ labels: []
+ };
+
+ S.token = next();
+
+ function is(type, value) {
+ return is_token(S.token, type, value);
+ };
+
+ function peek() { return S.peeked || (S.peeked = S.input()); };
+
+ function next() {
+ S.prev = S.token;
+ if (S.peeked) {
+ S.token = S.peeked;
+ S.peeked = null;
+ } else {
+ S.token = S.input();
+ }
+ return S.token;
+ };
+
+ function prev() {
+ return S.prev;
+ };
+
+ function croak(msg, line, col, pos) {
+ var ctx = S.input.context();
+ js_error(msg,
+ line != null ? line : ctx.tokline,
+ col != null ? col : ctx.tokcol,
+ pos != null ? pos : ctx.tokpos);
+ };
+
+ function token_error(token, msg) {
+ croak(msg, token.line, token.col);
+ };
+
+ function unexpected(token) {
+ if (token == null)
+ token = S.token;
+ token_error(token, "Unexpected token: " + token.type + " (" + token.value + ")");
+ };
+
+ function expect_token(type, val) {
+ if (is(type, val)) {
+ return next();
+ }
+ token_error(S.token, "Unexpected token " + S.token.type + ", expected " + type);
+ };
+
+ function expect(punc) { return expect_token("punc", punc); };
+
+ function can_insert_semicolon() {
+ return !strict_mode && (
+ S.token.nlb || is("eof") || is("punc", "}")
+ );
+ };
+
+ function semicolon() {
+ if (is("punc", ";")) next();
+ else if (!can_insert_semicolon()) unexpected();
+ };
+
+ function as() {
+ return slice(arguments);
+ };
+
+ function parenthesised() {
+ expect("(");
+ var ex = expression();
+ expect(")");
+ return ex;
+ };
+
+ function add_tokens(str, start, end) {
+ return new NodeWithToken(str, start, end);
+ };
+
+ var statement = embed_tokens ? function() {
+ var start = S.token;
+ var stmt = $statement();
+ stmt[0] = add_tokens(stmt[0], start, prev());
+ return stmt;
+ } : $statement;
+
+ function $statement() {
+ if (is("operator", "/")) {
+ S.peeked = null;
+ S.token = S.input(true); // force regexp
+ }
+ switch (S.token.type) {
+ case "num":
+ case "string":
+ case "regexp":
+ case "operator":
+ case "atom":
+ return simple_statement();
+
+ case "name":
+ return is_token(peek(), "punc", ":")
+ ? labeled_statement(prog1(S.token.value, next, next))
+ : simple_statement();
+
+ case "punc":
+ switch (S.token.value) {
+ case "{":
+ return as("block", block_());
+ case "[":
+ case "(":
+ return simple_statement();
+ case ";":
+ next();
+ return as("block");
+ default:
+ unexpected();
+ }
+
+ case "keyword":
+ switch (prog1(S.token.value, next)) {
+ case "break":
+ return break_cont("break");
+
+ case "continue":
+ return break_cont("continue");
+
+ case "debugger":
+ semicolon();
+ return as("debugger");
+
+ case "do":
+ return (function(body){
+ expect_token("keyword", "while");
+ return as("do", prog1(parenthesised, semicolon), body);
+ })(in_loop(statement));
+
+ case "for":
+ return for_();
+
+ case "function":
+ return function_(true);
+
+ case "if":
+ return if_();
+
+ case "return":
+ if (S.in_function == 0)
+ croak("'return' outside of function");
+ return as("return",
+ is("punc", ";")
+ ? (next(), null)
+ : can_insert_semicolon()
+ ? null
+ : prog1(expression, semicolon));
+
+ case "switch":
+ return as("switch", parenthesised(), switch_block_());
+
+ case "throw":
+ return as("throw", prog1(expression, semicolon));
+
+ case "try":
+ return try_();
+
+ case "var":
+ return prog1(var_, semicolon);
+
+ case "const":
+ return prog1(const_, semicolon);
+
+ case "while":
+ return as("while", parenthesised(), in_loop(statement));
+
+ case "with":
+ return as("with", parenthesised(), statement());
+
+ default:
+ unexpected();
+ }
+ }
+ };
+
+ function labeled_statement(label) {
+ S.labels.push(label);
+ var start = S.token, stat = statement();
+ if (strict_mode && !HOP(STATEMENTS_WITH_LABELS, stat[0]))
+ unexpected(start);
+ S.labels.pop();
+ return as("label", label, stat);
+ };
+
+ function simple_statement() {
+ return as("stat", prog1(expression, semicolon));
+ };
+
+ function break_cont(type) {
+ var name = is("name") ? S.token.value : null;
+ if (name != null) {
+ next();
+ if (!member(name, S.labels))
+ croak("Label " + name + " without matching loop or statement");
+ }
+ else if (S.in_loop == 0)
+ croak(type + " not inside a loop or switch");
+ semicolon();
+ return as(type, name);
+ };
+
+ function for_() {
+ expect("(");
+ var has_var = is("keyword", "var");
+ if (has_var)
+ next();
+ if (is("name") && is_token(peek(), "operator", "in")) {
+ // for (i in foo)
+ var name = S.token.value;
+ next(); next();
+ var obj = expression();
+ expect(")");
+ return as("for-in", has_var, name, obj, in_loop(statement));
+ } else {
+ // classic for
+ var init = is("punc", ";") ? null : has_var ? var_() : expression();
+ expect(";");
+ var test = is("punc", ";") ? null : expression();
+ expect(";");
+ var step = is("punc", ")") ? null : expression();
+ expect(")");
+ return as("for", init, test, step, in_loop(statement));
+ }
+ };
+
+ function function_(in_statement) {
+ var name = is("name") ? prog1(S.token.value, next) : null;
+ if (in_statement && !name)
+ unexpected();
+ expect("(");
+ return as(in_statement ? "defun" : "function",
+ name,
+ // arguments
+ (function(first, a){
+ while (!is("punc", ")")) {
+ if (first) first = false; else expect(",");
+ if (!is("name")) unexpected();
+ a.push(S.token.value);
+ next();
+ }
+ next();
+ return a;
+ })(true, []),
+ // body
+ (function(){
+ ++S.in_function;
+ var loop = S.in_loop;
+ S.in_loop = 0;
+ var a = block_();
+ --S.in_function;
+ S.in_loop = loop;
+ return a;
+ })());
+ };
+
+ function if_() {
+ var cond = parenthesised(), body = statement(), belse;
+ if (is("keyword", "else")) {
+ next();
+ belse = statement();
+ }
+ return as("if", cond, body, belse);
+ };
+
+ function block_() {
+ expect("{");
+ var a = [];
+ while (!is("punc", "}")) {
+ if (is("eof")) unexpected();
+ a.push(statement());
+ }
+ next();
+ return a;
+ };
+
+ var switch_block_ = curry(in_loop, function(){
+ expect("{");
+ var a = [], cur = null;
+ while (!is("punc", "}")) {
+ if (is("eof")) unexpected();
+ if (is("keyword", "case")) {
+ next();
+ cur = [];
+ a.push([ expression(), cur ]);
+ expect(":");
+ }
+ else if (is("keyword", "default")) {
+ next();
+ expect(":");
+ cur = [];
+ a.push([ null, cur ]);
+ }
+ else {
+ if (!cur) unexpected();
+ cur.push(statement());
+ }
+ }
+ next();
+ return a;
+ });
+
+ function try_() {
+ var body = block_(), bcatch, bfinally;
+ if (is("keyword", "catch")) {
+ next();
+ expect("(");
+ if (!is("name"))
+ croak("Name expected");
+ var name = S.token.value;
+ next();
+ expect(")");
+ bcatch = [ name, block_() ];
+ }
+ if (is("keyword", "finally")) {
+ next();
+ bfinally = block_();
+ }
+ if (!bcatch && !bfinally)
+ croak("Missing catch/finally blocks");
+ return as("try", body, bcatch, bfinally);
+ };
+
+ function vardefs() {
+ var a = [];
+ for (;;) {
+ if (!is("name"))
+ unexpected();
+ var name = S.token.value;
+ next();
+ if (is("operator", "=")) {
+ next();
+ a.push([ name, expression(false) ]);
+ } else {
+ a.push([ name ]);
+ }
+ if (!is("punc", ","))
+ break;
+ next();
+ }
+ return a;
+ };
+
+ function var_() {
+ return as("var", vardefs());
+ };
+
+ function const_() {
+ return as("const", vardefs());
+ };
+
+ function new_() {
+ var newexp = expr_atom(false), args;
+ if (is("punc", "(")) {
+ next();
+ args = expr_list(")");
+ } else {
+ args = [];
+ }
+ return subscripts(as("new", newexp, args), true);
+ };
+
+ function expr_atom(allow_calls) {
+ if (is("operator", "new")) {
+ next();
+ return new_();
+ }
+ if (is("operator") && HOP(UNARY_PREFIX, S.token.value)) {
+ return make_unary("unary-prefix",
+ prog1(S.token.value, next),
+ expr_atom(allow_calls));
+ }
+ if (is("punc")) {
+ switch (S.token.value) {
+ case "(":
+ next();
+ return subscripts(prog1(expression, curry(expect, ")")), allow_calls);
+ case "[":
+ next();
+ return subscripts(array_(), allow_calls);
+ case "{":
+ next();
+ return subscripts(object_(), allow_calls);
+ }
+ unexpected();
+ }
+ if (is("keyword", "function")) {
+ next();
+ return subscripts(function_(false), allow_calls);
+ }
+ if (HOP(ATOMIC_START_TOKEN, S.token.type)) {
+ var atom = S.token.type == "regexp"
+ ? as("regexp", S.token.value[0], S.token.value[1])
+ : as(S.token.type, S.token.value);
+ return subscripts(prog1(atom, next), allow_calls);
+ }
+ unexpected();
+ };
+
+ function expr_list(closing, allow_trailing_comma) {
+ var first = true, a = [];
+ while (!is("punc", closing)) {
+ if (first) first = false; else expect(",");
+ if (allow_trailing_comma && is("punc", closing))
+ break;
+ a.push(expression(false));
+ }
+ next();
+ return a;
+ };
+
+ function array_() {
+ return as("array", expr_list("]", !strict_mode));
+ };
+
+ function object_() {
+ var first = true, a = [];
+ while (!is("punc", "}")) {
+ if (first) first = false; else expect(",");
+ if (!strict_mode && is("punc", "}"))
+ // allow trailing comma
+ break;
+ var type = S.token.type;
+ var name = as_property_name();
+ if (type == "name" && (name == "get" || name == "set") && !is("punc", ":")) {
+ a.push([ as_name(), function_(false), name ]);
+ } else {
+ expect(":");
+ a.push([ name, expression(false) ]);
+ }
+ }
+ next();
+ return as("object", a);
+ };
+
+ function as_property_name() {
+ switch (S.token.type) {
+ case "num":
+ case "string":
+ return prog1(S.token.value, next);
+ }
+ return as_name();
+ };
+
+ function as_name() {
+ switch (S.token.type) {
+ case "name":
+ case "operator":
+ case "keyword":
+ case "atom":
+ return prog1(S.token.value, next);
+ default:
+ unexpected();
+ }
+ };
+
+ function subscripts(expr, allow_calls) {
+ if (is("punc", ".")) {
+ next();
+ return subscripts(as("dot", expr, as_name()), allow_calls);
+ }
+ if (is("punc", "[")) {
+ next();
+ return subscripts(as("sub", expr, prog1(expression, curry(expect, "]"))), allow_calls);
+ }
+ if (allow_calls && is("punc", "(")) {
+ next();
+ return subscripts(as("call", expr, expr_list(")")), true);
+ }
+ if (allow_calls && is("operator") && HOP(UNARY_POSTFIX, S.token.value)) {
+ return prog1(curry(make_unary, "unary-postfix", S.token.value, expr),
+ next);
+ }
+ return expr;
+ };
+
+ function make_unary(tag, op, expr) {
+ if ((op == "++" || op == "--") && !is_assignable(expr))
+ croak("Invalid use of " + op + " operator");
+ return as(tag, op, expr);
+ };
+
+ function expr_op(left, min_prec) {
+ var op = is("operator") ? S.token.value : null;
+ var prec = op != null ? PRECEDENCE[op] : null;
+ if (prec != null && prec > min_prec) {
+ next();
+ var right = expr_op(expr_atom(true), prec);
+ return expr_op(as("binary", op, left, right), min_prec);
+ }
+ return left;
+ };
+
+ function expr_ops() {
+ return expr_op(expr_atom(true), 0);
+ };
+
+ function maybe_conditional() {
+ var expr = expr_ops();
+ if (is("operator", "?")) {
+ next();
+ var yes = expression(false);
+ expect(":");
+ return as("conditional", expr, yes, expression(false));
+ }
+ return expr;
+ };
+
+ function is_assignable(expr) {
+ switch (expr[0]) {
+ case "dot":
+ case "sub":
+ return true;
+ case "name":
+ return expr[1] != "this";
+ }
+ };
+
+ function maybe_assign() {
+ var left = maybe_conditional(), val = S.token.value;
+ if (is("operator") && HOP(ASSIGNMENT, val)) {
+ if (is_assignable(left)) {
+ next();
+ return as("assign", ASSIGNMENT[val], left, maybe_assign());
+ }
+ croak("Invalid assignment");
+ }
+ return left;
+ };
+
+ function expression(commas) {
+ if (arguments.length == 0)
+ commas = true;
+ var expr = maybe_assign();
+ if (commas && is("punc", ",")) {
+ next();
+ return as("seq", expr, expression());
+ }
+ return expr;
+ };
+
+ function in_loop(cont) {
+ try {
+ ++S.in_loop;
+ return cont();
+ } finally {
+ --S.in_loop;
+ }
+ };
+
+ return as("toplevel", (function(a){
+ while (!is("eof"))
+ a.push(statement());
+ return a;
+ })([]));
+
+};
+
+/* -----[ Utilities ]----- */
+
+function curry(f) {
+ var args = slice(arguments, 1);
+ return function() { return f.apply(this, args.concat(slice(arguments))); };
+};
+
+function prog1(ret) {
+ if (ret instanceof Function)
+ ret = ret();
+ for (var i = 1, n = arguments.length; --n > 0; ++i)
+ arguments[i]();
+ return ret;
+};
+
+function array_to_hash(a) {
+ var ret = {};
+ for (var i = 0; i < a.length; ++i)
+ ret[a[i]] = true;
+ return ret;
+};
+
+function slice(a, start) {
+ return Array.prototype.slice.call(a, start == null ? 0 : start);
+};
+
+function characters(str) {
+ return str.split("");
+};
+
+function member(name, array) {
+ for (var i = array.length; --i >= 0;)
+ if (array[i] === name)
+ return true;
+ return false;
+};
+
+function HOP(obj, prop) {
+ return Object.prototype.hasOwnProperty.call(obj, prop);
+};
+
+/* -----[ Exports ]----- */
+
+exports.tokenizer = tokenizer;
+exports.parse = parse;
+exports.slice = slice;
+exports.curry = curry;
+exports.member = member;
+exports.array_to_hash = array_to_hash;
+exports.PRECEDENCE = PRECEDENCE;
+exports.KEYWORDS_ATOM = KEYWORDS_ATOM;
+exports.RESERVED_WORDS = RESERVED_WORDS;
+exports.KEYWORDS = KEYWORDS;
+exports.ATOMIC_START_TOKEN = ATOMIC_START_TOKEN;
+exports.OPERATORS = OPERATORS;
+exports.is_alphanumeric_char = is_alphanumeric_char;
diff --git a/Source/WebCore/inspector/front-end/UglifyJS/process.js b/Source/WebCore/inspector/front-end/UglifyJS/process.js
new file mode 100755
index 0000000..65dbc0e
--- /dev/null
+++ b/Source/WebCore/inspector/front-end/UglifyJS/process.js
@@ -0,0 +1,1560 @@
+/***********************************************************************
+
+ A JavaScript tokenizer / parser / beautifier / compressor.
+
+ This version is suitable for Node.js. With minimal changes (the
+ exports stuff) it should work on any JS platform.
+
+ This file implements some AST processors. They work on data built
+ by parse-js.
+
+ Exported functions:
+
+ - ast_mangle(ast, include_toplevel) -- mangles the
+ variable/function names in the AST. Returns an AST. Pass true
+ as second argument to mangle toplevel names too.
+
+ - ast_squeeze(ast) -- employs various optimizations to make the
+ final generated code even smaller. Returns an AST.
+
+ - gen_code(ast, beautify) -- generates JS code from the AST. Pass
+ true (or an object, see the code for some options) as second
+ argument to get "pretty" (indented) code.
+
+ -------------------------------- (C) ---------------------------------
+
+ Author: Mihai Bazon
+ <mihai.bazon@gmail.com>
+ http://mihai.bazon.net/blog
+
+ Distributed under the BSD license:
+
+ Copyright 2010 (c) Mihai Bazon <mihai.bazon@gmail.com>
+
+ 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.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “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 HOLDER 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.
+
+ ***********************************************************************/
+
+var jsp = require("./parse-js"),
+ slice = jsp.slice,
+ member = jsp.member,
+ PRECEDENCE = jsp.PRECEDENCE,
+ OPERATORS = jsp.OPERATORS;
+
+/* -----[ helper for AST traversal ]----- */
+
+function ast_walker(ast) {
+ function _vardefs(defs) {
+ return MAP(defs, function(def){
+ var a = [ def[0] ];
+ if (def.length > 1)
+ a[1] = walk(def[1]);
+ return a;
+ });
+ };
+ var walkers = {
+ "string": function(str) {
+ return [ "string", str ];
+ },
+ "num": function(num) {
+ return [ "num", num ];
+ },
+ "name": function(name) {
+ return [ "name", name ];
+ },
+ "toplevel": function(statements) {
+ return [ "toplevel", MAP(statements, walk) ];
+ },
+ "block": function(statements) {
+ var out = [ "block" ];
+ if (statements != null)
+ out.push(MAP(statements, walk));
+ return out;
+ },
+ "var": function(defs) {
+ return [ "var", _vardefs(defs) ];
+ },
+ "const": function(defs) {
+ return [ "const", _vardefs(defs) ];
+ },
+ "try": function(t, c, f) {
+ return [
+ "try",
+ MAP(t, walk),
+ c != null ? [ c[0], MAP(c[1], walk) ] : null,
+ f != null ? MAP(f, walk) : null
+ ];
+ },
+ "throw": function(expr) {
+ return [ "throw", walk(expr) ];
+ },
+ "new": function(ctor, args) {
+ return [ "new", walk(ctor), MAP(args, walk) ];
+ },
+ "switch": function(expr, body) {
+ return [ "switch", walk(expr), MAP(body, function(branch){
+ return [ branch[0] ? walk(branch[0]) : null,
+ MAP(branch[1], walk) ];
+ }) ];
+ },
+ "break": function(label) {
+ return [ "break", label ];
+ },
+ "continue": function(label) {
+ return [ "continue", label ];
+ },
+ "conditional": function(cond, t, e) {
+ return [ "conditional", walk(cond), walk(t), walk(e) ];
+ },
+ "assign": function(op, lvalue, rvalue) {
+ return [ "assign", op, walk(lvalue), walk(rvalue) ];
+ },
+ "dot": function(expr) {
+ return [ "dot", walk(expr) ].concat(slice(arguments, 1));
+ },
+ "call": function(expr, args) {
+ return [ "call", walk(expr), MAP(args, walk) ];
+ },
+ "function": function(name, args, body) {
+ return [ "function", name, args.slice(), MAP(body, walk) ];
+ },
+ "defun": function(name, args, body) {
+ return [ "defun", name, args.slice(), MAP(body, walk) ];
+ },
+ "if": function(conditional, t, e) {
+ return [ "if", walk(conditional), walk(t), walk(e) ];
+ },
+ "for": function(init, cond, step, block) {
+ return [ "for", walk(init), walk(cond), walk(step), walk(block) ];
+ },
+ "for-in": function(has_var, key, hash, block) {
+ return [ "for-in", has_var, key, walk(hash), walk(block) ];
+ },
+ "while": function(cond, block) {
+ return [ "while", walk(cond), walk(block) ];
+ },
+ "do": function(cond, block) {
+ return [ "do", walk(cond), walk(block) ];
+ },
+ "return": function(expr) {
+ return [ "return", walk(expr) ];
+ },
+ "binary": function(op, left, right) {
+ return [ "binary", op, walk(left), walk(right) ];
+ },
+ "unary-prefix": function(op, expr) {
+ return [ "unary-prefix", op, walk(expr) ];
+ },
+ "unary-postfix": function(op, expr) {
+ return [ "unary-postfix", op, walk(expr) ];
+ },
+ "sub": function(expr, subscript) {
+ return [ "sub", walk(expr), walk(subscript) ];
+ },
+ "object": function(props) {
+ return [ "object", MAP(props, function(p){
+ return p.length == 2
+ ? [ p[0], walk(p[1]) ]
+ : [ p[0], walk(p[1]), p[2] ]; // get/set-ter
+ }) ];
+ },
+ "regexp": function(rx, mods) {
+ return [ "regexp", rx, mods ];
+ },
+ "array": function(elements) {
+ return [ "array", MAP(elements, walk) ];
+ },
+ "stat": function(stat) {
+ return [ "stat", walk(stat) ];
+ },
+ "seq": function() {
+ return [ "seq" ].concat(MAP(slice(arguments), walk));
+ },
+ "label": function(name, block) {
+ return [ "label", name, walk(block) ];
+ },
+ "with": function(expr, block) {
+ return [ "with", walk(expr), walk(block) ];
+ },
+ "atom": function(name) {
+ return [ "atom", name ];
+ }
+ };
+
+ var user = {};
+ var stack = [];
+ function walk(ast) {
+ if (ast == null)
+ return null;
+ try {
+ stack.push(ast);
+ var type = ast[0];
+ var gen = user[type];
+ if (gen) {
+ var ret = gen.apply(ast, ast.slice(1));
+ if (ret != null)
+ return ret;
+ }
+ gen = walkers[type];
+ return gen.apply(ast, ast.slice(1));
+ } finally {
+ stack.pop();
+ }
+ };
+
+ function with_walkers(walkers, cont){
+ var save = {}, i;
+ for (i in walkers) if (HOP(walkers, i)) {
+ save[i] = user[i];
+ user[i] = walkers[i];
+ }
+ var ret = cont();
+ for (i in save) if (HOP(save, i)) {
+ if (!save[i]) delete user[i];
+ else user[i] = save[i];
+ }
+ return ret;
+ };
+
+ return {
+ walk: walk,
+ with_walkers: with_walkers,
+ parent: function() {
+ return stack[stack.length - 2]; // last one is current node
+ },
+ stack: function() {
+ return stack;
+ }
+ };
+};
+
+/* -----[ Scope and mangling ]----- */
+
+function Scope(parent) {
+ this.names = {}; // names defined in this scope
+ this.mangled = {}; // mangled names (orig.name => mangled)
+ this.rev_mangled = {}; // reverse lookup (mangled => orig.name)
+ this.cname = -1; // current mangled name
+ this.refs = {}; // names referenced from this scope
+ this.uses_with = false; // will become TRUE if eval() is detected in this or any subscopes
+ this.uses_eval = false; // will become TRUE if with() is detected in this or any subscopes
+ this.parent = parent; // parent scope
+ this.children = []; // sub-scopes
+ if (parent) {
+ this.level = parent.level + 1;
+ parent.children.push(this);
+ } else {
+ this.level = 0;
+ }
+};
+
+var base54 = (function(){
+ var DIGITS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_";
+ return function(num) {
+ var ret = "";
+ do {
+ ret = DIGITS.charAt(num % 54) + ret;
+ num = Math.floor(num / 54);
+ } while (num > 0);
+ return ret;
+ };
+})();
+
+Scope.prototype = {
+ has: function(name) {
+ for (var s = this; s; s = s.parent)
+ if (HOP(s.names, name))
+ return s;
+ },
+ has_mangled: function(mname) {
+ for (var s = this; s; s = s.parent)
+ if (HOP(s.rev_mangled, mname))
+ return s;
+ },
+ toJSON: function() {
+ return {
+ names: this.names,
+ uses_eval: this.uses_eval,
+ uses_with: this.uses_with
+ };
+ },
+
+ next_mangled: function() {
+ // we must be careful that the new mangled name:
+ //
+ // 1. doesn't shadow a mangled name from a parent
+ // scope, unless we don't reference the original
+ // name from this scope OR from any sub-scopes!
+ // This will get slow.
+ //
+ // 2. doesn't shadow an original name from a parent
+ // scope, in the event that the name is not mangled
+ // in the parent scope and we reference that name
+ // here OR IN ANY SUBSCOPES!
+ //
+ // 3. doesn't shadow a name that is referenced but not
+ // defined (possibly global defined elsewhere).
+ for (;;) {
+ var m = base54(++this.cname), prior;
+
+ // case 1.
+ prior = this.has_mangled(m);
+ if (prior && this.refs[prior.rev_mangled[m]] === prior)
+ continue;
+
+ // case 2.
+ prior = this.has(m);
+ if (prior && prior !== this && this.refs[m] === prior && !prior.has_mangled(m))
+ continue;
+
+ // case 3.
+ if (HOP(this.refs, m) && this.refs[m] == null)
+ continue;
+
+ // I got "do" once. :-/
+ if (!is_identifier(m))
+ continue;
+
+ return m;
+ }
+ },
+ get_mangled: function(name, newMangle) {
+ if (this.uses_eval || this.uses_with) return name; // no mangle if eval or with is in use
+ var s = this.has(name);
+ if (!s) return name; // not in visible scope, no mangle
+ if (HOP(s.mangled, name)) return s.mangled[name]; // already mangled in this scope
+ if (!newMangle) return name; // not found and no mangling requested
+
+ var m = s.next_mangled();
+ s.rev_mangled[m] = name;
+ return s.mangled[name] = m;
+ },
+ define: function(name) {
+ if (name != null)
+ return this.names[name] = name;
+ }
+};
+
+function ast_add_scope(ast) {
+
+ var current_scope = null;
+ var w = ast_walker(), walk = w.walk;
+ var having_eval = [];
+
+ function with_new_scope(cont) {
+ current_scope = new Scope(current_scope);
+ var ret = current_scope.body = cont();
+ ret.scope = current_scope;
+ current_scope = current_scope.parent;
+ return ret;
+ };
+
+ function define(name) {
+ return current_scope.define(name);
+ };
+
+ function reference(name) {
+ current_scope.refs[name] = true;
+ };
+
+ function _lambda(name, args, body) {
+ return [ this[0], define(name), args, with_new_scope(function(){
+ MAP(args, define);
+ return MAP(body, walk);
+ })];
+ };
+
+ return with_new_scope(function(){
+ // process AST
+ var ret = w.with_walkers({
+ "function": _lambda,
+ "defun": _lambda,
+ "with": function(expr, block) {
+ for (var s = current_scope; s; s = s.parent)
+ s.uses_with = true;
+ },
+ "var": function(defs) {
+ MAP(defs, function(d){ define(d[0]) });
+ },
+ "const": function(defs) {
+ MAP(defs, function(d){ define(d[0]) });
+ },
+ "try": function(t, c, f) {
+ if (c != null) return [
+ "try",
+ MAP(t, walk),
+ [ define(c[0]), MAP(c[1], walk) ],
+ f != null ? MAP(f, walk) : null
+ ];
+ },
+ "name": function(name) {
+ if (name == "eval")
+ having_eval.push(current_scope);
+ reference(name);
+ },
+ "for-in": function(has_var, name) {
+ if (has_var) define(name);
+ else reference(name);
+ }
+ }, function(){
+ return walk(ast);
+ });
+
+ // the reason why we need an additional pass here is
+ // that names can be used prior to their definition.
+
+ // scopes where eval was detected and their parents
+ // are marked with uses_eval, unless they define the
+ // "eval" name.
+ MAP(having_eval, function(scope){
+ if (!scope.has("eval")) while (scope) {
+ scope.uses_eval = true;
+ scope = scope.parent;
+ }
+ });
+
+ // for referenced names it might be useful to know
+ // their origin scope. current_scope here is the
+ // toplevel one.
+ function fixrefs(scope, i) {
+ // do children first; order shouldn't matter
+ for (i = scope.children.length; --i >= 0;)
+ fixrefs(scope.children[i]);
+ for (i in scope.refs) if (HOP(scope.refs, i)) {
+ // find origin scope and propagate the reference to origin
+ for (var origin = scope.has(i), s = scope; s; s = s.parent) {
+ s.refs[i] = origin;
+ if (s === origin) break;
+ }
+ }
+ };
+ fixrefs(current_scope);
+
+ return ret;
+ });
+
+};
+
+/* -----[ mangle names ]----- */
+
+function ast_mangle(ast, do_toplevel) {
+ var w = ast_walker(), walk = w.walk, scope;
+
+ function get_mangled(name, newMangle) {
+ if (!do_toplevel && !scope.parent) return name; // don't mangle toplevel
+ return scope.get_mangled(name, newMangle);
+ };
+
+ function _lambda(name, args, body) {
+ if (name) name = get_mangled(name);
+ body = with_scope(body.scope, function(){
+ args = MAP(args, function(name){ return get_mangled(name) });
+ return MAP(body, walk);
+ });
+ return [ this[0], name, args, body ];
+ };
+
+ function with_scope(s, cont) {
+ var _scope = scope;
+ scope = s;
+ for (var i in s.names) if (HOP(s.names, i)) {
+ get_mangled(i, true);
+ }
+ var ret = cont();
+ ret.scope = s;
+ scope = _scope;
+ return ret;
+ };
+
+ function _vardefs(defs) {
+ return MAP(defs, function(d){
+ return [ get_mangled(d[0]), walk(d[1]) ];
+ });
+ };
+
+ return w.with_walkers({
+ "function": _lambda,
+ "defun": function() {
+ // move function declarations to the top when
+ // they are not in some block.
+ var ast = _lambda.apply(this, arguments);
+ switch (w.parent()[0]) {
+ case "toplevel":
+ case "function":
+ case "defun":
+ return MAP.at_top(ast);
+ }
+ return ast;
+ },
+ "var": function(defs) {
+ return [ "var", _vardefs(defs) ];
+ },
+ "const": function(defs) {
+ return [ "const", _vardefs(defs) ];
+ },
+ "name": function(name) {
+ return [ "name", get_mangled(name) ];
+ },
+ "try": function(t, c, f) {
+ return [ "try",
+ MAP(t, walk),
+ c != null ? [ get_mangled(c[0]), MAP(c[1], walk) ] : null,
+ f != null ? MAP(f, walk) : null ];
+ },
+ "toplevel": function(body) {
+ return with_scope(this.scope, function(){
+ return [ "toplevel", MAP(body, walk) ];
+ });
+ },
+ "for-in": function(has_var, name, obj, stat) {
+ return [ "for-in", has_var, get_mangled(name), walk(obj), walk(stat) ];
+ }
+ }, function() {
+ return walk(ast_add_scope(ast));
+ });
+};
+
+/* -----[
+ - compress foo["bar"] into foo.bar,
+ - remove block brackets {} where possible
+ - join consecutive var declarations
+ - various optimizations for IFs:
+ - if (cond) foo(); else bar(); ==> cond?foo():bar();
+ - if (cond) foo(); ==> cond&&foo();
+ - if (foo) return bar(); else return baz(); ==> return foo?bar():baz(); // also for throw
+ - if (foo) return bar(); else something(); ==> {if(foo)return bar();something()}
+ ]----- */
+
+var warn = function(){};
+
+function best_of(ast1, ast2) {
+ return gen_code(ast1).length > gen_code(ast2[0] == "stat" ? ast2[1] : ast2).length ? ast2 : ast1;
+};
+
+function last_stat(b) {
+ if (b[0] == "block" && b[1] && b[1].length > 0)
+ return b[1][b[1].length - 1];
+ return b;
+}
+
+function aborts(t) {
+ if (t) {
+ t = last_stat(t);
+ if (t[0] == "return" || t[0] == "break" || t[0] == "continue" || t[0] == "throw")
+ return true;
+ }
+};
+
+function negate(c) {
+ var not_c = [ "unary-prefix", "!", c ];
+ switch (c[0]) {
+ case "unary-prefix":
+ return c[1] == "!" ? c[2] : not_c;
+ case "binary":
+ var op = c[1], left = c[2], right = c[3];
+ switch (op) {
+ case "<=": return [ "binary", ">", left, right ];
+ case "<": return [ "binary", ">=", left, right ];
+ case ">=": return [ "binary", "<", left, right ];
+ case ">": return [ "binary", "<=", left, right ];
+ case "==": return [ "binary", "!=", left, right ];
+ case "!=": return [ "binary", "==", left, right ];
+ case "===": return [ "binary", "!==", left, right ];
+ case "!==": return [ "binary", "===", left, right ];
+ case "&&": return best_of(not_c, [ "binary", "||", negate(left), negate(right) ]);
+ case "||": return best_of(not_c, [ "binary", "&&", negate(left), negate(right) ]);
+ }
+ break;
+ }
+ return not_c;
+};
+
+function make_conditional(c, t, e) {
+ if (c[0] == "unary-prefix" && c[1] == "!") {
+ return e ? [ "conditional", c[2], e, t ] : [ "binary", "||", c[2], t ];
+ } else {
+ return e ? [ "conditional", c, t, e ] : [ "binary", "&&", c, t ];
+ }
+};
+
+function empty(b) {
+ return !b || (b[0] == "block" && (!b[1] || b[1].length == 0));
+};
+
+function ast_squeeze(ast, options) {
+ options = defaults(options, {
+ make_seqs : true,
+ dead_code : true,
+ no_warnings : false,
+ extra : false
+ });
+
+ var w = ast_walker(), walk = w.walk, scope;
+
+ function with_scope(s, cont) {
+ var _scope = scope;
+ scope = s;
+ var ret = cont();
+ ret.scope = s;
+ scope = _scope;
+ return ret;
+ };
+
+ function is_constant(node) {
+ return node[0] == "string" || node[0] == "num";
+ };
+
+ function find_first_execute(node) {
+ if (!node)
+ return false;
+
+ switch (node[0]) {
+ case "num":
+ case "string":
+ case "name":
+ return node;
+ case "call":
+ case "conditional":
+ case "for":
+ case "if":
+ case "new":
+ case "return":
+ case "stat":
+ case "switch":
+ case "throw":
+ return find_first_execute(node[1]);
+ case "binary":
+ return find_first_execute(node[2]);
+ case "assign":
+ if (node[1] === true)
+ return find_first_execute(node[3]);
+ break;
+ case "var":
+ if (node[1][0].length > 1)
+ return find_first_execute(node[1][0][1]);
+ break;
+ }
+ return null;
+ }
+
+ function find_assign_recursive(p, v) {
+ if (p[0] == "assign" && p[1] != true || p[0] == "unary-prefix") {
+ if (p[2][0] == "name" && v[0] == "name" && p[2][1] == v[1])
+ return true;
+ return false;
+ }
+
+ if (p[0] != "assign" || p[1] !== true)
+ return false;
+
+ if ((is_constant(p[3]) && p[3][0] == v[0] && p[3][1] == v[1]) ||
+ (p[3][0] == "name" && v[0] == "name" && p[3][1] == v[1]) ||
+ (p[2][0] == "name" && v[0] == "name" && p[2][1] == v[1]))
+ return true;
+
+ return find_assign_recursive(p[3], v);
+ };
+
+ function rmblock(block) {
+ if (block != null && block[0] == "block" && block[1] && block[1].length == 1)
+ block = block[1][0];
+ return block;
+ };
+
+ function clone(obj) {
+ if (obj && obj.constructor == Array)
+ return MAP(obj, clone);
+ return obj;
+ };
+
+ function make_seq_to_statements(node) {
+ if (node[0] != "seq") {
+ switch (node[0]) {
+ case "var":
+ case "const":
+ return [ node ];
+ default:
+ return [ [ "stat", node ] ];
+ }
+ }
+
+ var ret = [];
+ for (var i = 1; i < node.length; i++)
+ ret.push.apply(ret, make_seq_to_statements(node[i]));
+
+ return ret;
+ };
+
+ function _lambda(name, args, body) {
+ return [ this[0], name, args, with_scope(body.scope, function(){
+ return tighten(MAP(body, walk), "lambda");
+ }) ];
+ };
+
+ // we get here for blocks that have been already transformed.
+ // this function does a few things:
+ // 1. discard useless blocks
+ // 2. join consecutive var declarations
+ // 3. remove obviously dead code
+ // 4. transform consecutive statements using the comma operator
+ // 5. if block_type == "lambda" and it detects constructs like if(foo) return ... - rewrite like if (!foo) { ... }
+ function tighten(statements, block_type) {
+ statements = statements.reduce(function(a, stat){
+ if (stat[0] == "block") {
+ if (stat[1]) {
+ a.push.apply(a, stat[1]);
+ }
+ } else {
+ a.push(stat);
+ }
+ return a;
+ }, []);
+
+ if (options.extra) {
+ // Detightening things. We do this because then we can assume that the
+ // statements are structured in a specific way.
+ statements = (function(a, prev) {
+ statements.forEach(function(cur) {
+ switch (cur[0]) {
+ case "for":
+ if (cur[1] != null) {
+ a.push.apply(a, make_seq_to_statements(cur[1]));
+ cur[1] = null;
+ }
+ a.push(cur);
+ break;
+ case "stat":
+ var stats = make_seq_to_statements(cur[1]);
+ stats.forEach(function(s) {
+ if (s[1][0] == "unary-postfix")
+ s[1][0] = "unary-prefix";
+ });
+ a.push.apply(a, stats);
+ break;
+ default:
+ a.push(cur);
+ }
+ });
+ return a;
+ })([]);
+
+ statements = (function(a, prev) {
+ statements.forEach(function(cur) {
+ if (!(prev && prev[0] == "stat")) {
+ a.push(cur);
+ prev = cur;
+ return;
+ }
+
+ var p = prev[1];
+ var c = find_first_execute(cur);
+ if (c && find_assign_recursive(p, c)) {
+ var old_cur = clone(cur);
+ c.splice(0, c.length);
+ c.push.apply(c, p);
+ var tmp_cur = best_of(cur, [ "toplevel", [ prev, old_cur ] ]);
+ if (tmp_cur == cur) {
+ a[a.length -1] = cur;
+ } else {
+ cur = old_cur;
+ a.push(cur);
+ }
+ } else {
+ a.push(cur);
+ }
+ prev = cur;
+ });
+ return a;
+ })([]);
+ }
+
+ statements = (function(a, prev){
+ statements.forEach(function(cur){
+ if (prev && ((cur[0] == "var" && prev[0] == "var") ||
+ (cur[0] == "const" && prev[0] == "const"))) {
+ prev[1] = prev[1].concat(cur[1]);
+ } else {
+ a.push(cur);
+ prev = cur;
+ }
+ });
+ return a;
+ })([]);
+
+ if (options.dead_code) statements = (function(a, has_quit){
+ statements.forEach(function(st){
+ if (has_quit) {
+ if (member(st[0], [ "function", "defun" , "var", "const" ])) {
+ a.push(st);
+ }
+ else if (!options.no_warnings)
+ warn("Removing unreachable code: " + gen_code(st, true));
+ }
+ else {
+ a.push(st);
+ if (member(st[0], [ "return", "throw", "break", "continue" ]))
+ has_quit = true;
+ }
+ });
+ return a;
+ })([]);
+
+ if (options.make_seqs) statements = (function(a, prev) {
+ statements.forEach(function(cur){
+ if (prev && prev[0] == "stat" && cur[0] == "stat") {
+ prev[1] = [ "seq", prev[1], cur[1] ];
+ } else {
+ a.push(cur);
+ prev = cur;
+ }
+ });
+ return a;
+ })([]);
+
+ if (options.extra) {
+ statements = (function(a, prev){
+ statements.forEach(function(cur){
+ var replaced = false;
+ if (prev && cur[0] == "for" && cur[1] == null && (prev[0] == "var" || prev[0] == "const" || prev[0] == "stat")) {
+ cur[1] = prev;
+ a[a.length - 1] = cur;
+ } else {
+ a.push(cur);
+ }
+ prev = cur;
+ });
+ return a;
+ })([]);
+ }
+
+ if (block_type == "lambda") statements = (function(i, a, stat){
+ while (i < statements.length) {
+ stat = statements[i++];
+ if (stat[0] == "if" && !stat[3]) {
+ if (stat[2][0] == "return" && stat[2][1] == null) {
+ a.push(make_if(negate(stat[1]), [ "block", statements.slice(i) ]));
+ break;
+ }
+ var last = last_stat(stat[2]);
+ if (last[0] == "return" && last[1] == null) {
+ a.push(make_if(stat[1], [ "block", stat[2][1].slice(0, -1) ], [ "block", statements.slice(i) ]));
+ break;
+ }
+ }
+ a.push(stat);
+ }
+ return a;
+ })(0, []);
+
+ return statements;
+ };
+
+ function make_if(c, t, e) {
+ c = walk(c);
+ t = walk(t);
+ e = walk(e);
+
+ if (empty(t)) {
+ c = negate(c);
+ t = e;
+ e = null;
+ } else if (empty(e)) {
+ e = null;
+ } else {
+ // if we have both else and then, maybe it makes sense to switch them?
+ (function(){
+ var a = gen_code(c);
+ var n = negate(c);
+ var b = gen_code(n);
+ if (b.length < a.length) {
+ var tmp = t;
+ t = e;
+ e = tmp;
+ c = n;
+ }
+ })();
+ }
+ if (empty(e) && empty(t))
+ return [ "stat", c ];
+ var ret = [ "if", c, t, e ];
+ if (t[0] == "stat") {
+ if (e) {
+ if (e[0] == "stat") {
+ ret = best_of(ret, [ "stat", make_conditional(c, t[1], e[1]) ]);
+ }
+ }
+ else {
+ ret = best_of(ret, [ "stat", make_conditional(c, t[1]) ]);
+ }
+ }
+ else if (e && t[0] == e[0] && (t[0] == "return" || t[0] == "throw")) {
+ ret = best_of(ret, [ t[0], make_conditional(c, t[1], e[1] ) ]);
+ }
+ else if (e && aborts(t)) {
+ ret = [ [ "if", c, t ] ];
+ if (e[0] == "block") {
+ if (e[1]) ret = ret.concat(e[1]);
+ }
+ else {
+ ret.push(e);
+ }
+ ret = walk([ "block", ret ]);
+ }
+ else if (t && aborts(e)) {
+ ret = [ [ "if", negate(c), e ] ];
+ if (t[0] == "block") {
+ if (t[1]) ret = ret.concat(t[1]);
+ } else {
+ ret.push(t);
+ }
+ ret = walk([ "block", ret ]);
+ }
+ return ret;
+ };
+
+ return w.with_walkers({
+ "sub": function(expr, subscript) {
+ if (subscript[0] == "string") {
+ var name = subscript[1];
+ if (is_identifier(name)) {
+ return [ "dot", walk(expr), name ];
+ }
+ }
+ },
+ "if": make_if,
+ "toplevel": function(body) {
+ return [ "toplevel", with_scope(this.scope, function(){
+ return tighten(MAP(body, walk));
+ }) ];
+ },
+ "switch": function(expr, body) {
+ var last = body.length - 1;
+ return [ "switch", walk(expr), MAP(body, function(branch, i){
+ var block = tighten(MAP(branch[1], walk));
+ if (i == last && block.length > 0) {
+ var node = block[block.length - 1];
+ if (node[0] == "break" && !node[1])
+ block.pop();
+ }
+ return [ branch[0] ? walk(branch[0]) : null, block ];
+ }) ];
+ },
+ "function": _lambda,
+ "defun": _lambda,
+ "block": function(body) {
+ if (body) return rmblock([ "block", tighten(MAP(body, walk)) ]);
+ },
+ "binary": function(op, left, right) {
+ left = walk(left);
+ right = walk(right);
+ var best = [ "binary", op, left, right ];
+ if (is_constant(right)) {
+ if (is_constant(left)) {
+ var val = null;
+ switch (op) {
+ case "+": val = left[1] + right[1]; break;
+ case "*": val = left[1] * right[1]; break;
+ case "/": val = left[1] / right[1]; break;
+ case "-": val = left[1] - right[1]; break;
+ case "<<": val = left[1] << right[1]; break;
+ case ">>": val = left[1] >> right[1]; break;
+ case ">>>": val = left[1] >>> right[1]; break;
+ }
+ if (val != null) {
+ best = best_of(best, [ typeof val == "string" ? "string" : "num", val ]);
+ }
+ } else if (left[0] == "binary" && left[1] == "+" && left[3][0] == "string") {
+ best = best_of(best, [ "binary", "+", left[2], [ "string", left[3][1] + right[1] ] ]);
+ }
+ }
+ return best;
+ },
+ "conditional": function(c, t, e) {
+ return make_conditional(walk(c), walk(t), walk(e));
+ },
+ "try": function(t, c, f) {
+ return [
+ "try",
+ tighten(MAP(t, walk)),
+ c != null ? [ c[0], tighten(MAP(c[1], walk)) ] : null,
+ f != null ? tighten(MAP(f, walk)) : null
+ ];
+ },
+ "unary-prefix": function(op, cond) {
+ if (op == "!") {
+ cond = walk(cond);
+ if (cond[0] == "unary-prefix" && cond[1] == "!") {
+ var p = w.parent();
+ if (p[0] == "unary-prefix" && p[1] == "!")
+ return cond[2];
+ return [ "unary-prefix", "!", cond ];
+ }
+ return best_of(this, negate(cond));
+ }
+ },
+ "name": function(name) {
+ switch (name) {
+ case "true": return [ "unary-prefix", "!", [ "num", 0 ]];
+ case "false": return [ "unary-prefix", "!", [ "num", 1 ]];
+ }
+ },
+ "new": function(ctor, args) {
+ if (ctor[0] == "name" && ctor[1] == "Array" && !scope.has("Array")) {
+ if (args.length != 1) {
+ return [ "array", args ];
+ } else {
+ return [ "call", [ "name", "Array" ], args ];
+ }
+ }
+ },
+ "call": function(expr, args) {
+ if (expr[0] == "name" && expr[1] == "Array" && args.length != 1 && !scope.has("Array")) {
+ return [ "array", args ];
+ }
+ }
+ }, function() {
+ return walk(ast_add_scope(ast));
+ });
+};
+
+/* -----[ re-generate code from the AST ]----- */
+
+var DOT_CALL_NO_PARENS = jsp.array_to_hash([
+ "name",
+ "array",
+ "string",
+ "dot",
+ "sub",
+ "call",
+ "regexp"
+]);
+
+function make_string(str) {
+ var dq = 0, sq = 0;
+ str = str.replace(/[\\\b\f\n\r\t\x22\x27]/g, function(s){
+ switch (s) {
+ case "\\": return "\\\\";
+ case "\b": return "\\b";
+ case "\f": return "\\f";
+ case "\n": return "\\n";
+ case "\r": return "\\r";
+ case "\t": return "\\t";
+ case '"': ++dq; return '"';
+ case "'": ++sq; return "'";
+ }
+ return s;
+ });
+ if (dq > sq) {
+ return "'" + str.replace(/\x27/g, "\\'") + "'";
+ } else {
+ return '"' + str.replace(/\x22/g, '\\"') + '"';
+ }
+};
+
+function gen_code(ast, beautify) {
+ if (beautify) beautify = defaults(beautify, {
+ indent_start : 0,
+ indent_level : 4,
+ quote_keys : false,
+ space_colon : false
+ });
+ var indentation = 0,
+ newline = beautify ? "\n" : "",
+ space = beautify ? " " : "";
+
+ function indent(line) {
+ if (line == null)
+ line = "";
+ if (beautify)
+ line = repeat_string(" ", beautify.indent_start + indentation * beautify.indent_level) + line;
+ return line;
+ };
+
+ function with_indent(cont, incr) {
+ if (incr == null) incr = 1;
+ indentation += incr;
+ try { return cont.apply(null, slice(arguments, 1)); }
+ finally { indentation -= incr; }
+ };
+
+ function add_spaces(a) {
+ if (beautify)
+ return a.join(" ");
+ var b = [];
+ for (var i = 0; i < a.length; ++i) {
+ var next = a[i + 1];
+ b.push(a[i]);
+ if (next &&
+ ((/[a-z0-9_\x24]$/i.test(a[i].toString()) && /^[a-z0-9_\x24]/i.test(next.toString())) ||
+ (/[\+\-]$/.test(a[i].toString()) && /^[\+\-]/.test(next.toString())))) {
+ b.push(" ");
+ }
+ }
+ return b.join("");
+ };
+
+ function add_commas(a) {
+ return a.join("," + space);
+ };
+
+ function parenthesize(expr) {
+ var gen = make(expr);
+ for (var i = 1; i < arguments.length; ++i) {
+ var el = arguments[i];
+ if ((el instanceof Function && el(expr)) || expr[0] == el)
+ return "(" + gen + ")";
+ }
+ return gen;
+ };
+
+ function best_of(a) {
+ if (a.length == 1) {
+ return a[0];
+ }
+ if (a.length == 2) {
+ var b = a[1];
+ a = a[0];
+ return a.length <= b.length ? a : b;
+ }
+ return best_of([ a[0], best_of(a.slice(1)) ]);
+ };
+
+ function needs_parens(expr) {
+ if (expr[0] == "function") {
+ // dot/call on a literal function requires the
+ // function literal itself to be parenthesized
+ // only if it's the first "thing" in a
+ // statement. This means that the parent is
+ // "stat", but it could also be a "seq" and
+ // we're the first in this "seq" and the
+ // parent is "stat", and so on. Messy stuff,
+ // but it worths the trouble.
+ var a = slice($stack), self = a.pop(), p = a.pop();
+ while (p) {
+ if (p[0] == "stat") return true;
+ if ((p[0] == "seq" && p[1] === self) ||
+ (p[0] == "call" && p[1] === self) ||
+ (p[0] == "binary" && p[2] === self)) {
+ self = p;
+ p = a.pop();
+ } else {
+ return false;
+ }
+ }
+ }
+ return !HOP(DOT_CALL_NO_PARENS, expr[0]);
+ };
+
+ function make_num(num) {
+ var str = num.toString(10), a = [ str.replace(/^0\./, ".") ], m;
+ if (Math.floor(num) === num) {
+ a.push("0x" + num.toString(16).toLowerCase(), // probably pointless
+ "0" + num.toString(8)); // same.
+ if ((m = /^(.*?)(0+)$/.exec(num))) {
+ a.push(m[1] + "e" + m[2].length);
+ }
+ } else if ((m = /^0?\.(0+)(.*)$/.exec(num))) {
+ a.push(m[2] + "e-" + (m[1].length + m[2].length),
+ str.substr(str.indexOf(".")));
+ }
+ return best_of(a);
+ };
+
+ var generators = {
+ "string": make_string,
+ "num": make_num,
+ "name": make_name,
+ "toplevel": function(statements) {
+ return make_block_statements(statements)
+ .join(newline + newline);
+ },
+ "block": make_block,
+ "var": function(defs) {
+ return "var " + add_commas(MAP(defs, make_1vardef)) + ";";
+ },
+ "const": function(defs) {
+ return "const " + add_commas(MAP(defs, make_1vardef)) + ";";
+ },
+ "try": function(tr, ca, fi) {
+ var out = [ "try", make_block(tr) ];
+ if (ca) out.push("catch", "(" + ca[0] + ")", make_block(ca[1]));
+ if (fi) out.push("finally", make_block(fi));
+ return add_spaces(out);
+ },
+ "throw": function(expr) {
+ return add_spaces([ "throw", make(expr) ]) + ";";
+ },
+ "new": function(ctor, args) {
+ args = args.length > 0 ? "(" + add_commas(MAP(args, make)) + ")" : "";
+ return add_spaces([ "new", parenthesize(ctor, "seq", "binary", "conditional", "assign", function(expr){
+ var w = ast_walker(), has_call = {};
+ try {
+ w.with_walkers({
+ "call": function() { throw has_call },
+ "function": function() { return this }
+ }, function(){
+ w.walk(expr);
+ });
+ } catch(ex) {
+ if (ex === has_call)
+ return true;
+ throw ex;
+ }
+ }) + args ]);
+ },
+ "switch": function(expr, body) {
+ return add_spaces([ "switch", "(" + make(expr) + ")", make_switch_block(body) ]);
+ },
+ "break": function(label) {
+ var out = "break";
+ if (label != null)
+ out += " " + make_name(label);
+ return out + ";";
+ },
+ "continue": function(label) {
+ var out = "continue";
+ if (label != null)
+ out += " " + make_name(label);
+ return out + ";";
+ },
+ "conditional": function(co, th, el) {
+ return add_spaces([ parenthesize(co, "assign", "seq", "conditional"), "?",
+ parenthesize(th, "seq"), ":",
+ parenthesize(el, "seq") ]);
+ },
+ "assign": function(op, lvalue, rvalue) {
+ if (op && op !== true) op += "=";
+ else op = "=";
+ return add_spaces([ make(lvalue), op, parenthesize(rvalue, "seq") ]);
+ },
+ "dot": function(expr) {
+ var out = make(expr), i = 1;
+ if (needs_parens(expr))
+ out = "(" + out + ")";
+ while (i < arguments.length)
+ out += "." + make_name(arguments[i++]);
+ return out;
+ },
+ "call": function(func, args) {
+ var f = make(func);
+ if (needs_parens(func))
+ f = "(" + f + ")";
+ return f + "(" + add_commas(MAP(args, function(expr){
+ return parenthesize(expr, "seq");
+ })) + ")";
+ },
+ "function": make_function,
+ "defun": make_function,
+ "if": function(co, th, el) {
+ var out = [ "if", "(" + make(co) + ")", el ? make_then(th) : make(th) ];
+ if (el) {
+ out.push("else", make(el));
+ }
+ return add_spaces(out);
+ },
+ "for": function(init, cond, step, block) {
+ var out = [ "for" ];
+ init = (init != null ? make(init) : "").replace(/;*\s*$/, ";" + space);
+ cond = (cond != null ? make(cond) : "").replace(/;*\s*$/, ";" + space);
+ step = (step != null ? make(step) : "").replace(/;*\s*$/, "");
+ var args = init + cond + step;
+ if (args == "; ; ") args = ";;";
+ out.push("(" + args + ")", make(block));
+ return add_spaces(out);
+ },
+ "for-in": function(has_var, key, hash, block) {
+ var out = add_spaces([ "for", "(" ]);
+ if (has_var)
+ out += "var ";
+ out += add_spaces([ make_name(key) + " in " + make(hash) + ")", make(block) ]);
+ return out;
+ },
+ "while": function(condition, block) {
+ return add_spaces([ "while", "(" + make(condition) + ")", make(block) ]);
+ },
+ "do": function(condition, block) {
+ return add_spaces([ "do", make(block), "while", "(" + make(condition) + ")" ]) + ";";
+ },
+ "return": function(expr) {
+ var out = [ "return" ];
+ if (expr != null) out.push(make(expr));
+ return add_spaces(out) + ";";
+ },
+ "binary": function(operator, lvalue, rvalue) {
+ var left = make(lvalue), right = make(rvalue);
+ // XXX: I'm pretty sure other cases will bite here.
+ // we need to be smarter.
+ // adding parens all the time is the safest bet.
+ if (member(lvalue[0], [ "assign", "conditional", "seq" ]) ||
+ lvalue[0] == "binary" && PRECEDENCE[operator] > PRECEDENCE[lvalue[1]]) {
+ left = "(" + left + ")";
+ }
+ if (member(rvalue[0], [ "assign", "conditional", "seq" ]) ||
+ rvalue[0] == "binary" && PRECEDENCE[operator] >= PRECEDENCE[rvalue[1]]) {
+ right = "(" + right + ")";
+ }
+ return add_spaces([ left, operator, right ]);
+ },
+ "unary-prefix": function(operator, expr) {
+ var val = make(expr);
+ if (!(expr[0] == "num" || (expr[0] == "unary-prefix" && !HOP(OPERATORS, operator + expr[1])) || !needs_parens(expr)))
+ val = "(" + val + ")";
+ return operator + (jsp.is_alphanumeric_char(operator.charAt(0)) ? " " : "") + val;
+ },
+ "unary-postfix": function(operator, expr) {
+ var val = make(expr);
+ if (!(expr[0] == "num" || (expr[0] == "unary-postfix" && !HOP(OPERATORS, operator + expr[1])) || !needs_parens(expr)))
+ val = "(" + val + ")";
+ return val + operator;
+ },
+ "sub": function(expr, subscript) {
+ var hash = make(expr);
+ if (needs_parens(expr))
+ hash = "(" + hash + ")";
+ return hash + "[" + make(subscript) + "]";
+ },
+ "object": function(props) {
+ if (props.length == 0)
+ return "{}";
+ return "{" + newline + with_indent(function(){
+ return MAP(props, function(p){
+ if (p.length == 3) {
+ // getter/setter. The name is in p[0], the arg.list in p[1][2], the
+ // body in p[1][3] and type ("get" / "set") in p[2].
+ return indent(make_function(p[0], p[1][2], p[1][3], p[2]));
+ }
+ var key = p[0], val = make(p[1]);
+ if (beautify && beautify.quote_keys) {
+ key = make_string(key);
+ } else if (typeof key == "number" || !beautify && +key + "" == key) {
+ key = make_num(+key);
+ } else if (!is_identifier(key)) {
+ key = make_string(key);
+ }
+ return indent(add_spaces(beautify && beautify.space_colon
+ ? [ key, ":", val ]
+ : [ key + ":", val ]));
+ }).join("," + newline);
+ }) + newline + indent("}");
+ },
+ "regexp": function(rx, mods) {
+ return "/" + rx + "/" + mods;
+ },
+ "array": function(elements) {
+ if (elements.length == 0) return "[]";
+ return add_spaces([ "[", add_commas(MAP(elements, function(el){
+ return parenthesize(el, "seq");
+ })), "]" ]);
+ },
+ "stat": function(stmt) {
+ return make(stmt).replace(/;*\s*$/, ";");
+ },
+ "seq": function() {
+ return add_commas(MAP(slice(arguments), make));
+ },
+ "label": function(name, block) {
+ return add_spaces([ make_name(name), ":", make(block) ]);
+ },
+ "with": function(expr, block) {
+ return add_spaces([ "with", "(" + make(expr) + ")", make(block) ]);
+ },
+ "atom": function(name) {
+ return make_name(name);
+ },
+ "comment1": function(text) {
+ return "//" + text + "\n";
+ },
+ "comment2": function(text) {
+ return "/*" + text + "*/";
+ }
+ };
+
+ // The squeezer replaces "block"-s that contain only a single
+ // statement with the statement itself; technically, the AST
+ // is correct, but this can create problems when we output an
+ // IF having an ELSE clause where the THEN clause ends in an
+ // IF *without* an ELSE block (then the outer ELSE would refer
+ // to the inner IF). This function checks for this case and
+ // adds the block brackets if needed.
+ function make_then(th) {
+ if (th[0] == "do") {
+ // https://github.com/mishoo/UglifyJS/issues/#issue/57
+ // IE croaks with "syntax error" on code like this:
+ // if (foo) do ... while(cond); else ...
+ // we need block brackets around do/while
+ return make([ "block", [ th ]]);
+ }
+ var b = th;
+ while (true) {
+ var type = b[0];
+ if (type == "if") {
+ if (!b[3])
+ // no else, we must add the block
+ return make([ "block", [ th ]]);
+ b = b[3];
+ }
+ else if (type == "while" || type == "do") b = b[2];
+ else if (type == "for" || type == "for-in") b = b[4];
+ else break;
+ }
+ return make(th);
+ };
+
+ function make_function(name, args, body, keyword) {
+ var out = keyword || "function";
+ if (name) {
+ out += " " + make_name(name);
+ }
+ out += "(" + add_commas(MAP(args, make_name)) + ")";
+ return add_spaces([ out, make_block(body) ]);
+ };
+
+ function make_name(name) {
+ return name.toString();
+ };
+
+ function make_block_statements(statements) {
+ for (var a = [], last = statements.length - 1, i = 0; i <= last; ++i) {
+ var stat = statements[i];
+ var code = make(stat);
+ if (code != ";") {
+ if (!beautify && i == last)
+ code = code.replace(/;+\s*$/, "");
+ a.push(code);
+ }
+ }
+ return MAP(a, indent);
+ };
+
+ function make_switch_block(body) {
+ var n = body.length;
+ if (n == 0) return "{}";
+ return "{" + newline + MAP(body, function(branch, i){
+ var has_body = branch[1].length > 0, code = with_indent(function(){
+ return indent(branch[0]
+ ? add_spaces([ "case", make(branch[0]) + ":" ])
+ : "default:");
+ }, 0.5) + (has_body ? newline + with_indent(function(){
+ return make_block_statements(branch[1]).join(newline);
+ }) : "");
+ if (!beautify && has_body && i < n - 1)
+ code += ";";
+ return code;
+ }).join(newline) + newline + indent("}");
+ };
+
+ function make_block(statements) {
+ if (!statements) return ";";
+ if (statements.length == 0) return "{}";
+ return "{" + newline + with_indent(function(){
+ return make_block_statements(statements).join(newline);
+ }) + newline + indent("}");
+ };
+
+ function make_1vardef(def) {
+ var name = def[0], val = def[1];
+ if (val != null)
+ name = add_spaces([ name, "=", make(val) ]);
+ return name;
+ };
+
+ var $stack = [];
+
+ function make(node) {
+ var type = node[0];
+ var gen = generators[type];
+ if (!gen)
+ throw new Error("Can't find generator for \"" + type + "\"");
+ $stack.push(node);
+ var ret = gen.apply(type, node.slice(1));
+ $stack.pop();
+ return ret;
+ };
+
+ return make(ast);
+};
+
+/* -----[ Utilities ]----- */
+
+function repeat_string(str, i) {
+ if (i <= 0) return "";
+ if (i == 1) return str;
+ var d = repeat_string(str, i >> 1);
+ d += d;
+ if (i & 1) d += str;
+ return d;
+};
+
+function defaults(args, defs) {
+ var ret = {};
+ if (args === true)
+ args = {};
+ for (var i in defs) if (HOP(defs, i)) {
+ ret[i] = (args && HOP(args, i)) ? args[i] : defs[i];
+ }
+ return ret;
+};
+
+function is_identifier(name) {
+ return /^[a-z_$][a-z0-9_$]*$/i.test(name)
+ && name != "this"
+ && !HOP(jsp.KEYWORDS_ATOM, name)
+ && !HOP(jsp.RESERVED_WORDS, name)
+ && !HOP(jsp.KEYWORDS, name);
+};
+
+function HOP(obj, prop) {
+ return Object.prototype.hasOwnProperty.call(obj, prop);
+};
+
+// some utilities
+
+var MAP;
+
+(function(){
+ MAP = function(a, f, o) {
+ var ret = [];
+ for (var i = 0; i < a.length; ++i) {
+ var val = f.call(o, a[i], i);
+ if (val instanceof AtTop) ret.unshift(val.v);
+ else ret.push(val);
+ }
+ return ret;
+ };
+ MAP.at_top = function(val) { return new AtTop(val) };
+ function AtTop(val) { this.v = val };
+})();
+
+/* -----[ Exports ]----- */
+
+exports.ast_walker = ast_walker;
+exports.ast_mangle = ast_mangle;
+exports.ast_squeeze = ast_squeeze;
+exports.gen_code = gen_code;
+exports.ast_add_scope = ast_add_scope;
+exports.ast_squeeze_more = require("./squeeze-more").ast_squeeze_more;
+exports.set_logger = function(logger) { warn = logger };
diff --git a/Source/WebCore/inspector/front-end/WebKit.qrc b/Source/WebCore/inspector/front-end/WebKit.qrc
index 80a6533..edc1861 100644
--- a/Source/WebCore/inspector/front-end/WebKit.qrc
+++ b/Source/WebCore/inspector/front-end/WebKit.qrc
@@ -23,6 +23,7 @@
<file>CookieParser.js</file>
<file>CookiesTable.js</file>
<file>CSSCompletions.js</file>
+ <file>CSSKeywordCompletions.js</file>
<file>CSSStyleModel.js</file>
<file>Database.js</file>
<file>DatabaseQueryView.js</file>
@@ -51,7 +52,6 @@
<file>HelpScreen.js</file>
<file>ImageView.js</file>
<file>InjectedFakeWorker.js</file>
- <file>InjectedScriptAccess.js</file>
<file>inspector.js</file>
<file>InspectorFrontendHostStub.js</file>
<file>KeyboardShortcut.js</file>
@@ -81,6 +81,8 @@
<file>ResourcesPanel.js</file>
<file>ScopeChainSidebarPane.js</file>
<file>Script.js</file>
+ <file>ScriptFormatter.js</file>
+ <file>ScriptFormatterWorker.js</file>
<file>ScriptsPanel.js</file>
<file>ScriptView.js</file>
<file>Section.js</file>
@@ -114,6 +116,8 @@
<file>WatchExpressionsSidebarPane.js</file>
<file>WelcomeView.js</file>
<file>WorkersSidebarPane.js</file>
+ <file>UglifyJS/parse-js.js</file>
+ <file>UglifyJS/process.js</file>
<file>audits.css</file>
<file>goToLineDialog.css</file>
<file>heapProfiler.css</file>
diff --git a/Source/WebCore/inspector/front-end/inspector.css b/Source/WebCore/inspector/front-end/inspector.css
index c908427..f629d12 100644
--- a/Source/WebCore/inspector/front-end/inspector.css
+++ b/Source/WebCore/inspector/front-end/inspector.css
@@ -778,8 +778,8 @@ body.platform-linux .monospace, body.platform-linux .source-code {
color: red;
}
-.auto-complete-text {
- color: rgb(128, 128, 128);
+.auto-complete-text, .editing .auto-complete-text {
+ color: rgb(128, 128, 128) !important;
-webkit-user-select: none;
-webkit-user-modify: read-only;
}
diff --git a/Source/WebCore/inspector/front-end/inspector.html b/Source/WebCore/inspector/front-end/inspector.html
index 44f096f..0e0b9e9 100644
--- a/Source/WebCore/inspector/front-end/inspector.html
+++ b/Source/WebCore/inspector/front-end/inspector.html
@@ -92,6 +92,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<script type="text/javascript" src="EventListenersSidebarPane.js"></script>
<script type="text/javascript" src="Color.js"></script>
<script type="text/javascript" src="CSSCompletions.js"></script>
+ <script type="text/javascript" src="CSSKeywordCompletions.js"></script>
<script type="text/javascript" src="StylesSidebarPane.js"></script>
<script type="text/javascript" src="PanelEnablerView.js"></script>
<script type="text/javascript" src="WelcomeView.js"></script>
@@ -121,6 +122,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<script type="text/javascript" src="NetworkItemView.js"></script>
<script type="text/javascript" src="ResourceView.js"></script>
<script type="text/javascript" src="SourceFrame.js"></script>
+ <script type="text/javascript" src="ScriptFormatter.js"></script>
<script type="text/javascript" src="DOMSyntaxHighlighter.js"></script>
<script type="text/javascript" src="TextEditorModel.js"></script>
<script type="text/javascript" src="TextEditorHighlighter.js"></script>
@@ -142,7 +144,6 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<script type="text/javascript" src="HeapSnapshotView.js"></script>
<script type="text/javascript" src="DebuggerModel.js"></script>
<script type="text/javascript" src="DOMAgent.js"></script>
- <script type="text/javascript" src="InjectedScriptAccess.js"></script>
<script type="text/javascript" src="TimelineAgent.js"></script>
<script type="text/javascript" src="TimelinePanel.js"></script>
<script type="text/javascript" src="TimelineOverviewPane.js"></script>
diff --git a/Source/WebCore/inspector/front-end/inspector.js b/Source/WebCore/inspector/front-end/inspector.js
index d8a93b1..77abe78 100644
--- a/Source/WebCore/inspector/front-end/inspector.js
+++ b/Source/WebCore/inspector/front-end/inspector.js
@@ -185,20 +185,9 @@ var WebInspector = {
}
},
- createJSBreakpointsSidebarPane: function()
- {
- var pane = new WebInspector.BreakpointsSidebarPane(WebInspector.UIString("Breakpoints"));
- function breakpointAdded(event)
- {
- pane.addBreakpointItem(new WebInspector.BreakpointItem(event.data));
- }
- WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.BreakpointAdded, breakpointAdded);
- return pane;
- },
-
createDOMBreakpointsSidebarPane: function()
{
- var pane = new WebInspector.BreakpointsSidebarPane(WebInspector.UIString("DOM Breakpoints"));
+ var pane = new WebInspector.NativeBreakpointsSidebarPane(WebInspector.UIString("DOM Breakpoints"));
function breakpointAdded(event)
{
pane.addBreakpointItem(new WebInspector.BreakpointItem(event.data));
@@ -534,7 +523,7 @@ WebInspector.doLoadedDone = function()
scripts: new WebInspector.ResourceCategory("scripts", WebInspector.UIString("Scripts"), "rgb(255,121,0)"),
xhr: new WebInspector.ResourceCategory("xhr", WebInspector.UIString("XHR"), "rgb(231,231,10)"),
fonts: new WebInspector.ResourceCategory("fonts", WebInspector.UIString("Fonts"), "rgb(255,82,62)"),
- websockets: new WebInspector.ResourceCategory("websockets", WebInspector.UIString("WebSocket"), "rgb(186,186,186)"), // FIXME: Decide the color.
+ websockets: new WebInspector.ResourceCategory("websockets", WebInspector.UIString("WebSockets"), "rgb(186,186,186)"), // FIXME: Decide the color.
other: new WebInspector.ResourceCategory("other", WebInspector.UIString("Other"), "rgb(186,186,186)")
};
@@ -601,14 +590,6 @@ WebInspector.doLoadedDone = function()
this.extensionServer.initExtensions();
- function populateInspectorState(inspectorState)
- {
- WebInspector.monitoringXHREnabled = inspectorState.monitoringXHREnabled;
- if ("pauseOnExceptionsState" in inspectorState)
- WebInspector.panels.scripts.updatePauseOnExceptionsState(inspectorState.pauseOnExceptionsState);
- }
- InspectorBackend.getInspectorState(populateInspectorState);
-
function onPopulateScriptObjects()
{
if (!WebInspector.currentPanel)
diff --git a/Source/WebCore/inspector/front-end/utilities.js b/Source/WebCore/inspector/front-end/utilities.js
index 4320ba8..5ed9a8c 100644
--- a/Source/WebCore/inspector/front-end/utilities.js
+++ b/Source/WebCore/inspector/front-end/utilities.js
@@ -745,6 +745,22 @@ Object.defineProperty(Array.prototype, "keySet", { value: function()
return keys;
}});
+Object.defineProperty(Array.prototype, "upperBound", { value: function(value)
+{
+ var first = 0;
+ var count = this.length;
+ while (count > 0) {
+ var step = count >> 1;
+ var middle = first + step;
+ if (value >= this[middle]) {
+ first = middle + 1;
+ count -= step + 1;
+ } else
+ count = step;
+ }
+ return first;
+}});
+
Array.diff = function(left, right)
{
var o = left;