1/*
2 * Copyright (C) 2013 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 *     * Neither the name of Google Inc. nor the names of its
11 * contributors may be used to endorse or promote products derived from
12 * this software without specific prior written permission.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
15 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
16 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
17 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
18 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
19 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
20 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#ifndef NodeChildRemovalTracker_h
28#define NodeChildRemovalTracker_h
29
30#include "core/dom/Node.h"
31#include "platform/heap/Handle.h"
32
33namespace blink {
34
35class NodeChildRemovalTracker {
36    STACK_ALLOCATED();
37public:
38    explicit NodeChildRemovalTracker(Node&);
39    ~NodeChildRemovalTracker();
40
41    static bool isBeingRemoved(Node*);
42
43private:
44    Node& node() const { return *m_node; }
45    NodeChildRemovalTracker* previous() { return m_previous; }
46
47    RawPtrWillBeMember<Node> m_node;
48    // Using raw pointers are safe because these NodeChildRemovalTrackers are
49    // guaranteed to be on a stack.
50    NodeChildRemovalTracker* m_previous;
51    static NodeChildRemovalTracker* s_last;
52};
53
54inline NodeChildRemovalTracker::NodeChildRemovalTracker(Node& node)
55    : m_node(node)
56    , m_previous(s_last)
57{
58    s_last = this;
59}
60
61inline NodeChildRemovalTracker::~NodeChildRemovalTracker()
62{
63    s_last = m_previous;
64}
65
66inline bool NodeChildRemovalTracker::isBeingRemoved(Node* node)
67{
68    for (NodeChildRemovalTracker* removal = s_last; removal; removal = removal->previous()) {
69        if (removal->node().containsIncludingShadowDOM(node))
70            return true;
71    }
72
73    return false;
74}
75
76} // namespace
77
78#endif
79