blob: 2966767768f0d714742e36bce5b61086977f91ff [file] [log] [blame]
adamk@chromium.orgd02d7602011-10-21 19:19:56 +00001/*
2 * Copyright (C) 2011 Google 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 are
6 * met:
7 *
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
13 * distribution.
14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
commit-queue@webkit.orgd862d772016-10-31 22:07:53 +000031#pragma once
adamk@chromium.orgd02d7602011-10-21 19:19:56 +000032
annulen@yandex.ru50e6dc92017-06-20 16:31:53 +000033#include "ContainerNode.h"
adamk@chromium.orgd4bf4892011-12-16 18:27:13 +000034#include "Document.h"
adamk@chromium.org0e07f342012-07-09 21:34:09 +000035#include "MutationObserver.h"
zandobersek@gmail.com9cf5edb2014-02-09 08:33:19 +000036#include <memory>
adamk@chromium.orgd02d7602011-10-21 19:19:56 +000037#include <wtf/Noncopyable.h>
adamk@chromium.orgb49e0c62012-09-22 00:30:48 +000038#include <wtf/RefCounted.h>
adamk@chromium.orgd02d7602011-10-21 19:19:56 +000039
40namespace WebCore {
41
adamk@chromium.orgb49e0c62012-09-22 00:30:48 +000042class MutationObserverInterestGroup;
43
44// ChildListMutationAccumulator is not meant to be used directly; ChildListMutationScope is the public interface.
adamk@chromium.orgb49e0c62012-09-22 00:30:48 +000045class ChildListMutationAccumulator : public RefCounted<ChildListMutationAccumulator> {
46public:
yusukesuzuki@slowstart.orgae5a8bd2018-12-22 06:37:39 +000047 static Ref<ChildListMutationAccumulator> getOrCreate(ContainerNode&);
adamk@chromium.orgb49e0c62012-09-22 00:30:48 +000048 ~ChildListMutationAccumulator();
49
weinig@apple.com2e067212013-09-23 03:40:47 +000050 void childAdded(Node&);
51 void willRemoveChild(Node&);
adamk@chromium.orgb49e0c62012-09-22 00:30:48 +000052
zandobersek@gmail.com9cf5edb2014-02-09 08:33:19 +000053 bool hasObservers() const { return !!m_observers; }
adamk@chromium.orgb49e0c62012-09-22 00:30:48 +000054
55private:
zandobersek@gmail.com9cf5edb2014-02-09 08:33:19 +000056 ChildListMutationAccumulator(ContainerNode&, std::unique_ptr<MutationObserverInterestGroup>);
adamk@chromium.orgb49e0c62012-09-22 00:30:48 +000057
58 void enqueueMutationRecord();
59 bool isEmpty();
weinig@apple.com2e067212013-09-23 03:40:47 +000060 bool isAddedNodeInOrder(Node&);
61 bool isRemovedNodeInOrder(Node&);
adamk@chromium.orgb49e0c62012-09-22 00:30:48 +000062
weinig@apple.com2e067212013-09-23 03:40:47 +000063 Ref<ContainerNode> m_target;
adamk@chromium.orgb49e0c62012-09-22 00:30:48 +000064
weinig@apple.com2e067212013-09-23 03:40:47 +000065 Vector<Ref<Node>> m_removedNodes;
66 Vector<Ref<Node>> m_addedNodes;
adamk@chromium.orgb49e0c62012-09-22 00:30:48 +000067 RefPtr<Node> m_previousSibling;
68 RefPtr<Node> m_nextSibling;
69 Node* m_lastAdded;
70
zandobersek@gmail.com9cf5edb2014-02-09 08:33:19 +000071 std::unique_ptr<MutationObserverInterestGroup> m_observers;
adamk@chromium.orgb49e0c62012-09-22 00:30:48 +000072};
73
adamk@chromium.orgd02d7602011-10-21 19:19:56 +000074class ChildListMutationScope {
75 WTF_MAKE_NONCOPYABLE(ChildListMutationScope);
76public:
weinig@apple.com2e067212013-09-23 03:40:47 +000077 explicit ChildListMutationScope(ContainerNode& target)
adamk@chromium.orgd4bf4892011-12-16 18:27:13 +000078 {
weinig@apple.com2e067212013-09-23 03:40:47 +000079 if (target.document().hasMutationObserversOfType(MutationObserver::ChildList))
adamk@chromium.orgb49e0c62012-09-22 00:30:48 +000080 m_accumulator = ChildListMutationAccumulator::getOrCreate(target);
adamk@chromium.orgd4bf4892011-12-16 18:27:13 +000081 }
82
rniwa@webkit.org2c03c2b2016-01-19 08:39:44 +000083 bool canObserve() const { return m_accumulator; }
84
weinig@apple.com2e067212013-09-23 03:40:47 +000085 void childAdded(Node& child)
adamk@chromium.orgd4bf4892011-12-16 18:27:13 +000086 {
adamk@chromium.orgb49e0c62012-09-22 00:30:48 +000087 if (m_accumulator && m_accumulator->hasObservers())
88 m_accumulator->childAdded(child);
adamk@chromium.orgd4bf4892011-12-16 18:27:13 +000089 }
90
weinig@apple.com2e067212013-09-23 03:40:47 +000091 void willRemoveChild(Node& child)
adamk@chromium.orgd4bf4892011-12-16 18:27:13 +000092 {
adamk@chromium.orgb49e0c62012-09-22 00:30:48 +000093 if (m_accumulator && m_accumulator->hasObservers())
94 m_accumulator->willRemoveChild(child);
adamk@chromium.orgd4bf4892011-12-16 18:27:13 +000095 }
adamk@chromium.orgd02d7602011-10-21 19:19:56 +000096
97private:
adamk@chromium.orgb49e0c62012-09-22 00:30:48 +000098 RefPtr<ChildListMutationAccumulator> m_accumulator;
adamk@chromium.orgd02d7602011-10-21 19:19:56 +000099};
100
101} // namespace WebCore