Changeset 197602 in webkit


Ignore:
Timestamp:
Mar 4, 2016 5:23:42 PM (8 years ago)
Author:
rniwa@webkit.org
Message:

Update defineCustomElement according to the spec rewrite
https://bugs.webkit.org/show_bug.cgi?id=155010
<rdar://problem/24970878>

Reviewed by Chris Dumez.

Source/WebCore:

Updated the implementation of defineCustomElement and HTMLConstructor per recent rewrite of the spec:
https://w3c.github.io/webcomponents/spec/custom/#dom-document-defineelement
https://w3c.github.io/webcomponents/spec/custom/#htmlelement-constructor

defineCustomElement is now called defineElement and we disallow defining multiple custom elements with
a single class and throw an exception in defineElement.

Test: fast/custom-elements/Document-defineElement.html

  • bindings/js/JSDocumentCustom.cpp:

(WebCore::JSDocument::defineElement): Renamed from defineCustomElement. Throw an exception when the interface
already defines another custom element. Also added FIXME's for missing steps.

  • bindings/js/JSHTMLElementCustom.cpp:

(WebCore::constructJSHTMLElement): Removed the support for specifying a tag name in the first argument when
a single class defines multiple custom elements since that now results in an exception (in defineElement).

  • dom/CustomElementDefinitions.cpp:

(WebCore::CustomElementDefinitions::containsConstructor): Added.

  • dom/CustomElementDefinitions.h:
  • dom/Document.idl: Renamed defineCustomElement to defineElement.
  • html/HTMLElement.idl: Removed the optional tag name from the constructor.

LayoutTests:

Update the tests for the rename and semantics change of defineCustomElement and HTMLElement constructor.

  • fast/custom-elements/Document-createElement.html:
  • fast/custom-elements/Document-defineCustomElement-expected.txt: Removed.
  • fast/custom-elements/Document-defineCustomElement.html: Removed.
  • fast/custom-elements/Document-defineElement-expected.txt: Renamed from LayoutTests/fast/custom-elements/Document-defineCustomElement-expected.txt.
  • fast/custom-elements/Document-defineElement.html: Renamed from LayoutTests/fast/custom-elements/Document-defineCustomElement.html.

Also added a test case for defining multiple custom elements with a single class, which must throw.

  • fast/custom-elements/HTMLElement-constructor-expected.txt:
  • fast/custom-elements/HTMLElement-constructor.html:

Removed test cases for the tag name in the first argument as well as ones that associate a single class with multiple tag names.

  • fast/custom-elements/parser/parser-constructs-custom-element-in-document-write.html:
  • fast/custom-elements/parser/parser-constructs-custom-element-synchronously.html:
  • fast/custom-elements/parser/parser-constructs-custom-elements.html:
  • fast/custom-elements/parser/parser-fallsback-to-unknown-element.html:
  • fast/custom-elements/parser/parser-sets-attributes-and-children.html:
  • fast/custom-elements/parser/parser-uses-constructed-element.html:
  • fast/custom-elements/parser/parser-uses-registry-of-owner-document.html:
Location:
trunk
Files:
18 edited
2 moved

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r197594 r197602  
     12016-03-04  Ryosuke Niwa  <rniwa@webkit.org>
     2
     3        Update defineCustomElement according to the spec rewrite
     4        https://bugs.webkit.org/show_bug.cgi?id=155010
     5        <rdar://problem/24970878>
     6
     7        Reviewed by Chris Dumez.
     8
     9        Update the tests for the rename and semantics change of defineCustomElement and HTMLElement constructor.
     10
     11        * fast/custom-elements/Document-createElement.html:
     12        * fast/custom-elements/Document-defineCustomElement-expected.txt: Removed.
     13        * fast/custom-elements/Document-defineCustomElement.html: Removed.
     14        * fast/custom-elements/Document-defineElement-expected.txt: Renamed from LayoutTests/fast/custom-elements/Document-defineCustomElement-expected.txt.
     15        * fast/custom-elements/Document-defineElement.html: Renamed from LayoutTests/fast/custom-elements/Document-defineCustomElement.html.
     16        Also added a test case for defining multiple custom elements with a single class, which must throw.
     17        * fast/custom-elements/HTMLElement-constructor-expected.txt:
     18        * fast/custom-elements/HTMLElement-constructor.html:
     19        Removed test cases for the tag name in the first argument as well as ones that associate a single class with multiple tag names.
     20        * fast/custom-elements/parser/parser-constructs-custom-element-in-document-write.html:
     21        * fast/custom-elements/parser/parser-constructs-custom-element-synchronously.html:
     22        * fast/custom-elements/parser/parser-constructs-custom-elements.html:
     23        * fast/custom-elements/parser/parser-fallsback-to-unknown-element.html:
     24        * fast/custom-elements/parser/parser-sets-attributes-and-children.html:
     25        * fast/custom-elements/parser/parser-uses-constructed-element.html:
     26        * fast/custom-elements/parser/parser-uses-registry-of-owner-document.html:
     27
    1282016-03-04  Simon Fraser  <simon.fraser@apple.com>
    229
  • trunk/LayoutTests/fast/custom-elements/Document-createElement.html

    r195538 r197602  
    1919    assert_false(document.createElement('my-custom-element') instanceof MyCustomElement);
    2020
    21     document.defineCustomElement('my-custom-element', MyCustomElement);
     21    document.defineElement('my-custom-element', MyCustomElement);
    2222    var instance = document.createElement('my-custom-element');
    2323    assert_true(instance instanceof MyCustomElement);
     
    3434        }
    3535    };
    36     document.defineCustomElement('object-custom-element', ObjectCustomElement);
     36    document.defineElement('object-custom-element', ObjectCustomElement);
    3737
    3838    var instance = new ObjectCustomElement;
     
    5050        }
    5151    };
    52     document.defineCustomElement('text-custom-element', TextCustomElement);
     52    document.defineElement('text-custom-element', TextCustomElement);
    5353    assert_true(new TextCustomElement instanceof Text);
    5454    assert_equals(document.createElement('object-custom-element'), null);
     
    6565        }
    6666    };
    67     document.defineCustomElement('div-custom-element', DivCustomElement);
     67    document.defineElement('div-custom-element', DivCustomElement);
    6868    assert_true(new DivCustomElement instanceof HTMLDivElement);
    6969
     
    8383        }
    8484    };
    85     document.defineCustomElement('throw-custom-element', ThrowCustomElement);
     85    document.defineElement('throw-custom-element', ThrowCustomElement);
    8686
    8787    assert_throws(null, function () { new ThrowCustomElement; });
  • trunk/LayoutTests/fast/custom-elements/Document-defineElement-expected.txt

    r197596 r197602  
    11
    2 PASS Check the existence of defineCustomElement on Document interface
    3 PASS document.defineCustomElement should throw with an invalid name
    4 PASS document.defineCustomElement should throw with a duplicate name
    5 PASS document.defineCustomElement must throw a NotSupportedError when the context object is an associated inert template document
    6 PASS document.defineCustomElement must throw a NotSupportedError when the context object is created by DOMImplementation.createHTMLDocument
    7 PASS document.defineCustomElement must throw a NotSupportedError when the context object is created by DOMImplementation.createDocument
    8 PASS document.defineCustomElement should throw when the element interface is not a constructor
    9 PASS document.defineCustomElement should define an instantiatable custom element
     2PASS Check the existence of defineElement on Document interface
     3PASS document.defineElement should throw with an invalid name
     4PASS document.defineElement should throw when there is already a custom element of the same name
     5PASS document.defineElement should throw when there is already a custom element with the same class
     6PASS document.defineElement must throw a NotSupportedError when the context object is an associated inert template document
     7PASS document.defineElement must throw a NotSupportedError when the context object is created by DOMImplementation.createHTMLDocument
     8PASS document.defineElement must throw a NotSupportedError when the context object is created by DOMImplementation.createDocument
     9PASS document.defineElement should throw when the element interface is not a constructor
     10PASS document.defineElement should define an instantiatable custom element
    1011
  • trunk/LayoutTests/fast/custom-elements/Document-defineElement.html

    r197596 r197602  
    44<title>Custom Elements: Extensions to Document interface</title>
    55<meta name="author" title="Ryosuke Niwa" href="mailto:rniwa@webkit.org">
    6 <meta name="assert" content="document.defineCustomElement should define a custom element">
     6<meta name="assert" content="document.defineElement should define a custom element">
    77<script src="../../resources/testharness.js"></script>
    88<script src="../../resources/testharnessreport.js"></script>
     
    1414
    1515test(function () {
    16     assert_true('defineCustomElement' in Document.prototype, '"defineCustomElement" exists on Document.prototype');
    17     assert_true('defineCustomElement' in document, '"defineCustomElement" exists on document');
    18 }, 'Check the existence of defineCustomElement on Document interface');
     16    assert_true('defineElement' in Document.prototype, '"defineElement" exists on Document.prototype');
     17    assert_true('defineElement' in document, '"defineElement" exists on document');
     18}, 'Check the existence of defineElement on Document interface');
    1919
    2020test(function () {
    2121    class MyCustomElement extends HTMLElement {};
    2222
    23     assert_throws({'name': 'SyntaxError'}, function () { document.defineCustomElement(null, MyCustomElement); },
    24         'document.defineCustomElement must throw a SyntaxError if the tag name is null');
    25     assert_throws({'name': 'SyntaxError'}, function () { document.defineCustomElement('', MyCustomElement); },
    26         'document.defineCustomElement must throw a SyntaxError if the tag name is empty');
    27     assert_throws({'name': 'SyntaxError'}, function () { document.defineCustomElement('abc', MyCustomElement); },
    28         'document.defineCustomElement must throw a SyntaxError if the tag name does not contain "-"');
    29     assert_throws({'name': 'SyntaxError'}, function () { document.defineCustomElement('a-Bc', MyCustomElement); },
    30         'document.defineCustomElement must throw a SyntaxError if the tag name contains an upper case letter');
     23    assert_throws({'name': 'SyntaxError'}, function () { document.defineElement(null, MyCustomElement); },
     24        'document.defineElement must throw a SyntaxError if the tag name is null');
     25    assert_throws({'name': 'SyntaxError'}, function () { document.defineElement('', MyCustomElement); },
     26        'document.defineElement must throw a SyntaxError if the tag name is empty');
     27    assert_throws({'name': 'SyntaxError'}, function () { document.defineElement('abc', MyCustomElement); },
     28        'document.defineElement must throw a SyntaxError if the tag name does not contain "-"');
     29    assert_throws({'name': 'SyntaxError'}, function () { document.defineElement('a-Bc', MyCustomElement); },
     30        'document.defineElement must throw a SyntaxError if the tag name contains an upper case letter');
    3131
    3232    var builtinTagNames = [
     
    4242
    4343    for (var tagName of builtinTagNames) {
    44         assert_throws({'name': 'SyntaxError'}, function () { document.defineCustomElement(tagName, MyCustomElement); },
    45             'document.defineCustomElement must throw a SyntaxError if the tag name is "' + tagName + '"');
     44        assert_throws({'name': 'SyntaxError'}, function () { document.defineElement(tagName, MyCustomElement); },
     45            'document.defineElement must throw a SyntaxError if the tag name is "' + tagName + '"');
    4646    }
    4747
    48 }, 'document.defineCustomElement should throw with an invalid name');
     48}, 'document.defineElement should throw with an invalid name');
    4949
    5050test(function () {
     
    5252    class OtherCustomElement extends HTMLElement {};
    5353
    54     document.defineCustomElement('some-custom-element', SomeCustomElement);
    55     assert_throws({'name': 'NotSupportedError'}, function () { document.defineCustomElement('some-custom-element', OtherCustomElement); },
    56         'document.defineCustomElement must throw a NotSupportedError if the specified tag name is already used');
     54    document.defineElement('some-custom-element', SomeCustomElement);
     55    assert_throws({'name': 'NotSupportedError'}, function () { document.defineElement('some-custom-element', OtherCustomElement); },
     56        'document.defineElement must throw a NotSupportedError if the specified tag name is already used');
    5757
    58 }, 'document.defineCustomElement should throw with a duplicate name');
     58}, 'document.defineElement should throw when there is already a custom element of the same name');
     59
     60test(function () {
     61    class AnotherCustomElement extends HTMLElement {};
     62
     63    document.defineElement('another-custom-element', AnotherCustomElement);
     64    assert_throws({'name': 'NotSupportedError'}, function () { document.defineElement('some-other-element', AnotherCustomElement); },
     65        'document.defineElement must throw a NotSupportedError if the specified class already defines an element');
     66
     67}, 'document.defineElement should throw when there is already a custom element with the same class');
    5968
    6069test(function () {
     
    6372    var templateContentOwnerDocument = document.createElement('template').content.ownerDocument;
    6473    assert_throws({'name': 'NotSupportedError'}, function () {
    65         templateContentOwnerDocument.defineCustomElement('some-custom-element', SomeCustomElement);
     74        templateContentOwnerDocument.defineElement('some-custom-element', SomeCustomElement);
    6675    });
    6776
    68 }, 'document.defineCustomElement must throw a NotSupportedError when the context object is an associated inert template document');
     77}, 'document.defineElement must throw a NotSupportedError when the context object is an associated inert template document');
    6978
    7079test(function () {
     
    7382    var windowlessDocument = document.implementation.createHTMLDocument();
    7483    assert_throws({'name': 'NotSupportedError'}, function () {
    75         windowlessDocument.defineCustomElement('some-custom-element', SomeCustomElement);
     84        windowlessDocument.defineElement('some-custom-element', SomeCustomElement);
    7685    });
    7786
    78 }, 'document.defineCustomElement must throw a NotSupportedError when the context object is created by DOMImplementation.createHTMLDocument');
     87}, 'document.defineElement must throw a NotSupportedError when the context object is created by DOMImplementation.createHTMLDocument');
    7988
    8089test(function () {
     
    8392    var windowlessDocument = document.implementation.createDocument('http://www.w3.org/1999/xhtml', 'html', null)
    8493    assert_throws({'name': 'NotSupportedError'}, function () {
    85         windowlessDocument.defineCustomElement('some-custom-element', SomeCustomElement);
     94        windowlessDocument.defineElement('some-custom-element', SomeCustomElement);
    8695    });
    8796
    88 }, 'document.defineCustomElement must throw a NotSupportedError when the context object is created by DOMImplementation.createDocument');
     97}, 'document.defineElement must throw a NotSupportedError when the context object is created by DOMImplementation.createDocument');
    8998
    9099test(function () {
    91     assert_throws({'name': 'TypeError'}, function () { document.defineCustomElement('invalid-element', 1); },
    92         'document.defineCustomElement must throw a TypeError when the element interface is a number');
    93     assert_throws({'name': 'TypeError'}, function () { document.defineCustomElement('invalid-element', '123'); },
    94         'document.defineCustomElement must throw a TypeError when the element interface is a string');
    95     assert_throws({'name': 'TypeError'}, function () { document.defineCustomElement('invalid-element', {}); },
    96         'document.defineCustomElement must throw a TypeError when the element interface is an object');
    97     assert_throws({'name': 'TypeError'}, function () { document.defineCustomElement('invalid-element', []); },
    98         'document.defineCustomElement must throw a TypeError when the element interface is an array');
    99 }, 'document.defineCustomElement should throw when the element interface is not a constructor');
     100    assert_throws({'name': 'TypeError'}, function () { document.defineElement('invalid-element', 1); },
     101        'document.defineElement must throw a TypeError when the element interface is a number');
     102    assert_throws({'name': 'TypeError'}, function () { document.defineElement('invalid-element', '123'); },
     103        'document.defineElement must throw a TypeError when the element interface is a string');
     104    assert_throws({'name': 'TypeError'}, function () { document.defineElement('invalid-element', {}); },
     105        'document.defineElement must throw a TypeError when the element interface is an object');
     106    assert_throws({'name': 'TypeError'}, function () { document.defineElement('invalid-element', []); },
     107        'document.defineElement must throw a TypeError when the element interface is an array');
     108}, 'document.defineElement should throw when the element interface is not a constructor');
    100109
    101110test(function () {
    102111    class MyCustomElement extends HTMLElement {};
    103     document.defineCustomElement('my-custom-element', MyCustomElement);
     112    document.defineElement('my-custom-element', MyCustomElement);
    104113
    105114    var instance = new MyCustomElement;
     
    116125        'A custom element HTML must use HTML namespace');
    117126
    118 }, 'document.defineCustomElement should define an instantiatable custom element');
     127}, 'document.defineElement should define an instantiatable custom element');
    119128
    120129</script>
  • trunk/LayoutTests/fast/custom-elements/HTMLElement-constructor-expected.txt

    r195087 r197602  
    33PASS HTMLElement constructor must throw TypeError when custom element is not well defined
    44PASS HTMLElement constructor must infer the tag name from the element interface
    5 PASS HTMLElement constructor must allow associating an element interface with multiple tag names
    65PASS HTMLElement constructor must allow subclassing a custom element
    76PASS HTMLElement constructor must allow subclassing an user-defined subclass of HTMLElement
  • trunk/LayoutTests/fast/custom-elements/HTMLElement-constructor.html

    r195087 r197602  
    1515test(function () {
    1616    class SomeDefinedElement extends HTMLElement {};
    17     document.defineCustomElement('defined-element', SomeDefinedElement);
     17    document.defineElement('defined-element', SomeDefinedElement);
    1818    assert_throws({'name': 'TypeError'}, function () { new HTMLElement('defined-element'); });
    1919}, 'HTMLElement constructor must throw a TypeError when there is no derived class');
     
    2222    class SomeCustomElement extends HTMLElement {};
    2323    assert_throws({'name': 'TypeError'}, function () { new SomeCustomElement; },
    24         'Instantiating a custom element without calling defineCustomElement must throw TypeError');
    25 
    26     class AnotherCustomElement extends HTMLElement {
    27         constructor() { super('some-element'); }
    28     };
    29     document.defineCustomElement('another-element', AnotherCustomElement);
    30     assert_throws({'name': 'TypeError'}, function () { new AnotherCustomElement; },
    31         'Calling HTMLElement constructor with a mismatching tag name throw TypeError');
    32 
    33     class YetAnotherCustomElement extends HTMLElement {
    34         constructor() { super(1); }
    35     };
    36     document.defineCustomElement('yet-another-element', YetAnotherCustomElement);
    37     assert_throws({'name': 'TypeError'}, function () { new YetAnotherCustomElement; },
    38         'Calling HTMLElement constructor with a bad tag name throw TypeError');
    39 
     24        'Instantiating a custom element without calling defineElement must throw TypeError');
    4025}, 'HTMLElement constructor must throw TypeError when custom element is not well defined');
    4126
    4227test(function () {
    4328    class CustomElementWithInferredTagName extends HTMLElement {};
    44     document.defineCustomElement('inferred-name', CustomElementWithInferredTagName);
     29    document.defineElement('inferred-name', CustomElementWithInferredTagName);
    4530
    4631    var instance = new CustomElementWithInferredTagName;
     
    6045
    6146test(function () {
    62     class ElementWithMultipleTagNames extends HTMLElement { };
    63     document.defineCustomElement('custom-element-1', ElementWithMultipleTagNames);
    64     document.defineCustomElement('custom-element-2', ElementWithMultipleTagNames);
    65 
    66     var instance1 = new ElementWithMultipleTagNames('custom-element-1');
    67     assert_true(instance1 instanceof ElementWithMultipleTagNames);
    68     assert_equals(instance1.localName, 'custom-element-1');
    69     assert_equals(instance1.nodeName, 'CUSTOM-ELEMENT-1');
    70 
    71     var instance2 = new ElementWithMultipleTagNames('custom-element-2');
    72     assert_true(instance2 instanceof ElementWithMultipleTagNames);
    73     assert_equals(instance2.localName, 'custom-element-2');
    74     assert_equals(instance2.nodeName, 'CUSTOM-ELEMENT-2');
    75 
    76     assert_throws({'name': 'TypeError'}, function () { new ElementWithMultipleTagNames; },
    77         'Instantiating an element interface associated with multiple tag names without specifying the tag name must throw TypeError');
    78 
    79 }, 'HTMLElement constructor must allow associating an element interface with multiple tag names');
    80 
    81 test(function () {
    8247    class ConcreteCustomElement extends HTMLElement { };
    8348    class SubCustomElement extends ConcreteCustomElement { };
    84     document.defineCustomElement('concrete-custom-element', ConcreteCustomElement);
    85     document.defineCustomElement('sub-custom-element', SubCustomElement);
     49    document.defineElement('concrete-custom-element', ConcreteCustomElement);
     50    document.defineElement('sub-custom-element', SubCustomElement);
     51
     52    var instance = new ConcreteCustomElement();
     53    assert_true(instance instanceof ConcreteCustomElement);
     54    assert_false(instance instanceof SubCustomElement);
     55    assert_equals(instance.localName, 'concrete-custom-element');
     56    assert_equals(instance.nodeName, 'CONCRETE-CUSTOM-ELEMENT');
    8657
    8758    var instance = new SubCustomElement();
     59    assert_true(instance instanceof ConcreteCustomElement);
    8860    assert_true(instance instanceof SubCustomElement);
    8961    assert_equals(instance.localName, 'sub-custom-element');
     
    9567    class AbstractCustomElement extends HTMLElement { };
    9668    class ConcreteSubCustomElement extends AbstractCustomElement { };
    97     document.defineCustomElement('concrete-sub-custom-element', ConcreteSubCustomElement);
     69    document.defineElement('concrete-sub-custom-element', ConcreteSubCustomElement);
    9870
    9971    var instance = new ConcreteSubCustomElement();
     72    assert_true(instance instanceof AbstractCustomElement);
    10073    assert_true(instance instanceof ConcreteSubCustomElement);
    10174    assert_equals(instance.localName, 'concrete-sub-custom-element');
  • trunk/LayoutTests/fast/custom-elements/parser/parser-constructs-custom-element-in-document-write.html

    r197528 r197602  
    1414
    1515class MyCustomElement extends HTMLElement { }
    16 document.defineCustomElement('my-custom-element', MyCustomElement);
     16document.defineElement('my-custom-element', MyCustomElement);
    1717
    1818document.write('<my-custom-element></my-custom-element>');
  • trunk/LayoutTests/fast/custom-elements/parser/parser-constructs-custom-element-synchronously.html

    r197466 r197602  
    2525    }
    2626};
    27 document.defineCustomElement('my-custom-element', MyCustomElement);
     27document.defineElement('my-custom-element', MyCustomElement);
    2828
    2929</script>
  • trunk/LayoutTests/fast/custom-elements/parser/parser-constructs-custom-elements.html

    r197463 r197602  
    2626}, 'HTML parser must NOT create a custom element before defineElement is called');
    2727
    28 document.defineCustomElement('my-custom-element', MyCustomElement);
     28document.defineElement('my-custom-element', MyCustomElement);
    2929
    3030</script>
  • trunk/LayoutTests/fast/custom-elements/parser/parser-fallsback-to-unknown-element.html

    r197463 r197602  
    1919    }
    2020};
    21 document.defineCustomElement('returns-text', ReturnsTextNode);
     21document.defineElement('returns-text', ReturnsTextNode);
    2222
    2323class ReturnsNonElementObject extends HTMLElement {
     
    2727    }
    2828};
    29 document.defineCustomElement('returns-non-element-object', ReturnsNonElementObject);
     29document.defineElement('returns-non-element-object', ReturnsNonElementObject);
    3030
    3131class LacksSuperCall extends HTMLElement {
    3232    constructor() { }
    3333};
    34 document.defineCustomElement('lacks-super-call', LacksSuperCall);
     34document.defineElement('lacks-super-call', LacksSuperCall);
    3535
    3636class ThrowsException extends HTMLElement {
     
    3939    }
    4040};
    41 document.defineCustomElement('throws-exception', ThrowsException);
     41document.defineElement('throws-exception', ThrowsException);
    4242
    4343</script>
  • trunk/LayoutTests/fast/custom-elements/parser/parser-sets-attributes-and-children.html

    r197463 r197602  
    2323    }
    2424};
    25 document.defineCustomElement('my-custom-element', MyCustomElement);
     25document.defineElement('my-custom-element', MyCustomElement);
    2626
    2727</script>
  • trunk/LayoutTests/fast/custom-elements/parser/parser-uses-constructed-element.html

    r197463 r197602  
    2626    }
    2727};
    28 document.defineCustomElement('instantiates-itself-before-super', InstantiatesItselfBeforeSuper);
     28document.defineElement('instantiates-itself-before-super', InstantiatesItselfBeforeSuper);
    2929
    3030let shouldCreateAnotherInstance = true;
     
    4343    }
    4444};
    45 document.defineCustomElement('returns-another-instance', ReturnsAnotherInstance);
     45document.defineElement('returns-another-instance', ReturnsAnotherInstance);
    4646
    4747</script>
  • trunk/LayoutTests/fast/custom-elements/parser/parser-uses-registry-of-owner-document.html

    r197528 r197602  
    1414
    1515class MyCustomElement extends HTMLElement { };
    16 document.defineCustomElement('my-custom-element', MyCustomElement);
     16document.defineElement('my-custom-element', MyCustomElement);
    1717
    1818document.write('<template><my-custom-element></my-custom-element></template>');
     
    4444
    4545class ElementInIFrame extends iframe.contentWindow.HTMLElement { };
    46 iframe.contentDocument.defineCustomElement('element-in-iframe', ElementInIFrame);
     46iframe.contentDocument.defineElement('element-in-iframe', ElementInIFrame);
    4747iframe.contentDocument.body.innerHTML = '<element-in-iframe></element-in-iframe>';
    4848
  • trunk/Source/WebCore/ChangeLog

    r197600 r197602  
     12016-03-04  Ryosuke Niwa  <rniwa@webkit.org>
     2
     3        Update defineCustomElement according to the spec rewrite
     4        https://bugs.webkit.org/show_bug.cgi?id=155010
     5        <rdar://problem/24970878>
     6
     7        Reviewed by Chris Dumez.
     8
     9        Updated the implementation of defineCustomElement and HTMLConstructor per recent rewrite of the spec:
     10        https://w3c.github.io/webcomponents/spec/custom/#dom-document-defineelement
     11        https://w3c.github.io/webcomponents/spec/custom/#htmlelement-constructor
     12
     13        defineCustomElement is now called defineElement and we disallow defining multiple custom elements with
     14        a single class and throw an exception in defineElement.
     15
     16        Test: fast/custom-elements/Document-defineElement.html
     17
     18        * bindings/js/JSDocumentCustom.cpp:
     19        (WebCore::JSDocument::defineElement): Renamed from defineCustomElement. Throw an exception when the interface
     20        already defines another custom element. Also added FIXME's for missing steps.
     21
     22        * bindings/js/JSHTMLElementCustom.cpp:
     23        (WebCore::constructJSHTMLElement): Removed the support for specifying a tag name in the first argument when
     24        a single class defines multiple custom elements since that now results in an exception (in defineElement).
     25
     26        * dom/CustomElementDefinitions.cpp:
     27        (WebCore::CustomElementDefinitions::containsConstructor): Added.
     28        * dom/CustomElementDefinitions.h:
     29        * dom/Document.idl: Renamed defineCustomElement to defineElement.
     30        * html/HTMLElement.idl: Removed the optional tag name from the constructor.
     31
    1322016-03-04  Tim Horton  <timothy_horton@apple.com>
    233
  • trunk/Source/WebCore/bindings/js/JSDocumentCustom.cpp

    r197528 r197602  
    136136
    137137#if ENABLE(CUSTOM_ELEMENTS)
    138 JSValue JSDocument::defineCustomElement(ExecState& state)
     138JSValue JSDocument::defineElement(ExecState& state)
    139139{
    140140    AtomicString tagName(state.argument(0).toString(&state)->toAtomicString(&state));
     
    164164    }
    165165
    166     QualifiedName name(nullAtom, tagName, HTMLNames::xhtmlNamespaceURI);
    167166    auto& definitions = document.ensureCustomElementDefinitions();
    168167    if (definitions.findInterface(tagName)) {
     
    170169        return jsUndefined();
    171170    }
     171
     172    if (definitions.containsConstructor(object)) {
     173        throwNotSupportedError(state, "Cannot define multiple custom elements with the same class");
     174        return jsUndefined();
     175    }
     176
     177    // FIXME: 10. Let prototype be Get(constructor, "prototype"). Rethrow any exceptions.
     178    // FIXME: 11. If Type(prototype) is not Object, throw a TypeError exception.
     179    // FIXME: 12. Let attachedCallback be Get(prototype, "attachedCallback"). Rethrow any exceptions.
     180    // FIXME: 13. Let detachedCallback be Get(prototype, "detachedCallback"). Rethrow any exceptions.
     181    // FIXME: 14. Let attributeChangedCallback be Get(prototype, "attributeChangedCallback"). Rethrow any exceptions.
     182
     183    QualifiedName name(nullAtom, tagName, HTMLNames::xhtmlNamespaceURI);
    172184    definitions.defineElement(name, JSCustomElementInterface::create(object, globalObject()));
    173185    PrivateName uniquePrivateName;
    174186    globalObject()->putDirect(globalObject()->vm(), uniquePrivateName, object);
     187
     188    // FIXME: 17. Let map be registry's upgrade candidates map.
     189    // FIXME: 18. Upgrade a newly-defined element given map and definition.
    175190
    176191    return jsUndefined();
  • trunk/Source/WebCore/bindings/js/JSHTMLElementCustom.cpp

    r195087 r197602  
    5555    JSObject* newTarget = newTargetValue.getObject();
    5656    QualifiedName fullName = definitions->findName(newTarget);
    57     if (fullName == nullQName()) {
    58         if (UNLIKELY(state->argumentCount() < 1))
    59             return throwVMError(state, createNotEnoughArgumentsError(state));
    60     }
    61 
    62     if (state->argumentCount()) {
    63         String name;
    64         if (!state->argument(0).getString(state, name))
    65             return throwVMTypeError(state, "The first argument is not a valid custom element name");
    66        
    67         auto* interface = definitions->findInterface(name);
    68         if (!interface)
    69             return throwVMTypeError(state, "The first argument is not a valid custom element name");
    70        
    71         if (newTarget != interface->constructor())
    72             return throwVMTypeError(state, "Attempt to construct a custom element with a wrong interface");
    73        
    74         fullName = QualifiedName(nullAtom, name, HTMLNames::xhtmlNamespaceURI);
    75     }
     57    if (fullName == nullQName())
     58        return throwVMTypeError(state, "new.target does not define a custom element");
    7659
    7760    auto* globalObject = jsConstructor->globalObject();
  • trunk/Source/WebCore/dom/CustomElementDefinitions.cpp

    r195538 r197602  
    9595}
    9696
     97bool CustomElementDefinitions::containsConstructor(const JSC::JSObject* constructor) const
     98{
     99    return m_constructorMap.contains(constructor);
     100}
     101
    97102const QualifiedName& CustomElementDefinitions::findName(const JSC::JSObject* constructor) const
    98103{
  • trunk/Source/WebCore/dom/CustomElementDefinitions.h

    r195538 r197602  
    5353    JSCustomElementInterface* findInterface(const QualifiedName&) const;
    5454    JSCustomElementInterface* findInterface(const AtomicString&) const;
     55    bool containsConstructor(const JSC::JSObject*) const;
    5556    const QualifiedName& findName(const JSC::JSObject*) const;
    5657
  • trunk/Source/WebCore/dom/Document.idl

    r197353 r197602  
    296296#if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT
    297297    [Custom, RaisesException, Conditional=CUSTOM_ELEMENTS]
    298     void defineCustomElement(DOMString tagName, CustomElementInterface elementInterface);
     298    void defineElement(DOMString localName, Function constructor);
    299299#endif
    300300
  • trunk/Source/WebCore/html/HTMLElement.idl

    r197353 r197602  
    2121[
    2222#if defined(ENABLE_CUSTOM_ELEMENTS) && ENABLE_CUSTOM_ELEMENTS
    23     CustomConstructor(optional DOMString localName),
     23    CustomConstructor(),
    2424#endif
    2525    JSGenerateToNativeObject,
Note: See TracChangeset for help on using the changeset viewer.