Move parseFontFaceDescriptor to CSSPropertyParser.cpp
[chromium-blink-merge.git] / third_party / WebKit / Source / core / dom / ExecutionContext.cpp
blobd7c503225059fccf0644153f1f681e25d157055f
1 /*
2 * Copyright (C) 2008 Apple Inc. All Rights Reserved.
3 * Copyright (C) 2012 Google Inc. All Rights Reserved.
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.
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.
28 #include "config.h"
29 #include "core/dom/ExecutionContext.h"
31 #include "core/dom/ExecutionContextTask.h"
32 #include "core/events/ErrorEvent.h"
33 #include "core/events/EventTarget.h"
34 #include "core/fetch/MemoryCache.h"
35 #include "core/frame/UseCounter.h"
36 #include "core/html/PublicURLManager.h"
37 #include "core/inspector/InspectorInstrumentation.h"
38 #include "core/inspector/ScriptCallStack.h"
39 #include "core/workers/WorkerGlobalScope.h"
40 #include "core/workers/WorkerThread.h"
41 #include "platform/RuntimeEnabledFeatures.h"
42 #include "wtf/MainThread.h"
44 namespace blink {
46 class ExecutionContext::PendingException : public NoBaseWillBeGarbageCollectedFinalized<ExecutionContext::PendingException> {
47 WTF_MAKE_NONCOPYABLE(PendingException);
48 public:
49 PendingException(const String& errorMessage, int lineNumber, int columnNumber, int scriptId, const String& sourceURL, PassRefPtrWillBeRawPtr<ScriptCallStack> callStack)
50 : m_errorMessage(errorMessage)
51 , m_lineNumber(lineNumber)
52 , m_columnNumber(columnNumber)
53 , m_scriptId(scriptId)
54 , m_sourceURL(sourceURL)
55 , m_callStack(callStack)
58 DEFINE_INLINE_TRACE()
60 visitor->trace(m_callStack);
62 String m_errorMessage;
63 int m_lineNumber;
64 int m_columnNumber;
65 int m_scriptId;
66 String m_sourceURL;
67 RefPtrWillBeMember<ScriptCallStack> m_callStack;
70 ExecutionContext::ExecutionContext()
71 : m_circularSequentialID(0)
72 , m_inDispatchErrorEvent(false)
73 , m_activeDOMObjectsAreSuspended(false)
74 , m_activeDOMObjectsAreStopped(false)
75 , m_strictMixedContentCheckingEnforced(false)
76 , m_windowInteractionTokens(0)
77 , m_isRunSuspendableTasksScheduled(false)
78 , m_referrerPolicy(ReferrerPolicyDefault)
82 ExecutionContext::~ExecutionContext()
86 void ExecutionContext::suspendActiveDOMObjects()
88 ASSERT(!m_activeDOMObjectsAreSuspended);
89 notifySuspendingActiveDOMObjects();
90 m_activeDOMObjectsAreSuspended = true;
93 void ExecutionContext::resumeActiveDOMObjects()
95 ASSERT(m_activeDOMObjectsAreSuspended);
96 m_activeDOMObjectsAreSuspended = false;
97 notifyResumingActiveDOMObjects();
100 void ExecutionContext::stopActiveDOMObjects()
102 m_activeDOMObjectsAreStopped = true;
103 notifyStoppingActiveDOMObjects();
106 void ExecutionContext::postSuspendableTask(PassOwnPtr<SuspendableTask> task)
108 m_suspendedTasks.append(task);
109 if (!m_activeDOMObjectsAreSuspended)
110 postTask(FROM_HERE, createSameThreadTask(&ExecutionContext::runSuspendableTasks, this));
113 void ExecutionContext::notifyContextDestroyed()
115 Deque<OwnPtr<SuspendableTask>> suspendedTasks;
116 suspendedTasks.swap(m_suspendedTasks);
117 for (Deque<OwnPtr<SuspendableTask>>::iterator it = suspendedTasks.begin(); it != suspendedTasks.end(); ++it)
118 (*it)->contextDestroyed();
119 ContextLifecycleNotifier::notifyContextDestroyed();
122 void ExecutionContext::suspendScheduledTasks()
124 suspendActiveDOMObjects();
125 tasksWereSuspended();
128 void ExecutionContext::resumeScheduledTasks()
130 resumeActiveDOMObjects();
131 tasksWereResumed();
132 // We need finish stack unwiding before running next task because it can suspend this context.
133 if (m_isRunSuspendableTasksScheduled)
134 return;
135 m_isRunSuspendableTasksScheduled = true;
136 postTask(FROM_HERE, createSameThreadTask(&ExecutionContext::runSuspendableTasks, this));
139 void ExecutionContext::suspendActiveDOMObjectIfNeeded(ActiveDOMObject* object)
141 ASSERT(contains(object));
142 // Ensure all ActiveDOMObjects are suspended also newly created ones.
143 if (m_activeDOMObjectsAreSuspended)
144 object->suspend();
147 bool ExecutionContext::shouldSanitizeScriptError(const String& sourceURL, AccessControlStatus corsStatus)
149 if (corsStatus == OpaqueResource)
150 return true;
151 return !(securityOrigin()->canRequestNoSuborigin(completeURL(sourceURL)) || corsStatus == SharableCrossOrigin);
154 void ExecutionContext::reportException(PassRefPtrWillBeRawPtr<ErrorEvent> event, int scriptId, PassRefPtrWillBeRawPtr<ScriptCallStack> callStack, AccessControlStatus corsStatus)
156 RefPtrWillBeRawPtr<ErrorEvent> errorEvent = event;
157 if (m_inDispatchErrorEvent) {
158 if (!m_pendingExceptions)
159 m_pendingExceptions = adoptPtrWillBeNoop(new WillBeHeapVector<OwnPtrWillBeMember<PendingException>>());
160 m_pendingExceptions->append(adoptPtrWillBeNoop(new PendingException(errorEvent->messageForConsole(), errorEvent->lineno(), errorEvent->colno(), scriptId, errorEvent->filename(), callStack)));
161 return;
164 // First report the original exception and only then all the nested ones.
165 if (!dispatchErrorEvent(errorEvent, corsStatus))
166 logExceptionToConsole(errorEvent->messageForConsole(), scriptId, errorEvent->filename(), errorEvent->lineno(), errorEvent->colno(), callStack);
168 if (!m_pendingExceptions)
169 return;
171 for (size_t i = 0; i < m_pendingExceptions->size(); i++) {
172 PendingException* e = m_pendingExceptions->at(i).get();
173 logExceptionToConsole(e->m_errorMessage, e->m_scriptId, e->m_sourceURL, e->m_lineNumber, e->m_columnNumber, e->m_callStack);
175 m_pendingExceptions.clear();
178 bool ExecutionContext::dispatchErrorEvent(PassRefPtrWillBeRawPtr<ErrorEvent> event, AccessControlStatus corsStatus)
180 EventTarget* target = errorEventTarget();
181 if (!target)
182 return false;
184 RefPtrWillBeRawPtr<ErrorEvent> errorEvent = event;
185 if (shouldSanitizeScriptError(errorEvent->filename(), corsStatus))
186 errorEvent = ErrorEvent::createSanitizedError(errorEvent->world());
188 ASSERT(!m_inDispatchErrorEvent);
189 m_inDispatchErrorEvent = true;
190 target->dispatchEvent(errorEvent);
191 m_inDispatchErrorEvent = false;
192 return errorEvent->defaultPrevented();
195 void ExecutionContext::runSuspendableTasks()
197 m_isRunSuspendableTasksScheduled = false;
198 while (!m_activeDOMObjectsAreSuspended && m_suspendedTasks.size()) {
199 OwnPtr<SuspendableTask> task = m_suspendedTasks.takeFirst();
200 task->run();
204 int ExecutionContext::circularSequentialID()
206 ++m_circularSequentialID;
207 if (m_circularSequentialID > ((1U << 31) - 1U))
208 m_circularSequentialID = 1;
210 return m_circularSequentialID;
213 PublicURLManager& ExecutionContext::publicURLManager()
215 if (!m_publicURLManager)
216 m_publicURLManager = PublicURLManager::create(this);
217 return *m_publicURLManager;
220 SecurityOrigin* ExecutionContext::securityOrigin()
222 return securityContext().securityOrigin();
225 ContentSecurityPolicy* ExecutionContext::contentSecurityPolicy()
227 return securityContext().contentSecurityPolicy();
230 const KURL& ExecutionContext::url() const
232 return virtualURL();
235 KURL ExecutionContext::completeURL(const String& url) const
237 return virtualCompleteURL(url);
240 bool ExecutionContext::hasSuborigin()
242 return securityContext().securityOrigin()->hasSuborigin();
245 String ExecutionContext::suboriginName()
247 return securityContext().securityOrigin()->suboriginName();
250 void ExecutionContext::allowWindowInteraction()
252 ++m_windowInteractionTokens;
255 void ExecutionContext::consumeWindowInteraction()
257 if (m_windowInteractionTokens == 0)
258 return;
259 --m_windowInteractionTokens;
262 bool ExecutionContext::isWindowInteractionAllowed() const
264 return m_windowInteractionTokens > 0;
267 void ExecutionContext::setReferrerPolicy(ReferrerPolicy referrerPolicy)
269 // FIXME: Can we adopt the CSP referrer policy merge algorithm? Or does the web rely on being able to modify the referrer policy in-flight?
270 UseCounter::count(this, UseCounter::SetReferrerPolicy);
271 if (m_referrerPolicy != ReferrerPolicyDefault)
272 UseCounter::count(this, UseCounter::ResetReferrerPolicy);
274 m_referrerPolicy = referrerPolicy;
277 void ExecutionContext::removeURLFromMemoryCache(const KURL& url)
279 memoryCache()->removeURLFromCache(url);
282 // |name| should be non-empty, and this should be enforced by parsing.
283 void ExecutionContext::enforceSuborigin(const String& name)
285 if (name.isNull())
286 return;
287 ASSERT(!name.isEmpty());
288 ASSERT(RuntimeEnabledFeatures::suboriginsEnabled());
289 SecurityOrigin* origin = securityContext().securityOrigin();
290 ASSERT(origin);
291 ASSERT(!origin->hasSuborigin() || origin->suboriginName() == name);
292 origin->addSuborigin(name);
293 securityContext().didUpdateSecurityOrigin();
296 DEFINE_TRACE(ExecutionContext)
298 #if ENABLE(OILPAN)
299 visitor->trace(m_pendingExceptions);
300 visitor->trace(m_publicURLManager);
301 HeapSupplementable<ExecutionContext>::trace(visitor);
302 #endif
303 ContextLifecycleNotifier::trace(visitor);
306 } // namespace blink