Copy link to clipboard
Copied
Hey all,
is there any way to delete an event once created?
Customers might close and reopen a plugin and the events will get fired twice and more often if I cannot check and delete them properly. Tried already several ways, here is one of them:
( Deleting them from a list of EventListeners doesn't seem to work either: app.eventListeners.item('afterSelection').remove(); )
function removeListener() {
app.removeEventListeners.item(Event.AFTER_SELECTION_CHANGED, afterSelection);
app.removeEventListeners.item(Event.AFTER_OPEN, afterOpen);
}
/**
* internal selection event handler dispatching to frontend
* @Param data
*/
function afterSelection (data) {
// important to catch here, some selections return data we wont handle
// sometimes a dialogue even appears in InDesign nagging to do something about it
try {
if (app.selection[0].id) {
eventObj.data = app.selection[0].id;
eventObj.type = "AfterSelectionChanged";
eventObj.dispatch();
}
} catch (exc) {
writeln(exc.message);
}
}
/**
* dispatch event when a document is loaded
* this is needed to tell the plugin to refresh its data
* @Param data
*/
function afterOpen(data) {
eventObj.data="newly opened document, just react!";
eventObj.type="AfterOpen";
eventObj.dispatch();
}
// This lib must be loaded into memory
var externalOb = new ExternalObject("lib:" + "PlugPlugExternalObject");
var eventObj = new CSXSEvent();
// listening to a selection
// --> always document level --> even fired when selecting a tool
app.addEventListener(Event.AFTER_SELECTION_CHANGED, afterSelection);
// listening to open document
app.addEventListener(Event.AFTER_OPEN,afterOpen);
The source above (.jsx) is called from the plugin when opened..
Thanks a lot for any hint!
Daniel
Hi Daniel,
First, let's make something clear. Technically an Event is not a kind of entity you can remove. What you can do with an Event is stopping its propagation, cancelling its default behavior—when possible—and, finally, stopping listening to it. That's of course the latter option your question relates to. So you don"t want to remove an event, you want to remove an event listener, which is a callback mechanism temporarily attached to a specific event type.
The above distinction is important,
...Copy link to clipboard
Copied
Hi Daniel,
First, let's make something clear. Technically an Event is not a kind of entity you can remove. What you can do with an Event is stopping its propagation, cancelling its default behavior—when possible—and, finally, stopping listening to it. That's of course the latter option your question relates to. So you don"t want to remove an event, you want to remove an event listener, which is a callback mechanism temporarily attached to a specific event type.
The above distinction is important, as it allows to rephrase your question the right way: How do I remove an EventListener? Which then leads to: How do I refer to the EventListener I want to remove? Keep in mind that multiple event listeners might be attached to the same event type, including listeners declared by scripts external to yours. So it is not a good idea, in general, to target every event listener available for a specific event type, the problem is clearly to recover your own event listener(s).
There are at least two ways to to that:
1. Using app.removeEventListener(eventType, handler, captures). — Here the recovery key is the handler function (or script file) that has been declared with the listener, with respect to a specific eventType and a specific captures flag. So you must provide a valid reference to the original handler to make it work. Maybe that's just a matter of taste but this approach doesn't sound very clean to me, as it somehow violate the encapsulation principle offered through the EventListener object.
In your code this would look like:
app.removeEventListener(Event.AFTER_SELECTION_CHANGED, afterSelection, <captures>)
(Note that afterSelection is not a name, but an actual reference to your handler function, assuming this makes sense in the lexical scope from which the code is interpreted.)
2. Identifying the EventListener by its name or its ID within the app.eventListeners collection, then removing it. — Here the recovery key is either the name, or the ID, of the event listener you want to remove. This supposes you have specified, or stored, this information somewhere, while you were adding the listener.
var myListener = app.eventListeners.add(…);
var myListenerID = myListener.id; // backup me
So later you will be able to recover that instance and remove it:
var myListener = app.eventListeners.itemByID(myListenerID);
if( myListener.isValid ) myListener.remove();
If the name is your recovery key, make sure you have assigned a unique name to a unique listener (unless you need to remove multiple listeners based on the same name…), then do something like this:
var myListener = app.eventListeners.itemByName(keyName);
if( myListener.isValid ) myListener.remove();
Hope that helps.
@+
Marc
Copy link to clipboard
Copied
Hello Marc,
thanks a lot for your really detailed and clarifying answer.
By today i am working on the plugin again and see how it tuns out and keep you informed.
I am pretty sure I tried already the first way you mentioned and had no success, surely some sort of typo.
Thanks,
Daniel
Copy link to clipboard
Copied
dapleh wrote
… I am pretty sure I tried already the first way you mentioned and had no success, surely some sort of typo.
Hi Daniel,
not necessarily.
It could be that the communication between your plugin ( a HTML5 extenion? or a C++ plug-in? ) is not synchronized.
Also possible that the event will not fire in the moment you anticipating this. Or that the event is fired and the listener cannot listen. And that a counter you may have established in your handler function will not count up to a point where you like to remove the listener…
I had this with a loop that is adding new items to a page and is selecting the added items one after another directly after creation. Just to test the listener, not for practical purposes. In this test case the listener only registered the last added and selected item in the loop.
About your comment that activated tools or changing tools can trigger the event:
Normally this is not the case if nothing is selected. One exception is the Page Tool that will select the active page immediately after activated. And this also counts as a "afterSelectionChanged" event. If the user has several documents open and switching over to a different active document the event is also triggered, because a different page is now selected.
Best,
Uwe
Copy link to clipboard
Copied
Hi Uwe,
it is a HTML 5 plugin.
I am not having problems with receiving events or listening to them except that they are often fired twice for whatever reason. I just couldn't get rid of them or better stop listening to them which made my plugin do the same task over and over again, eg. refreshing the list of text frames.
You're right about the page tool, the comment in the code is ... old
Glad I am not alone with all that,
Thank you!
Daniel
Copy link to clipboard
Copied
dapleh wrote
… just couldn't get rid of them or better stop listening to them which made my plugin do the same task over and over again, eg. refreshing the list of text frames.
Hi Daniel,
then you need a mechanism independent on the listener that is notifying you when a specific task is done.
Could be an IdleTask perhaps. Or a temp file where you write a status into it or you do the status with a label on the objects of interest.
Regards,
Uwe
Copy link to clipboard
Copied
Hi Uwe,
brilliant idea! Thank you!
I'll be using that independant mechanism,
regards
Daniel