1 /* 2 * Copyright (C) 2008, 2009 Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above 11 * copyright notice, this list of conditions and the following disclaimer 12 * in the documentation and/or other materials provided with the 13 * distribution. 14 * * Neither the name of Google Inc. nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #ifndef ScriptController_h 32 #define ScriptController_h 33 34 #include "ScriptControllerBase.h" 35 #include "ScriptInstance.h" 36 #include "ScriptValue.h" 37 38 #include "V8Proxy.h" 39 40 #include <v8.h> 41 42 #include <wtf/Forward.h> 43 #include <wtf/HashMap.h> 44 #include <wtf/RefCounted.h> 45 #include <wtf/Vector.h> 46 47 #if PLATFORM(QT) 48 #include <qglobal.h> 49 QT_BEGIN_NAMESPACE 50 class QScriptEngine; 51 QT_END_NAMESPACE 52 #endif 53 54 struct NPObject; 55 56 namespace WebCore { 57 58 class DOMWrapperWorld; 59 class Event; 60 class Frame; 61 class HTMLPlugInElement; 62 class ScriptSourceCode; 63 class Widget; 64 65 class ScriptController { 66 public: 67 ScriptController(Frame*); 68 ~ScriptController(); 69 70 // FIXME: V8Proxy should either be folded into ScriptController 71 // or this accessor should be made JSProxy* 72 V8Proxy* proxy() { return m_proxy.get(); } 73 74 ScriptValue executeScript(const ScriptSourceCode&); 75 ScriptValue executeScript(const String& script, bool forceUserGesture = false); 76 77 // Returns true if argument is a JavaScript URL. 78 bool executeIfJavaScriptURL(const KURL&, ShouldReplaceDocumentIfJavaScriptURL shouldReplaceDocumentIfJavaScriptURL = ReplaceDocumentIfJavaScriptURL); 79 80 // This function must be called from the main thread. It is safe to call it repeatedly. 81 static void initializeThreading(); 82 83 // Evaluate a script file in the environment of this proxy. 84 // If succeeded, 'succ' is set to true and result is returned 85 // as a string. 86 ScriptValue evaluate(const ScriptSourceCode&); 87 88 void evaluateInIsolatedWorld(unsigned worldID, const Vector<ScriptSourceCode>&); 89 90 // Executes JavaScript in an isolated world. The script gets its own global scope, 91 // its own prototypes for intrinsic JavaScript objects (String, Array, and so-on), 92 // and its own wrappers for all DOM nodes and DOM constructors. 93 // 94 // If an isolated world with the specified ID already exists, it is reused. 95 // Otherwise, a new world is created. 96 // 97 // If the worldID is 0, a new world is always created. 98 // 99 // FIXME: Get rid of extensionGroup here. 100 void evaluateInIsolatedWorld(unsigned worldID, const Vector<ScriptSourceCode>&, int extensionGroup); 101 102 // Masquerade 'this' as the windowShell. 103 // This is a bit of a hack, but provides reasonable compatibility 104 // with what JSC does as well. 105 ScriptController* windowShell(DOMWrapperWorld*) { return this; } 106 ScriptController* existingWindowShell(DOMWrapperWorld*) { return this; } 107 108 void collectGarbage(); 109 110 // Notify V8 that the system is running low on memory. 111 void lowMemoryNotification(); 112 113 // Creates a property of the global object of a frame. 114 void bindToWindowObject(Frame*, const String& key, NPObject*); 115 116 PassScriptInstance createScriptInstanceForWidget(Widget*); 117 118 // Check if the javascript engine has been initialized. 119 bool haveInterpreter() const; 120 121 static bool canAccessFromCurrentOrigin(Frame*); 122 123 #if ENABLE(INSPECTOR) 124 static void setCaptureCallStackForUncaughtExceptions(bool); 125 #endif 126 127 bool canExecuteScripts(ReasonForCallingCanExecuteScripts); 128 129 // FIXME: void* is a compile hack. 130 void attachDebugger(void*); 131 132 // --- Static methods assume we are running VM in single thread, --- 133 // --- and there is only one VM instance. --- 134 135 // Returns the frame for the entered context. See comments in 136 // V8Proxy::retrieveFrameForEnteredContext() for more information. 137 static Frame* retrieveFrameForEnteredContext(); 138 139 // Returns the frame for the current context. See comments in 140 // V8Proxy::retrieveFrameForEnteredContext() for more information. 141 static Frame* retrieveFrameForCurrentContext(); 142 143 // Check whether it is safe to access a frame in another domain. 144 static bool isSafeScript(Frame*); 145 146 // Pass command-line flags to the JS engine. 147 static void setFlags(const char* string, int length); 148 149 void finishedWithEvent(Event*); 150 151 TextPosition0 eventHandlerPosition() const; 152 153 void setProcessingTimerCallback(bool processingTimerCallback) { m_processingTimerCallback = processingTimerCallback; } 154 // FIXME: Currently we don't use the parameter world at all. 155 // See http://trac.webkit.org/changeset/54182 156 static bool processingUserGesture(); 157 bool anyPageIsProcessingUserGesture() const; 158 159 void setPaused(bool paused) { m_paused = paused; } 160 bool isPaused() const { return m_paused; } 161 162 const String* sourceURL() const { return m_sourceURL; } // 0 if we are not evaluating any script. 163 164 void clearWindowShell(bool = false); 165 void updateDocument(); 166 167 void namedItemAdded(HTMLDocument*, const AtomicString&); 168 void namedItemRemoved(HTMLDocument*, const AtomicString&); 169 170 void updateSecurityOrigin(); 171 void clearScriptObjects(); 172 void updatePlatformScriptObjects(); 173 void cleanupScriptObjectsForPlugin(Widget*); 174 175 #if ENABLE(NETSCAPE_PLUGIN_API) 176 NPObject* createScriptObjectForPluginElement(HTMLPlugInElement*); 177 NPObject* windowScriptNPObject(); 178 #endif 179 180 #if PLATFORM(QT) 181 QScriptEngine* qtScriptEngine(); 182 #endif 183 184 // Dummy method to avoid a bunch of ifdef's in WebCore. 185 void evaluateInWorld(const ScriptSourceCode&, DOMWrapperWorld*); 186 static void getAllWorlds(Vector<DOMWrapperWorld*>& worlds); 187 188 void setAllowPopupsFromPlugin(bool allowPopupsFromPlugin) { m_allowPopupsFromPlugin = allowPopupsFromPlugin; } 189 bool allowPopupsFromPlugin() const { return m_allowPopupsFromPlugin; } 190 191 private: 192 Frame* m_frame; 193 const String* m_sourceURL; 194 195 bool m_inExecuteScript; 196 197 bool m_processingTimerCallback; 198 bool m_paused; 199 bool m_allowPopupsFromPlugin; 200 201 OwnPtr<V8Proxy> m_proxy; 202 typedef HashMap<Widget*, NPObject*> PluginObjectMap; 203 #if PLATFORM(QT) 204 OwnPtr<QScriptEngine> m_qtScriptEngine; 205 #endif 206 207 // A mapping between Widgets and their corresponding script object. 208 // This list is used so that when the plugin dies, we can immediately 209 // invalidate all sub-objects which are associated with that plugin. 210 // The frame keeps a NPObject reference for each item on the list. 211 PluginObjectMap m_pluginObjects; 212 #if ENABLE(NETSCAPE_PLUGIN_API) 213 NPObject* m_windowScriptNPObject; 214 #endif 215 }; 216 217 } // namespace WebCore 218 219 #endif // ScriptController_h 220