1/*
2 * Copyright (C) 2011 Google Inc. All rights reserved.
3 * Copyright (C) 2018 Apple Inc. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following disclaimer
13 * in the documentation and/or other materials provided with the
14 * distribution.
15 * * Neither the name of Google Inc. nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32#pragma once
33
34#include "ExceptionOr.h"
35#include "GCReachableRef.h"
36#include <wtf/Forward.h>
37#include <wtf/HashSet.h>
38#include <wtf/IsoMalloc.h>
39#include <wtf/Vector.h>
40
41namespace WebCore {
42
43class HTMLSlotElement;
44class MutationCallback;
45class MutationObserverRegistration;
46class MutationRecord;
47class Node;
48
49using MutationObserverOptions = unsigned char;
50using MutationRecordDeliveryOptions = unsigned char;
51
52class MutationObserver final : public RefCounted<MutationObserver> {
53 WTF_MAKE_ISO_ALLOCATED(MutationObserver);
54 friend class MutationObserverMicrotask;
55public:
56 enum MutationType {
57 ChildList = 1 << 0,
58 Attributes = 1 << 1,
59 CharacterData = 1 << 2,
60
61 AllMutationTypes = ChildList | Attributes | CharacterData
62 };
63
64 enum ObservationFlags {
65 Subtree = 1 << 3,
66 AttributeFilter = 1 << 4
67 };
68
69 enum DeliveryFlags {
70 AttributeOldValue = 1 << 5,
71 CharacterDataOldValue = 1 << 6,
72 };
73
74 static Ref<MutationObserver> create(Ref<MutationCallback>&&);
75
76 ~MutationObserver();
77
78 struct Init {
79 bool childList;
80 Optional<bool> attributes;
81 Optional<bool> characterData;
82 bool subtree;
83 Optional<bool> attributeOldValue;
84 Optional<bool> characterDataOldValue;
85 Optional<Vector<String>> attributeFilter;
86 };
87
88 ExceptionOr<void> observe(Node&, const Init&);
89
90 struct TakenRecords {
91 Vector<Ref<MutationRecord>> records;
92 HashSet<GCReachableRef<Node>> pendingTargets;
93 };
94 TakenRecords takeRecords();
95 void disconnect();
96
97 void observationStarted(MutationObserverRegistration&);
98 void observationEnded(MutationObserverRegistration&);
99 void enqueueMutationRecord(Ref<MutationRecord>&&);
100 void setHasTransientRegistration();
101 bool canDeliver();
102
103 HashSet<Node*> observedNodes() const;
104
105 MutationCallback& callback() const { return m_callback.get(); }
106
107 static void enqueueSlotChangeEvent(HTMLSlotElement&);
108
109private:
110 explicit MutationObserver(Ref<MutationCallback>&&);
111 void deliver();
112
113 static void notifyMutationObservers();
114 static bool validateOptions(MutationObserverOptions);
115
116 Ref<MutationCallback> m_callback;
117 Vector<Ref<MutationRecord>> m_records;
118 HashSet<GCReachableRef<Node>> m_pendingTargets;
119 HashSet<MutationObserverRegistration*> m_registrations;
120 unsigned m_priority;
121};
122
123} // namespace WebCore
124