Web Inspector: provide a way to reload page with given script preprocessor.
authorpfeldman@chromium.org <pfeldman@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 7 Dec 2012 14:13:33 +0000 (14:13 +0000)
committerpfeldman@chromium.org <pfeldman@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 7 Dec 2012 14:13:33 +0000 (14:13 +0000)
https://bugs.webkit.org/show_bug.cgi?id=80992

Reviewed by Yury Semikhatsky.

Source/WebCore:

This change introduces a way to inject 'preprocessor' script that would process
each JavaScript file before it gets into the VM for compilation. That way inspector
can expose capabilities such as assessing code coverage or tracing all the calls.

Preprocessor script is stored in the page agent where it waits for reload to happen.
Upon reload, ScriptDebugServer is using it to patch the script sources.

Test: inspector/debugger/debugger-script-preprocessor.html

* bindings/js/ScriptDebugServer.h:
(WebCore::ScriptDebugServer::setScriptPreprocessor):
(ScriptDebugServer):
* bindings/v8/DebuggerScript.js:
* bindings/v8/ScriptDebugServer.cpp:
(ScriptDebugServer::ScriptPreprocessor):
(WebCore::ScriptDebugServer::ScriptPreprocessor::ScriptPreprocessor):
(WebCore::ScriptDebugServer::ScriptPreprocessor::preprocessSourceCode):
(WebCore::ScriptDebugServer::ScriptPreprocessor::~ScriptPreprocessor):
(WebCore):
(WebCore::ScriptDebugServer::~ScriptDebugServer):
(WebCore::ScriptDebugServer::setScriptSource):
(WebCore::ScriptDebugServer::setScriptPreprocessor):
(WebCore::ScriptDebugServer::handleV8DebugEvent):
* bindings/v8/ScriptDebugServer.h:
(ScriptDebugServer):
* bindings/v8/custom/V8InjectedScriptManager.cpp:
(WebCore::InjectedScriptManager::createInjectedScript):
* inspector/Inspector.json:
* inspector/InspectorController.cpp:
(WebCore::InspectorController::InspectorController):
* inspector/InspectorDebuggerAgent.h:
(InspectorDebuggerAgent):
* inspector/InspectorPageAgent.cpp:
(WebCore::InspectorPageAgent::reload):
(WebCore::InspectorPageAgent::frameNavigated):
* inspector/InspectorPageAgent.h:
(WebCore::InspectorPageAgent::page):
(WebCore::InspectorPageAgent::scriptPreprocessor):
(InspectorPageAgent):
* inspector/PageDebuggerAgent.cpp:
(WebCore::PageDebuggerAgent::create):
(WebCore::PageDebuggerAgent::PageDebuggerAgent):
(WebCore::PageDebuggerAgent::startListeningScriptDebugServer):
(WebCore::PageDebuggerAgent::stopListeningScriptDebugServer):
(WebCore::PageDebuggerAgent::injectedScriptForEval):
(WebCore::PageDebuggerAgent::didClearMainFrameWindowObject):
(WebCore):
* inspector/PageDebuggerAgent.h:
(WebCore):
(PageDebuggerAgent):

LayoutTests:

* http/tests/inspector/inspector-test.js:
(initialize_InspectorTest.InspectorTest.hardReloadPage):
(initialize_InspectorTest.InspectorTest.reloadPage):
(initialize_InspectorTest.InspectorTest._innerReloadPage):
* inspector/debugger/debugger-script-preprocessor-expected.txt: Added.
* inspector/debugger/debugger-script-preprocessor.html: Added.
* platform/chromium/inspector/debugger/debugger-script-preprocessor-expected.txt: Added.

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

18 files changed:
LayoutTests/ChangeLog
LayoutTests/http/tests/inspector/inspector-test.js
Source/WebCore/ChangeLog
Source/WebCore/bindings/js/ScriptDebugServer.h
Source/WebCore/bindings/v8/DebuggerScript.js
Source/WebCore/bindings/v8/ScriptDebugServer.cpp
Source/WebCore/bindings/v8/ScriptDebugServer.h
Source/WebCore/bindings/v8/custom/V8InjectedScriptManager.cpp
Source/WebCore/inspector/Inspector.json
Source/WebCore/inspector/InspectorController.cpp
Source/WebCore/inspector/InspectorDebuggerAgent.cpp
Source/WebCore/inspector/InspectorDebuggerAgent.h
Source/WebCore/inspector/InspectorInstrumentation.cpp
Source/WebCore/inspector/InspectorPageAgent.cpp
Source/WebCore/inspector/InspectorPageAgent.h
Source/WebCore/inspector/InstrumentingAgents.h
Source/WebCore/inspector/PageDebuggerAgent.cpp
Source/WebCore/inspector/PageDebuggerAgent.h

index cee70c1..bcc4d72 100644 (file)
@@ -1,3 +1,18 @@
+2012-10-03   Pavel Feldman  <pfeldman@chromium.org>
+
+        Web Inspector: provide a way to reload page with given script preprocessor.
+        https://bugs.webkit.org/show_bug.cgi?id=80992
+
+        Reviewed by Yury Semikhatsky.
+
+        * http/tests/inspector/inspector-test.js:
+        (initialize_InspectorTest.InspectorTest.hardReloadPage):
+        (initialize_InspectorTest.InspectorTest.reloadPage):
+        (initialize_InspectorTest.InspectorTest._innerReloadPage):
+        * inspector/debugger/debugger-script-preprocessor-expected.txt: Added.
+        * inspector/debugger/debugger-script-preprocessor.html: Added.
+        * platform/chromium/inspector/debugger/debugger-script-preprocessor-expected.txt: Added.
+
 2012-12-07  Alexander Pavlov  <apavlov@chromium.org>
 
         Web Inspector: the "Sources" column is always empty in CSS selector profiles
index 7d7149c..6987b92 100644 (file)
@@ -192,22 +192,23 @@ InspectorTest.navigate = function(url, callback)
     InspectorTest.evaluateInConsole("window.location = '" + url + "'");
 }
 
-InspectorTest.hardReloadPage = function(callback)
+InspectorTest.hardReloadPage = function(callback, scriptToEvaluateOnLoad, scriptPreprocessor)
 {
-    InspectorTest._innerReloadPage(true, callback);
+    InspectorTest._innerReloadPage(true, callback, scriptToEvaluateOnLoad, scriptPreprocessor);
 }
 
-InspectorTest.reloadPage = function(callback)
+InspectorTest.reloadPage = function(callback, scriptToEvaluateOnLoad, scriptPreprocessor)
 {
-    InspectorTest._innerReloadPage(false, callback);
+    InspectorTest._innerReloadPage(false, callback, scriptToEvaluateOnLoad, scriptPreprocessor);
 }
 
-InspectorTest._innerReloadPage = function(hardReload, callback)
+InspectorTest._innerReloadPage = function(hardReload, callback, scriptToEvaluateOnLoad, scriptPreprocessor)
 {
     InspectorTest._pageLoadedCallback = InspectorTest.safeWrap(callback);
 
-    WebInspector.panel("network")._reset();
-    PageAgent.reload(hardReload);
+    if (WebInspector.panels.network)
+        WebInspector.panels.network._reset();
+    PageAgent.reload(hardReload, scriptToEvaluateOnLoad, scriptPreprocessor);
 }
 
 InspectorTest.pageLoaded = function()
index 8b333fb..7fa4b0f 100644 (file)
@@ -1,3 +1,62 @@
+2012-10-03  Pavel Feldman  <pfeldman@chromium.org>
+
+        Web Inspector: provide a way to reload page with given script preprocessor.
+        https://bugs.webkit.org/show_bug.cgi?id=80992
+
+        Reviewed by Yury Semikhatsky.
+
+        This change introduces a way to inject 'preprocessor' script that would process
+        each JavaScript file before it gets into the VM for compilation. That way inspector
+        can expose capabilities such as assessing code coverage or tracing all the calls.
+
+        Preprocessor script is stored in the page agent where it waits for reload to happen.
+        Upon reload, ScriptDebugServer is using it to patch the script sources.
+
+        
+        Test: inspector/debugger/debugger-script-preprocessor.html
+
+        * bindings/js/ScriptDebugServer.h:
+        (WebCore::ScriptDebugServer::setScriptPreprocessor):
+        (ScriptDebugServer):
+        * bindings/v8/DebuggerScript.js:
+        * bindings/v8/ScriptDebugServer.cpp:
+        (ScriptDebugServer::ScriptPreprocessor):
+        (WebCore::ScriptDebugServer::ScriptPreprocessor::ScriptPreprocessor):
+        (WebCore::ScriptDebugServer::ScriptPreprocessor::preprocessSourceCode):
+        (WebCore::ScriptDebugServer::ScriptPreprocessor::~ScriptPreprocessor):
+        (WebCore):
+        (WebCore::ScriptDebugServer::~ScriptDebugServer):
+        (WebCore::ScriptDebugServer::setScriptSource):
+        (WebCore::ScriptDebugServer::setScriptPreprocessor):
+        (WebCore::ScriptDebugServer::handleV8DebugEvent):
+        * bindings/v8/ScriptDebugServer.h:
+        (ScriptDebugServer):
+        * bindings/v8/custom/V8InjectedScriptManager.cpp:
+        (WebCore::InjectedScriptManager::createInjectedScript):
+        * inspector/Inspector.json:
+        * inspector/InspectorController.cpp:
+        (WebCore::InspectorController::InspectorController):
+        * inspector/InspectorDebuggerAgent.h:
+        (InspectorDebuggerAgent):
+        * inspector/InspectorPageAgent.cpp:
+        (WebCore::InspectorPageAgent::reload):
+        (WebCore::InspectorPageAgent::frameNavigated):
+        * inspector/InspectorPageAgent.h:
+        (WebCore::InspectorPageAgent::page):
+        (WebCore::InspectorPageAgent::scriptPreprocessor):
+        (InspectorPageAgent):
+        * inspector/PageDebuggerAgent.cpp:
+        (WebCore::PageDebuggerAgent::create):
+        (WebCore::PageDebuggerAgent::PageDebuggerAgent):
+        (WebCore::PageDebuggerAgent::startListeningScriptDebugServer):
+        (WebCore::PageDebuggerAgent::stopListeningScriptDebugServer):
+        (WebCore::PageDebuggerAgent::injectedScriptForEval):
+        (WebCore::PageDebuggerAgent::didClearMainFrameWindowObject):
+        (WebCore):
+        * inspector/PageDebuggerAgent.h:
+        (WebCore):
+        (PageDebuggerAgent):
+
 2012-12-07  Alexander Pavlov  <apavlov@chromium.org>
 
         Web Inspector: the "Sources" column is always empty in CSS selector profiles
index e97fd61..64adc4a 100644 (file)
@@ -90,6 +90,11 @@ public:
     void recompileAllJSFunctionsSoon();
     virtual void recompileAllJSFunctions(Timer<ScriptDebugServer>* = 0) = 0;
 
+    void setScriptPreprocessor(const String&)
+    {
+        // FIXME(webkit.org/b/82203): Implement preprocessor.
+    }
+
     bool isPaused() { return m_paused; }
 
     void compileScript(ScriptState*, const String& expression, const String& sourceURL, String* scriptId, String* exceptionMessage);
index 62ccb73..7c20013 100644 (file)
@@ -210,7 +210,7 @@ DebuggerScript.stepOutOfFunction = function(execState)
     execState.prepareStep(Debug.StepAction.StepOut, 1);
 }
 
-DebuggerScript.setScriptSource = function(scriptId, newSource, preview)
+DebuggerScript.liveEditScriptSource = function(scriptId, newSource, preview)
 {
     var scripts = Debug.scripts();
     var scriptToEdit = null;
@@ -237,6 +237,18 @@ DebuggerScript.setBreakpointsActivated = function(execState, args)
     Debug.debuggerFlags().breakPointsActive.setValue(args.enabled);
 }
 
+DebuggerScript.getScriptSource = function(eventData)
+{
+    return eventData.script().source();
+}
+
+DebuggerScript.setScriptSource = function(eventData, source)
+{
+    if (eventData.script().data() === "injected-script")
+        return;
+    eventData.script().setSource(source);
+}
+
 DebuggerScript._frameMirrorToJSCallFrame = function(frameMirror, callerFrame)
 {
     // Get function name.
index 6f2ff3b..bc7fae0 100644 (file)
@@ -35,6 +35,7 @@
 
 #include "DebuggerScriptSource.h"
 #include "JavaScriptCallFrame.h"
+#include "ScopedPersistent.h"
 #include "ScriptDebugListener.h"
 #include "ScriptObject.h"
 #include "V8Binding.h"
@@ -56,6 +57,23 @@ private:
     OwnPtr<ScriptDebugServer::Task> m_task;
 };
 
+class RecursionScopeSuppression {
+public:
+    RecursionScopeSuppression()
+    {
+#ifndef NDEBUG
+        V8PerIsolateData::current()->incrementInternalScriptRecursionLevel();
+#endif
+    }
+
+    ~RecursionScopeSuppression()
+    {
+#ifndef NDEBUG
+        V8PerIsolateData::current()->decrementInternalScriptRecursionLevel();
+#endif
+    }
+};
+
 }
 
 v8::Local<v8::Value> ScriptDebugServer::callDebuggerMethod(const char* functionName, int argc, v8::Handle<v8::Value> argv[])
@@ -65,12 +83,83 @@ v8::Local<v8::Value> ScriptDebugServer::callDebuggerMethod(const char* functionN
     return function->Call(m_debuggerScript.get(), argc, argv);
 }
 
+class ScriptDebugServer::ScriptPreprocessor {
+    WTF_MAKE_NONCOPYABLE(ScriptPreprocessor);
+public:
+    explicit ScriptPreprocessor(const String& preprocessorScript)
+    {
+        v8::HandleScope scope;
+
+        m_utilityContext.set(v8::Context::New());
+        if (m_utilityContext.isEmpty())
+            return;
+
+        v8::Context::Scope contextScope(m_utilityContext.get());
+
+        v8::TryCatch tryCatch;
+
+        String wrappedScript = makeString("(", preprocessorScript, ")");
+        v8::Handle<v8::String> preprocessor = v8::String::New(wrappedScript.utf8().data(), wrappedScript.utf8().length());
+        v8::Handle<v8::Script> script = v8::Script::Compile(preprocessor);
+
+        if (tryCatch.HasCaught())
+            return;
+        RecursionScopeSuppression suppressionScope;
+        v8::Handle<v8::Value> preprocessorFunction = script->Run();
+
+        if (tryCatch.HasCaught() || !preprocessorFunction->IsFunction())
+            return;
+
+        m_preprocessorFunction.set(v8::Handle<v8::Function>::Cast(preprocessorFunction));
+    }
+
+    String preprocessSourceCode(const String& sourceCode)
+    {
+        v8::HandleScope scope;
+
+        if (m_preprocessorFunction.isEmpty())
+            return sourceCode;
+
+        v8::Local<v8::Context> context = v8::Local<v8::Context>::New(m_utilityContext.get());
+        v8::Context::Scope contextScope(context);
+
+        v8::Handle<v8::String> sourceCodeString = v8::String::New(sourceCode.utf8().data(), sourceCode.utf8().length());
+        v8::Handle<v8::Value> argv[] = { sourceCodeString };
+
+        v8::TryCatch tryCatch;
+        RecursionScopeSuppression suppressionScope;
+        v8::Handle<v8::Value> resultValue = m_preprocessorFunction->Call(context->Global(), 1, argv);
+        if (tryCatch.HasCaught())
+            return sourceCode;
+
+        if (resultValue->IsString()) {
+            v8::String::Utf8Value utf8Value(resultValue);
+            return String::fromUTF8(*utf8Value, utf8Value.length());
+        }
+
+        return sourceCode;
+    }
+
+    ~ScriptPreprocessor()
+    {
+    }
+
+private:
+    ScopedPersistent<v8::Context> m_utilityContext;
+    String m_preprocessorBody;
+    ScopedPersistent<v8::Function> m_preprocessorFunction;
+};
+
 ScriptDebugServer::ScriptDebugServer()
     : m_pauseOnExceptionsState(DontPauseOnExceptions)
     , m_breakpointsActivated(true)
 {
 }
 
+ScriptDebugServer::~ScriptDebugServer()
+{
+}
+
 String ScriptDebugServer::setBreakpoint(const String& sourceID, const ScriptBreakpoint& scriptBreakpoint, int* actualLineNumber, int* actualColumnNumber)
 {
     v8::HandleScope scope;
@@ -235,7 +324,7 @@ bool ScriptDebugServer::setScriptSource(const String& sourceID, const String& ne
 
     v8::TryCatch tryCatch;
     tryCatch.SetVerbose(false);
-    v8::Local<v8::Value> v8result = callDebuggerMethod("setScriptSource", 3, argv);
+    v8::Local<v8::Value> v8result = callDebuggerMethod("liveEditScriptSource", 3, argv);
     if (tryCatch.HasCaught()) {
         v8::Local<v8::Message> message = tryCatch.Message();
         if (!message.IsEmpty())
@@ -262,6 +351,13 @@ void ScriptDebugServer::updateCallStack(ScriptValue* callFrame)
 }
 
 
+void ScriptDebugServer::setScriptPreprocessor(const String& preprocessorBody)
+{
+    m_scriptPreprocessor.clear();
+    if (!preprocessorBody.isEmpty())
+        m_scriptPreprocessor = adoptPtr(new ScriptPreprocessor(preprocessorBody));
+}
+
 ScriptValue ScriptDebugServer::currentCallFrame()
 {
     ASSERT(isPaused());
@@ -336,7 +432,7 @@ void ScriptDebugServer::handleV8DebugEvent(const v8::Debug::EventDetails& eventD
         return;
     }
 
-    if (event != v8::Break && event != v8::Exception && event != v8::AfterCompile)
+    if (event != v8::Break && event != v8::Exception && event != v8::AfterCompile && event != v8::BeforeCompile)
         return;
 
     v8::Handle<v8::Context> eventContext = eventDetails.GetEventContext();
@@ -345,7 +441,22 @@ void ScriptDebugServer::handleV8DebugEvent(const v8::Debug::EventDetails& eventD
     ScriptDebugListener* listener = getDebugListenerForContext(eventContext);
     if (listener) {
         v8::HandleScope scope;
-        if (event == v8::AfterCompile) {
+        if (event == v8::BeforeCompile) {
+            if (!m_scriptPreprocessor)
+                return;
+
+            OwnPtr<ScriptPreprocessor> preprocessor(m_scriptPreprocessor.release());
+            v8::Context::Scope contextScope(v8::Debug::GetDebugContext());
+            v8::Handle<v8::Function> getScriptSourceFunction = v8::Local<v8::Function>::Cast(m_debuggerScript.get()->Get(v8::String::New("getScriptSource")));
+            v8::Handle<v8::Value> argv[] = { eventDetails.GetEventData() };
+            v8::Handle<v8::Value> script = getScriptSourceFunction->Call(m_debuggerScript.get(), 1, argv);
+
+            v8::Handle<v8::Function> setScriptSourceFunction = v8::Local<v8::Function>::Cast(m_debuggerScript.get()->Get(v8::String::New("setScriptSource")));
+            String patchedScript = preprocessor->preprocessSourceCode(toWebCoreStringWithUndefinedOrNullCheck(script));
+            v8::Handle<v8::Value> argv2[] = { eventDetails.GetEventData(), v8String(patchedScript) };
+            setScriptSourceFunction->Call(m_debuggerScript.get(), 2, argv2);
+            m_scriptPreprocessor = preprocessor.release();
+        } else if (event == v8::AfterCompile) {
             v8::Context::Scope contextScope(v8::Debug::GetDebugContext());
             v8::Handle<v8::Function> onAfterCompileFunction = v8::Local<v8::Function>::Cast(m_debuggerScript.get()->Get(v8::String::NewSymbol("getAfterCompileScript")));
             v8::Handle<v8::Value> argv[] = { eventDetails.GetEventData() };
index 5bc7392..e6cbdb9 100644 (file)
@@ -86,6 +86,8 @@ public:
     void recompileAllJSFunctionsSoon() { }
     void recompileAllJSFunctions(Timer<ScriptDebugServer>* = 0) { }
 
+    void setScriptPreprocessor(const String& preprocessorBody);
+
     class Task {
     public:
         virtual ~Task() { }
@@ -105,7 +107,7 @@ public:
 
 protected:
     ScriptDebugServer();
-    ~ScriptDebugServer() { }
+    virtual ~ScriptDebugServer();
     
     ScriptValue currentCallFrame();
 
@@ -125,14 +127,19 @@ protected:
 
     v8::Local<v8::Value> callDebuggerMethod(const char* functionName, int argc, v8::Handle<v8::Value> argv[]);
 
+    String preprocessSourceCode(const String& sourceCode);
+
     PauseOnExceptionsState m_pauseOnExceptionsState;
     ScopedPersistent<v8::Object> m_debuggerScript;
     ScopedPersistent<v8::Object> m_executionState;
     v8::Local<v8::Context> m_pausedContext;
-
     bool m_breakpointsActivated;
     ScopedPersistent<v8::FunctionTemplate> m_breakProgramCallbackTemplate;
     HashMap<String, OwnPtr<ScopedPersistent<v8::Script> > > m_compiledScripts;
+    
+private:
+    class ScriptPreprocessor;
+    OwnPtr<ScriptPreprocessor> m_scriptPreprocessor;
 };
 
 } // namespace WebCore
index f00d37b..7208dc8 100644 (file)
@@ -35,6 +35,7 @@
 #include "BindingState.h"
 #include "DOMWindow.h"
 #include "InjectedScriptHost.h"
+#include "ScriptDebugServer.h"
 #include "ScriptObject.h"
 #include "V8Binding.h"
 #include "V8DOMWindow.h"
index 8f22c7a..d21b520 100644 (file)
                 "name": "reload",
                 "parameters": [
                     { "name": "ignoreCache", "type": "boolean", "optional": true, "description": "If true, browser cache is ignored (as if the user pressed Shift+refresh)." },
-                    { "name": "scriptToEvaluateOnLoad", "type": "string", "optional": true, "description": "If set, the script will be injected into all frames of the inspected page after reload." }
+                    { "name": "scriptToEvaluateOnLoad", "type": "string", "optional": true, "description": "If set, the script will be injected into all frames of the inspected page after reload." },
+                    { "name": "scriptPreprocessor", "type": "string", "optional": true, "description": "Script body that should evaluate to function that will preprocess all the scripts before their compilation.", "hidden": true }
                 ],
                 "description": "Reloads given page optionally ignoring the cache."
             },
index c6f263d..d03886b 100644 (file)
@@ -135,7 +135,7 @@ InspectorController::InspectorController(Page* page, InspectorClient* inspectorC
     m_agents.append(consoleAgentPtr.release());
 
 #if ENABLE(JAVASCRIPT_DEBUGGER)
-    OwnPtr<InspectorDebuggerAgent> debuggerAgentPtr(PageDebuggerAgent::create(m_instrumentingAgents.get(), m_state.get(), page, m_injectedScriptManager.get(), m_overlay.get()));
+    OwnPtr<InspectorDebuggerAgent> debuggerAgentPtr(PageDebuggerAgent::create(m_instrumentingAgents.get(), m_state.get(), pageAgent, m_injectedScriptManager.get(), m_overlay.get()));
     m_debuggerAgent = debuggerAgentPtr.get();
     m_agents.append(debuggerAgentPtr.release());
 
index e653150..9cf8d01 100644 (file)
@@ -186,14 +186,6 @@ void InspectorDebuggerAgent::setBreakpointsActive(ErrorString*, bool active)
         scriptDebugServer().deactivateBreakpoints();
 }
 
-void InspectorDebuggerAgent::didClearMainFrameWindowObject()
-{
-    m_scripts.clear();
-    m_breakpointIdToDebugServerBreakpointIds.clear();
-    if (m_frontend)
-        m_frontend->globalObjectCleared();
-}
-
 bool InspectorDebuggerAgent::isPaused()
 {
     return scriptDebugServer().isPaused();
@@ -759,6 +751,14 @@ void ScriptDebugListener::Script::reportMemoryUsage(MemoryObjectInfo* memoryObje
     info.addMember(sourceMappingURL);
 }
 
+void InspectorDebuggerAgent::reset()
+{
+    m_scripts.clear();
+    m_breakpointIdToDebugServerBreakpointIds.clear();
+    if (m_frontend)
+        m_frontend->globalObjectCleared();
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(JAVASCRIPT_DEBUGGER) && ENABLE(INSPECTOR)
index 81bceed..c4fbfa4 100644 (file)
@@ -77,7 +77,6 @@ public:
     virtual void clearFrontend();
     virtual void restore();
 
-    void didClearMainFrameWindowObject();
     bool isPaused();
     void addMessageToConsole(MessageSource, MessageType);
 
@@ -144,6 +143,7 @@ protected:
     virtual void disable();
     virtual void didPause(ScriptState*, const ScriptValue& callFrames, const ScriptValue& exception);
     virtual void didContinue();
+    void reset();
 
 private:
     void enable();
index 1b79dd4..25ea6de 100644 (file)
@@ -60,6 +60,7 @@
 #include "InspectorTimelineAgent.h"
 #include "InspectorWorkerAgent.h"
 #include "InstrumentingAgents.h"
+#include "PageDebuggerAgent.h"
 #include "PageRuntimeAgent.h"
 #include "ScriptArguments.h"
 #include "ScriptCallStack.h"
@@ -121,7 +122,7 @@ void InspectorInstrumentation::didClearWindowObjectInWorldImpl(InstrumentingAgen
     if (InspectorAgent* inspectorAgent = instrumentingAgents->inspectorAgent())
         inspectorAgent->didClearWindowObjectInWorld(frame, world);
 #if ENABLE(JAVASCRIPT_DEBUGGER)
-    if (InspectorDebuggerAgent* debuggerAgent = instrumentingAgents->inspectorDebuggerAgent()) {
+    if (PageDebuggerAgent* debuggerAgent = instrumentingAgents->pageDebuggerAgent()) {
         if (pageAgent && world == mainThreadNormalWorld() && frame == pageAgent->mainFrame())
             debuggerAgent->didClearMainFrameWindowObject();
     }
index 04a545e..4b306f7 100644 (file)
@@ -435,9 +435,10 @@ void InspectorPageAgent::removeScriptToEvaluateOnLoad(ErrorString* error, const
     scripts->remove(identifier);
 }
 
-void InspectorPageAgent::reload(ErrorString*, const bool* const optionalIgnoreCache, const String* optionalScriptToEvaluateOnLoad)
+void InspectorPageAgent::reload(ErrorString*, const bool* const optionalIgnoreCache, const String* optionalScriptToEvaluateOnLoad, const String* optionalScriptPreprocessor)
 {
     m_pendingScriptToEvaluateOnLoadOnce = optionalScriptToEvaluateOnLoad ? *optionalScriptToEvaluateOnLoad : "";
+    m_pendingScriptPreprocessor = optionalScriptPreprocessor ? *optionalScriptPreprocessor : "";
     m_page->mainFrame()->loader()->reload(optionalIgnoreCache ? *optionalIgnoreCache : false);
 }
 
@@ -825,7 +826,9 @@ void InspectorPageAgent::frameNavigated(DocumentLoader* loader)
 {
     if (loader->frame() == m_page->mainFrame()) {
         m_scriptToEvaluateOnLoadOnce = m_pendingScriptToEvaluateOnLoadOnce;
+        m_scriptPreprocessor = m_pendingScriptPreprocessor;
         m_pendingScriptToEvaluateOnLoadOnce = String();
+        m_pendingScriptPreprocessor = String();
     }
     m_frontend->frameNavigated(buildObjectForFrame(loader->frame()));
 }
index 5d468a1..93fed0e 100644 (file)
@@ -97,7 +97,7 @@ public:
     virtual void disable(ErrorString*);
     virtual void addScriptToEvaluateOnLoad(ErrorString*, const String& source, String* result);
     virtual void removeScriptToEvaluateOnLoad(ErrorString*, const String& identifier);
-    virtual void reload(ErrorString*, const bool* optionalIgnoreCache, const String* optionalScriptToEvaluateOnLoad);
+    virtual void reload(ErrorString*, const bool* optionalIgnoreCache, const String* optionalScriptToEvaluateOnLoad, const String* optionalScriptPreprocessor);
     virtual void navigate(ErrorString*, const String& url);
     virtual void getCookies(ErrorString*, RefPtr<TypeBuilder::Array<TypeBuilder::Page::Cookie> >& cookies, WTF::String* cookiesString);
     virtual void deleteCookie(ErrorString*, const String& cookieName, const String& domain);
@@ -153,12 +153,14 @@ public:
     void webViewResized(const IntSize&);
 
     // Cross-agents API
+    Page* page() { return m_page; }
     Frame* mainFrame();
     String createIdentifier();
     Frame* frameForId(const String& frameId);
     String frameId(Frame*);
     String loaderId(DocumentLoader*);
     Frame* assertFrame(ErrorString*, String frameId);
+    String scriptPreprocessor() { return m_scriptPreprocessor; }
     static DocumentLoader* assertDocumentLoader(ErrorString*, Frame*);
 
 private:
@@ -182,6 +184,8 @@ private:
     long m_lastScriptIdentifier;
     String m_pendingScriptToEvaluateOnLoadOnce;
     String m_scriptToEvaluateOnLoadOnce;
+    String m_pendingScriptPreprocessor;
+    String m_scriptPreprocessor;
     HashMap<Frame*, String> m_frameToIdentifier;
     HashMap<String, Frame*> m_identifierToFrame;
     HashMap<DocumentLoader*, String> m_loaderToIdentifier;
index 884d9bb..e493410 100644 (file)
@@ -53,6 +53,7 @@ class InspectorResourceAgent;
 class InspectorTimelineAgent;
 class InspectorWorkerAgent;
 class Page;
+class PageDebuggerAgent;
 class PageRuntimeAgent;
 class WorkerContext;
 class WorkerRuntimeAgent;
@@ -81,6 +82,7 @@ public:
         , m_inspectorApplicationCacheAgent(0)
 #if ENABLE(JAVASCRIPT_DEBUGGER)
         , m_inspectorDebuggerAgent(0)
+        , m_pageDebuggerAgent(0)
         , m_inspectorDOMDebuggerAgent(0)
         , m_inspectorProfilerAgent(0)
 #endif
@@ -138,6 +140,9 @@ public:
     InspectorDebuggerAgent* inspectorDebuggerAgent() const { return m_inspectorDebuggerAgent; }
     void setInspectorDebuggerAgent(InspectorDebuggerAgent* agent) { m_inspectorDebuggerAgent = agent; }
 
+    PageDebuggerAgent* pageDebuggerAgent() const { return m_pageDebuggerAgent; }
+    void setPageDebuggerAgent(PageDebuggerAgent* agent) { m_pageDebuggerAgent = agent; }
+
     InspectorDOMDebuggerAgent* inspectorDOMDebuggerAgent() const { return m_inspectorDOMDebuggerAgent; }
     void setInspectorDOMDebuggerAgent(InspectorDOMDebuggerAgent* agent) { m_inspectorDOMDebuggerAgent = agent; }
 
@@ -173,6 +178,7 @@ private:
     InspectorApplicationCacheAgent* m_inspectorApplicationCacheAgent;
 #if ENABLE(JAVASCRIPT_DEBUGGER)
     InspectorDebuggerAgent* m_inspectorDebuggerAgent;
+    PageDebuggerAgent* m_pageDebuggerAgent;
     InspectorDOMDebuggerAgent* m_inspectorDOMDebuggerAgent;
     InspectorProfilerAgent* m_inspectorProfilerAgent;
 #endif
index c97323b..0e0a552 100644 (file)
 
 #include "Console.h"
 #include "InspectorOverlay.h"
+#include "InspectorPageAgent.h"
+#include "InstrumentingAgents.h"
 #include "Page.h"
 #include "PageScriptDebugServer.h"
 
 namespace WebCore {
 
-PassOwnPtr<PageDebuggerAgent> PageDebuggerAgent::create(InstrumentingAgents* instrumentingAgents, InspectorState* inspectorState, Page* inspectedPage, InjectedScriptManager* injectedScriptManager, InspectorOverlay* overlay)
+PassOwnPtr<PageDebuggerAgent> PageDebuggerAgent::create(InstrumentingAgents* instrumentingAgents, InspectorState* inspectorState, InspectorPageAgent* pageAgent, InjectedScriptManager* injectedScriptManager, InspectorOverlay* overlay)
 {
-    return adoptPtr(new PageDebuggerAgent(instrumentingAgents, inspectorState, inspectedPage, injectedScriptManager, overlay));
+    return adoptPtr(new PageDebuggerAgent(instrumentingAgents, inspectorState, pageAgent, injectedScriptManager, overlay));
 }
 
-PageDebuggerAgent::PageDebuggerAgent(InstrumentingAgents* instrumentingAgents, InspectorState* inspectorState, Page* inspectedPage, InjectedScriptManager* injectedScriptManager, InspectorOverlay* overlay)
+PageDebuggerAgent::PageDebuggerAgent(InstrumentingAgents* instrumentingAgents, InspectorState* inspectorState, InspectorPageAgent* pageAgent, InjectedScriptManager* injectedScriptManager, InspectorOverlay* overlay)
     : InspectorDebuggerAgent(instrumentingAgents, inspectorState, injectedScriptManager)
-    , m_inspectedPage(inspectedPage)
+    , m_pageAgent(pageAgent)
     , m_overlay(overlay)
 {
 }
@@ -57,14 +59,26 @@ PageDebuggerAgent::~PageDebuggerAgent()
 {
 }
 
+void PageDebuggerAgent::enable(ErrorString* errorString)
+{
+    InspectorDebuggerAgent::enable(errorString);
+    m_instrumentingAgents->setPageDebuggerAgent(this);
+}
+
+void PageDebuggerAgent::disable(ErrorString* errorString)
+{
+    InspectorDebuggerAgent::disable(errorString);
+    m_instrumentingAgents->setPageDebuggerAgent(0);
+}
+
 void PageDebuggerAgent::startListeningScriptDebugServer()
 {
-    scriptDebugServer().addListener(this, m_inspectedPage);
+    scriptDebugServer().addListener(this, m_pageAgent->page());
 }
 
 void PageDebuggerAgent::stopListeningScriptDebugServer()
 {
-    scriptDebugServer().removeListener(this, m_inspectedPage);
+    scriptDebugServer().removeListener(this, m_pageAgent->page());
 }
 
 PageScriptDebugServer& PageDebuggerAgent::scriptDebugServer()
@@ -85,7 +99,7 @@ void PageDebuggerAgent::unmuteConsole()
 InjectedScript PageDebuggerAgent::injectedScriptForEval(ErrorString* errorString, const int* executionContextId)
 {
     if (!executionContextId) {
-        ScriptState* scriptState = mainWorldScriptState(m_inspectedPage->mainFrame());
+        ScriptState* scriptState = mainWorldScriptState(m_pageAgent->mainFrame());
         return injectedScriptManager()->injectedScriptFor(scriptState);
     }
     InjectedScript injectedScript = injectedScriptManager()->injectedScriptForId(*executionContextId);
@@ -99,6 +113,12 @@ void PageDebuggerAgent::setOverlayMessage(ErrorString*, const String* message)
     m_overlay->setPausedInDebuggerMessage(message);
 }
 
+void PageDebuggerAgent::didClearMainFrameWindowObject()
+{
+    reset();
+    scriptDebugServer().setScriptPreprocessor(m_pageAgent->scriptPreprocessor());
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(JAVASCRIPT_DEBUGGER) && ENABLE(INSPECTOR)
index 810052e..de38af7 100644 (file)
@@ -38,6 +38,7 @@
 namespace WebCore {
 
 class InspectorOverlay;
+class InspectorPageAgent;
 class Page;
 class PageScriptDebugServer;
 
@@ -45,9 +46,14 @@ class PageDebuggerAgent : public InspectorDebuggerAgent {
     WTF_MAKE_NONCOPYABLE(PageDebuggerAgent);
     WTF_MAKE_FAST_ALLOCATED;
 public:
-    static PassOwnPtr<PageDebuggerAgent> create(InstrumentingAgents*, InspectorState*, Page*, InjectedScriptManager*, InspectorOverlay*);
+    static PassOwnPtr<PageDebuggerAgent> create(InstrumentingAgents*, InspectorState*, InspectorPageAgent*, InjectedScriptManager*, InspectorOverlay*);
     virtual ~PageDebuggerAgent();
 
+    virtual void enable(ErrorString*);
+    virtual void disable(ErrorString*);
+
+    void didClearMainFrameWindowObject();
+
 private:
     virtual void startListeningScriptDebugServer();
     virtual void stopListeningScriptDebugServer();
@@ -58,8 +64,8 @@ private:
     virtual InjectedScript injectedScriptForEval(ErrorString*, const int* executionContextId);
     virtual void setOverlayMessage(ErrorString*, const String*);
 
-    PageDebuggerAgent(InstrumentingAgents*, InspectorState*, Page*, InjectedScriptManager*, InspectorOverlay*);
-    Page* const m_inspectedPage;
+    PageDebuggerAgent(InstrumentingAgents*, InspectorState*, InspectorPageAgent*, InjectedScriptManager*, InspectorOverlay*);
+    InspectorPageAgent* m_pageAgent;
     InspectorOverlay* m_overlay;
 };