\r
import static com.google.gwt.query.client.plugins.Effects.Effects;\r
import static com.google.gwt.query.client.plugins.Events.Events;\r
+import static com.google.gwt.query.client.plugins.Widgets.Widgets;\r
\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
import java.util.HashMap;\r
+import java.util.List;\r
\r
import com.google.gwt.core.client.GWT;\r
import com.google.gwt.core.client.JavaScriptObject;\r
import com.google.gwt.dom.client.NodeList;\r
import com.google.gwt.dom.client.OptionElement;\r
import com.google.gwt.dom.client.SelectElement;\r
-import com.google.gwt.dom.client.TextAreaElement;\r
import com.google.gwt.dom.client.Style.Display;\r
+import com.google.gwt.dom.client.TextAreaElement;\r
import com.google.gwt.query.client.css.CssProperty;\r
import com.google.gwt.query.client.css.Length;\r
import com.google.gwt.query.client.css.Percentage;\r
import com.google.gwt.query.client.css.TakesPercentage;\r
import com.google.gwt.query.client.impl.DocumentStyleImpl;\r
import com.google.gwt.query.client.plugins.EventsListener;\r
+import com.google.gwt.user.client.DOM;\r
import com.google.gwt.user.client.Event;\r
+import com.google.gwt.user.client.EventListener;\r
import com.google.gwt.user.client.Window;\r
-import com.google.gwt.user.client.ui.Button;\r
-import com.google.gwt.user.client.ui.HTML;\r
-import com.google.gwt.user.client.ui.TextBox;\r
import com.google.gwt.user.client.ui.Widget;\r
\r
/**\r
}\r
\r
/**\r
- * Wrap a GQuery around an existing element.\r
+ * Wrap a GQuery around a collection of existing widget.\r
*/\r
- public static GQuery $(Element element) {\r
- return new GQuery(JSArray.create(element));\r
+ public static GQuery $(Collection<Widget> widgetList){\r
+ JSArray elements = JSArray.create();\r
+ for (Widget w : widgetList){\r
+ elements.addNode(w.getElement());\r
+ }\r
+ return $(elements);\r
}\r
\r
/**\r
- * Wrap a GQuery around an existing widget.\r
+ * Wrap a GQuery around an existing element.\r
*/\r
- public static GQuery $(Widget widget) {\r
- GQuery q = new GQuery(JSArray.create(widget.getElement()));\r
- q.data("widget", widget);\r
- return q;\r
+ public static GQuery $(Element element) {\r
+ return new GQuery(JSArray.create(element));\r
}\r
\r
/**\r
* reference to a plugin to be used.\r
*/\r
public static <T extends GQuery> T $(String selector, Class<T> plugin) {\r
- return $(selector, null, plugin);\r
+ return $(selector, (Node) null, plugin);\r
}\r
\r
/**\r
}\r
}\r
\r
+ /**\r
+ * This function accepts a string containing a CSS selector which is then used\r
+ * to match a set of elements, or it accepts raw HTML creating a GQuery\r
+ * element containing those elements.\r
+ * The second parameter is the context to use for the selector, or\r
+ * the document where the new elements will be created.\r
+ */\r
+ public static GQuery $(String selectorOrHtml, Widget context) {\r
+ return $(selectorOrHtml, context.getElement());\r
+ }\r
+\r
+ /**\r
+ * This function accepts a string containing a CSS selector which is then used\r
+ * to match a set of elements, or it accepts raw HTML creating a GQuery\r
+ * element containing those elements. The second parameter is the context to\r
+ * use for the selector. The third parameter is the class plugin to use.\r
+ */\r
+ public static <T extends GQuery> T $(String selector, Widget context,\r
+ Class<T> plugin) {\r
+ return $(selector, context.getElement(), plugin);\r
+ }\r
+\r
public static <T extends GQuery> T $(T gq) {\r
return gq;\r
}\r
\r
+ /**\r
+ * Wrap a GQuery around an existing widget.\r
+ */\r
+ public static GQuery $(Widget w){\r
+ return $(w.getElement());\r
+ }\r
+\r
+ /**\r
+ * Wrap a GQuery around a array of existing widget.\r
+ */\r
+ public static GQuery $(Widget... widgetArray){\r
+ JSArray elements = JSArray.create();\r
+ for (Widget w : widgetArray){\r
+ elements.addNode(w.getElement());\r
+ }\r
+ return $(elements);\r
+ }\r
+\r
/**\r
* Wrap a JSON object.\r
*/\r
}\r
}\r
\r
+ /**\r
+ * We will use the fact as GWT use the widget itself as EventListener !\r
+ * If no Widget associated with the element, this method returns null.\r
+ * @param e\r
+ * @return\r
+ */\r
+ protected static Widget getAssociatedWidget(Element e){\r
+ EventListener listener = DOM.getEventListener((com.google.gwt.user.client.Element) e);\r
+ \r
+ //No listener attached to the element, so no widget exist for this element\r
+ if (listener == null){\r
+ return null;\r
+ }\r
+ if (listener instanceof Widget){\r
+ //GWT uses the widget as event listener\r
+ return (Widget) listener;\r
+ }else if (listener instanceof EventsListener){\r
+ EventsListener gQueryListener = (EventsListener)listener;\r
+ if (gQueryListener.getOriginalEventListener() != null && gQueryListener.getOriginalEventListener() instanceof Widget){\r
+ return (Widget) gQueryListener.getOriginalEventListener();\r
+ }\r
+ }\r
+ // I think it's not a good idea to generate ourself a new widget wrapping the element...\r
+ // To be discussed\r
+ return null;\r
+ }\r
+\r
private static JSArray copyNodeList(NodeList<? extends Node> n) {\r
JSArray res = JSArray.create();\r
for (int i = 0; i < n.getLength(); i++) {\r
return res;\r
}\r
\r
+ private static native void emptyDocument(Document d) /*-{\r
+ d.open(); d.write("<head/><body/>"); d.close();\r
+ }-*/;\r
+\r
private native static Document getContentDocument(Node n) /*-{\r
var d = n.contentDocument || n.contentWindow.document;\r
if (!d.body) @com.google.gwt.query.client.GQuery::emptyDocument(Lcom/google/gwt/dom/client/Document;)(d);\r
return nl;\r
}-*/;\r
\r
- private static native void emptyDocument(Document d) /*-{\r
- d.open(); d.write("<head/><body/>"); d.close();\r
- }-*/;\r
-\r
private static NodeList<Element> select(String selector, Node context) {\r
if (engine == null) {\r
engine = new SelectorEngine();\r
public GQuery append(GQuery query) {\r
return domManip(query, FUNC_APPEND);\r
}\r
-\r
+ \r
/**\r
* Append content to the inside of every matched element. This operation is\r
* similar to doing an appendChild to all the specified elements, adding them\r
if (plugin == GQUERY) {\r
return (T) $(this);\r
} else if (plugins != null) {\r
- Plugin p = plugins.get(plugin);\r
+ Plugin<?> p = plugins.get(plugin);\r
if (p != null) {\r
return (T) p.init(this);\r
}\r
}\r
throw new RuntimeException("No plugin registered for class " + plugin.getName());\r
}\r
- \r
+\r
/**\r
* Return a GWT Widget containing the first matched element.\r
* \r
* \r
*/\r
public Widget asWidget() {\r
- // TODO: complete it and move to the Widget plugin\r
- if (data("widget") == null) {\r
- Element e = elements.getItem(0);\r
- Widget w = null;\r
- if ("div".equalsIgnoreCase(e.getTagName()) || "span".equalsIgnoreCase(e.getTagName())) {\r
- w = HTML.wrap(e); \r
- } else if ("button".equalsIgnoreCase(e.getTagName())) {\r
- w = Button.wrap(e);\r
- } else if ("text".equalsIgnoreCase(e.getTagName())) {\r
- w = TextBox.wrap(e);\r
- } else {\r
- w = new HTML($(e).toString());\r
- }\r
- data(e, "widget", w);\r
- }\r
- return (Widget) data("widget");\r
+ return as(Widgets).widget();\r
}\r
\r
/**\r
public GQuery attr(String key, Function closure) {\r
for (int i = 0; i < elements.getLength(); i++) {\r
Element e = elements.getItem(i);\r
- e.setAttribute(styleImpl.fixPropertyName(key), closure.f(e, i));\r
+ e.setAttribute(styleImpl.fixPropertyName(key), String.valueOf(closure.f(e, i)));\r
}\r
return this;\r
}\r
}\r
return pushStack(unique(result), "nextAll", getSelector());\r
}\r
-\r
+ \r
/**\r
* Removes the specified Element from the set of matched elements. This method\r
* is used to remove a single Element from a jQuery object.\r
}\r
return $(array);\r
}\r
-\r
+ \r
/**\r
* Removes any elements inside the passed set of elements from the set of\r
* matched elements.\r
ret = ret.not(e);\r
}\r
return ret;\r
- }\r
-\r
+ } \r
+ \r
/**\r
* Removes elements matching the specified expression from the set of matched\r
* elements.\r
}\r
return ret;\r
}\r
-\r
+ \r
/**\r
* Get the current offset of the first matched element, in pixels, relative to\r
* the document. The returned object contains two integer properties, top and\r
*/\r
public com.google.gwt.query.client.GQuery.Offset offset() {\r
return new Offset(get(0).getAbsoluteLeft(), get(0).getAbsoluteTop());\r
- }\r
+ } \r
\r
/**\r
* Returns a GQuery collection with the positioned parent of the first matched\r
public GQuery one(int eventbits, final Object data, final Function f) {\r
return as(Events).one(eventbits, data, f);\r
}\r
- \r
+\r
/**\r
* Get the current computed height for the first element in the set of matched elements, \r
* including padding, border, but not the margin.\r
public int outerHeight(){\r
return outerHeight(false);\r
}\r
- \r
+\r
/**\r
* Get the current computed height for the first element in the set of matched elements, \r
* including padding, border, and optionally margin.\r
outerHeight+=GQUtils.cur( get(0), "marginTop", true)+GQUtils.cur( get(0), "marginBottom", true);\r
}\r
return outerHeight;\r
- } \r
- \r
+ }\r
+\r
/**\r
* Get the current computed width for the first element in the set of matched elements, \r
* including padding, border, but not the margin.\r
public int outerWidth(){\r
return outerWidth(false);\r
}\r
- \r
+\r
/**\r
* Get the current computed width for the first element in the set of matched elements, \r
* including padding and border and optionally margin.\r
outerWidth+=GQUtils.cur( get(0), "marginRight", true)+GQUtils.cur( get(0), "marginLeft", true);\r
}\r
return outerWidth;\r
- } \r
+ }\r
\r
/**\r
* Get a set of elements containing the unique parents of the matched set of\r
return styleImpl.isVisible(get(0));\r
}\r
\r
+ /**\r
+ * Return the first non null attached widget from the matched elements\r
+ * or null if there isn't any.\r
+ */\r
+ public Widget widget(){\r
+ for (Element e : elements()){\r
+ Widget w = getAssociatedWidget(e);\r
+ if (w != null){\r
+ return w;\r
+ }\r
+ }\r
+ return null;\r
+ }\r
+\r
+ /**\r
+ * return the list of attached widgets matching the query\r
+ */\r
+ public List<Widget> widgets(){\r
+ List<Widget> widgets = new ArrayList<Widget>();\r
+ for (Element e : elements()){\r
+ Widget w = getAssociatedWidget(e);\r
+ if (w != null){\r
+ widgets.add(w);\r
+ }\r
+ }\r
+ return widgets;\r
+ }\r
+\r
/**\r
* Get the current computed, pixel, width of the first matched element.\r
*/\r
public GQuery wrapAll(String html) {\r
return wrapAll($(html));\r
}\r
-\r
+ \r
/**\r
* Wrap the inner child contents of each matched element (including text\r
* nodes) with an HTML structure. This wrapping process is most useful for\r
return g;\r
}\r
\r
+ \r
private void allNextSiblingElements(Element firstChildElement, JSArray result,\r
Element elem) {\r
while (firstChildElement != null) {\r
firstChildElement = firstChildElement.getNextSiblingElement();\r
}\r
}\r
-\r
+ \r
private void allPreviousSiblingElements(Element firstChildElement,\r
JSArray result) {\r
while (firstChildElement != null) {\r
firstChildElement = getPreviousSiblingElement(firstChildElement);\r
}\r
}\r
-\r
+ \r
/**\r
* Bind Handlers or fire Events for each matched element.\r
*/\r
return bind(eventbits, data, funcs);\r
}\r
}\r
-\r
+ \r
private GQuery domManip(GQuery g, int func, Element...elms) {\r
JSArray newNodes = JSArray.create();\r
if (elms.length == 0) {\r
}\r
return this;\r
}\r
-\r
+ \r
+ \r
private native Element getPreviousSiblingElement(Element elem) /*-{\r
var sib = elem.previousSibling;\r
while (sib && sib.nodeType != 1)\r
sib = sib.previousSibling;\r
return sib;\r
}-*/;\r
-\r
+ \r
private JSArray merge(NodeList<Element> first, NodeList<Element> second) {\r
JSArray res = copyNodeList(first);\r
for (int i = 0; i < second.getLength(); i++) {\r
}\r
return res;\r
}\r
-\r
+ \r
+ \r
+ \r
+ \r
+ \r
private void removeData(Element item, String name) {\r
if (dataCache == null) {\r
windowData = JavaScriptObject.createObject().cast();\r
--- /dev/null
+/*
+ * Copyright 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.query.client;
+
+import static com.google.gwt.query.client.GQuery.$;
+import static com.google.gwt.query.client.GQuery.document;
+
+import com.google.gwt.dom.client.Element;
+import com.google.gwt.event.dom.client.ClickEvent;
+import com.google.gwt.event.dom.client.ClickHandler;
+import com.google.gwt.junit.client.GWTTestCase;
+import com.google.gwt.query.client.plugins.Widgets;
+import com.google.gwt.user.client.ui.Button;
+import com.google.gwt.user.client.ui.FlowPanel;
+import com.google.gwt.user.client.ui.HTML;
+import com.google.gwt.user.client.ui.Label;
+import com.google.gwt.user.client.ui.RootPanel;
+import com.google.gwt.user.client.ui.Widget;
+
+/**
+ * Test class for testing gwtquery widgets plugin api.
+ */
+public class GQueryWidgetsTest extends GWTTestCase {
+
+ static Element e = null;
+
+ static HTML testPanel = null;
+
+ int testSubmitEventCont = 0;
+
+ public String getModuleName() {
+ return "com.google.gwt.query.Query";
+ }
+
+ public void testGWTQueryCoreWidgets() {
+ final FlowPanel p = new FlowPanel();
+ Button b = new Button("test");
+ RootPanel.get().add(b);
+ RootPanel.get().add(p);
+
+ int nitems = 4;
+ final String label1 = "I'm the label ";
+ final String label2 = "Finally I'm just a simple label";
+
+ for (int i = 0; i < nitems; i++) {
+ Label l = new Label(label1 + i);
+ p.add(l);
+ }
+ $("<div>whatever</div").appendTo($(p));
+
+ b.addClickHandler(new ClickHandler() {
+ public void onClick(ClickEvent event) {
+ $(".gwt-Label", p).each(new Function() {
+ @Override
+ public void f(Widget w) {
+ Label l = (Label) w;
+ l.setText(label2);
+ }
+ });
+ }
+ });
+
+ $(".gwt-Label", p).each(new Function() {
+ @Override
+ public Object f(Widget w, int i) {
+ assertEquals(label1 + i, ((Label)w).getText());
+ return null;
+ }
+ });
+
+ $(b).click();
+
+ $(".gwt-Label", p).each(new Function() {
+ public void f(Element e) {
+ assertEquals(label2, $(e).text());
+ }
+ });
+
+ $("div", p).each(new Function() {
+ public void f(Element e) {
+ // Just to avoid the exception when non-widget elements match
+ }
+ public void f(Widget w) {
+ if (w instanceof Label) {
+ assertEquals(label2, $(e).text());
+ }
+ }
+ });
+
+ p.removeFromParent();
+ b.removeFromParent();
+ }
+
+ public void testGQueryWidgets() {
+ final Button b1 = new Button("click-me");
+ RootPanel.get().add(b1);
+ GQuery g = $(b1);
+ Button b2 = (Button) g.as(Widgets.Widgets).widget();
+ assertEquals(b1, b2);
+
+
+ b2 = (Button)$("<button>Click-me</button>").appendTo(document).asWidget();
+ b2.addClickHandler(new ClickHandler() {
+ public void onClick(ClickEvent event) {
+ $(b1).css("color", "red");
+ }
+ });
+
+ b2.click();
+ assertEquals("red", $(b1).css("color"));
+ }
+
+}