1 /* 2 * Copyright (C) 2008 Apple Inc. All Rights Reserved. 3 * Copyright (C) 2012 Google Inc. All Rights Reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * 26 */ 27 28 #ifndef ScriptExecutionContext_h 29 #define ScriptExecutionContext_h 30 31 #include "core/dom/ActiveDOMObject.h" 32 #include "core/dom/ErrorEvent.h" 33 #include "core/dom/SecurityContext.h" 34 #include "core/loader/CrossOriginAccessControl.h" 35 #include "core/page/ConsoleTypes.h" 36 #include "core/page/DOMTimer.h" 37 #include "core/platform/LifecycleContext.h" 38 #include "core/platform/Supplementable.h" 39 #include "weborigin/KURL.h" 40 #include "wtf/HashSet.h" 41 #include "wtf/OwnPtr.h" 42 #include "wtf/PassOwnPtr.h" 43 44 namespace WebCore { 45 46 class ContextLifecycleNotifier; 47 class DOMWindow; 48 class DatabaseContext; 49 class EventListener; 50 class EventQueue; 51 class EventTarget; 52 class MessagePort; 53 class PublicURLManager; 54 class ScriptCallStack; 55 class ScriptState; 56 57 class ScriptExecutionContext : public LifecycleContext, public SecurityContext, public Supplementable<ScriptExecutionContext> { 58 public: 59 ScriptExecutionContext(); 60 virtual ~ScriptExecutionContext(); 61 62 virtual bool isDocument() const { return false; } 63 virtual bool isWorkerGlobalScope() const { return false; } 64 65 virtual bool isJSExecutionForbidden() const = 0; 66 67 virtual DOMWindow* executingWindow() { return 0; } 68 virtual void userEventWasHandled() { } 69 70 const KURL& url() const { return virtualURL(); } 71 KURL completeURL(const String& url) const { return virtualCompleteURL(url); } 72 73 virtual String userAgent(const KURL&) const = 0; 74 75 virtual void disableEval(const String& errorMessage) = 0; 76 77 bool shouldSanitizeScriptError(const String& sourceURL, AccessControlStatus); 78 void reportException(PassRefPtr<ErrorEvent>, PassRefPtr<ScriptCallStack>, AccessControlStatus); 79 80 void addConsoleMessage(MessageSource, MessageLevel, const String& message, const String& sourceURL, unsigned lineNumber, ScriptState* = 0, unsigned long requestIdentifier = 0); 81 virtual void addConsoleMessage(MessageSource, MessageLevel, const String& message, unsigned long requestIdentifier = 0) = 0; 82 83 PublicURLManager& publicURLManager(); 84 85 // Active objects are not garbage collected even if inaccessible, e.g. because their activity may result in callbacks being invoked. 86 bool canSuspendActiveDOMObjects(); 87 bool hasPendingActivity(); 88 89 // Active objects can be asked to suspend even if canSuspendActiveDOMObjects() returns 'false' - 90 // step-by-step JS debugging is one example. 91 virtual void suspendActiveDOMObjects(ActiveDOMObject::ReasonForSuspension); 92 virtual void resumeActiveDOMObjects(); 93 virtual void stopActiveDOMObjects(); 94 95 bool activeDOMObjectsAreSuspended() const { return m_activeDOMObjectsAreSuspended; } 96 bool activeDOMObjectsAreStopped() const { return m_activeDOMObjectsAreStopped; } 97 98 // Called after the construction of an ActiveDOMObject to synchronize suspend state. 99 void suspendActiveDOMObjectIfNeeded(ActiveDOMObject*); 100 101 // MessagePort is conceptually a kind of ActiveDOMObject, but it needs to be tracked separately for message dispatch. 102 void processMessagePortMessagesSoon(); 103 void dispatchMessagePortEvents(); 104 void createdMessagePort(MessagePort*); 105 void destroyedMessagePort(MessagePort*); 106 const HashSet<MessagePort*>& messagePorts() const { return m_messagePorts; } 107 108 void ref() { refScriptExecutionContext(); } 109 void deref() { derefScriptExecutionContext(); } 110 111 class Task { 112 WTF_MAKE_NONCOPYABLE(Task); 113 WTF_MAKE_FAST_ALLOCATED; 114 public: 115 Task() { } 116 virtual ~Task(); 117 virtual void performTask(ScriptExecutionContext*) = 0; 118 // Certain tasks get marked specially so that they aren't discarded, and are executed, when the context is shutting down its message queue. 119 virtual bool isCleanupTask() const { return false; } 120 }; 121 122 virtual void postTask(PassOwnPtr<Task>) = 0; // Executes the task on context's thread asynchronously. 123 124 // Gets the next id in a circular sequence from 1 to 2^31-1. 125 int circularSequentialID(); 126 127 void didChangeTimerAlignmentInterval(); 128 virtual double timerAlignmentInterval() const; 129 130 virtual EventQueue* eventQueue() const = 0; 131 132 void setDatabaseContext(DatabaseContext*); 133 134 protected: 135 class AddConsoleMessageTask : public Task { 136 public: 137 static PassOwnPtr<AddConsoleMessageTask> create(MessageSource source, MessageLevel level, const String& message) 138 { 139 return adoptPtr(new AddConsoleMessageTask(source, level, message)); 140 } 141 virtual void performTask(ScriptExecutionContext*); 142 private: 143 AddConsoleMessageTask(MessageSource source, MessageLevel level, const String& message) 144 : m_source(source) 145 , m_level(level) 146 , m_message(message.isolatedCopy()) 147 { 148 } 149 MessageSource m_source; 150 MessageLevel m_level; 151 String m_message; 152 }; 153 154 ContextLifecycleNotifier* lifecycleNotifier(); 155 156 private: 157 friend class DOMTimer; // For installNewTimeout() and removeTimeoutByID() below. 158 159 virtual const KURL& virtualURL() const = 0; 160 virtual KURL virtualCompleteURL(const String&) const = 0; 161 162 virtual void addMessage(MessageSource, MessageLevel, const String& message, const String& sourceURL, unsigned lineNumber, PassRefPtr<ScriptCallStack>, ScriptState* = 0, unsigned long requestIdentifier = 0) = 0; 163 virtual EventTarget* errorEventTarget() = 0; 164 virtual void logExceptionToConsole(const String& errorMessage, const String& sourceURL, int lineNumber, int columnNumber, PassRefPtr<ScriptCallStack>) = 0; 165 bool dispatchErrorEvent(PassRefPtr<ErrorEvent>, AccessControlStatus); 166 167 void closeMessagePorts(); 168 169 virtual void refScriptExecutionContext() = 0; 170 virtual void derefScriptExecutionContext() = 0; 171 virtual PassOwnPtr<LifecycleNotifier> createLifecycleNotifier() OVERRIDE; 172 173 // Implementation details for DOMTimer. No other classes should call these functions. 174 int installNewTimeout(PassOwnPtr<ScheduledAction>, int timeout, bool singleShot); 175 void removeTimeoutByID(int timeoutID); // This makes underlying DOMTimer instance destructed. 176 177 HashSet<MessagePort*> m_messagePorts; 178 179 int m_circularSequentialID; 180 typedef HashMap<int, OwnPtr<DOMTimer> > TimeoutMap; 181 TimeoutMap m_timeouts; 182 183 bool m_inDispatchErrorEvent; 184 class PendingException; 185 OwnPtr<Vector<OwnPtr<PendingException> > > m_pendingExceptions; 186 187 bool m_activeDOMObjectsAreSuspended; 188 ActiveDOMObject::ReasonForSuspension m_reasonForSuspendingActiveDOMObjects; 189 bool m_activeDOMObjectsAreStopped; 190 191 OwnPtr<PublicURLManager> m_publicURLManager; 192 193 RefPtr<DatabaseContext> m_databaseContext; 194 195 // The location of this member is important; to make sure contextDestroyed() notification on 196 // ScriptExecutionContext's members (notably m_timeouts) is called before they are destructed, 197 // m_lifecycleNotifer should be placed *after* such members. 198 OwnPtr<ContextLifecycleNotifier> m_lifecycleNotifier; 199 }; 200 201 } // namespace WebCore 202 203 #endif // ScriptExecutionContext_h 204