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(