2010-01-20 Yury Semikhatsky <yurys@chromium.org>
authoryurys@chromium.org <yurys@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 20 Jan 2010 17:44:10 +0000 (17:44 +0000)
committeryurys@chromium.org <yurys@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 20 Jan 2010 17:44:10 +0000 (17:44 +0000)
        Reviewed by Pavel Feldman.

        Inject inspector script directly into the inspected context. All the
        communication between the script and the frontend is serialized into
        JSON strings. It allows to get rid of object quarantines in Web Inspector.

        https://bugs.webkit.org/show_bug.cgi?id=32554

        Test: inspector/console-log-before-inspector-open.html

        * bindings/js/JSInjectedScriptHostCustom.cpp:
        (WebCore::JSInjectedScriptHost::databaseForId):
        (WebCore::JSInjectedScriptHost::currentCallFrame):
        (WebCore::JSInjectedScriptHost::nodeForId):
        (WebCore::JSInjectedScriptHost::pushNodePathToFrontend):
        (WebCore::JSInjectedScriptHost::selectDatabase):
        (WebCore::JSInjectedScriptHost::selectDOMStorage):
        * bindings/js/ScriptCallStack.h:
        (WebCore::ScriptCallStack::state):
        * bindings/js/ScriptController.cpp:
        (WebCore::ScriptController::mainWorldScriptState):
        * bindings/js/ScriptController.h:
        * bindings/js/ScriptObject.h:
        (WebCore::ScriptObject::scriptState):
        * bindings/js/ScriptValue.cpp:
        * bindings/js/ScriptValue.h:
        * bindings/v8/ScriptObject.h:
        (WebCore::ScriptObject::scriptState):
        * bindings/v8/ScriptValue.h:
        * bindings/v8/custom/V8InjectedScriptHostCustom.cpp:
        * inspector/ConsoleMessage.cpp:
        (WebCore::ConsoleMessage::ConsoleMessage):
        (WebCore::ConsoleMessage::addToConsole):
        (WebCore::ConsoleMessage::isEqual):
        * inspector/ConsoleMessage.h:
        * inspector/InjectedScriptHost.cpp:
        (WebCore::InjectedScriptHost::releaseWrapperObjectGroup):
        * inspector/InjectedScriptHost.h:
        * inspector/InjectedScriptHost.idl:
        * inspector/InspectorBackend.cpp:
        (WebCore::InspectorBackend::setInjectedScriptSource):
        (WebCore::InspectorBackend::dispatchOnInjectedScript):
        (WebCore::InspectorBackend::releaseWrapperObjectGroup):
        * inspector/InspectorBackend.h:
        * inspector/InspectorBackend.idl:
        * inspector/InspectorController.cpp:
        (WebCore::InspectorController::InspectorController):
        (WebCore::InspectorController::clearConsoleMessages):
        (WebCore::InspectorController::inspectedWindowScriptObjectCleared):
        (WebCore::InspectorController::windowScriptObjectAvailable):
        (WebCore::InspectorController::scriptObjectReady):
        (WebCore::InspectorController::setFrontendProxyObject):
        (WebCore::InspectorController::close):
        (WebCore::InspectorController::resetScriptObjects):
        (WebCore::InspectorController::didPause):
        (WebCore::InspectorController::injectedScriptForNodeId):
        * inspector/InspectorController.h:
        * inspector/InspectorFrontend.cpp:
        (WebCore::InspectorFrontend::addConsoleMessage):
        (WebCore::InspectorFrontend::pausedScript):
        * inspector/InspectorFrontend.h:
        * inspector/front-end/AuditsPanel.js:
        (WebInspector.AuditsPanel.prototype._reloadResources):
        * inspector/front-end/ConsoleView.js:
        (WebInspector.ConsoleView.prototype.requestClearMessages):
        (WebInspector.ConsoleView.prototype.doEvalInWindow):
        * inspector/front-end/DOMAgent.js:
        (WebInspector.DOMNode):
        (WebInspector.CSSStyleDeclaration):
        (WebInspector.CSSStyleDeclaration.parseRule):
        * inspector/front-end/Database.js:
        (WebInspector.Database.prototype.executeSql):
        * inspector/front-end/ElementsPanel.js:
        (WebInspector.ElementsPanel.this.treeOutline.focusedNodeChanged.InjectedScriptAccess.get addInspectedNode):
        (WebInspector.ElementsPanel.this.treeOutline.focusedNodeChanged):
        (WebInspector.ElementsPanel.prototype.setDocument):
        (WebInspector.ElementsPanel.prototype.searchCanceled):
        (WebInspector.ElementsPanel.prototype.performSearch):
        * inspector/front-end/ElementsTreeOutline.js:
        (WebInspector.ElementsTreeElement.prototype.createTooltipForImageNode):
        * inspector/front-end/EventListenersSidebarPane.js:
        ():
        * inspector/front-end/InjectedScript.js:
        (injectedScriptConstructor):
        (injectedScriptConstructor.):
        * inspector/front-end/InjectedScriptAccess.js:
        (InjectedScriptAccess):
        (InjectedScriptAccess.getDefault):
        (get InjectedScriptAccess):
        (InjectedScriptAccess._installHandler.InjectedScriptAccess.prototype.methodName):
        (InjectedScriptAccess._installHandler):
        * inspector/front-end/MetricsSidebarPane.js:
        (WebInspector.MetricsSidebarPane):
        (WebInspector.MetricsSidebarPane.prototype.update.inlineStyleCallback):
        * inspector/front-end/ObjectPropertiesSection.js:
        * inspector/front-end/ObjectProxy.js:
        (WebInspector.ObjectProxy):
        * inspector/front-end/PropertiesSidebarPane.js:
        (WebInspector.PropertiesSidebarPane.prototype.update.callback):
        * inspector/front-end/ResourcesPanel.js:
        (WebInspector.ResourceSidebarTreeElement.prototype.ondblclick):
        * inspector/front-end/ScriptsPanel.js:
        * inspector/front-end/StylesSidebarPane.js:
        (WebInspector.StylePropertyTreeElement.prototype):
        * inspector/front-end/WatchExpressionsSidebarPane.js:
        (WebInspector.WatchExpressionsSection.prototype.update):
        * inspector/front-end/inspector.js:
        (WebInspector.loaded):
        (WebInspector.pausedScript):
        (WebInspector.addConsoleMessage):
        (WebInspector.log.logMessage):
        (WebInspector.log):

2010-01-20  Yury Semikhatsky  <yurys@chromium.org>

        Reviewed by Pavel Feldman.

        Inject inspector script directly into the inspected context. All the
        communication between the script and the frontend is serialized into
        JSON strings. It allows to get rid of object quarantines in Web Inspector.

        Test that web inspector doesn't crash when opening if there are messages in
        the console. Refactor test case due to InjectedScriptAccess changes.

        https://bugs.webkit.org/show_bug.cgi?id=32554

        * inspector/console-log-before-inspector-open-expected.txt: Added.
        * inspector/console-log-before-inspector-open.html: Added.
        * inspector/styles-iframe.html:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@53552 268f45cc-cd09-0410-ab3c-d52691b4dbfc

45 files changed:
LayoutTests/ChangeLog
LayoutTests/inspector/console-log-before-inspector-open-expected.txt [new file with mode: 0644]
LayoutTests/inspector/console-log-before-inspector-open.html [new file with mode: 0755]
LayoutTests/inspector/styles-iframe.html
WebCore/ChangeLog
WebCore/bindings/js/JSInjectedScriptHostCustom.cpp
WebCore/bindings/js/ScriptCallStack.h
WebCore/bindings/js/ScriptController.cpp
WebCore/bindings/js/ScriptController.h
WebCore/bindings/js/ScriptObject.h
WebCore/bindings/js/ScriptValue.cpp
WebCore/bindings/js/ScriptValue.h
WebCore/bindings/v8/ScriptObject.h
WebCore/bindings/v8/ScriptValue.h
WebCore/bindings/v8/custom/V8InjectedScriptHostCustom.cpp
WebCore/inspector/ConsoleMessage.cpp
WebCore/inspector/ConsoleMessage.h
WebCore/inspector/InjectedScriptHost.cpp
WebCore/inspector/InjectedScriptHost.h
WebCore/inspector/InjectedScriptHost.idl
WebCore/inspector/InspectorBackend.cpp
WebCore/inspector/InspectorBackend.h
WebCore/inspector/InspectorBackend.idl
WebCore/inspector/InspectorController.cpp
WebCore/inspector/InspectorController.h
WebCore/inspector/InspectorFrontend.cpp
WebCore/inspector/InspectorFrontend.h
WebCore/inspector/front-end/AuditsPanel.js
WebCore/inspector/front-end/ConsoleView.js
WebCore/inspector/front-end/DOMAgent.js
WebCore/inspector/front-end/Database.js
WebCore/inspector/front-end/ElementsPanel.js
WebCore/inspector/front-end/ElementsTreeOutline.js
WebCore/inspector/front-end/EventListenersSidebarPane.js
WebCore/inspector/front-end/InjectedScript.js
WebCore/inspector/front-end/InjectedScriptAccess.js
WebCore/inspector/front-end/MetricsSidebarPane.js
WebCore/inspector/front-end/ObjectPropertiesSection.js
WebCore/inspector/front-end/ObjectProxy.js
WebCore/inspector/front-end/PropertiesSidebarPane.js
WebCore/inspector/front-end/ResourcesPanel.js
WebCore/inspector/front-end/ScriptsPanel.js
WebCore/inspector/front-end/StylesSidebarPane.js
WebCore/inspector/front-end/WatchExpressionsSidebarPane.js
WebCore/inspector/front-end/inspector.js

index 894264a..6b99f86 100644 (file)
@@ -1,3 +1,20 @@
+2010-01-20  Yury Semikhatsky  <yurys@chromium.org>
+
+        Reviewed by Pavel Feldman.
+
+        Inject inspector script directly into the inspected context. All the
+        communication between the script and the frontend is serialized into
+        JSON strings. It allows to get rid of object quarantines in Web Inspector.
+
+        Test that web inspector doesn't crash when opening if there are messages in
+        the console. Refactor test case due to InjectedScriptAccess changes.
+
+        https://bugs.webkit.org/show_bug.cgi?id=32554
+
+        * inspector/console-log-before-inspector-open-expected.txt: Added.
+        * inspector/console-log-before-inspector-open.html: Added.
+        * inspector/styles-iframe.html:
+
 2010-01-20  Kent Tamura  <tkent@chromium.org>
 
         Reviewed by Darin Adler.
diff --git a/LayoutTests/inspector/console-log-before-inspector-open-expected.txt b/LayoutTests/inspector/console-log-before-inspector-open-expected.txt
new file mode 100644 (file)
index 0000000..963e6e6
--- /dev/null
@@ -0,0 +1,13 @@
+CONSOLE MESSAGE: line 0: log
+CONSOLE MESSAGE: line 0: debug
+CONSOLE MESSAGE: line 0: info
+CONSOLE MESSAGE: line 0: warn
+CONSOLE MESSAGE: line 0: error
+Tests that Web Inspector won't crash if some console have been logged by the time it's opening.
+
+log
+debug
+info
+warn
+error
+
diff --git a/LayoutTests/inspector/console-log-before-inspector-open.html b/LayoutTests/inspector/console-log-before-inspector-open.html
new file mode 100755 (executable)
index 0000000..a8921f1
--- /dev/null
@@ -0,0 +1,27 @@
+<html>
+<head>
+<script src="inspector-test.js"></script>
+<script src="console-tests.js"></script>
+<script>
+
+console.log('log');
+console.debug('debug');
+console.info('info');
+console.warn('warn');
+console.error('error');
+
+function doit()
+{
+    dumpConsoleMessages();
+}
+
+</script>
+</head>
+
+<body onload="onload()">
+<p>
+Tests that Web Inspector won't crash if some console have been logged by the time it's opening.
+</p>
+
+</body>
+</html>
index d40a3cd..ddc51f5 100755 (executable)
@@ -56,22 +56,22 @@ function frontend_dumpStyles(testController)
 function frontend_dumpStylesContinuation(testController)
 {
     // 1. Get styles for body, store them in mainStyles var.
-    var bodyId = WebInspector.domAgent.document.body.id;
+    var body = WebInspector.domAgent.document.body;
     var mainStyles = null;
     function mainFrameCallback(styles) {
         mainStyles = styles;
     }
-    InjectedScriptAccess.getStyles(bodyId, false, mainFrameCallback);
+    InjectedScriptAccess.get(body.injectedScriptId).getStyles(body.id, false, mainFrameCallback);
 
     // 2. Find iframe node
     var innerMapping = WebInspector.domAgent._idToDOMNode;
-    var iframeBodyId = null;
+    var iframeBody = null;
 
     for (var nodeId in innerMapping) {
         if (innerMapping[nodeId].nodeName === "IFRAME")
-            iframeBodyId = innerMapping[nodeId].firstChild.lastChild.id;
+            iframeBody = innerMapping[nodeId].firstChild.lastChild;
     }
-    if (typeof iframeBodyId !== "number") {
+    if (!iframeBody) {
         testController.notifyDone(["No iframe node found"]);
         return;
     }
@@ -80,7 +80,7 @@ function frontend_dumpStylesContinuation(testController)
     function iframeCallback(styles) {
         testController.notifyDone([mainStyles, styles]);
     }
-    InjectedScriptAccess.getStyles(iframeBodyId, false, iframeCallback);
+    InjectedScriptAccess.get(iframeBody.injectedScriptId).getStyles(iframeBody.id, false, iframeCallback);
 }
 
 </script>
index d05699e..232a576 100644 (file)
@@ -1,3 +1,118 @@
+2010-01-20  Yury Semikhatsky  <yurys@chromium.org>
+
+        Reviewed by Pavel Feldman.
+
+        Inject inspector script directly into the inspected context. All the
+        communication between the script and the frontend is serialized into
+        JSON strings. It allows to get rid of object quarantines in Web Inspector.
+
+        https://bugs.webkit.org/show_bug.cgi?id=32554
+
+        Test: inspector/console-log-before-inspector-open.html
+
+        * bindings/js/JSInjectedScriptHostCustom.cpp:
+        (WebCore::JSInjectedScriptHost::databaseForId):
+        (WebCore::JSInjectedScriptHost::currentCallFrame):
+        (WebCore::JSInjectedScriptHost::nodeForId):
+        (WebCore::JSInjectedScriptHost::pushNodePathToFrontend):
+        (WebCore::JSInjectedScriptHost::selectDatabase):
+        (WebCore::JSInjectedScriptHost::selectDOMStorage):
+        * bindings/js/ScriptCallStack.h:
+        (WebCore::ScriptCallStack::state):
+        * bindings/js/ScriptController.cpp:
+        (WebCore::ScriptController::mainWorldScriptState):
+        * bindings/js/ScriptController.h:
+        * bindings/js/ScriptObject.h:
+        (WebCore::ScriptObject::scriptState):
+        * bindings/js/ScriptValue.cpp:
+        * bindings/js/ScriptValue.h:
+        * bindings/v8/ScriptObject.h:
+        (WebCore::ScriptObject::scriptState):
+        * bindings/v8/ScriptValue.h:
+        * bindings/v8/custom/V8InjectedScriptHostCustom.cpp:
+        * inspector/ConsoleMessage.cpp:
+        (WebCore::ConsoleMessage::ConsoleMessage):
+        (WebCore::ConsoleMessage::addToConsole):
+        (WebCore::ConsoleMessage::isEqual):
+        * inspector/ConsoleMessage.h:
+        * inspector/InjectedScriptHost.cpp:
+        (WebCore::InjectedScriptHost::releaseWrapperObjectGroup):
+        * inspector/InjectedScriptHost.h:
+        * inspector/InjectedScriptHost.idl:
+        * inspector/InspectorBackend.cpp:
+        (WebCore::InspectorBackend::setInjectedScriptSource):
+        (WebCore::InspectorBackend::dispatchOnInjectedScript):
+        (WebCore::InspectorBackend::releaseWrapperObjectGroup):
+        * inspector/InspectorBackend.h:
+        * inspector/InspectorBackend.idl:
+        * inspector/InspectorController.cpp:
+        (WebCore::InspectorController::InspectorController):
+        (WebCore::InspectorController::clearConsoleMessages):
+        (WebCore::InspectorController::inspectedWindowScriptObjectCleared):
+        (WebCore::InspectorController::windowScriptObjectAvailable):
+        (WebCore::InspectorController::scriptObjectReady):
+        (WebCore::InspectorController::setFrontendProxyObject):
+        (WebCore::InspectorController::close):
+        (WebCore::InspectorController::resetScriptObjects):
+        (WebCore::InspectorController::didPause):
+        (WebCore::InspectorController::injectedScriptForNodeId):
+        * inspector/InspectorController.h:
+        * inspector/InspectorFrontend.cpp:
+        (WebCore::InspectorFrontend::addConsoleMessage):
+        (WebCore::InspectorFrontend::pausedScript):
+        * inspector/InspectorFrontend.h:
+        * inspector/front-end/AuditsPanel.js:
+        (WebInspector.AuditsPanel.prototype._reloadResources):
+        * inspector/front-end/ConsoleView.js:
+        (WebInspector.ConsoleView.prototype.requestClearMessages):
+        (WebInspector.ConsoleView.prototype.doEvalInWindow):
+        * inspector/front-end/DOMAgent.js:
+        (WebInspector.DOMNode):
+        (WebInspector.CSSStyleDeclaration):
+        (WebInspector.CSSStyleDeclaration.parseRule):
+        * inspector/front-end/Database.js:
+        (WebInspector.Database.prototype.executeSql):
+        * inspector/front-end/ElementsPanel.js:
+        (WebInspector.ElementsPanel.this.treeOutline.focusedNodeChanged.InjectedScriptAccess.get addInspectedNode):
+        (WebInspector.ElementsPanel.this.treeOutline.focusedNodeChanged):
+        (WebInspector.ElementsPanel.prototype.setDocument):
+        (WebInspector.ElementsPanel.prototype.searchCanceled):
+        (WebInspector.ElementsPanel.prototype.performSearch):
+        * inspector/front-end/ElementsTreeOutline.js:
+        (WebInspector.ElementsTreeElement.prototype.createTooltipForImageNode):
+        * inspector/front-end/EventListenersSidebarPane.js:
+        ():
+        * inspector/front-end/InjectedScript.js:
+        (injectedScriptConstructor):
+        (injectedScriptConstructor.):
+        * inspector/front-end/InjectedScriptAccess.js:
+        (InjectedScriptAccess):
+        (InjectedScriptAccess.getDefault):
+        (get InjectedScriptAccess):
+        (InjectedScriptAccess._installHandler.InjectedScriptAccess.prototype.methodName):
+        (InjectedScriptAccess._installHandler):
+        * inspector/front-end/MetricsSidebarPane.js:
+        (WebInspector.MetricsSidebarPane):
+        (WebInspector.MetricsSidebarPane.prototype.update.inlineStyleCallback):
+        * inspector/front-end/ObjectPropertiesSection.js:
+        * inspector/front-end/ObjectProxy.js:
+        (WebInspector.ObjectProxy):
+        * inspector/front-end/PropertiesSidebarPane.js:
+        (WebInspector.PropertiesSidebarPane.prototype.update.callback):
+        * inspector/front-end/ResourcesPanel.js:
+        (WebInspector.ResourceSidebarTreeElement.prototype.ondblclick):
+        * inspector/front-end/ScriptsPanel.js:
+        * inspector/front-end/StylesSidebarPane.js:
+        (WebInspector.StylePropertyTreeElement.prototype):
+        * inspector/front-end/WatchExpressionsSidebarPane.js:
+        (WebInspector.WatchExpressionsSection.prototype.update):
+        * inspector/front-end/inspector.js:
+        (WebInspector.loaded):
+        (WebInspector.pausedScript):
+        (WebInspector.addConsoleMessage):
+        (WebInspector.log.logMessage):
+        (WebInspector.log):
+
 2010-01-20  Kent Tamura  <tkent@chromium.org>
 
         Reviewed by Darin Adler.
index 1409beb..a7836b0 100644 (file)
@@ -47,8 +47,6 @@
 #include "InspectorController.h"
 #include "InspectorResource.h"
 #include "JSDOMWindow.h"
-#include "JSInspectedObjectWrapper.h"
-#include "JSInspectorCallbackWrapper.h"
 #include "JSNode.h"
 #include "JSRange.h"
 #include "Node.h"
@@ -112,29 +110,10 @@ JSValue JSInjectedScriptHost::databaseForId(ExecState* exec, const ArgList& args
     Database* database = impl()->databaseForId(args.at(0).toInt32(exec));
     if (!database)
         return jsUndefined();
-    // Could use currentWorld(exec) ... but which exec!  The following mixed use of exec & inspectedWindow->globalExec() scares me!
-    JSDOMWindow* inspectedWindow = toJSDOMWindow(ic->inspectedPage()->mainFrame(), debuggerWorld());
-    return JSInspectedObjectWrapper::wrap(inspectedWindow->globalExec(), toJS(exec, database));
+    return toJS(exec, database);
 }
 #endif
 
-JSValue JSInjectedScriptHost::inspectedWindow(ExecState*, const ArgList&)
-{
-    InspectorController* ic = impl()->inspectorController();
-    if (!ic)
-        return jsUndefined();
-    JSDOMWindow* inspectedWindow = toJSDOMWindow(ic->inspectedPage()->mainFrame(), debuggerWorld());
-    return JSInspectedObjectWrapper::wrap(inspectedWindow->globalExec(), inspectedWindow);
-}
-
-JSValue JSInjectedScriptHost::wrapCallback(ExecState* exec, const ArgList& args)
-{
-    if (args.size() < 1)
-        return jsUndefined();
-
-    return JSInspectorCallbackWrapper::wrap(exec, args.at(0));
-}
-
 #if ENABLE(JAVASCRIPT_DEBUGGER)
 
 JSValue JSInjectedScriptHost::currentCallFrame(ExecState* exec, const ArgList&)
@@ -143,11 +122,8 @@ JSValue JSInjectedScriptHost::currentCallFrame(ExecState* exec, const ArgList&)
     if (!callFrame || !callFrame->isValid())
         return jsUndefined();
 
-    // FIXME: I am not sure if this is actually needed. Can we just use exec?
-    ExecState* globalExec = callFrame->scopeChain()->globalObject->globalExec();
-
     JSLock lock(SilenceAssertionsOnly);
-    return JSInspectedObjectWrapper::wrap(globalExec, toJS(exec, callFrame));
+    return toJS(exec, callFrame);
 }
 
 #endif
@@ -166,24 +142,7 @@ JSValue JSInjectedScriptHost::nodeForId(ExecState* exec, const ArgList& args)
         return jsUndefined();
 
     JSLock lock(SilenceAssertionsOnly);
-    JSDOMWindow* inspectedWindow = toJSDOMWindow(ic->inspectedPage()->mainFrame(), debuggerWorld());
-    return JSInspectedObjectWrapper::wrap(inspectedWindow->globalExec(), toJS(exec, deprecatedGlobalObjectForPrototype(inspectedWindow->globalExec()), node));
-}
-
-JSValue JSInjectedScriptHost::wrapObject(ExecState* exec, const ArgList& args)
-{
-    if (args.size() < 2)
-        return jsUndefined();
-
-    return impl()->wrapObject(ScriptValue(args.at(0)), args.at(1).toString(exec)).jsValue();
-}
-
-JSValue JSInjectedScriptHost::unwrapObject(ExecState* exec, const ArgList& args)
-{
-    if (args.size() < 1)
-        return jsUndefined();
-
-    return impl()->unwrapObject(args.at(0).toString(exec)).jsValue();
+    return toJS(exec, node);
 }
 
 JSValue JSInjectedScriptHost::pushNodePathToFrontend(ExecState* exec, const ArgList& args)
@@ -191,11 +150,7 @@ JSValue JSInjectedScriptHost::pushNodePathToFrontend(ExecState* exec, const ArgL
     if (args.size() < 3)
         return jsUndefined();
 
-    JSQuarantinedObjectWrapper* wrapper = JSQuarantinedObjectWrapper::asWrapper(args.at(0));
-    if (!wrapper)
-        return jsUndefined();
-
-    Node* node = toNode(wrapper->unwrappedObject());
+    Node* node = toNode(args.at(0));
     if (!node)
         return jsUndefined();
 
@@ -210,11 +165,7 @@ JSValue JSInjectedScriptHost::selectDatabase(ExecState*, const ArgList& args)
     if (args.size() < 1)
         return jsUndefined();
 
-    JSQuarantinedObjectWrapper* wrapper = JSQuarantinedObjectWrapper::asWrapper(args.at(0));
-    if (!wrapper)
-        return jsUndefined();
-
-    Database* database = toDatabase(wrapper->unwrappedObject());
+    Database* database = toDatabase(args.at(0));
     if (database)
         impl()->selectDatabase(database);
     return jsUndefined();
@@ -230,11 +181,7 @@ JSValue JSInjectedScriptHost::selectDOMStorage(ExecState*, const ArgList& args)
     if (!ic)
         return jsUndefined();
 
-    JSQuarantinedObjectWrapper* wrapper = JSQuarantinedObjectWrapper::asWrapper(args.at(0));
-    if (!wrapper)
-        return jsUndefined();
-
-    Storage* storage = toStorage(wrapper->unwrappedObject());
+    Storage* storage = toStorage(args.at(0));
     if (storage)
         impl()->selectDOMStorage(storage);
     return jsUndefined();
index 1907564..433c34c 100644 (file)
@@ -48,7 +48,7 @@ namespace WebCore {
         ScriptCallStack(JSC::ExecState*, const JSC::ArgList&, unsigned skipArgumentCount = 0);
         ~ScriptCallStack();
 
-        ScriptState* state() const { return m_exec; }
+        ScriptState* state() const { return m_exec->lexicalGlobalObject()->globalExec(); }
         // frame retrieval methods
         const ScriptCallFrame &at(unsigned);
         unsigned size();
index 698e93a..8659373 100644 (file)
@@ -380,6 +380,12 @@ NPObject* ScriptController::createScriptObjectForPluginElement(HTMLPlugInElement
 
 #endif
 
+ScriptState* ScriptController::mainWorldScriptState()
+{
+    JSDOMWindowShell* shell = windowShell(mainThreadNormalWorld());
+    return shell->window()->globalExec();
+}
+
 JSObject* ScriptController::jsObjectForPluginElement(HTMLPlugInElement* plugin)
 {
     // Can't create JSObjects when JavaScript is disabled
index f3e5adf..f265ab5 100644 (file)
@@ -24,6 +24,7 @@
 
 #include "JSDOMWindowShell.h"
 #include "ScriptInstance.h"
+#include "ScriptState.h"
 #include <runtime/Protect.h>
 #include <wtf/RefPtr.h>
 
@@ -159,6 +160,8 @@ public:
     
     XSSAuditor* xssAuditor() { return m_XSSAuditor.get(); }
 
+    ScriptState* mainWorldScriptState();
+
 private:
     JSDOMWindowShell* initScript(DOMWrapperWorld* world);
 
index fed7339..0c993e1 100644 (file)
@@ -47,6 +47,7 @@ namespace WebCore {
         ScriptObject(ScriptState*, JSC::JSObject*);
         ScriptObject() {}
         JSC::JSObject* jsObject() const { return asObject(jsValue()); }
+        ScriptState* scriptState() const { return m_scriptState; }
 
         bool set(const String& name, const String&);
         bool set(const char* name, const ScriptObject&);
index 5444e0e..ac92e14 100644 (file)
@@ -32,8 +32,6 @@
 #include <JavaScriptCore/APICast.h>
 #include <JavaScriptCore/JSValueRef.h>
 
-#include "JSInspectedObjectWrapper.h"
-
 #include <runtime/JSLock.h>
 #include <runtime/Protect.h>
 #include <runtime/UString.h>
@@ -42,14 +40,6 @@ using namespace JSC;
 
 namespace WebCore {
 
-#if ENABLE(INSPECTOR)
-ScriptValue ScriptValue::quarantineValue(ScriptState* scriptState, const ScriptValue& value)
-{
-    JSLock lock(SilenceAssertionsOnly);
-    return ScriptValue(JSInspectedObjectWrapper::wrap(scriptState, value.jsValue()));
-}
-#endif
-
 bool ScriptValue::getString(ScriptState* scriptState, String& result) const
 {
     if (!m_value)
index e11fa55..b1eaa21 100644 (file)
@@ -41,8 +41,6 @@ class String;
 
 class ScriptValue {
 public:
-    static ScriptValue quarantineValue(ScriptState* scriptState, const ScriptValue& value);
-
     ScriptValue(JSC::JSValue value = JSC::JSValue()) : m_value(value) {}
     virtual ~ScriptValue() {}
 
index 630d3b9..a60f2a8 100644 (file)
@@ -48,6 +48,7 @@ namespace WebCore {
         virtual ~ScriptObject() {}
 
         v8::Local<v8::Object> v8Object() const;
+        ScriptState* scriptState() const { return m_scriptState; }
 
         bool set(const String& name, const String&);
         bool set(const char* name, const ScriptObject&);
index c0ba8d5..6a70bd7 100644 (file)
@@ -44,11 +44,6 @@ namespace WebCore {
 
 class ScriptValue {
 public:
-    static ScriptValue quarantineValue(ScriptState* scriptState, const ScriptValue& value)
-    {
-        return value;
-    }
-
     ScriptValue() {}
 
     ScriptValue(v8::Handle<v8::Value> value) 
index dbed4a3..0ddcf97 100644 (file)
@@ -114,23 +114,6 @@ static ScriptObject createInjectedScript(const String& scriptSource, InjectedScr
     return ScriptObject(inspectedScriptState, injectedScript);
 }
 
-v8::Handle<v8::Value> V8InjectedScriptHost::inspectedWindowCallback(const v8::Arguments& args)
-{
-    INC_STATS("InjectedScriptHost.inspectedWindow()");
-
-    InjectedScriptHost* host = V8InjectedScriptHost::toNative(args.Holder());
-    InspectorController* ic = host->inspectorController();
-    if (!ic)
-        return v8::Undefined();
-    return V8DOMWrapper::convertToV8Object<DOMWindow>(V8ClassIndex::DOMWINDOW, ic->inspectedPage()->mainFrame()->domWindow());
-}
-
-v8::Handle<v8::Value> V8InjectedScriptHost::wrapCallbackCallback(const v8::Arguments& args)
-{
-    INC_STATS("InjectedScriptHost.wrapCallback()");
-    return args[0];
-}
-
 v8::Handle<v8::Value> V8InjectedScriptHost::nodeForIdCallback(const v8::Arguments& args)
 {
     INC_STATS("InjectedScriptHost.nodeForId()");
@@ -150,26 +133,6 @@ v8::Handle<v8::Value> V8InjectedScriptHost::nodeForIdCallback(const v8::Argument
     return V8DOMWrapper::convertToV8Object(V8ClassIndex::NODE, node);
 }
 
-v8::Handle<v8::Value> V8InjectedScriptHost::wrapObjectCallback(const v8::Arguments& args)
-{
-    INC_STATS("InjectedScriptHost.wrapObject()");
-    if (args.Length() < 2)
-        return v8::Undefined();
-
-    InjectedScriptHost* host = V8InjectedScriptHost::toNative(args.Holder());
-    return host->wrapObject(ScriptValue(args[0]), toWebCoreStringWithNullCheck(args[1])).v8Value();
-}
-
-v8::Handle<v8::Value> V8InjectedScriptHost::unwrapObjectCallback(const v8::Arguments& args)
-{
-    INC_STATS("InjectedScriptHost.unwrapObject()");
-    if (args.Length() < 1)
-        return v8::Undefined();
-
-    InjectedScriptHost* host = V8InjectedScriptHost::toNative(args.Holder());
-    return host->unwrapObject(toWebCoreStringWithNullCheck(args[0])).v8Value();
-}
-
 v8::Handle<v8::Value> V8InjectedScriptHost::pushNodePathToFrontendCallback(const v8::Arguments& args)
 {
     INC_STATS("InjectedScriptHost.pushNodePathToFrontend()");
index fe32da7..7826ed5 100644 (file)
@@ -54,7 +54,8 @@ ConsoleMessage::ConsoleMessage(MessageSource s, MessageType t, MessageLevel l, S
     , m_type(t)
     , m_level(l)
 #if ENABLE(INSPECTOR)
-    , m_wrappedArguments(callStack->at(0).argumentCount())
+    , m_arguments(callStack->at(0).argumentCount())
+    , m_scriptState(callStack->state())
 #endif
     , m_frames(storeTrace ? callStack->size() : 0)
     , m_groupLevel(g)
@@ -74,7 +75,7 @@ ConsoleMessage::ConsoleMessage(MessageSource s, MessageType t, MessageLevel l, S
 
 #if ENABLE(INSPECTOR)
     for (unsigned i = 0; i < lastCaller.argumentCount(); ++i)
-        m_wrappedArguments[i] = ScriptObject::quarantineValue(callStack->state(), lastCaller.argumentAt(i));
+        m_arguments[i] = lastCaller.argumentAt(i);
 #endif
 }
 
@@ -89,7 +90,7 @@ void ConsoleMessage::addToConsole(InspectorFrontend* frontend)
     jsonObj.set("url", m_url);
     jsonObj.set("groupLevel", static_cast<int>(m_groupLevel));
     jsonObj.set("repeatCount", static_cast<int>(m_repeatCount));
-    frontend->addConsoleMessage(jsonObj, m_frames, m_wrappedArguments,  m_message);
+    frontend->addConsoleMessage(jsonObj, m_frames, m_scriptState, m_arguments,  m_message);
 }
 
 void ConsoleMessage::updateRepeatCountInConsole(InspectorFrontend* frontend)
@@ -101,15 +102,15 @@ void ConsoleMessage::updateRepeatCountInConsole(InspectorFrontend* frontend)
 bool ConsoleMessage::isEqual(ScriptState* state, ConsoleMessage* msg) const
 {
 #if ENABLE(INSPECTOR)
-    if (msg->m_wrappedArguments.size() != m_wrappedArguments.size())
+    if (msg->m_arguments.size() != m_arguments.size())
         return false;
-    if (!state && msg->m_wrappedArguments.size())
+    if (!state && msg->m_arguments.size())
         return false;
 
-    ASSERT_ARG(state, state || msg->m_wrappedArguments.isEmpty());
+    ASSERT_ARG(state, state || msg->m_arguments.isEmpty());
 
-    for (size_t i = 0; i < msg->m_wrappedArguments.size(); ++i) {
-        if (!m_wrappedArguments[i].isEqual(state, msg->m_wrappedArguments[i]))
+    for (size_t i = 0; i < msg->m_arguments.size(); ++i) {
+        if (!m_arguments[i].isEqual(state, msg->m_arguments[i]))
             return false;
     }
 #else
index 07359bb..e9ae130 100644 (file)
@@ -63,7 +63,8 @@ namespace WebCore {
         MessageLevel m_level;
         String m_message;
 #if ENABLE(INSPECTOR)
-        Vector<ScriptValue> m_wrappedArguments;
+        Vector<ScriptValue> m_arguments;
+        ScriptState* m_scriptState;
 #endif
         Vector<ScriptString> m_frames;
         unsigned m_line;
index ce6f369..d5bbd1c 100644 (file)
@@ -98,20 +98,6 @@ Node* InjectedScriptHost::nodeForId(long nodeId)
     return 0;
 }
 
-ScriptValue InjectedScriptHost::wrapObject(const ScriptValue& object, const String& objectGroup)
-{
-    if (m_inspectorController)
-        return m_inspectorController->wrapObject(object, objectGroup);
-    return ScriptValue();
-}
-
-ScriptValue InjectedScriptHost::unwrapObject(const String& objectId)
-{
-    if (m_inspectorController)
-        return m_inspectorController->unwrapObject(objectId);
-    return ScriptValue();
-}
-
 long InjectedScriptHost::pushNodePathToFrontend(Node* node, bool withChildren, bool selectInUI)
 {
     InspectorFrontend* frontend = inspectorFrontend();
@@ -191,6 +177,19 @@ void InjectedScriptHost::discardInjectedScripts()
     m_idToInjectedScript.clear();
 }
 
+void InjectedScriptHost::releaseWrapperObjectGroup(long injectedScriptId, const String& objectGroup)
+{
+    if (injectedScriptId) {
+         ScriptObject injectedScript = m_idToInjectedScript.get(injectedScriptId);
+         if (!injectedScript.hasNoValue())
+             releaseWrapperObjectGroup(injectedScript, objectGroup);
+    } else {
+         // Iterate over all injected scripts if injectedScriptId is not specified.
+         for (IdToInjectedScriptMap::iterator it = m_idToInjectedScript.begin(); it != m_idToInjectedScript.end(); ++it)
+              releaseWrapperObjectGroup(it->second, objectGroup);
+    }
+}
+
 InspectorDOMAgent* InjectedScriptHost::inspectorDOMAgent()
 {
     if (!m_inspectorController)
@@ -205,6 +204,13 @@ InspectorFrontend* InjectedScriptHost::inspectorFrontend()
     return m_inspectorController->m_frontend.get();
 }
 
+void InjectedScriptHost::releaseWrapperObjectGroup(const ScriptObject& injectedScript, const String& objectGroup)
+{
+    ScriptFunctionCall releaseFunction(injectedScript.scriptState(), injectedScript, "releaseWrapperObjectGroup");
+    releaseFunction.appendArgument(objectGroup);
+    releaseFunction.call();
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(INSPECTOR)
index 654b9f8..d91c8e2 100644 (file)
@@ -66,8 +66,6 @@ public:
 
     void copyText(const String& text);
     Node* nodeForId(long nodeId);
-    ScriptValue wrapObject(const ScriptValue& object, const String& objectGroup);
-    ScriptValue unwrapObject(const String& objectId);
     long pushNodePathToFrontend(Node* node, bool withChildren, bool selectInUI);
 
     void addNodesToSearchResult(const String& nodeIds);
@@ -88,12 +86,15 @@ public:
     ScriptObject injectedScriptFor(ScriptState*);
     ScriptObject injectedScriptForId(long);
     void discardInjectedScripts();
+    void releaseWrapperObjectGroup(long injectedScriptId, const String& objectGroup);
 
 private:
     InjectedScriptHost(InspectorController* inspectorController);
     InspectorDOMAgent* inspectorDOMAgent();
     InspectorFrontend* inspectorFrontend();
 
+    void releaseWrapperObjectGroup(const ScriptObject& injectedScript, const String& objectGroup);
+
     InspectorController* m_inspectorController;
     String m_injectedScriptSource;
     long m_nextInjectedScriptId;
index c3d0092..f9abad7 100644 (file)
 
 module core {
     interface [Conditional=INSPECTOR] InjectedScriptHost {
-        [Custom] DOMWindow inspectedWindow();
-        [Custom] DOMObject wrapCallback(in DOMObject callback);
         void clearConsoleMessages();
 
         void copyText(in DOMString text);
         [Custom] DOMObject nodeForId(in long nodeId);
-        [Custom] long wrapObject(in DOMObject object, in DOMString objectGroup);
-        [Custom] DOMObject unwrapObject(in long objectId);
         [Custom] int pushNodePathToFrontend(in DOMObject node, in boolean withChildren, in boolean selectInUI);
 
         void addNodesToSearchResult(in DOMString nodeIds);
index 025ca87..a508479 100644 (file)
@@ -40,6 +40,7 @@
 #include "Frame.h"
 #include "FrameLoader.h"
 #include "HTMLFrameOwnerElement.h"
+#include "InjectedScriptHost.h"
 #include "InspectorClient.h"
 #include "InspectorController.h"
 #include "InspectorDOMAgent.h"
@@ -256,13 +257,31 @@ JavaScriptCallFrame* InspectorBackend::currentCallFrame() const
 }
 #endif
 
-void InspectorBackend::dispatchOnInjectedScript(long callId, const String& methodName, const String& arguments, bool async)
+void InspectorBackend::setInjectedScriptSource(const String& source)
+{
+    if (m_inspectorController)
+        m_inspectorController->injectedScriptHost()->setInjectedScriptSource(source);
+}
+
+void InspectorBackend::dispatchOnInjectedScript(long callId, long injectedScriptId, const String& methodName, const String& arguments, bool async)
 {
     InspectorFrontend* frontend = inspectorFrontend();
     if (!frontend)
         return;
 
-    ScriptFunctionCall function(m_inspectorController->m_scriptState, m_inspectorController->m_injectedScriptObj, "dispatch");
+    // FIXME: explicitly pass injectedScriptId along with node id to the frontend.
+    bool injectedScriptIdIsNodeId = injectedScriptId <= 0;
+
+    ScriptObject injectedScript;
+    if (injectedScriptIdIsNodeId)
+        injectedScript = m_inspectorController->injectedScriptForNodeId(-injectedScriptId);
+    else
+        injectedScript = m_inspectorController->injectedScriptHost()->injectedScriptForId(injectedScriptId);
+
+    if (injectedScript.hasNoValue())
+        return;
+
+    ScriptFunctionCall function(injectedScript.scriptState(), injectedScript, "dispatch");
     function.appendArgument(methodName);
     function.appendArgument(arguments);
     if (async)
@@ -274,7 +293,7 @@ void InspectorBackend::dispatchOnInjectedScript(long callId, const String& metho
     if (hadException)
         frontend->didDispatchOnInjectedScript(callId, "", true);
     else
-        frontend->didDispatchOnInjectedScript(callId, result.toString(m_inspectorController->m_scriptState), false);
+        frontend->didDispatchOnInjectedScript(callId, result.toString(injectedScript.scriptState()), false);
 }
 
 void InspectorBackend::getChildNodes(long callId, long nodeId)
@@ -371,10 +390,11 @@ void InspectorBackend::deleteCookie(const String& cookieName, const String& doma
     m_inspectorController->deleteCookie(cookieName, domain);
 }
 
-void InspectorBackend::releaseWrapperObjectGroup(const String& objectGroup)
+void InspectorBackend::releaseWrapperObjectGroup(long injectedScriptId, const String& objectGroup)
 {
-    if (m_inspectorController)
-        m_inspectorController->releaseWrapperObjectGroup(objectGroup);
+    if (!m_inspectorController)
+        return;
+    m_inspectorController->injectedScriptHost()->releaseWrapperObjectGroup(injectedScriptId, objectGroup);
 }
 
 void InspectorBackend::didEvaluateForTestInFrontend(long callId, const String& jsonResult)
index 05b5799..f46dcdd 100644 (file)
@@ -104,7 +104,8 @@ public:
     JavaScriptCallFrame* currentCallFrame() const;
 #endif
 
-    void dispatchOnInjectedScript(long callId, const String& methodName, const String& arguments, bool async);
+    void setInjectedScriptSource(const String& source);
+    void dispatchOnInjectedScript(long callId, long injectedScriptId, const String& methodName, const String& arguments, bool async);
     void getChildNodes(long callId, long nodeId);
     void setAttribute(long callId, long elementId, const String& name, const String& value);
     void removeAttribute(long callId, long elementId, const String& name);
@@ -119,7 +120,7 @@ public:
     void deleteCookie(const String& cookieName, const String& domain);
 
     // Generic code called from custom implementations.
-    void releaseWrapperObjectGroup(const String& objectGroup);
+    void releaseWrapperObjectGroup(long injectedScriptId, const String& objectGroup);
     void didEvaluateForTestInFrontend(long callId, const String& jsonResult);
 
 #if ENABLE(DATABASE)
index 351d244..d70c5cb 100644 (file)
@@ -75,7 +75,8 @@ module core {
         void getProfileHeaders(in long callId);
         void getProfile(in long callId, in unsigned long uid);
 #endif
-        void dispatchOnInjectedScript(in long callId, in DOMString methodName, in DOMString arguments, in boolean async);
+        void setInjectedScriptSource(in DOMString scriptSource);
+        void dispatchOnInjectedScript(in long callId, in long injectedScriptId, in DOMString methodName, in DOMString arguments, in boolean async);
         void getChildNodes(in long callId, in long nodeId);
         void setAttribute(in long callId, in long elementId, in DOMString name, in DOMString value);
         void removeAttribute(in long callId, in long elementId, in DOMString name);
@@ -89,7 +90,7 @@ module core {
         void getCookies(in long callId);
         void deleteCookie(in DOMString cookieName, in DOMString domain);
 
-        void releaseWrapperObjectGroup(in DOMString objectGroup);
+        void releaseWrapperObjectGroup(in long injectedScriptId, in DOMString objectGroup);
         void didEvaluateForTestInFrontend(in long callId, in DOMString jsonResult);
 
 #if defined(ENABLE_DATABASE) && ENABLE_DATABASE
index c84a415..cde0f5a 100644 (file)
@@ -143,7 +143,6 @@ InspectorController::InspectorController(Page* page, InspectorClient* client)
     , m_inspectorBackend(InspectorBackend::create(this))
     , m_inspectorFrontendHost(InspectorFrontendHost::create(this, client))
     , m_injectedScriptHost(InjectedScriptHost::create(this))
-    , m_lastBoundObjectId(1)
 #if ENABLE(JAVASCRIPT_DEBUGGER)
     , m_debuggerEnabled(false)
     , m_attachDebuggerWhenShown(false)
@@ -375,7 +374,7 @@ void InspectorController::clearConsoleMessages()
     m_expiredConsoleMessageCount = 0;
     m_previousMessage = 0;
     m_groupLevel = 0;
-    releaseWrapperObjectGroup("console");
+    m_injectedScriptHost->releaseWrapperObjectGroup(0 /* release the group in all scripts */, "console");
     if (m_domAgent)
         m_domAgent->releaseDanglingNodes();
     if (m_frontend)
@@ -500,7 +499,7 @@ void InspectorController::inspectedWindowScriptObjectCleared(Frame* frame)
 {
     if (!enabled() || !m_frontend || frame != m_inspectedPage->mainFrame())
         return;
-    resetInjectedScript();
+    m_injectedScriptHost->discardInjectedScripts();
 }
 
 void InspectorController::windowScriptObjectAvailable()
@@ -513,7 +512,6 @@ void InspectorController::windowScriptObjectAvailable()
     m_scriptState = scriptStateFromPage(debuggerWorld(), m_page);
     ScriptGlobalObject::set(m_scriptState, "InspectorBackend", m_inspectorBackend.get());
     ScriptGlobalObject::set(m_scriptState, "InspectorFrontendHost", m_inspectorFrontendHost.get());
-    ScriptGlobalObject::set(m_scriptState, "InjectedScriptHost", m_injectedScriptHost.get());
 }
 
 void InspectorController::scriptObjectReady()
@@ -526,8 +524,6 @@ void InspectorController::scriptObjectReady()
     if (!ScriptGlobalObject::get(m_scriptState, "WebInspector", webInspectorObj))
         return;
     ScriptObject injectedScriptObj;
-    if (!ScriptGlobalObject::get(m_scriptState, "InjectedScript", injectedScriptObj))
-        return;
     setFrontendProxyObject(m_scriptState, webInspectorObj, injectedScriptObj);
 
 #if ENABLE(JAVASCRIPT_DEBUGGER)
@@ -545,10 +541,9 @@ void InspectorController::scriptObjectReady()
     m_client->inspectorWindowObjectCleared();
 }
 
-void InspectorController::setFrontendProxyObject(ScriptState* scriptState, ScriptObject webInspectorObj, ScriptObject injectedScriptObj)
+void InspectorController::setFrontendProxyObject(ScriptState* scriptState, ScriptObject webInspectorObj, ScriptObject)
 {
     m_scriptState = scriptState;
-    m_injectedScriptObj = injectedScriptObj;
     m_frontend.set(new InspectorFrontend(this, scriptState, webInspectorObj));
     releaseDOMAgent();
     m_domAgent = InspectorDOMAgent::create(m_frontend.get());
@@ -606,7 +601,6 @@ void InspectorController::close()
 #endif
     closeWindow();
 
-    m_injectedScriptObj = ScriptObject();
     releaseDOMAgent();
     m_frontend.set(0);
     m_timelineAgent = 0;
@@ -715,8 +709,6 @@ void InspectorController::resetScriptObjects()
 
     m_frontend->reset();
     m_domAgent->reset();
-    m_objectGroups.clear();
-    m_idToWrappedObject.clear();
 }
 
 void InspectorController::pruneResources(ResourcesMap* resourceMap, DocumentLoader* loaderToKeep)
@@ -1591,8 +1583,14 @@ void InspectorController::failedToParseSource(ExecState*, const SourceCode& sour
 
 void InspectorController::didPause()
 {
-    ScriptFunctionCall function(m_scriptState, m_injectedScriptObj, "getCallFrames");
-    ScriptValue callFrames = function.call();
+    JavaScriptCallFrame* callFrame = m_injectedScriptHost->currentCallFrame();
+    ScriptState* scriptState = callFrame->scopeChain()->globalObject->globalExec();
+    ASSERT(scriptState);
+    ScriptObject injectedScriptObj = m_injectedScriptHost->injectedScriptFor(scriptState);
+    ScriptFunctionCall function(scriptState, injectedScriptObj, "getCallFrames");
+    ScriptValue callFramesValue = function.call();
+    String callFrames = callFramesValue.toString(scriptState);
+
     m_frontend->pausedScript(callFrames);
 }
 
@@ -1820,50 +1818,6 @@ InspectorController::SpecialPanels InspectorController::specialPanelForJSName(co
         return ElementsPanel;
 }
 
-ScriptValue InspectorController::wrapObject(const ScriptValue& quarantinedObject, const String& objectGroup)
-{
-    ScriptFunctionCall function(m_scriptState, m_injectedScriptObj, "createProxyObject");
-    function.appendArgument(quarantinedObject);
-    if (quarantinedObject.isObject()) {
-        long id = m_lastBoundObjectId++;
-        String objectId = String::format("object#%ld", id);
-        m_idToWrappedObject.set(objectId, quarantinedObject);
-        ObjectGroupsMap::iterator it = m_objectGroups.find(objectGroup);
-        if (it == m_objectGroups.end())
-            it = m_objectGroups.set(objectGroup, Vector<String>()).first;
-        it->second.append(objectId);
-        function.appendArgument(objectId);
-    }
-    ScriptValue wrapper = function.call();
-    return wrapper;
-}
-
-ScriptValue InspectorController::unwrapObject(const String& objectId)
-{
-    HashMap<String, ScriptValue>::iterator it = m_idToWrappedObject.find(objectId);
-    if (it != m_idToWrappedObject.end())
-        return it->second;
-    return ScriptValue();
-}
-
-void InspectorController::releaseWrapperObjectGroup(const String& objectGroup)
-{
-    ObjectGroupsMap::iterator groupIt = m_objectGroups.find(objectGroup);
-    if (groupIt == m_objectGroups.end())
-        return;
-
-    Vector<String>& groupIds = groupIt->second;
-    for (Vector<String>::iterator it = groupIds.begin(); it != groupIds.end(); ++it)
-        m_idToWrappedObject.remove(*it);
-    m_objectGroups.remove(groupIt);
-}
-
-void InspectorController::resetInjectedScript()
-{
-    ScriptFunctionCall function(m_scriptState, m_injectedScriptObj, "reset");
-    function.call();
-}
-
 void InspectorController::deleteCookie(const String& cookieName, const String& domain)
 {
     ResourcesMap::iterator resourcesEnd = m_resources.end();
@@ -1874,6 +1828,27 @@ void InspectorController::deleteCookie(const String& cookieName, const String& d
     }
 }
 
-}  // namespace WebCore
+ScriptObject 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(frame->script()->mainWorldScriptState());
+
+    return ScriptObject();
+}
+
+} // namespace WebCore
     
 #endif // ENABLE(INSPECTOR)
index 85e40df..860bf49 100644 (file)
@@ -100,7 +100,6 @@ public:
     typedef HashMap<RefPtr<Frame>, ResourcesMap*> FrameResourcesMap;
     typedef HashMap<int, RefPtr<InspectorDatabaseResource> > DatabaseResourcesMap;
     typedef HashMap<int, RefPtr<InspectorDOMStorageResource> > DOMStorageResourcesMap;
-    typedef HashMap<String, Vector<String> > ObjectGroupsMap;
 
     typedef enum {
         CurrentPanel,
@@ -249,6 +248,8 @@ public:
 
     void evaluateForTestInFrontend(long callId, const String& script);
 
+    ScriptObject injectedScriptForNodeId(long id);
+
 private:
     static const char* const FrontendSettingsSettingName;
     friend class InspectorBackend;
@@ -264,16 +265,6 @@ private:
     InspectorDOMAgent* domAgent() { return m_domAgent.get(); }
     void releaseDOMAgent();
 
-    friend class InspectorFrontend;
-    // Following are used from InspectorFrontend only. We don't want to expose them to the
-    // rest of the InspectorController clients.
-    // TODO: extract these into a separate interface.
-    ScriptValue wrapObject(const ScriptValue& object, const String& objectGroup);
-    ScriptValue unwrapObject(const String& objectId);
-    void releaseWrapperObjectGroup(const String& objectGroup);
-    
-    void resetInjectedScript();
-
     void deleteCookie(const String& cookieName, const String& domain);
 
 #if ENABLE(JAVASCRIPT_DEBUGGER)
@@ -321,7 +312,6 @@ private:
     OwnPtr<InspectorFrontend> m_frontend;
     RefPtr<InspectorDOMAgent> m_domAgent;
     OwnPtr<InspectorTimelineAgent> m_timelineAgent;
-    ScriptObject m_injectedScriptObj;
     Page* m_page;
     RefPtr<Node> m_nodeToFocus;
     RefPtr<InspectorResource> m_mainResource;
@@ -350,9 +340,6 @@ private:
     RefPtr<InspectorBackend> m_inspectorBackend;
     RefPtr<InspectorFrontendHost> m_inspectorFrontendHost;
     RefPtr<InjectedScriptHost> m_injectedScriptHost;
-    HashMap<String, ScriptValue> m_idToWrappedObject;
-    ObjectGroupsMap m_objectGroups;
-    long m_lastBoundObjectId;
 
     typedef HashMap<String, String> Settings;
     mutable Settings m_settings;
index 4da69f4..070f58e 100644 (file)
@@ -34,6 +34,7 @@
 
 #include "ConsoleMessage.h"
 #include "Frame.h"
+#include "InjectedScriptHost.h"
 #include "InspectorController.h"
 #include "Node.h"
 #include "ScriptFunctionCall.h"
@@ -93,19 +94,32 @@ void InspectorFrontend::updateConsoleMessageExpiredCount(unsigned count)
     function.call();
 }
 
-void InspectorFrontend::addConsoleMessage(const ScriptObject& messageObj, const Vector<ScriptString>& frames, const Vector<ScriptValue> wrappedArguments, const String& message)
+void InspectorFrontend::addConsoleMessage(const ScriptObject& messageObj, const Vector<ScriptString>& frames, ScriptState* scriptState, const Vector<ScriptValue> arguments, const String& message)
 {
     ScriptFunctionCall function(m_scriptState, m_webInspector, "dispatch"); 
     function.appendArgument("addConsoleMessage");
     function.appendArgument(messageObj);
     if (!frames.isEmpty()) {
+        function.appendArgument(false);
         for (unsigned i = 0; i < frames.size(); ++i)
             function.appendArgument(frames[i]);
-    } else if (!wrappedArguments.isEmpty()) {
-        for (unsigned i = 0; i < wrappedArguments.size(); ++i)
-            function.appendArgument(m_inspectorController->wrapObject(wrappedArguments[i], "console"));
-    } else
+    } else if (!arguments.isEmpty()) {
+        function.appendArgument(true);
+        ScriptObject injectedScript = m_inspectorController->injectedScriptHost()->injectedScriptFor(scriptState);
+        for (unsigned i = 0; i < arguments.size(); ++i) {
+            ScriptFunctionCall wrapFunction(scriptState, injectedScript, "wrapAndStringifyObject");
+            wrapFunction.appendArgument(arguments[i]);
+            wrapFunction.appendArgument("console");
+            ScriptValue r = wrapFunction.call();
+            if (r.hasNoValue())
+                return;
+            String s = r.toString(scriptState);
+            function.appendArgument(s);
+        }
+    } else {
+        function.appendArgument(false);
         function.appendArgument(message);
+    }
     function.call();
 }
 
@@ -312,7 +326,7 @@ void InspectorFrontend::didGetProfile(int callId, const ScriptValue& profile)
     function.call();
 }
 
-void InspectorFrontend::pausedScript(const ScriptValue& callFrames)
+void InspectorFrontend::pausedScript(const String& callFrames)
 {
     ScriptFunctionCall function(m_scriptState, m_webInspector, "dispatch"); 
     function.appendArgument("pausedScript");
index c1c4db5..c126d9b 100644 (file)
@@ -67,7 +67,7 @@ namespace WebCore {
         void populateFrontendSettings(const String& settings);
 
         void updateConsoleMessageExpiredCount(unsigned count);
-        void addConsoleMessage(const ScriptObject& messageObj, const Vector<ScriptString>& frames, const Vector<ScriptValue> wrappedArguments, const String& message);
+        void addConsoleMessage(const ScriptObject& messageObj, const Vector<ScriptString>& frames, ScriptState*, const Vector<ScriptValue> arguments, const String& message);
         void updateConsoleMessageRepeatCount(unsigned count);
         void clearConsoleMessages();
 
@@ -95,7 +95,7 @@ namespace WebCore {
         void setRecordingProfile(bool isProfiling);
         void didGetProfileHeaders(int callId, const ScriptArray& headers);
         void didGetProfile(int callId, const ScriptValue& profile);
-        void pausedScript(const ScriptValue& callFrames);
+        void pausedScript(const String& callFrames);
         void resumedScript();
 #endif
 
index c4d7aef..696d132 100644 (file)
@@ -193,7 +193,7 @@ WebInspector.AuditsPanel.prototype = {
             InspectorBackend.enableResourceTracking(false);
             this._updateLauncherViewControls();
         } else
-            InjectedScriptAccess.evaluate("window.location.reload()", nullCallback);
+            InjectedScriptAccess.getDefault().evaluate("window.location.reload()", nullCallback);
     },
 
     _didMainResourceLoad: function()
index ee56812..0c594c9 100644 (file)
@@ -292,7 +292,7 @@ WebInspector.ConsoleView.prototype = {
 
     requestClearMessages: function()
     {
-        InjectedScriptAccess.clearConsoleMessages(function() {});
+        InjectedScriptAccess.getDefault().clearConsoleMessages(function() {});
     },
 
     clearMessages: function()
@@ -334,9 +334,14 @@ WebInspector.ConsoleView.prototype = {
         // Collect comma separated object properties for the completion.
 
         var includeInspectorCommandLineAPI = (!dotNotation && !bracketNotation);
-        if (WebInspector.panels.scripts && WebInspector.panels.scripts.paused)
-            var callFrameId = WebInspector.panels.scripts.selectedCallFrameId();
-        InjectedScriptAccess.getCompletions(expressionString, includeInspectorCommandLineAPI, callFrameId, reportCompletions);
+        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.injectedScriptId);
+        } else
+            injectedScriptAccess = InjectedScriptAccess.getDefault();
+        injectedScriptAccess.getCompletions(expressionString, includeInspectorCommandLineAPI, callFrameId, reportCompletions);
     },
 
     _reportCompletions: function(bestMatchOnly, completionsReadyCallback, dotNotation, bracketNotation, prefix, result, isException) {
@@ -460,7 +465,7 @@ WebInspector.ConsoleView.prototype = {
         {
             callback(result.value, result.isException);
         };
-        InjectedScriptAccess.evaluate(expression, objectGroup, evalCallback);
+        InjectedScriptAccess.getDefault().evaluate(expression, objectGroup, evalCallback);
     },
 
     _enterKeyPressed: function(event)
@@ -533,12 +538,12 @@ WebInspector.ConsoleView.prototype = {
             elem.appendChild(treeOutline.element);
         }
 
-        InjectedScriptAccess.pushNodeToFrontend(object, printNode);
+        InjectedScriptAccess.get(object.injectedScriptId).pushNodeToFrontend(object, printNode);
     },
 
     _formatarray: function(arr, elem)
     {
-        InjectedScriptAccess.getProperties(arr, false, false, this._printArray.bind(this, elem));
+        InjectedScriptAccess.get(arr.injectedScriptId).getProperties(arr, false, false, this._printArray.bind(this, elem));
     },
 
     _formatstring: function(output, elem)
index c072d8a..6889408 100644 (file)
@@ -33,6 +33,10 @@ WebInspector.DOMNode = function(doc, payload) {
     this.ownerDocument = doc;
 
     this.id = payload.id;
+    // injectedScriptId is a node is for DOM nodes which should be converted
+    // to corresponding InjectedScript by the inspector backend. We indicate
+    // this by making injectedScriptId negative.
+    this.injectedScriptId = -payload.id;
     this.nodeType = payload.nodeType;
     this.nodeName = payload.nodeName;
     this.localName = payload.localName;
@@ -516,6 +520,7 @@ WebInspector.EventListeners.getEventListenersForNodeAsync = function(node, callb
 WebInspector.CSSStyleDeclaration = function(payload)
 {
     this.id = payload.id;
+    this.injectedScriptId = payload.injectedScriptId;
     this.width = payload.width;
     this.height = payload.height;
     this.__disabledProperties = payload.__disabledProperties;
@@ -558,6 +563,7 @@ WebInspector.CSSStyleDeclaration.parseRule = function(payload)
 {
     var rule = {};
     rule.id = payload.id;
+    rule.injectedScriptId = payload.injectedScriptId;
     rule.selectorText = payload.selectorText;
     rule.style = new WebInspector.CSSStyleDeclaration(payload.style);
     rule.style.parentRule = rule;
index 5edefb1..a0dc9ca 100644 (file)
@@ -95,7 +95,8 @@ WebInspector.Database.prototype = {
             }
             onSuccess(result);
         }
-        InjectedScriptAccess.executeSql(this._id, query, callback);
+        // FIXME: execute the query in the frame the DB comes from.
+        InjectedScriptAccess.getDefault().executeSql(this._id, query, callback);
     }
 }
 
index 1e64df0..e839a60 100644 (file)
@@ -63,7 +63,7 @@ WebInspector.ElementsPanel = function()
             this.panel.nodeSearchButton.toggled = false;
         }
         if (this._focusedDOMNode)
-            InjectedScriptAccess.addInspectedNode(this._focusedDOMNode.id, function() {});
+            InjectedScriptAccess.get(this._focusedDOMNode.injectedScriptId).addInspectedNode(this._focusedDOMNode.id, function() {});
     };
 
     this.contentElement.appendChild(this.treeOutline.element);
@@ -237,7 +237,7 @@ WebInspector.ElementsPanel.prototype = {
         }
 
         if (this._selectedPathOnReset)
-            InjectedScriptAccess.nodeByPath(this._selectedPathOnReset, selectLastSelectedNode.bind(this));
+            InjectedScriptAccess.getDefault().nodeByPath(this._selectedPathOnReset, selectLastSelectedNode.bind(this));
         else
             selectNode.call(this);
         delete this._selectedPathOnReset;
@@ -257,7 +257,7 @@ WebInspector.ElementsPanel.prototype = {
 
         this._currentSearchResultIndex = 0;
         this._searchResults = [];
-        InjectedScriptAccess.searchCanceled(function() {});
+        InjectedScriptAccess.getDefault().searchCanceled(function() {});
     },
 
     performSearch: function(query)
@@ -272,7 +272,7 @@ WebInspector.ElementsPanel.prototype = {
         this._updatedMatchCountOnce = false;
         this._matchesCountUpdateTimeout = null;
 
-        InjectedScriptAccess.performSearch(whitespaceTrimmedQuery, function() {});
+        InjectedScriptAccess.getDefault().performSearch(whitespaceTrimmedQuery, function() {});
     },
 
     _updateMatchesCount: function()
index dfed7ff..87fb8ce 100644 (file)
@@ -357,7 +357,7 @@ WebInspector.ElementsTreeElement.prototype = {
                 tooltipText = WebInspector.UIString("%d × %d pixels (Natural: %d × %d pixels)", properties.offsetWidth, properties.offsetHeight, properties.naturalWidth, properties.naturalHeight);
             callback(tooltipText);
         }
-        var objectProxy = new WebInspector.ObjectProxy(node.id);
+        var objectProxy = new WebInspector.ObjectProxy(node.injectedScriptId, node.id);
         WebInspector.ObjectProxy.getPropertiesAsync(objectProxy, ["naturalHeight", "naturalWidth", "offsetHeight", "offsetWidth"], createTooltipThenCallback);
     },
 
@@ -1075,10 +1075,10 @@ WebInspector.ElementsTreeElement.prototype = {
 
         function commitChange(value)
         {
-            InjectedScriptAccess.setOuterHTML(node.id, value, wasExpanded, selectNode.bind(this));
+            InjectedScriptAccess.get(node.injectedScriptId).setOuterHTML(node.id, value, wasExpanded, selectNode.bind(this));
         }
 
-        InjectedScriptAccess.getNodePropertyValue(node.id, "outerHTML", this._startEditingAsHTML.bind(this, commitChange));
+        InjectedScriptAccess.get(node.injectedScriptId).getNodePropertyValue(node.id, "outerHTML", this._startEditingAsHTML.bind(this, commitChange));
     },
 
     _copyHTML: function()
index 38e7fc2..649eea8 100644 (file)
@@ -191,7 +191,7 @@ WebInspector.EventListenerBar.prototype = {
             // Just build properties in place - no need to reach out for injected script.
             var value = this.eventListener[propertyName];
             if (value instanceof WebInspector.DOMNode)
-                value = new WebInspector.ObjectProxy(value.id, [], 0, appropriateSelectorForNode(value), true);
+                value = new WebInspector.ObjectProxy(value.injectedScriptId, value.id, [], 0, appropriateSelectorForNode(value), true);
             else
                 value = WebInspector.ObjectProxy.wrapPrimitiveValue(value);
             properties.push(new WebInspector.ObjectPropertyProxy(propertyName, value));
index f8150fa..f7d127b 100644 (file)
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+var injectedScriptConstructor = (function (InjectedScriptHost, inspectedWindow, injectedScriptId) {
+
 var InjectedScript = {};
 
+InjectedScript.lastBoundObjectId = 1;
+InjectedScript.idToWrappedObject = {};
+InjectedScript.objectGroups = {};
+InjectedScript.wrapObject = function(object, objectGroupName)
+{
+    var objectId;
+    if (typeof object === "object" || typeof object === "function" ||
+        (typeof object === "undefined" && object instanceof inspectedWindow.HTMLAllCollection)) { // FIXME(33716)
+        var id = InjectedScript.lastBoundObjectId++;
+        objectId = "object#" + id;
+        InjectedScript.idToWrappedObject[objectId] = object;
+
+        var group = InjectedScript.objectGroups[objectGroupName];
+        if (!group) {
+            group = [];
+            InjectedScript.objectGroups[objectGroupName] = group;
+        }
+        group.push(objectId);
+    }
+    return InjectedScript.createProxyObject(object, objectId);
+};
+
+InjectedScript.wrapAndStringifyObject = function(object, objectGroupName) {
+    var r = InjectedScript.wrapObject(object, objectGroupName);
+    return InjectedScript.JSON.stringify(r);
+};
+
+InjectedScript.unwrapObject = function(objectId) {
+    return InjectedScript.idToWrappedObject[objectId];
+};
+
+InjectedScript.releaseWrapperObjectGroup = function(objectGroupName) {
+    delete InjectedScript.objectGroups[objectGroupName];
+};
+
 // Called from within InspectorController on the 'inspected page' side.
 InjectedScript.reset = function()
 {
@@ -51,7 +88,7 @@ InjectedScript.dispatch = function(methodName, args, callId)
         InjectedScript._window().console.error("Web Inspector error: InjectedScript.%s returns undefined", methodName);
         result = null;
     }
-    return JSON.stringify(result);
+    return InjectedScript.JSON.stringify(result);
 }
 
 InjectedScript.getStyles = function(nodeId, authorOnly)
@@ -169,10 +206,9 @@ InjectedScript.toggleStyleEnabled = function(styleId, propertyName, disabled)
 
     if (disabled) {
         if (!style.__disabledPropertyValues || !style.__disabledPropertyPriorities) {
-            var inspectedWindow = InjectedScript._window();
-            style.__disabledProperties = new inspectedWindow.Object;
-            style.__disabledPropertyValues = new inspectedWindow.Object;
-            style.__disabledPropertyPriorities = new inspectedWindow.Object;
+            style.__disabledProperties = {};
+            style.__disabledPropertyValues = {};
+            style.__disabledPropertyPriorities = {};
         }
 
         style.__disabledPropertyValues[propertyName] = style.getPropertyValue(propertyName);
@@ -306,6 +342,7 @@ InjectedScript._serializeRule = function(rule)
             InjectedScript._styleRules[rule.id] = rule;
         }
         ruleValue.id = rule.id;
+        ruleValue.injectedScriptId = injectedScriptId;
     }
     return ruleValue;
 }
@@ -344,6 +381,7 @@ InjectedScript._serializeStyle = function(style, doBind)
             InjectedScript._styles[style.id] = style;
         }
         result.id = style.id;
+        result.injectedScriptId = injectedScriptId;
     }
     return result;
 }
@@ -445,7 +483,7 @@ InjectedScript.getPrototypes = function(nodeId)
 InjectedScript.getProperties = function(objectProxy, ignoreHasOwnProperty, abbreviate)
 {
     var object = InjectedScript._resolveObject(objectProxy);
-    if (!object)
+    if (!InjectedScript._isDefined(object))
         return false;
 
     var properties = [];
@@ -479,7 +517,7 @@ InjectedScript.getProperties = function(objectProxy, ignoreHasOwnProperty, abbre
 InjectedScript.setPropertyValue = function(objectProxy, propertyName, expression)
 {
     var object = InjectedScript._resolveObject(objectProxy);
-    if (!object)
+    if (!InjectedScript._isDefined(object))
         return false;
 
     var expressionLength = expression.length;
@@ -588,7 +626,8 @@ InjectedScript._evaluateAndWrap = function(evalFunction, object, expression, obj
 {
     var result = {};
     try {
-        result.value = InjectedScriptHost.wrapObject(InjectedScript._evaluateOn(evalFunction, object, expression), objectGroup);
+        result.value = InjectedScript.wrapObject(InjectedScript._evaluateOn(evalFunction, object, expression), objectGroup);
+
         // Handle error that might have happened while describing result.
         if (result.value.errorText) {
             result.value = result.value.errorText;
@@ -885,7 +924,7 @@ InjectedScript.getCallFrames = function()
         result.push(new InjectedScript.CallFrameProxy(depth++, callFrame));
         callFrame = callFrame.caller;
     } while (callFrame);
-    return result;
+    return InjectedScript.JSON.stringify(result);
 }
 
 InjectedScript.evaluateInCallFrame = function(callFrameId, code, objectGroup)
@@ -915,7 +954,6 @@ InjectedScript._inspectObject = function(o)
     if (arguments.length === 0)
         return;
 
-    var inspectedWindow = InjectedScript._window();
     inspectedWindow.console.log(o);
     if (Object.type(o) === "node") {
         InjectedScriptHost.pushNodePathToFrontend(o, false, true);
@@ -1014,9 +1052,9 @@ InjectedScript._ensureCommandLineAPIInstalled = function(evalFunction, evalObjec
         get $4() { return console._inspectorCommandLineAPI._inspectedNodes[4] }, \n\
     };");
 
-    inspectorCommandLineAPI.clear = InjectedScriptHost.wrapCallback(InjectedScript.clearConsoleMessages);
-    inspectorCommandLineAPI.inspect = InjectedScriptHost.wrapCallback(InjectedScript._inspectObject);
-    inspectorCommandLineAPI.copy = InjectedScriptHost.wrapCallback(InjectedScript._copy);
+    inspectorCommandLineAPI.clear = InjectedScript.clearConsoleMessages;
+    inspectorCommandLineAPI.inspect = InjectedScript._inspectObject;
+    inspectorCommandLineAPI.copy = InjectedScript._copy;
 }
 
 InjectedScript._resolveObject = function(objectProxy)
@@ -1026,11 +1064,11 @@ InjectedScript._resolveObject = function(objectProxy)
     var protoDepth = objectProxy.protoDepth;
 
     // Follow the property path.
-    for (var i = 0; object && path && i < path.length; ++i)
+    for (var i = 0; InjectedScript._isDefined(object) && path && i < path.length; ++i)
         object = object[path[i]];
 
     // Get to the necessary proto layer.
-    for (var i = 0; object && protoDepth && i < protoDepth; ++i)
+    for (var i = 0; InjectedScript._isDefined(object) && protoDepth && i < protoDepth; ++i)
         object = object.__proto__;
 
     return object;
@@ -1040,7 +1078,7 @@ InjectedScript._window = function()
 {
     // TODO: replace with 'return window;' once this script is injected into
     // the page's context.
-    return InjectedScriptHost.inspectedWindow();
+    return inspectedWindow;
 }
 
 InjectedScript._nodeForId = function(nodeId)
@@ -1059,7 +1097,7 @@ InjectedScript._objectForId = function(objectId)
     if (typeof objectId === "number") {
         return InjectedScript._nodeForId(objectId);
     } else if (typeof objectId === "string") {
-        return InjectedScriptHost.unwrapObject(objectId);
+        return InjectedScript.unwrapObject(objectId);
     } else if (typeof objectId === "object") {
         var callFrame = InjectedScript._callFrameForId(objectId.callFrame);
         if (objectId.thisObject)
@@ -1089,6 +1127,7 @@ InjectedScript.nodeByPath = function(path)
 InjectedScript.createProxyObject = function(object, objectId, abbreviate)
 {
     var result = {};
+    result.injectedScriptId = injectedScriptId;
     result.objectId = objectId;
     result.type = Object.type(object);
 
@@ -1170,31 +1209,40 @@ InjectedScript.executeSql = function(callId, databaseId, query)
                 data[columnIdentifier] = String(text);
             }
         }
-        InjectedScriptHost.reportDidDispatchOnInjectedScript(callId, JSON.stringify(result), false);
+        InjectedScriptHost.reportDidDispatchOnInjectedScript(callId, InjectedScript.JSON.stringify(result), false);
     }
 
     function errorCallback(tx, error)
     {
-        InjectedScriptHost.reportDidDispatchOnInjectedScript(callId, JSON.stringify(error), false);
+        InjectedScriptHost.reportDidDispatchOnInjectedScript(callId, InjectedScript.JSON.stringify(error), false);
     }
 
     function queryTransaction(tx)
     {
-        tx.executeSql(query, null, InjectedScriptHost.wrapCallback(successCallback), InjectedScriptHost.wrapCallback(errorCallback));
+        tx.executeSql(query, null, successCallback, errorCallback);
     }
 
     var database = InjectedScriptHost.databaseForId(databaseId);
     if (!database)
         errorCallback(null, { code : 2 });  // Return as unexpected version.
-    database.transaction(InjectedScriptHost.wrapCallback(queryTransaction), InjectedScriptHost.wrapCallback(errorCallback));
+    database.transaction(queryTransaction, errorCallback);
     return true;
 }
 
+InjectedScript._isDefined = function(object)
+{
+    return object || object instanceof inspectedWindow.HTMLAllCollection;
+}
+
 Object.type = function(obj)
 {
     if (obj === null)
         return "null";
 
+    // FIXME(33716): typeof document.all is always 'undefined'.
+    if (obj instanceof inspectedWindow.HTMLAllCollection)
+        return "array";
+
     var type = typeof obj;
     if (type !== "object" && type !== "function")
         return type;
@@ -1298,3 +1346,297 @@ String.prototype.escapeCharacters = function(chars)
 
     return result;
 }
+
+InjectedScript.JSON = {};
+
+// The following code is a slightly modified version of http://www.json.org/json2.js last modified on 2009-09-29.
+// Compared to the original version it ignores toJSON method on objects it serializes.
+// It's done to avoid weird behaviour when inspected application provides it's own implementation
+// of toJSON methods to the Object and other intrinsic types. We use InjectedScript.JSON implementation
+// instead of global JSON object since it can have been modified by the inspected code.
+(function() {
+
+    function f(n) {
+        // Format integers to have at least two digits.
+        return n < 10 ? '0' + n : n;
+    }
+
+    var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
+        escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
+        gap,
+        indent,
+        meta = {    // table of character substitutions
+            '\b': '\\b',
+            '\t': '\\t',
+            '\n': '\\n',
+            '\f': '\\f',
+            '\r': '\\r',
+            '"' : '\\"',
+            '\\': '\\\\'
+        },
+        rep;
+
+
+    function quote(string) {
+
+// If the string contains no control characters, no quote characters, and no
+// backslash characters, then we can safely slap some quotes around it.
+// Otherwise we must also replace the offending characters with safe escape
+// sequences.
+
+        escapable.lastIndex = 0;
+        return escapable.test(string) ?
+            '"' + string.replace(escapable, function (a) {
+                var c = meta[a];
+                return typeof c === 'string' ? c :
+                    '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
+            }) + '"' :
+            '"' + string + '"';
+    }
+
+
+    function str(key, holder) {
+
+// Produce a string from holder[key].
+
+        var i,          // The loop counter.
+            k,          // The member key.
+            v,          // The member value.
+            length,
+            mind = gap,
+            partial,
+            value = holder[key];
+
+// If we were called with a replacer function, then call the replacer to
+// obtain a replacement value.
+
+        if (typeof rep === 'function') {
+            value = rep.call(holder, key, value);
+        }
+
+// What happens next depends on the value's type.
+
+        switch (typeof value) {
+        case 'string':
+            return quote(value);
+
+        case 'number':
+
+// JSON numbers must be finite. Encode non-finite numbers as null.
+
+            return isFinite(value) ? String(value) : 'null';
+
+        case 'boolean':
+        case 'null':
+
+// If the value is a boolean or null, convert it to a string. Note:
+// typeof null does not produce 'null'. The case is included here in
+// the remote chance that this gets fixed someday.
+
+            return String(value);
+
+// If the type is 'object', we might be dealing with an object or an array or
+// null.
+
+        case 'object':
+
+// Due to a specification blunder in ECMAScript, typeof null is 'object',
+// so watch out for that case.
+
+            if (!value) {
+                return 'null';
+            }
+
+// Make an array to hold the partial results of stringifying this object value.
+
+            gap += indent;
+            partial = [];
+
+// Is the value an array?
+
+            if (Object.prototype.toString.apply(value) === '[object Array]') {
+
+// The value is an array. Stringify every element. Use null as a placeholder
+// for non-JSON values.
+
+                length = value.length;
+                for (i = 0; i < length; i += 1) {
+                    partial[i] = str(i, value) || 'null';
+                }
+
+// Join all of the elements together, separated with commas, and wrap them in
+// brackets.
+
+                v = partial.length === 0 ? '[]' :
+                    gap ? '[\n' + gap +
+                            partial.join(',\n' + gap) + '\n' +
+                                mind + ']' :
+                          '[' + partial.join(',') + ']';
+                gap = mind;
+                return v;
+            }
+
+// If the replacer is an array, use it to select the members to be stringified.
+
+            if (rep && typeof rep === 'object') {
+                length = rep.length;
+                for (i = 0; i < length; i += 1) {
+                    k = rep[i];
+                    if (typeof k === 'string') {
+                        v = str(k, value);
+                        if (v) {
+                            partial.push(quote(k) + (gap ? ': ' : ':') + v);
+                        }
+                    }
+                }
+            } else {
+
+// Otherwise, iterate through all of the keys in the object.
+
+                for (k in value) {
+                    if (Object.hasOwnProperty.call(value, k)) {
+                        v = str(k, value);
+                        if (v) {
+                            partial.push(quote(k) + (gap ? ': ' : ':') + v);
+                        }
+                    }
+                }
+            }
+
+// Join all of the member texts together, separated with commas,
+// and wrap them in braces.
+
+            v = partial.length === 0 ? '{}' :
+                gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' +
+                        mind + '}' : '{' + partial.join(',') + '}';
+            gap = mind;
+            return v;
+        }
+    }
+
+        InjectedScript.JSON.stringify = function (value, replacer, space) {
+
+// The stringify method takes a value and an optional replacer, and an optional
+// space parameter, and returns a JSON text. The replacer can be a function
+// that can replace values, or an array of strings that will select the keys.
+// A default replacer method can be provided. Use of the space parameter can
+// produce text that is more easily readable.
+
+            var i;
+            gap = '';
+            indent = '';
+
+// If the space parameter is a number, make an indent string containing that
+// many spaces.
+
+            if (typeof space === 'number') {
+                for (i = 0; i < space; i += 1) {
+                    indent += ' ';
+                }
+
+// If the space parameter is a string, it will be used as the indent string.
+
+            } else if (typeof space === 'string') {
+                indent = space;
+            }
+
+// If there is a replacer, it must be a function or an array.
+// Otherwise, throw an error.
+
+            rep = replacer;
+            if (replacer && typeof replacer !== 'function' &&
+                    (typeof replacer !== 'object' ||
+                     typeof replacer.length !== 'number')) {
+                throw new Error('JSON.stringify');
+            }
+
+// Make a fake root object containing our value under the key of ''.
+// Return the result of stringifying the value.
+
+            return str('', {'': value});
+        };
+
+
+// If the JSON object does not yet have a parse method, give it one.
+
+    InjectedScript.JSON.parse = function (text, reviver) {
+
+// The parse method takes a text and an optional reviver function, and returns
+// a JavaScript value if the text is a valid JSON text.
+
+            var j;
+
+            function walk(holder, key) {
+
+// The walk method is used to recursively walk the resulting structure so
+// that modifications can be made.
+
+                var k, v, value = holder[key];
+                if (value && typeof value === 'object') {
+                    for (k in value) {
+                        if (Object.hasOwnProperty.call(value, k)) {
+                            v = walk(value, k);
+                            if (v !== undefined) {
+                                value[k] = v;
+                            } else {
+                                delete value[k];
+                            }
+                        }
+                    }
+                }
+                return reviver.call(holder, key, value);
+            }
+
+
+// Parsing happens in four stages. In the first stage, we replace certain
+// Unicode characters with escape sequences. JavaScript handles many characters
+// incorrectly, either silently deleting them, or treating them as line endings.
+
+            cx.lastIndex = 0;
+            if (cx.test(text)) {
+                text = text.replace(cx, function (a) {
+                    return '\\u' +
+                        ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
+                });
+            }
+
+// In the second stage, we run the text against regular expressions that look
+// for non-JSON patterns. We are especially concerned with '()' and 'new'
+// because they can cause invocation, and '=' because it can cause mutation.
+// But just to be safe, we want to reject all unexpected forms.
+
+// We split the second stage into 4 regexp operations in order to work around
+// crippling inefficiencies in IE's and Safari's regexp engines. First we
+// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
+// replace all simple value tokens with ']' characters. Third, we delete all
+// open brackets that follow a colon or comma or that begin the text. Finally,
+// we look to see that the remaining characters are only whitespace or ']' or
+// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
+
+            if (/^[\],:{}\s]*$/.
+test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@').
+replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').
+replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
+
+// In the third stage we use the eval function to compile the text into a
+// JavaScript structure. The '{' operator is subject to a syntactic ambiguity
+// in JavaScript: it can begin a block or an object literal. We wrap the text
+// in parens to eliminate the ambiguity.
+
+                j = eval('(' + text + ')');
+
+// In the optional fourth stage, we recursively walk the new structure, passing
+// each name/value pair to a reviver function for possible transformation.
+
+                return typeof reviver === 'function' ?
+                    walk({'': j}, '') : j;
+            }
+
+// If the text is not JSON parseable, then a SyntaxError is thrown.
+
+            throw new SyntaxError('JSON.parse');
+        };
+}());
+
+return InjectedScript;
+});
index c07cd4d..2dd2908 100644 (file)
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-var InjectedScriptAccess = {};
+function InjectedScriptAccess(injectedScriptId) {
+    this._injectedScriptId = injectedScriptId;
+}
+
+InjectedScriptAccess.get = function(injectedScriptId)
+{
+    return new InjectedScriptAccess(injectedScriptId);
+}
+
+InjectedScriptAccess.getDefault = function()
+{
+    return InjectedScriptAccess.get(0);
+}
+
+InjectedScriptAccess.prototype = {};
 
 InjectedScriptAccess._installHandler = function(methodName, async)
 {
-    InjectedScriptAccess[methodName] = function()
+    InjectedScriptAccess.prototype[methodName] = function()
     {
         var allArgs = Array.prototype.slice.call(arguments);
         var callback = allArgs[allArgs.length - 1];
@@ -47,7 +61,8 @@ InjectedScriptAccess._installHandler = function(methodName, async)
                 WebInspector.console.addMessage(new WebInspector.ConsoleTextMessage("Error dispatching: " + methodName));
         }
         var callId = WebInspector.Callback.wrap(myCallback);
-        InspectorBackend.dispatchOnInjectedScript(callId, methodName, argsString, !!async);
+
+        InspectorBackend.dispatchOnInjectedScript(callId, this._injectedScriptId, methodName, argsString, !!async);
     };
 }
 
index f5e6758..767da1f 100644 (file)
@@ -30,6 +30,7 @@ WebInspector.MetricsSidebarPane = function()
 {
     WebInspector.SidebarPane.call(this, WebInspector.UIString("Metrics"));
     this._inlineStyleId = null;
+    this._inlineStyleInjectedScriptId = null;
 }
 
 WebInspector.MetricsSidebarPane.prototype = {
@@ -52,14 +53,15 @@ WebInspector.MetricsSidebarPane.prototype = {
             var style = WebInspector.CSSStyleDeclaration.parseStyle(stylePayload);
             self._update(style);
         };
-        InjectedScriptAccess.getComputedStyle(node.id, callback);
+        InjectedScriptAccess.get(node.injectedScriptId).getComputedStyle(node.id, callback);
 
         var inlineStyleCallback = function(stylePayload) {
             if (!stylePayload)
                 return;
             self._inlineStyleId = stylePayload.id;
+            self._inlineStyleInjectedScriptId = stylePayload.injectedScriptId;
         };
-        InjectedScriptAccess.getInlineStyle(node.id, inlineStyleCallback);
+        InjectedScriptAccess.get(node.injectedScriptId).getInlineStyle(node.id, inlineStyleCallback);
     },
 
     _update: function(style)
@@ -204,7 +206,7 @@ WebInspector.MetricsSidebarPane.prototype = {
             self.dispatchEventToListeners("metrics edited");
             self.update();
         };
-        InjectedScriptAccess.setStyleProperty(this._inlineStyleId, context.styleProperty, userInput, callback);
+        InjectedScriptAccess.get(this._inlineStyleInjectedScriptId).setStyleProperty(this._inlineStyleId, context.styleProperty, userInput, callback);
     }
 }
 
index 0f9dcec..6d71090 100644 (file)
@@ -50,7 +50,7 @@ WebInspector.ObjectPropertiesSection.prototype = {
                 return;
             self.updateProperties(properties);
         };
-        InjectedScriptAccess.getProperties(this.object, this.ignoreHasOwnProperty, true, callback);
+        InjectedScriptAccess.get(this.object.injectedScriptId).getProperties(this.object, this.ignoreHasOwnProperty, true, callback);
     },
 
     updateProperties: function(properties, rootTreeElementConstructor, rootPropertyComparer)
@@ -147,7 +147,7 @@ WebInspector.ObjectPropertyTreeElement.prototype = {
                 this.appendChild(new this.treeOutline.section.treeElementConstructor(properties[i]));
             }
         };
-        InjectedScriptAccess.getProperties(this.property.value, false, true, callback.bind(this));
+        InjectedScriptAccess.get(this.property.value.injectedScriptId).getProperties(this.property.value, false, true, callback.bind(this));
     },
 
     ondblclick: function(event)
@@ -251,7 +251,7 @@ WebInspector.ObjectPropertyTreeElement.prototype = {
                 self.updateSiblings();
             }
         };
-        InjectedScriptAccess.setPropertyValue(this.property.parentObjectProxy, this.property.name, expression.trim(), callback);
+        InjectedScriptAccess.get(this.property.parentObjectProxy.injectedScriptId).setPropertyValue(this.property.parentObjectProxy, this.property.name, expression.trim(), callback);
     }
 }
 
index 5129287..62517b8 100644 (file)
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-WebInspector.ObjectProxy = function(objectId, path, protoDepth, description, hasChildren)
+WebInspector.ObjectProxy = function(injectedScriptId, objectId, path, protoDepth, description, hasChildren)
 {
     this.objectId = objectId;
+    this.injectedScriptId = injectedScriptId;
     this.path = path || [];
     this.protoDepth = protoDepth || 0;
     this.description = description;
@@ -60,7 +61,7 @@ WebInspector.ObjectProxy.getPropertiesAsync = function(objectProxy, propertiesTo
                 result[propertiesPayload[i].name] = propertiesPayload[i].value.description;
         callback(result);
     };
-    InjectedScriptAccess.getProperties(objectProxy, true, false, createPropertiesMapThenCallback);
+    InjectedScriptAccess.get(objectProxy.injectedScriptId).getProperties(objectProxy, true, false, createPropertiesMapThenCallback);
 }
 
 WebInspector.ObjectPropertyProxy = function(name, value)
index d84874e..857d9a7 100644 (file)
@@ -50,13 +50,13 @@ WebInspector.PropertiesSidebarPane.prototype = {
 
             // Get array of prototype user-friendly names.
             for (var i = 0; i < prototypes.length; ++i) {
-                var prototype = new WebInspector.ObjectProxy(node.id, [], i);
+                var prototype = new WebInspector.ObjectProxy(node.injectedScriptId, node.id, [], i);
                 var section = new WebInspector.ObjectPropertiesSection(prototype, prototypes[i], WebInspector.UIString("Prototype"));
                 self.sections.push(section);
                 body.appendChild(section.element);
             }
         };
-        InjectedScriptAccess.getPrototypes(node.id, callback);
+        InjectedScriptAccess.get(node.injectedScriptId).getPrototypes(node.id, callback);
     }
 }
 
index a9b5146..c8a77a4 100644 (file)
@@ -978,7 +978,7 @@ WebInspector.ResourceSidebarTreeElement.prototype = {
     
     ondblclick: function(event)
     {
-        InjectedScriptAccess.openInInspectedWindow(this.resource.url, function() {});
+        InjectedScriptAccess.getDefault().openInInspectedWindow(this.resource.url, function() {});
     },
 
     ondragstart: function(event) {
index 20d5882..51aae9c 100644 (file)
@@ -400,7 +400,7 @@ WebInspector.ScriptsPanel.prototype = {
             if (result)
                 callback(result.value, result.isException);
         }
-        InjectedScriptAccess.evaluateInCallFrame(callFrame.id, code, objectGroup, evalCallback);
+        InjectedScriptAccess.get(callFrame.injectedScriptId).evaluateInCallFrame(callFrame.id, code, objectGroup, evalCallback);
     },
 
     debuggerPaused: function(callFrames)
index 1b5ffbc..f04cb66 100644 (file)
@@ -115,7 +115,7 @@ WebInspector.StylesSidebarPane.prototype = {
             self._update(refresh, body, node, editedSection, forceUpdate);
         }
 
-        InjectedScriptAccess.getStyles(node.id, !WebInspector.settings.showUserAgentStyles, callback);
+        InjectedScriptAccess.get(node.injectedScriptId).getStyles(node.id, !WebInspector.settings.showUserAgentStyles, callback);
     },
 
     _update: function(refresh, body, node, editedSection, forceUpdate)
@@ -692,7 +692,7 @@ WebInspector.StylePropertiesSection.prototype = {
             moveToNextIfNeeded.call(self);
         }
 
-        InjectedScriptAccess.applyStyleRuleText(this.rule.id, newContent, this.pane.node.id, callback);
+        InjectedScriptAccess.get(this.rule.injectedScriptId).applyStyleRuleText(this.rule.id, newContent, this.pane.node.id, callback);
     },
 
     editingSelectorCancelled: function()
@@ -746,7 +746,7 @@ WebInspector.BlankStylePropertiesSection.prototype = {
             self.addNewBlankProperty().startEditing();
         }
 
-        InjectedScriptAccess.addStyleSelector(newContent, this.pane.node.id, callback);
+        InjectedScriptAccess.get(this.pane.node.injectedScriptId).addStyleSelector(newContent, this.pane.node.id, callback);
     },
 
     editingSelectorCancelled: function()
@@ -1053,7 +1053,7 @@ WebInspector.StylePropertyTreeElement.prototype = {
             self.updateAll(true);
         }
 
-        InjectedScriptAccess.toggleStyleEnabled(this.style.id, this.name, disabled, callback);
+        InjectedScriptAccess.get(this.style.injectedScriptId).toggleStyleEnabled(this.style.id, this.name, disabled, callback);
     },
 
     updateState: function()
@@ -1216,7 +1216,7 @@ WebInspector.StylePropertyTreeElement.prototype = {
         } else {
             // Restore the original CSS text before applying user changes. This is needed to prevent
             // new properties from sticking around if the user adds one, then removes it.
-            InjectedScriptAccess.setStyleText(this.style.id, this.originalCSSText);
+            InjectedScriptAccess.get(this.style.injectedScriptId).setStyleText(this.style.id, this.originalCSSText);
         }
 
         this.applyStyleText(this.listItemElement.textContent);
@@ -1236,7 +1236,7 @@ WebInspector.StylePropertyTreeElement.prototype = {
         if (this._newProperty)
             this.treeOutline.removeChild(this);
         else if (this.originalCSSText) {
-            InjectedScriptAccess.setStyleText(this.style.id, this.originalCSSText);
+            InjectedScriptAccess.get(this.style.injectedScriptId).setStyleText(this.style.id, this.originalCSSText);
 
             if (this.treeOutline.section && this.treeOutline.section.pane)
                 this.treeOutline.section.pane.dispatchEventToListeners("style edited");
@@ -1361,7 +1361,7 @@ WebInspector.StylePropertyTreeElement.prototype = {
                 WebInspector.panels.elements.treeOutline.update();
         }
 
-        InjectedScriptAccess.applyStyleText(this.style.id, styleText.trim(), this.name, callback);
+        InjectedScriptAccess.get(this.style.injectedScriptId).applyStyleText(this.style.id, styleText.trim(), this.name, callback);
     }
 }
 
index 1dba3f8..a4e4867 100644 (file)
@@ -131,7 +131,8 @@ WebInspector.WatchExpressionsSection.prototype = {
             }
         }
 
-        InspectorBackend.releaseWrapperObjectGroup(this._watchObjectGroupId)
+        // TODO: pass exact injected script id.
+        InspectorBackend.releaseWrapperObjectGroup(0, this._watchObjectGroupId)
         var properties = [];
 
         // Count the properties, so we known when to call this.updateProperties()
index 5cf93b3..8b8e33e 100644 (file)
@@ -389,6 +389,8 @@ var WebInspector = {
 
 WebInspector.loaded = function()
 {
+    InspectorBackend.setInjectedScriptSource("(" + injectedScriptConstructor + ");");
+
     var platform = WebInspector.platform;
     document.body.addStyleClass("platform-" + platform);
     var port = WebInspector.port;
@@ -1147,6 +1149,7 @@ WebInspector.failedToParseScriptSource = function(sourceURL, source, startingLin
 
 WebInspector.pausedScript = function(callFrames)
 {
+    callFrames = JSON.parse(callFrames);
     this.panels.scripts.debuggerPaused(callFrames);
 }
 
@@ -1203,7 +1206,7 @@ WebInspector.updateConsoleMessageExpiredCount = function(count)
     WebInspector.console.addMessage(new WebInspector.ConsoleTextMessage(message, WebInspector.ConsoleMessage.MessageLevel.Warning));
 }
 
-WebInspector.addConsoleMessage = function(payload)
+WebInspector.addConsoleMessage = function(payload, argumentsStringified, opt_args)
 {
     var consoleMessage = new WebInspector.ConsoleMessage(
         payload.source,
@@ -1213,7 +1216,14 @@ WebInspector.addConsoleMessage = function(payload)
         payload.url,
         payload.groupLevel,
         payload.repeatCount);
-    consoleMessage.setMessageBody(Array.prototype.slice.call(arguments, 1));
+    var parsedArguments = [];
+    for (var i = 2; i < arguments.length; i++) {
+        if (argumentsStringified)
+            parsedArguments.push(JSON.parse(arguments[i]));
+        else
+            parsedArguments.push(arguments[i]);
+    }
+    consoleMessage.setMessageBody(parsedArguments);
     this.console.addMessage(consoleMessage);
 }
 
@@ -1270,7 +1280,7 @@ WebInspector.log = function(message)
         WebInspector.log.repeatCount = repeatCount;
 
         // ConsoleMessage expects a proxy object
-        message = new WebInspector.ObjectProxy(null, [], 0, message, false);
+        message = new WebInspector.ObjectProxy(null, null, [], 0, message, false);
 
         // post the message
         var msg = new WebInspector.ConsoleMessage(