Re: Identifying Tab in OnStateChange C++
Vaibhav <[email protected]> Tue, 20 Apr 2010 02:41:35 -0700 (PDT)
| Newsgroups | gmane.comp.mozilla.devel.dom |
|---|---|
| Organization | http://groups.google.com |
| Message-ID | <f12ce38b-e8ab-4ce4-89da-1d2a3d727c88@x42g2000vba.googlegroups.com> |
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