parsing form and query string variables in node.js using the new querystring and url modules
Thursday, January 21 2010node_debug - the node.js debugger
Friday, November 27 2009I finally took the time to dive into node.js and I must say, its pretty awesome.
It’s Server-Side JavaScript
It can handle a massive amount of concurrent requests
It’s very easy to pickup
The community is currently VERY active on IRC room on freenode and mailing list.
Many of the other developers I talked to are busy contemplating the current node.js application framework scene and plotting out their own node.js application frameworks. Having started and stopped countless framework projects, I wanted to start somewhere a bit more tangible (and useful): the debugger.
Front-End Development Manifesto
Thursday, November 19 2009Front-End Development Manifesto
HTML 4.01 / XHTML 1.0 / CSS 2.0 / JAVASCRIPT 1.5
This document is intended as a general front-end development guideline for web developers to follow. Through following these practices you will run into less problems, build better sites, and save yourself time and money.>
There are exceptions to every rule, but unless you have a solid justification you should try and follow every guideline.
This document is always being modified, please feel free to drop me an email if you have any changes or suggestions.
Supported Browsers:
- Firefox 2.0+
- Internet Explorer 6+
- Safari 3+
- Opera 9+
- Chrome 1+
General
- All pages must render relatively the same in all Supported Browsers
- All pages must be valid HTML 4.01 (W3 validation test at http://validator.w3.org/)
- No pages may be larger than 500k in size (including images)*, you may load any additional assets after the document is ready.
- Serve static content from a cookie-less CDN when possible.
- Websites should have a favorite icon stored in favicon.ico.
- All pages with JavaScript must be able to reasonable degrade if NOSCRIPT is enabled.
- All JavaScript must be declared in JavaScript documents and included using:
<script type = text/javascript” src = “js/file.js”/> - No references to ANY JavaScript events outside of an event selection library.
- No references to ANY DOM elements outside of a DOM selection library.
- No XMLHTTP requests outside of an AJAX library.
- NO INLINE JAVASCRIPT! (such as <input type = “button” onclick = “alert(‘hi’)” />)
- Don’t try to pipeline your AJAX requests, it’s not going to work.
- Never use a timer if you can use an event handler, see: Event Driven Programming
CSS
- All CSS styles must declared in a CSS documents and included using
<link rel="stylesheet" href="css/file.css" type="text/css" /> - No inline styles are allowed*
- <table> is not taboo and should be used when appropriate.
- CSS class names should be descriptive of item being styled. For example “leftmenu” or “testimonials”. Avoid generic names like “style15” or names that describe the default style (like “redtext”)
- Know the difference between percentage based layouts and pixel based layouts. Determine which one your design is going to follow before you write any code.
- Always attempt to use "relative" positioning before using absolute positioning
- If you are only building your site as one fixed size, it’s width should be 940 pixels.
- Negative margins should be avoided, this usually indicates your DOM layout structure is faulty.
*If you are performing dynamic manipulation of the DOM this could be justifiable
User Interface Requirements
- All layouts must be able to reasonable degrade to any number of screen sizes or resolutions.
- All images should possess ALT and TITLE attributes with relevant information.
- All clickable elements should possess a mouse hover property of “pointer” or another indicator that the item is interactive.
- Shadowbox / Lightbox type modals should be used as much as possible for image and video content. There is no reason to load an additional page if we can use an AJAX popup.
- Any elements which are being populated with dynamic content must be able to accommodate the size that content may become. Long strings should never break the layout.
- All links must have all CSS for all five states: hover, visited, link, active, focus
- Default web safe fonts must be set for all elements
- Use a Flash Detection Kit, don’t write your own. The installation process should be seamless.
- The site should be able to reasonable degrade if Flash is not available.
- To maintain compatibility with browsers in less-developed markets, always try to target the oldest version of Flash possible. The newest versions of the Flash Player will always have less market penetration then the previous version.
- Dynamic Flash websites should have a proper “crossdomain.xml” file stored in the root directory of the website.
- Always try to store as much data (such as text and photos) outside of the Flash application in an external source such as a XML file or as a webservice. You should only embed assets inside the Flash application if absolutely necessary as updating any data will require you rebuild the entire app and redeploy it.
JavaScript/jQuery versus Actionscript/Flex : Take 1
Monday, November 16 2009As part of my ongoing adventures in Flash I have began to work with more and more with Actionscript 3.0 and Adobe Flex. Having come from a strong Javascript/jQuery background I can’t help but compare the two technologies as they are both client-side scripting languages based on the ECMA standard.
There are numerous differences between these two sets of technologies. I’m not going to attempt to cover all of these differences, I just want to highlight some of the issues I find particularly compelling.
Browser penetration
Actionscript / Flex
This is perhaps one of the biggest considerations. In order to run a Flex application, the browser must have Flash Player 9 or above installed. Adobe brag’s that Flash has over 99% market penetration in the US Adobe.com, but frankly this is just not true.
There are millions of users who have never installed Flash, don’t know what Flash is, don’t have the security privileges to install any browser plugins, or are on mobile device that doesn’t support flash. Overall Flash has a large market penetration, but you need to consider your target audience and not just assume they will all have the correct version of Flash installed.
Javascript / jQuery
Unless your users are running NOSCRIPT or a similar JavaScript blocking software your Javascript / jQuery code is going to load, if that code works is an entirely different story.
Portability
Actionscript / Flex
If your Flex application works on one machine, it’s going to work on every machine that has the same version of the Flash player. Since Flex applications all run in the same Actionscript Virtual Machine they almost always behave the same regardless of the computer / browser. Unless you have strict control of every machine which is going to run your application, this is a HUGE benefit.
Javascript / jQuery
:-(
jQuery has done remarkable things to allow cross-browser development, but the bottom line is that there are multiple html rendering engines and they all hate you. jQuery has done a remarkable job normalizing the quirks between rendering engines, but if you are building any serious application YOU WILL run into cross browser issues. All JS developers have at least one story where they had an epic battle with IE6 or Safari or Firefox or Chrome or Opera….
Performance
Actionscript / Flex
If you need to do any heavy duty stuff (millions of records, animations, streaming data) you want to use Flex. The performance of the AVM isn’t great, but it’s going to outperform the browser’s JavaScript implementation every time (sorry V8, you don’t count).
Javascript / jQuery
You can get some great performance out of jQuery (if utilized correctly). It’s very possible to build extremely rich user interfaces with CSS, HTML and jQuery but there is a limit. HTML5 is still a long way aways and <canvas> isn’t all that great to begin with. If you think you are going to be pushing the limits of the browser, you need to consider switching to Flex. If this isn’t an option you need to test early, and often. Do not assume that your grid control will behave the same with 1,000 records as it did with 100. Do not assume that because your code runs lightning fast in Firefox, that Internet Explorer will run equally as fast (or at all for that matter). The browser loves to eat up 99% cpu.
Streaming Data
Actionscript / Flex
Flex has tcp/ip sockets. This means you can perform real-time data streaming, just like a real application. Adobe is very committed to allowing real-time data to stream to Flex applications and they have dedicated products, protocols, and lots and lots of documentation. Push technology is very much supported and works well.
Javascript / jQuery
Good luck with that. Javascript doesn’t support sockets. Any solution you implement is going to be long-polling. If you are serious about streaming data you MUST understand the concept of Comet . I would highly suggest using a Comet framework and not implementing your own. I’ve had to build an asynchronous message queue using jQuery and raw PHP, I wouldn’t recommend that anyone do this. Read up on Comet, again READ UP ON COMET. Streaming data to the browser is not out of the question by any means, but you will have to do the research and pick an appropriate server side software.
Conclusion
In no means am I trying to advocate one technology over the other. Personally, I love working with JavaScript and jQuery. I also like riding my bicycle. This is not to say that if I had to travel 500 miles I wouldn’t want to rent a car with satellite radio, gps, and air conditioning.
Remember in the end, it’s simply about evaluating your project’s requirements and making the suitable choice.
In Take 2 of this series I will begin to talk more about actual programming practices and implementations.
jquery.emoticon.js - very tiny Javascript emoticon replacement framework
Friday, November 13 2009While working on a web based instant messaging application I needed to implement a relatively common feature: emoticons. Since I am such a fan of jQuery the first thing I did was google “jquery emoticons”, this yielded no viable results. I broadened the search to “javascript emoticons” and had similar results.
I couldn’t find ANY decent plugins for doing simple emoticon replacement.
*UPDATE: MUCH SUCCESS!!! I was talking some smack on Freenode ben_alman decided it was time to step it up and released an emoticon plugin based on some existing code he had grilling on the barbecue or something. *
CHECK IT OUT!! http://benalman.com/projects/javascript-emotify/
To ensure easy customization and modularity , emotes are stored in a separate JSON document ensuring that the business logic is separated from your emotes.
Leveraging jQuery, the syntax is incredible simple: $().emoticon(myString).
The returned value will replace any emotes based on your emoticon.js file with an tag with the correct image.
Example Usage:
var myString = " This is a string with a smile :-) ";
var emotedString = $().emoticon(myString);
$(body).append(emotedString);
Project Home: http://maraksquires.com/jquery.emoticon.js/
Github: http://github.com/Marak/jquery.emoticon.js
I would really like to get some contributors on this project so we can have a large selection of emoticons to easily choose from for web development!
If you are interested please send me a message on the github or push a patch! If you aren’t that techy but still want to help feel free to Contact Me and I will do my best to get back to you.
route.js - JavaScript Event Pooling on location.hash changes
Thursday, October 22 2009What is location.hash?
location.hash is a getter/setter for the location object of the Document Object Model
To put it simply, the value of location.hash will be whatever is after the # symbol in your browser’s url bar.
Event Pooling in jQuery
jQuery makes event pooling simple through the use of jQuery.bind() and jQuery.trigger().
In jQuery you can do the following:
jQuery(document).bind('#/websites', function(e) {
alert('a');
});
jQuery(document).bind('#/websites', function(e) {
alert('b');
});
/* Now two alerts have been bound to the name "#/websites" */
jQuery(document).trigger('#/website');//This will execute both alerts.
You can find a more detailed explanation of event pooling in jQuery @ http://www.michaelhamrah.com/blog/index.php/2008/12/event-pooling-with-jquery-using-bind-and-trigger-managing-complex-javascript/
Creating a cross-browser location.hash event dispatcher
We can create a simple dispatcher to trigger events to be executed when the browser’s location.hash changes.
var _hashchange_last = '';
var _onhashchange=function(){
if(_hashchange_last!=location.hash){
_hashchange_last=location.hash;
jQuery(document).trigger(location.hash);
}
}
setInterval(function () {_onhashchange();}, 50); /* poll for hashchange every 50 ms */
Now every time the location.hash of a browser is modified (via JavaScript or the browser’s url bar, or the browser’s back button) jQuery will attempt to trigger any methods which have been bound to that location.hash.
Notice there is a 50 ms poll checking for location.hash changes. In HTML5 we could use the browser’s new hashchange event, unfortunately there simply isn’t cross browser support for onhashchange so we are stuck with a 50ms interval.
Now jQuery is great and I love jQuery. I’ve told John Resig he’s my hero on multiple occasions. I just didn’t want the overhead of an entire JavaScript library when I could get away with using less then (1k) of code.
This is where route.js comes in!
route.js enables you to create “routes” based on a unique path a route can be considered a unique state a route may have multiple functions bound to them
ROUTE.JS USAGE
route('#/account').bind(customMethod);
route('#/account').bind(customMethod2);
route('#/websites').bind(customMethod);
route('#/websites').bind(customMethod2);
route('#/account').run();
route('#/websites').run();
REGEX MATCHING:
When calling route(path) you may specify a REGEX string for path
WHERE THE ROUTES AT?
All routes are stored globally in window['routes']
console.log(window['routes']);
This is the good step towards building an advanced Javascript Application since we can now bind methods to unique location.hash’s.
Building on this concept Aaron Quint has created Sammy.js which is a jQuery implementation of Sinatra.
A great writeup on building applications around this concept can be found @ http://www.quirkey.com/blog/2009/09/15/sammy-js-couchdb-and-the-new-web-architecture/