diff options
author | Manolo Carrasco <manolo@apache.org> | 2015-01-03 20:03:49 +0100 |
---|---|---|
committer | Manolo Carrasco <manolo@apache.org> | 2015-01-03 20:48:21 +0100 |
commit | 85b16030e9636d01c98971b837818d182b3a657e (patch) | |
tree | 32182b051e3c0a6db50d34c4f13a74bbbc089dde | |
parent | 29e9e508cbf08a239f44f9d7df447cd32e9426b5 (diff) | |
download | gwtquery-85b16030e9636d01c98971b837818d182b3a657e.tar.gz gwtquery-85b16030e9636d01c98971b837818d182b3a657e.zip |
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.
14 files changed, 463 insertions, 390 deletions
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 @@ --> <define-linker name="stddoctype" class="com.google.gwt.query.linker.IFrameWithDocTypeLinker"/> + <!-- Let the user select type of animations to use --> + <define-property name="animation" values="js,transition" /> + <set-property name="animation" value="transition" /> + <set-property name="animation" value="js"> + <any> + <when-property-is name="user.agent" value="ie6" /> + <when-property-is name="user.agent" value="ie8" /> + <when-property-is name="user.agent" value="ie9" /> + </any> + </set-property> + <!-- Animations based on JS loops --> + <replace-with class="com.google.gwt.query.client.plugins.effects.ClipAnimation"> + <when-type-assignable + class="com.google.gwt.query.client.plugins.Effects.GQAnimation" /> + <when-property-is name="animation" value="js" /> + </replace-with> + <!-- Animations based on CSS3 transitions --> + <replace-with class="com.google.gwt.query.client.plugins.effects.TransitionsAnimation.TransitionsClipAnimation"> + <when-type-assignable + class="com.google.gwt.query.client.plugins.Effects.GQAnimation" /> + <when-property-is name="animation" value="transition" /> + </replace-with> </module> 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 @@ <!-- Inherit GQuery module --> <inherits name='com.google.gwt.query.Query'/> - + <source path="client"/> - <super-source path="super"/> - + <super-source path="super"/> + <!-- Detect whether querySelectorAll is available --> <define-property name="selectorCapability" values="native,js"/> <property-provider name="selectorCapability"> @@ -39,11 +39,9 @@ <when-property-is name="user.agent" value="ie6" /> </set-property> <set-property name="selectorCapability" value="native" > - <any> - <when-property-is name="user.agent" value="safari" /> - </any> + <when-property-is name="user.agent" value="safari" /> </set-property> - + <!-- Selector Engines --> <replace-with class="com.google.gwt.query.client.impl.SelectorEngineNativeMin"> <when-type-assignable class="com.google.gwt.query.client.impl.SelectorEngineImpl"/> 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: * <pre> * [0](com.google.gwt.query.client.plugins.QueuePlugin) <div>a1</div><div>a2</div> @@ -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 extends JavaScriptObject> 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> T getArgument(int argIdx, int pos, Class<? extends T> 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<Element> unique(JsArray<Element> 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 <code>name</code> - * defined. + * Check if an object has a property with <code>name</code> defined. + * It supports dots in the name meaning checking nested properties. + * + * Example: + * <pre> + * // Check whether a browser supports touch events + * hasProperty(window, "ontouchstart"); + * </pre> */ - 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) { @@ -481,6 +490,34 @@ public class JsUtils { }-*/; /** + * 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 + * <pre> + * // 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); + * </pre> + * + * @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> T jsni(String meth, Object... args) { + return runJavascriptFunction(null, meth, args); + } + + /** * Call via jsni any arbitrary function present in a Javascript object. * * It's thought for avoiding to create jsni methods to call external functions and @@ -494,20 +531,25 @@ public class JsUtils { * $(svg).appendTo(document); * </pre> * - * @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> T runJavascriptFunction(JavaScriptObject o, String meth, Object... args) { - return runJavascriptFunctionImpl(o, meth, JsObjectArray.create().add(args) - .<JsArrayMixed> cast()); + return runJavascriptFunctionImpl(o, meth, JsObjectArray.create().add(args).<JsArrayMixed>cast()); } - private static native <T> 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> 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<Effects> { // 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<Effects> { 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<Effects> { * @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,20 +202,26 @@ public class Effects extends QueuePlugin<Effects> { 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 * Attribute, CSS property, or color CSS property. @@ -309,53 +340,6 @@ public class Effects extends QueuePlugin<Effects> { } /** - * 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<Fx> 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<String, List<String>> map = new HashMap<String, List<String>>(); + + /** + * 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<String> 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<String, List<String>> 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<String> 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; * </pre> */ -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<String, List<String>> map = new HashMap<String, List<String>>(); - - public Transform(String s) { - parse(s); - } - - public String get(String prop) { - return listToStr(map.get(prop), ","); - } - - private String listToStr(List<String> 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<String, List<String>> e: map.entrySet()) { - if (has3d || !transform3dRegex.test(e.getKey())) { - String v = listToStr(e.getValue(), ","); - ret += (ret.isEmpty() ? "" : " ") + e.getKey() + "(" + v + ")"; - } - } - return ret; - } - - private List<String> 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> Transitions = GQuery.registerPlugin( Transitions.class, new Plugin<Transitions>() { @@ -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<String> filterTransitionPropertyNames(Properties p) { + public static List<String> filterTransitionPropertyNames(Properties p) { List<String> ret = new ArrayList<String>(); 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); * </pre> */ - 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<String> 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<String> 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 = $("<div style='top: 10px; width:50px'>foo</div>").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 = "<div id='test' style='color: #112233'>Test</div>"; $(e).html(html); |