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:, , , , , , , , ,

1 comment:

Charles said...

Bosky,
Wow, I've been looking for a way to read an IP from a widget to put it into a tag I can append to the commenter's info. This may well fit the bill. If I can get this to work as I intend, I'll be having a bunch of bloggers using it to help fend off the trolls. Between getting their IP and profile number, it should allow us to determine sock puppets, and redirect the trolls. Great work.