OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "core/dom/SynchronousMutationNotifier.h" | 5 #include "core/dom/SynchronousMutationNotifier.h" |
6 | 6 |
7 #include "core/dom/Document.h" | 7 #include "core/dom/Document.h" |
8 #include "core/dom/SynchronousMutationObserver.h" | 8 #include "core/dom/SynchronousMutationObserver.h" |
9 | 9 |
10 namespace blink { | 10 namespace blink { |
11 | 11 |
12 SynchronousMutationNotifier::SynchronousMutationNotifier() = default; | 12 SynchronousMutationNotifier::ScopedNotificationSuppressor:: |
| 13 ScopedNotificationSuppressor(SynchronousMutationNotifier* notifier) { |
| 14 m_notifier = notifier; |
| 15 m_notifier->incrementSuppressorCount(); |
| 16 } |
| 17 |
| 18 SynchronousMutationNotifier::ScopedNotificationSuppressor:: |
| 19 ~ScopedNotificationSuppressor() { |
| 20 m_notifier->decrementSuppressorCount(); |
| 21 } |
| 22 |
| 23 SynchronousMutationNotifier::SynchronousMutationNotifier() |
| 24 : m_suppressorCount(0), |
| 25 m_pendingCharacterData(nullptr), |
| 26 m_pendingOffset(0), |
| 27 m_pendingOldLength(0), |
| 28 m_pendingNewLength(0) {} |
| 29 |
| 30 DEFINE_TRACE(SynchronousMutationNotifier) { |
| 31 visitor->trace(m_pendingCharacterData); |
| 32 LifecycleNotifier<Document, SynchronousMutationObserver>::trace(visitor); |
| 33 } |
13 | 34 |
14 void SynchronousMutationNotifier::notifyChangeChildren( | 35 void SynchronousMutationNotifier::notifyChangeChildren( |
15 const ContainerNode& container) { | 36 const ContainerNode& container) { |
16 for (SynchronousMutationObserver* observer : m_observers) | 37 for (SynchronousMutationObserver* observer : m_observers) |
17 observer->didChangeChildren(container); | 38 observer->didChangeChildren(container); |
18 } | 39 } |
19 | 40 |
20 void SynchronousMutationNotifier::notifyMergeTextNodes( | 41 void SynchronousMutationNotifier::notifyMergeTextNodes( |
21 const Text& node, | 42 const Text& node, |
22 const NodeWithIndex& nodeToBeRemovedWithIndex, | 43 const NodeWithIndex& nodeToBeRemovedWithIndex, |
(...skipping 11 matching lines...) Expand all Loading... |
34 void SynchronousMutationNotifier::notifySplitTextNode(const Text& node) { | 55 void SynchronousMutationNotifier::notifySplitTextNode(const Text& node) { |
35 for (SynchronousMutationObserver* observer : m_observers) | 56 for (SynchronousMutationObserver* observer : m_observers) |
36 observer->didSplitTextNode(node); | 57 observer->didSplitTextNode(node); |
37 } | 58 } |
38 | 59 |
39 void SynchronousMutationNotifier::notifyUpdateCharacterData( | 60 void SynchronousMutationNotifier::notifyUpdateCharacterData( |
40 CharacterData* characterData, | 61 CharacterData* characterData, |
41 unsigned offset, | 62 unsigned offset, |
42 unsigned oldLength, | 63 unsigned oldLength, |
43 unsigned newLength) { | 64 unsigned newLength) { |
| 65 if (m_suppressorCount) { |
| 66 if (!m_pendingCharacterData) { |
| 67 m_pendingCharacterData = characterData; |
| 68 m_pendingOffset = offset; |
| 69 m_pendingOldLength = oldLength; |
| 70 m_pendingNewLength = newLength; |
| 71 return; |
| 72 } |
| 73 |
| 74 if (m_pendingCharacterData == characterData && m_pendingNewLength == 0 && |
| 75 oldLength == 0 && m_pendingOffset == offset) { |
| 76 // insert following a delete |
| 77 m_pendingNewLength = newLength; |
| 78 return; |
| 79 } |
| 80 |
| 81 // otherwise, flush what we're currently holding and store the new update |
| 82 // as pending |
| 83 flushPendingCharacterDataUpdate(); |
| 84 m_pendingCharacterData = characterData; |
| 85 m_pendingOffset = offset; |
| 86 m_pendingOldLength = oldLength; |
| 87 m_pendingNewLength = newLength; |
| 88 return; |
| 89 } |
| 90 |
44 for (SynchronousMutationObserver* observer : m_observers) { | 91 for (SynchronousMutationObserver* observer : m_observers) { |
45 observer->didUpdateCharacterData(characterData, offset, oldLength, | 92 observer->didUpdateCharacterData(characterData, offset, oldLength, |
46 newLength); | 93 newLength); |
47 } | 94 } |
48 } | 95 } |
49 | 96 |
50 void SynchronousMutationNotifier::notifyNodeChildrenWillBeRemoved( | 97 void SynchronousMutationNotifier::notifyNodeChildrenWillBeRemoved( |
51 ContainerNode& container) { | 98 ContainerNode& container) { |
52 for (SynchronousMutationObserver* observer : m_observers) | 99 for (SynchronousMutationObserver* observer : m_observers) |
53 observer->nodeChildrenWillBeRemoved(container); | 100 observer->nodeChildrenWillBeRemoved(container); |
54 } | 101 } |
55 | 102 |
56 void SynchronousMutationNotifier::notifyNodeWillBeRemoved(Node& node) { | 103 void SynchronousMutationNotifier::notifyNodeWillBeRemoved(Node& node) { |
57 for (SynchronousMutationObserver* observer : m_observers) | 104 for (SynchronousMutationObserver* observer : m_observers) |
58 observer->nodeWillBeRemoved(node); | 105 observer->nodeWillBeRemoved(node); |
59 } | 106 } |
60 | 107 |
| 108 void SynchronousMutationNotifier::incrementSuppressorCount() { |
| 109 m_suppressorCount++; |
| 110 } |
| 111 |
| 112 void SynchronousMutationNotifier::decrementSuppressorCount() { |
| 113 m_suppressorCount--; |
| 114 if (m_suppressorCount == 0) { |
| 115 flushPendingCharacterDataUpdate(); |
| 116 } |
| 117 } |
| 118 |
| 119 void SynchronousMutationNotifier::notifyUpdateCharacterDataImmediately( |
| 120 CharacterData* characterData, |
| 121 unsigned offset, |
| 122 unsigned oldLength, |
| 123 unsigned newLength) { |
| 124 for (SynchronousMutationObserver* observer : m_observers) { |
| 125 observer->didUpdateCharacterData(characterData, offset, oldLength, |
| 126 newLength); |
| 127 } |
| 128 } |
| 129 |
| 130 void SynchronousMutationNotifier::flushPendingCharacterDataUpdate() { |
| 131 if (!m_pendingCharacterData) |
| 132 return; |
| 133 notifyUpdateCharacterDataImmediately(m_pendingCharacterData, m_pendingOffset, |
| 134 m_pendingOldLength, m_pendingNewLength); |
| 135 m_pendingCharacterData = nullptr; |
| 136 } |
| 137 |
61 } // namespace blink | 138 } // namespace blink |
OLD | NEW |