Changeset 61966 in webkit
- Timestamp:
- Jun 27, 2010 1:38:22 AM (14 years ago)
- Location:
- trunk/WebCore
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebCore/ChangeLog
r61964 r61966 1 2010-06-27 Adam Barth <abarth@webkit.org> 2 3 Reviewed by Eric Seidel. 4 5 HTML5 tree builder should be able to execute inline scripts 6 https://bugs.webkit.org/show_bug.cgi?id=41257 7 8 This patch implements enough machinery so that we can execute inline 9 scripts in extremely simple documents such as the following: 10 11 <html> 12 <script> 13 alert(1); 14 </script> 15 16 To get this to work, I had to flesh out a surprising amount of the data 17 structures for processing the <head>. No tests because this is 18 already covered by most LayoutTests. 19 20 * html/HTMLTreeBuilder.cpp: 21 (WebCore::HTMLTreeBuilder::HTMLTreeBuilder): 22 (WebCore::HTMLTreeBuilder::constructTreeFromToken): 23 (WebCore::HTMLTreeBuilder::processStartTag): 24 (WebCore::HTMLTreeBuilder::processEndTag): 25 (WebCore::HTMLTreeBuilder::processCharacter): 26 (WebCore::HTMLTreeBuilder::insertComment): 27 (WebCore::HTMLTreeBuilder::insertElement): 28 (WebCore::HTMLTreeBuilder::insertScriptElement): 29 * html/HTMLTreeBuilder.h: 30 (WebCore::HTMLTreeBuilder::ElementRecord::ElementRecord): 31 (WebCore::HTMLTreeBuilder::ElementRecord::element): 32 (WebCore::HTMLTreeBuilder::ElementRecord::next): 33 (WebCore::HTMLTreeBuilder::ElementRecord::releaseNext): 34 (WebCore::HTMLTreeBuilder::ElementRecord::setNext): 35 (WebCore::HTMLTreeBuilder::ElementStack::pop): 36 (WebCore::HTMLTreeBuilder::ElementStack::push): 37 (WebCore::HTMLTreeBuilder::ElementStack::top): 38 (WebCore::HTMLTreeBuilder::ElementStack::remove): 39 (WebCore::HTMLTreeBuilder::currentElement): 40 1 41 2010-06-26 Brady Eidson <beidson@apple.com> 2 42 -
trunk/WebCore/html/HTMLTreeBuilder.cpp
r61925 r61966 27 27 #include "HTMLTreeBuilder.h" 28 28 29 #include "Comment.h" 29 30 #include "DocumentFragment.h" 30 31 #include "Element.h" 31 32 #include "Frame.h" 33 #include "HTMLElementFactory.h" 34 #include "HTMLScriptElement.h" 32 35 #include "HTMLTokenizer.h" 33 36 #include "HTMLToken.h" … … 39 42 #include "NotImplemented.h" 40 43 #include "ScriptController.h" 44 #include "Text.h" 41 45 #include <wtf/UnusedParam.h> 42 46 … … 62 66 , m_isPaused(false) 63 67 , m_insertionMode(InitialMode) 68 , m_originalInsertionMode(InitialMode) 64 69 , m_tokenizer(tokenizer) 65 70 , m_legacyTreeBuilder(new LegacyHTMLTreeBuilder(document, reportErrors)) … … 78 83 , m_isPaused(false) 79 84 , m_insertionMode(InitialMode) 85 , m_originalInsertionMode(InitialMode) 80 86 , m_tokenizer(tokenizer) 81 87 , m_legacyTreeBuilder(new LegacyHTMLTreeBuilder(fragment, scriptingPermission)) … … 302 308 } 303 309 if (token.name() == headTag) { 304 m_headElement = insertElement(token); 310 insertElement(token); 311 m_headElement = currentElement(); 305 312 setInsertionMode(InHeadMode); 306 313 return; … … 461 468 ASSERT(insertionMode() == InHeadNoscriptMode); 462 469 if (token.name() == noscriptTag) { 463 ASSERT( m_openElements.top()->tagQName() == noscriptTag);470 ASSERT(currentElement()->tagQName() == noscriptTag); 464 471 m_openElements.pop(); 465 ASSERT( m_openElements.top()->tagQName() == headTag);472 ASSERT(currentElement()->tagQName() == headTag); 466 473 setInsertionMode(InHeadMode); 467 474 return; … … 473 480 processDefaultForInHeadNoscriptMode(token); 474 481 processToken(token); 482 case TextMode: 483 if (token.name() == scriptTag) { 484 // Pause ourselves so that parsing stops until the script can be processed by the caller. 485 m_isPaused = true; 486 ASSERT(currentElement()->tagQName() == scriptTag); 487 m_scriptToProcess = currentElement(); 488 m_openElements.pop(); 489 m_insertionMode = m_originalInsertionMode; 490 return; 491 } 492 notImplemented(); 493 break; 475 494 default: 476 495 notImplemented(); … … 487 506 } 488 507 489 void HTMLTreeBuilder::processCharacter(AtomicHTMLToken&) 490 { 508 void HTMLTreeBuilder::processCharacter(AtomicHTMLToken& token) 509 { 510 if (insertionMode() == TextMode) { 511 currentElement()->addChild(Text::create(m_document, token.characters())); 512 return; 513 } 491 514 // FIXME: We need to figure out how to handle each character individually. 492 515 notImplemented(); … … 575 598 void HTMLTreeBuilder::insertComment(AtomicHTMLToken& token) 576 599 { 577 ASSERT_UNUSED(token, token.type() == HTMLToken::Comment); 578 } 579 580 PassRefPtr<Element> HTMLTreeBuilder::insertElement(AtomicHTMLToken& token) 600 ASSERT(token.type() == HTMLToken::Comment); 601 RefPtr<Node> element = Comment::create(m_document, token.comment()); 602 currentElement()->addChild(element); 603 } 604 605 void HTMLTreeBuilder::insertElement(AtomicHTMLToken& token) 606 { 607 ASSERT(token.type() == HTMLToken::StartTag); 608 RefPtr<Element> element = HTMLElementFactory::createHTMLElement(QualifiedName(nullAtom, token.name(), xhtmlNamespaceURI), m_document, 0); 609 currentElement()->addChild(element); 610 m_openElements.push(element.release()); 611 } 612 613 void HTMLTreeBuilder::insertCharacter(UChar cc) 614 { 615 ASSERT_UNUSED(cc, cc); 616 } 617 618 void HTMLTreeBuilder::insertGenericRCDATAElement(AtomicHTMLToken& token) 581 619 { 582 620 ASSERT_UNUSED(token, token.type() == HTMLToken::StartTag); 583 return 0; 584 } 585 586 void HTMLTreeBuilder::insertCharacter(UChar cc) 587 { 588 ASSERT_UNUSED(cc, cc); 589 } 590 591 void HTMLTreeBuilder::insertGenericRCDATAElement(AtomicHTMLToken& token) 621 } 622 623 void HTMLTreeBuilder::insertGenericRawTextElement(AtomicHTMLToken& token) 592 624 { 593 625 ASSERT_UNUSED(token, token.type() == HTMLToken::StartTag); 594 626 } 595 627 596 void HTMLTreeBuilder::insert GenericRawTextElement(AtomicHTMLToken& token)628 void HTMLTreeBuilder::insertScriptElement(AtomicHTMLToken& token) 597 629 { 598 630 ASSERT_UNUSED(token, token.type() == HTMLToken::StartTag); 599 } 600 601 void HTMLTreeBuilder::insertScriptElement(AtomicHTMLToken& token) 602 { 603 ASSERT_UNUSED(token, token.type() == HTMLToken::StartTag); 631 RefPtr<HTMLScriptElement> element = HTMLScriptElement::create(scriptTag, m_document, true); 632 currentElement()->addChild(element); 633 m_openElements.push(element.release()); 634 m_tokenizer->setState(HTMLTokenizer::ScriptDataState); 635 m_originalInsertionMode = m_insertionMode; 636 m_insertionMode = TextMode; 604 637 } 605 638 -
trunk/WebCore/html/HTMLTreeBuilder.h
r61925 r61966 31 31 #include <wtf/Noncopyable.h> 32 32 #include <wtf/OwnPtr.h> 33 #include <wtf/PassOwnPtr.h> 33 34 #include <wtf/PassRefPtr.h> 34 35 #include <wtf/RefPtr.h> … … 100 101 }; 101 102 103 class ElementRecord : public Noncopyable { 104 public: 105 ElementRecord(PassRefPtr<Element> element, PassOwnPtr<ElementRecord> next) 106 : m_element(element) 107 , m_next(next) 108 { 109 } 110 111 Element* element() const { return m_element.get(); } 112 ElementRecord* next() const { return m_next.get(); } 113 PassOwnPtr<ElementRecord> releaseNext() { return m_next.release(); } 114 void setNext(PassOwnPtr<ElementRecord> next) { m_next = next; } 115 116 private: 117 RefPtr<Element> m_element; 118 OwnPtr<ElementRecord> m_next; 119 }; 120 102 121 class ElementStack : public Noncopyable { 103 122 public: 104 void pop() { } 105 void push(PassRefPtr<Element>) { } 106 void remove(Element*) { } 107 Element* top() const { return 0; } 123 void pop() 124 { 125 m_top = m_top->releaseNext(); 126 } 127 128 void push(PassRefPtr<Element> element) 129 { 130 m_top.set(new ElementRecord(element, m_top.release())); 131 } 132 133 Element* top() const 134 { 135 return m_top->element(); 136 } 137 138 void remove(Element* element) 139 { 140 if (m_top->element() == element) { 141 pop(); 142 return; 143 } 144 ElementRecord* pos = m_top.get(); 145 while (pos->next()) { 146 if (pos->next()->element() == element) { 147 pos->setNext(pos->next()->releaseNext()); 148 return; 149 } 150 } 151 } 152 153 private: 154 OwnPtr<ElementRecord> m_top; 108 155 }; 109 156 … … 129 176 void insertDoctype(AtomicHTMLToken&); 130 177 void insertComment(AtomicHTMLToken&); 131 PassRefPtr<Element>insertElement(AtomicHTMLToken&);178 void insertElement(AtomicHTMLToken&); 132 179 void insertCharacter(UChar cc); 133 180 void insertGenericRCDATAElement(AtomicHTMLToken&); … … 138 185 void insertHTMLStartTagInBody(AtomicHTMLToken&); 139 186 187 Element* currentElement() { return m_openElements.top(); } 188 140 189 RefPtr<Element> m_headElement; 141 190 ElementStack m_openElements; … … 158 207 159 208 InsertionMode m_insertionMode; 209 InsertionMode m_originalInsertionMode; 160 210 161 211 // HTML5 spec requires that we be able to change the state of the tokenizer
Note: See TracChangeset
for help on using the changeset viewer.