Clean up ScriptExecutionContext::Task and subclasses
[WebKit-https.git] / Source / WebCore / dom / ScriptExecutionContext.h
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 "ActiveDOMObject.h"
32 #include "ConsoleTypes.h"
33 #include "URL.h"
34 #include "SecurityContext.h"
35 #include "Supplementable.h"
36 #include <wtf/HashSet.h>
37
38 namespace JSC {
39 class ExecState;
40 class VM;
41 }
42
43 namespace WebCore {
44
45 class CachedScript;
46 class DatabaseContext;
47 class DOMTimer;
48 class EventListener;
49 class EventQueue;
50 class EventTarget;
51 class MessagePort;
52 class ScriptCallStack;
53
54 #if ENABLE(BLOB)
55 class PublicURLManager;
56 #endif
57
58 class ScriptExecutionContext : public SecurityContext, public Supplementable<ScriptExecutionContext> {
59 public:
60     ScriptExecutionContext();
61     virtual ~ScriptExecutionContext();
62
63     virtual bool isDocument() const { return false; }
64     virtual bool isWorkerGlobalScope() const { return false; }
65
66     virtual bool isContextThread() const { return true; }
67     virtual bool isJSExecutionForbidden() const = 0;
68
69     virtual const URL& url() const = 0;
70     virtual URL completeURL(const String& url) const = 0;
71
72     virtual String userAgent(const URL&) const = 0;
73
74     virtual void disableEval(const String& errorMessage) = 0;
75
76     bool sanitizeScriptError(String& errorMessage, int& lineNumber, int& columnNumber, String& sourceURL, CachedScript* = 0);
77     // FIXME: <http://webkit.org/b/114315> ScriptExecutionContext log exception should include a column number
78     void reportException(const String& errorMessage, int lineNumber, int columnNumber, const String& sourceURL, PassRefPtr<ScriptCallStack>, CachedScript* = 0);
79
80     void addConsoleMessage(MessageSource, MessageLevel, const String& message, const String& sourceURL, unsigned lineNumber, unsigned columnNumber, JSC::ExecState* = 0, unsigned long requestIdentifier = 0);
81     virtual void addConsoleMessage(MessageSource, MessageLevel, const String& message, unsigned long requestIdentifier = 0) = 0;
82
83     virtual SecurityOrigin* topOrigin() const = 0;
84
85 #if ENABLE(BLOB)
86     PublicURLManager& publicURLManager();
87 #endif
88     // Active objects are not garbage collected even if inaccessible, e.g. because their activity may result in callbacks being invoked.
89     bool canSuspendActiveDOMObjects();
90     // Active objects can be asked to suspend even if canSuspendActiveDOMObjects() returns 'false' -
91     // step-by-step JS debugging is one example.
92     virtual void suspendActiveDOMObjects(ActiveDOMObject::ReasonForSuspension);
93     virtual void resumeActiveDOMObjects(ActiveDOMObject::ReasonForSuspension);
94     virtual void stopActiveDOMObjects();
95
96     bool activeDOMObjectsAreSuspended() const { return m_activeDOMObjectsAreSuspended; }
97     bool activeDOMObjectsAreStopped() const { return m_activeDOMObjectsAreStopped; }
98
99     // Called from the constructor and destructors of ActiveDOMObject.
100     void didCreateActiveDOMObject(ActiveDOMObject*);
101     void willDestroyActiveDOMObject(ActiveDOMObject*);
102
103     // Called after the construction of an ActiveDOMObject to synchronize suspend state.
104     void suspendActiveDOMObjectIfNeeded(ActiveDOMObject*);
105
106     typedef HashSet<ActiveDOMObject*> ActiveDOMObjectsSet;
107     const ActiveDOMObjectsSet& activeDOMObjects() const { return m_activeDOMObjects; }
108
109     void didCreateDestructionObserver(ContextDestructionObserver*);
110     void willDestroyDestructionObserver(ContextDestructionObserver*);
111
112     // MessagePort is conceptually a kind of ActiveDOMObject, but it needs to be tracked separately for message dispatch.
113     void processMessagePortMessagesSoon();
114     void dispatchMessagePortEvents();
115     void createdMessagePort(MessagePort*);
116     void destroyedMessagePort(MessagePort*);
117     const HashSet<MessagePort*>& messagePorts() const { return m_messagePorts; }
118
119     void ref() { refScriptExecutionContext(); }
120     void deref() { derefScriptExecutionContext(); }
121
122     class Task {
123         WTF_MAKE_NONCOPYABLE(Task);
124         WTF_MAKE_FAST_ALLOCATED;
125     public:
126         Task() { }
127         virtual ~Task();
128         virtual void performTask(ScriptExecutionContext*) = 0;
129         // Certain tasks get marked specially so that they aren't discarded, and are executed, when the context is shutting down its message queue.
130         virtual bool isCleanupTask() const { return false; }
131     };
132
133     virtual void postTask(std::unique_ptr<Task>) = 0; // Executes the task on context's thread asynchronously.
134
135     // Gets the next id in a circular sequence from 1 to 2^31-1.
136     int circularSequentialID();
137
138     bool addTimeout(int timeoutId, DOMTimer* timer) { return m_timeouts.add(timeoutId, timer).isNewEntry; }
139     void removeTimeout(int timeoutId) { m_timeouts.remove(timeoutId); }
140     DOMTimer* findTimeout(int timeoutId) { return m_timeouts.get(timeoutId); }
141
142     JSC::VM* vm();
143
144     // Interval is in seconds.
145     void adjustMinimumTimerInterval(double oldMinimumTimerInterval);
146     virtual double minimumTimerInterval() const;
147
148     void didChangeTimerAlignmentInterval();
149     virtual double timerAlignmentInterval() const;
150
151     virtual EventQueue& eventQueue() const = 0;
152
153 #if ENABLE(SQL_DATABASE)
154     void setDatabaseContext(DatabaseContext*);
155 #endif
156
157 protected:
158     class AddConsoleMessageTask : public Task {
159     public:
160         AddConsoleMessageTask(MessageSource source, MessageLevel level, const String& message)
161             : m_source(source)
162             , m_level(level)
163             , m_message(message.isolatedCopy())
164         {
165         }
166
167         virtual void performTask(ScriptExecutionContext*) OVERRIDE;
168
169         MessageSource m_source;
170         MessageLevel m_level;
171         String m_message;
172     };
173
174     ActiveDOMObject::ReasonForSuspension reasonForSuspendingActiveDOMObjects() const { return m_reasonForSuspendingActiveDOMObjects; }
175
176 private:
177     virtual void addMessage(MessageSource, MessageLevel, const String& message, const String& sourceURL, unsigned lineNumber, unsigned columnNumber, PassRefPtr<ScriptCallStack>, JSC::ExecState* = 0, unsigned long requestIdentifier = 0) = 0;
178     virtual EventTarget* errorEventTarget() = 0;
179     virtual void logExceptionToConsole(const String& errorMessage, const String& sourceURL, int lineNumber, int columnNumber, PassRefPtr<ScriptCallStack>) = 0;
180     bool dispatchErrorEvent(const String& errorMessage, int lineNumber, int columnNumber, const String& sourceURL, CachedScript*);
181
182     void closeMessagePorts();
183
184     virtual void refScriptExecutionContext() = 0;
185     virtual void derefScriptExecutionContext() = 0;
186
187     HashSet<MessagePort*> m_messagePorts;
188     HashSet<ContextDestructionObserver*> m_destructionObservers;
189     ActiveDOMObjectsSet m_activeDOMObjects;
190     bool m_iteratingActiveDOMObjects;
191     bool m_inDestructor;
192
193     int m_circularSequentialID;
194     typedef HashMap<int, DOMTimer*> TimeoutMap;
195     TimeoutMap m_timeouts;
196
197     bool m_inDispatchErrorEvent;
198     class PendingException;
199     OwnPtr<Vector<OwnPtr<PendingException> > > m_pendingExceptions;
200
201     bool m_activeDOMObjectsAreSuspended;
202     ActiveDOMObject::ReasonForSuspension m_reasonForSuspendingActiveDOMObjects;
203     bool m_activeDOMObjectsAreStopped;
204
205 #if ENABLE(BLOB)
206     OwnPtr<PublicURLManager> m_publicURLManager;
207 #endif
208
209 #if ENABLE(SQL_DATABASE)
210     RefPtr<DatabaseContext> m_databaseContext;
211 #endif
212 };
213
214 } // namespace WebCore
215
216 #endif // ScriptExecutionContext_h