Diff
Modified: trunk/LayoutTests/ChangeLog (197601 => 197602)
--- trunk/LayoutTests/ChangeLog 2016-03-05 01:06:19 UTC (rev 197601)
+++ trunk/LayoutTests/ChangeLog 2016-03-05 01:23:42 UTC (rev 197602)
@@ -1,3 +1,30 @@
+2016-03-04 Ryosuke Niwa <[email protected]>
+
+ Update defineCustomElement according to the spec rewrite
+ https://bugs.webkit.org/show_bug.cgi?id=155010
+ <rdar://problem/24970878>
+
+ Reviewed by Chris Dumez.
+
+ 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:
+
2016-03-04 Simon Fraser <[email protected]>
Use larger tiles when possible to reduce per-tile painting overhead
Modified: trunk/LayoutTests/fast/custom-elements/Document-createElement.html (197601 => 197602)
--- trunk/LayoutTests/fast/custom-elements/Document-createElement.html 2016-03-05 01:06:19 UTC (rev 197601)
+++ trunk/LayoutTests/fast/custom-elements/Document-createElement.html 2016-03-05 01:23:42 UTC (rev 197602)
@@ -18,7 +18,7 @@
assert_true(document.createElement('my-custom-element') instanceof HTMLElement);
assert_false(document.createElement('my-custom-element') instanceof MyCustomElement);
- document.defineCustomElement('my-custom-element', MyCustomElement);
+ document.defineElement('my-custom-element', MyCustomElement);
var instance = document.createElement('my-custom-element');
assert_true(instance instanceof MyCustomElement);
assert_equals(instance.localName, 'my-custom-element');
@@ -33,7 +33,7 @@
return {foo: 'bar'};
}
};
- document.defineCustomElement('object-custom-element', ObjectCustomElement);
+ document.defineElement('object-custom-element', ObjectCustomElement);
var instance = new ObjectCustomElement;
assert_true(instance instanceof Object);
@@ -49,7 +49,7 @@
return document.createTextNode('hello');
}
};
- document.defineCustomElement('text-custom-element', TextCustomElement);
+ document.defineElement('text-custom-element', TextCustomElement);
assert_true(new TextCustomElement instanceof Text);
assert_equals(document.createElement('object-custom-element'), null);
}, 'document.createElement must return null when a custom element constructor returns a Text node');
@@ -64,7 +64,7 @@
return createdElement;
}
};
- document.defineCustomElement('div-custom-element', DivCustomElement);
+ document.defineElement('div-custom-element', DivCustomElement);
assert_true(new DivCustomElement instanceof HTMLDivElement);
var instance = document.createElement('div-custom-element');
@@ -82,7 +82,7 @@
throw exceptionToThrow;
}
};
- document.defineCustomElement('throw-custom-element', ThrowCustomElement);
+ document.defineElement('throw-custom-element', ThrowCustomElement);
assert_throws(null, function () { new ThrowCustomElement; });
Deleted: trunk/LayoutTests/fast/custom-elements/Document-defineCustomElement-expected.txt (197601 => 197602)
--- trunk/LayoutTests/fast/custom-elements/Document-defineCustomElement-expected.txt 2016-03-05 01:06:19 UTC (rev 197601)
+++ trunk/LayoutTests/fast/custom-elements/Document-defineCustomElement-expected.txt 2016-03-05 01:23:42 UTC (rev 197602)
@@ -1,10 +0,0 @@
-
-PASS Check the existence of defineCustomElement on Document interface
-PASS document.defineCustomElement should throw with an invalid name
-PASS document.defineCustomElement should throw with a duplicate name
-PASS document.defineCustomElement must throw a NotSupportedError when the context object is an associated inert template document
-PASS document.defineCustomElement must throw a NotSupportedError when the context object is created by DOMImplementation.createHTMLDocument
-PASS document.defineCustomElement must throw a NotSupportedError when the context object is created by DOMImplementation.createDocument
-PASS document.defineCustomElement should throw when the element interface is not a constructor
-PASS document.defineCustomElement should define an instantiatable custom element
-
Deleted: trunk/LayoutTests/fast/custom-elements/Document-defineCustomElement.html (197601 => 197602)
--- trunk/LayoutTests/fast/custom-elements/Document-defineCustomElement.html 2016-03-05 01:06:19 UTC (rev 197601)
+++ trunk/LayoutTests/fast/custom-elements/Document-defineCustomElement.html 2016-03-05 01:23:42 UTC (rev 197602)
@@ -1,122 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<title>Custom Elements: Extensions to Document interface</title>
-<meta name="author" title="Ryosuke Niwa" href=""
-<meta name="assert" content="document.defineCustomElement should define a custom element">
-<script src=""
-<script src=""
-<link rel='stylesheet' href=''>
-</head>
-<body>
-<div id="log"></div>
-<script>
-
-test(function () {
- assert_true('defineCustomElement' in Document.prototype, '"defineCustomElement" exists on Document.prototype');
- assert_true('defineCustomElement' in document, '"defineCustomElement" exists on document');
-}, 'Check the existence of defineCustomElement on Document interface');
-
-test(function () {
- class MyCustomElement extends HTMLElement {};
-
- assert_throws({'name': 'SyntaxError'}, function () { document.defineCustomElement(null, MyCustomElement); },
- 'document.defineCustomElement must throw a SyntaxError if the tag name is null');
- assert_throws({'name': 'SyntaxError'}, function () { document.defineCustomElement('', MyCustomElement); },
- 'document.defineCustomElement must throw a SyntaxError if the tag name is empty');
- assert_throws({'name': 'SyntaxError'}, function () { document.defineCustomElement('abc', MyCustomElement); },
- 'document.defineCustomElement must throw a SyntaxError if the tag name does not contain "-"');
- assert_throws({'name': 'SyntaxError'}, function () { document.defineCustomElement('a-Bc', MyCustomElement); },
- 'document.defineCustomElement must throw a SyntaxError if the tag name contains an upper case letter');
-
- var builtinTagNames = [
- 'annotation-xml',
- 'color-profile',
- 'font-face',
- 'font-face-src',
- 'font-face-uri',
- 'font-face-format',
- 'font-face-name',
- 'missing-glyph'
- ];
-
- for (var tagName of builtinTagNames) {
- assert_throws({'name': 'SyntaxError'}, function () { document.defineCustomElement(tagName, MyCustomElement); },
- 'document.defineCustomElement must throw a SyntaxError if the tag name is "' + tagName + '"');
- }
-
-}, 'document.defineCustomElement should throw with an invalid name');
-
-test(function () {
- class SomeCustomElement extends HTMLElement {};
- class OtherCustomElement extends HTMLElement {};
-
- document.defineCustomElement('some-custom-element', SomeCustomElement);
- assert_throws({'name': 'NotSupportedError'}, function () { document.defineCustomElement('some-custom-element', OtherCustomElement); },
- 'document.defineCustomElement must throw a NotSupportedError if the specified tag name is already used');
-
-}, 'document.defineCustomElement should throw with a duplicate name');
-
-test(function () {
- class SomeCustomElement extends HTMLElement {};
-
- var templateContentOwnerDocument = document.createElement('template').content.ownerDocument;
- assert_throws({'name': 'NotSupportedError'}, function () {
- templateContentOwnerDocument.defineCustomElement('some-custom-element', SomeCustomElement);
- });
-
-}, 'document.defineCustomElement must throw a NotSupportedError when the context object is an associated inert template document');
-
-test(function () {
- class SomeCustomElement extends HTMLElement {};
-
- var windowlessDocument = document.implementation.createHTMLDocument();
- assert_throws({'name': 'NotSupportedError'}, function () {
- windowlessDocument.defineCustomElement('some-custom-element', SomeCustomElement);
- });
-
-}, 'document.defineCustomElement must throw a NotSupportedError when the context object is created by DOMImplementation.createHTMLDocument');
-
-test(function () {
- class SomeCustomElement extends HTMLElement {};
-
- var windowlessDocument = document.implementation.createDocument('http://www.w3.org/1999/xhtml', 'html', null)
- assert_throws({'name': 'NotSupportedError'}, function () {
- windowlessDocument.defineCustomElement('some-custom-element', SomeCustomElement);
- });
-
-}, 'document.defineCustomElement must throw a NotSupportedError when the context object is created by DOMImplementation.createDocument');
-
-test(function () {
- assert_throws({'name': 'TypeError'}, function () { document.defineCustomElement('invalid-element', 1); },
- 'document.defineCustomElement must throw a TypeError when the element interface is a number');
- assert_throws({'name': 'TypeError'}, function () { document.defineCustomElement('invalid-element', '123'); },
- 'document.defineCustomElement must throw a TypeError when the element interface is a string');
- assert_throws({'name': 'TypeError'}, function () { document.defineCustomElement('invalid-element', {}); },
- 'document.defineCustomElement must throw a TypeError when the element interface is an object');
- assert_throws({'name': 'TypeError'}, function () { document.defineCustomElement('invalid-element', []); },
- 'document.defineCustomElement must throw a TypeError when the element interface is an array');
-}, 'document.defineCustomElement should throw when the element interface is not a constructor');
-
-test(function () {
- class MyCustomElement extends HTMLElement {};
- document.defineCustomElement('my-custom-element', MyCustomElement);
-
- var instance = new MyCustomElement;
- assert_true(instance instanceof MyCustomElement,
- 'An instance of a custom HTML element be an instance of the associated interface');
-
- assert_true(instance instanceof HTMLElement,
- 'An instance of a custom HTML element must inherit from HTMLElement');
-
- assert_equals(instance.localName, 'my-custom-element',
- 'An instance of a custom element must use the associated tag name');
-
- assert_equals(instance.namespaceURI, 'http://www.w3.org/1999/xhtml',
- 'A custom element HTML must use HTML namespace');
-
-}, 'document.defineCustomElement should define an instantiatable custom element');
-
-</script>
-</body>
-</html>
Copied: trunk/LayoutTests/fast/custom-elements/Document-defineElement-expected.txt (from rev 197596, trunk/LayoutTests/fast/custom-elements/Document-defineCustomElement-expected.txt) (0 => 197602)
--- trunk/LayoutTests/fast/custom-elements/Document-defineElement-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/custom-elements/Document-defineElement-expected.txt 2016-03-05 01:23:42 UTC (rev 197602)
@@ -0,0 +1,11 @@
+
+PASS Check the existence of defineElement on Document interface
+PASS document.defineElement should throw with an invalid name
+PASS document.defineElement should throw when there is already a custom element of the same name
+PASS document.defineElement should throw when there is already a custom element with the same class
+PASS document.defineElement must throw a NotSupportedError when the context object is an associated inert template document
+PASS document.defineElement must throw a NotSupportedError when the context object is created by DOMImplementation.createHTMLDocument
+PASS document.defineElement must throw a NotSupportedError when the context object is created by DOMImplementation.createDocument
+PASS document.defineElement should throw when the element interface is not a constructor
+PASS document.defineElement should define an instantiatable custom element
+
Copied: trunk/LayoutTests/fast/custom-elements/Document-defineElement.html (from rev 197596, trunk/LayoutTests/fast/custom-elements/Document-defineCustomElement.html) (0 => 197602)
--- trunk/LayoutTests/fast/custom-elements/Document-defineElement.html (rev 0)
+++ trunk/LayoutTests/fast/custom-elements/Document-defineElement.html 2016-03-05 01:23:42 UTC (rev 197602)
@@ -0,0 +1,131 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>Custom Elements: Extensions to Document interface</title>
+<meta name="author" title="Ryosuke Niwa" href=""
+<meta name="assert" content="document.defineElement should define a custom element">
+<script src=""
+<script src=""
+<link rel='stylesheet' href=''>
+</head>
+<body>
+<div id="log"></div>
+<script>
+
+test(function () {
+ assert_true('defineElement' in Document.prototype, '"defineElement" exists on Document.prototype');
+ assert_true('defineElement' in document, '"defineElement" exists on document');
+}, 'Check the existence of defineElement on Document interface');
+
+test(function () {
+ class MyCustomElement extends HTMLElement {};
+
+ assert_throws({'name': 'SyntaxError'}, function () { document.defineElement(null, MyCustomElement); },
+ 'document.defineElement must throw a SyntaxError if the tag name is null');
+ assert_throws({'name': 'SyntaxError'}, function () { document.defineElement('', MyCustomElement); },
+ 'document.defineElement must throw a SyntaxError if the tag name is empty');
+ assert_throws({'name': 'SyntaxError'}, function () { document.defineElement('abc', MyCustomElement); },
+ 'document.defineElement must throw a SyntaxError if the tag name does not contain "-"');
+ assert_throws({'name': 'SyntaxError'}, function () { document.defineElement('a-Bc', MyCustomElement); },
+ 'document.defineElement must throw a SyntaxError if the tag name contains an upper case letter');
+
+ var builtinTagNames = [
+ 'annotation-xml',
+ 'color-profile',
+ 'font-face',
+ 'font-face-src',
+ 'font-face-uri',
+ 'font-face-format',
+ 'font-face-name',
+ 'missing-glyph'
+ ];
+
+ for (var tagName of builtinTagNames) {
+ assert_throws({'name': 'SyntaxError'}, function () { document.defineElement(tagName, MyCustomElement); },
+ 'document.defineElement must throw a SyntaxError if the tag name is "' + tagName + '"');
+ }
+
+}, 'document.defineElement should throw with an invalid name');
+
+test(function () {
+ class SomeCustomElement extends HTMLElement {};
+ class OtherCustomElement extends HTMLElement {};
+
+ document.defineElement('some-custom-element', SomeCustomElement);
+ assert_throws({'name': 'NotSupportedError'}, function () { document.defineElement('some-custom-element', OtherCustomElement); },
+ 'document.defineElement must throw a NotSupportedError if the specified tag name is already used');
+
+}, 'document.defineElement should throw when there is already a custom element of the same name');
+
+test(function () {
+ class AnotherCustomElement extends HTMLElement {};
+
+ document.defineElement('another-custom-element', AnotherCustomElement);
+ assert_throws({'name': 'NotSupportedError'}, function () { document.defineElement('some-other-element', AnotherCustomElement); },
+ 'document.defineElement must throw a NotSupportedError if the specified class already defines an element');
+
+}, 'document.defineElement should throw when there is already a custom element with the same class');
+
+test(function () {
+ class SomeCustomElement extends HTMLElement {};
+
+ var templateContentOwnerDocument = document.createElement('template').content.ownerDocument;
+ assert_throws({'name': 'NotSupportedError'}, function () {
+ templateContentOwnerDocument.defineElement('some-custom-element', SomeCustomElement);
+ });
+
+}, 'document.defineElement must throw a NotSupportedError when the context object is an associated inert template document');
+
+test(function () {
+ class SomeCustomElement extends HTMLElement {};
+
+ var windowlessDocument = document.implementation.createHTMLDocument();
+ assert_throws({'name': 'NotSupportedError'}, function () {
+ windowlessDocument.defineElement('some-custom-element', SomeCustomElement);
+ });
+
+}, 'document.defineElement must throw a NotSupportedError when the context object is created by DOMImplementation.createHTMLDocument');
+
+test(function () {
+ class SomeCustomElement extends HTMLElement {};
+
+ var windowlessDocument = document.implementation.createDocument('http://www.w3.org/1999/xhtml', 'html', null)
+ assert_throws({'name': 'NotSupportedError'}, function () {
+ windowlessDocument.defineElement('some-custom-element', SomeCustomElement);
+ });
+
+}, 'document.defineElement must throw a NotSupportedError when the context object is created by DOMImplementation.createDocument');
+
+test(function () {
+ assert_throws({'name': 'TypeError'}, function () { document.defineElement('invalid-element', 1); },
+ 'document.defineElement must throw a TypeError when the element interface is a number');
+ assert_throws({'name': 'TypeError'}, function () { document.defineElement('invalid-element', '123'); },
+ 'document.defineElement must throw a TypeError when the element interface is a string');
+ assert_throws({'name': 'TypeError'}, function () { document.defineElement('invalid-element', {}); },
+ 'document.defineElement must throw a TypeError when the element interface is an object');
+ assert_throws({'name': 'TypeError'}, function () { document.defineElement('invalid-element', []); },
+ 'document.defineElement must throw a TypeError when the element interface is an array');
+}, 'document.defineElement should throw when the element interface is not a constructor');
+
+test(function () {
+ class MyCustomElement extends HTMLElement {};
+ document.defineElement('my-custom-element', MyCustomElement);
+
+ var instance = new MyCustomElement;
+ assert_true(instance instanceof MyCustomElement,
+ 'An instance of a custom HTML element be an instance of the associated interface');
+
+ assert_true(instance instanceof HTMLElement,
+ 'An instance of a custom HTML element must inherit from HTMLElement');
+
+ assert_equals(instance.localName, 'my-custom-element',
+ 'An instance of a custom element must use the associated tag name');
+
+ assert_equals(instance.namespaceURI, 'http://www.w3.org/1999/xhtml',
+ 'A custom element HTML must use HTML namespace');
+
+}, 'document.defineElement should define an instantiatable custom element');
+
+</script>
+</body>
+</html>
Modified: trunk/LayoutTests/fast/custom-elements/HTMLElement-constructor-expected.txt (197601 => 197602)
--- trunk/LayoutTests/fast/custom-elements/HTMLElement-constructor-expected.txt 2016-03-05 01:06:19 UTC (rev 197601)
+++ trunk/LayoutTests/fast/custom-elements/HTMLElement-constructor-expected.txt 2016-03-05 01:23:42 UTC (rev 197602)
@@ -2,7 +2,6 @@
PASS HTMLElement constructor must throw a TypeError when there is no derived class
PASS HTMLElement constructor must throw TypeError when custom element is not well defined
PASS HTMLElement constructor must infer the tag name from the element interface
-PASS HTMLElement constructor must allow associating an element interface with multiple tag names
PASS HTMLElement constructor must allow subclassing a custom element
PASS HTMLElement constructor must allow subclassing an user-defined subclass of HTMLElement
Modified: trunk/LayoutTests/fast/custom-elements/HTMLElement-constructor.html (197601 => 197602)
--- trunk/LayoutTests/fast/custom-elements/HTMLElement-constructor.html 2016-03-05 01:06:19 UTC (rev 197601)
+++ trunk/LayoutTests/fast/custom-elements/HTMLElement-constructor.html 2016-03-05 01:23:42 UTC (rev 197602)
@@ -14,34 +14,19 @@
test(function () {
class SomeDefinedElement extends HTMLElement {};
- document.defineCustomElement('defined-element', SomeDefinedElement);
+ document.defineElement('defined-element', SomeDefinedElement);
assert_throws({'name': 'TypeError'}, function () { new HTMLElement('defined-element'); });
}, 'HTMLElement constructor must throw a TypeError when there is no derived class');
test(function () {
class SomeCustomElement extends HTMLElement {};
assert_throws({'name': 'TypeError'}, function () { new SomeCustomElement; },
- 'Instantiating a custom element without calling defineCustomElement must throw TypeError');
-
- class AnotherCustomElement extends HTMLElement {
- constructor() { super('some-element'); }
- };
- document.defineCustomElement('another-element', AnotherCustomElement);
- assert_throws({'name': 'TypeError'}, function () { new AnotherCustomElement; },
- 'Calling HTMLElement constructor with a mismatching tag name throw TypeError');
-
- class YetAnotherCustomElement extends HTMLElement {
- constructor() { super(1); }
- };
- document.defineCustomElement('yet-another-element', YetAnotherCustomElement);
- assert_throws({'name': 'TypeError'}, function () { new YetAnotherCustomElement; },
- 'Calling HTMLElement constructor with a bad tag name throw TypeError');
-
+ 'Instantiating a custom element without calling defineElement must throw TypeError');
}, 'HTMLElement constructor must throw TypeError when custom element is not well defined');
test(function () {
class CustomElementWithInferredTagName extends HTMLElement {};
- document.defineCustomElement('inferred-name', CustomElementWithInferredTagName);
+ document.defineElement('inferred-name', CustomElementWithInferredTagName);
var instance = new CustomElementWithInferredTagName;
assert_true(instance instanceof Element, 'A custom element must inherit from Element');
@@ -59,32 +44,19 @@
}, 'HTMLElement constructor must infer the tag name from the element interface');
test(function () {
- class ElementWithMultipleTagNames extends HTMLElement { };
- document.defineCustomElement('custom-element-1', ElementWithMultipleTagNames);
- document.defineCustomElement('custom-element-2', ElementWithMultipleTagNames);
-
- var instance1 = new ElementWithMultipleTagNames('custom-element-1');
- assert_true(instance1 instanceof ElementWithMultipleTagNames);
- assert_equals(instance1.localName, 'custom-element-1');
- assert_equals(instance1.nodeName, 'CUSTOM-ELEMENT-1');
-
- var instance2 = new ElementWithMultipleTagNames('custom-element-2');
- assert_true(instance2 instanceof ElementWithMultipleTagNames);
- assert_equals(instance2.localName, 'custom-element-2');
- assert_equals(instance2.nodeName, 'CUSTOM-ELEMENT-2');
-
- assert_throws({'name': 'TypeError'}, function () { new ElementWithMultipleTagNames; },
- 'Instantiating an element interface associated with multiple tag names without specifying the tag name must throw TypeError');
-
-}, 'HTMLElement constructor must allow associating an element interface with multiple tag names');
-
-test(function () {
class ConcreteCustomElement extends HTMLElement { };
class SubCustomElement extends ConcreteCustomElement { };
- document.defineCustomElement('concrete-custom-element', ConcreteCustomElement);
- document.defineCustomElement('sub-custom-element', SubCustomElement);
+ document.defineElement('concrete-custom-element', ConcreteCustomElement);
+ document.defineElement('sub-custom-element', SubCustomElement);
+ var instance = new ConcreteCustomElement();
+ assert_true(instance instanceof ConcreteCustomElement);
+ assert_false(instance instanceof SubCustomElement);
+ assert_equals(instance.localName, 'concrete-custom-element');
+ assert_equals(instance.nodeName, 'CONCRETE-CUSTOM-ELEMENT');
+
var instance = new SubCustomElement();
+ assert_true(instance instanceof ConcreteCustomElement);
assert_true(instance instanceof SubCustomElement);
assert_equals(instance.localName, 'sub-custom-element');
assert_equals(instance.nodeName, 'SUB-CUSTOM-ELEMENT');
@@ -94,9 +66,10 @@
test(function () {
class AbstractCustomElement extends HTMLElement { };
class ConcreteSubCustomElement extends AbstractCustomElement { };
- document.defineCustomElement('concrete-sub-custom-element', ConcreteSubCustomElement);
+ document.defineElement('concrete-sub-custom-element', ConcreteSubCustomElement);
var instance = new ConcreteSubCustomElement();
+ assert_true(instance instanceof AbstractCustomElement);
assert_true(instance instanceof ConcreteSubCustomElement);
assert_equals(instance.localName, 'concrete-sub-custom-element');
assert_equals(instance.nodeName, 'CONCRETE-SUB-CUSTOM-ELEMENT');
Modified: trunk/LayoutTests/fast/custom-elements/parser/parser-constructs-custom-element-in-document-write.html (197601 => 197602)
--- trunk/LayoutTests/fast/custom-elements/parser/parser-constructs-custom-element-in-document-write.html 2016-03-05 01:06:19 UTC (rev 197601)
+++ trunk/LayoutTests/fast/custom-elements/parser/parser-constructs-custom-element-in-document-write.html 2016-03-05 01:23:42 UTC (rev 197602)
@@ -13,7 +13,7 @@
<script>
class MyCustomElement extends HTMLElement { }
-document.defineCustomElement('my-custom-element', MyCustomElement);
+document.defineElement('my-custom-element', MyCustomElement);
document.write('<my-custom-element></my-custom-element>');
Modified: trunk/LayoutTests/fast/custom-elements/parser/parser-constructs-custom-element-synchronously.html (197601 => 197602)
--- trunk/LayoutTests/fast/custom-elements/parser/parser-constructs-custom-element-synchronously.html 2016-03-05 01:06:19 UTC (rev 197601)
+++ trunk/LayoutTests/fast/custom-elements/parser/parser-constructs-custom-element-synchronously.html 2016-03-05 01:23:42 UTC (rev 197602)
@@ -24,7 +24,7 @@
containerNextSilbingInConstructor = container.nextSibling;
}
};
-document.defineCustomElement('my-custom-element', MyCustomElement);
+document.defineElement('my-custom-element', MyCustomElement);
</script>
<div id="custom-element-container">
Modified: trunk/LayoutTests/fast/custom-elements/parser/parser-constructs-custom-elements.html (197601 => 197602)
--- trunk/LayoutTests/fast/custom-elements/parser/parser-constructs-custom-elements.html 2016-03-05 01:06:19 UTC (rev 197601)
+++ trunk/LayoutTests/fast/custom-elements/parser/parser-constructs-custom-elements.html 2016-03-05 01:23:42 UTC (rev 197602)
@@ -25,7 +25,7 @@
}, 'HTML parser must NOT create a custom element before defineElement is called');
-document.defineCustomElement('my-custom-element', MyCustomElement);
+document.defineElement('my-custom-element', MyCustomElement);
</script>
<my-custom-element id="instance2"></my-custom-element>
Modified: trunk/LayoutTests/fast/custom-elements/parser/parser-fallsback-to-unknown-element.html (197601 => 197602)
--- trunk/LayoutTests/fast/custom-elements/parser/parser-fallsback-to-unknown-element.html 2016-03-05 01:06:19 UTC (rev 197601)
+++ trunk/LayoutTests/fast/custom-elements/parser/parser-fallsback-to-unknown-element.html 2016-03-05 01:23:42 UTC (rev 197602)
@@ -18,7 +18,7 @@
return document.createTextNode('some text');
}
};
-document.defineCustomElement('returns-text', ReturnsTextNode);
+document.defineElement('returns-text', ReturnsTextNode);
class ReturnsNonElementObject extends HTMLElement {
constructor() {
@@ -26,19 +26,19 @@
return {};
}
};
-document.defineCustomElement('returns-non-element-object', ReturnsNonElementObject);
+document.defineElement('returns-non-element-object', ReturnsNonElementObject);
class LacksSuperCall extends HTMLElement {
constructor() { }
};
-document.defineCustomElement('lacks-super-call', LacksSuperCall);
+document.defineElement('lacks-super-call', LacksSuperCall);
class ThrowsException extends HTMLElement {
constructor() {
throw 'Bad';
}
};
-document.defineCustomElement('throws-exception', ThrowsException);
+document.defineElement('throws-exception', ThrowsException);
</script>
<returns-text></returns-text>
Modified: trunk/LayoutTests/fast/custom-elements/parser/parser-sets-attributes-and-children.html (197601 => 197602)
--- trunk/LayoutTests/fast/custom-elements/parser/parser-sets-attributes-and-children.html 2016-03-05 01:06:19 UTC (rev 197601)
+++ trunk/LayoutTests/fast/custom-elements/parser/parser-sets-attributes-and-children.html 2016-03-05 01:23:42 UTC (rev 197602)
@@ -22,7 +22,7 @@
numberOfChildNodesInConstructor = this.childNodes.length;
}
};
-document.defineCustomElement('my-custom-element', MyCustomElement);
+document.defineElement('my-custom-element', MyCustomElement);
</script>
<my-custom-element id="custom-element-id" class="class1 class2">hello <b>world</b></my-custom-element>
Modified: trunk/LayoutTests/fast/custom-elements/parser/parser-uses-constructed-element.html (197601 => 197602)
--- trunk/LayoutTests/fast/custom-elements/parser/parser-uses-constructed-element.html 2016-03-05 01:06:19 UTC (rev 197601)
+++ trunk/LayoutTests/fast/custom-elements/parser/parser-uses-constructed-element.html 2016-03-05 01:23:42 UTC (rev 197602)
@@ -25,7 +25,7 @@
elementCreatedBySuperCall = this;
}
};
-document.defineCustomElement('instantiates-itself-before-super', InstantiatesItselfBeforeSuper);
+document.defineElement('instantiates-itself-before-super', InstantiatesItselfBeforeSuper);
let shouldCreateAnotherInstance = true;
let anotherInstance = undefined;
@@ -42,7 +42,7 @@
return this;
}
};
-document.defineCustomElement('returns-another-instance', ReturnsAnotherInstance);
+document.defineElement('returns-another-instance', ReturnsAnotherInstance);
</script>
<instantiates-itself-before-super></instantiates-itself-before-super>
Modified: trunk/LayoutTests/fast/custom-elements/parser/parser-uses-registry-of-owner-document.html (197601 => 197602)
--- trunk/LayoutTests/fast/custom-elements/parser/parser-uses-registry-of-owner-document.html 2016-03-05 01:06:19 UTC (rev 197601)
+++ trunk/LayoutTests/fast/custom-elements/parser/parser-uses-registry-of-owner-document.html 2016-03-05 01:23:42 UTC (rev 197602)
@@ -13,7 +13,7 @@
<script>
class MyCustomElement extends HTMLElement { };
-document.defineCustomElement('my-custom-element', MyCustomElement);
+document.defineElement('my-custom-element', MyCustomElement);
document.write('<template><my-custom-element></my-custom-element></template>');
@@ -43,7 +43,7 @@
}, 'HTML parser must not use the registry of the owner element\'s document inside an iframe');
class ElementInIFrame extends iframe.contentWindow.HTMLElement { };
-iframe.contentDocument.defineCustomElement('element-in-iframe', ElementInIFrame);
+iframe.contentDocument.defineElement('element-in-iframe', ElementInIFrame);
iframe.contentDocument.body.innerHTML = '<element-in-iframe></element-in-iframe>';
test(function () {
Modified: trunk/Source/WebCore/ChangeLog (197601 => 197602)
--- trunk/Source/WebCore/ChangeLog 2016-03-05 01:06:19 UTC (rev 197601)
+++ trunk/Source/WebCore/ChangeLog 2016-03-05 01:23:42 UTC (rev 197602)
@@ -1,3 +1,34 @@
+2016-03-04 Ryosuke Niwa <[email protected]>
+
+ Update defineCustomElement according to the spec rewrite
+ https://bugs.webkit.org/show_bug.cgi?id=155010
+ <rdar://problem/24970878>
+
+ Reviewed by Chris Dumez.
+
+ 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.
+
2016-03-04 Tim Horton <[email protected]>
Begin implementing <attachment> painting on iOS
Modified: trunk/Source/WebCore/bindings/js/JSDocumentCustom.cpp (197601 => 197602)
--- trunk/Source/WebCore/bindings/js/JSDocumentCustom.cpp 2016-03-05 01:06:19 UTC (rev 197601)
+++ trunk/Source/WebCore/bindings/js/JSDocumentCustom.cpp 2016-03-05 01:23:42 UTC (rev 197602)
@@ -135,7 +135,7 @@
#endif
#if ENABLE(CUSTOM_ELEMENTS)
-JSValue JSDocument::defineCustomElement(ExecState& state)
+JSValue JSDocument::defineElement(ExecState& state)
{
AtomicString tagName(state.argument(0).toString(&state)->toAtomicString(&state));
if (UNLIKELY(state.hadException()))
@@ -163,16 +163,31 @@
return throwSyntaxError(&state, "Custom element name cannot contain an upper case letter");
}
- QualifiedName name(nullAtom, tagName, HTMLNames::xhtmlNamespaceURI);
auto& definitions = document.ensureCustomElementDefinitions();
if (definitions.findInterface(tagName)) {
throwNotSupportedError(state, "Cannot define multiple custom elements with the same tag name");
return jsUndefined();
}
+
+ if (definitions.containsConstructor(object)) {
+ throwNotSupportedError(state, "Cannot define multiple custom elements with the same class");
+ return jsUndefined();
+ }
+
+ // FIXME: 10. Let prototype be Get(constructor, "prototype"). Rethrow any exceptions.
+ // FIXME: 11. If Type(prototype) is not Object, throw a TypeError exception.
+ // FIXME: 12. Let attachedCallback be Get(prototype, "attachedCallback"). Rethrow any exceptions.
+ // FIXME: 13. Let detachedCallback be Get(prototype, "detachedCallback"). Rethrow any exceptions.
+ // FIXME: 14. Let attributeChangedCallback be Get(prototype, "attributeChangedCallback"). Rethrow any exceptions.
+
+ QualifiedName name(nullAtom, tagName, HTMLNames::xhtmlNamespaceURI);
definitions.defineElement(name, JSCustomElementInterface::create(object, globalObject()));
PrivateName uniquePrivateName;
globalObject()->putDirect(globalObject()->vm(), uniquePrivateName, object);
+ // FIXME: 17. Let map be registry's upgrade candidates map.
+ // FIXME: 18. Upgrade a newly-defined element given map and definition.
+
return jsUndefined();
}
#endif
Modified: trunk/Source/WebCore/bindings/js/JSHTMLElementCustom.cpp (197601 => 197602)
--- trunk/Source/WebCore/bindings/js/JSHTMLElementCustom.cpp 2016-03-05 01:06:19 UTC (rev 197601)
+++ trunk/Source/WebCore/bindings/js/JSHTMLElementCustom.cpp 2016-03-05 01:23:42 UTC (rev 197602)
@@ -54,26 +54,9 @@
JSValue newTargetValue = state->thisValue();
JSObject* newTarget = newTargetValue.getObject();
QualifiedName fullName = definitions->findName(newTarget);
- if (fullName == nullQName()) {
- if (UNLIKELY(state->argumentCount() < 1))
- return throwVMError(state, createNotEnoughArgumentsError(state));
- }
+ if (fullName == nullQName())
+ return throwVMTypeError(state, "new.target does not define a custom element");
- if (state->argumentCount()) {
- String name;
- if (!state->argument(0).getString(state, name))
- return throwVMTypeError(state, "The first argument is not a valid custom element name");
-
- auto* interface = definitions->findInterface(name);
- if (!interface)
- return throwVMTypeError(state, "The first argument is not a valid custom element name");
-
- if (newTarget != interface->constructor())
- return throwVMTypeError(state, "Attempt to construct a custom element with a wrong interface");
-
- fullName = QualifiedName(nullAtom, name, HTMLNames::xhtmlNamespaceURI);
- }
-
auto* globalObject = jsConstructor->globalObject();
Structure* baseStructure = getDOMStructure<JSHTMLElement>(vm, *globalObject);
auto* newElementStructure = InternalFunction::createSubclassStructure(state, newTargetValue, baseStructure);
Modified: trunk/Source/WebCore/dom/CustomElementDefinitions.cpp (197601 => 197602)
--- trunk/Source/WebCore/dom/CustomElementDefinitions.cpp 2016-03-05 01:06:19 UTC (rev 197601)
+++ trunk/Source/WebCore/dom/CustomElementDefinitions.cpp 2016-03-05 01:23:42 UTC (rev 197602)
@@ -94,6 +94,11 @@
return it == m_nameMap.end() ? nullptr : it->value.interface.get();
}
+bool CustomElementDefinitions::containsConstructor(const JSC::JSObject* constructor) const
+{
+ return m_constructorMap.contains(constructor);
+}
+
const QualifiedName& CustomElementDefinitions::findName(const JSC::JSObject* constructor) const
{
auto it = m_constructorMap.find(constructor);
Modified: trunk/Source/WebCore/dom/CustomElementDefinitions.h (197601 => 197602)
--- trunk/Source/WebCore/dom/CustomElementDefinitions.h 2016-03-05 01:06:19 UTC (rev 197601)
+++ trunk/Source/WebCore/dom/CustomElementDefinitions.h 2016-03-05 01:23:42 UTC (rev 197602)
@@ -52,6 +52,7 @@
JSCustomElementInterface* findInterface(const QualifiedName&) const;
JSCustomElementInterface* findInterface(const AtomicString&) const;
+ bool containsConstructor(const JSC::JSObject*) const;
const QualifiedName& findName(const JSC::JSObject*) const;
enum class NameStatus { Valid, ConflictsWithBuiltinNames, NoHyphen, ContainsUpperCase };
Modified: trunk/Source/WebCore/dom/Document.idl (197601 => 197602)
--- trunk/Source/WebCore/dom/Document.idl 2016-03-05 01:06:19 UTC (rev 197601)
+++ trunk/Source/WebCore/dom/Document.idl 2016-03-05 01:23:42 UTC (rev 197602)
@@ -295,7 +295,7 @@
#if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT
[Custom, RaisesException, Conditional=CUSTOM_ELEMENTS]
- void defineCustomElement(DOMString tagName, CustomElementInterface elementInterface);
+ void defineElement(DOMString localName, Function constructor);
#endif
// Page visibility API.
Modified: trunk/Source/WebCore/html/HTMLElement.idl (197601 => 197602)
--- trunk/Source/WebCore/html/HTMLElement.idl 2016-03-05 01:06:19 UTC (rev 197601)
+++ trunk/Source/WebCore/html/HTMLElement.idl 2016-03-05 01:23:42 UTC (rev 197602)
@@ -20,7 +20,7 @@
[
#if defined(ENABLE_CUSTOM_ELEMENTS) && ENABLE_CUSTOM_ELEMENTS
- CustomConstructor(optional DOMString localName),
+ CustomConstructor(),
#endif
JSGenerateToNativeObject,
JSCustomPushEventHandlerScope,