From 28c935fd3e83d13da18a7fc80866e3ef8ce15285 Mon Sep 17 00:00:00 2001 From: Manolo Carrasco Date: Wed, 3 Dec 2014 21:11:04 +0100 Subject: Faster implementation of filter --- .../java/com/google/gwt/query/client/GQuery.java | 90 ++++++++++++++++------ .../com/google/gwt/query/client/LazyGQuery.java | 17 ++++ .../gwt/query/client/plugins/LazyEffects.java | 7 ++ .../gwt/query/client/plugins/LazyEvents.java | 1 - .../google/gwt/query/client/GQueryCoreTestGwt.java | 1 - 5 files changed, 90 insertions(+), 26 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 32a30e1f..5217c92b 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 @@ -160,6 +160,12 @@ public class GQuery implements Lazy { private static final String OLD_DISPLAY = OLD_DATA_PREFIX + "display"; + /** + * Set it to false if all your elements are attached to the DOM and you want to + * increase filter performance. + */ + public static boolean filterDetached = true; + private static JsMap, Plugin> plugins; // Sizzle POS regex : usefull in some methods @@ -2268,40 +2274,76 @@ public class GQuery implements Lazy { /** * Removes all elements from the set of matched elements that do not pass the specified css * expression. This method is used to narrow down the results of a search. + * By default it works for either detached and attached elements unless the static + * {@link #filterDetached} is set to false. */ - // TODO performance bad... public GQuery filter(String... filters) { - if (filters.length == 0 || filters[0] == null) { - return this; - } - - JsNodeArray array = JsNodeArray.create(); + return filter(filterDetached, filters); + } + /** + * Removes all elements from the set of matched elements that do not pass the specified css + * expression. This method is used to narrow down the results of a search. + * Setting considerDetached parameter to true, means that we should consider detached elements + * as well which implies some performance penalties. + */ + public GQuery filter(boolean filterDetached, String... filters) { + String sel = ""; for (String f : filters) { - for (Element e : elements) { - boolean ghostParent = false; - if (e == window || e.getNodeName() == null) { - continue; - } - if (e.getParentNode() == null) { - DOM.createDiv().appendChild(e); - ghostParent = true; - } + sel += (sel.isEmpty() ? "" : ",") + f; + } + return filter(filterDetached, sel); + } - for (Element c : $(f, e.getParentNode()).elements) { - if (c == e) { - array.addNode(c); - break; + /** + * Removes all elements from the set of matched elements that do not pass the specified css + * expression. This method is used to narrow down the results of a search. + * Setting considerDetached parameter to true, means that we should consider detached elements + * as well which implies some performance penalties. + */ + public GQuery filter(boolean filterDetached, String selector) { + if (selector.isEmpty()) { + return this; + } + Element ghostParent = null; + ArrayList parents = new ArrayList(); + List elmList = new ArrayList(); + for (Node e : elements()) { + if (e == window || e == document || e.getNodeName() == null || "html".equalsIgnoreCase(e.getNodeName())) { + continue; + } + elmList.add(e); + if (filterDetached) { + Element p = e.getParentElement(); + if (p == null) { + if (ghostParent == null) { + ghostParent = Document.get().createDivElement(); + parents.add(ghostParent); } + p = ghostParent; + p.appendChild(e); + } else if (!parents.contains(p)) { + parents.add(p); } - - if (ghostParent) { - e.removeFromParent(); + } else if (parents.isEmpty()) { + parents.add(document); + } + } + JsNodeArray array = JsNodeArray.create(); + for (Node e : parents) { + NodeList n = getSelectorEngine().select(selector, e); + for (int i = 0, l = n.getLength(); i < l; i++) { + Element el = n.getItem(i); + if (elmList.contains(el)) { + elmList.remove(el); + array.addNode(el); } } } - - return pushStack(unique(array), "filter", filters[0]); + if (ghostParent != null) { + $(ghostParent).empty(); + } + return pushStack(array, "filter", selector); } /** 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 af506174..33b12731 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 @@ -1015,9 +1015,26 @@ public interface LazyGQuery extends LazyBase{ /** * Removes all elements from the set of matched elements that do not pass the specified css * expression. This method is used to narrow down the results of a search. + * {@link #filterDetached} is set to false. */ LazyGQuery filter(String... filters); + /** + * Removes all elements from the set of matched elements that do not pass the specified css + * expression. This method is used to narrow down the results of a search. + * Setting considerDetached parameter to true, means that we should consider detached elements + * as well which implies some performance penalties. + */ + LazyGQuery filter(boolean filterDetached, String... filters); + + /** + * Removes all elements from the set of matched elements that do not pass the specified css + * expression. This method is used to narrow down the results of a search. + * Setting considerDetached parameter to true, means that we should consider detached elements + * as well which implies some performance penalties. + */ + LazyGQuery filter(boolean filterDetached, String selector); + /** * Searches for all elements that match the specified css expression. This method is a good way to * find additional descendant elements with which to process. diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/LazyEffects.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/LazyEffects.java index cf62be4f..f0af09b8 100644 --- a/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/LazyEffects.java +++ b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/LazyEffects.java @@ -362,6 +362,13 @@ public interface LazyEffects extends LazyBase{ */ LazyEffects slideRight(int millisecs, Function... f); + /** + * Toggle the visibility of all matched elements by adjusting their height and firing an optional + * callback after completion. Only the height is adjusted for this animation, causing all matched + * elements to be hidden or shown in a "sliding" manner + */ + LazyEffects slideToggle(Function... f); + /** * Toggle the visibility of all matched elements by adjusting their height and * firing an optional callback after completion. Only the height is adjusted diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/LazyEvents.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/LazyEvents.java index dec30be8..081e1702 100644 --- a/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/LazyEvents.java +++ b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/LazyEvents.java @@ -16,7 +16,6 @@ import com.google.gwt.dom.client.Element; import com.google.gwt.dom.client.FormElement; import com.google.gwt.dom.client.NativeEvent; import com.google.gwt.dom.client.Node; -import com.google.gwt.event.dom.client.HasNativeEvent; import com.google.gwt.query.client.Function; import com.google.gwt.query.client.GQuery; import com.google.gwt.query.client.js.JsUtils; diff --git a/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryCoreTestGwt.java b/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryCoreTestGwt.java index f4a4d963..763655da 100644 --- a/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryCoreTestGwt.java +++ b/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryCoreTestGwt.java @@ -877,7 +877,6 @@ public class GQueryCoreTestGwt extends GWTTestCase { public void testShowHide() { $(e).html( "

Content 1

Content 2

Content 3

"); - final GQuery sectA = $("#id1"); final GQuery sectB = $("#id2"); final GQuery sectC = $("#id3"); -- cgit v1.2.3