Re: Identifying Tab in OnStateChange C++
Vaibhav <[email protected]> Tue, 20 Apr 2010 03:04:02 -0700 (PDT)
| Newsgroups | gmane.comp.mozilla.devel.dom |
|---|---|
| Organization | http://groups.google.com |
| Message-ID | <[email protected]> |
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 every tab.*** nsCOMPtr<nsIDOMEventTarget> evtTarget = do_QueryInterface(domtopwin); evtTarget->AddEventListener(NS_LITERAL_STRING("TabOpen"), this, PR_FALSE); evtTarget->AddEventListener(NS_LITERAL_STRING("TabClose"), this, PR_FALSE); evtTarget->AddEventListener(NS_LITERAL_STRING("TabMove"), this, PR_FALSE); evtTarget->AddEventListener(NS_LITERAL_STRING("TabSelect"), this, PR_FALSE); evtTarget->AddEventListener(NS_LITERAL_STRING("click"), this, PR_FALSE); } } Pseudocode of HandleEvent: HandleEvent(nsIDOMEvent *event) { nsEmbedString type; event->GetType(type); const PRUnichar *data = type.get(); if (0 == _wcsicmp(data, L"TabOpen")) { nsCOMPtr<nsIDOMEventTarget> tab; event->GetCurrentTarget(getter_AddRefs(tab)); nsCOMPtr<nsIDOMWindow> domwin; domwin = do_QueryInterface(tab, &rv); // Here I Called GetTop, but it also returns same pointer as that of domwin nsCOMPtr<nsIDOMWindow> domtopwin; domwin->GetTop(getter_AddRefs(domtopwin)); // Here domtopwin is equal to domwin } } Why DOM Window Pointer from OnStateChange is different than that of HandleEvent's TabOpen? With Best Regards, Vaibhav.