diff options
author | Julien Dramaix <julien.dramaix@gmail.com> | 2011-03-28 21:13:39 +0000 |
---|---|---|
committer | Julien Dramaix <julien.dramaix@gmail.com> | 2011-03-28 21:13:39 +0000 |
commit | 05167d6898ba2135d1fab5f9f7f0ae4bcd07ffa0 (patch) | |
tree | eec8e3a90391ad24e48da8af668dca69e89a920d /gwtquery-core | |
parent | 8c0f85f1b80a7c4fbfe7a27f6ab81dc0ca1a39ee (diff) | |
download | gwtquery-05167d6898ba2135d1fab5f9f7f0ae4bcd07ffa0.tar.gz gwtquery-05167d6898ba2135d1fab5f9f7f0ae4bcd07ffa0.zip |
add detach method.
refactoring of the remove() method to be compliant with jQuery documentation
add test for remove and detach methods.
Don't try to clean GQuery events if no one EventListener exists + correct bug in event cleaning
Diffstat (limited to 'gwtquery-core')
4 files changed, 250 insertions, 63 deletions
diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/GQuery.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/GQuery.java index e66cc950..9eee6b24 100644 --- a/gwtquery-core/src/main/java/com/google/gwt/query/client/GQuery.java +++ b/gwtquery-core/src/main/java/com/google/gwt/query/client/GQuery.java @@ -1064,9 +1064,9 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> { } else {
Node c = e.getFirstChild();
while (c != null) {
- removeData(c.<Element>cast(), null);
+ removeData(c.<Element> cast(), null);
GqUi.detachWidget(getAssociatedWidget(e));
- EventsListener.getInstance(c.<Element>cast()).clean();
+ EventsListener.clean(c.<Element> cast());
e.removeChild(c);
c = e.getFirstChild();
}
@@ -1165,26 +1165,26 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> { * filters at once.
*/
public GQuery filter(String... filters) {
-
+
JsNodeArray array = JsNodeArray.create();
-
+
for (String f : filters) {
for (Element e : elements()) {
boolean ghostParent = false;
-
- if (e.getParentNode() == null){
+
+ if (e.getParentNode() == null) {
DOM.createDiv().appendChild(e);
ghostParent = true;
}
-
+
for (Element c : $(f, e.getParentNode()).elements()) {
if (c == e) {
array.addNode(c);
break;
}
}
-
- if(ghostParent){
+
+ if (ghostParent) {
e.removeFromParent();
}
}
@@ -1240,6 +1240,7 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> { * negative index is counted from the end of the matched set.
*
* Example:
+ *
* <pre>
* $("div").get(0) will return the first matched div
* $("div").get(1) will return the second matched div
@@ -1562,7 +1563,6 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> { */
@SuppressWarnings("unchecked")
public <W> List<W> map(Function f) {
- @SuppressWarnings("rawtypes")
ArrayList ret = new ArrayList();
for (int i = 0; i < elements().length; i++) {
Object o = f.f(elements()[i], i);
@@ -1986,26 +1986,62 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> { * Removes all matched elements from the DOM.
*/
public GQuery remove() {
- for (Element e : elements()) {
- Widget w = getAssociatedWidget(e);
- if (w != null) {
- w.removeFromParent();
- } else {
- e.removeFromParent();
- }
- }
- return this;
+ return remove(null, true);
+ }
+
+ /**
+ * Removes from the DOM all matched elements filtered by the
+ * <code>filter</code>.
+ */
+ public GQuery remove(String filter) {
+ return remove(filter, true);
}
/**
- * Removes all matched elements from the DOM and cleans their data and bound events.
+ * Detach all matched elements from the DOM. This method is the same than
+ * {@link #remove()} method except all data and event handlers are not remove
+ * from the element. This method is useful when removed elements are to be
+ * reinserted into the DOM at a later time.
*/
- public GQuery remove(boolean clean) {
+ public GQuery detach() {
+ return remove(null, false);
+ }
+
+ /**
+ * Detach from the DOM all matched elements filtered by the
+ * <code>filter</code>.. This method is the same than {@link #remove(String)}
+ * method except all data and event handlers are not remove from the element.
+ * This method is useful when removed elements are to be reinserted into the
+ * DOM at a later time.
+ */
+ public GQuery detach(String filter) {
+ return remove(filter, false);
+ }
+
+ /**
+ * Removes all matched elements from the DOM and cleans their data and bound
+ * events if the value of <code>clean</code> parameter is set to true. The
+ * <code> filter</code> parameter allows to filter the matched set to remove.
+ */
+ protected GQuery remove(String filter, boolean clean) {
+
for (Element e : elements()) {
- EventsListener.getInstance(e).clean();
- removeData(e, null);
+ if (filter == null || $(e).filter(filter).length() == 1) {
+ if (clean) {
+ //clean data linked to the children
+ cleanGQData($(e.getElementsByTagName("*")).elements());
+ //clean data linked to the element itself
+ cleanGQData(e);
+ }
+ Widget w = getAssociatedWidget(e);
+ if (w != null) {
+ w.removeFromParent();
+ } else {
+ e.removeFromParent();
+ }
+ }
}
- remove();
+
return this;
}
@@ -2877,10 +2913,10 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> { // e.getOwnerDocument();
if (e.getNodeType() == Node.DOCUMENT_NODE) {
e = e.<Document> cast().getBody();
- }
+ }
for (int j = 0; j < g.size(); j++) {
-// Widget w = getAssociatedWidget(g.get(j));
-// GqUi.detachWidget(w);
+ // Widget w = getAssociatedWidget(g.get(j));
+ // GqUi.detachWidget(w);
Node n = g.get(j);
if (g.size() > 1) {
n = n.cloneNode(true);
@@ -2900,8 +2936,8 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> { newNodes.addNode(e.getParentNode().insertBefore(n, e));
break;
}
- EventsListener.getInstance(n.<Element>cast()).rebind();
-// GqUi.attachWidget(w);
+ EventsListener.getInstance(n.<Element> cast()).rebind();
+ // GqUi.attachWidget(w);
}
}
if (newNodes.size() > g.size()) {
@@ -2959,4 +2995,11 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> { dataCache.delete(id);
}
}
+
+ private void cleanGQData(Element... elements){
+ for (Element el : elements){
+ EventsListener.clean(el);
+ removeData(el, null);
+ }
+ }
}
diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/LazyGQuery.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/LazyGQuery.java index 98d3d035..ef43e69d 100644 --- a/gwtquery-core/src/main/java/com/google/gwt/query/client/LazyGQuery.java +++ b/gwtquery-core/src/main/java/com/google/gwt/query/client/LazyGQuery.java @@ -523,6 +523,7 @@ public interface LazyGQuery<T> extends LazyBase<T>{ * negative index is counted from the end of the matched set. * * Example: + * * <pre> * $("div").get(0) will return the first matched div * $("div").get(1) will return the second matched div @@ -966,6 +967,29 @@ public interface LazyGQuery<T> extends LazyBase<T>{ LazyGQuery<T> remove(); /** + * Removes from the DOM all matched elements filtered by the + * <code>filter</code>. + */ + LazyGQuery<T> remove(String filter); + + /** + * Detach all matched elements from the DOM. This method is the same than + * {@link #remove()} method except all data and event handlers are not remove + * from the element. This method is useful when removed elements are to be + * reinserted into the DOM at a later time. + */ + LazyGQuery<T> detach(); + + /** + * Detach from the DOM all matched elements filtered by the + * <code>filter</code>.. This method is the same than {@link #remove(String)} + * method except all data and event handlers are not remove from the element. + * This method is useful when removed elements are to be reinserted into the + * DOM at a later time. + */ + LazyGQuery<T> detach(String filter); + + /** * Remove the named attribute from every element in the matched set. */ LazyGQuery<T> removeAttr(String key); diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/events/EventsListener.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/events/EventsListener.java index 9bbae7ce..3903794d 100644 --- a/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/events/EventsListener.java +++ b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/events/EventsListener.java @@ -73,25 +73,35 @@ public class EventsListener implements EventListener { // Gwt Events class has not this event defined public static int ONSUBMIT = 0x08000; + public static void clean(Element e) { + EventsListener ret = getGQueryEventListener(e); + if (ret != null){ + ret.clean(); + } + } + public static EventsListener getInstance(Element e) { EventsListener ret = getGQueryEventListener(e); return ret != null ? ret : new EventsListener(e); } + private static native void cleanGQListeners(Element elem) /*-{ + if (elem.__gwtlistener) { + elem.__listener = elem.__gwtlistener; + } + elem.__gquerysubmit = null; + elem.__gqueryevent = null + + }-*/; + private static native EventsListener getGQueryEventListener(Element elem) /*-{ return elem.__gqueryevent; }-*/; - + private static native EventListener getGwtEventListener(Element elem) /*-{ return elem.__gwtlistener; }-*/; - - private static native void cleanGQListeners() /*-{ - elem.__listener = elem.__gwtlistener; - elem.__gquerysubmit = null; - elem.__gqueryevent = null; - }-*/; - + private static native void setGQueryEventListener(Element elem, EventsListener gqevent) /*-{ if (elem.__gqueryevent) { @@ -116,16 +126,16 @@ public class EventsListener implements EventListener { else elem.attachEvent("onsubmit", handle); }-*/; - + int eventBits = 0; double lastEvnt = 0; + int lastType = 0; - int eventBits = 0; private Element element; private JsObjectArray<BindFunction> elementEvents = JsObjectArray .createArray().cast(); - + private EventsListener(Element element) { this.element = element; } @@ -133,12 +143,12 @@ public class EventsListener implements EventListener { public void bind(int eventbits, final Object data, Function...funcs) { bind(eventbits, null, data, funcs); } - + public void bind(int eventbits, final Object data, final Function function, int times) { bind(eventbits, null, data, function, times); } - + public void bind(int eventbits, String name, final Object data, Function...funcs) { for (Function function: funcs) { bind(eventbits, name, data, function, -1); @@ -170,21 +180,6 @@ public class EventsListener implements EventListener { } } - private void sink() { - setGQueryEventListener(element, this); - DOM.setEventListener((com.google.gwt.user.client.Element)element, this); - if (eventBits == ONSUBMIT) { - sinkSubmitEvent(element); - } else { - if ((eventBits | Event.FOCUSEVENTS) == Event.FOCUSEVENTS && element.getAttribute("tabIndex").length() == 0) { - element.setAttribute("tabIndex", "0"); - } - DOM.sinkEvents((com.google.gwt.user.client.Element) element, eventBits - | DOM.getEventsSunk((com.google.gwt.user.client.Element) element)); - - } - } - public void dispatchEvent(Event event) { int etype = "submit".equalsIgnoreCase(event.getType()) ? ONSUBMIT : DOM.eventGetType(event); @@ -226,6 +221,10 @@ public class EventsListener implements EventListener { dispatchEvent(event); } + public void rebind() { + sink(); + } + public void unbind(int eventbits) { unbind(eventbits, null); } @@ -257,12 +256,23 @@ public class EventsListener implements EventListener { unbind(b, nameSpace); } - public void rebind() { - sink(); - } - - public void clean() { - cleanGQListeners(); + private void clean(){ + cleanGQListeners(element); elementEvents = JsObjectArray.createArray().cast(); } + + private void sink() { + setGQueryEventListener(element, this); + DOM.setEventListener((com.google.gwt.user.client.Element)element, this); + if (eventBits == ONSUBMIT) { + sinkSubmitEvent(element); + } else { + if ((eventBits | Event.FOCUSEVENTS) == Event.FOCUSEVENTS && element.getAttribute("tabIndex").length() == 0) { + element.setAttribute("tabIndex", "0"); + } + DOM.sinkEvents((com.google.gwt.user.client.Element) element, eventBits + | DOM.getEventsSunk((com.google.gwt.user.client.Element) element)); + + } + } } diff --git a/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryCoreTest.java b/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryCoreTest.java index 21365a01..1a53a88b 100644 --- a/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryCoreTest.java +++ b/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryCoreTest.java @@ -978,5 +978,115 @@ public class GQueryCoreTest extends GWTTestCase { Assert.assertNull($((String) null).get(-1)); Assert.assertEquals(0, $((String) null).eq(0).size()); } + + public void testRemoveMethod(){ + String html = "<div id='parent'>parent<div id='child'>child</div></div>"; + $(e).html(html); + + Function failCallback = new Function(){ + @Override + public void f() { + fail("Event binding not removed"); + } + }; + + Element parent = $("#parent", e).get(0); + Element child = $("#child", e).get(0); + + $("#child", e).data("key", "child"); + $("#child", e).click(failCallback); + $("#parent", e).data("key", "parent"); + $("#parent", e).click(failCallback); + + $("#parent", e).remove(); + + assertNull($(child).data("key")); + assertNull($(parent).data("key")); + //if failCallback is always binded, test fails... + $(child).click(); + $(parent).click(); + + + + } + + public void testRemoveMethodWithFilter(){ + String html = "<div id='parent'>parent<div id='child'>child</div></div>"; + $(e).html(html); + + Function failCallback = new Function(){ + @Override + public void f() { + fail("Event binding not removed"); + } + }; + + Function noFailCallback = new Function(){ + @Override + public void f(Element e) { + $(e).css(CSS.BACKGROUND_COLOR.with(RGBColor.RED)); + } + }; + + Element parent = $("#parent", e).get(0); + Element child = $("#child", e).get(0); + + $("#child", e).data("key", "child"); + $("#child", e).click(failCallback); + $("#parent", e).data("key", "parent"); + $("#parent", e).click(noFailCallback); + + $("div", e).remove("#child"); + + assertNull($(child).data("key")); + assertEquals("parent",$(parent).data("key")); + + //if failCallback is always binded, test fails... + $(child).click(); + + + $(parent).click(); + assertEquals("red", $(parent).css(CSS.BACKGROUND_COLOR)); + + + } + + public void testDetachMethod(){ + String html = "<div id='parent'>parent<div id='child'>child</div></div>"; + $(e).html(html); + + Function noFailCallback = new Function(){ + @Override + public void f(Element e) { + $(e).css(CSS.BACKGROUND_COLOR.with(RGBColor.RED)); + } + }; + + Element parent = $("#parent", e).get(0); + Element child = $("#child", e).get(0); + + $("#child", e).data("key", "child"); + $("#child", e).click(noFailCallback); + $("#parent", e).data("key", "parent"); + $("#parent", e).click(noFailCallback); + + GQuery $parent = $("#parent", e).detach(); + + assertEquals("child",$(child).data("key")); + assertEquals("parent",$(parent).data("key")); + + $(e).append($parent); + + assertEquals("child",$("#child", e).data("key")); + assertEquals("parent",$("#parent", e).data("key")); + + $("#child", e).click(); + assertEquals("red", $(child).css(CSS.BACKGROUND_COLOR)); + $("#parent", e).click(); + assertEquals("red", $(parent).css(CSS.BACKGROUND_COLOR)); + + + + } } |