Web Inspector: InspectorFrontendAPIDispatcher should not ignore all exceptions
[WebKit-https.git] / Source / WebCore / bindings / js / ScriptController.h
1 /*
2  *  Copyright (C) 1999 Harri Porten (porten@kde.org)
3  *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
4  *  Copyright (C) 2008-2019 Apple Inc. All rights reserved.
5  *  Copyright (C) 2008 Eric Seidel <eric@webkit.org>
6  *
7  *  This library is free software; you can redistribute it and/or
8  *  modify it under the terms of the GNU Lesser General Public
9  *  License as published by the Free Software Foundation; either
10  *  version 2 of the License, or (at your option) any later version.
11  *
12  *  This library is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  *  Lesser General Public License for more details.
16  *
17  *  You should have received a copy of the GNU Lesser General Public
18  *  License along with this library; if not, write to the Free Software
19  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
20  */
21
22 #pragma once
23
24 #include "FrameLoaderTypes.h"
25 #include "JSWindowProxy.h"
26 #include "SerializedScriptValue.h"
27 #include "WindowProxy.h"
28 #include <JavaScriptCore/JSBase.h>
29 #include <JavaScriptCore/Strong.h>
30 #include <wtf/Forward.h>
31 #include <wtf/Optional.h>
32 #include <wtf/RefPtr.h>
33 #include <wtf/WeakPtr.h>
34 #include <wtf/text/TextPosition.h>
35
36 #if PLATFORM(COCOA)
37 #include <wtf/RetainPtr.h>
38 OBJC_CLASS JSContext;
39 OBJC_CLASS WebScriptObject;
40 #endif
41
42 struct NPObject;
43
44 namespace JSC {
45 class CallFrame;
46 class JSGlobalObject;
47 class JSInternalPromise;
48 class JSModuleRecord;
49
50 namespace Bindings {
51 class Instance;
52 class RootObject;
53 }
54 }
55
56 namespace WebCore {
57
58 class CachedScriptFetcher;
59 class Frame;
60 class HTMLDocument;
61 class HTMLPlugInElement;
62 class LoadableModuleScript;
63 class ModuleFetchParameters;
64 class ScriptSourceCode;
65 class SecurityOrigin;
66 class Widget;
67
68 enum class RunAsAsyncFunction : bool;
69
70 struct ExceptionDetails;
71 struct RunJavaScriptParameters;
72
73 enum ReasonForCallingCanExecuteScripts {
74     AboutToCreateEventListener,
75     AboutToExecuteScript,
76     NotAboutToExecuteScript
77 };
78
79 using ValueOrException = Expected<JSC::JSValue, ExceptionDetails>;
80
81 class ScriptController : public CanMakeWeakPtr<ScriptController> {
82     WTF_MAKE_FAST_ALLOCATED;
83
84     using RootObjectMap = HashMap<void*, Ref<JSC::Bindings::RootObject>>;
85
86 public:
87     explicit ScriptController(Frame&);
88     ~ScriptController();
89
90     enum class WorldType { User, Internal };
91     WEBCORE_EXPORT static Ref<DOMWrapperWorld> createWorld(const String& name, WorldType = WorldType::Internal);
92
93     JSDOMWindow* globalObject(DOMWrapperWorld& world)
94     {
95         return JSC::jsCast<JSDOMWindow*>(jsWindowProxy(world).window());
96     }
97
98     static void getAllWorlds(Vector<Ref<DOMWrapperWorld>>&);
99
100     using ResolveFunction = CompletionHandler<void(ValueOrException)>;
101
102     WEBCORE_EXPORT JSC::JSValue executeScriptIgnoringException(const String& script, bool forceUserGesture = false);
103     WEBCORE_EXPORT JSC::JSValue executeScriptInWorldIgnoringException(DOMWrapperWorld&, const String& script, bool forceUserGesture = false);
104     WEBCORE_EXPORT JSC::JSValue executeUserAgentScriptInWorldIgnoringException(DOMWrapperWorld&, const String& script, bool forceUserGesture);
105     WEBCORE_EXPORT ValueOrException executeUserAgentScriptInWorld(DOMWrapperWorld&, const String& script, bool forceUserGesture);
106     WEBCORE_EXPORT void executeAsynchronousUserAgentScriptInWorld(DOMWrapperWorld&, RunJavaScriptParameters&&, ResolveFunction&&);
107     ValueOrException evaluateInWorld(const ScriptSourceCode&, DOMWrapperWorld&);
108     JSC::JSValue evaluateIgnoringException(const ScriptSourceCode&);
109     JSC::JSValue evaluateInWorldIgnoringException(const ScriptSourceCode&, DOMWrapperWorld&);
110
111     Expected<void, ExceptionDetails> shouldAllowUserAgentScripts(Document&) const;
112
113     // This asserts that URL argument is a JavaScript URL.
114     void executeJavaScriptURL(const URL&, RefPtr<SecurityOrigin> = nullptr, ShouldReplaceDocumentIfJavaScriptURL = ReplaceDocumentIfJavaScriptURL);
115
116     static void initializeMainThread();
117
118     void loadModuleScriptInWorld(LoadableModuleScript&, const String& moduleName, Ref<ModuleFetchParameters>&&, DOMWrapperWorld&);
119     void loadModuleScript(LoadableModuleScript&, const String& moduleName, Ref<ModuleFetchParameters>&&);
120     void loadModuleScriptInWorld(LoadableModuleScript&, const ScriptSourceCode&, DOMWrapperWorld&);
121     void loadModuleScript(LoadableModuleScript&, const ScriptSourceCode&);
122
123     JSC::JSValue linkAndEvaluateModuleScriptInWorld(LoadableModuleScript& , DOMWrapperWorld&);
124     JSC::JSValue linkAndEvaluateModuleScript(LoadableModuleScript&);
125
126     JSC::JSValue evaluateModule(const URL&, JSC::JSModuleRecord&, DOMWrapperWorld&);
127     JSC::JSValue evaluateModule(const URL&, JSC::JSModuleRecord&);
128
129     WTF::TextPosition eventHandlerPosition() const;
130
131     void enableEval();
132     void enableWebAssembly();
133     void disableEval(const String& errorMessage);
134     void disableWebAssembly(const String& errorMessage);
135
136     static bool canAccessFromCurrentOrigin(Frame*, Document& accessingDocument);
137     WEBCORE_EXPORT bool canExecuteScripts(ReasonForCallingCanExecuteScripts);
138
139     void setPaused(bool b) { m_paused = b; }
140     bool isPaused() const { return m_paused; }
141
142     const URL* sourceURL() const { return m_sourceURL; } // nullptr if we are not evaluating any script
143
144     void updateDocument();
145
146     void namedItemAdded(HTMLDocument*, const AtomString&) { }
147     void namedItemRemoved(HTMLDocument*, const AtomString&) { }
148
149     void clearScriptObjects();
150     WEBCORE_EXPORT void cleanupScriptObjectsForPlugin(void*);
151
152     void updatePlatformScriptObjects();
153
154     RefPtr<JSC::Bindings::Instance>  createScriptInstanceForWidget(Widget*);
155     WEBCORE_EXPORT JSC::Bindings::RootObject* bindingRootObject();
156     JSC::Bindings::RootObject* cacheableBindingRootObject();
157     JSC::Bindings::RootObject* existingCacheableBindingRootObject() const { return m_cacheableBindingRootObject.get(); }
158
159     WEBCORE_EXPORT Ref<JSC::Bindings::RootObject> createRootObject(void* nativeHandle);
160
161     void collectIsolatedContexts(Vector<std::pair<JSC::JSGlobalObject*, SecurityOrigin*>>&);
162
163 #if PLATFORM(COCOA)
164     WEBCORE_EXPORT WebScriptObject* windowScriptObject();
165     WEBCORE_EXPORT JSContext *javaScriptContext();
166 #endif
167
168     WEBCORE_EXPORT JSC::JSObject* jsObjectForPluginElement(HTMLPlugInElement*);
169     
170 #if ENABLE(NETSCAPE_PLUGIN_API)
171     WEBCORE_EXPORT NPObject* windowScriptNPObject();
172 #endif
173
174     void initScriptForWindowProxy(JSWindowProxy&);
175
176     bool willReplaceWithResultOfExecutingJavascriptURL() const { return m_willReplaceWithResultOfExecutingJavascriptURL; }
177
178 private:
179     ValueOrException executeUserAgentScriptInWorldInternal(DOMWrapperWorld&, RunJavaScriptParameters&&);
180     ValueOrException executeScriptInWorld(DOMWrapperWorld&, RunJavaScriptParameters&&);
181     ValueOrException callInWorld(RunJavaScriptParameters&&, DOMWrapperWorld&);
182     
183     void setupModuleScriptHandlers(LoadableModuleScript&, JSC::JSInternalPromise&, DOMWrapperWorld&);
184
185     void disconnectPlatformScriptObjects();
186
187     WEBCORE_EXPORT WindowProxy& windowProxy();
188     WEBCORE_EXPORT JSWindowProxy& jsWindowProxy(DOMWrapperWorld&);
189
190     Frame& m_frame;
191     const URL* m_sourceURL { nullptr };
192
193     bool m_paused;
194     bool m_willReplaceWithResultOfExecutingJavascriptURL { false };
195
196     // The root object used for objects bound outside the context of a plugin, such
197     // as NPAPI plugins. The plugins using these objects prevent a page from being cached so they
198     // are safe to invalidate() when WebKit navigates away from the page that contains them.
199     RefPtr<JSC::Bindings::RootObject> m_bindingRootObject;
200     // Unlike m_bindingRootObject these objects are used in pages that are cached, so they are not invalidate()'d.
201     // This ensures they are still available when the page is restored.
202     RefPtr<JSC::Bindings::RootObject> m_cacheableBindingRootObject;
203     RootObjectMap m_rootObjects;
204 #if ENABLE(NETSCAPE_PLUGIN_API)
205     NPObject* m_windowScriptNPObject;
206 #endif
207 #if PLATFORM(COCOA)
208     RetainPtr<WebScriptObject> m_windowScriptObject;
209 #endif
210 };
211
212 } // namespace WebCore