Add two new ClientBundle DataResource annotations:
1. @DoNotEmbed which allows a DataResource to be designated as not embeddable
Although in pre IE8, where there is no data URL support, the following test is a no-op
DataResourceDoNotEmbedTest#testDoNotEmbedAnnotationMissingShouldEmbed
2. @MimeType(String) which allows a MIME Type to be specified for use in embedded resources
Related changes:
3. Allow MIME Types with double quotes as per RFC 4281 e.g. video/3gpp2; codecs="sevc, s263"
4. While in the neighborhood, adding @Document to ClientBundle's @Source annotation
Review at http://gwt-code-reviews.appspot.com/714801
Review by: robertvawter@google.com
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@8479 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/resources/client/ClientBundle.java b/user/src/com/google/gwt/resources/client/ClientBundle.java
index 7bbd76c..bf4b34e 100644
--- a/user/src/com/google/gwt/resources/client/ClientBundle.java
+++ b/user/src/com/google/gwt/resources/client/ClientBundle.java
@@ -18,6 +18,7 @@
import com.google.gwt.resources.ext.ResourceGeneratorType;
import com.google.gwt.resources.rg.BundleResourceGenerator;
+import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -37,6 +38,7 @@
* Specifies the classpath location of the resource or resources associated
* with the {@link ResourcePrototype}.
*/
+ @Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Source {
diff --git a/user/src/com/google/gwt/resources/client/DataResource.java b/user/src/com/google/gwt/resources/client/DataResource.java
index fd3d2cb..e87d0c6 100644
--- a/user/src/com/google/gwt/resources/client/DataResource.java
+++ b/user/src/com/google/gwt/resources/client/DataResource.java
@@ -18,12 +18,43 @@
import com.google.gwt.resources.ext.ResourceGeneratorType;
import com.google.gwt.resources.rg.DataResourceGenerator;
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
/**
- * A non-text resource.
+ * A non-text resource. Use {@link MimeType} to provide MIME Types for embedded
+ * resources which may not be determined automatically at compile time. Use
+ * {@link DoNotEmbed} to prevent a resource from being embedded.
*/
@ResourceGeneratorType(DataResourceGenerator.class)
public interface DataResource extends ResourcePrototype {
/**
+ * Specifies that the resource or resources associated with the
+ * {@link ResourcePrototype} should not be embedded into the compiled output.
+ * This may be useful, for exmaple, when it a particular browser or plugin is
+ * unable to handle RFC 2397 data URLs.
+ */
+ @Documented
+ @Retention(RetentionPolicy.RUNTIME)
+ @Target(ElementType.METHOD)
+ public @interface DoNotEmbed {
+ }
+
+ /**
+ * Specifies the MIME Type of the resource or resources associated with the
+ * {@link ResourcePrototype}.
+ */
+ @Documented
+ @Retention(RetentionPolicy.RUNTIME)
+ @Target(ElementType.METHOD)
+ public @interface MimeType {
+ String value();
+ }
+
+ /**
* Retrieves a URL by which the contents of the resource can be obtained. This
* will be an absolute URL.
*/
diff --git a/user/src/com/google/gwt/resources/ext/ResourceContext.java b/user/src/com/google/gwt/resources/ext/ResourceContext.java
index f327eee..7c5f2ff 100644
--- a/user/src/com/google/gwt/resources/ext/ResourceContext.java
+++ b/user/src/com/google/gwt/resources/ext/ResourceContext.java
@@ -31,9 +31,10 @@
* Depending on the optimizations made by the implementation of {@link #deploy},
* the resulting URL may or may not be compatible with standard
* {@link com.google.gwt.http.client.RequestBuilder} / XMLHttpRequest security
- * semantics. If the resource is intended to be used with XHR, the
- * <code>xhrCompatible</code> paramater should be set to <code>true</code> when
- * invoking {@link #deploy}.
+ * semantics. If the resource is intended to be used with XHR, or if there are
+ * other reasons why embedding the resource is undesirable such as known
+ * incompatibilities, the <code>forceExternal</code> parameter should be set to
+ * <code>true</code> when invoking {@link #deploy}.
* </p>
*/
public interface ResourceContext {
@@ -48,13 +49,34 @@
* resource
* @param mimeType the MIME type of the data being provided
* @param data the bytes to add to the output
- * @param xhrCompatible enforces compatibility with security restrictions if
- * the resource is intended to be accessed via an XMLHttpRequest.
+ * @param forceExternal prevents embedding of the resource, e.g. in case of
+ * known incompatibilities or for example to enforce compatibility
+ * with security restrictions if the resource is intended to be
+ * accessed via an XMLHttpRequest
* @return a Java expression which will evaluate to the location of the
- * provided resource at runtime.
+ * provided resource at runtime
*/
String deploy(String suggestedFileName, String mimeType, byte[] data,
- boolean xhrCompatible) throws UnableToCompleteException;
+ boolean forceExternal) throws UnableToCompleteException;
+
+ /**
+ * Cause a specific collection of bytes to be available in the program's
+ * compiled output. The return value of this method is a Java expression which
+ * will evaluate to the location of the resource at runtime. The exact format
+ * should not be depended upon.
+ *
+ * @param resource the resource to add to the compiled output
+ * @param forceExternal prevents embedding of the resource, e.g. in case of
+ * known incompatibilities or for example to enforce compatibility
+ * with security restrictions if the resource is intended to be
+ * accessed via an XMLHttpRequest
+ * @return a Java expression which will evaluate to the location of the
+ * provided resource at runtime
+ * @deprecated use {@link #deploy(URL, String, boolean)} instead
+ */
+ @Deprecated
+ String deploy(URL resource, boolean forceExternal)
+ throws UnableToCompleteException;
/**
* Cause a specific collection of bytes to be available in the program's
@@ -63,12 +85,15 @@
* should not be depended upon.
*
* @param resource the resource to add to the compiled output
- * @param xhrCompatible enforces compatibility with security restrictions if
- * the resource is intended to be accessed via an XMLHttpRequest.
+ * @param mimeType optional MIME Type to be used for an embedded resource
+ * @param forceExternal prevents embedding of the resource, e.g. in case of
+ * known incompatibilities or for example to enforce compatibility
+ * with security restrictions if the resource is intended to be
+ * accessed via an XMLHttpRequest
* @return a Java expression which will evaluate to the location of the
- * provided resource at runtime.
+ * provided resource at runtime
*/
- String deploy(URL resource, boolean xhrCompatible)
+ String deploy(URL resource, String mimeType, boolean forceExternal)
throws UnableToCompleteException;
/**
diff --git a/user/src/com/google/gwt/resources/rebind/context/AbstractResourceContext.java b/user/src/com/google/gwt/resources/rebind/context/AbstractResourceContext.java
index 5058147..1fd7bd7 100644
--- a/user/src/com/google/gwt/resources/rebind/context/AbstractResourceContext.java
+++ b/user/src/com/google/gwt/resources/rebind/context/AbstractResourceContext.java
@@ -89,13 +89,20 @@
this.cache = getCache(context.getTypeOracle());
}
- public String deploy(URL resource, boolean xhrCompatible)
+ @Deprecated
+ public String deploy(URL resource, boolean forceExternal)
+ throws UnableToCompleteException {
+ return deploy(resource, null, forceExternal);
+ }
+
+ public String deploy(URL resource, String mimeType, boolean forceExternal)
throws UnableToCompleteException {
String fileName = ResourceGeneratorUtil.baseName(resource);
byte[] bytes = Util.readURLAsBytes(resource);
try {
- return deploy(fileName, resource.openConnection().getContentType(),
- bytes, xhrCompatible);
+ String finalMimeType = (mimeType != null)
+ ? mimeType : resource.openConnection().getContentType();
+ return deploy(fileName, finalMimeType, bytes, forceExternal);
} catch (IOException e) {
getLogger().log(TreeLogger.ERROR,
"Unable to determine mime type of resource", e);
diff --git a/user/src/com/google/gwt/resources/rebind/context/InlineResourceContext.java b/user/src/com/google/gwt/resources/rebind/context/InlineResourceContext.java
index dfb2e29..e473b7d 100644
--- a/user/src/com/google/gwt/resources/rebind/context/InlineResourceContext.java
+++ b/user/src/com/google/gwt/resources/rebind/context/InlineResourceContext.java
@@ -33,18 +33,18 @@
@Override
public String deploy(String suggestedFileName, String mimeType, byte[] data,
- boolean xhrCompatible) throws UnableToCompleteException {
+ boolean forceExternal) throws UnableToCompleteException {
TreeLogger logger = getLogger();
// data: URLs are not compatible with XHRs on FF and Safari browsers
- if ((!xhrCompatible) && (data.length < MAX_INLINE_SIZE)) {
+ if ((!forceExternal) && (data.length < MAX_INLINE_SIZE)) {
logger.log(TreeLogger.DEBUG, "Inlining", null);
String base64Contents = toBase64(data);
// CHECKSTYLE_OFF
- String encoded = "\"data:" + mimeType + ";base64," + base64Contents
- + "\"";
+ String encoded = "\"data:" + mimeType.replaceAll("\"", "\\\\\"")
+ + ";base64," + base64Contents + "\"";
// CHECKSTYLE_ON
/*
diff --git a/user/src/com/google/gwt/resources/rebind/context/MhtmlResourceContext.java b/user/src/com/google/gwt/resources/rebind/context/MhtmlResourceContext.java
index 95cd917..fa4e73c 100644
--- a/user/src/com/google/gwt/resources/rebind/context/MhtmlResourceContext.java
+++ b/user/src/com/google/gwt/resources/rebind/context/MhtmlResourceContext.java
@@ -64,7 +64,7 @@
@Override
public String deploy(String suggestedFileName, String mimeType, byte[] data,
- boolean xhrCompatible) throws UnableToCompleteException {
+ boolean forceExternal) throws UnableToCompleteException {
String strongName = Util.computeStrongName(data);
String toReturn = strongNameToExpressions.get(strongName);
@@ -80,13 +80,13 @@
* as a fallback.
*/
String staticLocation = super.deploy(suggestedFileName, mimeType, data,
- xhrCompatible);
+ forceExternal);
/*
* ie6 doesn't treat XHRs to mhtml as cross-site, but ie8 does, so we'll
* play it safe here.
*/
- if (xhrCompatible || data.length > MAX_INLINE_SIZE) {
+ if (forceExternal || data.length > MAX_INLINE_SIZE) {
return staticLocation;
}
diff --git a/user/src/com/google/gwt/resources/rebind/context/StaticResourceContext.java b/user/src/com/google/gwt/resources/rebind/context/StaticResourceContext.java
index 4f9ce27..e4a93dd 100644
--- a/user/src/com/google/gwt/resources/rebind/context/StaticResourceContext.java
+++ b/user/src/com/google/gwt/resources/rebind/context/StaticResourceContext.java
@@ -40,7 +40,7 @@
}
public String deploy(String suggestedFileName, String mimeType, byte[] data,
- boolean xhrCompatible) throws UnableToCompleteException {
+ boolean forceExternal) throws UnableToCompleteException {
TreeLogger logger = getLogger();
GeneratorContext context = getGeneratorContext();
PropertyOracle propertyOracle = context.getPropertyOracle();
diff --git a/user/src/com/google/gwt/resources/rg/DataResourceGenerator.java b/user/src/com/google/gwt/resources/rg/DataResourceGenerator.java
index dea8314..8fda74f 100644
--- a/user/src/com/google/gwt/resources/rg/DataResourceGenerator.java
+++ b/user/src/com/google/gwt/resources/rg/DataResourceGenerator.java
@@ -18,7 +18,9 @@
import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.core.ext.typeinfo.JMethod;
+import com.google.gwt.resources.client.DataResource.MimeType;
import com.google.gwt.resources.client.DataResource;
+import com.google.gwt.resources.client.DataResource.DoNotEmbed;
import com.google.gwt.resources.ext.AbstractResourceGenerator;
import com.google.gwt.resources.ext.ResourceContext;
import com.google.gwt.resources.ext.ResourceGeneratorUtil;
@@ -44,8 +46,18 @@
throw new UnableToCompleteException();
}
+ // Determine if a MIME Type has been specified
+ MimeType mimeTypeAnnotation = method.getAnnotation(MimeType.class);
+ String mimeType = mimeTypeAnnotation != null
+ ? mimeTypeAnnotation.value() : null;
+
+ // Determine if resource should not be embedded
+ DoNotEmbed doNotEmbed = method.getAnnotation(DoNotEmbed.class);
+ boolean forceExternal = (doNotEmbed != null);
+
URL resource = resources[0];
- String outputUrlExpression = context.deploy(resource, false);
+ String outputUrlExpression = context.deploy(
+ resource, mimeType, forceExternal);
SourceWriter sw = new StringSourceWriter();
// Write the expression to create the subtype.
diff --git a/user/src/com/google/gwt/resources/rg/ImageResourceGenerator.java b/user/src/com/google/gwt/resources/rg/ImageResourceGenerator.java
index c78dab5..5f926dc 100644
--- a/user/src/com/google/gwt/resources/rg/ImageResourceGenerator.java
+++ b/user/src/com/google/gwt/resources/rg/ImageResourceGenerator.java
@@ -53,6 +53,7 @@
* Represents a file that contains multiple image regions.
*/
static class BundledImage extends DisplayedImage {
+ private static final String MIME_TYPE_IMAGE_PNG = "image/png";
private final ImageBundleBuilder builder;
private boolean dirty = false;
private Map<LocalizedImage, ImageRect> images;
@@ -108,6 +109,7 @@
return images.get(localizedByImageResource.get(image));
}
+ @Override
public void render(TreeLogger logger, ResourceContext context,
ClientBundleFields fields, RepeatStyle repeatStyle)
throws UnableToCompleteException {
@@ -135,8 +137,9 @@
logger.log(TreeLogger.ERROR, "Unknown RepeatStyle " + repeatStyle);
throw new UnableToCompleteException();
}
- URL normalContents = renderToTempFile(logger, builder, arranger);
- normalContentsUrlExpression = context.deploy(normalContents, false);
+ URL normalContents = renderToTempPngFile(logger, builder, arranger);
+ normalContentsUrlExpression = context.deploy(
+ normalContents, MIME_TYPE_IMAGE_PNG, false);
if (!rtlImages.isEmpty()) {
for (LocalizedImage rtlImage : rtlImages) {
@@ -146,10 +149,11 @@
tx.setTransform(-1, 0, 0, 1, imageRect.getWidth(), 0);
imageRect.setTransform(tx);
}
- URL rtlContents = renderToTempFile(logger, builder,
+ URL rtlContents = renderToTempPngFile(logger, builder,
new ImageBundleBuilder.IdentityArranger());
assert rtlContents != null;
- rtlContentsUrlExpression = context.deploy(rtlContents, false);
+ rtlContentsUrlExpression = context.deploy(
+ rtlContents, MIME_TYPE_IMAGE_PNG, false);
}
dirty = false;
@@ -293,17 +297,20 @@
this.rect = rect;
}
+ @Override
public ImageRect getImageRect(ImageResourceDeclaration image) {
return this.image.equals(image) ? rect : null;
}
+ @Override
public void render(TreeLogger logger, ResourceContext context,
ClientBundleFields fields, RepeatStyle repeatStyle)
throws UnableToCompleteException {
JClassType stringType = context.getGeneratorContext().getTypeOracle().findType(
String.class.getCanonicalName());
- String contentsExpression = context.deploy(localized.getUrl(), false);
+ String contentsExpression = context.deploy(
+ localized.getUrl(), null, false);
normalContentsFieldName = fields.define(stringType, "externalImage",
contentsExpression, true, true);
@@ -321,6 +328,7 @@
}
}
+ @Override
public void setRtlImage(LocalizedImage localized) {
if (this.localized.equals(localized)) {
isRtl = true;
@@ -425,7 +433,7 @@
/**
* Re-encode an image as a PNG to strip random header data.
*/
- private static URL renderToTempFile(TreeLogger logger,
+ private static URL renderToTempPngFile(TreeLogger logger,
ImageBundleBuilder builder, Arranger arranger)
throws UnableToCompleteException {
try {
diff --git a/user/test/com/google/gwt/resources/ResourcesSuite.java b/user/test/com/google/gwt/resources/ResourcesSuite.java
index 679ed4e..1c1085c 100644
--- a/user/test/com/google/gwt/resources/ResourcesSuite.java
+++ b/user/test/com/google/gwt/resources/ResourcesSuite.java
@@ -20,6 +20,8 @@
import com.google.gwt.resources.client.ImageResourceNoInliningTest;
import com.google.gwt.resources.client.ImageResourceTest;
import com.google.gwt.resources.client.NestedBundleTest;
+import com.google.gwt.resources.client.DataResourceDoNotEmbedTest;
+import com.google.gwt.resources.client.DataResourceMimeTypeTest;
import com.google.gwt.resources.client.TextResourceTest;
import com.google.gwt.resources.css.CssExternalTest;
import com.google.gwt.resources.css.CssNodeClonerTest;
@@ -49,7 +51,9 @@
suite.addTestSuite(ImageResourceTest.class);
suite.addTestSuite(ImageResourceNoInliningTest.class);
suite.addTestSuite(NestedBundleTest.class);
+ suite.addTestSuite(DataResourceDoNotEmbedTest.class);
suite.addTestSuite(ResourceGeneratorUtilTest.class);
+ suite.addTestSuite(DataResourceMimeTypeTest.class);
suite.addTestSuite(TextResourceTest.class);
suite.addTestSuite(UnknownAtRuleTest.class);
return suite;
diff --git a/user/test/com/google/gwt/resources/client/DataResourceDoNotEmbedTest.java b/user/test/com/google/gwt/resources/client/DataResourceDoNotEmbedTest.java
new file mode 100644
index 0000000..cb96a26
--- /dev/null
+++ b/user/test/com/google/gwt/resources/client/DataResourceDoNotEmbedTest.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.resources.client;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.junit.client.GWTTestCase;
+
+/**
+ * Tests for {@link DataResource.DoNotEmbed @DoNotEmbed} resource annotations.
+ */
+public class DataResourceDoNotEmbedTest extends GWTTestCase {
+
+ interface Resources extends ClientBundle {
+
+ /**
+ * This is a binary file containing four 0x00 bytes, which is small enough
+ * to be embeddable, and contains insufficient information for a
+ * determination of a recognizable MIME Type.
+ */
+ String FOUR_ZEROS_SOURCE = "fourZeros.dat";
+
+ // Purposely missing a @DoNotEmbed annotation
+ @Source(FOUR_ZEROS_SOURCE)
+ DataResource resourceDoNotEmbedAnnotationMissing();
+
+ @DataResource.DoNotEmbed
+ @Source(FOUR_ZEROS_SOURCE)
+ DataResource resourceDoNotEmbedAnnotationPresent();
+ }
+
+ /**
+ * RFC 2397 data URL scheme
+ */
+ private static final String DATA_URL_SCHEME = "data:";
+
+ /**
+ * HACK: Older versions of IE do not support RFC 2397 data URLs. See
+ * com/google/gwt/resources/Resources.gwt.xml
+ */
+ private static native boolean isPreIe8() /*-{
+ var ua = navigator.userAgent.toLowerCase();
+ return ua.indexOf("msie") != -1
+ && !(document.documentMode >= 8);
+ }-*/;
+
+ @Override
+ public String getModuleName() {
+ return "com.google.gwt.resources.Resources";
+ }
+
+ public void testDoNotEmbedAnnotationMissingShouldEmbed() {
+ if (isPreIe8()) {
+ // Skip this test for browsers which do not support data URLs
+ return;
+ }
+ Resources r = GWT.create(Resources.class);
+ String url = r.resourceDoNotEmbedAnnotationMissing().getUrl();
+ assertTrue("url '" + url + "' doesn't start with'" + DATA_URL_SCHEME + "'",
+ url.startsWith(DATA_URL_SCHEME));
+ }
+
+ public void testDoNotEmbedAnnotationPresentShouldNotEmbed() {
+ Resources r = GWT.create(Resources.class);
+ String url = r.resourceDoNotEmbedAnnotationPresent().getUrl();
+ assertFalse(
+ "url '" + url + "' mustn't start with'" + DATA_URL_SCHEME + "'",
+ url.startsWith(DATA_URL_SCHEME));
+ }
+}
diff --git a/user/test/com/google/gwt/resources/client/DataResourceMimeTypeTest.java b/user/test/com/google/gwt/resources/client/DataResourceMimeTypeTest.java
new file mode 100644
index 0000000..0c0dce8
--- /dev/null
+++ b/user/test/com/google/gwt/resources/client/DataResourceMimeTypeTest.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.resources.client;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.junit.client.GWTTestCase;
+
+/**
+ * Tests for {@link DataResource.MimeType @MimeType} resource annotations.
+ */
+public class DataResourceMimeTypeTest extends GWTTestCase {
+
+ interface Resources extends ClientBundle {
+
+ /**
+ * This is a binary file containing four 0x00 bytes, which is small enough
+ * to be embeddable, and contains insufficient information for a
+ * determination of a recognizable MIME Type.
+ */
+ String FOUR_ZEROS_SOURCE = "fourZeros.dat";
+
+ /**
+ * A simple MIME Type as per RFC 1521.
+ */
+ String MIME_TYPE_AUDIO_OGG = "audio/ogg";
+
+ /**
+ * MIME Type with a single codecs specification as per RFC 4281.
+ */
+ String MIME_TYPE_WITH_CODECS = "audio/3gpp; codecs=samr";
+
+ /**
+ * MIME Type with a multiple codecs specification as per RFC 4281.
+ */
+ String MIME_TYPE_WITH_QUOTED_CODECS_LIST =
+ "video/3gpp; codecs=\"s263, samr\"";
+
+ // Purposely missing a @MimeType annotation
+ @Source(FOUR_ZEROS_SOURCE)
+ DataResource resourceMimeTypeNoAnnotation();
+
+ @DataResource.MimeType(MIME_TYPE_AUDIO_OGG)
+ @Source(FOUR_ZEROS_SOURCE)
+ DataResource resourceMimeTypeAnnotationAudioOgg();
+
+ @DataResource.MimeType(MIME_TYPE_WITH_CODECS)
+ @Source(FOUR_ZEROS_SOURCE)
+ DataResource resourceMimeTypeAnnotationWithCodecs();
+
+ @DataResource.MimeType(MIME_TYPE_WITH_QUOTED_CODECS_LIST)
+ @Source(FOUR_ZEROS_SOURCE)
+ DataResource resourceMimeTypeAnnotationWithQuotedCodecsList();
+ }
+
+ @Override
+ public String getModuleName() {
+ return "com.google.gwt.resources.Resources";
+ }
+
+ public void testMimeTypeAnnotationMissingDefaultsToContentUnknown() {
+ Resources r = GWT.create(Resources.class);
+ String url = r.resourceMimeTypeNoAnnotation().getUrl();
+ if (url.startsWith("http")) {
+ // Skip test, MIME Type will be provided by the HTTP server
+ return;
+ }
+ assertEquals("data:content/unknown;base64,AAAAAA==", url);
+ }
+
+ public void testMimeTypeAnnotationOverridesDefaultMimeType() {
+ Resources r = GWT.create(Resources.class);
+ String url = r.resourceMimeTypeAnnotationAudioOgg().getUrl();
+ if (url.startsWith("http")) {
+ // Skip test, MIME Type will be provided by the HTTP server
+ return;
+ }
+ assertEquals("data:audio/ogg;base64,AAAAAA==", url);
+ }
+
+ public void testMimeTypeAnnotationWithCodecs() {
+ Resources r = GWT.create(Resources.class);
+ String url = r.resourceMimeTypeAnnotationWithCodecs().getUrl();
+ if (url.startsWith("http")) {
+ // Skip test, MIME Type will be provided by the HTTP server
+ return;
+ }
+ assertEquals("data:audio/3gpp; codecs=samr;base64,AAAAAA==", url);
+ }
+
+ public void testMimeTypeAnnotationWithQuotedCodecsList() {
+ Resources r = GWT.create(Resources.class);
+ String url = r.resourceMimeTypeAnnotationWithQuotedCodecsList().getUrl();
+ if (url.startsWith("http")) {
+ // Skip test, MIME Type will be provided by the HTTP server
+ return;
+ }
+ assertEquals("data:video/3gpp; codecs=\"s263, samr\";base64,AAAAAA==", url);
+ }
+}
diff --git a/user/test/com/google/gwt/resources/client/fourZeros.dat b/user/test/com/google/gwt/resources/client/fourZeros.dat
new file mode 100644
index 0000000..593f470
--- /dev/null
+++ b/user/test/com/google/gwt/resources/client/fourZeros.dat
Binary files differ
diff --git a/user/test/com/google/gwt/resources/rg/CssTestCase.java b/user/test/com/google/gwt/resources/rg/CssTestCase.java
index 2974160..a4c07ae 100644
--- a/user/test/com/google/gwt/resources/rg/CssTestCase.java
+++ b/user/test/com/google/gwt/resources/rg/CssTestCase.java
@@ -39,7 +39,7 @@
*/
public class CssTestCase extends TestCase {
/*
- * NB: This class is in the resources.rg package so that it can acess
+ * NB: This class is in the resources.rg package so that it can access
* package-protected methods in CssResourceGenerator.
*/
@@ -79,11 +79,17 @@
*/
private static class FakeContext implements ResourceContext {
public String deploy(String suggestedFileName, String mimeType,
- byte[] data, boolean xhrCompatible) throws UnableToCompleteException {
+ byte[] data, boolean forceExternal) throws UnableToCompleteException {
return null;
}
- public String deploy(URL resource, boolean xhrCompatible)
+ @Deprecated
+ public String deploy(URL resource, boolean forceExternal)
+ throws UnableToCompleteException {
+ return null;
+ }
+
+ public String deploy(URL resource, String mimeType, boolean forceExternal)
throws UnableToCompleteException {
return null;
}
@@ -170,10 +176,10 @@
+ "/";
URL testUrl = getClass().getClassLoader().getResource(
packagePath + testName + "_test.css");
- assertNotNull("Cauld not find testUrl", testUrl);
+ assertNotNull("Could not find testUrl", testUrl);
URL expectedUrl = getClass().getClassLoader().getResource(
packagePath + testName + "_expected.css");
- assertNotNull("Cauld not find testUrl", expectedUrl);
+ assertNotNull("Could not find testUrl", expectedUrl);
test(logger, testUrl, expectedUrl, visitors);