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