Add a way to disable image inlining on a per-image basis.
Patch by: bobv
Review by: rjrjr
Review at http://gwt-code-reviews.appspot.com/1451809
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@10268 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/resources/client/ImageResource.java b/user/src/com/google/gwt/resources/client/ImageResource.java
index 31aefde..0266048 100644
--- a/user/src/com/google/gwt/resources/client/ImageResource.java
+++ b/user/src/com/google/gwt/resources/client/ImageResource.java
@@ -56,6 +56,14 @@
int height() default -1;
/**
+ * Set to {@code true} to require the ImageResource to be downloaded as a
+ * separate resource at runtime. Specifically, this will disable the use of
+ * {@code data:} URLs or other bundling optimizations for the image. This
+ * can be used for infrequently-displayed images.
+ */
+ boolean preventInlining() default false;
+
+ /**
* This option affects the image bundling optimization to allow the image to
* be used with the {@link CssResource} {@code @sprite} rule where
* repetition of the image is desired.
diff --git a/user/src/com/google/gwt/resources/rg/ImageResourceGenerator.java b/user/src/com/google/gwt/resources/rg/ImageResourceGenerator.java
index 9f53c5d..1d86ad1 100644
--- a/user/src/com/google/gwt/resources/rg/ImageResourceGenerator.java
+++ b/user/src/com/google/gwt/resources/rg/ImageResourceGenerator.java
@@ -191,9 +191,11 @@
* bytes should be associated with.
*/
static class BundleKey extends StringKey {
- private static String key(ResourceContext context,
- ImageResourceDeclaration image) {
- if (image.getRepeatStyle() == RepeatStyle.Both) {
+ private static String key(ImageResourceDeclaration image, boolean isExternal) {
+ if (isExternal) {
+ return "External: " + image.get();
+ }
+ if (image.isPreventInlining() || image.getRepeatStyle() == RepeatStyle.Both) {
return "Unbundled: " + image.get();
}
return "Arranged: " + image.getRepeatStyle().toString();
@@ -201,13 +203,8 @@
private final RepeatStyle repeatStyle;
- public BundleKey(ImageResourceDeclaration image) {
- super("External: " + image.get());
- this.repeatStyle = image.getRepeatStyle();
- }
-
- public BundleKey(ResourceContext context, ImageResourceDeclaration image) {
- super(key(context, image));
+ public BundleKey(ImageResourceDeclaration image, boolean isExternal) {
+ super(key(image, isExternal));
this.repeatStyle = image.getRepeatStyle();
}
@@ -314,7 +311,7 @@
String.class.getCanonicalName());
String contentsExpression = context.deploy(
- localized.getUrl(), null, false);
+ localized.getUrl(), null, image.isPreventInlining());
normalContentsFieldName = fields.define(stringType, "externalImage",
contentsExpression, true, true);
@@ -326,7 +323,7 @@
byte[] rtlData = ImageBundleBuilder.toPng(logger, rect);
String rtlContentsUrlExpression = context.deploy(image.getName()
- + "_rtl.png", "image/png", rtlData, false);
+ + "_rtl.png", "image/png", rtlData, image.isPreventInlining());
rtlContentsFieldName = fields.define(stringType, "externalImage_rtl",
rtlContentsUrlExpression, true, true);
}
@@ -384,6 +381,10 @@
public boolean isFlipRtl() {
return options == null ? false : options.flipRtl();
}
+
+ public boolean isPreventInlining() {
+ return options == null ? false : options.preventInlining();
+ }
}
/**
@@ -474,7 +475,7 @@
sw.println('"' + name + "\",");
ImageResourceDeclaration image = new ImageResourceDeclaration(method);
- DisplayedImage bundle = getImage(context, image);
+ DisplayedImage bundle = getImage(image);
ImageRect rect = bundle.getImageRect(image);
assert rect != null : "No ImageRect ever computed for " + name;
@@ -542,10 +543,13 @@
LocalizedImage localizedImage;
ImageRect rect;
try {
- BundledImage bundledImage = (BundledImage) getImage(context, image);
+ BundledImage bundledImage = (BundledImage) getImage(image);
localizedImage = bundledImage.addImage(logger, context, image);
rect = bundledImage.getImageRect(image);
displayed = bundledImage;
+ if (image.isPreventInlining()) {
+ cannotBundle = true;
+ }
} catch (CannotBundleImageException e) {
cannotBundle = true;
localizedImage = e.getLocalizedImage();
@@ -587,7 +591,7 @@
}
ExternalImage externalImage = new ExternalImage(image, localizedImage,
rect);
- shared.externalImages.put(new BundleKey(image), externalImage);
+ shared.externalImages.put(new BundleKey(image, true), externalImage);
displayed = externalImage;
}
@@ -620,14 +624,13 @@
return sb.toString();
}
- private DisplayedImage getImage(ResourceContext context,
- ImageResourceDeclaration image) {
- DisplayedImage toReturn = shared.externalImages.get(new BundleKey(image));
+ private DisplayedImage getImage(ImageResourceDeclaration image) {
+ DisplayedImage toReturn = shared.externalImages.get(new BundleKey(image, true));
if (toReturn != null) {
return toReturn;
}
- BundleKey key = new BundleKey(context, image);
+ BundleKey key = new BundleKey(image, false);
toReturn = shared.bundledImages.get(key);
if (toReturn == null) {
BundledImage bundled = new BundledImage();
diff --git a/user/test/com/google/gwt/resources/client/ImageResourceTest.java b/user/test/com/google/gwt/resources/client/ImageResourceTest.java
index ac3e9ef..07f1420 100644
--- a/user/test/com/google/gwt/resources/client/ImageResourceTest.java
+++ b/user/test/com/google/gwt/resources/client/ImageResourceTest.java
@@ -31,7 +31,17 @@
* Tests ImageResource generation.
*/
public class ImageResourceTest extends GWTTestCase {
- static interface Resources extends ClientBundle {
+ interface ExternalResources extends ClientBundle {
+ @ImageOptions(preventInlining = true)
+ @Source("16x16.png")
+ ImageResource i16x16();
+
+ @ImageOptions(preventInlining = true)
+ @Source("32x32.png")
+ ImageResource i32x32();
+ }
+
+ interface Resources extends ClientBundle {
@Source("animated.gif")
ImageResource animated();
@@ -166,4 +176,22 @@
assertEquals(128, r.scaledUp().getWidth());
assertEquals(128, r.scaledUp().getHeight());
}
+
+ public void testPreventInlining() {
+ ExternalResources r = GWT.create(ExternalResources.class);
+ ImageResource a = r.i16x16();
+ ImageResource b = r.i32x32();
+
+ // Should never be a data URL
+ assertFalse(a.getURL().startsWith("data:"));
+ assertFalse(b.getURL().startsWith("data:"));
+ // Should be fetched from different URLs
+ assertFalse(a.getURL().equals(b.getURL()));
+
+ // No image packing
+ assertEquals(0, a.getTop());
+ assertEquals(0, a.getLeft());
+ assertEquals(0, b.getTop());
+ assertEquals(0, b.getLeft());
+ }
}