Reviewers: metaweta,
Description:
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.
Please review this at http://codereview.appspot.com/3791041/
Affected files:
M src/com/google/caja/plugin/PluginMessageType.java
M src/com/google/caja/plugin/stages/LegacyNamespaceFixupStage.java
M
tests/com/google/caja/plugin/stages/LegacyNamespaceFixupStageTest.java
Index:
tests/com/google/caja/plugin/stages/LegacyNamespaceFixupStageTest.java
===================================================================
--- tests/com/google/caja/plugin/stages/LegacyNamespaceFixupStageTest.java
(revision 4337)
+++ tests/com/google/caja/plugin/stages/LegacyNamespaceFixupStageTest.java
(working copy)
@@ -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;
@@ -66,6 +67,37 @@
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(
""
Index: src/com/google/caja/plugin/PluginMessageType.java
===================================================================
--- src/com/google/caja/plugin/PluginMessageType.java (revision 4337)
+++ src/com/google/caja/plugin/PluginMessageType.java (working copy)
@@ -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),
;
Index: src/com/google/caja/plugin/stages/LegacyNamespaceFixupStage.java
===================================================================
--- src/com/google/caja/plugin/stages/LegacyNamespaceFixupStage.java
(revision 4337)
+++ src/com/google/caja/plugin/stages/LegacyNamespaceFixupStage.java
(working copy)
@@ -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) {