the next step, part 2
DESCRIPTION
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.TRANSCRIPT
![Page 1: The next step, part 2](https://reader037.vdocument.in/reader037/viewer/2022102716/54bd87754a7959d4438b45a3/html5/thumbnails/1.jpg)
The Next Step, Part 2
![Page 2: The next step, part 2](https://reader037.vdocument.in/reader037/viewer/2022102716/54bd87754a7959d4438b45a3/html5/thumbnails/2.jpg)
Where have we been?
![Page 3: The next step, part 2](https://reader037.vdocument.in/reader037/viewer/2022102716/54bd87754a7959d4438b45a3/html5/thumbnails/3.jpg)
SimpleYUI, inline JS
![Page 4: The next step, part 2](https://reader037.vdocument.in/reader037/viewer/2022102716/54bd87754a7959d4438b45a3/html5/thumbnails/4.jpg)
External JS file via <script>
![Page 5: The next step, part 2](https://reader037.vdocument.in/reader037/viewer/2022102716/54bd87754a7959d4438b45a3/html5/thumbnails/5.jpg)
Plugin for Node objects
![Page 6: The next step, part 2](https://reader037.vdocument.in/reader037/viewer/2022102716/54bd87754a7959d4438b45a3/html5/thumbnails/6.jpg)
Simple Widget
![Page 7: The next step, part 2](https://reader037.vdocument.in/reader037/viewer/2022102716/54bd87754a7959d4438b45a3/html5/thumbnails/7.jpg)
Why continue?
![Page 8: The next step, part 2](https://reader037.vdocument.in/reader037/viewer/2022102716/54bd87754a7959d4438b45a3/html5/thumbnails/8.jpg)
Then where are we going?
![Page 9: The next step, part 2](https://reader037.vdocument.in/reader037/viewer/2022102716/54bd87754a7959d4438b45a3/html5/thumbnails/9.jpg)
Widget provides some structure
![Page 10: The next step, part 2](https://reader037.vdocument.in/reader037/viewer/2022102716/54bd87754a7959d4438b45a3/html5/thumbnails/10.jpg)
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;},
![Page 11: The next step, part 2](https://reader037.vdocument.in/reader037/viewer/2022102716/54bd87754a7959d4438b45a3/html5/thumbnails/11.jpg)
renderUI
![Page 12: The next step, part 2](https://reader037.vdocument.in/reader037/viewer/2022102716/54bd87754a7959d4438b45a3/html5/thumbnails/12.jpg)
bindUI
![Page 13: The next step, part 2](https://reader037.vdocument.in/reader037/viewer/2022102716/54bd87754a7959d4438b45a3/html5/thumbnails/13.jpg)
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) });},
![Page 14: The next step, part 2](https://reader037.vdocument.in/reader037/viewer/2022102716/54bd87754a7959d4438b45a3/html5/thumbnails/14.jpg)
syncUI
![Page 15: The next step, part 2](https://reader037.vdocument.in/reader037/viewer/2022102716/54bd87754a7959d4438b45a3/html5/thumbnails/15.jpg)
syncUI : function() { this.publish("sync", { defaultFn : Y.bind(function() { this.get('contentBox') .setContent(this.get('content'));
}, this) }).fire();}
![Page 16: The next step, part 2](https://reader037.vdocument.in/reader037/viewer/2022102716/54bd87754a7959d4438b45a3/html5/thumbnails/16.jpg)
YUI().use("gallery-tooltip", function(Y) { var tooltip = new Y.Tooltip({ visible : false, render : true, node : Y.one("a") });});
![Page 17: The next step, part 2](https://reader037.vdocument.in/reader037/viewer/2022102716/54bd87754a7959d4438b45a3/html5/thumbnails/17.jpg)
Now what?
![Page 18: The next step, part 2](https://reader037.vdocument.in/reader037/viewer/2022102716/54bd87754a7959d4438b45a3/html5/thumbnails/18.jpg)
Plugins for new behaviors
![Page 19: The next step, part 2](https://reader037.vdocument.in/reader037/viewer/2022102716/54bd87754a7959d4438b45a3/html5/thumbnails/19.jpg)
new Y.Tooltip({ visible : false, render : true, node : Y.one("a"), plugins : [ Y.Plugin.TooltipSimpleDisplay ]});
//orvar tooltip = New Y.Tooltip({ visible : false, render : true, node : Y.one("a")});tooltip.plug(Y.Plugin.TooltipSimpleDisplay);
![Page 20: The next step, part 2](https://reader037.vdocument.in/reader037/viewer/2022102716/54bd87754a7959d4438b45a3/html5/thumbnails/20.jpg)
Simple Plugin
![Page 21: The next step, part 2](https://reader037.vdocument.in/reader037/viewer/2022102716/54bd87754a7959d4438b45a3/html5/thumbnails/21.jpg)
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' });
![Page 22: The next step, part 2](https://reader037.vdocument.in/reader037/viewer/2022102716/54bd87754a7959d4438b45a3/html5/thumbnails/22.jpg)
Powered by Custom Events
That call to preventDefault is important
![Page 23: The next step, part 2](https://reader037.vdocument.in/reader037/viewer/2022102716/54bd87754a7959d4438b45a3/html5/thumbnails/23.jpg)
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();}
![Page 24: The next step, part 2](https://reader037.vdocument.in/reader037/viewer/2022102716/54bd87754a7959d4438b45a3/html5/thumbnails/24.jpg)
We can go further
http://www.flickr.com/photos/st3f4n/4501172754/
![Page 25: The next step, part 2](https://reader037.vdocument.in/reader037/viewer/2022102716/54bd87754a7959d4438b45a3/html5/thumbnails/25.jpg)
Transitions Module
Adding some flash
![Page 26: The next step, part 2](https://reader037.vdocument.in/reader037/viewer/2022102716/54bd87754a7959d4438b45a3/html5/thumbnails/26.jpg)
new Y.Tooltip({ visible : false, render : true, node : Y.one("a"), plugins : [ //from gallery Y.Plugin.TransitionOverlay ]});
![Page 27: The next step, part 2](https://reader037.vdocument.in/reader037/viewer/2022102716/54bd87754a7959d4438b45a3/html5/thumbnails/27.jpg)
Still, not really all that useful
http://www.flickr.com/photos/zen/1174874997/
![Page 28: The next step, part 2](https://reader037.vdocument.in/reader037/viewer/2022102716/54bd87754a7959d4438b45a3/html5/thumbnails/28.jpg)
WidgetIO
![Page 29: The next step, part 2](https://reader037.vdocument.in/reader037/viewer/2022102716/54bd87754a7959d4438b45a3/html5/thumbnails/29.jpg)
YQL
![Page 30: The next step, part 2](https://reader037.vdocument.in/reader037/viewer/2022102716/54bd87754a7959d4438b45a3/html5/thumbnails/30.jpg)
WidgetYQL
![Page 31: The next step, part 2](https://reader037.vdocument.in/reader037/viewer/2022102716/54bd87754a7959d4438b45a3/html5/thumbnails/31.jpg)
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(); }
![Page 32: The next step, part 2](https://reader037.vdocument.in/reader037/viewer/2022102716/54bd87754a7959d4438b45a3/html5/thumbnails/32.jpg)
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); }});
![Page 33: The next step, part 2](https://reader037.vdocument.in/reader037/viewer/2022102716/54bd87754a7959d4438b45a3/html5/thumbnails/33.jpg)
Repeating yourself sucks
![Page 34: The next step, part 2](https://reader037.vdocument.in/reader037/viewer/2022102716/54bd87754a7959d4438b45a3/html5/thumbnails/34.jpg)
Plugins are full JS objects
![Page 35: The next step, part 2](https://reader037.vdocument.in/reader037/viewer/2022102716/54bd87754a7959d4438b45a3/html5/thumbnails/35.jpg)
Plugins on top of plugins
http://idont/have/a/source/its/just/funny
![Page 36: The next step, part 2](https://reader037.vdocument.in/reader037/viewer/2022102716/54bd87754a7959d4438b45a3/html5/thumbnails/36.jpg)
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(); });}
![Page 37: The next step, part 2](https://reader037.vdocument.in/reader037/viewer/2022102716/54bd87754a7959d4438b45a3/html5/thumbnails/37.jpg)
Multiple plugins
![Page 38: The next step, part 2](https://reader037.vdocument.in/reader037/viewer/2022102716/54bd87754a7959d4438b45a3/html5/thumbnails/38.jpg)
new Y.Tooltip({ visible : false, render : true, node : Y.one('a'), plugins : [ Y.Plugin.TransitionOverlay,
Y.Plugin.TooltipYQL, Y.Plugin.TooltipDisplay ]});
![Page 39: The next step, part 2](https://reader037.vdocument.in/reader037/viewer/2022102716/54bd87754a7959d4438b45a3/html5/thumbnails/39.jpg)
Done? Not so fast.
![Page 40: The next step, part 2](https://reader037.vdocument.in/reader037/viewer/2022102716/54bd87754a7959d4438b45a3/html5/thumbnails/40.jpg)
Prove it works, use tests
![Page 41: The next step, part 2](https://reader037.vdocument.in/reader037/viewer/2022102716/54bd87754a7959d4438b45a3/html5/thumbnails/41.jpg)
Widget & YUITest
![Page 42: The next step, part 2](https://reader037.vdocument.in/reader037/viewer/2022102716/54bd87754a7959d4438b45a3/html5/thumbnails/42.jpg)
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 testY.Test.Runner.add(test);Y.Test.Runner.run();
![Page 43: The next step, part 2](https://reader037.vdocument.in/reader037/viewer/2022102716/54bd87754a7959d4438b45a3/html5/thumbnails/43.jpg)
Didn’t do anything too dumb
(yet)
![Page 44: The next step, part 2](https://reader037.vdocument.in/reader037/viewer/2022102716/54bd87754a7959d4438b45a3/html5/thumbnails/44.jpg)
Not very useful though
http://www.flickr.com/photos/sewitsforyou/3466154372/
![Page 45: The next step, part 2](https://reader037.vdocument.in/reader037/viewer/2022102716/54bd87754a7959d4438b45a3/html5/thumbnails/45.jpg)
Event simulation adds utility
![Page 46: The next step, part 2](https://reader037.vdocument.in/reader037/viewer/2022102716/54bd87754a7959d4438b45a3/html5/thumbnails/46.jpg)
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“ ); }});
![Page 47: The next step, part 2](https://reader037.vdocument.in/reader037/viewer/2022102716/54bd87754a7959d4438b45a3/html5/thumbnails/47.jpg)
Lots of JS is async though
Sync tests don’t solve everything
![Page 48: The next step, part 2](https://reader037.vdocument.in/reader037/viewer/2022102716/54bd87754a7959d4438b45a3/html5/thumbnails/48.jpg)
this.wait()
![Page 49: The next step, part 2](https://reader037.vdocument.in/reader037/viewer/2022102716/54bd87754a7959d4438b45a3/html5/thumbnails/49.jpg)
this.resume()
![Page 50: The next step, part 2](https://reader037.vdocument.in/reader037/viewer/2022102716/54bd87754a7959d4438b45a3/html5/thumbnails/50.jpg)
"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);}
![Page 51: The next step, part 2](https://reader037.vdocument.in/reader037/viewer/2022102716/54bd87754a7959d4438b45a3/html5/thumbnails/51.jpg)
Inline JS, great for prototyping
Bad for more complicated testing
![Page 52: The next step, part 2](https://reader037.vdocument.in/reader037/viewer/2022102716/54bd87754a7959d4438b45a3/html5/thumbnails/52.jpg)
Scaling up the testing
![Page 53: The next step, part 2](https://reader037.vdocument.in/reader037/viewer/2022102716/54bd87754a7959d4438b45a3/html5/thumbnails/53.jpg)
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() { ... }
});
![Page 54: The next step, part 2](https://reader037.vdocument.in/reader037/viewer/2022102716/54bd87754a7959d4438b45a3/html5/thumbnails/54.jpg)
YUI Gallery
You’ve been meaning to share more anyways, right?
![Page 55: The next step, part 2](https://reader037.vdocument.in/reader037/viewer/2022102716/54bd87754a7959d4438b45a3/html5/thumbnails/55.jpg)
One way to flesh out your idea
Definitely not the only one
![Page 56: The next step, part 2](https://reader037.vdocument.in/reader037/viewer/2022102716/54bd87754a7959d4438b45a3/html5/thumbnails/56.jpg)
Patrick Cavit
@tivac on twitter
“tivac” in IRC
http://patcavit.com
http://lanyrd.com/people/tiva
c/