Revision: 9602
Author: p...@google.com
Date: Mon Jan 24 12:09:10 2011
Log: Improve canvas for browsers (and permutations) with partial canvas
support.
Review at http://gwt-code-reviews.appspot.com/1296801
http://code.google.com/p/google-web-toolkit/source/detail?r=9602
Added:
/trunk/user/src/com/google/gwt/dom/client/PartialSupport.java
Deleted:
/trunk/user/src/com/google/gwt/user/client/IsSupported.java
Modified:
/trunk/user/src/com/google/gwt/canvas/Canvas.gwt.xml
/trunk/user/src/com/google/gwt/canvas/client/Canvas.java
/trunk/user/test/com/google/gwt/canvas/client/CanvasTest.java
/trunk/user/test/com/google/gwt/canvas/dom/client/Context2dTest.java
=======================================
--- /dev/null
+++ /trunk/user/src/com/google/gwt/dom/client/PartialSupport.java Mon Jan
24 12:09:10 2011
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2011 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.dom.client;
+
+/**
+ * Annotation for classes that are only supported on a limited set of
browsers.
+ *
+ * <p>
+ * By convention, classes annotated with PartialSupport will provide two
static
+ * methods:
+ * <ol>
+ * <li> <code>static boolean isSupported()</code> that returns whether
the
+ * feature is supported. </li>
+ * <li> <code>static YourType createIfSupported()</code> factory method
that
+ * returns a new feature if supported, or null otherwise. </li>
+ * </ol>
+ * </p>
+ */
+public @interface PartialSupport {
+
+}
=======================================
--- /trunk/user/src/com/google/gwt/user/client/IsSupported.java Thu Jan 13
05:38:38 2011
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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.user.client;
-
-/**
- * Interface for classes that are only supported on a limited set of
browsers.
- *
- * <p>
- * <span style="color:red">Experimental API: This API is still under
development
- * and is subject to change.
- * </span>
- * </p>
- *
- * By convention, classes that implement IsSupported will provide a static
- * method <code>boolean isSupported()</code> that checks whether the
feature is
- * supported at runtime.
- */
-public interface IsSupported {
-
-}
=======================================
--- /trunk/user/src/com/google/gwt/canvas/Canvas.gwt.xml Tue Nov 30
06:11:17 2010
+++ /trunk/user/src/com/google/gwt/canvas/Canvas.gwt.xml Mon Jan 24
12:09:10 2011
@@ -16,5 +16,30 @@
<module>
<inherits name="com.google.gwt.user.User"/>
<inherits name="com.google.gwt.canvas.dom.DOM"/>
+
+ <!-- Define the support property -->
+ <define-property name="canvasElementSupport" values="maybe,no" />
+
+ <!-- Give default support value of no -->
+ <set-property name="canvasElementSupport" value="no" />
+
+ <set-property name="canvasElementSupport" value="maybe">
+ <any>
+ <when-property-is name="user.agent" value="safari" />
+ <when-property-is name="user.agent" value="gecko1_8" />
+ <when-property-is name="user.agent" value="opera" />
+ </any>
+ </set-property>
+
+ <replace-with
class="com.google.gwt.canvas.client.Canvas.CanvasElementSupportDetectedMaybe">
+ <when-type-is
class="com.google.gwt.canvas.client.Canvas.CanvasElementSupportDetector" />
+ <when-property-is name="canvasElementSupport" value="maybe" />
+ </replace-with>
+
+ <replace-with
class="com.google.gwt.canvas.client.Canvas.CanvasElementSupportDetectedNo">
+ <when-type-is
class="com.google.gwt.canvas.client.Canvas.CanvasElementSupportDetector" />
+ <when-property-is name="canvasElementSupport" value="no" />
+ </replace-with>
+
<source path="client"/>
</module>
=======================================
--- /trunk/user/src/com/google/gwt/canvas/client/Canvas.java Thu Jan 13
05:38:38 2011
+++ /trunk/user/src/com/google/gwt/canvas/client/Canvas.java Mon Jan 24
12:09:10 2011
@@ -17,9 +17,10 @@
import com.google.gwt.canvas.dom.client.Context;
import com.google.gwt.canvas.dom.client.Context2d;
+import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.CanvasElement;
import com.google.gwt.dom.client.Document;
-import com.google.gwt.user.client.IsSupported;
+import com.google.gwt.dom.client.PartialSupport;
import com.google.gwt.user.client.ui.FocusWidget;
/**
@@ -31,25 +32,55 @@
* </span>
* </p>
*
- * This widget may not be supported on all browsers, see {@link
IsSupported}
+ * This widget may not be supported on all browsers.
*/
-public class Canvas extends FocusWidget implements IsSupported {
+@PartialSupport
+public class Canvas extends FocusWidget {
+ private static CanvasElementSupportDetector detector;
+
+ /**
+ * Return a new {@link Canvas} if supported, and null otherwise.
+ *
+ * @return a new {@link Canvas} if supported, and null otherwise
+ */
+ public static Canvas createIfSupported() {
+ if (detector == null) {
+ detector = GWT.create(CanvasElementSupportDetector.class);
+ }
+ if (!detector.isSupportedCompileTime()) {
+ return null;
+ }
+ CanvasElement element = Document.get().createCanvasElement();
+ if (!detector.isSupportedRunTime(element)) {
+ return null;
+ }
+ return new Canvas(element);
+ }
/**
* Runtime check for whether the canvas element is supported in this
browser.
- * See {@link IsSupported}
*
* @return whether the canvas element is supported
*/
- public static final native boolean isSupported() /*-{
- return !!$doc.createElement('canvas').getContext;
- }-*/;
+ public static boolean isSupported() {
+ if (detector == null) {
+ detector = GWT.create(CanvasElementSupportDetector.class);
+ }
+ if (!detector.isSupportedCompileTime()) {
+ return false;
+ }
+ CanvasElement element = Document.get().createCanvasElement();
+ if (!detector.isSupportedRunTime(element)) {
+ return false;
+ }
+ return true;
+ }
/**
- * Creates a Canvas.
+ * Protected constructor. Use {@link #createIfSupported()} to create a
Canvas.
*/
- public Canvas() {
- setElement(Document.get().createCanvasElement());
+ private Canvas(CanvasElement element) {
+ setElement(element);
}
/**
@@ -142,4 +173,67 @@
public String toDataUrl(String type) {
return getCanvasElement().toDataUrl(type);
}
-}
+
+ /**
+ * Detector for browser support of {@link CanvasElement}.
+ */
+ private static class CanvasElementSupportDetector {
+ /**
+ * Using a run-time check, return true if the {@link CanvasElement} is
+ * supported.
+ *
+ * @return true if supported, false otherwise.
+ */
+ static native boolean isSupportedRunTime(CanvasElement element) /*-{
+ return !!element.getContext;
+ }-*/;
+
+ /**
+ * Using a compile-time check, return true if {@link CanvasElement}
might
+ * be supported.
+ *
+ * @return true if might be supported, false otherwise.
+ */
+ boolean isSupportedCompileTime() {
+ // will be true in CanvasElementSupportDetectedMaybe
+ // will be false in CanvasElementSupportDetectedNo
+ return false;
+ }
+ }
+
+ /**
+ * Detector for permutations that might support {@link CanvasElement}.
+ */
+ @SuppressWarnings("unused")
+ private static class CanvasElementSupportDetectedMaybe
+ extends CanvasElementSupportDetector {
+ /**
+ * Using a compile-time check, return true if {@link CanvasElement}
might be
+ * supported.
+ *
+ * @return true if might be supported, false otherwise.
+ */
+ @Override
+ boolean isSupportedCompileTime() {
+ return true;
+ }
+ }
+
+ /**
+ * Detector for permutations that do not support {@link CanvasElement}.
+ */
+ @SuppressWarnings("unused")
+ private static class CanvasElementSupportDetectedNo
+ extends CanvasElementSupportDetector {
+ /**
+ * Using a compile-time check, return true if {@link CanvasElement}
might be
+ * supported.
+ *
+ * @return true if might be supported, false otherwise.
+ */
+ @Override
+ boolean isSupportedCompileTime() {
+ return false;
+ }
+ }
+}
=======================================
--- /trunk/user/test/com/google/gwt/canvas/client/CanvasTest.java Wed Dec
1 10:08:22 2010
+++ /trunk/user/test/com/google/gwt/canvas/client/CanvasTest.java Mon Jan
24 12:09:10 2011
@@ -45,10 +45,11 @@
@Override
protected void gwtSetUp() throws Exception {
- canvas1 = new Canvas();
- canvas2 = new Canvas();
- if (!canvas1.isSupported()) {
- return; // disable tests if not supported
+ canvas1 = Canvas.createIfSupported();
+ canvas2 = Canvas.createIfSupported();
+
+ if (canvas1 == null) {
+ return; // don't continue if not supported
}
RootPanel.get().add(canvas1);
@@ -57,24 +58,29 @@
@Override
protected void gwtTearDown() throws Exception {
+ if (canvas1 == null) {
+ return; // don't continue if not supported
+ }
+
RootPanel.get().remove(canvas1);
RootPanel.get().remove(canvas2);
}
/*
- * If the canvas has no pixels (i.e. either its horizontal dimension or
its vertical dimension
- * is zero) then the method must return the string "data:,". (This is
the shortest data: URL;
- * it represents the empty string in a text/plain resource.)
- *
+ * If the canvas has no pixels (i.e. either its horizontal dimension or
its
+ * vertical dimension is zero) then the method must return the string
+ * "data:,". (This is the shortest data: URL; it represents the empty
string
+ * in a text/plain resource.)
+ *
* Due to browser inconsistencies, we just check for data:something.
*/
public void testBlankDataUrl() {
- if (!canvas1.isSupported()) {
- return; // disable tests if not supported
+ if (canvas1 == null) {
+ return; // don't continue if not supported
}
- // Safari 3.0 does not support toDataURL(), so the following tests are
disabled for
- // Safari 3.0 and before.
+ // Safari 3.0 does not support toDataURL(), so the following tests are
+ // disabled for Safari 3.0 and before.
if (isWebkit525OrBefore()) {
return;
}
@@ -87,12 +93,34 @@
canvas1.setCoordinateSpaceWidth(0);
String dataUrl = canvas1.toDataUrl();
- assertTrue("toDataURL() should return data:something",
dataUrl.startsWith("data:"));
+ assertTrue("toDataURL() should return data:something",
+ dataUrl.startsWith("data:"));
+ }
+
+ public void testDataUrlWithType() {
+ if (canvas1 == null) {
+ return; // don't continue if not supported
+ }
+
+ // Safari 3.0 does not support toDataURL(), so the following tests are
+ // disabled for Safari 3.0 and before.
+ if (isWebkit525OrBefore()) {
+ return;
+ }
+
+ canvas1.setHeight("10px");
+ canvas1.setWidth("10px");
+ canvas1.setCoordinateSpaceHeight(10);
+ canvas1.setCoordinateSpaceWidth(10);
+
+ String dataUrl = canvas1.toDataUrl("image/png");
+ assertTrue("toDataURL(image/png) should return data:image/png[data]",
+ dataUrl.startsWith("data:image/png"));
}
public void testHeightAndWidth() {
- if (!canvas1.isSupported()) {
- return; // disable tests if not supported
+ if (canvas1 == null) {
+ return; // don't continue if not supported
}
canvas1.setHeight("40px");
@@ -117,8 +145,8 @@
}
public void testInternalHeightAndWidth() {
- if (!canvas1.isSupported()) {
- return; // disable tests if not supported
+ if (canvas1 == null) {
+ return; // don't continue if not supported
}
canvas1.setHeight("40px");
@@ -147,24 +175,14 @@
assertEquals(161, canvas1.getCoordinateSpaceWidth());
}
- public void testDataUrlWithType() {
- if (!canvas1.isSupported()) {
- return; // disable tests if not supported
- }
-
- // Safari 3.0 does not support toDataURL(), so the following tests are
disabled for
- // Safari 3.0 and before.
- if (isWebkit525OrBefore()) {
- return;
- }
-
- canvas1.setHeight("10px");
- canvas1.setWidth("10px");
- canvas1.setCoordinateSpaceHeight(10);
- canvas1.setCoordinateSpaceWidth(10);
-
- String dataUrl = canvas1.toDataUrl("image/png");
- assertTrue("toDataURL(image/png) should return data:image/png[data]",
- dataUrl.startsWith("data:image/png"));
+ public void testIsSupported() {
+ if (canvas1 == null) {
+ assertFalse(
+ "isSupported() should be false when createIfSupported() returns
null",
+ Canvas.isSupported());
+ } else {
+ assertTrue(
+ "isSupported() should be true when createIfSupported() returns
non-null", Canvas.isSupported());
+ }
}
}
=======================================
--- /trunk/user/test/com/google/gwt/canvas/dom/client/Context2dTest.java
Tue Dec 7 11:12:47 2010
+++ /trunk/user/test/com/google/gwt/canvas/dom/client/Context2dTest.java
Mon Jan 24 12:09:10 2011
@@ -54,10 +54,11 @@
@Override
protected void gwtSetUp() throws Exception {
- canvas1 = new Canvas();
- canvas2 = new Canvas();
- if (!canvas1.isSupported()) {
- return; // disable tests if not supported
+ canvas1 = Canvas.createIfSupported();
+ canvas2 = Canvas.createIfSupported();
+
+ if (canvas1 == null) {
+ return; // don't continue if not supported
}
RootPanel.get().add(canvas1);
@@ -71,8 +72,8 @@
}
public void testArc() {
- if (!canvas1.isSupported()) {
- return; // disable tests if not supported
+ if (canvas1 == null) {
+ return; // don't continue if not supported
}
canvas1.setHeight("40px");
@@ -95,8 +96,8 @@
}
public void testFillRect() {
- if (!canvas1.isSupported()) {
- return; // disable tests if not supported
+ if (canvas1 == null) {
+ return; // don't continue if not supported
}
// Safari 3.0 does not support getImageData(), so the following tests
are disabled for
@@ -150,8 +151,8 @@
}
public void testFillStyle() {
- if (!canvas1.isSupported()) {
- return; // disable tests if not supported
+ if (canvas1 == null) {
+ return; // don't continue if not supported
}
// get the 2d contexts
@@ -193,8 +194,8 @@
}
public void testFont() {
- if (!canvas1.isSupported()) {
- return; // disable tests if not supported
+ if (canvas1 == null) {
+ return; // don't continue if not supported
}
Context2d context = canvas1.getContext2d();
@@ -203,8 +204,8 @@
}
public void testGlobalAlpha() {
- if (!canvas1.isSupported()) {
- return; // disable tests if not supported
+ if (canvas1 == null) {
+ return; // don't continue if not supported
}
Context2d context = canvas1.getContext2d();
@@ -214,8 +215,8 @@
// This test currently fails on IE9 and is disabled.
public void disabled_testGlobalComposite() {
- if (!canvas1.isSupported()) {
- return; // disable tests if not supported
+ if (canvas1 == null) {
+ return; // don't continue if not supported
}
Context2d context = canvas1.getContext2d();
@@ -226,8 +227,8 @@
}
public void testGradient() {
- if (!canvas1.isSupported()) {
- return; // disable tests if not supported
+ if (canvas1 == null) {
+ return; // don't continue if not supported
}
// Safari 3.0 does not support getImageData(), so the following tests
are disabled for
@@ -272,8 +273,8 @@
}
public void testImageData() {
- if (!canvas1.isSupported()) {
- return; // disable tests if not supported
+ if (canvas1 == null) {
+ return; // don't continue if not supported
}
// Firefox 3.0 does not support createImageData(), so the following
tests are disabled
@@ -342,8 +343,8 @@
}
public void testIsPointInPath() {
- if (!canvas1.isSupported()) {
- return; // disable tests if not supported
+ if (canvas1 == null) {
+ return; // don't continue if not supported
}
canvas1.setHeight("40px");
@@ -363,8 +364,8 @@
}
public void testLines() {
- if (!canvas1.isSupported()) {
- return; // disable tests if not supported
+ if (canvas1 == null) {
+ return; // don't continue if not supported
}
canvas1.setHeight("40px");
@@ -390,8 +391,8 @@
}
public void testMiter() {
- if (!canvas1.isSupported()) {
- return; // disable tests if not supported
+ if (canvas1 == null) {
+ return; // don't continue if not supported
}
Context2d context = canvas1.getContext2d();
@@ -400,8 +401,8 @@
}
public void testPixelManipulation() {
- if (!canvas1.isSupported()) {
- return; // disable tests if not supported
+ if (canvas1 == null) {
+ return; // don't continue if not supported
}
// Safari 3.0 does not support getImageData(), so the following tests
are disabled for
@@ -431,8 +432,8 @@
}
public void testShadows() {
- if (!canvas1.isSupported()) {
- return; // disable tests if not supported
+ if (canvas1 == null) {
+ return; // don't continue if not supported
}
// Firefox 3.0 returns the incorrect shadowBlur value so the following
tests are disabled
@@ -459,8 +460,8 @@
}
public void testStrokeStyle() {
- if (!canvas1.isSupported()) {
- return; // disable tests if not supported
+ if (canvas1 == null) {
+ return; // don't continue if not supported
}
// get the 2d contexts
@@ -502,8 +503,8 @@
}
public void testText() {
- if (!canvas1.isSupported()) {
- return; // disable tests if not supported
+ if (canvas1 == null) {
+ return; // don't continue if not supported
}
canvas1.setHeight("40px");
--
http://groups.google.com/group/Google-Web-Toolkit-Contributors