]> source.dussan.org Git - gwtquery.git/commitdiff
More implementations and docs
authorRay Cromwell <cromwellian@gmail.com>
Wed, 29 Apr 2009 23:40:20 +0000 (23:40 +0000)
committerRay Cromwell <cromwellian@gmail.com>
Wed, 29 Apr 2009 23:40:20 +0000 (23:40 +0000)
gwtquery-core/src/main/java/gwtquery/client/Effects.java
gwtquery-core/src/main/java/gwtquery/client/GQuery.java

index d7c42b9dc4703a78eb92b4b3390806671844526b..21fabb86bb2d252ad29cb8b3d7aac855cd281b85 100644 (file)
@@ -24,6 +24,75 @@ public class Effects extends GQuery {
     super(list);\r
   }\r
 \r
+  /**\r
+   * function( prop, speed, easing, callback ) {\r
+               var optall = jQuery.speed(speed, easing, callback);\r
+\r
+               return this[ optall.queue === false ? "each" : "queue" ](function(){\r
+               \r
+                       var opt = jQuery.extend({}, optall), p,\r
+                               hidden = this.nodeType == 1 && jQuery(this).is(":hidden"),\r
+                               self = this;\r
+       \r
+                       for ( p in prop ) {\r
+                               if ( prop[p] == "hide" && hidden || prop[p] == "show" && !hidden )\r
+                                       return opt.complete.call(this);\r
+\r
+                               if ( ( p == "height" || p == "width" ) && this.style ) {\r
+                                       // Store display property\r
+                                       opt.display = jQuery.css(this, "display");\r
+\r
+                                       // Make sure that nothing sneaks out\r
+                                       opt.overflow = this.style.overflow;\r
+                               }\r
+                       }\r
+\r
+                       if ( opt.overflow != null )\r
+                               this.style.overflow = "hidden";\r
+\r
+                       opt.curAnim = jQuery.extend({}, prop);\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
+   * @return\r
+   */\r
+  public Effects animate(Properties props, String speed, String easing,\r
+      Function callback) {\r
+    return this;\r
+  }\r
+  \r
   public Effects fadeOut() {\r
     Animation a = new Animation() {\r
 \r
index e5598598c73298ed59ae3c7ae44596d67fe43f85..3354bba8e691e853f39f51323e217716ae2c2a13 100644 (file)
@@ -2,9 +2,11 @@ package gwtquery.client;
 \r
 import com.google.gwt.core.client.GWT;\r
 import com.google.gwt.core.client.JavaScriptObject;\r
+import com.google.gwt.dom.client.BodyElement;\r
 import com.google.gwt.dom.client.ButtonElement;\r
 import com.google.gwt.dom.client.Document;\r
 import com.google.gwt.dom.client.Element;\r
+import com.google.gwt.dom.client.IFrameElement;\r
 import com.google.gwt.dom.client.InputElement;\r
 import com.google.gwt.dom.client.NativeEvent;\r
 import com.google.gwt.dom.client.Node;\r
@@ -16,6 +18,7 @@ import com.google.gwt.dom.client.TextAreaElement;
 import com.google.gwt.user.client.DOM;\r
 import com.google.gwt.user.client.Event;\r
 import com.google.gwt.user.client.EventListener;\r
+import com.google.gwt.user.client.Window;\r
 \r
 import java.util.HashMap;\r
 import java.util.Map;\r
@@ -169,6 +172,8 @@ public class GQuery {
     }-*/;\r
   }\r
 \r
+  public static boolean fxOff = false;\r
+\r
   private static Map<Class<? extends GQuery>, Plugin<? extends GQuery>> plugins;\r
 \r
   private static Element windowData = null;\r
@@ -177,6 +182,9 @@ public class GQuery {
 \r
   private static DocumentStyleImpl styleImpl;\r
 \r
+  private static final int FUNC_PREPEND = 0, FUNC_APPEND = 1, FUNC_AFTER = 2,\r
+      FUNC_BEFORE = 3;\r
+\r
   /**\r
    * This function accepts a string containing a CSS selector which is then used\r
    * to match a set of elements, or it accepts raw HTML creating a GQuery\r
@@ -338,6 +346,23 @@ public class GQuery {
     }\r
   }\r
 \r
+  private static String curCSS(Element elem, String name) {\r
+    Style s = elem.getStyle();\r
+    ensureStyleImpl();\r
+    name = styleImpl.getPropertyName(name);\r
+\r
+    if (SelectorEngine.truth(s.getProperty(name))) {\r
+      return s.getProperty(name);\r
+    }\r
+    return styleImpl.getCurrentStyle(elem, name);\r
+  }\r
+\r
+  private static void ensureStyleImpl() {\r
+    if (styleImpl != null) {\r
+      styleImpl = GWT.create(DocumentStyleImpl.class);\r
+    }\r
+  }\r
+\r
   private static boolean hasClass(Element e, String clz) {\r
     return e.getClassName().matches("\\s" + clz + "\\s");\r
   }\r
@@ -378,6 +403,10 @@ public class GQuery {
     elements = JSArray.create(element);\r
   }\r
 \r
+  public GQuery add(String selector) {\r
+    return add($(selector));\r
+  }\r
+\r
   /**\r
    * Adds the specified classes to each matched element.\r
    */\r
@@ -390,6 +419,69 @@ public class GQuery {
     return this;\r
   }\r
 \r
+  /**\r
+   * Insert content after each of the matched elements. The elements must\r
+   * already be inserted into the document (you can't insert an element after\r
+   * another if it's not in the page).\r
+   */\r
+  public GQuery after(Node n) {\r
+    return domManip(JSArray.create(n), FUNC_AFTER);\r
+  }\r
+\r
+  /**\r
+   * Insert content after each of the matched elements. The elements must\r
+   * already be inserted into the document (you can't insert an element after\r
+   * another if it's not in the page).\r
+   */\r
+  public GQuery after(String html) {\r
+    return domManip(html, FUNC_AFTER);\r
+  }\r
+\r
+  /**\r
+   * Insert content after each of the matched elements. The elements must\r
+   * already be inserted into the document (you can't insert an element after\r
+   * another if it's not in the page).\r
+   */\r
+  public GQuery after(GQuery query) {\r
+    return domManip(query.elements, FUNC_AFTER);\r
+  }\r
+\r
+  /**\r
+   * Add the previous selection to the current selection. Useful for traversing\r
+   * elements, and then adding something that was matched before the last\r
+   * traversal.\r
+   */\r
+  public GQuery andSelf() {\r
+    return add(previousObject);\r
+  }\r
+\r
+  /**\r
+   * Append content to the inside of every matched element. This operation is\r
+   * similar to doing an appendChild to all the specified elements, adding them\r
+   * into the document.\r
+   */\r
+  public GQuery append(String html) {\r
+    return domManip(html, FUNC_APPEND);\r
+  }\r
+\r
+  /**\r
+   * Append content to the inside of every matched element. This operation is\r
+   * similar to doing an appendChild to all the specified elements, adding them\r
+   * into the document.\r
+   */\r
+  public GQuery append(Node n) {\r
+    return domManip(JSArray.create(n), FUNC_APPEND);\r
+  }\r
+\r
+  /**\r
+   * Append content to the inside of every matched element. This operation is\r
+   * similar to doing an appendChild to all the specified elements, adding them\r
+   * into the document.\r
+   */\r
+  public GQuery append(GQuery query) {\r
+    return domManip(query.elements, FUNC_APPEND);\r
+  }\r
+\r
   /**\r
    * Convert to Plugin interface provided by Class literal.\r
    */\r
@@ -443,6 +535,33 @@ public class GQuery {
     return this;\r
   }\r
 \r
+  /**\r
+   * Insert content before each of the matched elements. The elements must\r
+   * already be inserted into the document (you can't insert an element before\r
+   * another if it's not in the page).\r
+   */\r
+  public GQuery before(Node n) {\r
+    return domManip(JSArray.create(n), FUNC_AFTER);\r
+  }\r
+\r
+  /**\r
+   * Insert content before each of the matched elements. The elements must\r
+   * already be inserted into the document (you can't insert an element before\r
+   * another if it's not in the page).\r
+   */\r
+  public GQuery before(GQuery query) {\r
+    return domManip(query.elements, FUNC_AFTER);\r
+  }\r
+\r
+  /**\r
+   * Insert content before each of the matched elements. The elements must\r
+   * already be inserted into the document (you can't insert an element before\r
+   * another if it's not in the page).\r
+   */\r
+  public GQuery before(String html) {\r
+    return domManip(html, FUNC_AFTER);\r
+  }\r
+\r
   /**\r
    * Binds a handler to one or more events (like click) for each matched\r
    * element.\r
@@ -506,11 +625,43 @@ public class GQuery {
     return bind(Event.ONCLICK, null, f);\r
   }\r
 \r
+  /**\r
+   * Clone matched DOM Elements and select the clones. This is useful for moving\r
+   * copies of the elements to another location in the DOM.\r
+   */\r
+  public GQuery clone() {\r
+    JSArray result = JSArray.create();\r
+    for (Element e : elements()) {\r
+      result.addNode(e.cloneNode(true));\r
+    }\r
+    return new GQuery(result);\r
+  }\r
+\r
+  /**\r
+   * Find all the child nodes inside the matched elements (including text\r
+   * nodes), or the content document, if the element is an iframe.\r
+   */\r
+  public GQuery contents() {\r
+    JSArray result = JSArray.create();\r
+    for (Element e : elements()) {\r
+      NodeList children = e.getChildNodes();\r
+      for (int i = 0; i < children.getLength(); i++) {\r
+        Node n = children.getItem(i);\r
+        if (IFrameElement.is(n)) {\r
+          result.addNode(getContentDocument(n));\r
+        } else {\r
+          result.addNode(n);\r
+        }\r
+      }\r
+    }\r
+    return new GQuery(unique(result));\r
+  }\r
+\r
   /**\r
    * Return a style property on the first matched element.\r
    */\r
   public String css(String name) {\r
-    return elements.getItem(0).getStyle().getProperty(name);\r
+    return curCSS(get(0), name);\r
   }\r
 \r
   /**\r
@@ -615,6 +766,21 @@ public class GQuery {
     return asArray(elements);\r
   }\r
 \r
+  /**\r
+   * Remove all child nodes from the set of matched elements.\r
+   */\r
+  public GQuery empty() {\r
+    //TODO: add memory leak cleanup, remove event handlers, and \r
+    // data caches\r
+    for (Element e : elements()) {\r
+      while (e.getFirstChild() != null) {\r
+        e.removeChild(e.getFirstChild());\r
+      }\r
+    }\r
+\r
+    return this;\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
@@ -740,6 +906,69 @@ public class GQuery {
     return -1;\r
   }\r
 \r
+  /**\r
+   * Insert all of the matched elements after another, specified, set of\r
+   * elements.\r
+   */\r
+  public GQuery insertAfter(String selector) {\r
+    return insertAfter($(selector));\r
+  }\r
+\r
+  /**\r
+   * Insert all of the matched elements after another, specified, set of\r
+   * elements.\r
+   */\r
+  public GQuery insertAfter(Element elem) {\r
+    return insertAfter($(elem));\r
+  }\r
+\r
+  /**\r
+   * Insert all of the matched elements after another, specified, set of\r
+   * elements.\r
+   */\r
+  public GQuery insertAfter(GQuery query) {\r
+    for (Element e : elements()) {\r
+      query.after(e);\r
+    }\r
+    return this;\r
+  }\r
+\r
+  /**\r
+   * Insert all of the matched elements before another, specified, set of\r
+   * elements.\r
+   *\r
+   * The elements must already be inserted into the document (you can't insert\r
+   * an element after another if it's not in the page).\r
+   */\r
+  public GQuery insertBefore(Element item) {\r
+    return insertBefore($(item));\r
+  }\r
+\r
+  /**\r
+   * Insert all of the matched elements before another, specified, set of\r
+   * elements.\r
+   *\r
+   * The elements must already be inserted into the document (you can't insert\r
+   * an element after another if it's not in the page).\r
+   */\r
+  public GQuery insertBefore(GQuery query) {\r
+    for (Element e : elements()) {\r
+      query.before(e);\r
+    }\r
+    return this;\r
+  }\r
+\r
+  /**\r
+   * Insert all of the matched elements before another, specified, set of\r
+   * elements.\r
+   *\r
+   * The elements must already be inserted into the document (you can't insert\r
+   * an element after another if it's not in the page).\r
+   */\r
+  public GQuery insertBefore(String selector) {\r
+    return insertBefore($(selector));\r
+  }\r
+\r
   public GQuery keydown() {\r
     return trigger(\r
         Document.get().createKeyDownEvent(false, false, false, false, 0, 0),\r
@@ -826,7 +1055,7 @@ public class GQuery {
   }\r
 \r
   /**\r
-   * Returns a jQuery collection with the positioned parent of the first matched\r
+   * Returns a GQuery collection with the positioned parent of the first matched\r
    * element. This is the first parent of the element that has position (as in\r
    * relative or absolute). This method only works with visible elements.\r
    */\r
@@ -869,6 +1098,58 @@ public class GQuery {
     return new GQuery(unique(result));\r
   }\r
 \r
+  /**\r
+   * Gets the top and left position of an element relative to its offset parent.\r
+   * The returned object contains two Integer properties, top and left. For\r
+   * accurate calculations make sure to use pixel values for margins, borders\r
+   * and padding. This method only works with visible elements.\r
+   */\r
+  public Offset position() {\r
+\r
+    if (size() > 0) {\r
+      GQuery offsetParent = offsetParent();\r
+      Offset offset = offset();\r
+      Element e = offsetParent.get(0);\r
+\r
+      Offset parentOffset = BodyElement.is(e) || "html".equals(e.getTagName())\r
+          ? new Offset(0, 0) : offsetParent.offset();\r
+      offset.top -= num(this, "marginTop");\r
+      offset.left -= num(this, "marginLeft");\r
+      parentOffset.top += num(offsetParent, "borderTopWidth");\r
+      parentOffset.left += num(offsetParent, "borderLeftWidth");\r
+      return new Offset(offset.top - parentOffset.top,\r
+          offset.left - parentOffset.left);\r
+    }\r
+    return null;\r
+  }\r
+\r
+  /**\r
+   * Prepend content to the inside of every matched element. This operation is\r
+   * the best way to insert elements inside, at the beginning, of all matched\r
+   * elements.\r
+   */\r
+  public GQuery prepend(String html) {\r
+    return domManip(html, FUNC_PREPEND);\r
+  }\r
+\r
+  /**\r
+   * Prepend content to the inside of every matched element. This operation is\r
+   * the best way to insert elements inside, at the beginning, of all matched\r
+   * elements.\r
+   */\r
+  public GQuery prepend(GQuery query) {\r
+    return domManip(query.elements, FUNC_PREPEND);\r
+  }\r
+\r
+  /**\r
+   * Prepend content to the inside of every matched element. This operation is\r
+   * the best way to insert elements inside, at the beginning, of all matched\r
+   * elements.\r
+   */\r
+  public GQuery prepend(Node n) {\r
+    return domManip(JSArray.create(n), FUNC_PREPEND);\r
+  }\r
+\r
   /**\r
    * Get a set of elements containing the unique previous siblings of each of\r
    * the matched set of elements. Only the immediately previous sibling is\r
@@ -940,6 +1221,20 @@ public class GQuery {
     return queue("__FX", data);\r
   }\r
 \r
+  /**\r
+   * Removes all matched elements from the DOM.\r
+   */\r
+  public GQuery remove() {\r
+    for (Element e : elements()) {\r
+      //TODO: cleanup event bindings\r
+      removeData(e, null);\r
+      if (e.getParentNode() != null) {\r
+        e.getParentNode().removeChild(e);\r
+      }\r
+    }\r
+    return this;\r
+  }\r
+\r
   /**\r
    * Remove the named attribute from every element in the matched set.\r
    */\r
@@ -972,15 +1267,134 @@ public class GQuery {
     return this;\r
   }\r
 \r
+  /**\r
+   * Replaces the elements matched by the specified selector with the matched\r
+   * elements. This function is the complement to replaceWith() which does the\r
+   * same task with the parameters reversed.\r
+   */\r
+  public GQuery replaceAll(GQuery query) {\r
+    for (Element e : elements()) {\r
+      $(e).replaceWith(query);\r
+    }\r
+    return this;\r
+  }\r
+\r
+  /**\r
+   * Replaces the elements matched by the specified selector with the matched\r
+   * elements. This function is the complement to replaceWith() which does the\r
+   * same task with the parameters reversed.\r
+   */\r
+  public GQuery replaceAll(String html) {\r
+    return replaceAll($(html));\r
+  }\r
+\r
+  /**\r
+   * Replaces the elements matched by the specified selector with the matched\r
+   * elements. This function is the complement to replaceWith() which does the\r
+   * same task with the parameters reversed.\r
+   */\r
+  public GQuery replaceAll(Element elem) {\r
+    return replaceAll($(elem));\r
+  }\r
+\r
+  /**\r
+   * Replaces all matched elements with the specified HTML or DOM elements. This\r
+   * returns the GQuery element that was just replaced, which has been removed\r
+   * from the DOM.\r
+   */\r
+  public GQuery replaceWith(GQuery query) {\r
+    return after(query).remove();\r
+  }\r
+\r
+  /**\r
+   * Replaces all matched elements with the specified HTML or DOM elements. This\r
+   * returns the GQuery element that was just replaced, which has been removed\r
+   * from the DOM.\r
+   */\r
+  public GQuery replaceWith(String html) {\r
+    return replaceWith($(html));\r
+  }\r
+\r
+  /**\r
+   * Replaces all matched elements with the specified HTML or DOM elements. This\r
+   * returns the GQuery element that was just replaced, which has been removed\r
+   * from the DOM.\r
+   */\r
+  public GQuery replaceWith(Element elem) {\r
+    return replaceWith($(elem));\r
+  }\r
+\r
   public GQuery scroll(Function f) {\r
     return bind(Event.ONSCROLL, null, f);\r
   }\r
 \r
+  /**\r
+   * When a value is passed in, the scroll left offset is set to that value on\r
+   * all matched elements. This method works for both visible and hidden\r
+   * elements.\r
+   */\r
+  public GQuery scrollLeft(int left) {\r
+    for (Element e : elements()) {\r
+      if (e == window() || e == (Node) Document.get()) {\r
+        Window.scrollTo(left, $(e).scrollTop());\r
+      } else {\r
+        e.setPropertyInt("scrollLeft", left);\r
+      }\r
+    }\r
+    return this;\r
+  }\r
+\r
+  /**\r
+   * Gets the scroll left offset of the first matched element. This method works\r
+   * for both visible and hidden elements.\r
+   */\r
+  public int scrollLeft() {\r
+    Element e = get(0);\r
+    if (e == window()) {\r
+      return Window.getScrollLeft();\r
+    } else if (e == (Node) Document.get()) {\r
+      return Document.get().getScrollLeft();\r
+    } else {\r
+      return e.getScrollLeft();\r
+    }\r
+  }\r
+\r
+  /**\r
+   * When a value is passed in, the scroll top offset is set to that value on\r
+   * all matched elements. This method works for both visible and hidden\r
+   * elements.\r
+   */\r
+  public GQuery scrollTop(int top) {\r
+    for (Element e : elements()) {\r
+      if (e == window() || e == (Node) Document.get()) {\r
+        Window.scrollTo($(e).scrollLeft(), top);\r
+      } else {\r
+        e.setPropertyInt("scrollTop", top);\r
+      }\r
+    }\r
+    return this;\r
+  }\r
+\r
+  /**\r
+   * Gets the scroll top offset of the first matched element. This method works\r
+   * for both visible and hidden elements.\r
+   */\r
+  public int scrollTop() {\r
+    Element e = get(0);\r
+    if (e == window()) {\r
+      return Window.getScrollTop();\r
+    } else if (e == (Node) Document.get()) {\r
+      return Document.get().getScrollTop();\r
+    } else {\r
+      return e.getScrollTop();\r
+    }\r
+  }\r
+\r
   public GQuery select() {\r
     return trigger(Document.get().createHtmlEvent("select", false, false),\r
         null);\r
   }\r
-  \r
+\r
   public void setPreviousObject(GQuery previousObject) {\r
     this.previousObject = previousObject;\r
   }\r
@@ -1168,6 +1582,149 @@ public class GQuery {
     return this;\r
   }\r
 \r
+  /**\r
+   * Wrap each matched element with the specified HTML content. This wrapping\r
+   * process is most useful for injecting additional structure into a document,\r
+   * without ruining the original semantic qualities of a document. This works\r
+   * by going through the first element provided (which is generated, on the\r
+   * fly, from the provided HTML) and finds the deepest descendant element\r
+   * within its structure -- it is that element that will enwrap everything\r
+   * else.\r
+   */\r
+  public GQuery wrap(GQuery query) {\r
+    for (Element e : elements()) {\r
+      $(e).wrapAll(query);\r
+    }\r
+    return this;\r
+  }\r
+\r
+  /**\r
+   * Wrap each matched element with the specified HTML content. This wrapping\r
+   * process is most useful for injecting additional structure into a document,\r
+   * without ruining the original semantic qualities of a document. This works\r
+   * by going through the first element provided (which is generated, on the\r
+   * fly, from the provided HTML) and finds the deepest descendant element\r
+   * within its structure -- it is that element that will enwrap everything\r
+   * else.\r
+   */\r
+  public GQuery wrap(Element elem) {\r
+    return wrap($(elem));\r
+  }\r
+\r
+  /**\r
+   * Wrap each matched element with the specified HTML content. This wrapping\r
+   * process is most useful for injecting additional structure into a document,\r
+   * without ruining the original semantic qualities of a document. This works\r
+   * by going through the first element provided (which is generated, on the\r
+   * fly, from the provided HTML) and finds the deepest descendant element\r
+   * within its structure -- it is that element that will enwrap everything\r
+   * else.\r
+   */\r
+  public GQuery wrap(String html) {\r
+    return wrap($(html));\r
+  }\r
+\r
+  /**\r
+   * Wrap all the elements in the matched set into a single wrapper element.\r
+   * This is different from .wrap() where each element in the matched set would\r
+   * get wrapped with an element. This wrapping process is most useful for\r
+   * injecting additional structure into a document, without ruining the\r
+   * original semantic qualities of a document.\r
+   *\r
+   * This works by going through the first element provided (which is generated,\r
+   * on the fly, from the provided HTML) and finds the deepest descendant\r
+   * element within its structure -- it is that element that will enwrap\r
+   * everything else.\r
+   */\r
+  public GQuery wrapAll(String html) {\r
+    return wrapAll($(html));\r
+  }\r
+\r
+  /**\r
+   * Wrap all the elements in the matched set into a single wrapper element.\r
+   * This is different from .wrap() where each element in the matched set would\r
+   * get wrapped with an element. This wrapping process is most useful for\r
+   * injecting additional structure into a document, without ruining the\r
+   * original semantic qualities of a document.\r
+   *\r
+   * This works by going through the first element provided (which is generated,\r
+   * on the fly, from the provided HTML) and finds the deepest descendant\r
+   * element within its structure -- it is that element that will enwrap\r
+   * everything else.\r
+   */\r
+  public GQuery wrapAll(Element elem) {\r
+    return wrapAll($(elem));\r
+  }\r
+\r
+  /**\r
+   * Wrap all the elements in the matched set into a single wrapper element.\r
+   * This is different from .wrap() where each element in the matched set would\r
+   * get wrapped with an element. This wrapping process is most useful for\r
+   * injecting additional structure into a document, without ruining the\r
+   * original semantic qualities of a document.\r
+   *\r
+   * This works by going through the first element provided (which is generated,\r
+   * on the fly, from the provided HTML) and finds the deepest descendant\r
+   * element within its structure -- it is that element that will enwrap\r
+   * everything else.\r
+   */\r
+  public GQuery wrapAll(GQuery query) {\r
+    GQuery wrap = query.clone();\r
+    if (elements.getItem(0).getParentNode() != null) {\r
+      wrap.insertBefore(elements.getItem(0));\r
+    }\r
+    for (Element e : wrap.elements()) {\r
+      Node n = e;\r
+      while (n.getFirstChild() != null) {\r
+        n = n.getFirstChild();\r
+        $((Element) n).append(this);\r
+      }\r
+    }\r
+    return this;\r
+  }\r
+\r
+  /**\r
+   * Wrap the inner child contents of each matched element (including text\r
+   * nodes) with an HTML structure. This wrapping process is most useful for\r
+   * injecting additional structure into a document, without ruining the\r
+   * original semantic qualities of a document. This works by going through the\r
+   * first element provided (which is generated, on the fly, from the provided\r
+   * HTML) and finds the deepest ancestor element within its structure -- it is\r
+   * that element that will enwrap everything else.\r
+   */\r
+  public GQuery wrapInner(GQuery query) {\r
+    for (Element e : elements()) {\r
+      $(e).contents().wrapAll(query);\r
+    }\r
+    return this;\r
+  }\r
+\r
+  /**\r
+   * Wrap the inner child contents of each matched element (including text\r
+   * nodes) with an HTML structure. This wrapping process is most useful for\r
+   * injecting additional structure into a document, without ruining the\r
+   * original semantic qualities of a document. This works by going through the\r
+   * first element provided (which is generated, on the fly, from the provided\r
+   * HTML) and finds the deepest ancestor element within its structure -- it is\r
+   * that element that will enwrap everything else.\r
+   */\r
+  public GQuery wrapInner(String html) {\r
+    return wrapInner($(html));\r
+  }\r
+\r
+  /**\r
+   * Wrap the inner child contents of each matched element (including text\r
+   * nodes) with an HTML structure. This wrapping process is most useful for\r
+   * injecting additional structure into a document, without ruining the\r
+   * original semantic qualities of a document. This works by going through the\r
+   * first element provided (which is generated, on the fly, from the provided\r
+   * HTML) and finds the deepest ancestor element within its structure -- it is\r
+   * that element that will enwrap everything else.\r
+   */\r
+  public GQuery wrapInner(Element elem) {\r
+    return wrapInner($(elem));\r
+  }\r
+\r
   protected GQuery pushStack(JSArray elts, String name, String selector) {\r
     GQuery g = new GQuery(elts);\r
     g.setPreviousObject(this);\r
@@ -1175,6 +1732,11 @@ public class GQuery {
     return g;\r
   }\r
 \r
+  private GQuery add(GQuery previousObject) {\r
+    return pushStack(unique(merge(elements, previousObject.elements)), "add",\r
+        getSelector() + "," + previousObject.getSelector());\r
+  }\r
+\r
   private void allNextSiblingElements(Element firstChildElement,\r
       JSArray result) {\r
     while (firstChildElement != null) {\r
@@ -1191,15 +1753,44 @@ public class GQuery {
     }\r
   }\r
 \r
-  private String curCSS(Element elem, String name) {\r
-    Style s = elem.getStyle();\r
-    ensureStyleImpl();\r
-    name = styleImpl.getPropertyName(name);\r
-\r
-    if (SelectorEngine.truth(s.getProperty(name))) {\r
-      return s.getProperty(name);\r
-    }\r
-    return styleImpl.getCurrentStyle(elem, name);\r
+  private JSArray clean(String elem) {\r
+    String tags = elem.trim().toLowerCase();\r
+    String preWrap = "", postWrap = "";\r
+    int wrapPos = 0;\r
+    if (tags.contains("<opt")) {\r
+      wrapPos = 1;\r
+      preWrap = "<select multiple=\"multiple\">";\r
+      postWrap = "</select>";\r
+    } else if (!tags.contains("<leg")) {\r
+      wrapPos = 1;\r
+      preWrap = "<fieldset>";\r
+      postWrap = "</fieldset>";\r
+    } else if (tags.matches("^<(thead|tbody|tfoot|colg|cap)")) {\r
+      wrapPos = 1;\r
+      preWrap = "<table>";\r
+      postWrap = "</table>";\r
+    } else if (tags.contains("<tr")) {\r
+      wrapPos = 2;\r
+      preWrap = "<table><tbody>";\r
+      postWrap = "</tbody></table>";\r
+    } else if (tags.contains("<td") || tags.contains("<th")) {\r
+      wrapPos = 3;\r
+      preWrap = "<table><tbody><tr>";\r
+      postWrap = "</tr></tbody></table>";\r
+    } else if (tags.contains("<col")) {\r
+      wrapPos = 2;\r
+      preWrap = "<table><tbody></tbody><colgroup>";\r
+      postWrap = "</colgroup></table>";\r
+    }\r
+    //TODO: fix IE link tag serialization\r
+    Element div = Document.get().createDivElement();\r
+    div.setInnerHTML(preWrap + elem + postWrap);\r
+    Node n = div;\r
+    while (wrapPos-- != 0) {\r
+      n = n.getLastChild();\r
+    }\r
+    //TODO: add fixes for IE TBODY issue\r
+    return JSArray.create(n);\r
   }\r
 \r
   private <S> Object data(Element item, String name, S value) {\r
@@ -1234,12 +1825,37 @@ public class GQuery {
     }\r
   }\r
 \r
-  private void ensureStyleImpl() {\r
-    if (styleImpl != null) {\r
-      styleImpl = GWT.create(DocumentStyleImpl.class);\r
+  private GQuery domManip(String html, int func) {\r
+    return domManip(clean(html), func);\r
+  }\r
+\r
+  private GQuery domManip(NodeList nodes, int func) {\r
+    for (Element e : elements()) {\r
+      for (int i = 0; i < nodes.getLength(); i++) {\r
+        Node n = nodes.getItem(i).cloneNode(true);\r
+        switch (func) {\r
+          case FUNC_PREPEND:\r
+            e.insertBefore(n, e.getFirstChild());\r
+            break;\r
+          case FUNC_APPEND:\r
+            e.appendChild(n);\r
+            break;\r
+          case FUNC_AFTER:\r
+            e.getParentNode().insertBefore(n, e.getNextSibling());\r
+            break;\r
+          case FUNC_BEFORE:\r
+            e.getParentNode().insertBefore(n, e);\r
+            break;\r
+        }\r
+      }\r
     }\r
+    return this;\r
   }\r
 \r
+  private native Document getContentDocument(Node n) /*-{\r
+    return n.contentDocument || n.contentWindow.document;\r
+  }-*/;\r
+\r
   private native Element getPreviousSiblingElement(Element elem)  /*-{\r
     var sib = elem.previousSibling;\r
     while (sib && sib.nodeType != 1)\r
@@ -1251,6 +1867,30 @@ public class GQuery {
     this.elements = gQuery.elements;\r
   }\r
 \r
+  private JSArray merge(NodeList<Element> first, NodeList<Element> second) {\r
+    JSArray res = JSArray.create();\r
+    for (int i = 0; i < first.getLength(); i++) {\r
+      res.addNode(first.getItem(i));\r
+    }\r
+    for (int i = 0; i < second.getLength(); i++) {\r
+      res.addNode(second.getItem(i));\r
+    }\r
+    return res;\r
+  }\r
+\r
+  private int num(GQuery gQuery, String val) {\r
+    Element elem = gQuery.get(0);\r
+    try {\r
+      if (elem != null) {\r
+        String v = GQuery.curCSS(elem, val);\r
+        return Integer.parseInt(v);\r
+      }\r
+    } catch (NumberFormatException e) {\r
+\r
+    }\r
+    return 0;\r
+  }\r
+\r
   private Queue<Function> queue(Element elem, String type, Function data) {\r
     if (elem != null) {\r
       type = type + "queue";\r