Thursday, November 16, 2006

Presenting - Proto.in Widget

I hacked this scriptlet today for proto.in ...

To add the following widget into your blog or webpage ,simply add the following line scriptlet into your html code , to get your own proto.in widget...
<script id="protoWidget" src="http://proto.in/protoWidget/protoWidget.js" type="text/javascript" language="'javascript"></script>

Developer Notes:
I used the following 4 files...
protoWidget.css , protoWidget.js , protoWidget.gif, protoLoad.php


I Initially used iframes and the xmlhttp to read cross domain ,but even though i could get around the infamous ' cross domain same origin ' policy ,couldnt pass the data between the iframe and the parent window . SO ,decided to shift to a dynamic script tag and json format where i spit out the feed xml using php into javascript which was dynamically appended to the dom .A word of caution if you are planning to make your own feed reader ! Dont fall for the unterminated string error .xml as you know will be nicely formatted with elements in different lines ,et cetera . But once you pass this into javascript ,line breaks are a strict NO NO .

Then again ,there 's a hack against this as well. Heres my version of how to retrive cross -domain feed/data without NO hassles of security ,NO browser prompts ,and NO script signing needed. Here you go.(PS: sorry for the code not being aligned properly,but hope u can get a gist of it )

protoLoad.php
var fullXML={bosky:101};

/* reading feed as string into json form */
var _xml={data:'/* pass any site / feed here as querystring. */
if($site){
$fp = fopen($site, "r");
$buffer = "";
// get output in buffer variable
if ($fp) {
while(!feof($fp)) {
$buffer .= fread($fp, 1076);
}
}
$buffer = str_replace("\n","", $buffer);
$buffer = str_replace("\r","", $buffer);
$buffer = str_replace("\t","", $buffer);
$buffer = str_replace("'};

/* ok so now we have the xml string in xml.data . Now to DOM ify it ! */
getXMLTree(_xml.data,'item');

function getXMLTree(xmlStr,nodeName)
{
var xml;
this.load = function (nodeName){
if (window.ActiveXObject)
{
xml = new ActiveXObject("Microsoft.XMLDOM");
xml.async="false";
xml.loadXML(xmlStr);
}
// code for Mozilla, etc.
else if (document.implementation && document.implementation.createDocument)
{
var vParser = new DOMParser();
xml= vParser.parseFromString(xmlStr,"text/xml");
}

if(nodeName!=undefined){
fullXML = xml.getElementsByTagName(nodeName);
}else{
return (xml);
}
}
this.load(nodeName);
}

/* ok so now we have the xml node in fullXML . Now to send it back to client */
parent.window.readData(fullXML);

protoWidget.js
./* client side that initiates the script tag to call protoLoad.php*/

/** METHOD 1 */
** @description This method uses hidden iframe and xmlhttp to read the feed.But it is limited since you cannnot reference data from a child iframe of url location A to the parent window of url location B. You can do this only if you set document.domain explicitly , or the are in the same domain . not very useful !
*/
protoWidget.prototype.readCrossDomain = function(){
this.iF = document.createElement('iframe');
this.iF.id='protoWidgetHost';
var iS = this.iF.style;
iS.border='0px';
iS.width='0px';
iS.height='0px';
this.iF.type='hidden';
this.iF.src = this.crossDomainSrc;
this.add('insert',this.script,this.iF);
}

/** METHOD 2 */
** @description This method uses a dynamically added script tag , which is actually a php file that splits out the feed and puts that into a javascript variable. no securty violations ,no issues . very useful !!!
*/

protoWidget.prototype.readJSON = function(){
var head = document.getElementsByTagName("head").item(0);
var oScript = document.createElement("script");
oScript.setAttribute("src",this.remoteURL);
oScript.setAttribute("id","src1");
this.add('append',head,oScript);
/* makes a call to protoLoad.php here */
}

protoWidget.prototype.add = function(type,addTo,obj){
if(type=='insert'){
addTo.parentNode.insertBefore(obj,addTo);
}else{
addTo.appendChild(obj);
}
}
.
.
.
/* this is called when reading feed is done .in otherwords this is the callback.*/
function readData(_fullXML){
/* thats it ._fullXML is the xml node of the feed ,carry on with the parsing,et cetera . cross browser issue solved . 8 )*/
}

For the full version of the protoWidget.js check it out here .

Oh ,theres no feeling for a geek to substitute writing beautiful code..... 8 )

Keep Clicking,
Bhasker V Kode

Technorati Tags:, , , , , , , , ,