More event handler improvements
[WebKit-https.git] / LayoutTests / fast / dom / event-handler-attributes.html
1 <!DOCTYPE html>
2 <html>
3 <body>
4 <script src="../../resources/js-test-pre.js"></script>
5 <script>
6 description("Test which event listeners are set up by event handler attributes (the ones with names like onclick).");
7
8 const unusualEventNames = {
9     "webkitanimationend": "webkitAnimationEnd",
10     "webkitanimationiteration": "webkitAnimationIteration",
11     "webkitanimationstart": "webkitAnimationStart",
12     "webkittransitionend": "webkitTransitionEnd",
13 };
14
15 const windowEvents = [
16     "abort",
17     "animationend",
18     "animationiteration",
19     "animationstart",
20     "beforeunload",
21     "blur",
22     "canplay",
23     "canplaythrough",
24     "change",
25     "click",
26     "contextmenu",
27     "dblclick",
28     "devicemotion",
29     "deviceorientation",
30     "drag",
31     "dragend",
32     "dragenter",
33     "dragleave",
34     "dragover",
35     "dragstart",
36     "drop",
37     "durationchange",
38     "emptied",
39     "ended",
40     "error",
41     "focus",
42     "gesturechange",
43     "gestureend",
44     "gesturestart",
45     "hashchange",
46     "input",
47     "invalid",
48     "keydown",
49     "keypress",
50     "keyup",
51     "load",
52     "loadeddata",
53     "loadedmetadata",
54     "loadstart",
55     "message",
56     "mousedown",
57     "mouseenter",
58     "mouseleave",
59     "mousemove",
60     "mouseout",
61     "mouseover",
62     "mouseup",
63     "mousewheel",
64     "offline",
65     "online",
66     "orientationchange",
67     "pagehide",
68     "pageshow",
69     "pause",
70     "play",
71     "playing",
72     "popstate",
73     "progress",
74     "ratechange",
75     "reset",
76     "resize",
77     "scroll",
78     "search",
79     "seeked",
80     "seeking",
81     "select",
82     "stalled",
83     "storage",
84     "submit",
85     "suspend",
86     "timeupdate",
87     "touchcancel",
88     "touchend",
89     "touchmove",
90     "touchstart",
91     "transitionend",
92     "unload",
93     "volumechange",
94     "waiting",
95     "webkitanimationend",
96     "webkitanimationiteration",
97     "webkitanimationstart",
98     "webkitdeviceproximity",
99     "webkittransitionend",
100     "webkitwillrevealbottom",
101     "webkitwillrevealleft",
102     "webkitwillrevealright",
103     "webkitwillrevealtop",
104     "wheel",
105 ];
106
107 const documentEvents = [
108     "abort",
109     "beforecopy",
110     "beforecut",
111     "beforepaste",
112     "blur",
113     "change",
114     "click",
115     "contextmenu",
116     "copy",
117     "cut",
118     "dblclick",
119     "drag",
120     "dragend",
121     "dragenter",
122     "dragleave",
123     "dragover",
124     "dragstart",
125     "drop",
126     "error",
127     "focus",
128     "input",
129     "invalid",
130     "keydown",
131     "keypress",
132     "keyup",
133     "load",
134     "mousedown",
135     "mouseenter",
136     "mouseleave",
137     "mousemove",
138     "mouseout",
139     "mouseover",
140     "mouseup",
141     "mousewheel",
142     "paste",
143     "pointerlockchange",
144     "pointerlockerror",
145     "readystatechange",
146     "reset",
147     "scroll",
148     "search",
149     "securitypolicyviolation",
150     "select",
151     "selectionchange",
152     "selectstart",
153     "submit",
154     "touchcancel",
155     "touchend",
156     "touchmove",
157     "touchstart",
158     "webkitfullscreenchange",
159     "webkitfullscreenerror",
160     "webkitwillrevealbottom",
161     "webkitwillrevealleft",
162     "webkitwillrevealright",
163     "webkitwillrevealtop",
164     "wheel",
165 ];
166
167 const elementEvents = [
168     "abort",
169     "animationend",
170     "animationiteration",
171     "animationstart",
172     "autocomplete",
173     "autocompleteerror",
174     "beforecopy",
175     "beforecut",
176     "beforeload",
177     "beforepaste",
178     "blur",
179     "canplay",
180     "canplaythrough",
181     "change",
182     "click",
183     "contextmenu",
184     "copy",
185     "cut",
186     "dblclick",
187     "drag",
188     "dragend",
189     "dragenter",
190     "dragleave",
191     "dragover",
192     "dragstart",
193     "drop",
194     "durationchange",
195     "emptied",
196     "ended",
197     "error",
198     "focus",
199     "focusin",
200     "focusout",
201     "gesturechange",
202     "gestureend",
203     "gesturestart",
204     "input",
205     "invalid",
206     "keydown",
207     "keypress",
208     "keyup",
209     "load",
210     "loadeddata",
211     "loadedmetadata",
212     "loadstart",
213     "mousedown",
214     "mouseenter",
215     "mouseleave",
216     "mousemove",
217     "mouseout",
218     "mouseover",
219     "mouseup",
220     "mousewheel",
221     "paste",
222     "pause",
223     "play",
224     "playing",
225     "progress",
226     "ratechange",
227     "reset",
228     "scroll",
229     "search",
230     "seeked",
231     "seeking",
232     "select",
233     "selectstart",
234     "stalled",
235     "submit",
236     "suspend",
237     "timeupdate",
238     "touchcancel",
239     "touchend",
240     "touchmove",
241     "touchstart",
242     "transitionend",
243     "volumechange",
244     "waiting",
245     "webkitanimationend",
246     "webkitanimationiteration",
247     "webkitanimationstart",
248     "webkitcurrentplaybacktargetiswirelesschanged",
249     "webkitfullscreenchange",
250     "webkitfullscreenerror",
251     "webkitkeyadded",
252     "webkitkeyerror",
253     "webkitkeymessage",
254     "webkitneedkey",
255     "webkitplaybacktargetavailabilitychanged",
256     "webkitpresentationmodechanged",
257     "webkittransitionend",
258     "webkitwillrevealbottom",
259     "webkitwillrevealleft",
260     "webkitwillrevealright",
261     "webkitwillrevealtop",
262     "wheel",
263 ];
264
265 const bodyElementWindowForwardedEvents = [
266     "beforeunload",
267     "blur",
268     "error",
269     "focus",
270     "focusin",
271     "focusout",
272     "hashchange",
273     "load",
274     "message",
275     "offline",
276     "online",
277     "orientationchange",
278     "pagehide",
279     "pageshow",
280     "popstate",
281     "resize",
282     "storage",
283     "unload",
284     "webkitwillrevealbottom",
285     "webkitwillrevealleft",
286     "webkitwillrevealright",
287     "webkitwillrevealtop",
288 ];
289
290 const bodyElementDocumentForwardedEvents = [
291     "selectionchange",
292 ];
293
294 const nonEventNames = [
295     "noneventname",
296 ];
297
298 var magicNumber = 2;
299 var sideEffect;
300
301 function testHandler(object, install, remove, eventName)
302 {
303     const capturedMagicNumber = ++magicNumber;
304     install(capturedMagicNumber);
305
306     if (unusualEventNames[eventName])
307         eventName = unusualEventNames[eventName];
308
309     sideEffect = capturedMagicNumber - 1;
310     if (object !== window && object !== document)
311         object.dispatchEvent(new Event(eventName));
312     const handlerOnTarget = sideEffect === capturedMagicNumber;
313     sideEffect = capturedMagicNumber - 1;
314     window.dispatchEvent(new Event(eventName));
315     const handlerOnWindow = sideEffect === capturedMagicNumber;
316     sideEffect = capturedMagicNumber - 1;
317     document.dispatchEvent(new Event(eventName));
318     const handlerOnDocument = sideEffect === capturedMagicNumber;
319
320     remove();
321
322     sideEffect = capturedMagicNumber - 1;
323
324     object.dispatchEvent(new Event(eventName));
325     window.dispatchEvent(new Event(eventName));
326     document.dispatchEvent(new Event(eventName));
327
328     const misfire = sideEffect === capturedMagicNumber;
329
330     var result;
331
332     if (!handlerOnTarget && !handlerOnWindow && !handlerOnDocument)
333         result = "none";
334     else
335         result = ((handlerOnTarget ? ", target" : "") + (handlerOnWindow ? ", window" : "") + (handlerOnDocument ? ", document" : "")).substring(2);
336
337     if (misfire)
338         result += ", remove failed";
339
340     return result;
341 }
342
343 function testScriptAttribute(object, eventName)
344 {
345     const attributeName = "on" + eventName;
346     return testHandler(object, function(capturedMagicNumber) {
347         object[attributeName] = function() { sideEffect = capturedMagicNumber };
348     }, function() {
349         object[attributeName] = null;
350     }, eventName);
351 }
352
353 function testContentAttribute(element, eventName)
354 {
355     const attributeName = "on" + eventName;
356     return testHandler(element, function(capturedMagicNumber) {
357         element.setAttribute(attributeName, "sideEffect = " + capturedMagicNumber);
358     }, function() {
359         element.removeAttribute(attributeName);
360     }, eventName);
361 }
362
363 function testElementAttribute(object, eventName)
364 {
365     const scriptAttributeResult = testScriptAttribute(object, eventName);
366     const contentAttributeResult = testContentAttribute(object, eventName);
367     if (scriptAttributeResult === contentAttributeResult)
368         return scriptAttributeResult;
369     return "script: " + scriptAttributeResult + "; content: " + contentAttributeResult;
370 }
371
372 function sortUnique(array)
373 {
374     return array.sort().filter(function(item, i) {
375         return i === 0 || item !== array[i - 1];
376     });
377 }
378
379 function arrayUnion()
380 {
381     var combined = [];
382     for (var i = 0; i < arguments.length; ++i)
383         combined = combined.concat(arguments[i]);
384     return sortUnique(combined);
385 }
386
387 function arrayDifference(a, b)
388 {
389     return a.filter(function(item) {
390         return b.indexOf(item) < 0;
391     });
392 }
393
394 const allEventNames = arrayUnion(windowEvents, documentEvents, elementEvents, bodyElementWindowForwardedEvents, bodyElementDocumentForwardedEvents, nonEventNames);
395
396 var sectionOpen = false;
397
398 function endSection()
399 {
400     if (sectionOpen) {
401         debug("");
402         sectionOpen = false;
403     }
404 }
405
406 function section(title)
407 {
408     endSection();
409     debug(title);
410     debug("");
411     sectionOpen = true;
412 }
413
414 function testArray(array, prefix, expected, sectionName)
415 {
416     section(sectionName);
417     for (var i = 0; i < array.length; ++i) {
418         shouldBeEqualToString(prefix + ", \"" + array[i] + "\")", expected);
419     }
420 }
421
422 const nonHTMLElement = document.createElementNS("foo", "foo");
423 const element = document.documentElement;
424 const bodyElement = document.body;
425 const audioElement = document.createElement("video");
426 const framesetElement = document.createElement("frameset");
427 const inputElement = document.createElement("input");
428 const videoElement = document.createElement("video");
429 const rectElement = document.createElementNS("http://www.w3.org/2000/svg", "rect");
430
431 testArray(windowEvents, "testScriptAttribute(window", "window", "Event names we expect to be able to set on the window object");
432 testArray(arrayDifference(allEventNames, windowEvents), "testScriptAttribute(window", "none", "Event names we expect not to be able to set on the window object");
433
434 testArray(documentEvents, "testScriptAttribute(document", "document", "Event names we expect to be able to set on the document");
435 testArray(arrayDifference(allEventNames, documentEvents), "testScriptAttribute(document", "none", "Event names we expect not to be able to set on the document");
436
437 testArray(elementEvents, "testElementAttribute(element", "target", "Event names we expect to be able to set on an element (tested on the &lt;html> element)");
438 testArray(arrayDifference(allEventNames, elementEvents), "testElementAttribute(element", "none", "Event names we expect not to be able to set on an element (tested on the &lt;html> element)");
439
440 testArray(elementEvents, "testElementAttribute(inputElement", "target", "Event names we expect to be able to set on an element (tested on the &lt;input> element)");
441 testArray(arrayDifference(allEventNames, elementEvents), "testElementAttribute(inputElement", "none", "Event names we expect not to be able to set on an element (tested on the &lt;input> element)");
442
443 testArray(elementEvents, "testElementAttribute(audioElement", "target", "Event names we expect to be able to set on an element (tested on the &lt;audio> element)");
444 testArray(arrayDifference(allEventNames, elementEvents), "testElementAttribute(audioElement", "none", "Event names we expect not to be able to set on an element (tested on the &lt;audio> element)");
445
446 testArray(elementEvents, "testElementAttribute(videoElement", "target", "Event names we expect to be able to set on an element (tested on the &lt;video> element)");
447 testArray(arrayDifference(allEventNames, elementEvents), "testElementAttribute(videoElement", "none", "Event names we expect not to be able to set on an element (tested on the &lt;video> element)");
448
449 testArray(bodyElementWindowForwardedEvents, "testElementAttribute(bodyElement", "window", "Event names we expect to be forwarded from &lt;body> element to window object)");
450 testArray(bodyElementDocumentForwardedEvents, "testElementAttribute(bodyElement", "document", "Event names we expect to be forwarded from &lt;body> element to document)");
451 testArray(arrayDifference(elementEvents, arrayUnion(bodyElementWindowForwardedEvents, bodyElementDocumentForwardedEvents)), "testElementAttribute(bodyElement", "target", "Non-forwarded event names on &lt;body> element");
452 testArray(arrayDifference(allEventNames, arrayUnion(elementEvents, bodyElementWindowForwardedEvents, bodyElementDocumentForwardedEvents)), "testElementAttribute(bodyElement", "none", "Event names we expect to not be able to set on &lt;body> element");
453
454 testArray(bodyElementWindowForwardedEvents, "testElementAttribute(framesetElement", "window", "Event names we expect to be forwarded from &lt;frameset> element to window object)");
455 testArray(bodyElementDocumentForwardedEvents, "testElementAttribute(framesetElement", "document", "Event names we expect to be forwarded from &lt;frameset> element to document)");
456 testArray(arrayDifference(elementEvents, arrayUnion(bodyElementWindowForwardedEvents, bodyElementDocumentForwardedEvents)), "testElementAttribute(framesetElement", "target", "Non-forwarded event names on &lt;frameset> element");
457 testArray(arrayDifference(allEventNames, arrayUnion(elementEvents, bodyElementWindowForwardedEvents, bodyElementDocumentForwardedEvents)), "testElementAttribute(framesetElement", "none", "Event names we expect to not be able to set on &lt;frameset> element");
458
459 testArray(elementEvents, "testElementAttribute(rectElement", "target", "Event names we expect to be able to set on an element (tested on the SVG &lt;rect> element)");
460 testArray(arrayDifference(allEventNames, elementEvents), "testElementAttribute(rectElement", "none", "Event names we expect not to be able to set on an element (tested on the SVG &lt;rect> element)");
461
462 testArray(allEventNames, "testElementAttribute(nonHTMLElement", "none", "Event names on a non-HTML element");
463
464 endSection();
465
466 /*
467
468 ----------------
469
470 To make the results of this test platform independent, there is no testing here for conditional events.
471 An alternative would be to always make these event handler attributes work even if the feature
472 that sends the events is turned off. See list here of IDL files that include these conditional events.
473
474 html/HTMLBodyElement.idl:    [Conditional=ORIENTATION_EVENTS, NotEnumerable, JSWindowEventListener] attribute EventListener onorientationchange;
475
476 html/HTMLFrameSetElement.idl:    [Conditional=ORIENTATION_EVENTS, NotEnumerable, JSWindowEventListener] attribute EventListener onorientationchange;
477
478 ----------------
479
480 It would be good to extend this test to cover more objects.
481 See list below of IDL files that indicate objects have these attributes as of the writing of this test.
482
483 Modules/battery/BatteryManager.idl:    attribute EventListener onchargingchange;
484 Modules/battery/BatteryManager.idl:    attribute EventListener onchargingtimechange;
485 Modules/battery/BatteryManager.idl:    attribute EventListener ondischargingtimechange;
486 Modules/battery/BatteryManager.idl:    attribute EventListener onlevelchange;
487
488 Modules/encryptedmedia/MediaKeySession.idl:    attribute EventListener onwebkitkeyadded;
489 Modules/encryptedmedia/MediaKeySession.idl:    attribute EventListener onwebkitkeyerror;
490 Modules/encryptedmedia/MediaKeySession.idl:    attribute EventListener onwebkitkeymessage;
491
492 Modules/indexeddb/IDBDatabase.idl:    attribute EventListener onabort;
493 Modules/indexeddb/IDBDatabase.idl:    attribute EventListener onerror;
494 Modules/indexeddb/IDBDatabase.idl:    attribute EventListener onversionchange;
495
496 Modules/indexeddb/IDBOpenDBRequest.idl:    attribute EventListener onblocked;
497 Modules/indexeddb/IDBOpenDBRequest.idl:    attribute EventListener onupgradeneeded;
498
499 Modules/indexeddb/IDBRequest.idl:    attribute EventListener onsuccess;
500 Modules/indexeddb/IDBRequest.idl:    attribute EventListener onerror;
501
502 Modules/indexeddb/IDBTransaction.idl:    attribute EventListener onabort;
503 Modules/indexeddb/IDBTransaction.idl:    attribute EventListener oncomplete;
504 Modules/indexeddb/IDBTransaction.idl:    attribute EventListener onerror;
505
506 Modules/mediastream/MediaStream.idl:    attribute EventListener onactive;
507 Modules/mediastream/MediaStream.idl:    attribute EventListener oninactive;
508 Modules/mediastream/MediaStream.idl:    attribute EventListener onaddtrack;
509 Modules/mediastream/MediaStream.idl:    attribute EventListener onremovetrack;
510 Modules/mediastream/MediaStreamTrack.idl:    attribute EventListener onmute;
511 Modules/mediastream/MediaStreamTrack.idl:    attribute EventListener onunmute;
512 Modules/mediastream/MediaStreamTrack.idl:    attribute EventListener onstarted;
513 Modules/mediastream/MediaStreamTrack.idl:    attribute EventListener onended;
514 Modules/mediastream/MediaStreamTrack.idl:    attribute EventListener onoverconstrained;
515 Modules/mediastream/RTCDTMFSender.idl:    attribute EventListener ontonechange;
516 Modules/mediastream/RTCDataChannel.idl:    attribute EventListener onopen;
517 Modules/mediastream/RTCDataChannel.idl:    attribute EventListener onerror;
518 Modules/mediastream/RTCDataChannel.idl:    attribute EventListener onclose;
519 Modules/mediastream/RTCDataChannel.idl:    attribute EventListener onmessage;
520 Modules/mediastream/RTCPeerConnection.idl:    attribute EventListener onnegotiationneeded;
521 Modules/mediastream/RTCPeerConnection.idl:    attribute EventListener onicecandidate;
522 Modules/mediastream/RTCPeerConnection.idl:    attribute EventListener onsignalingstatechange;
523 Modules/mediastream/RTCPeerConnection.idl:    attribute EventListener onaddstream;
524 Modules/mediastream/RTCPeerConnection.idl:    attribute EventListener onremovestream;
525 Modules/mediastream/RTCPeerConnection.idl:    attribute EventListener oniceconnectionstatechange;
526 Modules/mediastream/RTCPeerConnection.idl:    attribute EventListener ondatachannel;
527
528 Modules/notifications/Notification.idl:    attribute EventListener onshow;
529 Modules/notifications/Notification.idl:    attribute EventListener ondisplay;
530 Modules/notifications/Notification.idl:    attribute EventListener onerror;
531 Modules/notifications/Notification.idl:    attribute EventListener onclose;
532 Modules/notifications/Notification.idl:    attribute EventListener onclick;
533
534 Modules/speech/SpeechSynthesisUtterance.idl:    attribute EventListener onstart;
535 Modules/speech/SpeechSynthesisUtterance.idl:    attribute EventListener onend;
536 Modules/speech/SpeechSynthesisUtterance.idl:    attribute EventListener onerror;
537 Modules/speech/SpeechSynthesisUtterance.idl:    attribute EventListener onpause;
538 Modules/speech/SpeechSynthesisUtterance.idl:    attribute EventListener onresume;
539 Modules/speech/SpeechSynthesisUtterance.idl:    attribute EventListener onmark;
540 Modules/speech/SpeechSynthesisUtterance.idl:    attribute EventListener onboundary;
541
542 Modules/webaudio/AudioBufferSourceNode.idl:    attribute EventListener onended;
543 Modules/webaudio/AudioContext.idl:    attribute EventListener oncomplete;
544 Modules/webaudio/OscillatorNode.idl:    attribute EventListener onended;
545 Modules/webaudio/ScriptProcessorNode.idl:    attribute EventListener onaudioprocess;
546
547 Modules/websockets/WebSocket.idl:    attribute EventListener onopen;
548 Modules/websockets/WebSocket.idl:    attribute EventListener onmessage;
549 Modules/websockets/WebSocket.idl:    attribute EventListener onerror;
550 Modules/websockets/WebSocket.idl:    attribute EventListener onclose;
551
552 css/FontLoader.idl:    attribute EventListener onloading;
553 css/FontLoader.idl:    attribute EventListener onloadingdone;
554 css/FontLoader.idl:    attribute EventListener onloadstart;
555 css/FontLoader.idl:    attribute EventListener onload;
556 css/FontLoader.idl:    attribute EventListener onerror;
557
558 dom/MessagePort.idl:    attribute EventListener onmessage;
559
560 fileapi/FileReader.idl:    attribute EventListener onloadstart;
561 fileapi/FileReader.idl:    attribute EventListener onprogress;
562 fileapi/FileReader.idl:    attribute EventListener onload;
563 fileapi/FileReader.idl:    attribute EventListener onabort;
564 fileapi/FileReader.idl:    attribute EventListener onerror;
565 fileapi/FileReader.idl:    attribute EventListener onloadend;
566
567 html/track/AudioTrackList.idl:    attribute EventListener onchange;
568 html/track/AudioTrackList.idl:    attribute EventListener onaddtrack;
569 html/track/AudioTrackList.idl:    attribute EventListener onremovetrack;
570
571 html/track/TextTrack.idl:             attribute EventListener oncuechange;
572 html/track/TextTrackCue.idl:    attribute EventListener onenter;
573
574 html/track/TextTrackCue.idl:    attribute EventListener onexit;
575 html/track/TextTrackList.idl:    attribute EventListener onaddtrack;
576 html/track/TextTrackList.idl:    attribute EventListener onchange;
577 html/track/TextTrackList.idl:    attribute EventListener onremovetrack;
578
579 html/track/VideoTrackList.idl:    attribute EventListener onchange;
580 html/track/VideoTrackList.idl:    attribute EventListener onaddtrack;
581 html/track/VideoTrackList.idl:    attribute EventListener onremovetrack;
582
583 loader/appcache/DOMApplicationCache.idl:    attribute EventListener onchecking;
584 loader/appcache/DOMApplicationCache.idl:    attribute EventListener onerror;
585 loader/appcache/DOMApplicationCache.idl:    attribute EventListener onnoupdate;
586 loader/appcache/DOMApplicationCache.idl:    attribute EventListener ondownloading;
587 loader/appcache/DOMApplicationCache.idl:    attribute EventListener onprogress;
588 loader/appcache/DOMApplicationCache.idl:    attribute EventListener onupdateready;
589 loader/appcache/DOMApplicationCache.idl:    attribute EventListener oncached;
590 loader/appcache/DOMApplicationCache.idl:    attribute EventListener onobsolete;
591
592 page/EventSource.idl:    attribute EventListener onopen;
593 page/EventSource.idl:    attribute EventListener onmessage;
594 page/EventSource.idl:    attribute EventListener onerror;
595
596 page/Performance.idl:    attribute EventListener onwebkitresourcetimingbufferfull;
597
598 workers/AbstractWorker.idl:    attribute EventListener onerror;
599
600 workers/DedicatedWorkerGlobalScope.idl:             attribute EventListener onmessage;
601
602 workers/Worker.idl:    attribute EventListener onmessage;
603
604 workers/WorkerGlobalScope.idl:    attribute EventListener onerror;
605 workers/WorkerGlobalScope.idl:    attribute EventListener onoffline;
606 workers/WorkerGlobalScope.idl:    attribute EventListener ononline;
607
608 xml/XMLHttpRequest.idl:    attribute EventListener onabort;
609 xml/XMLHttpRequest.idl:    attribute EventListener onerror;
610 xml/XMLHttpRequest.idl:    attribute EventListener onload;
611 xml/XMLHttpRequest.idl:    attribute EventListener onloadend;
612 xml/XMLHttpRequest.idl:    attribute EventListener onloadstart;
613 xml/XMLHttpRequest.idl:    attribute EventListener onprogress;
614 xml/XMLHttpRequest.idl:    [Conditional=XHR_TIMEOUT] attribute EventListener ontimeout;
615 xml/XMLHttpRequest.idl:    attribute EventListener onreadystatechange;
616
617 xml/XMLHttpRequestUpload.idl:    attribute EventListener onabort;
618 xml/XMLHttpRequestUpload.idl:    attribute EventListener onerror;
619 xml/XMLHttpRequestUpload.idl:    attribute EventListener onload;
620 xml/XMLHttpRequestUpload.idl:    attribute EventListener onloadend;
621 xml/XMLHttpRequestUpload.idl:    attribute EventListener onloadstart;
622 xml/XMLHttpRequestUpload.idl:    attribute EventListener onprogress;
623
624 ----------------
625
626 */
627
628 </script>
629 <script src="../../resources/js-test-post.js"></script>
630 </body>
631 </html>