Last Comment Bug 768310 - initEvent on already-dispatched event should be a noop (rather than throwing)
: initEvent on already-dispatched event should be a noop (rather than throwing)
Status: RESOLVED FIXED
: dev-doc-complete
Product: Core
Classification: Components
Component: DOM: Events (show other bugs)
: Trunk
: All All
: -- normal with 1 vote (vote)
: mozilla17
Assigned To: :Ms2ger
:
Mentors:
Depends on: 771932
Blocks:
  Show dependency treegraph
 
Reported: 2012-06-25 20:10 PDT by John A. Bilicki III
Modified: 2015-01-01 08:43 PST (History)
6 users (show)
ryanvm: in‑testsuite+
See Also:
Crash Signature:
(edit)
QA Whiteboard:
Iteration: ---
Points: ---
Has Regression Range: ---
Has STR: ---


Attachments
Select text in the contenteditable element and then paste to trigger the event and the correlating error. (1.76 KB, application/xhtml+xml)
2012-06-25 20:11 PDT, John A. Bilicki III
no flags Details
Patch v1 (2.29 KB, patch)
2012-07-08 12:35 PDT, :Ms2ger
bugs: review+
Details | Diff | Splinter Review

Description John A. Bilicki III 2012-06-25 20:10:22 PDT
User Agent: Mozilla/5.0 (Windows NT 5.2; WOW64; rv:10.0.5) Gecko/20100101 Firefox/10.0.5
Build ID: 20120531185831

Steps to reproduce:

My goal is to move the caret to a hidden layer, allow the paste event to occur and then use textContent to prevent (X)HTML from being inserted in to a contenteditable element.


Actual results:

e.initEvent(x,y,z) throws errors regardless of the event name.

e.initEvent(e.type,false,true);

e.initEvent('onkeypress',false,true);

e.initEvent('keypress',false,true);

e.initEvent('keydown',false,true);

etc.

The error message...

[Exception... "Component returned failure code: 0x80070057 (NS_ERROR_ILLEGAL_VALUE) [nsIDOMKeyEvent.initEvent]"  nsresult: "0x80070057 (NS_ERROR_ILLEGAL_VALUE)"  location: "JS frame :: file:///gecko-keydown-initEvent-bugs.xhtml :: text_paste :: line 35"  data: no]

This occurs in Firefox 4, 10 and 16 Nightly.


Expected results:

initEvent DOES work I imagine? Unable to find any documentation. I have used alert(e.type) to ensure I'm passing the correct event name.
Comment 1 John A. Bilicki III 2012-06-25 20:11:30 PDT
Created attachment 636579 [details]
Select text in the contenteditable element and then paste to trigger the event and the correlating error.

Select text in the contenteditable element and then paste to trigger the event and the correlating error.
Comment 2 Anthony Hughes (:ashughes) [GFX][QA][Mentor] 2012-07-05 11:12:24 PDT
Is this a Firefox bug or are you just trying to get developer assistance for something you are trying to code?
Comment 3 John A. Bilicki III 2012-07-05 11:40:37 PDT
This is explicitly a bug. If the report doesn't sound like it consider the perspective of someone coding, encountering a bug and then answering the questions asked by the form to fill out the bug report.

I attached a file for testing in Firefox and all the other browsers almost two weeks ago. The initEvent method does not fire the event to the bubbling stage (if I recall the bug correctly) in Firefox, all other browsers do. Did you take a look at the attachment?
Comment 4 Olli Pettay [:smaug] 2012-07-06 14:35:31 PDT
Note, you're calling initEvent on an event which is being dispatched, so initEvent is no-op in that case. The current spec says that we shouldn't throw anything though, just make the
method no-op.
Comment 5 John A. Bilicki III 2012-07-07 08:33:39 PDT
...so that is an excuse to avoid making initEvent forward compatible and requiring web authors like myself to lame out by using setTimeout for say fifty versions of Firefoxes until an editor updates the specification to not require an explicit dispatch while all the other browsers support the intuitive approach all the while?

Specifications exist to help ensure browsers act the same with the same code though browser implementations help web authors figure out where the specification requirements should be ultimately. If web authors like myself can't rely on web specifications we will simply ignore them. I'll get in contact with the editor of DOM4 events if need be though the actual need to allow initEvent to function without an event being "dispatched" when an event is already active has been clearly demonstrated.
Comment 6 Olli Pettay [:smaug] 2012-07-07 08:50:14 PDT
(In reply to John A. Bilicki III from comment #5)
> ...so that is an excuse to avoid making initEvent forward compatible and
> requiring web authors like myself to lame out by using setTimeout for say
> fifty versions of Firefoxes until an editor updates the specification to not
> require an explicit dispatch while all the other browsers support the
> intuitive approach all the while?
In other browsers the initEvent() call is no-op. It doesn't to anything, AFAIK.
If it does, it is a possible security bug.

But I'll change initEvent to become no-op also in Gecko.
Comment 7 :Aryeh Gregor (away until August 15) 2012-07-08 05:20:50 PDT
(In reply to John A. Bilicki III from comment #1)
> Created attachment 636579 [details]
> Select text in the contenteditable element and then paste to trigger the
> event and the correlating error.
> 
> Select text in the contenteditable element and then paste to trigger the
> event and the correlating error.

Chrome 21 dev alerts "keydown", and the tab crashes (sad tab).  Firefox 16.0a1 alerts "keydown" and does not crash, but then alerts an exception, then "p.textContent = ", and the text I was pasting gets put in the second (red) box, unformatted.  IE10 Developer Preview alerts "keydown" and then "p.textContent = ", and then puts a "v" in the second box.  Opera Next 12.00 alpha is the same as Firefox except without alerting the exception in between.  What's the expected behavior here?  I vote that we do not follow Chrome's behavior of crashing.

What do you think initEvent should do here?  initEvent is meant to initialize an event you create -- it's not meant to do anything to an event fired by the browser.  If you try to do that, it should probably either do nothing or throw.  Ms2ger has filed a spec bug: https://www.w3.org/Bugs/Public/show_bug.cgi?id=17715

But basically, I'm not seeing what we're doing worse than other browsers here, except that we're firing an exception and they're apparently just ignoring the call.  Do you have any reason to believe that initEvent is not a no-op in other browsers?

(In reply to John A. Bilicki III from comment #5)
> ...so that is an excuse to avoid making initEvent forward compatible and
> requiring web authors like myself to lame out by using setTimeout for say
> fifty versions of Firefoxes until an editor updates the specification to not
> require an explicit dispatch while all the other browsers support the
> intuitive approach all the while?

You haven't explained what you think initEvent() is supposed to actually do here, or whether other browsers actually do it, so I can't really judge if it's intuitive or not.

> I'll get in
> contact with the editor of DOM4 events if need be though the actual need to
> allow initEvent to function without an event being "dispatched" when an
> event is already active has been clearly demonstrated.

FWIW, Ms2ger and I are two of the three DOM4 editors, and we both seem to think initEvent() should be a no-op here.  It says "init" in the name, which is short for "initialization", and one doesn't usually initialize an object that's already started to be used.  If you don't agree, you should probably explain what you want it to do in more detail, and why, because it's not clear at all.
Comment 8 John A. Bilicki III 2012-07-08 06:00:53 PDT
Please keep in mind that my perspective is that of a web author, I'm not versed in programming standards in to a browser and I can only interpret specifications from a web authoring perspective. I'm doing my best to make sure I have my references correct. One thing I'm not certain about is what "no-op" is, I am guessing it's a reference to a user-triggered event instead of a web author-triggered event?

The goal is to use initEvent to control the stages of event flow when necessary. After spending considerable amount of time going through DOM events I saw nothing more relevant to triggering the next phase of an event. I used the following image/chart as reference...

http://www.w3.org/TR/DOM-Level-3-Events/#event-flow

...I find it exceptionally difficult to believe that absolutely no one else who has ever written code for the web has never expressed the need to manually control the phases of an event.

Since initEvent was originally intended to work with an author-triggered dispatched event unless there are security concerns with handling user-triggered events as Olli mentioned then making this handle events regardless of whether it was author or user triggered makes the most sense. It would not make sense for me to cancel an event that is already occurring and then replace it with my own event, that would be redundant redundant.

Aryeh, in the browsers I tested I did not notice any errors (without try/catch) and the event phase was moved from 2 to 3 (targeting to bubbling) in my example allowing the event to finish the event of pasting text. In order to work around Firefox's behavior I had to add try/catch along with setTimeout however I think most people would agree that using initEvent makes more sense to trigger the bubbling phase than using setTimeout even if that's not how the context is currently/previously defined.

Firing the third phase/bubbling is necessary in my example because I still need to actually work on the same goal after the event has finished. Taking the text without the formatting (Firefox copies the (X)HTML if you copy a part of any webpage) and making THAT plain text (or formatting it yourself) and putting in place of where the inaccessible clipboard's contents would have been placed is the goal. From an end-users perspective they could (possibly CTRL+a or simply partially select part of a page) CTRL+c and CTRL+v on any page and instantly invalidate the contents intended to be submitted in the editor that I'm working on.

Without this ability the worst case scenario is I'd have to keep using this hack. Usually the problems with standards is that they are too ambiguous, this is an example where it's over-expressed where it's limited the functionality of initEvent. Using the approach of initEvent with filtering out just the text I'm able to allow legitimate copy/paste of web content in Firefox while in example making it exceptionally difficult for someone to go to an inappropriate site that is not safe for work and allow someone to potentially and *easily* post a lot of undesirable content as the project I'm working on is intended to eventually be used by businesses. In short I want to prevent people from copying full pages from 4chan (in example) and pasting their contents as (X)HTML code on business sites as easily as Firefox currently allows with contenteditable elements.

So in the case where the event is not created by dispatch event though is actually simply a user-initiated event the initEvent should simply trigger the bubbling phase and then (at the lower level of how things are coded I suppose) return control back to the script so that (in my example) the script can continue to process after the event has finished the bubbling phase.

If this doesn't clarify enough I'd be happy to take the time to shoot a demonstration video to visualize each step in relation to what code is triggering at each given point (not being sarcastic/rude/etc in case this may seem like it), sometimes things just don't click unless it's visual. I will also be implementing the feature that utilizes all of this sometime in the next few weeks though it will obviously not be a standalone demonstration like the attachment I added earlier.
Comment 9 Olli Pettay [:smaug] 2012-07-08 07:26:35 PDT
(In reply to John A. Bilicki III from comment #8)
> The goal is to use initEvent to control the stages of event flow when
> necessary.
Yes, you can control whether or not the event bubbles using initEvent, but that happens
*before* event dispatch. Once event is being dispatched, you should not be able to change
its type or whether it bubbles or whether the event is trusted or not.
During event dispatch you can control the flow using .stopPropagation() or .stopImmediatePropagation(),
and whether or not the default handling runs is controlled using .preventDefault() 

no-op in this context means a method which does nothing. http://catb.org/jargon/html/N/no-op.html
Comment 10 :Aryeh Gregor (away until August 15) 2012-07-08 07:50:33 PDT
(In reply to John A. Bilicki III from comment #8)
> The goal is to use initEvent to control the stages of event flow when
> necessary.

That is not what initEvent is meant to do.  As Olli says, it's what .stopPropagation(), .stopImmediatePropagation(), and .preventDefault() are for.

> Aryeh, in the browsers I tested I did not notice any errors (without
> try/catch) and the event phase was moved from 2 to 3 (targeting to bubbling)
> in my example allowing the event to finish the event of pasting text. In
> order to work around Firefox's behavior I had to add try/catch along with
> setTimeout however I think most people would agree that using initEvent
> makes more sense to trigger the bubbling phase than using setTimeout even if
> that's not how the context is currently/previously defined.

As far as anyone else here has been able to tell, initEvent() does nothing in any browser in your test-case.  It's ignored.  You can just leave it out and it will have the same effect.  Firefox throws, yes, but that doesn't matter because the call is pointless.

If you believe initEvent() is actually doing something in this case in non-Firefox browsers, please say exactly what and show evidence to that effect.  Preferably, please give a test-case that behaves in a different way (in non-Firefox browsers) if initEvent() is deleted entirely.

So just to be clear: if I run your test-case from comment 1 in IE10 Developer Preview, Chrome 21 dev, and Opera Next 12.00 alpha I observe the *exact same behavior* if I delete the line "try {e.initEvent(e.type,false,true);} catch (err) {alert(err);}".  So you may as well just not call initEvent().  It's a no-op in this case, i.e., does nothing.  We're happy to change Firefox to match the other browsers, and ignore initEvent().  But you seem to think that other browsers are *not* ignoring initEvent().  If that's the case, please demonstrate it with a test-case that behaves differently if initEvent() is removed.
Comment 11 :Ms2ger 2012-07-08 12:35:39 PDT
Created attachment 640094 [details] [diff] [review]
Patch v1
Comment 12 Olli Pettay [:smaug] 2012-07-08 12:41:27 PDT
Comment on attachment 640094 [details] [diff] [review]
Patch v1

Could you still test that other browsers have the same behavior.
Comment 13 :Ms2ger 2012-07-08 12:47:16 PDT
Opera, Chrome, IE10 pass <http://w3c-test.org/webapps/DOMCore/tests/submissions/Ms2ger/Event-initEvent.html>.
Comment 15 Ed Morley [:emorley] 2012-08-04 11:29:18 PDT
Backed out with the mass tree revert to get rid of the OS X M5 orange:
https://hg.mozilla.org/mozilla-central/rev/c801b99d726f
Comment 16 Ryan VanderMeulen [:RyanVM] 2012-08-04 14:48:10 PDT
https://hg.mozilla.org/integration/mozilla-inbound/rev/6932dd959e4c
Comment 17 Ryan VanderMeulen [:RyanVM] 2012-08-04 18:41:12 PDT
https://hg.mozilla.org/mozilla-central/rev/6932dd959e4c
Comment 18 Jean-Yves Perrier [:teoli] 2015-01-01 08:43:44 PST
I've updated:
https://developer.mozilla.org/en-US/Firefox/Releases/17#DOM
and
https://developer.mozilla.org/en-US/docs/Web/API/Event
https://developer.mozilla.org/en-US/docs/Web/API/Event.initEvent

Of course, the information that initEvent is nowadays deprecated is clearly indicated.

Note You need to log in before you can comment on or make changes to this bug.