Bug 19414 - Implement finishPropagation() method
Implement finishPropagation() method
Product: WebAppsWG
Classification: Unclassified
Component: DOM
PC Windows XP
: P2 major
: ---
Assigned To: Anne
Depends on:
  Show dependency treegraph
Reported: 2012-10-09 21:51 UTC by John A. Bilicki III
Modified: 2012-10-11 06:17 UTC (History)
3 users (show)

See Also:

Example of how stopPropagation is not what is needed. (785 bytes, application/xhtml+xml)
2012-10-11 05:58 UTC, John A. Bilicki III

Note You need to log in before you can comment on or make changes to this bug.
Description John A. Bilicki III 2012-10-09 21:51:17 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...

In short while working on a rich text editor I discovered that Gecko browsers copy the (X)HTML code of a page selection. In the absence of the ability to convert the selection to plain/text in older browsers I have the caret focused on an invisible textarea where after the event finishes the selection is automatically converted to plain/text. I then had to have JavaScript copy the text and place it where the user expected the text to be copied to. At best I had to use the setTimeout method under the presumption that x-number of milliseconds should be sufficient.

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.
Comment 1 Glenn Maynard 2012-10-09 22:40:35 UTC
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?
Comment 2 John A. Bilicki III 2012-10-10 00:08:43 UTC
@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.
Comment 3 Glenn Maynard 2012-10-10 00:43:35 UTC
(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.
Comment 4 John A. Bilicki III 2012-10-10 02:56:38 UTC
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.
Comment 5 Glenn Maynard 2012-10-10 04:26:14 UTC
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.
Comment 6 Anne 2012-10-10 10:10:16 UTC
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.
Comment 7 John A. Bilicki III 2012-10-10 23:37:04 UTC
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?!

[focus() textarea]
[copy .value from textarea]
[update nodes in relevant portion of rich editor]

Just use Firefox and then create a contenteditable element...
<div contenteditable="true"></div>

...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.
Comment 8 Anne 2012-10-11 03:48:36 UTC
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?
Comment 9 John A. Bilicki III 2012-10-11 04:04:11 UTC
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.
Comment 10 Anne 2012-10-11 04:12:14 UTC
It sounds like you do not know what event.stopPropagation() actually does. It is very different from event.preventDefault().
Comment 11 John A. Bilicki III 2012-10-11 05:58:48 UTC
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.
Comment 12 Anne 2012-10-11 06:17:21 UTC
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).