Skip to content

Commit

Permalink
Merge r234957 - Custom element constructor doesn't use HTMLElement in…
Browse files Browse the repository at this point in the history
… new.target's realm

https://bugs.webkit.org/show_bug.cgi?id=188634

Reviewed by Keith Miller.

LayoutTests/imported/w3c:

Rebaselined the test now that all relevant test cases pass. All remaining test failures are
for customized builtin, which we do not and shall not implement.

* web-platform-tests/custom-elements/htmlconstructor/newtarget-expected.txt:

Source/WebCore:

Fixed the bug that HTMLElement's constructor was constructing an element of its own realm
instead of the realm of new.target. This results in the JS wrapper created for the element
belonging to the global object of the HTMLElement constructor which was invoked instead of
the global object of new.target as specified in:
https://html.spec.whatwg.org/multipage/dom.html#html-element-constructors

In particular, step 9.2. specifies that we "perform element.[[SetPrototypeOf]](prototype)."
where prototype is the result of Get(NewTarget, "prototype") in step 7.

WebKit's new behavior matches that of Chrome and Firefox.

Test: imported/w3c/web-platform-tests/custom-elements/htmlconstructor/newtarget.html

* bindings/js/JSHTMLElementCustom.cpp:
(WebCore::constructJSHTMLElement):
  • Loading branch information
rniwa authored and carlosgcampos committed Aug 20, 2018
1 parent a690ba7 commit 93173f0
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 6 deletions.
12 changes: 12 additions & 0 deletions LayoutTests/imported/w3c/ChangeLog
@@ -1,3 +1,15 @@
2018-08-16 Ryosuke Niwa <rniwa@webkit.org>

Custom element constructor doesn't use HTMLElement in new.target's realm
https://bugs.webkit.org/show_bug.cgi?id=188634

Reviewed by Keith Miller.

Rebaselined the test now that all relevant test cases pass. All remaining test failures are
for customized builtin, which we do not and shall not implement.

* web-platform-tests/custom-elements/htmlconstructor/newtarget-expected.txt:

2018-08-16 Ryosuke Niwa <rniwa@webkit.org>

Custom element doesn't invalidate its style when :defined rule starts to apply
Expand Down
@@ -1,10 +1,10 @@

PASS Use NewTarget's prototype, not the one stored at definition time
PASS Rethrow any exceptions thrown while getting the prototype
FAIL If prototype is not object (null), derives the fallback from NewTarget's realm (autonomous custom elements) assert_equals: Must use the HTMLElement from the realm of NewTarget expected object "[object HTMLElementPrototype]" but got object "[object HTMLElementPrototype]"
FAIL If prototype is not object (undefined), derives the fallback from NewTarget's realm (autonomous custom elements) assert_equals: Must use the HTMLElement from the realm of NewTarget expected object "[object HTMLElementPrototype]" but got object "[object HTMLElementPrototype]"
FAIL If prototype is not object (5), derives the fallback from NewTarget's realm (autonomous custom elements) assert_equals: Must use the HTMLElement from the realm of NewTarget expected object "[object HTMLElementPrototype]" but got object "[object HTMLElementPrototype]"
FAIL If prototype is not object (string), derives the fallback from NewTarget's realm (autonomous custom elements) assert_equals: Must use the HTMLElement from the realm of NewTarget expected object "[object HTMLElementPrototype]" but got object "[object HTMLElementPrototype]"
PASS If prototype is not object (null), derives the fallback from NewTarget's realm (autonomous custom elements)
PASS If prototype is not object (undefined), derives the fallback from NewTarget's realm (autonomous custom elements)
PASS If prototype is not object (5), derives the fallback from NewTarget's realm (autonomous custom elements)
PASS If prototype is not object (string), derives the fallback from NewTarget's realm (autonomous custom elements)
FAIL If prototype is not object (null), derives the fallback from NewTarget's realm (customized built-in elements) promise_test: Unhandled rejection with value: object "TypeError: Reflect.construct requires the first argument be a constructor"
FAIL If prototype is not object (undefined), derives the fallback from NewTarget's realm (customized built-in elements) promise_test: Unhandled rejection with value: object "TypeError: Reflect.construct requires the first argument be a constructor"
FAIL If prototype is not object (5), derives the fallback from NewTarget's realm (customized built-in elements) promise_test: Unhandled rejection with value: object "TypeError: Reflect.construct requires the first argument be a constructor"
Expand Down
23 changes: 23 additions & 0 deletions Source/WebCore/ChangeLog
@@ -1,3 +1,26 @@
2018-08-16 Ryosuke Niwa <rniwa@webkit.org>

Custom element constructor doesn't use HTMLElement in new.target's realm
https://bugs.webkit.org/show_bug.cgi?id=188634

Reviewed by Keith Miller.

Fixed the bug that HTMLElement's constructor was constructing an element of its own realm
instead of the realm of new.target. This results in the JS wrapper created for the element
belonging to the global object of the HTMLElement constructor which was invoked instead of
the global object of new.target as specified in:
https://html.spec.whatwg.org/multipage/dom.html#html-element-constructors

In particular, step 9.2. specifies that we "perform element.[[SetPrototypeOf]](prototype)."
where prototype is the result of Get(NewTarget, "prototype") in step 7.

WebKit's new behavior matches that of Chrome and Firefox.

Test: imported/w3c/web-platform-tests/custom-elements/htmlconstructor/newtarget.html

* bindings/js/JSHTMLElementCustom.cpp:
(WebCore::constructJSHTMLElement):

2018-08-16 Ryosuke Niwa <rniwa@webkit.org>

Custom element doesn't invalidate its style when :defined rule starts to apply
Expand Down
4 changes: 2 additions & 2 deletions Source/WebCore/bindings/js/JSHTMLElementCustom.cpp
Expand Up @@ -55,7 +55,8 @@ EncodedJSValue JSC_HOST_CALL constructJSHTMLElement(ExecState& exec)
ASSERT(context->isDocument());

JSValue newTargetValue = exec.thisValue();
auto* globalObject = jsConstructor->globalObject();
auto* newTarget = newTargetValue.getObject();
auto* globalObject = jsCast<JSDOMGlobalObject*>(newTarget->globalObject(vm));
JSValue htmlElementConstructorValue = JSHTMLElement::getConstructor(vm, globalObject);
if (newTargetValue == htmlElementConstructorValue)
return throwVMTypeError(&exec, scope, "new.target is not a valid custom element constructor"_s);
Expand All @@ -70,7 +71,6 @@ EncodedJSValue JSC_HOST_CALL constructJSHTMLElement(ExecState& exec)
if (!registry)
return throwVMTypeError(&exec, scope, "new.target is not a valid custom element constructor"_s);

JSObject* newTarget = newTargetValue.getObject();
auto* elementInterface = registry->findInterface(newTarget);
if (!elementInterface)
return throwVMTypeError(&exec, scope, "new.target does not define a custom element"_s);
Expand Down

0 comments on commit 93173f0

Please sign in to comment.