Rename AtomicString to AtomString
[WebKit.git] / Source / WebCore / dom / CustomElementReactionQueue.h
1 /*
2  * Copyright (C) 2015, 2016 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #pragma once
27
28 #include "GCReachableRef.h"
29 #include <wtf/Forward.h>
30 #include <wtf/Noncopyable.h>
31 #include <wtf/Vector.h>
32
33 namespace JSC {
34
35 class ExecState;
36
37 }
38
39 namespace WebCore {
40
41 class CustomElementReactionQueueItem;
42 class Document;
43 class Element;
44 class JSCustomElementInterface;
45 class QualifiedName;
46
47 class CustomElementReactionQueue {
48     WTF_MAKE_FAST_ALLOCATED;
49     WTF_MAKE_NONCOPYABLE(CustomElementReactionQueue);
50 public:
51     CustomElementReactionQueue(JSCustomElementInterface&);
52     ~CustomElementReactionQueue();
53
54     static void enqueueElementUpgrade(Element&, bool alreadyScheduledToUpgrade);
55     static void enqueueElementUpgradeIfDefined(Element&);
56     static void enqueueConnectedCallbackIfNeeded(Element&);
57     static void enqueueDisconnectedCallbackIfNeeded(Element&);
58     static void enqueueAdoptedCallbackIfNeeded(Element&, Document& oldDocument, Document& newDocument);
59     static void enqueueAttributeChangedCallbackIfNeeded(Element&, const QualifiedName&, const AtomString& oldValue, const AtomString& newValue);
60     static void enqueuePostUpgradeReactions(Element&);
61
62     bool observesStyleAttribute() const;
63     void invokeAll(Element&);
64     void clear();
65
66     static void processBackupQueue();
67
68     class ElementQueue {
69     public:
70         void add(Element&);
71         void processQueue(JSC::ExecState*);
72
73     private:
74         void invokeAll();
75
76         Vector<GCReachableRef<Element>> m_elements;
77         bool m_invoking { false };
78     };
79
80 private:
81     static void enqueueElementOnAppropriateElementQueue(Element&);
82     static ElementQueue& ensureBackupQueue();
83     static ElementQueue& backupElementQueue();
84
85     Ref<JSCustomElementInterface> m_interface;
86     Vector<CustomElementReactionQueueItem> m_items;
87 };
88
89 class CustomElementReactionDisallowedScope {
90 public:
91     CustomElementReactionDisallowedScope()
92     {
93 #if !ASSERT_DISABLED
94         s_customElementReactionDisallowedCount++;
95 #endif
96     }
97
98     ~CustomElementReactionDisallowedScope()
99     {
100 #if !ASSERT_DISABLED
101         ASSERT(s_customElementReactionDisallowedCount);
102         s_customElementReactionDisallowedCount--;
103 #endif
104     }
105
106 #if !ASSERT_DISABLED
107     static bool isReactionAllowed() { return !s_customElementReactionDisallowedCount; }
108 #endif
109
110     class AllowedScope {
111 #if !ASSERT_DISABLED
112     public:
113         AllowedScope()
114             : m_originalCount(s_customElementReactionDisallowedCount)
115         {
116             s_customElementReactionDisallowedCount = 0;
117         }
118
119         ~AllowedScope()
120         {
121             s_customElementReactionDisallowedCount = m_originalCount;
122         }
123
124     private:
125         unsigned m_originalCount;
126 #endif
127     };
128
129 private:
130 #if !ASSERT_DISABLED
131     WEBCORE_EXPORT static unsigned s_customElementReactionDisallowedCount;
132
133     friend class AllowedScope;
134 #endif
135 };
136
137 class CustomElementReactionStack : public CustomElementReactionDisallowedScope::AllowedScope {
138 public:
139     ALWAYS_INLINE CustomElementReactionStack(JSC::ExecState* state)
140         : m_previousProcessingStack(s_currentProcessingStack)
141         , m_state(state)
142     {
143         s_currentProcessingStack = this;
144     }
145
146     ALWAYS_INLINE CustomElementReactionStack(JSC::ExecState& state)
147         : CustomElementReactionStack(&state)
148     { }
149
150     ALWAYS_INLINE ~CustomElementReactionStack()
151     {
152         if (UNLIKELY(m_queue))
153             processQueue(m_state);
154         s_currentProcessingStack = m_previousProcessingStack;
155     }
156
157 private:
158     WEBCORE_EXPORT void processQueue(JSC::ExecState*);
159
160     CustomElementReactionQueue::ElementQueue* m_queue { nullptr }; // Use raw pointer to avoid generating delete in the destructor.
161     CustomElementReactionStack* m_previousProcessingStack;
162     JSC::ExecState* m_state;
163
164     WEBCORE_EXPORT static CustomElementReactionStack* s_currentProcessingStack;
165
166     friend CustomElementReactionQueue;
167 };
168
169 }