Basic YUI 3 Plugin tutorial

Ever since the release of the PR2 version of YUI3 the library has support for writing plugins. Unfortunately, this doesn’t seem to be taken advantage of all that often & comes up a lot in the IRC channel as something people don’t understand. So let’s see if we can’t clarify the matter a little.

At their core YUI3 Plugins are a way to add new behavior to JS objects. It’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 & 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’s another example of YUI3′s great support for modularity of code. Want your widget to accept flaboozulms? Write a plugin! Want your widget to support flaboozulms & flibberdybops? Write a plugin for flibberdybops & then use both the flaboozulms & flibberdybops plugins together. It’s a really powerful idea.

With the pontificating out of the way, let’s touch on some code. I’ll be taking apart a VERY basic plugin I’ve created that listens for clicks on the host & changes the background color. This plugin specifically is targeted towards Node objects since the behavior involves listening for a click event, but the basic concepts could work for any host object. It’s not a very in-depth example of the power here but it is simple enough to show the basics.

Basic YUI3 Plugin Example

Quick breakdown of what this page contains. It’s got your standard HTML skeleton to allow us to easily run JS in the browser, a single <div> we’ll be using to show the interactions, some CSS to style that <div>, and some chunks of JS.

The first bit of JS is including the YUI3 seed file, as well as the loader (because we know for certain we’ll be using it we can save a HTTP request by getting these together).

The next piece is declaring the plugin itself. This occurs within a YUI.add() block that allows us to later specify that we want to use the plugin. You could of course declare the function within the same YUI().use() section where you use it but that wouldn’t be very reusable.

YUI.add('basic-plugin', function(Y) {
    /* Plugin code here */
}, "0.1", { requires : [ "base", "plugin", "node" ] });

Discussing the syntax for YUI.add() 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.

Once inside of the YUI.add() it’s time to actually create the plugin object. It’ll be stuck onto the Y variable so that we’ve got a place to reference it in other code blocks that request our “basic-plugin”. The plugin object’s creation is handled using Y.Base.create(), a very useful framework function that takes care of inheritance & a few other pieces for you. It’s a little hand wavey but if you want the nitty-gritty details feel free to ask & I can provide them.

Y.namespace('Examples').BasicPlugin = Y.Base.create("BasicPlugin", Y.Plugin.Base, [], { ... }, { ... });

A quick breakdown of what we’re doing here, Y.namespace('Examples').BasicPlugin 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 “BasicPlugin” instead of stupid names like “CavitExampleBasicPlugin”. Nobody likes stupid names.

Next up is the assignment of the object returned by Y.Base.create() to our brand-new namespaced object. Y.Base.create() 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 & combines them to allow for easy instantiating of objects later.

Let’s start with the prototype properties object that we’re passing to Y.Base.create(). This object is used as the .prototype property of the class being created which means that it’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.

Y.Base.create(..., ..., [], {
    _handle : null,
    initializer : function() { ... },
    destructor : function() { ... }
}, { ... });

Since this is a “basic” plugin we’re only providing one property & two functions. The two functions (initializer() & destructor()) are special functions that YUI3 will call every time a new instance of this plugin is plugged or unplugged into a host. Starting with initializer() we can see that for this basic plugin all it’s doing is attaching a click event handler to the host (in this case a DOM node) that the plugin was plugged into.

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);

It’s pretty straightforward YUI3 code but let’s run through it quickly. We attach an event handler to click events on the host object (this.get("host") 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’ll be important later. The callback saves the target of the click & the current color attribute’s value, then updates the color attribute with the target’s backgroundColor & finally updates the backgroundColor of the target. The only tricky part in here is the use of this.get() & this.set() which are used to access/update this plugins attributes data. We’ll talk about attributes in just a bit.

Next up is destructor() which is invoked whenever the plugin is destroyed (you’ll see how a little further down).

destructor : function() {
    this._handle.detach();

    this._handle = null;
}

This clean up function ensures we don’t leave little bits of code poop all over the place. The event handler is detached & the reference is nulled out to make sure that the garbage collector has no issue getting that little bit of memory back.

So at this point all we’ve really done is add an object to the Y variable that is accessible at Y.Example.BasicPlugin that when used in conjunction with .plug() later on will listen for clicks & change some background colors. I said we were making a basic plugin, excitement was never promised.

So if we step back up a bit to look at the next argument to Y.Base.create() we’ll notice that it is time to talk about the static properties. Here’s the code.

Y.Base.create(..., ..., {}, {...}, {
    NS : "sp",
    ATTRS : {
        color : { value : "blue" }
    }
});

Judging by the amount of code here it’s tempting to think that not a whole lot is happening. You’re right. More could be happening here but in the interest of time it’s been purposely kept very short. All this is doing is declaring two properties. NS is used for referencing the plugin object once it has been plugged into a host. The ATTRS 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 & custom events to allow you to validate/get updates/whatever you want when these things are changed. That’s outside the scope of this article but I could go on about that for a while. This is where the ability to use this.get()/this.set() comes from as those are brought in automatically to get/set attributes.

So at this point we’ve got a complete plugin that’s been registered using YUI.add(), what do we do with it? Well the whole point of using YUI.add() was so that anywhere we wanted to on the page we could make the plugin available simply by doing something like the following.

YUI().use("node", "basic-plugin", function(Y) { ... });

And since we made sure to add the plugin to a namespace hung off of the main YUI instance variable (by convention it’s simply “Y”) within the YUI().use() callback we can now access our plugin at Y.Examples.BasicPlugin. So what to do with it now that it’s hanging out waiting to be used? I dunno, how about we plug something?

Y.one("#wooga").plug(Y.Examples.BasicPlugin);

So we’ve just taken our plugin and applied it to a host object. In this case the host object is a YUI3 Node object. That initializer() function we declared as a prototype property inside of Y.Base.create() will now be called & the Node will now respond to clicks by changing its background color.

When you call .plug() you can also pass in a configuration object that’ll define defaults for the plugin, so for the second example we also define the color attribute.

Y.one("#booga").plug(Y.Examples.BasicPlugin, { color : "#666" });

This isn’t part of the live example but it’s an important concept, with YUI 3 plugins it’s just as easy to remove functionality as it is to add it. All you need to do is unplug() your plugin from the host. The plugin’s destructor() method is called and the host object loses whatever functionality was provided.

Y.one("#wooga").unplug(Y.Examples.BasicPlugin);

One more thing to note, aside from the YUI3 seed file & loader we never had to include any other <script> tags. This is because YUI3 is rad as hell and the Loader is able to determine based on the modules that YUI().use() asked for & the requires array for the YUI.add() which files it should automatically load from the Yahoo! CDN. It’s super-powerful and one of my favorite features in YUI3.

For a better overview, here’s the complete JS code w/ minimal comments

//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" });
});

And the entire shebang including all the HTML & CSS is available at the sample link.

Basic YUI3 Plugin Example

YUI 3 Loader & Aggregated Files

With the launch of the ArenaNet Blog I’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. 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 & I have been discussing the issue on YUI’s bug tracker without a resolution yet.

Since I need to keep moving on this stuff I’ve had to devise my own solution to the issue I’m experiencing. For background, we use Apache Ant to create a “Deploy” version of the WordPress theme on the blog. This process runs through CSS/JS & renames files, compresses them, updates references, does DataURI stuff, etc. It’s pretty nice and allows for easily deploying a very optimized site without making development a nightmare. As part of that I’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’s name YUI 3′s Loader was loading the file twice.

So until I can get a working version of what Adam has suggested here’s how I’ve set up the build system to allow for replacing individual modules in development mode with a single aggregate file for deploying.

//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"
                }
            }
        }
    }
};

which is modified by the Ant build script to

//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
            }
        }
    }
};

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




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

YUI().use("node", "event-base", "imageloader", "selector-css3", "chiclet", "slider-plugin", function(Y) {
    // Code goes here...
});

which will always make sure that both the “Chiclet” and “Slider-Plugin” modules are available. In dev mode it will request chiclet.js & slider.js versus just asking for sidebar.js when deployed.

Does anybody have a better way of doing this? I think Adam’s version is nicer looking in the config but I’m not sure how it will work if a) the rollup file doesn’t exist or b) you don’t want to use the rollup except in production. I guess you could always just do something similar to what I’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’t added to the Y instance what’s the point?

Awesome PHP debugging function

I still haven’t found a good free setup for debugging PHP but this is the next best thing. Jacob Rosenberg posted a copy of his yo() debugging function. We used it extensively when building http://video.yahoo.com and I can vouch for its awesomeness.

The Greatest PHP Debugging Function of All Time.

I did have one issue with it though, for whatever reason the install of PHP on my DreamHost account wasn’t ever able to pick up any vars if I used the yo() shortcut. I had to modify the shortcut so that it passed func_get_args() to the static function. Weird, and annoying that everything was now wrapped in a superfluous Array() but not the end of the world.

I’m happy to have yo() available to me again for what little PHP work I do these days. It makes me feel warm and safe.

YUI 2.8 Uploader

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’s a known issue with the Uploader component in YUI 2.8 and it’ll be fixed in the next patch release.

Important Issue: 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:

  • On line 509, in swfObj.addVariable(“elementID”, swfID);, replace “elementID” with “YUISwfId”.
  • On line 512, in swfObj.addVariable(“eventHandler”, “YAHOO.widget.FlashAdapter.eventHandler”);, replace “eventHandler” with “YUIBridgeCallback”.

That only had me frustrated for 5 minutes, thank god I read the documentation.

PatCavit.com

Sunday morning I had a few too many skittles after waking up and decided I wanted to build an actual landing page on patcavit.com

So then I started on it, I had grand plans. There were even icons that I was going to grab from… somewhere. That part of it was rather poorly planned. After doing the basic layout I spent about an hour trying to find the right icons. Eventually I threw up my hands and just dropped the whole idea.

Here’s what I’d planned for it to look like:
052520091392.jpg

Notice my awesome hand-drawn icons… :(

Today I was feeling more up for a challenge though. I did some reading and decided to use YQL thanks to Chris Heilmann’s screencast illustrating how he used it to pull multiple sources of data together. After deciding to just ditch the icons I picked a few colors for the top-level sections instead, and here’s what I came up with.

patcavit.com.png

I like it well enough. Still wish I could’ve found icons I was happy with.

YUI Uploader Implementation

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 that powers it also underpins the upload process on Yahoo! Video. I didn’t write the upload pages but I’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?

Yes, I know there’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.

As mentioned in the YUI Blog posting about 2.5.0, the Uploader is what not only powers VYC uploads but Flickr uploads as well. Flickr exposes more of it due to their allowing of multiple files uploaded at once. That’s not really very easy to do on VYC due to the much larger file sizes being used. Still, it’s there. I promise.

I’ve had a free-for-all, open to anyone image uploader chilling out for quite some time at http://tivac.com/upload/. I wrote it to solve a problem, namely the 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.

Here’s a good representation of my thought process while I contemplated redoing the image uploader.

Method Select multiple files from one dialog? Progress feedback available for updating the UI? Smart enough to not totally hose the browser while uploading? Able to dynamically update UI on completion?
Form + JS No No No Sorta
Uploader + JS Yes Yes Yes Yes

I think that paints a pretty compelling picture of why I’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’s really no downside. It’s provably better in every way. Since this is just a junky little personal project and not something important, I don’t even provide a fallback HTML form any more. That’s just how I roll.

Actual implementation was pretty basic. The YUI documentation is excellent as always. It more or less started life out as a copy of their Simple Upload Example and then I hacked the crap out of it. The flow ended up being something along the lines of the following.

  1. Browse for image files.
    upload step 1
  2. If you selected one you don’t actually want to upload, clicking it’s filename will remove it.
    upload step 2
  3. Upload the files, watch all the fun progress bars whiz around.
    upload step 3
  4. As each file completes, its filename is replaced with a thumbnail and various different pre-filled link codes for HTML and forums.
    upload step 4
  5. You can also hit the Export button to just get a list of the URLs of the uploaded images.
    upload step 5

It sounds complicated because I’m an engineer and don’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.

 

//certain things can only happen once the SWF is ready to rock
this.uploader.addListener('contentReady',   this.swfReady);
//event handlers
this.uploader.addListener('fileSelect',         this.onFileSelect);
this.uploader.addListener('uploadStart',        this.onUploadStart);
this.uploader.addListener('uploadError',        this.onUploadError);
this.uploader.addListener('uploadProgress',     this.onUploadProgress);
this.uploader.addListener('uploadCancel',       this.onUploadCancel);
this.uploader.addListener('uploadComplete',     this.onUploadComplete);
this.uploader.addListener('uploadCompleteData', this.onUploadCompleteData);

There’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 “allUploadsComplete” 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’s no more files left to upload, hey presto we’re done! A little roundabout, especially when having to watch out for files that were selected and then removed.

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’d instead use skeleton structures hidden in the DOM. A quick

YUD.get('upload_skeleton').cloneNode(true);

and you’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’s DOM is a little heavier because it contains these stubs, but there’s only two of them and page weight isn’t a big concern for this project.

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’s so simple and to the point that I didn’t see any reason to make it more complicated.

So that all works fine, but I was worried that if I didn’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’s been a few instances of people uploading porn and the like. I’d rather not deal with that, so there’s a little delete script as well. It’s protected by a .htaccess/.htpasswd basic auth setup. Nothing fancy, but it keeps other people from being able to delete my images.

image browser

The images are laid out in a big floating grid using Hedger’s very awesome work on getting display: inline-block to work across browsers. Item List Grid : Practice with display:inline block across browsers. It’s a technique we also used extensively on VYC so it was the first thing that came to mind when just floating a bunch of images that weren’t the same height went all crazy.

Oh, right. All the icons are the insanely awesome work of Mark James, specifically his Silk set of icons. I’m sure you’ve seen them used pretty much everywhere. There’s a good reason for that, they rock.

I’ve zipped up the source for anyone who wants it, it’s all pretty well-commented. You will have to handle the file permissions yourself though. UPDATE: Sitzmar 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’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.

upload.zip

Sites I read that are worth checking out

This is gonna be a long one, so watch out. I’ve been collecting feeds of people who I consider to have really worthwhile things to say about my chosen career (web development, for the people who don’t know that about me already). I’ve got quite a list, and since I’m of the opinion that sharing is caring I will be providing a huge list of links to sites that I think are awesome and deserve your attention.

I make no claims that this list is authoritative, in fact I’d love feedback pointing out really smart people I missed. I read a lot of feeds but none are more dear to me than the ones contained with my “development” folder. Adding new items to it is a joy each and every time.

  • Usability/Design

    • 456 Berea Street, full text rss icon

      Roger Johansson does a great job of covering usability issues on the web.

    • 90 Percent of Everything: Usability Blog rss icon

      Harry Brignull and Andy Baker cover usability design both on the web and in client apps.

    • flow|state rss icon

      Usability fascinates me, and this is one of the best usability blogs I’ve ever seen. Updates are infrequent, but always incredibly insightful.

    • Looks Good Works Well rss icon

      Bill Scott left Yahoo! for Netflix but we won’t hold it against him. His UI design comments are fantastic.

    • Theresaneil’s Weblog rss icon

      Another really fantastic UI blog. I wish there were a lot more done this well.

  • Web Development

    • A List Apart rss icon

      Great writers and a ton of content makes this a great resource. Doesn’t update that often, but always great content.

    • Bite Size Standards rss icon

      Tiny little nuggets of web knowledge, updates infrequently but with useful info.

    • Ajaxian rss icon

      Ajaxian’s great about updating with the newest and greatest javascript libraries and techniques.

    • Bartelme Design – Journal rss icon

      Small Design firm based out of Austria that posts nice wallpapers and some decent articles every now and then.

    • CSS Help Pile rss icon

      Monster collection of CSS tips and tricks, always a nice reference to have around.

    • CSS, JavaScript and XHTML Explained rss icon

      Browser quirks, CSS techniques, all sorts of stuff. Updated rarely.

    • DOM Scripting Task Force rss icon

      Unofficial group dedicated to promoting good Javascript, I can get behind that goal.

    • Douglas Crockford’s The Department of Style rss icon

      Crockford discovered JSON and writes great articles about Javascript best practices. Also see javascript.crockford.com and JSLint.com.

    • Dustin Diaz rss icon

      A Googler (we won’t hold it against him) yet he still loves YUI (yay!). Produces a lot of really interesting code snippets.

    • Fiftyfoureleven.com rss icon

      Mike Papageorge runs this general web developer resource/weblog. Good stuff though getting a little stale.

    • Firebug – Web Development Evolved rss icon

      Firebug development blog, updates almost never but good to have a subscription to in case it does.

    • Foo Hack rss icon

      Isaac Schlueter is a fellow Yahoo! and writes some fantastic pieces about web development.

    • Garrett Dimon rss icon

      Garrett Dimon’s weblog is wonderfully minimal, yet still provides really great insights into the development process.

    • HedgerWow`s Blog rss icon

      I worked with Hedger last summer, he’s a true mad scientist in the world of web developers. Seriously, I have no idea how he comes up with most of this but it’s insane and amazing.

    • If..Else Log rss icon

      Only occasionally development related, but still a good read.

    • JoeHewitt.com rss icon

      Joe created Firebug, so you know he’s pretty damn smart. Too bad his site appears to be unloved these days. Staying subscribed just in case!

    • John Resig rss icon

      Author of JQuery and an all-around Javascript genius, I love reading about John’s continuing adventures.

    • Johnnie Manzari rss icon

      Interesting observations about the web, definitely worth checking out.

    • Julien Lecomte’s Blog rss icon

      Julien’s the author of the YUI compressor and consistenly posts things you should be reading.

    • Matt Snider JavaScript Resource rss icon

      Matt Snider does a great job of breaking down JS and investigating all the 8 bajillion frameworks floating around these days.

    • Nate Koechley’s Blog rss icon

      One of the main YUI guys, Nate’s super smart and consistently posts interesting stuff. Not always web dev related, but always worth checking out.

    • Particletree RSS Digest rss icon

      Great articles, wish they’d start updating again a bit more regularly.

    • Pete Freitag’s Homepage rss icon

      Pete’s a Cold Fusion guy but still posts things that apply to web dev in general.

    • Ryan on WordPress rss icon

      I like WordPress an awful lot, so keeping tabs on its development is a good idea.

    • Schillmania: DHTML and other client-side experiments rss icon

      Scott Schiller is a web dev genius. I have no idea how he’s so good at what he does, I wish I did. He’s at Flickr now, before that he worked on the really impressive new Y! Photos that was canned.

    • Simon Willison’s Weblog Entries rss icon

      Django co-creator, Simon also writes a lot about OpenID.

    • SitePoint.com rss icon

      Lots of good articles to be found here.

    • snook.ca rss icon

      Lots of PHP talk, it’s good stuff.

    • Solution Watch rss icon

      Features new websites that do things well. Good for keeping up with the current state of web dev.

    • Vitamin Master Feed rss icon

      Vitamin is kind of like A List Apart, another big group of contributors writing amazing articles.

    • WordPress Development Blog rss icon

      Keeping tabs on WP development, even if I don’t have my hands into the guts as much as I used to.

  • General Development

    • Coding Horror rss icon

      Jeff Atwood’s posts are always well thought out and engaging, I love his blog.

    • Joel on Software rss icon

      Joel Spolsky writes about software development from a very pratical place, having done quite a lot of it himself.

    • Programmer’s Notepad rss icon

      Programmer’s Notepad rocks my world. I use it every day and love it to pieces. Keeping up with releases via a feed is tops.

    • Rasmus’ Toys Page rss icon

      Rasmus is really, really smart. Not surprising, given that he wrote a bunch of PHP (the language itself, not just PHP code). He’s another Yahoo! as well.

    • StickBlog rss icon

      Lots of good development tips to be found, as well as general programming talk.

    • untidy blog » PN rss icon

      Programmer’s Notepad author’s personal blog. The feed is just for the PN category, because that’s the programming related stuff!

And just in case you made it to the end of that huge list, here’s a link to everything I read on a not-at-all daily basis. It’s a little ridiculous. My Feeds.

Programmer’s Notepad and JSLint

I’ve been using Programmer’s Notepad for some time now as my go-to text editor for code. It’s simple to use and really robust and over all just a really great tool. As the Javascript I write has gotten more and more complicated, I’ve found myself often hitting up Douglas Crockford’s JS Lint to sanity check what I’m doing. When I found out that Textmate offered JSLint integration via a bundle I have to say I was pretty jealous.

Then I stumbled across a post from Simon Steele, the developer of Programmer’s Notepad.

Tools I Rely On – Those I Use From PN

So now I knew that you could use JSLint from within Programmer’s Notepad, and had a starting point in the link he provides to the Windows Scripting Host compatible version. I began stumbling around the tools menu in PN, trying to figure out how to get the jslint.js file I had downloaded to be usable as a tool. I figured it out with some help from Simon on the PN forums, Issues with using JSLint as a tool.

With that in place, I was able to get JSLint working as a easily-called tool within PN. With a simple keystroke I can sanity check my JS for all sorts of nasty behaviors, it’s totally awesome. Here’s a quick walkthrough I wrote up after mentioning this on a Yahoo! internal mailing list and getting a question about it.

  1. Downloaded the WSH version of JSLint from http://jslint.com/wsh/index.html and copied it into a tools subdirectory in the Programmer’s Notepad directory (just for ease of referencing).
  2. Added a new tool for Javascript files:
    Tools -> Add Tools -> Scheme: Javascript -> Add
  3. Settings are as follows:
    JSLint Settings

Those settings allow for double-clicking the JSLint output line and having PN jump to it, which is really handy. Unfortunately it stops after every error and always complains about a null character at the end of files, but those are minor annoyances. It works really well and is pretty quick to get started, which I appreciate.

I’d love to get it so that it’ll run JSLint every time I save a .js file, but I don’t think PN supports that for tools yet. Something to ask about on their forums, I suppose.

Work Work Work

I am insanely busy with work stuff, but we’re in the home stretch and that’s really exciting. I will share more about what I’ve been doing soon!

Javascript, ActiveX and IFrames

Been working on a project that involves getting some JS to interact with an ActiveX control and then have that work with an IFrame for asynchronous uploading.  It’s been interesting, at least.  Getting the AX object into the page so that my JS could actually reference its methods was the first hurdle.  After a day of banging my head against the wall I stumbled onto a site that recommended using innerHTML to write it out.  Wonder of wonders, it worked great.

I started building up the JS scaffolding  around that and promptly ran into another issue.  While the ActiveX object is thinking it calls a predetermined callback method in the JS to give status updates.  Unfortunately, you can’t declare this callback until the object is in the page.  This means dynamically inserting a new JS file in the initialization after dynamically inserting the ActiveX object.  That’s a lot of dynamic inserting and it makes me a bit nervous but it works fine in IE and since we’re using ActiveX that’s all I have to test!

The next step is getting asynchronous uploading using an IFrame working.  This is being complicated by most tutorials that cover this technique being old as dirt.  We’re talking 2002 old as dirt here, before AJAX was anything more than a cleaning product.  “Script Remoting” is not what I want to do (I have XMLHTTPRequest for that, thank god) but that’s what most of these tutorial focus on.  It makes parsing out the useful info needlessly complex and it’s really driving me up the wall.

Having a a good time at JumpCut though. :D