Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

DOMContentLoaded event from C++

85 views
Skip to first unread message

Martin Lutken

unread,
May 16, 2011, 2:03:54 AM5/16/11
to
I would like to get the "DOMContentLoaded" event from C++. It works
from javascript, but not from C++. However it seems I more or less
have the correct event target since "resize" and "unload" event does
work.

My XulFile is very simple where the interesting part is this line
declaring the browser:
<browser id="mybrowser1" src="http://www.google.dk" flex="1" />

The C++ code is like this:
void CSpecialThing::getBrowserQuestionForForum()
{
nsString wsHrefXul = NS_LITERAL_STRING( "chrome://xulcrawler/
content/main.xul" );
nsString wsIDBrowser = NS_LITERAL_STRING( "mybrowser1" );

// --- A lot of variables ---
nsresult rv;
nsCOMPtr<nsIDOMWindowInternal> pWinInt(0);
nsCOMPtr<nsISimpleEnumerator> pWinEnumerator;
nsCOMPtr<nsIDOMLocation> pDOMLocation;
nsCOMPtr<nsIDOMWindowCollection> pDOMWindowCollection;
nsCOMPtr<nsIDOMWindow> pDomWin;

// -----------------------------
// --- Get DomWindowInternal ---
// -----------------------------

nsCOMPtr<nsIWindowMediator>
pWindowMediator(do_GetService(NS_WINDOWMEDIATOR_CONTRACTID));

nsString sWindowType( NS_LITERAL_STRING("") );
rv = pWindowMediator->GetEnumerator( sWindowType.get(),
getter_AddRefs(pWinEnumerator));


PRBool bHasMoreElements;
rv = pWinEnumerator->HasMoreElements( &bHasMoreElements );

while ( bHasMoreElements ) {
nsCOMPtr<nsISupports> pSupportsWin;
rv = pWinEnumerator->GetNext( getter_AddRefs(pSupportsWin) );
nsCOMPtr<nsIDOMWindowInternal>
pWinInternal(do_QueryInterface(pSupportsWin));

rv = pWinInternal-
>GetLocation( getter_AddRefs(pDOMLocation) );

nsString wsHrefTest;
rv = pDOMLocation->GetHref( wsHrefTest );

// See if we have the correct (XUL) URI
if ( wsHrefXul == wsHrefTest ) pWinInt = pWinInternal;

rv = pWinEnumerator->HasMoreElements( &bHasMoreElements );
}

// --- Get the "mybrowser1" element ---
pWinInt->GetFrames( getter_AddRefs(pDOMWindowCollection) );
pDOMWindowCollection->NamedItem( wsIDBrowser,
getter_AddRefs(pDomWin) );

// --- Add events ---
nsCOMPtr<nsIDOMEventTarget>
pDomEventTarget(do_QueryInterface(pDomWin));
pDomEventTarget-
>AddEventListener(NS_LITERAL_STRING("DOMContentLoaded"), this,
PR_FALSE);
pDomEventTarget->AddEventListener(NS_LITERAL_STRING("resize"),
this, PR_FALSE);
pDomEventTarget->AddEventListener(NS_LITERAL_STRING("unload"),
this, PR_FALSE);
}

Neil

unread,
May 16, 2011, 4:46:30 AM5/16/11
to
Martin Lutken wrote:

>I would like to get the "DOMContentLoaded" event from C++. It works from javascript, but not from C++. However it seems I more or less have the correct event target since "resize" and "unload" event does work.
>

Chances are you did attach the event handler to the window, but
unfortunately loading a new document clears all extant event handlers.
In JavaScript you've probably been attaching a capturing event handler
to the browser element instead.

--
Warning: May contain traces of nuts.

Martin Lutken

unread,
May 16, 2011, 8:14:28 AM5/16/11
to

Ok. Any idea how I get the browser element ?

Is it one of those I already have interfaces to? Anyway I found the
code in the source for Songbird, but they do not listen to the
"DOMContentLoaded" so you're probably right that I am attaching event
listneners to the wrong element.

Thanks a lot

Neil

unread,
May 17, 2011, 8:05:48 AM5/17/11
to
Martin Lutken wrote:

>Ok. Any idea how I get the browser element ?
>
>

(Using abbreviated variable names to save space)

nsCOMPtr<nsIDOMDocument> doc;
win->GetDocument(getter_AddRefs(doc));
nsCOMPtr<nsIDOMElement> elt;
doc->GetElementById(NS_LITERAL_STRING("browser1"), getter_AddRefs(elt));
nsCOMPtr<nsIDOMEventTarget> tgt(do_QueryInterface(elt);
tgt->AddEventListener(NS_LITERAL_STRING("DOMContentLoaded"), this, PR_TRUE);

Martin Lutken

unread,
May 17, 2011, 11:43:07 AM5/17/11
to
Hi Neil


I'll try your way too. Again Thanks a lot :)
Also found a way myself which seems to work:

I found the solution. Just need to get the Parent windows of the one I
wa using. Except if you want the "unload" event which seems to only
work for the window I was first using. Here goes the complete updated
code for those who might have had the same troubles as I.
Thanks again to Neil for his great help.

void CSpecialThing::getBrowserQuestionForForum()
{
nsString wsHrefXul = NS_LITERAL_STRING( "chrome://xulcrawler/
content/main.xul" );
nsString wsIDBrowser = NS_LITERAL_STRING( "mybrowser1" );

// --- A lot of variables ---
nsresult rv;
nsCOMPtr<nsIDOMWindowInternal> pWinInt(0);
nsCOMPtr<nsISimpleEnumerator> pWinEnumerator;
nsCOMPtr<nsIDOMLocation> pDOMLocation;
nsCOMPtr<nsIDOMWindowCollection> pDOMWindowCollection;
nsCOMPtr<nsIDOMWindow> pDomWin;

nsCOMPtr<nsIDOMWindow> pDomWinBrowser;
nsCOMPtr<nsIDOMDocument> pDomDoc;

nsCOMPtr<nsIWindowMediator>
pWindowMediator(do_GetService(NS_WINDOWMEDIATOR_CONTRACTID));

pDomWin->GetParent( getter_AddRefs(pDomWinBrowser) );

// --- Add events ---
nsCOMPtr<nsIDOMEventTarget>

pDomEventTargetBrowserWin(do_QueryInterface(pDomWin));
nsCOMPtr<nsIDOMEventTarget>
pDomEventTargetBrowser(do_QueryInterface(pDomWinBrowser));
pDomEventTargetBrowser-


>AddEventListener(NS_LITERAL_STRING("DOMContentLoaded"), this,
PR_FALSE);

pDomEventTargetBrowser-


>AddEventListener(NS_LITERAL_STRING("resize"), this, PR_FALSE);

pDomEventTargetBrowserWin-


>AddEventListener(NS_LITERAL_STRING("unload"), this, PR_FALSE);

// ---------------------------------------------------------------
// --- Bonus example on how to get the current URI of the page ---
// ---------------------------------------------------------------
pDomWin->GetDocument( getter_AddRefs(pDomDoc) );
nsCOMPtr<nsIDOMDocumentView>
pDomDocumentView(do_QueryInterface(pDomDoc));
nsCOMPtr<nsIDOMAbstractView> domAbstractView =
getDefaultView(pDomDocumentView);
nsCOMPtr<nsIWebNavigation>
webNavigation(do_GetInterface(domAbstractView));
printf("webNavigation uri: %s\n",
getCurrentURI(webNavigation).c_str() );
}

Martin Lutken

unread,
May 17, 2011, 11:44:25 AM5/17/11
to
Hi Neil


I'll try your way too. Again Thanks a lot :)
Also found a way myself which seems to work:

I found the solution. Just need to get the Parent windows of the one I
wa using. Except if you want the "unload" event which seems to only
work for the window I was first using. Here goes the complete updated
code for those who might have had the same troubles as I.
Thanks again to Neil for his great help.

void CSpecialThing::getBrowserQuestionForForum()


{
nsString wsHrefXul = NS_LITERAL_STRING( "chrome://xulcrawler/
content/main.xul" );
nsString wsIDBrowser = NS_LITERAL_STRING( "mybrowser1" );

// --- A lot of variables ---
nsresult rv;
nsCOMPtr<nsIDOMWindowInternal> pWinInt(0);
nsCOMPtr<nsISimpleEnumerator> pWinEnumerator;
nsCOMPtr<nsIDOMLocation> pDOMLocation;
nsCOMPtr<nsIDOMWindowCollection> pDOMWindowCollection;
nsCOMPtr<nsIDOMWindow> pDomWin;

nsCOMPtr<nsIDOMWindow> pDomWinBrowser;
nsCOMPtr<nsIDOMDocument> pDomDoc;

nsCOMPtr<nsIWindowMediator>
pWindowMediator(do_GetService(NS_WINDOWMEDIATOR_CONTRACTID));

pDomWin->GetParent( getter_AddRefs(pDomWinBrowser) );

// --- Add events ---
nsCOMPtr<nsIDOMEventTarget>

pDomEventTargetBrowserWin(do_QueryInterface(pDomWin));
nsCOMPtr<nsIDOMEventTarget>
pDomEventTargetBrowser(do_QueryInterface(pDomWinBrowser));
pDomEventTargetBrowser-

>AddEventListener(NS_LITERAL_STRING("DOMContentLoaded"), this,
PR_FALSE);

pDomEventTargetBrowser-


>AddEventListener(NS_LITERAL_STRING("resize"), this, PR_FALSE);

pDomEventTargetBrowserWin-


>AddEventListener(NS_LITERAL_STRING("unload"), this, PR_FALSE);

// ---------------------------------------------------------------

YuLo

unread,
Oct 1, 2012, 8:15:15 AM10/1/12
to
вторник, 17 мая 2011 г., 19:44:25 UTC+4 пользователь Martin Lutken написал:
Hi, Martin.
A question for nubie. What function will be fired on event. The second parameter for "AddEventListener" is "this". It is the pointer to class, not function.

Neil

unread,
Oct 1, 2012, 11:47:02 AM10/1/12
to
YuLo wrote:

>A question for nubie. What function will be fired on event. The second parameter for "AddEventListener" is "this". It is the pointer to class, not function.
>
>
The second parameter is an nsIDOMEventListener type. This has a method
called handleEvent (or HandleEvent in C++).

XPConnect magic allows script to pass a function instead of a class.

YuLo

unread,
Oct 4, 2012, 5:35:32 AM10/4/12
to
понедельник, 1 октября 2012 г., 19:47:03 UTC+4 пользователь Neil написал:
> YuLo wrote:
>
>
>
> >A question for nubie. What function will be fired on event. The second parameter for "AddEventListener" is "this". It is the pointer to class, not function.
>
> >
>
> >
>
> The second parameter is an type. This has a method
>
> called handleEvent (or HandleEvent in C++).
>
>
>
> XPConnect magic allows script to pass a function instead of a class.
>

Thank you Neil,
now i understand.
I implemented nsIDOMEventListener class and can catch events.
Thanks again!

YuLo

unread,
Oct 6, 2012, 8:08:51 AM10/6/12
to
четверг, 4 октября 2012 г., 13:35:33 UTC+4 пользователь YuLo написал:
But my problem is not solved yet.
I can catch keyboard event but where can i get KeyCode?
The event variable of HandleEvent() is of type nsIDOMEvent.
Casting it to nsIDOMKeyEvent and using GetKeyCode() crashes XULRunner.

YuLo

unread,
Oct 6, 2012, 8:24:21 AM10/6/12
to
суббота, 6 октября 2012 г., 16:08:51 UTC+4 пользователь YuLo написал:
sorry, do_QueryInterface solved the problem.
0 new messages