You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@shindig.apache.org by li...@apache.org on 2011/03/25 16:54:37 UTC
svn commit: r1085433 - in /shindig/trunk: config/
java/gadgets/src/main/java/org/apache/shindig/gadgets/
java/gadgets/src/main/java/org/apache/shindig/gadgets/render/
java/gadgets/src/main/java/org/apache/shindig/gadgets/spec/
java/gadgets/src/test/jav...
Author: lindner
Date: Fri Mar 25 15:54:36 2011
New Revision: 1085433
URL: http://svn.apache.org/viewvc?rev=1085433&view=rev
Log:
SHINDIG-1504 | patch from Matthew Marum | Removing Quirks mode default
Modified:
shindig/trunk/config/container.js
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/Gadget.java
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/RenderingGadgetRewriter.java
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/spec/GadgetSpec.java
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/spec/ModulePrefs.java
shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/render/RenderingGadgetRewriterTest.java
Modified: shindig/trunk/config/container.js
URL: http://svn.apache.org/viewvc/shindig/trunk/config/container.js?rev=1085433&r1=1085432&r2=1085433&view=diff
==============================================================================
--- shindig/trunk/config/container.js (original)
+++ shindig/trunk/config/container.js Fri Mar 25 15:54:36 2011
@@ -108,6 +108,12 @@
// Authority (host:port without scheme) for the proxy and concat servlets.
"defaultShindigProxyConcatAuthority": "${SERVER_HOST}:${SERVER_PORT}",
+// OS 2.0 Gadget DOCTYPE: used in Gadgets with @specificationVersion 2.0 or greater and
+// quirksmode on Gadget has not been set.
+"gadgets.doctype_qname" : "HTML", //HTML5 doctype
+"gadgets.doctype_pubid" : "",
+"gadgets.doctype_sysid" : "",
+
// Default Uri config: these must be overridden - specified here for testing purposes
"gadgets.uri.iframe.unlockedDomain": "${Cur['defaultShindigTestHost']}",
"gadgets.uri.iframe.lockedDomainSuffix": "${Cur['defaultShindigTestHost']}",
Modified: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/Gadget.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/Gadget.java?rev=1085433&r1=1085432&r2=1085433&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/Gadget.java (original)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/Gadget.java Fri Mar 25 15:54:36 2011
@@ -17,7 +17,7 @@
*/
package org.apache.shindig.gadgets;
-import com.google.common.base.Preconditions;
+import org.apache.shindig.common.util.OpenSocialVersion;
import org.apache.shindig.gadgets.features.FeatureRegistry;
import org.apache.shindig.gadgets.preload.PreloadedData;
import org.apache.shindig.gadgets.spec.GadgetSpec;
@@ -25,6 +25,7 @@ import org.apache.shindig.gadgets.spec.L
import org.apache.shindig.gadgets.spec.View;
import org.apache.shindig.gadgets.uri.UriCommon;
+import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
@@ -33,6 +34,8 @@ import java.util.Collections;
import java.util.List;
import java.util.Set;
+
+
/**
* Intermediary representation of all state associated with processing
* of a single gadget request.
@@ -78,6 +81,31 @@ public class Gadget {
public GadgetSpec getSpec() {
return spec;
}
+
+ /**
+ * Returns open social specification version for this Gadget
+ * @return Version for this Gadget
+ */
+ public OpenSocialVersion getSpecificationVersion(){
+ if(spec != null){
+ return spec.getSpecificationVersion();
+ }
+ return null;
+ }
+
+ /**
+ * Returns if the doctype attribute is set to quirksmode.
+ * Needed to override default OpenSocial 2.0 behavior which is to render in standards mode,
+ * may not be possible to honor this attribute when inlining (caja)
+ *
+ * @return TRUE if this Gadget should be rendered in browser quirks mode
+ */
+ public boolean useQuirksMode(){
+ if(spec != null){
+ return GadgetSpec.DOCTYPE_QUIRKSMODE.equals(spec.getModulePrefs().getDoctype());
+ }
+ return false;
+ }
/**
* @param preloads The preloads for the gadget that is being processed.
Modified: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/RenderingGadgetRewriter.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/RenderingGadgetRewriter.java?rev=1085433&r1=1085432&r2=1085433&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/RenderingGadgetRewriter.java (original)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/RenderingGadgetRewriter.java Fri Mar 25 15:54:36 2011
@@ -18,7 +18,7 @@
*/
package org.apache.shindig.gadgets.render;
-import com.google.common.base.Splitter;
+import org.apache.commons.lang.StringUtils;
import org.apache.shindig.common.JsonSerializer;
import org.apache.shindig.common.logging.i18n.MessageKeys;
import org.apache.shindig.common.uri.Uri;
@@ -43,8 +43,8 @@ import org.apache.shindig.gadgets.spec.U
import org.apache.shindig.gadgets.spec.View;
import org.apache.shindig.gadgets.uri.JsUriManager;
import org.apache.shindig.gadgets.uri.JsUriManager.JsUri;
-import org.apache.commons.lang.StringUtils;
import org.w3c.dom.Document;
+import org.w3c.dom.DocumentType;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.Text;
@@ -56,6 +56,7 @@ import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
+import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.Lists;
@@ -93,6 +94,9 @@ public class RenderingGadgetRewriter imp
"body{margin: 0px;padding: 0px;background-color:white;}";
static final String IS_GADGET_BEACON = "window['__isgadget']=true;";
static final String INSERT_BASE_ELEMENT_KEY = "gadgets.insertBaseElement";
+ static final String REWRITE_DOCTYPE_QNAME = "gadgets.doctype_qname";
+ static final String REWRITE_DOCTYPE_PUBID = "gadgets.doctype_pubid";
+ static final String REWRITE_DOCTYPE_SYSID = "gadgets.doctype_sysid";
static final String FEATURES_KEY = "gadgets.features";
protected final MessageBundleFactory messageBundleFactory;
@@ -106,6 +110,11 @@ public class RenderingGadgetRewriter imp
protected Boolean externalizeFeatures = false;
+ //DOCTYPE for HTML5, OpenSocial 2.0 default
+ private String defaultDoctypeQName = "html";
+ private String defaultDoctypePubId = null;
+ private String defaultDoctypeSysId = null;
+
/**
* @param messageBundleFactory Used for injecting message bundles into gadget output.
*/
@@ -121,6 +130,18 @@ public class RenderingGadgetRewriter imp
this.jsUriManager = jsUriManager;
this.configContributors = configContributors;
}
+
+ public void setDefaultDoctypeQName(String qname) {
+ this.defaultDoctypeQName = qname;
+ }
+
+ public void setDefaultDoctypePubId( String pubid) {
+ this.defaultDoctypePubId = pubid;
+ }
+
+ public void setDefaultDoctypeSysId( String sysid) {
+ this.defaultDoctypeSysId = sysid;
+ }
@Inject
public void setDefaultForcedLibs(@Named("shindig.gadget-rewrite.default-forced-libs")String forcedLibs) {
@@ -143,7 +164,7 @@ public class RenderingGadgetRewriter imp
try {
Document document = mutableContent.getDocument();
- Element head = (Element)DomUtil.getFirstNamedChildNode(document.getDocumentElement(), "head");
+ Element head = (Element) DomUtil.getFirstNamedChildNode(document.getDocumentElement(), "head");
// Insert new content before any of the existing children of the head element
Node firstHeadChild = head.getFirstChild();
@@ -156,6 +177,36 @@ public class RenderingGadgetRewriter imp
defaultStyle.appendChild(defaultStyle.getOwnerDocument().
createTextNode(DEFAULT_CSS));
}
+ // Override & insert DocType if Gadget is written for OpenSocial 2.0 or greater,
+ // if quirksmode is not set
+ if(gadget.getSpecificationVersion().isEqualOrGreaterThan("2.0.0")
+ && !gadget.useQuirksMode()){
+ String container = gadget.getContext().getContainer();
+ String doctype_qname = defaultDoctypeQName;
+ String doctype_sysid = defaultDoctypeSysId;
+ String doctype_pubid = defaultDoctypePubId;
+ String value = containerConfig.getString(container, REWRITE_DOCTYPE_QNAME);
+ if(value != null){
+ doctype_qname = value;
+ }
+ value = containerConfig.getString(container, REWRITE_DOCTYPE_SYSID);
+ if(value != null){
+ doctype_sysid = value;
+ }
+ value = containerConfig.getString(container, REWRITE_DOCTYPE_PUBID);
+ if(value != null){
+ doctype_pubid = value;
+ }
+ //Don't inject DOCTYPE if QName is null
+ if(doctype_qname != null){
+ DocumentType docTypeNode = document.getImplementation()
+ .createDocumentType(doctype_qname, doctype_pubid, doctype_sysid);
+ if(document.getDoctype() != null){
+ document.removeChild(document.getDoctype());
+ }
+ document.insertBefore(docTypeNode, document.getFirstChild());
+ }
+ }
injectBaseTag(gadget, head);
injectGadgetBeacon(gadget, head, firstHeadChild);
Modified: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/spec/GadgetSpec.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/spec/GadgetSpec.java?rev=1085433&r1=1085432&r2=1085433&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/spec/GadgetSpec.java (original)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/spec/GadgetSpec.java Fri Mar 25 15:54:36 2011
@@ -21,10 +21,12 @@ import com.google.common.annotations.Vis
import com.google.common.base.Splitter;
import org.apache.shindig.common.uri.Uri;
import org.apache.shindig.common.util.HashUtil;
+import org.apache.shindig.common.util.OpenSocialVersion;
import org.apache.shindig.common.xml.XmlUtil;
import org.apache.shindig.gadgets.spec.View.ContentType;
import org.apache.shindig.gadgets.variables.Substitutions;
+
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.common.collect.MapMaker;
@@ -47,6 +49,9 @@ public class GadgetSpec {
public static final String DEFAULT_VIEW = "default";
public static final Locale DEFAULT_LOCALE = new Locale("all", "ALL");
+ private static final String ATTR_SPECIFICATION_VERSION = "specificationVersion";
+ public static final String DOCTYPE_QUIRKSMODE = "quirksmode";
+
/**
* Creates a new Module from the given xml input.
*
@@ -63,6 +68,8 @@ public class GadgetSpec {
this.checksum = HashUtil.checksum(original.getBytes());
NodeList children = doc.getChildNodes();
+ //Save specification version of this Gadget
+ setAttribute(ATTR_SPECIFICATION_VERSION,doc.getAttribute(ATTR_SPECIFICATION_VERSION));
ModulePrefs modulePrefs = null;
Map<String,UserPref> prefsBuilder = Maps.newHashMap();
@@ -137,6 +144,20 @@ public class GadgetSpec {
checksum = spec.checksum;
attributes.putAll(spec.attributes);
}
+
+ /**
+ * Returns this Gadget's specification version. Defaults to 1.0 if attribute not set.
+ * @return Version value as String
+ */
+ public OpenSocialVersion getSpecificationVersion(){
+ // 1.0 is default if unspecified as defined in Section 7 of OS 1.1 Core Gadget specification
+ String value = (String)attributes.get(ATTR_SPECIFICATION_VERSION);
+ if (value == null) {
+ return new OpenSocialVersion("1.0");
+ } else {
+ return new OpenSocialVersion(value);
+ }
+ }
/**
* The url for this gadget spec.
@@ -161,6 +182,7 @@ public class GadgetSpec {
public ModulePrefs getModulePrefs() {
return modulePrefs;
}
+
/**
* UserPref
Modified: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/spec/ModulePrefs.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/spec/ModulePrefs.java?rev=1085433&r1=1085432&r2=1085433&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/spec/ModulePrefs.java (original)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/spec/ModulePrefs.java Fri Mar 25 15:54:36 2011
@@ -77,6 +77,7 @@ public class ModulePrefs {
private static final String ATTR_SINGLETON = "singleton";
private static final String ATTR_SCALING = "scaling";
private static final String ATTR_SCROLLING = "scrolling";
+ private static final String ATTR_DOCTYPE = "doctype";
private static final String ATTR_WIDTH = "width";
private static final String ATTR_HEIGHT = "height";
private static final String ATTR_CATEGORY = "category";
@@ -342,6 +343,15 @@ public class ModulePrefs {
public int getHeight() {
return getIntAttribute(ATTR_HEIGHT);
}
+
+ /**
+ * Returns this Gadget's doctype mode. If null, we will use default mode.
+ *
+ * @return Value of doctype attribute
+ */
+ public String getDoctype(){
+ return getAttribute(ATTR_DOCTYPE);
+ }
/**
* @param name the attribute name
Modified: shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/render/RenderingGadgetRewriterTest.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/render/RenderingGadgetRewriterTest.java?rev=1085433&r1=1085432&r2=1085433&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/render/RenderingGadgetRewriterTest.java (original)
+++ shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/render/RenderingGadgetRewriterTest.java Fri Mar 25 15:54:36 2011
@@ -90,6 +90,10 @@ public class RenderingGadgetRewriterTest
static final Pattern DOCUMENT_SPLIT_PATTERN = Pattern.compile(
"(.*)<head>(.*?)<\\/head>(?:.*)<body(.*?)>(.*?)<\\/body>(?:.*)", Pattern.DOTALL |
Pattern.CASE_INSENSITIVE);
+ private static final String CUSTOM_DOCTYPE = "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">";
+ private static final String CUSTOM_DOCTYPE_QNAME = "html";
+ private static final String CUSTOM_DOCTYPE_PUBID = "-//W3C//DTD HTML 4.01 Transitional//EN";
+ private static final String CUSTOM_DOCTYPE_SYSID = "http://www.w3.org/TR/html4/loose.dtd";
static final int BEFORE_HEAD_GROUP = 1;
static final int HEAD_GROUP = 2;
@@ -138,6 +142,11 @@ public class RenderingGadgetRewriterTest
String defaultXml = "<Module><ModulePrefs title=''/><Content type='html'/></Module>";
return makeGadgetWithSpec(defaultXml);
}
+
+ private Gadget makeDefaultOpenSocial2Gadget(boolean useQuirks) throws GadgetException {
+ String defaultXml = "<Module specificationVersion='2' ><ModulePrefs " + (useQuirks ? "doctype='quirksmode'" : "") +" title=''/><Content type='html'/></Module>";
+ return makeGadgetWithSpec(defaultXml);
+ }
private String rewrite(Gadget gadget, String content) throws Exception {
MutableContent mc = new MutableContent(parser, content);
@@ -164,6 +173,63 @@ public class RenderingGadgetRewriterTest
assertTrue("gadgets.util.runOnLoadHandlers not invoked.",
matcher.group(BODY_GROUP).contains("gadgets.util.runOnLoadHandlers();"));
}
+
+ @Test
+ public void overrideDefaultDoctype() throws Exception{
+ Gadget gadget = makeDefaultOpenSocial2Gadget(false);
+ String body = "hello, world.";
+ String doc = new StringBuilder()
+ .append("<html><head>")
+ .append("</head><body>")
+ .append(body)
+ .append("</body></html>")
+ .toString();
+
+ rewriter.setDefaultDoctypeQName(CUSTOM_DOCTYPE_QNAME);
+ rewriter.setDefaultDoctypePubId(CUSTOM_DOCTYPE_PUBID);
+ rewriter.setDefaultDoctypeSysId(CUSTOM_DOCTYPE_SYSID);
+ String rewritten = rewrite(gadget, doc);
+
+ Matcher matcher = DOCUMENT_SPLIT_PATTERN.matcher(rewritten);
+ assertTrue("Output is not valid HTML.", matcher.matches());
+ assertTrue("DOCTYPE not preserved", matcher.group(BEFORE_HEAD_GROUP).contains(CUSTOM_DOCTYPE));
+
+ }
+
+ @Test
+ public void quirksmodeInOS2() throws Exception{
+ Gadget gadget = makeDefaultOpenSocial2Gadget(true);
+ String body = "hello, world.";
+ String doc = new StringBuilder()
+ .append("<html><head>")
+ .append("</head><body>")
+ .append(body)
+ .append("</body></html>")
+ .toString();
+
+ String rewritten = rewrite(gadget, doc);
+
+ Matcher matcher = DOCUMENT_SPLIT_PATTERN.matcher(rewritten);
+ assertTrue("Output is not valid HTML.", matcher.matches());
+ assertTrue("Should not include doctype, this will default to quirksmode (old Shindig behavior)", !matcher.group(BEFORE_HEAD_GROUP).contains("<!DOCTYPE"));
+
+ gadget = makeDefaultOpenSocial2Gadget(true);
+ String docType = "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">";
+ doc = new StringBuilder()
+ .append(docType)
+ .append("<html><head>")
+ .append("</head><body>")
+ .append(body)
+ .append("</body></html>")
+ .toString();
+ rewritten = rewrite(gadget, doc);
+
+ matcher = DOCUMENT_SPLIT_PATTERN.matcher(rewritten);
+ assertTrue("Output is not valid HTML.", matcher.matches());
+ assertTrue("Should include doctype, when in quirksmode we should use pre OS2.0 Shindig behavior.", matcher.group(BEFORE_HEAD_GROUP).contains(docType));
+
+
+ }
@Test
public void completeDocument() throws Exception {
@@ -221,6 +287,45 @@ public class RenderingGadgetRewriterTest
// Skipping other tests; code path should be the same for the rest.
}
+
+ @Test
+ public void completeDocumentOpenSocial2() throws Exception {
+ String head = "<script src=\"foo.js\"></script><style type=\"text/css\">body{color:red;}</style>";
+ String bodyAttr = " onload=\"foo();\"";
+ String body = "hello, world.";
+ String doc = new StringBuilder()
+ .append("<html><head>")
+ .append(head)
+ .append("</head><body").append(bodyAttr).append('>')
+ .append(body)
+ .append("</body></html>")
+ .toString();
+
+ GadgetContext context = new GadgetContext() {
+ @Override
+ public String getParameter(String name) {
+ if (name.equals("libs")) {
+ return "foo";
+ }
+ return null;
+ }
+ };
+
+ Gadget gadget = makeDefaultOpenSocial2Gadget(false)
+ .setContext(context);
+ expectFeatureCalls(gadget,
+ ImmutableList.<FeatureResource>of(),
+ ImmutableSet.of("foo"),
+ ImmutableList.of(inline("blah", "n/a")));
+
+ String rewritten = rewrite(gadget, doc);
+
+ Matcher matcher = DOCUMENT_SPLIT_PATTERN.matcher(rewritten);
+ assertTrue("Output is not valid HTML.", matcher.matches());
+ assertTrue("Doctype should have been rewritten to HTML5", matcher.group(BEFORE_HEAD_GROUP).contains("<!DOCTYPE html>"));
+
+ // Skipping other tests; code path should be the same for the rest.
+ }
@Test
public void bidiSettings() throws Exception {