]> source.dussan.org Git - gwtquery.git/commitdiff
Completion of Effects framework
authorRay Cromwell <cromwellian@gmail.com>
Wed, 6 May 2009 20:57:23 +0000 (20:57 +0000)
committerRay Cromwell <cromwellian@gmail.com>
Wed, 6 May 2009 20:57:23 +0000 (20:57 +0000)
gwtquery-core/src/main/java/com/google/gwt/query/client/Effects.java
gwtquery-core/src/main/java/com/google/gwt/query/client/GQuery.java
gwtquery-core/src/main/java/com/google/gwt/query/client/Properties.java

index a15948c7016b53213ab1c01a6386b7825a7360e8..e7bd17181a6600a2c6cb0b8b0cd8db8038985f0d 100644 (file)
@@ -15,7 +15,6 @@
  */\r
 package com.google.gwt.query.client;\r
 \r
-import com.google.gwt.animation.client.Animation;\r
 import com.google.gwt.dom.client.Element;\r
 import com.google.gwt.dom.client.NodeList;\r
 import com.google.gwt.core.client.Duration;\r
@@ -27,52 +26,66 @@ import com.google.gwt.user.client.Timer;
 public class Effects extends GQuery {\r
 \r
   /**\r
-   * Used to register the plugin.\r
+   * Built in easing functions.\r
    */\r
-  private static class EffectsPlugin implements Plugin<Effects> {\r
-\r
-    public Effects init(GQuery gq) {\r
-      return new Effects(gq.get());\r
-    }\r
-  }\r
-\r
-  public static final Class<Effects> Effects = Effects.class;\r
-\r
-  static {\r
-    GQuery.registerPlugin(Effects.class, new EffectsPlugin());\r
-  }\r
-\r
   public enum Easing {\r
 \r
+    /**\r
+     * Linear easing function.\r
+     */\r
     LINEAR {\r
       public double ease(double p, double n, double firstNum, double diff) {\r
         return firstNum + diff * p;\r
       }\r
-    }, SWING {\r
+    },\r
+    /**\r
+     * Sinusoidal easing function.\r
+     */\r
+    SWING {\r
       public double ease(double p, double n, double firstNum, double diff) {\r
         return ((-Math.cos(p * Math.PI) / 2) + 0.5) * diff + firstNum;\r
       }\r
     };\r
 \r
+    /**\r
+     * Override to implement custom easing functions.\r
+     */\r
     public abstract double ease(double p, double n, double firstNum,\r
         double diff);\r
   }\r
 \r
+  /**\r
+   * Build in speed constants.\r
+   */\r
   public enum Speed {\r
 \r
-    SLOW(600), FAST(200), DEFAULT(400);\r
-\r
-    public int getDuration() {\r
-      return duration;\r
-    }\r
+    /**\r
+     * 600 millisecond animation.\r
+     */\r
+    SLOW(600),\r
+    /**\r
+     * 200 millisecond animation.\r
+     */\r
+    FAST(200),\r
+    /**\r
+     * 400 millisecond animation.\r
+     */\r
+    DEFAULT(400);\r
 \r
     private final int duration;\r
 \r
     Speed(int dur) {\r
       this.duration = dur;\r
     }\r
+\r
+    public int getDuration() {\r
+      return duration;\r
+    }\r
   }\r
 \r
+  /**\r
+   * Utility class.\r
+   */\r
   protected class PropFx {\r
 \r
     public SpeedOpts opt;\r
@@ -100,9 +113,31 @@ public class Effects extends GQuery {
           || elem.getStyle().getProperty(prop) == null)) {\r
         return elem.getPropertyDouble(prop);\r
       }\r
-      double r = Double.parseDouble(GQuery.curCSS(elem, prop, force));\r
+      double r = parseDouble(GQuery.curCSS(elem, prop, force));\r
       return !Double.isNaN(r) && r > -10000 ? r\r
-          : Double.parseDouble(GQuery.curCSS(elem, prop, false));\r
+          : parseDouble(GQuery.curCSS(elem, prop, false));\r
+    }\r
+\r
+    public void hide() {\r
+      opt.cache.put(prop, elem.getStyle().getProperty(prop));\r
+      opt.hide = true;\r
+      custom(cur(false), 0);\r
+    }\r
+\r
+    public Effects hide(Speed speed) {\r
+      return hide(speed, null);\r
+    }\r
+\r
+    public Effects hide(Speed speed, Function callback) {\r
+      return animate(genFx("hide", 3), speed, Easing.LINEAR, callback);\r
+    }\r
+\r
+    public Effects show(Speed speed) {\r
+      return show(speed, null);\r
+    }\r
+\r
+    public Effects show(Speed speed, Function callback) {\r
+      return animate(genFx("show", 3), speed, Easing.LINEAR, callback);\r
     }\r
 \r
     public void show() {\r
@@ -112,6 +147,52 @@ public class Effects extends GQuery {
           cur(false));\r
     }\r
 \r
+    public Effects toggle(Speed speed) {\r
+      return hide(speed, null);\r
+    }\r
+\r
+    public Effects toggle(Speed speed, Function callback) {\r
+      return animate(genFx("toggle", 3), speed, Easing.LINEAR, callback);\r
+    }\r
+\r
+    public void update() {\r
+      if ("opacity".equals(prop)) {\r
+        GQuery.setStyleProperty(prop, "" + now, elem);\r
+      } else {\r
+        if (elem.getStyle() != null\r
+            && elem.getStyle().getProperty(prop) != null) {\r
+          elem.getStyle().setProperty(prop, now + unit);\r
+        } else {\r
+          elem.setPropertyString(prop, "" + now);\r
+        }\r
+      }\r
+      if (("height".equals(prop) || "width".equals(prop))\r
+          && elem.getStyle() != null) {\r
+        elem.getStyle().setProperty("display", "block");\r
+      }\r
+    }\r
+\r
+    private void custom(double from, double to) {\r
+      custom(from, to, "px");\r
+    }\r
+\r
+    private void custom(double from, double to, String unit) {\r
+      startTime = Duration.currentTimeMillis();\r
+      start = from;\r
+      end = to;\r
+      now = start;\r
+      this.unit = unit;\r
+      Timer t = new Timer() {\r
+        @Override\r
+        public void run() {\r
+          if (!step(false)) {\r
+            cancel();\r
+          }\r
+        }\r
+      };\r
+      t.scheduleRepeating(13);\r
+    }\r
+\r
     private boolean step(boolean gotoEnd) {\r
       double t = Duration.currentTimeMillis();\r
 \r
@@ -149,45 +230,35 @@ public class Effects extends GQuery {
         double n = t - startTime;\r
         state = n / opt.duration;\r
         pos = opt.easing.ease(this.state, n, 0, 1);\r
+        now = start + ((this.end - this.start) * this.pos);\r
+\r
         update();\r
         return true;\r
       }\r
     }\r
+  }\r
 \r
-    public void update() {\r
-               (jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );\r
+  /**\r
+   * Used to register the plugin.\r
+   */\r
+  private static class EffectsPlugin implements Plugin<Effects> {\r
 \r
-               // Set display property to block for height/width animations\r
-               if ( ( this.prop == "height" || this.prop == "width" ) && this.elem.style )\r
-                       this.elem.style.display = "block";\r
+    public Effects init(GQuery gq) {\r
+      return new Effects(gq.get());\r
     }\r
+  }\r
 \r
-    public void hide() {\r
-      opt.cache.put(prop, elem.getStyle().getProperty(prop));\r
-      opt.hide = true;\r
-      custom(cur(false), 0);\r
-    }\r
+  private class SpeedOpts {\r
 \r
-    private void custom(double from, double to) {\r
-      custom(from, to, "px");\r
-    }\r
+    public String display;\r
 \r
-    private void custom(double from, double to, String unit) {\r
-      startTime = Duration.currentTimeMillis();\r
-      start = from;\r
-      end = to;\r
-      now = start;\r
+    public String overflow;\r
 \r
-      Timer t = new Timer() {\r
-        @Override\r
-        public void run() {\r
-          step(false);\r
-        }\r
-      };\r
-    }\r
-  }\r
+    public Properties curAnim;\r
 \r
-  private class SpeedOpts {\r
+    public boolean hide;\r
+\r
+    public boolean show;\r
 \r
     private Properties properties;\r
 \r
@@ -199,80 +270,98 @@ public class Effects extends GQuery {
 \r
     private boolean queue = true;\r
 \r
-    public String display;\r
-\r
-    public String overflow;\r
+    private GQuery.DataCache cache = DataCache.createObject().cast();\r
 \r
-    public Properties curAnim;\r
+    protected SpeedOpts(int speed, Easing easing, Function complete) {\r
+      this.complete = complete;\r
+      this.easing = easing;\r
+      this.duration = speed;\r
+    }\r
 \r
-    public boolean hide;\r
+    protected SpeedOpts(Speed speed, Easing easing, Function complete) {\r
+      this.complete = complete;\r
+      this.easing = easing;\r
+      this.duration = speed.getDuration();\r
+    }\r
 \r
-    private GQuery.DataCache cache = DataCache.createObject().cast();\r
+    public void complete(Element elem) {\r
+      if (queue) {\r
+        $(elem).dequeue();\r
+      }\r
+      if (complete != null) {\r
+        complete.f(elem);\r
+      }\r
+    }\r
 \r
-    public boolean show;\r
+    public Function getComplete() {\r
+      return complete;\r
+    }\r
 \r
-    public boolean isQueue() {\r
-      return queue;\r
+    public int getDuration() {\r
+      return duration;\r
     }\r
 \r
-    public void setQueue(boolean queue) {\r
-      this.queue = queue;\r
+    public Easing getEasing() {\r
+      return easing;\r
     }\r
 \r
-    protected SpeedOpts(int speed, Easing easing, Function complete) {\r
-      this.complete = complete;\r
-      this.easing = easing;\r
-      this.duration = speed;\r
+    public Properties getProperties() {\r
+      return properties;\r
     }\r
 \r
-    public Function getComplete() {\r
-      return complete;\r
+    public boolean isQueue() {\r
+      return queue;\r
     }\r
 \r
     public void setComplete(Function complete) {\r
       this.complete = complete;\r
     }\r
 \r
-    public int getDuration() {\r
-      return duration;\r
-    }\r
-\r
     public void setDuration(int duration) {\r
       this.duration = duration;\r
     }\r
 \r
-    public Easing getEasing() {\r
-      return easing;\r
-    }\r
-\r
     public void setEasing(Easing easing) {\r
       this.easing = easing;\r
     }\r
 \r
-    public Properties getProperties() {\r
-      return properties;\r
-    }\r
-\r
     public void setProperties(Properties properties) {\r
       this.properties = properties;\r
     }\r
 \r
-    protected SpeedOpts(Speed speed, Easing easing, Function complete) {\r
-      this.complete = complete;\r
-      this.easing = easing;\r
-      this.duration = speed.getDuration();\r
+    public void setQueue(boolean queue) {\r
+      this.queue = queue;\r
     }\r
+  }\r
 \r
-    public void complete(Element elem) {\r
-      if (queue) {\r
-        $(elem).dequeue();\r
-      }\r
-      if (complete != null) {\r
-        complete.f(elem);\r
+  public static final Class<Effects> Effects = Effects.class;\r
+\r
+  private static String[][] fxAttrs = {\r
+      {"height", "marginTop", "marginBottom", "paddingTop", "paddingBottom"},\r
+      {"width", "marginLeft", "marginRight", "paddingLeft", "paddingRight"},\r
+      {"opacity"}};\r
+\r
+  static {\r
+    GQuery.registerPlugin(Effects.class, new EffectsPlugin());\r
+  }\r
+\r
+  private static Properties genFx(String type, int num) {\r
+    Properties prop = Properties.createObject().cast();\r
+    for (int i = 0; i < num; i++) {\r
+      for (int j = 0; j < fxAttrs[i].length; j++) {\r
+        prop.set(fxAttrs[i][j], type);\r
       }\r
     }\r
+    return prop;\r
   }\r
 \r
+  // don't valid double after parsing\r
+  private static native double parseDouble(String dstr) /*-{\r
+    return parseFloat(dstr);\r
+  }-*/;\r
+\r
+  private DataCache elemDisplay = DataCache.createObject().cast();\r
+\r
   public Effects(Element element) {\r
     super(element);\r
   }\r
@@ -287,7 +376,7 @@ public class Effects extends GQuery {
 \r
   public Effects animate(final Properties properties, final Speed speed,\r
       final Easing easing, final Function complete) {\r
-    if (properties.get("queue") != null) {\r
+    if (!"false".equals(properties.get("queue"))) {\r
       queue(new Function() {\r
         final SpeedOpts optall = new SpeedOpts(speed, easing, complete);\r
 \r
@@ -333,7 +422,7 @@ public class Effects extends GQuery {
               double start = fx.cur(true);\r
 \r
               if (parts != null) {\r
-                double end = Double.parseDouble(parts.getStr(2));\r
+                double end = parseDouble(parts.getStr(2));\r
                 String unit = parts.getStr(3);\r
                 if (unit == null) {\r
                   unit = "px";\r
@@ -348,7 +437,7 @@ public class Effects extends GQuery {
                 }\r
                 fx.custom(start, end, unit);\r
               } else {\r
-                fx.custom(start, Double.parseDouble(val), "");\r
+                fx.custom(start, parseDouble(val), "");\r
               }\r
             }\r
           }\r
@@ -358,106 +447,103 @@ public class Effects extends GQuery {
     return this;\r
   }\r
 \r
-//                     jQuery.each( prop, function(name, val){\r
-//                             var e = new jQuery.fx( self, opt, name );\r
-//\r
-//                             if ( /toggle|show|hide/.test(val) )\r
-//                                     e[ val == "toggle" ? hidden ? "show" : "hide" : val ]( prop );\r
-//                             else {\r
-//                                     var parts = val.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),\r
-//                                             start = e.cur(true) || 0;\r
-//\r
-//                                     if ( parts ) {\r
-//                                             var end = parseFloat(parts[2]),\r
-//                                                     unit = parts[3] || "px";\r
-//\r
-//                                             // We need to compute starting value\r
-//                                             if ( unit != "px" ) {\r
-//                                                     self.style[ name ] = (end || 1) + unit;\r
-//                                                     start = ((end || 1) / e.cur(true)) * start;\r
-//                                                     self.style[ name ] = start + unit;\r
-//                                             }\r
-//\r
-//                                             // If a +=/-= token was provided, we're doing a relative animation\r
-//                                             if ( parts[1] )\r
-//                                                     end = ((parts[1] == "-=" ? -1 : 1) * end) + start;\r
-//\r
-//                                             e.custom( start, end, unit );\r
-//                                     } else\r
-//                                             e.custom( start, val, "" );\r
-//                             }\r
-//                     });\r
-//\r
-//                     // For JS strict compliance\r
-//                     return true;\r
-//             });\r
-//     },  \r
-//  }\r
-\r
+  /**\r
+   * Fade in all matched elements by adjusting their opacity. Only the opacity\r
+   * is adjusted for this animation, meaning that all of the matched elements\r
+   * should already have some form of height and width associated with them.\r
+   */\r
   public Effects fadeIn() {\r
-    Animation a = new Animation() {\r
-\r
-      public void onCancel() {\r
-      }\r
-\r
-      public void onComplete() {\r
-      }\r
+    return fadeIn(Speed.DEFAULT);\r
+  }\r
 \r
-      public void onStart() {\r
-      }\r
+  /**\r
+   * Fade in all matched elements by adjusting their opacity. Only the opacity\r
+   * is adjusted for this animation, meaning that all of the matched elements\r
+   * should already have some form of height and width associated with them.\r
+   */\r
+  public Effects fadeIn(Speed speed) {\r
+    return fadeIn(speed, null);\r
+  }\r
 \r
-      public void onUpdate(double progress) {\r
-        for (int i = 0; i < elements.getLength(); i++) {\r
-          elements.getItem(i).getStyle()\r
-              .setProperty("opacity", String.valueOf(progress));\r
-        }\r
-      }\r
-    };\r
-    a.run(1000);\r
-    return this;\r
+  /**\r
+   * Fade in all matched elements by adjusting their opacity and firing an\r
+   * optional callback after completion. Only the opacity is adjusted for this\r
+   * animation, meaning that all of the matched elements should already have\r
+   * some form of height and width associated with them.\r
+   */\r
+  public Effects fadeIn(Speed speed, Function callback) {\r
+    return animate($$("opacity: \"hide\""), speed, Easing.LINEAR, callback);\r
   }\r
 \r
+  /**\r
+   * Fade out all matched elements by adjusting their opacity to 0, then setting\r
+   * display to "none". Only the opacity is adjusted for this animation, meaning\r
+   * that all of the matched elements should already have some form of height\r
+   * and width associated with them.\r
+   */\r
   public Effects fadeOut() {\r
-    Animation a = new Animation() {\r
+    return fadeOut(Speed.DEFAULT);\r
+  }\r
 \r
-      public void onCancel() {\r
-      }\r
+  /**\r
+   * Fade out all matched elements by adjusting their opacity to 0, then setting\r
+   * display to "none". Only the opacity is adjusted for this animation, meaning\r
+   * that all of the matched elements should already have some form of height\r
+   * and width associated with them.\r
+   */\r
+  public Effects fadeOut(Speed speed) {\r
+    return fadeOut(speed, null);\r
+  }\r
 \r
-      public void onComplete() {\r
-        for (int i = 0; i < elements.getLength(); i++) {\r
-          elements.getItem(i).getStyle().setProperty("opacity", "0");\r
-          elements.getItem(i).getStyle().setProperty("display", "none");\r
-        }\r
-      }\r
+  /**\r
+   * Fade out all matched elements by adjusting their opacity to 0, then setting\r
+   * display to "none" and firing an optional callback after completion. Only\r
+   * the opacity is adjusted for this animation, meaning that all of the matched\r
+   * elements should already have some form of height and width associated with\r
+   * them.\r
+   */\r
+  public Effects fadeOut(Speed speed, Function callback) {\r
+    return animate($$("opacity: \"hide\""), speed, Easing.LINEAR, callback);\r
+  }\r
 \r
-      public void onStart() {\r
-      }\r
+  /**\r
+   * Fade the opacity of all matched elements to a specified opacity. Only the\r
+   * opacity is adjusted for this animation, meaning that all of the matched\r
+   * elements should already have some form of height and width associated with\r
+   * them.\r
+   */\r
+  public Effects fadeTo(Speed speed, double opacity) {\r
+    return fadeTo(speed, opacity, null);\r
+  }\r
 \r
-      public void onUpdate(double progress) {\r
-        for (int i = 0; i < elements.getLength(); i++) {\r
-          elements.getItem(i).getStyle()\r
-              .setProperty("opacity", String.valueOf(1.0 - progress));\r
-        }\r
-      }\r
-    };\r
-    a.run(1000);\r
-    return this;\r
+  /**\r
+   * Fade the opacity of all matched elements to a specified opacity and firing\r
+   * an optional callback after completion. Only the opacity is adjusted for\r
+   * this animation, meaning that all of the matched elements should already\r
+   * have some form of height and width associated with them.\r
+   */\r
+  public Effects fadeTo(Speed speed, double opacity, Function callback) {\r
+    return animate($$("opacity: " + opacity), speed, Easing.LINEAR, callback);\r
   }\r
 \r
+  /**\r
+   * Hides each of the set of matched elements if they are shown.\r
+   */\r
   public Effects hide() {\r
     for (Element e : elements()) {\r
       GQuery q = $(e);\r
       String old = (String) q.data("olddisplay");\r
       if (old != null && !"none".equals(old)) {\r
         q.data("olddisplay", GQuery.curCSS(e, "display", false));\r
-        e.getStyle().setProperty("display", "none");\r
       }\r
+      e.getStyle().setProperty("display", "none");\r
     }\r
     return this;\r
   }\r
 \r
-  private DataCache elemDisplay = DataCache.createObject().cast();\r
-\r
+  /**\r
+   * Displays each of the set of matched elements if they are hidden.\r
+   */\r
   public Effects show() {\r
     for (Element e : elements()) {\r
       GQuery q = $(e);\r
@@ -482,6 +568,81 @@ public class Effects extends GQuery {
     return this;\r
   }\r
 \r
+  /**\r
+   * Reveal all matched elements by adjusting their height .\r
+   */\r
+  public Effects slideDown() {\r
+    return slideDown(Speed.DEFAULT, null);\r
+  }\r
+\r
+  /**\r
+   * Reveal all matched elements by adjusting their height .\r
+   */\r
+  public Effects slideDown(Speed speed) {\r
+    return slideDown(speed, null);\r
+  }\r
+\r
+  /**\r
+   * Reveal all matched elements by adjusting their height and firing an\r
+   * optional callback after completion.\r
+   */\r
+  public Effects slideDown(Speed speed, Function callback) {\r
+    return animate(genFx("show", 1), speed, Easing.LINEAR, callback);\r
+  }\r
+\r
+  /**\r
+   * Toggle the visibility of all matched elements by adjusting their height.\r
+   * Only the height is adjusted for this animation, causing all matched\r
+   * elements to be hidden or shown in a "sliding" manner\r
+   */\r
+  public Effects slideToggle() {\r
+    return slideToggle(Speed.DEFAULT, null);\r
+  }\r
+\r
+  /**\r
+   * Toggle the visibility of all matched elements by adjusting their height.\r
+   * Only the height is adjusted for this animation, causing all matched\r
+   * elements to be hidden or shown in a "sliding" manner\r
+   */\r
+  public Effects slideToggle(Speed speed) {\r
+    return slideToggle(speed, null);\r
+  }\r
+\r
+  /**\r
+   * Toggle the visibility of all matched elements by adjusting their height and\r
+   * firing an optional callback after completion. Only the height is adjusted\r
+   * for this animation, causing all matched elements to be hidden or shown in a\r
+   * "sliding" manner\r
+   */\r
+  public Effects slideToggle(Speed speed, Function callback) {\r
+    return animate(genFx("toggle", 1), speed, Easing.LINEAR, callback);\r
+  }\r
+\r
+  /**\r
+   * Hide all matched elements by adjusting their height .\r
+   */\r
+  public Effects slideUp() {\r
+    return slideUp(Speed.DEFAULT, null);\r
+  }\r
+\r
+  /**\r
+   * Hide all matched elements by adjusting their height.\r
+   */\r
+  public Effects slideUp(Speed speed) {\r
+    return slideUp(speed, null);\r
+  }\r
+\r
+  /**\r
+   * Hide all matched elements by adjusting their height and firing an optional\r
+   * callback after completion.\r
+   */\r
+  public Effects slideUp(Speed speed, Function callback) {\r
+    return animate(genFx("hide", 1), speed, Easing.LINEAR, callback);\r
+  }\r
+\r
+  /**\r
+   * Toggle displaying each of the set of matched elements.\r
+   */\r
   public Effects toggle() {\r
     for (Element e : elements()) {\r
       Effects ef = new Effects(e);\r
index 2c9c354ef35206a7d41f756a0a7db8e851183535..37e2c19612b6b6d81020285776d562e023c56a45 100644 (file)
@@ -122,11 +122,11 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
     }-*/;\r
 \r
     public native void put(String id, Object obj) /*-{\r
-      return this[id]=obj;\r
+      this[id]=obj;\r
     }-*/;\r
 \r
     public native void put(int id, Object obj) /*-{\r
-      return this[id]=obj;\r
+      this[id]=obj;\r
     }-*/;\r
   }\r
 \r
@@ -307,9 +307,24 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
   }\r
 \r
   public static native String camelize(String s)/*-{\r
-     return s.toLowerCase().replace(/-([a-z])/ig, function(a, c){return c.toUpperCase()} );\r
+     return s.replace(/\-(\w)/g, function(all, letter){\r
+                               return letter.toUpperCase();\r
+                       });\r
    }-*/;\r
 \r
+  public static String curCSS(Element elem, String name, boolean force) {\r
+    Style s = elem.getStyle();\r
+    ensureStyleImpl();\r
+    if (!force) {\r
+      name = styleImpl.getPropertyName(name);\r
+\r
+      if (SelectorEngine.truth(s.getProperty(name))) {\r
+        return s.getProperty(name);\r
+      }\r
+    }\r
+    return styleImpl.getCurrentStyle(elem, name);\r
+  }\r
+\r
   public static void registerPlugin(Class<? extends GQuery> plugin,\r
       Plugin<? extends GQuery> pluginFactory) {\r
     if (plugins == null) {\r
@@ -374,21 +389,18 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
     }\r
   }\r
 \r
-  private static String curCSS(Element elem, String name) {\r
-    return curCSS(elem, name, false);\r
+  protected static void setStyleProperty(String prop, String val, Element e) {\r
+    String property = camelize(prop);\r
+    e.getStyle().setProperty(property, val);\r
+    if ("opacity".equals(property)) {\r
+      e.getStyle().setProperty("zoom", "1");\r
+      e.getStyle().setProperty("filter",\r
+          "alpha(opacity=" + (int) (Double.valueOf(val) * 100) + ")");\r
+    }\r
   }\r
 \r
-  public static String curCSS(Element elem, String name, boolean force) {\r
-    Style s = elem.getStyle();\r
-    ensureStyleImpl();\r
-    if (!force) {\r
-      name = styleImpl.getPropertyName(name);\r
-\r
-      if (SelectorEngine.truth(s.getProperty(name))) {\r
-        return s.getProperty(name);\r
-      }\r
-    }\r
-    return styleImpl.getCurrentStyle(elem, name);\r
+  private static String curCSS(Element elem, String name) {\r
+    return curCSS(elem, name, false);\r
   }\r
 \r
   private static void ensureStyleImpl() {\r
@@ -794,13 +806,7 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
    */\r
   public GQuery css(String prop, String val) {\r
     for (Element e : elements()) {\r
-      String property = camelize(prop);\r
-      e.getStyle().setProperty(property, val);\r
-      if ("opacity".equals(property)) {\r
-        e.getStyle().setProperty("zoom", "1");\r
-        e.getStyle().setProperty("filter",\r
-            "alpha(opacity=" + (int) (Double.valueOf(val) * 100) + ")");\r
-      }\r
+      setStyleProperty(prop, val, e);\r
     }\r
     return this;\r
   }\r
@@ -900,10 +906,6 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
     return this;\r
   }\r
 \r
-  public LazyGQuery lazy() {\r
-    return GWT.create(GQuery.class);\r
-  }\r
-\r
   /**\r
    * Revert the most recent 'destructive' operation, changing the set of matched\r
    * elements to its previous state (right before the destructive operation).\r
@@ -1287,6 +1289,10 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
     return bind(Event.ONKEYUP, null, f);\r
   }\r
 \r
+  public LazyGQuery lazy() {\r
+    return GWT.create(GQuery.class);\r
+  }\r
+\r
   /**\r
    * Returns the number of elements currently matched. The size function will\r
    * return the same value.\r
@@ -1428,8 +1434,34 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
     return ret;\r
   }\r
 \r
+  /**\r
+   * Get the current offset of the first matched element, in pixels, relative to\r
+   * the document. The returned object contains two Float properties, top and\r
+   * left. Browsers usually round these values to the nearest integer pixel for\r
+   * actual positioning. The method works only with visible elements.\r
+   */\r
   public Offset offset() {\r
-    return new Offset(get(0).getOffsetLeft(), get(0).getOffsetTop());\r
+    if (length() == 0) {\r
+      return new Offset(0, 0);\r
+    }\r
+    int boxtop = getClientBoundingRectTop(get(0));\r
+    int boxleft = getClientBoundingRectLeft(get(0));\r
+    Element docElem = Document.get().getDocumentElement();\r
+    Element body = Document.get().getBody();\r
+    int clientTop = docElem.getPropertyInt("clientTop");\r
+    if (clientTop == 0) {\r
+      clientTop = body.getPropertyInt("clientTop");\r
+    }\r
+    int clientLeft = docElem.getPropertyInt("clientLeft");\r
+    if (clientLeft == 0) {\r
+      clientLeft = body.getPropertyInt("clientLeft");\r
+    }\r
+    int wleft = Window.getScrollLeft();\r
+    int wtop = Window.getScrollTop();\r
+    int top = boxtop + (wtop == 0 ? body.getScrollTop() : wtop) - clientTop;\r
+    int left = boxleft + (wleft == 0 ? body.getScrollLeft() : wleft)\r
+        - clientLeft;\r
+    return new Offset(top, left);\r
   }\r
 \r
   /**\r
@@ -2434,6 +2466,14 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
     return key;\r
   }\r
 \r
+  private native int getClientBoundingRectLeft(Element element) /*-{\r
+    return element.getClientBoundingRect().left;\r
+  }-*/;\r
+\r
+  private native int getClientBoundingRectTop(Element element) /*-{\r
+    return element.getClientBoundingRect().top;\r
+  }-*/;\r
+\r
   private native Document getContentDocument(Node n) /*-{\r
     return n.contentDocument || n.contentWindow.document;\r
   }-*/;\r
@@ -2483,7 +2523,7 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
       if (data != null) {\r
         qq.enqueue(data);\r
       }\r
-      if (SelectorEngine.eq(type, "__FX") && qq.length() == 1) {\r
+      if (SelectorEngine.eq(type, "__FXqueue") && qq.length() == 1) {\r
         data.f(elem);\r
       }\r
       return qq;\r
index 56e24a7be94be0ea60ef32baaaf6f7f9b2e8589c..9d6c1bfbfd2c708fba9a7c5a5841792654e41056 100644 (file)
@@ -64,14 +64,15 @@ public class Properties extends JavaScriptObject {
     return keys;\r
   }-*/;\r
 \r
-  public native Properties cloneProps() /*-{\r
+  public final native Properties cloneProps() /*-{\r
     var props = {};\r
     for(p in this) {\r
       props[p] =  this[p];\r
     }\r
+    return props;\r
   }-*/;\r
 \r
-  public native void set(String key, String val) /*-{\r
+  public final native void set(String key, String val) /*-{\r
     this[key]=val;\r
   }-*/;\r
 }\r