cocoon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Wojciech Gdela <elteh...@poczta.onet.pl>
Subject [blocks.serializers] XHtmlSerializer bugfixes and improvements
Date Sun, 07 Nov 2004 00:07:51 GMT
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 <eltehaem@poczta.onet.pl>


Mime
View raw message