Web Inspector: Page: re-add enable/disable after r248454
[WebKit-https.git] / Source / WebCore / inspector / agents / page / PageRuntimeAgent.cpp
1 /*
2  * Copyright (C) 2011 Google Inc. All rights reserved.
3  * Copyright (C) 2015 Apple Inc. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
9  *     * Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  *     * Redistributions in binary form must reproduce the above
12  * copyright notice, this list of conditions and the following disclaimer
13  * in the documentation and/or other materials provided with the
14  * distribution.
15  *     * Neither the name of Google Inc. nor the names of its
16  * contributors may be used to endorse or promote products derived from
17  * this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31
32 #include "config.h"
33 #include "PageRuntimeAgent.h"
34
35 #include "Chrome.h"
36 #include "ChromeClient.h"
37 #include "Document.h"
38 #include "Frame.h"
39 #include "InspectorPageAgent.h"
40 #include "InstrumentingAgents.h"
41 #include "JSDOMWindowBase.h"
42 #include "Page.h"
43 #include "PageConsoleClient.h"
44 #include "ScriptController.h"
45 #include "ScriptState.h"
46 #include "SecurityOrigin.h"
47 #include "UserGestureIndicator.h"
48 #include <JavaScriptCore/InjectedScript.h>
49 #include <JavaScriptCore/InjectedScriptManager.h>
50
51 using Inspector::Protocol::Runtime::ExecutionContextDescription;
52
53
54 namespace WebCore {
55
56 using namespace Inspector;
57
58 PageRuntimeAgent::PageRuntimeAgent(PageAgentContext& context)
59     : InspectorRuntimeAgent(context)
60     , m_frontendDispatcher(makeUnique<Inspector::RuntimeFrontendDispatcher>(context.frontendRouter))
61     , m_backendDispatcher(Inspector::RuntimeBackendDispatcher::create(context.backendDispatcher, this))
62     , m_instrumentingAgents(context.instrumentingAgents)
63     , m_inspectedPage(context.inspectedPage)
64 {
65 }
66
67 void PageRuntimeAgent::enable(ErrorString& errorString)
68 {
69     bool enabled = m_instrumentingAgents.pageRuntimeAgent() == this;
70
71     InspectorRuntimeAgent::enable(errorString);
72
73     m_instrumentingAgents.setPageRuntimeAgent(this);
74
75     if (!enabled)
76         reportExecutionContextCreation();
77 }
78
79 void PageRuntimeAgent::disable(ErrorString& errorString)
80 {
81     m_instrumentingAgents.setPageRuntimeAgent(nullptr);
82
83     InspectorRuntimeAgent::disable(errorString);
84 }
85
86 void PageRuntimeAgent::didCreateMainWorldContext(Frame& frame)
87 {
88     auto* pageAgent = m_instrumentingAgents.inspectorPageAgent();
89     if (!pageAgent)
90         return;
91
92     auto frameId = pageAgent->frameId(&frame);
93     auto* scriptState = mainWorldExecState(&frame);
94     notifyContextCreated(frameId, scriptState, nullptr, true);
95 }
96
97 InjectedScript PageRuntimeAgent::injectedScriptForEval(ErrorString& errorString, const int* executionContextId)
98 {
99     if (!executionContextId) {
100         JSC::ExecState* scriptState = mainWorldExecState(&m_inspectedPage.mainFrame());
101         InjectedScript result = injectedScriptManager().injectedScriptFor(scriptState);
102         if (result.hasNoValue())
103             errorString = "Internal error: main world execution context not found."_s;
104         return result;
105     }
106
107     InjectedScript injectedScript = injectedScriptManager().injectedScriptForId(*executionContextId);
108     if (injectedScript.hasNoValue())
109         errorString = "Execution context with given id not found."_s;
110     return injectedScript;
111 }
112
113 void PageRuntimeAgent::muteConsole()
114 {
115     PageConsoleClient::mute();
116 }
117
118 void PageRuntimeAgent::unmuteConsole()
119 {
120     PageConsoleClient::unmute();
121 }
122
123 void PageRuntimeAgent::reportExecutionContextCreation()
124 {
125     auto* pageAgent = m_instrumentingAgents.inspectorPageAgent();
126     if (!pageAgent)
127         return;
128
129     Vector<std::pair<JSC::ExecState*, SecurityOrigin*>> isolatedContexts;
130     for (Frame* frame = &m_inspectedPage.mainFrame(); frame; frame = frame->tree().traverseNext()) {
131         if (!frame->script().canExecuteScripts(NotAboutToExecuteScript))
132             continue;
133
134         String frameId = pageAgent->frameId(frame);
135
136         JSC::ExecState* scriptState = mainWorldExecState(frame);
137         notifyContextCreated(frameId, scriptState, nullptr, true);
138         frame->script().collectIsolatedContexts(isolatedContexts);
139         if (isolatedContexts.isEmpty())
140             continue;
141         for (auto& context : isolatedContexts)
142             notifyContextCreated(frameId, context.first, context.second, false);
143         isolatedContexts.clear();
144     }
145 }
146
147 void PageRuntimeAgent::notifyContextCreated(const String& frameId, JSC::ExecState* scriptState, SecurityOrigin* securityOrigin, bool isPageContext)
148 {
149     ASSERT(securityOrigin || isPageContext);
150
151     InjectedScript result = injectedScriptManager().injectedScriptFor(scriptState);
152     if (result.hasNoValue())
153         return;
154
155     int executionContextId = injectedScriptManager().injectedScriptIdFor(scriptState);
156     String name = securityOrigin ? securityOrigin->toRawString() : String();
157     m_frontendDispatcher->executionContextCreated(ExecutionContextDescription::create()
158         .setId(executionContextId)
159         .setIsPageContext(isPageContext)
160         .setName(name)
161         .setFrameId(frameId)
162         .release());
163 }
164
165 void PageRuntimeAgent::evaluate(ErrorString& errorString, const String& expression, const String* objectGroup, const bool* includeCommandLineAPI, const bool* doNotPauseOnExceptionsAndMuteConsole, const int* executionContextId, const bool* returnByValue, const bool* generatePreview, const bool* saveResult, const bool* emulateUserGesture, RefPtr<Inspector::Protocol::Runtime::RemoteObject>& result, Optional<bool>& wasThrown, Optional<int>& savedResultIndex)
166 {
167     auto& pageChromeClient = m_inspectedPage.chrome().client();
168
169     auto shouldEmulateUserGesture = emulateUserGesture && *emulateUserGesture;
170
171     Optional<ProcessingUserGestureState> userGestureState = shouldEmulateUserGesture ? Optional<ProcessingUserGestureState>(ProcessingUserGesture) : WTF::nullopt;
172     UserGestureIndicator gestureIndicator(userGestureState);
173
174     bool userWasInteracting = false;
175     if (shouldEmulateUserGesture) {
176         userWasInteracting = pageChromeClient.userIsInteracting();
177         if (!userWasInteracting)
178             pageChromeClient.setUserIsInteracting(true);
179     }
180
181     InspectorRuntimeAgent::evaluate(errorString, expression, objectGroup, includeCommandLineAPI, doNotPauseOnExceptionsAndMuteConsole, executionContextId, returnByValue, generatePreview, saveResult, emulateUserGesture, result, wasThrown, savedResultIndex);
182
183     if (shouldEmulateUserGesture && !userWasInteracting && pageChromeClient.userIsInteracting())
184         pageChromeClient.setUserIsInteracting(false);
185 }
186
187 } // namespace WebCore