| Differences between
and this patch
- a/Source/WebCore/ChangeLog +87 lines
Lines 1-5 a/Source/WebCore/ChangeLog_sec1
1
2012-07-23  Kwang Yul Seo  <skyul@company100.net>
1
2012-07-23  Kwang Yul Seo  <skyul@company100.net>
2
2
3
        Use the original token to create an element in "reconstruct the active formatting elements" and "call the adoption agency"
4
        https://bugs.webkit.org/show_bug.cgi?id=91703
5
6
        Reviewed by NOBODY (OOPS!).
7
8
        The current WebKit HTML5 parser implementation does not hold the original token
9
        in the stack of open elements and the active formatting elements. This is
10
        problematic because the original token is used to create an element in
11
        "reconstruct the active formatting elements" and "call the adoption agency".
12
13
        As a workaround, WebKit uses the saved element instead of the original token
14
        to create an element. But this causes us to fail examples like this:
15
        <b id="1"><p><script>document.getElementById("1").id = "2"</script></p>TEXT</b>
16
        reconstructTheActiveFormattingElements calls this method to open a second <b>
17
        tag to wrap TEXT, it will have id "2", even though the HTML5 spec implies it
18
        should be "1".
19
20
        Created a ref-counted container class, HTMLStackNode to hold the original token
21
        and the namespace URI as well as the element. Changed HTMLElementStack and
22
        HTMLFormattingElementList to use HTMLStackNode.
23
        Changed HTMLConstructionSite::reconstructTheActiveFormattingElements and
24
        HTMLTreeBuilder::callTheAdoptionAgency to create an element from the saved token
25
        instead of the saved element.
26
27
        Updated test expectation for html5lib/runner-expected.txt
28
        because now resources/scripted/adoption01.dat passes.
29
30
        * html/parser/HTMLConstructionSite.cpp:
31
        (WebCore::HTMLConstructionSite::insertHTMLHtmlStartTagBeforeHTML):
32
        (WebCore::HTMLConstructionSite::insertHTMLHeadElement):
33
        (WebCore::HTMLConstructionSite::insertHTMLBodyElement):
34
        (WebCore::HTMLConstructionSite::insertHTMLFormElement):
35
        (WebCore::HTMLConstructionSite::insertHTMLElement):
36
        (WebCore::HTMLConstructionSite::insertFormattingElement):
37
        (WebCore::HTMLConstructionSite::insertScriptElement):
38
        (WebCore::HTMLConstructionSite::insertForeignElement):
39
        (WebCore::HTMLConstructionSite::createElementFromSavedToken):
40
        (WebCore::HTMLConstructionSite::reconstructTheActiveFormattingElements):
41
        * html/parser/HTMLConstructionSite.h:
42
        (HTMLConstructionSite):
43
        (WebCore::HTMLConstructionSite::currentElementRecord):
44
        * html/parser/HTMLElementStack.cpp:
45
        (WebCore::HTMLElementStack::ElementRecord::ElementRecord):
46
        (WebCore::HTMLElementStack::ElementRecord::replaceElement):
47
        (WebCore::HTMLElementStack::pushRootNode):
48
        (WebCore::HTMLElementStack::pushHTMLHtmlElement):
49
        (WebCore::HTMLElementStack::pushRootNodeCommon):
50
        (WebCore::HTMLElementStack::pushHTMLHeadElement):
51
        (WebCore::HTMLElementStack::pushHTMLBodyElement):
52
        (WebCore::HTMLElementStack::push):
53
        (WebCore::HTMLElementStack::insertAbove):
54
        (WebCore::HTMLElementStack::pushCommon):
55
        * html/parser/HTMLElementStack.h:
56
        (WebCore::HTMLElementStack::ElementRecord::element):
57
        (WebCore::HTMLElementStack::ElementRecord::node):
58
        (WebCore::HTMLElementStack::ElementRecord::stackItem):
59
        (ElementRecord):
60
        (HTMLElementStack):
61
        * html/parser/HTMLFormattingElementList.cpp:
62
        (WebCore::HTMLFormattingElementList::swapTo):
63
        (WebCore::HTMLFormattingElementList::append):
64
        * html/parser/HTMLFormattingElementList.h:
65
        (WebCore::HTMLFormattingElementList::Entry::Entry):
66
        (WebCore::HTMLFormattingElementList::Entry::isMarker):
67
        (WebCore::HTMLFormattingElementList::Entry::stackItem):
68
        (WebCore::HTMLFormattingElementList::Entry::element):
69
        (WebCore::HTMLFormattingElementList::Entry::replaceElement):
70
        (WebCore::HTMLFormattingElementList::Entry::operator==):
71
        (WebCore::HTMLFormattingElementList::Entry::operator!=):
72
        (Entry):
73
        (HTMLFormattingElementList):
74
        * html/parser/HTMLStackItem.h: Added.
75
        (WebCore):
76
        (HTMLStackItem):
77
        (WebCore::HTMLStackItem::create):
78
        (WebCore::HTMLStackItem::element):
79
        (WebCore::HTMLStackItem::node):
80
        (WebCore::HTMLStackItem::token):
81
        (WebCore::HTMLStackItem::namespaceURI):
82
        (WebCore::HTMLStackItem::HTMLStackItem):
83
        * html/parser/HTMLTreeBuilder.cpp:
84
        (WebCore::HTMLTreeBuilder::HTMLTreeBuilder):
85
        (WebCore::HTMLTreeBuilder::processStartTag):
86
        (WebCore::HTMLTreeBuilder::callTheAdoptionAgency):
87
88
2012-07-23  Kwang Yul Seo  <skyul@company100.net>
89
3
        Ref-count AtomicHTMLToken
90
        Ref-count AtomicHTMLToken
4
        https://bugs.webkit.org/show_bug.cgi?id=91981
91
        https://bugs.webkit.org/show_bug.cgi?id=91981
5
92
- a/Source/WebCore/html/parser/HTMLConstructionSite.cpp -33 / +20 lines
Lines 39-44 a/Source/WebCore/html/parser/HTMLConstructionSite.cpp_sec1
39
#include "HTMLNames.h"
39
#include "HTMLNames.h"
40
#include "HTMLParserIdioms.h"
40
#include "HTMLParserIdioms.h"
41
#include "HTMLScriptElement.h"
41
#include "HTMLScriptElement.h"
42
#include "HTMLStackItem.h"
42
#include "HTMLToken.h"
43
#include "HTMLToken.h"
43
#include "HTMLTokenizer.h"
44
#include "HTMLTokenizer.h"
44
#include "LocalizedStrings.h"
45
#include "LocalizedStrings.h"
Lines 197-203 void HTMLConstructionSite::insertHTMLHtmlStartTagBeforeHTML(AtomicHTMLToken* tok a/Source/WebCore/html/parser/HTMLConstructionSite.cpp_sec2
197
    RefPtr<HTMLHtmlElement> element = HTMLHtmlElement::create(m_document);
198
    RefPtr<HTMLHtmlElement> element = HTMLHtmlElement::create(m_document);
198
    element->parserSetAttributes(token->attributes(), m_fragmentScriptingPermission);
199
    element->parserSetAttributes(token->attributes(), m_fragmentScriptingPermission);
199
    attachLater(m_attachmentRoot, element);
200
    attachLater(m_attachmentRoot, element);
200
    m_openElements.pushHTMLHtmlElement(element);
201
    m_openElements.pushHTMLHtmlElement(HTMLStackItem::create(element, token));
201
202
202
    executeQueuedTasks();
203
    executeQueuedTasks();
203
    element->insertedByParser();
204
    element->insertedByParser();
Lines 282-288 void HTMLConstructionSite::insertHTMLHeadElement(AtomicHTMLToken* token) a/Source/WebCore/html/parser/HTMLConstructionSite.cpp_sec3
282
    ASSERT(!shouldFosterParent());
283
    ASSERT(!shouldFosterParent());
283
    m_head = createHTMLElement(token);
284
    m_head = createHTMLElement(token);
284
    attachLater(currentNode(), m_head);
285
    attachLater(currentNode(), m_head);
285
    m_openElements.pushHTMLHeadElement(m_head);
286
    m_openElements.pushHTMLHeadElement(HTMLStackItem::create(m_head, token));
286
}
287
}
287
288
288
void HTMLConstructionSite::insertHTMLBodyElement(AtomicHTMLToken* token)
289
void HTMLConstructionSite::insertHTMLBodyElement(AtomicHTMLToken* token)
Lines 290-296 void HTMLConstructionSite::insertHTMLBodyElement(AtomicHTMLToken* token) a/Source/WebCore/html/parser/HTMLConstructionSite.cpp_sec4
290
    ASSERT(!shouldFosterParent());
291
    ASSERT(!shouldFosterParent());
291
    RefPtr<Element> body = createHTMLElement(token);
292
    RefPtr<Element> body = createHTMLElement(token);
292
    attachLater(currentNode(), body);
293
    attachLater(currentNode(), body);
293
    m_openElements.pushHTMLBodyElement(body.release());
294
    m_openElements.pushHTMLBodyElement(HTMLStackItem::create(body.release(), token));
294
}
295
}
295
296
296
void HTMLConstructionSite::insertHTMLFormElement(AtomicHTMLToken* token, bool isDemoted)
297
void HTMLConstructionSite::insertHTMLFormElement(AtomicHTMLToken* token, bool isDemoted)
Lines 300-313 void HTMLConstructionSite::insertHTMLFormElement(AtomicHTMLToken* token, bool is a/Source/WebCore/html/parser/HTMLConstructionSite.cpp_sec5
300
    m_form = static_pointer_cast<HTMLFormElement>(element.release());
301
    m_form = static_pointer_cast<HTMLFormElement>(element.release());
301
    m_form->setDemoted(isDemoted);
302
    m_form->setDemoted(isDemoted);
302
    attachLater(currentNode(), m_form);
303
    attachLater(currentNode(), m_form);
303
    m_openElements.push(m_form);
304
    m_openElements.push(HTMLStackItem::create(m_form, token));
304
}
305
}
305
306
306
void HTMLConstructionSite::insertHTMLElement(AtomicHTMLToken* token)
307
void HTMLConstructionSite::insertHTMLElement(AtomicHTMLToken* token)
307
{
308
{
308
    RefPtr<Element> element = createHTMLElement(token);
309
    RefPtr<Element> element = createHTMLElement(token);
309
    attachLater(currentNode(), element);
310
    attachLater(currentNode(), element);
310
    m_openElements.push(element.release());
311
    m_openElements.push(HTMLStackItem::create(element.release(), token));
311
}
312
}
312
313
313
void HTMLConstructionSite::insertSelfClosingHTMLElement(AtomicHTMLToken* token)
314
void HTMLConstructionSite::insertSelfClosingHTMLElement(AtomicHTMLToken* token)
Lines 327-333 void HTMLConstructionSite::insertFormattingElement(AtomicHTMLToken* token) a/Source/WebCore/html/parser/HTMLConstructionSite.cpp_sec6
327
    // Possible active formatting elements include:
328
    // Possible active formatting elements include:
328
    // a, b, big, code, em, font, i, nobr, s, small, strike, strong, tt, and u.
329
    // a, b, big, code, em, font, i, nobr, s, small, strike, strong, tt, and u.
329
    insertHTMLElement(token);
330
    insertHTMLElement(token);
330
    m_activeFormattingElements.append(currentElement());
331
    m_activeFormattingElements.append(currentElementRecord()->stackItem());
331
}
332
}
332
333
333
void HTMLConstructionSite::insertScriptElement(AtomicHTMLToken* token)
334
void HTMLConstructionSite::insertScriptElement(AtomicHTMLToken* token)
Lines 343-349 void HTMLConstructionSite::insertScriptElement(AtomicHTMLToken* token) a/Source/WebCore/html/parser/HTMLConstructionSite.cpp_sec7
343
    if (m_fragmentScriptingPermission != DisallowScriptingContent)
344
    if (m_fragmentScriptingPermission != DisallowScriptingContent)
344
        element->parserSetAttributes(token->attributes(), m_fragmentScriptingPermission);
345
        element->parserSetAttributes(token->attributes(), m_fragmentScriptingPermission);
345
    attachLater(currentNode(), element);
346
    attachLater(currentNode(), element);
346
    m_openElements.push(element.release());
347
    m_openElements.push(HTMLStackItem::create(element.release(), token));
347
}
348
}
348
349
349
void HTMLConstructionSite::insertForeignElement(AtomicHTMLToken* token, const AtomicString& namespaceURI)
350
void HTMLConstructionSite::insertForeignElement(AtomicHTMLToken* token, const AtomicString& namespaceURI)
Lines 354-360 void HTMLConstructionSite::insertForeignElement(AtomicHTMLToken* token, const At a/Source/WebCore/html/parser/HTMLConstructionSite.cpp_sec8
354
    RefPtr<Element> element = createElement(token, namespaceURI);
355
    RefPtr<Element> element = createElement(token, namespaceURI);
355
    attachLater(currentNode(), element, token->selfClosing());
356
    attachLater(currentNode(), element, token->selfClosing());
356
    if (!token->selfClosing())
357
    if (!token->selfClosing())
357
        m_openElements.push(element.release());
358
        m_openElements.push(HTMLStackItem::create(element.release(), token, namespaceURI));
358
}
359
}
359
360
360
void HTMLConstructionSite::insertTextNode(const String& characters, WhitespaceMode whitespaceMode)
361
void HTMLConstructionSite::insertTextNode(const String& characters, WhitespaceMode whitespaceMode)
Lines 418-445 PassRefPtr<Element> HTMLConstructionSite::createHTMLElement(AtomicHTMLToken* tok a/Source/WebCore/html/parser/HTMLConstructionSite.cpp_sec9
418
    return element.release();
419
    return element.release();
419
}
420
}
420
421
421
PassRefPtr<Element> HTMLConstructionSite::createHTMLElementFromElementRecord(HTMLElementStack::ElementRecord* record)
422
PassRefPtr<HTMLStackItem> HTMLConstructionSite::createElementFromSavedToken(HTMLStackItem* item)
422
{
423
{
423
    return createHTMLElementFromSavedElement(record->element());
424
    RefPtr<Element> element;
424
}
425
    if (item->namespaceURI() == HTMLNames::xhtmlNamespaceURI)
425
426
        element = createHTMLElement(item->token());
426
PassRefPtr<Element> HTMLConstructionSite::createHTMLElementFromSavedElement(Element* element)
427
    else
427
{
428
        element = createElement(item->token(), item->namespaceURI());
428
    // FIXME: This method is wrong.  We should be using the original token.
429
    return HTMLStackItem::create(element.release(), item->token(), item->namespaceURI());
429
    // Using an Element* causes us to fail examples like this:
430
    // <b id="1"><p><script>document.getElementById("1").id = "2"</script></p>TEXT</b>
431
    // When reconstructTheActiveFormattingElements calls this method to open
432
    // a second <b> tag to wrap TEXT, it will have id "2", even though the HTML5
433
    // spec implies it should be "1".  Minefield matches the HTML5 spec here.
434
435
    ASSERT(element->isHTMLElement()); // otherwise localName() might be wrong.
436
437
    Vector<Attribute> clonedAttributes;
438
    if (ElementAttributeData* attributeData = element->updatedAttributeData())
439
        clonedAttributes = attributeData->clonedAttributeVector();
440
441
    RefPtr<AtomicHTMLToken> fakeToken = AtomicHTMLToken::create(HTMLTokenTypes::StartTag, element->localName(), clonedAttributes);
442
    return createHTMLElement(fakeToken.get());
443
}
430
}
444
431
445
bool HTMLConstructionSite::indexOfFirstUnopenFormattingElement(unsigned& firstUnopenElementIndex) const
432
bool HTMLConstructionSite::indexOfFirstUnopenFormattingElement(unsigned& firstUnopenElementIndex) const
Lines 469-478 void HTMLConstructionSite::reconstructTheActiveFormattingElements() a/Source/WebCore/html/parser/HTMLConstructionSite.cpp_sec10
469
    ASSERT(unopenEntryIndex < m_activeFormattingElements.size());
456
    ASSERT(unopenEntryIndex < m_activeFormattingElements.size());
470
    for (; unopenEntryIndex < m_activeFormattingElements.size(); ++unopenEntryIndex) {
457
    for (; unopenEntryIndex < m_activeFormattingElements.size(); ++unopenEntryIndex) {
471
        HTMLFormattingElementList::Entry& unopenedEntry = m_activeFormattingElements.at(unopenEntryIndex);
458
        HTMLFormattingElementList::Entry& unopenedEntry = m_activeFormattingElements.at(unopenEntryIndex);
472
        RefPtr<Element> reconstructed = createHTMLElementFromSavedElement(unopenedEntry.element());
459
        RefPtr<HTMLStackItem> reconstructed = createElementFromSavedToken(unopenedEntry.stackItem().get());
473
        attachLater(currentNode(), reconstructed);
460
        attachLater(currentNode(), reconstructed->node());
474
        m_openElements.push(reconstructed.release());
461
        m_openElements.push(reconstructed);
475
        unopenedEntry.replaceElement(currentElement());
462
        unopenedEntry.replaceElement(reconstructed.release());
476
    }
463
    }
477
}
464
}
478
465
- a/Source/WebCore/html/parser/HTMLConstructionSite.h -2 / +2 lines
Lines 106-112 public: a/Source/WebCore/html/parser/HTMLConstructionSite.h_sec1
106
    void insertHTMLBodyStartTagInBody(AtomicHTMLToken*);
106
    void insertHTMLBodyStartTagInBody(AtomicHTMLToken*);
107
107
108
    PassRefPtr<Element> createHTMLElement(AtomicHTMLToken*);
108
    PassRefPtr<Element> createHTMLElement(AtomicHTMLToken*);
109
    PassRefPtr<Element> createHTMLElementFromElementRecord(HTMLElementStack::ElementRecord*);
109
    PassRefPtr<HTMLStackItem> createElementFromSavedToken(HTMLStackItem*);
110
110
111
    bool shouldFosterParent() const;
111
    bool shouldFosterParent() const;
112
    void fosterParent(PassRefPtr<Node>);
112
    void fosterParent(PassRefPtr<Node>);
Lines 118-123 public: a/Source/WebCore/html/parser/HTMLConstructionSite.h_sec2
118
    void generateImpliedEndTagsWithExclusion(const AtomicString& tagName);
118
    void generateImpliedEndTagsWithExclusion(const AtomicString& tagName);
119
119
120
    bool isEmpty() const { return !m_openElements.stackDepth(); }
120
    bool isEmpty() const { return !m_openElements.stackDepth(); }
121
    HTMLElementStack::ElementRecord* currentElementRecord() const { return m_openElements.topRecord(); }
121
    Element* currentElement() const { return m_openElements.top(); }
122
    Element* currentElement() const { return m_openElements.top(); }
122
    ContainerNode* currentNode() const { return m_openElements.topNode(); }
123
    ContainerNode* currentNode() const { return m_openElements.topNode(); }
123
    Element* oneBelowTop() const { return m_openElements.oneBelowTop(); }
124
    Element* oneBelowTop() const { return m_openElements.oneBelowTop(); }
Lines 160-166 private: a/Source/WebCore/html/parser/HTMLConstructionSite.h_sec3
160
161
161
    void findFosterSite(HTMLConstructionSiteTask&);
162
    void findFosterSite(HTMLConstructionSiteTask&);
162
163
163
    PassRefPtr<Element> createHTMLElementFromSavedElement(Element*);
164
    PassRefPtr<Element> createElement(AtomicHTMLToken*, const AtomicString& namespaceURI);
164
    PassRefPtr<Element> createElement(AtomicHTMLToken*, const AtomicString& namespaceURI);
165
165
166
    void mergeAttributesFromTokenIntoElement(AtomicHTMLToken*, Element*);
166
    void mergeAttributesFromTokenIntoElement(AtomicHTMLToken*, Element*);
- a/Source/WebCore/html/parser/HTMLElementStack.cpp -38 / +38 lines
Lines 125-147 inline bool isSelectScopeMarker(ContainerNode* node) a/Source/WebCore/html/parser/HTMLElementStack.cpp_sec1
125
125
126
}
126
}
127
127
128
HTMLElementStack::ElementRecord::ElementRecord(PassRefPtr<ContainerNode> node, PassOwnPtr<ElementRecord> next)
128
HTMLElementStack::ElementRecord::ElementRecord(PassRefPtr<HTMLStackItem> item, PassOwnPtr<ElementRecord> next)
129
    : m_node(node)
129
    : m_item(item)
130
    , m_next(next)
130
    , m_next(next)
131
{
131
{
132
    ASSERT(m_node);
132
    ASSERT(m_item);
133
}
133
}
134
134
135
HTMLElementStack::ElementRecord::~ElementRecord()
135
HTMLElementStack::ElementRecord::~ElementRecord()
136
{
136
{
137
}
137
}
138
138
139
void HTMLElementStack::ElementRecord::replaceElement(PassRefPtr<Element> element)
139
void HTMLElementStack::ElementRecord::replaceElement(PassRefPtr<HTMLStackItem> item)
140
{
140
{
141
    ASSERT(element);
141
    ASSERT(item);
142
    ASSERT(!m_node || m_node->isElementNode());
142
    ASSERT(!m_item || m_item->node()->isElementNode());
143
    // FIXME: Should this call finishParsingChildren?
143
    // FIXME: Should this call finishParsingChildren?
144
    m_node = element;
144
    m_item = item;
145
}
145
}
146
146
147
bool HTMLElementStack::ElementRecord::isAbove(ElementRecord* other) const
147
bool HTMLElementStack::ElementRecord::isAbove(ElementRecord* other) const
Lines 307-368 void HTMLElementStack::popUntilForeignContentScopeMarker() a/Source/WebCore/html/parser/HTMLElementStack.cpp_sec2
307
        pop();
307
        pop();
308
}
308
}
309
    
309
    
310
void HTMLElementStack::pushRootNode(PassRefPtr<ContainerNode> rootNode)
310
void HTMLElementStack::pushRootNode(PassRefPtr<HTMLStackItem> rootItem)
311
{
311
{
312
    ASSERT(rootNode->nodeType() == Node::DOCUMENT_FRAGMENT_NODE);
312
    ASSERT(rootItem->node()->nodeType() == Node::DOCUMENT_FRAGMENT_NODE);
313
    pushRootNodeCommon(rootNode);
313
    pushRootNodeCommon(rootItem);
314
}
314
}
315
315
316
void HTMLElementStack::pushHTMLHtmlElement(PassRefPtr<Element> element)
316
void HTMLElementStack::pushHTMLHtmlElement(PassRefPtr<HTMLStackItem> item)
317
{
317
{
318
    ASSERT(element->hasTagName(HTMLNames::htmlTag));
318
    ASSERT(item->element()->hasTagName(HTMLNames::htmlTag));
319
    pushRootNodeCommon(element);
319
    pushRootNodeCommon(item);
320
}
320
}
321
    
321
    
322
void HTMLElementStack::pushRootNodeCommon(PassRefPtr<ContainerNode> rootNode)
322
void HTMLElementStack::pushRootNodeCommon(PassRefPtr<HTMLStackItem> rootItem)
323
{
323
{
324
    ASSERT(!m_top);
324
    ASSERT(!m_top);
325
    ASSERT(!m_rootNode);
325
    ASSERT(!m_rootNode);
326
    m_rootNode = rootNode.get();
326
    m_rootNode = rootItem->node();
327
    pushCommon(rootNode);
327
    pushCommon(rootItem);
328
}
328
}
329
329
330
void HTMLElementStack::pushHTMLHeadElement(PassRefPtr<Element> element)
330
void HTMLElementStack::pushHTMLHeadElement(PassRefPtr<HTMLStackItem> item)
331
{
331
{
332
    ASSERT(element->hasTagName(HTMLNames::headTag));
332
    ASSERT(item->element()->hasTagName(HTMLNames::headTag));
333
    ASSERT(!m_headElement);
333
    ASSERT(!m_headElement);
334
    m_headElement = element.get();
334
    m_headElement = item->element();
335
    pushCommon(element);
335
    pushCommon(item);
336
}
336
}
337
337
338
void HTMLElementStack::pushHTMLBodyElement(PassRefPtr<Element> element)
338
void HTMLElementStack::pushHTMLBodyElement(PassRefPtr<HTMLStackItem> item)
339
{
339
{
340
    ASSERT(element->hasTagName(HTMLNames::bodyTag));
340
    ASSERT(item->element()->hasTagName(HTMLNames::bodyTag));
341
    ASSERT(!m_bodyElement);
341
    ASSERT(!m_bodyElement);
342
    m_bodyElement = element.get();
342
    m_bodyElement = item->element();
343
    pushCommon(element);
343
    pushCommon(item);
344
}
344
}
345
345
346
void HTMLElementStack::push(PassRefPtr<Element> element)
346
void HTMLElementStack::push(PassRefPtr<HTMLStackItem> item)
347
{
347
{
348
    ASSERT(!element->hasTagName(HTMLNames::htmlTag));
348
    ASSERT(!item->element()->hasTagName(HTMLNames::htmlTag));
349
    ASSERT(!element->hasTagName(HTMLNames::headTag));
349
    ASSERT(!item->element()->hasTagName(HTMLNames::headTag));
350
    ASSERT(!element->hasTagName(HTMLNames::bodyTag));
350
    ASSERT(!item->element()->hasTagName(HTMLNames::bodyTag));
351
    ASSERT(m_rootNode);
351
    ASSERT(m_rootNode);
352
    pushCommon(element);
352
    pushCommon(item);
353
}
353
}
354
354
355
void HTMLElementStack::insertAbove(PassRefPtr<Element> element, ElementRecord* recordBelow)
355
void HTMLElementStack::insertAbove(PassRefPtr<HTMLStackItem> item, ElementRecord* recordBelow)
356
{
356
{
357
    ASSERT(element);
357
    ASSERT(item);
358
    ASSERT(recordBelow);
358
    ASSERT(recordBelow);
359
    ASSERT(m_top);
359
    ASSERT(m_top);
360
    ASSERT(!element->hasTagName(HTMLNames::htmlTag));
360
    ASSERT(!item->element()->hasTagName(HTMLNames::htmlTag));
361
    ASSERT(!element->hasTagName(HTMLNames::headTag));
361
    ASSERT(!item->element()->hasTagName(HTMLNames::headTag));
362
    ASSERT(!element->hasTagName(HTMLNames::bodyTag));
362
    ASSERT(!item->element()->hasTagName(HTMLNames::bodyTag));
363
    ASSERT(m_rootNode);
363
    ASSERT(m_rootNode);
364
    if (recordBelow == m_top) {
364
    if (recordBelow == m_top) {
365
        push(element);
365
        push(item);
366
        return;
366
        return;
367
    }
367
    }
368
368
Lines 371-377 void HTMLElementStack::insertAbove(PassRefPtr<Element> element, ElementRecord* r a/Source/WebCore/html/parser/HTMLElementStack.cpp_sec3
371
            continue;
371
            continue;
372
372
373
        m_stackDepth++;
373
        m_stackDepth++;
374
        recordAbove->setNext(adoptPtr(new ElementRecord(element, recordAbove->releaseNext())));
374
        recordAbove->setNext(adoptPtr(new ElementRecord(item, recordAbove->releaseNext())));
375
        recordAbove->next()->element()->beginParsingChildren();
375
        recordAbove->next()->element()->beginParsingChildren();
376
        return;
376
        return;
377
    }
377
    }
Lines 567-578 ContainerNode* HTMLElementStack::rootNode() const a/Source/WebCore/html/parser/HTMLElementStack.cpp_sec4
567
    return m_rootNode;
567
    return m_rootNode;
568
}
568
}
569
569
570
void HTMLElementStack::pushCommon(PassRefPtr<ContainerNode> node)
570
void HTMLElementStack::pushCommon(PassRefPtr<HTMLStackItem> item)
571
{
571
{
572
    ASSERT(m_rootNode);
572
    ASSERT(m_rootNode);
573
573
574
    m_stackDepth++;
574
    m_stackDepth++;
575
    m_top = adoptPtr(new ElementRecord(node, m_top.release()));
575
    m_top = adoptPtr(new ElementRecord(item, m_top.release()));
576
}
576
}
577
577
578
void HTMLElementStack::popCommon()
578
void HTMLElementStack::popCommon()
- a/Source/WebCore/html/parser/HTMLElementStack.h -14 / +15 lines
Lines 29-34 a/Source/WebCore/html/parser/HTMLElementStack.h_sec1
29
29
30
#include "Element.h"
30
#include "Element.h"
31
#include "HTMLNames.h"
31
#include "HTMLNames.h"
32
#include "HTMLStackItem.h"
32
#include <wtf/Forward.h>
33
#include <wtf/Forward.h>
33
#include <wtf/Noncopyable.h>
34
#include <wtf/Noncopyable.h>
34
#include <wtf/OwnPtr.h>
35
#include <wtf/OwnPtr.h>
Lines 55-77 public: a/Source/WebCore/html/parser/HTMLElementStack.h_sec2
55
    public:
56
    public:
56
        ~ElementRecord(); // Public for ~PassOwnPtr()
57
        ~ElementRecord(); // Public for ~PassOwnPtr()
57
    
58
    
58
        Element* element() const { return toElement(m_node.get()); }
59
        Element* element() const { return m_item->element(); }
59
        ContainerNode* node() const { return m_node.get(); }
60
        ContainerNode* node() const { return m_item->node(); }
60
        void replaceElement(PassRefPtr<Element>);
61
        PassRefPtr<HTMLStackItem> stackItem() const { return m_item; }
62
        void replaceElement(PassRefPtr<HTMLStackItem>);
61
63
62
        bool isAbove(ElementRecord*) const;
64
        bool isAbove(ElementRecord*) const;
63
65
64
        ElementRecord* next() const { return m_next.get(); }
66
        ElementRecord* next() const { return m_next.get(); }
65
66
    private:
67
    private:
67
        friend class HTMLElementStack;
68
        friend class HTMLElementStack;
68
69
69
        ElementRecord(PassRefPtr<ContainerNode>, PassOwnPtr<ElementRecord>);
70
        ElementRecord(PassRefPtr<HTMLStackItem>, PassOwnPtr<ElementRecord>);
70
71
71
        PassOwnPtr<ElementRecord> releaseNext() { return m_next.release(); }
72
        PassOwnPtr<ElementRecord> releaseNext() { return m_next.release(); }
72
        void setNext(PassOwnPtr<ElementRecord> next) { m_next = next; }
73
        void setNext(PassOwnPtr<ElementRecord> next) { m_next = next; }
73
74
74
        RefPtr<ContainerNode> m_node;
75
        RefPtr<HTMLStackItem> m_item;
75
        OwnPtr<ElementRecord> m_next;
76
        OwnPtr<ElementRecord> m_next;
76
    };
77
    };
77
78
Lines 97-109 public: a/Source/WebCore/html/parser/HTMLElementStack.h_sec3
97
    ElementRecord* find(Element*) const;
98
    ElementRecord* find(Element*) const;
98
    ElementRecord* topmost(const AtomicString& tagName) const;
99
    ElementRecord* topmost(const AtomicString& tagName) const;
99
100
100
    void insertAbove(PassRefPtr<Element>, ElementRecord*);
101
    void insertAbove(PassRefPtr<HTMLStackItem>, ElementRecord*);
101
102
102
    void push(PassRefPtr<Element>);
103
    void push(PassRefPtr<HTMLStackItem>);
103
    void pushRootNode(PassRefPtr<ContainerNode>);
104
    void pushRootNode(PassRefPtr<HTMLStackItem>);
104
    void pushHTMLHtmlElement(PassRefPtr<Element>);
105
    void pushHTMLHtmlElement(PassRefPtr<HTMLStackItem>);
105
    void pushHTMLHeadElement(PassRefPtr<Element>);
106
    void pushHTMLHeadElement(PassRefPtr<HTMLStackItem>);
106
    void pushHTMLBodyElement(PassRefPtr<Element>);
107
    void pushHTMLBodyElement(PassRefPtr<HTMLStackItem>);
107
108
108
    void pop();
109
    void pop();
109
    void popUntil(const AtomicString& tagName);
110
    void popUntil(const AtomicString& tagName);
Lines 156-163 public: a/Source/WebCore/html/parser/HTMLElementStack.h_sec4
156
#endif
157
#endif
157
158
158
private:
159
private:
159
    void pushCommon(PassRefPtr<ContainerNode>);
160
    void pushCommon(PassRefPtr<HTMLStackItem>);
160
    void pushRootNodeCommon(PassRefPtr<ContainerNode>);
161
    void pushRootNodeCommon(PassRefPtr<HTMLStackItem>);
161
    void popCommon();
162
    void popCommon();
162
    void removeNonTopCommon(Element*);
163
    void removeNonTopCommon(Element*);
163
164
- a/Source/WebCore/html/parser/HTMLFormattingElementList.cpp -7 / +9 lines
Lines 87-111 HTMLFormattingElementList::Bookmark HTMLFormattingElementList::bookmarkFor(Eleme a/Source/WebCore/html/parser/HTMLFormattingElementList.cpp_sec1
87
    return Bookmark(&at(index));
87
    return Bookmark(&at(index));
88
}
88
}
89
89
90
void HTMLFormattingElementList::swapTo(Element* oldElement, Element* newElement, const Bookmark& bookmark)
90
void HTMLFormattingElementList::swapTo(Element* oldElement, PassRefPtr<HTMLStackItem> prpNewItem, const Bookmark& bookmark)
91
{
91
{
92
    RefPtr<HTMLStackItem> newItem = prpNewItem;
93
92
    ASSERT(contains(oldElement));
94
    ASSERT(contains(oldElement));
93
    ASSERT(!contains(newElement));
95
    ASSERT(!contains(newItem));
94
    if (!bookmark.hasBeenMoved()) {
96
    if (!bookmark.hasBeenMoved()) {
95
        ASSERT(bookmark.mark()->element() == oldElement);
97
        ASSERT(bookmark.mark()->element() == oldElement);
96
        bookmark.mark()->replaceElement(newElement);
98
        bookmark.mark()->replaceElement(newItem);
97
        return;
99
        return;
98
    }
100
    }
99
    size_t index = bookmark.mark() - first();
101
    size_t index = bookmark.mark() - first();
100
    ASSERT(index < size());
102
    ASSERT(index < size());
101
    m_entries.insert(index + 1, newElement);
103
    m_entries.insert(index + 1, newItem);
102
    remove(oldElement);
104
    remove(oldElement);
103
}
105
}
104
106
105
void HTMLFormattingElementList::append(Element* element)
107
void HTMLFormattingElementList::append(PassRefPtr<HTMLStackItem> item)
106
{
108
{
107
    ensureNoahsArkCondition(element);
109
    ensureNoahsArkCondition(item->element());
108
    m_entries.append(element);
110
    m_entries.append(item);
109
}
111
}
110
112
111
void HTMLFormattingElementList::remove(Element* element)
113
void HTMLFormattingElementList::remove(Element* element)
- a/Source/WebCore/html/parser/HTMLFormattingElementList.h -14 / +15 lines
Lines 26-31 a/Source/WebCore/html/parser/HTMLFormattingElementList.h_sec1
26
#ifndef HTMLFormattingElementList_h
26
#ifndef HTMLFormattingElementList_h
27
#define HTMLFormattingElementList_h
27
#define HTMLFormattingElementList_h
28
28
29
#include "HTMLStackItem.h"
29
#include <wtf/Forward.h>
30
#include <wtf/Forward.h>
30
#include <wtf/RefPtr.h>
31
#include <wtf/RefPtr.h>
31
#include <wtf/Vector.h>
32
#include <wtf/Vector.h>
Lines 47-81 public: a/Source/WebCore/html/parser/HTMLFormattingElementList.h_sec2
47
    class Entry {
48
    class Entry {
48
    public:
49
    public:
49
        // Inline because they're hot and Vector<T> uses them.
50
        // Inline because they're hot and Vector<T> uses them.
50
        explicit Entry(Element* element)
51
        explicit Entry(PassRefPtr<HTMLStackItem> item)
51
            : m_element(element)
52
            : m_item(item)
52
        {
53
        {
53
            ASSERT(element);
54
        }
54
        }
55
        enum MarkerEntryType { MarkerEntry };
55
        enum MarkerEntryType { MarkerEntry };
56
        Entry(MarkerEntryType)
56
        Entry(MarkerEntryType)
57
            : m_element(0)
57
            : m_item(0)
58
        {
58
        {
59
        }
59
        }
60
        ~Entry() {}
60
        ~Entry() {}
61
61
62
        bool isMarker() const { return !m_element; }
62
        bool isMarker() const { return !m_item; }
63
63
64
        PassRefPtr<HTMLStackItem> stackItem() const { return m_item; }
64
        Element* element() const
65
        Element* element() const
65
        {
66
        {
66
            // The fact that !m_element == isMarker() is an implementation detail
67
            // The fact that !m_item == isMarker() is an implementation detail
67
            // callers should check isMarker() before calling element().
68
            // callers should check isMarker() before calling element().
68
            ASSERT(m_element);
69
            ASSERT(m_item);
69
            return m_element.get();
70
            return m_item->element();
70
        }
71
        }
71
        void replaceElement(PassRefPtr<Element> element) { m_element = element; }
72
        void replaceElement(PassRefPtr<HTMLStackItem> item) { m_item = item; }
72
73
73
        // Needed for use with Vector.  These are super-hot and must be inline.
74
        // 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_item ? !element : m_item->element() == element; }
75
        bool operator!=(Element* element) const { return m_element != element; }
76
        bool operator!=(Element* element) const { return !m_item ? !!element : m_item->element() != element; }
76
77
77
    private:
78
    private:
78
        RefPtr<Element> m_element;
79
        RefPtr<HTMLStackItem> m_item;
79
    };
80
    };
80
81
81
    class Bookmark {
82
    class Bookmark {
Lines 107-117 public: a/Source/WebCore/html/parser/HTMLFormattingElementList.h_sec3
107
108
108
    Entry* find(Element*);
109
    Entry* find(Element*);
109
    bool contains(Element*);
110
    bool contains(Element*);
110
    void append(Element*);
111
    void append(PassRefPtr<HTMLStackItem>);
111
    void remove(Element*);
112
    void remove(Element*);
112
113
113
    Bookmark bookmarkFor(Element*);
114
    Bookmark bookmarkFor(Element*);
114
    void swapTo(Element* oldElement, Element* newElement, const Bookmark&);
115
    void swapTo(Element* oldElement, PassRefPtr<HTMLStackItem> prpNewItem, const Bookmark&);
115
116
116
    void appendMarker();
117
    void appendMarker();
117
    // clearToLastMarker also clears the marker (per the HTML5 spec).
118
    // clearToLastMarker also clears the marker (per the HTML5 spec).
- a/Source/WebCore/html/parser/HTMLStackItem.h +99 lines
Line 0 a/Source/WebCore/html/parser/HTMLStackItem.h_sec1
1
/*
2
 * Copyright (C) 2012 Company 100, 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 HTMLStackItem_h
27
#define HTMLStackItem_h
28
29
#include "Element.h"
30
#include "HTMLNames.h"
31
#include "HTMLToken.h"
32
33
#include <wtf/RefCounted.h>
34
#include <wtf/RefPtr.h>
35
#include <wtf/text/AtomicString.h>
36
37
namespace WebCore {
38
39
class ContainerNode;
40
41
class HTMLStackItem : public RefCounted<HTMLStackItem> {
42
public:
43
    // DocumentFragment case.
44
    static PassRefPtr<HTMLStackItem> create(PassRefPtr<ContainerNode> node)
45
    {
46
        return adoptRef(new HTMLStackItem(node));
47
    }
48
49
    // Used by HTMLElementStack.
50
    static PassRefPtr<HTMLStackItem> create(PassRefPtr<ContainerNode> node, AtomicHTMLToken* token, const AtomicString& namespaceURI = HTMLNames::xhtmlNamespaceURI)
51
    {
52
        return adoptRef(new HTMLStackItem(node, token, namespaceURI));
53
    }
54
55
    // Used by HTMLFormattingElementList.
56
    static PassRefPtr<HTMLStackItem> create(Element* element, AtomicHTMLToken* token, const AtomicString& namespaceURI = HTMLNames::xhtmlNamespaceURI)
57
    {
58
        return adoptRef(new HTMLStackItem(element, token, namespaceURI));
59
    }
60
61
    Element* element() const { return toElement(m_node.get()); }
62
    ContainerNode* node() const { return m_node.get(); }
63
64
    AtomicHTMLToken* token() { return m_token.get(); }
65
    const AtomicString& namespaceURI() const { return m_namespaceURI; }
66
67
private:
68
    HTMLStackItem(PassRefPtr<ContainerNode> node)
69
        : m_node(node)
70
        , m_isDocumentFragmentNode(true)
71
    {
72
    }
73
74
    HTMLStackItem(PassRefPtr<ContainerNode> node, PassRefPtr<AtomicHTMLToken> token, const AtomicString& namespaceURI = HTMLNames::xhtmlNamespaceURI)
75
        : m_node(node)
76
        , m_token(token)
77
        , m_namespaceURI(namespaceURI)
78
        , m_isDocumentFragmentNode(false)
79
    {
80
    }
81
82
    HTMLStackItem(Element* element, PassRefPtr<AtomicHTMLToken> token, const AtomicString& namespaceURI = HTMLNames::xhtmlNamespaceURI)
83
        : m_node(element)
84
        , m_token(token)
85
        , m_namespaceURI(namespaceURI)
86
        , m_isDocumentFragmentNode(false)
87
    {
88
    }
89
90
    RefPtr<ContainerNode> m_node;
91
92
    RefPtr<AtomicHTMLToken> m_token;
93
    AtomicString m_namespaceURI;
94
    bool m_isDocumentFragmentNode;
95
};
96
97
} // namespace WebCore
98
99
#endif // HTMLStackItem_h
- a/Source/WebCore/html/parser/HTMLTreeBuilder.cpp -13 / +15 lines
Lines 40-45 a/Source/WebCore/html/parser/HTMLTreeBuilder.cpp_sec1
40
#include "HTMLNames.h"
40
#include "HTMLNames.h"
41
#include "HTMLParserIdioms.h"
41
#include "HTMLParserIdioms.h"
42
#include "HTMLScriptElement.h"
42
#include "HTMLScriptElement.h"
43
#include "HTMLStackItem.h"
43
#include "HTMLToken.h"
44
#include "HTMLToken.h"
44
#include "HTMLTokenizer.h"
45
#include "HTMLTokenizer.h"
45
#include "LocalizedStrings.h"
46
#include "LocalizedStrings.h"
Lines 380-386 HTMLTreeBuilder::HTMLTreeBuilder(HTMLDocumentParser* parser, DocumentFragment* f a/Source/WebCore/html/parser/HTMLTreeBuilder.cpp_sec2
380
        // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#fragment-case
381
        // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#fragment-case
381
        // For efficiency, we skip step 4.2 ("Let root be a new html element with no attributes")
382
        // For efficiency, we skip step 4.2 ("Let root be a new html element with no attributes")
382
        // and instead use the DocumentFragment as a root node.
383
        // and instead use the DocumentFragment as a root node.
383
        m_tree.openElements()->pushRootNode(fragment);
384
        m_tree.openElements()->pushRootNode(HTMLStackItem::create(fragment));
384
        resetInsertionModeAppropriately();
385
        resetInsertionModeAppropriately();
385
        m_tree.setForm(closestFormAncestor(contextElement));
386
        m_tree.setForm(closestFormAncestor(contextElement));
386
    }
387
    }
Lines 1184-1190 void HTMLTreeBuilder::processStartTag(AtomicHTMLToken* token) a/Source/WebCore/html/parser/HTMLTreeBuilder.cpp_sec3
1184
            || token->name() == titleTag) {
1185
            || token->name() == titleTag) {
1185
            parseError(token);
1186
            parseError(token);
1186
            ASSERT(m_tree.head());
1187
            ASSERT(m_tree.head());
1187
            m_tree.openElements()->pushHTMLHeadElement(m_tree.head());
1188
            m_tree.openElements()->pushHTMLHeadElement(HTMLStackItem::create(m_tree.head(), token));
1188
            processStartTagForInHead(token);
1189
            processStartTagForInHead(token);
1189
            m_tree.openElements()->removeHTMLHeadElement(m_tree.head());
1190
            m_tree.openElements()->removeHTMLHeadElement(m_tree.head());
1190
            return;
1191
            return;
Lines 1559-1568 void HTMLTreeBuilder::callTheAdoptionAgency(AtomicHTMLToken* token) a/Source/WebCore/html/parser/HTMLTreeBuilder.cpp_sec4
1559
            if (node == formattingElementRecord)
1560
            if (node == formattingElementRecord)
1560
                break;
1561
                break;
1561
            // 6.5
1562
            // 6.5
1562
            RefPtr<Element> newElement = m_tree.createHTMLElementFromElementRecord(node);
1563
            RefPtr<HTMLStackItem> newItem = m_tree.createElementFromSavedToken(node->stackItem().get());
1564
1563
            HTMLFormattingElementList::Entry* nodeEntry = m_tree.activeFormattingElements()->find(node->element());
1565
            HTMLFormattingElementList::Entry* nodeEntry = m_tree.activeFormattingElements()->find(node->element());
1564
            nodeEntry->replaceElement(newElement.get());
1566
            nodeEntry->replaceElement(newItem);
1565
            node->replaceElement(newElement.release());
1567
            node->replaceElement(newItem.release());
1566
            // 6.4 -- Intentionally out of order to handle the case where node
1568
            // 6.4 -- Intentionally out of order to handle the case where node
1567
            // was replaced in 6.5.
1569
            // was replaced in 6.5.
1568
            // http://www.w3.org/Bugs/Public/show_bug.cgi?id=10096
1570
            // http://www.w3.org/Bugs/Public/show_bug.cgi?id=10096
Lines 1595-1619 void HTMLTreeBuilder::callTheAdoptionAgency(AtomicHTMLToken* token) a/Source/WebCore/html/parser/HTMLTreeBuilder.cpp_sec5
1595
                lastNode->element()->lazyAttach();
1597
                lastNode->element()->lazyAttach();
1596
        }
1598
        }
1597
        // 8
1599
        // 8
1598
        RefPtr<Element> newElement = m_tree.createHTMLElementFromElementRecord(formattingElementRecord);
1600
        RefPtr<HTMLStackItem> newItem = m_tree.createElementFromSavedToken(formattingElementRecord->stackItem().get());
1599
        // 9
1601
        // 9
1600
        newElement->takeAllChildrenFrom(furthestBlock->element());
1602
        newItem->element()->takeAllChildrenFrom(furthestBlock->element());
1601
        // 10
1603
        // 10
1602
        Element* furthestBlockElement = furthestBlock->element();
1604
        Element* furthestBlockElement = furthestBlock->element();
1603
        // FIXME: All this creation / parserAddChild / attach business should
1605
        // FIXME: All this creation / parserAddChild / attach business should
1604
        //        be in HTMLConstructionSite.  My guess is that steps 8--12
1606
        //        be in HTMLConstructionSite.  My guess is that steps 8--12
1605
        //        should all be in some HTMLConstructionSite function.
1607
        //        should all be in some HTMLConstructionSite function.
1606
        furthestBlockElement->parserAddChild(newElement);
1608
        furthestBlockElement->parserAddChild(newItem->element());
1607
        if (furthestBlockElement->attached() && !newElement->attached()) {
1609
        if (furthestBlockElement->attached() && !newItem->element()->attached()) {
1608
            // Notice that newElement might already be attached if, for example, one of the reparented
1610
            // Notice that newItem->element() might already be attached if, for example, one of the reparented
1609
            // children is a style element, which attaches itself automatically.
1611
            // children is a style element, which attaches itself automatically.
1610
            newElement->attach();
1612
            newItem->element()->attach();
1611
        }
1613
        }
1612
        // 11
1614
        // 11
1613
        m_tree.activeFormattingElements()->swapTo(formattingElement, newElement.get(), bookmark);
1615
        m_tree.activeFormattingElements()->swapTo(formattingElement, newItem, bookmark);
1614
        // 12
1616
        // 12
1615
        m_tree.openElements()->remove(formattingElement);
1617
        m_tree.openElements()->remove(formattingElement);
1616
        m_tree.openElements()->insertAbove(newElement, furthestBlock);
1618
        m_tree.openElements()->insertAbove(newItem, furthestBlock);
1617
    }
1619
    }
1618
}
1620
}
1619
1621
- a/LayoutTests/ChangeLog +12 lines
Lines 1-3 a/LayoutTests/ChangeLog_sec1
1
2012-07-23  Kwang Yul Seo  <skyul@company100.net>
2
3
        Use the original token to create an element in "reconstruct the active formatting elements" and "call the adoption agency"
4
        https://bugs.webkit.org/show_bug.cgi?id=91703
5
6
        Reviewed by NOBODY (OOPS!).
7
8
        Updated test expectation for html5lib/runner-expected.txt
9
        because now resources/scripted/adoption01.dat passes.
10
11
        * html5lib/runner-expected.txt:
12
1
2012-07-23  Christophe Dumez  <christophe.dumez@intel.com>
13
2012-07-23  Christophe Dumez  <christophe.dumez@intel.com>
2
14
3
        [EFL] Skip http/tests/inspector-enabled/injected-script-discard.html
15
        [EFL] Skip http/tests/inspector-enabled/injected-script-discard.html
- a/LayoutTests/html5lib/runner-expected.txt -29 / +2 lines
Lines 43-75 resources/tables01.dat: PASS a/LayoutTests/html5lib/runner-expected.txt_sec1
43
43
44
resources/tricky01.dat: PASS
44
resources/tricky01.dat: PASS
45
45
46
resources/scripted/adoption01.dat:
46
resources/scripted/adoption01.dat: PASS
47
1
47
48
49
Test 1 of 1 in resources/scripted/adoption01.dat failed. Input:
50
<p><b id="A"><script>document.getElementById("A").id = "B"</script></p>TEXT</b>
51
Got:
52
| <html>
53
|   <head>
54
|   <body>
55
|     <p>
56
|       <b>
57
|         id="B"
58
|         <script>
59
|           "document.getElementById("A").id = "B""
60
|     <b>
61
|       id="B"
62
|       "TEXT"
63
Expected:
64
| <html>
65
|   <head>
66
|   <body>
67
|     <p>
68
|       <b>
69
|         id="B"
70
|         <script>
71
|           "document.getElementById("A").id = "B""
72
|     <b>
73
|       id="A"
74
|       "TEXT"
75
resources/scripted/webkit01.dat: PASS
48
resources/scripted/webkit01.dat: PASS

Return to Bug 91703