Commit 3fd60e18 authored by darin's avatar darin
Browse files

LayoutTests:

        Reviewed by Maciej.

        - tests for http://bugs.webkit.org/show_bug.cgi?id=12794
          <rdar://problem/5028154> REGRESSION: TripTik planner at aaa.com never
          finishes loading due to unclosed canvas tag (12794)

        * fast/canvas/canvas-hides-fallback-expected.txt: Added.
        * fast/canvas/canvas-hides-fallback.html: Added.
        * fast/canvas/script-inside-canvas-fallback-expected.txt: Added.
        * fast/canvas/script-inside-canvas-fallback.html: Added.
        * fast/canvas/unclosed-canvas-1-expected.txt: Added.
        * fast/canvas/unclosed-canvas-1.html: Added.
        * fast/canvas/unclosed-canvas-2-expected.txt: Added.
        * fast/canvas/unclosed-canvas-2.html: Added.
        * fast/canvas/unclosed-canvas-3-expected.txt: Added.
        * fast/canvas/unclosed-canvas-3.html: Added.
        * fast/canvas/unclosed-canvas-4-expected.txt: Added.
        * fast/canvas/unclosed-canvas-4.html: Added.

WebCore:

        Reviewed by Maciej.

        - fix http://bugs.webkit.org/show_bug.cgi?id=12794
          <rdar://problem/5028154> REGRESSION: TripTik planner at aaa.com never
          finishes loading due to unclosed canvas tag (12794)

        Change <canvas> elements so that their contents are parsed normally,
        but not rendered. This change fixes the bug, because normal parsing
        rules close the <canvas> element in that case. The special parser
        stuff was just getting in the way.

        Also do some basic cleanup to the HTML parser. This was motivated by
        an earlier version of this patch that made even more changes to the
        parser, but the cleanup is still worth landing.

        Test: fast/canvas/canvas-hides-fallback.html
        Test: fast/canvas/script-inside-canvas-fallback.html
        Test: fast/canvas/unclosed-canvas-1.html
        Test: fast/canvas/unclosed-canvas-2.html
        Test: fast/canvas/unclosed-canvas-3.html
        Test: fast/canvas/unclosed-canvas-4.html

        * html/HTMLCanvasElement.h: Added a data member to keep track of whether the
        renderer is a RenderHTMLCanvas or not.
        * html/HTMLCanvasElement.cpp:
        (WebCore::HTMLCanvasElement::createRenderer): If JavaScript is enabled, create
        a RenderHTMLCanvas. If it's not, let the default code create the default type
        of renderer, which will result in fallback content being visible. The
        RenderHTMLCanvas class already hides all of its children. Set the m_rendererIsCanvas
        boolean accordingly. Since the actual storage for the canvas is allocated lazily
        when you actually get a drawing context, we don't need to do anything special
        to prevent it when JavaScript is disabled; the relevant functions won't be called.
        (WebCore::HTMLCanvasElement::reset): Protect the code that manipulates the
        RenderHTMLCanvas with a check of m_rendererIsCanvas. This is the only code inside
        the DOM element that relies on the renderer type.

        * html/HTMLParser.h: Removed unneeded includes. Marked HTMLParser as
        Noncopyable. Changed the Document parameter to the constructor to instead
        of HTMLDocument. Renamed discard_until to m_skipModeTag for clarity.
        Removed unused noSpaces function and unneeded public doc() function.
        Moved data members all down to the end so you can see them together in order.
        Renamed map to m_currentMapElement and isindex to m_isindexElement.
        Removed unused end and headLoaded data members.  Renamed m_fragment to
        m_isParsingFragment to make it clearer that it's a boolean, not a fragment.

        * html/HTMLParser.cpp:
        (WebCore::HTMLParser::HTMLParser): Changed to use member construction
        syntax instead of calling reset(). This is especially helpful in the
        fragment case, where calling reset() later on is illegal, so not using
        it in the constructor lets us assert.
        (WebCore::HTMLParser::~HTMLParser): Did an explicit deref instead of
        calling setCurrent for its side effect.
        (WebCore::HTMLParser::reset): Updated for member name changes and removal
        and to use document instead of doc().
        (WebCore::HTMLParser::setCurrent): Use document instead of doc().
        (WebCore::HTMLParser::setSkipMode): Added. No longer inline. Now sets the
        m_inCanvasBeforeFirstOpenTag data member to false.
        (WebCore::HTMLParser::parseToken): Tightened up the skip mode logic at the
        top of the function, and added a FIXME about the strange case there where
        we don't skip yet stay in skip mode. Updated for renaming and doc().
        (WebCore::HTMLParser::insertNode): Updated for renaming and doc().
        (WebCore::HTMLParser::handleError): Ditto.
        (WebCore::HTMLParser::framesetCreateErrorCheck): Ditto.
        (WebCore::HTMLParser::isindexCreateErrorCheck): Changed to use RefPtr.
        (WebCore::HTMLParser::noscriptCreateErrorCheck): Updated for renaming and doc().
        (WebCore::HTMLParser::mapCreateErrorCheck): Ditto.
        (WebCore::HTMLParser::getNode): Removed the special case for canvas here.
        Canvas fallback is now handled in the DOM, not the parser. Updated for
        renaming and doc().
        (WebCore::HTMLParser::allowNestedRedundantTag): Changed a #define into a C++
        constant.
        (WebCore::HTMLParser::processCloseTag): Updated for renaming and doc().
        (WebCore::HTMLParser::isInline): Ditto.
        (WebCore::HTMLParser::tagIsOnStack): Added. Used by new canvas logic.
        (WebCore::HTMLParser::popBlock): Updated for renaming and doc(). Also renamed
        the local variable Elem to elem.
        (WebCore::HTMLParser::createHead): Ditto.
        (WebCore::HTMLParser::handleIsindex): Changed to use RefPtr.
        (WebCore::HTMLParser::startBody): Updated for renaming and doc().
        (WebCore::HTMLParser::finished): Ditto.



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@20170 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent a0799c09
2007-03-13 Darin Adler <darin@apple.com>
Reviewed by Maciej.
- tests for http://bugs.webkit.org/show_bug.cgi?id=12794
<rdar://problem/5028154> REGRESSION: TripTik planner at aaa.com never
finishes loading due to unclosed canvas tag (12794)
* fast/canvas/canvas-hides-fallback-expected.txt: Added.
* fast/canvas/canvas-hides-fallback.html: Added.
* fast/canvas/script-inside-canvas-fallback-expected.txt: Added.
* fast/canvas/script-inside-canvas-fallback.html: Added.
* fast/canvas/unclosed-canvas-1-expected.txt: Added.
* fast/canvas/unclosed-canvas-1.html: Added.
* fast/canvas/unclosed-canvas-2-expected.txt: Added.
* fast/canvas/unclosed-canvas-2.html: Added.
* fast/canvas/unclosed-canvas-3-expected.txt: Added.
* fast/canvas/unclosed-canvas-3.html: Added.
* fast/canvas/unclosed-canvas-4-expected.txt: Added.
* fast/canvas/unclosed-canvas-4.html: Added.
2007-03-13 David Harrison <harrison@apple.com>
 
Reviewed by Justin.
The DOM part of this test succeeded. The canvas element had at least one child, indicating that we are hiding text by not rendering it, but we are creating DOM elements as expected.
There should be no text below this, because the text is inside a canvas element and JavaScript is enabled.
<head>
<script>
if (window.layoutTestController)
layoutTestController.dumpAsText();
</script>
</head>
<body>
<p>This text should NOT be visible. It should be overwritten by the result of the test.</p>
<p>There should be no text below this, because the text is inside a canvas element and JavaScript is enabled.</p>
<canvas>This text should NOT be visible if JavaScript is enabled.</canvas>
<script>
var result = "The DOM part of this test FAILED. The canvas element did not have a child.";
if (document.getElementsByTagName("canvas")[0].firstChild)
result = "The DOM part of this test succeeded. The canvas element had at least one child, "
+ "indicating that we are hiding text by not rendering it, but we are creating DOM elements as expected."
document.getElementsByTagName("p")[0].innerText = result;
</script>
</body>
This text was set by a script inside a canvas element. Such scripts run even though the content is not displayed.
<head>
<script>
if (window.layoutTestController)
layoutTestController.dumpAsText();
</script>
</head>
<body>
<div>This text should NOT be visible, because JavaScript should replace it.</div>
<canvas>
This text should NOT be visible if JavaScript is enabled.
<script>
document.getElementsByTagName("div")[0].innerText = "This text was set by a script inside a canvas element. "
+ "Such scripts run even though the content is not displayed."
</script>
</canvas>
</body>
There should be no text below this, because the text is inside a canvas element. The canvas is never closed, and the rest of the body ends up inside it.
<head>
<script>
if (window.layoutTestController)
layoutTestController.dumpAsText();
</script>
</head>
<body>
<p>There should be no text below this, because the text is inside a canvas element.
The canvas is never closed, and the rest of the body ends up inside it.</p>
<canvas>This text should NOT be visible if JavaScript is enabled.
</body>
This text should be visible, even though it's preceded by an unclosed canvas tag, because of the </div> that closes an element opened before the canvas. There's nothing special about div; we get the same results with other types of elements.
<head>
<script>
if (window.layoutTestController)
layoutTestController.dumpAsText();
</script>
</head>
<body>
<div><canvas></div>
This text should be visible, even though it's preceded by an unclosed canvas tag,
because of the &lt;/div&gt; that closes an element opened before the canvas.
There's nothing special about div; we get the same results with other types of elements.
</body>
There should be no text below this, because the text is inside a canvas element and the </div> that's also inside the canvas element does not close an open element. The canvas is never closed, and the rest of the body ends up inside it. There's nothing special about div; we get the same results with other types of elements.
<head>
<script>
if (window.layoutTestController)
layoutTestController.dumpAsText();
</script>
</head>
<body>
<p>There should be no text below this, because the text is inside a canvas element
and the &lt;/div&gt; that's also inside the canvas element does not close an open element.
The canvas is never closed, and the rest of the body ends up inside it.
There's nothing special about div; we get the same results with other types of elements.</p>
<canvas></div>This text should NOT be visible if JavaScript is enabled.
</body>
There should be no text below this, because the text is inside a canvas element and the </div> that's also inside the canvas element does not close an open element. The canvas is never closed, and the rest of the body ends up inside it. There's nothing special about div; we get the same results with other types of elements. The fact that the canvas tag uses XML self-closing syntax has no effect.
<head>
<script>
if (window.layoutTestController)
layoutTestController.dumpAsText();
</script>
</head>
<body>
<p>There should be no text below this, because the text is inside a canvas element
and the &lt;/div&gt; that's also inside the canvas element does not close an open element.
The canvas is never closed, and the rest of the body ends up inside it.
There's nothing special about div; we get the same results with other types of elements.
The fact that the canvas tag uses XML self-closing syntax has no effect.</p>
<canvas/></div>This text should NOT be visible if JavaScript is enabled.
</body>
2007-03-13 Darin Adler <darin@apple.com>
Reviewed by Maciej.
- fix http://bugs.webkit.org/show_bug.cgi?id=12794
<rdar://problem/5028154> REGRESSION: TripTik planner at aaa.com never
finishes loading due to unclosed canvas tag (12794)
Change <canvas> elements so that their contents are parsed normally,
but not rendered. This change fixes the bug, because normal parsing
rules close the <canvas> element in that case. The special parser
stuff was just getting in the way.
Also do some basic cleanup to the HTML parser. This was motivated by
an earlier version of this patch that made even more changes to the
parser, but the cleanup is still worth landing.
Test: fast/canvas/canvas-hides-fallback.html
Test: fast/canvas/script-inside-canvas-fallback.html
Test: fast/canvas/unclosed-canvas-1.html
Test: fast/canvas/unclosed-canvas-2.html
Test: fast/canvas/unclosed-canvas-3.html
Test: fast/canvas/unclosed-canvas-4.html
* html/HTMLCanvasElement.h: Added a data member to keep track of whether the
renderer is a RenderHTMLCanvas or not.
* html/HTMLCanvasElement.cpp:
(WebCore::HTMLCanvasElement::createRenderer): If JavaScript is enabled, create
a RenderHTMLCanvas. If it's not, let the default code create the default type
of renderer, which will result in fallback content being visible. The
RenderHTMLCanvas class already hides all of its children. Set the m_rendererIsCanvas
boolean accordingly. Since the actual storage for the canvas is allocated lazily
when you actually get a drawing context, we don't need to do anything special
to prevent it when JavaScript is disabled; the relevant functions won't be called.
(WebCore::HTMLCanvasElement::reset): Protect the code that manipulates the
RenderHTMLCanvas with a check of m_rendererIsCanvas. This is the only code inside
the DOM element that relies on the renderer type.
* html/HTMLParser.h: Removed unneeded includes. Marked HTMLParser as
Noncopyable. Changed the Document parameter to the constructor to instead
of HTMLDocument. Renamed discard_until to m_skipModeTag for clarity.
Removed unused noSpaces function and unneeded public doc() function.
Moved data members all down to the end so you can see them together in order.
Renamed map to m_currentMapElement and isindex to m_isindexElement.
Removed unused end and headLoaded data members. Renamed m_fragment to
m_isParsingFragment to make it clearer that it's a boolean, not a fragment.
* html/HTMLParser.cpp:
(WebCore::HTMLParser::HTMLParser): Changed to use member construction
syntax instead of calling reset(). This is especially helpful in the
fragment case, where calling reset() later on is illegal, so not using
it in the constructor lets us assert.
(WebCore::HTMLParser::~HTMLParser): Did an explicit deref instead of
calling setCurrent for its side effect.
(WebCore::HTMLParser::reset): Updated for member name changes and removal
and to use document instead of doc().
(WebCore::HTMLParser::setCurrent): Use document instead of doc().
(WebCore::HTMLParser::setSkipMode): Added. No longer inline. Now sets the
m_inCanvasBeforeFirstOpenTag data member to false.
(WebCore::HTMLParser::parseToken): Tightened up the skip mode logic at the
top of the function, and added a FIXME about the strange case there where
we don't skip yet stay in skip mode. Updated for renaming and doc().
(WebCore::HTMLParser::insertNode): Updated for renaming and doc().
(WebCore::HTMLParser::handleError): Ditto.
(WebCore::HTMLParser::framesetCreateErrorCheck): Ditto.
(WebCore::HTMLParser::isindexCreateErrorCheck): Changed to use RefPtr.
(WebCore::HTMLParser::noscriptCreateErrorCheck): Updated for renaming and doc().
(WebCore::HTMLParser::mapCreateErrorCheck): Ditto.
(WebCore::HTMLParser::getNode): Removed the special case for canvas here.
Canvas fallback is now handled in the DOM, not the parser. Updated for
renaming and doc().
(WebCore::HTMLParser::allowNestedRedundantTag): Changed a #define into a C++
constant.
(WebCore::HTMLParser::processCloseTag): Updated for renaming and doc().
(WebCore::HTMLParser::isInline): Ditto.
(WebCore::HTMLParser::tagIsOnStack): Added. Used by new canvas logic.
(WebCore::HTMLParser::popBlock): Updated for renaming and doc(). Also renamed
the local variable Elem to elem.
(WebCore::HTMLParser::createHead): Ditto.
(WebCore::HTMLParser::handleIsindex): Changed to use RefPtr.
(WebCore::HTMLParser::startBody): Updated for renaming and doc().
(WebCore::HTMLParser::finished): Ditto.
2007-03-13 David Hyatt <hyatt@apple.com>
 
Two more cleanup fixes to the cache. Don't call destroyDecodedData in the BitmapImage destructor, since
......
/*
* Copyright (C) 2004, 2006 Apple Computer, Inc. All rights reserved.
* Copyright (C) 2004, 2006, 2007 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
......@@ -30,15 +30,14 @@
#include "CanvasPattern.h"
#include "CanvasRenderingContext2D.h"
#include "CanvasStyle.h"
#include "Chrome.h"
#include "Document.h"
#include "Frame.h"
#include "GraphicsContext.h"
#include "HTMLNames.h"
#include "Page.h"
#include "RenderHTMLCanvas.h"
#include "Chrome.h"
#include "Settings.h"
#include "Screen.h"
#include <math.h>
namespace WebCore {
......@@ -95,12 +94,18 @@ void HTMLCanvasElement::parseMappedAttribute(MappedAttribute* attr)
HTMLElement::parseMappedAttribute(attr);
}
RenderObject* HTMLCanvasElement::createRenderer(RenderArena *arena, RenderStyle *style)
RenderObject* HTMLCanvasElement::createRenderer(RenderArena* arena, RenderStyle* style)
{
RenderHTMLCanvas* r = new (arena) RenderHTMLCanvas(this);
r->setIntrinsicWidth(width());
r->setIntrinsicHeight(height());
return r;
if (document()->frame() && document()->frame()->settings()->isJavaScriptEnabled()) {
m_rendererIsCanvas = true;
RenderHTMLCanvas* r = new (arena) RenderHTMLCanvas(this);
r->setIntrinsicWidth(width());
r->setIntrinsicHeight(height());
return r;
}
m_rendererIsCanvas = false;
return HTMLElement::createRenderer(arena, style);
}
void HTMLCanvasElement::setHeight(int value)
......@@ -144,12 +149,13 @@ void HTMLCanvasElement::reset()
h = defaultHeight;
m_size = IntSize(w, h);
RenderHTMLCanvas* r = static_cast<RenderHTMLCanvas*>(renderer());
if (r) {
r->setIntrinsicWidth(w);
r->setIntrinsicHeight(h);
r->repaint();
}
if (RenderObject* ro = renderer())
if (m_rendererIsCanvas) {
RenderHTMLCanvas* r = static_cast<RenderHTMLCanvas*>(ro);
r->setIntrinsicWidth(w);
r->setIntrinsicHeight(h);
r->repaint();
}
m_createdDrawingContext = false;
fastFree(m_data);
......
......@@ -76,6 +76,8 @@ private:
void createDrawingContext() const;
void reset();
bool m_rendererIsCanvas;
RefPtr<CanvasRenderingContext2D> m_2DContext;
IntSize m_size;
......
This diff is collapsed.
/*
This file is part of the KDE libraries
Copyright (C) 1997 Martin Jones (mjones@kde.org)
(C) 1997 Torben Weis (weis@kde.org)
(C) 1998 Waldo Bastian (bastian@kde.org)
(C) 1999 Lars Knoll (knoll@kde.org)
Copyright (C) 2004, 2005, 2006 Apple Computer, Inc.
Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
......@@ -22,34 +20,34 @@
the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
*/
//----------------------------------------------------------------------------
//
// KDE HTML Widget -- HTML Parser
#ifndef HTMLParser_h
#define HTMLParser_h
#include "HTMLDocument.h"
#include "QualifiedName.h"
#include <wtf/Forward.h>
#include <wtf/RefPtr.h>
namespace WebCore {
class Document;
class DocumentFragment;
class FrameView;
class HTMLElement;
class HTMLDocument;
class HTMLFormElement;
class HTMLHeadElement;
class HTMLMapElement;
class HTMLStackElem;
class Node;
class Token;
struct HTMLStackElem;
/**
* The parser for html. It receives a stream of tokens from the HTMLTokenizer, and
* builds up the Document structure form it.
* The parser for HTML. It receives a stream of tokens from the HTMLTokenizer, and
* builds up the Document structure from it.
*/
class HTMLParser
{
class HTMLParser : Noncopyable {
public:
HTMLParser(Document*);
HTMLParser(HTMLDocument*);
HTMLParser(DocumentFragment*);
virtual ~HTMLParser();
......@@ -68,17 +66,12 @@ public:
*/
void reset();
bool skipMode() const { return !discard_until.isNull(); }
bool noSpaces() const { return !inBody; }
HTMLDocument *doc() const { return static_cast<HTMLDocument *>(document); }
bool skipMode() const { return !m_skipModeTag.isNull(); }
private:
void setCurrent(Node* newCurrent);
void setCurrent(Node*);
void derefCurrent();
void setSkipMode(const QualifiedName& qName) { discard_until = qName.localName(); }
Document* document;
void setSkipMode(const QualifiedName& qName) { m_skipModeTag = qName.localName(); }
PassRefPtr<Node> getNode(Token*);
bool bodyCreateErrorCheck(Token*, RefPtr<Node>&);
......@@ -103,19 +96,12 @@ private:
bool tableSectionCreateErrorCheck(Token*, RefPtr<Node>&);
bool textCreateErrorCheck(Token*, RefPtr<Node>&);
void processCloseTag(Token *);
void processCloseTag(Token*);
bool insertNode(Node *n, bool flat = false);
bool handleError(Node* n, bool flat, const AtomicString& localName, int tagPriority);
bool insertNode(Node*, bool flat = false);
bool handleError(Node*, bool flat, const AtomicString& localName, int tagPriority);
// The currently active element (the one new elements will be added to). Can be a document fragment, a document or an element.
Node* current;
// 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.
bool didRefCurrent;
HTMLStackElem *blockStack;
void pushBlock(const AtomicString& tagName, int _level);
void pushBlock(const AtomicString& tagName, int level);
void popBlock(const AtomicString& tagName);
void popBlock(const QualifiedName& qName) { return popBlock(qName.localName()); } // Convenience function for readability.
void popOneBlock();
......@@ -127,8 +113,8 @@ private:
void createHead();
bool isResidualStyleTag(const AtomicString& tagName);
bool isAffectedByResidualStyle(const AtomicString& tagName);
static bool isResidualStyleTag(const AtomicString& tagName);
static bool isAffectedByResidualStyle(const AtomicString& tagName);
void handleResidualStyleCloseTagAcrossBlocks(HTMLStackElem*);
void reopenResidualStyleTags(HTMLStackElem*, Node* malformedTableParent);
......@@ -137,47 +123,32 @@ private:
static bool isHeaderTag(const AtomicString& tagName);
void popNestedHeaderTag();
bool isInline(Node* node) const;
bool isInline(Node*) const;
/*
* currently active form
*/
HTMLFormElement *form;
void startBody(); // inserts the isindex element
PassRefPtr<Node> handleIsindex(Token*);
/*
* current map
*/
HTMLMapElement *map;
Document* document;
/*
* the head element. Needed for crappy html which defines <base> after </head>
*/
HTMLHeadElement *head;
// The currently active element (the one new elements will be added to). Can be a document fragment, a document or an element.
Node* current;
// 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.
bool didRefCurrent;
/*
* a possible <isindex> element in the head. Compatibility hack for
* html from the stone age
*/
RefPtr<Node> isindex;
Node* handleIsindex(Token*);
HTMLStackElem* blockStack;
/*
* inserts the stupid isIndex element.
*/
void startBody();
HTMLFormElement* form; // currently active form
HTMLMapElement* m_currentMapElement; // current map
HTMLHeadElement* head; // head element; needed for HTML which defines <base> after </head>
RefPtr<Node> m_isindexElement; // a possible <isindex> element in the head
bool inBody;
bool haveContent;
bool haveFrameSet;
bool end;
/*
* tells the parser to discard all tags, until it reaches the one specified
*/
AtomicString discard_until;
AtomicString m_skipModeTag; // tells the parser to discard all tags until it reaches the one specified
bool headLoaded;
bool m_fragment;
bool m_isParsingFragment;
int inStrayTableContent;
};
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment