<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>PatCavit.com &#187; YUI</title>
	<atom:link href="http://patcavit.com/category/javascript/yui/feed/" rel="self" type="application/rss+xml" />
	<link>http://patcavit.com</link>
	<description>I &#60;3 Programming</description>
	<lastBuildDate>Fri, 02 Jul 2010 19:19:24 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Basic YUI 3 Plugin tutorial</title>
		<link>http://patcavit.com/2010/07/01/simple-yui3-plugin-tutorial/</link>
		<comments>http://patcavit.com/2010/07/01/simple-yui3-plugin-tutorial/#comments</comments>
		<pubDate>Fri, 02 Jul 2010 00:35:33 +0000</pubDate>
		<dc:creator>Pat Cavit</dc:creator>
				<category><![CDATA[Demos]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[YUI]]></category>
		<category><![CDATA[Yahoo!]]></category>

		<guid isPermaLink="false">http://patcavit.com/?p=282</guid>
		<description><![CDATA[Ever since the release of the PR2 version of YUI3 the library has support for writing plugins. Unfortunately, this doesn&#8217;t seem to be taken advantage of all that often &#38; comes up a lot in the IRC channel as something people don&#8217;t understand. So let&#8217;s see if we can&#8217;t clarify the matter a little. At [...]]]></description>
			<content:encoded><![CDATA[<p>Ever since the release of the PR2 version of YUI3 the library has support for writing plugins. Unfortunately, this doesn&#8217;t seem to be taken advantage of all that often &amp; comes up a lot in the IRC channel as something people don&#8217;t understand. So let&#8217;s see if we can&#8217;t clarify the matter a little.</p>
<p>At their core YUI3 Plugins are a way to add new behavior to JS objects. It&#8217;s really just that simple. Going into it a little deeper you can explain the idea behind them as providing a framework-backed way to add new functionality &amp; behaviors to host objects without the host needing to know anything about the plugins. Taking advantage of this means that you can add lots of functionality to your objects without requiring a lot of code. It&#8217;s another example of YUI3&#8242;s great support for modularity of code. Want your widget to accept flaboozulms? Write a plugin! Want your widget to support flaboozulms &amp; flibberdybops? Write a plugin for flibberdybops &amp; then use both the flaboozulms &amp; flibberdybops plugins together. It&#8217;s a really powerful idea.</p>
<p>With the pontificating out of the way, let&#8217;s touch on some code. I&#8217;ll be taking apart a <strong>VERY</strong> basic plugin I&#8217;ve created that listens for clicks on the host &amp; changes the background color. This plugin specifically is targeted towards <a href="http://developer.yahoo.com/yui/3/node/">Node</a> objects since the behavior involves listening for a click event, but the basic concepts could work for any host object. It&#8217;s not a very in-depth example of the power here but it is simple enough to show the basics.</p>
<p><strong><a href="http://tivac.com/yui3/examples/plugin.htm">Basic YUI3 Plugin Example</a></strong></p>
<p>Quick breakdown of what this page contains. It&#8217;s got your standard HTML skeleton to allow us to easily run JS in the browser, a single &lt;div&gt; we&#8217;ll be using to show the interactions, some CSS to style that &lt;div&gt;, and some chunks of JS.</p>
<p>The first bit of JS is including the YUI3 seed file, as well as the loader (because we know for certain we&#8217;ll be using it we can save a HTTP request by getting these together).</p>

<div class="wp_syntax"><div class="code"><pre class="html4strict" style="font-family:monospace;"><span class="sc2">&lt;<span class="kw2">script</span> <span class="kw3">src</span><span class="sy0">=</span><span class="st0">&quot;http://yui.yahooapis.com/combo?3.1.1/build/yui/yui.js&amp;amp;3.1.1/build/loader/loader.js&quot;</span>&gt;</span><span class="sc-1">&lt;!--mce:0--&gt;</span><span class="sc2">&lt;<span class="sy0">/</span><span class="kw2">script</span>&gt;</span></pre></div></div>

<p>The next piece is declaring the plugin itself. This occurs within a <code><a href="http://developer.yahoo.com/yui/3/api/YUI.html#method_add">YUI.add()</a></code> block that allows us to later specify that we want to use the plugin. You could of course declare the function within the same <code><a href="http://developer.yahoo.com/yui/3/api/YUI.html#method_use">YUI().use()</a></code> section where you use it but that wouldn&#8217;t be very reusable.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">YUI.<span class="me1">add</span><span class="br0">&#40;</span><span class="st0">'basic-plugin'</span><span class="sy0">,</span> <span class="kw2">function</span><span class="br0">&#40;</span>Y<span class="br0">&#41;</span> <span class="br0">&#123;</span>
    <span class="co2">/* Plugin code here */</span>
<span class="br0">&#125;</span><span class="sy0">,</span> <span class="st0">&quot;0.1&quot;</span><span class="sy0">,</span> <span class="br0">&#123;</span> requires <span class="sy0">:</span> <span class="br0">&#91;</span> <span class="st0">&quot;base&quot;</span><span class="sy0">,</span> <span class="st0">&quot;plugin&quot;</span><span class="sy0">,</span> <span class="st0">&quot;node&quot;</span> <span class="br0">&#93;</span> <span class="br0">&#125;</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div>

<p>Discussing the syntax for <code><a href="http://developer.yahoo.com/yui/3/api/YUI.html#method_add">YUI.add()</a></code> is a little outside the scope of this but you should note where we declare an array of modules that are required for the plugin to function.</p>
<p>Once inside of the <code><a href="http://developer.yahoo.com/yui/3/api/YUI.html#method_add">YUI.add()</a></code> it&#8217;s time to actually create the plugin object. It&#8217;ll be stuck onto the <code>Y</code> variable so that we&#8217;ve got a place to reference it in other code blocks that request our &#8220;basic-plugin&#8221;. The plugin object&#8217;s creation is handled using <code><a href="http://developer.yahoo.com/yui/3/api/Base.html#method_Base.create">Y.Base.create()</a></code>, a very useful framework function that takes care of inheritance &amp; a few other pieces for you. It&#8217;s a little hand wavey but if you want the nitty-gritty details feel free to ask &amp; I can provide them.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">Y.<span class="kw2">namespace</span><span class="br0">&#40;</span><span class="st0">'Examples'</span><span class="br0">&#41;</span>.<span class="me1">BasicPlugin</span> <span class="sy0">=</span> Y.<span class="me1">Base</span>.<span class="me1">create</span><span class="br0">&#40;</span><span class="st0">&quot;BasicPlugin&quot;</span><span class="sy0">,</span> Y.<span class="me1">Plugin</span>.<span class="me1">Base</span><span class="sy0">,</span> <span class="br0">&#91;</span><span class="br0">&#93;</span><span class="sy0">,</span> <span class="br0">&#123;</span> ... <span class="br0">&#125;</span><span class="sy0">,</span> <span class="br0">&#123;</span> ... <span class="br0">&#125;</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div>

<p>A quick breakdown of what we&#8217;re doing here, <code>Y.namespace('Examples').BasicPlugin</code> creates nested empty objects for us so everything stays nice and organized without any danger of collisions. Keeping things nested within namespaces like this helps to make sure we can use awesome names like &#8220;BasicPlugin&#8221; instead of stupid names like &#8220;CavitExampleBasicPlugin&#8221;. Nobody likes stupid names.</p>
<p>Next up is the assignment of the object returned by <code><a href="http://developer.yahoo.com/yui/3/api/Base.html#method_Base.create">Y.Base.create()</a></code> to our brand-new namespaced object. <code><a href="http://developer.yahoo.com/yui/3/api/Base.html#method_Base.create">Y.Base.create()</a></code> takes a name for the plugin, an class to inherit from, an array of classes to also optionally inherit from (unnecessary for our example), the prototype properties (more later), and static properties (again, more later). The function takes all of these objects &amp; combines them to allow for easy instantiating of objects later.</p>
<p>Let&#8217;s start with the prototype properties object that we&#8217;re passing to <code><a href="http://developer.yahoo.com/yui/3/api/Base.html#method_Base.create">Y.Base.create()</a></code>. This object is used as the <code><a href="https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Function/prototype">.prototype</a></code> property of the class being created which means that it&#8217;ll be shared by every instance of this class. This is where any functions you want to live as part of the class go, along with any properties for that class instance.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">Y.<span class="me1">Base</span>.<span class="me1">create</span><span class="br0">&#40;</span>...<span class="sy0">,</span> ...<span class="sy0">,</span> <span class="br0">&#91;</span><span class="br0">&#93;</span><span class="sy0">,</span> <span class="br0">&#123;</span>
    _handle <span class="sy0">:</span> <span class="kw2">null</span><span class="sy0">,</span>
    initializer <span class="sy0">:</span> <span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span> ... <span class="br0">&#125;</span><span class="sy0">,</span>
    destructor <span class="sy0">:</span> <span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span> ... <span class="br0">&#125;</span>
<span class="br0">&#125;</span><span class="sy0">,</span> <span class="br0">&#123;</span> ... <span class="br0">&#125;</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div>

<p>Since this is a &#8220;basic&#8221; plugin we&#8217;re only providing one property &amp; two functions. The two functions (<code><a href="http://developer.yahoo.com/yui/3/api/Plugin.Base.html#method_initializer">initializer()</a></code> &amp; <code><a href="http://developer.yahoo.com/yui/3/api/Plugin.Base.html#method_destructor">destructor()</a>)</code> are special functions that YUI3 will call every time a new instance of this plugin is plugged or unplugged into a host. Starting with <code><a href="http://developer.yahoo.com/yui/3/api/Plugin.Base.html#method_initializer">initializer()</a></code> we can see that for this basic plugin all it&#8217;s doing is attaching a click event handler to the host (in this case a DOM node) that the plugin was plugged into.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span class="kw1">this</span>._handle <span class="sy0">=</span> <span class="kw1">this</span>.<span class="me1">get</span><span class="br0">&#40;</span><span class="st0">&quot;host&quot;</span><span class="br0">&#41;</span>.<span class="me1">on</span><span class="br0">&#40;</span><span class="st0">&quot;click&quot;</span><span class="sy0">,</span> <span class="kw2">function</span><span class="br0">&#40;</span>e<span class="br0">&#41;</span> <span class="br0">&#123;</span>
    <span class="kw2">var</span> tgt <span class="sy0">=</span> e.<span class="me1">currentTarget</span><span class="sy0">,</span>
        color <span class="sy0">=</span> <span class="kw1">this</span>.<span class="me1">get</span><span class="br0">&#40;</span><span class="st0">&quot;color&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
    <span class="kw1">this</span>.<span class="me1">set</span><span class="br0">&#40;</span><span class="st0">&quot;color&quot;</span><span class="sy0">,</span> tgt.<span class="me1">getStyle</span><span class="br0">&#40;</span><span class="st0">&quot;backgroundColor&quot;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
    tgt.<span class="me1">setStyle</span><span class="br0">&#40;</span><span class="st0">&quot;background&quot;</span><span class="sy0">,</span> color<span class="br0">&#41;</span><span class="sy0">;</span>
<span class="br0">&#125;</span><span class="sy0">,</span> <span class="kw1">this</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div>

<p>It&#8217;s pretty straightforward YUI3 code but let&#8217;s run through it quickly. We attach an event handler to click events on the host object (<code><a href="http://developer.yahoo.com/yui/3/api/Attribute.html#method_get">this.get("host")</a></code> will get the special host attribute all plugins have) and provide a callback function to that handler. Note that we store a reference to the object returned by the event   attachment, this&#8217;ll be important later. The callback saves the target of the click &amp; the current color attribute&#8217;s value, then updates the color attribute with the target&#8217;s backgroundColor &amp; finally updates the backgroundColor of the target. The only tricky part in here is the use of <code><a href="http://developer.yahoo.com/yui/3/api/Attribute.html#method_get">this.get()</a></code> &amp; <code><a href="http://developer.yahoo.com/yui/3/api/Attribute.html#method_set">this.set()</a></code> which are used to access/update this plugins attributes data. We&#8217;ll talk about attributes in just a bit.</p>
<p>Next up is <code><a href="http://developer.yahoo.com/yui/3/api/Plugin.Base.html#method_destructor">destructor()</a></code> which is invoked whenever the plugin is destroyed (you&#8217;ll see how a little further down).</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">destructor <span class="sy0">:</span> <span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
    <span class="kw1">this</span>._handle.<span class="me1">detach</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
    <span class="kw1">this</span>._handle <span class="sy0">=</span> <span class="kw2">null</span><span class="sy0">;</span>
<span class="br0">&#125;</span></pre></div></div>

<p>This clean up function ensures we don&#8217;t leave little bits of code poop all over the place. The event handler is detached &amp; the reference is nulled out to make sure that the garbage collector has no issue getting that little bit of memory back.</p>
<p>So at this point all we&#8217;ve really done is add an object to the <code>Y</code> variable that is accessible at <code>Y.Example.BasicPlugin</code> that when used in conjunction with <code><a href="http://developer.yahoo.com/yui/3/api/Base.html#method_Base.plug">.plug()</a></code> later on will listen for clicks &amp; change some background colors. I said we were making a basic plugin, excitement was never promised.</p>
<p>So if we step back up a bit to look at the next argument to <code><a href="http://developer.yahoo.com/yui/3/api/Base.html#method_Base.create">Y.Base.create()</a></code> we&#8217;ll notice that it is time to talk about the static properties. Here&#8217;s the code.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">Y.<span class="me1">Base</span>.<span class="me1">create</span><span class="br0">&#40;</span>...<span class="sy0">,</span> ...<span class="sy0">,</span> <span class="br0">&#123;</span><span class="br0">&#125;</span><span class="sy0">,</span> <span class="br0">&#123;</span>...<span class="br0">&#125;</span><span class="sy0">,</span> <span class="br0">&#123;</span>
    NS <span class="sy0">:</span> <span class="st0">&quot;sp&quot;</span><span class="sy0">,</span>
    ATTRS <span class="sy0">:</span> <span class="br0">&#123;</span>
        color <span class="sy0">:</span> <span class="br0">&#123;</span> value <span class="sy0">:</span> <span class="st0">&quot;blue&quot;</span> <span class="br0">&#125;</span>
    <span class="br0">&#125;</span>
<span class="br0">&#125;</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div>

<p>Judging by the amount of code here it&#8217;s tempting to think that not a whole lot is happening. You&#8217;re right. More could be happening here but in the interest of time it&#8217;s been purposely kept very short. All this is doing is declaring two properties. <code><a href="http://developer.yahoo.com/yui/3/api/Plugin.Base.html#property_Plugin.NS">NS</a></code> is used for referencing the plugin object once it has been plugged into a host. The <code><a href="http://developer.yahoo.com/yui/3/api/Base.html#property_Base.ATTRS">ATTRS</a></code> property defines all the attributes that this plugin will support. The totally great thing about this is that it uses the YUI3 Attributes objects as its backend so you get a lot of power &amp; custom events to allow you to validate/get updates/whatever you want when these things are changed. That&#8217;s outside the scope of this article but I could go on about that for a while. This is where the ability to use <code><a href="http://developer.yahoo.com/yui/3/api/Attribute.html#method_get">this.get()</a></code>/<code><a href="http://developer.yahoo.com/yui/3/api/Attribute.html#method_set">this.set()</a></code> comes from as those are brought in automatically to get/set attributes.</p>
<p>So at this point we&#8217;ve got a complete plugin that&#8217;s been registered using <code><a href="http://developer.yahoo.com/yui/3/api/YUI.html#method_add">YUI.add()</a></code>, what do we do with it? Well the whole point of using <code><a href="http://developer.yahoo.com/yui/3/api/YUI.html#method_add">YUI.add()</a></code> was so that anywhere we wanted to on the page we could make the plugin available simply by doing something like the following.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">YUI<span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="kw2">use</span><span class="br0">&#40;</span><span class="st0">&quot;node&quot;</span><span class="sy0">,</span> <span class="st0">&quot;basic-plugin&quot;</span><span class="sy0">,</span> <span class="kw2">function</span><span class="br0">&#40;</span>Y<span class="br0">&#41;</span> <span class="br0">&#123;</span> ... <span class="br0">&#125;</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div>

<p>And since we made sure to add the plugin to a namespace hung off of the main YUI instance variable (by convention it&#8217;s simply &#8220;Y&#8221;) within the <code><a href="http://developer.yahoo.com/yui/3/api/YUI.html#method_use">YUI().use()</a></code> callback we can now access our plugin at <code>Y.Examples.BasicPlugin</code>. So what to do with it now that it&#8217;s hanging out waiting to be used? I dunno, how about we plug something?</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">Y.<span class="me1">one</span><span class="br0">&#40;</span><span class="st0">&quot;#wooga&quot;</span><span class="br0">&#41;</span>.<span class="me1">plug</span><span class="br0">&#40;</span>Y.<span class="me1">Examples</span>.<span class="me1">BasicPlugin</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div>

<p>So we&#8217;ve just taken our plugin and applied it to a host object. In this case the host object is a YUI3 Node object. That <code><a href="http://developer.yahoo.com/yui/3/api/Plugin.Base.html#method_initializer">initializer()</a></code> function we declared as a prototype property inside of <code><a href="http://developer.yahoo.com/yui/3/api/Base.html#method_Base.create">Y.Base.create()</a></code> will now be called &amp; the Node will now respond to clicks by changing its background color.</p>
<p>When you call <code><a href="http://developer.yahoo.com/yui/3/api/Plugin.Host.html#method_Plugin.Host.plug">.plug()</a></code> you can also pass in a configuration object that&#8217;ll define defaults for the plugin, so for the second example we also define the color attribute.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">Y.<span class="me1">one</span><span class="br0">&#40;</span><span class="st0">&quot;#booga&quot;</span><span class="br0">&#41;</span>.<span class="me1">plug</span><span class="br0">&#40;</span>Y.<span class="me1">Examples</span>.<span class="me1">BasicPlugin</span><span class="sy0">,</span> <span class="br0">&#123;</span> color <span class="sy0">:</span> <span class="st0">&quot;#666&quot;</span> <span class="br0">&#125;</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div>

<p>This isn&#8217;t part of the live example but it&#8217;s an important concept, with YUI 3 plugins it&#8217;s just as easy to remove functionality as it is to add it. All you need to do is <code><a href="http://developer.yahoo.com/yui/3/api/Plugin.Host.html#method_unplug">unplug()</a></code> your plugin from the host. The plugin&#8217;s <code><a href="http://developer.yahoo.com/yui/3/api/Plugin.Base.html#method_destructor">destructor()</a></code> method is called and the host object loses whatever functionality was provided.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">Y.<span class="me1">one</span><span class="br0">&#40;</span><span class="st0">&quot;#wooga&quot;</span><span class="br0">&#41;</span>.<span class="me1">unplug</span><span class="br0">&#40;</span>Y.<span class="me1">Examples</span>.<span class="me1">BasicPlugin</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div>

<p>One more thing to note, aside from the YUI3 seed file &amp; loader we never had to include any other &lt;script&gt; tags. This is because YUI3 is rad as hell and the Loader is able to determine based on the modules that <code><a href="http://developer.yahoo.com/yui/3/api/YUI.html#method_use">YUI().use()</a></code> asked for &amp; the requires array for the <code><a href="http://developer.yahoo.com/yui/3/api/YUI.html#method_add">YUI.add()</a></code> which files it should automatically load from the Yahoo! CDN. It&#8217;s super-powerful and one of my favorite features in YUI3.</p>
<p>For a better overview, here&#8217;s the complete JS code w/ minimal comments</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span class="co1">//create the module</span>
YUI.<span class="me1">add</span><span class="br0">&#40;</span><span class="st0">'basic-plugin'</span><span class="sy0">,</span> <span class="kw2">function</span><span class="br0">&#40;</span>Y<span class="br0">&#41;</span> <span class="br0">&#123;</span>
    <span class="co1">//create namespaced plugin class</span>
    Y.<span class="kw2">namespace</span><span class="br0">&#40;</span><span class="st0">'Examples'</span><span class="br0">&#41;</span>.<span class="me1">BasicPlugin</span> <span class="sy0">=</span> Y.<span class="me1">Base</span>.<span class="me1">create</span><span class="br0">&#40;</span><span class="st0">&quot;BasicPlugin&quot;</span><span class="sy0">,</span> Y.<span class="me1">Plugin</span>.<span class="me1">Base</span><span class="sy0">,</span> <span class="br0">&#91;</span><span class="br0">&#93;</span><span class="sy0">,</span> <span class="br0">&#123;</span>
&nbsp;
        _handle <span class="sy0">:</span> <span class="kw2">null</span><span class="sy0">,</span>
&nbsp;
        <span class="co1">//constructor</span>
        initializer <span class="sy0">:</span> <span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
            <span class="kw1">this</span>._handle <span class="sy0">=</span> <span class="kw1">this</span>.<span class="me1">get</span><span class="br0">&#40;</span><span class="st0">&quot;host&quot;</span><span class="br0">&#41;</span>.<span class="me1">on</span><span class="br0">&#40;</span><span class="st0">&quot;click&quot;</span><span class="sy0">,</span> <span class="kw2">function</span><span class="br0">&#40;</span>e<span class="br0">&#41;</span> <span class="br0">&#123;</span>
                <span class="kw2">var</span> tgt <span class="sy0">=</span> e.<span class="me1">currentTarget</span><span class="sy0">,</span>
                    color <span class="sy0">=</span> <span class="kw1">this</span>.<span class="me1">get</span><span class="br0">&#40;</span><span class="st0">&quot;color&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
                <span class="kw1">this</span>.<span class="me1">set</span><span class="br0">&#40;</span><span class="st0">&quot;color&quot;</span><span class="sy0">,</span> tgt.<span class="me1">getStyle</span><span class="br0">&#40;</span><span class="st0">&quot;backgroundColor&quot;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
                tgt.<span class="me1">setStyle</span><span class="br0">&#40;</span><span class="st0">&quot;background&quot;</span><span class="sy0">,</span> color<span class="br0">&#41;</span><span class="sy0">;</span>
            <span class="br0">&#125;</span><span class="sy0">,</span> <span class="kw1">this</span><span class="br0">&#41;</span><span class="sy0">;</span>
        <span class="br0">&#125;</span><span class="sy0">,</span>
&nbsp;
        <span class="co1">//clean up on destruction</span>
        destructor <span class="sy0">:</span> <span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
            <span class="kw1">this</span>._handle.<span class="me1">detach</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
            <span class="kw1">this</span>._handle <span class="sy0">=</span> <span class="kw2">null</span><span class="sy0">;</span>
        <span class="br0">&#125;</span>
    <span class="br0">&#125;</span><span class="sy0">,</span>
    <span class="br0">&#123;</span>
        NS <span class="sy0">:</span> <span class="st0">&quot;bp&quot;</span><span class="sy0">,</span>
        ATTRS <span class="sy0">:</span> <span class="br0">&#123;</span>
            color <span class="sy0">:</span> <span class="br0">&#123;</span> value <span class="sy0">:</span> <span class="st0">&quot;#00F&quot;</span> <span class="br0">&#125;</span>
        <span class="br0">&#125;</span>
    <span class="br0">&#125;</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="br0">&#125;</span><span class="sy0">,</span> <span class="st0">&quot;0.1&quot;</span><span class="sy0">,</span> <span class="br0">&#123;</span> requires <span class="sy0">:</span> <span class="br0">&#91;</span> <span class="st0">&quot;base&quot;</span><span class="sy0">,</span> <span class="st0">&quot;plugin&quot;</span><span class="sy0">,</span> <span class="st0">&quot;node&quot;</span> <span class="br0">&#93;</span> <span class="br0">&#125;</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
YUI<span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="kw2">use</span><span class="br0">&#40;</span><span class="st0">&quot;node&quot;</span><span class="sy0">,</span> <span class="st0">&quot;basic-plugin&quot;</span><span class="sy0">,</span> <span class="kw2">function</span><span class="br0">&#40;</span>Y<span class="br0">&#41;</span> <span class="br0">&#123;</span>
    Y.<span class="me1">one</span><span class="br0">&#40;</span><span class="st0">&quot;#wooga&quot;</span><span class="br0">&#41;</span>.<span class="me1">plug</span><span class="br0">&#40;</span>Y.<span class="me1">Examples</span>.<span class="me1">BasicPlugin</span><span class="br0">&#41;</span><span class="sy0">;</span>
    Y.<span class="me1">one</span><span class="br0">&#40;</span><span class="st0">&quot;#booga&quot;</span><span class="br0">&#41;</span>.<span class="me1">plug</span><span class="br0">&#40;</span>Y.<span class="me1">Examples</span>.<span class="me1">BasicPlugin</span><span class="sy0">,</span> <span class="br0">&#123;</span> color <span class="sy0">:</span> <span class="st0">&quot;#666&quot;</span> <span class="br0">&#125;</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="br0">&#125;</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div>

<p>And the entire shebang including all the HTML &amp; CSS is available at the sample link.</p>
<p><strong><a href="http://tivac.com/yui3/examples/plugin.htm">Basic YUI3 Plugin Example</a></strong></p>
]]></content:encoded>
			<wfw:commentRss>http://patcavit.com/2010/07/01/simple-yui3-plugin-tutorial/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>YUI 3 Loader &amp; Aggregated Files</title>
		<link>http://patcavit.com/2010/06/01/yui-3-loader-aggregated-files/</link>
		<comments>http://patcavit.com/2010/06/01/yui-3-loader-aggregated-files/#comments</comments>
		<pubDate>Tue, 01 Jun 2010 19:15:07 +0000</pubDate>
		<dc:creator>Pat Cavit</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Work]]></category>
		<category><![CDATA[YUI]]></category>
		<category><![CDATA[Yahoo!]]></category>

		<guid isPermaLink="false">http://patcavit.com/?p=269</guid>
		<description><![CDATA[With the launch of the ArenaNet Blog I&#8217;ve been working a lot with YUI3 since it is the JS framework that powers all the interactivity on the site. The other great thing it does is provide a Loader that can pull in JS files on-demand as defined by a configuration object you pass to it. [...]]]></description>
			<content:encoded><![CDATA[<p>With the launch of the <a title="ArenaNet Blog" href="http://www.arena.net/blog/">ArenaNet Blog</a> I&#8217;ve been working a lot with <a href="http://developer.yahoo.com/yui/3/">YUI3</a> since it is the JS framework that powers all the interactivity on the site. The other great thing it does is provide a Loader that can pull in JS files on-demand as defined by a configuration object you pass to it. Loader has the capability to roll up multiple requests into a single file using a CDN but the functionality to do the same without using a CDN appears to be broken. Adam Moore from the YUI team &amp; I have been discussing the issue on <a href="http://yuilibrary.com/projects/yui3/ticket/2528823">YUI&#8217;s bug tracker</a> without a resolution yet.</p>
<p>Since I need to keep moving on this stuff I&#8217;ve had to devise my own solution to the issue I&#8217;m experiencing. For background, we use Apache Ant to create a &#8220;Deploy&#8221; version of the WordPress theme on the blog. This process runs through CSS/JS &amp; renames files, <a href="http://yuilibrary.com/projects/yuicompressor/">compresses them</a>, updates references, does <a href="http://github.com/nzakas/cssembed">DataURI stuff</a>, etc. It&#8217;s pretty nice and allows for easily deploying a very optimized site without making development a nightmare. As part of that I&#8217;ve had it roll up two JS files that are always requested together into one file to avoid making an extra HTTP request. Unfortunately when I tried a simple replace of the previous filenames with the new aggregate file&#8217;s name YUI 3&#8242;s Loader was loading the file twice.</p>
<p>So until I can get a working version of what Adam has suggested here&#8217;s how I&#8217;ve set up the build system to allow for replacing individual modules in development mode with a single aggregate file for deploying.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span class="co1">//DEV CONFIG</span>
YUI_config <span class="sy0">=</span> <span class="br0">&#123;</span>
    <span class="co1">//yes this is a little gross but sadly it's necessary to make loader work how we want w/ ant</span>
    <span class="co2">/* dev */</span> ignore <span class="sy0">:</span> <span class="br0">&#91;</span> <span class="st0">&quot;sidebar-rollup&quot;</span> <span class="br0">&#93;</span><span class="sy0">,</span> <span class="co1">//dev */</span>
    <span class="coMULTI">/* live ignore : [ &quot;chiclet&quot;, &quot;slider-plugin&quot; ], //live */</span>
    groups <span class="sy0">:</span> <span class="br0">&#123;</span>
        anet <span class="sy0">:</span> <span class="br0">&#123;</span>
            combine <span class="sy0">:</span> <span class="kw2">false</span><span class="sy0">,</span>
            base <span class="sy0">:</span> <span class="st0">&quot;/blog/wp-content/themes/arenanet/js/lib/&quot;</span><span class="sy0">,</span>
            modules <span class="sy0">:</span> <span class="br0">&#123;</span>
                <span class="st0">&quot;chiclet&quot;</span> <span class="sy0">:</span> <span class="br0">&#123;</span>
                    path <span class="sy0">:</span> <span class="st0">&quot;chiclet.js&quot;</span><span class="sy0">,</span>
                    skinnable<span class="sy0">:</span> <span class="kw2">false</span><span class="sy0">,</span>
                    requires <span class="sy0">:</span> <span class="br0">&#91;</span> <span class="st0">&quot;base&quot;</span><span class="sy0">,</span> <span class="st0">&quot;widget&quot;</span><span class="sy0">,</span> <span class="st0">&quot;anim-base&quot;</span><span class="sy0">,</span> <span class="st0">&quot;anim-easing&quot;</span><span class="sy0">,</span> <span class="st0">&quot;sidebar-rollup&quot;</span> <span class="br0">&#93;</span>
                <span class="br0">&#125;</span><span class="sy0">,</span>
&nbsp;
                <span class="st0">&quot;slider-plugin&quot;</span> <span class="sy0">:</span> <span class="br0">&#123;</span>
                    path <span class="sy0">:</span> <span class="st0">&quot;slider.js&quot;</span><span class="sy0">,</span>
                    requires <span class="sy0">:</span> <span class="br0">&#91;</span><span class="st0">&quot;plugin&quot;</span><span class="sy0">,</span> <span class="st0">&quot;node&quot;</span><span class="sy0">,</span> <span class="st0">&quot;anim-base&quot;</span><span class="sy0">,</span> <span class="st0">&quot;anim-easing&quot;</span><span class="sy0">,</span> <span class="st0">&quot;sidebar-rollup&quot;</span> <span class="br0">&#93;</span>
                <span class="br0">&#125;</span><span class="sy0">,</span>
&nbsp;
                <span class="st0">&quot;gallery-lightbox&quot;</span> <span class="sy0">:</span> <span class="br0">&#123;</span>
                    path <span class="sy0">:</span> <span class="st0">&quot;lightbox.js&quot;</span><span class="sy0">,</span>
                    requires <span class="sy0">:</span> <span class="br0">&#91;</span><span class="st0">&quot;base&quot;</span><span class="sy0">,</span> <span class="st0">&quot;node&quot;</span><span class="sy0">,</span> <span class="st0">&quot;anim-base&quot;</span><span class="sy0">,</span> <span class="st0">&quot;selector-css3&quot;</span><span class="br0">&#93;</span>
                <span class="br0">&#125;</span><span class="sy0">,</span>
&nbsp;
                <span class="st0">&quot;scroller-plugin&quot;</span> <span class="sy0">:</span> <span class="br0">&#123;</span>
                    path <span class="sy0">:</span> <span class="st0">&quot;scroll.js&quot;</span><span class="sy0">,</span>
                    requires <span class="sy0">:</span> <span class="br0">&#91;</span><span class="st0">&quot;plugin&quot;</span><span class="sy0">,</span> <span class="st0">&quot;node&quot;</span><span class="sy0">,</span> <span class="st0">&quot;selector-css3&quot;</span><span class="sy0">,</span> <span class="st0">&quot;event-delegate&quot;</span><span class="sy0">,</span> <span class="st0">&quot;anim-base&quot;</span><span class="sy0">,</span> <span class="st0">&quot;anim-scroll&quot;</span><span class="sy0">,</span> <span class="st0">&quot;anim-easing&quot;</span><span class="br0">&#93;</span>
                <span class="br0">&#125;</span><span class="sy0">,</span>
&nbsp;
                <span class="st0">&quot;social-counts&quot;</span> <span class="sy0">:</span> <span class="br0">&#123;</span>
                    path <span class="sy0">:</span> <span class="st0">&quot;social.js&quot;</span><span class="sy0">,</span>
                    requires <span class="sy0">:</span> <span class="br0">&#91;</span> <span class="st0">&quot;gallery-yql&quot;</span><span class="sy0">,</span> <span class="st0">&quot;node&quot;</span> <span class="br0">&#93;</span>
                <span class="br0">&#125;</span><span class="sy0">,</span>
&nbsp;
                <span class="st0">&quot;sidebar-rollup&quot;</span> <span class="sy0">:</span> <span class="br0">&#123;</span>
                    path <span class="sy0">:</span> <span class="st0">&quot;sidebar.js&quot;</span>
                <span class="br0">&#125;</span>
            <span class="br0">&#125;</span>
        <span class="br0">&#125;</span>
    <span class="br0">&#125;</span>
<span class="br0">&#125;</span><span class="sy0">;</span></pre></div></div>

<p>which is modified by the Ant build script to</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span class="co1">//DEPLOY MODE</span>
YUI_config <span class="sy0">=</span> <span class="br0">&#123;</span>
    <span class="co1">//yes this is a little gross but sadly it's necessary to make loader work how we want w/ ant</span>
    <span class="coMULTI">/* dev  ignore : [ &quot;sidebar-rollup&quot; ], //dev */</span>
    <span class="co2">/* live */</span> ignore <span class="sy0">:</span> <span class="br0">&#91;</span> <span class="st0">&quot;chiclet&quot;</span><span class="sy0">,</span> <span class="st0">&quot;slider-plugin&quot;</span> <span class="br0">&#93;</span><span class="sy0">,</span> <span class="co1">//live */</span>
    groups <span class="sy0">:</span> <span class="br0">&#123;</span>
        anet <span class="sy0">:</span> <span class="br0">&#123;</span>
            <span class="co1">//omitted for brevity, see above code block because this doesn't change between them</span>
            <span class="br0">&#125;</span>
        <span class="br0">&#125;</span>
    <span class="br0">&#125;</span>
<span class="br0">&#125;</span><span class="sy0">;</span></pre></div></div>

<p>The comments get stripped out during compression so it doesn&#8217;t look quite so gnarly when sent to end-users. It&#8217;s also pretty easy to do as an Ant task, all it takes is this</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span class="sc-1">&lt;!-- update references to old js files to new concatted file --&gt;</span>
<span class="sc3"><span class="re1">&lt;replace</span> <span class="re0">file</span>=<span class="st0">&quot;${js.dir}/loader.js&quot;</span> <span class="re0">token</span>=<span class="st0">&quot;/* dev */&quot;</span> <span class="re0">value</span>=<span class="st0">&quot;/* dev &quot;</span> <span class="re0">summary</span>=<span class="st0">&quot;yes&quot;</span> <span class="re2">/&gt;</span></span>
<span class="sc3"><span class="re1">&lt;replace</span> <span class="re0">file</span>=<span class="st0">&quot;${js.dir}/loader.js&quot;</span> <span class="re0">token</span>=<span class="st0">&quot;/* live &quot;</span> <span class="re0">value</span>=<span class="st0">&quot;/* live */&quot;</span> <span class="re0">summary</span>=<span class="st0">&quot;yes&quot;</span> <span class="re2">/&gt;</span></span></pre></div></div>

<p>to do the switch. Later in my custom loader script those two modules are used with</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">YUI<span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="kw2">use</span><span class="br0">&#40;</span><span class="st0">&quot;node&quot;</span><span class="sy0">,</span> <span class="st0">&quot;event-base&quot;</span><span class="sy0">,</span> <span class="st0">&quot;imageloader&quot;</span><span class="sy0">,</span> <span class="st0">&quot;selector-css3&quot;</span><span class="sy0">,</span> <span class="st0">&quot;chiclet&quot;</span><span class="sy0">,</span> <span class="st0">&quot;slider-plugin&quot;</span><span class="sy0">,</span> <span class="kw2">function</span><span class="br0">&#40;</span>Y<span class="br0">&#41;</span> <span class="br0">&#123;</span>
    <span class="co1">// Code goes here...</span>
<span class="br0">&#125;</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div>

<p>which will always make sure that both the &#8220;Chiclet&#8221; and &#8220;Slider-Plugin&#8221; modules are available. In dev mode it will request chiclet.js &amp; slider.js versus just asking for sidebar.js when deployed.</p>
<p>Does anybody have a better way of doing this? I think Adam&#8217;s version is nicer looking in the config but I&#8217;m not sure how it will work if a) the rollup file doesn&#8217;t exist or b) you don&#8217;t want to use the rollup except in production. I guess you could always just do something similar to what I&#8217;m doing now to configure it. That all assumes that the issues with it not actually loading the module get figured out, because if the modules aren&#8217;t added to the Y instance what&#8217;s the point?</p>
]]></content:encoded>
			<wfw:commentRss>http://patcavit.com/2010/06/01/yui-3-loader-aggregated-files/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>YUI 2.8 Uploader</title>
		<link>http://patcavit.com/2010/01/06/yui-2-8-uploader/</link>
		<comments>http://patcavit.com/2010/01/06/yui-2-8-uploader/#comments</comments>
		<pubDate>Wed, 06 Jan 2010 18:47:46 +0000</pubDate>
		<dc:creator>Pat Cavit</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[No Category]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tivac.com Projects]]></category>
		<category><![CDATA[YUI]]></category>
		<category><![CDATA[Yahoo!]]></category>

		<guid isPermaLink="false">http://patcavit.com/?p=253</guid>
		<description><![CDATA[I know this is old but I finally tried upgrading my uploader implementation at http://tivac.com/upload/ to YUI 2.8. Ran into some nasty problems where the SWF would never fire its contentReady event. Turns out, it&#8217;s a known issue with the Uploader component in YUI 2.8 and it&#8217;ll be fixed in the next patch release. Important [...]]]></description>
			<content:encoded><![CDATA[<p>I know this is old but I finally tried upgrading my uploader implementation at <a href="http://tivac.com/upload/">http://tivac.com/upload/</a> to YUI 2.8. Ran into some nasty problems where the SWF would never fire its contentReady event.</p>
<p>Turns out, it&#8217;s a known issue with the Uploader component in YUI 2.8 and it&#8217;ll be fixed in the next patch release.</p>
<blockquote><p><strong>Important Issue:</strong> Due to a current bug, the current version of uploader.swf hosted on yui.yahooapis.com in the YUI 2.8 branch is NOT compatible with the uploader.js hosted on yui.yahooapis.com. Until the next bugfix release, you can work around this issue by either locally hosting the older version of uploader.swf (available here), or locally hosting the uploader.js and making the following changes to it:</p>
<ul>
<li>On line 509, in swfObj.addVariable(&#8220;elementID&#8221;, swfID);, replace &#8220;elementID&#8221; with &#8220;YUISwfId&#8221;.</li>
<li>On line 512, in swfObj.addVariable(&#8220;eventHandler&#8221;, &#8220;YAHOO.widget.FlashAdapter.eventHandler&#8221;);, replace &#8220;eventHandler&#8221; with &#8220;YUIBridgeCallback&#8221;.</li>
</ul>
</blockquote>
<p>That only had me frustrated for 5 minutes, thank god I read <a href="http://developer.yahoo.com/yui/uploader/">the documentation</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://patcavit.com/2010/01/06/yui-2-8-uploader/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Arena.net</title>
		<link>http://patcavit.com/2009/09/18/arena-net/</link>
		<comments>http://patcavit.com/2009/09/18/arena-net/#comments</comments>
		<pubDate>Fri, 18 Sep 2009 15:36:22 +0000</pubDate>
		<dc:creator>Pat Cavit</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Work]]></category>
		<category><![CDATA[YUI]]></category>

		<guid isPermaLink="false">http://patcavit.com/?p=234</guid>
		<description><![CDATA[While I don&#8217;t work on the team responsible for the Arena.net site I help out all over the company wherever I can. When it was decided that the old site needed to be updated I got the call. After some discussions around what exactly the site should encompass it came down to wanting to have [...]]]></description>
			<content:encoded><![CDATA[<p>While I don&#8217;t work on the team responsible for the <a href="http://arena.net">Arena.net</a> site I help out all over the company wherever I can. When it was decided that the old site needed to be updated I got the call. After some discussions around what exactly the site should encompass it came down to wanting to have the site be an aggregator of updates by arena.net on various different services.</p>
<p>Here&#8217;s the rundown:</p>
<ul>
<li><a href="http://twitter.com/arenanet/">Twitter</a></li>
<li><a href="http://www.guildwars.com/events/newsarchive/default.php">GuildWars.com News</a></li>
<li><a href="http://www.flickr.com/photos/arenanet/">Flickr</a></li>
<li><a href="http://us.ncsoft.com/en/jobs/arenanet.html">NCSoft Jobs page</a></li>
<li><a href="http://us.ncsoft.com/en/news/press-releases/index.html">Press Releases</a></li>
</ul>
<p>I certainly wasn&#8217;t looking forward to building parsers for the multiple different feed types that entails, but <a href="http://developer.yahoo.com/yql">YQL</a> came along and saved the day again. I only had to do simple things manually like make sure that Twitter links &amp; @username replies were properly wrappped in &lt;a&gt; tags. To keep from bashing on YQL every time the page is loaded it stores the transformed results of the updates for an hour in a local APC cache. This provided the best of both worlds and made caching super-easy.</p>
<p>The site itself was built using <a href="http://developer.yahoo.com/yui/grids/">YUI grids</a>, <a href="http://developer.yahoo.com/yui/3/">YUI 3b1</a>, and <a href="http://www.dillerdesign.com/experiment/DD_belatedPNG/">DD_belatedPNG</a> to solve transparent PNG issues in IE6. It&#8217;s also using my favorite new PHP framework, <a href="http://github.com/bastos/nicedog/">Nice Dog</a>. It&#8217;s a nano framework (about 100 lines) that is more of a VC than MVC. For a site like Arena.net it&#8217;s perfect as there&#8217;s no need for models. I could&#8217;ve plugged in an ORM to make it the full stack but when getting all your data is as simple as</p>
<p><code>apc_fetch($key);</code></p>
<p>the need to build a &#8220;proper&#8221; MVC site kinda isn&#8217;t there any longer.</p>
]]></content:encoded>
			<wfw:commentRss>http://patcavit.com/2009/09/18/arena-net/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>YUI Uploader Updated</title>
		<link>http://patcavit.com/2008/11/30/yui-uploader-updated/</link>
		<comments>http://patcavit.com/2008/11/30/yui-uploader-updated/#comments</comments>
		<pubDate>Sun, 30 Nov 2008 19:54:08 +0000</pubDate>
		<dc:creator>Pat Cavit</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tivac.com Projects]]></category>
		<category><![CDATA[YUI]]></category>

		<guid isPermaLink="false">http://patcavit.com/?p=212</guid>
		<description><![CDATA[The uploader I wrote and talked about in YUI Upload Implementation has been updated to work with YUI 2.6.0 and also with the new Flash security rules for browsing files. The changes were relatively minor, but here&#8217;s a quick explanation. A new element had to be added that could overlay the button that lets you [...]]]></description>
			<content:encoded><![CDATA[<p>The uploader I wrote and talked about in <a title="YUI Upload Implementation" href="http://patcavit.com/2008/03/01/yui-uploader-implementation/">YUI Upload Implementation</a> has been updated to work with YUI 2.6.0 and also with the new Flash security rules for browsing files. The changes were relatively minor, but here&#8217;s a quick explanation.</p>
<p>A new element had to be added that could overlay the button that lets you select files. Once the JS fires it makes that element the exact same size/position of the button you can see and then the YUI Upload fills that overlay with a flash object. While the button still exists when you click the event is actually captured by the flash object. This gets around the tighter flash security rules while not changing the upload experience at all. It&#8217;s not a perfect solution but at least the uploader works again.</p>
<p>Changed code looks like this in upload.js<br />
<code><br />
var button = YUD.getRegion('browse');<br />
var overlay = YUD.get('btn_overlay');<br />
YUD.setStyle(overlay, 'width', button.right - button.left + "px");<br />
YUD.setStyle(overlay, 'height', button.bottom - button.top + "px");<br />
YUD.setStyle(overlay, 'top', button.top + "px");<br />
YUD.setStyle(overlay, 'left', button.left + "px");<br />
this.uploader = new YAHOO.widget.Uploader('btn_overlay');</code></p>
<p>Updated uploader still lives at <a href="http://tivac.com/upload/">http://tivac.com/upload/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://patcavit.com/2008/11/30/yui-uploader-updated/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Tweaking the Image Uploader</title>
		<link>http://patcavit.com/2008/07/23/tweaking-the-image-uploader/</link>
		<comments>http://patcavit.com/2008/07/23/tweaking-the-image-uploader/#comments</comments>
		<pubDate>Thu, 24 Jul 2008 03:04:57 +0000</pubDate>
		<dc:creator>Pat Cavit</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[Demos]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tivac.com Projects]]></category>
		<category><![CDATA[YUI]]></category>

		<guid isPermaLink="false">http://patcavit.com/?p=192</guid>
		<description><![CDATA[For fun I went trolling through the images people have uploaded via the YUI Uploader implementation I wrote a while ago. When it took my browser a solid 30 seconds to even be remotely responsive and start rendering images it struck me that perhaps it was time to paginate the images instead of just dumping [...]]]></description>
			<content:encoded><![CDATA[<p>For fun I went trolling through the images people have uploaded via the <a title="YUI Upload Implementation" href="http://patcavit.com/2008/03/01/yui-uploader-implementation/">YUI Uploader implementation</a> I wrote a while ago. When it took my browser a solid 30 seconds to even be remotely responsive and start rendering images it struck me that perhaps it was time to paginate the images instead of just dumping them all out onto one page.</p>
<p>So I added pagination. It&#8217;s currently super simple which makes for easy explanation. The PHP still collects and sorts every single image in the directory by date. I don&#8217;t think there&#8217;s any other way to do that. Afterwards it checks to see if the &#8220;o&#8221; query param was set and is an integer (thanks for adding <a title="Filter Input PHP Man Page" href="http://www.php.net/manual/en/function.filter-input.php">filter_input</a> to PHP5, PHP devs!). Once there&#8217;s an offset to start from, it slices the array at that point and takes the next 50 images.</p>
<p>After that there&#8217;s just some simple logic around drawing the pagination numbers and figuring out which one is the current page. The numbers are centered and boxed using a variation on Hedger&#8217;s inline-block work (<a href="http://www.hedgerwow.com/360/dhtml/css-inline-block-layout.php">Item List Grid : Practice with display:inline block across browsers</a>) that I worked on for the next VYC release. It solves the problem with a minimum amount of code in a really semantic way that just makes my web developer brain as happy as can be. Granted the CSS is not what I would call &#8220;pretty&#8221; but it works everywhere and is not impossible to understand, so I&#8217;m not too bothered by it.</p>
<p>So here&#8217;s how it turned out. Be forewarned that I don&#8217;t control what is uploaded here, and as such there might be <strong>NSFW</strong> content on this page!</p>
<p><a title="Uploaded Images" href="http://tivac.com/upload/images/">http://tivac.com/upload/images/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://patcavit.com/2008/07/23/tweaking-the-image-uploader/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Xbox Live Friends Sidebar Gadget 1.1</title>
		<link>http://patcavit.com/2008/04/19/xbox-live-friends-sidebar-gadget-11/</link>
		<comments>http://patcavit.com/2008/04/19/xbox-live-friends-sidebar-gadget-11/#comments</comments>
		<pubDate>Sun, 20 Apr 2008 00:11:22 +0000</pubDate>
		<dc:creator>Pat Cavit</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[Gadgets]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[YUI]]></category>
		<category><![CDATA[xbox]]></category>

		<guid isPermaLink="false">http://patcavit.com/?p=189</guid>
		<description><![CDATA[I said I was working on it this morning, and I wasn&#8217;t even lying!  I&#8217;ve just updated the Xbox Live Friends Gadget to version 1.1 which brings with it almost everything I promised in the previous post! New Stuff! I&#8217;ve created an actual landing page for the gadget, http://patcavit.com/xbox-live-gadget/. There&#8217;s also a page helping people [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://patcavit.com/dev/gadgets/Xbox Live Friends.gadget"><img style="border-right: 0px; border-top: 0px; margin: 0px 0px 50px; border-left: 0px; border-bottom: 0px" src="http://patcavit.com/wp-content/uploads/2008/04/download-it.png" border="0" alt="Download the gadget" width="256" height="256" /></a></p>
<p>I said I was working on it this morning, and I wasn&#8217;t even lying!  I&#8217;ve just updated the Xbox Live Friends Gadget to version 1.1 which brings with it almost everything I promised in the <a href="http://patcavit.com/2008/04/19/closing-in-on-xbox-gadget-11/">previous post</a>!</p>
<h3>New Stuff!</h3>
<p>I&#8217;ve created an actual landing page for the gadget, <a title="http://patcavit.com/xbox-live-gadget/" href="http://patcavit.com/xbox-live-gadget/">http://patcavit.com/xbox-live-gadget/</a>. There&#8217;s also a page helping people copy gadgets from their old install to a new one, <a title="http://patcavit.com/xbox-live-gadget/how-to-update/" href="http://patcavit.com/xbox-live-gadget/how-to-update/">http://patcavit.com/xbox-live-gadget/how-to-update/</a>. Both of these pages need a lot of work but it&#8217;s a start. Had to learn a lot of wordpress knowledge I had long forgotten to be able to do that stuff!</p>
<p>So here&#8217;s what did end up making the cut for 1.1</p>
<ul>
<li>The backend web service caches results now, makes updating faster (but the data is no less fresh!)</li>
<li>Expanding in height was retarded, the guidelines were correct. To solve the problem of more than 5 online contacts without expanding there’s now pagination!</li>
<li>Undocked state exists now, might even be marginally useful.</li>
<li>Flyout has a link to open up xbox.com to send user a message over XBL</li>
<li>Error Handling for bad data from the WS</li>
<li>New background images, no longer quite so boring!</li>
<li>List updates are animated with a subtle fade effect. Probably needs more tweaking, but I think it makes a big difference.</li>
<li>Checks to make sure you have the latest version of the gadget and will nag you if not</li>
<li>(Online) Instructions for updating the gadget to save you from having to retype your friends list</li>
<li>(Online) Actual web page for the gadget to provide some useful info</li>
</ul>
<p>Unfortunately showing offline contacts didn&#8217;t make it. That task is quite a bit bigger than I originally though, but may still be coming down the pipe in a future update. There&#8217;s already a list of things I&#8217;m going to be working on next, so here&#8217;s a peek</p>
<ul>
<li>Show total count of online friends somewhere</li>
<li>Flyout wonkiness</li>
<li>Make flyout more useful (it&#8217;s getting there slowly!)</li>
<li>List update fades interfere with the hover effect. This will be amusing to fix, I just know it.</li>
</ul>
<p>So there&#8217;s still plenty for me to do and that was just after having one other person look at this. I&#8217;d love to get some feedback so I could keep working on this. After really getting into it I&#8217;m having a blast working with gadgets.</p>
<p>And now, <strong>pictures</strong>!</p>
<div id="scid:887EC618-8FBE-DEAD-BEEF-2339AF2EC721:1bf9e9b0-ab09-4378-a48b-d374f0fbf405" class="wlWriterSmartContent" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"><a title="Upgrade notification" rel="thumbnail" href="http://patcavit.com/wp-content/uploads/2008/04/upgrade-available-8x6.png"><img src="http://patcavit.com/wp-content/uploads/2008/04/upgrade-available.png" border="0" alt="" /></a></div>
<div id="scid:887EC618-8FBE-DEAD-BEEF-2339AF2EC721:bab44337-d0f3-4612-889b-39f9f2cbb8da" class="wlWriterSmartContent" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"><a title="Basic error handling" rel="thumbnail" href="http://patcavit.com/wp-content/uploads/2008/04/ws-error-8x6.png"><img src="http://patcavit.com/wp-content/uploads/2008/04/ws-error.png" border="0" alt="" /></a></div>
<div id="scid:887EC618-8FBE-DEAD-BEEF-2339AF2EC721:32f75cf1-1037-456c-8fcb-3944057d625e" class="wlWriterSmartContent" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"><a title="Send a message via flyout" rel="thumbnail" href="http://patcavit.com/wp-content/uploads/2008/04/new-flyout-8x6.png"><img src="http://patcavit.com/wp-content/uploads/2008/04/new-flyout.png" border="0" alt="" /></a></div>
]]></content:encoded>
			<wfw:commentRss>http://patcavit.com/2008/04/19/xbox-live-friends-sidebar-gadget-11/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Closing in on Xbox Gadget 1.1</title>
		<link>http://patcavit.com/2008/04/19/closing-in-on-xbox-gadget-11/</link>
		<comments>http://patcavit.com/2008/04/19/closing-in-on-xbox-gadget-11/#comments</comments>
		<pubDate>Sat, 19 Apr 2008 10:44:02 +0000</pubDate>
		<dc:creator>Pat Cavit</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[Gadgets]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[YUI]]></category>
		<category><![CDATA[xbox]]></category>

		<guid isPermaLink="false">http://patcavit.com/2008/04/19/closing-in-on-xbox-gadget-11/</guid>
		<description><![CDATA[I&#8217;ve been working on this off and on ever since releasing 1.0, I definitely feel like this is deserving of a whole tenth of a full version bump.&#160; Quick list of things that have changed so far off the top of my head. The backend web service caches results now, makes updating faster (but the [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been working on this off and on ever since releasing 1.0, I definitely feel like this is deserving of a whole tenth of a full version bump.&nbsp; Quick list of things that have changed so far off the top of my head.</p>
<ol>
<li>The backend web service caches results now, makes updating faster (but the data is no less fresh!)</li>
<li>Expanding in height was retarded, the guidelines were correct. To solve the problem of more than 5 online contacts without expanding there&#8217;s now pagination!</li>
<li>Undocked state exists now, might even be marginally useful.</li>
<li>Flyout has a link to open up xbox.com to send user a message over XBL</li>
<li>Error Handling for bad data from the WS</li>
<li>New background images, no longer quite so boring!</li>
<li>List updates are animated with a subtle fade effect. Probably needs more tweaking, but I think it makes a big difference.</li>
</ol>
<p>There&#8217;s still a few things left I want to do before making 1.1 official like update nagging and possibly adding a toggle to the settings page to show all your contacts and just filter it so that the only ones are a different color and show up first. Not sure about that one yet, but it&#8217;s a possibility.</p>
<p>Look, it&#8217;s a SCREENSHOT of the new stuff! Ok so mostly I wanted to play with a Windows Live Writer &#8220;Polariod Image&#8221; plugin, but it&#8217;s still a perfectly reasonable picture. I don&#8217;t feel bad for a second about posting it, so there!</p>
<p>
<div class="wlWriterSmartContent" id="scid:887EC618-8FBE-DEAD-BEEF-2339AF2EC721:dd547c69-2938-4795-b923-adac6156575e" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"><a href="http://patcavit.com/wp-content/uploads/2008/04/friends-gadget-11-undocked-8x6.png" title="New Undocked Mode" rel="thumbnail"><img border="0" src="http://patcavit.com/wp-content/uploads/2008/04/friends-gadget-11-undocked3.png" /></a></div>
</p>
<p>One last thing, I&#8217;ve given the gadget a &#8220;proper&#8221; home page at <a title="http://patcavit.com/xbox-live-gadget/" href="http://patcavit.com/xbox-live-gadget/">http://patcavit.com/xbox-live-gadget/</a> thanks to WordPress&#8217;s support for pages and custom templates.&nbsp; It took some hunting to figure out how to make a static page include a list of posts from a certain category, but <a title="http://www.transycan.net/blogtest/2007/09/10/static-frontpage-combined-with-dynamic-content/" href="http://www.transycan.net/blogtest/2007/09/10/static-frontpage-combined-with-dynamic-content/">http://www.transycan.net/blogtest/2007/09/10/static-frontpage-combined-with-dynamic-content/</a> was incredibly helpful in answering the questions I had.</p>
<p>Oh that reminds me I have to update the homepage in the gadget metadata&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://patcavit.com/2008/04/19/closing-in-on-xbox-gadget-11/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Xbox Live Friends Sidebar Gadget</title>
		<link>http://patcavit.com/2008/04/14/xbox-live-friends-sidebar-gadget/</link>
		<comments>http://patcavit.com/2008/04/14/xbox-live-friends-sidebar-gadget/#comments</comments>
		<pubDate>Mon, 14 Apr 2008 22:39:10 +0000</pubDate>
		<dc:creator>Pat Cavit</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[Gadgets]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[YUI]]></category>
		<category><![CDATA[xbox]]></category>

		<guid isPermaLink="false">http://patcavit.com/?p=172</guid>
		<description><![CDATA[What&#8217;s the problem? Knowing when my friends are online on Xbox Live has been a problem I&#8217;ve struggled with for years. When Microsoft announced the Xbox Community Developers program I thought I had found the answer. Then the recipients of the 50 API keys they gave out promptly made a bunch of websites I couldn&#8217;t [...]]]></description>
			<content:encoded><![CDATA[<h3>What&#8217;s the problem?</h3>
<p>Knowing when my friends are online on Xbox Live has been a problem I&#8217;ve struggled with for years. When Microsoft announced the Xbox Community Developers program I thought I had found the answer. Then the recipients of the 50 API keys they gave out promptly made a bunch of websites I couldn&#8217;t care less about&#8230;</p>
<p>Except for <a href="http://360voice.com">360voice.com</a> (&lt;3 their RSS feeds, I&#8217;m right <a href="http://www.360voice.com/tag/Tivac">here</a>). I really like the daily summaries that pop up into <a href="http://bloglines.com">Bloglines</a>, it&#8217;s cool knowing what games I should get so we can play more.</p>
<p>But even 360voice doesn&#8217;t handle the status info I was interested in. There&#8217;s no good way to have a list of my friends updating in the background so I can tell with a glance who is online and whether or not I should join them.  Plus there&#8217;s the hassle of actually getting someone else to sign up for it, so far I think all of 3 or so friends of mine are on there.</p>
<p>The other issue is one that isn&#8217;t anyone&#8217;s fault, per se. I don&#8217;t want to have to open a webpage to know who is online. The Xbox.com friends page is certainly easy to read, and it sticks all your friends at the top so you can scan it quickly. It still suffers from the fact that I have to actively go to it if I want to see who is online. I could hook up one of the Firefox extensions that checks a page for updates, but that still isn&#8217;t what I&#8217;m looking for.</p>
<h3>That sounds like it should work&#8230;</h3>
<p>So how do I get an unobtrusive, automatically updating list of my friends to sit on my desktop so I know at a glance who is online? Well I&#8217;m rocking Vista and dual-monitors, so I fired up the Sidebar and added the <a href="http://adamkinney.com/studios/xboxfriendswatch/"></a><a href="http://patcavit.com/wp-content/uploads/2008/04/xbox-friends-watch.png"><img style="border-right: 0px; border-top: 0px; margin: 10px 10px 0px 0px; border-left: 0px; border-bottom: 0px" src="http://patcavit.com/wp-content/uploads/2008/04/xbox-friends-watch-thumb.png" border="0" alt="Xbox Friends Watch" width="160" height="238" align="left" /></a>Xbox Friends Watch gadget. It&#8217;s doubly neat because it not only does what I want but it uses Silverlight so there&#8217;s lots of fancy animations and the like.</p>
<p>I was pretty happy with this solution for a while, but it&#8217;s still not quite right. Despite me having more than 5 friends on Xbox Live, I can&#8217;t get updates for them. The gadget will happily add them and even appears to render them on its list, but it doesn&#8217;t support scrolling of any sort. You can kinda mouseover the very bottom and see the highlight travel to the other people on your list, but you&#8217;ll never know if they are online or not. Adding gamertags to it wasn&#8217;t the easiest thing in the world either, as the settings dialog expects tags to be commas-separated , which I always found to be pretty clunky.</p>
<p>Like I mentioned, the hard limit of 5 gamertags wasn&#8217;t a huge issue for me and I was happily using the Xbox Friends Watch gadget for several months.  Eventually though I was having to swap people in and out of the list on a pretty regular basis, depending on which group of friend<a href="http://patcavit.com/wp-content/uploads/2008/04/xbox-friends-watch-config.png"><img style="border-right: 0px; border-top: 0px; margin: 15px 0px 5px 15px; border-left: 0px; border-bottom: 0px" src="http://patcavit.com/wp-content/uploads/2008/04/xbox-friends-watch-config-thumb.png" border="0" alt="Xbox Friends Watch Config" width="182" height="244" align="right" /></a>s I was going to try and play with next. It didn&#8217;t make sense to me that I would have to do that, so I went looking to see if there were any other options out there.</p>
<h3>Not quite, next!</h3>
<p>The closest I found was Duncan MacKenzie&#8217;s <a href="http://www.duncanmackenzie.net/blog/connect-your-xbox-360-gamertag-to-twitter/default.aspx">Xbox to Twitter</a> application. It&#8217;s very cool, and something I contemplated running for a while before deciding that I spammed Twitter (and Facebook, thanks to the Twitter App) and people probably wouldn&#8217;t care that much. Besides, I&#8217;m not looking for ways to broadcast to other people that I&#8217;m online, I want a way to keep tabs on my friends and know when they&#8217;re online.</p>
<p>So Xbox to Twitter wasn&#8217;t what I needed, but it did get me the hook I needed to be able to solve my problem. As part of his twitter app Duncan also put up a Webservice API you can hit to get Xbox status info for a gamertag. Even better, he put up a REST version of it that you can hit using plain old HTTP. It&#8217;s super simple, check this out:</p>
<p><a title="http://duncanmackenzie.net/services/GetXboxInfo.aspx?GamerTag=Tivac" href="http://duncanmackenzie.net/services/GetXboxInfo.aspx?GamerTag=Tivac">http://duncanmackenzie.net/services/GetXboxInfo.aspx?GamerTag=Tivac</a></p>
<div class="csharpcode">
<pre class="alt"><span class="kwrd">&lt;?</span><span class="html">xml</span> <span class="attr">version</span><span class="kwrd">="1.0"</span>?<span class="kwrd">&gt;</span></pre>
<pre><span class="kwrd">&lt;</span><span class="html">XboxInfo</span> <span class="attr">xmlns:xsi</span><span class="kwrd">=<a href="http://www.w3.org/2001/XMLSchema-instance">http://www.w3.org/2001/XMLSchema-instance</a></span></pre>
<pre><span class="attr">xmlns:xsd</span><span class="kwrd">="http://www.w3.org/2001/XMLSchema"</span><span class="kwrd">&gt;</span></pre>
<pre class="alt">  <span class="kwrd">&lt;</span><span class="html">AccountStatus</span><span class="kwrd">&gt;</span>Gold<span class="kwrd">&lt;/</span><span class="html">AccountStatus</span><span class="kwrd">&gt;</span></pre>
<pre>  <span class="kwrd">&lt;</span><span class="html">PresenceInfo</span><span class="kwrd">&gt;</span></pre>
<pre class="alt">    <span class="kwrd">&lt;</span><span class="html">Valid</span><span class="kwrd">&gt;</span>true<span class="kwrd">&lt;/</span><span class="html">Valid</span><span class="kwrd">&gt;</span></pre>
<pre>    <span class="kwrd">&lt;</span><span class="html">Info</span><span class="kwrd">&gt;</span>Last seen 58 minutes ago<span class="kwrd">&lt;/</span><span class="html">Info</span><span class="kwrd">&gt;</span></pre>
<pre class="alt">    <span class="kwrd">&lt;</span><span class="html">Info2</span> <span class="kwrd">/&gt;</span></pre>
<pre>    <span class="kwrd">&lt;</span><span class="html">LastSeen</span><span class="kwrd">&gt;</span>2008-04-14T15:42:05-05:00<span class="kwrd">&lt;/</span><span class="html">LastSeen</span><span class="kwrd">&gt;</span></pre>
<pre class="alt">    <span class="kwrd">&lt;</span><span class="html">Online</span><span class="kwrd">&gt;</span>false<span class="kwrd">&lt;/</span><span class="html">Online</span><span class="kwrd">&gt;</span></pre>
<pre>    <span class="kwrd">&lt;</span><span class="html">StatusText</span><span class="kwrd">&gt;</span>Offline<span class="kwrd">&lt;/</span><span class="html">StatusText</span><span class="kwrd">&gt;</span></pre>
<pre class="alt">    <span class="kwrd">&lt;</span><span class="html">Title</span><span class="kwrd">&gt;</span>www.xbox.com<span class="kwrd">&lt;/</span><span class="html">Title</span><span class="kwrd">&gt;</span></pre>
<pre>  <span class="kwrd">&lt;/</span><span class="html">PresenceInfo</span><span class="kwrd">&gt;</span></pre>
<pre class="alt">  <span class="kwrd">&lt;</span><span class="html">State</span><span class="kwrd">&gt;</span>Valid<span class="kwrd">&lt;/</span><span class="html">State</span><span class="kwrd">&gt;</span></pre>
<pre>  <span class="kwrd">&lt;</span><span class="html">Gamertag</span><span class="kwrd">&gt;</span>tivac<span class="kwrd">&lt;/</span><span class="html">Gamertag</span><span class="kwrd">&gt;</span></pre>
<pre class="alt">  <span class="kwrd">&lt;</span><span class="html">ProfileUrl</span><span class="kwrd">&gt;</span>http://live.xbox.com/member/tivac<span class="kwrd">&lt;/</span><span class="html">ProfileUrl</span><span class="kwrd">&gt;</span></pre>
<pre>  <span class="kwrd">&lt;</span><span class="html">TileUrl</span><span class="kwrd">&gt;</span>http://tiles.xbox.com/ti...8M6cr.jpg<span class="kwrd">&lt;/</span><span class="html">TileUrl</span><span class="kwrd">&gt;</span></pre>
<pre class="alt">  <span class="kwrd">&lt;</span><span class="html">Country</span><span class="kwrd">&gt;</span>United States<span class="kwrd">&lt;/</span><span class="html">Country</span><span class="kwrd">&gt;</span></pre>
<pre>  <span class="kwrd">&lt;</span><span class="html">Reputation</span><span class="kwrd">&gt;</span>99.98135<span class="kwrd">&lt;/</span><span class="html">Reputation</span><span class="kwrd">&gt;</span></pre>
<pre class="alt">  <span class="kwrd">&lt;</span><span class="html">ReputationImageUrl</span><span class="kwrd">&gt;</span>http://live.xbox.com/xweb/...gif<span class="kwrd">&lt;/</span><span class="html">ReputationImageUrl</span><span class="kwrd">&gt;</span></pre>
<pre>  <span class="kwrd">&lt;</span><span class="html">GamerScore</span><span class="kwrd">&gt;</span>12860<span class="kwrd">&lt;/</span><span class="html">GamerScore</span><span class="kwrd">&gt;</span></pre>
<pre>  <span class="kwrd">&lt;</span><span class="html">Zone</span><span class="kwrd">&gt;</span>Recreation<span class="kwrd">&lt;/</span><span class="html">Zone</span><span class="kwrd">&gt;</span></pre>
<pre class="alt">  <span class="kwrd">&lt;</span><span class="html">RecentGames</span><span class="kwrd">&gt;</span></pre>
<pre>    <span class="kwrd">&lt;</span><span class="html">XboxUserGameInfo</span><span class="kwrd">&gt;</span></pre>
<pre class="alt">      <span class="kwrd">&lt;</span><span class="html">Game</span><span class="kwrd">&gt;</span></pre>
<pre>        <span class="kwrd">&lt;</span><span class="html">Name</span><span class="kwrd">&gt;</span>Halo 3<span class="kwrd">&lt;/</span><span class="html">Name</span><span class="kwrd">&gt;</span></pre>
<pre class="alt">        <span class="kwrd">&lt;</span><span class="html">TotalAchievements</span><span class="kwrd">&gt;</span>49<span class="kwrd">&lt;/</span><span class="html">TotalAchievements</span><span class="kwrd">&gt;</span></pre>
<pre>        <span class="kwrd">&lt;</span><span class="html">TotalGamerScore</span><span class="kwrd">&gt;</span>1000<span class="kwrd">&lt;/</span><span class="html">TotalGamerScore</span><span class="kwrd">&gt;</span></pre>
<pre class="alt">        <span class="kwrd">&lt;</span><span class="html">Image32Url</span><span class="kwrd">&gt;</span>http://tiles.xbox.com/tiles/oo/P5/0...<span class="kwrd">&lt;/</span><span class="html">Image32Url</span><span class="kwrd">&gt;</span></pre>
<pre>        <span class="kwrd">&lt;</span><span class="html">Image64Url</span><span class="kwrd">&gt;</span>http://tiles.xbox.com/tiles/zS/3N/1W....jpg<span class="kwrd">&lt;/</span><span class="html">Image64Url</span><span class="kwrd">&gt;</span></pre>
<pre class="alt">      <span class="kwrd">&lt;/</span><span class="html">Game</span><span class="kwrd">&gt;</span></pre>
<pre>      <span class="kwrd">&lt;</span><span class="html">LastPlayed</span><span class="kwrd">&gt;</span>2008-04-10T00:25:48-05:00<span class="kwrd">&lt;/</span><span class="html">LastPlayed</span><span class="kwrd">&gt;</span></pre>
<pre class="alt">      <span class="kwrd">&lt;</span><span class="html">Achievements</span><span class="kwrd">&gt;</span>25<span class="kwrd">&lt;/</span><span class="html">Achievements</span><span class="kwrd">&gt;</span></pre>
<pre>      <span class="kwrd">&lt;</span><span class="html">GamerScore</span><span class="kwrd">&gt;</span>770<span class="kwrd">&lt;/</span><span class="html">GamerScore</span><span class="kwrd">&gt;</span></pre>
<pre class="alt">      <span class="kwrd">&lt;</span><span class="html">DetailsURL</span><span class="kwrd">&gt;</span>http://live.xbox.com/en-...o=tivac<span class="kwrd">&lt;/</span><span class="html">DetailsURL</span><span class="kwrd">&gt;</span></pre>
<pre>    <span class="kwrd">&lt;/</span><span class="html">XboxUserGameInfo</span><span class="kwrd">&gt;</span></pre>
<pre class="alt">    ...</pre>
<pre>  <span class="kwrd">&lt;/</span><span class="html">RecentGames</span><span class="kwrd">&gt;</span></pre>
<pre class="alt"><span class="kwrd">&lt;/</span><span class="html">XboxInfo</span><span class="kwrd">&gt;</span></pre>
</div>
<p>A little hard to parse in this format, I know. Hitting that URL in your browser will make it easier to understand though. I also shortened all the URLs and removed a the previous 9 games I had played because honestly, it&#8217;s not <strong>that</strong> interesting and it makes the XML way longer.</p>
<p>This is it though, the data that I needed to solve the problem of &#8220;I want to know what friends are on Xbox Live&#8221; (at least for me!). All I needed to do was to figure out how to use that info. Reaching back into the depths of my memory I recalled my previous attempt at building sidebar gadgets (<a title="http://patcavit.com/2007/05/04/vista-gadget-headaches/" href="http://patcavit.com/2007/05/04/vista-gadget-headaches/">http://patcavit.com/2007/05/04/vista-gadget-headaches/</a>) and how I in fact had tried to build this very gadget once before. Except it failed horribly because I couldn&#8217;t automate a Windows Live login. Well wonder of wonders, with this API I don&#8217;t have to!</p>
<h3>Finally, some progress!</h3>
<p>So after a few days of hacking in JavaScript and PHP I&#8217;ve got a sidebar gadget that takes a list of Xbox gamertags and will update to let you know when any of them are online. It even uses the cool <a href="http://blogs.msdn.com/sidebar/archive/2006/09/21/765604.aspx">Gadget Persistent Storage</a> library to store your list of gamertags when you remove and re-add the gadget. A lot of this is powered by a small subset of <a href="http://developer.yahoo.com/yui">YUI</a> because programming JS without it is too painful. Specifically I&#8217;m using <a href="http://developer.yahoo.com/yui/reset/">Reset</a>, <a href="http://developer.yahoo.com/yui/dom/">DOM</a>, <a href="http://developer.yahoo.com/yui/event/">Event</a>, <a href="http://developer.yahoo.com/yui/json/">JSON</a> &amp; <a href="http://developer.yahoo.com/yui/connection/">Connection</a>.</p>
<p>There are of course some caveats to this, but there always are.</p>
<p>Getting a list of gamertags isn&#8217;t automated. I&#8217;m not even sure the people who have direct access to the Xbox Community Developers Program ever got this capability. I doubt it. It means that for now you&#8217;ll still need to input a bunch of gamertags by hand. Fortunately this list is newline separated, so it&#8217;s very quick to add a bunch of them. I&#8217;ve got some stub code in there to parse it from a copy/paste of your <a href="http://live.xbox.com/en-US/profile/Friends.aspx?WT.svl=nav">Xbox.com friends management page</a>, but it isn&#8217;t ready for anyone to actually use yet.</p>
<ol>
<li>It violates Microsoft&#8217;s <a href="http://msdn2.microsoft.com/en-us/library/aa974179.aspx">Gadget UI Guidelines</a>, in that gadgets shouldn&#8217;t change size on anything other than a click. Mine does automatically depending on the number of people online. It could even conceivably become taller than your monitor. Microsoft is definitely right about this and I think it sucks, but I didn&#8217;t figure out a clean way of paginating the data that could stand. This is something I&#8217;m going to work on in the future, but for now it&#8217;s crappy.</li>
<li>There&#8217;s no undocked state. More accurately, it&#8217;s the exact same docked to the sidebar and undocked. Ideally it would expand a bit to shower bigger icons, larger text, and gamerscore (at a minimum) when you undocked the gadget. That&#8217;s on the list of things I&#8217;d like to do someday, but since I never use the gadget undocked is pretty low priority.</li>
<li>There&#8217;s still some weird behaviors. Here&#8217;s the ones I know about.
<ol>
<li>Sometimes the requests to the server for user info just take forever and return empty.</li>
<li>Opening a new flyout when there&#8217;s already one open causes the flyout to lose focus until you click on it. This appears to be a Sidebar/Gadgets limitation so it&#8217;s unlikely to be fixed.</li>
</ol>
</li>
</ol>
<p>Still, it works like I need it to which is really the only important thing! I&#8217;d love to have some other people use it and give me feedback though. I&#8217;m always down for hearing about bugs as well, though no promises that they will be something easily fixable.</p>
<p>It&#8217;s not the prettiest thing in the world, I&#8217;ve modelled it after <a href="http://live.xbox.com/en-US/profile/Friends.aspx?WT.svl=nav">xbox.com</a> and the flyout details are powered by the <a href="http://www.xbox.com/en-US/MyXbox/embedgamercard.htm">Embeddable Gamercards</a> offered on xbox.com.  Here&#8217;s an example of the what those look like</p>
<p>Put your gamertag here too.</p>
<p>It&#8217;s lazy but it gets the data I want in there without a lot of hassle on my part. In the future I would like to have a nicer flyout more akin to what Xbox Friends Watch has. Unfortunately, that&#8217;ll be a a good chunk of work to get the interactions right so that&#8217;s a challenge I&#8217;m putting off for another day. I don&#8217;t even really use the flyouts in my day to day gadget usage, but it&#8217;s nice to be able to interact and get a bit more information.</p>
<p>As usual I&#8217;ve written way too much and not posted enough links to just get the damn thing, so here you go!</p>
<p><strong><a href="http://patcavit.com/dev/gadgets/Xbox Live Friends.gadget">Xbox Live Friends Gadget 1.0</a></strong></p>
]]></content:encoded>
			<wfw:commentRss>http://patcavit.com/2008/04/14/xbox-live-friends-sidebar-gadget/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>YUI Uploader Implementation</title>
		<link>http://patcavit.com/2008/03/01/yui-uploader-implementation/</link>
		<comments>http://patcavit.com/2008/03/01/yui-uploader-implementation/#comments</comments>
		<pubDate>Sat, 01 Mar 2008 20:26:24 +0000</pubDate>
		<dc:creator>Pat Cavit</dc:creator>
				<category><![CDATA[Demos]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tivac.com Projects]]></category>
		<category><![CDATA[YUI]]></category>
		<category><![CDATA[Yahoo!]]></category>

		<guid isPermaLink="false">http://patcavit.com/2008/03/01/yui-uploader-implementation/</guid>
		<description><![CDATA[Image Uploading using YUI Uploader Widget A few days ago the YUI team released the latest and greatest version of the YUI Library, YUI 2.5.0. Along with the usual round of bugfixes and speed improvements this release came with several new components. I personally was the most excited about the Uploader component, as the technology [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://tivac.com/upload/"><strong>Image Uploading using YUI Uploader Widget</strong></a></p>
<p>A few days ago the YUI team released the latest and greatest version of the YUI Library, <a href="http://yuiblog.com/blog/2008/02/20/yui-250-released/">YUI 2.5.0</a>. Along with the usual round of bugfixes and speed improvements this release came with several new components. I personally was the most excited about the <a href="http://developer.yahoo.com/yui/uploader/" title="YUI Uploader Docs" target="_blank">Uploader</a> component, as the technology that powers it also underpins the upload process on <a href="http://video.yahoo.com" title="Yahoo! Video" target="_blank">Yahoo! Video</a>. I didn&#8217;t write the upload pages but I&#8217;m expected to be able to provide bugfixes and enhancements to those pages, so what better way to learn how they work than from the ground up with the Uploader?</p>
<p>Yes, I know there&#8217;s quite a few better ways. This was the most fun sounding way. What can I say, I like 4 day projects in my spare time instead of just reading the existing code. Besides, I wanted a better understanding of it from a lower level than just how the upload code on VYC works.</p>
<p>As mentioned in the YUI Blog posting about 2.5.0, the Uploader is what not only powers <abbr title="video.yahoo.com">VYC</abbr> uploads but Flickr uploads as well. Flickr exposes more of it due to their allowing of multiple files uploaded at once. That&#8217;s not really very easy to do on VYC due to the <strong>much</strong> larger file sizes being used. Still, it&#8217;s there.  I promise.</p>
<p>I&#8217;ve had a free-for-all, open to anyone image uploader chilling out for quite some time at <a href="http://tivac.com/upload/">http://tivac.com/upload/</a>. I wrote it to solve a problem, namely <a href="http://imageshack.us">the</a> other image uploading services available at the time sucked. It was just a quick little thing, with some basic JS that would hide the form element and create a new one so you could upload more than one file at a time.  When you were done it would barf out thumbs of the images along with some common types of link code for forums and the like.  Nothing fancy at all. Well, the new YUI Uploader seemed pretty much tailor-made to work instead of creating new form elements.</p>
<p>Here&#8217;s a good representation of my thought process while I contemplated redoing the image uploader.</p>
<table border="1" cellpadding="2" cellspacing="0" width="700">
<tr>
<th valign="top" width="155">Method</th>
<th valign="top" width="125">Select multiple files from one dialog?</th>
<th valign="top" width="139">Progress feedback available for updating the UI?</th>
<th valign="top" width="139">Smart enough to not totally hose the browser while uploading?</th>
<th valign="top" width="140">Able to dynamically update UI on completion?</th>
</tr>
<tr>
<td valign="top" width="155">Form + JS</td>
<td valign="top" width="125">No</td>
<td valign="top" width="138">No</td>
<td valign="top" width="139">No</td>
<td valign="top" width="141">Sorta</td>
</tr>
<tr>
<td valign="top" width="154">Uploader + JS</td>
<td valign="top" width="125"><strong>Yes</strong></td>
<td valign="top" width="139"><strong>Yes</strong></td>
<td valign="top" width="139"><strong>Yes</strong></td>
<td valign="top" width="142"><strong>Yes</strong></td>
</tr>
</table>
<p>I think that paints a pretty compelling picture of why I&#8217;d go with the YUI lib over the original solution. Aside from requiring Flash 9 and not working on the latest OSX because Adobe and Apple are feuding, there&#8217;s really no downside.  It&#8217;s provably better in every way. Since this is just a junky little personal project and not something important, I don&#8217;t even provide a fallback HTML form any more.  That&#8217;s just how I roll.</p>
<p>Actual implementation was pretty basic. The YUI documentation is excellent as always.  It more or less started life out as a copy of their <a href="http://developer.yahoo.com/yui/examples/uploader/uploader-simple.html">Simple Upload Example</a> and then I hacked the crap out of it. The flow ended up being something along the lines of the following.</p>
<ol>
<li>Browse for image files.<br />
<a href="http://patcavit.com/wp-content/uploads/2008/03/upload-step-1.png"><img src="http://patcavit.com/wp-content/uploads/2008/03/upload-step-1-thumb.png" style="border-width: 0px" alt="upload step 1" border="0" height="71" width="244" /></a></li>
<li>If you selected one you don&#8217;t actually want to upload, clicking it&#8217;s filename will remove it.<br />
<a href="http://patcavit.com/wp-content/uploads/2008/03/upload-step-2.png"><img src="http://patcavit.com/wp-content/uploads/2008/03/upload-step-2-thumb.png" style="border-width: 0px" alt="upload step 2" border="0" height="112" width="244" /></a></li>
<li>Upload the files, watch all the fun progress bars whiz around.<br />
<a href="http://patcavit.com/wp-content/uploads/2008/03/upload-step-3.png"><img src="http://patcavit.com/wp-content/uploads/2008/03/upload-step-3-thumb.png" style="border-width: 0px" alt="upload step 3" border="0" height="100" width="244" /></a></li>
<li>As each file completes, its filename is replaced with a thumbnail and various different pre-filled link codes for HTML and forums.<br />
<a href="http://patcavit.com/wp-content/uploads/2008/03/upload-step-4.png"><img src="http://patcavit.com/wp-content/uploads/2008/03/upload-step-4-thumb.png" style="border-width: 0px" alt="upload step 4" border="0" height="244" width="218" /></a></li>
<li>You can also hit the Export button to just get a list of the URLs of the uploaded images.<br />
<a href="http://patcavit.com/wp-content/uploads/2008/03/upload-step-5.png"><img src="http://patcavit.com/wp-content/uploads/2008/03/upload-step-5-thumb.png" style="border-width: 0px" alt="upload step 5" border="0" height="70" width="244" /></a></li>
</ol>
<p>It sounds complicated because I&#8217;m an engineer and don&#8217;t explain things well.  The cool nerdy thing about this is how very event-driven it is.  For example, take a look at this code chunk.</p>
<p class="csharpcode">&nbsp;</p>
<pre class="alt"><span class="rem">//certain things can only happen once the SWF is ready to rock</span></pre>
<pre><span class="kwrd">this</span>.uploader.addListener(<span class="str">'contentReady'</span>,   <span class="kwrd">this</span>.swfReady);</pre>
<pre class="alt"><span class="rem">//event handlers</span></pre>
<pre><span class="kwrd">this</span>.uploader.addListener(<span class="str">'fileSelect'</span>,         <span class="kwrd">this</span>.onFileSelect);</pre>
<pre class="alt"><span class="kwrd">this</span>.uploader.addListener(<span class="str">'uploadStart'</span>,        <span class="kwrd">this</span>.onUploadStart);</pre>
<pre><span class="kwrd">this</span>.uploader.addListener(<span class="str">'uploadError'</span>,        <span class="kwrd">this</span>.onUploadError);</pre>
<pre class="alt"><span class="kwrd">this</span>.uploader.addListener(<span class="str">'uploadProgress'</span>,     <span class="kwrd">this</span>.onUploadProgress);</pre>
<pre><span class="kwrd">this</span>.uploader.addListener(<span class="str">'uploadCancel'</span>,       <span class="kwrd">this</span>.onUploadCancel);</pre>
<pre class="alt"><span class="kwrd">this</span>.uploader.addListener(<span class="str">'uploadComplete'</span>,     <span class="kwrd">this</span>.onUploadComplete);</pre>
<pre><span class="kwrd">this</span>.uploader.addListener(<span class="str">'uploadCompleteData'</span>, <span class="kwrd">this</span>.onUploadCompleteData);</pre>
<style type="text/css">.csharpcode, .csharpcode pre { 	font-size: small; 	color: black; 	font-family: consolas, "Courier New", courier, monospace; 	background-color: #ffffff; 	/*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt  { 	background-color: #f4f4f4; 	width: 100%; 	margin: 0em; } .csharpcode .lnum { color: #606060; } </style>
<p>There&#8217;s an event fired by the flash object for pretty much everything you could want.  The only event I found myself wishing it supported was a &#8220;allUploadsComplete&#8221; method.  As it was I had to create a cache of all the file ids being uploaded, and in my handler for uploadComplete I would remove each id from the cache.  If there&#8217;s no more files left to upload, hey presto we&#8217;re done! A little roundabout, especially when having to watch out for files that were selected and then removed.</p>
<p>The other fun thing I decided upon was that instead of using innerHTML and getting back big chunks of HTML from the server (wrapped in JSON, of course) I&#8217;d instead use skeleton structures hidden in the DOM.  A quick</p>
<pre class="csharpcode">YUD.get(<span class="str">'upload_skeleton'</span>).cloneNode(<span class="kwrd">true</span>);</pre>
<style type="text/css">.csharpcode, .csharpcode pre { 	font-size: small; 	color: black; 	font-family: consolas, "Courier New", courier, monospace; 	background-color: #ffffff; 	/*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt  { 	background-color: #f4f4f4; 	width: 100%; 	margin: 0em; } .csharpcode .lnum { color: #606060; } </style>
<p>and you&#8217;ve got yourself a nice chunk of HTML just waiting for some delicious data to be inserted.  The actual insertion is pretty boring DOM traversals, but by using a skeleton as the base it avoids heavy node creation/appending or a massive innerHTML dump.  The page&#8217;s DOM is a little heavier because it contains these stubs, but there&#8217;s only two of them and page weight isn&#8217;t a big concern for this project.</p>
<p>The progress meters are basically a total ripoff of Flickr, I feel a little bad about it but I really liked their approach of using a background image and just changing the x offset each time uploadProgress was called. It&#8217;s so simple and to the point that I didn&#8217;t see any reason to make it more complicated.</p>
<p>So that all works fine, but I was worried that if I didn&#8217;t copy the URLs correctly right away the images would be lost forever. That meant that I had to write a little PHP script that would output linked thumbs of all the images that had been uploaded.  Since this is a totally unrestricted image uploader there&#8217;s been a few instances of people uploading porn and the like. I&#8217;d rather not deal with that, so there&#8217;s a little delete script as well. It&#8217;s protected by a .htaccess/.htpasswd basic auth setup.  Nothing fancy, but it keeps other people from being able to delete my images.</p>
<p><a href="http://patcavit.com/wp-content/uploads/2008/03/image-browser.png"><img src="http://patcavit.com/wp-content/uploads/2008/03/image-browser-thumb.png" style="border-width: 0px" alt="image browser" border="0" height="266" width="314" /></a></p>
<p>The images are laid out in a big floating grid using <a href="http://hedgerwow.com">Hedger&#8217;s</a> very awesome work on getting display: inline-block to work across browsers. <a href="http://www.hedgerwow.com/360/dhtml/css-inline-block-layout.php">Item List Grid : Practice with display:inline block across browsers</a>. It&#8217;s a technique we also used extensively on <abbr title="video.yahoo.com">VYC</abbr> so it was the first thing that came to mind when just floating a bunch of images that weren&#8217;t the same height went all crazy.</p>
<p>Oh, right.  All the icons are the insanely awesome work of <a href="http://famfamfam.com/">Mark James</a>, specifically his <a href="http://famfamfam.com/lab/icons/silk/">Silk</a> set of icons. I&#8217;m sure you&#8217;ve seen them used pretty much everywhere.  There&#8217;s a good reason for that, they rock.</p>
<p>I&#8217;ve zipped up the source for anyone who wants it, it&#8217;s all pretty well-commented.  You will have to handle the file permissions yourself though. <strong>UPDATE: </strong><a href="http://sitzmar.com">Sitzmar</a> wanted me to point out that all the paths are hard-coded for my uploader.  He says I should be ashamed, I say he should shut up.  Also I don&#8217;t think I included the .htpasswd (obviously) or the .htaccess.  Those are easily set up, a quick search on the internet will answer all questions.</p>
<p><a href="http://tivac.com/upload/upload.zip">upload.zip</a></p>
]]></content:encoded>
			<wfw:commentRss>http://patcavit.com/2008/03/01/yui-uploader-implementation/feed/</wfw:commentRss>
		<slash:comments>21</slash:comments>
		</item>
	</channel>
</rss>
