Changeset 62077 in webkit


Ignore:
Timestamp:
Jun 28, 2010 7:52:32 PM (14 years ago)
Author:
eric@webkit.org
Message:

2010-06-28 Eric Seidel <eric@webkit.org>

Reviewed by Adam Barth.

Implement HTMLTreeBuilder::reconstructTheActiveFormattingElements
https://bugs.webkit.org/show_bug.cgi?id=41319

This is basically a direct transcription of HTML5 TreeBuilder spec:

http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#list-of-active-formatting-elements

This code is covered by various tests in html5lib/runner which we
can't run yet due to other asserts. Adam and I are working on
getting rid of those ASSERTS so that this (and other code) will
be better tested shortly.

  • html/HTMLTreeBuilder.cpp: (WebCore::HTMLTreeBuilder::insertFormatingElement): (WebCore::HTMLTreeBuilder::reconstructTheActiveFormattingElements):
  • html/HTMLTreeBuilder.h: (WebCore::HTMLTreeBuilder::ElementStack::contains): (WebCore::HTMLTreeBuilder::FormatingElementEntry::FormatingElementEntry): (WebCore::HTMLTreeBuilder::FormatingElementEntry::): (WebCore::HTMLTreeBuilder::FormatingElementEntry::isMarker): (WebCore::HTMLTreeBuilder::FormatingElementEntry::element): (WebCore::HTMLTreeBuilder::FormatingElementEntry::replaceElement):
Location:
trunk/WebCore
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r62076 r62077  
     12010-06-28  Eric Seidel  <eric@webkit.org>
     2
     3        Reviewed by Adam Barth.
     4
     5        Implement HTMLTreeBuilder::reconstructTheActiveFormattingElements
     6        https://bugs.webkit.org/show_bug.cgi?id=41319
     7
     8        This is basically a direct transcription of HTML5 TreeBuilder spec:
     9         http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#list-of-active-formatting-elements
     10
     11        This code is covered by various tests in html5lib/runner which we
     12        can't run yet due to other asserts.  Adam and I are working on
     13        getting rid of those ASSERTS so that this (and other code) will
     14        be better tested shortly.
     15
     16        * html/HTMLTreeBuilder.cpp:
     17        (WebCore::HTMLTreeBuilder::insertFormatingElement):
     18        (WebCore::HTMLTreeBuilder::reconstructTheActiveFormattingElements):
     19        * html/HTMLTreeBuilder.h:
     20        (WebCore::HTMLTreeBuilder::ElementStack::contains):
     21        (WebCore::HTMLTreeBuilder::FormatingElementEntry::FormatingElementEntry):
     22        (WebCore::HTMLTreeBuilder::FormatingElementEntry::):
     23        (WebCore::HTMLTreeBuilder::FormatingElementEntry::isMarker):
     24        (WebCore::HTMLTreeBuilder::FormatingElementEntry::element):
     25        (WebCore::HTMLTreeBuilder::FormatingElementEntry::replaceElement):
     26
    1272010-06-28  Adam Barth  <abarth@webkit.org>
    228
  • trunk/WebCore/html/HTMLTreeBuilder.cpp

    r62047 r62077  
    428428            notImplemented();
    429429            reconstructTheActiveFormattingElements();
    430             insertFormatingElement(token);
     430            insertFormattingElement(token);
    431431            return;
    432432        }
    433433        if (token.name() == bTag || token.name() == bigTag || token.name() == codeTag || token.name() == emTag || token.name() == fontTag || token.name() == iTag || token.name() == sTag || token.name() == smallTag || token.name() == strikeTag || token.name() == strongTag || token.name() == ttTag || token.name() == uTag) {
    434434            reconstructTheActiveFormattingElements();
    435             insertFormatingElement(token);
     435            insertFormattingElement(token);
    436436            return;
    437437        }
     
    439439            reconstructTheActiveFormattingElements();
    440440            notImplemented();
    441             insertFormatingElement(token);
     441            insertFormattingElement(token);
    442442            return;
    443443        }
     
    865865}
    866866
    867 void HTMLTreeBuilder::insertFormatingElement(AtomicHTMLToken& token)
    868 {
     867void HTMLTreeBuilder::insertFormattingElement(AtomicHTMLToken& token)
     868{
     869    // http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#the-stack-of-open-elements
     870    // Possible active formatting elements include:
     871    // a, b, big, code, em, font, i, nobr, s, small, strike, strong, tt, and u.
    869872    insertElement(token);
    870873    m_activeFormattingElements.append(currentElement());
     
    912915}
    913916
     917unsigned HTMLTreeBuilder::indexOfLastOpenFormattingElementOrMarker() const
     918{
     919    ASSERT(!m_activeFormattingElements.isEmpty());
     920    for (int index = m_activeFormattingElements.size() - 1; index >= 0; --index) {
     921        const FormattingElementEntry& entry = m_activeFormattingElements[index];
     922        if (entry.isMarker() || m_openElements.contains(entry.element()))
     923            return index;
     924    }
     925    return -1; // No elements are open!
     926}
     927
     928void HTMLTreeBuilder::reopenFormattingElementsAfterIndex(unsigned lastOpenElementIndex)
     929{
     930    Vector<FormattingElementEntry>& stack = m_activeFormattingElements;
     931    unsigned unopenEntryIndex = lastOpenElementIndex + 1;
     932    ASSERT(unopenEntryIndex < stack.size());
     933    for (; unopenEntryIndex < stack.size(); ++unopenEntryIndex) {
     934        FormattingElementEntry& unopenedEntry = stack[unopenEntryIndex];
     935        // FIXME: We're supposed to save the original token in the entry.
     936        AtomicHTMLToken fakeToken(HTMLToken::StartTag, unopenedEntry.element()->localName());
     937        insertElement(fakeToken);
     938        unopenedEntry.replaceElement(currentElement());
     939    }
     940}
     941
    914942void HTMLTreeBuilder::reconstructTheActiveFormattingElements()
    915943{
    916     notImplemented();
     944    if (m_activeFormattingElements.isEmpty())
     945        return;
     946
     947    unsigned lastOpenElementIndex = indexOfLastOpenFormattingElementOrMarker();
     948    if (lastOpenElementIndex < m_activeFormattingElements.size() - 1)
     949        reopenFormattingElementsAfterIndex(lastOpenElementIndex);
    917950}
    918951
  • trunk/WebCore/html/HTMLTreeBuilder.h

    r62076 r62077  
    153153        }
    154154
     155        bool contains(Element* element) const
     156        {
     157            for (ElementRecord* pos = m_top.get(); pos; pos = pos->next()) {
     158                if (pos->element() == element)
     159                    return true;
     160            }
     161            return false;
     162        }
     163
    155164    private:
    156165        OwnPtr<ElementRecord> m_top;
     
    197206    void insertElement(AtomicHTMLToken&);
    198207    void insertSelfClosingElement(AtomicHTMLToken&);
    199     void insertFormatingElement(AtomicHTMLToken&);
     208    void insertFormattingElement(AtomicHTMLToken&);
    200209    void insertGenericRCDATAElement(AtomicHTMLToken&);
    201210    void insertGenericRawTextElement(AtomicHTMLToken&);
     
    207216
    208217    PassRefPtr<Element> createElement(AtomicHTMLToken&);
     218    unsigned indexOfLastOpenFormattingElementOrMarker() const;
     219    void reopenFormattingElementsAfterIndex(unsigned lastOpenElementIndex);
    209220    void reconstructTheActiveFormattingElements();
    210221
     
    214225    RefPtr<Element> m_formElement;
    215226    ElementStack m_openElements;
    216     Vector<Element*> m_activeFormattingElements;
     227
     228    class FormattingElementEntry {
     229    public:
     230        FormattingElementEntry(Element* element)
     231            : m_element(element)
     232        {
     233            ASSERT(element);
     234        }
     235
     236        enum MarkerEntryType { MarkerEntry };
     237        FormattingElementEntry(MarkerEntryType)
     238        {
     239        }
     240
     241        bool isMarker() const { return !m_element; }
     242
     243        Element* element() const
     244        {
     245            // The fact that !m_element == isMarker is an implementation detail
     246            // callers should check isMarker() before calling element().
     247            ASSERT(m_element);
     248            return m_element.get();
     249        }
     250
     251        void replaceElement(PassRefPtr<Element> element)
     252        {
     253            ASSERT(m_element); // Once a marker, always a marker.
     254            m_element = element;
     255        }
     256
     257    private:
     258        RefPtr<Element> m_element;
     259    };
     260
     261    Vector<FormattingElementEntry> m_activeFormattingElements;
    217262    bool m_framesetOk;
    218263
Note: See TracChangeset for help on using the changeset viewer.