<?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; JavaScript</title>
	<atom:link href="http://patcavit.com/category/javascript/feed/" rel="self" type="application/rss+xml" />
	<link>http://patcavit.com</link>
	<description>I &#60;3 Programming</description>
	<lastBuildDate>Mon, 16 May 2011 16:11:26 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.3</generator>
		<item>
		<title>YUI 3 Quick Tip: Conditionally load dataURI&#8217;d CSS or MHTML</title>
		<link>http://patcavit.com/2010/11/12/yui-3-quick-tip-conditionally-load-dataurid-css-or-mhtml/</link>
		<comments>http://patcavit.com/2010/11/12/yui-3-quick-tip-conditionally-load-dataurid-css-or-mhtml/#comments</comments>
		<pubDate>Fri, 12 Nov 2010 22:35:14 +0000</pubDate>
		<dc:creator>Pat Cavit</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Quick Tips]]></category>
		<category><![CDATA[Work]]></category>
		<category><![CDATA[YUI]]></category>

		<guid isPermaLink="false">http://patcavit.com/?p=322</guid>
		<description><![CDATA[If you&#8217;re already using the YUI 3 Loader to load some of your CSS like I do for some sites this can come in really handy. You could also do this via conditional comments, but you can&#8217;t control when the load happens in that case. The trick is to define the trigger for the MHTML [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re already using the <a href="http://developer.yahoo.com/yui/3/yui/#loader" target="_blank">YUI 3 Loader</a> to load some of your CSS like I do for <a title="GW2 Hall of Monuments" href="http://hom.guildwars2.com/" target="_blank">some sites</a> this can come in really handy. You could also do this via conditional comments, but you can&#8217;t control when the load happens in that case.</p>
<p>The trick is to define the trigger for the MHTML module to trigger off of the regular module, &amp; also make sure that the MHTML module will supersede the regular one. Then, it&#8217;s a simple matter of setting up either the simple UA check or a test function that returns <em>true</em>/false.</p>
<p><script src="https://gist.github.com/674804.js"> </script></p>
<p>Note the <em>when</em> config setting&#8217;s value of &#8220;instead&#8221; that specifies that this module should replace &#8220;icons-css&#8221;. That only happens if the test function returns true, indicating hte module should be loaded. Since IE 8+ supports dataURIs, we return true only if running IE 7 or lower which causes the &#8220;icons-css&#8221; module to be replaced by &#8220;icons-css-mhtml&#8221;.</p>
<p>It&#8217;s a neat trick, huge thanks to Adam Moore of the YUI team for teaching me about it on the forums! Also thanks to <a href="http://www.nczonline.net/">Nicholas Zakas</a> for creating <a href="https://github.com/nzakas/cssembed/wiki" target="_blank">CSSEmbed</a> (also <a href="http://www.nczonline.net/blog/2009/11/03/automatic-data-uri-embedding-in-css-files/" target="_blank">here</a>), the tool that makes generating DataURI &amp; MHTML versions of a stylesheet ridiculously easy. <a href="http://www.phpied.com/" target="_blank">Stoyan Stefanov</a> gets a mention here too because of his <a href="http://www.phpied.com/the-proper-mhtml-syntax/" target="_blank">awesome</a> <a href="http://www.phpied.com/mhtml-when-you-need-data-uris-in-ie7-and-under/">DataURI/MHTML</a> <a href="http://www.phpied.com/data-uris-mhtml-ie7-win7-vista-blues/">research</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://patcavit.com/2010/11/12/yui-3-quick-tip-conditionally-load-dataurid-css-or-mhtml/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<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[Yahoo!]]></category>
		<category><![CDATA[YUI]]></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>
<pre lang="html4strict"><script src="http://yui.yahooapis.com/combo?3.1.1/build/yui/yui.js&amp;3.1.1/build/loader/loader.js"><!--mce:0--></script></pre>
<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>
<pre lang="javascript">YUI.add('basic-plugin', function(Y) {
    /* Plugin code here */
}, "0.1", { requires : [ "base", "plugin", "node" ] });</pre>
<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>
<pre lang="javascript">Y.namespace('Examples').BasicPlugin = Y.Base.create("BasicPlugin", Y.Plugin.Base, [], { ... }, { ... });</pre>
<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>
<pre lang="javascript">Y.Base.create(..., ..., [], {
    _handle : null,
    initializer : function() { ... },
    destructor : function() { ... }
}, { ... });</pre>
<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>
<pre lang="javascript">this._handle = this.get("host").on("click", function(e) {
    var tgt = e.currentTarget,
        color = this.get("color");

    this.set("color", tgt.getStyle("backgroundColor"));

    tgt.setStyle("background", color);
}, this);</pre>
<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>
<pre lang="javascript">destructor : function() {
    this._handle.detach();

    this._handle = null;
}</pre>
<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>
<pre lang="javascript">Y.Base.create(..., ..., {}, {...}, {
    NS : "sp",
    ATTRS : {
        color : { value : "blue" }
    }
});</pre>
<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>
<pre lang="javascript">YUI().use("node", "basic-plugin", function(Y) { ... });</pre>
<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>
<pre lang="javascript">Y.one("#wooga").plug(Y.Examples.BasicPlugin);</pre>
<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>
<pre lang="javascript">Y.one("#booga").plug(Y.Examples.BasicPlugin, { color : "#666" });</pre>
<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>
<pre lang="javascript">Y.one("#wooga").unplug(Y.Examples.BasicPlugin);</pre>
<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>
<pre lang="javascript">//create the module
YUI.add('basic-plugin', function(Y) {
    //create namespaced plugin class
    Y.namespace('Examples').BasicPlugin = Y.Base.create("BasicPlugin", Y.Plugin.Base, [], {

        _handle : null,

        //constructor
        initializer : function() {
            this._handle = this.get("host").on("click", function(e) {
                var tgt = e.currentTarget,
                    color = this.get("color");

                this.set("color", tgt.getStyle("backgroundColor"));

                tgt.setStyle("background", color);
            }, this);
        },

        //clean up on destruction
        destructor : function() {
            this._handle.detach();

            this._handle = null;
        }
    },
    {
        NS : "bp",
        ATTRS : {
            color : { value : "#00F" }
        }
    });
}, "0.1", { requires : [ "base", "plugin", "node" ] });

YUI().use("node", "basic-plugin", function(Y) {
    Y.one("#wooga").plug(Y.Examples.BasicPlugin);
    Y.one("#booga").plug(Y.Examples.BasicPlugin, { color : "#666" });
});</pre>
<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[Yahoo!]]></category>
		<category><![CDATA[YUI]]></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>
<pre lang="javascript">//DEV CONFIG
YUI_config = {
    //yes this is a little gross but sadly it's necessary to make loader work how we want w/ ant
    /* dev */ ignore : [ "sidebar-rollup" ], //dev */
    /* live ignore : [ "chiclet", "slider-plugin" ], //live */
    groups : {
        anet : {
            combine : false,
            base : "/blog/wp-content/themes/arenanet/js/lib/",
            modules : {
                "chiclet" : {
                    path : "chiclet.js",
                    skinnable: false,
                    requires : [ "base", "widget", "anim-base", "anim-easing", "sidebar-rollup" ]
                },

                "slider-plugin" : {
                    path : "slider.js",
                    requires : ["plugin", "node", "anim-base", "anim-easing", "sidebar-rollup" ]
                },

                "gallery-lightbox" : {
                    path : "lightbox.js",
                    requires : ["base", "node", "anim-base", "selector-css3"]
                },

                "scroller-plugin" : {
                    path : "scroll.js",
                    requires : ["plugin", "node", "selector-css3", "event-delegate", "anim-base", "anim-scroll", "anim-easing"]
                },

                "social-counts" : {
                    path : "social.js",
                    requires : [ "gallery-yql", "node" ]
                },

                "sidebar-rollup" : {
                    path : "sidebar.js"
                }
            }
        }
    }
};</pre>
<p>which is modified by the Ant build script to</p>
<pre lang="javascript">//DEPLOY MODE
YUI_config = {
    //yes this is a little gross but sadly it's necessary to make loader work how we want w/ ant
    /* dev  ignore : [ "sidebar-rollup" ], //dev */
    /* live */ ignore : [ "chiclet", "slider-plugin" ], //live */
    groups : {
        anet : {
            //omitted for brevity, see above code block because this doesn't change between them
            }
        }
    }
};</pre>
<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>
<pre lang="xml"><!-- update references to old js files to new concatted file -->
<replace file="${js.dir}/loader.js" token="/* dev */" value="/* dev " summary="yes" />
<replace file="${js.dir}/loader.js" token="/* live " value="/* live */" summary="yes" />
</pre>
<p>to do the switch. Later in my custom loader script those two modules are used with</p>
<pre lang="javascript">YUI().use("node", "event-base", "imageloader", "selector-css3", "chiclet", "slider-plugin", function(Y) {
    // Code goes here...
});
</pre>
<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>JSLint in Programmer&#8217;s Notepad, Revisited</title>
		<link>http://patcavit.com/2010/05/11/jslint-in-programmers-notepad-revisited/</link>
		<comments>http://patcavit.com/2010/05/11/jslint-in-programmers-notepad-revisited/#comments</comments>
		<pubDate>Wed, 12 May 2010 00:58:41 +0000</pubDate>
		<dc:creator>Pat Cavit</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[text editors]]></category>

		<guid isPermaLink="false">http://patcavit.com/?p=262</guid>
		<description><![CDATA[This is an update to my previous post, Programmer&#8217;s Notepad and JSLint. After a few dev versions where the tools didn&#8217;t work they&#8217;re back in fighting shape. There were a few annoyances with my previous version around the actual running of JSLint. The old official WSH JSLint script was set to return after only a [...]]]></description>
			<content:encoded><![CDATA[<p>This is an update to my previous post, <a href="http://patcavit.com/2008/02/05/programmers-notepad-and-jslint/">Programmer&#8217;s Notepad and JSLint</a>. After a few dev versions where the tools didn&#8217;t work they&#8217;re back in fighting shape. </p>
<p>There were a few annoyances with my previous version around the actual running of JSLint. The old official WSH JSLint script was set to return after only a single error &amp; read from Standard Input. I finally got fed up enough with these limitations to figure out how to fix them. Now it reads read in the file from disk instead of Standard Input &amp; can output multiple errors per file, a huge improvement imo.</p>
<p><strong>Quick Note</strong>: wsh.js doesn&#8217;t exist on JSLint.com anymore. I&#8217;ve taken my modified version and put it on <a href="https://github.com/tivac/JSLint">GitHub</a>.</p>
<ol>
<li>Grab the <a href="https://github.com/douglascrockford/JSLint/blob/master/fulljslint.js">fulljslint.js</a> from Crockford&#8217;s github repo.</li>
<li>Concatenate <a href="https://github.com/tivac/JSLint/blob/master/wsh.js">wsh.js</a> to the end of fulljslint.js</li>
<li>Save it somewhere easy to reference, I used C:\Users\Pcavit\tools\jslint.js for easy referencing via the %USERPROFILE% environment variable</li>
</ol>
<p>Once you&#8217;ve done that you&#8217;ll want to change a few tools settings.</p>
<p><img class="alignnone size-full wp-image-263" title="JSLint Settings, v2" src="http://patcavit.com/wp-content/uploads/2010/05/jslintv2.png" alt="" width="802" height="494" /></p>
<p>And now you can get multiple error output, with clickable errors. It&#8217;s totally awesome.</p>
<p><img class="alignnone size-full wp-image-264" title="JSLint Error Display" src="http://patcavit.com/wp-content/uploads/2010/05/jslint-errors.png" alt="" width="444" height="308" /></p>
]]></content:encoded>
			<wfw:commentRss>http://patcavit.com/2010/05/11/jslint-in-programmers-notepad-revisited/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[Yahoo!]]></category>
		<category><![CDATA[YUI]]></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>Xbox Live Friends 1.3</title>
		<link>http://patcavit.com/2008/08/06/xbox-live-friends-13/</link>
		<comments>http://patcavit.com/2008/08/06/xbox-live-friends-13/#comments</comments>
		<pubDate>Wed, 06 Aug 2008 15:45:35 +0000</pubDate>
		<dc:creator>Pat Cavit</dc:creator>
				<category><![CDATA[Gadgets]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[xbox]]></category>

		<guid isPermaLink="false">http://patcavit.com/?p=198</guid>
		<description><![CDATA[In a fit of inspiration I&#8217;ve updated the xbox live friends gadget with offline friends and hopefully taken care of the phantom friend problem in a more thorough way. Also went ahead and added a refresh button because two minutes is apparently too much time for some people to wait. Pictures! You know what time [...]]]></description>
			<content:encoded><![CDATA[<p>In a fit of inspiration I&#8217;ve updated the xbox live friends gadget with offline friends and hopefully taken care of the phantom friend problem in a more thorough way. Also went ahead and added a refresh button because two minutes is apparently too much time for some people to wait.</p>
<p>Pictures!</p>
<p><a href="http://patcavit.com/wp-content/uploads/2008/08/offline-users.png"><img class="alignnone size-thumbnail wp-image-199" title="Offline Users" src="http://patcavit.com/wp-content/uploads/2008/08/offline-users-150x150.png" alt="" width="150" height="150" /></a> <a href="http://patcavit.com/wp-content/uploads/2008/08/offline-users-config.png"><img class="alignnone size-thumbnail wp-image-200" title="Offline Users Config" src="http://patcavit.com/wp-content/uploads/2008/08/offline-users-config-150x150.png" alt="" width="150" height="150" /></a></p>
<p><strong>You know what time it is!</strong></p>
<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>
]]></content:encoded>
			<wfw:commentRss>http://patcavit.com/2008/08/06/xbox-live-friends-13/feed/</wfw:commentRss>
		<slash:comments>4</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.2</title>
		<link>http://patcavit.com/2008/06/20/xbox-live-friends-sidebar-gadget-12/</link>
		<comments>http://patcavit.com/2008/06/20/xbox-live-friends-sidebar-gadget-12/#comments</comments>
		<pubDate>Sat, 21 Jun 2008 01:42:19 +0000</pubDate>
		<dc:creator>Pat Cavit</dc:creator>
				<category><![CDATA[Gadgets]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[xbox]]></category>

		<guid isPermaLink="false">http://patcavit.com/?p=191</guid>
		<description><![CDATA[I&#8217;ve had this sitting on my hard drive for quite some time. I think there was something else I wanted to do with it, but I&#8217;m not really sure.  It&#8217;s been running pretty well for me for months though, so I think it&#8217;s about time I released it! Version 1.2 has a bunch of small [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve had this sitting on my hard drive for quite some time. I think there was something else I wanted to do with it, but I&#8217;m not really sure.  It&#8217;s been running pretty well for me for months though, so I think it&#8217;s about time I released it!</p>
<p>Version 1.2 has a bunch of small fixes in it and some cleaned up graphics. There&#8217;s some issues with the API I&#8217;m hitting causing ghost friends to show up, not much I can do about that. I&#8217;m also noticing some weirdness with the scroll bar in the config panel. It&#8217;s not worth fixing right now.</p>
<p><strong>You know what time it is!</strong></p>
<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>
]]></content:encoded>
			<wfw:commentRss>http://patcavit.com/2008/06/20/xbox-live-friends-sidebar-gadget-12/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

