You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@shindig.apache.org by aw...@apache.org on 2009/04/20 22:24:01 UTC
svn commit: r766854 - in /incubator/shindig/trunk/java/gadgets/src:
main/java/org/apache/shindig/gadgets/templates/DefaultTemplateProcessor.java
test/java/org/apache/shindig/gadgets/templates/DefaultTemplateProcessorTest.java
Author: awiner
Date: Mon Apr 20 20:24:01 2009
New Revision: 766854
URL: http://svn.apache.org/viewvc?rev=766854&view=rev
Log:
Support boolean HTML4 attributes (enabled="enabled" and such)
Modified:
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/templates/DefaultTemplateProcessor.java
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/templates/DefaultTemplateProcessorTest.java
Modified: incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/templates/DefaultTemplateProcessor.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/templates/DefaultTemplateProcessor.java?rev=766854&r1=766853&r2=766854&view=diff
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/templates/DefaultTemplateProcessor.java (original)
+++ incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/templates/DefaultTemplateProcessor.java Mon Apr 20 20:24:01 2009
@@ -24,8 +24,10 @@
import java.io.IOException;
import java.util.Iterator;
+import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
+import java.util.Set;
import java.util.logging.Logger;
import javax.el.ELContext;
@@ -44,7 +46,9 @@
import org.w3c.dom.NodeList;
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.inject.Inject;
@@ -70,6 +74,13 @@
public static final String ATTRIBUTE_VAR = "var";
public static final String ATTRIBUTE_CUR = "cur";
+ /**
+ * Set of attributes in HTML 4 that are boolean, and may only be set
+ * to that value, and should be omitted to indicate "false".
+ */
+ private static final Set<String> HTML4_BOOLEAN_ATTRIBUTES =
+ ImmutableSet.of("checked", "compact", "declare", "defer", "disabled", "ismap",
+ "multiple", "nohref", "noresize", "noshade", "nowrap", "readonly", "selected");
private final Expressions expressions;
// Reused buffer for creating template output
private final StringBuilder outputBuffer;
@@ -350,15 +361,42 @@
}
/**
- * Process expressions on attributes. For custom tags, in addition to
- * processing attributes,
+ * Process expressions on attributes.
* @param element The Element to process attributes on
*/
private void processAttributes(Element element) {
NamedNodeMap attributes = element.getAttributes();
+ List<Attr> attrsToRemove = null;
for (int i = 0; i < attributes.getLength(); i++) {
Attr attribute = (Attr) attributes.item(i);
- attribute.setNodeValue(evaluate(attribute.getValue(), String.class, null));
+ // Boolean attributes: evaluate as a boolean. If true, set the value to the
+ // name of the attribute, e.g. selected="selected". If false, remove the attribute
+ // altogether. The check here has some limitations for efficiency: it assumes the
+ // attribute is lowercase, and doesn't bother to check whether the boolean attribute
+ // actually exists on the referred element (but HTML has no attrs that are sometimes
+ // boolean and sometimes not)
+ if (element.getNamespaceURI() == null &&
+ HTML4_BOOLEAN_ATTRIBUTES.contains(attribute.getName())) {
+ if (Boolean.TRUE.equals(evaluate(attribute.getValue(), Boolean.class, Boolean.FALSE))) {
+ attribute.setNodeValue(attribute.getName());
+ } else {
+ // Because NamedNodeMaps are live, removing them interferes with iteration.
+ // Remove the attributes in a later pass
+ if (attrsToRemove == null) {
+ attrsToRemove = Lists.newArrayListWithCapacity(attributes.getLength());
+ }
+
+ attrsToRemove.add(attribute);
+ }
+ } else {
+ attribute.setNodeValue(evaluate(attribute.getValue(), String.class, null));
+ }
+ }
+
+ if (attrsToRemove != null) {
+ for (Attr attr : attrsToRemove) {
+ element.removeAttributeNode(attr);
+ }
}
}
Modified: incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/templates/DefaultTemplateProcessorTest.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/templates/DefaultTemplateProcessorTest.java?rev=766854&r1=766853&r2=766854&view=diff
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/templates/DefaultTemplateProcessorTest.java (original)
+++ incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/templates/DefaultTemplateProcessorTest.java Mon Apr 20 20:24:01 2009
@@ -187,6 +187,13 @@
assertEquals("<b>BAR</b>", output);
}
+ @Test
+ public void testBooleanAttributes() throws Exception {
+ String output = executeTemplate("<input class=\"${1 == 2}\" readonly=\"${1 == 2}\"" +
+ "disabled=\"${1 == 1}\">");
+ assertEquals("<input class=\"false\" disabled=\"disabled\">", output);
+ }
+
private String executeTemplate(String markup) throws Exception {
return executeTemplate(markup, "");
}