From: Manolo Carrasco Date: Sat, 3 Jan 2015 19:03:49 +0000 (+0100) Subject: Allow to use customized animations. And Fixes. X-Git-Tag: gwtquery-project-1.4.3~2^2~3 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=85b16030e9636d01c98971b837818d182b3a657e;p=gwtquery.git Allow to use customized animations. And Fixes. In this patch there are many fixes found when playing with plugins. Also I have refactored Effects and Transitions plugins so as it is easier to extend and implement customized animations. Now we use properties instead of the Fx.css3 hack to disable modern animations. --- diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/Query.gwt.xml b/gwtquery-core/src/main/java/com/google/gwt/query/Query.gwt.xml index 08a6ff11..9bbc7431 100644 --- a/gwtquery-core/src/main/java/com/google/gwt/query/Query.gwt.xml +++ b/gwtquery-core/src/main/java/com/google/gwt/query/Query.gwt.xml @@ -172,4 +172,26 @@ --> + + + + + + + + + + + + + + + + + + + + diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/QueryMin.gwt.xml b/gwtquery-core/src/main/java/com/google/gwt/query/QueryMin.gwt.xml index 28cfea6c..f21b6ba5 100644 --- a/gwtquery-core/src/main/java/com/google/gwt/query/QueryMin.gwt.xml +++ b/gwtquery-core/src/main/java/com/google/gwt/query/QueryMin.gwt.xml @@ -22,10 +22,10 @@ - + - - + + @@ -39,11 +39,9 @@ - - - + - + diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/Function.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/Function.java index 063aaf38..bd5e9be1 100644 --- a/gwtquery-core/src/main/java/com/google/gwt/query/client/Function.java +++ b/gwtquery-core/src/main/java/com/google/gwt/query/client/Function.java @@ -35,11 +35,11 @@ public abstract class Function { * Utility method to get a string representation with the content * of the arguments array. It recursively visits arrays and inspect * object to print an appropriate representation of them. - * + * * It is very useful to debug arguments passed in nested promises. - * + * * It is protected so as it can be used in Inner functions. - * + * * Output example: *
    * [0](com.google.gwt.query.client.plugins.QueuePlugin) 
a1
a2
@@ -124,7 +124,7 @@ public abstract class Function { /** * Return the first element of the arguments list. - * + * * @deprecated use getArgument(idx) instead. */ @Deprecated @@ -143,7 +143,7 @@ public abstract class Function { /** * Utility method for safety getting a JavaScriptObject present at a certain * position in the list of arguments composed by arrays. - * + * */ @SuppressWarnings("unchecked") public T getArgumentJSO(int argIdx, int pos) { @@ -161,10 +161,10 @@ public abstract class Function { /** * Utility method for safety getting an array present at a certain * position in the list of arguments. - * + * * Useful for Deferred chains where result of each resolved * promise is set as an array in the arguments list. - * + * * Always returns an array. */ public Object[] getArgumentArray(int idx) { @@ -179,7 +179,7 @@ public abstract class Function { /** * Return the argument in the position idx or null if it doesn't exist. - * + * * Note: if the return type doesn't match the object, you * will get a casting exception. */ @@ -204,7 +204,7 @@ public abstract class Function { /** * Safety return the argument in the position idx. - * + * * If the element class is not of the requested type it returns null and * you don't get casting exeption. */ @@ -214,7 +214,7 @@ public abstract class Function { /** * Safety return the argument in the position idx. - * + * * If the element class is not of the requested type it returns null and * you don't get casting exeption. */ @@ -225,15 +225,15 @@ public abstract class Function { /** * Utility method for safety getting an object present at a certain * position in the list of arguments composed by arrays. - * + * * Useful for Deferred chains where result of each resolved * promise is set as an array in the arguments list. - * + * * When the object found in the array doesn't match the type required it returns a null. - * + * * Note: If type is null, we don't check the class of the object found andd you could * eventually get a casting exception. - * + * */ @SuppressWarnings("unchecked") public T getArgument(int argIdx, int pos, Class type) { @@ -302,7 +302,7 @@ public abstract class Function { /** * Return the index in a loop execution. - * + * * Used in GQuery.each() */ public int getIndex() { @@ -427,6 +427,8 @@ public abstract class Function { /** * Override this method for bound event handlers if you wish to deal with * per-handler user data. + * + * @return boolean false means stop propagation and prevent default */ public boolean f(Event e, Object... arg) { setArguments(arg); @@ -437,7 +439,7 @@ public abstract class Function { /** * Override this method for bound event handlers. * - * @return boolean: false means stop propagation and prevent default + * @return boolean false means stop propagation and prevent default */ public boolean f(Event e) { setEvent(e); diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/js/JsCache.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/js/JsCache.java index 13f6c4a3..2862ee0f 100644 --- a/gwtquery-core/src/main/java/com/google/gwt/query/client/js/JsCache.java +++ b/gwtquery-core/src/main/java/com/google/gwt/query/client/js/JsCache.java @@ -135,7 +135,7 @@ public class JsCache extends JavaScriptObject { } public final native boolean isEmpty() /*-{ - for (k in this) return false; + for (k in this) if (this.hasOwnProperty(k)) return false; return true; }-*/; @@ -240,7 +240,7 @@ public class JsCache extends JavaScriptObject { var key, keys=[]; // Chrome in DevMode sets '__gwt_ObjectId' to JS objects // GWT sets '$H' when calling getHashCode (see com/google/gwt/core/client/impl/Impl.java) - for(key in this) if (key != '__gwt_ObjectId' && key != '$H') keys.push(String(key)); + for(key in this) if (this.hasOwnProperty(key) && key != '__gwt_ObjectId' && key != '$H') keys.push(String(key)); return keys; }-*/; diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/js/JsUtils.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/js/JsUtils.java index 13520fe4..ecd7c6a8 100644 --- a/gwtquery-core/src/main/java/com/google/gwt/query/client/js/JsUtils.java +++ b/gwtquery-core/src/main/java/com/google/gwt/query/client/js/JsUtils.java @@ -15,10 +15,13 @@ */ package com.google.gwt.query.client.js; +import static com.google.gwt.query.client.GQuery.browser; + import com.google.gwt.core.client.GWT; import com.google.gwt.core.client.JavaScriptObject; import com.google.gwt.core.client.JsArray; import com.google.gwt.core.client.JsArrayMixed; +import com.google.gwt.core.client.JsonUtils; import com.google.gwt.dom.client.Document; import com.google.gwt.dom.client.Element; import com.google.gwt.dom.client.Node; @@ -90,9 +93,9 @@ public class JsUtils { * Default JsUtils implementation. */ public static class JsUtilsImpl { - public native Properties parseJSON(String json) /*-{ - return $wnd.JSON.parse(json); - }-*/; + public Properties parseJSON(String json) { + return JsonUtils.safeEval(json); + } public native String JSON2String(JavaScriptObject o) /*-{ return $wnd.JSON.stringify(o); @@ -129,15 +132,9 @@ public class JsUtils { * IE JsUtils implemetation. */ public static class JsUtilsImplIE6 extends JsUtilsImpl { - public static final native Properties evalImpl(String properties) /*-{ - return eval(properties); - }-*/; - @Override public Properties parseJSON(String json) { - // No checks to the passed string so json should be - // a well-formed json string. - return evalImpl("(" + json + ")"); + return JsonUtils.unsafeEval(json); } @Override @@ -190,7 +187,7 @@ public class JsUtils { @Override public JsArray unique(JsArray a) { // in IE6 XML elements does not support adding hashId to the object - if (a.length() > 0 && isXML(a.get(0))) { + if (browser.ie6 && isXML(a.get(0))) { return a; } return super.unique(a); @@ -299,11 +296,23 @@ public class JsUtils { } /** - * Check if an object has already a property with name name - * defined. + * Check if an object has a property with name defined. + * It supports dots in the name meaning checking nested properties. + * + * Example: + *
+   *  // Check whether a browser supports touch events
+   *  hasProperty(window, "ontouchstart");
+   * 
*/ - public static native boolean hasProperty(JavaScriptObject o, String name) /*-{ + public static native boolean hasProperty(JavaScriptObject o, String name)/*-{ return o && name in o; + var p = name.split('.'); + for (var i in p) { + if (!(o && p[i] in o)) return false; + o = o[p[i]]; + } + return true; }-*/; /** @@ -348,7 +357,7 @@ public class JsUtils { /** * Return whether a node is detached to the DOM. - * + * * Be careful : This method works only on node that should be inserted within the body node. */ public static boolean isDetached(Node n) { @@ -480,6 +489,34 @@ public class JsUtils { return a }-*/; + /** + * Run any arbitrary function in javascript scope using the window as the base object. + * It checks the existence of the function and object hierarchy before executing it. + * It's very useful in order to avoid writing jsni blocks for very simple snippets. + * + * Note that GWT 3.0 jsinterop will come with a method similar, so we might deprecate + * this in the future. + * + * Example + *
+   *  // Create a svg node in our document.
+   *  Element svg = jsni("document.createElementNS", "http://www.w3.org/2000/svg", "svg");
+   *  // Append it to the dom
+   *  $(svg).appendTo(document);
+   *  // show the svg element in the debug console
+   *  jsni("console.log", svg);
+   * 
+ * + * @param meth the literal name of the function to call, dot separators are allowed. + * @param args an array with the arguments to pass to the function. + * @return the java ready boxed object returned by the jsni method or null, if the + * call return a number we will get a Double, if it returns a boolean we get a java + * Boolean, strings comes as java String, otherwise we get the javascript object. + */ + public static T jsni(String meth, Object... args) { + return runJavascriptFunction(null, meth, args); + } + /** * Call via jsni any arbitrary function present in a Javascript object. * @@ -494,20 +531,25 @@ public class JsUtils { * $(svg).appendTo(document); *
* - * @param o the javascript object where the function is. - * @param meth the literal name of the function to call. + * @param o the javascript object where the function is, it it is null we use window. + * @param meth the literal name of the function to call, dot separators are allowed. * @param args an array with the arguments to pass to the function. - * @return the javascript object returned by the jsni method or null. + * @return the java ready boxed object returned by the jsni method or null, if the + * call return a number we will get a Double, if it returns a boolean we get a java + * Boolean, strings comes as java String, otherwise we get the javascript object. */ public static T runJavascriptFunction(JavaScriptObject o, String meth, Object... args) { - return runJavascriptFunctionImpl(o, meth, JsObjectArray.create().add(args) - . cast()); + return runJavascriptFunctionImpl(o, meth, JsObjectArray.create().add(args).cast()); } - private static native T runJavascriptFunctionImpl(JavaScriptObject o, String meth, - JsArrayMixed args) /*-{ - return (f = o && o[meth]) - && @com.google.gwt.query.client.js.JsUtils::isFunction(*)(f) + private static native T runJavascriptFunctionImpl(JavaScriptObject o, String meth, JsArrayMixed args) /*-{ + var f = o || window, p = meth.split('.'); + for (var i in p) { + o = f; + f = f[p[i]]; + if (!f) return null; + } + return @com.google.gwt.query.client.js.JsUtils::isFunction(*)(f) && @com.google.gwt.query.client.js.JsCache::gwtBox(*)([f.apply(o, args)]); }-*/; @@ -542,7 +584,7 @@ public class JsUtils { /** * Returns a QueryString representation of a JavascriptObject. - * + * * TODO: jquery implementation accepts a second parameter (traditional) */ public static String param(JavaScriptObject js) { diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/Effects.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/Effects.java index acb7fc17..762f4444 100755 --- a/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/Effects.java +++ b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/Effects.java @@ -16,16 +16,14 @@ package com.google.gwt.query.client.plugins; import com.google.gwt.animation.client.Animation; +import com.google.gwt.core.client.GWT; import com.google.gwt.dom.client.Element; import com.google.gwt.query.client.Function; import com.google.gwt.query.client.GQuery; import com.google.gwt.query.client.Properties; -import com.google.gwt.query.client.plugins.effects.ClipAnimation; -import com.google.gwt.query.client.plugins.effects.ClipAnimation.Direction; import com.google.gwt.query.client.plugins.effects.Fx; import com.google.gwt.query.client.plugins.effects.PropertiesAnimation.Easing; import com.google.gwt.query.client.plugins.effects.PropertiesAnimation.EasingCurve; -import com.google.gwt.query.client.plugins.effects.TransitionsAnimation.TransitionsClipAnimation; /** * Effects plugin for Gwt Query. @@ -42,14 +40,34 @@ public class Effects extends QueuePlugin { // Each Animation is associated to one element protected Element e; protected Properties prps; + protected Easing easing; + protected Function[] funcs; + protected Effects g; - protected GQAnimation setElement(Element element) { + public GQAnimation setElement(Element element) { e = element; + g = $(e).as(Effects); return this; } - protected GQAnimation setProperties(Properties properties) { + public GQAnimation setProperties(Properties properties) { prps = properties == null ? Properties.create() : properties; + if (prps.defined("easing")) { + try { + easing = EasingCurve.valueOf(prps.getStr("easing")); + } catch (Exception ignore) { + } + } + return this; + } + + public GQAnimation setEasing(Easing ease) { + easing = ease != null ? ease : EasingCurve.swing; + return this; + } + + public GQAnimation setCallback(Function... f) { + funcs = f; return this; } @@ -92,12 +110,20 @@ public class Effects extends QueuePlugin { super(gq); } - private void queueAnimation(final Element e, final GQAnimation anim, final int duration) { + /** + * Queue an animation for an element. + * + * The goal of this method is to reuse animations. + * @param e + * @param anim + * @param duration + */ + public void queueAnimation(final GQAnimation anim, final int duration) { if (isOff()) { anim.onStart(); anim.onComplete(); } else { - queue(e, DEFAULT_NAME, new Function() { + queue(anim.e, DEFAULT_NAME, new Function() { public void cancel(Element e) { Animation anim = (Animation) data(e, GQAnimation.ACTUAL_ANIMATION, null); if (anim != null) { @@ -169,7 +195,6 @@ public class Effects extends QueuePlugin { * @param easing the easing function to use for the transition */ public Effects animate(Object stringOrProperties, int duration, Easing easing, Function... funcs) { - final Properties p = (stringOrProperties instanceof String) ? (Properties) $$((String) stringOrProperties) : (Properties) stringOrProperties; @@ -177,19 +202,25 @@ public class Effects extends QueuePlugin { if (p.getStr("duration") != null) { duration = p.getInt("duration"); } - duration = Math.abs(duration); for (Element e : elements()) { - if (Fx.css3) { - new TransitionsClipAnimation(easing, e, p, funcs).run(duration); - } else { - queueAnimation(e, new ClipAnimation(easing, e, p, funcs), duration); - } + GQAnimation a = createAnimation(); + a.setEasing(easing).setProperties(p).setElement(e).setCallback(funcs); + queueAnimation(a, duration); } return this; } + /** + * Override this to create plugins with customized animation implementation. + * + * By default it uses deferred binding. + */ + protected GQAnimation createAnimation() { + return GWT.create(GQAnimation.class); + } + /** * * The animate() method allows you to create animation effects on any numeric @@ -308,53 +339,6 @@ public class Effects extends QueuePlugin { return animate(stringOrProperties, duration, EasingCurve.linear, funcs); } - /** - * Animate the set of matched elements using the clip or scale property. It is possible to show or - * hide a set of elements, specify the direction of the animation and the start corner of the - * effect. Finally it executes the set of functions passed as arguments. - * - * @deprecated use animate() instead - */ - @Deprecated - public Effects clip(ClipAnimation.Action a, ClipAnimation.Corner c, - ClipAnimation.Direction d, Function... f) { - return clip(a, c, d, Speed.DEFAULT, f); - } - - /** - * Animate the set of matched elements using the clip or scale property. It is possible to show or - * hide a set of elements, specify the direction of the animation and the start corner of the - * effect. Finally it executes the set of functions passed as arguments. - * - * @deprecated use animate() instead - */ - @Deprecated - public Effects clip(final ClipAnimation.Action a, - final ClipAnimation.Corner c, final ClipAnimation.Direction d, - final int duration, final Function... f) { - for (Element e : elements()) { - if (Fx.css3) { - new TransitionsClipAnimation(e, a, c, d, null, null, f).run(duration); - } else { - queueAnimation(e, new ClipAnimation(e, a, c, d, f), duration); - } - } - return this; - } - - /** - * Animate the set of matched elements using the clip or scale property. It is possible to show or - * hide a set of elements, specify the direction of the animation and the start corner of the - * effect. Finally it executes the set of functions passed as arguments. - * - * @deprecated use animate() instead - */ - @Deprecated - public Effects clip(ClipAnimation.Action a, ClipAnimation.Corner c, - Function... f) { - return clip(a, c, Direction.BIDIRECTIONAL, Speed.DEFAULT, f); - } - /** * Reveal all matched elements by adjusting the clip or scale property firing an optional callback * after completion. The effect goes from the center to the perimeter. diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/effects/ClipAnimation.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/effects/ClipAnimation.java index 627c0b47..6794d1c1 100755 --- a/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/effects/ClipAnimation.java +++ b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/effects/ClipAnimation.java @@ -15,12 +15,11 @@ */ package com.google.gwt.query.client.plugins.effects; -import com.google.gwt.dom.client.Element; -import com.google.gwt.query.client.Function; import com.google.gwt.query.client.GQuery; import com.google.gwt.query.client.Properties; import com.google.gwt.query.client.js.JsUtils; import com.google.gwt.query.client.plugins.Effects; +import com.google.gwt.query.client.plugins.Effects.GQAnimation; /** * Animation which uses the css clip property to show/hide an element. @@ -55,15 +54,10 @@ public class ClipAnimation extends PropertiesAnimation { private Corner corner; private Direction direction; private GQuery back = Effects.$(); - private Effects g; private Action currentAction; - public ClipAnimation(Element elem, Properties p, Function... funcs) { - this(null, elem, p, funcs); - } - - public ClipAnimation(Easing easing, Element elem, Properties p, Function... funcs) { - super(easing, elem, p, funcs); + @Override + public GQAnimation setProperties(Properties p) { corner = Corner.CENTER; try { corner = Corner.valueOf(getNormalizedValue("clip-origin", p)); @@ -78,26 +72,13 @@ public class ClipAnimation extends PropertiesAnimation { action = Action.valueOf(getNormalizedValue("clip-action", p)); } catch (Exception e) { } - g = GQuery.$(e).as(Effects.Effects); + return super.setProperties(p); } public static String getNormalizedValue(String value, Properties p) { return JsUtils.hyphenize(p.getStr(value)).replace("-", "_").toUpperCase(); } - public ClipAnimation(Element elem, Action a, Corner c, Direction d, Easing easing, - Properties p, final Function... funcs) { - super(easing, elem, p, funcs); - this.action = a; - this.corner = c; - this.direction = d; - g = GQuery.$(e).as(Effects.Effects); - } - - public ClipAnimation(Element elem, Action a, Corner c, Direction d, final Function... funcs) { - this(elem, a, c, d, null, Properties.create(), funcs); - } - @Override public void onComplete() { super.onComplete(); diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/effects/Fx.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/effects/Fx.java index b81a9de9..1e202e33 100644 --- a/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/effects/Fx.java +++ b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/effects/Fx.java @@ -33,8 +33,6 @@ public class Fx { */ public static boolean off = false; - public static boolean css3 = Transitions.transition != null; - /** * A pojo to store css3 transition values. */ diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/effects/PropertiesAnimation.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/effects/PropertiesAnimation.java index e5a4c8f6..ceb6b556 100644 --- a/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/effects/PropertiesAnimation.java +++ b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/effects/PropertiesAnimation.java @@ -15,12 +15,8 @@ */ package com.google.gwt.query.client.plugins.effects; -import static com.google.gwt.query.client.GQuery.$; - import com.google.gwt.dom.client.Element; -import com.google.gwt.query.client.Function; import com.google.gwt.query.client.GQuery; -import com.google.gwt.query.client.Properties; import com.google.gwt.query.client.js.JsObjectArray; import com.google.gwt.query.client.plugins.Effects; import com.google.gwt.query.client.plugins.Effects.GQAnimation; @@ -159,7 +155,7 @@ public class PropertiesAnimation extends GQAnimation { .compile("^([+-]=)?([0-9+-.]+)(.*)?$"); protected static final RegExp REGEX_NON_PIXEL_ATTRS = - RegExp.compile("z-?index|font-?weight|opacity|zoom|line-?height|scale|rotation|^\\$", "i"); + RegExp.compile("z-?index|font-?weight|opacity|zoom|line-?height|scale|rotat|^\\$", "i"); private static final RegExp REGEX_COLOR_ATTR = RegExp.compile(".*color$", "i"); @@ -173,7 +169,6 @@ public class PropertiesAnimation extends GQAnimation { if (REGEX_COLOR_ATTR.test(key)) { return computeFxColorProp(e, key, val); } - return computeFxNumericProp(e, key, val, hidden); } @@ -288,32 +283,7 @@ public class PropertiesAnimation extends GQAnimation { return new Fx(key, val, start, end, unit, rkey); } - protected Easing easing; protected JsObjectArray effects; - private Function[] funcs; - private Effects g; - - public PropertiesAnimation(Element elem, Properties p, Function... funcs) { - this(null, elem, p, funcs); - } - - public PropertiesAnimation(Easing ease, Element elem, Properties p, Function... funcs) { - try { - easing = EasingCurve.valueOf(p.getStr("easing")); - } catch (Exception e) { - } - if (easing == null) { - easing = ease; - } - if (easing == null) { - easing = EasingCurve.swing; - } - this.funcs = funcs; - setProperties(p); - setElement(elem); - - g = $(e).as(Effects.Effects); - } @Override public void onCancel() { @@ -329,7 +299,7 @@ public class PropertiesAnimation extends GQAnimation { @Override public void onComplete() { super.onComplete(); - for (int i = 0; i < effects.length(); i++) { + for (int i = 0; effects != null && i < effects.length(); i++) { Fx fx = effects.get(i); if ("hide".equals(fx.value)) { g.hide(); diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/effects/Transform.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/effects/Transform.java new file mode 100644 index 00000000..641a02cc --- /dev/null +++ b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/effects/Transform.java @@ -0,0 +1,165 @@ +/* + * Copyright 2014, The gwtquery team. + * + * 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.query.client.plugins.effects; + +import com.google.gwt.dom.client.Element; +import com.google.gwt.query.client.GQuery; +import com.google.gwt.regexp.shared.MatchResult; +import com.google.gwt.regexp.shared.RegExp; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map.Entry; + +/** + * A dictionary class with all the properties of an element transform + * which is able to return the correct syntax for setting the css transform + * property. + */ +public class Transform { + + private static final String TRANSFORM = "_t_"; + + protected static final RegExp transformRegex = RegExp.compile("^(scale([XYZ]|)|translate([XYZ]|3d)|rotate([XYZ]|3d)?|perspective|skew[XYZ]|x|y)$"); + private static final RegExp transform3dRegex = RegExp.compile("^(rotate([XYZ]|3d)|perspective)$"); + + private HashMap> map = new HashMap>(); + + /** + * Return the Transform dictionary object of a element. + */ + public static Transform getInstance(Element e) { + return getInstance(e, null); + } + + public static boolean isTransform(String propName) { + return transformRegex.test(propName); + } + + /** + * Return the Transform dictionary object of an element, but reseting + * historical values and setting them to the initial value passed. + */ + public static Transform getInstance(Element e, String initial) { + Transform t = GQuery.data(e, TRANSFORM); + if (t == null || initial != null && !initial.isEmpty()) { + t = new Transform(initial); + GQuery.data(e, TRANSFORM, t); + } + return t; + } + + public Transform(String s) { + parse(s); + } + + public String get(String prop) { + return listToStr(map.get(prop), ","); + } + + private String listToStr(List l, String sep) { + String v = ""; + if (l != null) { + for (String s : l) { + v += (v.isEmpty() ? "" : sep) + s; + } + } + return v; + } + + private void parse(String s) { + if (s != null) { + RegExp re = RegExp.compile("([a-zA-Z0-9]+)\\((.*?)\\)", "g"); + for (MatchResult r = re.exec(s); r != null; r = re.exec(s)) { + setFromString(r.getGroup(1), r.getGroup(2)); + } + } + } + + public void set(String prop, String ...val) { + setter(prop, val); + } + + public void setFromString(String prop, String ...val) { + if (val.length == 1) { + String[] vals = val[0].split("[\\s*,\\s*]"); + set(prop, vals); + } else { + set(prop, val); + } + } + + private void setter(String prop, String ...val) { + if (prop.matches("(rotate[XYZ]?|skew[XYZ])")) { + map.put(prop, unit(val[0], "deg")); + } else if ("scale".equals(prop)) { + String x = val.length < 1 ? "1" : val[0]; + String y = val.length < 2 ? x : val[1]; + map.put(prop, Arrays.asList(x, y)); + } else if ("perspective".equals(prop)) { + map.put(prop, unit(val[0], "px")); + } else if ("x".equals(prop)) { + setter("translate", val[0], null); + } else if ("y".equals(prop)) { + setter("translate", null, val[0]); + } else if (prop.matches("(translate[XYZ])")) { + map.put(prop, unit(val[0], "px")); + } else if ("translate".equals(prop)) { + if (map.get("translateX") == null) { + map.put("translateX", unit("0", "px")); + } + if (val[0] != null) { + map.put("translateX", unit(val[0], "px")); + } + if (map.get("translateY") == null) { + map.put("translateY", unit("0", "px")); + } + if (val.length > 1 && val[1] != null) { + map.put("translateY", unit(val[1], "px")); + } + if (map.get("translateZ") == null) { + map.put("translateZ", unit("0", "px")); + } + if (val.length > 2 && val[2] != null) { + map.put("translateZ", unit(val[0], "px")); + } + map.put("translate", Arrays.asList(map.get("translateX").get(0), map.get("translateY").get(0), map.get("translateY").get(0))); + } else { + map.put(prop, unit(val[0], "")); + } + } + + /** + * Converts the dictionary to a transition css string. + */ + public String toString() { + // purposely using string addition, since my last tests demonstrate + // that string addition performs better than string builders in gwt-prod. + String ret = ""; + for (Entry> e: map.entrySet()) { + if (Transitions.has3d || !transform3dRegex.test(e.getKey())) { + String v = listToStr(e.getValue(), ","); + ret += (ret.isEmpty() ? "" : " ") + e.getKey() + "(" + v + ")"; + } + } + return ret; + } + + private List unit(String val, String unit) { + return Arrays.asList(val + (val.endsWith(unit) ? "" : unit)); + } +} \ No newline at end of file diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/effects/Transitions.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/effects/Transitions.java index cefedceb..b939a9b1 100644 --- a/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/effects/Transitions.java +++ b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/effects/Transitions.java @@ -28,26 +28,22 @@ */ package com.google.gwt.query.client.plugins.effects; -import com.google.gwt.core.client.Duration; +import com.google.gwt.dom.client.Document; import com.google.gwt.dom.client.Element; import com.google.gwt.dom.client.Style; import com.google.gwt.query.client.Function; import com.google.gwt.query.client.GQuery; import com.google.gwt.query.client.Properties; import com.google.gwt.query.client.js.JsUtils; +import com.google.gwt.query.client.plugins.Effects; import com.google.gwt.query.client.plugins.Plugin; import com.google.gwt.query.client.plugins.effects.PropertiesAnimation.Easing; import com.google.gwt.query.client.plugins.effects.PropertiesAnimation.EasingCurve; -import com.google.gwt.regexp.shared.MatchResult; +import com.google.gwt.query.client.plugins.effects.TransitionsAnimation.TransitionsClipAnimation; import com.google.gwt.regexp.shared.RegExp; -import com.google.gwt.user.client.DOM; -import com.google.gwt.user.client.Timer; import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; import java.util.List; -import java.util.Map.Entry; /** * Transitions and transformation plugin for gQuery. @@ -69,127 +65,24 @@ import java.util.Map.Entry; * */ -public class Transitions extends GQuery { - - /** - * A dictionary class with all the properties of an element transform - * which is able to return the correct syntax for setting css properties. - */ - public static class Transform { - - private static final RegExp transform3dRegex = RegExp.compile("^(rotate([XY]|3d)|perspective)$"); - - private HashMap> map = new HashMap>(); - - public Transform(String s) { - parse(s); - } - - public String get(String prop) { - return listToStr(map.get(prop), ","); - } - - private String listToStr(List l, String sep) { - String v = ""; - if (l != null) { - for (String s : l) { - v += (v.isEmpty() ? "" : sep) + s; - } - } - return v; - } - - private void parse(String s) { - if (s != null) { - RegExp re = RegExp.compile("([a-zA-Z0-9]+)\\((.*?)\\)", "g"); - for (MatchResult r = re.exec(s); r != null; r = re.exec(s)) { - setFromString(r.getGroup(1), r.getGroup(2)); - } - } - } - - public void set(String prop, String ...val) { - setter(prop, val); - } - - public void setFromString(String prop, String ...val) { - if (val.length == 1) { - String[] vals = val[0].split("[\\s*,\\s*]"); - set(prop, vals); - } else { - set(prop, val); - } - } - - private void setter(String prop, String ...val) { - if (prop.matches("(rotate[XY]?|skew[XY])")) { - map.put(prop, unit(val[0], "deg")); - } else if ("scale".equals(prop)) { - String x = val.length < 1 ? "1" : val[0]; - String y = val.length < 2 ? x : val[1]; - map.put(prop, Arrays.asList(x, y)); - } else if ("perspective".equals(prop)) { - map.put(prop, unit(val[0], "px")); - } else if ("x".equals(prop)) { - setter("translate", val[0], null); - } else if ("y".equals(prop)) { - setter("translate", null, val[0]); - } else if ("translate".equals(prop)) { - if (map.get("translateX") == null) { - map.put("translateX", unit("0", "px")); - } - if (val[0] != null) { - map.put("translateX", unit(val[0], "px")); - } - if (map.get("translateY") == null) { - map.put("translateY", unit("0", "px")); - } - if (val[1] != null) { - map.put("translateY", unit(val[1], "px")); - } - map.put("translate", Arrays.asList(map.get("translateX").get(0), map.get("translateY").get(0))); - } - } - - /** - * Converts the dictionary to a transition css string. - */ - public String toString() { - // purposely using string addition, since my last tests demonstrate - // that string addition performs better than string builders in gwt-prod. - String ret = ""; - for (Entry> e: map.entrySet()) { - if (has3d || !transform3dRegex.test(e.getKey())) { - String v = listToStr(e.getValue(), ","); - ret += (ret.isEmpty() ? "" : " ") + e.getKey() + "(" + v + ")"; - } - } - return ret; - } - - private List unit(String val, String unit) { - return Arrays.asList(val + (val.endsWith(unit) ? "" : unit)); - } - } +public class Transitions extends Effects { // Used to check supported properties in the browser - private static Style divStyle = DOM.createDiv().getStyle(); + protected static final Style divStyle = Document.get().createDivElement().getStyle(); - private static final String prefix = browser.msie ? "ms" : browser.opera ? "o" : browser.mozilla ? "moz" : browser.webkit ? "webkit" : ""; + public static final String prefix = browser.msie ? "ms" : browser.opera ? "o" : browser.mozilla ? "moz" : browser.webkit ? "webkit" : ""; private static final String transform = getVendorPropertyName("transform"); - private static final String TRANSFORM = "_t_"; private static final String transformOrigin = getVendorPropertyName("transformOrigin"); - protected static final RegExp transformRegex = RegExp.compile("^(scale|translate|rotate([XY]|3d)?|perspective|skew[XY]|x|y)$"); protected static final String transition = getVendorPropertyName("transition"); // passing an invalid transition property in chrome, makes disable all transitions in the element - private static final RegExp invalidTransitionNamesRegex = RegExp.compile("^(.*transform.*|duration|easing|delay|clip-.*)$"); + public static final RegExp invalidTransitionNamesRegex = RegExp.compile("^(.*transform.*|duration|function|easing|delay|clip-.*)$"); - private static final String transitionDelay = getVendorPropertyName("transitionDelay"); - private static final String transitionEnd = browser.mozilla || browser.msie ? "transitionend" : (prefix + "transitionEnd"); + protected static final String transitionDelay = getVendorPropertyName("transitionDelay"); + protected static final String transitionEnd = browser.mozilla || browser.msie ? "transitionend" : (prefix + "TransitionEnd"); - public static boolean has3d = supportsTransform3d(); + public static final boolean has3d = supportsTransform3d(); public static final Class Transitions = GQuery.registerPlugin( Transitions.class, new Plugin() { @@ -198,7 +91,8 @@ public class Transitions extends GQuery { } }); - private static String getVendorPropertyName(String prop) { + public static String getVendorPropertyName(String prop) { + assert divStyle != null; // we prefer vendor specific names by default String vendorProp = JsUtils.camelize("-" + prefix + "-" + prop); if (JsUtils.hasProperty(divStyle, vendorProp)) { @@ -215,7 +109,7 @@ public class Transitions extends GQuery { } private static String property(String prop) { - if (transformRegex.test(prop)) { + if (Transform.isTransform(prop)) { return transform; } return prop.replaceFirst("^(margin|padding).+$", "$1"); @@ -238,16 +132,15 @@ public class Transitions extends GQuery { @Override public String css(String prop, boolean force) { if ("transform".equals(prop)) { - return isEmpty() ? "" : getTransform(get(0), null).toString(); + return isEmpty() ? "" : Transform.getInstance(get(0), null).toString(); } else if ("transformOrigin".equals(prop)) { return super.css(transformOrigin, force); } else if ("transition".equals(prop)) { return super.css(transition, force); - } else if (transformRegex.test(prop)) { - return isEmpty() ? "" : getTransform(get(0), null).get(prop); + } else if (Transform.isTransform(prop)) { + return isEmpty() ? "" : Transform.getInstance(get(0), null).get(prop); } else { - String ret = super.css(prop, force); - return ret; + return super.css(prop, force); } } @@ -255,16 +148,16 @@ public class Transitions extends GQuery { public Transitions css(String prop, String value) { if ("transform".equals(prop)) { for (Element e : elements()) { - Transform t = getTransform(e, value); + Transform t = Transform.getInstance(e, value); getStyleImpl().setStyleProperty(e, transform, t.toString()); } } else if ("transformOrigin".equals(prop)) { super.css(transformOrigin, value); } else if ("transition".equals(prop)) { super.css(transition, value); - } else if (transformRegex.test(prop)) { + } else if (Transform.isTransform(prop)) { for (Element e : elements()) { - Transform t = getTransform(e, null); + Transform t = Transform.getInstance(e, null); t.setFromString(prop, value); getStyleImpl().setStyleProperty(e, transform, t.toString()); } @@ -274,7 +167,7 @@ public class Transitions extends GQuery { return this; } - private List filterTransitionPropertyNames(Properties p) { + public static List filterTransitionPropertyNames(Properties p) { List ret = new ArrayList(); for (String s : p.keys()) { if (invalidTransitionNamesRegex.test(s)) { @@ -295,15 +188,6 @@ public class Transitions extends GQuery { return ret; } - private Transform getTransform(Element e, String initial) { - Transform t = data(e, TRANSFORM); - if (t == null || initial != null && !initial.isEmpty()) { - t = new Transform(initial); - data(e, TRANSFORM, t); - } - return t; - } - /** * The transition() method allows you to create animation effects on any numeric HTML Attribute, * CSS property, or color using CSS3 transformations and transitions. @@ -320,49 +204,17 @@ public class Transitions extends GQuery { .transition("{x: +100, width: +40px}", 2000, EasingCurve.easeOut); * */ - public Transitions transition(Object stringOrProperties, final int duration, final Easing easing, final int delay, final Function... funcs) { - if (isEmpty()) { - return this; - } - - final Properties cssProps = (stringOrProperties instanceof String) - ? (Properties) $$((String) stringOrProperties) - : (Properties) stringOrProperties; - - final String ease = easing == null ? "ease" : easing.toString(); - final List transProps = filterTransitionPropertyNames(cssProps); - final double queuedAt = delay > 0 ? Duration.currentTimeMillis() : 0; - - // Use gQuery queue, so as we can chain transitions, animations etc. - queue(new Function() { - public void f() { - // This is called once per element - final String oldTransitionValue = $(this).css(transition); - // Recompute delay based on the time spent in the queue - int d = Math.max(0, delay - (int) (Duration.currentTimeMillis() - queuedAt)); - // Generate transition value - String attribs = duration + "ms" + " " + ease + " " + d + "ms"; - String newTransitionValue = ""; - for (String s : transProps) { - newTransitionValue += (newTransitionValue.isEmpty() ? "" : ", ") + s + " " + attribs; - } - - final Transitions thisTrans = $(this).as(Transitions); - // Configure animation using transition property - thisTrans.css(transition, newTransitionValue); - // Set all css properties for this transition using the css method in this class - thisTrans.css(cssProps); - - // TODO: Use transitionEnd events once GQuery supports non-bit events - // last time I tried, setting 'transitionEnd' made custom events fail (slideEnter) - new Timer() { - public void run() { - thisTrans.css(transition, oldTransitionValue).each(funcs).dequeue(); - } - }.schedule(d + duration); + public Transitions transition(Object stringOrProperties, final int duration, final Easing easing, + final int delay, final Function... funcs) { + if (!isEmpty()) { + Properties p = (stringOrProperties instanceof String) + ? $$((String) stringOrProperties) + : (Properties) stringOrProperties; + for (Element e : elements()) { + queueAnimation(new TransitionsClipAnimation().setEasing(easing).setProperties(p) + .setElement(e).setCallback(funcs), duration); } - }); - + } return this; } @@ -380,4 +232,9 @@ public class Transitions extends GQuery { public Transitions transition(Object stringOrProperties, int duration, String easing, int delay) { return transition(stringOrProperties, duration, EasingCurve.valueOf(easing), delay); } + + @Override + protected GQAnimation createAnimation() { + return new TransitionsAnimation(); + } } diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/effects/TransitionsAnimation.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/effects/TransitionsAnimation.java index 4636b12e..5a79e311 100644 --- a/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/effects/TransitionsAnimation.java +++ b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/effects/TransitionsAnimation.java @@ -20,13 +20,16 @@ import static com.google.gwt.query.client.GQuery.$$; import static com.google.gwt.query.client.plugins.effects.ClipAnimation.getNormalizedValue; import com.google.gwt.dom.client.Element; -import com.google.gwt.query.client.Function; import com.google.gwt.query.client.Properties; +import com.google.gwt.query.client.plugins.Effects.GQAnimation; import com.google.gwt.query.client.plugins.effects.ClipAnimation.Action; import com.google.gwt.query.client.plugins.effects.ClipAnimation.Corner; import com.google.gwt.query.client.plugins.effects.ClipAnimation.Direction; import com.google.gwt.query.client.plugins.effects.Fx.TransitFx; import com.google.gwt.regexp.shared.MatchResult; +import com.google.gwt.user.client.Timer; + +import java.util.List; /** * Animation effects on any numeric CSS3 property or transformation @@ -44,12 +47,8 @@ public class TransitionsAnimation extends PropertiesAnimation { private Direction direction; private Action currentAction; - public TransitionsClipAnimation(Element elem, Properties p, Function... funcs) { - this(null, elem, p, funcs); - } - - public TransitionsClipAnimation(Easing easing, Element elem, Properties p, Function... funcs) { - super(easing, elem, p, funcs); + @Override + public GQAnimation setProperties(Properties p) { corner = Corner.CENTER; try { corner = Corner.valueOf(getNormalizedValue("clip-origin", p)); @@ -64,14 +63,7 @@ public class TransitionsAnimation extends PropertiesAnimation { action = Action.valueOf(getNormalizedValue("clip-action", p)); } catch (Exception e) { } - } - - public TransitionsClipAnimation(Element elem, Action a, Corner c, Direction d, Easing easing, - Properties p, final Function... funcs) { - super(easing, elem, p, funcs); - this.action = a; - this.corner = c; - this.direction = d; + return super.setProperties(p); } public void onStart() { @@ -119,7 +111,7 @@ public class TransitionsAnimation extends PropertiesAnimation { g.hide(); } g.css("transformOrigin", ""); - g.css("transform", "scale(1 1)"); + g.css("transform", ""); } } @@ -139,7 +131,7 @@ public class TransitionsAnimation extends PropertiesAnimation { } String cur = g.css(key, true); - String trsStart = cur, trsEnd = trsStart; + String trsStart = cur.matches("auto|initial") ? "" : cur, trsEnd = trsStart; if ("show".equals(val)) { g.saveCssAttrs(key); @@ -196,18 +188,26 @@ public class TransitionsAnimation extends PropertiesAnimation { protected Transitions g; protected int delay = 0; + private String oldTransitionValue; - public TransitionsAnimation(Element elem, Properties p, Function... funcs) { - this(null, elem, p, funcs); + @Override + public GQAnimation setProperties(Properties p) { + delay = p.getInt("delay"); + return super.setProperties(p); } - public TransitionsAnimation(Easing easing, Element elem, Properties p, Function... funcs) { - super(easing, elem, p, funcs); - delay = p.getInt("delay"); - g = $(e).as(Transitions.Transitions); + @Override + public GQAnimation setElement(Element elem) { + g = $(elem).as(Transitions.Transitions); + return super.setElement(elem); } - private Properties getFxProperties(boolean isStart) { + public TransitionsAnimation setDelay(int delay) { + this.delay = delay; + return this; + } + + public Properties getFxProperties(boolean isStart) { Properties p = $$(); for (int i = 0; i < effects.length(); i++) { TransitFx fx = (TransitFx) effects.get(i); @@ -221,7 +221,7 @@ public class TransitionsAnimation extends PropertiesAnimation { @Override protected Fx getFx(Element e, String key, String val, boolean hidden) { - return computeFxProp(e, key, val, hidden); + return Transitions.invalidTransitionNamesRegex.test(key) ? null : computeFxProp(e, key, val, hidden); } @Override @@ -229,21 +229,43 @@ public class TransitionsAnimation extends PropertiesAnimation { } @Override + public void onComplete() { + g.css(Transitions.transition, oldTransitionValue); + super.onComplete(); + } + public void run(int duration) { + // Calculate all Fx values for this animation onStart(); - // Compute initial properties Properties p = getFxProperties(true); - g.css(p) - // Some browsers need after setting initial properties re-flow (FF 24.4.0). - .offset(); + g.css(p); + // Some browsers need re-flow after setting initial properties (FF 24.4.0). + g.offset(); // Compute final properties p = getFxProperties(false); - g.transition(p, duration, easing, delay, new Function() { - public void f() { + + // Save old transition value + oldTransitionValue = g.css(Transitions.transition); + + // Set new transition value + String newTransitionValue = ""; + List transProps = Transitions.filterTransitionPropertyNames(p); + String attribs = duration + "ms" + " " + easing + " " + delay + "ms"; + for (String s : transProps) { + newTransitionValue += (newTransitionValue.isEmpty() ? "" : ", ") + s + " " + attribs; + } + g.css(Transitions.transition, newTransitionValue); + + // Set new css properties so as the element is animated + g.css(p); + + // Wait until transition has finished to run finish animation and dequeue + new Timer() { + public void run() { onComplete(); } - }); + }.schedule(delay + duration); } } diff --git a/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryDeferredTestGwt.java b/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryDeferredTestGwt.java index a5a502ea..1ab2ca24 100644 --- a/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryDeferredTestGwt.java +++ b/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryDeferredTestGwt.java @@ -263,7 +263,6 @@ public class GQueryDeferredTestGwt extends GWTTestCase { $("button", e) .click(new Function(){public void f() { - Fx.css3 = false; $("p", e).append(" Started... "); GQuery.when( effect ).done(new Function(){public void f() { $("p", e).append(" Finished! "); @@ -291,7 +290,6 @@ public class GQueryDeferredTestGwt extends GWTTestCase { $("button", e) .bind("click", new Function(){public void f() { - Fx.css3 = false; $("p", e).append(" Started... "); $("div",e).each(new Function(){public Object f(Element e, int i) { diff --git a/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryEffectsTestGwt.java b/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryEffectsTestGwt.java index da19afb1..9658e98b 100644 --- a/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryEffectsTestGwt.java +++ b/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryEffectsTestGwt.java @@ -15,7 +15,9 @@ */ package com.google.gwt.query.client; -import static com.google.gwt.query.client.GQuery.*; +import static com.google.gwt.query.client.GQuery.$; +import static com.google.gwt.query.client.GQuery.$$; +import static com.google.gwt.query.client.GQuery.Effects; import com.google.gwt.core.client.Scheduler; import com.google.gwt.core.client.Scheduler.RepeatingCommand; @@ -24,12 +26,13 @@ import com.google.gwt.junit.DoNotRunWith; import com.google.gwt.junit.Platform; import com.google.gwt.junit.client.GWTTestCase; import com.google.gwt.query.client.GQuery.Offset; -import com.google.gwt.query.client.plugins.effects.Fx; +import com.google.gwt.query.client.plugins.Effects.GQAnimation; import com.google.gwt.query.client.plugins.effects.Fx.ColorFx; import com.google.gwt.query.client.plugins.effects.Fx.TransitFx; import com.google.gwt.query.client.plugins.effects.PropertiesAnimation; import com.google.gwt.query.client.plugins.effects.PropertiesAnimation.EasingCurve; import com.google.gwt.query.client.plugins.effects.TransitionsAnimation; +import com.google.gwt.query.client.plugins.effects.TransitionsAnimation.TransitionsClipAnimation; import com.google.gwt.user.client.Timer; import com.google.gwt.user.client.ui.HTML; import com.google.gwt.user.client.ui.Label; @@ -55,7 +58,6 @@ public class GQueryEffectsTestGwt extends GWTTestCase { } public void gwtSetUp() { - Fx.css3 = false; if (e == null) { testPanel = new HTML(); RootPanel.get().add(testPanel); @@ -259,9 +261,8 @@ public class GQueryEffectsTestGwt extends GWTTestCase { .toString()); prop1 = GQuery.$$("marginTop: '-110px', marginLeft: '-110px', top: '50%', left: '50%', width: '174px', height: '174px', padding: '20px'"); - PropertiesAnimation an = new PropertiesAnimation(EasingCurve.swing, g.get(0), prop1); - an.onStart(); - an.onComplete(); + GQAnimation an = new PropertiesAnimation().setEasing(EasingCurve.swing).setElement(g.get(0)).setProperties(prop1); + an.run(0); assertEquals("cssprop=marginTop value=0 start=-110 end=0 unit=px", PropertiesAnimation.computeFxProp(g.get(0), "marginTop", "0", false) @@ -285,9 +286,8 @@ public class GQueryEffectsTestGwt extends GWTTestCase { .toString()); prop1 = GQuery.$$("marginTop: '0', marginLeft: '0', top: '0%', left: '0%', width: '100px', height: '100px', padding: '5px'"); - an = new PropertiesAnimation(EasingCurve.swing, g.get(0), prop1); - an.onStart(); - an.onComplete(); + an = new PropertiesAnimation().setEasing(EasingCurve.swing).setElement(g.get(0)).setProperties(prop1); + an.run(0); assertEquals("cssprop=marginTop value=-110px start=0 end=-110 unit=px", PropertiesAnimation.computeFxProp(g.get(0), "marginTop", "-110px", @@ -312,6 +312,40 @@ public class GQueryEffectsTestGwt extends GWTTestCase { .toString()); } + public void testTransitionsAnimation() { + final GQuery m = $("
foo
").appendTo(e); + + TransitionsClipAnimation a = new TransitionsClipAnimation(); + a.setElement(m.get(0)); + a.setProperties($$("clip-action: show, clip-origin: top-right, scaleZ: 0.5, delay: 30, left: 100, top: +=50, rotateZ: 90, rotateY: 45deg, easing: custom, duration: 400")); + a.onStart(); + + Properties from = a.getFxProperties(true); + Properties to = a.getFxProperties(false); + + // HTMLUnit and chrome return different decimal part + assertEquals("0px", from.getStr("left").replace(".0", "")); + assertEquals("100px", to.getStr("left").replace(".0", "")); + assertEquals("10px", from.getStr("top").replace(".0", "")); + assertEquals("60px", to.getStr("top").replace(".0", "")); + assertEquals("0", from.getStr("rotateZ").replace(".0", "")); + assertEquals("90", to.getStr("rotateZ").replace(".0", "")); + assertEquals("0", from.getStr("rotateY").replace(".0", "")); + assertEquals("45", to.getStr("rotateY").replace(".0", "")); + assertEquals("0 0", from.getStr("scale").replace(".0", "")); + assertEquals("1 1", to.getStr("scale")); + assertNull(to.get("delay")); + assertNull(to.get("easing")); + + // HTMLUnit and chrome return different values + assertTrue(m.attr("style").contains("rigin: 100% 0%") || m.attr("style").contains("rigin: right top")); + assertTrue(m.attr("style").contains("top: 10px")); + + a.run(1); + assertTrue(m.attr("style").contains("rigin: 100% 0%") || m.attr("style").contains("rigin: right top")); + assertTrue(m.attr("style").contains("top: 60px")); + } + public void testColorEffectParsing(){ String html = "
Test
"; $(e).html(html);