Changeset 20170 in webkit
- Timestamp:
- Mar 13, 2007 4:18:23 PM (17 years ago)
- Location:
- trunk
- Files:
-
- 12 added
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r20166 r20170 1 2007-03-13 Darin Adler <darin@apple.com> 2 3 Reviewed by Maciej. 4 5 - tests for http://bugs.webkit.org/show_bug.cgi?id=12794 6 <rdar://problem/5028154> REGRESSION: TripTik planner at aaa.com never 7 finishes loading due to unclosed canvas tag (12794) 8 9 * fast/canvas/canvas-hides-fallback-expected.txt: Added. 10 * fast/canvas/canvas-hides-fallback.html: Added. 11 * fast/canvas/script-inside-canvas-fallback-expected.txt: Added. 12 * fast/canvas/script-inside-canvas-fallback.html: Added. 13 * fast/canvas/unclosed-canvas-1-expected.txt: Added. 14 * fast/canvas/unclosed-canvas-1.html: Added. 15 * fast/canvas/unclosed-canvas-2-expected.txt: Added. 16 * fast/canvas/unclosed-canvas-2.html: Added. 17 * fast/canvas/unclosed-canvas-3-expected.txt: Added. 18 * fast/canvas/unclosed-canvas-3.html: Added. 19 * fast/canvas/unclosed-canvas-4-expected.txt: Added. 20 * fast/canvas/unclosed-canvas-4.html: Added. 21 1 22 2007-03-13 David Harrison <harrison@apple.com> 2 23 -
trunk/WebCore/ChangeLog
r20169 r20170 1 2007-03-13 Darin Adler <darin@apple.com> 2 3 Reviewed by Maciej. 4 5 - fix http://bugs.webkit.org/show_bug.cgi?id=12794 6 <rdar://problem/5028154> REGRESSION: TripTik planner at aaa.com never 7 finishes loading due to unclosed canvas tag (12794) 8 9 Change <canvas> elements so that their contents are parsed normally, 10 but not rendered. This change fixes the bug, because normal parsing 11 rules close the <canvas> element in that case. The special parser 12 stuff was just getting in the way. 13 14 Also do some basic cleanup to the HTML parser. This was motivated by 15 an earlier version of this patch that made even more changes to the 16 parser, but the cleanup is still worth landing. 17 18 Test: fast/canvas/canvas-hides-fallback.html 19 Test: fast/canvas/script-inside-canvas-fallback.html 20 Test: fast/canvas/unclosed-canvas-1.html 21 Test: fast/canvas/unclosed-canvas-2.html 22 Test: fast/canvas/unclosed-canvas-3.html 23 Test: fast/canvas/unclosed-canvas-4.html 24 25 * html/HTMLCanvasElement.h: Added a data member to keep track of whether the 26 renderer is a RenderHTMLCanvas or not. 27 * html/HTMLCanvasElement.cpp: 28 (WebCore::HTMLCanvasElement::createRenderer): If JavaScript is enabled, create 29 a RenderHTMLCanvas. If it's not, let the default code create the default type 30 of renderer, which will result in fallback content being visible. The 31 RenderHTMLCanvas class already hides all of its children. Set the m_rendererIsCanvas 32 boolean accordingly. Since the actual storage for the canvas is allocated lazily 33 when you actually get a drawing context, we don't need to do anything special 34 to prevent it when JavaScript is disabled; the relevant functions won't be called. 35 (WebCore::HTMLCanvasElement::reset): Protect the code that manipulates the 36 RenderHTMLCanvas with a check of m_rendererIsCanvas. This is the only code inside 37 the DOM element that relies on the renderer type. 38 39 * html/HTMLParser.h: Removed unneeded includes. Marked HTMLParser as 40 Noncopyable. Changed the Document parameter to the constructor to instead 41 of HTMLDocument. Renamed discard_until to m_skipModeTag for clarity. 42 Removed unused noSpaces function and unneeded public doc() function. 43 Moved data members all down to the end so you can see them together in order. 44 Renamed map to m_currentMapElement and isindex to m_isindexElement. 45 Removed unused end and headLoaded data members. Renamed m_fragment to 46 m_isParsingFragment to make it clearer that it's a boolean, not a fragment. 47 48 * html/HTMLParser.cpp: 49 (WebCore::HTMLParser::HTMLParser): Changed to use member construction 50 syntax instead of calling reset(). This is especially helpful in the 51 fragment case, where calling reset() later on is illegal, so not using 52 it in the constructor lets us assert. 53 (WebCore::HTMLParser::~HTMLParser): Did an explicit deref instead of 54 calling setCurrent for its side effect. 55 (WebCore::HTMLParser::reset): Updated for member name changes and removal 56 and to use document instead of doc(). 57 (WebCore::HTMLParser::setCurrent): Use document instead of doc(). 58 (WebCore::HTMLParser::setSkipMode): Added. No longer inline. Now sets the 59 m_inCanvasBeforeFirstOpenTag data member to false. 60 (WebCore::HTMLParser::parseToken): Tightened up the skip mode logic at the 61 top of the function, and added a FIXME about the strange case there where 62 we don't skip yet stay in skip mode. Updated for renaming and doc(). 63 (WebCore::HTMLParser::insertNode): Updated for renaming and doc(). 64 (WebCore::HTMLParser::handleError): Ditto. 65 (WebCore::HTMLParser::framesetCreateErrorCheck): Ditto. 66 (WebCore::HTMLParser::isindexCreateErrorCheck): Changed to use RefPtr. 67 (WebCore::HTMLParser::noscriptCreateErrorCheck): Updated for renaming and doc(). 68 (WebCore::HTMLParser::mapCreateErrorCheck): Ditto. 69 (WebCore::HTMLParser::getNode): Removed the special case for canvas here. 70 Canvas fallback is now handled in the DOM, not the parser. Updated for 71 renaming and doc(). 72 (WebCore::HTMLParser::allowNestedRedundantTag): Changed a #define into a C++ 73 constant. 74 (WebCore::HTMLParser::processCloseTag): Updated for renaming and doc(). 75 (WebCore::HTMLParser::isInline): Ditto. 76 (WebCore::HTMLParser::tagIsOnStack): Added. Used by new canvas logic. 77 (WebCore::HTMLParser::popBlock): Updated for renaming and doc(). Also renamed 78 the local variable Elem to elem. 79 (WebCore::HTMLParser::createHead): Ditto. 80 (WebCore::HTMLParser::handleIsindex): Changed to use RefPtr. 81 (WebCore::HTMLParser::startBody): Updated for renaming and doc(). 82 (WebCore::HTMLParser::finished): Ditto. 83 1 84 2007-03-13 David Hyatt <hyatt@apple.com> 2 85 -
trunk/WebCore/html/HTMLCanvasElement.cpp
r19876 r20170 1 1 /* 2 * Copyright (C) 2004, 2006 Apple Computer, Inc.All rights reserved.2 * Copyright (C) 2004, 2006, 2007 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 31 31 #include "CanvasRenderingContext2D.h" 32 32 #include "CanvasStyle.h" 33 #include "Chrome.h" 33 34 #include "Document.h" 34 35 #include "Frame.h" … … 37 38 #include "Page.h" 38 39 #include "RenderHTMLCanvas.h" 39 #include "Chrome.h"40 40 #include "Settings.h" 41 #include "Screen.h"42 41 #include <math.h> 43 42 … … 96 95 } 97 96 98 RenderObject* HTMLCanvasElement::createRenderer(RenderArena *arena, RenderStyle *style) 99 { 100 RenderHTMLCanvas* r = new (arena) RenderHTMLCanvas(this); 101 r->setIntrinsicWidth(width()); 102 r->setIntrinsicHeight(height()); 103 return r; 97 RenderObject* HTMLCanvasElement::createRenderer(RenderArena* arena, RenderStyle* style) 98 { 99 if (document()->frame() && document()->frame()->settings()->isJavaScriptEnabled()) { 100 m_rendererIsCanvas = true; 101 RenderHTMLCanvas* r = new (arena) RenderHTMLCanvas(this); 102 r->setIntrinsicWidth(width()); 103 r->setIntrinsicHeight(height()); 104 return r; 105 } 106 107 m_rendererIsCanvas = false; 108 return HTMLElement::createRenderer(arena, style); 104 109 } 105 110 … … 145 150 m_size = IntSize(w, h); 146 151 147 RenderHTMLCanvas* r = static_cast<RenderHTMLCanvas*>(renderer()); 148 if (r) { 149 r->setIntrinsicWidth(w); 150 r->setIntrinsicHeight(h); 151 r->repaint(); 152 } 152 if (RenderObject* ro = renderer()) 153 if (m_rendererIsCanvas) { 154 RenderHTMLCanvas* r = static_cast<RenderHTMLCanvas*>(ro); 155 r->setIntrinsicWidth(w); 156 r->setIntrinsicHeight(h); 157 r->repaint(); 158 } 153 159 154 160 m_createdDrawingContext = false; -
trunk/WebCore/html/HTMLCanvasElement.h
r18874 r20170 77 77 void reset(); 78 78 79 bool m_rendererIsCanvas; 80 79 81 RefPtr<CanvasRenderingContext2D> m_2DContext; 80 82 IntSize m_size; -
trunk/WebCore/html/HTMLParser.cpp
r20127 r20170 1 1 /* 2 This file is part of the KDE libraries3 4 2 Copyright (C) 1997 Martin Jones (mjones@kde.org) 5 3 (C) 1997 Torben Weis (weis@kde.org) 6 4 (C) 1999,2001 Lars Knoll (knoll@kde.org) 7 5 (C) 2000,2001 Dirk Mueller (mueller@kde.org) 8 Copyright (C) 2004, 2005, 2006 Apple Computer, Inc.6 Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved. 9 7 10 8 This library is free software; you can redistribute it and/or … … 34 32 #include "Frame.h" 35 33 #include "HTMLBodyElement.h" 36 #include "HTML CanvasElement.h"34 #include "HTMLDocument.h" 37 35 #include "HTMLDivElement.h" 38 36 #include "HTMLDListElement.h" … … 57 55 using namespace HTMLNames; 58 56 59 /** 60 * @internal 61 */ 62 63 class HTMLStackElem 64 { 65 public: 57 const int maxRedundantTagDepth = 20; 58 59 struct HTMLStackElem : Noncopyable { 66 60 HTMLStackElem(const AtomicString& t, int lvl, Node* n, bool r, HTMLStackElem* nx) 67 61 : tagName(t) … … 89 83 90 84 /** 91 * @internal 85 * The parser parses tokenized input into the document, building up the 86 * document tree. If the document is well-formed, parsing it is straightforward. 92 87 * 93 * The parser parses tokenized input into the document, building up the 94 * document tree. If the document is wellformed, parsing it is 95 * straightforward. 96 * Unfortunately, people can't write wellformed HTML documents, so the parser 97 * has to be tolerant about errors. 88 * Unfortunately, we have to handle many HTML documents that are not well-formed, 89 * so the parser has to be tolerant about errors. 98 90 * 99 * We have to take care of the following error conditions: 91 * We have to take care of at least the following error conditions: 92 * 100 93 * 1. The element being added is explicitly forbidden inside some outer tag. 101 94 * In this case we should close all tags up to the one, which forbids 102 95 * the element, and add it afterwards. 103 * 2. We are not allowed to add the element directly. It could be, that 104 * the person writing the document forgot some tag inbetween (or that the 105 * tag inbetween is optional...) This could be the case with the following 106 * tags: HTML HEAD BODY TBODY TR TD LI (did I forget any?) 107 * 3. We wan't to add a block element inside to an inline element. Close all 96 * 97 * 2. We are not allowed to add the element directly. It could be that 98 * the person writing the document forgot some tag in between (or that the 99 * tag in between is optional). This could be the case with the following 100 * tags: HTML HEAD BODY TBODY TR TD LI (did I forget any?). 101 * 102 * 3. We want to add a block element inside to an inline element. Close all 108 103 * inline elements up to the next higher block element. 109 * 4. If this doesn't help close elements, until we are allowed to add the 104 * 105 * 4. If this doesn't help, close elements until we are allowed to add the 110 106 * element or ignore the tag. 111 107 * 112 108 */ 113 HTMLParser::HTMLParser(Document* doc) 109 110 HTMLParser::HTMLParser(HTMLDocument* doc) 114 111 : document(doc) 115 , current( 0)112 , current(doc) 116 113 , didRefCurrent(false) 117 114 , blockStack(0) 118 , m_fragment(false) 119 { 120 reset(); 115 , form(0) 116 , m_currentMapElement(0) 117 , head(0) 118 , inBody(false) 119 , haveContent(false) 120 , haveFrameSet(false) 121 , m_isParsingFragment(false) 122 , inStrayTableContent(0) 123 { 121 124 } 122 125 123 126 HTMLParser::HTMLParser(DocumentFragment* frag) 124 127 : document(frag->document()) 125 , current( 0)126 , didRefCurrent( false)128 , current(frag) 129 , didRefCurrent(true) 127 130 , blockStack(0) 128 , m_fragment(true) 129 { 130 reset(); 131 setCurrent(frag); 132 inBody = true; 131 , form(0) 132 , m_currentMapElement(0) 133 , head(0) 134 , inBody(true) 135 , haveContent(false) 136 , haveFrameSet(false) 137 , m_isParsingFragment(true) 138 , inStrayTableContent(0) 139 { 140 if (frag) 141 frag->ref(); 133 142 } 134 143 … … 136 145 { 137 146 freeBlock(); 138 139 setCurrent(0);147 if (didRefCurrent) 148 current->deref(); 140 149 } 141 150 142 151 void HTMLParser::reset() 143 152 { 144 setCurrent(doc()); 153 ASSERT(!m_isParsingFragment); 154 155 setCurrent(document); 145 156 146 157 freeBlock(); … … 150 161 haveContent = false; 151 162 inStrayTableContent = 0; 152 163 153 164 form = 0; 154 m ap= 0;165 m_currentMapElement = 0; 155 166 head = 0; 156 end = false; 157 isindex = 0; 158 159 discard_until = nullAtom; 167 m_isindexElement = 0; 168 169 m_skipModeTag = nullAtom; 160 170 } 161 171 162 172 void HTMLParser::setCurrent(Node* newCurrent) 163 173 { 164 bool didRefNewCurrent = newCurrent && newCurrent != doc ();174 bool didRefNewCurrent = newCurrent && newCurrent != document; 165 175 if (didRefNewCurrent) 166 176 newCurrent->ref(); … … 171 181 } 172 182 173 PassRefPtr<Node> HTMLParser::parseToken(Token *t) 174 { 175 if (!discard_until.isNull()) { 176 if (t->tagName == discard_until && !t->beginTag) 177 discard_until = nullAtom; 178 179 // do not skip </iframe> 180 if (!discard_until.isNull() || (current->localName() != t->tagName)) 183 PassRefPtr<Node> HTMLParser::parseToken(Token* t) 184 { 185 if (!m_skipModeTag.isNull()) { 186 if (!t->beginTag && t->tagName == m_skipModeTag) 187 // Found the end tag for the current skip mode, so we're done skipping. 188 m_skipModeTag = nullAtom; 189 else if (current->localName() == t->tagName) 190 // Do not skip </iframe>. 191 // FIXME: What does that comment mean? How can it be right to parse a token without clearing m_skipModeTag? 192 ; 193 else 181 194 return 0; 182 195 } 183 196 184 // Apparently some sites use </br> instead of <br>. 185 if (t->isCloseTag(brTag) && doc ()->inCompatMode())197 // Apparently some sites use </br> instead of <br>. Be compatible with IE and Firefox and treat this like <br>. 198 if (t->isCloseTag(brTag) && document->inCompatMode()) 186 199 t->beginTag = true; 187 200 … … 236 249 } 237 250 238 if (m ap== n)239 m ap= 0;251 if (m_currentMapElement == n) 252 m_currentMapElement = 0; 240 253 241 254 if (form == n) … … 266 279 } 267 280 268 bool HTMLParser::insertNode(Node *n, bool flat)281 bool HTMLParser::insertNode(Node* n, bool flat) 269 282 { 270 283 RefPtr<Node> protectNode(n); … … 295 308 didRefCurrent = true; 296 309 } 297 if (parentAttached && !n->attached() && !m_ fragment)310 if (parentAttached && !n->attached() && !m_isParsingFragment) 298 311 n->attach(); 299 312 } else { 300 if (parentAttached && !n->attached() && !m_ fragment)313 if (parentAttached && !n->attached() && !m_isParsingFragment) 301 314 n->attach(); 302 315 n->closeRenderer(); … … 309 322 { 310 323 // Error handling code. This is just ad hoc handling of specific parent/child combinations. 311 HTMLElement *e;324 HTMLElement* e; 312 325 bool handled = false; 313 326 … … 333 346 if (head) { 334 347 if (head->addChild(n)) { 335 if (!n->attached() && !m_ fragment)348 if (!n->attached() && !m_isParsingFragment) 336 349 n->attach(); 337 350 return true; … … 341 354 } else if (h->hasLocalName(htmlTag)) { 342 355 if (!current->isDocumentNode() ) { 343 if (doc ()->firstChild()->hasTagName(htmlTag)) {356 if (document->firstChild()->hasTagName(htmlTag)) { 344 357 // we have another <HTML> element.... apply attributes to existing one 345 358 // make sure we don't overwrite already existing attributes 346 NamedAttrMap *map = static_cast<Element*>(n)->attributes(true);347 Element *existingHTML = static_cast<Element*>(doc()->firstChild());348 NamedAttrMap *bmap = existingHTML->attributes(false);359 NamedAttrMap* map = static_cast<Element*>(n)->attributes(true); 360 Element* existingHTML = static_cast<Element*>(document->firstChild()); 361 NamedAttrMap* bmap = existingHTML->attributes(false); 349 362 for (unsigned l = 0; map && l < map->length(); ++l) { 350 363 Attribute* it = map->attributeItem(l); … … 366 379 pushBlock(localName, tagPriority); 367 380 setCurrent(newNode); 368 if (!n->attached() && !m_ fragment)381 if (!n->attached() && !m_isParsingFragment) 369 382 n->attach(); 370 383 return true; … … 375 388 } 376 389 } else if (h->hasLocalName(bodyTag)) { 377 if (inBody && doc ()->body()) {390 if (inBody && document->body()) { 378 391 // we have another <BODY> element.... apply attributes to existing one 379 392 // make sure we don't overwrite already existing attributes 380 393 // some sites use <body bgcolor=rightcolor>...<body bgcolor=wrongcolor> 381 NamedAttrMap *map = static_cast<Element*>(n)->attributes(true);382 Element *existingBody = doc()->body();383 NamedAttrMap *bmap = existingBody->attributes(false);394 NamedAttrMap* map = static_cast<Element*>(n)->attributes(true); 395 Element* existingBody = document->body(); 396 NamedAttrMap* bmap = existingBody->attributes(false); 384 397 for (unsigned l = 0; map && l < map->length(); ++l) { 385 398 Attribute* it = map->attributeItem(l); … … 394 407 if (equalIgnoringCase(h->getAttribute(typeAttr), "hidden") && form) { 395 408 form->addChild(n); 396 if (!n->attached() && !m_ fragment)409 if (!n->attached() && !m_isParsingFragment) 397 410 n->attach(); 398 411 return true; … … 405 418 } 406 419 } else if (h->hasLocalName(areaTag)) { 407 if (m ap) {408 m ap->addChild(n);409 if (!n->attached() && !m_ fragment)420 if (m_currentMapElement) { 421 m_currentMapElement->addChild(n); 422 if (!n->attached() && !m_isParsingFragment) 410 423 n->attach(); 411 424 handled = true; … … 443 456 if (head) { 444 457 head->addChild(n); 445 if (!n->attached() && !m_ fragment)458 if (!n->attached() && !m_isParsingFragment) 446 459 n->attach(); 447 460 } … … 468 481 } else { 469 482 if (n->isTextNode()) { 470 Text *t = static_cast<Text*>(n);483 Text* t = static_cast<Text*>(n); 471 484 if (t->containsOnlyWhitespace()) 472 485 return false; … … 509 522 ExceptionCode ec = 0; 510 523 if (n->isTextNode()) { 511 Text *t = static_cast<Text*>(n);524 Text* t = static_cast<Text*>(n); 512 525 if (t->containsOnlyWhitespace()) 513 526 return false; 514 StringImpl *i = t->string();527 StringImpl* i = t->string(); 515 528 unsigned int pos = 0; 516 529 while (pos < i->length() && ((*i)[pos] == ' ' || (*i)[pos] == noBreakSpace)) … … 520 533 } 521 534 if (possiblyMoveStrayContent) { 522 Node *node = current;523 Node *parent = node->parentNode();535 Node* node = current; 536 Node* parent = node->parentNode(); 524 537 // A script may have removed the current node's parent from the DOM 525 538 // http://bugs.webkit.org/show_bug.cgi?id=7137 … … 527 540 if (!parent) 528 541 return false; 529 Node *grandparent = parent->parentNode();542 Node* grandparent = parent->parentNode(); 530 543 531 544 if (n->isTextNode() || … … 537 550 node = (node->hasTagName(tableTag)) ? node : 538 551 ((node->hasTagName(trTag)) ? grandparent : parent); 539 Node *parent = node->parentNode();552 Node* parent = node->parentNode(); 540 553 if (!parent) 541 554 return false; … … 659 672 // regressions and the headaches are not worth the work as long as there is 660 673 // no site actually relying on that detail (Dirk) 661 if (doc ()->body())662 doc ()->body()->setAttribute(styleAttr, "display:none");674 if (document->body()) 675 document->body()->setAttribute(styleAttr, "display:none"); 663 676 inBody = false; 664 677 } … … 690 703 bool HTMLParser::isindexCreateErrorCheck(Token* t, RefPtr<Node>& result) 691 704 { 692 Node *n = handleIsindex(t);705 RefPtr<Node> n = handleIsindex(t); 693 706 if (!inBody) { 694 isindex = n;707 m_isindexElement = n.release(); 695 708 } else { 696 709 t->flat = true; 697 result = n ;710 result = n.release(); 698 711 } 699 712 return false; … … 759 772 bool HTMLParser::noscriptCreateErrorCheck(Token* t, RefPtr<Node>& result) 760 773 { 761 if (!m_ fragment && document->frame() && document->frame()->settings()->isJavaScriptEnabled())774 if (!m_isParsingFragment && document->frame() && document->frame()->settings()->isJavaScriptEnabled()) 762 775 setSkipMode(noscriptTag); 763 776 return true; … … 766 779 bool HTMLParser::mapCreateErrorCheck(Token* t, RefPtr<Node>& result) 767 780 { 768 m ap= new HTMLMapElement(document);769 result = m ap;781 m_currentMapElement = new HTMLMapElement(document); 782 result = m_currentMapElement; 770 783 return false; 771 }772 773 bool HTMLParser::canvasCreateErrorCheck(Token* t, RefPtr<Node>& result)774 {775 if (document->frame() && document->frame()->settings()->usesDashboardBackwardCompatibilityMode())776 return true;777 778 if (!m_fragment && document->frame() && document->frame()->settings()->isJavaScriptEnabled())779 setSkipMode(canvasTag);780 return true;781 784 } 782 785 … … 791 794 gFunctionMap.set(bodyTag.localName().impl(), &HTMLParser::bodyCreateErrorCheck); 792 795 gFunctionMap.set(buttonTag.localName().impl(), &HTMLParser::nestedCreateErrorCheck); 793 gFunctionMap.set(canvasTag.localName().impl(), &HTMLParser::canvasCreateErrorCheck);794 796 gFunctionMap.set(commentAtom.impl(), &HTMLParser::commentCreateErrorCheck); 795 797 gFunctionMap.set(ddTag.localName().impl(), &HTMLParser::ddCreateErrorCheck); … … 828 830 proceed = (this->*errorCheckFunc)(t, result); 829 831 if (proceed) 830 result = HTMLElementFactory::createHTMLElement(t->tagName, doc (), form);832 result = HTMLElementFactory::createHTMLElement(t->tagName, document, form); 831 833 return result.release(); 832 834 } 833 835 834 #define MAX_REDUNDANT 20 835 836 bool HTMLParser::allowNestedRedundantTag(const AtomicString& _tagName) 836 bool HTMLParser::allowNestedRedundantTag(const AtomicString& tagName) 837 837 { 838 838 // www.liceo.edu.mx is an example of a site that achieves a level of nesting of … … 841 841 int i = 0; 842 842 for (HTMLStackElem* curr = blockStack; 843 i < MAX_REDUNDANT && curr && curr->tagName == _tagName;843 i < maxRedundantTagDepth && curr && curr->tagName == tagName; 844 844 curr = curr->next, i++); 845 return i != MAX_REDUNDANT;846 } 847 848 void HTMLParser::processCloseTag(Token *t)845 return i != maxRedundantTagDepth; 846 } 847 848 void HTMLParser::processCloseTag(Token* t) 849 849 { 850 850 // Support for really broken html. … … 857 857 form = 0; 858 858 else if (t->tagName == mapTag) 859 m ap= 0;859 m_currentMapElement = 0; 860 860 861 861 HTMLStackElem* oldElem = blockStack; … … 917 917 e->hasLocalName(supTag) || e->hasLocalName(spanTag) || e->hasLocalName(nobrTag) || 918 918 e->hasLocalName(wbrTag) || e->hasLocalName(noframesTag) || e->hasLocalName(nolayerTag) || 919 e->hasLocalName(noembedTag) || (e->hasLocalName(noscriptTag) && !m_ fragment && document->frame() && document->frame()->settings()->isJavaScriptEnabled()))919 e->hasLocalName(noembedTag) || (e->hasLocalName(noscriptTag) && !m_isParsingFragment && document->frame() && document->frame()->settings()->isJavaScriptEnabled())) 920 920 return true; 921 921 } … … 1208 1208 } 1209 1209 1210 void HTMLParser::popBlock(const AtomicString& _tagName)1211 { 1212 HTMLStackElem *Elem = blockStack;1210 void HTMLParser::popBlock(const AtomicString& tagName) 1211 { 1212 HTMLStackElem* elem = blockStack; 1213 1213 1214 1214 int maxLevel = 0; 1215 1215 1216 while ( Elem && (Elem->tagName != _tagName)) {1217 if (maxLevel < Elem->level)1218 maxLevel = Elem->level;1219 Elem = Elem->next;1220 } 1221 1222 if (! Elem)1216 while (elem && (elem->tagName != tagName)) { 1217 if (maxLevel < elem->level) 1218 maxLevel = elem->level; 1219 elem = elem->next; 1220 } 1221 1222 if (!elem) 1223 1223 return; 1224 1224 1225 if (maxLevel > Elem->level) {1225 if (maxLevel > elem->level) { 1226 1226 // We didn't match because the tag is in a different scope, e.g., 1227 1227 // <b><p>Foo</b>. Try to correct the problem. 1228 if (!isResidualStyleTag( _tagName))1228 if (!isResidualStyleTag(tagName)) 1229 1229 return; 1230 return handleResidualStyleCloseTagAcrossBlocks( Elem);1231 } 1232 1233 bool isAffectedByStyle = isAffectedByResidualStyle( Elem->tagName);1230 return handleResidualStyleCloseTagAcrossBlocks(elem); 1231 } 1232 1233 bool isAffectedByStyle = isAffectedByResidualStyle(elem->tagName); 1234 1234 HTMLStackElem* residualStyleStack = 0; 1235 1235 Node* malformedTableParent = 0; 1236 1236 1237 Elem = blockStack;1238 while ( Elem) {1239 if ( Elem->tagName == _tagName) {1237 elem = blockStack; 1238 while (elem) { 1239 if (elem->tagName == tagName) { 1240 1240 int strayTable = inStrayTableContent; 1241 1241 popOneBlock(); 1242 Elem = 0;1242 elem = 0; 1243 1243 1244 1244 // This element was the root of some malformed content just inside an implicit or … … 1254 1254 } 1255 1255 else { 1256 if (form && Elem->tagName == formTag)1256 if (form && elem->tagName == formTag) 1257 1257 // A <form> is being closed prematurely (and this is 1258 1258 // malformed HTML). Set an attribute on the form to clear out its … … 1262 1262 // Schedule this tag for reopening 1263 1263 // after we complete the close of this entire block. 1264 if (isAffectedByStyle && isResidualStyleTag( Elem->tagName))1264 if (isAffectedByStyle && isResidualStyleTag(elem->tagName)) 1265 1265 // We've overloaded the use of stack elements and are just reusing the 1266 1266 // struct with a slightly different meaning to the variables. Instead of chaining … … 1268 1268 // from the outermost to the innermost, i.e., residualStyleStack will end up pointing 1269 1269 // to the outermost tag we need to reopen. 1270 // We also set Elem->node to be the actual element that corresponds to the ID stored in1271 // Elem->id rather than the node that you should pop to when the element gets pulled off1270 // We also set elem->node to be the actual element that corresponds to the ID stored in 1271 // elem->id rather than the node that you should pop to when the element gets pulled off 1272 1272 // the stack. 1273 1273 moveOneBlockToStack(residualStyleStack); 1274 1274 else 1275 1275 popOneBlock(); 1276 Elem = blockStack;1276 elem = blockStack; 1277 1277 } 1278 1278 } … … 1348 1348 void HTMLParser::createHead() 1349 1349 { 1350 if (head || !doc ()->firstChild())1350 if (head || !document->firstChild()) 1351 1351 return; 1352 1352 1353 1353 head = new HTMLHeadElement(document); 1354 HTMLElement* body = doc ()->body();1354 HTMLElement* body = document->body(); 1355 1355 ExceptionCode ec = 0; 1356 doc ()->firstChild()->insertBefore(head, body, ec);1356 document->firstChild()->insertBefore(head, body, ec); 1357 1357 if (ec) 1358 1358 head = 0; 1359 1359 } 1360 1360 1361 Node*HTMLParser::handleIsindex(Token* t)1362 { 1363 Node*n = new HTMLDivElement(document);1361 PassRefPtr<Node> HTMLParser::handleIsindex(Token* t) 1362 { 1363 RefPtr<Node> n = new HTMLDivElement(document); 1364 1364 1365 1365 NamedMappedAttrMap* attrs = t->attrs.get(); … … 1371 1371 String text = searchableIndexIntroduction(); 1372 1372 if (attrs) { 1373 if (Attribute *a = attrs->getAttributeItem(promptAttr))1373 if (Attribute* a = attrs->getAttributeItem(promptAttr)) 1374 1374 text = a->value().domString() + " "; 1375 1375 t->attrs = 0; … … 1378 1378 n->addChild(new HTMLHRElement(document)); 1379 1379 n->addChild(new Text(document, text)); 1380 n->addChild(isIndex. get());1380 n->addChild(isIndex.release()); 1381 1381 n->addChild(new HTMLHRElement(document)); 1382 1382 1383 return n ;1383 return n.release(); 1384 1384 } 1385 1385 1386 1386 void HTMLParser::startBody() 1387 1387 { 1388 if(inBody) return; 1388 if (inBody) 1389 return; 1389 1390 1390 1391 inBody = true; 1391 1392 1392 if ( isindex) {1393 insertNode( isindex.get(), true /* don't decend into this node */);1394 isindex= 0;1393 if (m_isindexElement) { 1394 insertNode(m_isindexElement.get(), true /* don't descend into this node */); 1395 m_isindexElement = 0; 1395 1396 } 1396 1397 } … … 1407 1408 1408 1409 // Warning, this may delete the tokenizer and parser, so don't try to do anything else after this. 1409 if (!m_ fragment)1410 if (!m_isParsingFragment) 1410 1411 document->finishedParsing(); 1411 1412 } -
trunk/WebCore/html/HTMLParser.h
r18874 r20170 1 1 /* 2 This file is part of the KDE libraries3 4 2 Copyright (C) 1997 Martin Jones (mjones@kde.org) 5 3 (C) 1997 Torben Weis (weis@kde.org) 6 4 (C) 1998 Waldo Bastian (bastian@kde.org) 7 5 (C) 1999 Lars Knoll (knoll@kde.org) 8 Copyright (C) 2004, 2005, 2006 Apple Computer, Inc.6 Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved. 9 7 10 8 This library is free software; you can redistribute it and/or … … 23 21 Boston, MA 02111-1307, USA. 24 22 */ 25 //----------------------------------------------------------------------------26 //27 // KDE HTML Widget -- HTML Parser28 23 29 24 #ifndef HTMLParser_h 30 25 #define HTMLParser_h 31 26 32 #include "HTMLDocument.h" 27 #include "QualifiedName.h" 28 #include <wtf/Forward.h> 29 #include <wtf/RefPtr.h> 33 30 34 31 namespace WebCore { 35 32 33 class Document; 36 34 class DocumentFragment; 37 class FrameView; 38 class HTMLElement; 35 class HTMLDocument; 39 36 class HTMLFormElement; 40 37 class HTMLHeadElement; 41 38 class HTMLMapElement; 42 class HTMLStackElem;39 class Node; 43 40 class Token; 44 41 42 struct HTMLStackElem; 43 45 44 /** 46 * The parser for html. It receives a stream of tokens from the HTMLTokenizer, and47 * builds up the Document structure f orm it.45 * The parser for HTML. It receives a stream of tokens from the HTMLTokenizer, and 46 * builds up the Document structure from it. 48 47 */ 49 class HTMLParser 50 { 48 class HTMLParser : Noncopyable { 51 49 public: 52 HTMLParser( Document*);50 HTMLParser(HTMLDocument*); 53 51 HTMLParser(DocumentFragment*); 54 52 virtual ~HTMLParser(); … … 69 67 void reset(); 70 68 71 bool skipMode() const { return !discard_until.isNull(); } 72 bool noSpaces() const { return !inBody; } 73 74 HTMLDocument *doc() const { return static_cast<HTMLDocument *>(document); } 69 bool skipMode() const { return !m_skipModeTag.isNull(); } 75 70 76 71 private: 77 void setCurrent(Node* newCurrent);72 void setCurrent(Node*); 78 73 void derefCurrent(); 79 void setSkipMode(const QualifiedName& qName) { discard_until = qName.localName(); } 80 81 Document* document; 74 void setSkipMode(const QualifiedName& qName) { m_skipModeTag = qName.localName(); } 82 75 83 76 PassRefPtr<Node> getNode(Token*); … … 104 97 bool textCreateErrorCheck(Token*, RefPtr<Node>&); 105 98 106 void processCloseTag(Token 99 void processCloseTag(Token*); 107 100 108 bool insertNode(Node *n, bool flat = false);109 bool handleError(Node* n, bool flat, const AtomicString& localName, int tagPriority);101 bool insertNode(Node*, bool flat = false); 102 bool handleError(Node*, bool flat, const AtomicString& localName, int tagPriority); 110 103 111 // The currently active element (the one new elements will be added to). Can be a document fragment, a document or an element. 112 Node* current; 113 // We can't ref a document, but we don't want to constantly check if a node is a document just to decide whether to deref. 114 bool didRefCurrent; 115 116 HTMLStackElem *blockStack; 117 118 void pushBlock(const AtomicString& tagName, int _level); 104 void pushBlock(const AtomicString& tagName, int level); 119 105 void popBlock(const AtomicString& tagName); 120 106 void popBlock(const QualifiedName& qName) { return popBlock(qName.localName()); } // Convenience function for readability. … … 128 114 void createHead(); 129 115 130 bool isResidualStyleTag(const AtomicString& tagName);131 bool isAffectedByResidualStyle(const AtomicString& tagName);116 static bool isResidualStyleTag(const AtomicString& tagName); 117 static bool isAffectedByResidualStyle(const AtomicString& tagName); 132 118 void handleResidualStyleCloseTagAcrossBlocks(HTMLStackElem*); 133 119 void reopenResidualStyleTags(HTMLStackElem*, Node* malformedTableParent); … … 138 124 void popNestedHeaderTag(); 139 125 140 bool isInline(Node* node) const;126 bool isInline(Node*) const; 141 127 142 /* 143 * currently active form 144 */ 145 HTMLFormElement *form; 128 void startBody(); // inserts the isindex element 129 PassRefPtr<Node> handleIsindex(Token*); 146 130 147 /* 148 * current map 149 */ 150 HTMLMapElement *map; 131 Document* document; 151 132 152 / *153 * the head element. Needed for crappy html which defines <base> after </head>154 */155 HTMLHeadElement *head;133 // The currently active element (the one new elements will be added to). Can be a document fragment, a document or an element. 134 Node* current; 135 // We can't ref a document, but we don't want to constantly check if a node is a document just to decide whether to deref. 136 bool didRefCurrent; 156 137 157 /* 158 * a possible <isindex> element in the head. Compatibility hack for 159 * html from the stone age 160 */ 161 RefPtr<Node> isindex; 162 Node* handleIsindex(Token*); 138 HTMLStackElem* blockStack; 163 139 164 /*165 * inserts the stupid isIndex element.166 */167 void startBody();140 HTMLFormElement* form; // currently active form 141 HTMLMapElement* m_currentMapElement; // current map 142 HTMLHeadElement* head; // head element; needed for HTML which defines <base> after </head> 143 RefPtr<Node> m_isindexElement; // a possible <isindex> element in the head 168 144 169 145 bool inBody; 170 146 bool haveContent; 171 147 bool haveFrameSet; 172 bool end;173 148 174 /* 175 * tells the parser to discard all tags, until it reaches the one specified 176 */ 177 AtomicString discard_until; 149 AtomicString m_skipModeTag; // tells the parser to discard all tags until it reaches the one specified 178 150 179 bool headLoaded; 180 bool m_fragment; 151 bool m_isParsingFragment; 181 152 int inStrayTableContent; 182 153 };
Note: See TracChangeset
for help on using the changeset viewer.