15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/*
25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *           (C) 1999 Antti Koivisto (koivisto@kde.org)
45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *           (C) 2001 Dirk Mueller (mueller@kde.org)
5197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch * Copyright (C) 2004, 2005, 2006, 2007, 2009, 2010, 2011, 2013 Apple Inc. All rights reserved.
65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is free software; you can redistribute it and/or
85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modify it under the terms of the GNU Library General Public
95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * License as published by the Free Software Foundation; either
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * version 2 of the License, or (at your option) any later version.
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is distributed in the hope that it will be useful,
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * but WITHOUT ANY WARRANTY; without even the implied warranty of
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Library General Public License for more details.
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * You should have received a copy of the GNU Library General Public License
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * along with this library; see the file COPYING.LIB.  If not, write to
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Boston, MA 02110-1301, USA.
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */
235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#ifndef ContainerNode_h
255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#define ContainerNode_h
265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
27197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "bindings/core/v8/ExceptionStatePlaceholder.h"
2853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/Node.h"
29c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#include "core/html/CollectionType.h"
30e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch#include "wtf/OwnPtr.h"
31e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch#include "wtf/Vector.h"
325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
33c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink {
345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3576c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)class ClassCollection;
36df95704c49daea886ddad70775bda23618d6274dBen Murdochclass ExceptionState;
375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class FloatPoint;
38e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)class HTMLCollection;
39e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)template <typename NodeType> class StaticNodeTypeList;
40e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)typedef StaticNodeTypeList<Element> StaticElementList;
4176c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)class TagCollection;
42e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)
4307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdochenum DynamicRestyleFlags {
44f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    ChildrenOrSiblingsAffectedByFocus = 1 << 0,
45f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    ChildrenOrSiblingsAffectedByHover = 1 << 1,
46f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    ChildrenOrSiblingsAffectedByActive = 1 << 2,
47f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    ChildrenOrSiblingsAffectedByDrag = 1 << 3,
4807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    ChildrenAffectedByFirstChildRules = 1 << 4,
4907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    ChildrenAffectedByLastChildRules = 1 << 5,
5007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    ChildrenAffectedByDirectAdjacentRules = 1 << 6,
5107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    ChildrenAffectedByIndirectAdjacentRules = 1 << 7,
5207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    ChildrenAffectedByForwardPositionalRules = 1 << 8,
5307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    ChildrenAffectedByBackwardPositionalRules = 1 << 9,
5407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch
5507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    NumberOfDynamicRestyleFlags = 10,
5607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch};
5707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch
58f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)// This constant controls how much buffer is initially allocated
59f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)// for a Node Vector that is used to store child Nodes of a given Node.
60f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)// FIXME: Optimize the value.
61f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)const int initialNodeVectorSize = 11;
62f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)typedef WillBeHeapVector<RefPtrWillBeMember<Node>, initialNodeVectorSize> NodeVector;
63f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class ContainerNode : public Node {
655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public:
665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    virtual ~ContainerNode();
675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Node* firstChild() const { return m_firstChild; }
695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Node* lastChild() const { return m_lastChild; }
70d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    bool hasChildren() const { return m_firstChild; }
715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
72e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    bool hasOneChild() const { return m_firstChild && !m_firstChild->nextSibling(); }
73e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    bool hasOneTextChild() const { return hasOneChild() && m_firstChild->isTextNode(); }
74d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    bool hasChildCount(unsigned) const;
75e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
76d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    PassRefPtrWillBeRawPtr<HTMLCollection> children();
77e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)
78d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    unsigned countChildren() const;
795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
80d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    PassRefPtrWillBeRawPtr<Element> querySelector(const AtomicString& selectors, ExceptionState&);
81e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    PassRefPtrWillBeRawPtr<StaticElementList> querySelectorAll(const AtomicString& selectors, ExceptionState&);
8209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
83197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    PassRefPtrWillBeRawPtr<Node> insertBefore(PassRefPtrWillBeRawPtr<Node> newChild, Node* refChild, ExceptionState& = ASSERT_NO_EXCEPTION);
84197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    PassRefPtrWillBeRawPtr<Node> replaceChild(PassRefPtrWillBeRawPtr<Node> newChild, PassRefPtrWillBeRawPtr<Node> oldChild, ExceptionState& = ASSERT_NO_EXCEPTION);
85197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    PassRefPtrWillBeRawPtr<Node> removeChild(PassRefPtrWillBeRawPtr<Node> child, ExceptionState& = ASSERT_NO_EXCEPTION);
86197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    PassRefPtrWillBeRawPtr<Node> appendChild(PassRefPtrWillBeRawPtr<Node> newChild, ExceptionState& = ASSERT_NO_EXCEPTION);
875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
88f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    Element* getElementById(const AtomicString& id) const;
8976c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    PassRefPtrWillBeRawPtr<TagCollection> getElementsByTagName(const AtomicString&);
9076c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    PassRefPtrWillBeRawPtr<TagCollection> getElementsByTagNameNS(const AtomicString& namespaceURI, const AtomicString& localName);
9176c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    PassRefPtrWillBeRawPtr<NameNodeList> getElementsByName(const AtomicString& elementName);
9276c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    PassRefPtrWillBeRawPtr<ClassCollection> getElementsByClassName(const AtomicString& classNames);
93d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    PassRefPtrWillBeRawPtr<RadioNodeList> radioNodeList(const AtomicString&, bool onlyMatchImgElements = false);
9409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // These methods are only used during parsing.
965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // They don't send DOM mutation events or handle reparenting.
97f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    void parserAppendChild(PassRefPtrWillBeRawPtr<Node>);
98f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    void parserRemoveChild(Node&);
99f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    void parserInsertBefore(PassRefPtrWillBeRawPtr<Node> newChild, Node& refChild);
10019cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)    void parserTakeAllChildrenFrom(ContainerNode&);
1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void removeChildren();
1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void cloneChildNodes(ContainerNode* clone);
1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
106521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    virtual void attach(const AttachContext& = AttachContext()) OVERRIDE;
107521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    virtual void detach(const AttachContext& = AttachContext()) OVERRIDE;
10809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    virtual LayoutRect boundingBox() const OVERRIDE FINAL;
109926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    virtual void setFocus(bool) OVERRIDE;
11051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    void focusStateChanged();
11151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    virtual void setActive(bool = true) OVERRIDE;
1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    virtual void setHovered(bool = true) OVERRIDE;
1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
114f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    bool childrenOrSiblingsAffectedByFocus() const { return hasRestyleFlag(ChildrenOrSiblingsAffectedByFocus); }
115f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    void setChildrenOrSiblingsAffectedByFocus() { setRestyleFlag(ChildrenOrSiblingsAffectedByFocus); }
11607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch
117f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    bool childrenOrSiblingsAffectedByHover() const { return hasRestyleFlag(ChildrenOrSiblingsAffectedByHover); }
118f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    void setChildrenOrSiblingsAffectedByHover() { setRestyleFlag(ChildrenOrSiblingsAffectedByHover); }
11907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch
120f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    bool childrenOrSiblingsAffectedByActive() const { return hasRestyleFlag(ChildrenOrSiblingsAffectedByActive); }
121f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    void setChildrenOrSiblingsAffectedByActive() { setRestyleFlag(ChildrenOrSiblingsAffectedByActive); }
12207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch
123f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    bool childrenOrSiblingsAffectedByDrag() const { return hasRestyleFlag(ChildrenOrSiblingsAffectedByDrag); }
124f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    void setChildrenOrSiblingsAffectedByDrag() { setRestyleFlag(ChildrenOrSiblingsAffectedByDrag); }
12507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch
12607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    bool childrenAffectedByPositionalRules() const { return hasRestyleFlag(ChildrenAffectedByForwardPositionalRules) || hasRestyleFlag(ChildrenAffectedByBackwardPositionalRules); }
12707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch
12807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    bool childrenAffectedByFirstChildRules() const { return hasRestyleFlag(ChildrenAffectedByFirstChildRules); }
12907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    void setChildrenAffectedByFirstChildRules() { setRestyleFlag(ChildrenAffectedByFirstChildRules); }
13007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch
13107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    bool childrenAffectedByLastChildRules() const { return hasRestyleFlag(ChildrenAffectedByLastChildRules); }
13207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    void setChildrenAffectedByLastChildRules() { setRestyleFlag(ChildrenAffectedByLastChildRules); }
13307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch
13407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    bool childrenAffectedByDirectAdjacentRules() const { return hasRestyleFlag(ChildrenAffectedByDirectAdjacentRules); }
13507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    void setChildrenAffectedByDirectAdjacentRules() { setRestyleFlag(ChildrenAffectedByDirectAdjacentRules); }
13607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch
13707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    bool childrenAffectedByIndirectAdjacentRules() const { return hasRestyleFlag(ChildrenAffectedByIndirectAdjacentRules); }
13807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    void setChildrenAffectedByIndirectAdjacentRules() { setRestyleFlag(ChildrenAffectedByIndirectAdjacentRules); }
13907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch
14007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    bool childrenAffectedByForwardPositionalRules() const { return hasRestyleFlag(ChildrenAffectedByForwardPositionalRules); }
14107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    void setChildrenAffectedByForwardPositionalRules() { setRestyleFlag(ChildrenAffectedByForwardPositionalRules); }
14207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch
14307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    bool childrenAffectedByBackwardPositionalRules() const { return hasRestyleFlag(ChildrenAffectedByBackwardPositionalRules); }
14407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    void setChildrenAffectedByBackwardPositionalRules() { setRestyleFlag(ChildrenAffectedByBackwardPositionalRules); }
14507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch
14610f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch    // FIXME: These methods should all be renamed to something better than "check",
14710f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch    // since it's not clear that they alter the style bits of siblings and children.
14807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    void checkForChildrenAdjacentRuleChanges();
149c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    enum SiblingCheckType { FinishedParsingChildren, SiblingElementInserted, SiblingElementRemoved };
150197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    void checkForSiblingStyleChanges(SiblingCheckType, Node* nodeBeforeChange, Node* nodeAfterChange);
1517242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    void recalcChildStyle(StyleRecalcChange);
15207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch
15307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    bool childrenSupportStyleSharing() const { return !hasRestyleFlags(); }
15407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch
1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // -----------------------------------------------------------------------------
15653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    // Notification of document structure changes (see core/dom/Node.h for more notification methods)
1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
158c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    enum ChildrenChangeType { ElementInserted, NonElementInserted, ElementRemoved, NonElementRemoved, AllChildrenRemoved, TextChanged };
159197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    enum ChildrenChangeSource { ChildrenChangeSourceAPI, ChildrenChangeSourceParser };
160197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    struct ChildrenChange {
161197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        STACK_ALLOCATED();
162197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    public:
163c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        static ChildrenChange forInsertion(Node& node, ChildrenChangeSource byParser)
164c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        {
165c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            ChildrenChange change = {
166c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)                node.isElementNode() ? ElementInserted : NonElementInserted,
167c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)                node.previousSibling(),
168c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)                node.nextSibling(),
169c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)                byParser
170c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            };
171c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            return change;
172c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        }
173c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
174c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        static ChildrenChange forRemoval(Node& node, Node* previousSibling, Node* nextSibling, ChildrenChangeSource byParser)
175c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        {
176c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            ChildrenChange change = {
177c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)                node.isElementNode() ? ElementRemoved : NonElementRemoved,
178c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)                previousSibling,
179c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)                nextSibling,
180c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)                byParser
181c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            };
182c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            return change;
183c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        }
184c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
185c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        bool isChildInsertion() const { return type == ElementInserted || type == NonElementInserted; }
186c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        bool isChildRemoval() const { return type == ElementRemoved || type == NonElementRemoved; }
187c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        bool isChildElementChange() const { return type == ElementInserted || type == ElementRemoved; }
188c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
189197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        ChildrenChangeType type;
190197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        RawPtrWillBeMember<Node> siblingBeforeChange;
191197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        RawPtrWillBeMember<Node> siblingAfterChange;
192197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        ChildrenChangeSource byParser;
193197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    };
194197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
1955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Notifies the node that it's list of children have changed (either by adding or removing child nodes), or a child
1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // node that is of the type CDATA_SECTION_NODE, TEXT_NODE or COMMENT_NODE has changed its value.
197197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    virtual void childrenChanged(const ChildrenChange&);
1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void disconnectDescendantFrames();
2005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
201323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    virtual void trace(Visitor*) OVERRIDE;
202323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)
2035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)protected:
2045267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    ContainerNode(TreeScope*, ConstructionType = CreateContainer);
2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
206c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    void invalidateNodeListCachesInAncestors(const QualifiedName* attrName = 0, Element* attributeOwnerElement = 0);
207c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
208323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)#if !ENABLE(OILPAN)
209926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    void removeDetachedChildren();
210323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)#endif
211323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)
2125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void setFirstChild(Node* child) { m_firstChild = child; }
2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void setLastChild(Node* child) { m_lastChild = child; }
2145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
215c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    // Utility functions for NodeListsNodeData API.
216c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    template <typename Collection> PassRefPtrWillBeRawPtr<Collection> ensureCachedCollection(CollectionType);
217c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    template <typename Collection> PassRefPtrWillBeRawPtr<Collection> ensureCachedCollection(CollectionType, const AtomicString& name);
218c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    template <typename Collection> PassRefPtrWillBeRawPtr<Collection> ensureCachedCollection(CollectionType, const AtomicString& namespaceURI, const AtomicString& localName);
219c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    template <typename Collection> Collection* cachedCollection(CollectionType);
220c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
2215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)private:
222c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    bool isContainerNode() const WTF_DELETED_FUNCTION; // This will catch anyone doing an unnecessary check.
223c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    bool isTextNode() const WTF_DELETED_FUNCTION; // This will catch anyone doing an unnecessary check.
224c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
225c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    NodeListsNodeData& ensureNodeLists();
226f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    void removeBetween(Node* previousChild, Node* nextChild, Node& oldChild);
227f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    void insertBeforeCommon(Node& nextChild, Node& oldChild);
2285d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    void appendChildCommon(Node& child);
22951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    void updateTreeAfterInsertion(Node& child);
23051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    void willRemoveChildren();
23151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    void willRemoveChild(Node& child);
232197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    void removeDetachedChildrenInContainer(ContainerNode&);
233197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    void addChildNodesToDeletionQueue(Node*&, Node*&, ContainerNode&);
23451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
235c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    void notifyNodeInserted(Node&, ChildrenChangeSource = ChildrenChangeSourceAPI);
236f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    void notifyNodeInsertedInternal(Node&, NodeVector& postInsertionNotificationTargets);
237c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    void notifyNodeRemoved(Node&);
238f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
23907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    bool hasRestyleFlag(DynamicRestyleFlags mask) const { return hasRareData() && hasRestyleFlagInternal(mask); }
24007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    bool hasRestyleFlags() const { return hasRareData() && hasRestyleFlagsInternal(); }
24107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    void setRestyleFlag(DynamicRestyleFlags);
24207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    bool hasRestyleFlagInternal(DynamicRestyleFlags) const;
24307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    bool hasRestyleFlagsInternal() const;
24407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch
245a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    inline bool checkAcceptChildGuaranteedNodeTypes(const Node& newChild, ExceptionState&) const;
246a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    inline bool checkAcceptChild(const Node* newChild, const Node* oldChild, ExceptionState&) const;
24751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    inline bool containsConsideringHostElements(const Node&) const;
24851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    inline bool isChildTypeAllowed(const Node& child) const;
2495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
250591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    void attachChildren(const AttachContext& = AttachContext());
251591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    void detachChildren(const AttachContext& = AttachContext());
252591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch
253521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    bool getUpperLeftCorner(FloatPoint&) const;
254521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    bool getLowerRightCorner(FloatPoint&) const;
2555267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
256323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    RawPtrWillBeMember<Node> m_firstChild;
257323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    RawPtrWillBeMember<Node> m_lastChild;
2585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
2595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
260197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#if ENABLE(ASSERT)
2615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool childAttachedAllowedWhenAttachingChildren(ContainerNode*);
2625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif
2635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2641e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)DEFINE_NODE_TYPE_CASTS(ContainerNode, isContainerNode());
2655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
266d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)inline bool ContainerNode::hasChildCount(unsigned count) const
267d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
268d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    Node* child = m_firstChild;
269d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    while (count && child) {
270d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        child = child->nextSibling();
271d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        --count;
272d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    }
273d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return !count && !child;
274d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
275d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
2765267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)inline ContainerNode::ContainerNode(TreeScope* treeScope, ConstructionType type)
2775267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    : Node(treeScope, type)
278323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    , m_firstChild(nullptr)
279323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    , m_lastChild(nullptr)
2805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
283591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochinline void ContainerNode::attachChildren(const AttachContext& context)
2845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
285591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    AttachContext childrenContext(context);
286591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    childrenContext.resolvedStyle = 0;
287591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch
2885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (Node* child = firstChild(); child; child = child->nextSibling()) {
2891e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        ASSERT(child->needsAttach() || childAttachedAllowedWhenAttachingChildren(this));
2901e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        if (child->needsAttach())
291591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch            child->attach(childrenContext);
2925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
295591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochinline void ContainerNode::detachChildren(const AttachContext& context)
2965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
297591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    AttachContext childrenContext(context);
298591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    childrenContext.resolvedStyle = 0;
2995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (Node* child = firstChild(); child; child = child->nextSibling())
301591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        child->detach(childrenContext);
3025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
304d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)inline unsigned Node::countChildren() const
3055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!isContainerNode())
3075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
308d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return toContainerNode(this)->countChildren();
3095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)inline Node* Node::firstChild() const
3125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!isContainerNode())
3145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
3155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return toContainerNode(this)->firstChild();
3165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)inline Node* Node::lastChild() const
3195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!isContainerNode())
3215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
3225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return toContainerNode(this)->lastChild();
3235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
32507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdochinline ContainerNode* Node::parentElementOrShadowRoot() const
326d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
327d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    ContainerNode* parent = parentNode();
328d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return parent && (parent->isElementNode() || parent->isShadowRoot()) ? parent : 0;
3295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
331d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)inline ContainerNode* Node::parentElementOrDocumentFragment() const
332d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles){
333d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    ContainerNode* parent = parentNode();
334d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    return parent && (parent->isElementNode() || parent->isDocumentFragment()) ? parent : 0;
335d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)}
336d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
337197021e6b966cfb06891637935ef33fff06433d1Ben Murdochinline bool Node::isTreeScope() const
338197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{
339197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    return &treeScope().rootNode() == this;
340197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch}
341197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
342c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)inline void getChildNodes(ContainerNode& node, NodeVector& nodes)
3435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(!nodes.size());
34519cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)    for (Node* child = node.firstChild(); child; child = child->nextSibling())
3465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        nodes.append(child);
3475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
349c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink
3505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif // ContainerNode_h
352