Changeset 62468 in webkit
- Timestamp:
- Jul 4, 2010 2:15:44 PM (14 years ago)
- Location:
- trunk
- Files:
-
- 1 added
- 13 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r62465 r62468 1 2010-07-02 Eric Seidel <eric@webkit.org> 2 3 Reviewed by Adam Barth. 4 5 HTMLTreeBuilder needs an adoption agency 6 https://bugs.webkit.org/show_bug.cgi?id=41453 7 8 Added new adoption01 suite for testing adoption agency 9 bugs. Right now only the simplest adoption test passes. 10 I'll be adding more in future commits. 11 12 * html5lib/resources/adoption01.dat: Added. 13 * html5lib/runner-expected-html5.txt: 14 * html5lib/runner-expected.txt: 15 * html5lib/runner.html: 16 1 17 2010-07-04 Robert Hogan <robert@webkit.org> 2 18 -
trunk/LayoutTests/html5lib/runner-expected-html5.txt
r62460 r62468 130 130 | <a> 131 131 | "Y" 132 | 132 | "Z" 133 133 Expected: 134 134 | <html> … … 389 389 | <body> 390 390 | <b> 391 | <p> 391 | <p> 392 | <b> 392 393 | "TEST" 393 394 Expected: … … 436 437 | <b> 437 438 | "cruel" 438 | 439 | "world" 439 440 Expected: 440 441 | <html> … … 526 527 | <cite> 527 528 | "B" 528 | <div> 529 | "C" 530 | "D" 529 | <div> 530 | <b> 531 | "C" 532 | "D" 531 533 Expected: 532 534 | <html> … … 562 564 | <i> 563 565 | <i> 564 | <div> 565 | "X" 566 | "TEST" 566 | <i> 567 | <i> 568 | <i> 569 | <div> 570 | <b> 571 | "X" 572 | "TEST" 567 573 Expected: 568 574 | <html> … … 698 704 | <i> 699 705 | " ghi " 700 | <p> 706 | <i> 707 | <p> 708 | <b> 701 709 | " jkl " 702 710 Expected: … … 728 736 | <i> 729 737 | " ghi " 730 | <p> 738 | <i> 739 | <p> 740 | <b> 731 741 | " jkl " 732 742 | " mno" … … 760 770 | <i> 761 771 | " ghi " 762 | <p> 772 | <i> 773 | <p> 774 | <i> 775 | <b> 763 776 | " jkl " 764 777 | " mno " … … 793 806 | <i> 794 807 | " ghi " 795 | <p> 808 | <i> 809 | <p> 810 | <i> 811 | <b> 796 812 | " jkl " 797 813 | " mno " … … 828 844 | <i> 829 845 | " ghi " 830 | <p> 846 | <i> 847 | <p> 848 | <i> 849 | <b> 831 850 | " jkl " 832 851 | " mno " … … 863 882 | <i> 864 883 | " ghi " 865 | <p> 884 | <i> 885 | <p> 886 | <i> 887 | <b> 866 888 | " jkl " 867 889 | " mno " 868 890 | " pqr " 869 | 891 | " stu" 870 892 Expected: 871 893 | <html> … … 1013 1035 | <strike> 1014 1036 | <code> 1015 | <code> 1016 | <code> 1017 | <code> 1018 | <strike> 1037 | <code> 1038 | <code> 1039 | <strike> 1019 1040 Expected: 1020 1041 | <html> … … 1252 1273 | <b> 1253 1274 | <em> 1254 | 1275 | <li> 1255 1276 Expected: 1256 1277 | <html> … … 1901 1922 | <nobr> 1902 1923 | <nobr> 1924 | <nobr> 1903 1925 | <nobr> 1904 | <nobr>1905 1926 Expected: 1906 1927 | <!DOCTYPE html> … … 3101 3122 | "a" 3102 3123 | <div> 3103 | <div> 3124 | <div> 3125 | <b> 3104 3126 | "y" 3105 3127 Expected: … … 3121 3143 | <body> 3122 3144 | <a> 3123 | <div> 3145 | <div> 3146 | <a> 3124 3147 | <p> 3125 3148 Expected: … … 5489 5512 5490 5513 resources/comments01.dat: PASS 5514 5515 resources/adoption01.dat: 5516 2 5517 3 5518 4 5519 5 5520 6 5521 5522 Test 2 of 6 in resources/adoption01.dat failed. Input: 5523 <a>1<p>2</a>3</p> 5524 Got: 5525 | <html> 5526 | <head> 5527 | <body> 5528 | <a> 5529 | "1" 5530 | <p> 5531 | <a> 5532 | "2" 5533 | "3" 5534 Expected: 5535 | <html> 5536 | <head> 5537 | <body> 5538 | <a> 5539 | "1" 5540 | <p> 5541 | <a> 5542 | "2" 5543 | "3" 5544 5545 Test 3 of 6 in resources/adoption01.dat failed. Input: 5546 <a>1<button>2</a>3</button> 5547 Got: 5548 | <html> 5549 | <head> 5550 | <body> 5551 | <a> 5552 | "1" 5553 | <a> 5554 | <button> 5555 | "2" 5556 | "3" 5557 Expected: 5558 | <html> 5559 | <head> 5560 | <body> 5561 | <a> 5562 | "1" 5563 | <button> 5564 | "2" 5565 | "3" 5566 5567 Test 4 of 6 in resources/adoption01.dat failed. Input: 5568 <a>1<b>2</a>3</b> 5569 Got: 5570 | <html> 5571 | <head> 5572 | <body> 5573 | <a> 5574 | "1" 5575 | <a> 5576 | <b> 5577 | "2" 5578 | "3" 5579 Expected: 5580 | <html> 5581 | <head> 5582 | <body> 5583 | <a> 5584 | "1" 5585 | <b> 5586 | "2" 5587 | <b> 5588 | "3" 5589 5590 Test 5 of 6 in resources/adoption01.dat failed. Input: 5591 <a>1<div>2<div>3</a>4</div>5</div> 5592 Got: 5593 | <html> 5594 | <head> 5595 | <body> 5596 | <a> 5597 | "1" 5598 | <div> 5599 | <a> 5600 | "2" 5601 | <div> 5602 | "3" 5603 | "4" 5604 | "5" 5605 Expected: 5606 | <html> 5607 | <head> 5608 | <body> 5609 | <a> 5610 | "1" 5611 | <div> 5612 | <a> 5613 | "2" 5614 | <div> 5615 | <a> 5616 | "3" 5617 | "4" 5618 | "5" 5619 5620 Test 6 of 6 in resources/adoption01.dat failed. Input: 5621 <table><a>1<p>2</a>3</p> 5622 Got: 5623 | <html> 5624 | <head> 5625 | <body> 5626 | <table> 5627 Expected: 5628 | <html> 5629 | <head> 5630 | <body> 5631 | <a> 5632 | "1" 5633 | <p> 5634 | <a> 5635 | "2" 5636 | "3" 5637 | <table> 5491 5638 #EOF -
trunk/LayoutTests/html5lib/runner-expected.txt
r62460 r62468 4891 4891 4892 4892 resources/comments01.dat: PASS 4893 4894 resources/adoption01.dat: 4895 1 4896 6 4897 4898 Test 1 of 6 in resources/adoption01.dat failed. Input: 4899 <a><p></a></p> 4900 Got: 4901 | <html> 4902 | <head> 4903 | <body> 4904 | <a> 4905 | <p> 4906 Expected: 4907 | <html> 4908 | <head> 4909 | <body> 4910 | <a> 4911 | <p> 4912 | <a> 4913 4914 Test 6 of 6 in resources/adoption01.dat failed. Input: 4915 <table><a>1<p>2</a>3</p> 4916 Got: 4917 | <html> 4918 | <head> 4919 | <body> 4920 | <a> 4921 | "1" 4922 | <p> 4923 | "2" 4924 | "3" 4925 | <table> 4926 | <tbody> 4927 Expected: 4928 | <html> 4929 | <head> 4930 | <body> 4931 | <a> 4932 | "1" 4933 | <p> 4934 | <a> 4935 | "2" 4936 | "3" 4937 | <table> -
trunk/LayoutTests/html5lib/runner.html
r62237 r62468 59 59 'resources/entities01.dat', 60 60 'resources/entities02.dat', 61 'resources/comments01.dat' 61 'resources/comments01.dat', 62 'resources/adoption01.dat' 62 63 ], 63 64 tests = [], -
trunk/WebCore/ChangeLog
r62467 r62468 1 2010-07-01 Eric Seidel <eric@webkit.org> 2 3 Reviewed by Adam Barth. 4 5 HTMLTreeBuilder needs an adoption agency 6 https://bugs.webkit.org/show_bug.cgi?id=41453 7 8 This changes some test results, but only makes the simplest 9 adoption agency cases pass. I think the code is likely 10 very close, but further iteration to make this change larger 11 seems counter-productive. I recommend we check in this 12 progression and work from here. 13 14 * dom/ContainerNode.cpp: 15 (WebCore::ContainerNode::addChildCommon): 16 - Make sure callers don't assume this will reparent. 17 (WebCore::ContainerNode::parserAddChild): 18 - Update comment to document lack of reparenting behavior. 19 * html/HTMLElementStack.cpp: 20 (WebCore::HTMLElementStack::ElementRecord::ElementRecord): 21 (WebCore::HTMLElementStack::ElementRecord::~ElementRecord): 22 (WebCore::HTMLElementStack::ElementRecord::replaceElement): 23 (WebCore::HTMLElementStack::ElementRecord::isAbove): 24 - Added for debugging. 25 (WebCore::HTMLElementStack::pushHTMLHtmlElement): 26 (WebCore::HTMLElementStack::insertAbove): 27 - Needed for the adoption agency. 28 (WebCore::HTMLElementStack::topRecord): 29 (WebCore::HTMLElementStack::bottom): 30 (WebCore::HTMLElementStack::removeHTMLHeadElement): 31 (WebCore::HTMLElementStack::remove): 32 (WebCore::HTMLElementStack::find): 33 (WebCore::HTMLElementStack::topmost): 34 (WebCore::HTMLElementStack::contains): 35 (WebCore::HTMLElementStack::htmlElement): 36 (WebCore::HTMLElementStack::headElement): 37 (WebCore::HTMLElementStack::bodyElement): 38 (WebCore::HTMLElementStack::pushCommon): 39 (WebCore::HTMLElementStack::removeNonTopCommon): 40 - Fix the name to match top/bottom. 41 * html/HTMLElementStack.h: 42 (WebCore::HTMLElementStack::ElementRecord::element): 43 (WebCore::HTMLElementStack::ElementRecord::next): 44 (WebCore::HTMLElementStack::ElementRecord::releaseNext): 45 (WebCore::HTMLElementStack::ElementRecord::setNext): 46 * html/HTMLFormattingElementList.cpp: 47 (WebCore::HTMLFormattingElementList::closestElementInScopeWithName): 48 (WebCore::HTMLFormattingElementList::contains): 49 (WebCore::HTMLFormattingElementList::find): 50 (WebCore::HTMLFormattingElementList::remove): 51 * html/HTMLFormattingElementList.h: 52 (WebCore::HTMLFormattingElementList::isEmpty): 53 (WebCore::HTMLFormattingElementList::size): 54 * html/HTMLTreeBuilder.cpp: 55 (WebCore::HTMLTreeBuilder::processStartTag): 56 (WebCore::HTMLTreeBuilder::furthestBlockForFormattingElement): 57 - Part of the Adoption Agency algorithm. 58 (WebCore::HTMLTreeBuilder::findFosterParentFor): 59 - Used to move mis-nested content out of tables. 60 This doesn't seem to work quite right yet. 61 (WebCore::HTMLTreeBuilder::reparentChildren): 62 (WebCore::HTMLTreeBuilder::callTheAdoptionAgency): 63 - The ridiculously long/complicated adoption agency algorithm from HTML5. 64 (WebCore::HTMLTreeBuilder::processEndTag): 65 * html/HTMLTreeBuilder.h: 66 1 67 2010-07-04 Justin Schuh <jschuh@chromium.org> 2 68 -
trunk/WebCore/dom/ContainerNode.cpp
r62086 r62468 540 540 void ContainerNode::addChildCommon(Node* newChild) 541 541 { 542 ASSERT(!newChild->parent()); // Use appendChild if you need to handle reparenting. 542 543 forbidEventDispatch(); 543 544 Node* last = m_lastChild; … … 556 557 ASSERT(newChild); 557 558 // This function is only used during parsing. 558 // It does not send any DOM mutation events .559 // It does not send any DOM mutation events or handle reparenting. 559 560 560 561 addChildCommon(newChild.get()); -
trunk/WebCore/html/HTMLElementStack.cpp
r62438 r62468 39 39 using namespace HTMLNames; 40 40 41 class HTMLElementStack::ElementRecord : public Noncopyable { 42 public: 43 ElementRecord(PassRefPtr<Element> element, PassOwnPtr<ElementRecord> next) 44 : m_element(element) 45 , m_next(next) 46 { 47 } 48 49 Element* element() const { return m_element.get(); } 50 ElementRecord* next() const { return m_next.get(); } 51 PassOwnPtr<ElementRecord> releaseNext() { return m_next.release(); } 52 void setNext(PassOwnPtr<ElementRecord> next) { m_next = next; } 53 54 private: 55 RefPtr<Element> m_element; 56 OwnPtr<ElementRecord> m_next; 57 }; 41 HTMLElementStack::ElementRecord::ElementRecord(PassRefPtr<Element> element, PassOwnPtr<ElementRecord> next) 42 : m_element(element) 43 , m_next(next) 44 { 45 ASSERT(m_element); 46 } 47 48 HTMLElementStack::ElementRecord::~ElementRecord() 49 { 50 } 51 52 void HTMLElementStack::ElementRecord::replaceElement(PassRefPtr<Element> element) 53 { 54 ASSERT(element); 55 // FIXME: Should this call finishParsingChildren? 56 m_element = element; 57 } 58 59 bool HTMLElementStack::ElementRecord::isAbove(ElementRecord* other) const 60 { 61 for (ElementRecord* below = next(); below; below = below->next()) { 62 if (below == other) 63 return true; 64 } 65 return false; 66 } 58 67 59 68 HTMLElementStack::HTMLElementStack() … … 105 114 void HTMLElementStack::pushHTMLHtmlElement(PassRefPtr<Element> element) 106 115 { 116 ASSERT(!m_top); // <html> should always be the bottom of the stack. 107 117 ASSERT(element->hasTagName(HTMLNames::htmlTag)); 108 118 ASSERT(!m_htmlElement); … … 136 146 } 137 147 148 void HTMLElementStack::insertAbove(PassRefPtr<Element> element, ElementRecord* recordBelow) 149 { 150 ASSERT(element); 151 ASSERT(recordBelow); 152 ASSERT(m_top); 153 ASSERT(!element->hasTagName(HTMLNames::htmlTag)); 154 ASSERT(!element->hasTagName(HTMLNames::headTag)); 155 ASSERT(!element->hasTagName(HTMLNames::bodyTag)); 156 ASSERT(m_htmlElement); 157 if (recordBelow == m_top) { 158 push(element); 159 return; 160 } 161 162 for (ElementRecord* recordAbove = m_top.get(); recordAbove; recordAbove = recordAbove->next()) { 163 if (recordAbove->next() != recordBelow) 164 continue; 165 166 recordAbove->setNext(new ElementRecord(element, recordAbove->releaseNext())); 167 recordAbove->next()->element()->beginParsingChildren(); 168 return; 169 } 170 ASSERT_NOT_REACHED(); 171 } 172 173 HTMLElementStack::ElementRecord* HTMLElementStack::topRecord() const 174 { 175 return m_top.get(); 176 } 177 138 178 Element* HTMLElementStack::top() const 139 179 { 140 180 return m_top->element(); 181 } 182 183 Element* HTMLElementStack::bottom() const 184 { 185 return htmlElement(); 141 186 } 142 187 … … 149 194 } 150 195 m_headElement = 0; 151 removeNon FirstCommon(element);196 removeNonTopCommon(element); 152 197 } 153 198 … … 159 204 return; 160 205 } 161 removeNon FirstCommon(element);162 } 163 164 bool HTMLElementStack::contains(Element* element) const206 removeNonTopCommon(element); 207 } 208 209 HTMLElementStack::ElementRecord* HTMLElementStack::find(Element* element) const 165 210 { 166 211 for (ElementRecord* pos = m_top.get(); pos; pos = pos->next()) { 167 212 if (pos->element() == element) 168 return true; 169 } 170 return false; 213 return pos; 214 } 215 return 0; 216 } 217 218 HTMLElementStack::ElementRecord* HTMLElementStack::topmost(const AtomicString& tagName) const 219 { 220 for (ElementRecord* pos = m_top.get(); pos; pos = pos->next()) { 221 if (pos->element()->hasLocalName(tagName)) 222 return pos; 223 } 224 return 0; 225 } 226 227 bool HTMLElementStack::contains(Element* element) const 228 { 229 return !!find(element); 171 230 } 172 231 173 232 namespace { 174 233 175 inline bool isScopeMarker( constElement* element)234 inline bool isScopeMarker(Element* element) 176 235 { 177 236 return element->hasTagName(appletTag) 237 || element->hasTagName(buttonTag) 178 238 || element->hasTagName(captionTag) 179 || element->hasTagName(appletTag)180 239 || element->hasTagName(htmlTag) 240 || element->hasTagName(marqueeTag) 241 || element->hasTagName(objectTag) 181 242 || element->hasTagName(tableTag) 182 243 || element->hasTagName(tdTag) 183 244 || element->hasTagName(thTag) 184 || element->hasTagName(buttonTag)185 || element->hasTagName(marqueeTag)186 || element->hasTagName(objectTag)187 245 #if ENABLE(SVG_FOREIGN_OBJECT) 188 246 || element->hasTagName(SVGNames::foreignObjectTag) … … 191 249 } 192 250 193 inline bool isListItemScopeMarker( constElement* element)251 inline bool isListItemScopeMarker(Element* element) 194 252 { 195 253 return isScopeMarker(element) … … 197 255 || element->hasTagName(ulTag); 198 256 } 199 inline bool isTableScopeMarker( constElement* element)257 inline bool isTableScopeMarker(Element* element) 200 258 { 201 259 return element->hasTagName(htmlTag) … … 205 263 } 206 264 207 template <bool isMarker( constElement*)>265 template <bool isMarker(Element*)> 208 266 bool inScopeCommon(HTMLElementStack::ElementRecord* top, const AtomicString& targetTag) 209 267 { … … 247 305 } 248 306 249 Element* HTMLElementStack::htmlElement() 307 Element* HTMLElementStack::htmlElement() const 250 308 { 251 309 ASSERT(m_htmlElement); … … 253 311 } 254 312 255 Element* HTMLElementStack::headElement() 313 Element* HTMLElementStack::headElement() const 256 314 { 257 315 ASSERT(m_headElement); … … 259 317 } 260 318 261 Element* HTMLElementStack::bodyElement() 319 Element* HTMLElementStack::bodyElement() const 262 320 { 263 321 ASSERT(m_bodyElement); … … 267 325 void HTMLElementStack::pushCommon(PassRefPtr<Element> element) 268 326 { 327 ASSERT(m_htmlElement); 269 328 m_top.set(new ElementRecord(element, m_top.release())); 270 329 top()->beginParsingChildren(); … … 280 339 } 281 340 282 void HTMLElementStack::removeNon FirstCommon(Element* element)341 void HTMLElementStack::removeNonTopCommon(Element* element) 283 342 { 284 343 ASSERT(!element->hasTagName(HTMLNames::htmlTag)); 285 344 ASSERT(!element->hasTagName(HTMLNames::bodyTag)); 286 ElementRecord* pos = m_top.get(); 287 ASSERT(pos->element() != element); 288 while (pos->next()) { 345 ASSERT(top() != element); 346 for (ElementRecord* pos = m_top.get(); pos; pos = pos->next()) { 289 347 if (pos->next()->element() == element) { 290 348 // FIXME: Is it OK to call finishParsingChildren() -
trunk/WebCore/html/HTMLElementStack.h
r62438 r62468 27 27 #define HTMLElementStack_h 28 28 29 #include <wtf/Forward.h>30 29 #include <wtf/Noncopyable.h> 31 30 #include <wtf/OwnPtr.h> 31 #include <wtf/PassOwnPtr.h> 32 #include <wtf/RefPtr.h> 32 33 33 34 namespace WebCore { … … 36 37 class Element; 37 38 39 // NOTE: The HTML5 spec uses a backwards (grows downward) stack. We're using 40 // more standard (grows upwards) stack terminology here. 38 41 class HTMLElementStack : public Noncopyable { 39 42 public: … … 41 44 ~HTMLElementStack(); 42 45 46 class ElementRecord : public Noncopyable { 47 public: 48 ~ElementRecord(); // Public for ~PassOwnPtr() 49 50 Element* element() const { return m_element.get(); } 51 void replaceElement(PassRefPtr<Element>); 52 53 bool isAbove(ElementRecord*) const; 54 55 ElementRecord* next() const { return m_next.get(); } 56 57 private: 58 friend class HTMLElementStack; 59 60 ElementRecord(PassRefPtr<Element>, PassOwnPtr<ElementRecord>); 61 62 PassOwnPtr<ElementRecord> releaseNext() { return m_next.release(); } 63 void setNext(PassOwnPtr<ElementRecord> next) { m_next = next; } 64 65 RefPtr<Element> m_element; 66 OwnPtr<ElementRecord> m_next; 67 }; 68 43 69 Element* top() const; 70 ElementRecord* topRecord() const; 71 Element* bottom() const; 72 ElementRecord* find(Element*) const; 73 ElementRecord* topmost(const AtomicString& tagName) const; 74 75 void insertAbove(PassRefPtr<Element>, ElementRecord*); 44 76 45 77 void push(PassRefPtr<Element>); … … 64 96 bool inTableScope(const AtomicString& tagName) const; 65 97 66 Element* htmlElement() ;67 Element* headElement() ;68 Element* bodyElement() ;98 Element* htmlElement() const; 99 Element* headElement() const; 100 Element* bodyElement() const; 69 101 70 // Public so free functions can use it, but defined privately.71 class ElementRecord;72 102 private: 73 103 void pushCommon(PassRefPtr<Element>); 74 104 void popCommon(); 75 void removeNon FirstCommon(Element*);105 void removeNonTopCommon(Element*); 76 106 77 107 OwnPtr<ElementRecord> m_top; -
trunk/WebCore/html/HTMLFormattingElementList.cpp
r62235 r62468 65 65 } 66 66 67 bool HTMLFormattingElementList::Entry::operator==(const Entry& other) const 68 { 69 return element() == other.element(); 70 } 71 72 bool HTMLFormattingElementList::Entry::operator!=(const Entry& other) const 73 { 74 return element() != other.element(); 75 } 76 67 77 HTMLFormattingElementList::HTMLFormattingElementList() 68 78 { … … 73 83 } 74 84 85 Element* HTMLFormattingElementList::closestElementInScopeWithName(const AtomicString& targetName) 86 { 87 for (unsigned i = 1; i <= m_entries.size(); ++i) { 88 const Entry& entry = m_entries[m_entries.size() - i]; 89 if (entry.isMarker()) 90 return 0; 91 if (entry.element()->hasLocalName(targetName)) 92 return entry.element(); 93 } 94 return 0; 95 } 96 97 bool HTMLFormattingElementList::contains(Element* element) 98 { 99 return !!find(element); 100 } 101 102 HTMLFormattingElementList::Entry* HTMLFormattingElementList::find(Element* element) 103 { 104 size_t index = m_entries.find(element); 105 if (index != notFound) { 106 // This is somewhat of a hack, and is why this method can't be const. 107 return &m_entries[index]; 108 } 109 return 0; 110 } 111 75 112 void HTMLFormattingElementList::append(Element* element) 76 113 { 77 114 m_entries.append(element); 115 } 116 117 void HTMLFormattingElementList::remove(Element* element) 118 { 119 size_t index = m_entries.find(element); 120 if (index != notFound) 121 m_entries.remove(index); 78 122 } 79 123 -
trunk/WebCore/html/HTMLFormattingElementList.h
r62235 r62468 33 33 namespace WebCore { 34 34 35 class AtomicString; 35 36 class Element; 36 37 … … 40 41 HTMLFormattingElementList(); 41 42 ~HTMLFormattingElementList(); 42 43 bool isEmpty() const { return !size(); }44 size_t size() const { return m_entries.size(); }45 46 void append(Element*);47 void clearToLastMarker();48 43 49 44 // Ideally Entry would be private, but HTMLTreeBuilder has to coordinate … … 62 57 void replaceElement(PassRefPtr<Element>); 63 58 59 // Needed for use with Vector. 60 bool operator==(const Entry&) const; 61 bool operator!=(const Entry&) const; 62 64 63 private: 65 64 RefPtr<Element> m_element; 66 65 }; 66 67 bool isEmpty() const { return !size(); } 68 size_t size() const { return m_entries.size(); } 69 70 Element* closestElementInScopeWithName(const AtomicString&); 71 72 Entry* find(Element*); 73 bool contains(Element*); 74 void append(Element*); 75 void remove(Element*); 76 void clearToLastMarker(); 67 77 68 78 const Entry& operator[](size_t i) const { return m_entries[i]; } -
trunk/WebCore/html/HTMLTreeBuilder.cpp
r62460 r62468 32 32 #include "Element.h" 33 33 #include "Frame.h" 34 #include "HTMLDocument.h" 34 35 #include "HTMLElementFactory.h" 36 #include "HTMLHtmlElement.h" 37 #include "HTMLNames.h" 35 38 #include "HTMLScriptElement.h" 39 #include "HTMLToken.h" 36 40 #include "HTMLTokenizer.h" 37 #include "HTMLToken.h"38 #include "HTMLDocument.h"39 #include "HTMLHtmlElement.h"40 41 #include "LegacyHTMLDocumentParser.h" 41 #include "HTMLNames.h"42 42 #include "LegacyHTMLTreeBuilder.h" 43 43 #include "NotImplemented.h" 44 #include "SVGNames.h" 45 #include "ScriptController.h" 44 46 #include "Settings.h" 45 #include "ScriptController.h"46 47 #include "Text.h" 47 48 #include <wtf/UnusedParam.h> … … 63 64 { 64 65 return !document->settings() || !document->settings()->html5TreeBuilderEnabled(); 66 } 67 68 bool isNumberedHeaderTag(const AtomicString& tagName) 69 { 70 return tagName == h1Tag 71 || tagName == h2Tag 72 || tagName == h3Tag 73 || tagName == h4Tag 74 || tagName == h5Tag 75 || tagName == h6Tag; 76 } 77 78 // http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#special 79 bool isSpecialTag(const AtomicString& tagName) 80 { 81 return tagName == addressTag 82 || tagName == articleTag 83 || tagName == asideTag 84 || tagName == baseTag 85 || tagName == basefontTag 86 || tagName == "bgsound" 87 || tagName == blockquoteTag 88 || tagName == bodyTag 89 || tagName == brTag 90 || tagName == buttonTag 91 || tagName == centerTag 92 || tagName == colTag 93 || tagName == colgroupTag 94 || tagName == "command" 95 || tagName == ddTag 96 || tagName == "details" 97 || tagName == dirTag 98 || tagName == divTag 99 || tagName == dlTag 100 || tagName == dtTag 101 || tagName == embedTag 102 || tagName == fieldsetTag 103 || tagName == "figure" 104 || tagName == footerTag 105 || tagName == formTag 106 || tagName == frameTag 107 || tagName == framesetTag 108 || isNumberedHeaderTag(tagName) 109 || tagName == headTag 110 || tagName == headerTag 111 || tagName == hgroupTag 112 || tagName == hrTag 113 || tagName == iframeTag 114 || tagName == imgTag 115 || tagName == inputTag 116 || tagName == isindexTag 117 || tagName == liTag 118 || tagName == linkTag 119 || tagName == listingTag 120 || tagName == menuTag 121 || tagName == metaTag 122 || tagName == navTag 123 || tagName == noembedTag 124 || tagName == noframesTag 125 || tagName == noscriptTag 126 || tagName == olTag 127 || tagName == pTag 128 || tagName == paramTag 129 || tagName == plaintextTag 130 || tagName == preTag 131 || tagName == scriptTag 132 || tagName == sectionTag 133 || tagName == selectTag 134 || tagName == styleTag 135 || tagName == tbodyTag 136 || tagName == textareaTag 137 || tagName == tfootTag 138 || tagName == theadTag 139 || tagName == titleTag 140 || tagName == trTag 141 || tagName == ulTag 142 || tagName == wbrTag 143 || tagName == xmpTag; 144 } 145 146 // http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#scoping 147 // Same as isScopingTag in LegacyHTMLTreeBuilder.cpp 148 // and isScopeMarker in HTMLElementStack.cpp 149 bool isScopingTag(const AtomicString& tagName) 150 { 151 return tagName == appletTag 152 || tagName == buttonTag 153 || tagName == captionTag 154 #if ENABLE(SVG_FOREIGN_OBJECT) 155 || tagName == SVGNames::foreignObjectTag 156 #endif 157 || tagName == htmlTag 158 || tagName == marqueeTag 159 || tagName == objectTag 160 || tagName == tableTag 161 || tagName == tdTag 162 || tagName == thTag; 163 } 164 165 bool isNonAnchorFormattingTag(const AtomicString& tagName) 166 { 167 return tagName == bTag 168 || tagName == bigTag 169 || tagName == codeTag 170 || tagName == emTag 171 || tagName == fontTag 172 || tagName == iTag 173 || tagName == nobrTag 174 || tagName == sTag 175 || tagName == smallTag 176 || tagName == strikeTag 177 || tagName == strongTag 178 || tagName == ttTag 179 || tagName == uTag; 180 } 181 182 // http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#formatting 183 bool isFormattingTag(const AtomicString& tagName) 184 { 185 return tagName == aTag || isNonAnchorFormattingTag(tagName); 186 } 187 188 // http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#phrasing 189 bool isPhrasingTag(const AtomicString& tagName) 190 { 191 return !isSpecialTag(tagName) && !isScopingTag(tagName) && !isFormattingTag(tagName); 65 192 } 66 193 … … 420 547 return; 421 548 } 422 if ( token.name() == h1Tag || token.name() == h2Tag || token.name() == h3Tag || token.name() == h4Tag || token.name() == h5Tag || token.name() == h6Tag) {549 if (isNumberedHeaderTag(token.name())) { 423 550 processFakePEndTagIfPInScope(); 424 551 notImplemented(); … … 471 598 return; 472 599 } 473 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) {600 if (isNonAnchorFormattingTag(token.name())) { 474 601 reconstructTheActiveFormattingElements(); 475 602 insertFormattingElement(token); … … 672 799 m_insertionMode = AfterBodyMode; 673 800 return true; 801 } 802 803 // FIXME: This probably belongs on HTMLElementStack. 804 HTMLElementStack::ElementRecord* HTMLTreeBuilder::furthestBlockForFormattingElement(Element* formattingElement) 805 { 806 HTMLElementStack::ElementRecord* furthestBlock = 0; 807 HTMLElementStack::ElementRecord* record = m_openElements.topRecord(); 808 for (; record; record = record->next()) { 809 if (record->element() == formattingElement) 810 return furthestBlock; 811 const AtomicString& tagName = record->element()->localName(); 812 // !phrasing && !formatting == scoping || special 813 if (isScopingTag(tagName) || isSpecialTag(tagName)) 814 furthestBlock = record; 815 } 816 ASSERT_NOT_REACHED(); 817 return 0; 818 } 819 820 void HTMLTreeBuilder::findFosterParentFor(Element* element) 821 { 822 Element* fosterParentElement = 0; 823 HTMLElementStack::ElementRecord* lastTableElementRecord = m_openElements.topmost(tableTag.localName()); 824 if (lastTableElementRecord) { 825 Element* lastTableElement = lastTableElementRecord->element(); 826 if (lastTableElement->parent()) { 827 // FIXME: We need an insertElement which does not send mutation events. 828 ExceptionCode ec = 0; 829 lastTableElement->parent()->insertBefore(element, lastTableElement, ec); 830 ASSERT(!ec); 831 return; 832 } 833 fosterParentElement = lastTableElementRecord->next()->element(); 834 } else { 835 ASSERT(m_isParsingFragment); 836 fosterParentElement = m_openElements.bottom(); // <html> element 837 } 838 839 fosterParentElement->parserAddChild(element); 840 } 841 842 // FIXME: This should have a whitty name. 843 // FIXME: This must be implemented in many other places in WebCore. 844 void HTMLTreeBuilder::reparentChildren(Element* oldParent, Element* newParent) 845 { 846 Node* child = oldParent->firstChild(); 847 while (child) { 848 Node* nextChild = child->nextSibling(); 849 ExceptionCode ec; 850 newParent->appendChild(child, ec); 851 ASSERT(!ec); 852 child = nextChild; 853 } 854 } 855 856 // http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html#parsing-main-inbody 857 void HTMLTreeBuilder::callTheAdoptionAgency(AtomicHTMLToken& token) 858 { 859 while (1) { 860 // 1. 861 Element* formattingElement = m_activeFormattingElements.closestElementInScopeWithName(token.name()); 862 if (!formattingElement || !m_openElements.inScope(formattingElement)) { 863 parseError(token); 864 notImplemented(); // Check the stack of open elements for a more specific parse error. 865 return; 866 } 867 HTMLElementStack::ElementRecord* formattingElementRecord = m_openElements.find(formattingElement); 868 if (!formattingElementRecord) { 869 parseError(token); 870 m_activeFormattingElements.remove(formattingElement); 871 return; 872 } 873 if (formattingElement != currentElement()) 874 parseError(token); 875 // 2. 876 HTMLElementStack::ElementRecord* furthestBlock = furthestBlockForFormattingElement(formattingElement); 877 // 3. 878 if (!furthestBlock) { 879 m_openElements.popUntil(formattingElement); 880 m_openElements.pop(); 881 m_activeFormattingElements.remove(formattingElement); 882 return; 883 } 884 // 4. 885 ASSERT(furthestBlock->isAbove(formattingElementRecord)); 886 Element* commonAncestor = formattingElementRecord->next()->element(); 887 // 5. 888 notImplemented(); // bookmark? 889 // 6. 890 HTMLElementStack::ElementRecord* node = furthestBlock; 891 HTMLElementStack::ElementRecord* nextNode = node->next(); 892 HTMLElementStack::ElementRecord* lastNode = furthestBlock; 893 while (1) { 894 // 6.1 895 node = nextNode; 896 ASSERT(node); 897 nextNode = node->next(); // Save node->next() for the next iteration in case node is deleted in 6.2. 898 // 6.2 899 if (!m_activeFormattingElements.contains(node->element())) { 900 m_openElements.remove(node->element()); 901 node = 0; 902 continue; 903 } 904 // 6.3 905 if (node == formattingElementRecord) 906 break; 907 // 6.4 908 if (lastNode == furthestBlock) 909 notImplemented(); // move bookmark. 910 // 6.5 911 // FIXME: We're supposed to save the original token in the entry. 912 AtomicHTMLToken fakeToken(HTMLToken::StartTag, node->element()->localName()); 913 // Is createElement correct? (instead of insertElement) 914 // Does this code ever leave newElement unattached? 915 RefPtr<Element> newElement = createElement(fakeToken); 916 HTMLFormattingElementList::Entry* nodeEntry = m_activeFormattingElements.find(node->element()); 917 nodeEntry->replaceElement(newElement.get()); 918 node->replaceElement(newElement.release()); 919 // 6.6 920 // Use appendChild instead of parserAddChild to handle possible reparenting. 921 ExceptionCode ec; 922 node->element()->appendChild(lastNode->element(), ec); 923 ASSERT(!ec); 924 // 6.7 925 lastNode = node; 926 } 927 // 7 928 const AtomicString& commonAncestorTag = commonAncestor->localName(); 929 if (commonAncestorTag == tableTag 930 || commonAncestorTag == tbodyTag 931 || commonAncestorTag == tfootTag 932 || commonAncestorTag == theadTag 933 || commonAncestorTag == trTag) 934 findFosterParentFor(lastNode->element()); 935 else { 936 ExceptionCode ec; 937 commonAncestor->appendChild(lastNode->element(), ec); 938 ASSERT(!ec); 939 } 940 // 8 941 // FIXME: We're supposed to save the original token in the entry. 942 AtomicHTMLToken fakeToken(HTMLToken::StartTag, formattingElement->localName()); 943 RefPtr<Element> newElement = createElement(fakeToken); 944 // 9 945 reparentChildren(furthestBlock->element(), newElement.get()); 946 // 10 947 furthestBlock->element()->parserAddChild(newElement); 948 // 11 949 m_activeFormattingElements.remove(formattingElement); 950 notImplemented(); // insert new element at bookmark 951 // 12 952 m_openElements.remove(formattingElement); 953 m_openElements.insertAbove(newElement, furthestBlock); 954 } 674 955 } 675 956 … … 788 1069 return; 789 1070 } 790 if ( token.name() == h1Tag || token.name() == h2Tag || token.name() == h3Tag || token.name() == h4Tag || token.name() == h5Tag || token.name() == h6Tag) {1071 if (isNumberedHeaderTag(token.name())) { 791 1072 if (!m_openElements.inScope(token.name())) { 792 1073 parseError(token); … … 804 1085 return; 805 1086 } 806 if (token.name() == aTag || token.name() == bTag || token.name() == bigTag || token.name() == codeTag || token.name() == emTag || token.name() == fontTag || token.name() == iTag || token.name() == nobrTag || token.name() == sTag || token.name() == smallTag || token.name() == strikeTag || token.name() == strongTag || token.name() == ttTag || token.name() == uTag) { 807 notImplemented(); 808 // FIXME: There's a complicated algorithm that goes here. 1087 if (isFormattingTag(token.name())) { 1088 callTheAdoptionAgency(token); 809 1089 return; 810 1090 } -
trunk/WebCore/html/HTMLTreeBuilder.h
r62431 r62468 126 126 void processFakePEndTagIfPInScope(); 127 127 128 HTMLElementStack::ElementRecord* furthestBlockForFormattingElement(Element*); 129 void findFosterParentFor(Element*); 130 void reparentChildren(Element* oldParent, Element* newParent); 131 void callTheAdoptionAgency(AtomicHTMLToken&); 132 128 133 template<typename ChildType> 129 134 PassRefPtr<ChildType> attach(Node* parent, PassRefPtr<ChildType> prpChild) -
trunk/WebCore/page/Frame.cpp
r61324 r62468 153 153 , m_excludeFromTextSearch(false) 154 154 { 155 ASSERT(page); 155 156 AtomicString::init(); 156 157 HTMLNames::init();
Note: See TracChangeset
for help on using the changeset viewer.