Re: Identifying Tab in OnStateChange C++

Vaibhav <[email protected]> Mon, 26 Apr 2010 20:52:04 -0700 (PDT)
Newsgroups gmane.comp.mozilla.devel.dom
Organization http://groups.google.com
Message-ID <e5711426-49f1-4cb1-8757-0773cd5e507d@v12g2000prb.googlegroups.com>
On Apr 22, 6:07 pm, Vaibhav <[email protected]> wrote:
> On Apr 21, 7:19 am, Jens Sorensen <[email protected]> wrote:> You are using the wrong DOM window in "HandleEvent"...
>
> > I assume you already saved off the panel container, and that you added
> > the event listeners  (if not then look at one of my ealier posts). But
> > the call basically looks like this..
>
> > xbl->GetAnonymousElementByAttribute(domEl,
> > NS_LITERAL_STRING("anonid"), NS_LITERAL_STRING("panelcontainer"),
> > getter_AddRefs(panelcontainer)  );
>
> > NS_IMETHODIMP XXXXXX::HandleEvent(nsIDOMEvent* event)
>
> >         if( This_Is_The_TabOpen_Event )
> >         {      
> >                 // Get a collection of all the tabs using the saved off panelcontainer pointer
> >                 nsCOMPtr<nsIDOMNodeList> tabs;
> >                 panelContainer->GetChildNodes(getter_AddRefs(tabs));
>
> >                 // Its pretty safe to assume that the new tab will be last in the collection
> >                 // since new tabs are always appended, lets get the # of tabs
> >                 PRUint32 tabCount = 0;
> >                 tabs->GetLength(&tabCount);
>
> >                 // Lets get the last tab which is the 'xul::notificationbox' element
> > for the given tab
> >                 nsCOMPtr<nsIDOMNode> newTab;
> >                 tabs->Item(tabCount-1, getter_AddRefs(newTab));
>
> >                 // get the last child of the 'xul::notificationbox' which is the
> > 'xul:browser' element
> >                 nsCOMPtr<nsIDOMNode> domXULBrowser;
> >                 newTab->GetLastChild(getter_AddRefs(domXULBrowser));
>
> >                 nsCOMPtr<nsIDOMXULElement> xulElement = do_QueryInterface(domXULBrowser);
> >                 nsCOMPtr<nsIBoxObject> boxObject;
> >                 xulElement->GetBoxObject(getter_AddRefs(boxObject));
> >                 nsCOMPtr<nsIBrowserBoxObject> browserboxObject = do_QueryInterface(boxObject);
>
> >                 nsCOMPtr<nsIDocShell> docShell;
> >                 browserboxObject->GetDocShell(getter_AddRefs(docShell));
>
> >                 nsCOMPtr<nsIDOMWindow> domWindow = do_GetInterface(docShell);
> >                 // From here you can get the dom document etc...
> >                                         :                                      
> >                                         :
>
> > You should be able to match up the above domWindow with the one you
> > get in your progress listener
>
> > Plus you should not be adding "TabOpen" etc. event listeners in you
> > OnStateChange function. This function will get called a lot plus its
> > the wrong object that you are adding the event listeners to. You want
> > to keep "OnStateChange" as light as possible since it will impact
> > browser performance.
>
> > You might find this link very usefulhttps://developer.mozilla.org/en/Code_snippets/Tabbed_browser
>
> > Here is a Java script example.. (Taken from the above link)
>
> > // During initialisation
> > var container = gBrowser.tabContainer;
> > container.addEventListener("TabOpen", exampleTabAdded, false);
>
> > Hope this helps.. You are almost there :)
>
> > -Jens
>
> > On Tue, Apr 20, 2010 at 3:04 AM, Vaibhav <[email protected]> wrote:
> > > On Apr 20, 2:41 pm, Vaibhav <[email protected]> wrote:
> > >> On Apr 19, 6:13 pm, Vaibhav <[email protected]> wrote:
>
> > >> > Hi,
>
> > >> > I am writing Firefox extension using C++.
> > >> > In OnStateChange method I want to determine the tab associated with
> > >> > particular request.
>
> > >> > Currently I compare DOM Document Pointers to do it.
>
> > >> > Following is the Pseudocode:
>
> > >> > OnStateChange()
> > >> > {
> > >> >         //==================================================
> > >> >         //+
> > >> >         // GET URL
>
> > >> >         nsCString url;
> > >> >         const char *pcszURL;
> > >> >         aRequest->GetName(url);
> > >> >         NS_CStringGetData(url, &pcszURL);
>
> > >> >         //-
> > >> >         //==================================================
>
> > >> >         nsCOMPtr<nsIDOMWindow> DOMWin;
> > >> >         rv = aWebProgress->GetDOMWindow(getter_AddRefs(DOMWin));
> > >> >         nsCOMPtr<nsIDOMDocument> DOMDoc;
> > >> >         rv = DOMWin->GetDocument(getter_AddRefs(DOMDoc));
>
> > >> >         INT iTabIndex;
> > >> >         nsCOMPtr<nsIWindowMediator> windowMediator =
> > >> > do_GetService(NS_WINDOWMEDIATOR_CONTRACTID, &rv);
> > >> >         nsCOMPtr<nsIDOMWindowInternal> dwi;
> > >> >         windowMediator->GetMostRecentWindow(L"navigator:browser",
> > >> > getter_AddRefs(dwi));
> > >> >         nsCOMPtr<nsIDOMDocument> doc;
> > >> >         dwi->GetDocument(getter_AddRefs(doc));
> > >> >         nsCOMPtr<nsIDOMDocumentXBL> xbl(do_QueryInterface(doc));
> > >> >         nsCOMPtr<nsIDOMElement> domEl;
> > >> >         doc->GetElementById(NS_LITERAL_STRING("content"),
> > >> > getter_AddRefs(domEl));
> > >> >         nsCOMPtr<nsIDOMElement> pAnoEl;
>
> > >> >         //
> > >> >     // getting xul:tabpanels
> > >> >         //
> > >> >         xbl->GetAnonymousElementByAttribute(
> > >> >                                                                                 domEl,
> > >> >                                                                                 NS_LITERAL_STRING("anonid"),
> > >> > NS_LITERAL_STRING("panelcontainer"),
> > >> >                                                                                 getter_AddRefs(pAnoEl)
> > >> >                                                                                 );
> > >> >         nsString retval;
> > >> >         PRBool bRet = 0;
> > >> >         nsCOMPtr<nsIDOMNodeList> nodeList;
> > >> >         pAnoEl->GetChildNodes(getter_AddRefs(nodeList));
> > >> >         nsCOMPtr<nsIDOMNode> domNode;
> > >> >         PRUint32 len = 0;
> > >> >         rv = nodeList->GetLength(&len);
> > >> >         for( PRUint32 i=0; i<len; i++ )
> > >> >         {
> > >> >                 // getting the xul::notificationbox
> > >> >                 nsCOMPtr<nsIDOMNode> domNode;
> > >> >                 nodeList->Item(i, getter_AddRefs(domNode));
> > >> >                 // get the last child of the 'xul::notificationbox' which is the
> > >> > 'xul:browser'
> > >> >                 nsCOMPtr<nsIDOMNode> domXULBrowser;
> > >> >                 domNode->GetLastChild(getter_AddRefs(domXULBrowser));
> > >> >                 nsCOMPtr<nsIDOMXULElement> xulElement =
> > >> > do_QueryInterface(domXULBrowser);
> > >> >                 nsCOMPtr<nsIBoxObject> boxObject;
> > >> >                 xulElement->GetBoxObject(getter_AddRefs(boxObject));
> > >> >                 nsCOMPtr<nsIBrowserBoxObject> browserboxObject =
> > >> > do_QueryInterface(boxObject);
> > >> >                 nsCOMPtr<nsIDocShell> docShell;
> > >> >                 browserboxObject->GetDocShell(getter_AddRefs(docShell));
> > >> >                 nsCOMPtr<nsIWebNavigation> webNav = do_QueryInterface(docShell);
> > >> >                 nsCOMPtr<nsIURI> uri;
> > >> >                 webNav->GetCurrentURI(getter_AddRefs(uri));
> > >> >                 nsCString path;
> > >> >                 uri->GetAsciiSpec(path);
> > >> >                 const CHAR *ppathspec = path.get();
> > >> >                 if (0 == _stricmp(ppathspec, pcszURL))
> > >> >                 {
> > >> >                         nsCOMPtr<nsIDOMDocument> tabdoc;
> > >> >                         webNav->GetDocument(getter_AddRefs(tabdoc));
> > >> >                         if (tabdoc.get() == DOMDoc.get())
> > >> >                         {
> > >> >                                 //
> > >> >                                 //      !!! This is the required tab. !!!
> > >> >                                 //      !!! This is the tab associated with the request. !!!
> > >> >                                 //
> > >> >                         }
> > >> >                 }
> > >> >         }
>
> > >> > }
>
> > >> > In above code I am comparing nsIDOMDocument pointers to get currently
> > >> > navigated tab.
>
> > >> > Is there another sure way to do this?
>
> > >> > With Best Regards,
> > >> > Vaibhav.
>
> > >> Jens Replied:
>
> > >> I would do it like this. Have a map (or whatever fits your needs) that
> > >> keeps track of tab instances. Whenever a tab is created then save off
> > >> the DOM Window (nsIDOMWindow) which represents the tab in the given
> > >> container. You can add a "TabOpen" event handler to the browser window
> > >> if you want to get notified when a new tab has been created and find
> > >> the DOM window which represents the tab and do whatever you need to
> > >> do.
>
> > >> Now when "OnStateChange" is being called then check if the
> > >> "STATE_IS_DOCUMENT" bit is set in aStateFlags. If the bit is set then
> > >> grab the DOMWindow pointer from the passed in aWebProgress argument.
> > >> This can be a sub frame so you want to make sure that you call
> > >> "GetTop" on the window. Now that you have the top window then use that
> > >> to identify your tab. You can make a quick look up in your map to
> > >> return the desired data.
>
> > >> A few things to remember, if save off the nsIDOMWindow point in the
> > >> map then remember to the reference count it correctly.(when you add it
> > >> and remove it)
>
> > >> If I remember correctly then you can get a " OnStateChange " event for
> > >> a given tab before the "TabOpen" event. If you try to locate the
> > >> window in the map then it might not exist. If you do add the
> > >> nsDOMWindow to the map at this time then it will match the
> > >> nsIDOMWindow that you get when "TabOpen" is invoked so its all good.
>
> > >> You can also add a "TabClose" to keep track of when the user closes a
> > >> tab and remove the instance from the map.
>
> > >> Hope this helps.
> > >> -Jens Sorensen
>
> > > Hi,
>
> > > Jens, Very Thanks for your reply.
>
> > > In OnStateChange method, nsIDOMWindow pointer is unique for every tab,
> > > but it is different from nsIDOMWindow pointer I get in "TabSelect"/
> > > "TabOpen" event handler i.e. HandleEvent method.
>
> > > I am registering for Tab Events i.e. (TabOpen, TabClose, TabSelect,
> > > TabMove) in OnStateChange.
>
> > > Pseudocode of OnStateChange:
>
> > > OnStateChange()
> > > {
> > >   if ((aStateFlags & STATE_START) && (aStateFlags &
> > > STATE_IS_DOCUMENT))
> > >   {
> > >        nsCOMPtr<nsIDOMWindow> domwin;
> > >        aWebProgress->GetDOMWindow(getter_AddRefs(domwin));
> > >        nsCOMPtr<nsIDOMWindow> domtopwin;
> > >        domwin->GetTop(getter_AddRefs(domtopwin)); // *** This
> > > domtopwin pointer is unique for...
>
> > read more »
>
> Hello Jens,
>
> Very Thanks for providing me solution.
>
> I am still confused about where do I register Tab & Click events in C+
> +.
> After reading your last post, I moved my Tab & Click Registration code
> to javascript file.
>
> It is as follows:
>
> /////////////////////////////////////////////////////////////////////////// ////
> function Init()
> {
>         var container;
>         container = gBrowser.tabContainer;
>
> netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
>         const cid = '@MyXPCOM/TestComponent';
>         var obj =
> Components.classes[cid].getService(Components.interfaces.iTestComponent);
>
>         container.addEventListener("TabOpen", obj, false);
>         container.addEventListener("TabMove", obj, false);
>         container.addEventListener("TabClose", obj, false);
>         container.addEventListener("TabSelect", obj, false);
>         window.addEventListener("click", obj, false);
>
> }
>
> function DeInit()
> {
>     // Actually I want to unregister Tab & Click events, but till this
> function gets called
>     // component instance is no more.
>
> }
>
> window.addEventListener('load', Init, false);
> window.addEventListener('unload', DeInit, false);
>
> ///////////////////////////////////////////////////////////////
>
> But I want to do above things in C++.
>
> Vaibhav.

Hi,

Answer to above question is at:

http://groups.google.com/group/mozilla.dev.tech.dom/browse_thread/thread/3a4cbe436f4cf22b#

Vaibhav.