Click here to Skip to main content
6,635,160 members and growing! (13,800 online)
Email Password   helpLost your password?
Platforms, Frameworks & Libraries » Libraries » General     Beginner

A C++ Firefox component intercepting/operating HTML DOM

By Jia.C

This article uses a simple example to show how to build a Firefox component intercepting/operating DOM
VC6, Windows, Visual Studio, MFC, COM, COM+, Dev
Posted:28 Sep 2007
Updated:10 Oct 2007
Views:45,223
Bookmarked:42 times
Unedited contribution
Announcements
Loading...
 
Search    
Advanced Search
Add to IE Search
printPrint   add Share
      Discuss Discuss   Broken Article?Report  
14 votes for this article.
Popularity: 4.06 Rating: 3.54 out of 5
3 votes, 21.4%
1
1 vote, 7.1%
2
1 vote, 7.1%
3
2 votes, 14.3%
4
7 votes, 50.0%
5

Background

I have been working on BHO for few months. It's neat to develop BHO components. On the contrary, Firefox seems really frustrating. I guess the first reason is that there are never enough examples and codes for you to follow. Secondly, Mozilla does not provide enough documents like Microsoft does. Well, I don't blame them for that. It's a small company and it's free source after all.

In the following parts, I will use an example to show you how to intercept Firefox's DOM elements and operates like in BHO.

There are two articles I strongly recommend you to read before you scroll down this page.

http://www.iosart.com/firefox/xpcom/ Creating a XPCOM component

http://www.borngeek.com/firefox/toolbar-tutorial/ Firefox toolbar tutorial

The first one teaches you how to build a component; the second teaches you how to make an extension.

The example here is based on the example in first article.

It took me two whole weeks to learn how Firefox as well as XPCOM operate. Just use this simple graph to demonstrate the structure:

UI--> XPConnect--> XPCOM

Most of the add-ons you have seen and you can download are extensions such as a toolbar etc. The majority of them are written with javascript. It's alright and neat if you don't want to touch some advanced components; for instance a toolbar only navigates the window etc. But if you want to go further, you have to call components built under XPConnect or XPCOM.

Following code is a simple cookie manager from Mozilla's official tutorial.

var
cookiemanager = Components.classes["@mozilla.org/1005953"> <o:p />
color: black;">     cookiemanager;1"].getService();1009012"> <o:p />
cookiemanager
= cookiemanager.QueryInterface<o:p />
     (Components.interfaces.nsICookieManager);1005955"> <o:p />1005956"> <o:p />
// called as
part of a largerDeleteAllCookies() function1005976"> <o:p />
function
FinalizeCookieDeletions() {1005960"> <o:p />
  for (var c=0; c<deletedCookies.length;
c++) {1005961"> <o:p />
   
cookiemanager.remove(deletedCookies[c].host,1005962"> <o:p />
                        
deletedCookies[c].name,1005963"> <o:p />
                        
deletedCookies[c].path);1005964"> <o:p />            1005965"> <o:p />
  }1005966"> <o:p />
  deletedCookies.length = 0;1005967"> <o:p />
}1001113"> <o:p /> 

It is quite easy to understand the procedure.

  • Get Service of Components
  • QI the components
  • Call the methods under the components

There isn't too much technology in this part. But, how the components work is another issue.

Firefox are based on Gecko SDK. Basically all those APIs starts with "ns" such as "nsIWebBrowser" (similar to IWebBrowser on BHO) are from Gecko SDK. You can find the information on www.xulplanet.com

Let's get to the point. Now, I want to build a FormFiller for firefox. Meanwhile, I do not want to use javascript to do the job due to following reasons:

  • Javascript will expose your code
  • Javascript has very limited functionalities.

So, here are two solutions

  • Build a Firefox extension with C++
  • Build a Firefox component with C++

I go for the second. Although registering a component is far more complicated than registering an extension on Firefox. But it's much more secured when calling core components and operates the data.

How to do it

Like BHO, there is an nsIWebBrowser that provides the APIs of any XPCOM based browsers such as SeaMonkey or NetScape.

Through nsIWebBrowser, we can get nsIDOMWindow-> nsIDOMDocument->nsIDOMElement then fill in the information we want.

However, this does NOT work on Firefox. The reason is very simple: Firefox does not use nsIWebBrowser. They will return some random useless stuffs when you call nsIWebBrowser via Component Manager.

I have no idea why do they do that. Maybe it's because of the multi-tab structure of Firefox.

So, our problem is here. We must initialize nsIDOMWindow before we move further.

To save your time on googling all the information, please let me present the simple function prototype:

var res = obj.Nothing(window);

where Nothing is the method called for filling in forms. "window" is the browser window object that javascript naturally has.

So inside your code, you have the method declared as:

  NS_IMETHOD Nothing(nsIDOMWindow *domWindow); //.h file


 NS_IMETHODIMP MyComponent::Nothing(nsIDOMWindow *domWindow) //cpp file


When javascript pass window into the method, it will be automatically converted into nsIDOMWindow.

Ok, half of the job has been done.


Another half is easy. Look at following code, and you will understand.

NS_IMETHODIMP MyComponent::Nothing(nsIDOMWindow *domWindow)
{
nsEmbedString temp(L"test");
nsEmbedString attribute(L"value");
nsEmbedString id(L"id");
nsEmbedString value(L"value");

//The above declare some strings. 

/* 
Please note that the string in XPCOM is declared as either nsAString or nsString or nsEmbedString Please refer to http://developer.mozilla.org/en/docs/XPCOM:Strings for more information
*/

nsIDOMWindow* window; //you can use the parameter directly

window=domWindow;
nsCOMPtr<nsIDOMDocument> domDocument; 
nsCOMPtr<nsIDOMElement> element;
window->GetDocument(getter_AddRefs(domDocument)); //Get document

domDocument->GetElementById(temp,getter_AddRefs(element)); 
//Find target element, you also can use GetElementByTagName to get a node list. Then loop through the node list. Please refer to XULPlanet for more info //about nsIDOMDocument

element->GetAttribute(id,value);
 //I get the value of "id" attribute and fill it into "value attribute"

element->SetAttribute(attribute,value);
    return NS_OK;
}

Ok, above is the all the code you need.

How to build the project

I strongly recommend
http://www.iosart.com/firefox/xpcom/

I learned most of the things about XPCOM components there.

To started your project, you need to have a .idl file.

#include "nsISupports.idl"

#include "nsIDOMWindow.idl"

[scriptable, uuid(_YOUR_INTERFACE_GUID_)]
interface IMyComponent : nsISupports
{
  void Nothing(in nsIDOMWindow domWindow);
};


Then download a XPIDL.exe to generate the .h file:

Quote from the article:
� xpidl -m header -I_DIR_ IMyComponent.idl will create the IMyComponent.h header file.
� xpidl -m typelib -I_DIR_ IMyComponent.idl will create the IMyComponent.xpt typelib file.

Then follow http://www.iosart.com/firefox/xpcom/

Calling the component

There are two ways to call the component

  • Through an extension
  • Call from Javascript on a page.


It's the same. An extension is a XUL with javascript. Please refer to
http://www.borngeek.com/firefox/toolbar-tutorial/ to find out how it works

Following code on HTML page called the component:

<HTML>
<SCRIPT  type="text/javascript">
function MyComponentTestGo() {
    try {
        netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
        const cid = "@mydomain.com/XPCOMSample/MyComponent;1";
        obj = Components.classes[cid].createInstance();
        obj = obj.QueryInterface(Components.interfaces.IMyComponent);
    } catch (err) {
        alert(err);
        return; 
    }
    var res = obj.Nothing(window);}
</SCRIPT>
<BODY>
<BUTTON ONCLICK="MyComponentTestGo();" id="go">Go</BUTTON>
<input id="test" value="" />
</BODY>
</HTML>

Conclusion

The biggest problem of developing Firefox components is the lack of documents and codes. Even XPCOM itself has the same problem. But I think situation will get better and better. Usually, there are some skilled people on Mozillzine you can ask for help.

I hope this simple article is helpful to those people who are frustrated by Firefox. If you have any comments or questions, please leave here. I will reply you as much as I can.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Jia.C


Member
Nerd is cool~

www.horizonideas.com
Occupation: Web Developer
Location: Canada Canada

Other popular Libraries articles:

Article Top
You must Sign In to use this message board.
FAQ FAQ 
 
Noise Tolerance  Layout  Per page   
 Msgs 1 to 25 of 60 (Total in Forum: 60) (Refresh)FirstPrevNext
GeneralHow can I get the event from dom? Pinmembersuperleolx4:05 8 Feb '09  
GeneralIt doesn't work under FireFox 5.0! PinmemberAndretS8210:43 1 Aug '08  
GeneralRe: It doesn't work under FireFox 5.0! PinmemberAndretS824:51 2 Aug '08  
GeneralRe: It doesn't work under FireFox 5.0! PinmemberAndretS820:51 22 Aug '08  
QuestionRe: It doesn't work under FireFox 5.0! Pinmember101621:57 18 Sep '08  
GeneralGeting parse error .. Empty file .. XPIDL Pinmembertornado_saurabh3:51 24 Mar '08  
GeneralRe: Geting parse error .. Empty file .. XPIDL PinmemberJia.C6:25 24 Mar '08  
Questionalways getting NULL pointer for nsIDOMWindow Pinmemberunita_logica16:50 27 Nov '07  
AnswerRe: always getting NULL pointer for nsIDOMWindow Pinmemberunita_logica17:19 27 Nov '07  
GeneralHow can we get current mozilla's url address? PinmemberGofur Halmurat6:10 27 Nov '07  
GeneralRe: How can we get current mozilla's url address? PinmemberJia.C20:20 27 Nov '07  
GeneralRe: How can we get current mozilla's url address? PinmemberGofur Halmurat0:25 28 Nov '07  
GeneralRe: How can we get current mozilla's url address? PinmemberJia.C9:24 28 Nov '07  
GeneralHandle win32 calls with mozilla extension [modified] Pinmembercinni1:23 15 Nov '07  
GeneralRe: Handle win32 calls with mozilla extension PinmemberJia.C20:23 27 Nov '07  
GeneralNeed your help for instantiate an firefox extension Pinmemberjohn_zzhang14:53 13 Nov '07  
GeneralRe: Need your help for instantiate an firefox extension PinmemberJia.C15:03 13 Nov '07  
GeneralnsAString Pinmemberhorrid21:13 11 Nov '07  
GeneralRe: nsAString PinmemberJia.C15:01 13 Nov '07  
QuestionHelp me with XPCOM Pinmembermaivantai23:53 9 Nov '07  
AnswerRe: Help me with XPCOM PinmemberJia.C14:55 13 Nov '07  
QuestionRe: Help me with XPCOM Pinmembermaivantai21:25 30 Nov '07  
AnswerRe: Help me with XPCOM PinmemberJia.C17:33 1 Dec '07  
GeneralRe: Help me with XPCOM Pinmembermaivantai19:01 5 Dec '07  
GeneralJust Fill in Some Edit Boxes Pinmembervikrant kpr4:37 14 Oct '07  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 10 Oct 2007
Editor:
Copyright 2007 by Jia.C
Everything else Copyright © CodeProject, 1999-2009
Web19 | Advertise on the Code Project