mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-24 01:17:34 +09:00
Bug 1274159 - Part 4: Add test cases for HTMLConstructor;
Tag UXP Issue #1344
This commit is contained in:
parent
af9931215b
commit
d76a336cd0
8 changed files with 437 additions and 0 deletions
9
dom/tests/mochitest/webcomponents/chrome.ini
Normal file
9
dom/tests/mochitest/webcomponents/chrome.ini
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
[DEFAULT]
|
||||
support-files =
|
||||
dummy_page.html
|
||||
|
||||
[test_custom_element_htmlconstructor_chrome.html]
|
||||
skip-if = os == 'android' # bug 1323645
|
||||
support-files =
|
||||
htmlconstructor_autonomous_tests.js
|
||||
htmlconstructor_builtin_tests.js
|
||||
10
dom/tests/mochitest/webcomponents/dummy_page.html
Normal file
10
dom/tests/mochitest/webcomponents/dummy_page.html
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Dummy test page</title>
|
||||
<meta charset="utf-8"/>
|
||||
</head>
|
||||
<body>
|
||||
<p>Dummy test page</p>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
promises.push(test_with_new_window((testWindow) => {
|
||||
// Test calling the HTMLElement constructor.
|
||||
(() => {
|
||||
SimpleTest.doesThrow(() => {
|
||||
testWindow.HTMLElement();
|
||||
}, 'calling the HTMLElement constructor should throw a TypeError');
|
||||
})();
|
||||
|
||||
// Test constructing a HTMLELement.
|
||||
(() => {
|
||||
SimpleTest.doesThrow(() => {
|
||||
new testWindow.HTMLElement();
|
||||
}, 'constructing a HTMLElement should throw a TypeError');
|
||||
})();
|
||||
|
||||
// Test constructing a custom element with defining HTMLElement as entry.
|
||||
(() => {
|
||||
testWindow.customElements.define('x-defining-html-element',
|
||||
testWindow.HTMLElement);
|
||||
SimpleTest.doesThrow(() => {
|
||||
new testWindow.HTMLElement();
|
||||
}, 'constructing a custom element with defining HTMLElement as registry ' +
|
||||
'entry should throw a TypeError');
|
||||
})();
|
||||
|
||||
// Test calling a custom element constructor and constructing an autonomous
|
||||
// custom element.
|
||||
(() => {
|
||||
let num_constructor_invocations = 0;
|
||||
class X extends testWindow.HTMLElement {
|
||||
constructor() {
|
||||
super();
|
||||
num_constructor_invocations++;
|
||||
}
|
||||
}
|
||||
testWindow.customElements.define('x-element', X);
|
||||
SimpleTest.doesThrow(() => {
|
||||
X();
|
||||
}, 'calling an autonomous custom element constructor should throw a TypeError');
|
||||
|
||||
let element = new X();
|
||||
SimpleTest.is(Object.getPrototypeOf(Cu.waiveXrays(element)), X.prototype,
|
||||
'constructing an autonomous custom element; ' +
|
||||
'the element should be a registered constructor');
|
||||
SimpleTest.is(element.localName, 'x-element',
|
||||
'constructing an autonomous custom element; ' +
|
||||
'the element tag name should be "x-element"');
|
||||
SimpleTest.is(element.namespaceURI, 'http://www.w3.org/1999/xhtml',
|
||||
'constructing an autonomous custom element; ' +
|
||||
'the element should be in the HTML namespace');
|
||||
SimpleTest.is(element.prefix, null,
|
||||
'constructing an autonomous custom element; ' +
|
||||
'the element name should not have a prefix');
|
||||
SimpleTest.is(element.ownerDocument, testWindow.document,
|
||||
'constructing an autonomous custom element; ' +
|
||||
'the element should be owned by the registry\'s associated ' +
|
||||
'document');
|
||||
SimpleTest.is(num_constructor_invocations, 1,
|
||||
'constructing an autonomous custom element; ' +
|
||||
'the constructor should have been invoked once');
|
||||
})();
|
||||
|
||||
// Test if prototype is no an object.
|
||||
(() => {
|
||||
function ElementWithNonObjectPrototype() {
|
||||
let o = Reflect.construct(testWindow.HTMLElement, [], new.target);
|
||||
SimpleTest.is(Object.getPrototypeOf(Cu.waiveXrays(o)), window.HTMLElement.prototype,
|
||||
'constructing an autonomous custom element; ' +
|
||||
'if prototype is not object, fallback from NewTarget\'s realm');
|
||||
}
|
||||
|
||||
// Prototype have to be an object during define(), otherwise define will
|
||||
// throw an TypeError exception.
|
||||
ElementWithNonObjectPrototype.prototype = {};
|
||||
testWindow.customElements.define('x-non-object-prototype',
|
||||
ElementWithNonObjectPrototype);
|
||||
|
||||
ElementWithNonObjectPrototype.prototype = "string";
|
||||
new ElementWithNonObjectPrototype();
|
||||
})();
|
||||
}));
|
||||
|
|
@ -0,0 +1,247 @@
|
|||
[
|
||||
// [TagName, InterfaceName]
|
||||
['a', 'Anchor'],
|
||||
['abbr', ''],
|
||||
['acronym', ''],
|
||||
['address', ''],
|
||||
['area', 'Area'],
|
||||
['article', ''],
|
||||
['aside', ''],
|
||||
['audio', 'Audio'],
|
||||
['b', ''],
|
||||
['base', 'Base'],
|
||||
['basefont', ''],
|
||||
['bdo', ''],
|
||||
['big', ''],
|
||||
['blockquote', 'Quote'],
|
||||
['body', 'Body'],
|
||||
['br', 'BR'],
|
||||
['button', 'Button'],
|
||||
['canvas', 'Canvas'],
|
||||
['caption', 'TableCaption'],
|
||||
['center', ''],
|
||||
['cite', ''],
|
||||
['code', ''],
|
||||
['col', 'TableCol'],
|
||||
['colgroup', 'TableCol'],
|
||||
['data', 'Data'],
|
||||
['datalist', 'DataList'],
|
||||
['dd', ''],
|
||||
['del', 'Mod'],
|
||||
['details', 'Details'],
|
||||
['dfn', ''],
|
||||
['dir', 'Directory'],
|
||||
['div', 'Div'],
|
||||
['dl', 'DList'],
|
||||
['dt', ''],
|
||||
['em', ''],
|
||||
['embed', 'Embed'],
|
||||
['fieldset', 'FieldSet'],
|
||||
['figcaption', ''],
|
||||
['figure', ''],
|
||||
['font', 'Font'],
|
||||
['footer', ''],
|
||||
['form', 'Form'],
|
||||
['frame', 'Frame'],
|
||||
['frameset', 'FrameSet'],
|
||||
['h1', 'Heading'],
|
||||
['h2', 'Heading'],
|
||||
['h3', 'Heading'],
|
||||
['h4', 'Heading'],
|
||||
['h5', 'Heading'],
|
||||
['h6', 'Heading'],
|
||||
['head', 'Head'],
|
||||
['header', ''],
|
||||
['hgroup', ''],
|
||||
['hr', 'HR'],
|
||||
['html', 'Html'],
|
||||
['i', ''],
|
||||
['iframe', 'IFrame'],
|
||||
['image', ''],
|
||||
['img', 'Image'],
|
||||
['input', 'Input'],
|
||||
['ins', 'Mod'],
|
||||
['kbd', ''],
|
||||
['label', 'Label'],
|
||||
['legend', 'Legend'],
|
||||
['li', 'LI'],
|
||||
['link', 'Link'],
|
||||
['listing', 'Pre'],
|
||||
['main', ''],
|
||||
['map', 'Map'],
|
||||
['mark', ''],
|
||||
['marquee', 'Div'],
|
||||
['menu', 'Menu'],
|
||||
['menuitem', 'MenuItem'],
|
||||
['meta', 'Meta'],
|
||||
['meter', 'Meter'],
|
||||
['nav', ''],
|
||||
['nobr', ''],
|
||||
['noembed', ''],
|
||||
['noframes', ''],
|
||||
['noscript', ''],
|
||||
['object', 'Object'],
|
||||
['ol', 'OList'],
|
||||
['optgroup', 'OptGroup'],
|
||||
['option', 'Option'],
|
||||
['output', 'Output'],
|
||||
['p', 'Paragraph'],
|
||||
['param', 'Param'],
|
||||
['picture', 'Picture'],
|
||||
['plaintext', ''],
|
||||
['pre', 'Pre'],
|
||||
['progress', 'Progress'],
|
||||
['q', 'Quote'],
|
||||
['rb', ''],
|
||||
['rp', ''],
|
||||
['rt', ''],
|
||||
['rtc', ''],
|
||||
['ruby', ''],
|
||||
['s', ''],
|
||||
['samp', ''],
|
||||
['script', 'Script'],
|
||||
['section', ''],
|
||||
['select', 'Select'],
|
||||
['small', ''],
|
||||
['source', 'Source'],
|
||||
['span', 'Span'],
|
||||
['strike', ''],
|
||||
['strong', ''],
|
||||
['style', 'Style'],
|
||||
['sub', ''],
|
||||
['summary', ''],
|
||||
['sup', ''],
|
||||
['table', 'Table'],
|
||||
['tbody', 'TableSection'],
|
||||
['td', 'TableCell'],
|
||||
['textarea', 'TextArea'],
|
||||
['tfoot', 'TableSection'],
|
||||
['th', 'TableCell'],
|
||||
['thead', 'TableSection'],
|
||||
['template', 'Template'],
|
||||
['time', 'Time'],
|
||||
['title', 'Title'],
|
||||
['tr', 'TableRow'],
|
||||
['track', 'Track'],
|
||||
['tt', ''],
|
||||
['u', ''],
|
||||
['ul', 'UList'],
|
||||
['var', ''],
|
||||
['video', 'Video'],
|
||||
['wbr', ''],
|
||||
['xmp', 'Pre'],
|
||||
].forEach((e) => {
|
||||
let tagName = e[0];
|
||||
let interfaceName = 'HTML' + e[1] + 'Element';
|
||||
promises.push(test_with_new_window((testWindow) => {
|
||||
// Use window from iframe to isolate the test.
|
||||
// Test calling the HTML*Element constructor.
|
||||
(() => {
|
||||
SimpleTest.doesThrow(() => {
|
||||
testWindow[interfaceName]();
|
||||
}, 'calling the ' + interfaceName + ' constructor should throw a TypeError');
|
||||
})();
|
||||
|
||||
// Test constructing a HTML*ELement.
|
||||
(() => {
|
||||
SimpleTest.doesThrow(() => {
|
||||
new testWindow[interfaceName]();
|
||||
}, 'constructing a ' + interfaceName + ' should throw a TypeError');
|
||||
})();
|
||||
|
||||
// Test constructing a custom element with defining HTML*Element as entry.
|
||||
(() => {
|
||||
testWindow.customElements.define('x-defining-' + tagName,
|
||||
testWindow[interfaceName]);
|
||||
SimpleTest.doesThrow(() => {
|
||||
new testWindow[interfaceName]();
|
||||
}, 'constructing a custom element with defining ' + interfaceName +
|
||||
' as registry entry should throw a TypeError');
|
||||
})();
|
||||
|
||||
// Since HTMLElement can be registered without specifying "extends", skip
|
||||
// testing HTMLElement tags.
|
||||
if (interfaceName !== "HTMLElement") {
|
||||
// Test constructing a customized HTML*Element with defining a registry entry
|
||||
// without specifying "extends".
|
||||
(() => {
|
||||
class X extends testWindow[interfaceName] {}
|
||||
testWindow.customElements.define('x-defining-invalid-' + tagName, X);
|
||||
SimpleTest.doesThrow(() => {
|
||||
new X();
|
||||
}, 'constructing a customized ' + interfaceName + ' with defining a ' +
|
||||
'registry entry without specifying "extends" should throw a TypeError');
|
||||
})();
|
||||
}
|
||||
|
||||
// Test constructing a built-in custom element with defining a registry entry
|
||||
// with incorrect "extends" information.
|
||||
(() => {
|
||||
class X extends testWindow[interfaceName] {}
|
||||
testWindow.customElements.define('x-defining-incorrect-' + tagName, X,
|
||||
{ extends: tagName === 'img' ? 'p' : 'img' });
|
||||
SimpleTest.doesThrow(() => {
|
||||
new X();
|
||||
}, 'constructing a customized ' + interfaceName + ' with defining a ' +
|
||||
'registry entry with incorrect "extends" should throw a TypeError');
|
||||
})();
|
||||
|
||||
// Test calling a custom element constructor and constructing a built-in
|
||||
// custom element.
|
||||
(() => {
|
||||
let num_constructor_invocations = 0;
|
||||
class X extends testWindow[interfaceName] {
|
||||
constructor() {
|
||||
super();
|
||||
num_constructor_invocations++;
|
||||
}
|
||||
}
|
||||
testWindow.customElements.define('x-' + tagName, X, { extends: tagName });
|
||||
SimpleTest.doesThrow(() => {
|
||||
X();
|
||||
}, 'calling a customized ' + interfaceName + ' constructor should throw a TypeError');
|
||||
|
||||
let element = new X();
|
||||
|
||||
SimpleTest.is(Object.getPrototypeOf(Cu.waiveXrays(element)), X.prototype,
|
||||
'constructing a customized ' + interfaceName +
|
||||
'; the element should be a registered constructor');
|
||||
SimpleTest.is(element.localName, tagName,
|
||||
'constructing a customized ' + interfaceName +
|
||||
'; the element tag name should be "' + tagName + '"');
|
||||
SimpleTest.is(element.namespaceURI, 'http://www.w3.org/1999/xhtml',
|
||||
'constructing a customized ' + interfaceName +
|
||||
'; the element should be in the HTML namespace');
|
||||
SimpleTest.is(element.prefix, null,
|
||||
'constructing a customized ' + interfaceName +
|
||||
'; the element name should not have a prefix');
|
||||
SimpleTest.is(element.ownerDocument, testWindow.document,
|
||||
'constructing a customized ' + interfaceName +
|
||||
'; the element should be owned by the registry\'s associated ' +
|
||||
'document');
|
||||
SimpleTest.is(num_constructor_invocations, 1,
|
||||
'constructing a customized ' + interfaceName +
|
||||
'; the constructor should have been invoked once');
|
||||
})();
|
||||
|
||||
// Test if prototype is no an object.
|
||||
(() => {
|
||||
function ElementWithNonObjectPrototype() {
|
||||
let o = Reflect.construct(testWindow[interfaceName], [], new.target);
|
||||
SimpleTest.is(Object.getPrototypeOf(Cu.waiveXrays(o)), window[interfaceName].prototype,
|
||||
'constructing a customized ' + interfaceName +
|
||||
'; if prototype is not object, fallback from NewTarget\'s realm');
|
||||
}
|
||||
|
||||
// Prototype have to be an object during define(), otherwise define will
|
||||
// throw an TypeError exception.
|
||||
ElementWithNonObjectPrototype.prototype = {};
|
||||
testWindow.customElements.define('x-non-object-prototype-' + tagName,
|
||||
ElementWithNonObjectPrototype,
|
||||
{ extends: tagName });
|
||||
|
||||
ElementWithNonObjectPrototype.prototype = "string";
|
||||
new ElementWithNonObjectPrototype();
|
||||
})();
|
||||
}));
|
||||
});
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
[DEFAULT]
|
||||
support-files =
|
||||
inert_style.css
|
||||
dummy_page.html
|
||||
|
||||
[test_bug900724.html]
|
||||
[test_bug1017896.html]
|
||||
|
|
@ -11,6 +12,11 @@ support-files =
|
|||
[test_custom_element_callback_innerhtml.html]
|
||||
[test_custom_element_clone_callbacks.html]
|
||||
[test_custom_element_clone_callbacks_extended.html]
|
||||
[test_custom_element_htmlconstructor.html]
|
||||
skip-if = os == 'android' # bug 1323645
|
||||
support-files =
|
||||
htmlconstructor_autonomous_tests.js
|
||||
htmlconstructor_builtin_tests.js
|
||||
[test_custom_element_import_node_created_callback.html]
|
||||
[test_custom_element_in_shadow.html]
|
||||
[test_custom_element_register_invalid_callbacks.html]
|
||||
|
|
|
|||
|
|
@ -0,0 +1,42 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=1274159
|
||||
-->
|
||||
<head>
|
||||
<title>Test HTMLConstructor for custom elements.</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1274159">Bug 1274159</a>
|
||||
<script type="text/javascript">
|
||||
function test_with_new_window(f) {
|
||||
return new Promise((aResolve) => {
|
||||
let iframe = document.createElement('iframe');
|
||||
iframe.setAttribute('type', 'content');
|
||||
iframe.setAttribute('src', 'dummy_page.html');
|
||||
iframe.onload = function() {
|
||||
f(iframe.contentWindow);
|
||||
aResolve();
|
||||
};
|
||||
document.body.appendChild(iframe);
|
||||
});
|
||||
}
|
||||
|
||||
// Fake the Cu.waiveXrays, so that we can share the tests with mochitest chrome.
|
||||
var Cu = { waiveXrays: (obj) => obj };
|
||||
var promises = [];
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
</script>
|
||||
<!-- Test cases for autonomous element -->
|
||||
<script type="text/javascript" src="htmlconstructor_autonomous_tests.js"></script>
|
||||
<!-- Test cases for customized built-in element -->
|
||||
<script type="text/javascript" src="htmlconstructor_builtin_tests.js"></script>
|
||||
<script type="text/javascript">
|
||||
Promise.all(promises).then(() => {
|
||||
SimpleTest.finish();
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=1274159
|
||||
-->
|
||||
<head>
|
||||
<title>Test HTMLConstructor for custom elements.</title>
|
||||
<script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1274159">Bug 1274159</a>
|
||||
<script type="text/javascript">
|
||||
function test_with_new_window(f) {
|
||||
return new Promise((aResolve) => {
|
||||
let iframe = document.createElement('iframe');
|
||||
iframe.setAttribute('type', 'content');
|
||||
iframe.setAttribute('src', 'http://example.org/tests/dom/tests/mochitest/webcomponents/dummy_page.html');
|
||||
iframe.onload = function() {
|
||||
f(iframe.contentWindow);
|
||||
aResolve();
|
||||
};
|
||||
document.body.appendChild(iframe);
|
||||
});
|
||||
}
|
||||
|
||||
var Cu = Components.utils;
|
||||
var promises = [];
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
</script>
|
||||
<!-- Test cases for autonomous element -->
|
||||
<script type="text/javascript" src="htmlconstructor_autonomous_tests.js"></script>
|
||||
<!-- Test cases for customized built-in element -->
|
||||
<script type="text/javascript" src="htmlconstructor_builtin_tests.js"></script>
|
||||
<script type="text/javascript">
|
||||
Promise.all(promises).then(() => {
|
||||
SimpleTest.finish();
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Loading…
Add table
Add a link
Reference in a new issue