From b519726e13820e3788f207b6d4c11e88c12482d5 Mon Sep 17 00:00:00 2001 From: Manolo Carrasco Date: Sat, 7 May 2011 15:07:51 +0000 Subject: [PATCH] Accept xpath selectors and pass them to the native engine, it should work in most browsers, IE is not supported --- .../com/google/gwt/query/client/GQuery.java | 32 +++++++++++-------- .../gwt/query/client/impl/SelectorEngine.java | 4 +-- .../client/impl/SelectorEngineCssToXPath.java | 9 +++++- .../gwt/query/client/GQueryCoreTest.java | 11 +++++++ 4 files changed, 40 insertions(+), 16 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 414022bc..8b5309bd 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 @@ -18,6 +18,7 @@ package com.google.gwt.query.client; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.Map; import com.google.gwt.core.client.GWT; import com.google.gwt.core.client.JavaScriptObject; @@ -40,7 +41,9 @@ 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; @@ -117,6 +120,8 @@ public class GQuery implements Lazy { protected static JsCache dataCache = null; private static SelectorEngine engine; + + private static HasSelector xpahtEngine; private static final int FUNC_PREPEND = 0, FUNC_APPEND = 1, FUNC_AFTER = 2, FUNC_BEFORE = 3; @@ -191,12 +196,6 @@ public class GQuery implements Lazy { * element containing those elements. */ public static GQuery $(String selectorOrHtml) { - if (selectorOrHtml == null || selectorOrHtml.trim().length() == 0) { - return $(); - } - if (selectorOrHtml.trim().charAt(0) == '<') { - return innerHtml(selectorOrHtml); - } return $(selectorOrHtml, document); } @@ -218,11 +217,12 @@ public class GQuery implements Lazy { * created. */ public static GQuery $(String selectorOrHtml, Node ctx) { - if (selectorOrHtml == null || selectorOrHtml.trim().length() == 0) { + String selector = null; + if (selectorOrHtml == null || (selector = selectorOrHtml.trim()).length() == 0) { return $(); } - if (selectorOrHtml.trim().charAt(0) == '<') { - return $(cleanHtmlString(selectorOrHtml, getOwnerDocument(ctx))); + if (selector.startsWith("<")) { + return innerHtml(selectorOrHtml, getOwnerDocument(ctx)); } return new GQuery().select(selectorOrHtml, ctx); } @@ -433,8 +433,8 @@ public class GQuery implements Lazy { return e.getClassName().matches("(^|.*\\s)" + clz + "(\\s.*|$)"); } - private static GQuery innerHtml(String html) { - return $(cleanHtmlString(html, document)); + private static GQuery innerHtml(String html, Document doc) { + return $(cleanHtmlString(html, doc)); } private static native String[] jsArrayToString0(JsArrayString array) /*-{ @@ -454,14 +454,20 @@ public class GQuery implements Lazy { if (engine == null) { engine = new SelectorEngine(); } - NodeList n = engine.select(selector, context); + HasSelector impl = engine; + if (selector.startsWith("./") || selector.startsWith("/")) { + if (xpahtEngine == null) { + impl = xpahtEngine = engine.impl instanceof SelectorEngineCssToXPath ? + engine.impl : new SelectorEngineCssToXPath(); + } + } + NodeList n = impl.select(selector, context); JsNodeArray res = copyNodeList(n); currentSelector = selector; currentContext = context != null ? context : document; return setArray(res); - } private static native Element window() /*-{ 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 ddf66974..4f6a7e48 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 @@ -25,7 +25,7 @@ import com.google.gwt.query.client.js.JsNodeArray; /** * Core Selector engine functions, and native JS utility functions. */ -public class SelectorEngine { +public class SelectorEngine implements HasSelector { public static native NodeList getElementsByClassName(String clazz, Node ctx) /*-{ @@ -72,7 +72,7 @@ public class SelectorEngine { return r; }-*/; - protected SelectorEngineImpl impl; + public final SelectorEngineImpl impl; protected Node root = Document.get(); 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 fc80085c..32e4965b 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 @@ -212,7 +212,14 @@ public class SelectorEngineCssToXPath extends SelectorEngineImpl { xsel = sel.startsWith("./") || sel.startsWith("/") ? sel : css2Xpath(sel); cache.put(sel, xsel); } - SelectorEngine.xpathEvaluate(xsel, ctx, elm); + try { + SelectorEngine.xpathEvaluate(xsel, ctx, elm); + } catch (Exception e) { + if (sel.startsWith("./") || sel.startsWith("/")) { + System.err.println("ERROR: xpathEvaluate: " + sel + " xpath: " + xsel + + "\nIf the syntax of your css selector is correct, report the error to gquery team.\n\n" + e.getMessage()); + } + } return JsUtils.unique(elm.> cast()).cast(); } 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 f1d7790d..4d49e44d 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 @@ -20,6 +20,7 @@ import static com.google.gwt.query.client.GQuery.$$; import static com.google.gwt.query.client.GQuery.document; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.List; @@ -35,6 +36,7 @@ import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.junit.client.GWTTestCase; import com.google.gwt.query.client.css.CSS; import com.google.gwt.query.client.css.RGBColor; +import com.google.gwt.query.client.impl.SelectorEngineCssToXPath; import com.google.gwt.query.client.impl.SelectorEngineImpl; import com.google.gwt.query.client.impl.SelectorEngineSizzle; import com.google.gwt.query.client.js.JsNamedArray; @@ -1520,5 +1522,14 @@ public class GQueryCoreTest extends GWTTestCase { label.removeFromParent(); } + + public void testXpathSelector() { + $(e).html("
A TextB
"); + SelectorEngineCssToXPath s = new SelectorEngineCssToXPath(); + for (String selector : Arrays.asList("td[width]", "table > td", "*[width!=440]")) { + String xselector = s.css2Xpath(selector); + assertEquals($(selector).toString(), $(xselector).toString()); + } + } } -- 2.39.5