HTMLFormattingElementList.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 HTMLFormattingElementList_h
27#define HTMLFormattingElementList_h
28
29#include <wtf/Forward.h>
30#include <wtf/RefPtr.h>
31#include <wtf/Vector.h>
32
33namespace WebCore {
34
35class Element;
36
37// This may end up merged into HTMLElementStack.
38class HTMLFormattingElementList {
39    WTF_MAKE_NONCOPYABLE(HTMLFormattingElementList);
40public:
41    HTMLFormattingElementList();
42    ~HTMLFormattingElementList();
43
44    // Ideally Entry would be private, but HTMLTreeBuilder has to coordinate
45    // between the HTMLFormattingElementList and HTMLElementStack and needs
46    // access to Entry::isMarker() and Entry::replaceElement() to do so.
47    class Entry {
48    public:
49        // Inline because they're hot and Vector<T> uses them.
50        explicit Entry(Element* element)
51            : m_element(element)
52        {
53            ASSERT(element);
54        }
55        enum MarkerEntryType { MarkerEntry };
56        Entry(MarkerEntryType)
57            : m_element(0)
58        {
59        }
60        ~Entry() {}
61
62        bool isMarker() const { return !m_element; }
63
64        Element* element() const
65        {
66            // The fact that !m_element == isMarker() is an implementation detail
67            // callers should check isMarker() before calling element().
68            ASSERT(m_element);
69            return m_element.get();
70        }
71        void replaceElement(PassRefPtr<Element> element) { m_element = element; }
72
73        // Needed for use with Vector.  These are super-hot and must be inline.
74        bool operator==(Element* element) const { return m_element == element; }
75        bool operator!=(Element* element) const { return m_element != element; }
76
77    private:
78        RefPtr<Element> m_element;
79    };
80
81    class Bookmark {
82    public:
83        Bookmark(Entry* entry)
84            : m_hasBeenMoved(false)
85            , m_mark(entry)
86        {
87        }
88
89        void moveToAfter(Entry* before)
90        {
91            m_hasBeenMoved = true;
92            m_mark = before;
93        }
94
95        bool hasBeenMoved() const { return m_hasBeenMoved; }
96        Entry* mark() const { return m_mark; }
97
98    private:
99        bool m_hasBeenMoved;
100        Entry* m_mark;
101    };
102
103    bool isEmpty() const { return !size(); }
104    size_t size() const { return m_entries.size(); }
105
106    Element* closestElementInScopeWithName(const AtomicString&);
107
108    Entry* find(Element*);
109    bool contains(Element*);
110    void append(Element*);
111    void remove(Element*);
112
113    Bookmark bookmarkFor(Element*);
114    void swapTo(Element* oldElement, Element* newElement, const Bookmark&);
115
116    void appendMarker();
117    // clearToLastMarker also clears the marker (per the HTML5 spec).
118    void clearToLastMarker();
119
120    const Entry& at(size_t i) const { return m_entries[i]; }
121    Entry& at(size_t i) { return m_entries[i]; }
122
123#ifndef NDEBUG
124    void show();
125#endif
126
127private:
128    Entry* first() { return &at(0); }
129
130    Vector<Entry> m_entries;
131};
132
133}
134
135#endif // HTMLFormattingElementList_h
136