More event handler improvements
authordarin@apple.com <darin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 15 Mar 2015 17:00:33 +0000 (17:00 +0000)
committerdarin@apple.com <darin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 15 Mar 2015 17:00:33 +0000 (17:00 +0000)
https://bugs.webkit.org/show_bug.cgi?id=142701

Reviewed by Anders Carlsson.

Source/WebCore:

These are the improvements:

- Use EventHandler rather than EventListener as the the type for event handler
  attributes. This matches the HTML specification, and also makes sense, since
  EventListener means something else (and we use it to mean that!). Also renamed
  JSWindowEventListener to WindowEventHandler. Even though this only affects the
  JavaScript code generated, it's not really a JavaScript-specific flag.

- Tweak formatting on addEventListener/removeEventListener/dispatchEvent in
  all the IDL files where the appear. This includes changing the spelling from
  "evt" to "event". Some day we should fix this so these functions only need to
  appear in EventTarget.idl.

- Tweak formatting a bit on the IDL files we had to modify anyway.

- Use [Conditional] more often and #if less often in IDL files.

- Added a new [DocumentEventHandler] attribute for the selectionchange event.
  This involved adding new event handler attribute functions to JSEventListener.h
  for use by the JavaScript bindings.

- Removed a little unused code from the JavaScript code bindings generator.

- Improved the mechanism used by HTMLElement and SVGElement to share the list of
  content attributes that are event handlers so there is only one map rather than
  two. Made a similar mechanism so that HTMLBodyElement and HTMLFrameSetElement
  can share the list of window event handlers.

- Followed the HTML specification by putting all the event handler support in
  the HTMLElement class rather than having event handlers apply only a the
  particular element that uses those events. We already did this for most of
  our event handlers, but we are now doing it for all of them.

* Modules/battery/BatteryManager.idl: Use EventHandler instead of EventListener
as appropriate. Also reformatted addEventListener/removeEventListener/dispatchEvent.
* Modules/encryptedmedia/MediaKeySession.idl: Ditto.
* Modules/indexeddb/IDBDatabase.idl: Ditto.
* Modules/indexeddb/IDBOpenDBRequest.idl: Ditto.
* Modules/indexeddb/IDBRequest.idl: Ditto.
* Modules/indexeddb/IDBTransaction.idl: Ditto.
* Modules/mediastream/MediaStream.idl: Ditto.
* Modules/mediastream/MediaStreamTrack.idl: Ditto.
* Modules/mediastream/RTCDTMFSender.idl: Ditto.
* Modules/mediastream/RTCDataChannel.idl: Ditto.
* Modules/mediastream/RTCPeerConnection.idl: Ditto.
* Modules/speech/SpeechSynthesisUtterance.idl: Ditto.
* Modules/webaudio/AudioBufferSourceNode.idl: Ditto.
* Modules/webaudio/AudioContext.idl: Ditto.
* Modules/webaudio/OscillatorNode.idl: Ditto.
* Modules/webaudio/ScriptProcessorNode.idl: Ditto.
* Modules/websockets/WebSocket.idl: Ditto.
* css/FontLoader.idl: Ditto.
* dom/EventListener.idl: Ditto.
* dom/EventTarget.idl: Ditto.
* dom/MessagePort.idl: Ditto.
* dom/Node.idl: Ditto.
* dom/WebKitNamedFlow.idl: Ditto.
* fileapi/FileReader.idl: Ditto.
* html/MediaController.idl: Ditto.
* html/track/AudioTrackList.idl: Ditto.
* html/track/TextTrackCue.idl: Ditto.
* html/track/TextTrackList.idl: Ditto.
* html/track/VideoTrackList.idl: Ditto.
* loader/appcache/DOMApplicationCache.idl: Ditto.
* page/EventSource.idl: Ditto.
* page/Performance.idl: Ditto.
* workers/AbstractWorker.idl: Ditto.
* workers/DedicatedWorkerGlobalScope.idl: Ditto.
* workers/Worker.idl: Ditto.
* workers/WorkerGlobalScope.idl: Ditto.
* xml/XMLHttpRequest.idl: Ditto.
* xml/XMLHttpRequestUpload.idl: Ditto.

* Modules/notifications/Notification.idl: Did the above, but also used
[Conditional] instead of #if throughout.
* html/track/TextTrack.idl: Ditto.

* Modules/webaudio/AudioNode.idl: Tweaked paragraphing of this file.

* bindings/js/JSEventListener.cpp:
(WebCore::windowEventHandlerAttribute): Renamed to take the word "forwarded"
out of this. More closely matches the terminology used in IDL files and the
HTML specification.
(WebCore::setWindowEventHandlerAttribute): Ditto.
(WebCore::documentEventHandlerAttribute): Added.
(WebCore::setDocumentEventHandlerAttribute): Added.
* bindings/js/JSEventListener.h: Updated for above changes.

* bindings/objc/PublicDOMInterfaces.h: Renamed argument from "evt" to "event".

* bindings/scripts/CodeGeneratorGObject.pm:
(SkipAttribute): Skip attributes of type "EventHandler" rather than attributes
of type "EventListener".
* bindings/scripts/CodeGeneratorObjC.pm:
(SkipAttribute): Ditto.

* bindings/scripts/CodeGeneratorJS.pm:
(GenerateImplementation): Look for the type EventHandler instead of the type
EventListener for event handler attributes. Also added code to handle the new
DocumentEventHandler, and use the name WindowEventHandler instead of the name
JSWindowEventListener. Removed unneeded preflight check to see if we have
writable attributes; it was not doing us any good. (That caused a lot of code
to be un-indented and makes the diff hard to read.)

* bindings/scripts/IDLAttributes.txt: Removed JSWindowEventListener, and added
WindowEventHandler and DocumentEventHandler.

* bindings/scripts/test/TestObj.idl: Use the type EventHandler instead of the
type EventListener. The test output is unchanged, though.

* dom/Document.idl: Got rid of the conditionals and merged all the event handler
attributes into a single sorted, unconditional list. Added some that were missing,
as detected by the event-handler-attributes.html test.

* dom/Element.idl: Ditto. This includes moving attributes here that were formerly
only in certain element classes. Note that the script event handler attribute
support is still here, even though it should be in HTMLElement and SVGElement
instead. There's a FIXME about that, but no real urgency in fixing it.

* html/HTMLAttributeNames.in: Added onmessage. Previously, the support for this
was from the script attribute only, not the content attribute.

* html/HTMLBodyElement.cpp:
(WebCore::HTMLBodyElement::createWindowEventHandlerNameMap): Added. This
contains the list of all the window event handlers that can be set on a body
or frameset element and which are triggered by events on the window.
(WebCore::HTMLBodyElement::eventNameForWindowEventHandlerAttribute): Added.
This is the function to call to use the map above. Given an attribute, it
returns either null if it is not a window event handler attribute, or the
event type if it is one.
(WebCore::HTMLBodyElement::parseAttribute): Updated to use the new
functions above. Handling of these attributes is now unconditional, but
also we don't have to keep the nested if statements here up to date, just
the list of event handler attributes names in the map create function above.

* html/HTMLBodyElement.h: Added public eventNameForWindowEventHandlerAttribute
and private createWindowEventHandlerNameMap functions.

* html/HTMLBodyElement.idl: Updated to use WindowEventHandler, DocumentEventHandler,
and EventHandler. Also made everything unconditional. Also filled out the list here
to match the list handled as content attributes. All covered by the test.

* html/HTMLElement.cpp:
(WebCore::HTMLElement::createEventHandlerNameMap): Added. Replaces the old
populate function. Changed the list of event handler attributes to be a bit more
complete, and to be entirely unconditional. Also refactored this function to use
a new populateEventHandlerNameMap helper, shared with HTMLBodyElement.
(WebCore::HTMLElement::populateEventHandlerNameMap): Added. Factors out the code
that both this class and HTMLBodyElement use to build event handler name maps.
(WebCore::HTMLElement::eventNameForEventHandlerAttribute): Added. This is the
function that call to use the map above. Given an attribute it returns either
null if it is not an event handler attribute, or the event type if it is one.
This is actually two functions. One is a protected function for use by both this
class and HTMLBodyElement so they can share things like the optimization to look
for the "on" prefix. The other is the public function that we actually use in
HTMLElement and SVGElement.
(WebCore::HTMLElement::editabilityFromContentEditableAttr): Tweaked and refactored
to use lineageOfType. Would have been even simpler if this took an element instead
of a node. Unrelated to the event handler changes.
(WebCore::HTMLElement::parseAttribute): Removed long-obsolete code that decided
whether to call through to the base class. The base class function is empty and
never needs to be called, and in any case there is no value in doing work to
decide whether to call through to an empty function. Changed the style of the
function to use early return instead of else. Worth considering whether we want
to return early or call through to base class in this family of functions. It's
more efficient to return early, but doesn't work well if both the derived class
and base class want to respond to changes to the same attribute. The new logic
for event handler attributes is more straightforward than the old, since the
eventNameForEventHandlerAttribute has the logic.
(WebCore::HTMLElement::textToFragment): Tweaked and refactored a bit, and also
changed to return a Ref since this never fails and needs to return null.

* html/HTMLElement.h: Updated for above changes. This includes a template version
of populateEventHandlerNameMap that extracts the array size at compile time and
passes it to the non-template function that does the work.

* html/HTMLFrameElementBase.cpp:
(WebCore::HTMLFrameElementBase::parseAttribute): Removed unneeded code to handle
event handler attributes handled by HTMLElement.
* html/HTMLImageElement.cpp:
(WebCore::HTMLImageElement::parseAttribute): Ditto.
* html/HTMLLinkElement.cpp:
(WebCore::HTMLLinkElement::parseAttribute): Ditto.
* html/HTMLObjectElement.cpp:
(WebCore::HTMLObjectElement::parseAttribute): Ditto.
* html/HTMLScriptElement.cpp:
(WebCore::HTMLScriptElement::parseAttribute): Ditto.

* html/HTMLFrameSetElement.cpp:
(WebCore::HTMLFrameSetElement::parseAttribute): Changed function to early return
style, and added FIXMEs about the many problems in the attribute handling code.
Replaced all the code to handle window event handlers with a new bit of code that
calls HTMLBodyElement::eventNameForWindowEventHandlerAttribute.

* html/HTMLFrameSetElement.idl: Changed to match the list of window event handlers
in HTMLBodyElement.idl, although I did not add the document event handler here.
As in the various other cases, having some extra event handlers does not seem to
do harm and this is covered by the event-handler-attributes.html test.

* html/HTMLMarqueeElement.idl: Renamed EventListener to EventHandler in comment.

* page/DOMWindow.idl: As with Element and Document, removed conditionals, and
filled out the list of event handlers so all the tests in
event-handler-attributes.html will pass.

* svg/SVGElement.cpp:
(WebCore::SVGElement::parseAttribute): Changed code to the early return style,
and replaced the event handler attribute code with new much simpler code that
uses the new HTMLElement::eventNameForEventHandlerAttribute. Also changed the
way we call through to base classes. Just call through to the
SVGLangSpace::parseAttribute function unconditionally, and don't try to use
early return style to arbitrate among base classes. We should make this
simplification throughout the SVG code; there's no need for the complexity
that was there before just to cut down slightly on calls through to base
class parseAttribute functions.

* svg/SVGSVGElement.cpp:
(WebCore::SVGSVGElement::parseAttribute): Changed some of this code to the
early return style and corrected some comments about the window event handler
attributes here. These could use some further testing and might later need to be
properly supported when the attributes are set in script, not just in content.

* svg/SVGScriptElement.cpp:
(WebCore::SVGScriptElement::isSupportedAttribute): Deleted.
(WebCore::SVGScriptElement::parseAttribute): Changed this function to use the
early return style and also to call through to all three base classes. This is
a pattern we should follow elsewhere in SVG to simplify the code. There is no
need for the supportedAttributes sets like the one in this calass, and the code
is unnecessarily complex, perhaps in an attempt to optimize performance. I'm
pretty sure the old code was slower than this new code will be. No need for the
extra hash table lookup every time. Also removed handling of event handler
attribute which is taken care of by SVGElement now.
(WebCore::SVGScriptElement::svgAttributeChanged): Made similar changes for
the same reason as in parseAttribute. This function really needs a new name:
It's the same as parseAttribute, except it's also used when implementing
changes due to SVG animation.

* svg/SVGScriptElement.h: Removed isSupportedAttribute.

LayoutTests:

* fast/dom/event-handler-attributes-expected.txt: Updated to expect more passing tests,
and to accomodate some changes to what's tested and expected.

* fast/dom/event-handler-attributes.html: Update test to cover more events since we
no longer compile the event handlers conditionally; it's OK to have some handlers for
events even if the features in question aren't turned on.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@181507 268f45cc-cd09-0410-ab3c-d52691b4dbfc

74 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/dom/event-handler-attributes-expected.txt
LayoutTests/fast/dom/event-handler-attributes.html
Source/WebCore/ChangeLog
Source/WebCore/Modules/battery/BatteryManager.idl
Source/WebCore/Modules/encryptedmedia/MediaKeySession.idl
Source/WebCore/Modules/indexeddb/IDBDatabase.idl
Source/WebCore/Modules/indexeddb/IDBOpenDBRequest.idl
Source/WebCore/Modules/indexeddb/IDBRequest.idl
Source/WebCore/Modules/indexeddb/IDBTransaction.idl
Source/WebCore/Modules/mediastream/MediaStream.idl
Source/WebCore/Modules/mediastream/MediaStreamTrack.idl
Source/WebCore/Modules/mediastream/RTCDTMFSender.idl
Source/WebCore/Modules/mediastream/RTCDataChannel.idl
Source/WebCore/Modules/mediastream/RTCPeerConnection.idl
Source/WebCore/Modules/notifications/Notification.idl
Source/WebCore/Modules/speech/SpeechSynthesisUtterance.idl
Source/WebCore/Modules/webaudio/AudioBufferSourceNode.idl
Source/WebCore/Modules/webaudio/AudioContext.idl
Source/WebCore/Modules/webaudio/AudioNode.idl
Source/WebCore/Modules/webaudio/OscillatorNode.idl
Source/WebCore/Modules/webaudio/ScriptProcessorNode.idl
Source/WebCore/Modules/websockets/WebSocket.idl
Source/WebCore/bindings/js/JSEventListener.cpp
Source/WebCore/bindings/js/JSEventListener.h
Source/WebCore/bindings/objc/PublicDOMInterfaces.h
Source/WebCore/bindings/scripts/CodeGeneratorGObject.pm
Source/WebCore/bindings/scripts/CodeGeneratorJS.pm
Source/WebCore/bindings/scripts/CodeGeneratorObjC.pm
Source/WebCore/bindings/scripts/IDLAttributes.txt
Source/WebCore/bindings/scripts/test/TestObj.idl
Source/WebCore/css/FontLoader.idl
Source/WebCore/dom/Document.idl
Source/WebCore/dom/Element.idl
Source/WebCore/dom/EventListener.idl
Source/WebCore/dom/EventTarget.idl
Source/WebCore/dom/MessagePort.idl
Source/WebCore/dom/Node.idl
Source/WebCore/dom/WebKitNamedFlow.idl
Source/WebCore/fileapi/FileReader.idl
Source/WebCore/html/HTMLAttributeNames.in
Source/WebCore/html/HTMLBodyElement.cpp
Source/WebCore/html/HTMLBodyElement.h
Source/WebCore/html/HTMLBodyElement.idl
Source/WebCore/html/HTMLElement.cpp
Source/WebCore/html/HTMLElement.h
Source/WebCore/html/HTMLFrameElementBase.cpp
Source/WebCore/html/HTMLFrameSetElement.cpp
Source/WebCore/html/HTMLFrameSetElement.idl
Source/WebCore/html/HTMLImageElement.cpp
Source/WebCore/html/HTMLLinkElement.cpp
Source/WebCore/html/HTMLMarqueeElement.idl
Source/WebCore/html/HTMLObjectElement.cpp
Source/WebCore/html/HTMLScriptElement.cpp
Source/WebCore/html/MediaController.idl
Source/WebCore/html/track/AudioTrackList.idl
Source/WebCore/html/track/TextTrack.idl
Source/WebCore/html/track/TextTrackCue.idl
Source/WebCore/html/track/TextTrackList.idl
Source/WebCore/html/track/VideoTrackList.idl
Source/WebCore/loader/appcache/DOMApplicationCache.idl
Source/WebCore/page/DOMWindow.idl
Source/WebCore/page/EventSource.idl
Source/WebCore/page/Performance.idl
Source/WebCore/svg/SVGElement.cpp
Source/WebCore/svg/SVGSVGElement.cpp
Source/WebCore/svg/SVGScriptElement.cpp
Source/WebCore/svg/SVGScriptElement.h
Source/WebCore/workers/AbstractWorker.idl
Source/WebCore/workers/DedicatedWorkerGlobalScope.idl
Source/WebCore/workers/Worker.idl
Source/WebCore/workers/WorkerGlobalScope.idl
Source/WebCore/xml/XMLHttpRequest.idl
Source/WebCore/xml/XMLHttpRequestUpload.idl

index 85a3083..a2fa882 100644 (file)
@@ -1,3 +1,17 @@
+2015-03-14  Darin Adler  <darin@apple.com>
+
+        More event handler improvements
+        https://bugs.webkit.org/show_bug.cgi?id=142701
+
+        Reviewed by Anders Carlsson.
+
+        * fast/dom/event-handler-attributes-expected.txt: Updated to expect more passing tests,
+        and to accomodate some changes to what's tested and expected.
+
+        * fast/dom/event-handler-attributes.html: Update test to cover more events since we
+        no longer compile the event handlers conditionally; it's OK to have some handlers for
+        events even if the features in question aren't turned on.
+
 2015-03-15  David Kilzer  <ddkilzer@apple.com>
 
         [iOS] REGRESSION (r181191): Add results for css3/blending/svg-blend-plus-lighter.html
index 756cbd1..921ccce 100644 (file)
@@ -17,6 +17,8 @@ PASS testScriptAttribute(window, "change") is "window"
 PASS testScriptAttribute(window, "click") is "window"
 PASS testScriptAttribute(window, "contextmenu") is "window"
 PASS testScriptAttribute(window, "dblclick") is "window"
+PASS testScriptAttribute(window, "devicemotion") is "window"
+PASS testScriptAttribute(window, "deviceorientation") is "window"
 PASS testScriptAttribute(window, "drag") is "window"
 PASS testScriptAttribute(window, "dragend") is "window"
 PASS testScriptAttribute(window, "dragenter") is "window"
@@ -29,6 +31,9 @@ PASS testScriptAttribute(window, "emptied") is "window"
 PASS testScriptAttribute(window, "ended") is "window"
 PASS testScriptAttribute(window, "error") is "window"
 PASS testScriptAttribute(window, "focus") is "window"
+PASS testScriptAttribute(window, "gesturechange") is "window"
+PASS testScriptAttribute(window, "gestureend") is "window"
+PASS testScriptAttribute(window, "gesturestart") is "window"
 PASS testScriptAttribute(window, "hashchange") is "window"
 PASS testScriptAttribute(window, "input") is "window"
 PASS testScriptAttribute(window, "invalid") is "window"
@@ -50,6 +55,7 @@ PASS testScriptAttribute(window, "mouseup") is "window"
 PASS testScriptAttribute(window, "mousewheel") is "window"
 PASS testScriptAttribute(window, "offline") is "window"
 PASS testScriptAttribute(window, "online") is "window"
+PASS testScriptAttribute(window, "orientationchange") is "window"
 PASS testScriptAttribute(window, "pagehide") is "window"
 PASS testScriptAttribute(window, "pageshow") is "window"
 PASS testScriptAttribute(window, "pause") is "window"
@@ -70,6 +76,10 @@ PASS testScriptAttribute(window, "storage") is "window"
 PASS testScriptAttribute(window, "submit") is "window"
 PASS testScriptAttribute(window, "suspend") is "window"
 PASS testScriptAttribute(window, "timeupdate") is "window"
+PASS testScriptAttribute(window, "touchcancel") is "window"
+PASS testScriptAttribute(window, "touchend") is "window"
+PASS testScriptAttribute(window, "touchmove") is "window"
+PASS testScriptAttribute(window, "touchstart") is "window"
 PASS testScriptAttribute(window, "transitionend") is "window"
 PASS testScriptAttribute(window, "unload") is "window"
 PASS testScriptAttribute(window, "volumechange") is "window"
@@ -77,11 +87,18 @@ PASS testScriptAttribute(window, "waiting") is "window"
 PASS testScriptAttribute(window, "webkitanimationend") is "window"
 PASS testScriptAttribute(window, "webkitanimationiteration") is "window"
 PASS testScriptAttribute(window, "webkitanimationstart") is "window"
+PASS testScriptAttribute(window, "webkitdeviceproximity") is "window"
 PASS testScriptAttribute(window, "webkittransitionend") is "window"
+PASS testScriptAttribute(window, "webkitwillrevealbottom") is "window"
+PASS testScriptAttribute(window, "webkitwillrevealleft") is "window"
+PASS testScriptAttribute(window, "webkitwillrevealright") is "window"
+PASS testScriptAttribute(window, "webkitwillrevealtop") is "window"
 PASS testScriptAttribute(window, "wheel") is "window"
 
 Event names we expect not to be able to set on the window object
 
+PASS testScriptAttribute(window, "autocomplete") is "none"
+PASS testScriptAttribute(window, "autocompleteerror") is "none"
 PASS testScriptAttribute(window, "beforecopy") is "none"
 PASS testScriptAttribute(window, "beforecut") is "none"
 PASS testScriptAttribute(window, "beforeload") is "none"
@@ -92,13 +109,21 @@ PASS testScriptAttribute(window, "focusin") is "none"
 PASS testScriptAttribute(window, "focusout") is "none"
 PASS testScriptAttribute(window, "noneventname") is "none"
 PASS testScriptAttribute(window, "paste") is "none"
+PASS testScriptAttribute(window, "pointerlockchange") is "none"
+PASS testScriptAttribute(window, "pointerlockerror") is "none"
 PASS testScriptAttribute(window, "readystatechange") is "none"
+PASS testScriptAttribute(window, "securitypolicyviolation") is "none"
 PASS testScriptAttribute(window, "selectionchange") is "none"
 PASS testScriptAttribute(window, "selectstart") is "none"
-PASS testScriptAttribute(window, "touchcancel") is "none"
-PASS testScriptAttribute(window, "touchend") is "none"
-PASS testScriptAttribute(window, "touchmove") is "none"
-PASS testScriptAttribute(window, "touchstart") is "none"
+PASS testScriptAttribute(window, "webkitcurrentplaybacktargetiswirelesschanged") is "none"
+PASS testScriptAttribute(window, "webkitfullscreenchange") is "none"
+PASS testScriptAttribute(window, "webkitfullscreenerror") is "none"
+PASS testScriptAttribute(window, "webkitkeyadded") is "none"
+PASS testScriptAttribute(window, "webkitkeyerror") is "none"
+PASS testScriptAttribute(window, "webkitkeymessage") is "none"
+PASS testScriptAttribute(window, "webkitneedkey") is "none"
+PASS testScriptAttribute(window, "webkitplaybacktargetavailabilitychanged") is "none"
+PASS testScriptAttribute(window, "webkitpresentationmodechanged") is "none"
 
 Event names we expect to be able to set on the document
 
@@ -137,14 +162,27 @@ PASS testScriptAttribute(document, "mouseover") is "document"
 PASS testScriptAttribute(document, "mouseup") is "document"
 PASS testScriptAttribute(document, "mousewheel") is "document"
 PASS testScriptAttribute(document, "paste") is "document"
+PASS testScriptAttribute(document, "pointerlockchange") is "document"
+PASS testScriptAttribute(document, "pointerlockerror") is "document"
 PASS testScriptAttribute(document, "readystatechange") is "document"
 PASS testScriptAttribute(document, "reset") is "document"
 PASS testScriptAttribute(document, "scroll") is "document"
 PASS testScriptAttribute(document, "search") is "document"
+PASS testScriptAttribute(document, "securitypolicyviolation") is "document"
 PASS testScriptAttribute(document, "select") is "document"
 PASS testScriptAttribute(document, "selectionchange") is "document"
 PASS testScriptAttribute(document, "selectstart") is "document"
 PASS testScriptAttribute(document, "submit") is "document"
+PASS testScriptAttribute(document, "touchcancel") is "document"
+PASS testScriptAttribute(document, "touchend") is "document"
+PASS testScriptAttribute(document, "touchmove") is "document"
+PASS testScriptAttribute(document, "touchstart") is "document"
+PASS testScriptAttribute(document, "webkitfullscreenchange") is "document"
+PASS testScriptAttribute(document, "webkitfullscreenerror") is "document"
+PASS testScriptAttribute(document, "webkitwillrevealbottom") is "document"
+PASS testScriptAttribute(document, "webkitwillrevealleft") is "document"
+PASS testScriptAttribute(document, "webkitwillrevealright") is "document"
+PASS testScriptAttribute(document, "webkitwillrevealtop") is "document"
 PASS testScriptAttribute(document, "wheel") is "document"
 
 Event names we expect not to be able to set on the document
@@ -152,15 +190,22 @@ Event names we expect not to be able to set on the document
 PASS testScriptAttribute(document, "animationend") is "none"
 PASS testScriptAttribute(document, "animationiteration") is "none"
 PASS testScriptAttribute(document, "animationstart") is "none"
+PASS testScriptAttribute(document, "autocomplete") is "none"
+PASS testScriptAttribute(document, "autocompleteerror") is "none"
 PASS testScriptAttribute(document, "beforeload") is "none"
 PASS testScriptAttribute(document, "beforeunload") is "none"
 PASS testScriptAttribute(document, "canplay") is "none"
 PASS testScriptAttribute(document, "canplaythrough") is "none"
+PASS testScriptAttribute(document, "devicemotion") is "none"
+PASS testScriptAttribute(document, "deviceorientation") is "none"
 PASS testScriptAttribute(document, "durationchange") is "none"
 PASS testScriptAttribute(document, "emptied") is "none"
 PASS testScriptAttribute(document, "ended") is "none"
 PASS testScriptAttribute(document, "focusin") is "none"
 PASS testScriptAttribute(document, "focusout") is "none"
+PASS testScriptAttribute(document, "gesturechange") is "none"
+PASS testScriptAttribute(document, "gestureend") is "none"
+PASS testScriptAttribute(document, "gesturestart") is "none"
 PASS testScriptAttribute(document, "hashchange") is "none"
 PASS testScriptAttribute(document, "loadeddata") is "none"
 PASS testScriptAttribute(document, "loadedmetadata") is "none"
@@ -169,6 +214,7 @@ PASS testScriptAttribute(document, "message") is "none"
 PASS testScriptAttribute(document, "noneventname") is "none"
 PASS testScriptAttribute(document, "offline") is "none"
 PASS testScriptAttribute(document, "online") is "none"
+PASS testScriptAttribute(document, "orientationchange") is "none"
 PASS testScriptAttribute(document, "pagehide") is "none"
 PASS testScriptAttribute(document, "pageshow") is "none"
 PASS testScriptAttribute(document, "pause") is "none"
@@ -184,10 +230,6 @@ PASS testScriptAttribute(document, "stalled") is "none"
 PASS testScriptAttribute(document, "storage") is "none"
 PASS testScriptAttribute(document, "suspend") is "none"
 PASS testScriptAttribute(document, "timeupdate") is "none"
-PASS testScriptAttribute(document, "touchcancel") is "none"
-PASS testScriptAttribute(document, "touchend") is "none"
-PASS testScriptAttribute(document, "touchmove") is "none"
-PASS testScriptAttribute(document, "touchstart") is "none"
 PASS testScriptAttribute(document, "transitionend") is "none"
 PASS testScriptAttribute(document, "unload") is "none"
 PASS testScriptAttribute(document, "volumechange") is "none"
@@ -195,6 +237,14 @@ PASS testScriptAttribute(document, "waiting") is "none"
 PASS testScriptAttribute(document, "webkitanimationend") is "none"
 PASS testScriptAttribute(document, "webkitanimationiteration") is "none"
 PASS testScriptAttribute(document, "webkitanimationstart") is "none"
+PASS testScriptAttribute(document, "webkitcurrentplaybacktargetiswirelesschanged") is "none"
+PASS testScriptAttribute(document, "webkitdeviceproximity") is "none"
+PASS testScriptAttribute(document, "webkitkeyadded") is "none"
+PASS testScriptAttribute(document, "webkitkeyerror") is "none"
+PASS testScriptAttribute(document, "webkitkeymessage") is "none"
+PASS testScriptAttribute(document, "webkitneedkey") is "none"
+PASS testScriptAttribute(document, "webkitplaybacktargetavailabilitychanged") is "none"
+PASS testScriptAttribute(document, "webkitpresentationmodechanged") is "none"
 PASS testScriptAttribute(document, "webkittransitionend") is "none"
 
 Event names we expect to be able to set on an element (tested on the <html> element)
@@ -203,6 +253,8 @@ PASS testElementAttribute(element, "abort") is "target"
 PASS testElementAttribute(element, "animationend") is "target"
 PASS testElementAttribute(element, "animationiteration") is "target"
 PASS testElementAttribute(element, "animationstart") is "target"
+PASS testElementAttribute(element, "autocomplete") is "target"
+PASS testElementAttribute(element, "autocompleteerror") is "target"
 PASS testElementAttribute(element, "beforecopy") is "target"
 PASS testElementAttribute(element, "beforecut") is "target"
 PASS testElementAttribute(element, "beforeload") is "target"
@@ -230,6 +282,9 @@ PASS testElementAttribute(element, "error") is "target"
 PASS testElementAttribute(element, "focus") is "target"
 PASS testElementAttribute(element, "focusin") is "target"
 PASS testElementAttribute(element, "focusout") is "target"
+PASS testElementAttribute(element, "gesturechange") is "target"
+PASS testElementAttribute(element, "gestureend") is "target"
+PASS testElementAttribute(element, "gesturestart") is "target"
 PASS testElementAttribute(element, "input") is "target"
 PASS testElementAttribute(element, "invalid") is "target"
 PASS testElementAttribute(element, "keydown") is "target"
@@ -271,28 +326,48 @@ PASS testElementAttribute(element, "touchstart") is "target"
 PASS testElementAttribute(element, "transitionend") is "target"
 PASS testElementAttribute(element, "volumechange") is "target"
 PASS testElementAttribute(element, "waiting") is "target"
-FAIL testElementAttribute(element, "webkitanimationend") should be target. Was script: none; content: target.
-FAIL testElementAttribute(element, "webkitanimationiteration") should be target. Was script: none; content: target.
-FAIL testElementAttribute(element, "webkitanimationstart") should be target. Was script: none; content: target.
-FAIL testElementAttribute(element, "webkittransitionend") should be target. Was script: none; content: target.
+PASS testElementAttribute(element, "webkitanimationend") is "target"
+PASS testElementAttribute(element, "webkitanimationiteration") is "target"
+PASS testElementAttribute(element, "webkitanimationstart") is "target"
+PASS testElementAttribute(element, "webkitcurrentplaybacktargetiswirelesschanged") is "target"
+PASS testElementAttribute(element, "webkitfullscreenchange") is "target"
+PASS testElementAttribute(element, "webkitfullscreenerror") is "target"
+PASS testElementAttribute(element, "webkitkeyadded") is "target"
+PASS testElementAttribute(element, "webkitkeyerror") is "target"
+PASS testElementAttribute(element, "webkitkeymessage") is "target"
+PASS testElementAttribute(element, "webkitneedkey") is "target"
+PASS testElementAttribute(element, "webkitplaybacktargetavailabilitychanged") is "target"
+PASS testElementAttribute(element, "webkitpresentationmodechanged") is "target"
+PASS testElementAttribute(element, "webkittransitionend") is "target"
+PASS testElementAttribute(element, "webkitwillrevealbottom") is "target"
+PASS testElementAttribute(element, "webkitwillrevealleft") is "target"
+PASS testElementAttribute(element, "webkitwillrevealright") is "target"
+PASS testElementAttribute(element, "webkitwillrevealtop") is "target"
 PASS testElementAttribute(element, "wheel") is "target"
 
 Event names we expect not to be able to set on an element (tested on the <html> element)
 
 PASS testElementAttribute(element, "beforeunload") is "none"
+PASS testElementAttribute(element, "devicemotion") is "none"
+PASS testElementAttribute(element, "deviceorientation") is "none"
 PASS testElementAttribute(element, "hashchange") is "none"
 PASS testElementAttribute(element, "message") is "none"
 PASS testElementAttribute(element, "noneventname") is "none"
 PASS testElementAttribute(element, "offline") is "none"
 PASS testElementAttribute(element, "online") is "none"
+PASS testElementAttribute(element, "orientationchange") is "none"
 PASS testElementAttribute(element, "pagehide") is "none"
 PASS testElementAttribute(element, "pageshow") is "none"
+PASS testElementAttribute(element, "pointerlockchange") is "none"
+PASS testElementAttribute(element, "pointerlockerror") is "none"
 PASS testElementAttribute(element, "popstate") is "none"
 PASS testElementAttribute(element, "readystatechange") is "none"
 PASS testElementAttribute(element, "resize") is "none"
+PASS testElementAttribute(element, "securitypolicyviolation") is "none"
 PASS testElementAttribute(element, "selectionchange") is "none"
 PASS testElementAttribute(element, "storage") is "none"
 PASS testElementAttribute(element, "unload") is "none"
+PASS testElementAttribute(element, "webkitdeviceproximity") is "none"
 
 Event names we expect to be able to set on an element (tested on the <input> element)
 
@@ -300,6 +375,8 @@ PASS testElementAttribute(inputElement, "abort") is "target"
 PASS testElementAttribute(inputElement, "animationend") is "target"
 PASS testElementAttribute(inputElement, "animationiteration") is "target"
 PASS testElementAttribute(inputElement, "animationstart") is "target"
+PASS testElementAttribute(inputElement, "autocomplete") is "target"
+PASS testElementAttribute(inputElement, "autocompleteerror") is "target"
 PASS testElementAttribute(inputElement, "beforecopy") is "target"
 PASS testElementAttribute(inputElement, "beforecut") is "target"
 PASS testElementAttribute(inputElement, "beforeload") is "target"
@@ -327,6 +404,9 @@ PASS testElementAttribute(inputElement, "error") is "target"
 PASS testElementAttribute(inputElement, "focus") is "target"
 PASS testElementAttribute(inputElement, "focusin") is "target"
 PASS testElementAttribute(inputElement, "focusout") is "target"
+PASS testElementAttribute(inputElement, "gesturechange") is "target"
+PASS testElementAttribute(inputElement, "gestureend") is "target"
+PASS testElementAttribute(inputElement, "gesturestart") is "target"
 PASS testElementAttribute(inputElement, "input") is "target"
 PASS testElementAttribute(inputElement, "invalid") is "target"
 PASS testElementAttribute(inputElement, "keydown") is "target"
@@ -368,28 +448,48 @@ PASS testElementAttribute(inputElement, "touchstart") is "target"
 PASS testElementAttribute(inputElement, "transitionend") is "target"
 PASS testElementAttribute(inputElement, "volumechange") is "target"
 PASS testElementAttribute(inputElement, "waiting") is "target"
-FAIL testElementAttribute(inputElement, "webkitanimationend") should be target. Was script: none; content: target.
-FAIL testElementAttribute(inputElement, "webkitanimationiteration") should be target. Was script: none; content: target.
-FAIL testElementAttribute(inputElement, "webkitanimationstart") should be target. Was script: none; content: target.
-FAIL testElementAttribute(inputElement, "webkittransitionend") should be target. Was script: none; content: target.
+PASS testElementAttribute(inputElement, "webkitanimationend") is "target"
+PASS testElementAttribute(inputElement, "webkitanimationiteration") is "target"
+PASS testElementAttribute(inputElement, "webkitanimationstart") is "target"
+PASS testElementAttribute(inputElement, "webkitcurrentplaybacktargetiswirelesschanged") is "target"
+PASS testElementAttribute(inputElement, "webkitfullscreenchange") is "target"
+PASS testElementAttribute(inputElement, "webkitfullscreenerror") is "target"
+PASS testElementAttribute(inputElement, "webkitkeyadded") is "target"
+PASS testElementAttribute(inputElement, "webkitkeyerror") is "target"
+PASS testElementAttribute(inputElement, "webkitkeymessage") is "target"
+PASS testElementAttribute(inputElement, "webkitneedkey") is "target"
+PASS testElementAttribute(inputElement, "webkitplaybacktargetavailabilitychanged") is "target"
+PASS testElementAttribute(inputElement, "webkitpresentationmodechanged") is "target"
+PASS testElementAttribute(inputElement, "webkittransitionend") is "target"
+PASS testElementAttribute(inputElement, "webkitwillrevealbottom") is "target"
+PASS testElementAttribute(inputElement, "webkitwillrevealleft") is "target"
+PASS testElementAttribute(inputElement, "webkitwillrevealright") is "target"
+PASS testElementAttribute(inputElement, "webkitwillrevealtop") is "target"
 PASS testElementAttribute(inputElement, "wheel") is "target"
 
 Event names we expect not to be able to set on an element (tested on the <input> element)
 
 PASS testElementAttribute(inputElement, "beforeunload") is "none"
+PASS testElementAttribute(inputElement, "devicemotion") is "none"
+PASS testElementAttribute(inputElement, "deviceorientation") is "none"
 PASS testElementAttribute(inputElement, "hashchange") is "none"
 PASS testElementAttribute(inputElement, "message") is "none"
 PASS testElementAttribute(inputElement, "noneventname") is "none"
 PASS testElementAttribute(inputElement, "offline") is "none"
 PASS testElementAttribute(inputElement, "online") is "none"
+PASS testElementAttribute(inputElement, "orientationchange") is "none"
 PASS testElementAttribute(inputElement, "pagehide") is "none"
 PASS testElementAttribute(inputElement, "pageshow") is "none"
+PASS testElementAttribute(inputElement, "pointerlockchange") is "none"
+PASS testElementAttribute(inputElement, "pointerlockerror") is "none"
 PASS testElementAttribute(inputElement, "popstate") is "none"
 PASS testElementAttribute(inputElement, "readystatechange") is "none"
 PASS testElementAttribute(inputElement, "resize") is "none"
+PASS testElementAttribute(inputElement, "securitypolicyviolation") is "none"
 PASS testElementAttribute(inputElement, "selectionchange") is "none"
 PASS testElementAttribute(inputElement, "storage") is "none"
 PASS testElementAttribute(inputElement, "unload") is "none"
+PASS testElementAttribute(inputElement, "webkitdeviceproximity") is "none"
 
 Event names we expect to be able to set on an element (tested on the <audio> element)
 
@@ -397,6 +497,8 @@ PASS testElementAttribute(audioElement, "abort") is "target"
 PASS testElementAttribute(audioElement, "animationend") is "target"
 PASS testElementAttribute(audioElement, "animationiteration") is "target"
 PASS testElementAttribute(audioElement, "animationstart") is "target"
+PASS testElementAttribute(audioElement, "autocomplete") is "target"
+PASS testElementAttribute(audioElement, "autocompleteerror") is "target"
 PASS testElementAttribute(audioElement, "beforecopy") is "target"
 PASS testElementAttribute(audioElement, "beforecut") is "target"
 PASS testElementAttribute(audioElement, "beforeload") is "target"
@@ -424,6 +526,9 @@ PASS testElementAttribute(audioElement, "error") is "target"
 PASS testElementAttribute(audioElement, "focus") is "target"
 PASS testElementAttribute(audioElement, "focusin") is "target"
 PASS testElementAttribute(audioElement, "focusout") is "target"
+PASS testElementAttribute(audioElement, "gesturechange") is "target"
+PASS testElementAttribute(audioElement, "gestureend") is "target"
+PASS testElementAttribute(audioElement, "gesturestart") is "target"
 PASS testElementAttribute(audioElement, "input") is "target"
 PASS testElementAttribute(audioElement, "invalid") is "target"
 PASS testElementAttribute(audioElement, "keydown") is "target"
@@ -465,28 +570,48 @@ PASS testElementAttribute(audioElement, "touchstart") is "target"
 PASS testElementAttribute(audioElement, "transitionend") is "target"
 PASS testElementAttribute(audioElement, "volumechange") is "target"
 PASS testElementAttribute(audioElement, "waiting") is "target"
-FAIL testElementAttribute(audioElement, "webkitanimationend") should be target. Was script: none; content: target.
-FAIL testElementAttribute(audioElement, "webkitanimationiteration") should be target. Was script: none; content: target.
-FAIL testElementAttribute(audioElement, "webkitanimationstart") should be target. Was script: none; content: target.
-FAIL testElementAttribute(audioElement, "webkittransitionend") should be target. Was script: none; content: target.
+PASS testElementAttribute(audioElement, "webkitanimationend") is "target"
+PASS testElementAttribute(audioElement, "webkitanimationiteration") is "target"
+PASS testElementAttribute(audioElement, "webkitanimationstart") is "target"
+PASS testElementAttribute(audioElement, "webkitcurrentplaybacktargetiswirelesschanged") is "target"
+PASS testElementAttribute(audioElement, "webkitfullscreenchange") is "target"
+PASS testElementAttribute(audioElement, "webkitfullscreenerror") is "target"
+PASS testElementAttribute(audioElement, "webkitkeyadded") is "target"
+PASS testElementAttribute(audioElement, "webkitkeyerror") is "target"
+PASS testElementAttribute(audioElement, "webkitkeymessage") is "target"
+PASS testElementAttribute(audioElement, "webkitneedkey") is "target"
+PASS testElementAttribute(audioElement, "webkitplaybacktargetavailabilitychanged") is "target"
+PASS testElementAttribute(audioElement, "webkitpresentationmodechanged") is "target"
+PASS testElementAttribute(audioElement, "webkittransitionend") is "target"
+PASS testElementAttribute(audioElement, "webkitwillrevealbottom") is "target"
+PASS testElementAttribute(audioElement, "webkitwillrevealleft") is "target"
+PASS testElementAttribute(audioElement, "webkitwillrevealright") is "target"
+PASS testElementAttribute(audioElement, "webkitwillrevealtop") is "target"
 PASS testElementAttribute(audioElement, "wheel") is "target"
 
 Event names we expect not to be able to set on an element (tested on the <audio> element)
 
 PASS testElementAttribute(audioElement, "beforeunload") is "none"
+PASS testElementAttribute(audioElement, "devicemotion") is "none"
+PASS testElementAttribute(audioElement, "deviceorientation") is "none"
 PASS testElementAttribute(audioElement, "hashchange") is "none"
 PASS testElementAttribute(audioElement, "message") is "none"
 PASS testElementAttribute(audioElement, "noneventname") is "none"
 PASS testElementAttribute(audioElement, "offline") is "none"
 PASS testElementAttribute(audioElement, "online") is "none"
+PASS testElementAttribute(audioElement, "orientationchange") is "none"
 PASS testElementAttribute(audioElement, "pagehide") is "none"
 PASS testElementAttribute(audioElement, "pageshow") is "none"
+PASS testElementAttribute(audioElement, "pointerlockchange") is "none"
+PASS testElementAttribute(audioElement, "pointerlockerror") is "none"
 PASS testElementAttribute(audioElement, "popstate") is "none"
 PASS testElementAttribute(audioElement, "readystatechange") is "none"
 PASS testElementAttribute(audioElement, "resize") is "none"
+PASS testElementAttribute(audioElement, "securitypolicyviolation") is "none"
 PASS testElementAttribute(audioElement, "selectionchange") is "none"
 PASS testElementAttribute(audioElement, "storage") is "none"
 PASS testElementAttribute(audioElement, "unload") is "none"
+PASS testElementAttribute(audioElement, "webkitdeviceproximity") is "none"
 
 Event names we expect to be able to set on an element (tested on the <video> element)
 
@@ -494,6 +619,8 @@ PASS testElementAttribute(videoElement, "abort") is "target"
 PASS testElementAttribute(videoElement, "animationend") is "target"
 PASS testElementAttribute(videoElement, "animationiteration") is "target"
 PASS testElementAttribute(videoElement, "animationstart") is "target"
+PASS testElementAttribute(videoElement, "autocomplete") is "target"
+PASS testElementAttribute(videoElement, "autocompleteerror") is "target"
 PASS testElementAttribute(videoElement, "beforecopy") is "target"
 PASS testElementAttribute(videoElement, "beforecut") is "target"
 PASS testElementAttribute(videoElement, "beforeload") is "target"
@@ -521,6 +648,9 @@ PASS testElementAttribute(videoElement, "error") is "target"
 PASS testElementAttribute(videoElement, "focus") is "target"
 PASS testElementAttribute(videoElement, "focusin") is "target"
 PASS testElementAttribute(videoElement, "focusout") is "target"
+PASS testElementAttribute(videoElement, "gesturechange") is "target"
+PASS testElementAttribute(videoElement, "gestureend") is "target"
+PASS testElementAttribute(videoElement, "gesturestart") is "target"
 PASS testElementAttribute(videoElement, "input") is "target"
 PASS testElementAttribute(videoElement, "invalid") is "target"
 PASS testElementAttribute(videoElement, "keydown") is "target"
@@ -562,50 +692,77 @@ PASS testElementAttribute(videoElement, "touchstart") is "target"
 PASS testElementAttribute(videoElement, "transitionend") is "target"
 PASS testElementAttribute(videoElement, "volumechange") is "target"
 PASS testElementAttribute(videoElement, "waiting") is "target"
-FAIL testElementAttribute(videoElement, "webkitanimationend") should be target. Was script: none; content: target.
-FAIL testElementAttribute(videoElement, "webkitanimationiteration") should be target. Was script: none; content: target.
-FAIL testElementAttribute(videoElement, "webkitanimationstart") should be target. Was script: none; content: target.
-FAIL testElementAttribute(videoElement, "webkittransitionend") should be target. Was script: none; content: target.
+PASS testElementAttribute(videoElement, "webkitanimationend") is "target"
+PASS testElementAttribute(videoElement, "webkitanimationiteration") is "target"
+PASS testElementAttribute(videoElement, "webkitanimationstart") is "target"
+PASS testElementAttribute(videoElement, "webkitcurrentplaybacktargetiswirelesschanged") is "target"
+PASS testElementAttribute(videoElement, "webkitfullscreenchange") is "target"
+PASS testElementAttribute(videoElement, "webkitfullscreenerror") is "target"
+PASS testElementAttribute(videoElement, "webkitkeyadded") is "target"
+PASS testElementAttribute(videoElement, "webkitkeyerror") is "target"
+PASS testElementAttribute(videoElement, "webkitkeymessage") is "target"
+PASS testElementAttribute(videoElement, "webkitneedkey") is "target"
+PASS testElementAttribute(videoElement, "webkitplaybacktargetavailabilitychanged") is "target"
+PASS testElementAttribute(videoElement, "webkitpresentationmodechanged") is "target"
+PASS testElementAttribute(videoElement, "webkittransitionend") is "target"
+PASS testElementAttribute(videoElement, "webkitwillrevealbottom") is "target"
+PASS testElementAttribute(videoElement, "webkitwillrevealleft") is "target"
+PASS testElementAttribute(videoElement, "webkitwillrevealright") is "target"
+PASS testElementAttribute(videoElement, "webkitwillrevealtop") is "target"
 PASS testElementAttribute(videoElement, "wheel") is "target"
 
 Event names we expect not to be able to set on an element (tested on the <video> element)
 
 PASS testElementAttribute(videoElement, "beforeunload") is "none"
+PASS testElementAttribute(videoElement, "devicemotion") is "none"
+PASS testElementAttribute(videoElement, "deviceorientation") is "none"
 PASS testElementAttribute(videoElement, "hashchange") is "none"
 PASS testElementAttribute(videoElement, "message") is "none"
 PASS testElementAttribute(videoElement, "noneventname") is "none"
 PASS testElementAttribute(videoElement, "offline") is "none"
 PASS testElementAttribute(videoElement, "online") is "none"
+PASS testElementAttribute(videoElement, "orientationchange") is "none"
 PASS testElementAttribute(videoElement, "pagehide") is "none"
 PASS testElementAttribute(videoElement, "pageshow") is "none"
+PASS testElementAttribute(videoElement, "pointerlockchange") is "none"
+PASS testElementAttribute(videoElement, "pointerlockerror") is "none"
 PASS testElementAttribute(videoElement, "popstate") is "none"
 PASS testElementAttribute(videoElement, "readystatechange") is "none"
 PASS testElementAttribute(videoElement, "resize") is "none"
+PASS testElementAttribute(videoElement, "securitypolicyviolation") is "none"
 PASS testElementAttribute(videoElement, "selectionchange") is "none"
 PASS testElementAttribute(videoElement, "storage") is "none"
 PASS testElementAttribute(videoElement, "unload") is "none"
+PASS testElementAttribute(videoElement, "webkitdeviceproximity") is "none"
 
 Event names we expect to be forwarded from <body> element to window object)
 
 PASS testElementAttribute(bodyElement, "beforeunload") is "window"
 PASS testElementAttribute(bodyElement, "blur") is "window"
-FAIL testElementAttribute(bodyElement, "error") should be window. Was script: window; content: target.
+PASS testElementAttribute(bodyElement, "error") is "window"
 PASS testElementAttribute(bodyElement, "focus") is "window"
+PASS testElementAttribute(bodyElement, "focusin") is "window"
+PASS testElementAttribute(bodyElement, "focusout") is "window"
 PASS testElementAttribute(bodyElement, "hashchange") is "window"
 PASS testElementAttribute(bodyElement, "load") is "window"
-FAIL testElementAttribute(bodyElement, "message") should be window. Was script: window; content: none.
+PASS testElementAttribute(bodyElement, "message") is "window"
 PASS testElementAttribute(bodyElement, "offline") is "window"
 PASS testElementAttribute(bodyElement, "online") is "window"
+PASS testElementAttribute(bodyElement, "orientationchange") is "window"
 PASS testElementAttribute(bodyElement, "pagehide") is "window"
 PASS testElementAttribute(bodyElement, "pageshow") is "window"
 PASS testElementAttribute(bodyElement, "popstate") is "window"
 PASS testElementAttribute(bodyElement, "resize") is "window"
 PASS testElementAttribute(bodyElement, "storage") is "window"
 PASS testElementAttribute(bodyElement, "unload") is "window"
+PASS testElementAttribute(bodyElement, "webkitwillrevealbottom") is "window"
+PASS testElementAttribute(bodyElement, "webkitwillrevealleft") is "window"
+PASS testElementAttribute(bodyElement, "webkitwillrevealright") is "window"
+PASS testElementAttribute(bodyElement, "webkitwillrevealtop") is "window"
 
 Event names we expect to be forwarded from <body> element to document)
 
-FAIL testElementAttribute(bodyElement, "selectionchange") should be document. Was script: none; content: document.
+PASS testElementAttribute(bodyElement, "selectionchange") is "document"
 
 Non-forwarded event names on <body> element
 
@@ -613,6 +770,8 @@ PASS testElementAttribute(bodyElement, "abort") is "target"
 PASS testElementAttribute(bodyElement, "animationend") is "target"
 PASS testElementAttribute(bodyElement, "animationiteration") is "target"
 PASS testElementAttribute(bodyElement, "animationstart") is "target"
+PASS testElementAttribute(bodyElement, "autocomplete") is "target"
+PASS testElementAttribute(bodyElement, "autocompleteerror") is "target"
 PASS testElementAttribute(bodyElement, "beforecopy") is "target"
 PASS testElementAttribute(bodyElement, "beforecut") is "target"
 PASS testElementAttribute(bodyElement, "beforeload") is "target"
@@ -635,8 +794,9 @@ PASS testElementAttribute(bodyElement, "drop") is "target"
 PASS testElementAttribute(bodyElement, "durationchange") is "target"
 PASS testElementAttribute(bodyElement, "emptied") is "target"
 PASS testElementAttribute(bodyElement, "ended") is "target"
-PASS testElementAttribute(bodyElement, "focusin") is "target"
-PASS testElementAttribute(bodyElement, "focusout") is "target"
+PASS testElementAttribute(bodyElement, "gesturechange") is "target"
+PASS testElementAttribute(bodyElement, "gestureend") is "target"
+PASS testElementAttribute(bodyElement, "gesturestart") is "target"
 PASS testElementAttribute(bodyElement, "input") is "target"
 PASS testElementAttribute(bodyElement, "invalid") is "target"
 PASS testElementAttribute(bodyElement, "keydown") is "target"
@@ -660,7 +820,7 @@ PASS testElementAttribute(bodyElement, "playing") is "target"
 PASS testElementAttribute(bodyElement, "progress") is "target"
 PASS testElementAttribute(bodyElement, "ratechange") is "target"
 PASS testElementAttribute(bodyElement, "reset") is "target"
-FAIL testElementAttribute(bodyElement, "scroll") should be target. Was script: target; content: window.
+FAIL testElementAttribute(bodyElement, "scroll") should be target. Was window.
 PASS testElementAttribute(bodyElement, "search") is "target"
 PASS testElementAttribute(bodyElement, "seeked") is "target"
 PASS testElementAttribute(bodyElement, "seeking") is "target"
@@ -677,34 +837,56 @@ PASS testElementAttribute(bodyElement, "touchstart") is "target"
 PASS testElementAttribute(bodyElement, "transitionend") is "target"
 PASS testElementAttribute(bodyElement, "volumechange") is "target"
 PASS testElementAttribute(bodyElement, "waiting") is "target"
-FAIL testElementAttribute(bodyElement, "webkitanimationend") should be target. Was script: none; content: target.
-FAIL testElementAttribute(bodyElement, "webkitanimationiteration") should be target. Was script: none; content: target.
-FAIL testElementAttribute(bodyElement, "webkitanimationstart") should be target. Was script: none; content: target.
-FAIL testElementAttribute(bodyElement, "webkittransitionend") should be target. Was script: none; content: target.
+PASS testElementAttribute(bodyElement, "webkitanimationend") is "target"
+PASS testElementAttribute(bodyElement, "webkitanimationiteration") is "target"
+PASS testElementAttribute(bodyElement, "webkitanimationstart") is "target"
+PASS testElementAttribute(bodyElement, "webkitcurrentplaybacktargetiswirelesschanged") is "target"
+PASS testElementAttribute(bodyElement, "webkitfullscreenchange") is "target"
+PASS testElementAttribute(bodyElement, "webkitfullscreenerror") is "target"
+PASS testElementAttribute(bodyElement, "webkitkeyadded") is "target"
+PASS testElementAttribute(bodyElement, "webkitkeyerror") is "target"
+PASS testElementAttribute(bodyElement, "webkitkeymessage") is "target"
+PASS testElementAttribute(bodyElement, "webkitneedkey") is "target"
+PASS testElementAttribute(bodyElement, "webkitplaybacktargetavailabilitychanged") is "target"
+PASS testElementAttribute(bodyElement, "webkitpresentationmodechanged") is "target"
+PASS testElementAttribute(bodyElement, "webkittransitionend") is "target"
 PASS testElementAttribute(bodyElement, "wheel") is "target"
 
 Event names we expect to not be able to set on <body> element
 
+PASS testElementAttribute(bodyElement, "devicemotion") is "none"
+PASS testElementAttribute(bodyElement, "deviceorientation") is "none"
 PASS testElementAttribute(bodyElement, "noneventname") is "none"
+PASS testElementAttribute(bodyElement, "pointerlockchange") is "none"
+PASS testElementAttribute(bodyElement, "pointerlockerror") is "none"
 PASS testElementAttribute(bodyElement, "readystatechange") is "none"
+PASS testElementAttribute(bodyElement, "securitypolicyviolation") is "none"
+PASS testElementAttribute(bodyElement, "webkitdeviceproximity") is "none"
 
 Event names we expect to be forwarded from <frameset> element to window object)
 
 PASS testElementAttribute(framesetElement, "beforeunload") is "window"
 PASS testElementAttribute(framesetElement, "blur") is "window"
-FAIL testElementAttribute(framesetElement, "error") should be window. Was script: window; content: target.
+PASS testElementAttribute(framesetElement, "error") is "window"
 PASS testElementAttribute(framesetElement, "focus") is "window"
+PASS testElementAttribute(framesetElement, "focusin") is "window"
+PASS testElementAttribute(framesetElement, "focusout") is "window"
 PASS testElementAttribute(framesetElement, "hashchange") is "window"
 PASS testElementAttribute(framesetElement, "load") is "window"
-FAIL testElementAttribute(framesetElement, "message") should be window. Was script: window; content: none.
+PASS testElementAttribute(framesetElement, "message") is "window"
 PASS testElementAttribute(framesetElement, "offline") is "window"
 PASS testElementAttribute(framesetElement, "online") is "window"
-FAIL testElementAttribute(framesetElement, "pagehide") should be window. Was none.
-FAIL testElementAttribute(framesetElement, "pageshow") should be window. Was none.
+PASS testElementAttribute(framesetElement, "orientationchange") is "window"
+PASS testElementAttribute(framesetElement, "pagehide") is "window"
+PASS testElementAttribute(framesetElement, "pageshow") is "window"
 PASS testElementAttribute(framesetElement, "popstate") is "window"
 PASS testElementAttribute(framesetElement, "resize") is "window"
 PASS testElementAttribute(framesetElement, "storage") is "window"
 PASS testElementAttribute(framesetElement, "unload") is "window"
+PASS testElementAttribute(framesetElement, "webkitwillrevealbottom") is "window"
+PASS testElementAttribute(framesetElement, "webkitwillrevealleft") is "window"
+PASS testElementAttribute(framesetElement, "webkitwillrevealright") is "window"
+PASS testElementAttribute(framesetElement, "webkitwillrevealtop") is "window"
 
 Event names we expect to be forwarded from <frameset> element to document)
 
@@ -716,6 +898,8 @@ PASS testElementAttribute(framesetElement, "abort") is "target"
 PASS testElementAttribute(framesetElement, "animationend") is "target"
 PASS testElementAttribute(framesetElement, "animationiteration") is "target"
 PASS testElementAttribute(framesetElement, "animationstart") is "target"
+PASS testElementAttribute(framesetElement, "autocomplete") is "target"
+PASS testElementAttribute(framesetElement, "autocompleteerror") is "target"
 PASS testElementAttribute(framesetElement, "beforecopy") is "target"
 PASS testElementAttribute(framesetElement, "beforecut") is "target"
 PASS testElementAttribute(framesetElement, "beforeload") is "target"
@@ -738,8 +922,9 @@ PASS testElementAttribute(framesetElement, "drop") is "target"
 PASS testElementAttribute(framesetElement, "durationchange") is "target"
 PASS testElementAttribute(framesetElement, "emptied") is "target"
 PASS testElementAttribute(framesetElement, "ended") is "target"
-FAIL testElementAttribute(framesetElement, "focusin") should be target. Was script: target; content: window.
-FAIL testElementAttribute(framesetElement, "focusout") should be target. Was script: target; content: window.
+PASS testElementAttribute(framesetElement, "gesturechange") is "target"
+PASS testElementAttribute(framesetElement, "gestureend") is "target"
+PASS testElementAttribute(framesetElement, "gesturestart") is "target"
 PASS testElementAttribute(framesetElement, "input") is "target"
 PASS testElementAttribute(framesetElement, "invalid") is "target"
 PASS testElementAttribute(framesetElement, "keydown") is "target"
@@ -763,7 +948,7 @@ PASS testElementAttribute(framesetElement, "playing") is "target"
 PASS testElementAttribute(framesetElement, "progress") is "target"
 PASS testElementAttribute(framesetElement, "ratechange") is "target"
 PASS testElementAttribute(framesetElement, "reset") is "target"
-FAIL testElementAttribute(framesetElement, "scroll") should be target. Was script: target; content: window.
+FAIL testElementAttribute(framesetElement, "scroll") should be target. Was window.
 PASS testElementAttribute(framesetElement, "search") is "target"
 PASS testElementAttribute(framesetElement, "seeked") is "target"
 PASS testElementAttribute(framesetElement, "seeking") is "target"
@@ -780,16 +965,31 @@ PASS testElementAttribute(framesetElement, "touchstart") is "target"
 PASS testElementAttribute(framesetElement, "transitionend") is "target"
 PASS testElementAttribute(framesetElement, "volumechange") is "target"
 PASS testElementAttribute(framesetElement, "waiting") is "target"
-FAIL testElementAttribute(framesetElement, "webkitanimationend") should be target. Was script: none; content: target.
-FAIL testElementAttribute(framesetElement, "webkitanimationiteration") should be target. Was script: none; content: target.
-FAIL testElementAttribute(framesetElement, "webkitanimationstart") should be target. Was script: none; content: target.
-FAIL testElementAttribute(framesetElement, "webkittransitionend") should be target. Was script: none; content: target.
+PASS testElementAttribute(framesetElement, "webkitanimationend") is "target"
+PASS testElementAttribute(framesetElement, "webkitanimationiteration") is "target"
+PASS testElementAttribute(framesetElement, "webkitanimationstart") is "target"
+PASS testElementAttribute(framesetElement, "webkitcurrentplaybacktargetiswirelesschanged") is "target"
+PASS testElementAttribute(framesetElement, "webkitfullscreenchange") is "target"
+PASS testElementAttribute(framesetElement, "webkitfullscreenerror") is "target"
+PASS testElementAttribute(framesetElement, "webkitkeyadded") is "target"
+PASS testElementAttribute(framesetElement, "webkitkeyerror") is "target"
+PASS testElementAttribute(framesetElement, "webkitkeymessage") is "target"
+PASS testElementAttribute(framesetElement, "webkitneedkey") is "target"
+PASS testElementAttribute(framesetElement, "webkitplaybacktargetavailabilitychanged") is "target"
+PASS testElementAttribute(framesetElement, "webkitpresentationmodechanged") is "target"
+PASS testElementAttribute(framesetElement, "webkittransitionend") is "target"
 PASS testElementAttribute(framesetElement, "wheel") is "target"
 
 Event names we expect to not be able to set on <frameset> element
 
+PASS testElementAttribute(framesetElement, "devicemotion") is "none"
+PASS testElementAttribute(framesetElement, "deviceorientation") is "none"
 PASS testElementAttribute(framesetElement, "noneventname") is "none"
+PASS testElementAttribute(framesetElement, "pointerlockchange") is "none"
+PASS testElementAttribute(framesetElement, "pointerlockerror") is "none"
 PASS testElementAttribute(framesetElement, "readystatechange") is "none"
+PASS testElementAttribute(framesetElement, "securitypolicyviolation") is "none"
+PASS testElementAttribute(framesetElement, "webkitdeviceproximity") is "none"
 
 Event names we expect to be able to set on an element (tested on the SVG <rect> element)
 
@@ -797,6 +997,8 @@ PASS testElementAttribute(rectElement, "abort") is "target"
 PASS testElementAttribute(rectElement, "animationend") is "target"
 PASS testElementAttribute(rectElement, "animationiteration") is "target"
 PASS testElementAttribute(rectElement, "animationstart") is "target"
+PASS testElementAttribute(rectElement, "autocomplete") is "target"
+PASS testElementAttribute(rectElement, "autocompleteerror") is "target"
 PASS testElementAttribute(rectElement, "beforecopy") is "target"
 PASS testElementAttribute(rectElement, "beforecut") is "target"
 PASS testElementAttribute(rectElement, "beforeload") is "target"
@@ -824,6 +1026,9 @@ PASS testElementAttribute(rectElement, "error") is "target"
 PASS testElementAttribute(rectElement, "focus") is "target"
 PASS testElementAttribute(rectElement, "focusin") is "target"
 PASS testElementAttribute(rectElement, "focusout") is "target"
+PASS testElementAttribute(rectElement, "gesturechange") is "target"
+PASS testElementAttribute(rectElement, "gestureend") is "target"
+PASS testElementAttribute(rectElement, "gesturestart") is "target"
 PASS testElementAttribute(rectElement, "input") is "target"
 PASS testElementAttribute(rectElement, "invalid") is "target"
 PASS testElementAttribute(rectElement, "keydown") is "target"
@@ -865,28 +1070,48 @@ PASS testElementAttribute(rectElement, "touchstart") is "target"
 PASS testElementAttribute(rectElement, "transitionend") is "target"
 PASS testElementAttribute(rectElement, "volumechange") is "target"
 PASS testElementAttribute(rectElement, "waiting") is "target"
-FAIL testElementAttribute(rectElement, "webkitanimationend") should be target. Was script: none; content: target.
-FAIL testElementAttribute(rectElement, "webkitanimationiteration") should be target. Was script: none; content: target.
-FAIL testElementAttribute(rectElement, "webkitanimationstart") should be target. Was script: none; content: target.
-FAIL testElementAttribute(rectElement, "webkittransitionend") should be target. Was script: none; content: target.
+PASS testElementAttribute(rectElement, "webkitanimationend") is "target"
+PASS testElementAttribute(rectElement, "webkitanimationiteration") is "target"
+PASS testElementAttribute(rectElement, "webkitanimationstart") is "target"
+PASS testElementAttribute(rectElement, "webkitcurrentplaybacktargetiswirelesschanged") is "target"
+PASS testElementAttribute(rectElement, "webkitfullscreenchange") is "target"
+PASS testElementAttribute(rectElement, "webkitfullscreenerror") is "target"
+PASS testElementAttribute(rectElement, "webkitkeyadded") is "target"
+PASS testElementAttribute(rectElement, "webkitkeyerror") is "target"
+PASS testElementAttribute(rectElement, "webkitkeymessage") is "target"
+PASS testElementAttribute(rectElement, "webkitneedkey") is "target"
+PASS testElementAttribute(rectElement, "webkitplaybacktargetavailabilitychanged") is "target"
+PASS testElementAttribute(rectElement, "webkitpresentationmodechanged") is "target"
+PASS testElementAttribute(rectElement, "webkittransitionend") is "target"
+PASS testElementAttribute(rectElement, "webkitwillrevealbottom") is "target"
+PASS testElementAttribute(rectElement, "webkitwillrevealleft") is "target"
+PASS testElementAttribute(rectElement, "webkitwillrevealright") is "target"
+PASS testElementAttribute(rectElement, "webkitwillrevealtop") is "target"
 PASS testElementAttribute(rectElement, "wheel") is "target"
 
 Event names we expect not to be able to set on an element (tested on the SVG <rect> element)
 
 PASS testElementAttribute(rectElement, "beforeunload") is "none"
+PASS testElementAttribute(rectElement, "devicemotion") is "none"
+PASS testElementAttribute(rectElement, "deviceorientation") is "none"
 PASS testElementAttribute(rectElement, "hashchange") is "none"
 PASS testElementAttribute(rectElement, "message") is "none"
 PASS testElementAttribute(rectElement, "noneventname") is "none"
 PASS testElementAttribute(rectElement, "offline") is "none"
 PASS testElementAttribute(rectElement, "online") is "none"
+PASS testElementAttribute(rectElement, "orientationchange") is "none"
 PASS testElementAttribute(rectElement, "pagehide") is "none"
 PASS testElementAttribute(rectElement, "pageshow") is "none"
+PASS testElementAttribute(rectElement, "pointerlockchange") is "none"
+PASS testElementAttribute(rectElement, "pointerlockerror") is "none"
 PASS testElementAttribute(rectElement, "popstate") is "none"
 PASS testElementAttribute(rectElement, "readystatechange") is "none"
 PASS testElementAttribute(rectElement, "resize") is "none"
+PASS testElementAttribute(rectElement, "securitypolicyviolation") is "none"
 PASS testElementAttribute(rectElement, "selectionchange") is "none"
 PASS testElementAttribute(rectElement, "storage") is "none"
 PASS testElementAttribute(rectElement, "unload") is "none"
+PASS testElementAttribute(rectElement, "webkitdeviceproximity") is "none"
 
 Event names on a non-HTML element
 
@@ -894,6 +1119,8 @@ FAIL testElementAttribute(nonHTMLElement, "abort") should be none. Was script: t
 FAIL testElementAttribute(nonHTMLElement, "animationend") should be none. Was script: target; content: none.
 FAIL testElementAttribute(nonHTMLElement, "animationiteration") should be none. Was script: target; content: none.
 FAIL testElementAttribute(nonHTMLElement, "animationstart") should be none. Was script: target; content: none.
+FAIL testElementAttribute(nonHTMLElement, "autocomplete") should be none. Was script: target; content: none.
+FAIL testElementAttribute(nonHTMLElement, "autocompleteerror") should be none. Was script: target; content: none.
 FAIL testElementAttribute(nonHTMLElement, "beforecopy") should be none. Was script: target; content: none.
 FAIL testElementAttribute(nonHTMLElement, "beforecut") should be none. Was script: target; content: none.
 FAIL testElementAttribute(nonHTMLElement, "beforeload") should be none. Was script: target; content: none.
@@ -908,6 +1135,8 @@ FAIL testElementAttribute(nonHTMLElement, "contextmenu") should be none. Was scr
 FAIL testElementAttribute(nonHTMLElement, "copy") should be none. Was script: target; content: none.
 FAIL testElementAttribute(nonHTMLElement, "cut") should be none. Was script: target; content: none.
 FAIL testElementAttribute(nonHTMLElement, "dblclick") should be none. Was script: target; content: none.
+PASS testElementAttribute(nonHTMLElement, "devicemotion") is "none"
+PASS testElementAttribute(nonHTMLElement, "deviceorientation") is "none"
 FAIL testElementAttribute(nonHTMLElement, "drag") should be none. Was script: target; content: none.
 FAIL testElementAttribute(nonHTMLElement, "dragend") should be none. Was script: target; content: none.
 FAIL testElementAttribute(nonHTMLElement, "dragenter") should be none. Was script: target; content: none.
@@ -922,6 +1151,9 @@ FAIL testElementAttribute(nonHTMLElement, "error") should be none. Was script: t
 FAIL testElementAttribute(nonHTMLElement, "focus") should be none. Was script: target; content: none.
 FAIL testElementAttribute(nonHTMLElement, "focusin") should be none. Was script: target; content: none.
 FAIL testElementAttribute(nonHTMLElement, "focusout") should be none. Was script: target; content: none.
+FAIL testElementAttribute(nonHTMLElement, "gesturechange") should be none. Was script: target; content: none.
+FAIL testElementAttribute(nonHTMLElement, "gestureend") should be none. Was script: target; content: none.
+FAIL testElementAttribute(nonHTMLElement, "gesturestart") should be none. Was script: target; content: none.
 PASS testElementAttribute(nonHTMLElement, "hashchange") is "none"
 FAIL testElementAttribute(nonHTMLElement, "input") should be none. Was script: target; content: none.
 FAIL testElementAttribute(nonHTMLElement, "invalid") should be none. Was script: target; content: none.
@@ -944,12 +1176,15 @@ FAIL testElementAttribute(nonHTMLElement, "mousewheel") should be none. Was scri
 PASS testElementAttribute(nonHTMLElement, "noneventname") is "none"
 PASS testElementAttribute(nonHTMLElement, "offline") is "none"
 PASS testElementAttribute(nonHTMLElement, "online") is "none"
+PASS testElementAttribute(nonHTMLElement, "orientationchange") is "none"
 PASS testElementAttribute(nonHTMLElement, "pagehide") is "none"
 PASS testElementAttribute(nonHTMLElement, "pageshow") is "none"
 FAIL testElementAttribute(nonHTMLElement, "paste") should be none. Was script: target; content: none.
 FAIL testElementAttribute(nonHTMLElement, "pause") should be none. Was script: target; content: none.
 FAIL testElementAttribute(nonHTMLElement, "play") should be none. Was script: target; content: none.
 FAIL testElementAttribute(nonHTMLElement, "playing") should be none. Was script: target; content: none.
+PASS testElementAttribute(nonHTMLElement, "pointerlockchange") is "none"
+PASS testElementAttribute(nonHTMLElement, "pointerlockerror") is "none"
 PASS testElementAttribute(nonHTMLElement, "popstate") is "none"
 FAIL testElementAttribute(nonHTMLElement, "progress") should be none. Was script: target; content: none.
 FAIL testElementAttribute(nonHTMLElement, "ratechange") should be none. Was script: target; content: none.
@@ -958,6 +1193,7 @@ FAIL testElementAttribute(nonHTMLElement, "reset") should be none. Was script: t
 PASS testElementAttribute(nonHTMLElement, "resize") is "none"
 FAIL testElementAttribute(nonHTMLElement, "scroll") should be none. Was script: target; content: none.
 FAIL testElementAttribute(nonHTMLElement, "search") should be none. Was script: target; content: none.
+PASS testElementAttribute(nonHTMLElement, "securitypolicyviolation") is "none"
 FAIL testElementAttribute(nonHTMLElement, "seeked") should be none. Was script: target; content: none.
 FAIL testElementAttribute(nonHTMLElement, "seeking") should be none. Was script: target; content: none.
 FAIL testElementAttribute(nonHTMLElement, "select") should be none. Was script: target; content: none.
@@ -976,10 +1212,24 @@ FAIL testElementAttribute(nonHTMLElement, "transitionend") should be none. Was s
 PASS testElementAttribute(nonHTMLElement, "unload") is "none"
 FAIL testElementAttribute(nonHTMLElement, "volumechange") should be none. Was script: target; content: none.
 FAIL testElementAttribute(nonHTMLElement, "waiting") should be none. Was script: target; content: none.
-PASS testElementAttribute(nonHTMLElement, "webkitanimationend") is "none"
-PASS testElementAttribute(nonHTMLElement, "webkitanimationiteration") is "none"
-PASS testElementAttribute(nonHTMLElement, "webkitanimationstart") is "none"
-PASS testElementAttribute(nonHTMLElement, "webkittransitionend") is "none"
+FAIL testElementAttribute(nonHTMLElement, "webkitanimationend") should be none. Was script: target; content: none.
+FAIL testElementAttribute(nonHTMLElement, "webkitanimationiteration") should be none. Was script: target; content: none.
+FAIL testElementAttribute(nonHTMLElement, "webkitanimationstart") should be none. Was script: target; content: none.
+FAIL testElementAttribute(nonHTMLElement, "webkitcurrentplaybacktargetiswirelesschanged") should be none. Was script: target; content: none.
+PASS testElementAttribute(nonHTMLElement, "webkitdeviceproximity") is "none"
+FAIL testElementAttribute(nonHTMLElement, "webkitfullscreenchange") should be none. Was script: target; content: none.
+FAIL testElementAttribute(nonHTMLElement, "webkitfullscreenerror") should be none. Was script: target; content: none.
+FAIL testElementAttribute(nonHTMLElement, "webkitkeyadded") should be none. Was script: target; content: none.
+FAIL testElementAttribute(nonHTMLElement, "webkitkeyerror") should be none. Was script: target; content: none.
+FAIL testElementAttribute(nonHTMLElement, "webkitkeymessage") should be none. Was script: target; content: none.
+FAIL testElementAttribute(nonHTMLElement, "webkitneedkey") should be none. Was script: target; content: none.
+FAIL testElementAttribute(nonHTMLElement, "webkitplaybacktargetavailabilitychanged") should be none. Was script: target; content: none.
+FAIL testElementAttribute(nonHTMLElement, "webkitpresentationmodechanged") should be none. Was script: target; content: none.
+FAIL testElementAttribute(nonHTMLElement, "webkittransitionend") should be none. Was script: target; content: none.
+FAIL testElementAttribute(nonHTMLElement, "webkitwillrevealbottom") should be none. Was script: target; content: none.
+FAIL testElementAttribute(nonHTMLElement, "webkitwillrevealleft") should be none. Was script: target; content: none.
+FAIL testElementAttribute(nonHTMLElement, "webkitwillrevealright") should be none. Was script: target; content: none.
+FAIL testElementAttribute(nonHTMLElement, "webkitwillrevealtop") should be none. Was script: target; content: none.
 FAIL testElementAttribute(nonHTMLElement, "wheel") should be none. Was script: target; content: none.
 
 PASS successfullyParsed is true
index 9381a56..f363cf2 100644 (file)
@@ -25,6 +25,8 @@ const windowEvents = [
     "click",
     "contextmenu",
     "dblclick",
+    "devicemotion",
+    "deviceorientation",
     "drag",
     "dragend",
     "dragenter",
@@ -37,6 +39,9 @@ const windowEvents = [
     "ended",
     "error",
     "focus",
+    "gesturechange",
+    "gestureend",
+    "gesturestart",
     "hashchange",
     "input",
     "invalid",
@@ -58,6 +63,7 @@ const windowEvents = [
     "mousewheel",
     "offline",
     "online",
+    "orientationchange",
     "pagehide",
     "pageshow",
     "pause",
@@ -78,6 +84,10 @@ const windowEvents = [
     "submit",
     "suspend",
     "timeupdate",
+    "touchcancel",
+    "touchend",
+    "touchmove",
+    "touchstart",
     "transitionend",
     "unload",
     "volumechange",
@@ -85,7 +95,12 @@ const windowEvents = [
     "webkitanimationend",
     "webkitanimationiteration",
     "webkitanimationstart",
+    "webkitdeviceproximity",
     "webkittransitionend",
+    "webkitwillrevealbottom",
+    "webkitwillrevealleft",
+    "webkitwillrevealright",
+    "webkitwillrevealtop",
     "wheel",
 ];
 
@@ -125,14 +140,27 @@ const documentEvents = [
     "mouseup",
     "mousewheel",
     "paste",
+    "pointerlockchange",
+    "pointerlockerror",
     "readystatechange",
     "reset",
     "scroll",
     "search",
+    "securitypolicyviolation",
     "select",
     "selectionchange",
     "selectstart",
     "submit",
+    "touchcancel",
+    "touchend",
+    "touchmove",
+    "touchstart",
+    "webkitfullscreenchange",
+    "webkitfullscreenerror",
+    "webkitwillrevealbottom",
+    "webkitwillrevealleft",
+    "webkitwillrevealright",
+    "webkitwillrevealtop",
     "wheel",
 ];
 
@@ -141,6 +169,8 @@ const elementEvents = [
     "animationend",
     "animationiteration",
     "animationstart",
+    "autocomplete",
+    "autocompleteerror",
     "beforecopy",
     "beforecut",
     "beforeload",
@@ -168,6 +198,9 @@ const elementEvents = [
     "focus",
     "focusin",
     "focusout",
+    "gesturechange",
+    "gestureend",
+    "gesturestart",
     "input",
     "invalid",
     "keydown",
@@ -212,7 +245,20 @@ const elementEvents = [
     "webkitanimationend",
     "webkitanimationiteration",
     "webkitanimationstart",
+    "webkitcurrentplaybacktargetiswirelesschanged",
+    "webkitfullscreenchange",
+    "webkitfullscreenerror",
+    "webkitkeyadded",
+    "webkitkeyerror",
+    "webkitkeymessage",
+    "webkitneedkey",
+    "webkitplaybacktargetavailabilitychanged",
+    "webkitpresentationmodechanged",
     "webkittransitionend",
+    "webkitwillrevealbottom",
+    "webkitwillrevealleft",
+    "webkitwillrevealright",
+    "webkitwillrevealtop",
     "wheel",
 ];
 
@@ -221,17 +267,24 @@ const bodyElementWindowForwardedEvents = [
     "blur",
     "error",
     "focus",
+    "focusin",
+    "focusout",
     "hashchange",
     "load",
     "message",
     "offline",
     "online",
+    "orientationchange",
     "pagehide",
     "pageshow",
     "popstate",
     "resize",
     "storage",
     "unload",
+    "webkitwillrevealbottom",
+    "webkitwillrevealleft",
+    "webkitwillrevealright",
+    "webkitwillrevealtop",
 ];
 
 const bodyElementDocumentForwardedEvents = [
@@ -418,52 +471,6 @@ To make the results of this test platform independent, there is no testing here
 An alternative would be to always make these event handler attributes work even if the feature
 that sends the events is turned off. See list here of IDL files that include these conditional events.
 
-page/DOMWindow.idl:    [Conditional=ORIENTATION_EVENTS] attribute EventListener onorientationchange;
-page/DOMWindow.idl:    [Conditional=TOUCH_EVENTS] attribute EventListener ontouchstart;
-page/DOMWindow.idl:    [Conditional=TOUCH_EVENTS] attribute EventListener ontouchmove;
-page/DOMWindow.idl:    [Conditional=TOUCH_EVENTS] attribute EventListener ontouchend;
-page/DOMWindow.idl:    [Conditional=TOUCH_EVENTS] attribute EventListener ontouchcancel;
-page/DOMWindow.idl:    [Conditional=IOS_GESTURE_EVENTS] attribute EventListener ongesturestart;
-page/DOMWindow.idl:    [Conditional=IOS_GESTURE_EVENTS] attribute EventListener ongesturechange;
-page/DOMWindow.idl:    [Conditional=IOS_GESTURE_EVENTS] attribute EventListener ongestureend;
-page/DOMWindow.idl:    [Conditional=DEVICE_ORIENTATION] attribute EventListener ondevicemotion;
-page/DOMWindow.idl:    [Conditional=DEVICE_ORIENTATION] attribute EventListener ondeviceorientation;
-page/DOMWindow.idl:    [Conditional=PROXIMITY_EVENTS] attribute EventListener onwebkitdeviceproximity;
-page/DOMWindow.idl:    [Conditional=WILL_REVEAL_EDGE_EVENTS] attribute EventListener onwebkitwillrevealbottom;
-page/DOMWindow.idl:    [Conditional=WILL_REVEAL_EDGE_EVENTS] attribute EventListener onwebkitwillrevealleft;
-page/DOMWindow.idl:    [Conditional=WILL_REVEAL_EDGE_EVENTS] attribute EventListener onwebkitwillrevealright;
-page/DOMWindow.idl:    [Conditional=WILL_REVEAL_EDGE_EVENTS] attribute EventListener onwebkitwillrevealtop;
-
-dom/Document.idl:    [NotEnumerable, Conditional=TOUCH_EVENTS] attribute EventListener ontouchstart;
-dom/Document.idl:    [NotEnumerable, Conditional=TOUCH_EVENTS] attribute EventListener ontouchmove;
-dom/Document.idl:    [NotEnumerable, Conditional=TOUCH_EVENTS] attribute EventListener ontouchend;
-dom/Document.idl:    [NotEnumerable, Conditional=TOUCH_EVENTS] attribute EventListener ontouchcancel;
-dom/Document.idl:    [NotEnumerable, Conditional=FULLSCREEN_API] attribute EventListener onwebkitfullscreenchange;
-dom/Document.idl:    [NotEnumerable, Conditional=FULLSCREEN_API] attribute EventListener onwebkitfullscreenerror;
-dom/Document.idl:    [NotEnumerable, Conditional=POINTER_LOCK] attribute EventListener onpointerlockchange;
-dom/Document.idl:    [NotEnumerable, Conditional=POINTER_LOCK] attribute EventListener onpointerlockerror;
-dom/Document.idl:    [NotEnumerable, Conditional=CSP_NEXT] attribute EventListener onsecuritypolicyviolation;
-dom/Document.idl:    [NotEnumerable, Conditional=WILL_REVEAL_EDGE_EVENTS] attribute EventListener onwebkitwillrevealbottom;
-dom/Document.idl:    [NotEnumerable, Conditional=WILL_REVEAL_EDGE_EVENTS] attribute EventListener onwebkitwillrevealleft;
-dom/Document.idl:    [NotEnumerable, Conditional=WILL_REVEAL_EDGE_EVENTS] attribute EventListener onwebkitwillrevealright;
-dom/Document.idl:    [NotEnumerable, Conditional=WILL_REVEAL_EDGE_EVENTS] attribute EventListener onwebkitwillrevealtop;
-
-dom/Element.idl:    [NotEnumerable, Conditional=ENCRYPTED_MEDIA] attribute EventListener onwebkitkeyadded;
-dom/Element.idl:    [NotEnumerable, Conditional=ENCRYPTED_MEDIA] attribute EventListener onwebkitkeyerror;
-dom/Element.idl:    [NotEnumerable, Conditional=ENCRYPTED_MEDIA] attribute EventListener onwebkitkeymessage;
-dom/Element.idl:    [NotEnumerable, Conditional=ENCRYPTED_MEDIA|ENCRYPTED_MEDIA_V2] attribute EventListener onwebkitneedkey;
-dom/Element.idl:    [NotEnumerable, Conditional=FULLSCREEN_API] attribute EventListener onwebkitfullscreenchange;
-dom/Element.idl:    [NotEnumerable, Conditional=FULLSCREEN_API] attribute EventListener onwebkitfullscreenerror;
-dom/Element.idl:    [NotEnumerable, Conditional=REQUEST_AUTOCOMPLETE] attribute EventListener onautocomplete;
-dom/Element.idl:    [NotEnumerable, Conditional=REQUEST_AUTOCOMPLETE] attribute EventListener onautocompleteerror;
-dom/Element.idl:    [NotEnumerable, Conditional=VIDEO_PRESENTATION_MODE] attribute EventListener onwebkitpresentationmodechanged;
-dom/Element.idl:    [NotEnumerable, Conditional=WILL_REVEAL_EDGE_EVENTS] attribute EventListener onwebkitwillrevealbottom;
-dom/Element.idl:    [NotEnumerable, Conditional=WILL_REVEAL_EDGE_EVENTS] attribute EventListener onwebkitwillrevealleft;
-dom/Element.idl:    [NotEnumerable, Conditional=WILL_REVEAL_EDGE_EVENTS] attribute EventListener onwebkitwillrevealright;
-dom/Element.idl:    [NotEnumerable, Conditional=WILL_REVEAL_EDGE_EVENTS] attribute EventListener onwebkitwillrevealtop;
-dom/Element.idl:    [NotEnumerable, Conditional=WIRELESS_PLAYBACK_TARGET] attribute EventListener onwebkitcurrentplaybacktargetiswirelesschanged;
-dom/Element.idl:    [NotEnumerable, Conditional=WIRELESS_PLAYBACK_TARGET] attribute EventListener onwebkitplaybacktargetavailabilitychanged;
-
 html/HTMLBodyElement.idl:    [Conditional=ORIENTATION_EVENTS, NotEnumerable, JSWindowEventListener] attribute EventListener onorientationchange;
 
 html/HTMLFrameSetElement.idl:    [Conditional=ORIENTATION_EVENTS, NotEnumerable, JSWindowEventListener] attribute EventListener onorientationchange;
index 0ac3c60..14e971f 100644 (file)
@@ -1,3 +1,249 @@
+2015-03-14  Darin Adler  <darin@apple.com>
+
+        More event handler improvements
+        https://bugs.webkit.org/show_bug.cgi?id=142701
+
+        Reviewed by Anders Carlsson.
+
+        These are the improvements:
+
+        - Use EventHandler rather than EventListener as the the type for event handler
+          attributes. This matches the HTML specification, and also makes sense, since
+          EventListener means something else (and we use it to mean that!). Also renamed
+          JSWindowEventListener to WindowEventHandler. Even though this only affects the
+          JavaScript code generated, it's not really a JavaScript-specific flag.
+
+        - Tweak formatting on addEventListener/removeEventListener/dispatchEvent in
+          all the IDL files where the appear. This includes changing the spelling from
+          "evt" to "event". Some day we should fix this so these functions only need to
+          appear in EventTarget.idl.
+
+        - Tweak formatting a bit on the IDL files we had to modify anyway.
+
+        - Use [Conditional] more often and #if less often in IDL files.
+
+        - Added a new [DocumentEventHandler] attribute for the selectionchange event.
+          This involved adding new event handler attribute functions to JSEventListener.h
+          for use by the JavaScript bindings.
+
+        - Removed a little unused code from the JavaScript code bindings generator.
+
+        - Improved the mechanism used by HTMLElement and SVGElement to share the list of
+          content attributes that are event handlers so there is only one map rather than
+          two. Made a similar mechanism so that HTMLBodyElement and HTMLFrameSetElement
+          can share the list of window event handlers.
+
+        - Followed the HTML specification by putting all the event handler support in
+          the HTMLElement class rather than having event handlers apply only a the
+          particular element that uses those events. We already did this for most of
+          our event handlers, but we are now doing it for all of them.
+
+        * Modules/battery/BatteryManager.idl: Use EventHandler instead of EventListener
+        as appropriate. Also reformatted addEventListener/removeEventListener/dispatchEvent.
+        * Modules/encryptedmedia/MediaKeySession.idl: Ditto.
+        * Modules/indexeddb/IDBDatabase.idl: Ditto.
+        * Modules/indexeddb/IDBOpenDBRequest.idl: Ditto.
+        * Modules/indexeddb/IDBRequest.idl: Ditto.
+        * Modules/indexeddb/IDBTransaction.idl: Ditto.
+        * Modules/mediastream/MediaStream.idl: Ditto.
+        * Modules/mediastream/MediaStreamTrack.idl: Ditto.
+        * Modules/mediastream/RTCDTMFSender.idl: Ditto.
+        * Modules/mediastream/RTCDataChannel.idl: Ditto.
+        * Modules/mediastream/RTCPeerConnection.idl: Ditto.
+        * Modules/speech/SpeechSynthesisUtterance.idl: Ditto.
+        * Modules/webaudio/AudioBufferSourceNode.idl: Ditto.
+        * Modules/webaudio/AudioContext.idl: Ditto.
+        * Modules/webaudio/OscillatorNode.idl: Ditto.
+        * Modules/webaudio/ScriptProcessorNode.idl: Ditto.
+        * Modules/websockets/WebSocket.idl: Ditto.
+        * css/FontLoader.idl: Ditto.
+        * dom/EventListener.idl: Ditto.
+        * dom/EventTarget.idl: Ditto.
+        * dom/MessagePort.idl: Ditto.
+        * dom/Node.idl: Ditto.
+        * dom/WebKitNamedFlow.idl: Ditto.
+        * fileapi/FileReader.idl: Ditto.
+        * html/MediaController.idl: Ditto.
+        * html/track/AudioTrackList.idl: Ditto.
+        * html/track/TextTrackCue.idl: Ditto.
+        * html/track/TextTrackList.idl: Ditto.
+        * html/track/VideoTrackList.idl: Ditto.
+        * loader/appcache/DOMApplicationCache.idl: Ditto.
+        * page/EventSource.idl: Ditto.
+        * page/Performance.idl: Ditto.
+        * workers/AbstractWorker.idl: Ditto.
+        * workers/DedicatedWorkerGlobalScope.idl: Ditto.
+        * workers/Worker.idl: Ditto.
+        * workers/WorkerGlobalScope.idl: Ditto.
+        * xml/XMLHttpRequest.idl: Ditto.
+        * xml/XMLHttpRequestUpload.idl: Ditto.
+
+        * Modules/notifications/Notification.idl: Did the above, but also used
+        [Conditional] instead of #if throughout.
+        * html/track/TextTrack.idl: Ditto.
+
+        * Modules/webaudio/AudioNode.idl: Tweaked paragraphing of this file.
+
+        * bindings/js/JSEventListener.cpp:
+        (WebCore::windowEventHandlerAttribute): Renamed to take the word "forwarded"
+        out of this. More closely matches the terminology used in IDL files and the
+        HTML specification.
+        (WebCore::setWindowEventHandlerAttribute): Ditto.
+        (WebCore::documentEventHandlerAttribute): Added.
+        (WebCore::setDocumentEventHandlerAttribute): Added.
+        * bindings/js/JSEventListener.h: Updated for above changes.
+
+        * bindings/objc/PublicDOMInterfaces.h: Renamed argument from "evt" to "event".
+
+        * bindings/scripts/CodeGeneratorGObject.pm:
+        (SkipAttribute): Skip attributes of type "EventHandler" rather than attributes
+        of type "EventListener".
+        * bindings/scripts/CodeGeneratorObjC.pm:
+        (SkipAttribute): Ditto.
+
+        * bindings/scripts/CodeGeneratorJS.pm:
+        (GenerateImplementation): Look for the type EventHandler instead of the type
+        EventListener for event handler attributes. Also added code to handle the new
+        DocumentEventHandler, and use the name WindowEventHandler instead of the name
+        JSWindowEventListener. Removed unneeded preflight check to see if we have
+        writable attributes; it was not doing us any good. (That caused a lot of code
+        to be un-indented and makes the diff hard to read.)
+
+        * bindings/scripts/IDLAttributes.txt: Removed JSWindowEventListener, and added
+        WindowEventHandler and DocumentEventHandler.
+
+        * bindings/scripts/test/TestObj.idl: Use the type EventHandler instead of the
+        type EventListener. The test output is unchanged, though.
+
+        * dom/Document.idl: Got rid of the conditionals and merged all the event handler
+        attributes into a single sorted, unconditional list. Added some that were missing,
+        as detected by the event-handler-attributes.html test.
+
+        * dom/Element.idl: Ditto. This includes moving attributes here that were formerly
+        only in certain element classes. Note that the script event handler attribute
+        support is still here, even though it should be in HTMLElement and SVGElement
+        instead. There's a FIXME about that, but no real urgency in fixing it.
+
+        * html/HTMLAttributeNames.in: Added onmessage. Previously, the support for this
+        was from the script attribute only, not the content attribute.
+
+        * html/HTMLBodyElement.cpp:
+        (WebCore::HTMLBodyElement::createWindowEventHandlerNameMap): Added. This
+        contains the list of all the window event handlers that can be set on a body
+        or frameset element and which are triggered by events on the window.
+        (WebCore::HTMLBodyElement::eventNameForWindowEventHandlerAttribute): Added.
+        This is the function to call to use the map above. Given an attribute, it
+        returns either null if it is not a window event handler attribute, or the
+        event type if it is one.
+        (WebCore::HTMLBodyElement::parseAttribute): Updated to use the new
+        functions above. Handling of these attributes is now unconditional, but
+        also we don't have to keep the nested if statements here up to date, just
+        the list of event handler attributes names in the map create function above.
+
+        * html/HTMLBodyElement.h: Added public eventNameForWindowEventHandlerAttribute
+        and private createWindowEventHandlerNameMap functions.
+
+        * html/HTMLBodyElement.idl: Updated to use WindowEventHandler, DocumentEventHandler,
+        and EventHandler. Also made everything unconditional. Also filled out the list here
+        to match the list handled as content attributes. All covered by the test.
+
+        * html/HTMLElement.cpp:
+        (WebCore::HTMLElement::createEventHandlerNameMap): Added. Replaces the old
+        populate function. Changed the list of event handler attributes to be a bit more
+        complete, and to be entirely unconditional. Also refactored this function to use
+        a new populateEventHandlerNameMap helper, shared with HTMLBodyElement.
+        (WebCore::HTMLElement::populateEventHandlerNameMap): Added. Factors out the code
+        that both this class and HTMLBodyElement use to build event handler name maps.
+        (WebCore::HTMLElement::eventNameForEventHandlerAttribute): Added. This is the
+        function that call to use the map above. Given an attribute it returns either
+        null if it is not an event handler attribute, or the event type if it is one.
+        This is actually two functions. One is a protected function for use by both this
+        class and HTMLBodyElement so they can share things like the optimization to look
+        for the "on" prefix. The other is the public function that we actually use in
+        HTMLElement and SVGElement.
+        (WebCore::HTMLElement::editabilityFromContentEditableAttr): Tweaked and refactored
+        to use lineageOfType. Would have been even simpler if this took an element instead
+        of a node. Unrelated to the event handler changes.
+        (WebCore::HTMLElement::parseAttribute): Removed long-obsolete code that decided
+        whether to call through to the base class. The base class function is empty and
+        never needs to be called, and in any case there is no value in doing work to
+        decide whether to call through to an empty function. Changed the style of the
+        function to use early return instead of else. Worth considering whether we want
+        to return early or call through to base class in this family of functions. It's
+        more efficient to return early, but doesn't work well if both the derived class
+        and base class want to respond to changes to the same attribute. The new logic
+        for event handler attributes is more straightforward than the old, since the
+        eventNameForEventHandlerAttribute has the logic.
+        (WebCore::HTMLElement::textToFragment): Tweaked and refactored a bit, and also
+        changed to return a Ref since this never fails and needs to return null.
+
+        * html/HTMLElement.h: Updated for above changes. This includes a template version
+        of populateEventHandlerNameMap that extracts the array size at compile time and
+        passes it to the non-template function that does the work.
+
+        * html/HTMLFrameElementBase.cpp:
+        (WebCore::HTMLFrameElementBase::parseAttribute): Removed unneeded code to handle
+        event handler attributes handled by HTMLElement.
+        * html/HTMLImageElement.cpp:
+        (WebCore::HTMLImageElement::parseAttribute): Ditto.
+        * html/HTMLLinkElement.cpp:
+        (WebCore::HTMLLinkElement::parseAttribute): Ditto.
+        * html/HTMLObjectElement.cpp:
+        (WebCore::HTMLObjectElement::parseAttribute): Ditto.
+        * html/HTMLScriptElement.cpp:
+        (WebCore::HTMLScriptElement::parseAttribute): Ditto.
+
+        * html/HTMLFrameSetElement.cpp:
+        (WebCore::HTMLFrameSetElement::parseAttribute): Changed function to early return
+        style, and added FIXMEs about the many problems in the attribute handling code.
+        Replaced all the code to handle window event handlers with a new bit of code that
+        calls HTMLBodyElement::eventNameForWindowEventHandlerAttribute.
+
+        * html/HTMLFrameSetElement.idl: Changed to match the list of window event handlers
+        in HTMLBodyElement.idl, although I did not add the document event handler here.
+        As in the various other cases, having some extra event handlers does not seem to
+        do harm and this is covered by the event-handler-attributes.html test.
+
+        * html/HTMLMarqueeElement.idl: Renamed EventListener to EventHandler in comment.
+
+        * page/DOMWindow.idl: As with Element and Document, removed conditionals, and
+        filled out the list of event handlers so all the tests in
+        event-handler-attributes.html will pass.
+
+        * svg/SVGElement.cpp:
+        (WebCore::SVGElement::parseAttribute): Changed code to the early return style,
+        and replaced the event handler attribute code with new much simpler code that
+        uses the new HTMLElement::eventNameForEventHandlerAttribute. Also changed the
+        way we call through to base classes. Just call through to the
+        SVGLangSpace::parseAttribute function unconditionally, and don't try to use
+        early return style to arbitrate among base classes. We should make this
+        simplification throughout the SVG code; there's no need for the complexity
+        that was there before just to cut down slightly on calls through to base
+        class parseAttribute functions.
+
+        * svg/SVGSVGElement.cpp:
+        (WebCore::SVGSVGElement::parseAttribute): Changed some of this code to the
+        early return style and corrected some comments about the window event handler
+        attributes here. These could use some further testing and might later need to be
+        properly supported when the attributes are set in script, not just in content.
+
+        * svg/SVGScriptElement.cpp:
+        (WebCore::SVGScriptElement::isSupportedAttribute): Deleted.
+        (WebCore::SVGScriptElement::parseAttribute): Changed this function to use the
+        early return style and also to call through to all three base classes. This is
+        a pattern we should follow elsewhere in SVG to simplify the code. There is no
+        need for the supportedAttributes sets like the one in this calass, and the code
+        is unnecessarily complex, perhaps in an attempt to optimize performance. I'm
+        pretty sure the old code was slower than this new code will be. No need for the
+        extra hash table lookup every time. Also removed handling of event handler
+        attribute which is taken care of by SVGElement now.
+        (WebCore::SVGScriptElement::svgAttributeChanged): Made similar changes for
+        the same reason as in parseAttribute. This function really needs a new name:
+        It's the same as parseAttribute, except it's also used when implementing
+        changes due to SVG animation.
+
+        * svg/SVGScriptElement.h: Removed isSupportedAttribute.
+
 2015-03-14  Simon Fraser  <simon.fraser@apple.com>
 
         Clean up use of flags in localToContainer-type functions
index 787185e..eda1d51 100644 (file)
     readonly attribute unrestricted double dischargingTime;
     readonly attribute unrestricted double level;
 
-    attribute EventListener onchargingchange;
-    attribute EventListener onchargingtimechange;
-    attribute EventListener ondischargingtimechange;
-    attribute EventListener onlevelchange;
+    attribute EventHandler onchargingchange;
+    attribute EventHandler onchargingtimechange;
+    attribute EventHandler ondischargingtimechange;
+    attribute EventHandler onlevelchange;
 
     // EventTarget interface
-    void addEventListener(DOMString type,
-                          EventListener listener,
-                          optional boolean useCapture);
-    void removeEventListener(DOMString type,
-                             EventListener listener,
-                             optional boolean useCapture);
+    void addEventListener(DOMString type, EventListener listener, optional boolean useCapture);
+    void removeEventListener(DOMString type, EventListener listener, optional boolean useCapture);
     [RaisesException] boolean dispatchEvent(Event event);
 };
index 255902a..2e6ac01 100644 (file)
     [RaisesException] void update(Uint8Array key);
     void close();
     
-    // EventListeners
-    attribute EventListener onwebkitkeyadded;
-    attribute EventListener onwebkitkeyerror;
-    attribute EventListener onwebkitkeymessage;
+    attribute EventHandler onwebkitkeyadded;
+    attribute EventHandler onwebkitkeyerror;
+    attribute EventHandler onwebkitkeymessage;
 
     // EventTarget interface
-    void addEventListener(DOMString type, 
-                          EventListener listener, 
-                          optional boolean useCapture);
-    void removeEventListener(DOMString type, 
-                             EventListener listener, 
-                             optional boolean useCapture);
-    [RaisesException] boolean dispatchEvent(Event evt);
+    void addEventListener(DOMString type, EventListener listener, optional boolean useCapture);
+    void removeEventListener(DOMString type, EventListener listener, optional boolean useCapture);
+    [RaisesException] boolean dispatchEvent(Event event);
 };
index 8ebb879..b786dc2 100644 (file)
@@ -41,9 +41,9 @@
     [CallWith=ScriptExecutionContext, RaisesException] IDBTransaction transaction(sequence<DOMString> storeNames, [Default=NullString] optional DOMString mode);
     void close();
 
-    attribute EventListener onabort;
-    attribute EventListener onerror;
-    attribute EventListener onversionchange;
+    attribute EventHandler onabort;
+    attribute EventHandler onerror;
+    attribute EventHandler onversionchange;
 
 };
 
index b0a33b7..02de6c8 100644 (file)
@@ -29,6 +29,6 @@
     JSGenerateToJSObject,
     JSGenerateToNativeObject
 ] interface IDBOpenDBRequest : IDBRequest {
-    attribute EventListener onblocked;
-    attribute EventListener onupgradeneeded;
+    attribute EventHandler onblocked;
+    attribute EventHandler onupgradeneeded;
 };
index 404edc5..5606232 100644 (file)
@@ -40,6 +40,6 @@
     readonly attribute IDBTransaction transaction;
     readonly attribute DOMString readyState;
 
-    attribute EventListener onsuccess;
-    attribute EventListener onerror;
+    attribute EventHandler onsuccess;
+    attribute EventHandler onerror;
 };
index d137cc5..60d26c4 100644 (file)
@@ -38,7 +38,7 @@
     [RaisesException] IDBObjectStore objectStore (DOMString name);
     [RaisesException] void abort ();
 
-    attribute EventListener onabort;
-    attribute EventListener oncomplete;
-    attribute EventListener onerror;
+    attribute EventHandler onabort;
+    attribute EventHandler oncomplete;
+    attribute EventHandler onerror;
 };
index 091d9de..55a90e5 100644 (file)
 
     readonly attribute boolean active;
 
-    attribute EventListener onactive;
-    attribute EventListener oninactive;
-    attribute EventListener onaddtrack;
-    attribute EventListener onremovetrack;
+    attribute EventHandler onactive;
+    attribute EventHandler oninactive;
+    attribute EventHandler onaddtrack;
+    attribute EventHandler onremovetrack;
 
     // EventTarget interface
-    void addEventListener(DOMString type,
-                          EventListener listener,
-                          optional boolean useCapture);
-    void removeEventListener(DOMString type,
-                             EventListener listener,
-                             optional boolean useCapture);
+    void addEventListener(DOMString type, EventListener listener, optional boolean useCapture);
+    void removeEventListener(DOMString type, EventListener listener, optional boolean useCapture);
     [RaisesException] boolean dispatchEvent(Event event);
 };
 
index 2edf3b4..e821f35 100644 (file)
@@ -34,15 +34,15 @@ enum MediaStreamTrackState { "new", "live", "ended" };
     readonly attribute DOMString kind;
     readonly attribute DOMString id;
     readonly attribute DOMString label;
-             attribute boolean enabled;
+    attribute boolean enabled;
     readonly attribute boolean muted;
-    attribute EventListener onmute;
-    attribute EventListener onunmute;
+    attribute EventHandler onmute;
+    attribute EventHandler onunmute;
     readonly attribute boolean _readonly;
     readonly attribute boolean remote;
     readonly attribute MediaStreamTrackState readyState;
-    attribute EventListener onstarted;
-    attribute EventListener onended;
+    attribute EventHandler onstarted;
+    attribute EventHandler onended;
 
     [CallWith=ScriptExecutionContext, RaisesException] static void getSources(MediaStreamTrackSourcesCallback callback);
 
@@ -54,17 +54,13 @@ enum MediaStreamTrackState { "new", "live", "ended" };
 
     void applyConstraints(Dictionary constraints);
 
-    attribute EventListener onoverconstrained;
+    attribute EventHandler onoverconstrained;
     MediaStreamTrack clone();
     [ImplementedAs=stopProducingData] void stop();
 
     // EventTarget interface
-    void addEventListener(DOMString type,
-                          EventListener listener,
-                          optional boolean useCapture);
-    void removeEventListener(DOMString type,
-                             EventListener listener,
-                             optional boolean useCapture);
+    void addEventListener(DOMString type, EventListener listener, optional boolean useCapture);
+    void removeEventListener(DOMString type, EventListener listener, optional boolean useCapture);
     [RaisesException] boolean dispatchEvent(Event event);
 };
 
index f4fb771..fb86aff 100644 (file)
 
     [RaisesException] void insertDTMF(DOMString tones, optional long duration, optional long interToneGap);
 
-    attribute EventListener ontonechange;
+    attribute EventHandler ontonechange;
 
     // EventTarget interface
-    void addEventListener(DOMString type,
-                          EventListener listener,
-                          optional boolean useCapture);
-    void removeEventListener(DOMString type,
-                             EventListener listener,
-                             optional boolean useCapture);
+    void addEventListener(DOMString type, EventListener listener, optional boolean useCapture);
+    void removeEventListener(DOMString type, EventListener listener, optional boolean useCapture);
     [RaisesException] boolean dispatchEvent(Event event);
 };
index 19c24fa..e9919ff 100644 (file)
 
     void close();
 
-    attribute EventListener onopen;
-    attribute EventListener onerror;
-    attribute EventListener onclose;
-    attribute EventListener onmessage;
+    attribute EventHandler onopen;
+    attribute EventHandler onerror;
+    attribute EventHandler onclose;
+    attribute EventHandler onmessage;
 
     // EventTarget interface
-    void addEventListener(DOMString type,
-                          EventListener listener,
-                          optional boolean useCapture);
-    void removeEventListener(DOMString type,
-                             EventListener listener,
-                             optional boolean useCapture);
+    void addEventListener(DOMString type, EventListener listener, optional boolean useCapture);
+    void removeEventListener(DOMString type, EventListener listener, optional boolean useCapture);
     [RaisesException] boolean dispatchEvent(Event event);
 };
index a6dd8d7..8b2207e 100644 (file)
 
     [RaisesException] void close();
 
-    attribute EventListener onnegotiationneeded;
-    attribute EventListener onicecandidate;
-    attribute EventListener onsignalingstatechange;
-    attribute EventListener onaddstream;
-    attribute EventListener onremovestream;
-    attribute EventListener oniceconnectionstatechange;
-    attribute EventListener ondatachannel;
+    attribute EventHandler onnegotiationneeded;
+    attribute EventHandler onicecandidate;
+    attribute EventHandler onsignalingstatechange;
+    attribute EventHandler onaddstream;
+    attribute EventHandler onremovestream;
+    attribute EventHandler oniceconnectionstatechange;
+    attribute EventHandler ondatachannel;
 
     // EventTarget interface
-    void addEventListener(DOMString type,
-                          EventListener listener,
-                          optional boolean useCapture);
-    void removeEventListener(DOMString type,
-                             EventListener listener,
-                             optional boolean useCapture);
+    void addEventListener(DOMString type, EventListener listener, optional boolean useCapture);
+    void removeEventListener(DOMString type, EventListener listener, optional boolean useCapture);
     [RaisesException] boolean dispatchEvent(Event event);
 };
 
index 1ddf5b3..8675223 100644 (file)
 #endif
 ] interface Notification {
     void show();
-#if defined(ENABLE_LEGACY_NOTIFICATIONS) && ENABLE_LEGACY_NOTIFICATIONS
-    void cancel();
-#endif
-#if defined(ENABLE_NOTIFICATIONS) && ENABLE_NOTIFICATIONS
-    void close();
-#endif
+    [Conditional=LEGACY_NOTIFICATIONS] void cancel();
+    [Conditional=NOTIFICATIONS] void close();
 
+    [Conditional=NOTIFICATIONS, CallWith=ScriptExecutionContext] static readonly attribute DOMString permission;
+    [Conditional=NOTIFICATIONS, CallWith=ScriptExecutionContext] static void requestPermission(optional NotificationPermissionCallback callback);
 
-#if defined(ENABLE_NOTIFICATIONS) && ENABLE_NOTIFICATIONS
-    [CallWith=ScriptExecutionContext] static readonly attribute DOMString permission;
-    [CallWith=ScriptExecutionContext] static void requestPermission(optional NotificationPermissionCallback callback);
-#endif
-
-    attribute EventListener onshow;
-#if defined(ENABLE_LEGACY_NOTIFICATIONS) && ENABLE_LEGACY_NOTIFICATIONS
-    attribute EventListener ondisplay;
-#endif
-    attribute EventListener onerror;
-    attribute EventListener onclose;
-    attribute EventListener onclick;
+    attribute EventHandler onclick;
+    attribute EventHandler onclose;
+    attribute EventHandler ondisplay;
+    attribute EventHandler onerror;
+    attribute EventHandler onshow;
 
-#if defined(ENABLE_LEGACY_NOTIFICATIONS) && ENABLE_LEGACY_NOTIFICATIONS
-    attribute DOMString dir;
-    attribute DOMString replaceId;
-#endif
-#if defined(ENABLE_NOTIFICATIONS) && ENABLE_NOTIFICATIONS
-    attribute DOMString tag;
-#endif
+    [Conditional=LEGACY_NOTIFICATIONS] attribute DOMString dir;
+    [Conditional=LEGACY_NOTIFICATIONS] attribute DOMString replaceId;
+    [Conditional=NOTIFICATIONS] attribute DOMString tag;
 
     // EventTarget interface
-    void addEventListener(DOMString type, 
-                          EventListener listener, 
-                          optional boolean useCapture);
-    void removeEventListener(DOMString type, 
-                             EventListener listener, 
-                             optional boolean useCapture);
-    [RaisesException] boolean dispatchEvent(Event evt);
+    void addEventListener(DOMString type, EventListener listener, optional boolean useCapture);
+    void removeEventListener(DOMString type, EventListener listener, optional boolean useCapture);
+    [RaisesException] boolean dispatchEvent(Event event);
 };
 
index 2c06e9d..cad34a2 100644 (file)
     attribute unrestricted float rate;
     attribute unrestricted float pitch;
 
-    attribute EventListener onstart;
-    attribute EventListener onend;
-    attribute EventListener onerror;
-    attribute EventListener onpause;
-    attribute EventListener onresume;
-    attribute EventListener onmark;
-    attribute EventListener onboundary;
+    attribute EventHandler onstart;
+    attribute EventHandler onend;
+    attribute EventHandler onerror;
+    attribute EventHandler onpause;
+    attribute EventHandler onresume;
+    attribute EventHandler onmark;
+    attribute EventHandler onboundary;
 
     // EventTarget interface
-    void addEventListener(DOMString type, 
-                          EventListener listener, 
-                          optional boolean useCapture);
-    void removeEventListener(DOMString type, 
-                             EventListener listener, 
-                             optional boolean useCapture);
-    [RaisesException] boolean dispatchEvent(Event evt);
+    void addEventListener(DOMString type, EventListener listener, optional boolean useCapture);
+    void removeEventListener(DOMString type, EventListener listener, optional boolean useCapture);
+    [RaisesException] boolean dispatchEvent(Event event);
 };
index 3e42e92..0c50700 100644 (file)
@@ -53,5 +53,5 @@
     [Conditional=LEGACY_WEB_AUDIO, RaisesException] void noteGrainOn(unrestricted double when, unrestricted double grainOffset, unrestricted double grainDuration);
     [Conditional=LEGACY_WEB_AUDIO, RaisesException] void noteOff(unrestricted double when);
     
-    attribute EventListener onended;
+    attribute EventHandler onended;
 };
index bc8d27b..b975e47 100644 (file)
@@ -83,7 +83,7 @@
 
     // Offline rendering
     // void prepareOfflineBufferRendering(unsigned long numberOfChannels, unsigned long numberOfFrames, unrestricted float sampleRate);
-    attribute EventListener oncomplete;
+    attribute EventHandler oncomplete;
     void startRendering();
 
     [Conditional=LEGACY_WEB_AUDIO, ImplementedAs=createGain] GainNode createGainNode();
index 9167e57..431b715 100644 (file)
     readonly attribute unsigned long numberOfOutputs;
 
     [SetterRaisesException] attribute unsigned long channelCount;
-
     [SetterRaisesException] attribute DOMString channelCountMode;
-
     [SetterRaisesException] attribute DOMString channelInterpretation;
 
     [RaisesException] void connect(AudioNode? destination, [Default=Undefined] optional unsigned long output, [Default=Undefined] optional unsigned long input);
-
     [RaisesException] void connect(AudioParam? destination, [Default=Undefined] optional unsigned long output);
-
     [RaisesException] void disconnect([Default=Undefined] optional unsigned long output);
 
     void addEventListener(DOMString type, EventListener listener, optional boolean useCapture);
-
     void removeEventListener(DOMString type, EventListener listener, optional boolean useCapture);
-
     [RaisesException] boolean dispatchEvent(Event event);
 };
index 878bc89..3de3980 100644 (file)
@@ -56,5 +56,5 @@
 
     void setPeriodicWave(PeriodicWave wave);
 
-    attribute EventListener onended;
+    attribute EventHandler onended;
 };
index d5dcd50..45cc630 100644 (file)
@@ -29,7 +29,7 @@
     JSGenerateToNativeObject
 ] interface ScriptProcessorNode : AudioNode {
     // Rendering callback
-    attribute EventListener onaudioprocess;
+    attribute EventHandler onaudioprocess;
 
     readonly attribute long bufferSize;
 };
index ab9d19e..51f10af 100644 (file)
     readonly attribute unsigned long bufferedAmount;
 
     // networking
-    attribute EventListener onopen;
-    attribute EventListener onmessage;
-    attribute EventListener onerror;
-    attribute EventListener onclose;
+    attribute EventHandler onopen;
+    attribute EventHandler onmessage;
+    attribute EventHandler onerror;
+    attribute EventHandler onclose;
 
     [TreatReturnedNullStringAs=Undefined] readonly attribute DOMString protocol;
     [TreatReturnedNullStringAs=Undefined] readonly attribute DOMString extensions;
     [RaisesException] void close([Clamp] optional unsigned short code, optional DOMString reason);
 
     // EventTarget interface
-    void addEventListener(DOMString type,
-                          EventListener listener,
-                          optional boolean useCapture);
-    void removeEventListener(DOMString type,
-                             EventListener listener,
-                             optional boolean useCapture);
-    [RaisesException] boolean dispatchEvent(Event evt);
+    void addEventListener(DOMString type, EventListener listener, optional boolean useCapture);
+    void removeEventListener(DOMString type, EventListener listener, optional boolean useCapture);
+    [RaisesException] boolean dispatchEvent(Event event);
 };
index 959b236..e2d292d 100644 (file)
@@ -24,6 +24,7 @@
 #include "Event.h"
 #include "Frame.h"
 #include "HTMLElement.h"
+#include "JSDocument.h"
 #include "JSEvent.h"
 #include "JSEventTarget.h"
 #include "JSMainThreadExecState.h"
@@ -204,16 +205,31 @@ void setEventHandlerAttribute(JSC::ExecState& state, JSC::JSObject& wrapper, Eve
     target.setAttributeEventListener(eventType, createEventListenerForEventHandlerAttribute(state, value, wrapper));
 }
 
-JSC::JSValue windowForwardedEventHandlerAttribute(HTMLElement& element, const AtomicString& eventType)
+JSC::JSValue windowEventHandlerAttribute(HTMLElement& element, const AtomicString& eventType)
 {
     auto& document = element.document();
     return eventHandlerAttribute(document.getWindowAttributeEventListener(eventType), document);
 }
 
-void setWindowForwardedEventHandlerAttribute(JSC::ExecState& state, JSC::JSObject& wrapper, HTMLElement& element, const AtomicString& eventType, JSC::JSValue value)
+void setWindowEventHandlerAttribute(JSC::ExecState& state, JSC::JSObject& wrapper, HTMLElement& element, const AtomicString& eventType, JSC::JSValue value)
 {
     ASSERT(wrapper.globalObject());
     element.document().setWindowAttributeEventListener(eventType, createEventListenerForEventHandlerAttribute(state, value, *wrapper.globalObject()));
 }
 
+JSC::JSValue documentEventHandlerAttribute(HTMLElement& element, const AtomicString& eventType)
+{
+    auto& document = element.document();
+    return eventHandlerAttribute(document.getAttributeEventListener(eventType), document);
+}
+
+void setDocumentEventHandlerAttribute(JSC::ExecState& state, JSC::JSObject& wrapper, HTMLElement& element, const AtomicString& eventType, JSC::JSValue value)
+{
+    ASSERT(wrapper.globalObject());
+    auto& document = element.document();
+    auto* documentWrapper = jsDocumentCast(toJS(&state, JSC::jsCast<JSDOMGlobalObject*>(wrapper.globalObject()), document));
+    ASSERT(documentWrapper);
+    document.setAttributeEventListener(eventType, createEventListenerForEventHandlerAttribute(state, value, *documentWrapper));
+}
+
 } // namespace WebCore
index 554c6a8..d460a19 100644 (file)
@@ -82,8 +82,12 @@ JSC::JSValue eventHandlerAttribute(EventTarget&, const AtomicString& eventType);
 void setEventHandlerAttribute(JSC::ExecState&, JSC::JSObject&, EventTarget&, const AtomicString& eventType, JSC::JSValue);
 
 // Like the functions above, but for attributes that forward event handlers to the window object rather than setting them on the target.
-JSC::JSValue windowForwardedEventHandlerAttribute(HTMLElement&, const AtomicString& eventType);
-void setWindowForwardedEventHandlerAttribute(JSC::ExecState&, JSC::JSObject&, HTMLElement&, const AtomicString& eventType, JSC::JSValue);
+JSC::JSValue windowEventHandlerAttribute(HTMLElement&, const AtomicString& eventType);
+void setWindowEventHandlerAttribute(JSC::ExecState&, JSC::JSObject&, HTMLElement&, const AtomicString& eventType, JSC::JSValue);
+
+// Like the functions above, but for attributes that forward event handlers to the document rather than setting them on the target.
+JSC::JSValue documentEventHandlerAttribute(HTMLElement&, const AtomicString& eventType);
+void setDocumentEventHandlerAttribute(JSC::ExecState&, JSC::JSObject&, HTMLElement&, const AtomicString& eventType, JSC::JSValue);
 
 Ref<JSEventListener> createJSEventListenerForAdd(JSC::ExecState&, JSC::JSObject& listener, JSC::JSObject& wrapper);
 Ref<JSEventListener> createJSEventListenerForRemove(JSC::ExecState&, JSC::JSObject& listener, JSC::JSObject& wrapper);
index 73b26ec..f2d6690 100644 (file)
 // Protocols
 
 @protocol DOMEventListener <NSObject> 10_4
-- (void)handleEvent:(DOMEvent *)evt;
+- (void)handleEvent:(DOMEvent *)event;
 @end
 
 @protocol DOMEventTarget <NSObject, NSCopying> 10_4
index f88741c..c86362e 100644 (file)
@@ -237,9 +237,7 @@ sub SkipAttribute {
         return 1;
     }
 
-    if ($attribute->signature->type eq "EventListener") {
-        return 1;
-    }
+    return 1 if $attribute->signature->type eq "EventHandler";
 
     if ($attribute->signature->type eq "MediaQueryListListener") {
         return 1;
index 507fba0..e597271 100644 (file)
@@ -2286,8 +2286,10 @@ sub GenerateImplementation
                 $implIncludes{"JSDOMBinding.h"} = 1;
                 push(@implContent, "    auto& impl = castedThis->impl();\n");
                 push(@implContent, "    return JSValue::encode(shouldAllowAccessToNode(exec, impl." . $attribute->signature->name . "()) ? " . NativeToJSValue($attribute->signature, 0, $interfaceName, "impl.$implGetterFunctionName()", "castedThis") . " : jsNull());\n");
-            } elsif ($type eq "EventListener") {
-                my $getter = $attribute->signature->extendedAttributes->{"JSWindowEventListener"} ? "windowForwardedEventHandlerAttribute" : "eventHandlerAttribute";
+            } elsif ($type eq "EventHandler") {
+                my $getter = $attribute->signature->extendedAttributes->{"WindowEventHandler"} ? "windowEventHandlerAttribute"
+                    : $attribute->signature->extendedAttributes->{"DocumentEventHandler"} ? "documentEventHandlerAttribute"
+                    : "eventHandlerAttribute";
                 my $eventName = EventHandlerAttributeEventName($attribute);
                 push(@implContent, "    UNUSED_PARAM(exec);\n");
                 push(@implContent, "    return JSValue::encode($getter(castedThis->impl(), $eventName));\n");
@@ -2506,194 +2508,185 @@ sub GenerateImplementation
         }
     }
 
-    # Check if we have any writable attributes
-    my $hasReadWriteProperties = 0;
     foreach my $attribute (@{$interface->attributes}) {
-        $hasReadWriteProperties = 1 if !IsReadonly($attribute) && !$attribute->isStatic;
+        if (!IsReadonly($attribute)) {
+            my $name = $attribute->signature->name;
+            my $type = $attribute->signature->type;
+            my $putFunctionName = GetAttributeSetterName($interfaceName, $className, $attribute);
+            my $implSetterFunctionName = $codeGenerator->WK_ucfirst($name);
+            my $setterRaisesException = $attribute->signature->extendedAttributes->{"SetterRaisesException"};
 
-        if ($attribute->signature->type eq "EventListener") {
-            $implIncludes{"JSEventListener.h"} = 1;
-        }
-    }
+            my $attributeConditionalString = $codeGenerator->GenerateConditionalString($attribute->signature);
+            push(@implContent, "#if ${attributeConditionalString}\n") if $attributeConditionalString;
 
-    if ($hasReadWriteProperties) {
-        foreach my $attribute (@{$interface->attributes}) {
-            if (!IsReadonly($attribute)) {
-                my $name = $attribute->signature->name;
-                my $type = $attribute->signature->type;
-                my $putFunctionName = GetAttributeSetterName($interfaceName, $className, $attribute);
-                my $implSetterFunctionName = $codeGenerator->WK_ucfirst($name);
-                my $setterRaisesException = $attribute->signature->extendedAttributes->{"SetterRaisesException"};
-
-                my $attributeConditionalString = $codeGenerator->GenerateConditionalString($attribute->signature);
-                push(@implContent, "#if ${attributeConditionalString}\n") if $attributeConditionalString;
-
-                push(@implContent, "void ${putFunctionName}(ExecState* exec, JSObject* baseObject, EncodedJSValue");
-                push(@implContent, " thisValue") if !$attribute->isStatic;
-                push(@implContent, ", EncodedJSValue encodedValue)\n");
-                push(@implContent, "{\n");
-                push(@implContent, "    JSValue value = JSValue::decode(encodedValue);\n");
-                push(@implContent, "    UNUSED_PARAM(baseObject);\n");
-                if (!$attribute->isStatic) {
-                    if ($interface->extendedAttributes->{"CustomProxyToJSObject"}) {
-                        push(@implContent, "    ${className}* castedThis = to${className}(JSValue::decode(thisValue));\n");
-                    } elsif (AttributeShouldBeOnInstance($interface, $attribute)) {
-                        push(@implContent, "    UNUSED_PARAM(thisValue);\n");
-                        push(@implContent, "    auto* castedThis = jsCast<JS${interfaceName}*>(baseObject);\n");
-                        if (InterfaceRequiresAttributesOnInstanceForCompatibility($interface)) {
-                            push(@implContent, "    ${className}* castedThisObject = " . GetCastingHelperForThisObject($interface) . "(JSValue::decode(thisValue));\n");
-                            push(@implContent, "    if (UNLIKELY(!castedThisObject))\n");
-                            push(@implContent, "        reportDeprecatedSetterError(*exec, \"$interfaceName\", \"$name\");\n");
-                        } else {
-                            push(@implContent, "    UNUSED_PARAM(thisValue);\n");
-                            push(@implContent, "    UNUSED_PARAM(exec);\n");
-                        }
-                    } else {
-                        push(@implContent, "    ${className}* castedThis = " . GetCastingHelperForThisObject($interface) . "(JSValue::decode(thisValue));\n");
-                        push(@implContent, "    if (UNLIKELY(!castedThis)) {\n");
-                        push(@implContent, "        if (jsDynamicCast<${className}Prototype*>(JSValue::decode(thisValue)))\n");
-                        push(@implContent, "            reportDeprecatedSetterError(*exec, \"$interfaceName\", \"$name\");\n");
-                        push(@implContent, "        else\n");
-                        push(@implContent, "            throwSetterTypeError(*exec, \"$interfaceName\", \"$name\");\n");
-                        push(@implContent, "        return;\n");
-                        push(@implContent, "    }\n");
-                    }
-                }
-                if ($interface->extendedAttributes->{"CheckSecurity"} && !$attribute->signature->extendedAttributes->{"DoNotCheckSecurity"}) {
-                    if ($interfaceName eq "DOMWindow") {
-                        push(@implContent, "    if (!BindingSecurity::shouldAllowAccessToDOMWindow(exec, castedThis->impl()))\n");
+            push(@implContent, "void ${putFunctionName}(ExecState* exec, JSObject* baseObject, EncodedJSValue");
+            push(@implContent, " thisValue") if !$attribute->isStatic;
+            push(@implContent, ", EncodedJSValue encodedValue)\n");
+            push(@implContent, "{\n");
+            push(@implContent, "    JSValue value = JSValue::decode(encodedValue);\n");
+            push(@implContent, "    UNUSED_PARAM(baseObject);\n");
+            if (!$attribute->isStatic) {
+                if ($interface->extendedAttributes->{"CustomProxyToJSObject"}) {
+                    push(@implContent, "    ${className}* castedThis = to${className}(JSValue::decode(thisValue));\n");
+                } elsif (AttributeShouldBeOnInstance($interface, $attribute)) {
+                    push(@implContent, "    UNUSED_PARAM(thisValue);\n");
+                    push(@implContent, "    auto* castedThis = jsCast<JS${interfaceName}*>(baseObject);\n");
+                    if (InterfaceRequiresAttributesOnInstanceForCompatibility($interface)) {
+                        push(@implContent, "    ${className}* castedThisObject = " . GetCastingHelperForThisObject($interface) . "(JSValue::decode(thisValue));\n");
+                        push(@implContent, "    if (UNLIKELY(!castedThisObject))\n");
+                        push(@implContent, "        reportDeprecatedSetterError(*exec, \"$interfaceName\", \"$name\");\n");
                     } else {
-                        push(@implContent, "    if (!shouldAllowAccessToFrame(exec, castedThis->impl().frame()))\n");
+                        push(@implContent, "    UNUSED_PARAM(thisValue);\n");
+                        push(@implContent, "    UNUSED_PARAM(exec);\n");
                     }
+                } else {
+                    push(@implContent, "    ${className}* castedThis = " . GetCastingHelperForThisObject($interface) . "(JSValue::decode(thisValue));\n");
+                    push(@implContent, "    if (UNLIKELY(!castedThis)) {\n");
+                    push(@implContent, "        if (jsDynamicCast<${className}Prototype*>(JSValue::decode(thisValue)))\n");
+                    push(@implContent, "            reportDeprecatedSetterError(*exec, \"$interfaceName\", \"$name\");\n");
+                    push(@implContent, "        else\n");
+                    push(@implContent, "            throwSetterTypeError(*exec, \"$interfaceName\", \"$name\");\n");
                     push(@implContent, "        return;\n");
+                    push(@implContent, "    }\n");
                 }
+            }
+            if ($interface->extendedAttributes->{"CheckSecurity"} && !$attribute->signature->extendedAttributes->{"DoNotCheckSecurity"}) {
+                if ($interfaceName eq "DOMWindow") {
+                    push(@implContent, "    if (!BindingSecurity::shouldAllowAccessToDOMWindow(exec, castedThis->impl()))\n");
+                } else {
+                    push(@implContent, "    if (!shouldAllowAccessToFrame(exec, castedThis->impl().frame()))\n");
+                }
+                push(@implContent, "        return;\n");
+            }
 
-                if (HasCustomSetter($attribute->signature->extendedAttributes)) {
-                    push(@implContent, "    castedThis->set$implSetterFunctionName(exec, value);\n");
-                } elsif ($type eq "EventListener") {
-                    my $eventName = EventHandlerAttributeEventName($attribute);
-                    # FIXME: Find a way to do this special case without hardcoding the class and attribute names here.
-                    if ((($interfaceName eq "DOMWindow") or ($interfaceName eq "WorkerGlobalScope")) and $name eq "onerror") {
-                        $implIncludes{"JSErrorHandler.h"} = 1;
-                        push(@implContent, "    castedThis->impl().setAttributeEventListener($eventName, createJSErrorHandler(exec, value, castedThis));\n");
-                    } else {
-                        $implIncludes{"JSEventListener.h"} = 1;
-                        my $setter = $attribute->signature->extendedAttributes->{"JSWindowEventListener"} ? "setWindowForwardedEventHandlerAttribute" : "setEventHandlerAttribute";
-                        push(@implContent, "    $setter(*exec, *castedThis, castedThis->impl(), $eventName, value);\n");
-                    }
-                } elsif ($attribute->signature->type =~ /Constructor$/) {
-                    my $constructorType = $attribute->signature->type;
-                    $constructorType =~ s/Constructor$//;
-                    # $constructorType ~= /Constructor$/ indicates that it is NamedConstructor.
-                    # We do not generate the header file for NamedConstructor of class XXXX,
-                    # since we generate the NamedConstructor declaration into the header file of class XXXX.
-                    if ($constructorType ne "any" and $constructorType !~ /Named$/) {
-                        AddToImplIncludes("JS" . $constructorType . ".h", $attribute->signature->extendedAttributes->{"Conditional"});
-                    }
-                    push(@implContent, "    // Shadowing a built-in constructor.\n");
-                    push(@implContent, "    castedThis->putDirect(exec->vm(), Identifier(exec, \"$name\"), value);\n");
-                } elsif ($attribute->signature->extendedAttributes->{"Replaceable"}) {
-                    push(@implContent, "    // Shadowing a built-in object.\n");
-                    push(@implContent, "    castedThis->putDirect(exec->vm(), Identifier(exec, \"$name\"), value);\n");
+            if (HasCustomSetter($attribute->signature->extendedAttributes)) {
+                push(@implContent, "    castedThis->set$implSetterFunctionName(exec, value);\n");
+            } elsif ($type eq "EventHandler") {
+                $implIncludes{"JSEventListener.h"} = 1;
+                my $eventName = EventHandlerAttributeEventName($attribute);
+                # FIXME: Find a way to do this special case without hardcoding the class and attribute names here.
+                if ((($interfaceName eq "DOMWindow") or ($interfaceName eq "WorkerGlobalScope")) and $name eq "onerror") {
+                    $implIncludes{"JSErrorHandler.h"} = 1;
+                    push(@implContent, "    castedThis->impl().setAttributeEventListener($eventName, createJSErrorHandler(exec, value, castedThis));\n");
                 } else {
-                    if (!$attribute->isStatic) {
-                        push(@implContent, "    auto& impl = castedThis->impl();\n");
-                    }
-                    push(@implContent, "    ExceptionCode ec = 0;\n") if $setterRaisesException;
-
-                    # If the "StrictTypeChecking" extended attribute is present, and the attribute's type is an
-                    # interface type, then if the incoming value does not implement that interface, a TypeError
-                    # is thrown rather than silently passing NULL to the C++ code.
-                    # Per the Web IDL and ECMAScript specifications, incoming values can always be converted to
-                    # both strings and numbers, so do not throw TypeError if the attribute is of these types.
-                    if ($attribute->signature->extendedAttributes->{"StrictTypeChecking"}) {
-                        $implIncludes{"<runtime/Error.h>"} = 1;
-
-                        my $argType = $attribute->signature->type;
-                        if ($codeGenerator->IsWrapperType($argType)) {
-                            push(@implContent, "    if (!value.isUndefinedOrNull() && !value.inherits(JS${argType}::info())) {\n");
-                            push(@implContent, "        throwAttributeTypeError(*exec, \"$interfaceName\", \"$name\", \"$argType\");\n");
-                            push(@implContent, "        return;\n");
-                            push(@implContent, "    };\n");
-                        }
+                    $implIncludes{"JSEventListener.h"} = 1;
+                    my $setter = $attribute->signature->extendedAttributes->{"WindowEventHandler"} ? "setWindowEventHandlerAttribute"
+                        : $attribute->signature->extendedAttributes->{"DocumentEventHandler"} ? "setDocumentEventHandlerAttribute"
+                        : "setEventHandlerAttribute";
+                    push(@implContent, "    $setter(*exec, *castedThis, castedThis->impl(), $eventName, value);\n");
+                }
+            } elsif ($attribute->signature->type =~ /Constructor$/) {
+                my $constructorType = $attribute->signature->type;
+                $constructorType =~ s/Constructor$//;
+                # $constructorType ~= /Constructor$/ indicates that it is NamedConstructor.
+                # We do not generate the header file for NamedConstructor of class XXXX,
+                # since we generate the NamedConstructor declaration into the header file of class XXXX.
+                if ($constructorType ne "any" and $constructorType !~ /Named$/) {
+                    AddToImplIncludes("JS" . $constructorType . ".h", $attribute->signature->extendedAttributes->{"Conditional"});
+                }
+                push(@implContent, "    // Shadowing a built-in constructor.\n");
+                push(@implContent, "    castedThis->putDirect(exec->vm(), Identifier(exec, \"$name\"), value);\n");
+            } elsif ($attribute->signature->extendedAttributes->{"Replaceable"}) {
+                push(@implContent, "    // Shadowing a built-in object.\n");
+                push(@implContent, "    castedThis->putDirect(exec->vm(), Identifier(exec, \"$name\"), value);\n");
+            } else {
+                if (!$attribute->isStatic) {
+                    push(@implContent, "    auto& impl = castedThis->impl();\n");
+                }
+                push(@implContent, "    ExceptionCode ec = 0;\n") if $setterRaisesException;
+
+                # If the "StrictTypeChecking" extended attribute is present, and the attribute's type is an
+                # interface type, then if the incoming value does not implement that interface, a TypeError
+                # is thrown rather than silently passing NULL to the C++ code.
+                # Per the Web IDL and ECMAScript specifications, incoming values can always be converted to
+                # both strings and numbers, so do not throw TypeError if the attribute is of these types.
+                if ($attribute->signature->extendedAttributes->{"StrictTypeChecking"}) {
+                    $implIncludes{"<runtime/Error.h>"} = 1;
+
+                    my $argType = $attribute->signature->type;
+                    if ($codeGenerator->IsWrapperType($argType)) {
+                        push(@implContent, "    if (!value.isUndefinedOrNull() && !value.inherits(JS${argType}::info())) {\n");
+                        push(@implContent, "        throwAttributeTypeError(*exec, \"$interfaceName\", \"$name\", \"$argType\");\n");
+                        push(@implContent, "        return;\n");
+                        push(@implContent, "    };\n");
                     }
+                }
 
-                    push(@implContent, "    " . GetNativeTypeFromSignature($attribute->signature) . " nativeValue(" . JSValueToNative($attribute->signature, "value", $attribute->signature->extendedAttributes->{"Conditional"}) . ");\n");
-                    push(@implContent, "    if (UNLIKELY(exec->hadException()))\n");
-                    push(@implContent, "        return;\n");
+                push(@implContent, "    " . GetNativeTypeFromSignature($attribute->signature) . " nativeValue(" . JSValueToNative($attribute->signature, "value", $attribute->signature->extendedAttributes->{"Conditional"}) . ");\n");
+                push(@implContent, "    if (UNLIKELY(exec->hadException()))\n");
+                push(@implContent, "        return;\n");
 
-                    if ($codeGenerator->IsEnumType($type)) {
-                        my @enumValues = $codeGenerator->ValidEnumValues($type);
-                        my @enumChecks = ();
-                        foreach my $enumValue (@enumValues) {
-                            push(@enumChecks, "nativeValue != \"$enumValue\"");
-                        }
-                        push (@implContent, "    if (" . join(" && ", @enumChecks) . ")\n");
-                        push (@implContent, "        return;\n");
+                if ($codeGenerator->IsEnumType($type)) {
+                    my @enumValues = $codeGenerator->ValidEnumValues($type);
+                    my @enumChecks = ();
+                    foreach my $enumValue (@enumValues) {
+                        push(@enumChecks, "nativeValue != \"$enumValue\"");
                     }
+                    push (@implContent, "    if (" . join(" && ", @enumChecks) . ")\n");
+                    push (@implContent, "        return;\n");
+                }
+
+                if ($attribute->signature->type eq "double" or $attribute->signature->type eq "float") {
+                    push(@implContent, "    if (!std::isfinite(nativeValue)) {\n");
+                    push(@implContent, "        setDOMException(exec, TypeError);\n");
+                    push(@implContent, "        return;\n");
+                    push(@implContent, "    }\n");
+                }
 
-                    if ($attribute->signature->type eq "double" or $attribute->signature->type eq "float") {
-                        push(@implContent, "    if (!std::isfinite(nativeValue)) {\n");
-                        push(@implContent, "        setDOMException(exec, TypeError);\n");
+                if ($svgPropertyOrListPropertyType) {
+                    if ($svgPropertyType) {
+                        push(@implContent, "    if (impl.isReadOnly()) {\n");
+                        push(@implContent, "        setDOMException(exec, NO_MODIFICATION_ALLOWED_ERR);\n");
                         push(@implContent, "        return;\n");
                         push(@implContent, "    }\n");
+                        $implIncludes{"ExceptionCode.h"} = 1;
                     }
-
-                    if ($svgPropertyOrListPropertyType) {
-                        if ($svgPropertyType) {
-                            push(@implContent, "    if (impl.isReadOnly()) {\n");
-                            push(@implContent, "        setDOMException(exec, NO_MODIFICATION_ALLOWED_ERR);\n");
-                            push(@implContent, "        return;\n");
-                            push(@implContent, "    }\n");
-                            $implIncludes{"ExceptionCode.h"} = 1;
-                        }
-                        push(@implContent, "    $svgPropertyOrListPropertyType& podImpl = impl.propertyReference();\n");
-                        if ($svgPropertyOrListPropertyType eq "float") { # Special case for JSSVGNumber
-                            push(@implContent, "    podImpl = nativeValue;\n");
-                        } else {
-                            push(@implContent, "    podImpl.set$implSetterFunctionName(nativeValue");
-                            push(@implContent, ", ec") if $setterRaisesException;
-                            push(@implContent, ");\n");
-                            push(@implContent, "    setDOMException(exec, ec);\n") if $setterRaisesException;
-                        }
-                        if ($svgPropertyType) {
-                            if ($setterRaisesException) {
-                                push(@implContent, "    if (!ec)\n");
-                                push(@implContent, "        impl.commitChange();\n");
-                            } else {
-                                push(@implContent, "    impl.commitChange();\n");
-                            }
-                        }
+                    push(@implContent, "    $svgPropertyOrListPropertyType& podImpl = impl.propertyReference();\n");
+                    if ($svgPropertyOrListPropertyType eq "float") { # Special case for JSSVGNumber
+                        push(@implContent, "    podImpl = nativeValue;\n");
                     } else {
-                        my ($functionName, @arguments) = $codeGenerator->SetterExpression(\%implIncludes, $interfaceName, $attribute);
-                        if ($codeGenerator->IsTypedArrayType($attribute->signature->type) and not $attribute->signature->type eq "ArrayBuffer") {
-                            push(@arguments, "nativeValue.get()");
-                        } else {
-                            push(@arguments, "nativeValue");
-                        }
-                        if ($attribute->signature->extendedAttributes->{"ImplementedBy"}) {
-                            my $implementedBy = $attribute->signature->extendedAttributes->{"ImplementedBy"};
-                            AddToImplIncludes("${implementedBy}.h", $attribute->signature->extendedAttributes->{"Conditional"});
-                            unshift(@arguments, "&impl") if !$attribute->isStatic;
-                            $functionName = "${implementedBy}::${functionName}";
-                        } elsif ($attribute->isStatic) {
-                            $functionName = "${interfaceName}::${functionName}";
+                        push(@implContent, "    podImpl.set$implSetterFunctionName(nativeValue");
+                        push(@implContent, ", ec") if $setterRaisesException;
+                        push(@implContent, ");\n");
+                        push(@implContent, "    setDOMException(exec, ec);\n") if $setterRaisesException;
+                    }
+                    if ($svgPropertyType) {
+                        if ($setterRaisesException) {
+                            push(@implContent, "    if (!ec)\n");
+                            push(@implContent, "        impl.commitChange();\n");
                         } else {
-                            $functionName = "impl.${functionName}";
+                            push(@implContent, "    impl.commitChange();\n");
                         }
+                    }
+                } else {
+                    my ($functionName, @arguments) = $codeGenerator->SetterExpression(\%implIncludes, $interfaceName, $attribute);
+                    if ($codeGenerator->IsTypedArrayType($attribute->signature->type) and not $attribute->signature->type eq "ArrayBuffer") {
+                        push(@arguments, "nativeValue.get()");
+                    } else {
+                        push(@arguments, "nativeValue");
+                    }
+                    if ($attribute->signature->extendedAttributes->{"ImplementedBy"}) {
+                        my $implementedBy = $attribute->signature->extendedAttributes->{"ImplementedBy"};
+                        AddToImplIncludes("${implementedBy}.h", $attribute->signature->extendedAttributes->{"Conditional"});
+                        unshift(@arguments, "&impl") if !$attribute->isStatic;
+                        $functionName = "${implementedBy}::${functionName}";
+                    } elsif ($attribute->isStatic) {
+                        $functionName = "${interfaceName}::${functionName}";
+                    } else {
+                        $functionName = "impl.${functionName}";
+                    }
 
-                        unshift(@arguments, GenerateCallWith($attribute->signature->extendedAttributes->{"CallWith"}, \@implContent, ""));
+                    unshift(@arguments, GenerateCallWith($attribute->signature->extendedAttributes->{"CallWith"}, \@implContent, ""));
 
-                        push(@arguments, "ec") if $setterRaisesException;
-                        push(@implContent, "    ${functionName}(" . join(", ", @arguments) . ");\n");
-                        push(@implContent, "    setDOMException(exec, ec);\n") if $setterRaisesException;
-                    }
+                    push(@arguments, "ec") if $setterRaisesException;
+                    push(@implContent, "    ${functionName}(" . join(", ", @arguments) . ");\n");
+                    push(@implContent, "    setDOMException(exec, ec);\n") if $setterRaisesException;
                 }
-
-                push(@implContent, "}\n\n");
-                push(@implContent, "#endif\n") if $attributeConditionalString;
-                push(@implContent, "\n");
             }
+
+            push(@implContent, "}\n\n");
+            push(@implContent, "#endif\n") if $attributeConditionalString;
+            push(@implContent, "\n");
         }
     }
 
index 6b6ad4a..e59fc1b 100644 (file)
@@ -555,7 +555,7 @@ sub SkipAttribute
     return 1 if $codeGenerator->GetArrayType($type);
     return 1 if $codeGenerator->IsTypedArrayType($type);
     return 1 if $codeGenerator->IsEnumType($type);
-    return 1 if $type eq "EventListener";
+    return 1 if $type eq "EventHandler";
     return 1 if $attribute->isStatic;
 
     # This is for DynamicsCompressorNode.idl.
index 5632d31..7badb13 100644 (file)
@@ -55,6 +55,7 @@ DoNotCheckConstants
 DoNotCheckSecurity
 DoNotCheckSecurityOnGetter
 DoNotCheckSecurityOnSetter
+DocumentEventHandler
 EnabledAtRuntime=*
 EnabledBySetting=*
 EnforceRange
@@ -82,7 +83,6 @@ JSCustomToNativeObject
 JSGenerateToJSObject
 JSGenerateToNativeObject
 JSLegacyParent=*
-JSWindowEventListener
 MasqueradesAsUndefined
 NamedConstructor=*
 NewImpurePropertyFiresWatchpoints
@@ -115,6 +115,7 @@ TreatReturnedNullStringAs=Null|Undefined
 TreatUndefinedAs=NullString
 TypedArray=*
 URL
+WindowEventHandler
 
 # PLATFORM(IOS)
 AppleCopyright
index 931c037..e92775a 100644 (file)
@@ -111,7 +111,7 @@ enum _optional { "", "OptionalValue1", "OptionalValue2", "OptionalValue3" };
 
     void addEventListener(DOMString type, EventListener listener, optional boolean useCapture);
     void removeEventListener(DOMString type, EventListener listener, optional boolean useCapture);
-    attribute EventListener onfoo;
+    attribute EventHandler onfoo;
 
     // 'CallWith' extended attribute
     [CallWith=ScriptState] void withScriptStateVoid();
index a8190b8..18649cf 100644 (file)
     GenerateIsReachable=ImplDocument,
 ] interface FontLoader {
 
-    attribute EventListener onloading;
-    attribute EventListener onloadingdone;
-    attribute EventListener onloadstart;
-    attribute EventListener onload;
-    attribute EventListener onerror;
+    attribute EventHandler onloading;
+    attribute EventHandler onloadingdone;
+    attribute EventHandler onloadstart;
+    attribute EventHandler onload;
+    attribute EventHandler onerror;
 
     boolean checkFont(DOMString font, [Default=NullString] optional DOMString text);
     void loadFont(Dictionary params);
     void notifyWhenFontsReady(VoidCallback callback);
     readonly attribute boolean loading;
 
-    void addEventListener(DOMString type,
-                          EventListener listener,
-                          optional boolean useCapture);
-    void removeEventListener(DOMString type,
-                             EventListener listener,
-                             optional boolean useCapture);
-    [RaisesException] boolean dispatchEvent(Event evt);
+    void addEventListener(DOMString type, EventListener listener, optional boolean useCapture);
+    void removeEventListener(DOMString type, EventListener listener, optional boolean useCapture);
+    [RaisesException] boolean dispatchEvent(Event event);
 };
index 3ad88bb..2b658e5 100644 (file)
     [Conditional=FONT_LOAD_EVENTS] readonly attribute FontLoader fonts;
 #endif
 
-    [NotEnumerable] attribute EventListener onabort;
-    [NotEnumerable] attribute EventListener onbeforecopy;
-    [NotEnumerable] attribute EventListener onbeforecut;
-    [NotEnumerable] attribute EventListener onbeforepaste;
-    [NotEnumerable] attribute EventListener onblur;
-    [NotEnumerable] attribute EventListener onchange;
-    [NotEnumerable] attribute EventListener onclick;
-    [NotEnumerable] attribute EventListener oncontextmenu;
-    [NotEnumerable] attribute EventListener oncopy;
-    [NotEnumerable] attribute EventListener oncut;
-    [NotEnumerable] attribute EventListener ondblclick;
-    [NotEnumerable] attribute EventListener ondrag;
-    [NotEnumerable] attribute EventListener ondragend;
-    [NotEnumerable] attribute EventListener ondragenter;
-    [NotEnumerable] attribute EventListener ondragleave;
-    [NotEnumerable] attribute EventListener ondragover;
-    [NotEnumerable] attribute EventListener ondragstart;
-    [NotEnumerable] attribute EventListener ondrop;
-    [NotEnumerable] attribute EventListener onerror;
-    [NotEnumerable] attribute EventListener onfocus;
-    [NotEnumerable] attribute EventListener oninput;
-    [NotEnumerable] attribute EventListener oninvalid;
-    [NotEnumerable] attribute EventListener onkeydown;
-    [NotEnumerable] attribute EventListener onkeypress;
-    [NotEnumerable] attribute EventListener onkeyup;
-    [NotEnumerable] attribute EventListener onload;
-    [NotEnumerable] attribute EventListener onmousedown;
-    [NotEnumerable] attribute EventListener onmouseenter;
-    [NotEnumerable] attribute EventListener onmouseleave;
-    [NotEnumerable] attribute EventListener onmousemove;
-    [NotEnumerable] attribute EventListener onmouseout;
-    [NotEnumerable] attribute EventListener onmouseover;
-    [NotEnumerable] attribute EventListener onmouseup;
-    [NotEnumerable] attribute EventListener onmousewheel;
-    [NotEnumerable] attribute EventListener onpaste;
-    [NotEnumerable] attribute EventListener onreadystatechange;
-    [NotEnumerable] attribute EventListener onreset;
-    [NotEnumerable] attribute EventListener onscroll;
-    [NotEnumerable] attribute EventListener onsearch;
-    [NotEnumerable] attribute EventListener onselect;
-    [NotEnumerable] attribute EventListener onselectionchange;
-    [NotEnumerable] attribute EventListener onselectstart;
-    [NotEnumerable] attribute EventListener onsubmit;
-    [NotEnumerable] attribute EventListener onwheel;
-
-    [NotEnumerable, Conditional=CSP_NEXT] attribute EventListener onsecuritypolicyviolation;
-
-    [NotEnumerable, Conditional=FULLSCREEN_API] attribute EventListener onwebkitfullscreenchange;
-    [NotEnumerable, Conditional=FULLSCREEN_API] attribute EventListener onwebkitfullscreenerror;
-
-    [NotEnumerable, Conditional=POINTER_LOCK] attribute EventListener onpointerlockchange;
-    [NotEnumerable, Conditional=POINTER_LOCK] attribute EventListener onpointerlockerror;
-
-    [NotEnumerable, Conditional=TOUCH_EVENTS] attribute EventListener ontouchstart;
-    [NotEnumerable, Conditional=TOUCH_EVENTS] attribute EventListener ontouchmove;
-    [NotEnumerable, Conditional=TOUCH_EVENTS] attribute EventListener ontouchend;
-    [NotEnumerable, Conditional=TOUCH_EVENTS] attribute EventListener ontouchcancel;
-
-    [NotEnumerable, Conditional=WILL_REVEAL_EDGE_EVENTS] attribute EventListener onwebkitwillrevealbottom;
-    [NotEnumerable, Conditional=WILL_REVEAL_EDGE_EVENTS] attribute EventListener onwebkitwillrevealleft;
-    [NotEnumerable, Conditional=WILL_REVEAL_EDGE_EVENTS] attribute EventListener onwebkitwillrevealright;
-    [NotEnumerable, Conditional=WILL_REVEAL_EDGE_EVENTS] attribute EventListener onwebkitwillrevealtop;
+    [NotEnumerable] attribute EventHandler onabort;
+    [NotEnumerable] attribute EventHandler onbeforecopy;
+    [NotEnumerable] attribute EventHandler onbeforecut;
+    [NotEnumerable] attribute EventHandler onbeforepaste;
+    [NotEnumerable] attribute EventHandler onblur;
+    [NotEnumerable] attribute EventHandler onchange;
+    [NotEnumerable] attribute EventHandler onclick;
+    [NotEnumerable] attribute EventHandler oncontextmenu;
+    [NotEnumerable] attribute EventHandler oncopy;
+    [NotEnumerable] attribute EventHandler oncut;
+    [NotEnumerable] attribute EventHandler ondblclick;
+    [NotEnumerable] attribute EventHandler ondrag;
+    [NotEnumerable] attribute EventHandler ondragend;
+    [NotEnumerable] attribute EventHandler ondragenter;
+    [NotEnumerable] attribute EventHandler ondragleave;
+    [NotEnumerable] attribute EventHandler ondragover;
+    [NotEnumerable] attribute EventHandler ondragstart;
+    [NotEnumerable] attribute EventHandler ondrop;
+    [NotEnumerable] attribute EventHandler onerror;
+    [NotEnumerable] attribute EventHandler onfocus;
+    [NotEnumerable] attribute EventHandler oninput;
+    [NotEnumerable] attribute EventHandler oninvalid;
+    [NotEnumerable] attribute EventHandler onkeydown;
+    [NotEnumerable] attribute EventHandler onkeypress;
+    [NotEnumerable] attribute EventHandler onkeyup;
+    [NotEnumerable] attribute EventHandler onload;
+    [NotEnumerable] attribute EventHandler onmousedown;
+    [NotEnumerable] attribute EventHandler onmouseenter;
+    [NotEnumerable] attribute EventHandler onmouseleave;
+    [NotEnumerable] attribute EventHandler onmousemove;
+    [NotEnumerable] attribute EventHandler onmouseout;
+    [NotEnumerable] attribute EventHandler onmouseover;
+    [NotEnumerable] attribute EventHandler onmouseup;
+    [NotEnumerable] attribute EventHandler onmousewheel;
+    [NotEnumerable] attribute EventHandler onpaste;
+    [NotEnumerable] attribute EventHandler onpointerlockchange;
+    [NotEnumerable] attribute EventHandler onpointerlockerror;
+    [NotEnumerable] attribute EventHandler onreadystatechange;
+    [NotEnumerable] attribute EventHandler onreset;
+    [NotEnumerable] attribute EventHandler onscroll;
+    [NotEnumerable] attribute EventHandler onsearch;
+    [NotEnumerable] attribute EventHandler onsecuritypolicyviolation;
+    [NotEnumerable] attribute EventHandler onselect;
+    [NotEnumerable] attribute EventHandler onselectionchange;
+    [NotEnumerable] attribute EventHandler onselectstart;
+    [NotEnumerable] attribute EventHandler onsubmit;
+    [NotEnumerable] attribute EventHandler ontouchcancel;
+    [NotEnumerable] attribute EventHandler ontouchend;
+    [NotEnumerable] attribute EventHandler ontouchmove;
+    [NotEnumerable] attribute EventHandler ontouchstart;
+    [NotEnumerable] attribute EventHandler onwebkitfullscreenchange;
+    [NotEnumerable] attribute EventHandler onwebkitfullscreenerror;
+    [NotEnumerable] attribute EventHandler onwebkitwillrevealbottom;
+    [NotEnumerable] attribute EventHandler onwebkitwillrevealleft;
+    [NotEnumerable] attribute EventHandler onwebkitwillrevealright;
+    [NotEnumerable] attribute EventHandler onwebkitwillrevealtop;
+    [NotEnumerable] attribute EventHandler onwheel;
 
 #if defined(ENABLE_IOS_TOUCH_EVENTS) && ENABLE_IOS_TOUCH_EVENTS
 #include <WebKitAdditions/DocumentIOS.idl>
index f3561ed..d46f982 100644 (file)
     // But we don't want to copy and paste this entire list; we can leave on Element
     // for the moment since it doesn't do much real harm.
 
-    [NotEnumerable] attribute EventListener onabort;
-    [NotEnumerable] attribute EventListener onanimationend;
-    [NotEnumerable] attribute EventListener onanimationiteration;
-    [NotEnumerable] attribute EventListener onanimationstart;
-    [NotEnumerable] attribute EventListener onbeforecopy;
-    [NotEnumerable] attribute EventListener onbeforecut;
-    [NotEnumerable] attribute EventListener onbeforeload;
-    [NotEnumerable] attribute EventListener onbeforepaste;
-    [NotEnumerable] attribute EventListener onblur;
-    [NotEnumerable] attribute EventListener oncanplay;
-    [NotEnumerable] attribute EventListener oncanplaythrough;
-    [NotEnumerable] attribute EventListener onchange;
-    [NotEnumerable] attribute EventListener onclick;
-    [NotEnumerable] attribute EventListener oncontextmenu;
-    [NotEnumerable] attribute EventListener oncopy;
-    [NotEnumerable] attribute EventListener oncut;
-    [NotEnumerable] attribute EventListener ondblclick;
-    [NotEnumerable] attribute EventListener ondrag;
-    [NotEnumerable] attribute EventListener ondragend;
-    [NotEnumerable] attribute EventListener ondragenter;
-    [NotEnumerable] attribute EventListener ondragleave;
-    [NotEnumerable] attribute EventListener ondragover;
-    [NotEnumerable] attribute EventListener ondragstart;
-    [NotEnumerable] attribute EventListener ondrop;
-    [NotEnumerable] attribute EventListener ondurationchange;
-    [NotEnumerable] attribute EventListener onemptied;
-    [NotEnumerable] attribute EventListener onended;
-    [NotEnumerable] attribute EventListener onerror;
-    [NotEnumerable] attribute EventListener onfocus;
-    [NotEnumerable] attribute EventListener onfocusin;
-    [NotEnumerable] attribute EventListener onfocusout;
-    [NotEnumerable] attribute EventListener oninput;
-    [NotEnumerable] attribute EventListener oninvalid;
-    [NotEnumerable] attribute EventListener onkeydown;
-    [NotEnumerable] attribute EventListener onkeypress;
-    [NotEnumerable] attribute EventListener onkeyup;
-    [NotEnumerable] attribute EventListener onload;
-    [NotEnumerable] attribute EventListener onloadeddata;
-    [NotEnumerable] attribute EventListener onloadedmetadata;
-    [NotEnumerable] attribute EventListener onloadstart;
-    [NotEnumerable] attribute EventListener onmousedown;
-    [NotEnumerable] attribute EventListener onmouseenter;
-    [NotEnumerable] attribute EventListener onmouseleave;
-    [NotEnumerable] attribute EventListener onmousemove;
-    [NotEnumerable] attribute EventListener onmouseout;
-    [NotEnumerable] attribute EventListener onmouseover;
-    [NotEnumerable] attribute EventListener onmouseup;
-    [NotEnumerable] attribute EventListener onmousewheel;
-    [NotEnumerable] attribute EventListener onpaste;
-    [NotEnumerable] attribute EventListener onpause;
-    [NotEnumerable] attribute EventListener onplay;
-    [NotEnumerable] attribute EventListener onplaying;
-    [NotEnumerable] attribute EventListener onprogress;
-    [NotEnumerable] attribute EventListener onratechange;
-    [NotEnumerable] attribute EventListener onreset;
-    [NotEnumerable] attribute EventListener onscroll;
-    [NotEnumerable] attribute EventListener onsearch;
-    [NotEnumerable] attribute EventListener onseeked;
-    [NotEnumerable] attribute EventListener onseeking;
-    [NotEnumerable] attribute EventListener onselect;
-    [NotEnumerable] attribute EventListener onselectstart;
-    [NotEnumerable] attribute EventListener onstalled;
-    [NotEnumerable] attribute EventListener onsubmit;
-    [NotEnumerable] attribute EventListener onsuspend;
-    [NotEnumerable] attribute EventListener ontimeupdate;
-    [NotEnumerable] attribute EventListener ontouchcancel;
-    [NotEnumerable] attribute EventListener ontouchend;
-    [NotEnumerable] attribute EventListener ontouchmove;
-    [NotEnumerable] attribute EventListener ontouchstart;
-    [NotEnumerable] attribute EventListener ontransitionend;
-    [NotEnumerable] attribute EventListener onvolumechange;
-    [NotEnumerable] attribute EventListener onwaiting;
-    [NotEnumerable] attribute EventListener onwheel;
-
-    // FIXME: If event handler attributes are all not enumerable, is there really a need to have them be conditional?
-    // I suggest just including them all unconditionally even if the event in question won't ever be sent.
-
-    [NotEnumerable, Conditional=ENCRYPTED_MEDIA] attribute EventListener onwebkitkeyadded;
-    [NotEnumerable, Conditional=ENCRYPTED_MEDIA] attribute EventListener onwebkitkeyerror;
-    [NotEnumerable, Conditional=ENCRYPTED_MEDIA] attribute EventListener onwebkitkeymessage;
-
-    [NotEnumerable, Conditional=ENCRYPTED_MEDIA|ENCRYPTED_MEDIA_V2] attribute EventListener onwebkitneedkey;
-
-    [NotEnumerable, Conditional=FULLSCREEN_API] attribute EventListener onwebkitfullscreenchange;
-    [NotEnumerable, Conditional=FULLSCREEN_API] attribute EventListener onwebkitfullscreenerror;
-
-    [NotEnumerable, Conditional=REQUEST_AUTOCOMPLETE] attribute EventListener onautocomplete;
-    [NotEnumerable, Conditional=REQUEST_AUTOCOMPLETE] attribute EventListener onautocompleteerror;
-
-    [NotEnumerable, Conditional=VIDEO_PRESENTATION_MODE] attribute EventListener onwebkitpresentationmodechanged;
-
-    [NotEnumerable, Conditional=WILL_REVEAL_EDGE_EVENTS] attribute EventListener onwebkitwillrevealbottom;
-    [NotEnumerable, Conditional=WILL_REVEAL_EDGE_EVENTS] attribute EventListener onwebkitwillrevealleft;
-    [NotEnumerable, Conditional=WILL_REVEAL_EDGE_EVENTS] attribute EventListener onwebkitwillrevealright;
-    [NotEnumerable, Conditional=WILL_REVEAL_EDGE_EVENTS] attribute EventListener onwebkitwillrevealtop;
-
-    [NotEnumerable, Conditional=WIRELESS_PLAYBACK_TARGET] attribute EventListener onwebkitcurrentplaybacktargetiswirelesschanged;
-    [NotEnumerable, Conditional=WIRELESS_PLAYBACK_TARGET] attribute EventListener onwebkitplaybacktargetavailabilitychanged;
+    [NotEnumerable] attribute EventHandler onabort;
+    [NotEnumerable] attribute EventHandler onanimationend;
+    [NotEnumerable] attribute EventHandler onanimationiteration;
+    [NotEnumerable] attribute EventHandler onanimationstart;
+    [NotEnumerable] attribute EventHandler onautocomplete;
+    [NotEnumerable] attribute EventHandler onautocompleteerror;
+    [NotEnumerable] attribute EventHandler onbeforecopy;
+    [NotEnumerable] attribute EventHandler onbeforecut;
+    [NotEnumerable] attribute EventHandler onbeforeload;
+    [NotEnumerable] attribute EventHandler onbeforepaste;
+    [NotEnumerable] attribute EventHandler onblur;
+    [NotEnumerable] attribute EventHandler oncanplay;
+    [NotEnumerable] attribute EventHandler oncanplaythrough;
+    [NotEnumerable] attribute EventHandler onchange;
+    [NotEnumerable] attribute EventHandler onclick;
+    [NotEnumerable] attribute EventHandler oncontextmenu;
+    [NotEnumerable] attribute EventHandler oncopy;
+    [NotEnumerable] attribute EventHandler oncut;
+    [NotEnumerable] attribute EventHandler ondblclick;
+    [NotEnumerable] attribute EventHandler ondrag;
+    [NotEnumerable] attribute EventHandler ondragend;
+    [NotEnumerable] attribute EventHandler ondragenter;
+    [NotEnumerable] attribute EventHandler ondragleave;
+    [NotEnumerable] attribute EventHandler ondragover;
+    [NotEnumerable] attribute EventHandler ondragstart;
+    [NotEnumerable] attribute EventHandler ondrop;
+    [NotEnumerable] attribute EventHandler ondurationchange;
+    [NotEnumerable] attribute EventHandler onemptied;
+    [NotEnumerable] attribute EventHandler onended;
+    [NotEnumerable] attribute EventHandler onerror;
+    [NotEnumerable] attribute EventHandler onfocus;
+    [NotEnumerable] attribute EventHandler onfocusin;
+    [NotEnumerable] attribute EventHandler onfocusout;
+    [NotEnumerable] attribute EventHandler ongesturechange;
+    [NotEnumerable] attribute EventHandler ongestureend;
+    [NotEnumerable] attribute EventHandler ongesturestart;
+    [NotEnumerable] attribute EventHandler oninput;
+    [NotEnumerable] attribute EventHandler oninvalid;
+    [NotEnumerable] attribute EventHandler onkeydown;
+    [NotEnumerable] attribute EventHandler onkeypress;
+    [NotEnumerable] attribute EventHandler onkeyup;
+    [NotEnumerable] attribute EventHandler onload;
+    [NotEnumerable] attribute EventHandler onloadeddata;
+    [NotEnumerable] attribute EventHandler onloadedmetadata;
+    [NotEnumerable] attribute EventHandler onloadstart;
+    [NotEnumerable] attribute EventHandler onmousedown;
+    [NotEnumerable] attribute EventHandler onmouseenter;
+    [NotEnumerable] attribute EventHandler onmouseleave;
+    [NotEnumerable] attribute EventHandler onmousemove;
+    [NotEnumerable] attribute EventHandler onmouseout;
+    [NotEnumerable] attribute EventHandler onmouseover;
+    [NotEnumerable] attribute EventHandler onmouseup;
+    [NotEnumerable] attribute EventHandler onmousewheel;
+    [NotEnumerable] attribute EventHandler onpaste;
+    [NotEnumerable] attribute EventHandler onpause;
+    [NotEnumerable] attribute EventHandler onplay;
+    [NotEnumerable] attribute EventHandler onplaying;
+    [NotEnumerable] attribute EventHandler onprogress;
+    [NotEnumerable] attribute EventHandler onratechange;
+    [NotEnumerable] attribute EventHandler onreset;
+    [NotEnumerable] attribute EventHandler onscroll;
+    [NotEnumerable] attribute EventHandler onsearch;
+    [NotEnumerable] attribute EventHandler onseeked;
+    [NotEnumerable] attribute EventHandler onseeking;
+    [NotEnumerable] attribute EventHandler onselect;
+    [NotEnumerable] attribute EventHandler onselectstart;
+    [NotEnumerable] attribute EventHandler onstalled;
+    [NotEnumerable] attribute EventHandler onsubmit;
+    [NotEnumerable] attribute EventHandler onsuspend;
+    [NotEnumerable] attribute EventHandler ontimeupdate;
+    [NotEnumerable] attribute EventHandler ontouchcancel;
+    [NotEnumerable] attribute EventHandler ontouchend;
+    [NotEnumerable] attribute EventHandler ontouchmove;
+    [NotEnumerable] attribute EventHandler ontouchstart;
+    [NotEnumerable] attribute EventHandler ontransitionend;
+    [NotEnumerable] attribute EventHandler onvolumechange;
+    [NotEnumerable] attribute EventHandler onwaiting;
+    [NotEnumerable] attribute EventHandler onwebkitanimationend;
+    [NotEnumerable] attribute EventHandler onwebkitanimationiteration;
+    [NotEnumerable] attribute EventHandler onwebkitanimationstart;
+    [NotEnumerable] attribute EventHandler onwebkitcurrentplaybacktargetiswirelesschanged;
+    [NotEnumerable] attribute EventHandler onwebkitfullscreenchange;
+    [NotEnumerable] attribute EventHandler onwebkitfullscreenerror;
+    [NotEnumerable] attribute EventHandler onwebkitkeyadded;
+    [NotEnumerable] attribute EventHandler onwebkitkeyerror;
+    [NotEnumerable] attribute EventHandler onwebkitkeymessage;
+    [NotEnumerable] attribute EventHandler onwebkitneedkey;
+    [NotEnumerable] attribute EventHandler onwebkitplaybacktargetavailabilitychanged;
+    [NotEnumerable] attribute EventHandler onwebkitpresentationmodechanged;
+    [NotEnumerable] attribute EventHandler onwebkittransitionend;
+    [NotEnumerable] attribute EventHandler onwebkitwillrevealbottom;
+    [NotEnumerable] attribute EventHandler onwebkitwillrevealleft;
+    [NotEnumerable] attribute EventHandler onwebkitwillrevealright;
+    [NotEnumerable] attribute EventHandler onwebkitwillrevealtop;
+    [NotEnumerable] attribute EventHandler onwheel;
 };
 
 Element implements ChildNode;
index 6caa25e..841e24e 100644 (file)
@@ -24,6 +24,5 @@
     ObjCProtocol,
     CPPPureInterface,
 ] interface EventListener {
-    void               handleEvent(Event evt);
+    void handleEvent(Event event);
 };
-
index 5d9a3e5..1ffb16c 100644 (file)
     JSCustomToNativeObject,
     EventTarget,
 ] interface EventTarget {
-    [ObjCLegacyUnnamedParameters] void addEventListener(DOMString type, 
-                                         EventListener listener, 
-                                         optional boolean useCapture);
-    [ObjCLegacyUnnamedParameters] void removeEventListener(DOMString type, 
-                                            EventListener listener, 
-                                            optional boolean useCapture);
+    [ObjCLegacyUnnamedParameters] void addEventListener(DOMString type, EventListener listener, optional boolean useCapture);
+    [ObjCLegacyUnnamedParameters] void removeEventListener(DOMString type, EventListener listener, optional boolean useCapture);
     [RaisesException] boolean dispatchEvent(Event event);
 };
-
index d8e9055..2f4d739 100644 (file)
     void start();
     void close();
 
-    // event handler attributes
-    attribute EventListener onmessage;
+    attribute EventHandler onmessage;
 
     // EventTarget interface
-    void addEventListener(DOMString type, 
-                          EventListener listener, 
-                          optional boolean useCapture);
-    void removeEventListener(DOMString type, 
-                             EventListener listener, 
-                             optional boolean useCapture);
-    [RaisesException] boolean dispatchEvent(Event evt);
+    void addEventListener(DOMString type, EventListener listener, optional boolean useCapture);
+    void removeEventListener(DOMString type, EventListener listener, optional boolean useCapture);
+    [RaisesException] boolean dispatchEvent(Event event);
 #endif
 };
 
index efb5f71..ed4d405 100644 (file)
     readonly attribute boolean          isContentEditable;
 
     void inspect();
-#endif /* defined(LANGUAGE_OBJECTIVE_C) */
+#endif
 
 #if !defined(LANGUAGE_OBJECTIVE_C) || !LANGUAGE_OBJECTIVE_C
-    void addEventListener(DOMString type, 
-                          EventListener listener, 
-                          optional boolean useCapture);
-    void removeEventListener(DOMString type, 
-                             EventListener listener, 
-                             optional boolean useCapture);
+    void addEventListener(DOMString type, EventListener listener, optional boolean useCapture);
+    void removeEventListener(DOMString type, EventListener listener, optional boolean useCapture);
     [RaisesException] boolean dispatchEvent(Event event);
 #endif
 
index b27e0d0..2e41e99 100644 (file)
     NodeList getContent();
     
     // EventTarget interface
-    void addEventListener(DOMString type, 
-                          EventListener listener, 
-                          optional boolean useCapture);
-    void removeEventListener(DOMString type, 
-                             EventListener listener, 
-                             optional boolean useCapture);
+    void addEventListener(DOMString type, EventListener listener, optional boolean useCapture);
+    void removeEventListener(DOMString type, EventListener listener, optional boolean useCapture);
     [RaisesException] boolean dispatchEvent(Event event);
 };
index 8b330c3..c65a880 100644 (file)
     readonly attribute FileError error;
 
     // EventTarget interface
-    void addEventListener(DOMString type,
-                          EventListener listener,
-                          optional boolean useCapture);
-    void removeEventListener(DOMString type,
-                             EventListener listener,
-                             optional boolean useCapture);
-    [RaisesException] boolean dispatchEvent(Event evt);
+    void addEventListener(DOMString type, EventListener listener, optional boolean useCapture);
+    void removeEventListener(DOMString type, EventListener listener, optional boolean useCapture);
+    [RaisesException] boolean dispatchEvent(Event event);
 
-    attribute EventListener onloadstart;
-    attribute EventListener onprogress;
-    attribute EventListener onload;
-    attribute EventListener onabort;
-    attribute EventListener onerror;
-    attribute EventListener onloadend;
+    attribute EventHandler onloadstart;
+    attribute EventHandler onprogress;
+    attribute EventHandler onload;
+    attribute EventHandler onabort;
+    attribute EventHandler onerror;
+    attribute EventHandler onloadend;
 };
index 9c71c92..1cf65de 100644 (file)
@@ -215,6 +215,7 @@ onload
 onloadeddata
 onloadedmetadata
 onloadstart
+onmessage
 onmousedown
 onmouseenter
 onmouseleave
index 37d4a61..c6bc570 100644 (file)
@@ -36,6 +36,7 @@
 #include "HTMLParserIdioms.h"
 #include "Page.h"
 #include "StyleProperties.h"
+#include <wtf/NeverDestroyed.h>
 
 namespace WebCore {
 
@@ -94,6 +95,45 @@ void HTMLBodyElement::collectStyleForPresentationAttribute(const QualifiedName&
         HTMLElement::collectStyleForPresentationAttribute(name, value, style);
 }
 
+HTMLElement::EventHandlerNameMap HTMLBodyElement::createWindowEventHandlerNameMap()
+{
+    static const QualifiedName* const table[] = {
+        &onbeforeunloadAttr,
+        &onblurAttr,
+        &onerrorAttr,
+        &onfocusAttr,
+        &onfocusinAttr,
+        &onfocusoutAttr,
+        &onhashchangeAttr,
+        &onloadAttr,
+        &onmessageAttr,
+        &onofflineAttr,
+        &ononlineAttr,
+        &onorientationchangeAttr,
+        &onpagehideAttr,
+        &onpageshowAttr,
+        &onpopstateAttr,
+        &onresizeAttr,
+        &onscrollAttr,
+        &onstorageAttr,
+        &onunloadAttr,
+        &onwebkitwillrevealbottomAttr,
+        &onwebkitwillrevealleftAttr,
+        &onwebkitwillrevealrightAttr,
+        &onwebkitwillrevealtopAttr,
+    };
+
+    EventHandlerNameMap map;
+    populateEventHandlerNameMap(map, table);
+    return map;
+}
+
+const AtomicString& HTMLBodyElement::eventNameForWindowEventHandlerAttribute(const QualifiedName& attributeName)
+{
+    static NeverDestroyed<EventHandlerNameMap> map = createWindowEventHandlerNameMap();
+    return eventNameForEventHandlerAttribute(attributeName, map.get());
+}
+
 void HTMLBodyElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
 {
     if (name == vlinkAttr || name == alinkAttr || name == linkAttr) {
@@ -117,52 +157,21 @@ void HTMLBodyElement::parseAttribute(const QualifiedName& name, const AtomicStri
         }
 
         setNeedsStyleRecalc();
-    } else if (name == onloadAttr)
-        document().setWindowAttributeEventListener(eventNames().loadEvent, name, value);
-    else if (name == onbeforeunloadAttr)
-        document().setWindowAttributeEventListener(eventNames().beforeunloadEvent, name, value);
-    else if (name == onunloadAttr)
-        document().setWindowAttributeEventListener(eventNames().unloadEvent, name, value);
-    else if (name == onpagehideAttr)
-        document().setWindowAttributeEventListener(eventNames().pagehideEvent, name, value);
-    else if (name == onpageshowAttr)
-        document().setWindowAttributeEventListener(eventNames().pageshowEvent, name, value);
-    else if (name == onpopstateAttr)
-        document().setWindowAttributeEventListener(eventNames().popstateEvent, name, value);
-    else if (name == onblurAttr)
-        document().setWindowAttributeEventListener(eventNames().blurEvent, name, value);
-    else if (name == onfocusAttr)
-        document().setWindowAttributeEventListener(eventNames().focusEvent, name, value);
-#if ENABLE(ORIENTATION_EVENTS)
-    else if (name == onorientationchangeAttr)
-        document().setWindowAttributeEventListener(eventNames().orientationchangeEvent, name, value);
-#endif
-    else if (name == onhashchangeAttr)
-        document().setWindowAttributeEventListener(eventNames().hashchangeEvent, name, value);
-    else if (name == onresizeAttr)
-        document().setWindowAttributeEventListener(eventNames().resizeEvent, name, value);
-    else if (name == onscrollAttr)
-        document().setWindowAttributeEventListener(eventNames().scrollEvent, name, value);
-    else if (name == onselectionchangeAttr)
+        return;
+    }
+
+    if (name == onselectionchangeAttr) {
         document().setAttributeEventListener(eventNames().selectionchangeEvent, name, value);
-    else if (name == onstorageAttr)
-        document().setWindowAttributeEventListener(eventNames().storageEvent, name, value);
-    else if (name == ononlineAttr)
-        document().setWindowAttributeEventListener(eventNames().onlineEvent, name, value);
-    else if (name == onofflineAttr)
-        document().setWindowAttributeEventListener(eventNames().offlineEvent, name, value);
-#if ENABLE(WILL_REVEAL_EDGE_EVENTS)
-    else if (name == onwebkitwillrevealbottomAttr)
-        document().setWindowAttributeEventListener(eventNames().webkitwillrevealbottomEvent, name, value);
-    else if (name == onwebkitwillrevealleftAttr)
-        document().setWindowAttributeEventListener(eventNames().webkitwillrevealleftEvent, name, value);
-    else if (name == onwebkitwillrevealrightAttr)
-        document().setWindowAttributeEventListener(eventNames().webkitwillrevealrightEvent, name, value);
-    else if (name == onwebkitwillrevealtopAttr)
-        document().setWindowAttributeEventListener(eventNames().webkitwillrevealtopEvent, name, value);
-#endif
-    else
-        HTMLElement::parseAttribute(name, value);
+        return;
+    }
+
+    auto& eventName = eventNameForWindowEventHandlerAttribute(name);
+    if (!eventName.isNull()) {
+        document().setWindowAttributeEventListener(eventName, name, value);
+        return;
+    }
+
+    HTMLElement::parseAttribute(name, value);
 }
 
 Node::InsertionNotificationRequest HTMLBodyElement::insertedInto(ContainerNode& insertionPoint)
index 28398d3..ff99e33 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
  *           (C) 2000 Simon Hausmann <hausmann@kde.org>
- * Copyright (C) 2004, 2006, 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2006, 2009, 2010, 2015 Apple Inc. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
 
 namespace WebCore {
 
-class Document;
-
 class HTMLBodyElement final : public HTMLElement {
 public:
     static Ref<HTMLBodyElement> create(Document&);
     static Ref<HTMLBodyElement> create(const QualifiedName&, Document&);
     virtual ~HTMLBodyElement();
 
+    static const AtomicString& eventNameForWindowEventHandlerAttribute(const QualifiedName& attributeName);
+
 private:
     HTMLBodyElement(const QualifiedName&, Document&);
 
@@ -59,6 +59,8 @@ private:
     virtual int scrollWidth() override;
     
     virtual void addSubresourceAttributeURLs(ListHashSet<URL>&) const override;
+
+    static EventHandlerNameMap createWindowEventHandlerNameMap();
 };
 
 } //namespace
index 6ac26fa..4bfdf03 100644 (file)
@@ -26,22 +26,30 @@ interface HTMLBodyElement : HTMLElement {
     [Reflect] attribute DOMString text;
     [Reflect] attribute DOMString vLink;
 
-    [NotEnumerable, JSWindowEventListener] attribute EventListener onbeforeunload;
-    [NotEnumerable, JSWindowEventListener] attribute EventListener onblur;
-    [NotEnumerable, JSWindowEventListener] attribute EventListener onerror;
-    [NotEnumerable, JSWindowEventListener] attribute EventListener onfocus;
-    [NotEnumerable, JSWindowEventListener] attribute EventListener onhashchange;
-    [NotEnumerable, JSWindowEventListener] attribute EventListener onload;
-    [NotEnumerable, JSWindowEventListener] attribute EventListener onmessage;
-    [NotEnumerable, JSWindowEventListener] attribute EventListener onoffline;
-    [NotEnumerable, JSWindowEventListener] attribute EventListener ononline;
-    [NotEnumerable, JSWindowEventListener] attribute EventListener onpagehide;
-    [NotEnumerable, JSWindowEventListener] attribute EventListener onpageshow;
-    [NotEnumerable, JSWindowEventListener] attribute EventListener onpopstate;
-    [NotEnumerable, JSWindowEventListener] attribute EventListener onresize;
-    [NotEnumerable, JSWindowEventListener] attribute EventListener onstorage;
-    [NotEnumerable, JSWindowEventListener] attribute EventListener onunload;
+    [NotEnumerable, WindowEventHandler] attribute EventHandler onbeforeunload;
+    [NotEnumerable, WindowEventHandler] attribute EventHandler onblur;
+    [NotEnumerable, WindowEventHandler] attribute EventHandler onerror;
+    [NotEnumerable, WindowEventHandler] attribute EventHandler onfocus;
+    [NotEnumerable, WindowEventHandler] attribute EventHandler onfocusin;
+    [NotEnumerable, WindowEventHandler] attribute EventHandler onfocusout;
+    [NotEnumerable, WindowEventHandler] attribute EventHandler onhashchange;
+    [NotEnumerable, WindowEventHandler] attribute EventHandler onload;
+    [NotEnumerable, WindowEventHandler] attribute EventHandler onmessage;
+    [NotEnumerable, WindowEventHandler] attribute EventHandler onoffline;
+    [NotEnumerable, WindowEventHandler] attribute EventHandler ononline;
+    [NotEnumerable, WindowEventHandler] attribute EventHandler onorientationchange;
+    [NotEnumerable, WindowEventHandler] attribute EventHandler onpagehide;
+    [NotEnumerable, WindowEventHandler] attribute EventHandler onpageshow;
+    [NotEnumerable, WindowEventHandler] attribute EventHandler onpopstate;
+    [NotEnumerable, WindowEventHandler] attribute EventHandler onresize;
+    [NotEnumerable, WindowEventHandler] attribute EventHandler onscroll;
+    [NotEnumerable, WindowEventHandler] attribute EventHandler onstorage;
+    [NotEnumerable, WindowEventHandler] attribute EventHandler onunload;
+    [NotEnumerable, WindowEventHandler] attribute EventHandler onwebkitwillrevealbottom;
+    [NotEnumerable, WindowEventHandler] attribute EventHandler onwebkitwillrevealleft;
+    [NotEnumerable, WindowEventHandler] attribute EventHandler onwebkitwillrevealright;
+    [NotEnumerable, WindowEventHandler] attribute EventHandler onwebkitwillrevealtop;
 
-    [Conditional=ORIENTATION_EVENTS, NotEnumerable, JSWindowEventListener] attribute EventListener onorientationchange;
+    [NotEnumerable, DocumentEventHandler] attribute EventHandler onselectionchange;
 };
 
index 9e4ae52..e67f756 100644 (file)
@@ -248,13 +248,17 @@ void HTMLElement::collectStyleForPresentationAttribute(const QualifiedName& name
         StyledElement::collectStyleForPresentationAttribute(name, value, style);
 }
 
-void HTMLElement::populateEventNameForAttributeLocalNameMap(HashMap<AtomicStringImpl*, AtomicString>& map)
+HTMLElement::EventHandlerNameMap HTMLElement::createEventHandlerNameMap()
 {
-    static const QualifiedName* const simpleTable[] = {
+    EventHandlerNameMap map;
+
+    static const QualifiedName* const table[] = {
         &onabortAttr,
         &onanimationendAttr,
         &onanimationiterationAttr,
         &onanimationstartAttr,
+        &onautocompleteAttr,
+        &onautocompleteerrorAttr,
         &onbeforecopyAttr,
         &onbeforecutAttr,
         &onbeforeloadAttr,
@@ -282,6 +286,9 @@ void HTMLElement::populateEventNameForAttributeLocalNameMap(HashMap<AtomicString
         &onfocusAttr,
         &onfocusinAttr,
         &onfocusoutAttr,
+        &ongesturechangeAttr,
+        &ongestureendAttr,
+        &ongesturestartAttr,
         &oninputAttr,
         &oninvalidAttr,
         &onkeydownAttr,
@@ -324,88 +331,105 @@ void HTMLElement::populateEventNameForAttributeLocalNameMap(HashMap<AtomicString
         &onvolumechangeAttr,
         &onwaitingAttr,
         &onwebkitbeginfullscreenAttr,
+        &onwebkitcurrentplaybacktargetiswirelesschangedAttr,
         &onwebkitendfullscreenAttr,
-        &onwheelAttr,
-#if ENABLE(FULLSCREEN_API)
         &onwebkitfullscreenchangeAttr,
         &onwebkitfullscreenerrorAttr,
-#endif
-#if ENABLE(IOS_GESTURE_EVENTS)
-        &ongesturechangeAttr,
-        &ongestureendAttr,
-        &ongesturestartAttr,
-#endif
-#if ENABLE(REQUEST_AUTOCOMPLETE)
-        &onautocompleteAttr,
-        &onautocompleteerrorAttr,
-#endif
-#if ENABLE(VIDEO_PRESENTATION_MODE)
+        &onwebkitkeyaddedAttr,
+        &onwebkitkeyerrorAttr,
+        &onwebkitkeymessageAttr,
+        &onwebkitneedkeyAttr,
+        &onwebkitplaybacktargetavailabilitychangedAttr,
         &onwebkitpresentationmodechangedAttr,
-#endif
-#if ENABLE(WILL_REVEAL_EDGE_EVENTS)
         &onwebkitwillrevealbottomAttr,
         &onwebkitwillrevealleftAttr,
         &onwebkitwillrevealrightAttr,
         &onwebkitwillrevealtopAttr,
-#endif
-#if ENABLE(WIRELESS_PLAYBACK_TARGET)
-        &onwebkitcurrentplaybacktargetiswirelesschangedAttr,
-        &onwebkitplaybacktargetavailabilitychangedAttr,
-#endif
+        &onwheelAttr,
     };
 
-    for (unsigned i = 0, size = WTF_ARRAY_LENGTH(simpleTable); i < size; ++i) {
-        // FIXME: Would be nice to check these against the actual event names in eventNames().
-        // Not obvious how to do that simply, though.
-        const AtomicString& attributeName = simpleTable[i]->localName();
+    populateEventHandlerNameMap(map, table);
 
-        // Remove the "on" prefix. Requires some memory allocation and computing a hash, but
-        // by not using pointers from eventNames(), simpleTable can be initialized at compile time.
-        AtomicString eventName = attributeName.string().substring(2);
-
-        map.add(attributeName.impl(), eventName);
-    }
-
-    struct CustomMapping {
+    struct UnusualMapping {
         const QualifiedName& attributeName;
         const AtomicString& eventName;
     };
 
-    const CustomMapping customTable[] = {
+    const UnusualMapping unusualPairsTable[] = {
         { onwebkitanimationendAttr, eventNames().webkitAnimationEndEvent },
         { onwebkitanimationiterationAttr, eventNames().webkitAnimationIterationEvent },
         { onwebkitanimationstartAttr, eventNames().webkitAnimationStartEvent },
         { onwebkittransitionendAttr, eventNames().webkitTransitionEndEvent },
     };
 
-    for (unsigned i = 0, size = WTF_ARRAY_LENGTH(customTable); i < size; ++i)
-        map.add(customTable[i].attributeName.localName().impl(), customTable[i].eventName);
+    for (auto& entry : unusualPairsTable)
+        map.add(entry.attributeName.localName().impl(), entry.eventName);
+
+    return map;
+}
+
+void HTMLElement::populateEventHandlerNameMap(EventHandlerNameMap& map, const QualifiedName* const table[], size_t tableSize)
+{
+    for (size_t i = 0; i < tableSize; ++i) {
+        auto* entry = table[i];
+
+        // FIXME: Would be nice to check these against the actual event names in eventNames().
+        // Not obvious how to do that simply, though.
+        auto& attributeName = entry->localName();
+
+        // Remove the "on" prefix. Requires some memory allocation and computing a hash, but by not
+        // using pointers from eventNames(), the passed-in table can be initialized at compile time.
+        AtomicString eventName = attributeName.string().substring(2);
+
+        map.add(attributeName.impl(), WTF::move(eventName));
+    }
+}
+
+const AtomicString& HTMLElement::eventNameForEventHandlerAttribute(const QualifiedName& attributeName, const EventHandlerNameMap& map)
+{
+    ASSERT(!attributeName.localName().isNull());
+
+    // Event handler attributes have no namespace.
+    if (!attributeName.namespaceURI().isNull())
+        return nullAtom;
+
+    // Fast early return for names that don't start with "on".
+    AtomicStringImpl& localName = *attributeName.localName().impl();
+    if (localName.length() < 3 || localName[0] != 'o' || localName[1] != 'n')
+        return nullAtom;
+
+    auto it = map.find(&localName);
+    return it == map.end() ? nullAtom : it->value;
+}
+
+const AtomicString& HTMLElement::eventNameForEventHandlerAttribute(const QualifiedName& attributeName)
+{
+    static NeverDestroyed<EventHandlerNameMap> map = createEventHandlerNameMap();
+    return eventNameForEventHandlerAttribute(attributeName, map.get());
 }
 
 Node::Editability HTMLElement::editabilityFromContentEditableAttr(const Node& node)
 {
-    const Node* currentNode = &node;
-    do {
-        if (is<HTMLElement>(*currentNode)) {
-            switch (contentEditableType(downcast<HTMLElement>(*currentNode))) {
+    if (auto* startElement = is<Element>(node) ? &downcast<Element>(node) : node.parentElement()) {
+        for (auto& element : lineageOfType<HTMLElement>(*startElement)) {
+            switch (contentEditableType(element)) {
             case ContentEditableType::True:
-                return Node::Editability::CanEditRichly;
+                return Editability::CanEditRichly;
             case ContentEditableType::PlaintextOnly:
-                return Node::Editability::CanEditPlainText;
+                return Editability::CanEditPlainText;
             case ContentEditableType::False:
-                return Node::Editability::ReadOnly;
+                return Editability::ReadOnly;
             case ContentEditableType::Inherit:
                 break;
             }
         }
-        currentNode = currentNode->parentNode();
-    } while (currentNode);
+    }
 
-    const Document& document = node.document();
+    auto& document = node.document();
     if (is<HTMLDocument>(document))
-        return downcast<HTMLDocument>(document).inDesignMode() ? Node::Editability::CanEditRichly : Node::Editability::ReadOnly;
+        return downcast<HTMLDocument>(document).inDesignMode() ? Editability::CanEditRichly : Editability::ReadOnly;
 
-    return Node::Editability::ReadOnly;
+    return Editability::ReadOnly;
 }
 
 bool HTMLElement::matchesReadWritePseudoClass() const
@@ -415,39 +439,38 @@ bool HTMLElement::matchesReadWritePseudoClass() const
 
 void HTMLElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
 {
-    if (name == HTMLNames::idAttr || name == HTMLNames::classAttr || name == HTMLNames::styleAttr)
-        return StyledElement::parseAttribute(name, value);
-
-    if (name == dirAttr)
+    if (name == dirAttr) {
         dirAttributeChanged(value);
-    else if (name == tabindexAttr) {
-        int tabindex = 0;
+        return;
+    }
+
+    if (name == tabindexAttr) {
+        int tabIndex = 0;
         if (value.isEmpty())
             clearTabIndexExplicitlyIfNeeded();
-        else if (parseHTMLInteger(value, tabindex)) {
-            // Clamp tabindex to the range of 'short' to match Firefox's behavior.
-            setTabIndexExplicitly(std::max(static_cast<int>(std::numeric_limits<short>::min()), std::min(tabindex, static_cast<int>(std::numeric_limits<short>::max()))));
+        else if (parseHTMLInteger(value, tabIndex)) {
+            // Clamp tab index to a 16-bit value to match Firefox's behavior.
+            setTabIndexExplicitly(std::max(-0x8000, std::min(tabIndex, 0x7FFF)));
         }
-    } else if (name.namespaceURI().isNull()) {
-        // FIXME: Can we do this even faster by checking the local name "on" prefix before we do anything with the map?
-        static NeverDestroyed<HashMap<AtomicStringImpl*, AtomicString>> eventNamesGlobal;
-        auto& eventNames = eventNamesGlobal.get();
-        if (eventNames.isEmpty())
-            populateEventNameForAttributeLocalNameMap(eventNames);
-        const AtomicString& eventName = eventNames.get(name.localName().impl());
-        if (!eventName.isNull())
-            setAttributeEventListener(eventName, name, value);
+        return;
     }
+
+    auto& eventName = eventNameForEventHandlerAttribute(name);
+    if (!eventName.isNull())
+        setAttributeEventListener(eventName, name, value);
 }
 
-RefPtr<DocumentFragment> HTMLElement::textToFragment(const String& text, ExceptionCode& ec)
+Ref<DocumentFragment> HTMLElement::textToFragment(const String& text, ExceptionCode& ec)
 {
-    RefPtr<DocumentFragment> fragment = DocumentFragment::create(document());
-    unsigned int i, length = text.length();
-    UChar c = 0;
-    for (unsigned int start = 0; start < length; ) {
+    ec = 0;
+
+    auto fragment = DocumentFragment::create(document());
+
+    for (unsigned start = 0, length = text.length(); start < length; ) {
 
         // Find next line break.
+        UChar c;
+        unsigned i;
         for (i = start; i < length; i++) {
             c = text[i];
             if (c == '\r' || c == '\n')
@@ -456,16 +479,18 @@ RefPtr<DocumentFragment> HTMLElement::textToFragment(const String& text, Excepti
 
         fragment->appendChild(Text::create(document(), text.substring(start, i - start)), ec);
         if (ec)
-            return nullptr;
+            break;
 
-        if (c == '\r' || c == '\n') {
-            fragment->appendChild(HTMLBRElement::create(document()), ec);
-            if (ec)
-                return nullptr;
-            // Make sure \r\n doesn't result in two line breaks.
-            if (c == '\r' && i + 1 < length && text[i + 1] == '\n')
-                i++;
-        }
+        if (i == length)
+            break;
+
+        fragment->appendChild(HTMLBRElement::create(document()), ec);
+        if (ec)
+            break;
+
+        // Make sure \r\n doesn't result in two line breaks.
+        if (c == '\r' && i + 1 < length && text[i + 1] == '\n')
+            ++i;
 
         start = i + 1; // Character after line break.
     }
index 58053b7..7949d62 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
- * Copyright (C) 2004, 2005, 2006, 2007, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2004-2009, 2015 Apple Inc. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -99,10 +99,10 @@ public:
     virtual bool isLabelable() const { return false; }
     virtual FormNamedItem* asFormNamedItem() { return 0; }
 
-    static void populateEventNameForAttributeLocalNameMap(HashMap<AtomicStringImpl*, AtomicString>&);
-
     bool hasTagName(const HTMLQualifiedName& name) const { return hasLocalName(name.localName()); }
 
+    static const AtomicString& eventNameForEventHandlerAttribute(const QualifiedName& attributeName);
+
 protected:
     HTMLElement(const QualifiedName& tagName, Document&, ConstructionType);
 
@@ -121,6 +121,10 @@ protected:
     virtual void childrenChanged(const ChildChange&) override;
     void calculateAndAdjustDirectionality();
 
+    typedef HashMap<AtomicStringImpl*, AtomicString> EventHandlerNameMap;
+    template<size_t tableSize> static void populateEventHandlerNameMap(EventHandlerNameMap&, const QualifiedName* const (&table)[tableSize]);
+    static const AtomicString& eventNameForEventHandlerAttribute(const QualifiedName& attributeName, const EventHandlerNameMap&);
+
 private:
     virtual String nodeName() const override final;
 
@@ -129,7 +133,7 @@ private:
     virtual HTMLFormElement* virtualForm() const;
 
     Node* insertAdjacent(const String& where, Node* newChild, ExceptionCode&);
-    RefPtr<DocumentFragment> textToFragment(const String&, ExceptionCode&);
+    Ref<DocumentFragment> textToFragment(const String&, ExceptionCode&);
 
     void dirAttributeChanged(const AtomicString&);
     void adjustDirectionalityIfNeededAfterChildAttributeChanged(Element* child);
@@ -137,6 +141,9 @@ private:
     TextDirection directionality(Node** strongDirectionalityTextNode= 0) const;
 
     TranslateAttributeMode translateAttributeMode() const;
+
+    static void populateEventHandlerNameMap(EventHandlerNameMap&, const QualifiedName* const table[], size_t tableSize);
+    static EventHandlerNameMap createEventHandlerNameMap();
 };
 
 inline HTMLElement::HTMLElement(const QualifiedName& tagName, Document& document, ConstructionType type = CreateHTMLElement)
@@ -145,6 +152,11 @@ inline HTMLElement::HTMLElement(const QualifiedName& tagName, Document& document
     ASSERT(tagName.localName().impl());
 }
 
+template<size_t tableSize> inline void HTMLElement::populateEventHandlerNameMap(EventHandlerNameMap& map, const QualifiedName* const (&table)[tableSize])
+{
+    populateEventHandlerNameMap(map, table, tableSize);
+}
+
 inline bool Node::hasTagName(const HTMLQualifiedName& name) const
 {
     return is<HTMLElement>(*this) && downcast<HTMLElement>(*this).hasTagName(name);
index fbddf11..68cfb17 100644 (file)
@@ -118,11 +118,6 @@ void HTMLFrameElementBase::parseAttribute(const QualifiedName& name, const Atomi
         else if (equalIgnoringCase(value, "no"))
             m_scrolling = ScrollbarAlwaysOff;
         // FIXME: If we are already attached, this has no effect.
-    } else if (name == onbeforeloadAttr)
-        setAttributeEventListener(eventNames().beforeloadEvent, name, value);
-    else if (name == onbeforeunloadAttr) {
-        // FIXME: should <frame> elements have beforeunload handlers?
-        setAttributeEventListener(eventNames().beforeunloadEvent, name, value);
     } else
         HTMLFrameOwnerElement::parseAttribute(name, value);
 }
index 79d15d7..ce7896b 100644 (file)
@@ -33,6 +33,7 @@
 #include "Frame.h"
 #include "FrameLoader.h"
 #include "FrameLoaderClient.h"
+#include "HTMLBodyElement.h"
 #include "HTMLNames.h"
 #include "Length.h"
 #include "MouseEvent.h"
@@ -81,16 +82,28 @@ void HTMLFrameSetElement::collectStyleForPresentationAttribute(const QualifiedNa
 void HTMLFrameSetElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
 {
     if (name == rowsAttr) {
+        // FIXME: What is the right thing to do when removing this attribute?
+        // Why not treat it the same way we treat setting it to the empty string?
         if (!value.isNull()) {
             m_rowLengths = newLengthArray(value.string(), m_totalRows);
+            // FIXME: Would be nice to optimize the case where m_rowLengths did not change.
             setNeedsStyleRecalc();
         }
-    } else if (name == colsAttr) {
+        return;
+    }
+
+    if (name == colsAttr) {
+        // FIXME: What is the right thing to do when removing this attribute?
+        // Why not treat it the same way we treat setting it to the empty string?
         if (!value.isNull()) {
             m_colLengths = newLengthArray(value.string(), m_totalCols);
+            // FIXME: Would be nice to optimize the case where m_colLengths did not change.
             setNeedsStyleRecalc();
         }
-    } else if (name == frameborderAttr) {
+        return;
+    }
+
+    if (name == frameborderAttr) {
         if (!value.isNull()) {
             if (equalIgnoringCase(value, "no") || equalIgnoringCase(value, "0")) {
                 m_frameborder = false;
@@ -102,50 +115,40 @@ void HTMLFrameSetElement::parseAttribute(const QualifiedName& name, const Atomic
             m_frameborder = false;
             m_frameborderSet = false;
         }
-    } else if (name == noresizeAttr) {
+        // FIXME: Do we need to trigger repainting?
+        return;
+    }
+
+    if (name == noresizeAttr) {
+        // FIXME: This should set m_noresize to false if the value is null.
         m_noresize = true;
-    } else if (name == borderAttr) {
+        return;
+    }
+
+    if (name == borderAttr) {
         if (!value.isNull()) {
             m_border = value.toInt();
             m_borderSet = true;
         } else
             m_borderSet = false;
-    } else if (name == bordercolorAttr)
+        // FIXME: Do we need to trigger repainting?
+        return;
+    }
+
+    if (name == bordercolorAttr) {
         m_borderColorSet = !value.isEmpty();
-    else if (name == onloadAttr)
-        document().setWindowAttributeEventListener(eventNames().loadEvent, name, value);
-    else if (name == onbeforeunloadAttr)
-        document().setWindowAttributeEventListener(eventNames().beforeunloadEvent, name, value);
-    else if (name == onunloadAttr)
-        document().setWindowAttributeEventListener(eventNames().unloadEvent, name, value);
-    else if (name == onblurAttr)
-        document().setWindowAttributeEventListener(eventNames().blurEvent, name, value);
-    else if (name == onfocusAttr)
-        document().setWindowAttributeEventListener(eventNames().focusEvent, name, value);
-    else if (name == onfocusinAttr)
-        document().setWindowAttributeEventListener(eventNames().focusinEvent, name, value);
-    else if (name == onfocusoutAttr)
-        document().setWindowAttributeEventListener(eventNames().focusoutEvent, name, value);
-#if ENABLE(ORIENTATION_EVENTS)
-    else if (name == onorientationchangeAttr)
-        document().setWindowAttributeEventListener(eventNames().orientationchangeEvent, name, value);
-#endif
-    else if (name == onhashchangeAttr)
-        document().setWindowAttributeEventListener(eventNames().hashchangeEvent, name, value);
-    else if (name == onresizeAttr)
-        document().setWindowAttributeEventListener(eventNames().resizeEvent, name, value);
-    else if (name == onscrollAttr)
-        document().setWindowAttributeEventListener(eventNames().scrollEvent, name, value);
-    else if (name == onstorageAttr)
-        document().setWindowAttributeEventListener(eventNames().storageEvent, name, value);
-    else if (name == ononlineAttr)
-        document().setWindowAttributeEventListener(eventNames().onlineEvent, name, value);
-    else if (name == onofflineAttr)
-        document().setWindowAttributeEventListener(eventNames().offlineEvent, name, value);
-    else if (name == onpopstateAttr)
-        document().setWindowAttributeEventListener(eventNames().popstateEvent, name, value);
-    else
-        HTMLElement::parseAttribute(name, value);
+        // FIXME: Clearly wrong: This can overwrite the value inherited from the parent frameset.
+        // FIXME: Do we need to trigger repainting?
+        return;
+    }
+
+    auto& eventName = HTMLBodyElement::eventNameForWindowEventHandlerAttribute(name);
+    if (!eventName.isNull()) {
+        document().setWindowAttributeEventListener(eventName, name, value);
+        return;
+    }
+
+    HTMLElement::parseAttribute(name, value);
 }
 
 bool HTMLFrameSetElement::rendererIsNeeded(const RenderStyle& style)
index acd5528..b993d49 100644 (file)
     [Reflect] attribute DOMString cols;
     [Reflect] attribute DOMString rows;
 
-    [NotEnumerable, JSWindowEventListener] attribute EventListener onbeforeunload;
-    [NotEnumerable, JSWindowEventListener] attribute EventListener onblur;
-    [NotEnumerable, JSWindowEventListener] attribute EventListener onerror;
-    [NotEnumerable, JSWindowEventListener] attribute EventListener onfocus;
-    [NotEnumerable, JSWindowEventListener] attribute EventListener onhashchange;
-    [NotEnumerable, JSWindowEventListener] attribute EventListener onload;
-    [NotEnumerable, JSWindowEventListener] attribute EventListener onmessage;
-    [NotEnumerable, JSWindowEventListener] attribute EventListener onoffline;
-    [NotEnumerable, JSWindowEventListener] attribute EventListener ononline;
-    [NotEnumerable, JSWindowEventListener] attribute EventListener onpopstate;
-    [NotEnumerable, JSWindowEventListener] attribute EventListener onresize;
-    [NotEnumerable, JSWindowEventListener] attribute EventListener onstorage;
-    [NotEnumerable, JSWindowEventListener] attribute EventListener onunload;
-
-    [Conditional=ORIENTATION_EVENTS, NotEnumerable, JSWindowEventListener] attribute EventListener onorientationchange;
+    [NotEnumerable, WindowEventHandler] attribute EventHandler onbeforeunload;
+    [NotEnumerable, WindowEventHandler] attribute EventHandler onblur;
+    [NotEnumerable, WindowEventHandler] attribute EventHandler onerror;
+    [NotEnumerable, WindowEventHandler] attribute EventHandler onfocus;
+    [NotEnumerable, WindowEventHandler] attribute EventHandler onfocusin;
+    [NotEnumerable, WindowEventHandler] attribute EventHandler onfocusout;
+    [NotEnumerable, WindowEventHandler] attribute EventHandler onhashchange;
+    [NotEnumerable, WindowEventHandler] attribute EventHandler onload;
+    [NotEnumerable, WindowEventHandler] attribute EventHandler onmessage;
+    [NotEnumerable, WindowEventHandler] attribute EventHandler onoffline;
+    [NotEnumerable, WindowEventHandler] attribute EventHandler ononline;
+    [NotEnumerable, WindowEventHandler] attribute EventHandler onorientationchange;
+    [NotEnumerable, WindowEventHandler] attribute EventHandler onpagehide;
+    [NotEnumerable, WindowEventHandler] attribute EventHandler onpageshow;
+    [NotEnumerable, WindowEventHandler] attribute EventHandler onpopstate;
+    [NotEnumerable, WindowEventHandler] attribute EventHandler onresize;
+    [NotEnumerable, WindowEventHandler] attribute EventHandler onscroll;
+    [NotEnumerable, WindowEventHandler] attribute EventHandler onstorage;
+    [NotEnumerable, WindowEventHandler] attribute EventHandler onunload;
+    [NotEnumerable, WindowEventHandler] attribute EventHandler onwebkitwillrevealbottom;
+    [NotEnumerable, WindowEventHandler] attribute EventHandler onwebkitwillrevealleft;
+    [NotEnumerable, WindowEventHandler] attribute EventHandler onwebkitwillrevealright;
+    [NotEnumerable, WindowEventHandler] attribute EventHandler onwebkitwillrevealtop;
 };
 
index 554b541..1c855dc 100644 (file)
@@ -162,9 +162,7 @@ void HTMLImageElement::parseAttribute(const QualifiedName& name, const AtomicStr
 
         if (inDocument() && !m_lowercasedUsemap.isNull())
             document().addImageElementByLowercasedUsemap(*m_lowercasedUsemap.impl(), *this);
-    } else if (name == onbeforeloadAttr)
-        setAttributeEventListener(eventNames().beforeloadEvent, name, value);
-    else if (name == compositeAttr) {
+    } else if (name == compositeAttr) {
         // FIXME: images don't support blend modes in their compositing attribute.
         BlendMode blendOp = BlendModeNormal;
         if (!parseCompositeAndBlendOperator(value, m_compositeOperator, blendOp))
index 0ad1378..b1ebafd 100644 (file)
@@ -160,8 +160,6 @@ void HTMLLinkElement::parseAttribute(const QualifiedName& name, const AtomicStri
         process();
     } else if (name == disabledAttr)
         setDisabledState(!value.isNull());
-    else if (name == onbeforeloadAttr)
-        setAttributeEventListener(eventNames().beforeloadEvent, name, value);
     else {
         if (name == titleAttr && m_sheet)
             m_sheet->setTitle(value);
index 5b8e3a9..a805614 100644 (file)
@@ -35,7 +35,7 @@ interface HTMLMarqueeElement : HTMLElement {
 
     // FIXME: Implement the following event handler attributes
     // https://bugs.webkit.org/show_bug.cgi?id=49788
-    // attribute EventListener onbounce;
-    // attribute EventListener onfinish;
-    // attribute EventListener onstart;
+    // attribute EventHandler onbounce;
+    // attribute EventHandler onfinish;
+    // attribute EventHandler onstart;
 };
index cbd458b..ece4417 100644 (file)
@@ -128,9 +128,7 @@ void HTMLObjectElement::parseAttribute(const QualifiedName& name, const AtomicSt
     } else if (name == classidAttr) {
         invalidateRenderer = true;
         setNeedsWidgetUpdate(true);
-    } else if (name == onbeforeloadAttr)
-        setAttributeEventListener(eventNames().beforeloadEvent, name, value);
-    else
+    } else
         HTMLPlugInImageElement::parseAttribute(name, value);
 
     if (!invalidateRenderer || !inDocument() || !renderer())
index 4758c61..8d0bfff 100644 (file)
@@ -64,8 +64,6 @@ void HTMLScriptElement::parseAttribute(const QualifiedName& name, const AtomicSt
         handleSourceAttribute(value);
     else if (name == asyncAttr)
         handleAsyncAttribute();
-    else if (name == onbeforeloadAttr)
-        setAttributeEventListener(eventNames().beforeloadEvent, name, value);
     else
         HTMLElement::parseAttribute(name, value);
 }
index e0d78e4..ee0c277 100644 (file)
     attribute boolean muted;
 
     // EventTarget interface
-    void addEventListener(DOMString type, 
-                          EventListener listener, 
-                          optional boolean useCapture);
-    void removeEventListener(DOMString type, 
-                             EventListener listener, 
-                             optional boolean useCapture);
-    [RaisesException] boolean dispatchEvent(Event evt);
+    void addEventListener(DOMString type, EventListener listener, optional boolean useCapture);
+    void removeEventListener(DOMString type, EventListener listener, optional boolean useCapture);
+    [RaisesException] boolean dispatchEvent(Event event);
 };
index 50bd68c..8c24cab 100644 (file)
     getter AudioTrack item(unsigned long index);
     AudioTrack getTrackById(DOMString id);
 
-    attribute EventListener onchange;
-    attribute EventListener onaddtrack;
-    attribute EventListener onremovetrack;
+    attribute EventHandler onchange;
+    attribute EventHandler onaddtrack;
+    attribute EventHandler onremovetrack;
 
-    void addEventListener(DOMString type,
-                          EventListener listener,
-                          optional boolean useCapture);
-    void removeEventListener(DOMString type,
-                             EventListener listener,
-                             optional boolean useCapture);
-    [RaisesException] boolean dispatchEvent(Event evt);
+    void addEventListener(DOMString type, EventListener listener, optional boolean useCapture);
+    void removeEventListener(DOMString type, EventListener listener, optional boolean useCapture);
+    [RaisesException] boolean dispatchEvent(Event event);
 };
 
index d60358b..404d022 100644 (file)
@@ -47,20 +47,16 @@ enum TextTrackKind { "subtitles",  "captions",  "descriptions",  "chapters", "me
     [RaisesException] void addCue(TextTrackCue cue);
     [RaisesException] void removeCue(TextTrackCue cue);
 
-             attribute EventListener oncuechange;
+    attribute EventHandler oncuechange;
 
-#if defined(ENABLE_WEBVTT_REGIONS) && ENABLE_WEBVTT_REGIONS
-    readonly attribute VTTRegionList regions;
-    void addRegion(VTTRegion region);
-    [RaisesException] void removeRegion(VTTRegion region);
+#if !defined(LANGUAGE_GOBJECT) || !LANGUAGE_GOBJECT // Work around shortcomings in the gobject binding generator handling of conditional features by turning these off for gobject.
+    [Conditional=WEBVTT_REGIONS] readonly attribute VTTRegionList regions;
+    [Conditional=WEBVTT_REGIONS] void addRegion(VTTRegion region);
+    [Conditional=WEBVTT_REGIONS, RaisesException] void removeRegion(VTTRegion region);
 #endif
 
     // EventTarget interface
-    void addEventListener(DOMString type, 
-                          EventListener listener, 
-                          optional boolean useCapture);
-    void removeEventListener(DOMString type, 
-                             EventListener listener, 
-                             optional boolean useCapture);
-    [RaisesException] boolean dispatchEvent(Event evt);
+    void addEventListener(DOMString type, EventListener listener, optional boolean useCapture);
+    void removeEventListener(DOMString type, EventListener listener, optional boolean useCapture);
+    [RaisesException] boolean dispatchEvent(Event event);
 };
index d17b4b5..b772bb6 100644 (file)
     [SetterRaisesException] attribute unrestricted double endTime;
     attribute boolean pauseOnExit;
 
-    attribute EventListener onenter;
-    attribute EventListener onexit;
+    attribute EventHandler onenter;
+    attribute EventHandler onexit;
 
     // EventTarget interface
-    void addEventListener(DOMString type, 
-                          EventListener listener, 
-                          optional boolean useCapture);
-    void removeEventListener(DOMString type, 
-                             EventListener listener, 
-                             optional boolean useCapture);
-    [RaisesException] boolean dispatchEvent(Event evt);
+    void addEventListener(DOMString type, EventListener listener, optional boolean useCapture);
+    void removeEventListener(DOMString type, EventListener listener, optional boolean useCapture);
+    [RaisesException] boolean dispatchEvent(Event event);
 };
 
index 66530ab..08cca4a 100644 (file)
     getter TextTrack item(unsigned long index);
     TextTrack getTrackById(DOMString id);
 
-    attribute EventListener onaddtrack;
-    attribute EventListener onchange;
-    attribute EventListener onremovetrack;
+    attribute EventHandler onaddtrack;
+    attribute EventHandler onchange;
+    attribute EventHandler onremovetrack;
 
-    void addEventListener(DOMString type,
-                          EventListener listener,
-                          optional boolean useCapture);
-    void removeEventListener(DOMString type,
-                             EventListener listener,
-                             optional boolean useCapture);
-    [RaisesException] boolean dispatchEvent(Event evt);
+    void addEventListener(DOMString type, EventListener listener, optional boolean useCapture);
+    void removeEventListener(DOMString type, EventListener listener, optional boolean useCapture);
+    [RaisesException] boolean dispatchEvent(Event event);
 };
 
index 476fe8d..a91f778 100644 (file)
     VideoTrack getTrackById(DOMString id);
     readonly attribute long selectedIndex;
 
-    attribute EventListener onchange;
-    attribute EventListener onaddtrack;
-    attribute EventListener onremovetrack;
+    attribute EventHandler onchange;
+    attribute EventHandler onaddtrack;
+    attribute EventHandler onremovetrack;
 
-    void addEventListener(DOMString type,
-                          EventListener listener,
-                          optional boolean useCapture);
-    void removeEventListener(DOMString type,
-                             EventListener listener,
-                             optional boolean useCapture);
-    [RaisesException] boolean dispatchEvent(Event evt);
+    void addEventListener(DOMString type, EventListener listener, optional boolean useCapture);
+    void removeEventListener(DOMString type, EventListener listener, optional boolean useCapture);
+    [RaisesException] boolean dispatchEvent(Event event);
 };
 
index 9622c12..b55f1b5 100644 (file)
     [RaisesException] void swapCache();
     void abort();
 
-    // events
-    attribute EventListener onchecking;
-    attribute EventListener onerror;
-    attribute EventListener onnoupdate;
-    attribute EventListener ondownloading;
-    attribute EventListener onprogress;
-    attribute EventListener onupdateready;
-    attribute EventListener oncached;
-    attribute EventListener onobsolete;
+    attribute EventHandler onchecking;
+    attribute EventHandler onerror;
+    attribute EventHandler onnoupdate;
+    attribute EventHandler ondownloading;
+    attribute EventHandler onprogress;
+    attribute EventHandler onupdateready;
+    attribute EventHandler oncached;
+    attribute EventHandler onobsolete;
 
     // EventTarget interface
-    void addEventListener(DOMString type, 
-                          EventListener listener, 
-                          optional boolean useCapture);
-    void removeEventListener(DOMString type, 
-                             EventListener listener, 
-                             optional boolean useCapture);
-    [RaisesException] boolean dispatchEvent(Event evt);
+    void addEventListener(DOMString type, EventListener listener, optional boolean useCapture);
+    void removeEventListener(DOMString type, EventListener listener, optional boolean useCapture);
+    [RaisesException] boolean dispatchEvent(Event event);
 };
 
index ce56822..504067c 100644 (file)
 
     [Replaceable] readonly attribute DOMWindowCSS CSS;
 
-    attribute EventListener onabort;
-    attribute EventListener onanimationend;
-    attribute EventListener onanimationiteration;
-    attribute EventListener onanimationstart;
-    attribute EventListener onbeforeunload;
-    attribute EventListener onblur;
-    attribute EventListener oncanplay;
-    attribute EventListener oncanplaythrough;
-    attribute EventListener onchange;
-    attribute EventListener onclick;
-    attribute EventListener oncontextmenu;
-    attribute EventListener ondblclick;
-    attribute EventListener ondrag;
-    attribute EventListener ondragend;
-    attribute EventListener ondragenter;
-    attribute EventListener ondragleave;
-    attribute EventListener ondragover;
-    attribute EventListener ondragstart;
-    attribute EventListener ondrop;
-    attribute EventListener ondurationchange;
-    attribute EventListener onemptied;
-    attribute EventListener onended;
-    attribute EventListener onerror;
-    attribute EventListener onfocus;
-    attribute EventListener onhashchange;
-    attribute EventListener oninput;
-    attribute EventListener oninvalid;
-    attribute EventListener onkeydown;
-    attribute EventListener onkeypress;
-    attribute EventListener onkeyup;
-    attribute EventListener onload;
-    attribute EventListener onloadeddata;
-    attribute EventListener onloadedmetadata;
-    attribute EventListener onloadstart;
-    attribute EventListener onmessage;
-    attribute EventListener onmousedown;
-    attribute EventListener onmouseenter;
-    attribute EventListener onmouseleave;
-    attribute EventListener onmousemove;
-    attribute EventListener onmouseout;
-    attribute EventListener onmouseover;
-    attribute EventListener onmouseup;
-    attribute EventListener onmousewheel;
-    attribute EventListener onoffline;
-    attribute EventListener ononline;
-    attribute EventListener onpagehide;
-    attribute EventListener onpageshow;
-    attribute EventListener onpause;
-    attribute EventListener onplay;
-    attribute EventListener onplaying;
-    attribute EventListener onpopstate;
-    attribute EventListener onprogress;
-    attribute EventListener onratechange;
-    attribute EventListener onreset;
-    attribute EventListener onresize;
-    attribute EventListener onscroll;
-    attribute EventListener onsearch;
-    attribute EventListener onseeked;
-    attribute EventListener onseeking;
-    attribute EventListener onselect;
-    attribute EventListener onstalled;
-    attribute EventListener onstorage;
-    attribute EventListener onsubmit;
-    attribute EventListener onsuspend;
-    attribute EventListener ontimeupdate;
-    attribute EventListener ontransitionend;
-    attribute EventListener onunload;
-    attribute EventListener onvolumechange;
-    attribute EventListener onwaiting;
-    attribute EventListener onwebkitanimationend;
-    attribute EventListener onwebkitanimationiteration;
-    attribute EventListener onwebkitanimationstart;
-    attribute EventListener onwebkittransitionend;
-    attribute EventListener onwheel;
-
-    [Conditional=DEVICE_ORIENTATION] attribute EventListener ondevicemotion;
-    [Conditional=DEVICE_ORIENTATION] attribute EventListener ondeviceorientation;
-
-    [Conditional=IOS_GESTURE_EVENTS] attribute EventListener ongesturestart;
-    [Conditional=IOS_GESTURE_EVENTS] attribute EventListener ongesturechange;
-    [Conditional=IOS_GESTURE_EVENTS] attribute EventListener ongestureend;
-
-    [Conditional=ORIENTATION_EVENTS] attribute EventListener onorientationchange;
-
-    [Conditional=TOUCH_EVENTS] attribute EventListener ontouchstart;
-    [Conditional=TOUCH_EVENTS] attribute EventListener ontouchmove;
-    [Conditional=TOUCH_EVENTS] attribute EventListener ontouchend;
-    [Conditional=TOUCH_EVENTS] attribute EventListener ontouchcancel;
-
-    [Conditional=PROXIMITY_EVENTS] attribute EventListener onwebkitdeviceproximity;
-
-    [Conditional=WILL_REVEAL_EDGE_EVENTS] attribute EventListener onwebkitwillrevealbottom;
-    [Conditional=WILL_REVEAL_EDGE_EVENTS] attribute EventListener onwebkitwillrevealleft;
-    [Conditional=WILL_REVEAL_EDGE_EVENTS] attribute EventListener onwebkitwillrevealright;
-    [Conditional=WILL_REVEAL_EDGE_EVENTS] attribute EventListener onwebkitwillrevealtop;
+    [NotEnumerable] attribute EventHandler onabort;
+    [NotEnumerable] attribute EventHandler onanimationend;
+    [NotEnumerable] attribute EventHandler onanimationiteration;
+    [NotEnumerable] attribute EventHandler onanimationstart;
+    [NotEnumerable] attribute EventHandler onbeforeunload;
+    [NotEnumerable] attribute EventHandler onblur;
+    [NotEnumerable] attribute EventHandler oncanplay;
+    [NotEnumerable] attribute EventHandler oncanplaythrough;
+    [NotEnumerable] attribute EventHandler onchange;
+    [NotEnumerable] attribute EventHandler onclick;
+    [NotEnumerable] attribute EventHandler oncontextmenu;
+    [NotEnumerable] attribute EventHandler ondblclick;
+    [NotEnumerable] attribute EventHandler ondevicemotion;
+    [NotEnumerable] attribute EventHandler ondeviceorientation;
+    [NotEnumerable] attribute EventHandler ondrag;
+    [NotEnumerable] attribute EventHandler ondragend;
+    [NotEnumerable] attribute EventHandler ondragenter;
+    [NotEnumerable] attribute EventHandler ondragleave;
+    [NotEnumerable] attribute EventHandler ondragover;
+    [NotEnumerable] attribute EventHandler ondragstart;
+    [NotEnumerable] attribute EventHandler ondrop;
+    [NotEnumerable] attribute EventHandler ondurationchange;
+    [NotEnumerable] attribute EventHandler onemptied;
+    [NotEnumerable] attribute EventHandler onended;
+    [NotEnumerable] attribute EventHandler onerror;
+    [NotEnumerable] attribute EventHandler onfocus;
+    [NotEnumerable] attribute EventHandler ongesturechange;
+    [NotEnumerable] attribute EventHandler ongestureend;
+    [NotEnumerable] attribute EventHandler ongesturestart;
+    [NotEnumerable] attribute EventHandler onhashchange;
+    [NotEnumerable] attribute EventHandler oninput;
+    [NotEnumerable] attribute EventHandler oninvalid;
+    [NotEnumerable] attribute EventHandler onkeydown;
+    [NotEnumerable] attribute EventHandler onkeypress;
+    [NotEnumerable] attribute EventHandler onkeyup;
+    [NotEnumerable] attribute EventHandler onload;
+    [NotEnumerable] attribute EventHandler onloadeddata;
+    [NotEnumerable] attribute EventHandler onloadedmetadata;
+    [NotEnumerable] attribute EventHandler onloadstart;
+    [NotEnumerable] attribute EventHandler onmessage;
+    [NotEnumerable] attribute EventHandler onmousedown;
+    [NotEnumerable] attribute EventHandler onmouseenter;
+    [NotEnumerable] attribute EventHandler onmouseleave;
+    [NotEnumerable] attribute EventHandler onmousemove;
+    [NotEnumerable] attribute EventHandler onmouseout;
+    [NotEnumerable] attribute EventHandler onmouseover;
+    [NotEnumerable] attribute EventHandler onmouseup;
+    [NotEnumerable] attribute EventHandler onmousewheel;
+    [NotEnumerable] attribute EventHandler onoffline;
+    [NotEnumerable] attribute EventHandler ononline;
+    [NotEnumerable] attribute EventHandler onorientationchange;
+    [NotEnumerable] attribute EventHandler onpagehide;
+    [NotEnumerable] attribute EventHandler onpageshow;
+    [NotEnumerable] attribute EventHandler onpause;
+    [NotEnumerable] attribute EventHandler onplay;
+    [NotEnumerable] attribute EventHandler onplaying;
+    [NotEnumerable] attribute EventHandler onpopstate;
+    [NotEnumerable] attribute EventHandler onprogress;
+    [NotEnumerable] attribute EventHandler onratechange;
+    [NotEnumerable] attribute EventHandler onreset;
+    [NotEnumerable] attribute EventHandler onresize;
+    [NotEnumerable] attribute EventHandler onscroll;
+    [NotEnumerable] attribute EventHandler onsearch;
+    [NotEnumerable] attribute EventHandler onseeked;
+    [NotEnumerable] attribute EventHandler onseeking;
+    [NotEnumerable] attribute EventHandler onselect;
+    [NotEnumerable] attribute EventHandler onstalled;
+    [NotEnumerable] attribute EventHandler onstorage;
+    [NotEnumerable] attribute EventHandler onsubmit;
+    [NotEnumerable] attribute EventHandler onsuspend;
+    [NotEnumerable] attribute EventHandler ontimeupdate;
+    [NotEnumerable] attribute EventHandler ontouchcancel;
+    [NotEnumerable] attribute EventHandler ontouchend;
+    [NotEnumerable] attribute EventHandler ontouchmove;
+    [NotEnumerable] attribute EventHandler ontouchstart;
+    [NotEnumerable] attribute EventHandler ontransitionend;
+    [NotEnumerable] attribute EventHandler onunload;
+    [NotEnumerable] attribute EventHandler onvolumechange;
+    [NotEnumerable] attribute EventHandler onwaiting;
+    [NotEnumerable] attribute EventHandler onwebkitanimationend;
+    [NotEnumerable] attribute EventHandler onwebkitanimationiteration;
+    [NotEnumerable] attribute EventHandler onwebkitanimationstart;
+    [NotEnumerable] attribute EventHandler onwebkitdeviceproximity;
+    [NotEnumerable] attribute EventHandler onwebkittransitionend;
+    [NotEnumerable] attribute EventHandler onwebkitwillrevealbottom;
+    [NotEnumerable] attribute EventHandler onwebkitwillrevealleft;
+    [NotEnumerable] attribute EventHandler onwebkitwillrevealright;
+    [NotEnumerable] attribute EventHandler onwebkitwillrevealtop;
+    [NotEnumerable] attribute EventHandler onwheel;
 
     // EventTarget interface
     [Custom] void addEventListener(DOMString type, EventListener listener, optional boolean useCapture);
index ea888b5..e011e41 100644 (file)
     readonly attribute unsigned short readyState;
 
     // networking
-    attribute EventListener onopen;
-    attribute EventListener onmessage;
-    attribute EventListener onerror;
+    attribute EventHandler onopen;
+    attribute EventHandler onmessage;
+    attribute EventHandler onerror;
     void close();
 
     // EventTarget interface
-    void addEventListener(DOMString type,
-                          EventListener listener,
-                          optional boolean useCapture);
-    void removeEventListener(DOMString type,
-                             EventListener listener,
-                             optional boolean useCapture);
-    [RaisesException] boolean dispatchEvent(Event evt);
+    void addEventListener(DOMString type, EventListener listener, optional boolean useCapture);
+    void removeEventListener(DOMString type, EventListener listener, optional boolean useCapture);
+    [RaisesException] boolean dispatchEvent(Event event);
 
 };
index 556d956..81117d2 100644 (file)
@@ -47,7 +47,7 @@
     void webkitClearResourceTimings();
     void webkitSetResourceTimingBufferSize(unsigned long maxSize);
 
-    attribute EventListener onwebkitresourcetimingbufferfull;
+    attribute EventHandler onwebkitresourcetimingbufferfull;
 #endif
 
     // See http://www.w3.org/TR/2012/CR-user-timing-20120726/
index 9fbb4d1..68b0324 100644 (file)
@@ -510,9 +510,12 @@ void SVGElement::setCorrespondingElement(SVGElement* correspondingElement)
 
 void SVGElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
 {
-    if (name == HTMLNames::classAttr)
+    if (name == HTMLNames::classAttr) {
         setClassNameBaseValue(value);
-    else if (name == HTMLNames::tabindexAttr) {
+        return;
+    }
+
+    if (name == HTMLNames::tabindexAttr) {
         int tabindex = 0;
         if (value.isEmpty())
             clearTabIndexExplicitlyIfNeeded();
@@ -520,21 +523,16 @@ void SVGElement::parseAttribute(const QualifiedName& name, const AtomicString& v
             // Clamp tabindex to the range of 'short' to match Firefox's behavior.
             setTabIndexExplicitly(std::max(static_cast<int>(std::numeric_limits<short>::min()), std::min(tabindex, static_cast<int>(std::numeric_limits<short>::max()))));
         }
-    } else if (SVGLangSpace::parseAttribute(name, value))
         return;
-    else {
-        // FIXME: Can we do this even faster by checking the local name "on" prefix before we do anything with the map?
-        // See HTMLElement::parseAttribute().
-        static NeverDestroyed<HashMap<AtomicStringImpl*, AtomicString>> eventNamesGlobal;
-        auto& eventNames = eventNamesGlobal.get();
-        if (eventNames.isEmpty())
-            HTMLElement::populateEventNameForAttributeLocalNameMap(eventNames);
-        const AtomicString& eventName = eventNames.get(name.localName().impl());
-        if (!eventName.isNull())
-            setAttributeEventListener(eventName, name, value);
-        else
-            StyledElement::parseAttribute(name, value);
     }
+
+    auto& eventName = HTMLElement::eventNameForEventHandlerAttribute(name);
+    if (!eventName.isNull()) {
+        setAttributeEventListener(eventName, name, value);
+        return;
+    }
+
+    SVGLangSpace::parseAttribute(name, value);
 }
 
 Vector<AnimatedPropertyType> SVGElement::animatedPropertyTypesForAttribute(const QualifiedName& attributeName)
index ea531c1..988861b 100644 (file)
@@ -199,10 +199,8 @@ void SVGSVGElement::updateCurrentTranslate()
 void SVGSVGElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
 {
     if (!nearestViewportElement()) {
-        // Since we only handle events if we're the outermost <svg> element, set listeners only
-        // if we are. Set the listeners directly on the window attribute.
-        // FIXME: This strategy is wrong. It won't work if we an existing <svg> element becomes
-        // the outermost or if an existing <svg> element later becomes no longer outmost.
+        // For these events, the outermost <svg> element works like a <body> element does,
+        // setting certain event handlers directly on the window object.
         if (name == HTMLNames::onunloadAttr) {
             document().setWindowAttributeEventListener(eventNames().unloadEvent, name, value);
             return;
@@ -221,13 +219,21 @@ void SVGSVGElement::parseAttribute(const QualifiedName& name, const AtomicString
         }
     }
 
-    SVGParsingError parseError = NoError;
-
-    if (name == HTMLNames::onabortAttr)
+    // For these events, any <svg> element works like a <body> element does,
+    // setting certain event handlers directly on the window object.
+    // FIXME: Why different from the events above that work only on the outermost <svg> element?
+    if (name == HTMLNames::onabortAttr) {
         document().setWindowAttributeEventListener(eventNames().abortEvent, name, value);
-    else if (name == HTMLNames::onerrorAttr)
+        return;
+    }
+    if (name == HTMLNames::onerrorAttr) {
         document().setWindowAttributeEventListener(eventNames().errorEvent, name, value);
-    else if (name == SVGNames::xAttr)
+        return;
+    }
+
+    SVGParsingError parseError = NoError;
+
+    if (name == SVGNames::xAttr)
         setXBaseValue(SVGLength::construct(LengthModeWidth, value, parseError));
     else if (name == SVGNames::yAttr)
         setYBaseValue(SVGLength::construct(LengthModeHeight, value, parseError));
index b87f990..ce77ab7 100644 (file)
@@ -55,62 +55,24 @@ Ref<SVGScriptElement> SVGScriptElement::create(const QualifiedName& tagName, Doc
     return adoptRef(*new SVGScriptElement(tagName, document, insertedByParser, false));
 }
 
-bool SVGScriptElement::isSupportedAttribute(const QualifiedName& attrName)
-{
-    static NeverDestroyed<HashSet<QualifiedName>> supportedAttributes;
-    if (supportedAttributes.get().isEmpty()) {
-        SVGURIReference::addSupportedAttributes(supportedAttributes);
-        SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes);
-        supportedAttributes.get().add(SVGNames::typeAttr);
-        supportedAttributes.get().add(HTMLNames::onerrorAttr);
-    }
-    return supportedAttributes.get().contains<SVGAttributeHashTranslator>(attrName);
-}
-
 void SVGScriptElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
 {
-    if (!isSupportedAttribute(name)) {
-        SVGElement::parseAttribute(name, value);
-        return;
-    }
-
-    if (name == SVGNames::typeAttr)
-        return;
-
-    if (name == HTMLNames::onerrorAttr) {
-        setAttributeEventListener(eventNames().errorEvent, name, value);
-        return;
-    }
-
-    if (SVGURIReference::parseAttribute(name, value))
-        return;
-    if (SVGExternalResourcesRequired::parseAttribute(name, value))
-        return;
-
-    ASSERT_NOT_REACHED();
+    SVGElement::parseAttribute(name, value);
+    SVGURIReference::parseAttribute(name, value);
+    SVGExternalResourcesRequired::parseAttribute(name, value);
 }
 
 void SVGScriptElement::svgAttributeChanged(const QualifiedName& attrName)
 {
-    if (!isSupportedAttribute(attrName)) {
-        SVGElement::svgAttributeChanged(attrName);
-        return;
-    }
-
     InstanceInvalidationGuard guard(*this);
 
-    if (attrName == SVGNames::typeAttr || attrName == HTMLNames::onerrorAttr)
-        return;
-
     if (SVGURIReference::isKnownAttribute(attrName)) {
         handleSourceAttribute(href());
         return;
     }
 
-    if (SVGExternalResourcesRequired::handleAttributeChange(this, attrName))
-        return;
-
-    ASSERT_NOT_REACHED();
+    SVGExternalResourcesRequired::handleAttributeChange(this, attrName);
+    SVGElement::svgAttributeChanged(attrName);
 }
 
 Node::InsertionNotificationRequest SVGScriptElement::insertedInto(ContainerNode& rootParent)
index 9e9bb16..dec3e40 100644 (file)
@@ -40,7 +40,6 @@ public:
 private:
     SVGScriptElement(const QualifiedName&, Document&, bool wasInsertedByParser, bool alreadyStarted);
 
-    bool isSupportedAttribute(const QualifiedName&);
     virtual void parseAttribute(const QualifiedName&, const AtomicString&) override;
     virtual InsertionNotificationRequest insertedInto(ContainerNode&) override;
     virtual void childrenChanged(const ChildChange&) override;
index b2aee68..3933b93 100644 (file)
@@ -32,6 +32,6 @@
 [
     NoInterfaceObject,
 ] interface AbstractWorker {
-    attribute EventListener onerror;
+    attribute EventHandler onerror;
 };
 
index df7f966..01f3739 100644 (file)
@@ -41,7 +41,6 @@
     [RaisesException] void postMessage(DOMString message, optional MessagePort messagePort);
 #endif
 
-             attribute EventListener onmessage;
-
+    attribute EventHandler onmessage;
 };
 
index 80b05b2..33c27d0 100644 (file)
@@ -32,7 +32,7 @@
     ActiveDOMObject,
 ] interface Worker : EventTarget {
 
-    attribute EventListener onmessage;
+    attribute EventHandler onmessage;
 
 #if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT
     [Custom, RaisesException] void postMessage(SerializedScriptValue message, optional Array messagePorts);
index 05e35ac..57f39b3 100644 (file)
@@ -39,9 +39,9 @@
     [Replaceable] readonly attribute WorkerLocation location;
     void close();
 
-    attribute EventListener onerror;
-    attribute EventListener onoffline;
-    attribute EventListener ononline;
+    attribute EventHandler onerror;
+    attribute EventHandler onoffline;
+    attribute EventHandler ononline;
 
     // WorkerUtils
 
index 3a0320a..b71a391 100644 (file)
@@ -44,17 +44,15 @@ enum XMLHttpRequestResponseType {
     EventTarget,
 ] interface XMLHttpRequest {
     // From XMLHttpRequestEventTarget
-    // event handler attributes
-    attribute EventListener onabort;
-    attribute EventListener onerror;
-    attribute EventListener onload;
-    attribute EventListener onloadend;
-    attribute EventListener onloadstart;
-    attribute EventListener onprogress;
-    [Conditional=XHR_TIMEOUT] attribute EventListener ontimeout;
-
-    // event handler attributes
-    attribute EventListener onreadystatechange;
+    attribute EventHandler onabort;
+    attribute EventHandler onerror;
+    attribute EventHandler onload;
+    attribute EventHandler onloadend;
+    attribute EventHandler onloadstart;
+    attribute EventHandler onprogress;
+    [Conditional=XHR_TIMEOUT] attribute EventHandler ontimeout;
+
+    attribute EventHandler onreadystatechange;
 
     // state
     const unsigned short UNSENT = 0;
@@ -95,11 +93,7 @@ enum XMLHttpRequestResponseType {
     [RaisesException] void overrideMimeType(DOMString override);
 
     // EventTarget interface
-    void addEventListener(DOMString type, 
-                          EventListener listener, 
-                          optional boolean useCapture);
-    void removeEventListener(DOMString type, 
-                             EventListener listener, 
-                             optional boolean useCapture);
-    [RaisesException] boolean dispatchEvent(Event evt);
+    void addEventListener(DOMString type, EventListener listener, optional boolean useCapture);
+    void removeEventListener(DOMString type, EventListener listener, optional boolean useCapture);
+    [RaisesException] boolean dispatchEvent(Event event);
 };
index a0559c8..924dfe5 100644 (file)
     EventTarget,
 ] interface XMLHttpRequestUpload {
     // From XMLHttpRequestEventTarget
-    // event handler attributes
-    attribute EventListener onabort;
-    attribute EventListener onerror;
-    attribute EventListener onload;
-    attribute EventListener onloadend;
-    attribute EventListener onloadstart;
-    attribute EventListener onprogress;
+    attribute EventHandler onabort;
+    attribute EventHandler onerror;
+    attribute EventHandler onload;
+    attribute EventHandler onloadend;
+    attribute EventHandler onloadstart;
+    attribute EventHandler onprogress;
 
     // EventTarget interface
-    void addEventListener(DOMString type, 
-                          EventListener listener, 
-                          optional boolean useCapture);
-    void removeEventListener(DOMString type, 
-                             EventListener listener, 
-                             optional boolean useCapture);
-    [RaisesException] boolean dispatchEvent(Event evt);
+    void addEventListener(DOMString type, EventListener listener, optional boolean useCapture);
+    void removeEventListener(DOMString type, EventListener listener, optional boolean useCapture);
+    [RaisesException] boolean dispatchEvent(Event event);
 };