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 "WindowProxy.h" |
27 | #include <JavaScriptCore/JSBase.h> |
28 | #include <JavaScriptCore/Strong.h> |
29 | #include <wtf/Forward.h> |
30 | #include <wtf/RefPtr.h> |
31 | #include <wtf/WeakPtr.h> |
32 | #include <wtf/text/TextPosition.h> |
33 | |
34 | #if PLATFORM(COCOA) |
35 | #include <wtf/RetainPtr.h> |
36 | OBJC_CLASS JSContext; |
37 | OBJC_CLASS WebScriptObject; |
38 | #endif |
39 | |
40 | struct NPObject; |
41 | |
42 | namespace JSC { |
43 | class ExecState; |
44 | class JSGlobalObject; |
45 | class JSInternalPromise; |
46 | class JSModuleRecord; |
47 | |
48 | namespace Bindings { |
49 | class Instance; |
50 | class RootObject; |
51 | } |
52 | } |
53 | |
54 | namespace WebCore { |
55 | |
56 | class CachedScriptFetcher; |
57 | class Frame; |
58 | class HTMLDocument; |
59 | class HTMLPlugInElement; |
60 | class LoadableModuleScript; |
61 | class ModuleFetchParameters; |
62 | class ScriptSourceCode; |
63 | class SecurityOrigin; |
64 | class Widget; |
65 | struct ExceptionDetails; |
66 | |
67 | enum ReasonForCallingCanExecuteScripts { |
68 | AboutToCreateEventListener, |
69 | AboutToExecuteScript, |
70 | NotAboutToExecuteScript |
71 | }; |
72 | |
73 | class ScriptController : public CanMakeWeakPtr<ScriptController> { |
74 | WTF_MAKE_FAST_ALLOCATED; |
75 | |
76 | using RootObjectMap = HashMap<void*, Ref<JSC::Bindings::RootObject>>; |
77 | |
78 | public: |
79 | explicit ScriptController(Frame&); |
80 | ~ScriptController(); |
81 | |
82 | WEBCORE_EXPORT static Ref<DOMWrapperWorld> createWorld(); |
83 | |
84 | JSDOMWindow* globalObject(DOMWrapperWorld& world) |
85 | { |
86 | return JSC::jsCast<JSDOMWindow*>(jsWindowProxy(world).window()); |
87 | } |
88 | |
89 | static void getAllWorlds(Vector<Ref<DOMWrapperWorld>>&); |
90 | |
91 | JSC::JSValue executeScript(const ScriptSourceCode&, ExceptionDetails* = nullptr); |
92 | WEBCORE_EXPORT JSC::JSValue executeScript(const String& script, bool forceUserGesture = false, ExceptionDetails* = nullptr); |
93 | JSC::JSValue executeScriptInWorld(DOMWrapperWorld&, const String& script, bool forceUserGesture = false, ExceptionDetails* = nullptr); |
94 | WEBCORE_EXPORT JSC::JSValue executeUserAgentScriptInWorld(DOMWrapperWorld&, const String& script, bool forceUserGesture, ExceptionDetails* = nullptr); |
95 | |
96 | bool shouldAllowUserAgentScripts(Document&) const; |
97 | |
98 | // Returns true if argument is a JavaScript URL. |
99 | bool executeIfJavaScriptURL(const URL&, ShouldReplaceDocumentIfJavaScriptURL shouldReplaceDocumentIfJavaScriptURL = ReplaceDocumentIfJavaScriptURL); |
100 | |
101 | // This function must be called from the main thread. It is safe to call it repeatedly. |
102 | // Darwin is an exception to this rule: it is OK to call this function from any thread, even reentrantly. |
103 | static void initializeThreading(); |
104 | |
105 | JSC::JSValue evaluate(const ScriptSourceCode&, ExceptionDetails* = nullptr); |
106 | JSC::JSValue evaluateInWorld(const ScriptSourceCode&, DOMWrapperWorld&, ExceptionDetails* = nullptr); |
107 | |
108 | void loadModuleScriptInWorld(LoadableModuleScript&, const String& moduleName, Ref<ModuleFetchParameters>&&, DOMWrapperWorld&); |
109 | void loadModuleScript(LoadableModuleScript&, const String& moduleName, Ref<ModuleFetchParameters>&&); |
110 | void loadModuleScriptInWorld(LoadableModuleScript&, const ScriptSourceCode&, DOMWrapperWorld&); |
111 | void loadModuleScript(LoadableModuleScript&, const ScriptSourceCode&); |
112 | |
113 | JSC::JSValue linkAndEvaluateModuleScriptInWorld(LoadableModuleScript& , DOMWrapperWorld&); |
114 | JSC::JSValue linkAndEvaluateModuleScript(LoadableModuleScript&); |
115 | |
116 | JSC::JSValue evaluateModule(const URL&, JSC::JSModuleRecord&, DOMWrapperWorld&); |
117 | JSC::JSValue evaluateModule(const URL&, JSC::JSModuleRecord&); |
118 | |
119 | WTF::TextPosition eventHandlerPosition() const; |
120 | |
121 | void enableEval(); |
122 | void enableWebAssembly(); |
123 | void disableEval(const String& errorMessage); |
124 | void disableWebAssembly(const String& errorMessage); |
125 | |
126 | static bool canAccessFromCurrentOrigin(Frame*); |
127 | WEBCORE_EXPORT bool canExecuteScripts(ReasonForCallingCanExecuteScripts); |
128 | |
129 | void setPaused(bool b) { m_paused = b; } |
130 | bool isPaused() const { return m_paused; } |
131 | |
132 | const String* sourceURL() const { return m_sourceURL; } // 0 if we are not evaluating any script |
133 | |
134 | void updateDocument(); |
135 | |
136 | void namedItemAdded(HTMLDocument*, const AtomicString&) { } |
137 | void namedItemRemoved(HTMLDocument*, const AtomicString&) { } |
138 | |
139 | void clearScriptObjects(); |
140 | WEBCORE_EXPORT void cleanupScriptObjectsForPlugin(void*); |
141 | |
142 | void updatePlatformScriptObjects(); |
143 | |
144 | RefPtr<JSC::Bindings::Instance> createScriptInstanceForWidget(Widget*); |
145 | WEBCORE_EXPORT JSC::Bindings::RootObject* bindingRootObject(); |
146 | JSC::Bindings::RootObject* cacheableBindingRootObject(); |
147 | JSC::Bindings::RootObject* existingCacheableBindingRootObject() const { return m_cacheableBindingRootObject.get(); } |
148 | |
149 | WEBCORE_EXPORT Ref<JSC::Bindings::RootObject> createRootObject(void* nativeHandle); |
150 | |
151 | void collectIsolatedContexts(Vector<std::pair<JSC::ExecState*, SecurityOrigin*>>&); |
152 | |
153 | #if PLATFORM(COCOA) |
154 | WEBCORE_EXPORT WebScriptObject* windowScriptObject(); |
155 | WEBCORE_EXPORT JSContext *javaScriptContext(); |
156 | #endif |
157 | |
158 | WEBCORE_EXPORT JSC::JSObject* jsObjectForPluginElement(HTMLPlugInElement*); |
159 | |
160 | #if ENABLE(NETSCAPE_PLUGIN_API) |
161 | WEBCORE_EXPORT NPObject* windowScriptNPObject(); |
162 | #endif |
163 | |
164 | void initScriptForWindowProxy(JSWindowProxy&); |
165 | |
166 | private: |
167 | void setupModuleScriptHandlers(LoadableModuleScript&, JSC::JSInternalPromise&, DOMWrapperWorld&); |
168 | |
169 | void disconnectPlatformScriptObjects(); |
170 | |
171 | WEBCORE_EXPORT WindowProxy& windowProxy(); |
172 | WEBCORE_EXPORT JSWindowProxy& jsWindowProxy(DOMWrapperWorld&); |
173 | |
174 | Frame& m_frame; |
175 | const String* m_sourceURL; |
176 | |
177 | bool m_paused; |
178 | |
179 | // The root object used for objects bound outside the context of a plugin, such |
180 | // as NPAPI plugins. The plugins using these objects prevent a page from being cached so they |
181 | // are safe to invalidate() when WebKit navigates away from the page that contains them. |
182 | RefPtr<JSC::Bindings::RootObject> m_bindingRootObject; |
183 | // Unlike m_bindingRootObject these objects are used in pages that are cached, so they are not invalidate()'d. |
184 | // This ensures they are still available when the page is restored. |
185 | RefPtr<JSC::Bindings::RootObject> m_cacheableBindingRootObject; |
186 | RootObjectMap m_rootObjects; |
187 | #if ENABLE(NETSCAPE_PLUGIN_API) |
188 | NPObject* m_windowScriptNPObject; |
189 | #endif |
190 | #if PLATFORM(COCOA) |
191 | RetainPtr<WebScriptObject> m_windowScriptObject; |
192 | #endif |
193 | }; |
194 | |
195 | } // namespace WebCore |
196 | |