Revision: 4338
Author: jasvir
Date: Sun Dec 19 17:40:12 2010
Log: Handle xmlns attributes when importing a non-namespace aware DOM
http://codereview.appspot.com/3791041

DOMs created in non-namespace aware mode treat xmlns has yet another attribute. This change recognizes the xmlns attribute and creates a namespaced element instead
of trying to create an attribute called xmlns.

[email protected]

http://code.google.com/p/google-caja/source/detail?r=4338

Modified:
 /trunk/src/com/google/caja/plugin/PluginMessageType.java
 /trunk/src/com/google/caja/plugin/stages/LegacyNamespaceFixupStage.java
/trunk/tests/com/google/caja/plugin/stages/LegacyNamespaceFixupStageTest.java

=======================================
--- /trunk/src/com/google/caja/plugin/PluginMessageType.java Tue Mar 2 13:55:40 2010 +++ /trunk/src/com/google/caja/plugin/PluginMessageType.java Sun Dec 19 17:40:12 2010
@@ -101,6 +101,9 @@
       "%s: specialized CSS property %s to %s", MessageLevel.WARNING),
   MISSING_XML_NAMESPACE(
       "%s: XML %s has prefix but no namespace", MessageLevel.ERROR),
+  CONFLICTING_XML_NAMESPACE(
+          "%s: Overriding unexpected xmlns attr %s with %s in element %s",
+          MessageLevel.WARNING),
INVALID_PIPELINE("Cannot find plan from %s to %s", MessageLevel.FATAL_ERROR),
   ;

=======================================
--- /trunk/src/com/google/caja/plugin/stages/LegacyNamespaceFixupStage.java Thu Oct 28 19:44:52 2010 +++ /trunk/src/com/google/caja/plugin/stages/LegacyNamespaceFixupStage.java Sun Dec 19 17:40:12 2010
@@ -112,13 +112,26 @@
     private void fixAttr(String elNsUri, Attr a) {
       Element e = a.getOwnerElement();
       String ns = guessNamespaceAndWarn(elNsUri, a);
-      Attr newA = a.getOwnerDocument().createAttributeNS(ns, a.getName());
-      newA.setNodeValue(a.getValue());
-      Nodes.setFilePositionFor(newA, Nodes.getFilePositionFor(a));
- Nodes.setFilePositionForValue(newA, Nodes.getFilePositionForValue(a));
-      Nodes.setRawValue(newA, Nodes.getRawValue(a));
-      e.removeAttributeNode(a);
-      e.setAttributeNodeNS(newA);
+      if ("xmlns".equals(a.getName())) {
+        e.removeAttributeNode(a);
+        if (!a.getValue().equals(ns)) {
+          mq.addMessage(
+ PluginMessageType.CONFLICTING_XML_NAMESPACE, MessageLevel.WARNING,
+              Nodes.getFilePositionFor(a),
+              MessagePart.Factory.valueOf(a.getValue()),
+              MessagePart.Factory.valueOf(ns),
+              MessagePart.Factory.valueOf(e.getNodeName()));
+        }
+        e.getOwnerDocument().renameNode(e, ns, e.getNodeName());
+      } else {
+ Attr newA = a.getOwnerDocument().createAttributeNS(ns, a.getName());
+        newA.setNodeValue(a.getValue());
+        Nodes.setFilePositionFor(newA, Nodes.getFilePositionFor(a));
+ Nodes.setFilePositionForValue(newA, Nodes.getFilePositionForValue(a));
+        Nodes.setRawValue(newA, Nodes.getRawValue(a));
+        e.removeAttributeNode(a);
+        e.setAttributeNodeNS(newA);
+      }
     }

     private String guessNamespaceAndWarn(String defaultNsUri, Node n) {
=======================================
--- /trunk/tests/com/google/caja/plugin/stages/LegacyNamespaceFixupStageTest.java Thu Oct 28 19:44:52 2010 +++ /trunk/tests/com/google/caja/plugin/stages/LegacyNamespaceFixupStageTest.java Sun Dec 19 17:40:12 2010
@@ -17,6 +17,7 @@
 import com.google.caja.lexer.InputSource;
 import com.google.caja.parser.html.Dom;
 import com.google.caja.parser.html.DomParser;
+import com.google.caja.parser.html.Namespaces;
 import com.google.caja.plugin.Job;
 import com.google.caja.plugin.JobEnvelope;
 import com.google.caja.plugin.Jobs;
@@ -65,6 +66,37 @@
         MessagePart.Factory.valueOf("xml:lang"));
     assertTrue(mq.getMessages().isEmpty());
   }
+
+  public final void testNoXmlnsAttr() {
+    assertFixed(
+        ""
+        + "<a href=\"bar.html\">Foo</a>",
+        builder().open("a").attr("href", "bar.html")
+            .text("Foo").close().job());
+    assertTrue(mq.getMessages().isEmpty());
+  }
+
+  public final void testSameXmlnsAttr() {
+    assertFixed(
+        ""
+        + "<a href=\"bar.html\">Foo</a>",
+        builder().open("a").attr("href", "bar.html")
+        .attr("xmlns", Namespaces.HTML_NAMESPACE_URI).text("Foo")
+        .close().job());
+    assertTrue(mq.getMessages().isEmpty());
+  }
+
+  public final void testNewXmlnsAttr() {
+    assertFixed(
+        ""
+        + "<a href=\"bar.html\">Foo</a>",
+        builder().open("a").attr("href", "bar.html")
+            .attr("xmlns", "http://foo.com";).text("Foo").close().job());
+    assertMessage(
+ true, PluginMessageType.CONFLICTING_XML_NAMESPACE, MessageLevel.WARNING,
+        MessagePart.Factory.valueOf("a"));
+    assertTrue(mq.getMessages().isEmpty());
+  }

   public final void testPrefixedAttribWithUnknownPrefix() {
     assertFixed(

Reply via email to