Tuesday, April 6, 2010

CSS Inline Transformer

Apparently designing emails and email campaigns are a painful process, particularly when it comes to styling them up.. Why? Cause the CSS styles have to be written inline in order to work across all email clients (particularly Gmail) that traditionally strip out potentially malicious tags (script/style,etc..) as a result leaving markup ONLY.

Since IE5 (when stylesheets were finally at a more 'standard compliant' stage for the first time - CSS1) we've been able to easily abstract styles from markup. Web developers have worked hard to maintain CSS's growth by implementing for standards compliant CSS2 browsers (yeah, I know UI engineers just twitched, but generally speaking...) and continue to work even harder in an effort that CSS3 will be embraced more timely than its predecessors.  So now, it appears that all the progress is rendered useless and we have to go back to before IE5 times for a pretty significant revenue generator? shudder.

Remember the days when HTML tags were laden with inline 'style attributes', making it (almost) impossible to decipher tags and attribute settings with content/text?

Web clients available from email campaign providers are notorious for their poor WYSIWYG (what you see is what you get) editors, that do not maintain any tab delineation or document structure, as a result making the email a nightmare to look at while creating.

How about sticking to what we do best? Let marketing create the content, and let the developer create the stylesheet ontop of their semantically defined and clearly written out HTML. Sounds good, right? Right.

With JavaScript and jQuery on fire recently, I thought what better place for implementing a little script that inspects a given stylesheet, traverses through the rules present in that sheet with each selector text utilizing jQuery's awesomeness, and then inspecting the rules only to end up applying them to the selectors defined HTML code, using jQuery's 'css' method - that essentially inlines styles.

So what does the code look like? (Note: This was thrown together on FireFox, and I haven't drilled down to figure out why it doesn't work in Chrome yet, but I will update this when I get a cross browser solution)



I've put it up for use, if ever this comes in handy. Check it out at http://www.tikku.com/css-inline-transformer Alternatively, you can bring the code in house and as long as you utilize jQuery and FireFox.

Saturday, March 6, 2010

OOJS Framework; Package Structure

The FRAMEWORK singleton (core object) in my previous post was simply 'FRAMEWORK' in the global ns. This was so that any methods within the framework that needed to be called would be triggered simply by using FRAMEWORK.method() and any public availably object directly accessible on FRAMEWORK.

Of course we can follow a naming convention similar to the Java package structure, like com.domain.core.Framework (simply create com={},com.domain={},...),in which case, each time you wanted to reference the framework you would be required to type the unnecessarily long string.

Personally, I have not wanted to go use this convention, but understand the flexibility attained by using it. Instead, I use {frameworkName}.{util/type}.js for the file system name, and extend the FRAMEWORK object in js with the util/type name. An example is - FRAMEWORK.ajax.js for the file, FRAMEWORK.ajax for the ajax util.

In websites that I've worked on, the file system's package structure is usually:

/scripts/jquery/jquery.min.js
/scripts/core/framework.core.js
/scripts/ui/*
/scripts/thirdparty/*
/scripts/websites/*

Everything through /scripts/ is served up through a HTTP server (Apache) for speed as well as the ability to have the stream GZipped (compression) for performance optimization in the production environment.

The file structure is broken out such that the particular library that you are using contains all library related js files, as well as any plugins created for the library. In my case, jQuery is the library of choice, and so there is a dedicated jQuery directory.

Alongside the library dir, there is the CORE directory, for all core utility wrappers -- ajax, json, notifications, loggers, form, etc. A separate directory is also maintained for all user interface components, which would in some cases ideally be lazy loaded (using a dependency injection method like jQuery.require). The downside of using this of course, is that the end user has to make another request to get the js file, as opposed to having it be available through a minified / compressed file already cached from the first hit on the server. Sometimes, due to the size of a framework, this is simply necessary.

Aside from the library, core and ui directories, there should also be a directory for 'thirdparty' tools/plugins, in an effort to separate code. This directory should house any third party tools brought in, that do not depend on a particular library - an example of this may be any given WYSIWYG/WYSIWYM - like WYMEditor, HTMLBox, TinyMCE, etc.

Finally, a separate directory for the websites utilizing the code. In some cases, the framework you are creating may only serve up one website, in which case this directory may be redundant. But that being said, I like the separation of code so that I can decouple core, required methods, from website implementation specific code; allowing for a more framework oriented style of development. Also, the naming convention for the website directory should be {website}.{util/type}.js, and should extend the framework object like: FRAMEWORK.{website}.

Here's an example of how I have things setup right now --
jQuery
/scripts/jquery/jquery-1.4.min.js
/scripts/jquery/jquery.dimensions.js

Core
/scripts/core/tikku.core.js
/scripts/core/tikku.logger.js
/scripts/core/tikku.ajax.js
/scripts/core/tikku.json.js
/scripts/core/tikku.form.js
/scripts/core/tikku.notify.js
/scripts/core/tikku.resources.js

UI
/scripts/ui/tikku.accordion.js
/scripts/ui/tikku.carousel.js
/scripts/ui/tikku.dialog.js
/scripts/ui/tikku.dragdrop.js
/scripts/ui/tikku.contextmenu.js
/scripts/ui/tikku.tabs.js

Third-Party
/scripts/thirdparty/swfobject.js

WebSites
/scripts/websites/tikku/tikku.core.js
/scripts/websites/admin/admin.core.js

The resulting DOM structure is -
TT
   | // core
   + -- log
       + debug(msg:String,opts:Object)
       + warn(msg:String,opts:Object)
       + error(msg:String,opts:Object)
   + -- ajax
       + send(opts:Object,async:Boolean)
       + sync(opts:Object)
       + asnc(opts:Object)
       + defaultOpts(Object)
   + -- json
   + -- form
   + -- notify
   + -- resources
   | // ui
   + -- accordion
   + -- carousel
   + -- dialog
   + -- dragdrop
   + -- contextmenu
   + -- tabs
   | // websites
   + -- tikku
   + -- admin // only avail if in 'admin' mode

I have given some insight into the contents of the log and ajax modules, but mainly wanted to illustrate the resulting structure after document.ready is fired.

Also note, global pointers can be created to point to the particular sub-level nodes. I like to have 'log' available within the global NS, so even though TT.log suffices, I create a global log var that points to TT.log. This allows me to use log.debug, log.warn and log.error w/ Firebug, similar to how I instantiate log4j in java.

Importing the framework


There are two environments that must be taken care of: (1) development and (2) production. In the development case, any given website requires a set of js files to include in the meta header. This list should be compressed for the production case. For compression, I recommend using Google's Closure Compiler, or Yahoo's Compressor (which works for CSS too).

It's worth noting that you will want to import your library's javascript BEFORE your framework's. You will also want to make sure to understand any dependencies for framework modules, as the order in which modules is imported dictates how they are initialized (remember the readyFunctionStack?).

Friday, March 5, 2010

OOJS Framework; The Core Global Object

So far I've introduced a design pattern for object oriented JavaScript and then I showed an example of the pattern in practice.

Now I would like to introduce the concept of a framework singleton that avoids clutter in the global namespace and simplifies management of JavaScript codebase.

This singleton must provide the following piece of functionality -
  1. Contained namespace
  2. Window onload stack
  3. Initialization method to allow modular extensions to the framework
  4. Public, Global attributes (such as a debugging flag, a DOM signature, etc)
  5. Global helpers, added as necessary

Skip the steps & get straight to the final product

Let's start:

The Global FRAMEWORK node

In my first post, I described two patterns, (a) create a singleton and (b) create a 'base' object like a java pojo. Applying the first pattern, creating a singleton, we essentially initialize the framework like so --

Note: FRAMEWORK is in the global ns in the example above. I would recommend, like most library/api conventions, you keep it short since you'll be referencing it.

The above example satisfies our first goal, containing the namespace so that any variables defined with the 'var' modifier, will be treated private to FRAMEWORK; allowing us to specify attributes that can only be overridden if public methods exist to access them.

FRAMEWORK's window onload stack

Often times events or utility init's require a loaded DOM. Rather than initializing the function immediately, we can store the init functions in local memory in an array and piggy back on a framework to perform the window onload event. This ensures a synchronous initialization of extended utils.

The array, readyFunctionStack is init'd as an array literal with the initFramework function as the internal init function. The initFramework() function is private, which ensures that the init method cannot be modified. The p.ready is a public method, which has a timer within it to display how long the framework initialization takes to init all the functions pushed to the stack.

The p.ready function is referenced as FRAMEWORK.ready, and should be passed onto document ready (window load) methods, like in jQuery: jQuery(document).ready(FRAMEWORK.ready), after the code for FRAMEWORK.

Initialization method for extending objects

The readyFunctionStack described earlier holds all the init functions to be initialized when the window is loaded. In order to modify the private stack, a public method is required to append the function to the array.

Global variables within FRAMEWORK

It's good to store constants/global variables within the framework in an object (hashmap equivalent). In the global object I think there are two attributes that are essential: a debug flag (boolean), i.e. if the framework is in debug mode & a framework signature (why? when interacting with iframes, the framework will be loaded in a different window. the stamp can be used to differentiate the windows). My proposal is shown below.

Finally, all of it together

Sunday, February 28, 2010

Practical Object-Oriented JavaScript

In my last post, I provided insight into a object oriented design pattern for JavaScript that I've been using. In this post I want to show a practical implementation of the design pattern.

In the example below I have implemented the abstraction of a base class, Vehicle, with different sub classes: Car, Bike and Truck. The goals I have set out to illustrate this are:
  1. declare public methods in the base class, to be inherited in the different vehicle types
  2. define public variables, accessed through public methods (able to be overloaded)
  3. define a private variable, only utilized within a method from the base class unable to be modified unless overloading the public class calling it
  4. create a constructor that inits and requires arguments
  5. create a constructor in the base classes that overloads an argument ONLY if present
  6. simulate the 'super' call from within the constructor, like in Java

The model:

Vehicle [Parent]
   |
   +--- Car [Child]
   |
   +--- Bike [Child]
   |
   +--- Truck [Child]

The Code:

The organization of the code above has the base class as well as the sub classes within ONE closure. This means that private variables within this closure are directly accessible to other sub-classes as well, in effect making those private variables act like Java's 'protected' variables to the sub classes, and remaining invisible to the global NS.

Equally acceptable is breaking out the various subclasses into their own separate closures ((function(){****})()), but then of course the private variables available in the base class, are not directly available in the extending object's scope. If the base class has a required private variable that needs to be accessed from inheriting classes, there should be a public helper method (appended to the prototype) to access it.

Now let's see an example of using the defined classes:

This code prints out:

VEHICLE is a CAR, Model is a Honda Civic
VEHICLE is a CAR:SPORTS CAR, Model is a BMW m3
VEHICLE is a CAR:FAST SPORTS CAR, Model is a Porsche Turbo
VEHICLE is a BIKE, Model is a Ducati 999
VEHICLE is a TRUCK, Model is a Chevy Silverado 1500

If you've understood the model so far I'd appreciate any feedback. Same goes for anyone having difficulty understanding what i'm getting at. I'm new to blogging and I want to make sure that what i'm writing is as clear and straight-forward as possible.

In my next post I will share what I have found to be the basics for a JavaScript 'framework', and possible package structures.