As mentioned at the end of my last post, i continued exploring the idea of having a custom homepage with content aggregated from different sites on the client side. I tried using the about:blank page of Firefox as the starting point on which to build content, but could not succeed. After googling on this issue i found that doing this is not a good idea, since many sites use the about:blank page to create an empty iframe and then set its source. I also read that doing this could make your site prone to XSS attacks. Maybe thats why Firefox blocked access to it (?)
Then i thought about using Google as my start page. I decided to add a 10-day weather forecast at the top of the screen. Had to do some screenscraping to get this content. Next came news. I decided to use the RSS feeds for this purpose. I came across a site->www.webrss.com that will parse the xml content of the RSS feed and provide it via a javascript call. It also gives you the option of converting the rss feed to html, php or asp call. I added feeds from Google News, Times of India, CNN and BBC. Here is how it looks now (click on the image to get a bigger view):
I decided to hold off on adding mail since that requires authentication.
Here’s the code so far:
// ==UserScript== // @name Homepage // @namespace http://amarphadke.com/userscripts/customhomepage // @include http://www.google.co.in // @include http://www.google.com // ==/UserScript== GM_xmlhttpRequest({ method: 'GET', url: 'http://www.weather.com/outlook/travel/businesstraveler/tenday/44130?from=36hr_topnav_business', headers: { 'User-agent': 'Mozilla/4.0 (compatible) Greasemonkey', 'Accept': 'application/xml,text/xml', }, onload: function(responseDetails) { var startIndex = responseDetails.responseText.indexOf('<div id="tenDayWrap">'); var endIndex = responseDetails.responseText.indexOf('<div id="TFbuttonB">', startIndex); var reqdString = responseDetails.responseText.substring(startIndex,endIndex); reqdString = reqdString.replace(/°/g, "==deg=="); reqdString = reqdString.replace(/ /g, " "); reqdString = reqdString.replace(/<br>/g, "<br/>"); reqdString = reqdString.replace(/\"\" width/g, "\" width"); reqdString = closeImgTags(reqdString); var parser = new DOMParser(); var dom = parser.parseFromString(reqdString,"application/xml"); var tdWraps = getArrayOf(dom,"tdWrap"); var weatherTableHTML = "<table border='0' cellspacing='0' cellpadding='0' width='100%' style='font-size:11px;background-image:url(http://i.imwx.com/web/common/backgrounds/tenday_bkgd.jpg)'><tr>"; for(var i=0;i<tdWraps.length;i++){ var divs = tdWraps[i].getElementsByTagName("div"); var dayOfWeek, date,imgSrc, imgText, high, low ; for(var j=0;j<divs.length;j++){ if(divs[j].getAttribute("class")=="tdDate"){ dayOfWeek = getDayOfWeek(divs[j]); date = getDate(divs[j]); } if(divs[j].getAttribute("class")=="tdForecast"){ imgSrc = getImageSrc(divs[j]); imgText = getImageText(divs[j]); } if(divs[j].getAttribute("class")=="tdTemps"){ high = getHighTemp(divs[j]); low = getLowTemp(divs[j]); } } weatherTableHTML+=renderCol(dayOfWeek, date,imgSrc, imgText, high, low); } weatherTableHTML+="</tr></table>"; document.body.innerHTML = ""; document.title="It's my custom homepage"; document.body.setAttribute("style","margin:0px;"); var weatherDiv = document.createElement('div'); weatherDiv.innerHTML = "<div style='text-align:center;font-weight:bold;font-weight:14px;font-family:Verdana;background-image:url(http://i.imwx.com/web/common/backgrounds/tenday_bkgd.jpg);'>Weather</div>"; var newElement = document.createElement('div'); newElement.setAttribute("style","text-align:center;vertical-align:center;font-weight:bold;font-family:Verdana;"); newElement.innerHTML = weatherTableHTML; weatherDiv.appendChild(newElement); document.body.appendChild(weatherDiv); var newsDiv = document.createElement('div'); newsDiv.innerHTML = "<div style='text-align:center;font-weight:bold;font-weight:14px;font-family:Verdana;background-image:url(http://i.imwx.com/web/common/backgrounds/tenday_bkgd.jpg);'>News</div>"; addWebRSSFeed(newsDiv, 7885); addWebRSSFeed(newsDiv, 7887); addWebRSSFeed(newsDiv, 7888); addWebRSSFeed(newsDiv, 7889); document.body.appendChild(newsDiv); } }); function addWebRSSFeed(parentDiv, feedId){ var feed = document.createElement('iframe'); feed.setAttribute("src", "http://www.webrss.com/get_mysite.php?mysiteId="+feedId); feed.setAttribute("width","300px"); feed.setAttribute("height","400px"); feed.setAttribute("frameborder","0"); parentDiv.appendChild(feed); } function getArrayOf(parentNode, tdClassName){ var tdWraps = new Array(0); var divArrays = parentNode.getElementsByTagName("div"); for(var i=0;i<divArrays.length;i++){ if(divArrays[i].getAttribute("class")==tdClassName){ tdWraps[tdWraps.length] = divArrays[i]; } } return tdWraps; } function closeImgTags(string){ var updatedString = ""; var lastIndexOfImg=0; var endBracketIndex = 0; while((lastIndexOfImg=string.indexOf("<img ", lastIndexOfImg+1)) != -1){ updatedString+= string.substring(endBracketIndex, lastIndexOfImg); var endBracketIndex = string.indexOf(">", lastIndexOfImg); updatedString+= string.substring(lastIndexOfImg, endBracketIndex)+"/"; } updatedString+= string.substring(endBracketIndex); return updatedString; } function getDayOfWeek(tdDateDiv){ return tdDateDiv.getElementsByTagName("a")[0].firstChild.textContent; } function getDate(tdDateDiv){ return tdDateDiv.getElementsByTagName("p")[0].lastChild.textContent; } function getImageSrc(tdForecast){ return tdForecast.getElementsByTagName("img")[0].getAttribute("src"); } function getImageText(tdForecast){ return tdForecast.getElementsByTagName("p")[0].lastChild.textContent; } function getHighTemp(tdTemps){ return tdTemps.getElementsByTagName("strong")[0].textContent.replace(/==deg==/g,"° F"); } function getLowTemp(tdTemps){ return tdTemps.getElementsByTagName("p")[0].lastChild.textContent.replace(/==deg==/g,"° F"); } function renderCol(dayOfWeek, date,imgSrc, imgText, high, low){ return "<td width='10%' align='center'>"+dayOfWeek+","+date+"<div style='background-color:white;width:81px;height:75px; border: 1px solid #F0EBD5;'><br/><img src='"+imgSrc+"' border='0'/><br/></div>"+imgText+"<br/>"+high+", "+low+"</td>"; }
After reading this post, you may ask why build this when there are sites that offer this kind of feature for free (Eg., Google, Yahoo, BBC, etc.,). My answer to that would be ->This customization is being done on the client side. You have more flexibility in terms of what content to display and from what source. Can you imagine iGoogle giving you a widget to read your Yahoo emails? or BBC presenting a news widget on its portal the content of which comes from Times of India? or how easily can you convince Google to build a 10-day weather forecast widget for you on iGoogle?

