Loading…

Flash Player 9 (or above) is needed to view presentations.
We have detected that you do not have it on your computer. To install it, go here.

Like this presentation? Why not share!

The next step, part 2

on

  • 3,053 views

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.

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.

Statistics

Views

Total Views
3,053
Views on SlideShare
3,043
Embed Views
10

Actions

Likes
1
Downloads
43
Comments
0

1 Embed 10

http://lanyrd.com 10

Accessibility

Upload Details

Uploaded via as Microsoft PowerPoint

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.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment
  • http://www.flickr.com/photos/st3f4n/4501172754/
  • http://www.flickr.com/photos/zen/1174874997/
  • http://www.flickr.com/photos/sewitsforyou/3466154372/

The next step, part 2 The next step, part 2 Presentation Transcript

  • The Next Step, Part 2
  • Where have we been?
  • SimpleYUI, inline JS
  • External JS file via <script>
  • Plugin for Node objects
  • Simple Widget
  • Why continue?
  • Then where are we going?
  • Widget provides some structure
  • initializer:function(config){
    varnode =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;
    },
  • renderUI
  • bindUI
  • bindUI:function(){
    varnode =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)
    });
    },
  • syncUI
  • syncUI:function(){
    this.publish("sync",{
    defaultFn:Y.bind(function(){
    this.get('contentBox')
    .setContent(this.get('content'));
    },this)
    }).fire();
    }
  • YUI().use("gallery-tooltip",function(Y){
    vartooltip =newY.Tooltip({
    visible :false,
    render: true,
    node :Y.one("a")
    });
    });
  • Now what?
  • Plugins for new behaviors
  • newY.Tooltip({
    visible :false,
    render : true,
    node :Y.one("a"),
    plugins:[Y.Plugin.TooltipSimpleDisplay]
    });
    //or
    vartooltip = New Y.Tooltip({
    visible : false,
    render : true,
    node : Y.one("a")
    });
    tooltip.plug(Y.Plugin.TooltipSimpleDisplay);
  • Simple Plugin
  • Y.Base.create("TooltipSimpleDisplay",Y.Plugin.Base,[],{
    initializer:function(){
    varhost=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'
    });
  • Powered by Custom Events
    That call to preventDefault is important
  • syncUI:function(){
    this.publish("sync",{
    //Now we see why this slightly
    //odd syntax was important
    //it lets this method be
    //overridenby plugins
    defaultFn:Y.bind(function(){
    this.get('contentBox')
    .setContent(this.get('content'));
    },this)
    }).fire();
    }
  • We can go further
    http://www.flickr.com/photos/st3f4n/4501172754/
  • Transitions Module
    Adding some flash
  • newY.Tooltip({
    visible:false,
    render : true,
    node:Y.one("a"),
    plugins:[
    //from gallery
    Y.Plugin.TransitionOverlay
    ]
    });
  • Still, not really all that useful
    http://www.flickr.com/photos/zen/1174874997/
  • WidgetIO
  • YQL
  • WidgetYQL
  • 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();
    }
  • 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);
    }
    });
  • Repeating yourself sucks
  • Plugins are full JS objects
  • Plugins on top of plugins
    http://idont/have/a/source/its/just/funny
  • initializer:function(){
    varhost =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();
    });
    }
  • Multiple plugins
  • newY.Tooltip({
    visible:false,
    render : true,
    node:Y.one('a'),
    plugins:[
    Y.Plugin.TransitionOverlay,
    Y.Plugin.TooltipYQL,
    Y.Plugin.TooltipDisplay
    ]
    });
  • Done? Not so fast.
  • Prove it works, use tests
  • Widget & YUITest
  • vartest =newY.Test.Case({
    name :"Simple Tooltip Test",
    "tooltip should render without errors":
    function(){
    vartooltip =newY.Tooltip({
    visible :false,
    render : true,
    node :Y.one('a')
    });
    }
    });
    //add & run test
    Y.Test.Runner.add(test);
    Y.Test.Runner.run();
  • Didn’t do anything too dumb
    (yet)
  • Not very useful though
    http://www.flickr.com/photos/sewitsforyou/3466154372/
  • Event simulation adds utility
  • newY.Test.Case({
    name:"Tooltip Event Simulation Test",
    "tooltip should show on mouseenter":
    function(){
    //create tooltip
    vartooltip=...
    //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“
    );
    }
    });
  • Lots of JS is async though
    Sync tests don’t solve everything
  • this.wait()
  • this.resume()
  • "tooltip should transition to visible":function(){
    vartooltip =...
    //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);
    }
  • Inline JS, great for prototyping
    Bad for more complicated testing
  • Scaling up the testing
  • newY.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(){...}
    });
  • YUI Gallery
    You’ve been meaning to share more anyways, right?
  • One way to flesh out your idea
    Definitely not the only one
  • Patrick Cavit
    @tivac on twitter
    “tivac” in IRC
    http://patcavit.com
    http://lanyrd.com/people/tivac/