Bugzilla – Bug 19414
Implement finishPropagation() method
Last modified: 2012-10-11 06:17:21 UTC
The DOM lacks the ability to finish executing events leaving authors having to guess if an event has finished executing or not.
The need for the finishPropagation method can be summarized by the following Gecko bug here...
By having the finishPropagation method I would instead be able to not guess if an event has finished firing. This would free authors from having to rely on setTimeout which should NOT have to be used so far out of context as work-arounds.
It's very important that finishPropagation be implemented for ALL events both triggered by users and those artificially created through document.createEvent.
The term "finishPropagation" doesn't occur on that page, and it looks like it's about another topic entirely (initEvent). Did you link the wrong page?
@Glenn, no I determined the method name some time afterwards. The Gecko bug I mentioned merely fills a large chunk of the story of how I came to determine the need for the finishPropagation method.
(That bug is ten pages of comments on my screen, so I don't think it's really a "summary". :)
Note that if you just want to run a function from an event listener after all other event handlers for an event have completed, setTimeout(f, 0) is correct. This is guaranteed, with no guesswork involved, because event dispatch happens synchronously; nothing else (such as timers) can happen in the middle.
If that's not what you mean, I'd suggest showing a brief code example.
Compared to nearly a year's worth of work on just a rich editor alone a hundred pages would still be a summary. I neither have the time nor desire to put a test case together. What I have described should make plenty of logical sense and besides this can be tested out on my blog with public comments at jabcreations.com.
My point is simple, I shouldn't have to hack my code by using setTimeout when it's very clear that finishPropagation is what should be used, that's a clear conflict of the context in which it is used for. In fact I'm absolutely astonished and dumbfounded that finishPropagation was not in DOM Level 1 for goodness sakes. The fact that you even THOUGHT to suggest using setTimeout as an acceptable route should stop you immediately in your tracks. I'm not telling the computer to wait, I'm telling the computer to finish executing an event, those are completely different contexts. Even if I was told finishPropagation was slower than setTimeout I would still use finishPropagation instead because it is crystal clear that is what it is intended for. Using setTimeout is a clearly undeniable hack used to get around the limitation of the DOM and when ambiguities start to arise the specification can either clarify by doing what is right or sit back and watch sites begin implementing hacks leaving bad examples of code to live on for years while simultaneously misguiding people who are learning when they come across it.
It's not a hack or a workaround at all; it's a common paradigm in every event-based system to queue tasks, and in the Web platform setTimeout is how you do it. If you want it to run as soon as possible when the current task completes, you set the timeout to 0. It's simple and clean, and it doesn't care whether you're running from an event handler, a timer, a generic callback, or anything else: it works everywhere consistently.
I'll point out that what you're saying is a moving target: you started by saying that there's "guessing" and "presumption", and after explaining that there's no guesswork and that setTimeout is guaranteed to work, you started saying something else.
Beyond that, I'm not spending more time on this ticket; I'll leave it to others.
John, I read through that bug and it suggests you were using initEvent() inappropriately and should instead have used stopPropagation() and friends. As Aryeh mentions in this bug setTimeout(0, ...) is indeed the preferred way to queue something you want to have executed. I'm not sure there's anything for me to do here.
If you think there is something to be done, maybe an example (in code) of what you are trying to accomplish and how your proposed method would make that easier could help me understand what we are talking about here as the bug did not.
This is a joke right? No spare tire, a doughnut is round so use a doughnut right?
The setTimeout method has nothing to do with events.
[setTimeout] -> [something unrelated to event waits for event to expire]
Anne, why would I want to use stopPropagation to stop an event when I'm trying to have it FINISH firing the event?!
[copy .value from textarea]
[update nodes in relevant portion of rich editor]
Just use Firefox and then create a contenteditable element...
...and then either use the onpaste event or capture e.ctrl and the v key's keyCode and then give focus to a textarea.
Without using setTimeout fire the event.
You CAN'T fire the event, the event is stuck waiting on the code.
No, we DON'T want to stop the event because we're under the presumption that we do NOT have access to the clipboard.
The event MUST be fired AFTER focus is given to the textarea to convert the pasted content to text/plain. Then AFTER the event has fired thanks to finishPropagation use scripting to move the textarea's .value and determine where the user intended to paste the content in to the contenteditable element.
This is not a difficult concept by any means. We should NOT be hacking a language and using things out of far out of their context because over a decade ago people thought of FOUR different ways to stop an event but not a single way to finish it! There is no logical valid reason to argue against doing what should have been done in DOM Level 1.
So why not use event.stopPropagation() if you want the event to stop being dispatched? Or event.stopImmediatePropagation() if you want it not to reach any other listeners either?
The user triggers the event when they paste content, why would I stop the event from pasting the content inside of the textarea? That makes absolutely no sense! I *WANT* the paste event to trigger in the textarea after I have given it focus so that I can take the text (that now no longer is (X)HTML) so I can put it in to the contenteditable element where the user intended. The whole point is to prevent someone from going to a highly inappropriate site, selecting large portion or even the entire page in Firefox and then easily posting it with the rich text editor. Stopping the event and finishing the event are two completely opposite things.
It sounds like you do not know what event.stopPropagation() actually does. It is very different from event.preventDefault().
Created attachment 1222 [details]
Example of how stopPropagation is not what is needed.
Again stopPropagation is not the answer.
In this very simple test case I alert the value of the textarea. Because there is no correct way to tell the browser to FINISH the event there is nothing I can alert.
This means that without the setTimeout *HACK* I can not retrieve the filtered paste value from the textarea properly to put it back in to the editing element.
Well yeah, as far as I can tell that's because paste is not synchronous but rather queues a task to insert the data. So either you get the data from the clipboard (if that's supported already, not sure about the details here) and prevent the default action of the user operation, or you queue a task yourself (indeed, using setTimeout()).
There is nothing really we could introduce for this kind of thing like you proposed since pasting is apparently asynchronous (afaict).