1ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block/*
2ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block * Copyright (C) 2010 Google, Inc. All Rights Reserved.
3ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block *
4ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block * Redistribution and use in source and binary forms, with or without
5ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block * modification, are permitted provided that the following conditions
6ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block * are met:
7ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block * 1. Redistributions of source code must retain the above copyright
8ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block *    notice, this list of conditions and the following disclaimer.
9ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block * 2. Redistributions in binary form must reproduce the above copyright
10ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block *    notice, this list of conditions and the following disclaimer in the
11ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block *    documentation and/or other materials provided with the distribution.
12ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block *
13ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY
14ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL GOOGLE INC. OR
17ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block */
25ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
26ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block#ifndef HTMLFormattingElementList_h
27ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block#define HTMLFormattingElementList_h
28ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
29ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block#include <wtf/Forward.h>
30ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block#include <wtf/RefPtr.h>
31ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block#include <wtf/Vector.h>
32ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
33ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Blocknamespace WebCore {
34ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
35ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Blockclass Element;
36ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
37ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block// This may end up merged into HTMLElementStack.
38ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdochclass HTMLFormattingElementList {
39ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch    WTF_MAKE_NONCOPYABLE(HTMLFormattingElementList);
40ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Blockpublic:
41ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    HTMLFormattingElementList();
42ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    ~HTMLFormattingElementList();
43ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
44ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    // Ideally Entry would be private, but HTMLTreeBuilder has to coordinate
45ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    // between the HTMLFormattingElementList and HTMLElementStack and needs
46ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    // access to Entry::isMarker() and Entry::replaceElement() to do so.
47ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    class Entry {
48ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    public:
49e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        // Inline because they're hot and Vector<T> uses them.
50e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        explicit Entry(Element* element)
51e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            : m_element(element)
52e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        {
53e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            ASSERT(element);
54e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        }
55ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        enum MarkerEntryType { MarkerEntry };
56e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        Entry(MarkerEntryType)
57e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            : m_element(0)
58e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        {
59e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        }
60e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        ~Entry() {}
61e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
62e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        bool isMarker() const { return !m_element; }
63e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
64e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        Element* element() const
65e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        {
66e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            // The fact that !m_element == isMarker() is an implementation detail
67e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            // callers should check isMarker() before calling element().
68e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            ASSERT(m_element);
69e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            return m_element.get();
70e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        }
71e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        void replaceElement(PassRefPtr<Element> element) { m_element = element; }
72e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
73e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        // Needed for use with Vector.  These are super-hot and must be inline.
74e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        bool operator==(Element* element) const { return m_element == element; }
75e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        bool operator!=(Element* element) const { return m_element != element; }
76ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
77e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    private:
78e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        RefPtr<Element> m_element;
79e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    };
80e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
81e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    class Bookmark {
82e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    public:
83967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        Bookmark(Entry* entry)
84967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch            : m_hasBeenMoved(false)
85967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch            , m_mark(entry)
86e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        {
87e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        }
88ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
89967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        void moveToAfter(Entry* before)
90e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        {
91967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch            m_hasBeenMoved = true;
92967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch            m_mark = before;
93e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        }
94ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
95967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        bool hasBeenMoved() const { return m_hasBeenMoved; }
96967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        Entry* mark() const { return m_mark; }
97ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
98ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    private:
99967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        bool m_hasBeenMoved;
100967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        Entry* m_mark;
101ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    };
102ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
103ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    bool isEmpty() const { return !size(); }
104ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    size_t size() const { return m_entries.size(); }
105ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
106ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    Element* closestElementInScopeWithName(const AtomicString&);
107ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
108ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    Entry* find(Element*);
109ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    bool contains(Element*);
110ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    void append(Element*);
111ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    void remove(Element*);
112ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
113e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    Bookmark bookmarkFor(Element*);
114967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    void swapTo(Element* oldElement, Element* newElement, const Bookmark&);
115e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
116ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    void appendMarker();
117967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    // clearToLastMarker also clears the marker (per the HTML5 spec).
118ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    void clearToLastMarker();
119ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
120e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    const Entry& at(size_t i) const { return m_entries[i]; }
121e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    Entry& at(size_t i) { return m_entries[i]; }
122e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
123e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#ifndef NDEBUG
124e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    void show();
125e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#endif
126ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
127ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Blockprivate:
128967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    Entry* first() { return &at(0); }
129967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch
130ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    Vector<Entry> m_entries;
131ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block};
132ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
133ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block}
134ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
135ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block#endif // HTMLFormattingElementList_h
136