Matt Snider JavaScript Resource

Understanding JavaScript and Frameworks

Saturday, June 28, 2008

Functional JavaScript

Most of the time my focus is on OOP JavaScript, and I provide very little discussion of functional JavaScript. This is because although JavaScript is not a traditional OOP language, it is an OOP language (a ‘prototype’ based one). I prefer to leverage the OOP structure of the language, however JavaScript is very versatile and you are not limited to one coding style. Functional programming is one of these styles, it is a technique where one uses global methods to manipulate basic data structures, such as strings, integers, objects, etc. (PHP < v5 is a good example of a function-driven programming language).

Consider for example the 'trim' method that removes the surrounding whitespace from strings. Many developers and libraries choose to add ‘trim’ to the ‘prototype’ of the String Object:

Example 1: Prototype-Based Trim

String.trim = function() { return this.remove(\/^\\s\\s*\/).remove(\/\\s\\s*$\/); };

In functional programming one would write the same function as follows:

Example 2: Functional Trim

string_trim = function(str) { return str.remove(\/^\\s\\s*\/).remove(/\\s\\s*$\/); };

The work of the method hasn’t changed; we are still doing two regular expression removes on a String. However the method structure has. First, because we are putting the method in the global namespace, we need to use a naming convention. In example 2, I have used the naming convention, nameOfObject + ‘_’ + nameOfFunction, with the first letter of each part lower-case, and all subsequent words camel-case (not shown in example, since ‘trim’ is a single word). The Object name is used as a prefix, because you may have multiple ‘trim’ functions (perhaps an ‘array_trim’ that removes empty elements from an Array). Also, in Example 2, we pass the String Object into the Function instead of referencing ‘this’ as done in Example 1.

Those are the two major differences between Functional and OOP programming in JavaScript. In OOP you will extend ‘prototype’ and your methods will directly reference the instantiated Object with the ‘this’ keyword. In Functional JavaScript you will call global methods and pass primitive objects around, ideally never need to the ‘this’ keyword.

My initial thoughts on Functional JavaScript produced these considerations:

Functional JavaScript will be slower than OOP
This is probably just a knee-jerk reaction, because I don’t see why this would be true. Functions are executed quickly in JavaScript, whether attached to an Object or referenced by a closure. It is true that you will use slightly fewer characters using the OOP method, because the names of the functions are generally shorter. However, we attach fewer methods to primitive objects with the Functional method, so each primitive Object instantiation will be faster and lighter.
Functional JavaScript will have namespace conflicts
While this could be an issue, with a good naming convention it can be easily avoided. I recommend extending the method used in Example 2 to also include the author’s initials (nameOfObject + ‘_’ + authorsInitials + ‘_’ + nameOfFunction). This naming convention allows you to have multiple methods for the same operation, in-case you needed that. And also gives the JavaScript community an idea of the author of a given method.
What About the Module Pattern and encapsulation
While, you won’t be able to leverage all the goodness of the module pattern, because true Functional JavaScript will not return an instance of ‘this’, as the module pattern does. You still can benefit from the use of anonymous functions to encapsulate your business logic and avoid local namespace conflicts.
Are there Frameworks written for Functional JavaScript
As far as I know, there are none. I would be interested in seeing how effective this pattern works on the library level. However, it would be a colossal undertaking.

I do not believe there is a drastic performance improvement with either technique; however one would need two comparable libraries using the different techniques and run many tests against each to verify this. I believe the decision on whether you use Functional or OOP JavaScript comes down to your own coding preference and whether you want to use an existing framework or not.

Peter Michaux also wrote a good article about JavaScript Namespacing, if you are interested in additional reading. If you have experience with Functional JavaScript libraries and would like to share, please post a comment.

posted by Matt Snider at 12:37 am  

Tuesday, June 24, 2008

Server Logs Filled with Invalid Chunk Ignored Errors

Something a little different today. Have you ever look through your server-side logs and seen the following error everywhere:

“Parameters - Parameters: Invalid chunk ignored”

If your requests are improperly formatted, then this error will flood your logs. Although not critical, this can be severally frustrating as it bloats your log files, taking up precious disk space and making them ever more unreadable. As usual with logs, this message is nearly meaningless and doesn’t explain how to fix it.

The error is recorded because your requests are malformed. This happens when you are creating a query string and you place an amperes next to the question mark. For example:

http://www.mattsnider.com?&param1=test&param2=abc

Most likely this occurs most frequently when sending AJAX requests as it is easy to sloppily prepend all parameters to the request with an amperes. However, any malformed request can cause this error (not just AJAX requests). To avoid this error all you need to do is ensure that your requests have no amperes’ next to a ‘?’, and for good measure, ensure that they also don’t have any amperes’ next to each other (such as ‘&&&’).

For this purpose I wrote a Function that prepares any AJAX query before passing the query into your AJAX framework (such as YUI connect.js). This method uses two regexes to replace all repeated amperes with a single amperes and also replaces all instances of ‘?&’ with just ‘?’. This will allow you to not worry about the format of your queries, however, it is best practice to format your queries without needless amperes’.

Example 1: Prepare Query Function

var prepareQuery = function(str) { return str.replace(/\\&+/g, '&').replace(/\\?\\&/, '?'); };
posted by Matt Snider at 11:45 pm  

Tuesday, June 24, 2008

News: Unobtrusive JavaScript Presentation and YUI Widget HowTo

PPK - An Event Apart Boston Slides

Peter Paul Koch gave a great presentation at the “An Event Apart” Boston conference about unobtrusive JavaScript. He has provided us a link to his slide from the event on his blog. The slides take less than 10 minutes to browse through and offer a strong argument for unobtrusive JavaScript. I firmly believe that JavaScript should only be use unobtrusively and hope it becomes a standard soon.

Building Your Own Widget Library with YUI

The YUI team has written a collection of articles that educate developers on how best to write a YUI widget. I recommend reading these article, not only if you are a new YUI user, but also if you have been following the project for a long time, because a lot has changed, and reading these articles help one write better more efficient code. Read the YUI article here.

posted by Matt Snider at 10:44 pm  

Friday, June 20, 2008

Weird Issue with responseXML and JSON in FF3

I recently (like today) upgraded Mint to support FireFox 3. I was not expecting this to be a difficult process, because there is no drastic difference between the JavaScript engines of FF3 and FF2. However, I was surprised to find that many parts of the site did not work. Upon further studied I realized the most peculiar behavior. Upon receiving a JSON response from the server using GetXmlHttpObject(), FF3 populates the XmlHttpObject.responseXML with the following:

Example 1: Parser Error

<parsererror xmlns="http://www.mozilla.org/newlayout/xml/parsererror.xml">XML-Processing error: not well formed Address: URL_BEING_REQUESTED Line Number 1, Column 1:<sourcetext>JSON_OBJECT^</sourcetext></parsererror>

In all other browsers, including FF2, the responseXML value is ‘null’ when the response is a JSON object, and occasionally ‘undefined’, but never populated with a value. On Mint we have several different code paths, depending on if a response is an XML or JSON object, or just text. Because the responseXML was not NULL, the code assumed that all my JSON Objects were XML and crashed.

Obviously, this was unacceptable, so I wrote a hack that fixes FF3. If you do any responseXML detection, then the following hack might help you as well:

Example 2: Parser Error Fix

var doc = (data.responseXML); var docString = Dom.getContentAsString(doc); var isXML = $defined(doc) && 0 !== docString.indexOf('<parsererror ');

First, note that the parentheses are required, otherwise FF3 (and possibly other browsers) will set the ‘doc’ to ‘undefined’, even if it has a value. The method ‘getContentAsString’ iterates through the nodes inside of the XmlHttpObject, in a browser safe way, turning everything into a String (useful with ‘innerHTML’). This was originally modeled after a method in OpenRico by the same name. If ‘doc’ is not defined, then isXML is false and everything works as before. Wowever, if ‘doc’ is defined then we look at its content and see if it starts with parsererror. When it does, we assume that the response was not suppose to be XML.

This works for almost every case, with the possible exception that your response is supposed to be XML, and does actually have an XML parser error. However, since that is another issue and I cannot think of any reason why one would intentionally return XML with a parse error, I believe this hack solves the problem.

I have also posted on the FireFox forums and am hoping to here back from somewhere there on why the behavior of ‘responseXML’ has changed (click here to see my post).

—–

I have resolved the issue. The mime-type was not being properly set to ‘text/json’ in the server-side code. However, as I read on Mozilla Docs XMLHttpRequest, responseXML should be null if you do not explicitly send ‘text/xml’ or if the XML is not well formed. So unless I’m missing something, it should still be null, and not a parser error.

Debugging this also, made me ask myself, “Why am I not using the mime-type for response detection”? Kinda of a “Doh” moment. This is a much more robust way of type detection and if you use YUI’s Connect.js, you have the mime-type readily available in the data Object passed into your AJAX callback function. Simply do the following:

var ajaxCallback = function(data) { var isMimeType = data.getResponseHeader['Content-Type'].indexOf(mimeType); };

Where ‘mimeType’ is the type that you wish to test for, such as ‘text/json’.

posted by Matt Snider at 3:46 pm  

Tuesday, June 17, 2008

Object Subscription Pattern

I have said this before and will probably say it again, “I love CustomEvent“. This was one of the major reasons why I chose YUI as my preferred JavaScript framework. Using CustomEvent you are able to create a subscribable event for anything you might want an event for, and fire that event programmatically.

I find this most useful when leveraging the Module Pattern, as I can keep the event management and all important methods private, while allowing users to define actions at key times during the execution of the code. You can also use this process to pass private data from inside the current Module Pattern to external Object with some degree of control (if absolutely necessary). However, for this pattern to work you need a way to expose the events to the other objects, without attaching every event to ‘this’. For this purpose I use the “Object Subscription Pattern”, which uses one public method and coding conventions for subscribing to events. Here is an example of an Object, Dialog, using both the Module and “Object Subscription Pattern”.

Example 1: Subscript Pattern, Dialog Object

var Dialog = function() { var CE = YAHOO.util.CustomEvent, F = function() {}, that = null; var evt = { beforeCloseEvent: new CE('DialogBeforeCloseEvent', that, CE.FLAT), beforeOpenEvent: new CE('DialogBeforeOpenEvent', that, CE.FLAT), closeEvent: new CE('DialogCloseEvent', that, CE.FLAT), openEvent: new CE('DialogOpenEvent', that, CE.FLAT) }; /** private methods here */ F.prototype = { EVENT_BEFORE_CLOSE: 'beforeClose', EVENT_BEFORE_OPEN: 'beforeOpen', EVENT_CLOSE: 'close', EVENT_OPEN: 'open', subscribe: function(type, func, obj) { var eventName = type + 'Event'; if (evt[eventName]) {evt[eventName].subscribe(func, obj);} else {throw('Invalid event type (' + type + ') inside of Dialog.');} } }; that = new F(); return that; };

Lets assume that Dialog is used to manage a div-based popup system, similar to YUI Dialog. In Example 1 we assume you might care about 4 events: after the dialog opens or closes, and before those same events. For this purpose we have created 4 custom events and attached them to the internal namespace ‘evt’. I always use the FLAT CustomEvent type, because I find the default annoying; the difference is well explained in the YUI documentation. The first parameter of CustomEvent is the name of your events and is very important, because the CustomEvent manager maintains a global list of all names to know what to subscribe to and fire. For this reason, make sure you use a unique name. I prefer the convention of the String NameOfObject + NameOfEvent + ‘Event’. The second parameter will be the execution scope of the callback Functions and I generally pass in a reference to the parent Module Pattern Object. The localized event name, attached to ‘evt’, should follow a convention as well; I prefer to use the String NameOfEvent + ‘Event’ (this will be important in the public ’subscribe’ method).

Now, moving on the the public part of the Module Pattern. I have first exposed some constants that are the event names (NameOfEvent) that I used above. These constants make your public interface easier to read and use by others (and even yourself, when returning to an object you wrote some time ago), since there is no need to search the internal namespace for the available event names. The ’subscribe’ method is just a wrapper for calling the ’subscribe’ method of the internal CustomEvents with the proper parameters. We first test to make sure that the internal event exists, and throw an informative exception otherwise. The second parameter will be your callback function and the third is an optional, additional Object that will also be passed through to the callback method, when your CustomEvent is fired.

That is the gist of the pattern. You have exposed private module events through a public ’subscribe’ method. It is relatively simple to use and setup, just requiring that you use some conventions (mine or your own), with which you can apply the Subscription Pattern to any Module Pattern Object. Lastly, lets go over the actual firing of events. When a point in your code is reach and you want to fire an event, use the following syntax:

Example 2: Firing a CustomEvent

var open = function() { evt.beforeOpenEvent.fire(); /** logic to show the dialog */ evt.openEvent.fire([1, 2, 3]); };

Example 2 could be an internal method of our Dialog object that actually shows the Dialog. Notice, we first first the ‘beforeOpen’ event, followed by the opening logic, then we fire the ‘open’ event. I have also illustrated with the ‘open’ how to pass values through to the callback function. With FLAT CustomEvent types, this should always be an Array and will be the second parameter of your callback function.

posted by Matt Snider at 11:44 pm  

Saturday, June 14, 2008

Using Bitmasks to Efficiently Store Data

There are many times when programing that you need to store state, and when this state is simply on or off, one usually uses Booleans. As your projects group, there tends to be collections of similar boolean states, such as turned on features, or user hidden/displayed content. On Mint.com we are (re)adding the ability to hide/show certain account types on the Overview page. I will be using this as a test case for todays article. There are 4 account types in Mint: bank, credit card, investment, and loans; each of these accounts types has a section in the sidebar that can be hidden or displayed. When the user hides/shows these sections we want to remember it between sessions, so I am using a binary number to store the state and a bitmask to modify it.

First, lets discuss several technologies for storing the state, each of which have associated costs and benefits: cookies, session, database, or some combo thereof. In the Mint case, we are storing a visual preference for the user, so I initially want to use cookies. By using cookies, we have a light-weight solution remembers the users preferences on their main, or do we? If they use two computers, have multiple people using the same computer, or occasionally clear out there cookies, then there is no way to ensure that the state is remembered. However, for something minor, such as a visual preference, this might be acceptable, as cookies are fast and light-weight (unless you have lots of them). Alternatively, you could store the state in the database, and load it into the users session whenever they login. This is better than cookies, because it fixes all the above mentioned issues, and is still relatively light-weight, as you only need to make 1 DB call to fetch the preference. The only issue would be if the user is is using two simultaneous computers, which could have two separate sessions. That means setting and getting from the database is the only way to ensure that the users experience is the same on all computers, all the time. The drawback is making frequent database calls is rather expensive. On Mint we solve this by using a database caching layer, but if you don’t have a caching layer, then I recommend storing data in the session.

Now, I’ve written a JavaScript BitWriter Object that manages writing/reading bitmasks on a binary number, so I will be doing a simple cookie example. For more information on the methods I use to write/read cookies, see the post Cookies.

Lets define 4 constants to be our bitmasks, where the bitmask is the 2^n value, and n represents the binary position we are masking. So, 4 values would be represented by the binary number 2^4 (or ‘1111′). Having a ZERO in any position, indicates that the value is not set (false), and having a 1 indicates that the value is set (true). The bitmask is the value of 2 to the power of the position you are masking. Here is an example:

Example 1: Defining Bitmask

var BITMASK = { BANK: 1, // 2^0 CREDIT: 2, // 2^1 INVESTMENT: 4, // 2^2 LOAN: 8 // 2^3 };

So in our example, we use these constants to update the binary value stored in the cookie anytime the state changes. One simply fetches the binary value that is stores in the cookie, and updates it by removing, or adding the desired bitmask:

Example 2: Updating the Cookies

var COOKIE_ACCOUNT_STATE = 'accountPreferences'; var update = function(name, b) { var n = parseInt(Core.Client.readCookie(COOKIE_ACCOUNT_STATE), 10); var bw = Core.Widget.BitWriter(n); bw[b ? 'addBitmask' : 'removeBitmask'](BITMASK[name]); Core.Client.createCookie(COOKIE_ACCOUNT_STATE, bw.getValue(), 365); };

Here we read the cookie called ‘accountPreferences’ and create a new BitWriter from the value. The sample method requires two parameters: the constant name of the bitamsk, and the boolean value of the state (true = on, false = off). Then we use the add/remove bitmask methods of BitWriter to update the value, before updating the cookie value.

The BitWriter Object has the following methods: ‘addBitmask’, ‘getValue’, ‘hasBitmask’, ‘removeBitmask’. Each method ensures that bitmask is valid (a value of 2^n), before attempting the operation. The ‘addBitmask’ method tests to see if the state of the bitmask is ‘0′, and adds the bitmask from value (this is like the binary operator ‘|’ in other languages). The ‘removeBitmask’ method tests to see if the state of the bitmask is ‘1′, and removes the bitmask from value (this is like the binary operator ‘^’ in other languages). The ‘hasBitmask’ method tests to see if the state of the bitmask is ‘1′, and returns the mask in that case or 0 otherwise (this is like the binary operator ‘&’ in other languages). The ‘getValue’ method just returns the current value of the binary number managed by BitWriter.

The logic that runs BitWriter is not anything fancy, just a lot of basic binary math (see the source code here). I have also thrown together a simple test page, so that you can experiment with values and validate the logic of BitWriter.

Following a user comment, I took another look at binary operations in JavaScript only to learn that it does properly support it. I have since upgraded BitWriter to properly use binary operators instead of manually doing it. Needless to say it is much faster, regardless of the size of your binary value and about 1k smaller.

posted by Matt Snider at 12:32 pm  

Wednesday, June 11, 2008

No Mid-Week Article

My other projects have been extra demanding this week and I was unable to put together a decent article. I will be writing about using bitmasks to optimize cookies on Friday.

posted by Matt Snider at 10:20 pm  

Saturday, June 7, 2008

RegExp Escape

If you use regular expressions on your site, then I am sure you have encountered situations where you use a String value, possibly returned from the some user input, as part of your regular expressions. The syntax you might use:

Example 1: Typical Syntax

var haystack = 'Hello World, my name is NAME!'; var needle = 'NAME'; var rx = new RegExp(needle); alert(haystack.replace(rx, 'Matt Snider'));

This very simple example shows how you create a RegExp Object from a String, and use that regex to find and replace a substring of the haystack String. This works great, as long as the needle String does not contain any regex special characters, such as: ‘/’, ‘.’, ‘*’, ‘+’, ‘?’, ‘|’, ‘(’, ‘)’, ‘[', ']‘, ‘{’, ‘}’, ‘\’. If the needle contains any of these characters, your regex will return unexpected results or possibly throw an error.

Suppose we have the following situation: you have a large page of text, at the top of which there is an input Element tied to a JavaScript Function that search the pages text, counting the number of times the provided String occurs. The user then wonders how many sentences are in your text, so they do a search for ‘.’. The ‘rx’ variable of the JavaScript Function, actually becomes the regular expression, ‘/./’, which matches all characters in the text, instead of just the periods. What we need is a method to escape the text before creating a regular expression:

Example 2: RegExp Escape

var RegExp.esc = function(text) { if (! arguments.callee.sRE) { var specials = ['/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '\\' ]; arguments.callee.sRE = new RegExp('(\\' + specials.join('|\\') + ')', 'g'); } return text.replace(arguments.callee.sRE, '\\$1'); };

Example 2 searches the text and properly escapes all regular expressions. I did not write this method and am not sure where it came from, but it is effective and fast. Lastly, we need a count method extending the prototype of a RegExp Object to return the number of times the current regular expression matches a haystack String:

Example 3: SubString Count

RegExp.prototype.count = function(haystack) { return (haystack || '').match(this).length; };

Now using these last two methods in conjunction we can search the text and properly count the number of times that period or other special characters occur, see Test Page for a full text count example.

posted by Matt Snider at 2:14 pm  

Wednesday, June 4, 2008

Intro to HTML Canvas Tag

I remember hearing about the Canvas tag some time ago, but until recently I had not given it much thought. However, now we have John Resig using JavaScript and the Canvas tag to compile and render the Processing language (Processing.js), and Jacob Seidelin emulating Mario Kart. I have even read opinion articles claiming that Canvas could replace Flash. Although, that is unlikely, all this buzz portends that Canvas is here to stay and may be a big player in the future of the web. Todays article will address: what the Canvas tag is, who supports it, and a basic example of how you can use it.

What is the Canvas Tag?

The Canvas tag was first introduced by Apple for the Mac OS X Dashboard and later implemented into Safari. Other browsers would follow Safari’s lead and eventually WHATWG standardized it for the HTML5 specification, which was recently adopted by the W3C HTML Working Group. At its core Canvas is an HTML Element, inheriting the same DOM attributes as other HTML Elements: class, id, style, etc. It has two optional attributes: width and height; it will default to 300 pixels wide and 150 pixels high, if optional attributes are not included. Canvas was introduced to support 2-dimensional graphic rendering on the web, driven by a scripting language with access to the context of the desired Canvas Element.

Why Should I Care?

Canvas is important because it provides a standard, non-proprietary rendering platform that has been strangely absent on the web. In fact, it is the absence of such a standard technology that spawned proprietary frameworks, such as Flash. In the future, we will probably be able to do full 3-dimensional rendering using OpenGL ES, and I would be surprised if someone does not attempt to write a complete Flash-like engine.

Who Supports Canvas

Unfortunately, not all browsers support Canvas (most notably IE), but most do: FireFox v1.5+, Opera 9+, Safari, and even Konquerer (Bug 108069). As far as I can tell, IE 8 still does not have native support for the Canvas Element, which is sad. Fortunately, Google came to the rescue and has created CanvasExplorer which emulates Canvas in IE using one 50kb JavaScript file. Therefore, after a fashion, all major browsers support Canvas.

However, not each browser supports it in exactly the same way. Safari does not require the closing “</canvas>” tag, where Mozilla does. Mozilla made this decision to be more backwards compatible with browsers that do not support the Canvas tag, allowing for fallback content. For example if you take the following example:

Example 1: Fallback Content

<canvas id="stockGraph" width="150" height="150"> <p>current stock price: $3.15 +0.15</p> </canvas>

The text inside the HTML block will render in any browser not supporting Canvas (FireFox 1.0 or IE without CanvasExplorer). Generally, Safari simply drops the closing tag and ignores it, causing no problems, but if you desire to use fallback content, then you need to target Safari in your CSS to not show the fallback content:

Example 2: CSS Targeting Safari

canvas * {display: none;} canvas * {display: block; #} /** Safari will ignore this */

This hack initially applies a style that displays all sub-elements of a Canvas Element as ‘none’, then it tells the browsers to display the sub-elements as ‘block’. However, by putting an extra ‘#’ after the semicolon, we cause Safari to stop rendering the styles and simply drop all declarations inside that bracket. Other browsers just ignore the ‘#’ and apply the ‘block’ display style. Lastly, for the ‘*’ selector to work, all fallback content must be contained inside of another HTML tag (I used the ‘p’ tag in Example 1). Remember, this is a hack and won’t validate, and/or may not always work. However it has continued to work since Nicholas Gagne’s first blogged about it in 2004.

Basic Example

The Test Page contains 3 Canvas Elements, each with alternative fallback content: 1) does nothing, just shows that the alternative content works correctly, 2) draws two rectangles, the second of which overlays part of the first and demonstrates transparency, and 3) draws a heart shape using a more advanced transformation. These examples were found at Mozilla Developer Center: Canvas Tutorial, which provides a much more indepth explanation about the various Canvas rendering options. That article and the Wikipedia Canvas HTML Element Article provided the majority of todays content. I recommend reading both articles if you have additional interest in exploring Canvas.

posted by Matt Snider at 11:01 pm  

Powered by WordPress