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);