Home | History | Annotate | Download | only in dom
      1 /*
      2  * Copyright (C) 2011 Google Inc. All Rights Reserved.
      3  * Copyright (C) 2012 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
      7  * are met:
      8  * 1. Redistributions of source code must retain the above copyright
      9  *    notice, this list of conditions and the following disclaimer.
     10  * 2. Redistributions in binary form must reproduce the above copyright
     11  *    notice, this list of conditions and the following disclaimer in the
     12  *    documentation and/or other materials provided with the distribution.
     13  *
     14  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
     15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     17  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
     18  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     19  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     20  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     21  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
     22  * 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 TreeScope_h
     28 #define TreeScope_h
     29 
     30 #include "core/dom/DocumentOrderedMap.h"
     31 #include "platform/heap/Handle.h"
     32 #include "wtf/text/AtomicString.h"
     33 
     34 namespace blink {
     35 
     36 class ContainerNode;
     37 class DOMSelection;
     38 class Document;
     39 class Element;
     40 class HTMLLabelElement;
     41 class HTMLMapElement;
     42 class HitTestResult;
     43 class IdTargetObserverRegistry;
     44 class ScopedStyleResolver;
     45 class Node;
     46 
     47 // A class which inherits both Node and TreeScope must call clearRareData() in its destructor
     48 // so that the Node destructor no longer does problematic NodeList cache manipulation in
     49 // the destructor.
     50 class TreeScope : public WillBeGarbageCollectedMixin {
     51 public:
     52     TreeScope* parentTreeScope() const { return m_parentTreeScope; }
     53 
     54     TreeScope* olderShadowRootOrParentTreeScope() const;
     55     bool isInclusiveOlderSiblingShadowRootOrAncestorTreeScopeOf(const TreeScope&) const;
     56 
     57     Element* adjustedFocusedElement() const;
     58     Element* getElementById(const AtomicString&) const;
     59     const WillBeHeapVector<RawPtrWillBeMember<Element> >& getAllElementsById(const AtomicString&) const;
     60     bool hasElementWithId(const AtomicString& id) const;
     61     bool containsMultipleElementsWithId(const AtomicString& id) const;
     62     void addElementById(const AtomicString& elementId, Element*);
     63     void removeElementById(const AtomicString& elementId, Element*);
     64 
     65     Document& document() const
     66     {
     67         ASSERT(m_document);
     68         return *m_document;
     69     }
     70 
     71     Node* ancestorInThisScope(Node*) const;
     72 
     73     void addImageMap(HTMLMapElement*);
     74     void removeImageMap(HTMLMapElement*);
     75     HTMLMapElement* getImageMap(const String& url) const;
     76 
     77     Element* elementFromPoint(int x, int y) const;
     78 
     79     // For accessibility.
     80     bool shouldCacheLabelsByForAttribute() const { return m_labelsByForAttribute; }
     81     void addLabel(const AtomicString& forAttributeValue, HTMLLabelElement*);
     82     void removeLabel(const AtomicString& forAttributeValue, HTMLLabelElement*);
     83     HTMLLabelElement* labelElementForId(const AtomicString& forAttributeValue);
     84 
     85     DOMSelection* getSelection() const;
     86 
     87     // Find first anchor with the given name.
     88     // First searches for an element with the given ID, but if that fails, then looks
     89     // for an anchor with the given name. ID matching is always case sensitive, but
     90     // Anchor name matching is case sensitive in strict mode and not case sensitive in
     91     // quirks mode for historical compatibility reasons.
     92     Element* findAnchor(const String& name);
     93 
     94     // Used by the basic DOM mutation methods (e.g., appendChild()).
     95     void adoptIfNeeded(Node&);
     96 
     97     ContainerNode& rootNode() const { return *m_rootNode; }
     98 
     99     IdTargetObserverRegistry& idTargetObserverRegistry() const { return *m_idTargetObserverRegistry.get(); }
    100 
    101 
    102 #if !ENABLE(OILPAN)
    103     // Nodes belonging to this scope hold guard references -
    104     // these are enough to keep the scope from being destroyed, but
    105     // not enough to keep it from removing its children. This allows a
    106     // node that outlives its scope to still have a valid document
    107     // pointer without introducing reference cycles.
    108     void guardRef()
    109     {
    110         ASSERT(!deletionHasBegun());
    111         ++m_guardRefCount;
    112     }
    113 
    114     void guardDeref()
    115     {
    116         ASSERT(m_guardRefCount > 0);
    117         ASSERT(!deletionHasBegun());
    118         --m_guardRefCount;
    119         if (!m_guardRefCount && !refCount() && !rootNodeHasTreeSharedParent()) {
    120             beginDeletion();
    121             delete this;
    122         }
    123     }
    124 #endif
    125 
    126     void removedLastRefToScope();
    127 
    128     bool isInclusiveAncestorOf(const TreeScope&) const;
    129     unsigned short comparePosition(const TreeScope&) const;
    130 
    131     const TreeScope* commonAncestorTreeScope(const TreeScope& other) const;
    132     TreeScope* commonAncestorTreeScope(TreeScope& other);
    133 
    134     Element* getElementByAccessKey(const String& key) const;
    135 
    136     virtual void trace(Visitor*);
    137 
    138     ScopedStyleResolver* scopedStyleResolver() const { return m_scopedStyleResolver.get(); }
    139     ScopedStyleResolver& ensureScopedStyleResolver();
    140     void clearScopedStyleResolver();
    141 
    142 protected:
    143     TreeScope(ContainerNode&, Document&);
    144     TreeScope(Document&);
    145     virtual ~TreeScope();
    146 
    147 #if !ENABLE(OILPAN)
    148     void destroyTreeScopeData();
    149 #endif
    150 
    151     void setDocument(Document& document) { m_document = &document; }
    152     void setParentTreeScope(TreeScope&);
    153 
    154 #if !ENABLE(OILPAN)
    155     bool hasGuardRefCount() const { return m_guardRefCount; }
    156 #endif
    157 
    158     void setNeedsStyleRecalcForViewportUnits();
    159 
    160 private:
    161     virtual void dispose() { }
    162 
    163 #if !ENABLE(OILPAN)
    164     int refCount() const;
    165 
    166 #if ENABLE(SECURITY_ASSERT)
    167     bool deletionHasBegun();
    168     void beginDeletion();
    169 #else
    170     bool deletionHasBegun() { return false; }
    171     void beginDeletion() { }
    172 #endif
    173 #endif
    174 
    175     bool rootNodeHasTreeSharedParent() const;
    176 
    177     RawPtrWillBeMember<ContainerNode> m_rootNode;
    178     RawPtrWillBeMember<Document> m_document;
    179     RawPtrWillBeMember<TreeScope> m_parentTreeScope;
    180 
    181 #if !ENABLE(OILPAN)
    182     int m_guardRefCount;
    183 #endif
    184 
    185     OwnPtrWillBeMember<DocumentOrderedMap> m_elementsById;
    186     OwnPtrWillBeMember<DocumentOrderedMap> m_imageMapsByName;
    187     OwnPtrWillBeMember<DocumentOrderedMap> m_labelsByForAttribute;
    188 
    189     OwnPtrWillBeMember<IdTargetObserverRegistry> m_idTargetObserverRegistry;
    190 
    191     OwnPtrWillBeMember<ScopedStyleResolver> m_scopedStyleResolver;
    192 
    193     mutable RefPtrWillBeMember<DOMSelection> m_selection;
    194 };
    195 
    196 inline bool TreeScope::hasElementWithId(const AtomicString& id) const
    197 {
    198     ASSERT(!id.isNull());
    199     return m_elementsById && m_elementsById->contains(id);
    200 }
    201 
    202 inline bool TreeScope::containsMultipleElementsWithId(const AtomicString& id) const
    203 {
    204     return m_elementsById && m_elementsById->containsMultiple(id);
    205 }
    206 
    207 DEFINE_COMPARISON_OPERATORS_WITH_REFERENCES(TreeScope)
    208 
    209 HitTestResult hitTestInDocument(const Document*, int x, int y);
    210 TreeScope* commonTreeScope(Node*, Node*);
    211 
    212 } // namespace blink
    213 
    214 #endif // TreeScope_h
    215