Cherry picking r9602 into releases/2.2 git-svn-id: https://google-web-toolkit.googlecode.com/svn/releases/2.2@9612 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/canvas/Canvas.gwt.xml b/user/src/com/google/gwt/canvas/Canvas.gwt.xml index 3b1da45..ea94f47 100644 --- a/user/src/com/google/gwt/canvas/Canvas.gwt.xml +++ b/user/src/com/google/gwt/canvas/Canvas.gwt.xml
@@ -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>
diff --git a/user/src/com/google/gwt/canvas/client/Canvas.java b/user/src/com/google/gwt/canvas/client/Canvas.java index c6372b3..13a530b 100644 --- a/user/src/com/google/gwt/canvas/client/Canvas.java +++ b/user/src/com/google/gwt/canvas/client/Canvas.java
@@ -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; + } + } }
diff --git a/user/src/com/google/gwt/dom/client/PartialSupport.java b/user/src/com/google/gwt/dom/client/PartialSupport.java new file mode 100644 index 0000000..b8b4d20 --- /dev/null +++ b/user/src/com/google/gwt/dom/client/PartialSupport.java
@@ -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 { + +}
diff --git a/user/src/com/google/gwt/user/client/IsSupported.java b/user/src/com/google/gwt/user/client/IsSupported.java deleted file mode 100644 index f439842..0000000 --- a/user/src/com/google/gwt/user/client/IsSupported.java +++ /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 { - -}
diff --git a/user/test/com/google/gwt/canvas/client/CanvasTest.java b/user/test/com/google/gwt/canvas/client/CanvasTest.java index 147ddfe..d1b308a 100644 --- a/user/test/com/google/gwt/canvas/client/CanvasTest.java +++ b/user/test/com/google/gwt/canvas/client/CanvasTest.java
@@ -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 + 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()); } - - // 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")); } }
diff --git a/user/test/com/google/gwt/canvas/dom/client/Context2dTest.java b/user/test/com/google/gwt/canvas/dom/client/Context2dTest.java index 666ff46..259cf9a 100644 --- a/user/test/com/google/gwt/canvas/dom/client/Context2dTest.java +++ b/user/test/com/google/gwt/canvas/dom/client/Context2dTest.java
@@ -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");