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 "bindings/v8/ScriptInstance.h" 35 #include "bindings/v8/ScriptValue.h" 36 37 #include "core/loader/CrossOriginAccessControl.h" 38 #include "wtf/Forward.h" 39 #include "wtf/HashMap.h" 40 #include "wtf/RefCounted.h" 41 #include "wtf/Vector.h" 42 #include "wtf/text/TextPosition.h" 43 #include <v8.h> 44 45 struct NPObject; 46 47 namespace WebCore { 48 49 class DOMWrapperWorld; 50 class Event; 51 class Frame; 52 class HTMLDocument; 53 class HTMLPlugInElement; 54 class KURL; 55 class ScriptSourceCode; 56 class ScriptState; 57 class SecurityOrigin; 58 class V8WindowShell; 59 class Widget; 60 61 typedef WTF::Vector<v8::Extension*> V8Extensions; 62 63 enum ReasonForCallingCanExecuteScripts { 64 AboutToExecuteScript, 65 NotAboutToExecuteScript 66 }; 67 68 enum IsolatedWorldConstants { 69 EmbedderWorldIdLimit = (1 << 29) 70 }; 71 72 class ScriptController { 73 public: 74 ScriptController(Frame*); 75 ~ScriptController(); 76 77 bool initializeMainWorld(); 78 V8WindowShell* windowShell(DOMWrapperWorld*); 79 V8WindowShell* existingWindowShell(DOMWrapperWorld*); 80 81 ScriptValue executeScript(const ScriptSourceCode&); 82 ScriptValue executeScript(const String& script, bool forceUserGesture = false); 83 84 // Evaluate JavaScript in the main world. 85 ScriptValue executeScriptInMainWorld(const ScriptSourceCode&, AccessControlStatus = NotSharableCrossOrigin); 86 87 // Executes JavaScript in an isolated world. The script gets its own global scope, 88 // its own prototypes for intrinsic JavaScript objects (String, Array, and so-on), 89 // and its own wrappers for all DOM nodes and DOM constructors. 90 // 91 // If an isolated world with the specified ID already exists, it is reused. 92 // Otherwise, a new world is created. 93 // 94 // FIXME: Get rid of extensionGroup here. 95 void executeScriptInIsolatedWorld(int worldID, const Vector<ScriptSourceCode>& sources, int extensionGroup, Vector<ScriptValue>* results); 96 97 // Returns true if argument is a JavaScript URL. 98 bool executeScriptIfJavaScriptURL(const KURL&); 99 100 v8::Local<v8::Value> compileAndRunScript(const ScriptSourceCode&, AccessControlStatus = NotSharableCrossOrigin); 101 102 v8::Local<v8::Value> callFunction(v8::Handle<v8::Function>, v8::Handle<v8::Object>, int argc, v8::Handle<v8::Value> argv[]); 103 ScriptValue callFunctionEvenIfScriptDisabled(v8::Handle<v8::Function>, v8::Handle<v8::Object>, int argc, v8::Handle<v8::Value> argv[]); 104 static v8::Local<v8::Value> callFunctionWithInstrumentation(ScriptExecutionContext*, v8::Handle<v8::Function>, v8::Handle<v8::Object> receiver, int argc, v8::Handle<v8::Value> args[]); 105 106 // Returns true if the current world is isolated, and has its own Content 107 // Security Policy. In this case, the policy of the main world should be 108 // ignored when evaluating resources injected into the DOM. 109 bool shouldBypassMainWorldContentSecurityPolicy(); 110 111 // Creates a property of the global object of a frame. 112 void bindToWindowObject(Frame*, const String& key, NPObject*); 113 114 PassScriptInstance createScriptInstanceForWidget(Widget*); 115 116 void enableEval(); 117 void disableEval(const String& errorMessage); 118 119 static bool canAccessFromCurrentOrigin(Frame*); 120 121 static void setCaptureCallStackForUncaughtExceptions(bool); 122 void collectIsolatedContexts(Vector<std::pair<ScriptState*, SecurityOrigin*> >&); 123 124 bool canExecuteScripts(ReasonForCallingCanExecuteScripts); 125 126 // Returns V8 Context. If none exists, creates a new context. 127 // It is potentially slow and consumes memory. 128 static v8::Local<v8::Context> mainWorldContext(Frame*); 129 v8::Local<v8::Context> mainWorldContext(); 130 v8::Local<v8::Context> currentWorldContext(); 131 132 TextPosition eventHandlerPosition() const; 133 134 static bool processingUserGesture(); 135 136 void setPaused(bool paused) { m_paused = paused; } 137 bool isPaused() const { return m_paused; } 138 139 const String* sourceURL() const { return m_sourceURL; } // 0 if we are not evaluating any script. 140 141 void clearWindowShell(); 142 void updateDocument(); 143 144 void namedItemAdded(HTMLDocument*, const AtomicString&); 145 void namedItemRemoved(HTMLDocument*, const AtomicString&); 146 147 void updateSecurityOrigin(); 148 void clearScriptObjects(); 149 void cleanupScriptObjectsForPlugin(Widget*); 150 151 void clearForClose(); 152 void clearForOutOfMemory(); 153 154 NPObject* createScriptObjectForPluginElement(HTMLPlugInElement*); 155 NPObject* windowScriptNPObject(); 156 157 // Registers a v8 extension to be available on webpages. Will only 158 // affect v8 contexts initialized after this call. Takes ownership of 159 // the v8::Extension object passed. 160 static void registerExtensionIfNeeded(v8::Extension*); 161 static V8Extensions& registeredExtensions(); 162 163 bool setContextDebugId(int); 164 static int contextDebugId(v8::Handle<v8::Context>); 165 166 private: 167 typedef HashMap<int, OwnPtr<V8WindowShell> > IsolatedWorldMap; 168 typedef HashMap<Widget*, NPObject*> PluginObjectMap; 169 170 void clearForClose(bool destroyGlobal); 171 172 Frame* m_frame; 173 const String* m_sourceURL; 174 v8::Isolate* m_isolate; 175 176 OwnPtr<V8WindowShell> m_windowShell; 177 IsolatedWorldMap m_isolatedWorlds; 178 179 bool m_paused; 180 181 // A mapping between Widgets and their corresponding script object. 182 // This list is used so that when the plugin dies, we can immediately 183 // invalidate all sub-objects which are associated with that plugin. 184 // The frame keeps a NPObject reference for each item on the list. 185 PluginObjectMap m_pluginObjects; 186 187 NPObject* m_windowScriptNPObject; 188 }; 189 190 } // namespace WebCore 191 192 #endif // ScriptController_h 193