![]() |
Platforms, Frameworks & Libraries »
Libraries »
General
Beginner
A C++ Firefox component intercepting/operating HTML DOMBy Jia.CThis article uses a simple example to show how to build a Firefox component intercepting/operating DOM |
VC6, Windows, Visual Studio, MFC, COM, COM+, Dev
|
||||||||||
|
Advanced Search Add to IE Search |
|
|
|
||||||||||||||||
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.
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:
So, here are
two solutions
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.
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;
}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/
There are two ways to call the component
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>
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.
General
News
Question
Answer
Joke
Rant
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 |