diff options
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)); + + + + } } |