Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

The next step, part 2

4,627 views

Published on

YUIConf 2010 talk about how to go from a simple widget to one that can do all sorts of tricks, all without cluttering up the simple base widget.

Published in: Technology, Art & Photos
  • Be the first to comment

The next step, part 2

  1. The Next Step, Part 2
  2. Where have we been?
  3. SimpleYUI, inline JS
  4. External JS file via <script>
  5. Plugin for Node objects
  6. Simple Widget
  7. Why continue?
  8. Then where are we going?
  9. Widget provides some structure
  10. initializer : function(config) { var node = this.get("node"); if(node) { if(!this.get("content")) { this.set("content", node.getAttribute("title")); } node.removeAttribute("title"); } }, destructor : function() { this._handlers.detach(); this._handlers = null; },
  11. renderUI
  12. bindUI
  13. bindUI : function() { var node = this.get("node"); this._handlers = node.on({ mouseenter : { fn : function() { this.get('boundingBox').setStyles({ left : e.pageX + 5, top : e.pageY + 5 }); this.show(); }, context : this }, mouseleave: Y.bind(this.hide, this) }); },
  14. syncUI
  15. syncUI : function() { this.publish("sync", { defaultFn : Y.bind(function() { this.get('contentBox') .setContent(this.get('content')); }, this) }).fire(); }
  16. YUI().use("gallery-tooltip", function(Y) { var tooltip = new Y.Tooltip({ visible : false, render : true, node : Y.one("a") }); });
  17. Now what?
  18. Plugins for new behaviors
  19. new Y.Tooltip({ visible : false, render : true, node : Y.one("a"), plugins : [ Y.Plugin.TooltipSimpleDisplay ] }); //or var tooltip = New Y.Tooltip({ visible : false, render : true, node : Y.one("a") }); tooltip.plug(Y.Plugin.TooltipSimpleDisplay);
  20. Simple Plugin
  21. Y.Base.create("TooltipSimpleDisplay", Y.Plugin.Base, [], { initializer : function() { var host = this.get("host"); host.on("sync", function(e) { //prevent default sync method e.preventDefault(); var content = host.get('content') + " + plugin"; host.get("contentBox").setContent(content); }, this); } }, { NS : 'TooltipSimpleDisplay' });
  22. Powered by Custom Events That call to preventDefault is important
  23. syncUI : function() { this.publish("sync", { //Now we see why this slightly //odd syntax was important //it lets this method be //overriden by plugins defaultFn : Y.bind(function() { this.get('contentBox') .setContent(this.get('content')); }, this) }).fire(); }
  24. We can go further http://www.flickr.com/photos/st3f4n/4501172754/
  25. Transitions Module Adding some flash
  26. new Y.Tooltip({ visible : false, render : true, node : Y.one("a"), plugins : [ //from gallery Y.Plugin.TransitionOverlay ] });
  27. Still, not really all that useful http://www.flickr.com/photos/zen/1174874997/
  28. WidgetIO
  29. YQL
  30. WidgetYQL
  31. Y.Base.create("WidgetYQL", Y.Plugin.Base, [], { _yql : null, initializer : function() { this.after([ "queryChange", "formatterChange", "configChange" ], this._createYQL, this); }, _ _createYQL : function() { attrs = this.getAttrs([ "query", "formatter", "config" ]); this._yql = new Y.YQLRequest( attrs.query, Y.bind(attrs.formatter, this), attrs.config ); }, sendQuery : function() { return this._yql.send(); }
  32. tooltip.plug(Y.Plugin.WidgetYQL, { query : "SELECT * FROM ...", formatter : function(r) { host._yqlData = r.query.results.quote; host.set("content", r.query...LastTradePriceOnly); host.fire("yqlResponse", r); } });
  33. Repeating yourself sucks
  34. Plugins are full JS objects
  35. Plugins on top of plugins http://idont/have/a/source/its/just/funny
  36. initializer : function() { var host = this.get("host"); host.plug(Y.namespace("Plugin").WidgetYQL, { query : "SELECT * FROM ...", formatter : function(r) { host.set("content", r.query.res...); host.fire("yqlResponse"); } } host.on(["visibleChange", "renderedChange"], function(e) { host.YQL.sendQuery(); }, this); host.on("yqlResponse", function() { host.syncUI(); }); }
  37. Multiple plugins
  38. new Y.Tooltip({ visible : false, render : true, node : Y.one('a'), plugins : [ Y.Plugin.TransitionOverlay, Y.Plugin.TooltipYQL, Y.Plugin.TooltipDisplay ] });
  39. Done? Not so fast.
  40. Prove it works, use tests
  41. Widget & YUITest
  42. var test = new Y.Test.Case({ name : "Simple Tooltip Test", "tooltip should render without errors" : function() { var tooltip = new Y.Tooltip({ visible : false, render : true, node : Y.one('a') }); } }); //add & run test Y.Test.Runner.add(test); Y.Test.Runner.run();
  43. Didn’t do anything too dumb (yet)
  44. Not very useful though http://www.flickr.com/photos/sewitsforyou/3466154372/
  45. Event simulation adds utility
  46. new Y.Test.Case({ name : "Tooltip Event Simulation Test", "tooltip should show on mouseenter" : function() { //create tooltip var tooltip = ... //simulate mousing over the link Y.one("a").simulate("mouseover"); //fail if the tooltip isn't visible Y.assert( tooltip.get("visible"), "Tooltip wasn't visible“ ); } });
  47. Lots of JS is async though Sync tests don’t solve everything
  48. this.wait()
  49. this.resume()
  50. "tooltip should transition to visible" : function() { var tooltip = ... //resume the test once the transition has finished tooltip.transitionPlugin.on("end", function(visible) { this.resume(function() { Y.assert(visible && tooltip.get("visible"), "Tooltip wasn't visible"); }); }, this); //show the overlay, triggering the transition tooltip.show(); //wait for a bit for the transition to end this.wait(1000); }
  51. Inline JS, great for prototyping Bad for more complicated testing
  52. Scaling up the testing
  53. new Y.Test.Case({ name : "Advanced Tests", //set up a tooltip before every test, clean it up setUp : function() { ... }, tearDown : function() { ... }, //multiple tests "tooltip should render without errors" : function() { ... }, "tooltip should show on mouseenter" : function() { ... }, "tooltip should transition to visible" : function() { ... }, "YQL plugin should get data from YQL" : function() { ... } });
  54. YUI Gallery You’ve been meaning to share more anyways, right?
  55. One way to flesh out your idea Definitely not the only one
  56. Patrick Cavit @tivac on twitter “tivac” in IRC http://patcavit.com http://lanyrd.com/people/tivac/

×