• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
GQuery a jQuery clone for Gwt, RivieraDev 2011

GQuery a jQuery clone for Gwt, RivieraDev 2011



Talk given at the rivieradev conferences Oct-2011

Talk given at the rivieradev conferences Oct-2011



Total Views
Views on SlideShare
Embed Views



7 Embeds 41

http://thinkery.me 15
http://localhost 8
http://paper.li 7
https://twitter.com 5
http://a0.twimg.com 4
http://twitter.com 1
http://www.slashdocs.com 1



Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
Post Comment
Edit your comment

    GQuery a jQuery clone for Gwt, RivieraDev 2011 GQuery a jQuery clone for Gwt, RivieraDev 2011 Presentation Transcript

    • GwtQuery:A jQuery clone for GWT, and much more ... Manuel Carrasco Moñino manolo@apache.org @dodotis
    • About me● Apache James ● HUPA● GWT ● Gquery & Gquery-plugins ● GwtExporter ● GwtUpload ● Chronoscope● Jenkins ● Performance plugin ● Emma plugin● Linux ● LXP a light and visual window manager based on icewm
    • Contents● What is GWT● What is Gquery● Learning Gquery – GQuery, $(), Function – Collections & grabbing Values – Selectors – Traversing the DOM – Method Chaining – CSS – Events – Effects – Ajax – Data binding – Plugins● Js Size● jsQuery
    • What is GWTJava to Javascript Compiler, Linker, Optimizer and Obfuscator One compiled js per browser (like c++ one exec per processor) Is a full SDK. Not a Js Framework Not a Js Library Not a new language Not a Web Framework
    • Advantages of using Java.● A high level language allows that the developer doesnt get lost with low level details: DOM, Ajax, Cross-domain, Compression, Obfuscation, Dependencies, Browser differences, etc.● Huge Java ecosystem: IDE, Re-factoring, Debug, Code assist, Maven.● Metrics, TDD, CI, Reusing (libraries)● Patterns, Builders …● Type safe, syntax checking, reduce errors.● Separate code maintenance from the effectiveness of the executable.● Normally, the compiler would produce better js code than the code we could write by hand (less code, compressed, obfuscated, remove dead code, etc).
    • What does the Gwt SDK provide● Generators, Compiler, Linker, Optimizer, Obfuscater.● Client side libraries: DOM, XML, JSON, RPC, RF, I18n, MVP, Widgets● Server libraries: RPC, RF● Eclipse plugin● Multi-browser Dev mode● Unit testing and Debug tools.● Performance tools (speed tracer)● Compiler Statistics● Everything is open sourced (Apache v2.0)
    • GWT Eclipse Java Code (IDE) Plugin Java Server Java Client Side Side Toolkit (SDK) GWT development GWT Compiler Debug/Hosted/Test JRE Emulation Browser libs GWT server Widgets libs RPC/RF Test Runner FF/IE/Ch-Plugin 3ª Party 3ª PartyServer libs Client libs JavaScript. GQuery J-Byte Code Bundles (css, sprite). JSON/XML/HTML/TXT JSON/XML/HTML/TXT RPC/RF Browser Any Backend JVM App-Server (php, ruby, ...)
    • What is GQuery● A library for GWT● Provides jQuery API and syntax (small differences)● Entirely re-written in java, not a wrapper, optimized for Gwt.● Has many features not available in jQuery. – Data binding generators – Type-safe structures – Compile selectors● It is a useful complement for Gwt. – CSS selectors – Widget finders – Light weight collections – DOM and Widget enhancers.● Can be used as an alternative to traditional Gwt developing (progressive enhancement)● Performance in mind, Unit tested.● Extensible via Plugins
    • Easy to getting started● Use the gquery maven Archetype. mvn archetype:generate -DarchetypeGroupId=com.googlecode.gwtquery -DarchetypeArtifactId=gquery-archetype -DarchetypeVersion=1.1.2 -DgroupId=fr.rivieradev -DartifactId=hello -DprojectName=HelloWorld● Maven Ready (see README.txt). mvn clean package mvn gwt:run
    • IDE Friendly● Eclipse, IntelliJ, Netbeans● Run, Debug, Test● Code Assist● Re-Factoring● Software Metrics
    • The GQuery Object● Like in jQuery ... ● Selectors return an object ... ● Which represents a collection of Elements ... ● And each has plenty of useful methods. ● Most methods return the object itself so you can chain them. ● Other methods return a value of the first element GQuery g = $("img.photo"); g.attr("src", "/default.png"); String color = g.css("color"); int size = $("img.photo").css("border", "none").size();
    • The Dollar $() Method● As in Javascript, the symbol $ is legal for methods and classes.● But The Gwt Compiler disallows it for class names, So we use GQuery. // Import GQuery utility methods statically // it should be ...client.$.* but the compiler complains import static com.google.gwt.query.client.GQuery.*; // The $ method always returns a GQuery object GQuery g; // Use $ to create new DOM elements g = $("<div>hello</div>"); // Use $ to select DOM elements g = $("div:hidden"); // Use $ to wrap existing elements g = $(document); // Use $ to wrap Gwt widgets Button button = new Button(); g = $(button); // $ can handle other arguments: // Function, Event, Element[], NodeList ...
    • Functions● java hasnt got closures.● We use Function inner class to emulate javascript function● Override the appropriate f() to write your code
    • Collections and Grabbing Values GQuery Java. jQuery JavaScript.// Returns a GQuery object // Returns a jQuery objectGQuery g = $("div.section"); var g = $(div.section);// Returns a nodelist // Returns a nodelistNodeList<Element> l = $("div.section").get(); var l = $(div.section).get();// Returns the size of the collection // Returns the size of the collectionint size = $("div.section").size(); var size = $(div.section).size();// Modify all elements in the collection // Modify all elements in the collection$("div.section").addClass("highlighted"); $(div.section).addClass(highlighted);$("a.foo").html("<em>Hello</em>"); $(a.foo).html(<em>Hello</em>);// Iterate and runs a function around each // Iterate and runs a function around each// element // element$("div.section").each(new Function(){ $(div.section).each(function(){ public void f() { $(this).css(background, red); $(this).css("background", "red"); }); }});// Some methods return results from the first // Some methods return results from the first// matched element // matched elementint height = $("div#intro").height(); var height = $("div#intro").height();String src = $("img.photo").attr("src"); var src = $("img.photo").attr(src);String lastP = $("p:last").html(); var lastP = $("p:last").html();- We have to define the appropriate return type.- and to use double instead of single quotes
    • Selectors● Both GQuery and jQuery are built around selectors.● Both support CSS standard selectors plus extra selectors (:text :password :hidden etc).● jQuery uses the sizzle engine. A javascript engine which works with any browser and has optimizations per browser.● GQuery has optimized engines written in java.● The more appropriate engine is selected in compile time.● GQuery uses a modified sizzle version for IE6/7● GQuery adds compile-time optimizations when using compiled selectors.
    • Dynamic selectors$("#note"); ● Use $(string) with dynamic selectors$(".note");$("body");$("div p"); ● Add the context if the target$("div + p");$("div .example"); elements have not been attached yet$("div > div");$("div ~ p"); or to improve performance.$("h1[id]:contains(Selectors)");$("tr:first");$("tr:last"); ● It supports XML documents as well$("*:checked");$("*:visible");$("a[href][lang][class]");$("div:not(.example)");$("div[class]");$("div[class*=e]"); String className = "note";$("div[class=example]"); $("." + className);$("div[class~=dialog]");$("div[class^=exa]"); // Specify the context to improve performance$("div[class$=mple]"); Element e = DOM.getElementById("whatever");$("p:first-child"); $(".note", e);$("p:last-child");$("p:nth-child(n)"); // Use the context with unattached elements$("p:nth-child(2n)"); Widget w = new MyWidget();$("p:nth-child(2n+1)"); $(".note", w);$("p:nth-child(even)");$("p:nth-child(odd)");$("p:only-child");[...]
    • Compiled Selectors ● Use them with immutable selectors. ● And when selector performance is a goal in your application. ● Context is supportedinterface MySelectors extends Selectors { @Selector("*:checked") GQuery allChecked(); @Selector("*:checked") GQuery allChecked(Node context);}public void onModuleLoad() { MySelectors selectors = GWT.create(MySelectors.class); selectors.allChecked(); Element e = DOM.getElementById("whatever"); selectors.allChecked(e);}
    • Selectors Performance → Click to open the benchmarking application
    • Selectors Performance● GQuery in compiled mode produces the faster javascript code to select DOM elements.● GQuery dynamic selectors are, in most cases, faster or equal than any other library.
    • Traversing the Dom● Like jQuery, GQuery provides enhanced methods for traversing the DOM GQuery nextSibling = $("div.section").next(); GQuery prevSibling = $("div.section").prev(); GQuery prevAnchorSibling = $("div.section").prev("a"); GQuery firstParent = $("div.section").parent(); GQuery allParents = $("div.section").parents();● Additionally it provides useful method to locate Gwt Widgets. // We can traverse the DOM to locate widgets // Return the CellTree widget whose id is myTree CellTree tree = $("#myTree").widget(); // Now we can use the instance tree.addCloseHandler(...); // Return all gwt Labels in the dom List<Label> allLabels = $("div").widgets(Label.class);
    • Chaining Methods● Most GQuery methods return another GQuery object often representing the same collection. This means that you can chain methods together. $("div.section").show().addClass("comeBack");● Crazy chaining. $("form#login") // hide all the labels inside the form with the "optional" class .find("label.optional").hide().end() // add a red border to any password fields in the form .find("input:password").css("border", "1px solid red").end() // add a submit handler to the form .submit(new Function(){ public boolean f(Event e) { return confirm("Are you sure you want to submit?"); } });
    • CSS// jQuery like syntax: property, value$("#myId") .css("color", "red");// jQuery like syntax: javascript object$("#myId") .css($$("top: 50px, left: 25px, color: red"));// Additionally GQuery supports css style-sheet syntax (copy and paste)$("#myId") .css($$("margin: 3px; padding: 3px; font-size: small;"));// Many properties require a strict syntax:// background: color url repeat attachment position$("#myId").css("background", "transparent url(back.jpg) no-repeat scroll center");// border: width style color$("#myId").css("border", "medium dotted #cdcd");- We use the $$ method to generate javascript property structures
    • CSS Type-safe// Set the border style of a button widget to dotted valueButton myButton = new Button();$(myButton).css(CSS.BORDER_STYLE.with(BorderStyle.DOTTED));// vertical-align can take a constant value$("#myId").css(CSS.VERTICAL_ALIGN.with(VerticalAlign.MIDDLE));// or a length : here 120 px$("#myId").css(CSS.VERTICAL_ALIGN.with(Length.px(120)));// it easy now to specify shorthand property,// we do not have to remember the order!$("#myId").css(CSS.BACKGROUND.with( RGBColor.TRANSPARENT, UriValue.url("back.jpg"), BackgroundRepeat.NO_REPEAT, BackgroundAttachment.SCROLL, BackgroundPosition.CENTER));// specify margin, padding, text-decoration and font-size in one pass$("#myId").css(CSS.MARGIN.with(Length.px(3)), CSS.PADDING.with(Length.px(3), Length.px(5)), CSS.TEXT_DECORATION.with(TextDecoration.NONE), CSS.FONT_SIZE.with(FontSize.SMALL));
    • Events● GQuery provides methods for assigning event in a cross-browser way.● GQuery event system is compatible with Gwt.● issues: – When Gwt detaches a widget, events added via GQuery are lost. – If you use live for future elements, consider performance (be carefully with onmouse... events)
    • Events examples// GQuery provides methods for assigning event// handlers to elements in a cross-browser way.$("a").click(new Function() { public boolean f(Event ev) { $(this).css("backgroundColor", "orange"); // return false to stop default action and event-bubbling return false; }});// Fires the event click on all labels$(".gwt-Label").click();// Remove event handlers$("a").unbind("click");// Attach a handler to all elements matching the// selector, now and in the future$("a") .live("over", new Function(){ public void f() { $(this).css("color", "red"); } }) // Type-safe .live(Event.ONMOUSEOUT, new Function(){ public void f() { $(this).css("color", null); } });
    • Effects● GQuery provides several techniques for adding animations to a web page.● These include simple, standard animations that are frequently used: ● fadeIn, fadeOut, slideDown, slideUp … $(".foo").fadeIn(2000);● and the ability to craft sophisticated custom effects via the animate method using jquery animation syntax ● queue, delay, stop, css, attr, colors ... $(".foo") .stop() .animate("left:+=1000", 2000, Easing.SWING) .delay(500) .animate("left:-=1000", 2000); → Go to zoom example
    • Ajax● Gwt includes its own facilities for performing communications with the server: ● RPC, Request Factory (Only Java) ● Request Builder● But GQuery complements it adding: ● jQuery syntax. ● Builders to handle JSON and XML.
    • Ajax methods GQuery Java. jQuery JavaScript.// Load a remote html fragment in a set of // Load a remote html fragment in a set of// dom elements // dom elements$("#c").load("file.html #mid"); $(#c).load(file.html #mid); // Unsupported in GQuery// More advanced methods $.getScript(url, callback);GQuery.get("file.html", null, new Function(){ public void f() { // More advanced methods alert("success " + getData()[0]); $.get(file.php, null, function(data){ } alert("success " + data);}); });GQuery.post("file.html",$$("name:John,time:2pm"), $.post(file.php, {name: John, time: 2pm}, new Function(){ public void f() { function(data){ alert("success " + getData()[0]); alert("success" + data);}}); });GQuery.getJSON("file.html",$$("name:John,time:2pm"), $.getJSON(file.php, {name: John, time: 2pm}, new Function(){ public void f() { function(data){ alert("success " + getData()[0]); alert("success" + data);}}); }); - Gwt compiler disallows a class named $, so we use GQuery
    • Data binding● Although Gquery – provides the class Properties to handle Json objects... Properties p = $$("key1: value1, key2: [1,2]"); String v1 = p.getStr("key1"); – and it is able to inspect Xml objects using css selector engine... Element e = JsUtils.parseXML("<root><message>hello</message></root>"); String txt = $("root message", e).text(); GQuery provides generators to produce builders and handle Xml and Json as java objects.● Data binding objects support getters, setters and attribute renaming via annotations● The usage of data binding makes the code more readable, type- safe, checks null conditions, castings, etc.
    • Data binding example // GQuery generator will create the implementation interface Site extends JsonBuilder { long getId(); String getUrl(); String[] getTags(); // change the name to fix the misspelling @Name("referer") Site getReferrer(); String getTitle(); [{ "id": 1234, "referer": {"id": 2, "url": "http://google.com"}, //NOTE: Setters not displayed to simplify "url": "http://mochikit.com/interpreter/index.html", } "title": "Interpreter", "tags": [GQuery.getJSON("test.json", null, new Function() { "mochikit","webdev","tool","tools", public void f() { "javascript","interactive","interpreter","repl" // Create the Site instance ] Site s = GWT.create(Site.class); }] // Load the data got from the server s.load(getData()[0]); // We can use standard getters and setters, // making the code more readable and type-safe alert("OK " + s.getUrl() + " " + s.getTags()[0] + " " + s.getReferrer().getUrl()); }}); // Alternative: handle data using GQuery Properties class Properties p = (Properties)getData()[0]; alert ("OK " + p.getStr("url") + " " + p.getArray("tags").getString(0) + " " + ((Properties)p.getJavaScriptObject("referer")).getStr("url"));
    • Plugins● GQuery is extensible through plugins, adding new features for different purposes.● Because of java constrains, we can not add new methods to the GQuery class so we have to use the method as to use plugin methods.● Core already includes: Events, Effects, Widgets and Ajax plugins● GQuery has its own site to host plugins. Contributions welcomed! → Go to the plugins site
    • Plugins: Create and UsageUsage a Plugin. // jQuery syntax$("h1").as(MyPlugin).newMethod(); $("h1").newMethod();Develop a Plugin.public static class MyPlugin extends GQuery { // Register the plugin in the GQuery plugin system public static final Class<MyPlugin> MyPlugin = Gquery.registerPlugin(MyPlugin.class, new Plugin<MyPlugin>() { public MyPlugin init(GQuery gq) { return new MyPlugin(gq); } }); // Initialization protected MyPlugin(GQuery gq) { super(gq); } // Add a new methods to GQuery objects public GQuery newMethod() { // Write your code here return this; }}
    • Progressive Enhancement● Enhance pure Html pages: Crawlers friendly. $("a").click(new Function() { public void f() { GWT.log("Clicked: " + $(this).text() + " " + $(this).attr("href")); } });● Enhance Gwt Widgets: Without manipulating the class. $(".gwt-Button").prepend("<img src=help.png>");● Enhance Gwt Views: MVP pattern compatible. $("textarea").as(Enhance).richText();
    • JavaScript size● Gquery takes advantage of the gwt compiler which produces optimized and striped code.● Gquery core tends to use light-weight stuff to reduce the javascript size and improve the performance.● A small GQuery application normally is smaller than the jQuery minimized library.● The js size which GQuery adds to a Gwt application is 3 or more times smaller than the jquery library.
    • Comparing sizes● The ImageZoom Example needs a 17% less of javascript code (FF).● When using deflate-gzip in webserver, gwt js code is pre-ordered so the compression factor is better.
    • jsQuery● The latest work in GQuery is to produce a clone of jquery which could be used as a replacement of jQuery. We call this library jsQuery.● The goal is not to compete against jquery, but ● To avoid including jquery in Gwt applications which need some native jQuery methods like jquery plugins. ● As an investigative work which demonstrates that any js API can be developed in Gwt (jQuery is the js API most widely used).● We use the gwt-exporter library which is able to expose Gwt classes and methods to javascript.● Right now most GQuery object methods are exposed but we have to implement and export many static methods which are in jQuery like extend, each, map …● The main goal is to encourage people to wrap jQuery plugins, just including them as jsni and creating java wrappers methods around it.
    • jsQuery issues● Gwt-exporter introduces a high amount of extra code to deal with types and wrappers. If we consider compression, jsQuery is only 8KB greater● Gwt-exporter spends time figuring out which methods to call and how to wrap parameters and return objects.● Apart of the code in GQuery, we will need extra code to emulate all jQuery API.
    • jsQuery example<!-- <script src="http://code.jquery.com/jquery-latest.min.js" /> --><script src="http://code.google.com/p/gwtquery/source/browse/api/jsquery.nocache.js" /><script type="text/javascript"> $(document).ready(function(){ $("ul.thumb li").hover(function() { $(this).css({z-index : 10}); $(this).find(img).addClass("hover").stop() .animate({ marginTop: -110px, marginLeft: -110px, top: 50%, left: 50%, width: 174px, height: 174px, padding: 20px }, 200); } , function() { $(this).css({z-index : 0}); $(this).find(img).removeClass("hover").stop() .animate({ marginTop: 0, marginLeft: 0, top: 0, left: 0, width: 100px, height: 100px, padding: 5px }, 400); }); });</script>
    • Links GwtQuery http://code.google.com/p/gwtquery/ http://gwtquery.googlecode.com/svn/trunk/gwtquery-core/javadoc/com/google/gwt/query/client/GQuery.html http://code.google.com/p/gwtquery/w/list http://code.google.com/p/gwtquery-plugins/Plugins http://gwtquery-plugins.googlecode.com/svn/trunk/ratings/demos/Ratings/RatingsSample.html http://gwtquery-plugins.googlecode.com/svn/trunk/enhance/demos/Enhance/EnhanceSample.html http://gwtquery-plugins.googlecode.com/svn/trunk/droppable/demo/GFinderSample/GFinderSample.html http://gwtquery-plugins.googlecode.com/svn/trunk/droppable/demo/GwtPortletSample/GwtPortletSample.html http://gwtquery-ui.googlecode.com/svn/demos/GwtQueryUi.html Application http://talkwheel.com
    • Conclusions● People knowing jquery can easily use GQuery because share the API.● GQuery uses java : – Type safe, discover errors early (compile time instead of runtime) – Advanced IDE (code completion, refactoring) – Most people knows java but only a few js.● GQuery uses gwt: – Do not worry about compression, obfuscation … – TDD, Debug – Many libraries available● GQuery complements the Gwt world making easier code: write less, do more.● GQuery helps to develop applications using the jquery paradigm based on Enhancement, instead of the Gwt one based on Widgets.● GQuery is mature, just released version 1.1.0, and well documented.● The GQuery plugin system is simple.● Contributors are Welcome !!!
    • Announcement GQuery 1.1.0 released today !We wanted to match the new release announcement with the RivieraDev event.