} else {\r
Node c = e.getFirstChild();\r
while (c != null) {\r
- removeData(c.<Element>cast(), null);\r
+ removeData(c.<Element> cast(), null);\r
GqUi.detachWidget(getAssociatedWidget(e));\r
- EventsListener.getInstance(c.<Element>cast()).clean();\r
+ EventsListener.clean(c.<Element> cast());\r
e.removeChild(c);\r
c = e.getFirstChild();\r
}\r
* filters at once.\r
*/\r
public GQuery filter(String... filters) {\r
- \r
+\r
JsNodeArray array = JsNodeArray.create();\r
- \r
+\r
for (String f : filters) {\r
for (Element e : elements()) {\r
boolean ghostParent = false;\r
- \r
- if (e.getParentNode() == null){\r
+\r
+ if (e.getParentNode() == null) {\r
DOM.createDiv().appendChild(e);\r
ghostParent = true;\r
}\r
- \r
+\r
for (Element c : $(f, e.getParentNode()).elements()) {\r
if (c == e) {\r
array.addNode(c);\r
break;\r
}\r
}\r
- \r
- if(ghostParent){\r
+\r
+ if (ghostParent) {\r
e.removeFromParent();\r
}\r
}\r
* negative index is counted from the end of the matched set.\r
* \r
* Example:\r
+ * \r
* <pre>\r
* $("div").get(0) will return the first matched div\r
* $("div").get(1) will return the second matched div\r
*/\r
@SuppressWarnings("unchecked")\r
public <W> List<W> map(Function f) {\r
- @SuppressWarnings("rawtypes")\r
ArrayList ret = new ArrayList();\r
for (int i = 0; i < elements().length; i++) {\r
Object o = f.f(elements()[i], i);\r
* Removes all matched elements from the DOM.\r
*/\r
public GQuery remove() {\r
- for (Element e : elements()) {\r
- Widget w = getAssociatedWidget(e);\r
- if (w != null) {\r
- w.removeFromParent();\r
- } else {\r
- e.removeFromParent();\r
- }\r
- }\r
- return this;\r
+ return remove(null, true);\r
+ }\r
+\r
+ /**\r
+ * Removes from the DOM all matched elements filtered by the\r
+ * <code>filter</code>.\r
+ */\r
+ public GQuery remove(String filter) {\r
+ return remove(filter, true);\r
}\r
\r
/**\r
- * Removes all matched elements from the DOM and cleans their data and bound events.\r
+ * Detach all matched elements from the DOM. This method is the same than\r
+ * {@link #remove()} method except all data and event handlers are not remove\r
+ * from the element. This method is useful when removed elements are to be\r
+ * reinserted into the DOM at a later time.\r
*/\r
- public GQuery remove(boolean clean) {\r
+ public GQuery detach() {\r
+ return remove(null, false);\r
+ }\r
+\r
+ /**\r
+ * Detach from the DOM all matched elements filtered by the\r
+ * <code>filter</code>.. This method is the same than {@link #remove(String)}\r
+ * method except all data and event handlers are not remove from the element.\r
+ * This method is useful when removed elements are to be reinserted into the\r
+ * DOM at a later time.\r
+ */\r
+ public GQuery detach(String filter) {\r
+ return remove(filter, false);\r
+ }\r
+\r
+ /**\r
+ * Removes all matched elements from the DOM and cleans their data and bound\r
+ * events if the value of <code>clean</code> parameter is set to true. The\r
+ * <code> filter</code> parameter allows to filter the matched set to remove.\r
+ */\r
+ protected GQuery remove(String filter, boolean clean) {\r
+ \r
for (Element e : elements()) {\r
- EventsListener.getInstance(e).clean();\r
- removeData(e, null);\r
+ if (filter == null || $(e).filter(filter).length() == 1) {\r
+ if (clean) {\r
+ //clean data linked to the children\r
+ cleanGQData($(e.getElementsByTagName("*")).elements());\r
+ //clean data linked to the element itself\r
+ cleanGQData(e);\r
+ }\r
+ Widget w = getAssociatedWidget(e);\r
+ if (w != null) {\r
+ w.removeFromParent();\r
+ } else {\r
+ e.removeFromParent();\r
+ }\r
+ }\r
}\r
- remove();\r
+\r
return this;\r
}\r
\r
// e.getOwnerDocument();\r
if (e.getNodeType() == Node.DOCUMENT_NODE) {\r
e = e.<Document> cast().getBody();\r
- } \r
+ }\r
for (int j = 0; j < g.size(); j++) {\r
-// Widget w = getAssociatedWidget(g.get(j));\r
-// GqUi.detachWidget(w);\r
+ // Widget w = getAssociatedWidget(g.get(j));\r
+ // GqUi.detachWidget(w);\r
Node n = g.get(j);\r
if (g.size() > 1) {\r
n = n.cloneNode(true);\r
newNodes.addNode(e.getParentNode().insertBefore(n, e));\r
break;\r
}\r
- EventsListener.getInstance(n.<Element>cast()).rebind();\r
-// GqUi.attachWidget(w);\r
+ EventsListener.getInstance(n.<Element> cast()).rebind();\r
+ // GqUi.attachWidget(w);\r
}\r
}\r
if (newNodes.size() > g.size()) {\r
dataCache.delete(id);\r
}\r
}\r
+ \r
+ private void cleanGQData(Element... elements){\r
+ for (Element el : elements){\r
+ EventsListener.clean(el);\r
+ removeData(el, null);\r
+ }\r
+ }\r
}\r
* 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
*/
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.
*/
// 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) {
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;
}
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);
}
}
- 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);
dispatchEvent(event);
}
+ public void rebind() {
+ sink();
+ }
+
public void unbind(int eventbits) {
unbind(eventbits, null);
}
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));
+
+ }
+ }
}
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));
+
+
+
+ }
}