Digital Me

Random contributions to digital noise

Archived Posts

Displaying posts 21 - 28 of 28

New version of Intranet Feed Reader add-on - 0.2.0 is available now. Source code is available here.
The add-on now has improved security by executing JSONP in sandbox instead of running it in chrome. This improvement will stop malicious code served by XML2JSON proxy, there is still possibility that unsafe code might leave sandbox but threat surface is much smaller now. Blog entry about that will follow and will continue to work on ways to improve security so stay tuned.
New version brings support for Atom feeds so now you can use: http://feeds.feedburner.com/blogspot/digitalmihailo as XML Url :) I added some HTML cleansing code as well - in our intranet we are using confluence and some feeds are featuring unclosed img tags. What the code does is using very simple algorithm (and un-optimized) to close unclosed tags and remove closing tags without openning tag. These improvements are implemented by following functions in content/sidebar.js of the add-on source code:
desinfictHtml
runInSandbox
adaptData - for Atom to RSS (we are using RSS to render content)
so give it a look.

Sandbox execution is inspired by Greasemonkey implementation.
Converting Atom dates is inspired by Convert Atom documents to JSON document by IBM.


Testing remarks

For setting up testing environment locally one possible solution would be to download feed's XML and put it to your local web server - url something like: http://localhost/testfeed/somefeed.xml. Using XML2JSON proxy is described in the first post on the Intranet Feed Reader Add-on.

jQuery and dynamic HTML in XUL

Sunday June 08, 2008 @ 11:05 AM (PDT)
There is a problem with doing dynamic HTML in Firefox Extensions using jQuery, actually only if you use XUL windows. This is probably applicable to all JavaScript frameworks that are allowing dynamic manipulation of DOM.
Consider the following example:




<?xml version="1.0"?>
<window id="rootWnd" title="Test"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:html="http://www.w3.org/1999/xhtml" >
<script type="application/x-javascript" src="jquery-1.2.3.js"/>
<script type="application/x-javascript">
function test(){
$("#content").append('&lt;p&gt;test&lt;/p&gt;');
alert('done');
}
</script>
<vbox hidden="false" height="0">
<button label="click me" oncommand="test();"/>
<html:div id="content"></html:div>
</vbox>
</window>




There is nothing special about this code, highlighted text JavaScript should add paragraph to content div and show text "test". That is probably very common statement when using jQuery to change some HTML content (and probably doing something more useful). Nothing special about the code as I said but it does not work. If you try this into web browser it will work though however in XUL it won't.
This example follows a tutorial on adding HTML elements to XUL. It is obvious now that $("#content").append('test') won't work. According to the article it has to be: $("#content").append('test'). Unfortunately it does not work again. The problem is in jQuery.1.2.3.js, more precisely in the line 968:
var tags = jQuery.trim( elem ).toLowerCase(), div = context.createElement("div");
Again if we try to put "html:div" it will not work and now the problem is in the Mozilla's document.createElement implementation which will create the element in the default namespace of http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul since it is XUL document. I think this is not how it should be but non the less it is the way it works so solution to the problem would be:
div = context.createElementNS("http://www.w3.org/1999/xhtml", "html:div")
which will create the element in the correct namespace. Unfortunately it will not work again since exception will be thrown in the line 998: div.innerHTML = wrap[1] + elem + wrap[2]; it does not like html:... part I guess.
So is there a solution? Here it comes:

Solution

If we rewrite the XUL document to look like this:




<?xml version="1.0"?>
<xul:window id="rootWnd" title="Test"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns="http://www.w3.org/1999/xhtml" >
<xul:script type="application/x-javascript" src="jquery-1.2.3.js"/>
<xul:script type="application/x-javascript">
function test(){
$("#content").append('&lt;p&gt;test&lt;/p&gt;');
alert('done');
}
</xul:script>
<xul:vbox hidden="false" height="0">
<xul:button label="click me" oncommand="test();"/>
<div id="content"></div>
</xul:vbox>
</xul:window>




What we are doing here is setting the default namespace to be the XHTML namespace instead of XUL. It requires a bit of rewriting the XUL elements but it will presumably enable us to use any JavaScript framework. however there is another bit that has to be changed in the jQuery script:
line 968 should stand as:
div = context.createElementNS("http://www.w3.org/1999/xhtml", "div")
And of course any createElement calls should be amended.

Another problem

At the end to conclude with another unsolved problem. This will all work if you have control over the html contents you want to change, but if you don't, e.g. showing rss feed, then you might end up with a problem. If you check the namespaces in the XUL document you'll see that namespace is of XHTML and actually the document is XML document. Because of that, sometimes you might end up with error similar to:
[Exception... "Component returned failure code: 0x80004003 (NS_ERROR_INVALID_POINTER) [nsIDOMNSHTMLElement.innerHTML]" nsresult: "0x80004003 (NS_ERROR_INVALID_POINTER)"
Which is Firefox's friendly way to say that your XHTML is invalid. Thanks to this article in Russian (here is the English version, courtasy of the Google language tools, mind that translation is a bit awkward but it can be understood if you badly need it) I managed to decypher the error message.
This message can occure because of many things, unclosed tags, text in elements that are not supposed to have text etc. It can pass in regular browser since browser will do its best to parse whatever you give it but if it ain't proper XHTML it won't work in Firefox. If you have any suggestions on how to clean the HTML to get proper XHTML please let me know.
Just uploaded new version of the Firebug Net Panel History Overlay. The new version is 0.2.1. It adds support for Firefox 3.0.* and adds new menu item Clear History.
I don't know why the addon's main page is not showing the latest version but the file can be downloaded from here, and source code from here. As with the previous version login is required since the addon is in the sandbox. Talking about sandbox, some review/feedback would be highly appreciated so I can nominate it for becoming public. Thanks.

**Update**
The public page of the add on has been updated, seems there is a bit of lag between uploading new version and showing on the site, none the less all links should work.

Intranet Feed Reader - Firefox Add On

Tuesday May 27, 2008 @ 01:33 AM (PDT)
I just ported Michal Bali's iGoogle gadget: Intranet Feed Reader. The add on can be found here. Again, log in is required for download since it is still in sandbox.

The add on adds capabilities to read intranet feeds into your Firefox's sidebar:


More details can be found at this Michal's blog post:
http://blog.decaresystems.ie/index.php/2008/05/20/google-gadget-intranet-feed-reader/

I will just shortly quote the conclusion of the article:
The intranet feed reader gadget can be used as part of a developer’s dashboard. It can display any intranet feed. Most useful might be information necessary for day-to-day work (e.g. current assigned issues in the bug tracking system, changed resources in company’s wiki or version control system).
Here is in short how to setup and use it:
After installation there will be new menu item added to the Firefox's Tools menu - Internet Feed Reader. It has sub menu items Properties and Show Panel, intuitively Properties are setting up the extension and Show Panel is showing sidebar panel with the feed contents.
Parameters of the Properties dialog are:
  • XML Url: required, url of the rss feed you want to follow
  • XML2JSONP Proxy Url: required, url of the XML to JSONP proxy. The extension uses JSONP to display the feed contents so proxy is required to convert XML feed to JSONP. How to setup the proxy for testing the extension is following up shortly
  • cookiesJson: optional, authentication cookie if required by the feed provider
Test the extension
In order to test extension you will need XML2JSONP Proxy. Basic implementation of the proxy by Michal Bali can be found here:
http://michalbali.googlepages.com/xml2jsonp
I did install the Apach Tomcat 6.0 and setup the xml2json.war from the proxy's site. After installation XML2JSONP Proxy Url parameter would look like something like this:
http://localhost:8080/xml2json/Xml2JsonpProxyServlet
Just put any feed url into XML Url, maybe:
http://blog.decaresystems.ie/index.php/author/mbali/feed/
And after setting up the stuff just click on Tools > Intranet Feed Reader > Show Panel.

IMPORTANT!!!
Use only trusted XML 2 JSONP proxy, ideally from your own machine or from your intranet. JSONP works by injecting Javascript into the page thus using untrusted server might cause injection of malicious code and by doing that in the priviledged mode that the extension is working in can cause serious damage to your computer!

Related articles:
http://digitalmihailo.blogspot.com/2008/05/make-jsonp-work-in-firefox-chrome.html

Make JSONP work in Firefox Chrome

Sunday May 25, 2008 @ 04:24 AM (PDT)
I have been doing some Firefox extension and I needed to do some JSONP Ajax call in the sidebar and then show the result. jQuery makes it easy, you do something like:




$.ajax({
type: "GET",
dataType: "jsonp",
url: "http://someurl.com",
data: aRequestData,
cache: false,
error: function (XMLHttpRequest, textStatus, errorThrown) {
// typically only one of textStatus or errorThrown
// will have info
alert("Error occured textStatus=" + textStatus + " errorThrown=" + errorThrown);
},
success: function(data) {
alert('success');
}
});




Plain and simple and it works in browser window, however, to my big surprise it did not work in Chrome, never got to the success alert. After turning on Firebug I got an error from jQuery: head is null. OK, What is JSONP?
How it works is that script is injected into the head element of the HTML document. Source of the script is a link to the external server that is providing customized javascript function call with the retrieved data. Upon receiving data jQuery is deleting that script element.
So head is null indeed since document.getElementsByTag("head") is not returning enything since I don't have head element in my XUL file:



<?xml version="1.0"?>
<?xml-stylesheet href="chrome://browser/skin/browser.css" type="text/css" ?>
<?xml-stylesheet href="chrome://intranetfeedreader/skin/sidebar.css" type="text/css"?>
<!DOCTYPE prefwindow SYSTEM "chrome://intranetfeedreader/locale/intranetfeedreader.dtd">

<page id="sbIntranetFeedReaderSidebar" title="&sidebar.title;"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
>
<script src="jquery-1.2.3.js"/>
<script src="sidebar.js"/>
<vbox flex="1">
<label id="atest" value="&sidebar.title;" />
</vbox>
</page>



So nothing fancy but no head tag. Well lets add head tag and see if we can trick the jQuery:



<?xml version="1.0"?>
<?xml-stylesheet href="chrome://browser/skin/browser.css" type="text/css" ?>
<?xml-stylesheet href="chrome://intranetfeedreader/skin/sidebar.css" type="text/css"?>
<!DOCTYPE prefwindow SYSTEM "chrome://intranetfeedreader/locale/intranetfeedreader.dtd">

<page id="sbIntranetFeedReaderSidebar" title="&sidebar.title;"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
>
<head>
<script src="jquery-1.2.3.js"/>
<script src="sidebar.js"/>
</head>
<vbox flex="1">
<label id="atest" value="&sidebar.title;" />
</vbox>
</page>



And it worked :) I got rid of the error, but still no success alert. To make the long story short: injection of scripts this way is not working in Chrome. It will allow only urls starting with chrome://. Well it should work that way, working from browser window is pretty harmless (well it depends ...) compared to working in chrome where the code has much more privileges and can do some serious damage. I am not really convinced that getting the data this way is really smart thing to do, simply injecting javascript code from another server is scary - I can imagine that it is not too hard to inject whatever harmful code this way.
So I guess one big warning is due for the reminder of the post:

WARNING!!!! The following code should be used only with trusted servers. Ideally only in intranet. Never, never, never use this code with server that you do not trust 100%. Of course you are using this code on your own risk.

Since the injection of the script by purely adding script element to the document does not work in chrome then we have to do the script loading manually. Idea is to download the script ourselves and then execute it ourselves. That is not hard at all, and here is (almost) all the code:



var scriptCollection = document.getElementsByTagName("script");
var reader = new httpReader(scriptCollection[scriptCollection.length - 1].src);

function evaluateJs(aReader){
if(aReader && aReader.mData)
eval(aReader.mData);
}

reader.AsyncLoad(bind(evaluateJs, this, reader));


The code is really simple, firstly we get all the script elements from the document, then we initialize httpReader object with the source of the last script (jQuery is appending it to the head, well keep all your scripts enclosed in the head tag or modify the code to get the correct script). evaluateJs is simply helper function that is calling eval function on the script we get from the server. And at the end we asyncronuosly load the url with the script.

This code executes javascript code as browser would in the normal html document - get the script and then execute it. Some further testing should probably be involved here to check the code we are going to evaluate but anyhow if you plan on using this approach you should really take security seriously into consideration.

The last bit is httpReader, it is simple implementation from the article: Creating Sandboxed HTTP Connections from the developer.mozilla.org. bind functions are based on Firebug code. And the file is here.

Baby boy Luka

Monday May 12, 2008 @ 12:45 PM (PDT)
I just got a baby boy Luka:


He was born on 7th May 2008 in Cork University Maternity Hospital. That was the happiest day of my life, and probably the scariest at the same time :)

Just wanted to say one big Thank You! to everyone in CUMH - they were all absolutely brilliant, I have never seen so many nice people in the same place in my life. Everyone was so nice and caring, we've seen like 50 people in three days we've been there and I have no words to describe how nice they all were. Guys we love you all!

Network History Support for Firebug

Tuesday April 29, 2008 @ 01:14 AM (PDT)
Recently I started developing Firefox add-ons. Firefox is my browser of choice and I use it almost exclusively. Firebug comes handy when you want to analyse what you are getting from site, which I needed to do recently. I needed network history functionality to record the whole conversation but there was no such functionality in Firebug and since I prefer to work in environment/tool I am comfortable with I decided to add overlay to Firebug and add functionality myself.

Here is the add-on on Firefox add-ons: Firebug Net Panel History Overlay, current version 0.2.0. You need to log in to install it since it is still in sandbox/review phase. Here is the screen shot on how it looks like:


The code has lots of comments and it might be worthwhile giving it a look if you want to build your own net panel overlay. Here is the full source code (again log in required), version is 0.2.0, let me know if you have any comments or need any help with it. Files are as follows:
  • chrome.manifest -defines contents of the add on and sets the add on as Firebug overlay
  • install.rdf - file that describes the add on
  • /chrome/firebugNetHistory/NetPanelHistoryOverlay.xul - UI for the add on. Huh, UI is couple of buttons and label to navigate through history
  • /chrome/firebugNetHistory/NetPanelHistoryOverlay.js - main functionality for the add on, defines NetPanelHistoryOverlayModel and registeres it with Firebug
  • /chrome/firebugNetHistory/netHistoryParameters.xul and netHistoryParameters.js - dialog and dialog event handlers for setting parameters
  • defaults/preferences/netHistory.js - configuration for the add on
I tested add on with Firebug 1.1.0b10.

If you want to extend Firebug yourself - Jan Odvarko has a great tutorial on his blog.

At the moment if you have YSlow installed you might not see menu items for the net panel history in the options menu of the net panel. The problem is that YSlow is replacing menu items in the menu instead of just adding its own items.

While Popping Bubble Wrap

Monday April 28, 2008 @ 07:25 AM (PDT)
Couple of mine earlier blog entries:
Start using new C# 3.0 language features in 5 minutes

WCF and interoperability - Consuming REST Services (with eBay search application example in WPF)

More blogging from DeCare Systems Ireland.
Copyright © 2010 Mihailo Lalevic. All rights reserved.
Powered by Thoth.