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 "wtf/Forward.h"
     32 #include "wtf/text/AtomicString.h"
     33 
     34 namespace WebCore {
     35 
     36 class ContainerNode;
     37 class DOMSelection;
     38 class Document;
     39 class Element;
     40 class HTMLLabelElement;
     41 class HTMLMapElement;
     42 class LayoutPoint;
     43 class IdTargetObserverRegistry;
     44 class Node;
     45 class RenderObject;
     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 {
     51     friend class Document;
     52     friend class TreeScopeAdopter;
     53 
     54 public:
     55     TreeScope* parentTreeScope() const { return m_parentTreeScope; }
     56     void setParentTreeScope(TreeScope*);
     57 
     58     Element* adjustedFocusedElement() const;
     59     Element* getElementById(const AtomicString&) const;
     60     bool hasElementWithId(StringImpl* 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* documentScope() const { return m_documentScope; }
     66 
     67     Node* ancestorInThisScope(Node*) const;
     68 
     69     void addImageMap(HTMLMapElement*);
     70     void removeImageMap(HTMLMapElement*);
     71     HTMLMapElement* getImageMap(const String& url) const;
     72 
     73     Element* elementFromPoint(int x, int y) const;
     74 
     75     // For accessibility.
     76     bool shouldCacheLabelsByForAttribute() const { return m_labelsByForAttribute; }
     77     void addLabel(const AtomicString& forAttributeValue, HTMLLabelElement*);
     78     void removeLabel(const AtomicString& forAttributeValue, HTMLLabelElement*);
     79     HTMLLabelElement* labelElementForId(const AtomicString& forAttributeValue);
     80 
     81     DOMSelection* getSelection() const;
     82 
     83     // Find first anchor with the given name.
     84     // First searches for an element with the given ID, but if that fails, then looks
     85     // for an anchor with the given name. ID matching is always case sensitive, but
     86     // Anchor name matching is case sensitive in strict mode and not case sensitive in
     87     // quirks mode for historical compatibility reasons.
     88     Element* findAnchor(const String& name);
     89 
     90     bool applyAuthorStyles() const;
     91 
     92     // Used by the basic DOM mutation methods (e.g., appendChild()).
     93     void adoptIfNeeded(Node&);
     94 
     95     Node* rootNode() const { return m_rootNode; }
     96 
     97     IdTargetObserverRegistry& idTargetObserverRegistry() const { return *m_idTargetObserverRegistry.get(); }
     98 
     99     // Nodes belonging to this scope hold guard references -
    100     // these are enough to keep the scope from being destroyed, but
    101     // not enough to keep it from removing its children. This allows a
    102     // node that outlives its scope to still have a valid document
    103     // pointer without introducing reference cycles.
    104     void guardRef()
    105     {
    106         ASSERT(!deletionHasBegun());
    107         ++m_guardRefCount;
    108     }
    109 
    110     void guardDeref()
    111     {
    112         ASSERT(!deletionHasBegun());
    113         --m_guardRefCount;
    114         if (!m_guardRefCount && !refCount() && !rootNodeHasTreeSharedParent()) {
    115             beginDeletion();
    116             delete this;
    117         }
    118     }
    119 
    120     void removedLastRefToScope();
    121 
    122     bool isInclusiveAncestorOf(const TreeScope&) const;
    123     unsigned short comparePosition(const TreeScope&) const;
    124 
    125     Element* getElementByAccessKey(const String& key) const;
    126 
    127 protected:
    128     TreeScope(ContainerNode*, Document*);
    129     TreeScope(Document*);
    130     virtual ~TreeScope();
    131 
    132     void destroyTreeScopeData();
    133     void clearDocumentScope();
    134     void setDocumentScope(Document* document)
    135     {
    136         ASSERT(document);
    137         m_documentScope = document;
    138     }
    139 
    140     bool hasGuardRefCount() const { return m_guardRefCount; }
    141 
    142 private:
    143     TreeScope();
    144 
    145     virtual void dispose() { }
    146 
    147     int refCount() const;
    148 #if SECURITY_ASSERT_ENABLED
    149     bool deletionHasBegun();
    150     void beginDeletion();
    151 #else
    152     bool deletionHasBegun() { return false; }
    153     void beginDeletion() { }
    154 #endif
    155 
    156     bool rootNodeHasTreeSharedParent() const;
    157 
    158     Node* m_rootNode;
    159     Document* m_documentScope;
    160     TreeScope* m_parentTreeScope;
    161     int m_guardRefCount;
    162 
    163     OwnPtr<DocumentOrderedMap> m_elementsById;
    164     OwnPtr<DocumentOrderedMap> m_imageMapsByName;
    165     OwnPtr<DocumentOrderedMap> m_labelsByForAttribute;
    166 
    167     OwnPtr<IdTargetObserverRegistry> m_idTargetObserverRegistry;
    168 
    169     mutable RefPtr<DOMSelection> m_selection;
    170 };
    171 
    172 inline bool TreeScope::hasElementWithId(StringImpl* id) const
    173 {
    174     ASSERT(id);
    175     return m_elementsById && m_elementsById->contains(id);
    176 }
    177 
    178 inline bool TreeScope::containsMultipleElementsWithId(const AtomicString& id) const
    179 {
    180     return m_elementsById && m_elementsById->containsMultiple(id.impl());
    181 }
    182 
    183 inline bool operator==(const TreeScope& a, const TreeScope& b) { return &a == &b; }
    184 inline bool operator==(const TreeScope& a, const TreeScope* b) { return &a == b; }
    185 inline bool operator==(const TreeScope* a, const TreeScope& b) { return a == &b; }
    186 inline bool operator!=(const TreeScope& a, const TreeScope& b) { return !(a == b); }
    187 inline bool operator!=(const TreeScope& a, const TreeScope* b) { return !(a == b); }
    188 inline bool operator!=(const TreeScope* a, const TreeScope& b) { return !(a == b); }
    189 
    190 RenderObject* rendererFromPoint(Document*, int x, int y, LayoutPoint* localPoint = 0);
    191 TreeScope* commonTreeScope(Node*, Node*);
    192 
    193 } // namespace WebCore
    194 
    195 #endif // TreeScope_h
    196