Bug 1081037 - LinkConstructorAndPrototype in RegisterElement. r=wchen

This commit is contained in:
Gabor Krizsanits 2014-12-15 11:28:54 +01:00
parent 939f70baf5
commit 0781df2733
10 changed files with 153 additions and 73 deletions

View File

@ -6265,7 +6265,13 @@ nsDocument::RegisterElement(JSContext* aCx, const nsAString& aType,
return;
}
aRetval.set(JS_GetFunctionObject(constructor));
JS::Rooted<JSObject*> constructorObj(aCx, JS_GetFunctionObject(constructor));
if (!JS_LinkConstructorAndPrototype(aCx, constructorObj, protoObject)) {
rv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
return;
}
aRetval.set(constructorObj);
}
void

View File

@ -578,4 +578,5 @@ skip-if = buildapp == 'b2g' || e10s
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') || e10s #Bug 931116, b2g desktop specific, initial triage
support-files = file_bug871161-1.html file_bug871161-2.html
[test_bug1013316.html]
[test_bug1081037.html]

View File

@ -0,0 +1,142 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1081037
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 1081037</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="application/javascript">
/** Test for Bug 1081037 **/
function shouldThrow(fun, msg, ex, todo) {
try {
fun();
ok(todo, msg);
} catch (e) {
ok(new RegExp(ex).test(e), msg + " (thrown:" + e + ")")
}
}
var Foo = document.registerElement('x-foo', {
prototype: {bar: 5}
});
Foo.prototype.bar = 6;
var foo = new Foo();
is(foo.bar, 6, "prototype of the ctor returned from registerElement works");
var protoDesc = Object.getOwnPropertyDescriptor(Foo, "prototype");
is(protoDesc.configurable, false, "proto should be non-configurable");
is(protoDesc.enumerable, false, "proto should be non-enumerable");
is(protoDesc.writable, false, "proto should be non-writable");
// TODO: FIXME!
shouldThrow(function() {
document.registerElement('x-foo2', {
prototype: Foo.prototype
});
},
"if proto is an interface prototype object, registerElement should throw",
"not supported",
/* todo = */ true);
var nonConfigReadonlyProto = Object.create(HTMLElement.prototype,
{ constructor: { configurable: false, writable: false, value: 42 } });
shouldThrow(function() {
document.registerElement('x-nonconfig-readonly', {
prototype: nonConfigReadonlyProto
});
},
"non-configurable and not-writable constructor property",
"not supported");
// this is not defined in current spec:
var readonlyProto = Object.create(HTMLElement.prototype,
{ constructor: { configurable: true, writable: false, value: 42 } });
var Readonly = document.registerElement('x-nonconfig-readonly', {
prototype: readonlyProto
});
is(Readonly.prototype, readonlyProto, "configurable readonly constructor property");
var handler = {
getOwnPropertyDescriptor: function(target, name) {
return name == "constructor" ? undefined : Object.getOwnPropertyDescriptor(target,name);
},
defineProperty: function(target, name, propertyDescriptor) {
if (name == "constructor") {
throw "spec this";
}
return Object.defineProperty(target, name, propertyDescriptor);
},
has: function(target, name) {
if (name == "constructor") {
return false;
}
return name in target;
}
};
var proxy = new Proxy({}, handler);
shouldThrow(function() {
document.registerElement('x-proxymagic', {
prototype: proxy
});
},
"proxy magic",
"spec this");
var getOwn = 0;
var defineProp = 0;
var _has = 0;
var handler2 = {
getOwnPropertyDescriptor: function(target, name) {
if (name == "constructor") {
getOwn++;
}
return Object.getOwnPropertyDescriptor(target,name);
},
defineProperty: function(target, name, propertyDescriptor) {
if (name == "constructor") {
defineProp++;
}
return Object.defineProperty(target, name, propertyDescriptor);
},
has: function(target, name) {
if (name == "constructor") {
_has++;
}
return name in target;
}
};
var proxy2 = new Proxy({}, handler2);
document.registerElement('x-proxymagic2', {
prototype: proxy2
});
is(getOwn, 1, "number of getOwnPropertyDescriptor calls from registerElement: " + getOwn);
is(defineProp, 1, "number of defineProperty calls from registerElement: " + defineProp);
is(_has, 1, "number of 'has' calls from registerElement: " + _has);
</script>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1081037">Mozilla Bug 1081037</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
</pre>
</body>
</html>

View File

@ -1,7 +1,5 @@
[share-registry-create-document.html]
type: testharness
[Document created by createHTMLDocument should share an existing registry]
expected: FAIL
[Document created by createDocument with HTML namespace should share an existing registry]
expected: FAIL

View File

@ -1,20 +1,5 @@
[created-callback-element-prototype-test.html]
type: testharness
[Test custom element prototype inside created callback when custom element is created in HTML before registration of a custom element]
expected: FAIL
[Test custom element prototype inside created callback when custom element is created in HTML after registration of a custom element]
[Document created by createHTMLDocument should share an existing registry]
expected: FAIL
[Test custom element prototype inside created callback when custom element is created via document.createElement() before registration of a custom element]
expected: FAIL
[Test custom element prototype inside created callback when custom element is created via document.createElement() after registration of a custom element]
expected: FAIL
[Test custom element prototype inside created callback when custom element is created via constructor returned by method registerElement]
expected: FAIL
[Test custom element prototype inside created callback when custom element is created by UA parser before registration of a custom element]
expected: FAIL

View File

@ -1,29 +1,7 @@
[changing-is-attribute.html]
type: testharness
[Test custom element type, after assigning IS attribute value. Element is created by constructor]
expected: FAIL
[Test custom element type, after assigning IS attribute value. Element is created via innerHTML property]
expected: FAIL
[Test custom element type, after assigning IS attribute value to unresolved element. Element is created via innerHTML property]
expected: FAIL
[Test custom element type, after assigning IS attribute value. Element is defined in loaded HTML document]
expected: FAIL
[Test custom element type, after assigning IS attribute value to unresolved element. Element is defined in loaded HTML document]
expected: FAIL
[Test custom element type after changing IS attribute value. Element is HTML5 element with IS attribute referring to custom element type]
expected: FAIL
[Test custom element type after changing IS attribute value several times. Element is HTML5 element with IS attribute referring to custom element type]
expected: FAIL
[Test custom element type, after removing IS attribute value. Element is created via innerHTML property]
expected: FAIL
[Test custom element type, after removing IS attribute value. Element is HTML5 element with IS attribute referring to custom element type]
expected: FAIL

View File

@ -1,13 +1,5 @@
[custom-element-type-local-name-and-is-attribute.html]
type: testharness
[Custom element type must be taken from the local name of the element even if IS attribute provided.]
expected: FAIL
[Custom element type must be taken from the local name of the element even if IS attribute provided. Custom element is unresolved at first]
expected: FAIL
[Custom element type must be taken from the local name of the element even if IS attribute provided. There\'s no definition for the value of IS attribute at first]
expected: FAIL
[Custom element type must be taken from the local name of the element even if IS attribute provided. IS attribute refers to another custom element type, which extends HTML5 elements]
expected: FAIL
@ -15,3 +7,5 @@
[Custom element type must be taken from the local name of the custom element even if IS attribute provided. The element extends HTML5 elements, IS attribute refers to another custom element type.]
expected: FAIL
[Test custom element type after changing IS attribute value. Element is HTML5 element with IS attribute referring to custom element type]
expected: FAIL

View File

@ -1,8 +0,0 @@
[custom-element-type-local-name.html]
type: testharness
[Test custom element type, which is given via the local name of the custom element. Custom element created via innerHTML property]
expected: FAIL
[Test custom element type, which is given via the local name of the custom element. Custom element is defined in loaded HTML document]
expected: FAIL

View File

@ -1,8 +0,0 @@
[create-element-interface-type-is-a-local-name.html]
type: testharness
[Test Document.createElement() creates custom element of type, specified by localName argument, if an element definition with matching localName, namespace, and type is not registered]
expected: FAIL
[Test Document.createElementNS() creates custom element of type, specified by localName argument, if an element definition with matching localName, namespace, and type is not registered]
expected: FAIL

View File

@ -1,8 +0,0 @@
[create-element-type-is-a-local-name.html]
type: testharness
[Test Document.createElement() creates custom element of type, specified by single localName argument]
expected: FAIL
[Test Document.createElementNS() creates custom element of type, specified by localName argument. Argument typeExtension is not passed]
expected: FAIL