« LfVr: moving navigation box to left side | Main | [Ajax] Hacking Rojo - Ajaxize 'Mark as Read' function »

[Ajax] Hacking Rojo - an Ajax Wrapper for Rojo

Tags: Ajax , Greasemonkey , Rojo

Rojo is a great web-based RSS reader. It supports tagging not only feeds but also article entries. The user interface is neat and well organized. The use of DHTML and CSS makes the site easier reading and more accessible.

As we already knew, Rojo uses a lot of DHTML + Javascript techniques to enhance the user interface. Despite Rojo has the modern design of tagging and social share, it seems not to be an Ajax approach I talked in my previous post, "Hacking Rojo - Rojo is not Ajax? ". Rojo retrieve asynchronous data by remote scripting with iframe, not by calling XMLHttpRequest. There would be a little bit slower when using remote script instead of XMLHttpRequest. Therefore I did a small experiment to replace the iframe remote script by the Ajax way. The Greasemonkey user script can meet my need to override the methods of Remote object in Rojo.

This Greasemonkey user script is a wrapper for Rojo to replace its iframe request by the XMLHttpRequest function. The data retrivial will proceed in background, so the browser won't be seen in loading pages any more. After installing the script, the response of using Rojo should become faster.

Download: rojo.ajax.user.js

Let's take a look at the two original methods of Remote object.

Remote.execRequest = function(resource, callback, callbackArguments) {
    //NOTE: we need to prevent corruption here due to multi-threaded IO and
    //non-blocking UI controls in IE/Mozilla

    this.callback = callback;
    this.callbackArguments = callbackArguments;
    this.waitingForResponse = true;
    this.changeIFrameLocation(resource);
}

Remote.iFrameOnLoad = function() {

    if ( this.callback != null ) {
        var currentCallback = this.callback;
        var currentCallbackArguments = this.callbackArguments;
        this.callback = null;
        this.callbackArguments = null;
        this.resource = null;
        this.waitingForResponse = false;
        if (this.requests.length > 0) {
            var nextRequest = Util.shift(this.requests);
            this.waitingForResponse = true;
            this.execRequest(nextRequest.resource, nextRequest.callback,
                             nextRequest.callbackArguments);
        }
        var iframeContents = Remote.getIFrameContents();
        if (currentCallbackArguments == undefined ||
            currentCallbackArguments == null) {
            currentCallbackArguments = new Array();
        }
        currentCallbackArguments[currentCallbackArguments.length] = iframeContents;
        currentCallback.apply(null, currentCallbackArguments);
    }
}

Now we can override the above two methods by the following new methods with a real Ajax XMLHttpRequest call.

Remote.fakeiFrameOnLoad = function(result) {
    if ( this.callback != null ) {
        var currentCallback = this.callback;
        var currentCallbackArguments = this.callbackArguments;
        this.callback = null;
        this.callbackArguments = null;
        this.resource = null;
        this.waitingForResponse = false;
        if (this.requests.length > 0) {
            var nextRequest = Util.shift(this.requests);
            this.waitingForResponse = true;
            this.execRequest(nextRequest.resource, nextRequest.callback, nextRequest.callbackArguments);
        }

        var iframeContents = result;
        if (currentCallbackArguments == undefined || currentCallbackArguments == null) {
            currentCallbackArguments = new Array();
        }
        currentCallbackArguments[currentCallbackArguments.length] = iframeContents;
        currentCallback.apply(null, currentCallbackArguments);
    }
}

Remote.execRequest = function(resource, callback, callbackArguments) {
    this.callback = callback;
    this.callbackArguments = callbackArguments;
    this.waitingForResponse = true;
//    this.changeIFrameLocation(resource);

    var xmlhttp = new XMLHttpRequest();
    xmlhttp.onreadystatechange = function() {
        if (xmlhttp.readyState==4) {
            if (xmlhttp.status==200) Remote.fakeiFrameOnLoad(xmlhttp.responseText);
        }
    }
    xmlhttp.open('GET', resource, true);
    xmlhttp.send(null);
}

TrackBack

Listed below are links to weblogs that reference [Ajax] Hacking Rojo - an Ajax Wrapper for Rojo:

» [Ajax] Hacking Rojo - Ajaxize 'Mark as Read' function from Yuan.CC Web Experiments
Since my previous work 'an Ajax Wrapper for Rojo' has replaced the iframe remote scripting by XMLHttpRequest, some slow 'loading whole page' transactions of Rojo need remodeling now. Well, I use the term "Ajaxize" which means turning the old-fashioned ... [Read More]

» [Ajax] Hacking Rojo - Ajaxize more of 'Mark as Read' from Yuan.CC Web Experiments
Last time I have Ajaxized a 'Mark as Read' on a single feed to move the HTTP request to background by calling XMLHttpRequest instead of bringing to a new page. The counters of unread entries are reset on LHS... [Read More]

» [Ajax] Hacking Rojo - Adding bits to feeds in Rojo from Yuan.CC Web Experiments
Rojo is lacking of some designs of user friendly. Why am I saying that? Sometimes we need to make an unnecessary click to get some basic but useful information of a feed. While reading stories of a feed, we... [Read More]

» [Ajax] Hacking Rojo - Quick unsubscribe feeds in Rojo from Yuan.CC Web Experiments
In Rojo, you can unsubscribe feeds only within two pages, the page of managing your feed list or the one of viewing the feed profile. Now the rojo.ajax.user.js script injects quick links to let you unsubscribe feeds any time.... [Read More]

» [Ajax] Hacking Rojo - Clearance of All Additions from Yuan.CC Web Experiments
I have been adding some additions to Rojo and keeping this script updated with Rojo. Lately, Rojo slightly changed its HTML layout, so some features of the script failed. I also fixed the compatible problem with Firefox 1.5RC3. Following... [Read More]