aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorManolo Carrasco <manolo@apache.org>2011-07-28 09:44:01 +0000
committerManolo Carrasco <manolo@apache.org>2011-07-28 09:44:01 +0000
commit9db75b2103c3e2258f0c8a5c9fc6e426ba3fc1a6 (patch)
tree5ed6f915584ab3d1ba2b5fa359e450ae4cf433f4
parent22079d84f5edcb42b4bc494c2a89a618c906f24f (diff)
downloadgwtquery-9db75b2103c3e2258f0c8a5c9fc6e426ba3fc1a6.tar.gz
gwtquery-9db75b2103c3e2258f0c8a5c9fc6e426ba3fc1a6.zip
implement :hidden and :visible pseudo selectors, fixes issue86
-rw-r--r--gwtquery-core/src/main/java/com/google/gwt/query/client/GQuery.java44
-rw-r--r--gwtquery-core/src/main/java/com/google/gwt/query/client/impl/SelectorEngine.java40
-rw-r--r--gwtquery-core/src/main/java/com/google/gwt/query/client/impl/SelectorEngineCssToXPath.java5
-rw-r--r--gwtquery-core/src/main/java/com/google/gwt/query/client/js/JsUtils.java16
-rwxr-xr-xgwtquery-core/src/main/java/com/google/gwt/query/client/plugins/effects/ClipAnimation.java2
-rwxr-xr-xgwtquery-core/src/main/java/com/google/gwt/query/client/plugins/effects/PropertiesAnimation.java2
-rw-r--r--gwtquery-core/src/test/java/com/google/gwt/query/client/GQuerySelectorsTest.java39
7 files changed, 99 insertions, 49 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 625521c7..cdc8cbee 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
@@ -40,9 +40,7 @@ import com.google.gwt.query.client.css.HasCssValue;
import com.google.gwt.query.client.css.TakesCssValue;
import com.google.gwt.query.client.css.TakesCssValue.CssSetter;
import com.google.gwt.query.client.impl.DocumentStyleImpl;
-import com.google.gwt.query.client.impl.HasSelector;
import com.google.gwt.query.client.impl.SelectorEngine;
-import com.google.gwt.query.client.impl.SelectorEngineCssToXPath;
import com.google.gwt.query.client.js.JsCache;
import com.google.gwt.query.client.js.JsMap;
import com.google.gwt.query.client.js.JsNamedArray;
@@ -443,14 +441,6 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
}
}
- private static JsNodeArray copyNodeList(NodeList<? extends Node> nodes) {
- JsNodeArray res = JsNodeArray.create();
- for (int i = 0, l = nodes.getLength(); i < l; i++) {
- res.addNode(nodes.getItem(i), i);
- }
- return res;
- }
-
private static native void emptyDocument(Document d) /*-{
d.open();
d.write("<head/><body/>");
@@ -490,14 +480,11 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
if (engine == null) {
engine = new SelectorEngine();
}
-
- NodeList<Element> n = engine.select(selector, context == null ? document : context);
- JsNodeArray res = copyNodeList(n);
+ NodeList<Element> n = engine.select(selector, context == null ? document : context);
currentSelector = selector;
currentContext = context != null ? context : document;
-
- return setArray(res);
+ return setArray(n);
}
private static native Element window() /*-{
@@ -545,14 +532,13 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
* It also update the selector appending the new one.
*/
public GQuery add(GQuery previousObject) {
- return pushStack(unique(merge(nodeList, previousObject.nodeList)), "add",
+ return pushStack(unique(JsUtils.copyNodeList(previousObject.nodeList, nodeList)), "add",
getSelector() + "," + previousObject.getSelector());
}
/**
* Add elements to the set of matched elements if they are not included yet.
*/
-
public GQuery add(String selector) {
return add($(selector));
}
@@ -1876,7 +1862,7 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
}
return pushStack(unique(array), "filter", filters[0]);
}
-
+
/**
* Searches for all elements that match the specified css expression. This
* method is a good way to find additional descendant elements with which to
@@ -3532,7 +3518,7 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
*/
public GQuery toggle() {
for (Element e : elements) {
- if ($(e).visible()) {
+ if (styleImpl.isVisible(e)) {
$(e).hide();
} else {
$(e).show();
@@ -3688,7 +3674,7 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
* Remove all duplicate elements from an array of elements. Note that this
* only works on arrays of DOM elements, not strings or numbers.
*/
- public JsNodeArray unique(JsNodeArray result) {
+ public JsNodeArray unique(NodeList<Element> result) {
return JsUtils.unique(result.<JsArray<Element>> cast()).cast();
}
@@ -3832,12 +3818,18 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
return new String[0];
}
+
/**
- * Return true if the first element is visible.
+ * Return true if the first element is visible.isVisible
*/
- public boolean visible() {
+ public boolean isVisible() {
return isEmpty() ? false : styleImpl.isVisible(get(0));
}
+
+ @Deprecated
+ public boolean visible() {
+ return isVisible();
+ }
/**
* Return the first non null attached widget from the matched elements or null
@@ -4216,14 +4208,6 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
return sib;
}-*/;
- private JsNodeArray merge(NodeList<Element> first, NodeList<Element> second) {
- JsNodeArray res = copyNodeList(first);
- for (int i = 0, l = second.getLength(); i < l; i++) {
- res.addNode(second.getItem(i));
- }
- return res;
- }
-
private void removeData(Element item, String name) {
if (dataCache == null) {
windowData = JavaScriptObject.createObject().cast();
diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/impl/SelectorEngine.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/impl/SelectorEngine.java
index 8451be10..65d735df 100644
--- a/gwtquery-core/src/main/java/com/google/gwt/query/client/impl/SelectorEngine.java
+++ b/gwtquery-core/src/main/java/com/google/gwt/query/client/impl/SelectorEngine.java
@@ -16,16 +16,20 @@
package com.google.gwt.query.client.impl;
import com.google.gwt.core.client.GWT;
+import com.google.gwt.core.client.JsArray;
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.Node;
import com.google.gwt.dom.client.NodeList;
import com.google.gwt.query.client.js.JsNodeArray;
+import com.google.gwt.query.client.js.JsUtils;
/**
* Core Selector engine functions, and native JS utility functions.
*/
public class SelectorEngine implements HasSelector {
+
+ private static DocumentStyleImpl styleImpl;
public static native NodeList<Element> getElementsByClassName(String clazz,
Node ctx) /*-{
@@ -86,17 +90,47 @@ public class SelectorEngine implements HasSelector {
public SelectorEngine() {
impl = (SelectorEngineImpl) GWT.create(SelectorEngineImpl.class);
- System.out.println("Create SelectorEngineImpl " + impl.getClass().getName());
+ System.out.println("Created SelectorEngineImpl: " + impl.getClass().getName());
+ styleImpl = GWT.create(DocumentStyleImpl.class);
+ System.out.println("Created DocumentStyleImpl: " + styleImpl.getClass().getName());
}
public Node getRoot() {
return root;
}
+ public NodeList<Element> filterByVisibility (NodeList<Element> nodes, boolean visible) {
+ JsNodeArray res = JsNodeArray.create();
+ for (int i = 0, l = nodes.getLength(), j = 0; i < l; i++) {
+ Element e = nodes.getItem(i);
+ if (visible == ((e.getOffsetWidth() + e.getOffsetHeight()) > 0 && styleImpl.isVisible(e))) {
+ res.addNode(e, j++);
+ }
+ }
+ return res;
+ }
+
public NodeList<Element> select(String selector, Node ctx) {
- return impl.select(selector, ctx);
+ if (selector.matches(".*:(visible|hidden)\\s*(,|$).*")) {
+ // :visible and :hidden pseudo selectors are computed by gquery
+ JsNodeArray res = JsNodeArray.create();
+ for (String s : selector.trim().split("\\s*,\\s*")) {
+ NodeList<Element> nodes;
+ if (s.endsWith(":visible")) {
+ nodes = filterByVisibility(select(s.substring(0, s.length() - 8), ctx), true);
+ } else if (s.endsWith(":hidden")) {
+ nodes = filterByVisibility(select(s.substring(0, s.length() - 7), ctx), false);
+ } else {
+ nodes = select(s, ctx);
+ }
+ JsUtils.copyNodeList(res, nodes);
+ }
+ return JsUtils.unique(res.<JsArray<Element>> cast()).cast();
+ } else {
+ return impl.select(selector, ctx);
+ }
}
-
+
public void setRoot(Node root) {
assert root != null;
this.root = root;
diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/impl/SelectorEngineCssToXPath.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/impl/SelectorEngineCssToXPath.java
index 4ed673f6..5feec66f 100644
--- a/gwtquery-core/src/main/java/com/google/gwt/query/client/impl/SelectorEngineCssToXPath.java
+++ b/gwtquery-core/src/main/java/com/google/gwt/query/client/impl/SelectorEngineCssToXPath.java
@@ -34,7 +34,7 @@ import com.google.gwt.query.client.js.JsUtils;
*/
public class SelectorEngineCssToXPath extends SelectorEngineImpl {
- JsNamedArray<String> cache;
+ static JsNamedArray<String> cache;
/**
* Interface for callbacks in replaceAll operations.
@@ -225,7 +225,8 @@ public class SelectorEngineCssToXPath extends SelectorEngineImpl {
return JsUtils.unique(elm.<JsArray<Element>> cast()).cast();
} catch (Exception e) {
System.err.println("ERROR: xpathEvaluate invalid xpath expression:"
- + xsel + " css-selector:" + sel + "\n\n" + e.getMessage());
+ + xsel + " css-selector:" + sel + "\n");
+ e.printStackTrace();
return elm;
}
}
diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/js/JsUtils.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/js/JsUtils.java
index b504d6e4..686550ec 100644
--- a/gwtquery-core/src/main/java/com/google/gwt/query/client/js/JsUtils.java
+++ b/gwtquery-core/src/main/java/com/google/gwt/query/client/js/JsUtils.java
@@ -18,6 +18,7 @@ package com.google.gwt.query.client.js;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.client.JsArray;
import com.google.gwt.dom.client.Element;
+import com.google.gwt.dom.client.NodeList;
import com.google.gwt.query.client.GQuery;
import com.google.gwt.user.client.DOM;
@@ -110,5 +111,20 @@ public class JsUtils {
}
return ret;
}
+
+ /**
+ * Merge the newNodes list into the oldNodes one.
+ * If oldNodes is null, a new list will be created and returned,
+ * newNodes list is never modified.
+ */
+ public static NodeList<Element> copyNodeList(NodeList<Element> oldNodes, NodeList<Element> newNodes) {
+ if (oldNodes == null) {
+ oldNodes = JsNodeArray.create();
+ }
+ for (int i = 0, l = newNodes.getLength(), j = oldNodes.getLength(); i < l; i++) {
+ oldNodes.<JsNodeArray>cast().addNode(newNodes.getItem(i), j++);
+ }
+ return oldNodes;
+ }
}
diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/effects/ClipAnimation.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/effects/ClipAnimation.java
index be06f997..3af40938 100755
--- a/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/effects/ClipAnimation.java
+++ b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/effects/ClipAnimation.java
@@ -62,7 +62,7 @@ public class ClipAnimation extends GQAnimation {
public ClipAnimation(Element elem, Action a, Corner c, Direction d,
final Function... funcs) {
if (a == Action.TOGGLE) {
- a = GQuery.$(elem).visible() ? Action.HIDE : Action.SHOW;
+ a = GQuery.$(elem).isVisible() ? Action.HIDE : Action.SHOW;
}
this.action = a;
this.corner = c;
diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/effects/PropertiesAnimation.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/effects/PropertiesAnimation.java
index 2552b03b..72559a70 100755
--- a/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/effects/PropertiesAnimation.java
+++ b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/effects/PropertiesAnimation.java
@@ -240,7 +240,7 @@ public class PropertiesAnimation extends GQAnimation {
public void onStart() {
boolean resize = false;
boolean move = false;
- boolean hidden = !g.visible();
+ boolean hidden = !g.isVisible();
Fx fx;
// g.show();
for (String key : prps.keys()) {
diff --git a/gwtquery-core/src/test/java/com/google/gwt/query/client/GQuerySelectorsTest.java b/gwtquery-core/src/test/java/com/google/gwt/query/client/GQuerySelectorsTest.java
index 306869d7..57a4f7fd 100644
--- a/gwtquery-core/src/test/java/com/google/gwt/query/client/GQuerySelectorsTest.java
+++ b/gwtquery-core/src/test/java/com/google/gwt/query/client/GQuerySelectorsTest.java
@@ -42,16 +42,18 @@ import com.google.gwt.user.client.ui.RootPanel;
public class GQuerySelectorsTest extends GWTTestCase {
protected interface AllSelectors extends Selectors {
- // @Selector("h1[id]:contains(Selectors)")
- // NodeList<Element> h1IdContainsSelectors();
- // @Selector("*:first")
- // NodeList<Element> allFirst();
- // @Selector("div[class!=madeup]")
+ @Selector("h1[id]:contains(Selectors)")
+ NodeList<Element> h1IdContainsSelectors();
+ @Selector("tr:first")
+ NodeList<Element> trFirst();
+ @Selector("tr:last")
+ NodeList<Element> trLast();
+ // @Selector("div[class!='madeup']")
// NodeList<Element> divWithClassNotContainsMadeup();
// @Selector("div, p a")
// NodeList<Element> divCommaPA();
- // @Selector("p:contains(selectors)")
- // NodeList<Element> pContainsSelectors();
+ @Selector("p:contains(selectors)")
+ NodeList<Element> pContainsSelectors();
@Selector("a[href][lang][class]")
NodeList<Element> aHrefLangClass();
@Selector("*:checked")
@@ -173,22 +175,32 @@ public class GQuerySelectorsTest extends GWTTestCase {
e.setInnerHTML("");
}
}
+
+ public void testVisibleHidden() {
+ $(e).html("<table border=1 id=idtest width=440><tr><td width=50%>A Text</td><td width=50%><a></a><p id=a></p><p id=b style='display: none'><span id=c></span></p></td></tr></table>");
+ assertEquals(9, $("* ", e).size());
+ assertEquals(1, $("*:hidden ", e).size());
+ assertEquals(8, $("*:visible ", e).size());
+ assertEquals(2, $("*:hidden , span", e).size());
+ assertEquals(8, $("*:visible , span", e).size());
+ }
public void testCompiledSelectors() {
final AllSelectors sel = GWT.create(AllSelectors.class);
$(e).html(getTestContent());
// TODO: fix these selectors
- // sel.h1IdContainsSelectors().getLength()
- // sel.allFirst().getLength()
// sel.divWithClassNotContainsMadeup().getLength()
// sel.divCommaPA().getLength()
- // sel.pContainsSelectors().getLength()
+
// assertArrayContains(sel.title().getLength(), 1);
-
assertEquals(1, sel.body().getLength());
assertArrayContains(sel.bodyDiv().getLength(), 53, 55);
sel.setRoot(e);
+ assertArrayContains(sel.trFirst().getLength(), 5);
+ assertArrayContains(sel.trLast().getLength(), 5);
+ assertArrayContains(sel.pContainsSelectors().getLength(), 54);
+ assertArrayContains(sel.h1IdContainsSelectors().getLength(), 1);
assertArrayContains(sel.aHrefLangClass().getLength(), 0, 1);
assertArrayContains(sel.allChecked().getLength(), 1);
assertArrayContains(sel.divExample().getLength(), 43);
@@ -392,7 +404,10 @@ public class GQuerySelectorsTest extends GWTTestCase {
assertArrayContains(selEng.select("body", document).getLength(), 1);
assertArrayContains(selEng.select("body div", document).getLength(), 53, 55);
-
+
+ assertArrayContains(selEng.select("tr:first", e).getLength(), 0, 1, 5);
+ assertArrayContains(selEng.select("tr:last", e).getLength(), 0, 1, 5);
+ assertArrayContains(selEng.select("p:contains(selectors)", e).getLength(), 54);
assertArrayContains(selEng.select("h1[id]:contains(Selectors)", e).getLength(), 1);
assertArrayContains(selEng.select("div[class!=madeup]", e).getLength(), 52, 53);
assertArrayContains(selEng.select("div, p a", e).getLength(), 136, 137, 138);