Hi Robert,
I wouldn't say Event.stopPropagation() does not work, it simply doesn't operate the way you expect it to. In fact, there are very few cases where stopping the propagation of an event is relevant in the InDesign DOM event field, because most of the time we only manage an event from a single listener and through a single event handler. That is, our code usually manages a single propagation step and there is no further stage to be stopped at all.
What is confusing in your code is that two distinct events are actually considered, each having its own propagation process. The first event that occurs—say ev1—is a beforeClose on the LayoutWindow target, then a distinct beforeClose event occurs—ev2—on the Document target.
Stopping event propagation has sense only if some event has multiple registered listeners and/or handlers that may manage the event instance during its BUBBLING phase, that is, from the AT_TARGET step to the very last listener in the hierarchy. Let's consider ev1 (that is, the LayoutWindow beforeClose event). It occurs at the LayoutWindow target, then it 'bubbles' to the Document level (since LayoutWindow.parent is a doc) and finally to the Application level. Hence there are three propagation steps for that event. As for ev2 (that is, the Document beforeClose event), it occurs separately. Its target is the document being closed, then it bubbles to the app, so there are two propagation steps for that event.
To highlight this, let's create a generic event handler (evHandler) then attach it to any possible listener for the 'beforeClose' event:
#targetengine 'test01'
function evHandler(ev)
{
alert([
'evHandler being called.',
'target: ' + ev.target.constructor.name,
'listener: ' + ev.currentTarget.constructor.name,
'phase: ' + ev.eventPhase
].join('\r'));
}
// assuming that a document is open
// just before you execute the script
// ---
app.activeWindow.addEventListener('beforeClose', evHandler);
app.activeDocument.addEventListener('beforeClose', evHandler);
app.addEventListener('beforeClose', evHandler);
On closing the document's window, you will observe that evHandler is called 5 times, that is:
• 3 times for the window's beforeClose event (ev1) which traverses LayoutWindow, Document and Application, in that order;
• 2 times for the document's beforeClose event (ev2) which traverses Document and Application, in that order.
Now if you restart InDesign, set up a similar context and append the line
ev.stopPropagation();
to evHandler before you run the script, then you observe that evHandler is now called twice, that is, once for each event. Only the AT_TARGET phase is reported, because both the window and the document event propagation is stopped as soon as the event has been managed (at the target stage). That's the actual meaning of stopPropagation(). This method only prevents a specific event from being handled by higher listeners during the bubbling mechanism. More on this topic can be found here: http://www.quirksmode.org/js/events_order.html
But as I said above, there is usually no point in handling events from volatile listeners such as Document or Window instances when dealing with InDesign DOM events. Most scripts set listeners and handlers at the Application level, since this is a stable entity that can listen to any event (whatever its target).
Hope that helps.
@+
Marc