Home | History | Annotate | Download | only in dom
      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