You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cocoon.apache.org by Wojciech Gdela <el...@poczta.onet.pl> on 2004/11/07 01:07:51 UTC

[blocks.serializers] XHtmlSerializer bugfixes and improvements

Hello,

--- Improvement ---

Recently I've found discussion about IE problems with empty textarea
tags in XHtml notation (ie. <textarea name="foo"/>)
[http://thread.gmane.org/gmane.text.xml.cocoon.devel/33345]. There are
also problems with other tags, here is a snippet of code:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
       <a name="foo"/> This text is supposed not to be a link.
       <div style="text-decoration: underline"/> This text shouldn't be
underlined
<body>
</html>

In order to have this work in IE you have to add closing tags:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
       <a name="foo"></a> This text is not a link.
       <div style="text-decoration: underline"></div> This text is not
underlined
<body>
</html>

So I think that o.a.c.components.serializers.XHtmlSerializer should be
extended in this way:

    public void endElementImpl(String uri, String local, String qual)
    throws SAXException {
        if (uri.length() == 0) uri = XHTML1_NAMESPACE;

        if (XHTML1_NAMESPACE.equals(uri)) {
            if ((local.equalsIgnoreCase("textarea")) ||
                (local.equalsIgnoreCase("script")) ||
                (local.equalsIgnoreCase("style")) ||
                (local.equalsIgnoreCase("a")) || // THIS LINE ADDED
                (local.equalsIgnoreCase("div"))) { // THIS LINE ADDED
                this.closeElement(false);
            } else if (local.equalsIgnoreCase("head")) {
                String loc = "meta";
                String qua = namespaces.qualify(XHTML1_NAMESPACE, loc,
"meta");
                String nsp[][] = new String[0][0];
                String att[][] = new String[2][ATTRIBUTE_LENGTH];

                att[0][ATTRIBUTE_NSURI] = att[1][ATTRIBUTE_NSURI] = "";
                att[0][ATTRIBUTE_LOCAL] = att[0][ATTRIBUTE_QNAME] =
"http-equiv";
                att[1][ATTRIBUTE_LOCAL] = att[1][ATTRIBUTE_QNAME] =
"content";
                att[0][ATTRIBUTE_VALUE] = "Content-Type";
                att[1][ATTRIBUTE_VALUE] = this.getMimeType();

                this.closeElement(false);
                this.startElementImpl(XHTML1_NAMESPACE, loc, qua, nsp,
att);
                this.endElementImpl(XHTML1_NAMESPACE, loc, qua);
            }
        }
        super.endElementImpl(uri, local, qual);
    }

--- Bugfix ---

When I first tried to use XHtmlSerializer I've got this exception
[mentioned in
http://article.gmane.org/gmane.text.xml.cocoon.user/42495]:

org.xml.sax.SAXException: Unable to map "http://www.w3.org/2000/xmlns/"

After reading http://www.w3.org/2000/xmlns/ I think that adding one line
to Namespaces constructor will help:

    public Namespaces() {
        super();

        this.push("", "");
        this.push("xml", "http://www.w3.org/XML/1998/namespace");
        this.push("xmlns", "http://www.w3.org/2000/xmlns/"); // THIS
LINE ADDED
        this.last = this.depth;
    }

The xmlns is a special namespace, so i think that this would be ok.

--- Possibly Bugfix ---

In Namespaces there is a method named pop:

    public synchronized void pop(String prefix)
    throws SAXException {
        for (int x = this.position(prefix, pre); x < (--this.depth);
x++) {
            int k = (x + 1);
            this.pre[x] = this.pre[k];
            this.uri[x] = this.uri[k];
        }
        this.pre[this.depth] = null;
        this.uri[this.depth] = null;
        this.last--;
    }

In every iteration the field this.depth will be decremented by one, I
think that the loop should look like this:

    public synchronized void pop(String prefix)
    throws SAXException {
        for (int x = this.position(prefix, pre); x < (this.depth - 1);
x++) {
            int k = (x + 1);
            this.pre[x] = this.pre[k];
            this.uri[x] = this.uri[k];
        }
        this.pre[this.depth] = null;
        this.uri[this.depth] = null;
        this.last--;
    }

By the way: why don't you simply use HashMap with prefix as key and uri
as value?

-- 
Best regards,
Wojciech Gdela <el...@poczta.onet.pl>


Re: [blocks.serializers] XHtmlSerializer bugfixes and improvements

Posted by Wojciech Gdela <el...@poczta.onet.pl>.
Jean Pierre LeJacq wrote:

> IMHO, it is bad idea to hardcode work arounds for broken browsers.

I agree, but I think it's the main purpose of new XHtmlSerializer to
workaround IE bugs. It already has workarounds for "textarea", "script"
and "style", so It should have "div" and "a" too, to be complete.
 
> I would prefer a serializer that works to the standard and either
> provide an optional parameter asking for IE workarounds or a
> transformer that applys the workarounds prior to serialization.

+1 for parameter in serialzer.

Actually serializer can detect if user agent accepts
"applicaton/xhtml+xml" content type, and if not switch to workarounds
mode.

-- 
Best regards,
Wojciech Gdela.


Re: [blocks.serializers] XHtmlSerializer bugfixes and improvements

Posted by Jean Pierre LeJacq <jp...@quoininc.com>.
On Sun, 7 Nov 2004, Wojciech Gdela wrote:

> Recently I've found discussion about IE problems with empty textarea
> tags in XHtml notation (ie. <textarea name="foo"/>)
> [http://thread.gmane.org/gmane.text.xml.cocoon.devel/33345]. There are
> also problems with other tags, here is a snippet of code:
>
> <?xml version="1.0" encoding="UTF-8"?>
> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
> "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
> <html xmlns="http://www.w3.org/1999/xhtml">
> <body>
>        <a name="foo"/> This text is supposed not to be a link.
>        <div style="text-decoration: underline"/> This text shouldn't be
> underlined
> <body>
> </html>
>
> In order to have this work in IE you have to add closing tags:
>
> <?xml version="1.0" encoding="UTF-8"?>
> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
> "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
> <html xmlns="http://www.w3.org/1999/xhtml">
> <body>
>        <a name="foo"></a> This text is not a link.
>        <div style="text-decoration: underline"></div> This text is not
> underlined
> <body>
> </html>

> ...snip...

IMHO, it is bad idea to hardcode work arounds for broken browsers.

I would prefer a serializer that works to the standard and either
provide an optional parameter asking for IE workarounds or a
transformer that applys the workarounds prior to serialization.

-- 
JP