Changeset 205263 in webkit


Ignore:
Timestamp:
Aug 31, 2016 12:53:44 PM (8 years ago)
Author:
rniwa@webkit.org
Message:

HTML constructor must throw when newTarget is itself
https://bugs.webkit.org/show_bug.cgi?id=161430

Reviewed by Antti Koivisto.

Source/WebCore:

Per https://github.com/w3c/webcomponents/issues/541, we must throw a TypeError when the HTMLElement constructor
is called with new.target set to itself (i.e. new HTMLElement after registering it with a custom element).

Note that we can't check this at the time of customElements.define because it could be a Proxy object.

Also see: https://html.spec.whatwg.org/#html-element-constructors

Tests: fast/custom-elements/CustomElementRegistry.html

fast/custom-elements/HTMLElement-constructor.html

  • bindings/js/JSHTMLElementCustom.cpp:

(WebCore::constructJSHTMLElement): Throw a TypeError when NewTarget is HTMLElement constructor itself.

LayoutTests:

Added test cases for defining a custom element with the HTMLElement constructor,
and making sure the HTMLElement constructor throws an exception when newTarget is itself.

  • fast/custom-elements/CustomElementRegistry-expected.txt:
  • fast/custom-elements/CustomElementRegistry.html:
  • fast/custom-elements/HTMLElement-constructor-expected.txt:
  • fast/custom-elements/HTMLElement-constructor.html:
Location:
trunk
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r205261 r205263  
     12016-08-31  Ryosuke Niwa  <rniwa@webkit.org>
     2
     3        HTML constructor must throw when newTarget is itself
     4        https://bugs.webkit.org/show_bug.cgi?id=161430
     5
     6        Reviewed by Antti Koivisto.
     7
     8        Added test cases for defining a custom element with the HTMLElement constructor,
     9        and making sure the HTMLElement constructor throws an exception when newTarget is itself.
     10
     11        * fast/custom-elements/CustomElementRegistry-expected.txt:
     12        * fast/custom-elements/CustomElementRegistry.html:
     13        * fast/custom-elements/HTMLElement-constructor-expected.txt:
     14        * fast/custom-elements/HTMLElement-constructor.html:
     15
    1162016-08-31  Ryosuke Niwa  <rniwa@webkit.org>
    217
  • trunk/LayoutTests/fast/custom-elements/CustomElementRegistry-expected.txt

    r205261 r205263  
    22PASS CustomElementRegistry interface must have define as a method
    33PASS customElements.define must throw when the element interface is not a constructor
     4PASS customElements.define must not throw the constructor is HTMLElement
    45PASS customElements.define must throw with an invalid name
    56PASS customElements.define must throw when there is already a custom element of the same name
  • trunk/LayoutTests/fast/custom-elements/CustomElementRegistry.html

    r205261 r205263  
    2828        'customElements.define must throw a TypeError when the element interface is an array');
    2929}, 'customElements.define must throw when the element interface is not a constructor');
     30
     31test(function () {
     32    customElements.define('custom-html-element', HTMLElement);
     33}, 'customElements.define must not throw the constructor is HTMLElement');
    3034
    3135test(function () {
  • trunk/LayoutTests/fast/custom-elements/HTMLElement-constructor-expected.txt

    r197602 r205263  
    11
    2 PASS HTMLElement constructor must throw a TypeError when there is no derived class
    3 PASS HTMLElement constructor must throw TypeError when custom element is not well defined
     2PASS HTMLElement constructor must throw a TypeError when NewTarget is equal to itself
     3PASS HTMLElement constructor must throw a TypeError when NewTarget is equal to itself via a Proxy object
     4PASS HTMLElement constructor must throw TypeError when it has not been defined by customElements.define
    45PASS HTMLElement constructor must infer the tag name from the element interface
    56PASS HTMLElement constructor must allow subclassing a custom element
  • trunk/LayoutTests/fast/custom-elements/HTMLElement-constructor.html

    r204367 r205263  
    55<meta name="author" title="Ryosuke Niwa" href="mailto:rniwa@webkit.org">
    66<meta name="assert" content="HTMLElement must allow subclassing">
     7<link rel="help" href="https://html.spec.whatwg.org/#html-element-constructors">
    78<script src="../../resources/testharness.js"></script>
    89<script src="../../resources/testharnessreport.js"></script>
     
    1415
    1516test(function () {
    16     class SomeDefinedElement extends HTMLElement {};
    17     customElements.define('defined-element', SomeDefinedElement);
    18     assert_throws({'name': 'TypeError'}, function () { new HTMLElement('defined-element'); });
    19 }, 'HTMLElement constructor must throw a TypeError when there is no derived class');
     17    customElements.define('html-custom-element', HTMLElement);
     18    assert_throws({'name': 'TypeError'}, function () { new HTMLElement(); });
     19}, 'HTMLElement constructor must throw a TypeError when NewTarget is equal to itself');
     20
     21test(function () {
     22    customElements.define('html-proxy-custom-element', new Proxy(HTMLElement, {}));
     23    assert_throws({'name': 'TypeError'}, function () { new HTMLElement(); });
     24}, 'HTMLElement constructor must throw a TypeError when NewTarget is equal to itself via a Proxy object');
    2025
    2126test(function () {
    2227    class SomeCustomElement extends HTMLElement {};
    23     assert_throws({'name': 'TypeError'}, function () { new SomeCustomElement; },
    24         'Instantiating a custom element without calling customElements.define must throw TypeError');
    25 }, 'HTMLElement constructor must throw TypeError when custom element is not well defined');
     28    assert_throws({'name': 'TypeError'}, function () { new SomeCustomElement; });
     29}, 'HTMLElement constructor must throw TypeError when it has not been defined by customElements.define');
    2630
    2731test(function () {
  • trunk/Source/WebCore/ChangeLog

    r205262 r205263  
     12016-08-31  Ryosuke Niwa  <rniwa@webkit.org>
     2
     3        HTML constructor must throw when newTarget is itself
     4        https://bugs.webkit.org/show_bug.cgi?id=161430
     5
     6        Reviewed by Antti Koivisto.
     7
     8        Per https://github.com/w3c/webcomponents/issues/541, we must throw a TypeError when the HTMLElement constructor
     9        is called with new.target set to itself (i.e. new HTMLElement after registering it with a custom element).
     10
     11        Note that we can't check this at the time of customElements.define because it could be a Proxy object.
     12
     13        Also see: https://html.spec.whatwg.org/#html-element-constructors
     14
     15        Tests: fast/custom-elements/CustomElementRegistry.html
     16               fast/custom-elements/HTMLElement-constructor.html
     17
     18        * bindings/js/JSHTMLElementCustom.cpp:
     19        (WebCore::constructJSHTMLElement): Throw a TypeError when NewTarget is HTMLElement constructor itself.
     20
    1212016-08-31  Ryosuke Niwa  <rniwa@webkit.org>
    222
  • trunk/Source/WebCore/bindings/js/JSHTMLElementCustom.cpp

    r205198 r205263  
    5555    ASSERT(context->isDocument());
    5656
     57    JSValue newTargetValue = exec.thisValue();
     58    auto* globalObject = jsConstructor->globalObject();
     59    JSValue htmlElementConstructorValue = JSHTMLElement::getConstructor(vm, globalObject);
     60    if (newTargetValue == htmlElementConstructorValue)
     61        return throwVMTypeError(&exec, scope, ASCIILiteral("new.target is not a valid custom element constructor"));
     62
    5763    auto& document = downcast<Document>(*context);
    5864
     
    6571        return throwVMTypeError(&exec, scope, ASCIILiteral("new.target is not a valid custom element constructor"));
    6672
    67     JSValue newTargetValue = exec.thisValue();
    6873    JSObject* newTarget = newTargetValue.getObject();
    6974    auto* elementInterface = registry->findInterface(newTarget);
     
    7277
    7378    if (!elementInterface->isUpgradingElement()) {
    74         auto* globalObject = jsConstructor->globalObject();
    7579        Structure* baseStructure = getDOMStructure<JSHTMLElement>(vm, *globalObject);
    7680        auto* newElementStructure = InternalFunction::createSubclassStructure(&exec, newTargetValue, baseStructure);
Note: See TracChangeset for help on using the changeset viewer.