Closed Bug 302546 Opened 19 years ago Closed 19 years ago

initkeyEvent does not work in firefox versions > 1.0.4

Categories

(Core :: DOM: Events, defect)

Other Branch
defect
Not set
normal

Tracking

()

RESOLVED INVALID

People

(Reporter: sergej.z, Assigned: jst)

References

()

Details

User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; ru-RU; rv:1.7.10) Gecko/20050717 Firefox/1.0.6 Build Identifier: Mozilla/5.0 (Windows; U; Windows NT 5.1; ru-RU; rv:1.7.10) Gecko/20050717 Firefox/1.0.6 initKeyEvent function properly workes on all Firefoxes < 1.0.5 and seamonkey. Since 1.0.5 it fails with: "uncaught exception: [Exception... "Component returned failure code: 0x80070057 (NS_ERROR_ILLEGAL_VALUE) [nsIDOMKeyEvent.initKeyEvent]" nsresult: "0x80070057 (NS_ERROR_ILLEGAL_VALUE)" location: "JS frame :: http://forum.vingrad.ru/html/translit_only.js :: encodeCharacter :: line 4" data: no]" Reproducible: Always Steps to Reproduce: 1. Go to http://files.vingrad.ru/sergej.z/bugs/initevent.html , or use the sample code. Try this with firefox and seamonkey. write some random characters into textarea. <!-sample.html----------------------> <html> <head> <title>initEvent Test</title> <script> function printJ(MyEvent) { var letter="J"; //This letter should always replace the original one. //everything, but the letter, should remain same. MyEvent.initKeyEvent( MyEvent.type, MyEvent.canBubble,MyEvent.cancelable, MyEvent.view,MyEvent.ctrlKey,MyEvent.altKey,MyEvent.shiftKey, MyEvent.metaKey, letter, //letter itself letter.charCodeAt(0)//its code ); return true; } </script> </head> <body> Just press any key. The result should always be "J" <br> <textarea onkeypress="printJ(event);"></textarea> </body> </html> <!-----------------------------> Actual Results: Firefox < 1.0.5 as well as seamonkey correctly replace every letter with "J". Newer versions of firefox don't. Take a look into javascript console for details. Expected Results: initKeyEvent should not throw an exception. I need this function for implementation of "translit", a function which replaces pressed latin characters by its cyrillic sound-eqvivalent characters. This script worked for about an year at http://www.forum.vingrad.ru. Now, after new releases of mozilla it become useless :( PS: Anyway, Graet Thanks to whole mozilla team for a wondefull browser :) Sergej.Z
Events were changed pretty dramatically, including dispatching events to chrome code, because in some cases that would be a security hole. I don't know if this was meant to be broken or not, though.
Assignee: nobody → events
Component: General → DOM: Events
Product: Firefox → Core
QA Contact: general → ian
Version: unspecified → Other Branch
(bug 289940, I forgot to mention)
-> jst to determine whether this bug is valid
Assignee: events → jst
This is INVALID according to DOM2 Events spec. initKeyEvent() is depending on initEvent(), and it has the following restrictions. http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-Event-initEvent | This method may only be called before the Event has been | dispatched via the dispatchEvent method, though it may be | called multiple times during that phase if necessary. See bug 296704 for details of the change made in firefox 1.0.5.
First of all, thanks for your reaction. Thank you for the explanation of DOM.initKeyEvent as well. Anyway, . I realy don't know how exactly the event handling is implemented into the browser, but does component.dispatchEvent really come before my "onkeypress" internally? If so, my function would be called after event is processed, or am I wrong? Anyway, I rewrote the code in the way such that initKeyEvent should work in acording to your assumption. Now I first try to create event, than to init and finally to dispatch. http://files.vingrad.ru/sergej.z/bugs/createevent.html Unfortunatly this did not help. Message is still "uncaught exception: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsIDOMKeyEvent.initKeyEvent]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: http://files.vingrad.ru/sergej.z/bugs/createevent.html :: printO :: line 19" data: no]" Thus in my opinion it can oly be a bug.... Can it be handled here, or shoul one open a new ticket? Here the sample code: <!--sample.html----------------------> <html> <head> <title>createEvent Test</title> <script> function printO(MyComponent,MyEvent) { var letter="O"; //This letter should always replace the original one. var NewEvent = document.createEvent("Events"); //New created event //everything, but the letter, should remain same. NewEvent.initKeyEvent( MyEvent.type, MyEvent.canBubble,MyEvent.cancelable, MyEvent.view,MyEvent.ctrlKey,MyEvent.altKey,MyEvent.shiftKey, MyEvent.metaKey, letter, //letter itself letter.charCodeAt(0)//its code ); MyComponent.dispatchEvent(NewEvent); MyEvent.stopPropagation(); MyEvent.preventDefault(); return true; } </script> </head> <body> Just press any key. The result should always be "O" <br> <textarea onkeypress="printO(this,event);"></textarea> </body> </html> <!----------------------------->
(In reply to comment #5) > I realy don't know how exactly the event handling is implemented into the > browser, but does component.dispatchEvent really come before my "onkeypress" > internally? If so, my function would be called after event is processed, > or am I wrong? dispatchEvent() is called internally and it invokes your onkeypress handler. So it is not valid to call MyEvent.initKeyEvent() in the event handler. > var NewEvent = document.createEvent("Events"); //New created event The event must be created with a parameter "KeyEvents" but not "Events" in order to use initKeyEvents(). Although this change solves the error, you are still unable to replace the input character. Because mozilla ignores any keyboard events triggered by web pages' scripts.
Thank you. I tried out to replace Events by KeyEvents and now can see, that my listener function goes into endless recursion becouse calling of dispatchEvent calls my listener function. Finally I have some questions : 1) Is it not strange, that endless recurion occure at this point? This means, that dispatchEvent into listener function combination would never work. 2) What is initKeyEvent than good for? There is no possibility to make any use out of it in this. 3) In that context I realized, that there is no possibility to exchange letters by the script. Is it right? I'm very sorry if those questions dont belong to this board, but I know no other way to communicate with you, developers. Please tell me if there are chances for my plan to be realized. Otherwise I have to rewrite whole script. It is not difficult, but I would like to be sure, that there is no other possibilities. Thanks in advance.
> 1) Is it not strange, that endless recurion occure at this point? No. DOM events are fully reentrant. Event handlers can trigger other events, including ones that trigger the same handler. > 2) What is initKeyEvent than good for? Initializing and sending a new event. > 3) In that context I realized, that there is no possibility to exchange > letters Sure there is. preventDefault() on the original event, dispatch your new one, don't mess with your own event... Note that you might have to have expanded privileges in some cases for this to work. Marking invalid, since the event system behavior is correct...
Status: UNCONFIRMED → RESOLVED
Closed: 19 years ago
Resolution: --- → INVALID
Thanks for you answer. It sounds very logicaly in theory, but in the praxis there are stil problems.. ------------------------------- Me: >>2) What is initKeyEvent than good for? You: >Initializing and sending a new event. --------------------- Sure, but the system does not allow to send event created by me. I realized 2 things, that make the usage of functions like "initKeyEvent" impossible 1) One is not allowed to change events created by browser. 2) One is not allowed to send her own events. That´s a magic circle in my eyes.. That was the reason, why I wrote that it is impossible to handle events correctly with current model. What I need is a running example, where event is created and send and accepted by the system. I was unable to create such one for reasons written above... Otherwise it´s impossible to talk with each other, becouse we are speaking about different kind of problem... I solved my problem now by 1) divide text into to parts. before letter and after letter. 2) inserting before_text + new_letter + after_text. It is obviously worse solution, that become very slovly with growing amount of text.
> Sure, but the system does not allow to send event created by me. Sure it does. What makes you say it does not? Your code in comment 5 dispatches an event just fine, if it's fixed per comment 6. You say so yourself in comment 7 -- your event is clearly being sent. So I'm really not sure what you're talking about.
The event seems to be dispatched (listener function is called). But the textarea simply ignores the created event. Here is a workaround to avoid endless loop(I mark the event). As one can see, everything works as expected, but there is no result at the textarea... <!--sample.html----------------------> <html> <head> <title>createEvent Test</title> <script> function printO(MyComponent,MyEvent) { if(MyEvent.createdByMe) return true; var letter="O"; //This letter should always replace the original one. var NewEvent = document.createEvent("KeyEvents"); //New created event //everything, but the letter, should remain same. NewEvent.initKeyEvent( MyEvent.type, MyEvent.canBubble,MyEvent.cancelable, MyEvent.view,MyEvent.ctrlKey,MyEvent.altKey,MyEvent.shiftKey, MyEvent.metaKey, letter, //letter itself letter.charCodeAt(0)//its code ); //here we set the flag signilising, that event can be passed through NewEvent.createdByMe=true; MyComponent.dispatchEvent(NewEvent); return false; } </script> </head> <body> Just press any key. The result should always be "O" <br> <textarea onkeypress="return printO(this,event);"></textarea> </body>
> But the textarea simply ignores the created event. See comment 8 (about privileges) and bug 303713 (which describes exactly that issue and only that issue).
Thank you for detailed explanation and wasted time... Unfortunatly the solution with expanding privileges is not acceptable in my case. The tool should be the small and fast one. Nobody will use it if she needs to click additional buttons each time she writes something into textarea. The microsoft solution with createRange seems to be more logical for such purposes, unfortinatly it is not available on mozilla... Thus I will stay useng the long version with copy, cut and paste in hope, that nobody will write long texts on my forum using the transliterator. Thanks anyway :) At this point I have no question anymore regarding this issue.
> The microsoft solution with createRange seems to be more logical You can insert text into a textarea at the caret using and selectionStart and selectionEnd: javascript:var textToAdd = "BBB"; var ta = document.getElementsByTagName("textarea")[0]; var v = ta.value, ss = ta.selectionStart, se = ta.selectionEnd; ta.value = v.substr(0, ss) + textToAdd + v.slice(se); var newIP = ss + textToAdd.length; ta.setSelectionRange(newIP, newIP); void 0
Jesse Ruderman, thank you for your suggestion. in Comment #9. I wrote already, that this is now the only one solution to my task. The problem is hidden by: ta.value = v.substr(0, ss) +textToAdd + v.slice(se); Inserting large amount of text the system slows down. It is not possible to type text any more...
You need to log in before you can comment on or make changes to this bug.