[Web IDL] interface objects should be Function objects
https://bugs.webkit.org/show_bug.cgi?id=154038
<rdar://problem/24569358>
Reviewed by Geoffrey Garen.
LayoutTests/imported/w3c:
Rebaseline W3C tests now that more checks are passing. Some checks still
fail because a lot of our interfaces should inherit EventTarget and
currently don't (they duplicate the EventTarget API instead).
Also, as per WebIDL, window.NodeFilter's proto should be ObjectPrototype
instead of FunctionPrototype but this is an exceptional case and our new
behavior is consistent with Firefox and Chrome.
* web-platform-tests/XMLHttpRequest/interfaces-expected.txt:
* web-platform-tests/dom/events/Event-constructors-expected.txt:
* web-platform-tests/dom/historical-expected.txt:
* web-platform-tests/dom/interfaces-expected.txt:
* web-platform-tests/fetch/api/headers/headers-idl-expected.txt:
* web-platform-tests/fetch/api/request/request-idl-expected.txt:
* web-platform-tests/html/dom/interfaces-expected.txt:
* web-platform-tests/html/semantics/embedded-content/the-audio-element/audio_constructor-expected.txt:
Source/JavaScriptCore:
Update functionProtoFuncToString() to handle JSObjects that
have the TypeOfShouldCallGetCallData flag and are callable,
as these behave like functions and use ClassInfo::className()
as function name in this case.
* runtime/FunctionPrototype.cpp:
(JSC::functionProtoFuncToString):
Source/WebCore:
interface objects should be Function objects as per Web IDL:
- http://heycam.github.io/webidl/#interface-object
- http://heycam.github.io/webidl/#es-interfaces
So window.Event should be a Function object for e.g. but in WebKit it
is a regular EventConstructor JSObject.
Firefox and Chrome match the specification.
Test: js/interface-objects.html
* bindings/js/JSDOMBinding.cpp:
(WebCore::callThrowTypeError):
(WebCore::DOMConstructorObject::getCallData):
When calling the interface object as a function, we throw a TypeError
with a message asking to use the 'new' operator to match the behavior
of Firefox and Chrome.
* bindings/js/JSDOMBinding.h:
Add JSC::TypeOfShouldCallGetCallData structure flag and implement
getCallData() so that typeof returns "function", as per the
specification and the behavior of other browsers.
(WebCore::DOMConstructorObject::className):
Implement className() and return "Function" to match the specification and
other browsers. Otherwise, it would fall back to using ClassInfo::className
which os the function name and interface name (e.g. "Event").
* bindings/js/JSDOMConstructor.h:
(WebCore::JSDOMConstructorNotConstructable::callThrowTypeError):
(WebCore::JSDOMConstructorNotConstructable::getCallData):
As per the specification, interfaces that do not have a [Constructor]
should throw a TypeError when called as a function. Use the "Illegal
constructor" error message to match Firefox and Chrome.
* bindings/js/JSDOMGlobalObject.h:
(WebCore::getDOMConstructor):
Instead of using objectPrototype as prototype for all DOM constructors,
we now call the prototypeForStructure() static function that is
generated for each bindings class. As per the Web IDL specification,
The [[Prototype]] internal property of an interface object for a
non-callback interface is determined as follows:
1. If the interface inherits from some other interface, the value of
[[Prototype]] is the interface object for that other interface.
2. If the interface doesn't inherit from any other interface, the value
of [[Prototype]] is %FunctionPrototype% ([ECMA-262], section 6.1.7.4).
* bindings/js/JSImageConstructor.cpp:
(WebCore::JSImageConstructor::prototypeForStructure):
Have the Image's interface object use HTMLElement's interface object
as prototype as HTMLImageElement inherits HTMLElement.
* bindings/scripts/CodeGenerator.pm:
(getInterfaceExtendedAttributesFromName):
Add a utility function to cheaply retrieve an interface's IDL extended
attributes without actually parsing the IDL. This is used to check if
an interface's parent is marked as [NoInterfaceObject] currently.
* bindings/scripts/CodeGeneratorJS.pm:
(GenerateHeader):
(GenerateImplementation):
(GenerateCallbackHeader):
(GenerateCallbackImplementation):
Mark JSGlobalObject* parameter as const as the implementation does not
alter the globalObject.
(GenerateConstructorHelperMethods):
- Generate prototypeForStructure() function for each bindings class that
is not marked as [NoInterfaceObject] so getDOMConstructor() knows which
prototype to use for the interface object / constructor when constructing
it.
- Use the interface name for the interface object, without the "Constructor"
suffix, to match the behavior of Firefox and Chrome.
* bindings/scripts/test/*:
Rebaseline bindings tests.
LayoutTests:
Rebaseline / update existing layout tests now that interface objects
are now Function objects. Also add a layout test to cover various
aspects of interface objects.
* css3/blending/background-blend-mode-property-parsing-expected.txt:
* css3/blending/blend-mode-property-parsing-expected.txt:
* css3/blending/script-tests/background-blend-mode-property-parsing.js:
(shouldBeType):
* css3/blending/script-tests/blend-mode-property-parsing.js:
(shouldBeType):
* css3/filters/backdrop/backdropfilter-property-parsing-expected.txt:
* css3/filters/backdrop/script-tests/backdropfilter-property-parsing.js:
(shouldBeType):
* css3/filters/filter-property-parsing-expected.txt:
* css3/filters/script-tests/filter-property-parsing.js:
(shouldBeType):
* fast/css/image-set-parsing-expected.txt:
* fast/css/script-tests/image-set-parsing.js:
(shouldBeType):
* fast/dom/DOMException/XPathException-expected.txt:
* fast/dom/DOMException/prototype-object-expected.txt:
* fast/dom/DOMException/prototype-object.html:
* fast/dom/DOMException/resources/XPathException.js:
* fast/dom/MutationObserver/mutation-record-constructor-expected.txt:
* fast/dom/MutationObserver/mutation-record-constructor.html:
* fast/dom/Window/element-constructors-on-window-expected.txt:
* fast/dom/call-a-constructor-as-a-function-expected.txt:
* fast/dom/constructor-proto-expected.txt:
* fast/dom/constructor-proto.html:
* fast/dom/wrapper-classes-expected.txt:
* fast/dom/wrapper-classes.html:
* fast/mediastream/MediaStreamConstructor-expected.txt:
* fast/mediastream/MediaStreamConstructor.html:
* fast/workers/constructor-proto-expected.txt:
* fast/workers/worker-location-expected.txt:
* http/tests/xmlhttprequest/XMLHttpRequestException-expected.txt:
* http/tests/xmlhttprequest/XMLHttpRequestException.html:
* js/dom/global-constructors-attributes-dedicated-worker-expected.txt:
* js/dom/script-tests/global-constructors-attributes-idb.js:
(constructorPropertiesOnGlobalObject):
* js/dom/script-tests/global-constructors-attributes.js:
(constructorPropertiesOnGlobalObject):
* js/interface-objects-expected.txt: Added.
* js/interface-objects.html: Added.
* media/encrypted-media/encrypted-media-v2-syntax-expected.txt:
* media/encrypted-media/encrypted-media-v2-syntax.html:
* media/track/track-vttcue-expected.txt:
* platform/mac/fast/dom/Window/window-lookup-precedence-expected.txt:
* platform/mac/js/dom/global-constructors-attributes-expected.txt:
* svg/custom/SVGException-expected.txt:
* svg/custom/global-constructors-expected.txt:
* svg/custom/script-tests/SVGException.js:
* svg/custom/script-tests/global-constructors.js:
(shouldBeDefined):
* transforms/2d/transform-value-types-expected.txt:
* transforms/2d/transform-value-types.html:
Canonical link: https://commits.webkit.org/172193@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@196392 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-02-10 21:51:18 +00:00
|
|
|
<script src="../resources/js-test-pre.js"></script>
|
|
|
|
<script>
|
|
|
|
description("Tests that interfaces objects have the right type");
|
|
|
|
// http://heycam.github.io/webidl/#interface-object
|
|
|
|
|
|
|
|
object = {};
|
|
|
|
|
|
|
|
debug("* Interface with constructor");
|
|
|
|
shouldBeTrue("window.Event instanceof Function");
|
|
|
|
shouldBeEqualToString("typeof Event", "function");
|
|
|
|
shouldBe("Object.getPrototypeOf(Event)", "Function.prototype");
|
|
|
|
shouldThrow("Event('click')");
|
|
|
|
shouldThrow("Event.call('click')");
|
|
|
|
shouldNotThrow("new Event('click')");
|
|
|
|
shouldBeEqualToString("Event.toString()", "function Event() {\n [native code]\n}");
|
|
|
|
shouldBeEqualToString("object.toString.call(Event)", "[object Function]");
|
|
|
|
|
|
|
|
debug("");
|
|
|
|
debug("* Interface with named constructor");
|
|
|
|
shouldBeTrue("window.Audio instanceof Function");
|
|
|
|
shouldBeEqualToString("typeof Audio", "function");
|
2018-10-02 22:53:33 +00:00
|
|
|
shouldBe("Object.getPrototypeOf(Audio)", "Function.prototype");
|
[Web IDL] interface objects should be Function objects
https://bugs.webkit.org/show_bug.cgi?id=154038
<rdar://problem/24569358>
Reviewed by Geoffrey Garen.
LayoutTests/imported/w3c:
Rebaseline W3C tests now that more checks are passing. Some checks still
fail because a lot of our interfaces should inherit EventTarget and
currently don't (they duplicate the EventTarget API instead).
Also, as per WebIDL, window.NodeFilter's proto should be ObjectPrototype
instead of FunctionPrototype but this is an exceptional case and our new
behavior is consistent with Firefox and Chrome.
* web-platform-tests/XMLHttpRequest/interfaces-expected.txt:
* web-platform-tests/dom/events/Event-constructors-expected.txt:
* web-platform-tests/dom/historical-expected.txt:
* web-platform-tests/dom/interfaces-expected.txt:
* web-platform-tests/fetch/api/headers/headers-idl-expected.txt:
* web-platform-tests/fetch/api/request/request-idl-expected.txt:
* web-platform-tests/html/dom/interfaces-expected.txt:
* web-platform-tests/html/semantics/embedded-content/the-audio-element/audio_constructor-expected.txt:
Source/JavaScriptCore:
Update functionProtoFuncToString() to handle JSObjects that
have the TypeOfShouldCallGetCallData flag and are callable,
as these behave like functions and use ClassInfo::className()
as function name in this case.
* runtime/FunctionPrototype.cpp:
(JSC::functionProtoFuncToString):
Source/WebCore:
interface objects should be Function objects as per Web IDL:
- http://heycam.github.io/webidl/#interface-object
- http://heycam.github.io/webidl/#es-interfaces
So window.Event should be a Function object for e.g. but in WebKit it
is a regular EventConstructor JSObject.
Firefox and Chrome match the specification.
Test: js/interface-objects.html
* bindings/js/JSDOMBinding.cpp:
(WebCore::callThrowTypeError):
(WebCore::DOMConstructorObject::getCallData):
When calling the interface object as a function, we throw a TypeError
with a message asking to use the 'new' operator to match the behavior
of Firefox and Chrome.
* bindings/js/JSDOMBinding.h:
Add JSC::TypeOfShouldCallGetCallData structure flag and implement
getCallData() so that typeof returns "function", as per the
specification and the behavior of other browsers.
(WebCore::DOMConstructorObject::className):
Implement className() and return "Function" to match the specification and
other browsers. Otherwise, it would fall back to using ClassInfo::className
which os the function name and interface name (e.g. "Event").
* bindings/js/JSDOMConstructor.h:
(WebCore::JSDOMConstructorNotConstructable::callThrowTypeError):
(WebCore::JSDOMConstructorNotConstructable::getCallData):
As per the specification, interfaces that do not have a [Constructor]
should throw a TypeError when called as a function. Use the "Illegal
constructor" error message to match Firefox and Chrome.
* bindings/js/JSDOMGlobalObject.h:
(WebCore::getDOMConstructor):
Instead of using objectPrototype as prototype for all DOM constructors,
we now call the prototypeForStructure() static function that is
generated for each bindings class. As per the Web IDL specification,
The [[Prototype]] internal property of an interface object for a
non-callback interface is determined as follows:
1. If the interface inherits from some other interface, the value of
[[Prototype]] is the interface object for that other interface.
2. If the interface doesn't inherit from any other interface, the value
of [[Prototype]] is %FunctionPrototype% ([ECMA-262], section 6.1.7.4).
* bindings/js/JSImageConstructor.cpp:
(WebCore::JSImageConstructor::prototypeForStructure):
Have the Image's interface object use HTMLElement's interface object
as prototype as HTMLImageElement inherits HTMLElement.
* bindings/scripts/CodeGenerator.pm:
(getInterfaceExtendedAttributesFromName):
Add a utility function to cheaply retrieve an interface's IDL extended
attributes without actually parsing the IDL. This is used to check if
an interface's parent is marked as [NoInterfaceObject] currently.
* bindings/scripts/CodeGeneratorJS.pm:
(GenerateHeader):
(GenerateImplementation):
(GenerateCallbackHeader):
(GenerateCallbackImplementation):
Mark JSGlobalObject* parameter as const as the implementation does not
alter the globalObject.
(GenerateConstructorHelperMethods):
- Generate prototypeForStructure() function for each bindings class that
is not marked as [NoInterfaceObject] so getDOMConstructor() knows which
prototype to use for the interface object / constructor when constructing
it.
- Use the interface name for the interface object, without the "Constructor"
suffix, to match the behavior of Firefox and Chrome.
* bindings/scripts/test/*:
Rebaseline bindings tests.
LayoutTests:
Rebaseline / update existing layout tests now that interface objects
are now Function objects. Also add a layout test to cover various
aspects of interface objects.
* css3/blending/background-blend-mode-property-parsing-expected.txt:
* css3/blending/blend-mode-property-parsing-expected.txt:
* css3/blending/script-tests/background-blend-mode-property-parsing.js:
(shouldBeType):
* css3/blending/script-tests/blend-mode-property-parsing.js:
(shouldBeType):
* css3/filters/backdrop/backdropfilter-property-parsing-expected.txt:
* css3/filters/backdrop/script-tests/backdropfilter-property-parsing.js:
(shouldBeType):
* css3/filters/filter-property-parsing-expected.txt:
* css3/filters/script-tests/filter-property-parsing.js:
(shouldBeType):
* fast/css/image-set-parsing-expected.txt:
* fast/css/script-tests/image-set-parsing.js:
(shouldBeType):
* fast/dom/DOMException/XPathException-expected.txt:
* fast/dom/DOMException/prototype-object-expected.txt:
* fast/dom/DOMException/prototype-object.html:
* fast/dom/DOMException/resources/XPathException.js:
* fast/dom/MutationObserver/mutation-record-constructor-expected.txt:
* fast/dom/MutationObserver/mutation-record-constructor.html:
* fast/dom/Window/element-constructors-on-window-expected.txt:
* fast/dom/call-a-constructor-as-a-function-expected.txt:
* fast/dom/constructor-proto-expected.txt:
* fast/dom/constructor-proto.html:
* fast/dom/wrapper-classes-expected.txt:
* fast/dom/wrapper-classes.html:
* fast/mediastream/MediaStreamConstructor-expected.txt:
* fast/mediastream/MediaStreamConstructor.html:
* fast/workers/constructor-proto-expected.txt:
* fast/workers/worker-location-expected.txt:
* http/tests/xmlhttprequest/XMLHttpRequestException-expected.txt:
* http/tests/xmlhttprequest/XMLHttpRequestException.html:
* js/dom/global-constructors-attributes-dedicated-worker-expected.txt:
* js/dom/script-tests/global-constructors-attributes-idb.js:
(constructorPropertiesOnGlobalObject):
* js/dom/script-tests/global-constructors-attributes.js:
(constructorPropertiesOnGlobalObject):
* js/interface-objects-expected.txt: Added.
* js/interface-objects.html: Added.
* media/encrypted-media/encrypted-media-v2-syntax-expected.txt:
* media/encrypted-media/encrypted-media-v2-syntax.html:
* media/track/track-vttcue-expected.txt:
* platform/mac/fast/dom/Window/window-lookup-precedence-expected.txt:
* platform/mac/js/dom/global-constructors-attributes-expected.txt:
* svg/custom/SVGException-expected.txt:
* svg/custom/global-constructors-expected.txt:
* svg/custom/script-tests/SVGException.js:
* svg/custom/script-tests/global-constructors.js:
(shouldBeDefined):
* transforms/2d/transform-value-types-expected.txt:
* transforms/2d/transform-value-types.html:
Canonical link: https://commits.webkit.org/172193@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@196392 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-02-10 21:51:18 +00:00
|
|
|
shouldThrow("Audio()");
|
|
|
|
shouldThrow("Audio.call()");
|
|
|
|
shouldNotThrow("new Audio()");
|
|
|
|
shouldBeEqualToString("Audio.toString()", "function Audio() {\n [native code]\n}");
|
|
|
|
shouldBeEqualToString("object.toString.call(Audio)", "[object Function]");
|
|
|
|
|
|
|
|
debug("");
|
|
|
|
debug("* Interface without constructor");
|
|
|
|
shouldBeTrue("window.Element instanceof Function");
|
|
|
|
shouldBeEqualToString("typeof Element", "function");
|
|
|
|
shouldBe("Object.getPrototypeOf(Element)", "Node");
|
|
|
|
shouldThrow("Element()");
|
|
|
|
shouldThrow("Element.call()");
|
|
|
|
shouldThrow("new Element()");
|
|
|
|
shouldBeEqualToString("Element.toString()", "function Element() {\n [native code]\n}");
|
|
|
|
shouldBeEqualToString("object.toString.call(Element)", "[object Function]");
|
|
|
|
|
|
|
|
</script>
|
|
|
|
<script src="../resources/js-test-post.js"></script>
|