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