|
15 | 15 | var globalMutationObservers = [];
|
16 | 16 | var isScheduled = false;
|
17 | 17 |
|
18 |
| - function scheduleCallback(observer) { |
| 18 | + function scheduleCallback() { |
19 | 19 | if (isScheduled)
|
20 | 20 | return;
|
21 | 21 | setEndOfMicrotask(notifyObservers);
|
|
26 | 26 | function notifyObservers() {
|
27 | 27 | isScheduled = false;
|
28 | 28 |
|
29 |
| - do { |
30 |
| - var notifyList = globalMutationObservers.slice(); |
31 |
| - var anyNonEmpty = false; |
| 29 | + while (globalMutationObservers.length) { |
| 30 | + var notifyList = globalMutationObservers; |
| 31 | + globalMutationObservers = []; |
| 32 | + |
| 33 | + // Deliver changes in birth order of the MutationObservers. |
| 34 | + notifyList.sort(function(x, y) { return x.uid_ - y.uid_; }); |
| 35 | + |
32 | 36 | for (var i = 0; i < notifyList.length; i++) {
|
33 | 37 | var mo = notifyList[i];
|
34 | 38 | var queue = mo.takeRecords();
|
35 | 39 | removeTransientObserversFor(mo);
|
36 | 40 | if (queue.length) {
|
37 | 41 | mo.callback_(queue, mo);
|
38 |
| - anyNonEmpty = true; |
39 | 42 | }
|
40 | 43 | }
|
41 |
| - } while (anyNonEmpty); |
| 44 | + } |
42 | 45 | }
|
43 | 46 |
|
| 47 | + |
44 | 48 | /**
|
45 | 49 | * @param {string} type
|
46 | 50 | * @param {Node} target
|
|
146 | 150 | }
|
147 | 151 | }
|
148 | 152 |
|
149 |
| - var anyRecordsEnqueued = false; |
| 153 | + var anyObserversEnqueued = false; |
150 | 154 |
|
151 | 155 | // 4.
|
152 | 156 | for (var uid in interestedObservers) {
|
|
180 | 184 | record.oldValue = associatedStrings[uid];
|
181 | 185 |
|
182 | 186 | // 8.
|
| 187 | + if (!observer.records_.length) { |
| 188 | + globalMutationObservers.push(observer); |
| 189 | + anyObserversEnqueued = true; |
| 190 | + } |
183 | 191 | observer.records_.push(record);
|
184 |
| - |
185 |
| - anyRecordsEnqueued = true; |
186 | 192 | }
|
187 | 193 |
|
188 |
| - if (anyRecordsEnqueued) |
| 194 | + if (anyObserversEnqueued) |
189 | 195 | scheduleCallback();
|
190 | 196 | }
|
191 | 197 |
|
|
249 | 255 | this.nodes_ = [];
|
250 | 256 | this.records_ = [];
|
251 | 257 | this.uid_ = ++uidCounter;
|
252 |
| - |
253 |
| - // This will leak. There is no way to implement this without WeakRefs :'( |
254 |
| - globalMutationObservers.push(this); |
255 | 258 | }
|
256 | 259 |
|
257 | 260 | MutationObserver.prototype = {
|
|
0 commit comments