Skip to content

Commit

Permalink
Implement EventTarget constructor
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=174313

Reviewed by Darin Adler.

LayoutTests/imported/w3c:

* web-platform-tests/WebIDL/ecmascript-binding/constructors-expected.txt:
* web-platform-tests/dom/events/Event-subclasses-constructors-expected.txt:
* web-platform-tests/dom/events/EventTarget-constructible.any-expected.txt:
* web-platform-tests/dom/events/EventTarget-constructible.any.worker-expected.txt:
* web-platform-tests/dom/events/event-global-extra.window-expected.txt:
* web-platform-tests/dom/idlharness.any.worker-expected.txt:
* web-platform-tests/dom/idlharness.window-expected.txt:

Source/WebCore:

Currently, EventTarget can't be directly constructed or be subclassed in JavaScript.
The spec for EventTarget was updated (whatwg/dom#467) to allow
constructing and subclassing EventTarget. This feature was shipped in Chrome 64 and Firefox 59.

This patch introduces EventTargetConcrete class, a user-constructable version of EventTarget,
exposed as "EventTarget" to JavaScript. We don't use EventTarget directly because it is an abstract
class and making it non-abstract is unfavorable due to size increase of EventTarget and all of its
subclasses with code that is mostly unnecessary for them, resulting in a performance decrease.

To prevent definition of specific to EventTargetConcrete `toJS` and `toJSNewlyCreated` functions,
we don't define EventTargetConcrete interface type, but rather tweak make_event_factory.pl to
default to base interface (like it does for Event).

To allow subclassing of all DOM constructors, non-custom ones replace structures of newly created
wrapper objects with ones returned by InternalFunction::createSubclassStructure. Per WebIDL spec [1],
`setSubclassStructureIfNeeded` helper uses realm of `newTarget` for default prototypes.

This approach was chosen because a) detecting [[Construct]] with callFrame->newTarget() is
unreliable outside constructor, and b) passing `newTarget` down to `createWrapper` via
`toJSNewlyCreated` is quite awkward and would result in massive code change.

[1] https://heycam.github.io/webidl/#internally-create-a-new-object-implementing-the-interface
(step 3.3.2)

Tests: fast/dom/dom-constructors.html
       imported/w3c/web-platform-tests/WebIDL/ecmascript-binding/constructors.html
       imported/w3c/web-platform-tests/dom/events/Event-subclasses-constructors.html
       imported/w3c/web-platform-tests/dom/events/EventTarget-constructible.any.html
       imported/w3c/web-platform-tests/dom/idlharness.window.html

* Headers.cmake:
* Sources.txt:
* WebCore.xcodeproj/project.pbxproj:
* bindings/js/JSDOMWrapperCache.h:
(WebCore::setSubclassStructureIfNeeded):
* bindings/js/JSEventTargetCustom.cpp:
(WebCore::toJSNewlyCreated):
* bindings/scripts/CodeGeneratorJS.pm:
(GenerateConstructorDefinition):
* bindings/scripts/InFilesCompiler.pm:
(generateInterfacesHeader):
* bindings/scripts/test/JS/*: Adjust bindings expectations.
* dom/EventTarget.cpp:
(WebCore::EventTarget::create):
* dom/EventTarget.h:
* dom/EventTarget.idl:
* dom/EventTargetConcrete.cpp: Added.
* dom/EventTargetConcrete.h: Added.
* dom/make_event_factory.pl:
(generateImplementation):

LayoutTests:

* fast/dom/dom-constructors-expected.txt:
* fast/dom/dom-constructors.html:
* platform/ios/imported/w3c/web-platform-tests/dom/events/Event-subclasses-constructors-expected.txt: Removed.


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@256716 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
shvaikalesh@gmail.com committed Feb 17, 2020
1 parent 3c14cc0 commit e1b7274
Show file tree
Hide file tree
Showing 35 changed files with 336 additions and 120 deletions.
11 changes: 11 additions & 0 deletions LayoutTests/ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
2020-02-16 Alexey Shvayka <shvaikalesh@gmail.com>

Implement EventTarget constructor
https://bugs.webkit.org/show_bug.cgi?id=174313

Reviewed by Darin Adler.

* fast/dom/dom-constructors-expected.txt:
* fast/dom/dom-constructors.html:
* platform/ios/imported/w3c/web-platform-tests/dom/events/Event-subclasses-constructors-expected.txt: Removed.

2020-02-16 Wenson Hsieh <wenson_hsieh@apple.com>

Add a layout test for <rdar://problem/59090510>
Expand Down
4 changes: 3 additions & 1 deletion LayoutTests/fast/dom/dom-constructors-expected.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ PASS TryAllocate('CharacterData') is 'exception'
PASS TryAllocate('CDATASection') is 'exception'
PASS TryAllocate('DocumentType') is 'exception'
PASS TryAllocate('Element') is 'exception'
PASS TryAllocate('EventTarget') is 'exception'
PASS TryAllocate('HTMLDocument') is 'exception'
PASS TryAllocate('Node') is 'exception'
PASS TryAllocate('ProcessingInstruction') is 'exception'
Expand Down Expand Up @@ -131,6 +130,9 @@ PASS TryAllocate('Document') is '[object Document]'
PASS TryAllocate('DocumentFragment') is '[object DocumentFragment]'
PASS TryAllocate('DocumentFragment') is '[object DocumentFragment]'
PASS TryAllocate('DocumentFragment') is '[object DocumentFragment]'
PASS TryAllocate('EventTarget') is '[object EventTarget]'
PASS TryAllocate('EventTarget') is '[object EventTarget]'
PASS TryAllocate('EventTarget') is '[object EventTarget]'
PASS TryAllocate('Range') is '[object Range]'
PASS TryAllocate('Range') is '[object Range]'
PASS TryAllocate('Range') is '[object Range]'
Expand Down
2 changes: 1 addition & 1 deletion LayoutTests/fast/dom/dom-constructors.html
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
'CDATASection',
'DocumentType',
'Element',
'EventTarget',
'HTMLDocument',
'Node',
'ProcessingInstruction',
Expand Down Expand Up @@ -132,6 +131,7 @@
'DOMParser',
'Document',
'DocumentFragment',
'EventTarget',
'Range',
'Text',
'XMLHttpRequest',
Expand Down
15 changes: 15 additions & 0 deletions LayoutTests/imported/w3c/ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
2020-02-16 Alexey Shvayka <shvaikalesh@gmail.com>

Implement EventTarget constructor
https://bugs.webkit.org/show_bug.cgi?id=174313

Reviewed by Darin Adler.

* web-platform-tests/WebIDL/ecmascript-binding/constructors-expected.txt:
* web-platform-tests/dom/events/Event-subclasses-constructors-expected.txt:
* web-platform-tests/dom/events/EventTarget-constructible.any-expected.txt:
* web-platform-tests/dom/events/EventTarget-constructible.any.worker-expected.txt:
* web-platform-tests/dom/events/event-global-extra.window-expected.txt:
* web-platform-tests/dom/idlharness.any.worker-expected.txt:
* web-platform-tests/dom/idlharness.window-expected.txt:

2020-02-14 Rossana Monteriso <rmonteriso@igalia.com>

[css-grid] Move grid-gutters-and-alignment test to WPT folder
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@
PASS Realm for constructed objects
PASS Normal constructor in parent window
PASS Normal constructor in child window
FAIL Constructor in child window with normal NewTarget from parent window assert_equals: expected object "[object DOMParserPrototype]" but got object "[object DOMParserPrototype]"
FAIL Constructor in parent window with normal NewTarget from child window assert_equals: expected object "[object DOMParserPrototype]" but got object "[object DOMParserPrototype]"
FAIL Subclass constructor in parent window assert_equals: expected object "[object Object]" but got object "[object DOMParserPrototype]"
FAIL Subclass constructor in child window assert_equals: expected object "[object Object]" but got object "[object DOMParserPrototype]"
FAIL Subclass constructor in parent window with parent class in child window assert_equals: expected object "[object Object]" but got object "[object DOMParserPrototype]"
FAIL Subclass constructor in child window with parent class in parent window assert_equals: expected object "[object Object]" but got object "[object DOMParserPrototype]"
FAIL Constructor in child window with bad NewTarget from parent window assert_equals: expected object "[object DOMParserPrototype]" but got object "[object DOMParserPrototype]"
FAIL Constructor in parent window with bad NewTarget from child window assert_equals: expected object "[object DOMParserPrototype]" but got object "[object DOMParserPrototype]"
PASS Constructor in child window with normal NewTarget from parent window
PASS Constructor in parent window with normal NewTarget from child window
PASS Subclass constructor in parent window
PASS Subclass constructor in child window
PASS Subclass constructor in parent window with parent class in child window
PASS Subclass constructor in child window with parent class in parent window
PASS Constructor in child window with bad NewTarget from parent window
PASS Constructor in parent window with bad NewTarget from child window
FAIL Constructor in parent window with bad NewTarget from parent window that's a bound child window function assert_equals: expected object "[object DOMParserPrototype]" but got object "[object DOMParserPrototype]"
FAIL Constructor in child window with bad NewTarget from child window that's a bound parent window function assert_equals: expected object "[object DOMParserPrototype]" but got object "[object DOMParserPrototype]"
FAIL Constructor in parent window with bad NewTarget from parent window that's a proxy for a child window function assert_equals: expected object "[object DOMParserPrototype]" but got object "[object DOMParserPrototype]"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,11 @@ PASS CompositionEvent constructor (null argument)
PASS CompositionEvent constructor (empty argument)
PASS CompositionEvent constructor (argument with default values)
PASS CompositionEvent constructor (argument with non-default values)
FAIL SubclassedEvent constructor (no argument) assert_true: expected true got false
FAIL SubclassedEvent constructor (undefined argument) assert_true: expected true got false
FAIL SubclassedEvent constructor (null argument) assert_true: expected true got false
FAIL SubclassedEvent constructor (empty argument) assert_true: expected true got false
FAIL SubclassedEvent constructor (argument with default values) assert_true: expected true got false
FAIL SubclassedEvent constructor (argument with non-default values) assert_true: expected true got false
PASS SubclassedEvent constructor (no argument)
PASS SubclassedEvent constructor (undefined argument)
PASS SubclassedEvent constructor (null argument)
PASS SubclassedEvent constructor (empty argument)
PASS SubclassedEvent constructor (argument with default values)
PASS SubclassedEvent constructor (argument with non-default values)
PASS UIEvent constructor (view argument with wrong type)

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@

FAIL A constructed EventTarget can be used as expected function is not a constructor (evaluating 'new EventTarget()')
FAIL EventTarget can be subclassed function is not a constructor (evaluating 'super(...args)')
PASS A constructed EventTarget can be used as expected
PASS EventTarget can be subclassed

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@

FAIL A constructed EventTarget can be used as expected function is not a constructor (evaluating 'new EventTarget()')
FAIL EventTarget can be subclassed function is not a constructor (evaluating 'super(...args)')
PASS A constructed EventTarget can be used as expected
PASS EventTarget can be subclassed

Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

FAIL window.event for constructors from another global: EventTarget function is not a constructor (evaluating 'new otherWindow[constructorName]()')
FAIL window.event for constructors from another global: EventTarget assert_equals: expected (undefined) undefined but got (object) object "[object Event]"
FAIL window.event for constructors from another global: XMLHttpRequest assert_equals: expected (undefined) undefined but got (object) object "[object Event]"
PASS window.event and element from another document
FAIL window.event and moving an element post-dispatch assert_equals: expected (object) object "[object Event]" but got (undefined) undefined
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,14 +133,14 @@ PASS EventTarget interface: existence and properties of interface prototype obje
PASS EventTarget interface: operation addEventListener(DOMString, EventListener, [object Object],[object Object])
PASS EventTarget interface: operation removeEventListener(DOMString, EventListener, [object Object],[object Object])
PASS EventTarget interface: operation dispatchEvent(Event)
FAIL EventTarget must be primary interface of new EventTarget() assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: function is not a constructor (evaluating 'new EventTarget()')"
FAIL Stringification of new EventTarget() assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: function is not a constructor (evaluating 'new EventTarget()')"
FAIL EventTarget interface: new EventTarget() must inherit property "addEventListener(DOMString, EventListener, [object Object],[object Object])" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: function is not a constructor (evaluating 'new EventTarget()')"
FAIL EventTarget interface: calling addEventListener(DOMString, EventListener, [object Object],[object Object]) on new EventTarget() with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: function is not a constructor (evaluating 'new EventTarget()')"
FAIL EventTarget interface: new EventTarget() must inherit property "removeEventListener(DOMString, EventListener, [object Object],[object Object])" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: function is not a constructor (evaluating 'new EventTarget()')"
FAIL EventTarget interface: calling removeEventListener(DOMString, EventListener, [object Object],[object Object]) on new EventTarget() with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: function is not a constructor (evaluating 'new EventTarget()')"
FAIL EventTarget interface: new EventTarget() must inherit property "dispatchEvent(Event)" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: function is not a constructor (evaluating 'new EventTarget()')"
FAIL EventTarget interface: calling dispatchEvent(Event) on new EventTarget() with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: function is not a constructor (evaluating 'new EventTarget()')"
PASS EventTarget must be primary interface of new EventTarget()
PASS Stringification of new EventTarget()
PASS EventTarget interface: new EventTarget() must inherit property "addEventListener(DOMString, EventListener, [object Object],[object Object])" with the proper type
PASS EventTarget interface: calling addEventListener(DOMString, EventListener, [object Object],[object Object]) on new EventTarget() with too few arguments must throw TypeError
PASS EventTarget interface: new EventTarget() must inherit property "removeEventListener(DOMString, EventListener, [object Object],[object Object])" with the proper type
PASS EventTarget interface: calling removeEventListener(DOMString, EventListener, [object Object],[object Object]) on new EventTarget() with too few arguments must throw TypeError
PASS EventTarget interface: new EventTarget() must inherit property "dispatchEvent(Event)" with the proper type
PASS EventTarget interface: calling dispatchEvent(Event) on new EventTarget() with too few arguments must throw TypeError
PASS EventListener interface: existence and properties of interface object
PASS AbortController interface: existence and properties of interface object
PASS AbortController interface object length
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,14 +158,14 @@ PASS EventTarget interface: existence and properties of interface prototype obje
PASS EventTarget interface: operation addEventListener(DOMString, EventListener, [object Object],[object Object])
PASS EventTarget interface: operation removeEventListener(DOMString, EventListener, [object Object],[object Object])
PASS EventTarget interface: operation dispatchEvent(Event)
FAIL EventTarget must be primary interface of new EventTarget() assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: function is not a constructor (evaluating 'new EventTarget()')"
FAIL Stringification of new EventTarget() assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: function is not a constructor (evaluating 'new EventTarget()')"
FAIL EventTarget interface: new EventTarget() must inherit property "addEventListener(DOMString, EventListener, [object Object],[object Object])" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: function is not a constructor (evaluating 'new EventTarget()')"
FAIL EventTarget interface: calling addEventListener(DOMString, EventListener, [object Object],[object Object]) on new EventTarget() with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: function is not a constructor (evaluating 'new EventTarget()')"
FAIL EventTarget interface: new EventTarget() must inherit property "removeEventListener(DOMString, EventListener, [object Object],[object Object])" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: function is not a constructor (evaluating 'new EventTarget()')"
FAIL EventTarget interface: calling removeEventListener(DOMString, EventListener, [object Object],[object Object]) on new EventTarget() with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: function is not a constructor (evaluating 'new EventTarget()')"
FAIL EventTarget interface: new EventTarget() must inherit property "dispatchEvent(Event)" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: function is not a constructor (evaluating 'new EventTarget()')"
FAIL EventTarget interface: calling dispatchEvent(Event) on new EventTarget() with too few arguments must throw TypeError assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: function is not a constructor (evaluating 'new EventTarget()')"
PASS EventTarget must be primary interface of new EventTarget()
PASS Stringification of new EventTarget()
PASS EventTarget interface: new EventTarget() must inherit property "addEventListener(DOMString, EventListener, [object Object],[object Object])" with the proper type
PASS EventTarget interface: calling addEventListener(DOMString, EventListener, [object Object],[object Object]) on new EventTarget() with too few arguments must throw TypeError
PASS EventTarget interface: new EventTarget() must inherit property "removeEventListener(DOMString, EventListener, [object Object],[object Object])" with the proper type
PASS EventTarget interface: calling removeEventListener(DOMString, EventListener, [object Object],[object Object]) on new EventTarget() with too few arguments must throw TypeError
PASS EventTarget interface: new EventTarget() must inherit property "dispatchEvent(Event)" with the proper type
PASS EventTarget interface: calling dispatchEvent(Event) on new EventTarget() with too few arguments must throw TypeError
PASS EventListener interface: existence and properties of interface object
PASS EventListener interface: existence and properties of interface prototype object
PASS EventListener interface: existence and properties of interface prototype object's "constructor" property
Expand Down

This file was deleted.

Loading

0 comments on commit e1b7274

Please sign in to comment.