Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(206)

Side by Side Diff: Source/core/dom/CustomElementCallbackDispatcher.cpp

Issue 18167006: Implement Custom Elements' entered and left document callbacks. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Feedback. Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2013 Google Inc. All rights reserved. 2 * Copyright (C) 2013 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 7 *
8 * 1. Redistributions of source code must retain the above copyright 8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
42 size_t CustomElementCallbackDispatcher::s_elementQueueEnd = 1; 42 size_t CustomElementCallbackDispatcher::s_elementQueueEnd = 1;
43 43
44 CustomElementCallbackDispatcher& CustomElementCallbackDispatcher::instance() 44 CustomElementCallbackDispatcher& CustomElementCallbackDispatcher::instance()
45 { 45 {
46 DEFINE_STATIC_LOCAL(CustomElementCallbackDispatcher, instance, ()); 46 DEFINE_STATIC_LOCAL(CustomElementCallbackDispatcher, instance, ());
47 return instance; 47 return instance;
48 } 48 }
49 49
50 void CustomElementCallbackDispatcher::enqueueAttributeChangedCallback(PassRefPtr <CustomElementLifecycleCallbacks> callbacks, PassRefPtr<Element> element, const AtomicString& name, const AtomicString& oldValue, const AtomicString& newValue) 50 void CustomElementCallbackDispatcher::enqueueAttributeChangedCallback(PassRefPtr <CustomElementLifecycleCallbacks> callbacks, PassRefPtr<Element> element, const AtomicString& name, const AtomicString& oldValue, const AtomicString& newValue)
51 { 51 {
52 if (!callbacks->hasAttributeChanged()) 52 if (!callbacks->hasAttributeChangedCallback())
53 return; 53 return;
54 54
55 CustomElementCallbackQueue* queue = ensureCallbackQueue(callbacks, element); 55 CustomElementCallbackQueue* queue = scheduleInCurrentElementQueue(element);
56 bool isInCurrentQueue = queue->owner() == currentElementQueue(); 56 queue->append(CustomElementCallbackInvocation::createAttributeChangedInvocat ion(callbacks, name, oldValue, newValue));
57 if (!isInCurrentQueue) {
58 queue->setOwner(currentElementQueue());
59 m_flattenedProcessingStack.append(queue);
60 s_elementQueueEnd++;
61 }
62
63 queue->append(CustomElementCallbackInvocation::createAttributeChangedInvocat ion(name, oldValue, newValue));
64 } 57 }
65 58
66 void CustomElementCallbackDispatcher::enqueueCreatedCallback(PassRefPtr<CustomEl ementLifecycleCallbacks> callbacks, PassRefPtr<Element> element) 59 void CustomElementCallbackDispatcher::enqueueCreatedCallback(PassRefPtr<CustomEl ementLifecycleCallbacks> callbacks, PassRefPtr<Element> element)
67 { 60 {
68 if (!callbacks->hasCreated()) 61 if (!callbacks->hasCreatedCallback())
69 return; 62 return;
70 63
71 CustomElementCallbackQueue* queue = createCallbackQueue(callbacks, element); 64 CustomElementCallbackQueue* queue = createCallbackQueue(element);
72 queue->setOwner(currentElementQueue()); 65 queue->setOwner(currentElementQueue());
73 66
74 // The created callback is unique in being prepended to the front 67 // The created callback is unique in being prepended to the front
75 // of the element queue 68 // of the element queue
76 m_flattenedProcessingStack.insert(inCallbackDeliveryScope() ? s_elementQueue Start : /* skip null sentinel */ 1, queue); 69 m_flattenedProcessingStack.insert(inCallbackDeliveryScope() ? s_elementQueue Start : /* skip null sentinel */ 1, queue);
77 s_elementQueueEnd++; 70 ++s_elementQueueEnd;
78 71
79 queue->append(CustomElementCallbackInvocation::createCreatedInvocation()); 72 queue->append(CustomElementCallbackInvocation::createInvocation(callbacks, C ustomElementLifecycleCallbacks::Created));
73 }
74
75 void CustomElementCallbackDispatcher::enqueueEnteredDocumentCallback(PassRefPtr< CustomElementLifecycleCallbacks> callbacks, PassRefPtr<Element> element)
76 {
77 if (!callbacks->hasEnteredDocumentCallback())
78 return;
79
80 CustomElementCallbackQueue* queue = scheduleInCurrentElementQueue(element);
81 queue->append(CustomElementCallbackInvocation::createInvocation(callbacks, C ustomElementLifecycleCallbacks::EnteredDocument));
82 }
83
84 void CustomElementCallbackDispatcher::enqueueLeftDocumentCallback(PassRefPtr<Cus tomElementLifecycleCallbacks> callbacks, PassRefPtr<Element> element)
85 {
86 if (!callbacks->hasLeftDocumentCallback())
87 return;
88
89 CustomElementCallbackQueue* queue = scheduleInCurrentElementQueue(element);
90 queue->append(CustomElementCallbackInvocation::createInvocation(callbacks, C ustomElementLifecycleCallbacks::LeftDocument));
80 } 91 }
81 92
82 // Dispatches callbacks at microtask checkpoint. 93 // Dispatches callbacks at microtask checkpoint.
83 bool CustomElementCallbackDispatcher::dispatch() 94 bool CustomElementCallbackDispatcher::dispatch()
84 { 95 {
85 ASSERT(isMainThread()); 96 ASSERT(isMainThread());
86 if (inCallbackDeliveryScope()) 97 if (inCallbackDeliveryScope())
87 return false; 98 return false;
88 99
89 size_t start = 1; // skip null sentinel 100 size_t start = 1; // skip null sentinel
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
128 } 139 }
129 140
130 // Pop the element queue from the processing stack 141 // Pop the element queue from the processing stack
131 m_flattenedProcessingStack.resize(start); 142 m_flattenedProcessingStack.resize(start);
132 s_elementQueueEnd = start; 143 s_elementQueueEnd = start;
133 144
134 if (start == /* allow sentinel */ 1) 145 if (start == /* allow sentinel */ 1)
135 m_elementCallbackQueueMap.clear(); 146 m_elementCallbackQueueMap.clear();
136 } 147 }
137 148
138 CustomElementCallbackQueue* CustomElementCallbackDispatcher::createCallbackQueue (PassRefPtr<CustomElementLifecycleCallbacks> callbacks, PassRefPtr<Element> elem ent) 149 CustomElementCallbackQueue* CustomElementCallbackDispatcher::createCallbackQueue (PassRefPtr<Element> element)
139 { 150 {
140 Element* key = element.get(); 151 Element* key = element.get();
141 ElementCallbackQueueMap::AddResult result = m_elementCallbackQueueMap.add(ke y, CustomElementCallbackQueue::create(callbacks, element)); 152 ElementCallbackQueueMap::AddResult result = m_elementCallbackQueueMap.add(ke y, CustomElementCallbackQueue::create(element));
142 ASSERT(result.isNewEntry); 153 ASSERT(result.isNewEntry);
143 return result.iterator->value.get(); 154 return result.iterator->value.get();
144 } 155 }
145 156
146 CustomElementCallbackQueue* CustomElementCallbackDispatcher::ensureCallbackQueue (PassRefPtr<CustomElementLifecycleCallbacks> callbacks, PassRefPtr<Element> elem ent) 157 CustomElementCallbackQueue* CustomElementCallbackDispatcher::ensureCallbackQueue (PassRefPtr<Element> element)
147 { 158 {
148 Element* key = element.get(); 159 Element* key = element.get();
149 ElementCallbackQueueMap::iterator it = m_elementCallbackQueueMap.find(key); 160 ElementCallbackQueueMap::iterator it = m_elementCallbackQueueMap.find(key);
150 if (it == m_elementCallbackQueueMap.end()) 161 if (it == m_elementCallbackQueueMap.end())
151 it = m_elementCallbackQueueMap.add(key, CustomElementCallbackQueue::crea te(callbacks, element)).iterator; 162 it = m_elementCallbackQueueMap.add(key, CustomElementCallbackQueue::crea te(element)).iterator;
152 return it->value.get(); 163 return it->value.get();
153 } 164 }
154 165
166 // Finds or creates the callback queue for element. If the element's
167 // callback queue is scheduled in an earlier processing stack frame,
168 // its owner is set to the element queue on the top of the processing
169 // stack. Because callback queues are processed exhaustively, this
170 // effectively moves the callback queue to the top of the stack.
171 CustomElementCallbackQueue* CustomElementCallbackDispatcher::scheduleInCurrentEl ementQueue(PassRefPtr<Element> element)
172 {
173 CustomElementCallbackQueue* queue = ensureCallbackQueue(element);
174 bool isInCurrentQueue = queue->owner() == currentElementQueue();
175 if (!isInCurrentQueue) {
176 queue->setOwner(currentElementQueue());
177 m_flattenedProcessingStack.append(queue);
178 ++s_elementQueueEnd;
179 }
180 return queue;
181 }
182
155 } // namespace WebCore 183 } // namespace WebCore
OLDNEW
« no previous file with comments | « Source/core/dom/CustomElementCallbackDispatcher.h ('k') | Source/core/dom/CustomElementCallbackInvocation.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698