Nov 3, 2011

Using HTML5's Navigation Timing API to measure Page Load speed

To measure the time taken for a page to load one can use the Date object in the head section and calculate the time taken for the page to load in window.onload function. However, it calculates the time taken for the page to load after the first bit of JavaScript in the head is executed. This doesn't indicate the time taken by the web server to serve the requested page. The Navigation Timing API introduced in HTML5 provides data that can be used to measure the performance of a website. The API provides a PerformanceTiming interface which contains several attributes that can be used to get end-to-end latency data.

Nov 1, 2011

Using HTML5's PageVisibility API

Today I stumbled upon the PageVisibility API introduced in HTML5, which gives developers an opportunity to improve the performance of a web page and to better the user experience. Whenever a user opens a new tab or navigates to another tab, the behavior of the current page from which user navigated can be controlled using this API. Consider a webmail client that is trying to look for new mails every two seconds, if a user opens a new tab or minimizes the browser window then retrieving mails every two seconds would expend resources, whilst the user is not actively viewing the page. Here the PageVisibilty API would come handy and would allow developers to alter the behavior of the web page.

Oct 10, 2011

PubSubHubBub and ColdFusion

I came across a publisher\subscriber protocol called PubSubHubBub. It is a server-to-server web-hook-based pubsub (publish/subscribe) protocol - an extension to Atom and RSS. Here the parties (servers) get an instant notification when a feed URL, that  they are interested in is updated.

Traditionally a subscriber would subscribe to a feed and poll for it at regular intervals, to see if there is an updated feed available. In this protocol rather than polling for a feed, the content is pushed out from the publisher. The theory here is that the subscriber can subscribe to a feed via a 'Hub', which then would inform the subscribers when the feed is updated.

How PubSubHubBub works?
  • A Publisher instead of sending an update to every subscriber, it includes a in its feed URL and sends an update to the Hub.
  • A Subscriber sends a subscription request to the Hub with the feed URL that it is interested in. The request also contains a callback URL to which the Hub should send an update.
  • To verify the subscription request, the Hub sends a GET request to subscribers' callback URL. The
    Subscriber then verifies itself by responding to the request.
  • When the Publisher posts new content, it notifies the Hub of the updates by sending a ping notification (POST request).
  • Hub on receiving a notification from the Publisher, fetches the new content and then POSTs an update to the Subscribers callback URL.
If the feed has multiple subscribers, then the Hub would send an update to each of these subscribers. The Subscription flow posted on the PubSubHubBub site is here:



Where is the Hub?

Anybody can run a hub, it is not owned by any company. The protocol is decentralized and free. A couple of implementations include pubsubhubbub.appspot.com and superfeedr.com

Publishing

Whenever a publisher adds new content (a new blog post), the subscribers are to be notified of the updated feed. A notification (POST request) is sent to the Hub by the Publisher. The Content-Type header must be set to application/x-www-form-urlencoded and the request should contain the parameters 'hub.mode' and 'hub.url' in the request body. The parameter hub.mode is set to 'publish' and the hub.url is set to topic URL that is updated.

The Hub then accepts the POST request and fetches the new content by sending a GET request to the topic URL. After fetching the content the Hub determines whether the feed has changed. The Hub would then send this information about the changes to each subscriber.

Subscribing

The Subscriber initiates its subscription by sending a POST request to the Hub URL. The Content-Type header must be set to application/x-www-form-urlencoded and it should contain the following parameters in the request body:
  • hub.mode - set to 'subscribe'
  • hub.callback - subscribers callback URL where the notifications should be delivered by the Hub.
  • hub.topic - the topic URL to which the subscriber wishes to subscribe
  • hub.verify - it can be either sync/async. 
    • sync when the verification request must occur before the subscription request's HTTP response is returned.
    • async when the verification request may occur at a later point after the subscription request has returned.

Verifying the subscription:

The Hub on receiving a subscription request verifies the same by sending a GET request to the subscriber's callback URL. The request contains the following query strings:
  • hub.mode - subscribe or unsubscribe depending on what was set in the original request.
  • hub.topic - the topic URL given in the subscription request.
  • hub.challenge - a random string.  
The subscriber's callback URL should respond to this request by echoing the hub.challenge string in response.

Code:

Registering the Publisher with the Hub:

The Publisher and Subscriber can be registered at pubsubhubbub.appspot.com and it is a one time activity. However, one can do the same programmatically:

<cfset machineIP = CreateObject("java", "java.net.InetAddress").getLocalHost().getHostAddress()> <cfhttp method="POST" url="http://pubsubhubbub.appspot.com" result="pub_result> <cfhttpparam type="header" name="Content-Type" value="application/x-www-form-urlencoded"> <cfhttpparam type="url" name="hub.mode" value="publish> <cfhttpparam type="url" name="hub.url" value="http://#machineIP#/ZeusTutorial/pubsubhubbub/example/Publisher.cfc?method=getFeed"> </cfhttp> <cfif #pub_result.Responseheader.Status_Code# eq 204> Publisher registered successfully <cfelse> Publisher failed to register returned #pub_result.Responseheader.Status_Code# </cfif>

The Hub responds with a '204 No content' if the publishers feed is successfully registered.

Publishing content:

A form accepting the post title and description:
publisher_form.cfm:
<cfparam name="FORM.feedTitle" default="" > <cfparam name="FORM.feedDescription" default="" > <cfif FORM.feedTitle NEQ "" AND FORM.feedDescription NEQ ""> <cfset publisherObject = createObject("component","Publisher") > <cfset publisherObject.publish_update(FORM.feedTitle,FORM.feedDescription) > </cfif> <form action="publisher_form.cfm" method="post"> Add a new post here:
Title: <input name="feedTitle" type="text" style="width:300px">
Description:
<textarea name="feedDescription" rows="5" cols="50" ></textarea>
<input type="submit" value="Submit"> </form>

A ping notification is sent to the Hub, to notify of the new content. The function publish_update does that:
<cffunction name="publish_update" access="remote" returntype="String"> <cfargument name="feedTitle" required="true"/> <cfargument name="feedDescription" required="true"/> <cfscript> if(!isDefined("application.feedQuery")) { application.feedQuery = queryNew("title,description,pubdate"); } queryAddRow(application.feedQuery, 1); querySetCell(application.feedQuery, "title", '#arguments.feedTitle#'); querySetCell(application.feedQuery, "description", '#arguments.feedDescription#'); querySetCell(application.feedQuery, "pubdate", '#DATEFORMAT(now(), "mm/dd/yyyy")#'); </cfscript> <cfhttp method="POST" url="http://pubsubhubbub.appspot.com" result="new_content"> <cfhttpparam type="header" name="Content-Type" value="application/x-www-form-urlencoded"> <cfhttpparam type="url" name="hub.mode" value="publish"> <cfhttpparam type="url" name="hub.url" value="http://#machineIP#/ZeusTutorial/pubsubhubbub/example/Publisher.cfc?method=getFeed"> </cfhttp>

The Hub then fetches the feed from the mentioned URL (hub.url). Here it is the getFeed method in Publisher.cfc:

<cffunction name="getFeed" access="remote"> <cfscript> /* Feed metadata structure */ feedMetaData = structNew(); feedMetaData.author = arrayNew(1); //arrayAppend(feedMetaData.author,{name:'Sagar Ganatra',email:'sagar@sagarganatra.com'}); feedMetaData.encoding = "UTF-8"; feedMetaData.link = arrayNew(1); //arrayAppend(feedMetaData.link,{href:'http://pubsubhubbub.appspot.com',rel:'rel'}); feedMetaData.title = structNew(); feedMetaData.title.type = "text"; feedMetaData.title.value = "Sagar's Kitchen"; feedMetaData.updated = "#now()#"; </cfscript> <cfset colMap = {publishedDate="pubdate", title="title", content="description"}> <cffeed action="create" query="#application.feedQuery#" properties="#feedMetaData#" columnmap="#colMap#" xmlvar="xmlResult"> <cfcontent type="text/xml" reset="true"> <cfoutput>#xmlResult#</cfoutput> </cffunction>

Registering a Subscriber with the Hub:

The Subscriber can subscribe to the feed by specifying the topic URL in the request body:

<cfset machineIP = CreateObject("java", "java.net.InetAddress").getLocalHost().getHostAddress()> <cfhttp method="POST" url="http://pubsubhubbub.appspot.com" result="sub_result"> <cfhttpparam type="header" name="Content-Type" value="application/x-www-form-urlencoded"> <cfhttpparam type="url" name="hub.mode" value="subscribe"> <cfhttpparam type="url" name="hub.verify" value="sync"> <cfhttpparam type="url" name="hub.topic" value="http://#machineIP#/ZeusTutorial/pubsubhubbub/example/Publisher.cfc?method=getFeed"> <cfhttpparam type="url" name="hub.callback" value="http://#machineIP#/ZeusTutorial/pubsubhubbub/example/subscriber.cfc?method=receiveFeed> </cfhttp> <cfif #sub_result.Responseheader.Status_Code# eq 204> Subscriber registered successfully <cfelse> Subscriber failed to register. Returned <cfoutput>#sub_result.Responseheader.Status_Code#</cfoutput> </cfif>

Subscribing

As mentioned earlier, Hub checks the Subscribers' intent by sending a GET request to the callback URL. The Subscriber is then required to respond, by echoing back the 'hub.challenge' parameter present in the URL:
<cffunction name="receiveFeed" access="remote" returnformat="plain" returntype="string" output="false"> <cfheader name="Content-Type" value="text/plain"> <cfif structKeyExists(URL, "hub.challenge")> <cflog text="#url['hub.challenge']#"> <cfreturn #url['hub.challenge']> <cfelse> <cfset feeddata="getHTTPRequestData().content"> <cfset feeddata="feeddata" feedsource.xml="feedsource.xml" filewrite="filewrite" ram:="ram:" trim="trim"> <cffeed action="read" query="feedReceived" source="ram:///feedSource.xml"> <cfdump output="console" var="#feedReceived#"> <cfheader statuscode="200"> <cfreturn> </cfif> </cffunction>
As seen in the above code the feed is read in else part. One can store the read content in a database for later retrieval or send the same over a websocket to the clients so that it can be read live.

Who is using PubSubHubBub?

Google products - Google Alerts, FeedBurner, Blogger and Google Reader are using PubSubHubBub.

Reference:

Project Home - http://code.google.com/p/pubsubhubbub/
Protocol Basics - http://pubsubhubbub.googlecode.com/svn/trunk/pubsubhubbub-core-0.3.html

Oct 6, 2011

Steve Jobs - An insanely brilliant man passes away

Today when I woke up and switched on the Television to see what's making the news; I heard about Steve Jobs death. For the first time in my life, I'm feeling very sorry for a tech giant who passed away. Steve was an extraordinary human being. He kissed success not just once but many times. He changed the way we experience technology. His charisma, passion and more importantly desperation to do something great is matchless.

Oct 3, 2011

Building resposive Web applications with HTML5 Web Workers

One of the key aspects of building web applications that deliver great user experience is to build applications that are highly responsive. Browser vendors are trying to improve the speed of their JavaScript engines and are enabling the web applications to perform well. Since JavaScript was introduced, there has been no way to execute the code outside of the browser UI thread i.e. it has remained single threaded. The Web Workers API introduced in HTML5 enables web applications to run scripts in the background, independent of the UI thread.

The performance of a web application can be greatly improved by using Web Workers since each worker would spawn its own thread. These threads can be used to perform computationally intensive tasks in the background without affecting the performance of the entire application.

Sep 22, 2011

Merging password protected PDF files in ColdFusion

In ColdFusion, CFPDF tag can be used to perform several PDF related operations such as adding a watermark, generating thumbnails, deleting pages, merging documents and securing a PDF with password. Today I wanted to merge all my bank statements into a single PDF document, such that only the first page from each document containing the summary of the statement is present in the merged document.

Sep 20, 2011

An odd behavior with localStorage events in HTML5

Today I was looking into web storage (localStorage) feature introduced in HTML5. Most of the modern browsers provide means through which key/value pairs can be securely stored and retrieved for later use. Browser cookies can indeed be used for the storage of persistent data but are limited in capacity. Also with cookies, the data is transmitted in every HTTP request thereby making the web applications run slow. Unlike cookies, in local storage there is no limit on the size of the data and it is never transmitted to the web server unless an attempt is made to send it manually. Whenever the data in the storage area changes a 'storage' event is fired. This event is fired whenever the methods setItem(), removeItem(), or clear() are called on the localStorage object.


However, when I tried to use these methods to update the localStorage area, the storage event never fired:

The methods setItem and clear did change the storage area and I confirmed this by referring to the resources  section in chrome developer tools. This looked very odd, but on referring to the w3c specification I found this: "When the setItem(), removeItem(), and clear() methods are called on a Storage object x that is associated with a local storage area, if the methods did something, then in every Document object whose Window object's localStorage attribute's Storage object is associated with the same storage area, other than x, a storage event must be fired". This meant that, the storage event would be fired in any other window\tab which used the same storage area.

Now on opening another tab and on clicking the Add\Clear button the localStorage area was affected and a storage event was fired in the other tab; not on the one that invoked the setItem or clear method. In a way this makes sense because the invoking window would already know of event and would perform the necessary action. Windows that share the same storage area would then be notified of the event and can update the DOM or perform the required action.


Sep 15, 2011

A Cloud of Productivity features in ColdFusion Builder

Yesterday at the ColdFusion Developer Week, I had demonstrated the Productivity features in ColdFusion Builder. Here is a cloud of these features: 

Aug 24, 2011

Speaking at Adobe ColdFusion Developer Week

The Adobe ColdFusion Developer Week is here and is scheduled from 12th of September to 16th of September 2011. I'm pleased to announce that I'll be speaking on Wednesday, 14th of September and my session title is 'ColdFusion Builder: The Professional IDE to Boost Your Productivity'.

This session would focus on how you can get started with using ColdFusion Builder and productivity features that would enable you to develop ColdFusion applications in no time. I'll also be demonstrating the new features that have been introduced in ColdFusion Builder 2.0.

You can register for the session here - http://www.adobe.com/cfusion/event/index.cfm?event=detail&id=1489920&loc=en_us


Aug 9, 2011

Kiss My App: Collaborating using HTML5 Canvas and WebSockets

The Canvas element introduced in HTML5 is the most talked about feature in HTML5. It allows a developer to draw on a rectangular area and the ability to control each pixel in it. I'm not a very big fan of powerful graphics and animation on the web, however I wanted to try Canvas in conjunction with another popular feature - Web Sockets. The idea is to use the mouse events to draw on the Canvas and then send the coordinates to remote clients using Web Sockets. I have used the pusherapp Web Socket library in my example and this video shows how two clients can play a Tic-Tac-Toe game:

Unable to display content. Adobe Flash is required.


As you can see in this video, the mouse movements made on the canvas will draw lines on it and also cause lines to be drawn on another browser window.

Jul 19, 2011

Using Google Maps Places API and ColdFusion's CFMAP to render places of interests

Google announced the Places API recently at Google I/O (2011) and I was looking into this, to see how this API can be used in conjunction with ColdFusion maps created with CFMAP. The Places API can be used to retrieve place information which includes:
  • Places of interests such as parks, restaurants, hospitals which are nearby to the users location.
  • More detailed information on the place, such as the address, phone number etc,.
The API can also be used to perform check-in at a particular place and to add\delete a place. These check-ins can then be used to evaluate the popularity of the place. In this post I'll explain how to retrieve the places of interests and displaying the same on a ColdFusion map using CFMAP.

Jul 8, 2011

Custom validation messages for HTML5 Input elements using the constraint validation API

HTML5 has introduced several input types such as EMAIL, URL, RANGE, SEARCH, DATE, TIME, etc,. Most of the modern browsers have implemented them and are ready to be used in a HTML document. Another exciting feature introduced in HTML5 is the form validation. Instead of writing JavaScript to validate users input, browsers can now validate it and show an appropriate message if the validation fails. The validation message is shown in line with the field for which the validation has failed. The default error message is shown when the validation fails. In this post I'll explain how these error messages can be changed.

Jul 7, 2011

Submitting Form using FormData object in HTML5 using XmlHttpRequest Level 2

The other day I had posted on uploading a file using XmlHttpRequest 2 and tracking the progress of the file upload process using the progress event on XHR2 object and the progress tag. Another enhancement added to the XHR2 specification is the introduction of FormData object. Using the FormData object, one can create a set of key-value pairs and send them as form data in a XHR request. The FormData object is passed in the send() method of the XHR object:

Jun 20, 2011

Auto Insertion of Tag attributes and Function arguments in ColdFusion Builder 2

The Editor is the most important feature in an IDE and the code assist features in the Editor helps in developing applications quickly and hence help in increasing the productivity. One of features is the 'auto insertion of tag attributes'. Most of the tags in ColdFusion have a mandatory attribute, for example the attribute 'name' is mandatory when using the cffunction tag. In ColdFusion Builder 2, these attributes are auto inserted i.e. when a user types in the cffunction tag and invokes code assist (using CTRL + SPACE) the name attribute is auto inserted.

auto insertion also works for function arguments wherein the required arguments are auto inserted.

Auto Insertion of Tag attributes

As explained above, the mandatory attributes are auto inserted whenever the code assist is invoked for tags such as cffunction:


In the above picture, code assist for cffunction is invoked and the tag is selected from the list. This would auto insert the required attribute 'name':


There are some tags such as cfpdf, cfimage wherein a few attributes become mandatory when one of the attributes' value is specified. For example, in case of cfimage when the action attribute is specified as 'convert', the attributes destination and source become mandatory and are auto inserted:


Now on selecting the action attributes' value as convert, the attributes destination and source are auto inserted:


If the user selects action attributes' value as rotate, then the attributes angle and source are auto inserted:


Another thing to note here is that, after inserting the required attributes the cursor is positioned such that one can go about specifying the next attributes' value.

auto Insertion of required function arguments

Whenever one tries to invoke a built-in function or a user defined function the required arguments are auto inserted. For example, consider a function foo which takes three arguments, of which the first two arguments are mandatory:

When this function is invoked using code assist, the required arguments are auto inserted. As seen above, arguments arg1 and arg2 are marked as required and are auto inserted when the function is invoked. After inserting the required arguments the first argument is selected so that the user can go about specifying a value for the argument. The tooltip here shows the list of arguments that the function accepts along with the argument type. The last argument - arg3 is marked optional and is surrounded by square brackets indicating that it is optional. 

Jun 17, 2011

De-obfuscating javascript code in Chrome Developer Tools

I had blogged about JavaScript debugging with Chrome Developer Tools some time back, wherein I have explained how these developer tools can help in debugging javascript code. Today Google Chrome 12 was released and my Chrome browser was updated to this version. As with every release, there have been some improvements made on performance, usability etc,. One feature that stood out for me is the ability to De-obfuscate the javascript code.

What is Minification?

Minification is the process of removing unnecessary characters such as white spaces, comments, new lines from the source code. These otherwise would be added to make the code more readable. Minifying the source code helps in reducing the file size and thereby reducing the time taken to download the file. This is the reason why most of the popular javascript libraries such as jQuery are minified. A minified jQuery file is of 31 KB in size where as an uncompressed one is about 229 KB. Unfortunately, debugging minified javascript files is an impossible task.

With the latest version of Google Chrome one can choose to de-obfuscate the javascript code right with in the developer tools. This is how the jquery.js file would look before de-obfuscation:



Now, to de-obfuscate the code one can right click on the file and select the 'De-obfuscate Source' option. This would de-obfuscate the javascript code and present the code which is readable and ready to debug:



Update:

This post was written when Chrome 12 was released. In recent versions, this option is available as a button - 'pretty print', at the bottom left corner of the screen. Look for the button with the icon '{ }'.


Jun 8, 2011

Getting notifications of Network Status changes using online and offline events introduced in HTML5

I was working on an online\offline application, wherein I wanted to display a set of records stored in the local database to the user when he goes offline. The only way to determine the network status is to send a XHR request to the server at particular time intervals (polling). If the server responds back with some data it is understood that the user is online. However, I came across two event listeners 'ononline' and 'onoffline' which are triggered when the network status changes.

Jun 2, 2011

ColdFusion's CFDIV tag can be used to output HTML5's semantic tags

HTML5 has introduced several semantic tags such as HEADER, FOOTER, SECTION, ARTICLE, ASIDE, NAV etc,. The rationale behind creating these structural tags is to divide the web pages into logical parts with tags that are descriptive of the type of content they contain. Before HTML5 the div tags were used in creating blocks of content in a HTML document.

Recently, I was having a conversation with one of my team members from whom I learnt that the CFDIV tag can be used to output these semantic tags.

The CFDIV tag has an attribute 'tagname'. This attribute can be used to specify the HTML container tag i.e. one can specify tagname="header" to output the header tag. Similarly the tagname attribute can be used to specify other HTML5 semantic tags.

Why should I use CFDIV tag to output the semantic tags?

Well, this is an obvious question you are likely to ask yourself before you write the CFDIV tag. It is not so obvious to one who uses CFDIV tag in their day to day development because CFDIV tag comes with an attribute bind, which is used to specify a bind expression that returns the container contents. One can dynamically populate the tag contents by specifying the bind expression which can be a CFC function, a URL or even a javascript function. You can refer to the CFDIV tag documentation here.

May 13, 2011

Drawing paths on Google Maps, the Indiana Jones way

I was looking into the Google Maps API the other day and came across some APIs which are really cool. I came up with a use case to show path from the current location to a particular destination entered by the user. I was also trying to achieve that Indiana Jones like effect on the map i.e. to show an animation of the path being drawn on the map.


The idea here is to show the moving path until the destination is reached and also to pan the map accordingly.

Unable to display content. Adobe Flash is required.

As seen in the video, a marker is added to the map specifying my current location (Bangalore, India). The current location data is retrieved using the HTML5’s Geolocation API. Once the latitude and longitude information are available, a marker can be added to the map. You can now enter one of your favorite destinations in the text box provided and click the Submit button to see a path drawn from your current location to the destination. The path is drawn using the Google maps ‘Polyline’ API.

May 9, 2011

JavaScript debugging with Chrome Developer Tools and some tips\tricks

Last Friday I was having a conversation with Ben Nadel and Jonothan Joyce on Twitter about examining the content of a JavaScript object. While the firebug add-on for Firefox comes in very handy in examining the request\response header and for various other internals, I can’t really debug the JavaScript code by adding breakpoints. I use Google’s Chrome browser for my day to day web application development. Both Chrome and Safari provide ‘Developer tools’ which help the user not only in debugging the JavaScript code but also in examining the content of an object at any point in time by providing watch expressions. What I like about debugging in Chrome is that it is very much similar to how I debug my server-side code using ColdFusion Builder or Eclipse. This certainly reduces the learning curve to understand debugging in a browser. However, Chrome has more to give when it comes to debugging web applications.

In this post I’ll explain how Google Chrome can help you debug web applications and several other internals.

Apr 27, 2011

File upload and Progress events with HTML5 XmlHttpRequest Level 2

The XmlHttpRequest Level 2 specification adds several enhancements to the XmlHttpRequest object. Last week I had blogged about cross-origin-requests and how it is different from Flash\Silverlight's approach.  With Level 2 specification one can upload the file to the server by passing the file object to the send method. In this post I'll try to explore uploading file using XmlHttpRequest 2 in conjunction with the progress events. I'll also provide a description on the new HTML5 tag - progress which can be updated while the file is being uploaded to the server. And of course, some ColdFusion code that will show how the file is accepted and stored on the server directory.

Apr 21, 2011

HTML5 XmlHttpRequest 2 v/s Flash\Silverlight approach to cross-origin requests

A few days back I had posted on XmlHttpRequest Level 2, describing how cross-origin requests can be achieved. A few folks on my team asked me how different it is from Flash\Silverlight's approach to achieve cross domain request\response with crossdomain.xml. The approach that these plugins take to send a request and receive a response is completely different from that of XmlHttpRequest's approach.

Apr 18, 2011

HTML5 XmlHttpRequest 2 - Cross origin request

HTML5 specification has introduced a few enhancements for XmlHttpRequest object and one of them is the ability to make cross-origin request. That is, a host can send a XmlHttpRequest request to another host and receive a response in return. On the server-side, a check can be made to see whether the request can be accepted from the given origin. In this post I'll try to explain how this can be done using ColdFusion.

Client side:

On the client side, a XmlHttpRequest object is created and then a GET request is made to the remote server.

 var client = new XMLHttpRequest();  
client.onreadystatechange = readyStateChangeHandler;  
client.open("GET","http://{remote-address}/{path-to-file}.cfm",true);  
client.send();       

For example, say example.com wants to get a response from another domain say abc.com, then as observed from the above code the request would look like:


client.open("GET","http://abc.com/dir1/foo.cfm",true);  

Server side:

When a request is sent to the server, the request header would contain a key ORIGIN whose value will be the domain name from which the request was made. In this case the value would be example.com. The server side code can then perform a check to see whether the request origin belongs to the list of origins from which the request can be accepted.

 <cfif structKeyExists(getHTTPRequestData().headers,"origin") >   
    <cfset origin = getHTTPRequestData().headers.origin />   
    <cfif origin eq "http://example.com">   
      <cfheader name="Access-Control-Allow-Origin"   
         value="http://example.com">   
      <cfoutput>#timeFormat(now(),"medium")#</cfoutput>   
    </cfif>   
 </cfif>   
As seen from the above code, the response header ACCESS-CONTROL-ALLOW-ORIGIN is set to allow cross-origin requests from example.com. This now enables requests from example.com to be served from abc.com. 



Apr 7, 2011

Navigation enhancements in ColdFusion Builder 2.0

Do you spend a lot of  time scrolling large files, just to find out the next function definition in place or to figure out the end\start of a tag? If your answer is YES, then why don’t you try the Navigation enhancements in ColdFusion Builder 2.0?
ColdFusion Builder comes to you with three types of Navigation enhancements:
-         Code Navigation
-         Smart Tab Navigation
-         Jumping to matching tag.

Code Navigation

Code Navigation is all about navigating to the next function definition in place. Imagine a CFC containing various cffunction tags. It is a time-consuming task to keep scrolling and keep an eye on the file to get to the next cffunction tag. ColdFusion Builder 2.0 provides a shortcut key CTRL + SHIFT + DOWN to navigate to the next function definition. And to navigate to the previous function definition, you can use the shortcut CTRL + SHIFT + UP.

Code Navigation works in conditional statements as well. Consider an example of a cfif-cfelseif-cfelse conditional statement. If the cursor is placed, say at the start tag and if this particular conditional statement has several conditions in it, then on pressing the shortcut key, the next condition in place is highlighted. That is, on placing the cursor at the start of the cfif tag and pressing the shortcut CTRL + SHIFT + DOWN, the next cfelseif condition is highlighted.

Smart Tab Navigation

Smart Tab navigation is about navigating to the next attribute value. The shortcut key for this is CTRL + ]. On pressing the shortcut key, the next attribute value is highlighted. This works in script style code as well, wherein the function arguments are also highlighted.

Jump to matching tag

If you have several nested cfif tags, it becomes very difficult to find out the end of a particular cfif tag. ColdFusion Builder 2.0 provides the shortcut CTRL + ALT + M, which shifts the cursor position to end of the tag. If the cursor is placed at the end tag, then on pressing the same shortcut key the cursor position shifts to the start tag.

Summary:
  • Code Navigation - Navigate to the next function definition or the next condition. Shortcut- CTRL + SHIFT + DOWN \ UP.
  • Smart Tab Navigation - Navigate to the next attribute value or arguments (cfscript). Shortcut- CTRL + ] \ [.
  • Jump to matching tag - Jump to the start or end tag. Shortcut- CTRL + ALT + M.

    Mar 14, 2011

    Tag replace - Actions in ColdFusion Builder

    Tag search is that one powerful feature in ColdFusion Builder 2.0 which allows you to search for tags that match some criteria. Also, there are various actions that the user can perform once the tag is found. Actions such as
    •  'Replacing the tag block' with some text,
    •  'Removing the Tag block', 
    •  'Setting an attribute', 
    •  'Removing an attribute',
    •  'Adding text before the tag block' and
    •  'Adding text after the tag block'. 
    In this post I'll explain how these actions can help you increase your productivity in your day to day application development.

    Action - Setting an attribute

    Consider a use-case where you would like your ColdFusion application to be available to other web clients such as a HTML client or a FLEX client. In these cases you will have to update the cffunction's access attribute to remote. Updating each and every function definition can be a time consuming task. With the action Set attribute one can specify the attribute that you would like to update with the given value:


    As we can see in the above screenshot, a condition 'cffunction tag with attribute access is Any value' is specified (i.e. the tag search engine would search for cffunction tags whose access attribute will be any value). The action selected is Set attribute with attribute access selected with its value set to remote. On clicking 'Replace All', all cffunction tags in the CFC will now have the access attribute set to remote. How easy was that? Gone are the days when you had to go through the entire file and update the tag attributes where ever required.

    If you specify an attribute which doesn't exist, then the attribute would be added to the tag definition. Action Set Attribute is used for both adding and updating the tag definitions.

    Action - Remove attribute

    Action Remove attribute is used to remove an attribute from the tag. So if you would like to remove an attribute, say output attribute of cffunction tag, then select Remove attribute as the action and specify the attribute that you would like to remove:


    Actions - Adding text before and after the tag block

    While editing a CFC containing various cffunction tags, there are times when you would like to add a generic comment before the function definition, stating its description. Also you would want to add a comment stating the end of the function tag block at the end of the cffunction tag. With the new Tag search, you can specify the tag as cffunction and then add a condition (if required) and click 'Add'. Now in the Action list, select Add before Tag and specify the text that you would like to add. In this case, it would be a comment as shown in the picture below:


    Click on Replace All and you will see that the comment is added before the tag block.

    Similarly, in case of Adding text after the tag block, select Add after tag and specify the text that you want to add after the function definition:


    Again, click 'Replace All' to add the comment at the end of every function definition.

    Actions - Replace tag block and Remove tag block


    Other actions provided include Replacing a tag block and Removing a tag block. As the name suggests, on selecting the action Replace tag block, the tag block is replaced with the text that the user has provided:


    Similarly if you would like to remove the tag block, then select the action Remove tag block:


    All the actions mentioned above can be performed in all the scopes. Please refer to my previous post where in I have describe various scopes available for both text and tag search. 

    Mar 12, 2011

    A cheat sheet of keyboard shortcuts in ColdFusion Builder

    In my last post I have explained about keyboard shortcuts in ColdFusion Builder 2.0. This blog post contains a list of all shortcut keys and I have listed these keyboard shortcuts based on the categories that it falls into. Well, this post was not planned since users can easily get to know the keyboard shortcuts by navigating to the preferences (ColdFusion -> Profiles -> Keys). However, I met Joshua at Scotch on the rocks in Edinburgh and he suggested that it would be nice to have the list of keyboard shortcuts handy. So this post is for those who would like to have the list with them and refer it whenever required.


    Keyboard shortcuts for inserting text:

    These are the keyboard shortcuts which are used to insert some text into the editor:

    Command Keyboard shortcuts on Windows Keyboard shortcuts on Mac
    Insert anchor tag CTRL + T, L CMD + T, L
    Insert bold tag CTRL + T, B CMD + T, B
    Insert br tag CTRL + T, R CMD + T, R
    Insert cfabort CTRL + T, A CMD + T, A
    Insert cfdump CTRL + T, D CMD + T, D
    Insert cfscript block CTRL + T, S CMD + T, S
    Insert cfset CTRL + T, = CMD + T, =
    Insert HTML comment CTRL + T, / CMD + T, /
    Insert Italic tag CTRL + T, I CMD + T, I
    Insert nbsp tag CTRL + T, N CMD + T, N
    Insert p tag CTRL + T, P CMD + T, P
    Insert strong tag CTRL + T, K CMD + T, K
    Wrap in ## CTRL + T, H CMD + T, H
    Wrap in cfoutput CTRL + T, O CMD + T, O
    Wrap in try catch CTRL + T, T CMD + T, T
    Wrap/Unwrap in CF comment CTRL + T, M CMD + T, M
    Wrap/Unwrap in CF script comment CTRL + SHIFT + 8 CMD + SHIFT + 8
    Wrap in double quotes CTRL + SHIFT + ' CMD + SHIFT + '
    Wrap in single quotes CTRL + ' CMD + '

    Keyboard shortcuts for invoking wizards:

    There are various wizards in ColdFusion Builder, now you can invoke these wizards using a keyboard shortcut:

    Command Keyboard shortcuts on Windows Keyboard shortcuts on Mac
    Add CF Server CTRL + ALT + W, A CMD + ALT + W, A
    Import CF Project CTRL + ALT + W, I CMD + ALT + W, I
    Launch RDS Query Builder CTRL + ALT + W, R CMD + ALT + W, R
    New CF Project CTRL + ALT + W, P CMD + ALT + W, P
    New CFC CTRL + ALT + W, C CMD + ALT + W, C
    New CFI CTRL + ALT + W, W CMD + ALT + W, W
    New CFM CTRL + ALT + W, M CMD + ALT + W, M
    SQL Editor CTRL + ALT + W, S CMD + ALT + W, S


    Keyboard shortcuts for Extensions:

    Command Keyboard shortcuts on Windows Keyboard shortcuts on Mac
    Import Extension CTRL + SHIFT + E, M CMD + SHIFT + E, M
    Install Extension CTRL + SHIFT + E, I CMD + SHIFT + E, I
    Reload Extension CTRL + SHIFT + E, R CMD + SHIFT + E, R

    Keyboard shortcuts for various Editor features:

    Navigation enhancements:

    Command Keyboard shortcuts on Windows Keyboard shortcuts on Mac
    Go To Next Member CTRL + SHIFT + DOWN CMD + SHIFT + DOWN
    Go To Previous Member CTRL + SHIFT + UP CMD + SHIFT + UP
    Jump To Next Attribute Value CTRL + ] CMD + ]
    Jump To Previous Attribute Value CTRL + [ CMD + [
    Jump to Matching tag CTRL + ALT + M CMD + ALT + M

    Other Editor features:

    Command Keyboard shortcuts on Windows Keyboard shortcuts on Mac
    Launch in External Browser CTRL + ALT + E CMD + ALT + E
    Lowercase CTRL + SHIFT + L CMD + SHIFT + L
    Uppercase CTRL + SHIFT + U CMD + SHIFT + U
    Select Tag Block CTRL + ALT + B CMD + ALT + B
    Toggle Folding at Selection CTRL + ALT + F CMD + ALT + F
    Tag Editor CTRL + SHIFT + T CMD + SHIFT + T

    You can also download the pdf containing this list of keyboard shortcuts from http://tinyurl.com/4uztbe2

    Mar 11, 2011

    Forget the mouse, keyboard shortcuts are here - ColdFusion Builder

    ColdFuison Builder 2.0 is all about productivity, it has introduced a lot of keyboard shortcuts, about 42 of them. Shortcuts have been provided for inserting text, invoking wizards, shortcuts for all new editor features and shortcuts for Extensions. Want to define a keyboard shortcut for a piece of code? Possible. Not only that, you can also Export and Import the keyboard shortcuts, so that you need not redo the task of defining a list of keyboard shortcuts on a different installation.

    What comes with ColdFusion Builder 2.0?

    You get 42 keyboard shortcuts and I know remembering all of these 42 keyboard shortcuts seems to be a daunting task, but the way these keyboard shortcuts have been designed doesn't require you to remember each and every shortcut. The keyboard shortcuts have been grouped into three categories: Insert options, Wizard options and the Extensions options. Each of these categories start with a key combination. For example the Insert options start with CTRL + T and when you press this key a list of keyboard shortcuts will be shown at the bottom right corner of the screen. The same goes with Wizards (CTRL + ALT + W) and Extensions (CTRL + SHIFT + E).

    You can refer to all the keyboard shortcuts by navigating to Windows -> Preferences -> ColdFusion -> Profiles -> Keys.


    This list also includes some special keyboard shortcuts, these are used to perform some specific editor functionality. For example the shortcut key for 'Jump to the matching tag' is CTRL + ALT + M, 'Code Folding' it is CTRL + ALT + F. It is easy remember these as well; M for 'Matching tag' and 'F' for 'Code Folding'.

    Example:
    Press CTRL + T and you should get a list of keyboard shortcuts at the bottom right corner of the screen:


    As you can see the above list shows all the Insert options and all of them start with the key combination CTRL +T. Now to insert say a cfscript tag, press CTRL + T and then press S. Please note it is not CTRL + T + S, one is required to press CTRL + T and then press S. Also, one need not wait for the popup to come up, just press the associated key and the action would be performed.

    It is also possible to change the key binding for any of these keyboard shortcuts. Navigate to the Keyboard shortcut preferences, click on the shortcut key that you want to change and update the key binding in the section below the list.

    Define your own keyboard shortcut

    To define your own keyboard shortcut navigate to the keyboard shortcut preferences and click on 'Add' button. This would enable the section for defining your shortcut key, enter any name, provide a description (not mandatory) and then provide the key binding. If the provided key binding conflicts with any of the key bindings then the conflict section would be shown listing the shortcut keys with which the key binding conflicts. User will not be able to save the shortcut key until the conflicts are resolved. After providing a valid key binding, provide the text that you would like to insert and then click the 'Save' button. This would save the custom key binding and the same would be shown in the list.

    It is also possible to define the cursor position once the text is inserted i.e. while providing the 'Insert text' if one adds the macro $${CP}, the cursor would placed at this position.

    For example, if the 'Insert text' is say

    $${CP}

    and once the text is inserted the cursor would be placed at $${CP}.

    Export and Import Keyboard shortcuts

    If you have defined several keyboard shortcuts, it would be a big pain to do the same on a different installation. However, with the Export\Import functionality one can export the keyboard shortcut definitions to a csv file and import the same in a different installation.

    Mar 9, 2011

    Quick Fix in ColdFusion Builder

    Quick Fix is another interesting feature introduced in ColdFusion Builder 2.0. The CFML Editor now provides corrections to the problems found in the file that you are editing. The Editor tries to resolve the CFCs specified at various places i.e. in createObject function, the new operator or the ones specified in the tags cfinvoke\cfobject. The Editor also tries to resolve the functions using CFC introspection. Now if you have declared a CFC or a function which doesn't exist, then the CFML Editor instead of showing an error in document provides Quick Fix suggestions.


    Quick fix suggestions for components:


    As shown in picture above, the CFML Editor was not able to resolve the component 'Component1' and instead of showing an error, the Editor has shown a yellow marker indicating that a quick fix suggestion is available. On clicking the yellow marker, a list containing suggestions are shown.
    On selecting the first suggestion, the component will be created in the same directory as the cfm file. The user need not invoke the New CFC wizard. Instead, the IDE will create the component on users' behalf. 
    On selecting the second option, the component would be created right under the webroot of the associated server. If the server is not associated with the project, then this suggestion would not be shown.
    The third option would create the component in a directory location specified by the user.

    Similarly quick fix suggestions would be shown for the tags cfinvoke and cfobject. Quick fix suggestions are also shown if the Editor is not able to resolve the components mentioned as attribute values to extends or implements in a cfcomponent tag.

    Quick fix suggestions for functions:

    Quick fix suggestions are also provided for functions which are not defined. Taking the above example, once the component is created and when you try to invoke a function which doesn't exist, then the quick fix will suggest you to create a function. 


    On accepting the suggestion, the function would be created in Component1. 

    If one invokes a function with arguments, then the cffunction with arguments would be created. Say if I invoke a function with two arguments 'arg1' and 'arg2' which are of type numeric and string respectively, then a cffunction would be created with two arguments and the type of those arguments will be numeric and string.   That is, arguments will be of the same type as the parameters passed to the function.
    How cool is that... 

    If you are writing a script style code, then the component or the function would be created in script style syntax.


    Mar 6, 2011

    ColdFusion Builder Search\Replace - A new story

    ColdFusion Builder 2 (codenamed 'Storm') the next version of ColdFusion Builder is now public beta and it comes packed with several new features. One of the highlights of this release is the ColdFusion specific Search and Replace feature; CFB is an Eclipse based IDE and the search\replace functionality provided in the 1.0 version of the product (codenamed 'Bolt') used the Eclipse's search and replace functionality. Storm now comes with a separate engine for Search and Replace.
    One can search not only for text but also tags based on the conditions that you specify. The search scope is now widened and users can search over various scopes such as Open documents, Projects, WorkingsetWorkspace, Local directory, Selected Resources and over any of your FTP\RDS connections. And that's not it, you can also perform certain actions on the matches found. In this post I'll be providing an overview and will try to deliver more complex scenarios in the coming posts.



    The Search dialog:


    The search dialog shown above looks very compact and is packed with features. The scope combo box lists various scopes across which search can be performed, by default the 'Current Document' will be set as the scope. The search combo box lists two options Text and Tag. There is text box for entering the string that you would like to search and a text box to replace the matching string. Also, as noted from the above screenshot there are various options provided to perform search. However, you get more options when you switch to other scopes or when you switch to Tag search.

    Tag search:



    When the search scope is changed to Tag search, the ColdFusion search dialog box changes its layout to provide various options which are relevant to the tag you search. After selecting the tag from the list ('Choose Tag'), there are various conditions that the user can select and add to the list.

    Conditions:

    There are various conditions that you can specify to search for tags. Conditions such as With attribute, Without attribute, Containing (Tag\Text), and Not containing (Tag\Text).

    With attribute:


    When the condition 'With attribute' is selected the dialog box also provides attribute matching conditions 'is\is not\containing\does not contain\starts with\ends with'. User can provide the attribute name and the value for the same. If no conditions are added to the list then the file would be searched for the mentioned tag.

    Without attribute:




    When Without attribute is selected an attribute list is shown and this will match all the tags which do not contain the specified attribute.

    Containing Tag\Text:




    Users can now search tags that contain the specified Tag\Text. An example would be to search for cffunction tags that contain cfargument tags.

    Not Containing Tag\Text:




    Similar to containing; the Not containing condition would select those tags which do not contain the specified text\tag.

    Users can specify multiple conditions for tag search. By specifying Any of the conditions an 'OR' operation would be performed by the tag search engine; meaning that if any of the tags match any of the conditions then it would be returned. Similarly with 'All of the conditions' an 'AND' operation would be performed and only the tags matching all of the conditions would be returned.

    Actions:

    The Action section lists everything that you can do with the tag searched and found. Apart from Replace\Remove the tag block you can perform various other actions such as Add Text Before\After the tag block and Set\Remove the attribute.
    I will be explaining more about Actions in my next blog post.

    Mar 3, 2011

    What's new in ColdFusion Builder Storm- picture

    ColdFusion Builder - Storm is public beta and you can download Storm from labs.adobe.com.
    I just completed my session at SOTR and all the new features are on the picture below:

    Jan 8, 2011

    Server sent events with HTML5 and ColdFusion

    There are several ways to interact with the server apart from the traditional request\response and refresh all protocol. They are polling, long polling, Ajax and Websockets (pusherapp). Of all these Ajax and Websockets have been very popular. There is another way to interact with the server such that the server can send notifications to the client using Server Sent Events (SSE). SSE is a part of HTML5 spec: http://dev.w3.org/html5/eventsource/