Code On Fire Passionate About Cool Code

15Mar/100

Code & Style Separation – Not Always so Useful

Best practices exist for a reason. And sometimes we get so carried away with following the ‘best practices’ that we lose focus of the reason why we’re doing it.

It is important to take a step back every now and then and question our best practices just to make sure they’re still serving their purpose. This is especially true when you start complicating your development arena with newer and evolving technologies.

HTML– Code or Styling?

When we look at HTML and CSS, along with technologies such as vanilla JavaScript, it is easy to categorize HTML into the realm of styling, while JavaScript is obviously code. It is then easy to generalize and state that the separation of code and style should be definitive and large.

function handleClick(){
// perform some action
}

function handleMouseOver(){
// perform some action
}

function handleMouseOut(){
// perform some action
}

<a class=”someClass” href=”javascript:;”
onClick=”handleClick();”
onMouseOver=”handleMouseOver();”
onMouseOut=”handleMouseOut();”>Perform Some Action</a>

In this case it is quite obvious how separation can abstract complex behavior and make your code more readable.

Where things become blurry is when you start using DOM manipulation via JavaScript. If you kept to the code and style separation pattern, you would never even dream of doing DOM manipulation via JavaScript because it violates that principle: Creating HTML using JavaScript just seems to go against the grain.

CSS – Code or Styling?

Same goes for CSS to a lesser degree. CSS is very obviously in the realm of styling. However, if you start using CSS selectors to add behavior to HTML elements via DOM manipulation, the lines start blurring again. In this way, CSS is often used to group a set of elements together for the purpose of behavior modification, which is in the realm of programming, not styling.

Also, CSS styling is often applied to elements based on state changes in your application. This is dragging styling back into your code, further dissolving the boundaries between code and styling.

Redefining the Best Practice

Unless we want to throw away all the possibilities that technologies like DOM manipulation and CSS grouping for programmatic purposes, we have to redefine what ‘best practice’ means in this context.

This means going back to the purpose behind ‘code and style separation’. And this is where the real debate starts.. To keep things simple, I’ll provisionally just say: Let’s assume the purpose behind code and style separation is:

  1. To allow developers and designers to co-exist gracefully. Developers don’t need to know how the styling is being done and designers don’t have to know how the behaviors are being implemented.
  2. To allow design or code to change independent of each other. This, of course, is the ideal – though never really completely achievable. There will always have to be references from the styling towards the behavior and from the code back to the styling.

Now that we have that very basic understanding of why we want to separate code and styling, we can reassemble those goals into a new best practice that achieves the goals and allows for the new methodologies and technologies we want to leverage.

I believe this topic needs a lot more discussion than just my singular input, but here's where I started looking for a solution:

Bring MVC to Browser-based Applications

As soon as you start playing with this concept, you realize that this is a little more complicated than MVC implementations in compiled languages and old-style server-side-scripting implementations.

For one, your model is now a complex interplay between local data objects (JavaScript Objects, cookies, environment variables etc..) and remote data objects (mostly in response to user interaction, these data objects need to be fetched from the server before they become available in the client-side application). The instinctive approach for any good OOP programmer is to try and treat local and remote data sources in the same manner: i.e. write a general class* describing a data source and then extend it to handle the different resources. This way you can access all data sources in the same manner and support multiple types of data.

This however quickly becomes problematic when you run into issues like different storage capabilities of the different data sources and different speed and reliability ratios between remote and local data sources. At a later stage I’ll write more in depth about my implementation of synchronous and asynchronous data model implementations including a framework for caching, retrying, look-aheads and other necessities that made its way into the code.

With regards to the controller, things also complicate themselves considerably on the client side. In a standard implementation of MVC, one would expect the controller to house the code routing the workflow into implementing the correct model tied to the correct view. This was true for PHP, but gets a little more complicated when dealing with a stateful application on the client-side. Suffice it to say, in my framework, the controller performs the function of creating, rendering, updating and destroying elements in the DOM that are bound together by a specific set of view(s) and model(s). More about that in a future post.

Views are also slightly more complicated in the browser. In the standard MVC implementation, a view only defines the actual display along with it’s styling and placeholders for data that the controller will get from the model and fill into the view.

In the browser, we have to conserve resources. For this reason, the actual HTML contained in the view might not reside locally. And once it has been loaded, it might have to be cached locally for future use. Also, it might need to have an expiration date so that we release unused memory for the browser to use on other sites while the user just leaves the tab open.

Once again, in a future post, I will discuss my framework concept of resources with built in customizable functionality catering for caching, expiration, e-tag based versioning and more.

Having those kind of resources available makes it a lot easier to implement views as a structure that does the actual rendering of the elements needed. You might ponder that the rendering should really be part of the control: in the traditional implementation, I would have to agree. But in this environment, rendering might involve more than just filling out a HTML template with values. It might involve DOM manipulation and contextually sensitive event handling. Sound’s hairy.. because it is. But it does simplify life considerably once you start implementing it. In a later post, I’ll discuss the details of how I’ve implemented the view structure in this MVC framework.

Once you have this basic structure in place, you have once again separated the coders from the designers. CSS and the view templates are left to be honed by the designers, while the code can be tended to by the coders.

Bring Semantic Events to the Browser

A second strategy I employ to keep the coders and the designers out of each others’ hair: Semantic Event management. JavaScript doesn’t really support a proper event structure that can be applied to objects. This is something you have to create yourself. And it is a good thing too, because it allows us to implement an event management structure that allows for verbose semantic events.

This means we can expose business-sensible events to the designers, making life a whole lot easier for them. But it also allows modular design based on the observer pattern, making life for the developers a whole lot easier.

Keep in mind the fact that once you start implementing events of this nature in the browser, you quickly want to start propagating events of this type between the browser and the server too. And later on, client-to-server-to-other clients. It gets real exciting.

When you approach this arena, however, you start running into issues best catered for in your event model right from the get go: blocking vs. non-blocking events, event queuing, event stacking and bursts of cached events. More on that in a later post.

In Summary

In the browser application environment, we need to re-think a lot of our ‘best practices’, because the available technologies often force us to go against our instincts. But if we pull things apart and discover the reasons behind our best practices, we can re-assemble them to support the new technologies while still achieving their original goals.

Onwards and Upwards!

Resources

24Feb/100

Why a JSON parser for JavaScript?

JSON is a proper subset of JavaScript, effectively reflecting the definition of a JavaScript object. The easiest way to parse a JSON string into a JavaScript object is using the eval statement:

var obj=eval(‘(‘+jsonString+’)’);

And therein lies the problem. Eval statements are dangerous, especially in a web2.0 environment and can be abused if your evaluation string is contaminated by content you don’t control. Even if your server side code does JSON encoding you could still end up with some severe problems. For example:

jsonString={a:new function(){document.body.innerHTML=”This script just hijacked your page”;}}

That is why JSON parsers that don’t make use of eval is recommended. The smallest and best one I’ve come across can be found at http://code.google.com/p/json-sans-eval/

22Feb/100

WebSocket Support Investigation

WebSocketWith Comet technology dying out and HTML5 around the corner, WebSocket support is  becoming a very hot topic on the edge of the new Push Button Web revolution.

I set out to discover how viable that technology is right now.

Client Side

HTML5 Compliant Technologies

HTML5 compliance includes a WebSocket object that can be used to make persistent streaming tcp connections to a WebSocket server (cross-domain).

The only browsers currently supporting this technology is Google Chrome and Safari. (Webkit implementors). Firefox is planning on including WebSocket support in their 3.7 release. IE is quiet on the matter (we're used to this by now).

I have tested HTML5 WebSocket implementation using Chrome as client and PHP for the WebSocket server. It was blazingly fast, reliable and robust when I intentionally disrupted network availability.

WebSocket using Flash

For browsers not offering native WebSocket support, the standard workaround is to use Flash socket connections. I implemented a few of these methods, and even though I eventually got it to work, I found it not very robust (when it broke, I had to refresh the page to get the connection back up and running) and definitely not very friendly (Flash TCP connections require a security policy file to be rendered from the same server on port 843 before the socket connection is allowed)

This is an awkward solution, and feels mostly like a hack. It is also dependent on client-side variables like whether Flash is supported on the client and what version is running.

Server Side

The server side implementation of WebSocket is well supported. Most server side programming languages provide an implementation of CURL, which is quite enough to support WebSockets.

The main challenges on this end is configuring your hosting platform to open the chosen port for traffic.

Filed under: Uncategorized No Comments
17Feb/100

Comet support on GAE

What is Comet?

Comet is a set of web methodologies (like AJAX) that allows client browsers to have persistent http connections to their servers. It is also known as long polling. The benefits of making use of this type of connection is that any state change on the server can be immediately pushed to all connected clients. The physical result of this can be seen in applications like Google wave, where one user is typing a message into a wave, and another subscriber to that wave can see the letters appearing as they are being typed. [see wikipedia]

Browser Limitations

To maintain the security model, browsers are endpoints that don't allow connections to originate from a remote location. This means that whatever network connectivity is implemented in the browser environment has to be initiated in the browser and cannot come from the server.

This means when a state changes on the server, there is no way for the server to let the client know about the change. It has to wait until the client requests an update before it can be notified about the state change.

How Comet Works

There are several implementations of the comet meme, but they all rely on the same concept: opening a page on the server that never quite finishes loading. If, for instance, you load a JavaScript file and the server keeps the connection open, to the browser and to the rest of the world it just looks like a file that takes forever to download. The server, however, can now send updates to the client by pushing a JavaScript statement through the slow-loading file.

On the browser side, JavaScript includes are executed line by line as they arrive through the network. So when it gets the server's update code, it will immediately execute it, and your client can respond to the message.

Comet and GAE

As soon as you make use of Google AppEngine, you run into some limitations. Two of those limitations directly affect the comet concept:

  • GAE does not allow streaming. This means that the entire resource has to be rendered on the server and the script on the server must exit before the response is sent off to the client. This makes using a long-loading file impossible to implement.
  • GAE has a 30second execution restriction on scripts. So even if it were possible to stream files from GAE, it could only happen for 30 seconds before GAE automatically shuts it down.

This means that comet is not a viable option for achieving persistent HTTP connections between the client and the server. [see cometdaily.com]

Other Alternatives

There are other alternatives to accomplish a similar effect:

Java Sockets

Java plugins on an html page can create sockets that listen to incoming messages. This could be used by the server as an endpoint to which it can make announcements. Due to the fact that communications in this model is initiated on the server, this strategy comes with a heap of network baggage. Dealing with proxies, firewalls and non-standard endpoint network configurations becomes the responsibility of the Java plugin and the server announcer.

Very Frequent Short Polling

This is technically not in the same league, but attempts to recreate close to real-time connectivity with the server. In this model, the server is short-polled on a frequent basis (1 to 2 times a second, or whenever a previous poll completes).

As one can imagine, this method is very resource intensive and bandwidth hungry. Even if polling the server returns no data, just the TCP/HTTP overhead will consume a lot of bandwidth.

Also, when dealing with software residing on GAE, there are limitations imposed (and for premium users, costs applied) with regards to the number of connections made to the server. Even if these numbers were very large, it becomes a very real problem when very frequent short polling is used.

HTML5

With the wide adoption of this standard, browsers will have access to web sockets. This will essentially open up a two way connection to the server where the same connection can be re-used. It will be ideal for a RPC pipe. It will also be ideal for comet-type connectivity where the server can push information onto the pipe and the client can then respond to it. [see w3.org]

12Feb/100

Google App Engine SDK 1.3.1 Released

This release is a fairly sizable one with several enhancements:

  • Datastore Query Cursors – Query cursors allow an app to perform a query and retrieve a batch of results, then fetch additional results for the same query in a subsequent web request without the overhead of a query offset. [more]
  • Transactional Tasks – The ability to group a set of SQL operations into a single transaction that either succeeds or fails as a whole. [more]
  • Custom Admin Console Pages -
  • New “month” and “synchronized” syntax for Cron configuration – [more]
  • Removal of the 1000 query result limit – Stability and performance improvements as well as new technologies such as Query Cursors prompted the GAE team to get rid of their 1000 query result limit altogether.
  • Automatic Datastore Retries – Sporadically, Bigtable is not available on request. The standard workaround was to manually retry the request until it succeeded. This is now a built in automatic feature, and app engine will automatically retry queries that failed due to Bigtable inaccessibility.
  • AppStats (for Python GAE) – a RPC instrumentation library for profiling performance of calls from the app to backend services to identify bottlenecks, ineffective caching and redundant RPC calls in their app. (The Java counterpart is in beta testing at the moment) [more]
  • Unit-Testing Framework (for Java GAE). This framework also allows for integrating App Engine apps into other existing testing and automation frameworks.
  • E-Tags Support! – If-matches, If-not-matches in HTTP headers for content version control.
18Nov/090

Adobe Air 2 Beta Finally Out!

In an industry that are working with virtual file systems and online document management (www.knowledgetree.com), I have been waiting for this moment for some time now – Adobe Air 2 is finally in beta.

This version of Air opens up several new functionalities – eg. :

  • Drag & Drop support of remote files via the filePromiseList clipboard object.
  • Socket Server Support – Air apps can now listen on a port and no longer need to initiate a network conversation. This also enables different air apps to now communicate with each other using socket connections.
  • New Filesystem API – This includes functionalities like being able to open files with their default registered application, flag files as downloaded so that the operating system can warn against opening them and notification of mounting and dismounting volumes.
  • NativeProcess API allows you to execute a third party process and interact with it.
  • Microphone Capabilities allows you to access raw data from the microphone, inspect it, alter it, encapsulate it as WAV and store it to the local filesystem.
  • HTML5 & CSS3 Support will let you implement the provisional features of next-gen interactive document markup.

For more information on where to get all this goodness: Adobe Labs

12Nov/090

Adobe Air MouseLeave Window

It took me a while to figure out how to get an Air application to let me know when the mouse leaves the window. Once I got it.. easy as pie:


window.nativeWindow.stage.addEventListener('mouseLeave',function(e){
    alert('The mouse just left the Window');
});

 

Tada!

6Nov/090

Zend Server 5.0 Beta Code Tracing

Zend Server 5.0 Beta is promising an awesome bug-tracking method that will help find and solve problems much easier. Whenever an error is encountered, the new tracing feature will automatically log full error tracing information – even when in production mode.

Just as cool, one can manually run the trace to profile the execution of your code in real time. This will allow you to find bottlenecks, see the function tree for the entire execution of your script and use that information to optimize execution.

Take a look at Zend

Filed under: Uncategorized No Comments
6Nov/090

jQuery & JavaScript Tips to Improve your Code

jquery-logo_pngHere’s a nice post on TripWire Magazine on improving your JavaScript coding, especially in  jQuery.

It deals with these topics:

  • Improving your selector skills
  • Testing for empty collection containers
  • A URL you can use to get the very latest jQuery on page load
  • Using callbacks to synchronize Effects
  • Using the Event model for DOM and custom object interaction
  • Creating custom selectors & how to use them
  • Making entire elements clickable – the easy way
  • Preloading images – jQuery style
  • Disabling / capturing right-click contextual menu
  • Grouping queries for simpler code
  • Using QUnit for integrated unit testing

To find the article, go to TripWire Magazine

20Oct/090

Converting Binary String to ByteArray

While using HTML/JavaScript in air, I have found no way of getting the Air-Ajax functionalities to run in synchronous mode. For this reason we are forced to manage certain upload / download functionality using the XMLHTTPRequest object available via Javascript.

However, one quickly runs into problems trying to write binary strings requested in this fashion, to the local file system. Write operations for binary files need to be passed a flash ByteArray object that contains the data.

Here is how to convert a JavaScript binary string to a ByteArray, ready for use with file IO functionality in Adobe Air:


string2byteArray=function(str){
    var ba=new air.ByteArray();
    for(var i=0;i<str.length; i++){
        ba.writeByte(str.charCodeAt(i));
    }
    return ba;
}


Hope this helps some.