Changeset 62166 in webkit
- Timestamp:
- Jun 30, 2010 1:18:54 AM (14 years ago)
- Location:
- trunk
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r62165 r62166 1 2010-06-28 Eric Seidel <eric@webkit.org> 2 3 Reviewed by Adam Barth. 4 5 Teach HTML5TreeBuilder how to merge attributes from extra html/body elements 6 https://bugs.webkit.org/show_bug.cgi?id=41337 7 8 * html5lib/resources/webkit01.dat: Add a test for double body. 9 1 10 2010-06-30 Yury Semikhatsky <yurys@chromium.org> 2 11 -
trunk/LayoutTests/html5lib/resources/webkit01.dat
r61239 r62166 219 219 | <body> 220 220 | "<" 221 222 #data 223 <body foo='bar'><body foo='baz' yo='mama'> 224 #errors 225 #document 226 | <html> 227 | <head> 228 | <body> 229 | foo="bar" 230 | yo="mama" -
trunk/LayoutTests/html5lib/runner-expected-html5.txt
r62091 r62166 78 78 11 79 79 13 80 1481 80 17 82 81 18 … … 104 103 48 105 104 49 106 50107 105 51 108 52109 106 53 110 107 54 … … 276 273 2 277 274 278 resources/tests14.dat: 279 3 280 6 275 resources/tests14.dat: PASS 281 276 282 277 resources/tests15.dat: -
trunk/WebCore/ChangeLog
r62164 r62166 1 2010-06-28 Eric Seidel <eric@webkit.org> 2 3 Reviewed by Adam Barth. 4 5 Teach HTML5TreeBuilder how to merge attributes from extra html/body elements 6 https://bugs.webkit.org/show_bug.cgi?id=41337 7 8 Had to teach ElementStack to store pointers to html, head, and body 9 elements. 10 11 This fixed a few tests in LayoutTests/html5lib. 12 13 * html/HTMLTreeBuilder.cpp: 14 (WebCore::HTMLTreeBuilder::insertHTMLStartTagBeforeHTML): 15 (WebCore::HTMLTreeBuilder::mergeAttributesFromTokenIntoElement): 16 (WebCore::HTMLTreeBuilder::insertHTMLStartTagInBody): 17 (WebCore::HTMLTreeBuilder::processStartTag): 18 (WebCore::HTMLTreeBuilder::processEndTag): 19 (WebCore::HTMLTreeBuilder::createElementAndAttachToCurrent): 20 (WebCore::HTMLTreeBuilder::insertHTMLHtmlElement): 21 (WebCore::HTMLTreeBuilder::insertHTMLHeadElement): 22 (WebCore::HTMLTreeBuilder::insertHTMLBodyElement): 23 (WebCore::HTMLTreeBuilder::insertElement): 24 (WebCore::HTMLTreeBuilder::insertGenericRCDATAElement): 25 (WebCore::HTMLTreeBuilder::insertGenericRawTextElement): 26 * html/HTMLTreeBuilder.h: 27 (WebCore::HTMLTreeBuilder::ElementStack::ElementStack): 28 (WebCore::HTMLTreeBuilder::ElementStack::popHTMLHeadElement): 29 (WebCore::HTMLTreeBuilder::ElementStack::pop): 30 (WebCore::HTMLTreeBuilder::ElementStack::pushHTMLHtmlElement): 31 (WebCore::HTMLTreeBuilder::ElementStack::pushHTMLHeadElement): 32 (WebCore::HTMLTreeBuilder::ElementStack::pushHTMLBodyElement): 33 (WebCore::HTMLTreeBuilder::ElementStack::push): 34 (WebCore::HTMLTreeBuilder::ElementStack::removeHTMLHeadElement): 35 (WebCore::HTMLTreeBuilder::ElementStack::remove): 36 (WebCore::HTMLTreeBuilder::ElementStack::htmlElement): 37 (WebCore::HTMLTreeBuilder::ElementStack::headElement): 38 (WebCore::HTMLTreeBuilder::ElementStack::bodyElement): 39 (WebCore::HTMLTreeBuilder::ElementStack::pushCommon): 40 (WebCore::HTMLTreeBuilder::ElementStack::popCommon): 41 (WebCore::HTMLTreeBuilder::ElementStack::removeNonFirstCommon): 42 1 43 2010-06-30 José Millán Soto <jmillan@igalia.com> 2 44 -
trunk/WebCore/html/HTMLTreeBuilder.cpp
r62090 r62166 284 284 RefPtr<Element> element = HTMLHtmlElement::create(m_document); 285 285 element->setAttributeMap(token.attributes(), m_fragmentScriptingPermission); 286 m_openElements.push(attach(m_document, element.release())); 287 } 288 289 void HTMLTreeBuilder::insertHTMLStartTagInBody(AtomicHTMLToken&) 290 { 291 notImplemented(); 286 m_openElements.pushHTMLHtmlElement(attach(m_document, element.release())); 287 } 288 289 void HTMLTreeBuilder::mergeAttributesFromTokenIntoElement(AtomicHTMLToken& token, Element* element) 290 { 291 if (!token.attributes()) 292 return; 293 294 NamedNodeMap* attributes = element->attributes(false); 295 for (unsigned i = 0; i < token.attributes()->length(); ++i) { 296 Attribute* attribute = token.attributes()->attributeItem(i); 297 if (!attributes->getAttributeItem(attribute->name())) 298 element->setAttribute(attribute->name(), attribute->value()); 299 } 300 } 301 302 void HTMLTreeBuilder::insertHTMLStartTagInBody(AtomicHTMLToken& token) 303 { 304 parseError(token); 305 mergeAttributesFromTokenIntoElement(token, m_openElements.htmlElement()); 292 306 } 293 307 … … 315 329 } 316 330 if (token.name() == headTag) { 317 insertElement(token); 318 m_headElement = currentElement(); 331 insertHTMLHeadElement(token); 319 332 setInsertionMode(InHeadMode); 320 333 return; … … 336 349 if (token.name() == bodyTag) { 337 350 m_framesetOk = false; 338 insert Element(token);351 insertHTMLBodyElement(token); 339 352 m_insertionMode = InBodyMode; 340 353 return; … … 348 361 parseError(token); 349 362 ASSERT(m_headElement); 350 m_openElements.push (m_headElement);351 notImplemented(); 352 m_openElements.remove (m_headElement.get());363 m_openElements.pushHTMLHeadElement(m_headElement); 364 notImplemented(); 365 m_openElements.removeHTMLHeadElement(m_headElement.get()); 353 366 return; 354 367 } … … 372 385 if (token.name() == bodyTag) { 373 386 parseError(token); 374 notImplemented(); 387 notImplemented(); // fragment case 388 mergeAttributesFromTokenIntoElement(token, m_openElements.bodyElement()); 375 389 return; 376 390 } … … 597 611 ASSERT(insertionMode() == InHeadMode); 598 612 if (token.name() == headTag) { 599 ASSERT(m_openElements.top()->tagQName() == headTag); 600 m_openElements.pop(); 613 m_openElements.popHTMLHeadElement(); 601 614 setInsertionMode(AfterHeadMode); 602 615 return; … … 937 950 } 938 951 952 PassRefPtr<Element> HTMLTreeBuilder::createElementAndAttachToCurrent(AtomicHTMLToken& token) 953 { 954 ASSERT(token.type() == HTMLToken::StartTag); 955 return attach(currentElement(), createElement(token)); 956 } 957 958 void HTMLTreeBuilder::insertHTMLHtmlElement(AtomicHTMLToken& token) 959 { 960 m_openElements.pushHTMLHtmlElement(createElementAndAttachToCurrent(token)); 961 } 962 963 void HTMLTreeBuilder::insertHTMLHeadElement(AtomicHTMLToken& token) 964 { 965 m_headElement = createElementAndAttachToCurrent(token); 966 m_openElements.pushHTMLHeadElement(m_headElement); 967 } 968 969 void HTMLTreeBuilder::insertHTMLBodyElement(AtomicHTMLToken& token) 970 { 971 m_openElements.pushHTMLBodyElement(createElementAndAttachToCurrent(token)); 972 } 973 939 974 void HTMLTreeBuilder::insertElement(AtomicHTMLToken& token) 940 975 { 941 ASSERT(token.type() == HTMLToken::StartTag); 942 m_openElements.push(attach(currentElement(), createElement(token))); 976 m_openElements.push(createElementAndAttachToCurrent(token)); 943 977 } 944 978 … … 962 996 void HTMLTreeBuilder::insertGenericRCDATAElement(AtomicHTMLToken& token) 963 997 { 964 ASSERT(token.type() == HTMLToken::StartTag);965 998 insertElement(token); 966 999 m_tokenizer->setState(HTMLTokenizer::RCDATAState); … … 971 1004 void HTMLTreeBuilder::insertGenericRawTextElement(AtomicHTMLToken& token) 972 1005 { 973 ASSERT(token.type() == HTMLToken::StartTag);974 1006 insertElement(token); 975 1007 m_tokenizer->setState(HTMLTokenizer::RAWTEXTState); -
trunk/WebCore/html/HTMLTreeBuilder.h
r62090 r62166 29 29 #include "Element.h" 30 30 #include "FragmentScriptingPermission.h" 31 #include "HTMLNames.h" 31 32 #include "HTMLTokenizer.h" 32 33 #include <wtf/Noncopyable.h> … … 121 122 class ElementStack : public Noncopyable { 122 123 public: 124 ElementStack() 125 : m_htmlElement(0) 126 , m_headElement(0) 127 , m_bodyElement(0) 128 { 129 } 130 131 void popHTMLHeadElement() 132 { 133 ASSERT(top() == m_headElement); 134 m_headElement = 0; 135 popCommon(); 136 } 137 123 138 void pop() 124 139 { 125 top()->finishParsingChildren(); 126 m_top = m_top->releaseNext(); 140 ASSERT(!top()->hasTagName(HTMLNames::headTag)); 141 popCommon(); 142 } 143 144 void pushHTMLHtmlElement(PassRefPtr<Element> element) 145 { 146 ASSERT(element->hasTagName(HTMLNames::htmlTag)); 147 ASSERT(!m_htmlElement); 148 m_htmlElement = element.get(); 149 pushCommon(element); 150 } 151 152 void pushHTMLHeadElement(PassRefPtr<Element> element) 153 { 154 ASSERT(element->hasTagName(HTMLNames::headTag)); 155 ASSERT(!m_headElement); 156 m_headElement = element.get(); 157 pushCommon(element); 158 } 159 160 void pushHTMLBodyElement(PassRefPtr<Element> element) 161 { 162 ASSERT(element->hasTagName(HTMLNames::bodyTag)); 163 ASSERT(!m_bodyElement); 164 m_bodyElement = element.get(); 165 pushCommon(element); 127 166 } 128 167 129 168 void push(PassRefPtr<Element> element) 130 169 { 131 m_top.set(new ElementRecord(element, m_top.release())); 132 top()->beginParsingChildren(); 170 ASSERT(!element->hasTagName(HTMLNames::htmlTag)); 171 ASSERT(!element->hasTagName(HTMLNames::headTag)); 172 ASSERT(!element->hasTagName(HTMLNames::bodyTag)); 173 ASSERT(m_htmlElement); 174 pushCommon(element); 133 175 } 134 176 … … 138 180 } 139 181 182 void removeHTMLHeadElement(Element* element) 183 { 184 ASSERT(m_headElement == element); 185 if (m_top->element() == element) { 186 popHTMLHeadElement(); 187 return; 188 } 189 m_headElement = 0; 190 removeNonFirstCommon(element); 191 } 192 140 193 void remove(Element* element) 141 194 { 195 ASSERT(!element->hasTagName(HTMLNames::headTag)); 142 196 if (m_top->element() == element) { 143 197 pop(); 144 198 return; 145 199 } 146 ElementRecord* pos = m_top.get(); 147 while (pos->next()) { 148 if (pos->next()->element() == element) { 149 pos->setNext(pos->next()->releaseNext()); 150 return; 151 } 152 } 200 removeNonFirstCommon(element); 153 201 } 154 202 … … 178 226 } 179 227 228 Element* htmlElement() 229 { 230 ASSERT(m_htmlElement); 231 return m_htmlElement; 232 } 233 234 Element* headElement() 235 { 236 ASSERT(m_headElement); 237 return m_headElement; 238 } 239 240 Element* bodyElement() 241 { 242 ASSERT(m_bodyElement); 243 return m_bodyElement; 244 } 245 180 246 private: 247 void pushCommon(PassRefPtr<Element> element) 248 { 249 m_top.set(new ElementRecord(element, m_top.release())); 250 top()->beginParsingChildren(); 251 } 252 253 void popCommon() 254 { 255 ASSERT(!top()->hasTagName(HTMLNames::htmlTag)); 256 ASSERT(!top()->hasTagName(HTMLNames::bodyTag)); 257 top()->finishParsingChildren(); 258 m_top = m_top->releaseNext(); 259 } 260 261 void removeNonFirstCommon(Element* element) 262 { 263 ASSERT(!element->hasTagName(HTMLNames::htmlTag)); 264 ASSERT(!element->hasTagName(HTMLNames::bodyTag)); 265 ElementRecord* pos = m_top.get(); 266 ASSERT(pos->element() != element); 267 while (pos->next()) { 268 if (pos->next()->element() == element) { 269 // FIXME: Is it OK to call finishParsingChildren() 270 // when the children aren't actually finished? 271 element->finishParsingChildren(); 272 pos->setNext(pos->next()->releaseNext()); 273 return; 274 } 275 } 276 ASSERT_NOT_REACHED(); 277 } 278 181 279 OwnPtr<ElementRecord> m_top; 280 281 // We remember <html>, <head> and <body> as they are pushed. Their 282 // ElementRecords keep them alive. <html> and <body> are never popped. 283 // FIXME: We don't currently require type-specific information about 284 // these elements so we haven't yet bothered to plumb the types all the 285 // way down through createElement, etc. 286 Element* m_htmlElement; 287 Element* m_headElement; 288 Element* m_bodyElement; 182 289 }; 183 290 … … 220 327 void insertComment(AtomicHTMLToken&); 221 328 void insertCommentOnDocument(AtomicHTMLToken&); 329 void insertHTMLHtmlElement(AtomicHTMLToken&); 330 void insertHTMLHeadElement(AtomicHTMLToken&); 331 void insertHTMLBodyElement(AtomicHTMLToken&); 222 332 void insertElement(AtomicHTMLToken&); 223 333 void insertSelfClosingElement(AtomicHTMLToken&); … … 232 342 233 343 PassRefPtr<Element> createElement(AtomicHTMLToken&); 344 PassRefPtr<Element> createElementAndAttachToCurrent(AtomicHTMLToken&); 345 346 void mergeAttributesFromTokenIntoElement(AtomicHTMLToken&, Element*); 234 347 235 348 bool indexOfFirstUnopenFormattingElement(unsigned& firstUnopenElementIndex) const;
Note: See TracChangeset
for help on using the changeset viewer.