1/* 2 * Copyright (C) 1999 Harri Porten (porten@kde.org) 3 * Copyright (C) 2001 Peter Kelly (pmk@post.com) 4 * Copyright (C) 2008 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#ifndef ScriptController_h 23#define ScriptController_h 24 25#include "JSDOMWindowShell.h" 26#include "ScriptControllerBase.h" 27#include "ScriptInstance.h" 28#include <heap/Strong.h> 29#include <wtf/Forward.h> 30#include <wtf/RefPtr.h> 31 32#if PLATFORM(MAC) 33#include <wtf/RetainPtr.h> 34 35#ifdef __OBJC__ 36@class WebScriptObject; 37#else 38class WebScriptObject; 39#endif 40#endif 41 42struct NPObject; 43 44namespace JSC { 45 class JSGlobalObject; 46 47 namespace Bindings { 48 class RootObject; 49 } 50} 51 52namespace WebCore { 53 54class Event; 55class EventListener; 56class HTMLPlugInElement; 57class Frame; 58class Node; 59class ScriptSourceCode; 60class ScriptValue; 61class Widget; 62 63typedef HashMap<void*, RefPtr<JSC::Bindings::RootObject> > RootObjectMap; 64 65class ScriptController { 66 friend class ScriptCachedFrameData; 67 typedef WTF::HashMap< RefPtr<DOMWrapperWorld>, JSC::Strong<JSDOMWindowShell> > ShellMap; 68 69public: 70 ScriptController(Frame*); 71 ~ScriptController(); 72 73 static PassRefPtr<DOMWrapperWorld> createWorld(); 74 75 JSDOMWindowShell* createWindowShell(DOMWrapperWorld*); 76 void destroyWindowShell(DOMWrapperWorld*); 77 78 JSDOMWindowShell* windowShell(DOMWrapperWorld* world) 79 { 80 ShellMap::iterator iter = m_windowShells.find(world); 81 return (iter != m_windowShells.end()) ? iter->second.get() : initScript(world); 82 } 83 JSDOMWindowShell* existingWindowShell(DOMWrapperWorld* world) const 84 { 85 ShellMap::const_iterator iter = m_windowShells.find(world); 86 return (iter != m_windowShells.end()) ? iter->second.get() : 0; 87 } 88 JSDOMWindow* globalObject(DOMWrapperWorld* world) 89 { 90 return windowShell(world)->window(); 91 } 92 93 static void getAllWorlds(Vector<DOMWrapperWorld*>&); 94 95 ScriptValue executeScript(const ScriptSourceCode&); 96 ScriptValue executeScript(const String& script, bool forceUserGesture = false); 97 ScriptValue executeScriptInWorld(DOMWrapperWorld*, const String& script, bool forceUserGesture = false); 98 99 // Returns true if argument is a JavaScript URL. 100 bool executeIfJavaScriptURL(const KURL&, ShouldReplaceDocumentIfJavaScriptURL shouldReplaceDocumentIfJavaScriptURL = ReplaceDocumentIfJavaScriptURL); 101 102 // This function must be called from the main thread. It is safe to call it repeatedly. 103 // Darwin is an exception to this rule: it is OK to call this function from any thread, even reentrantly. 104 static void initializeThreading(); 105 106 ScriptValue evaluate(const ScriptSourceCode&); 107 ScriptValue evaluateInWorld(const ScriptSourceCode&, DOMWrapperWorld*); 108 109 int eventHandlerLineNumber() const; 110 111 void setProcessingTimerCallback(bool b) { m_processingTimerCallback = b; } 112 static bool processingUserGesture(); 113 bool anyPageIsProcessingUserGesture() const; 114 115 static bool canAccessFromCurrentOrigin(Frame*); 116 bool canExecuteScripts(ReasonForCallingCanExecuteScripts); 117 118 // Debugger can be 0 to detach any existing Debugger. 119 void attachDebugger(JSC::Debugger*); // Attaches/detaches in all worlds/window shells. 120 void attachDebugger(JSDOMWindowShell*, JSC::Debugger*); 121 122 void setPaused(bool b) { m_paused = b; } 123 bool isPaused() const { return m_paused; } 124 125 void setAllowPopupsFromPlugin(bool allowPopupsFromPlugin) { m_allowPopupsFromPlugin = allowPopupsFromPlugin; } 126 bool allowPopupsFromPlugin() const { return m_allowPopupsFromPlugin; } 127 128 const String* sourceURL() const { return m_sourceURL; } // 0 if we are not evaluating any script 129 130 void clearWindowShell(bool goingIntoPageCache = false); 131 void updateDocument(); 132 133 void namedItemAdded(HTMLDocument*, const AtomicString&) { } 134 void namedItemRemoved(HTMLDocument*, const AtomicString&) { } 135 136 // Notifies the ScriptController that the securityOrigin of the current 137 // document was modified. For example, this method is called when 138 // document.domain is set. This method is *not* called when a new document 139 // is attached to a frame because updateDocument() is called instead. 140 void updateSecurityOrigin(); 141 142 void clearScriptObjects(); 143 void cleanupScriptObjectsForPlugin(void*); 144 145 void updatePlatformScriptObjects(); 146 147 PassScriptInstance createScriptInstanceForWidget(Widget*); 148 JSC::Bindings::RootObject* bindingRootObject(); 149 JSC::Bindings::RootObject* cacheableBindingRootObject(); 150 151 PassRefPtr<JSC::Bindings::RootObject> createRootObject(void* nativeHandle); 152 153#if ENABLE(INSPECTOR) 154 static void setCaptureCallStackForUncaughtExceptions(bool); 155#endif 156 157#if PLATFORM(MAC) 158#if ENABLE(JAVA_BRIDGE) 159 static void initJavaJSBindings(); 160#endif 161 WebScriptObject* windowScriptObject(); 162#endif 163 164 JSC::JSObject* jsObjectForPluginElement(HTMLPlugInElement*); 165 166#if ENABLE(NETSCAPE_PLUGIN_API) 167 NPObject* createScriptObjectForPluginElement(HTMLPlugInElement*); 168 NPObject* windowScriptNPObject(); 169#endif 170 171private: 172 JSDOMWindowShell* initScript(DOMWrapperWorld* world); 173 174 void disconnectPlatformScriptObjects(); 175 176 bool isJavaScriptAnchorNavigation() const; 177 178 ShellMap m_windowShells; 179 Frame* m_frame; 180 const String* m_sourceURL; 181 182 bool m_inExecuteScript; 183 184 bool m_processingTimerCallback; 185 bool m_paused; 186 bool m_allowPopupsFromPlugin; 187 188 // The root object used for objects bound outside the context of a plugin, such 189 // as NPAPI plugins. The plugins using these objects prevent a page from being cached so they 190 // are safe to invalidate() when WebKit navigates away from the page that contains them. 191 RefPtr<JSC::Bindings::RootObject> m_bindingRootObject; 192 // Unlike m_bindingRootObject these objects are used in pages that are cached, so they are not invalidate()'d. 193 // This ensures they are still available when the page is restored. 194 RefPtr<JSC::Bindings::RootObject> m_cacheableBindingRootObject; 195 RootObjectMap m_rootObjects; 196#if ENABLE(NETSCAPE_PLUGIN_API) 197 NPObject* m_windowScriptNPObject; 198#endif 199#if PLATFORM(MAC) 200 RetainPtr<WebScriptObject> m_windowScriptObject; 201#endif 202}; 203 204} // namespace WebCore 205 206#endif // ScriptController_h 207