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