HTMLElementStack.h revision ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddb
1/* 2 * Copyright (C) 2010 Google, Inc. All Rights Reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#ifndef HTMLElementStack_h 27#define HTMLElementStack_h 28 29#include <wtf/Forward.h> 30#include <wtf/Noncopyable.h> 31#include <wtf/OwnPtr.h> 32#include <wtf/PassOwnPtr.h> 33#include <wtf/RefPtr.h> 34 35namespace WebCore { 36 37class Element; 38class QualifiedName; 39 40// NOTE: The HTML5 spec uses a backwards (grows downward) stack. We're using 41// more standard (grows upwards) stack terminology here. 42class HTMLElementStack { 43 WTF_MAKE_NONCOPYABLE(HTMLElementStack); WTF_MAKE_FAST_ALLOCATED; 44public: 45 HTMLElementStack(); 46 ~HTMLElementStack(); 47 48 class ElementRecord { 49 WTF_MAKE_NONCOPYABLE(ElementRecord); 50 public: 51 ~ElementRecord(); // Public for ~PassOwnPtr() 52 53 Element* element() const { return m_element.get(); } 54 void replaceElement(PassRefPtr<Element>); 55 56 bool isAbove(ElementRecord*) const; 57 58 ElementRecord* next() const { return m_next.get(); } 59 60 private: 61 friend class HTMLElementStack; 62 63 ElementRecord(PassRefPtr<Element>, PassOwnPtr<ElementRecord>); 64 65 PassOwnPtr<ElementRecord> releaseNext() { return m_next.release(); } 66 void setNext(PassOwnPtr<ElementRecord> next) { m_next = next; } 67 68 RefPtr<Element> m_element; 69 OwnPtr<ElementRecord> m_next; 70 }; 71 72 // Inlining this function is a (small) performance win on the parsing 73 // benchmark. 74 Element* top() const 75 { 76 ASSERT(m_top->element()); 77 return m_top->element(); 78 } 79 80 Element* oneBelowTop() const; 81 ElementRecord* topRecord() const; 82 Element* bottom() const; 83 ElementRecord* find(Element*) const; 84 ElementRecord* topmost(const AtomicString& tagName) const; 85 86 void insertAbove(PassRefPtr<Element>, ElementRecord*); 87 88 void push(PassRefPtr<Element>); 89 void pushHTMLHtmlElement(PassRefPtr<Element>); 90 void pushHTMLHeadElement(PassRefPtr<Element>); 91 void pushHTMLBodyElement(PassRefPtr<Element>); 92 93 void pop(); 94 void popUntil(const AtomicString& tagName); 95 void popUntil(Element*); 96 void popUntilPopped(const AtomicString& tagName); 97 void popUntilPopped(Element*); 98 void popUntilNumberedHeaderElementPopped(); 99 void popUntilTableScopeMarker(); // "clear the stack back to a table context" in the spec. 100 void popUntilTableBodyScopeMarker(); // "clear the stack back to a table body context" in the spec. 101 void popUntilTableRowScopeMarker(); // "clear the stack back to a table row context" in the spec. 102 void popUntilForeignContentScopeMarker(); 103 void popHTMLHeadElement(); 104 void popHTMLBodyElement(); 105 void popAll(); 106 107 void remove(Element*); 108 void removeHTMLHeadElement(Element*); 109 110 bool contains(Element*) const; 111 bool contains(const AtomicString& tagName) const; 112 113 bool inScope(Element*) const; 114 bool inScope(const AtomicString& tagName) const; 115 bool inScope(const QualifiedName&) const; 116 bool inListItemScope(const AtomicString& tagName) const; 117 bool inListItemScope(const QualifiedName&) const; 118 bool inTableScope(const AtomicString& tagName) const; 119 bool inTableScope(const QualifiedName&) const; 120 bool inButtonScope(const AtomicString& tagName) const; 121 bool inButtonScope(const QualifiedName&) const; 122 bool inSelectScope(const AtomicString& tagName) const; 123 bool inSelectScope(const QualifiedName&) const; 124 125 bool hasOnlyHTMLElementsInScope() const; 126 bool hasNumberedHeaderElementInScope() const; 127 128 bool hasOnlyOneElement() const; 129 bool secondElementIsHTMLBodyElement() const; 130 131 Element* htmlElement() const; 132 Element* headElement() const; 133 Element* bodyElement() const; 134 135#ifndef NDEBUG 136 void show(); 137#endif 138 139private: 140 void pushCommon(PassRefPtr<Element>); 141 void popCommon(); 142 void removeNonTopCommon(Element*); 143 144 OwnPtr<ElementRecord> m_top; 145 146 // We remember <html>, <head> and <body> as they are pushed. Their 147 // ElementRecords keep them alive. <html> is never popped. 148 // FIXME: We don't currently require type-specific information about 149 // these elements so we haven't yet bothered to plumb the types all the 150 // way down through createElement, etc. 151 Element* m_htmlElement; 152 Element* m_headElement; 153 Element* m_bodyElement; 154}; 155 156} // namespace WebCore 157 158#endif // HTMLElementStack_h 159