15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/*
25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2012 Google Inc. All rights reserved.
35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without
55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modification, are permitted provided that the following conditions are
65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * met:
75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *     * Redistributions of source code must retain the above copyright
95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * notice, this list of conditions and the following disclaimer.
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *     * Neither the name of Google Inc. nor the names of its
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * contributors may be used to endorse or promote products derived from
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * this software without specific prior written permission.
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
253c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch */
265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2743e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)#ifndef ElementShadow_h
28e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)#define ElementShadow_h
2953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "core/dom/shadow/InsertionPoint.h"
31c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#include "core/dom/shadow/SelectRuleFeatureSet.h"
325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "core/dom/shadow/ShadowRoot.h"
333c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch#include "platform/heap/Handle.h"
345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "wtf/DoublyLinkedList.h"
355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "wtf/HashMap.h"
363c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch#include "wtf/Noncopyable.h"
375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "wtf/PassOwnPtr.h"
385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace blink {
403c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch
415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class ElementShadow FINAL : public NoBaseWillBeGarbageCollectedFinalized<ElementShadow> {
425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    WTF_MAKE_NONCOPYABLE(ElementShadow);
435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public:
45d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    static PassOwnPtrWillBeRawPtr<ElementShadow> create();
465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ~ElementShadow();
4743e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)
485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Element* host() const;
495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ShadowRoot* youngestShadowRoot() const { return m_shadowRoots.head(); }
5010f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch    ShadowRoot* oldestShadowRoot() const { return m_shadowRoots.tail(); }
515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ElementShadow* containingShadow() const;
525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ShadowRoot& addShadowRoot(Element& shadowHost, ShadowRoot::ShadowRootType);
545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
553c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    bool hasSameStyles(const ElementShadow*) const;
565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void attach(const Node::AttachContext&);
585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void detach(const Node::AttachContext&);
595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
603c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    void distributedNodePseudoStateChanged(CSSSelector::PseudoType);
615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void willAffectSelector();
625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const SelectRuleFeatureSet& ensureSelectFeatureSet();
635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void distributeIfNeeded();
653c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    void setNeedsDistributionRecalc();
665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const InsertionPoint* finalDestinationInsertionPointFor(const Node*) const;
685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const DestinationInsertionPoints* destinationInsertionPointsFor(const Node*) const;
695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
703c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    void didDistributeNode(const Node*, InsertionPoint*);
715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void trace(Visitor*);
735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)private:
753c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    ElementShadow();
765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#if !ENABLE(OILPAN)
785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void removeDetachedShadowRoots();
795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif
803c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch
815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void distribute();
825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void clearDistribution();
835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void collectSelectFeatureSetFrom(ShadowRoot&);
853c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    void distributeNodeChildrenTo(InsertionPoint*, ContainerNode*);
865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool needsSelectFeatureSet() const { return m_needsSelectFeatureSet; }
885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void setNeedsSelectFeatureSet() { m_needsSelectFeatureSet = true; }
895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
903c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    typedef WillBeHeapHashMap<RawPtrWillBeMember<const Node>, DestinationInsertionPoints> NodeToDestinationInsertionPoints;
915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    NodeToDestinationInsertionPoints m_nodeToInsertionPoints;
925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    SelectRuleFeatureSet m_selectFeatures;
945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // FIXME: Oilpan: add a heap-based version of DoublyLinkedList<>.
953c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    DoublyLinkedList<ShadowRoot> m_shadowRoots;
965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool m_needsDistributionRecalc;
975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool m_needsSelectFeatureSet;
985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1003c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdochinline Element* ElementShadow::host() const
1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(!m_shadowRoots.isEmpty());
1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return youngestShadowRoot()->host();
1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1053c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch
1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)inline ShadowRoot* Node::youngestShadowRoot() const
1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!isElementNode())
1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
1103c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    return toElement(this)->youngestShadowRoot();
111926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
112926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
113926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)inline ShadowRoot* Element::youngestShadowRoot() const
114926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (ElementShadow* shadow = this->shadow())
116        return shadow->youngestShadowRoot();
117    return 0;
118}
119
120inline ElementShadow* ElementShadow::containingShadow() const
121{
122    if (ShadowRoot* parentRoot = host()->containingShadowRoot())
123        return parentRoot->owner();
124    return 0;
125}
126
127inline void ElementShadow::distributeIfNeeded()
128{
129    if (m_needsDistributionRecalc)
130        distribute();
131    m_needsDistributionRecalc = false;
132}
133
134} // namespace
135
136#endif
137