summaryrefslogtreecommitdiffstats
path: root/js/xpconnect/tests/mochitest
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
commit26a029d407be480d791972afb5975cf62c9360a6 (patch)
treef435a8308119effd964b339f76abb83a57c29483 /js/xpconnect/tests/mochitest
parentInitial commit. (diff)
downloadfirefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz
firefox-26a029d407be480d791972afb5975cf62c9360a6.zip
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'js/xpconnect/tests/mochitest')
-rw-r--r--js/xpconnect/tests/mochitest/bug1681664_helper.js1
-rw-r--r--js/xpconnect/tests/mochitest/bug500931_helper.html8
-rw-r--r--js/xpconnect/tests/mochitest/bug571849_helper.html7
-rw-r--r--js/xpconnect/tests/mochitest/bug589028_helper.html27
-rw-r--r--js/xpconnect/tests/mochitest/bug92773_helper.html7
-rw-r--r--js/xpconnect/tests/mochitest/chrome_wrappers_helper.html29
-rw-r--r--js/xpconnect/tests/mochitest/class_static_worker.js13
-rw-r--r--js/xpconnect/tests/mochitest/file1_bug629227.html32
-rw-r--r--js/xpconnect/tests/mochitest/file2_bug629227.html11
-rw-r--r--js/xpconnect/tests/mochitest/file_bug505915.html10
-rw-r--r--js/xpconnect/tests/mochitest/file_bug605167.html7
-rw-r--r--js/xpconnect/tests/mochitest/file_bug650273.html31
-rw-r--r--js/xpconnect/tests/mochitest/file_bug658560.html4
-rw-r--r--js/xpconnect/tests/mochitest/file_bug706301.html27
-rw-r--r--js/xpconnect/tests/mochitest/file_bug720619.html10
-rw-r--r--js/xpconnect/tests/mochitest/file_bug731471.html5
-rw-r--r--js/xpconnect/tests/mochitest/file_bug738244.html10
-rw-r--r--js/xpconnect/tests/mochitest/file_bug760131.html23
-rw-r--r--js/xpconnect/tests/mochitest/file_bug781476.html15
-rw-r--r--js/xpconnect/tests/mochitest/file_bug789713.html51
-rw-r--r--js/xpconnect/tests/mochitest/file_bug795275.html14
-rw-r--r--js/xpconnect/tests/mochitest/file_bug799348.html11
-rw-r--r--js/xpconnect/tests/mochitest/file_bug802557.html62
-rw-r--r--js/xpconnect/tests/mochitest/file_bug860494.html16
-rw-r--r--js/xpconnect/tests/mochitest/file_crosscompartment_weakmap.html8
-rw-r--r--js/xpconnect/tests/mochitest/file_documentdomain.html41
-rw-r--r--js/xpconnect/tests/mochitest/file_doublewrappedcompartments.html10
-rw-r--r--js/xpconnect/tests/mochitest/file_empty.html3
-rw-r--r--js/xpconnect/tests/mochitest/file_evalInSandbox.html8
-rw-r--r--js/xpconnect/tests/mochitest/file_exnstack.html23
-rw-r--r--js/xpconnect/tests/mochitest/file_expandosharing.html34
-rw-r--r--js/xpconnect/tests/mochitest/file_matches.html1
-rw-r--r--js/xpconnect/tests/mochitest/file_nodelists.html7
-rw-r--r--js/xpconnect/tests/mochitest/file_wrappers-2.html13
-rw-r--r--js/xpconnect/tests/mochitest/file_xrayic.html15
-rw-r--r--js/xpconnect/tests/mochitest/finalizationRegistry_worker.js96
-rw-r--r--js/xpconnect/tests/mochitest/inner.html7
-rw-r--r--js/xpconnect/tests/mochitest/mochitest.toml297
-rw-r--r--js/xpconnect/tests/mochitest/moz.build7
-rw-r--r--js/xpconnect/tests/mochitest/private_field_worker.js21
-rw-r--r--js/xpconnect/tests/mochitest/shadow_realm_module.js1
-rw-r--r--js/xpconnect/tests/mochitest/shadow_realm_worker.js81
-rw-r--r--js/xpconnect/tests/mochitest/test1_bug629331.html19
-rw-r--r--js/xpconnect/tests/mochitest/test2_bug629331.html18
-rw-r--r--js/xpconnect/tests/mochitest/test_bug1005806.html27
-rw-r--r--js/xpconnect/tests/mochitest/test_bug1094930.html29
-rw-r--r--js/xpconnect/tests/mochitest/test_bug1158558.html47
-rw-r--r--js/xpconnect/tests/mochitest/test_bug1448048.html33
-rw-r--r--js/xpconnect/tests/mochitest/test_bug1681664.html42
-rw-r--r--js/xpconnect/tests/mochitest/test_bug384632.html34
-rw-r--r--js/xpconnect/tests/mochitest/test_bug390488.html64
-rw-r--r--js/xpconnect/tests/mochitest/test_bug393269.html46
-rw-r--r--js/xpconnect/tests/mochitest/test_bug396851.html53
-rw-r--r--js/xpconnect/tests/mochitest/test_bug428021.html40
-rw-r--r--js/xpconnect/tests/mochitest/test_bug446584.html47
-rw-r--r--js/xpconnect/tests/mochitest/test_bug462428.html51
-rw-r--r--js/xpconnect/tests/mochitest/test_bug478438.html65
-rw-r--r--js/xpconnect/tests/mochitest/test_bug484107.html99
-rw-r--r--js/xpconnect/tests/mochitest/test_bug500691.html27
-rw-r--r--js/xpconnect/tests/mochitest/test_bug505915.html49
-rw-r--r--js/xpconnect/tests/mochitest/test_bug560351.html36
-rw-r--r--js/xpconnect/tests/mochitest/test_bug585745.html43
-rw-r--r--js/xpconnect/tests/mochitest/test_bug589028.html62
-rw-r--r--js/xpconnect/tests/mochitest/test_bug601299.html18
-rw-r--r--js/xpconnect/tests/mochitest/test_bug605167.html56
-rw-r--r--js/xpconnect/tests/mochitest/test_bug618017.html28
-rw-r--r--js/xpconnect/tests/mochitest/test_bug623437.html43
-rw-r--r--js/xpconnect/tests/mochitest/test_bug628410.html34
-rw-r--r--js/xpconnect/tests/mochitest/test_bug628794.html43
-rw-r--r--js/xpconnect/tests/mochitest/test_bug629227.html47
-rw-r--r--js/xpconnect/tests/mochitest/test_bug629331.html37
-rw-r--r--js/xpconnect/tests/mochitest/test_bug636097.html62
-rw-r--r--js/xpconnect/tests/mochitest/test_bug650273.html42
-rw-r--r--js/xpconnect/tests/mochitest/test_bug655297-1.html49
-rw-r--r--js/xpconnect/tests/mochitest/test_bug655297-2.html49
-rw-r--r--js/xpconnect/tests/mochitest/test_bug661980.html61
-rw-r--r--js/xpconnect/tests/mochitest/test_bug691059.html59
-rw-r--r--js/xpconnect/tests/mochitest/test_bug720619.html55
-rw-r--r--js/xpconnect/tests/mochitest/test_bug731471.html42
-rw-r--r--js/xpconnect/tests/mochitest/test_bug764389.html40
-rw-r--r--js/xpconnect/tests/mochitest/test_bug772288.html50
-rw-r--r--js/xpconnect/tests/mochitest/test_bug781476.html36
-rw-r--r--js/xpconnect/tests/mochitest/test_bug789713.html39
-rw-r--r--js/xpconnect/tests/mochitest/test_bug790732.html55
-rw-r--r--js/xpconnect/tests/mochitest/test_bug793969.html53
-rw-r--r--js/xpconnect/tests/mochitest/test_bug800864.html51
-rw-r--r--js/xpconnect/tests/mochitest/test_bug802557.html116
-rw-r--r--js/xpconnect/tests/mochitest/test_bug803730.html41
-rw-r--r--js/xpconnect/tests/mochitest/test_bug809547.html42
-rw-r--r--js/xpconnect/tests/mochitest/test_bug829872.html52
-rw-r--r--js/xpconnect/tests/mochitest/test_bug862380.html54
-rw-r--r--js/xpconnect/tests/mochitest/test_bug865260.html33
-rw-r--r--js/xpconnect/tests/mochitest/test_bug871887.html43
-rw-r--r--js/xpconnect/tests/mochitest/test_bug912322.html35
-rw-r--r--js/xpconnect/tests/mochitest/test_bug916945.html78
-rw-r--r--js/xpconnect/tests/mochitest/test_bug92773.html43
-rw-r--r--js/xpconnect/tests/mochitest/test_bug940783.html62
-rw-r--r--js/xpconnect/tests/mochitest/test_bug960820.html56
-rw-r--r--js/xpconnect/tests/mochitest/test_bug965082.html39
-rw-r--r--js/xpconnect/tests/mochitest/test_bug993423.html47
-rw-r--r--js/xpconnect/tests/mochitest/test_class_static_block_worker.html32
-rw-r--r--js/xpconnect/tests/mochitest/test_crosscompartment_weakmap.html36
-rw-r--r--js/xpconnect/tests/mochitest/test_enable_privilege.html26
-rw-r--r--js/xpconnect/tests/mochitest/test_finalizationRegistry.html168
-rw-r--r--js/xpconnect/tests/mochitest/test_finalizationRegistryInWorker.html40
-rw-r--r--js/xpconnect/tests/mochitest/test_finalizationRegistry_cleanupSome.html13
-rw-r--r--js/xpconnect/tests/mochitest/test_finalizationRegistry_incumbent.html62
-rw-r--r--js/xpconnect/tests/mochitest/test_frameWrapping.html37
-rw-r--r--js/xpconnect/tests/mochitest/test_getWebIDLCaller.html49
-rw-r--r--js/xpconnect/tests/mochitest/test_getweakmapkeys.html59
-rw-r--r--js/xpconnect/tests/mochitest/test_isRemoteProxy.html55
-rw-r--r--js/xpconnect/tests/mochitest/test_nukeContentWindow.html75
-rw-r--r--js/xpconnect/tests/mochitest/test_paris_weakmap_keys.html94
-rw-r--r--js/xpconnect/tests/mochitest/test_private_field_dom.html221
-rw-r--r--js/xpconnect/tests/mochitest/test_private_field_worker.html27
-rw-r--r--js/xpconnect/tests/mochitest/test_sameOriginPolicy.html109
-rw-r--r--js/xpconnect/tests/mochitest/test_sandbox_fetch.html54
-rw-r--r--js/xpconnect/tests/mochitest/test_shadowRealm.html34
-rw-r--r--js/xpconnect/tests/mochitest/test_shadowRealm_worker.html63
-rw-r--r--js/xpconnect/tests/mochitest/test_spectre_mitigations.html28
-rw-r--r--js/xpconnect/tests/mochitest/test_weakRefs.html80
-rw-r--r--js/xpconnect/tests/mochitest/test_weakRefs_collected_wrapper.html52
-rw-r--r--js/xpconnect/tests/mochitest/test_weakRefs_cross_compartment.html68
-rw-r--r--js/xpconnect/tests/mochitest/test_weakmaps.html264
124 files changed, 5571 insertions, 0 deletions
diff --git a/js/xpconnect/tests/mochitest/bug1681664_helper.js b/js/xpconnect/tests/mochitest/bug1681664_helper.js
new file mode 100644
index 0000000000..14f2289a19
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/bug1681664_helper.js
@@ -0,0 +1 @@
+while (true) {};
diff --git a/js/xpconnect/tests/mochitest/bug500931_helper.html b/js/xpconnect/tests/mochitest/bug500931_helper.html
new file mode 100644
index 0000000000..da268d99d8
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/bug500931_helper.html
@@ -0,0 +1,8 @@
+<html>
+ <head>
+ <title>Inner frame for bug 500931 mochitest</title>
+ <script>x = 42;</script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/bug571849_helper.html b/js/xpconnect/tests/mochitest/bug571849_helper.html
new file mode 100644
index 0000000000..234cd57ccf
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/bug571849_helper.html
@@ -0,0 +1,7 @@
+<html>
+ <head>
+ </head>
+ <body>
+ TEXT NODE TEXT NODE
+ </body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/bug589028_helper.html b/js/xpconnect/tests/mochitest/bug589028_helper.html
new file mode 100644
index 0000000000..dc56ecbc3c
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/bug589028_helper.html
@@ -0,0 +1,27 @@
+<html>
+ <head>
+ <script>
+ function getMyOption() {
+ return new Option();
+ }
+ function getCallersOption(caller) {
+ return new caller.Option();
+ }
+ function getMyAudio() {
+ return new Audio();
+ }
+ function getCallersAudio(caller) {
+ return new caller.Audio();
+ }
+ function getMyImage() {
+ return new Image();
+ }
+ function getCallersImage(caller) {
+ return new caller.Image();
+ }
+ </script>
+ </head>
+ <body>
+ the iframe
+ </body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/bug92773_helper.html b/js/xpconnect/tests/mochitest/bug92773_helper.html
new file mode 100644
index 0000000000..be10dd54ae
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/bug92773_helper.html
@@ -0,0 +1,7 @@
+<html>
+ <head>
+ <script>
+ Object.defineProperty(window, "foo", { get() { alert("FAIL"); } });
+ </script>
+ </head>
+</html>
diff --git a/js/xpconnect/tests/mochitest/chrome_wrappers_helper.html b/js/xpconnect/tests/mochitest/chrome_wrappers_helper.html
new file mode 100644
index 0000000000..a0c1ec87e3
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/chrome_wrappers_helper.html
@@ -0,0 +1,29 @@
+<html>
+ <head>
+ <script>
+ function check_wrapper(ok, wrapper, expected, note) {
+ let { getClassName } = SpecialPowers.unwrap(
+ SpecialPowers.wrap(window).ChromeUtils
+ );
+ ok(getClassName(wrapper, false) === expected, note);
+ }
+ function run_test(ok, xpcnw, sjow) {
+ // both wrappers should point to our window: XOW
+ check_wrapper(ok, ok, "Proxy", "functions are wrapped properly");
+ check_wrapper(ok, xpcnw, "Proxy", "XPCNWs are transformed correctly");
+ check_wrapper(ok, sjow, "Proxy", "SJOWs are transformed correctly");
+
+ check_wrapper(ok, window.location, "Location",
+ "same-compartment security wrappers are gone");
+
+ ok(defprop1 === 1, "defprop1 exists");
+ window.defprop1 = 2;
+ ok(defprop1 === 2, "defprop1 is properly writable");
+
+ // defprop2 = {}; disabled because the test doesn't work
+ }
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/class_static_worker.js b/js/xpconnect/tests/mochitest/class_static_worker.js
new file mode 100644
index 0000000000..eb949226ba
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/class_static_worker.js
@@ -0,0 +1,13 @@
+class A {
+ static { this.x = 12; }
+}
+
+
+self.onmessage = function (e) {
+ console.log(e)
+ if (e.data == 'get') {
+ postMessage(A.x);
+ return;
+ }
+ postMessage('Unknown message type.');
+} \ No newline at end of file
diff --git a/js/xpconnect/tests/mochitest/file1_bug629227.html b/js/xpconnect/tests/mochitest/file1_bug629227.html
new file mode 100644
index 0000000000..dd12484068
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/file1_bug629227.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <script>
+ function doIt() {
+ var doc = window.frames[0].document;
+ var ok = (doc.form1 == doc.getElementById("test1"));
+ window.parent.postMessage(
+ JSON.stringify({ ok: ok,
+ reason: "Should be able to get named items by name" }),
+ "*");
+ window.parent.postMessage("finish", "*");
+ }
+
+ window.onmessage = function(ev) {
+ if (ev.data == "start") {
+ doIt();
+ }
+ }
+
+ document.domain = "example.org";
+ </script>
+ </head>
+ <body>
+ <iframe id="subframe"></iframe>
+ <script>
+ document.getElementById("subframe").src =
+ "http://test2.example.org" +
+ location.pathname.replace(/file1_bug629227.html/, "file2_bug629227.html");
+ </script>
+ </body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/file2_bug629227.html b/js/xpconnect/tests/mochitest/file2_bug629227.html
new file mode 100644
index 0000000000..02a0540865
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/file2_bug629227.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <script>
+ document.domain = "example.org";
+ </script>
+ </head>
+ <body>
+ <form name="form1" id="test1"></form>
+ </body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/file_bug505915.html b/js/xpconnect/tests/mochitest/file_bug505915.html
new file mode 100644
index 0000000000..5129126914
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/file_bug505915.html
@@ -0,0 +1,10 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+Inner frame for testing bug 505915.
+https://bugzilla.mozilla.org/show_bug.cgi?id=505915
+-->
+<head>
+<body onload="parent.postMessage('', '*');">
+</body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/file_bug605167.html b/js/xpconnect/tests/mochitest/file_bug605167.html
new file mode 100644
index 0000000000..d5253315b8
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/file_bug605167.html
@@ -0,0 +1,7 @@
+<html>
+<body>
+<script>
+ parent.f = function() { return this; };
+</script>
+</body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/file_bug650273.html b/js/xpconnect/tests/mochitest/file_bug650273.html
new file mode 100644
index 0000000000..5fe33e9695
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/file_bug650273.html
@@ -0,0 +1,31 @@
+<!-- test by moz_bug_r_a4@yahoo.com -->
+<body onload="a()">
+<script>
+var targetUrl = "http://example.com/";
+var l;
+
+function a() {
+ var o = {};
+ o.toString = function() {
+ l();
+ return "a";
+ };
+ var f = Object.getOwnPropertyDescriptor(Document.prototype, "title").set;
+ setTimeout(f.bind(document), 0, o);
+}
+
+function l() {
+ var l = false;
+ onunload = function() {
+ l = true;
+ };
+ location = targetUrl;
+ do {
+ var r = new XMLHttpRequest();
+ r.open("GET", location.href, false);
+ r.overrideMimeType("text/plain");
+ try { r.send(null); }
+ catch (e) {}
+ } while (!l);
+}
+</script>
diff --git a/js/xpconnect/tests/mochitest/file_bug658560.html b/js/xpconnect/tests/mochitest/file_bug658560.html
new file mode 100644
index 0000000000..411d31ac73
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/file_bug658560.html
@@ -0,0 +1,4 @@
+<html>
+ <body>
+ </body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/file_bug706301.html b/js/xpconnect/tests/mochitest/file_bug706301.html
new file mode 100644
index 0000000000..805449b4aa
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/file_bug706301.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <script type="application/javascript">
+ window.addEventListener('message', doContentTest);
+
+ function doContentTest() {
+
+ // This has always worked.
+ var nodelist1 = document.getElementsByTagName('details');
+ Object.getOwnPropertyDescriptor(nodelist1, 'length');
+ ok(nodelist1['length'] == 0, "Content should be able to get the length of " +
+ "its own nodelist after calling getOwnPropertyDescriptor.");
+
+ // This is bug 706301.
+ var nodelist2 = document.getElementsByTagName('section');
+ ok(getLengthInChrome(nodelist2), "Chrome should be able to get the length of " +
+ "content nodelist after calling getOwnPropertyDescriptor.");
+
+ // All done.
+ finishTestInChrome();
+ }
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/file_bug720619.html b/js/xpconnect/tests/mochitest/file_bug720619.html
new file mode 100644
index 0000000000..d198ba1fa3
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/file_bug720619.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <script>
+ valueOf = function() { return "v"; }
+ toString = function() { return "s"; }
+ </script>
+ </head>
+ <body></body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/file_bug731471.html b/js/xpconnect/tests/mochitest/file_bug731471.html
new file mode 100644
index 0000000000..fcfb194cb6
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/file_bug731471.html
@@ -0,0 +1,5 @@
+<html>
+<body>
+1
+</body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/file_bug738244.html b/js/xpconnect/tests/mochitest/file_bug738244.html
new file mode 100644
index 0000000000..a399d9f0e0
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/file_bug738244.html
@@ -0,0 +1,10 @@
+<html>
+<body>
+<form name="form1">
+ <input name="input1" />
+ <input name="appendChild" />
+</form>
+<iframe name="frame1">
+</iframe>
+</body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/file_bug760131.html b/js/xpconnect/tests/mochitest/file_bug760131.html
new file mode 100644
index 0000000000..736732a0a4
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/file_bug760131.html
@@ -0,0 +1,23 @@
+<html>
+<div id="target" ontouchstart="alert();"></div>
+<script type="application/javascript">
+
+/** Test for Bug 760131 **/
+
+function accessTouches(evt)
+{
+ var thrown = false;
+ try {
+ var a = evt.touches;
+ } catch (e) {
+ thrown = true;
+ }
+ ok(!thrown, "Unwrapping a TouchList shouldn't throw");
+}
+
+document.getElementById("target").ontouchstart = accessTouches;
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/file_bug781476.html b/js/xpconnect/tests/mochitest/file_bug781476.html
new file mode 100644
index 0000000000..745f8818e5
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/file_bug781476.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script type="application/javascript">
+function makeEvent() {
+ var evt = new Event("MouseEvents");
+ evt.expando = 42;
+ is(evt.expando, 42, "Expando properly visible in iframe");
+ return evt;
+}
+</script>
+</head>
+<body>
+</body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/file_bug789713.html b/js/xpconnect/tests/mochitest/file_bug789713.html
new file mode 100644
index 0000000000..4c30fe8275
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/file_bug789713.html
@@ -0,0 +1,51 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=789713
+-->
+<head>
+ <meta charset="utf-8">
+</head>
+<body>
+
+<script type="application/javascript">
+
+/** Test for Bug 789713 **/
+
+function go() {
+ var ifr = document.getElementById('ifr');
+ var pass = true;
+ var doc = ifr.contentDocument;
+ var win = ifr.contentWindow;
+
+ var walker = doc.createTreeWalker(doc.body);
+ pass = pass && (walker.root === doc.body);
+ walker.foo = "expando";
+
+ win.bar = "another-expando";
+
+ // First, do the document.domain operation. This shouldn't crash.
+ document.domain = "example.org";
+
+ // Now make sure we can still access properties on "walker".
+ try {
+ walker.root;
+ pass = pass && walker.foo == "expando";
+ } catch (e) {
+ pass = false;
+ }
+
+ // And make sure we can't access properties on "win", because the
+ // document.domain change revoked the access.
+ try {
+ win.bar;
+ pass = false;
+ } catch (e) { pass = pass && /Permission denied/.exec(e.message); }
+ window.parent.postMessage(pass, '*');
+}
+
+</script>
+<iframe id="ifr" src="file_empty.html" onload="go()"></iframe>
+</pre>
+</body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/file_bug795275.html b/js/xpconnect/tests/mochitest/file_bug795275.html
new file mode 100644
index 0000000000..c3886b8ba8
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/file_bug795275.html
@@ -0,0 +1,14 @@
+<html>
+<head>
+<script type="application/javascript">
+ function touchComponents() {
+ Components;
+ }
+ function touchInterfaces() {
+ Components.interfaces;
+ }
+</script>
+</head>
+<body>
+</body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/file_bug799348.html b/js/xpconnect/tests/mochitest/file_bug799348.html
new file mode 100644
index 0000000000..5800868db0
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/file_bug799348.html
@@ -0,0 +1,11 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<script>
+ var foo = window.open('file_empty.html', '', 'width=550, height=420, status=no, resizable=yes, scrollbars=yes, toolbar=no, left=945, top=225');
+</script>
+</head>
+<body>
+</body>
+</html>
+
diff --git a/js/xpconnect/tests/mochitest/file_bug802557.html b/js/xpconnect/tests/mochitest/file_bug802557.html
new file mode 100644
index 0000000000..39f952bc5b
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/file_bug802557.html
@@ -0,0 +1,62 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script>
+var gTS = window.location.toString;
+var gGHR = Object.getOwnPropertyDescriptor(window.location, 'href').get;
+function getTests(fromOuter) {
+
+ function loc() {
+ return fromOuter ? window.location : location;
+ }
+ return {
+ getLocationImplicit: function() {
+ return loc() + "";
+ },
+ getLocationExplicit: function() {
+ return loc().toString();
+ },
+ getLocationApply1: function() {
+ return gTS.call(loc());
+ },
+ getLocationApply2: function() {
+ return gTS.apply(loc(), []);
+ },
+ getLocationApply3: function() {
+ return Function.call.apply(gTS, [loc()]);
+ },
+ getHref: function() {
+ return loc().href;
+ },
+ getHrefViaApply: function() {
+ return Function.call.apply(gGHR, [loc()]);
+ },
+ }
+};
+
+function mungeNames(obj, suffix) {
+ var rv = {};
+ Object.getOwnPropertyNames(obj)
+ .forEach(name => rv[name + suffix] = obj[name]);
+ return rv;
+}
+
+function mergeObjects(a, b) {
+ var rv = {};
+ Object.getOwnPropertyNames(a).forEach(name => rv[name] = a[name]);
+ Object.getOwnPropertyNames(b).forEach(name => rv[name] = b[name]);
+ return rv;
+}
+
+function getAllTests() {
+ var innerTests = getTests(false);
+ var outerTests = getTests(true);
+ return mergeObjects(mungeNames(innerTests, '_inner'),
+ mungeNames(outerTests, '_outer'));
+}
+
+</script>
+</head>
+<body>
+</body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/file_bug860494.html b/js/xpconnect/tests/mochitest/file_bug860494.html
new file mode 100644
index 0000000000..63a7003796
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/file_bug860494.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="UTF-8">
+<title></title>
+</head>
+<body>
+<iframe name="top"></iframe>
+<iframe name="parent"></iframe>
+<iframe name="location"></iframe>
+<iframe name="length"></iframe>
+<iframe name="window"></iframe>
+<iframe name="navigator"></iframe>
+<iframe name="alert"></iframe>
+</body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/file_crosscompartment_weakmap.html b/js/xpconnect/tests/mochitest/file_crosscompartment_weakmap.html
new file mode 100644
index 0000000000..127c479ebe
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/file_crosscompartment_weakmap.html
@@ -0,0 +1,8 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Test Cross-Compartment DOM WeakMaps</title>
+</head>
+<body>
+</body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/file_documentdomain.html b/js/xpconnect/tests/mochitest/file_documentdomain.html
new file mode 100644
index 0000000000..784ed269d0
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/file_documentdomain.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script type="application/javascript">
+
+ function setDomain(domain) {
+ document.domain = domain;
+ }
+
+ function tryToAccess(otherWin) {
+ try {
+ var text = otherWin.document.getElementById('foo').innerHTML;
+ return /Better Late/.exec(text);
+ } catch (e) { return false; }
+ }
+
+ var gRef = null;
+ function storeReference(otherWin) {
+ gRef = otherWin.document.getElementById('foo');
+ }
+
+ function tryToAccessStored() {
+ try {
+ return /Better Late/.exec(gRef.innerHTML);
+ } catch (e) { return false; }
+ }
+
+ function invokingFunctionThrowsSecurityException(name) {
+ try {
+ window[name]();
+ return false;
+ } catch (e) { return /insecure|denied/.test(e); }
+ }
+
+
+</script>
+</head>
+<body>
+<span id="foo">Better Late than Never</span>
+</body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/file_doublewrappedcompartments.html b/js/xpconnect/tests/mochitest/file_doublewrappedcompartments.html
new file mode 100644
index 0000000000..f789a33d76
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/file_doublewrappedcompartments.html
@@ -0,0 +1,10 @@
+<html>
+ <head>
+ <script>
+ // We want to put an expando on the object, but we want this object
+ // to be wrapped in other compartments. This means that the expando
+ // must implement precreate, which happens (in general) for nodes.
+ // So we just do a cyclic reference to the document body.
+ window.expando = document.documentElement;
+ </script>
+ </head>
diff --git a/js/xpconnect/tests/mochitest/file_empty.html b/js/xpconnect/tests/mochitest/file_empty.html
new file mode 100644
index 0000000000..ebe8e56a68
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/file_empty.html
@@ -0,0 +1,3 @@
+<!DOCTYPE html>
+<!-- Note: other tests throughout the tree depend on the layout of this, including the title. Don't make big changes without a try run. -->
+<html><head><title>empty test page</title></head><body><span id="text">Nothing to see here</span><iframe name="subframe"></iframe></body></html>
diff --git a/js/xpconnect/tests/mochitest/file_evalInSandbox.html b/js/xpconnect/tests/mochitest/file_evalInSandbox.html
new file mode 100644
index 0000000000..f53aa1166c
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/file_evalInSandbox.html
@@ -0,0 +1,8 @@
+<html>
+ <body>
+ <script>
+ document.foo = "bar";
+ windowfoo = "windowbar";
+ </script>
+ </body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/file_exnstack.html b/js/xpconnect/tests/mochitest/file_exnstack.html
new file mode 100644
index 0000000000..448e3c0a70
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/file_exnstack.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script type="application/javascript">
+ window.doThrow = function(other) {
+ if (other)
+ throwAsOuter(other);
+ else
+ throwAsInner();
+ }
+
+ function throwAsInner() {
+ throw Error('look at me go!');
+ }
+
+ function throwAsOuter(other) {
+ other.doThrow(null);
+ }
+ </script>
+</head>
+<body>
+</body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/file_expandosharing.html b/js/xpconnect/tests/mochitest/file_expandosharing.html
new file mode 100644
index 0000000000..ceb4131bb8
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/file_expandosharing.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script type="application/javascript">
+ function setup() {
+ // Set up different target objects for expandos, one for each binding type.
+ window.targetWN = window;
+ window.targetDOM = new XMLHttpRequest();
+ window.targetJS = new Date();
+ }
+
+ function placeExpando(name, val, target) {
+ target[name] = val;
+ }
+
+ // If val === null, then we shouldn't have access.
+ function checkExpando(name, val, target, msg) {
+ if (val !== null) {
+ ok(name in target, msg);
+ try {
+ is(target[name], val, "Got the right expando value");
+ } catch(e) { ok(false, "Threw when accessing same-origin expando"); }
+ }
+ else {
+ ok(!(name in target), msg);
+ }
+ }
+
+</script>
+</head>
+<body onload="setup();">
+ <span>Salut, Ma Cherise. ;-)</span>
+</body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/file_matches.html b/js/xpconnect/tests/mochitest/file_matches.html
new file mode 100644
index 0000000000..0dc101b533
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/file_matches.html
@@ -0,0 +1 @@
+<html><body></body></html>
diff --git a/js/xpconnect/tests/mochitest/file_nodelists.html b/js/xpconnect/tests/mochitest/file_nodelists.html
new file mode 100644
index 0000000000..2195c62ccf
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/file_nodelists.html
@@ -0,0 +1,7 @@
+<html>
+ <body>
+ <p>
+ <p>
+ <p>
+ </body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/file_wrappers-2.html b/js/xpconnect/tests/mochitest/file_wrappers-2.html
new file mode 100644
index 0000000000..e27b07ed6a
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/file_wrappers-2.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+ <body>
+ <script>
+ var obj = {a: 3, next: 1};
+ var to_iterate = Object.create(obj);
+ var enumerate = { 0: 0, "hi": "there" };
+ function func () {};
+ var o = {};
+ var a = [1];
+ </script>
+ </body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/file_xrayic.html b/js/xpconnect/tests/mochitest/file_xrayic.html
new file mode 100644
index 0000000000..ad06a3118b
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/file_xrayic.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script type="application/javascript">
+ function setup() {
+ // Set up targets for sandbox expandos.
+ window.targetDOM = [document.getElementById("hello"), document.getElementById("there")];
+ }
+</script>
+</head>
+<body onload="setup();">
+<span id="hello" class="iamaspan">Hello</span>
+<span id="there" class="iamaspan">There</span>
+</body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/finalizationRegistry_worker.js b/js/xpconnect/tests/mochitest/finalizationRegistry_worker.js
new file mode 100644
index 0000000000..d603cdab38
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/finalizationRegistry_worker.js
@@ -0,0 +1,96 @@
+let holdings1 = [];
+let holdings2 = [];
+let holdings3 = [];
+let holdings4 = [];
+let holdings5 = [];
+
+onmessage = (event) => {
+ switch (event.data) {
+ case 'startTest':
+ startTest();
+ break;
+ case 'checkResults':
+ checkResults();
+ break;
+ default:
+ throw "Unknown message";
+ }
+};
+
+function startTest() {
+ // Registry with no registered objects.
+ let registry1 = new FinalizationRegistry(v => { holdings1.push(v); });
+
+ // Registry with three registered objects.
+ let registry2 = new FinalizationRegistry(v => { holdings2.push(v); });
+ registry2.register({}, 1);
+ registry2.register({}, 2);
+ registry2.register({}, 3);
+
+ // Registry with registered object that is then unregistered.
+ let registry3 = new FinalizationRegistry(v => { holdings3.push(v); });
+ let token3 = {}
+ registry3.register({}, 1, token3);
+ registry3.unregister(token3);
+
+ // Registry with registered object that doesn't die.
+ let registry4 = new FinalizationRegistry(v => { holdings4.push(v); });
+ let object4 = {};
+ registry4.register(object4, 1);
+
+ // Registry observing cyclic JS data structure.
+ let registry5 = new FinalizationRegistry(v => { holdings5.push(v); });
+ registry5.register(makeJSCycle(4), 5);
+
+ const { gc } = getJSTestingFunctions();
+ gc();
+
+ Promise.resolve().then(() => {
+ checkNoCallbacks();
+ });
+
+ postMessage('started');
+}
+
+function checkNoCallbacks() {
+ is(holdings1.length, 0);
+ is(holdings2.length, 0);
+ is(holdings3.length, 0);
+ is(holdings4.length, 0);
+ is(holdings5.length, 0);
+}
+
+function checkResults() {
+ is(holdings1.length, 0);
+
+ let result = holdings2.sort((a, b) => a - b);
+ is(result.length, 3);
+ is(result[0], 1);
+ is(result[1], 2);
+ is(result[2], 3);
+
+ is(holdings3.length, 0);
+ is(holdings4.length, 0);
+
+ is(holdings5.length, 1);
+ is(holdings5[0], 5);
+
+ postMessage('passed');
+}
+
+function is(a, b) {
+ if (a !== b) {
+ throw `Expected ${b} but got ${a}`;
+ }
+}
+
+function makeJSCycle(size) {
+ let first = {};
+ let current = first;
+ for (let i = 0; i < size; i++) {
+ current.next = {};
+ current = current.next;
+ }
+ current.next = first;
+ return first;
+}
diff --git a/js/xpconnect/tests/mochitest/inner.html b/js/xpconnect/tests/mochitest/inner.html
new file mode 100644
index 0000000000..8021a55539
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/inner.html
@@ -0,0 +1,7 @@
+<html>
+ <head>
+ <title>Inner frame for bug 39685 mochitest</title>
+ </head>
+ <body onload="x = 4">
+ </body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/mochitest.toml b/js/xpconnect/tests/mochitest/mochitest.toml
new file mode 100644
index 0000000000..c57cb26890
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/mochitest.toml
@@ -0,0 +1,297 @@
+[DEFAULT]
+support-files = [
+ "bug500931_helper.html",
+ "bug571849_helper.html",
+ "bug589028_helper.html",
+ "bug92773_helper.html",
+ "chrome_wrappers_helper.html",
+ "file1_bug629227.html",
+ "file2_bug629227.html",
+ "file_bug505915.html",
+ "file_bug605167.html",
+ "file_bug650273.html",
+ "file_bug658560.html",
+ "file_bug706301.html",
+ "file_bug720619.html",
+ "file_bug731471.html",
+ "file_bug738244.html",
+ "file_bug760131.html",
+ "file_bug781476.html",
+ "file_bug789713.html",
+ "file_bug795275.html",
+ "file_bug799348.html",
+ "file_bug802557.html",
+ "file_bug860494.html",
+ "file_crosscompartment_weakmap.html",
+ "file_documentdomain.html",
+ "file_doublewrappedcompartments.html",
+ "file_empty.html",
+ "file_evalInSandbox.html",
+ "file_exnstack.html",
+ "file_expandosharing.html",
+ "file_matches.html",
+ "file_nodelists.html",
+ "file_wrappers-2.html",
+ "file_xrayic.html",
+ "inner.html",
+ "test1_bug629331.html",
+ "test2_bug629331.html",
+ "finalizationRegistry_worker.js",
+ "private_field_worker.js",
+ "class_static_worker.js",
+ "bug1681664_helper.js",
+ "shadow_realm_worker.js",
+ "shadow_realm_module.js",
+]
+prefs = [
+ "javascript.options.weakrefs=true",
+ "javascript.options.spectre.disable_for_isolated_content=true",
+ "javascript.options.experimental.shadow_realms=true",
+]
+
+["test_bug92773.html"]
+skip-if = [
+ "http3",
+ "http2",
+]
+
+["test_bug384632.html"]
+
+["test_bug390488.html"]
+
+["test_bug393269.html"]
+
+["test_bug396851.html"]
+skip-if = [
+ "http3",
+ "http2",
+]
+
+["test_bug428021.html"]
+
+["test_bug446584.html"]
+
+["test_bug462428.html"]
+
+["test_bug478438.html"]
+skip-if = [
+ "http3",
+ "http2",
+]
+
+["test_bug500691.html"]
+
+["test_bug505915.html"]
+skip-if = [
+ "http3",
+ "http2",
+]
+
+["test_bug560351.html"]
+
+["test_bug585745.html"]
+
+["test_bug589028.html"]
+
+["test_bug601299.html"]
+
+["test_bug605167.html"]
+skip-if = [
+ "http3",
+ "http2",
+]
+
+["test_bug618017.html"]
+
+["test_bug623437.html"]
+
+["test_bug628410.html"]
+
+["test_bug628794.html"]
+
+["test_bug629227.html"]
+skip-if = [
+ "http3",
+ "http2",
+]
+
+["test_bug629331.html"]
+skip-if = [
+ "http3",
+ "http2",
+]
+
+["test_bug636097.html"]
+skip-if = [
+ "http3",
+ "http2",
+]
+
+["test_bug650273.html"]
+skip-if = [
+ "http3",
+ "http2",
+]
+
+["test_bug655297-1.html"]
+
+["test_bug655297-2.html"]
+
+["test_bug661980.html"]
+
+["test_bug691059.html"]
+
+["test_bug720619.html"]
+skip-if = [
+ "http3",
+ "http2",
+]
+
+["test_bug731471.html"]
+skip-if = ["os == 'android' && debug"]
+
+["test_bug764389.html"]
+
+["test_bug772288.html"]
+
+["test_bug781476.html"]
+
+["test_bug789713.html"]
+skip-if = [
+ "http3",
+ "http2",
+]
+
+["test_bug790732.html"]
+
+["test_bug793969.html"]
+
+["test_bug800864.html"]
+skip-if = [
+ "http3",
+ "http2",
+]
+
+["test_bug802557.html"]
+skip-if = [
+ "http3",
+ "http2",
+]
+
+["test_bug803730.html"]
+
+["test_bug809547.html"]
+
+["test_bug829872.html"]
+skip-if = [
+ "http3",
+ "http2",
+]
+
+["test_bug862380.html"]
+skip-if = [
+ "http3",
+ "http2",
+]
+
+["test_bug865260.html"]
+skip-if = [
+ "http3",
+ "http2",
+]
+
+["test_bug871887.html"]
+
+["test_bug912322.html"]
+
+["test_bug916945.html"]
+skip-if = [
+ "http3",
+ "http2",
+]
+
+["test_bug940783.html"]
+skip-if = [
+ "http3",
+ "http2",
+]
+
+["test_bug960820.html"]
+
+["test_bug965082.html"]
+skip-if = [
+ "http3",
+ "http2",
+]
+
+["test_bug993423.html"]
+
+["test_bug1005806.html"]
+
+["test_bug1094930.html"]
+
+["test_bug1158558.html"]
+
+["test_bug1448048.html"]
+
+["test_bug1681664.html"]
+
+["test_class_static_block_worker.html"]
+skip-if = ["!nightly_build"]
+
+["test_crosscompartment_weakmap.html"]
+
+["test_enable_privilege.html"]
+
+["test_finalizationRegistry.html"]
+
+["test_finalizationRegistryInWorker.html"]
+
+["test_finalizationRegistry_cleanupSome.html"]
+
+["test_finalizationRegistry_incumbent.html"]
+
+["test_frameWrapping.html"]
+# The JS test component we use below is only available in debug builds.
+
+["test_getWebIDLCaller.html"]
+skip-if = ["!debug"]
+
+["test_getweakmapkeys.html"]
+
+["test_isRemoteProxy.html"]
+
+["test_nukeContentWindow.html"]
+
+["test_paris_weakmap_keys.html"]
+skip-if = ["!debug"]
+
+["test_private_field_dom.html"]
+
+["test_private_field_worker.html"]
+
+["test_sameOriginPolicy.html"]
+skip-if = [
+ "http3",
+ "http2",
+]
+
+["test_sandbox_fetch.html"]
+support-files = ["../../../../dom/tests/mochitest/fetch/test_fetch_basic.js"]
+
+["test_shadowRealm.html"]
+# This test has been updated to work with worker modules
+
+["test_shadowRealm_worker.html"]
+skip-if = ["!nightly_build"]
+
+["test_spectre_mitigations.html"]
+skip-if = ["os == 'android'"] # Fission situation on Android is more complicated.
+
+["test_weakRefs.html"]
+
+["test_weakRefs_collected_wrapper.html"]
+
+["test_weakRefs_cross_compartment.html"]
+
+["test_weakmaps.html"]
diff --git a/js/xpconnect/tests/mochitest/moz.build b/js/xpconnect/tests/mochitest/moz.build
new file mode 100644
index 0000000000..2f41008128
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/moz.build
@@ -0,0 +1,7 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+MOCHITEST_MANIFESTS += ["mochitest.toml"]
diff --git a/js/xpconnect/tests/mochitest/private_field_worker.js b/js/xpconnect/tests/mochitest/private_field_worker.js
new file mode 100644
index 0000000000..b822c16248
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/private_field_worker.js
@@ -0,0 +1,21 @@
+class A {
+ #x;
+
+ g(o) {
+ return #x in o;
+ }
+}
+
+let objects = [];
+
+self.onmessage = function (e) {
+ if (e.data === 'allocate') {
+ objects.push(new A);
+ return;
+ }
+ if (e.data == 'count') {
+ postMessage(objects.length);
+ return;
+ }
+ postMessage('Unknown message type.');
+} \ No newline at end of file
diff --git a/js/xpconnect/tests/mochitest/shadow_realm_module.js b/js/xpconnect/tests/mochitest/shadow_realm_module.js
new file mode 100644
index 0000000000..35ba80666b
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/shadow_realm_module.js
@@ -0,0 +1 @@
+export var x = 1;
diff --git a/js/xpconnect/tests/mochitest/shadow_realm_worker.js b/js/xpconnect/tests/mochitest/shadow_realm_worker.js
new file mode 100644
index 0000000000..c91c9bc30c
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/shadow_realm_worker.js
@@ -0,0 +1,81 @@
+
+var sr = new ShadowRealm();
+var resolve;
+
+var allSettled = new Promise((resolved) => { resolve = resolved });
+
+self.onmessage = async function (e) {
+ try {
+ // Test evaluate
+ if (e.data === 'evaluate') {
+ sr.evaluate("var s = 'PASS set string in realm';")
+ var res = sr.evaluate('s');
+ postMessage(res);
+ return;
+ }
+
+ // If Import works in a worker, then it ought to work in a shadow realm
+ //
+ // See https://bugzilla.mozilla.org/show_bug.cgi?id=1247687 and
+ // https://bugzilla.mozilla.org/show_bug.cgi?id=1772162
+ if (e.data == 'import') {
+ var import_worked = false;
+ var importValue_worked = false;
+ var importNested_worked = false;
+ try {
+ var module = await import("./shadow_realm_module.js");
+ if (module.x != 1) {
+ throw "mismatch";
+ }
+ import_worked = true;
+ } catch (e) { }
+
+ try {
+ await sr.importValue("./shadow_realm_module.js", 'x').then((x) => {
+ if (x == 1) { importValue_worked = true; }
+ });
+ } catch (e) { }
+
+ try {
+ sr.evaluate(`
+ var imported = false;
+ import("./shadow_realm_module.js").then((module) => {
+ if (module.x == 1) {
+ imported = true;
+ }
+ });
+ true;
+ `);
+
+ importNested_worked = sr.evaluate("imported");
+ } catch (e) {
+
+ }
+
+ if (importValue_worked == importNested_worked) {
+ postMessage(`PASS: import in workers ${
+ import_worked ? "worked" : "failed"
+ }. importValue, and nested import all ${
+ importValue_worked ? "worked" : "failed"
+ } `);
+ resolve();
+ return;
+ }
+
+ postMessage(`FAIL: importValue ${importValue_worked}, import ${import_worked}, importNested ${importNested_worked}`);
+ resolve();
+ return;
+ }
+
+
+ // Reply back with finish
+ if (e.data == 'finish') {
+ await allSettled;
+ postMessage("finish");
+ return;
+ }
+ } catch (e) {
+ postMessage("FAIL: " + e.message);
+ }
+ postMessage('Unknown message type.');
+}
diff --git a/js/xpconnect/tests/mochitest/test1_bug629331.html b/js/xpconnect/tests/mochitest/test1_bug629331.html
new file mode 100644
index 0000000000..18843e08da
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test1_bug629331.html
@@ -0,0 +1,19 @@
+<body>
+<iframe src="about:blank" id="ifr"></iframe>
+<script>
+/** Test for Bug 629331 **/
+function finish() {
+ parent.postMessage(JSON.stringify({fun: "finish"}), "*");
+}
+
+function is(a, b, description) {
+ parent.postMessage(JSON.stringify({ fun: "is", a: a, b: b, description: description }), "*");
+}
+
+document.domain = "example.org";
+var i = 0;
+is(i, 0, 'i meets starting conditions');
+document.getElementById('ifr').src = 'http://test2.example.org/tests/js/xpconnect/tests/mochitest/test2_bug629331.html';
+</script>
+
+
diff --git a/js/xpconnect/tests/mochitest/test2_bug629331.html b/js/xpconnect/tests/mochitest/test2_bug629331.html
new file mode 100644
index 0000000000..1bcf037398
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test2_bug629331.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ </head>
+ <body>
+ <script>
+ document.domain = "example.org";
+
+ for (var j = 1; j <= 9; j++) {
+ parent.i = j;
+ var locali = parent.i;
+ parent.is(locali, j, 'step ' + j + ' worked');
+ }
+
+ parent.finish();
+ </script>
+ </body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/test_bug1005806.html b/js/xpconnect/tests/mochitest/test_bug1005806.html
new file mode 100644
index 0000000000..41fe6ee1e6
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_bug1005806.html
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1005806
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1005806</title>
+ <script 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=1005806">Mozilla Bug 1005806</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+ <input id="ipt"></input>
+</div>
+<pre id="test">
+</pre>
+<script type="application/javascript">
+
+/** Test for Bug 1005806 **/
+is(typeof document.getElementById('ipt').controllers, 'undefined', "Controllers property should not appear for content");
+
+</script>
+</body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/test_bug1094930.html b/js/xpconnect/tests/mochitest/test_bug1094930.html
new file mode 100644
index 0000000000..d303bf2495
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_bug1094930.html
@@ -0,0 +1,29 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1094930
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1094930</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <iframe id="ifr"></iframe>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1094930">Mozilla Bug 1094930</a>
+<p id="display"></p>
+<script type="application/javascript">
+ SimpleTest.waitForExplicitFinish();
+ class XFoo extends frames[0].HTMLElement {
+ connectedCallback() {
+ ok(true, "connectedCallback was called");
+ SimpleTest.finish();
+ }
+ };
+
+ customElements.define.call(frames[0].customElements, "x-foo", XFoo);
+ frames[0].document.firstChild.appendChild(new XFoo());
+</script>
+</body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/test_bug1158558.html b/js/xpconnect/tests/mochitest/test_bug1158558.html
new file mode 100644
index 0000000000..f5c50d640e
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_bug1158558.html
@@ -0,0 +1,47 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1158558
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1158558</title>
+ <script 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=1158558">Mozilla Bug 1158558</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+ <input id="ipt"></input>
+</div>
+<pre id="test">
+</pre>
+<script type="application/javascript">
+
+/** Test for Bug 1158558 **/
+
+// Observers of cycle-collector-begin can be implemented in JS, and
+// thus can end up starting an incremental GC while we're in the middle
+// of a CC slice.
+
+SimpleTest.waitForExplicitFinish();
+
+var observer = {
+ observe: function(subject, topic, data) {
+ SpecialPowers.removeObserver(observer, "cycle-collector-begin");
+ SpecialPowers.Cu.getJSTestingFunctions().startgc(1);
+
+ ok(true, "Do something so the test harness doesn't get angry");
+
+ SimpleTest.finish();
+ }
+};
+
+SpecialPowers.addObserver(observer, "cycle-collector-begin");
+
+SpecialPowers.Cu.forceCC();
+
+</script>
+</body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/test_bug1448048.html b/js/xpconnect/tests/mochitest/test_bug1448048.html
new file mode 100644
index 0000000000..7cd747b5c7
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_bug1448048.html
@@ -0,0 +1,33 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1448048
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1448048</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript">
+
+ /** Test for Bug 1448048 **/
+ var { AppConstants } = SpecialPowers.ChromeUtils.importESModule(
+ "resource://gre/modules/AppConstants.sys.mjs"
+ );
+ if (AppConstants.NIGHTLY_BUILD) {
+ is(typeof Components, "undefined", "Should be no Components shim on Nightly");
+ } else {
+ is(typeof Components, "object", "Should have a components shim on non-Nightly");
+ }
+ </script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1448048">Mozilla Bug 1448048</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+</pre>
+</body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/test_bug1681664.html b/js/xpconnect/tests/mochitest/test_bug1681664.html
new file mode 100644
index 0000000000..685d4aa669
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_bug1681664.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<html lang="en" dir="ltr">
+ <head>
+ <title>Test page for bug 1681664</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script>
+ SimpleTest.waitForExplicitFinish()
+ async function init() {
+ var Services = SpecialPowers.Services;
+ var observer = {
+ observe(subject, topic, data) {
+ if (topic === "process-hang-report") {
+ var report = subject.QueryInterface(Ci.nsIHangReport);
+ report.terminateScript();
+ Services.obs.removeObserver(observer, "process-hang-report");
+ }
+ }
+ }
+
+ Services.obs.addObserver(observer, "process-hang-report");
+ try {
+ await import("test_bug1681664_helper.js");
+ result.textContent = "FAIL";
+ } catch (ex) {
+ result.textContent = "PASS";
+ }
+ }
+ </script>
+ </head>
+ <body>
+ <p id="result"></p>
+ <script>
+ (async function() {
+ await init();
+ is(result.textContent, "PASS", "Infinite loop script should not cause browser crash");
+ SimpleTest.finish()
+ })();
+ </script>
+ </body>
+</html>
+
diff --git a/js/xpconnect/tests/mochitest/test_bug384632.html b/js/xpconnect/tests/mochitest/test_bug384632.html
new file mode 100644
index 0000000000..251ec9b153
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_bug384632.html
@@ -0,0 +1,34 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=384632
+-->
+<head>
+ <title>Test for Bug 384632</title>
+ <script 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=384632">Mozilla Bug 384632</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 384632 **/
+var Cc = SpecialPowers.Cc, Ci = SpecialPowers.Ci;
+var propBag = Cc["@mozilla.org/hash-property-bag;1"].createInstance(Ci.nsIWritablePropertyBag);
+var obj = {};
+propBag.setProperty("foopy", obj);
+ok(SpecialPowers.unwrap(propBag.getProperty("foopy")) === obj,
+ "nsIVariant works with regular objects");
+propBag.setProperty("foopy1", external);
+ok(SpecialPowers.unwrap(propBag.getProperty("foopy1")) === external,
+ "nsIVariant works with bizarre objects");
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/test_bug390488.html b/js/xpconnect/tests/mochitest/test_bug390488.html
new file mode 100644
index 0000000000..ca4bc4024b
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_bug390488.html
@@ -0,0 +1,64 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=390488
+-->
+<head>
+ <title>Test for Bug 390488</title>
+ <script 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=390488">Mozilla Bug 390488</a>
+<p id="display">
+ <div id="testdiv" onclick="checkForStacks();" style="visibility:hidden">
+ </div>
+</p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+/** Test for Bug 390488 **/
+ function getStack1() {
+ var func = arguments.callee.caller;
+ var stack = "";
+ for (var i = 1; func && i < 8; i++) {
+ stack += " " + i + ". " + func.name;
+ func = func.caller;
+ }
+ return stack;
+ }
+
+ function getStack2() {
+ var stack = new Error().stack;
+ // Remove the two lines due to calling this
+ return stack.substring(stack.indexOf("\n", stack.indexOf("\n")+1)+1);
+ }
+
+ function simulateClick() {
+ var evt = document.createEvent("MouseEvents");
+ evt.initMouseEvent("click", true, true, window,
+ 0, 0, 0, 0, 0, false, false, false, false, 0, null);
+ $("testdiv").dispatchEvent(evt);
+ }
+
+ function matches(s, p, name) {
+ ok(s.match(p) != null,
+ name + " - got " + s + ", expected a string matching " + p);
+ }
+
+ function checkForStacks() {
+ matches(getStack1(), /checkForStacks .* onclick .* simulateClick/,
+ "Stack from walking caller chain should be correct");
+ isnot(getStack2().indexOf("simulateClick@"), -1,
+ "Stack from |new Error().stack| should include simulateClick");
+ }
+
+ simulateClick();
+</script>
+</pre>
+</body>
+</html>
+
diff --git a/js/xpconnect/tests/mochitest/test_bug393269.html b/js/xpconnect/tests/mochitest/test_bug393269.html
new file mode 100644
index 0000000000..d69e9ef2d1
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_bug393269.html
@@ -0,0 +1,46 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=393269
+-->
+<head>
+ <title>Test for Bug 393269</title>
+ <script 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=393269">Mozilla Bug 393269</a>
+<iframe id="ifr"></iframe>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+(function () {
+ /** Test for Bug 393269 **/
+ var doc = $("ifr").contentDocument;
+ is("UTF-8", doc.characterSet, "control, getting a property");
+ doc.open();
+ try {
+ is("UTF-8", doc.characterSet,
+ "can get a property after 1 document.open")
+ } catch (e) {
+ fail("Shouldn't have thrown: " + e);
+ return;
+ } finally {
+ doc.close();
+ }
+
+ doc.open();
+ try {
+ is("UTF-8", doc.characterSet,
+ "can get a property after 2 document.opens")
+ } catch (e) {
+ fail("Shouldn't have thrown: " + e);
+ } finally {
+ doc.close();
+ }
+})();
+</script>
+</pre>
+</body>
+</html>
+
diff --git a/js/xpconnect/tests/mochitest/test_bug396851.html b/js/xpconnect/tests/mochitest/test_bug396851.html
new file mode 100644
index 0000000000..dc6bd25d52
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_bug396851.html
@@ -0,0 +1,53 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=396851
+-->
+<head>
+ <title>Test for Bug 396851</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+
+ <script type="text/javascript">
+ function throws(func, pattern, msg) {
+ try {
+ func();
+ ok(false, msg);
+ } catch (e) {
+ ok(pattern.test(e), `${msg}: Expect exception mathing ${pattern}`);
+ }
+ }
+
+ function go() {
+ var iframe = $("ifr");
+ var win = iframe.contentWindow;
+ throws(() => win.document,
+ /Permission denied/,
+ "Unprivileged code should not be able to access cross-origin document");
+
+ if (SpecialPowers.useRemoteSubframes) {
+ throws(() => win.document,
+ /Permission denied/,
+ "Privileged code should not be able to access cross-process document");
+ } else {
+ ok(SpecialPowers.wrap(win).document != null,
+ "Able to access the cross-origin document");
+ }
+ SimpleTest.finish();
+ }
+ </script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=396851">Mozilla Bug 396851</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+</div>
+<script type="text/javascript">
+ SimpleTest.waitForExplicitFinish();
+</script>
+<iframe id="ifr"
+ src="http://example.org/tests/js/xpconnect/tests/mochitest/inner.html"
+ onload="go()">
+</iframe>
+</body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/test_bug428021.html b/js/xpconnect/tests/mochitest/test_bug428021.html
new file mode 100644
index 0000000000..932dcf7428
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_bug428021.html
@@ -0,0 +1,40 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=428021
+-->
+<head>
+ <title>Test for Bug 428021</title>
+ <script 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=428021">Mozilla Bug 428021</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+ /** Test for Bug 428021 **/
+ var rangetter, ransetter;
+ this.__defineGetter__('x', function() { rangetter = true; });
+ this.__defineSetter__('x', function(val) { ransetter = true; });
+
+ var exn;
+ try {
+ e = x;
+ x = false;
+ } catch (e) {
+ exn = e;
+ }
+ ok(!exn, "Exception caught: " + exn);
+ ok(rangetter, "Failed to run getter");
+ ok(ransetter, "Failed to run setter");
+
+</script>
+</pre>
+</body>
+</html>
+
diff --git a/js/xpconnect/tests/mochitest/test_bug446584.html b/js/xpconnect/tests/mochitest/test_bug446584.html
new file mode 100644
index 0000000000..09fef92867
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_bug446584.html
@@ -0,0 +1,47 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=446584
+-->
+<head>
+ <title>Test for Bug 446584</title>
+ <script 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=446584">Mozilla Bug 446584</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+/** Test for Bug 446584 **/
+
+function test(val) {
+ try {
+ document.createNodeIterator(document.body,
+ NodeFilter.SHOW_ALL,
+ function() { throw val }).nextNode();
+ ok(false, "NodeIterator::nextNode() should have thrown an exception.");
+ } catch (ex) {
+ ok(val === ex, "NodeIterator did not properly forward exception " +
+ val + " of type " + typeof val + ". Thrown value was " + ex + ".");
+ }
+}
+
+test(0);
+test(1);
+test(3.14);
+test('roses');
+test({});
+test(false);
+test(true);
+test([1,2,3]);
+test(function(){});
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/test_bug462428.html b/js/xpconnect/tests/mochitest/test_bug462428.html
new file mode 100644
index 0000000000..a3f7b7c39a
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_bug462428.html
@@ -0,0 +1,51 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=462428
+-->
+<head>
+ <title>Test for Bug 462428</title>
+ <script 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=462428">Mozilla Bug 462428</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 462428 **/
+var getter = document.__lookupGetter__('documentElement');
+ok(getter !== undefined, "But able to look it up the normal way");
+ok(!document.hasOwnProperty('documentElement'), "property should still be on the prototype");
+
+var sawProp = false;
+for (var i in document) {
+ if (i === "documentElement") {
+ sawProp = true;
+ }
+}
+
+ok(sawProp, "property should be enumerable");
+
+is(getter.call(document), document.documentElement, "the getter actually works");
+
+Document.prototype.__defineSetter__('documentElement', function() {});
+is(getter.call(document), document.documentElement, "the getter works after defineSetter");
+
+var oldTitle = document.title;
+try {
+ var setter = document.__lookupSetter__('title');
+ setter.call(document, "title 1");
+ is(document.title, "title 1", "the setter is bound correctly");
+} finally {
+ document.title = oldTitle
+}
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/test_bug478438.html b/js/xpconnect/tests/mochitest/test_bug478438.html
new file mode 100644
index 0000000000..e64a1e89fb
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_bug478438.html
@@ -0,0 +1,65 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=478438
+-->
+<head>
+ <title>Test for Bug 478438</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript">
+ function fail(s, e) { ok(false, s + e) }
+ function pass(s, e) { ok(true, s) }
+ (pass.opposite = fail).opposite = pass;
+
+ function test() {
+ if (test.calledAlready)
+ return;
+ test.calledAlready = true;
+
+ var iwin = document.getElementById("f").contentWindow;
+
+ function testOne(fn, onAllow, infinitive) {
+ try { fn(); onAllow("able " + infinitive, "") }
+ catch (e) { onAllow.opposite("unable " + infinitive, ": " + e) }
+ }
+
+ testOne(() => iwin.focus, pass,
+ "to resolve/get allAccess property iwin.focus");
+
+ testOne(() => iwin.focus(), pass,
+ "to call allAccess method iwin.focus");
+
+ testOne(() => iwin.alert, fail,
+ "to resolve/get restricted property iwin.alert");
+
+ testOne(() => iwin.alert(), fail,
+ "to call restricted method iwin.alert");
+
+ testOne(() => iwin.location.toString(), fail,
+ "to call restricted method iwin.location.toString");
+
+ testOne(function() { iwin.location = "http://example.org" }, pass,
+ "to set writable property iwin.location");
+
+ SimpleTest.finish();
+ }
+ </script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=478438">Mozilla Bug 478438</a>
+<p id="display"></p>
+<div id="content">
+ <iframe id="f" src="http://example.com" onload="test()"></iframe>
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 478438 **/
+
+SimpleTest.waitForExplicitFinish();
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/test_bug484107.html b/js/xpconnect/tests/mochitest/test_bug484107.html
new file mode 100644
index 0000000000..38ca7b207b
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_bug484107.html
@@ -0,0 +1,99 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=484107
+-->
+<head>
+ <title>Test for Bug 484107</title>
+ <script 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=484107">Mozilla Bug 484107</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 484107 **/
+
+ var text = "first group",
+ xpcWin = new XPCSafeJSObjectWrapper(window);
+ function get$1() { return RegExp.$1 };
+
+ function reset() {
+ var match = /(.*)/.exec(text);
+ if (!reset.skipStupidTests) {
+ reset.skipStupidTests = true;
+ ok(match, "No match?");
+ is(match[1], text, "Bad match?");
+ is(text, RegExp.$1, "RegExp.$1 missing?");
+ is(text, get$1(), "RegExp.$1 inaccessible?");
+ }
+ }
+
+ function test_XPC_SJOW_Call() {
+ isnot(text, xpcWin.get$1(), "Able to see RegExp.$1 from wrapped method.");
+ is("", xpcWin.get$1(), "Saw something other than an empty string for " +
+ "RegExp.$1 from wrapped method.");
+ is(text, window.get$1(), "Unable to see RegExp.$1 from non-wrapped method.");
+ }
+
+ function test_XPC_SJOW_Call_foreign_obj() {
+ var obj = {
+ xpcGet: xpcWin.get$1,
+ rawGet: window.get$1
+ };
+ isnot(text, obj.xpcGet(), "obj.xpcGet() returned matched text.");
+ is("", obj.xpcGet(), "obj.xpcGet() returned something other than the empty string.");
+ is(text, obj.rawGet(), "obj.rawGet() did not return matched text.");
+ }
+
+ function test_XPC_SJOW_toString() {
+ var str = new XPCSafeJSObjectWrapper({
+ toString: function() { return RegExp.$1 }
+ }) + "";
+ isnot(text, str, "toString() returned the matched text.");
+ is("", str, "toString() returned something other than the empty string.");
+ }
+
+ function test_XPC_SJOW_GetOrSetProperty() {
+ window.__defineGetter__("firstMatch", function() { return RegExp.$1 });
+ isnot(text, xpcWin.firstMatch, "Getter xpcWin.firstMatch returned matched text.");
+ is("", xpcWin.firstMatch,
+ "Getter xpcWin.firstMatch returned something other than the empty string.");
+ is(text, window.firstMatch, "Getter window.firstMatch did not return matched text.");
+ }
+
+ function test_XPC_SJOW_Create() {
+ function ctor() {
+ this.match = RegExp.$1;
+ return this; // XXX Why is this necessary?
+ }
+ ctor.prototype.getMatch = function() { return this.match };
+ var xpcCtor = new XPCSafeJSObjectWrapper(ctor),
+ match = (new xpcCtor).getMatch();
+ isnot(text, match, "(new xpcCtor).getMatch() was the matched text.");
+ is("", match, "(new xpcCtor).getMatch() was not the empty string.");
+ }
+
+ var tests = [
+ test_XPC_SJOW_Call,
+ test_XPC_SJOW_Call_foreign_obj,
+ test_XPC_SJOW_toString,
+ test_XPC_SJOW_GetOrSetProperty,
+ test_XPC_SJOW_Create
+ ];
+
+ for (var i = 0; i < tests.length; i++) {
+ reset();
+ tests[i]();
+ is(text, RegExp.$1, "RegExp.$1 was clobbered.");
+ }
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/test_bug500691.html b/js/xpconnect/tests/mochitest/test_bug500691.html
new file mode 100644
index 0000000000..2ed127c099
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_bug500691.html
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=500691
+-->
+<head>
+ <title>Test for Bug 500691</title>
+ <script 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=500691">Mozilla Bug 500691</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 500691 **/
+ok(Function === alert.constructor, "alert's constructor is our Function");
+ok(window.Function === alert.constructor, "window.Function is also correct");
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/test_bug505915.html b/js/xpconnect/tests/mochitest/test_bug505915.html
new file mode 100644
index 0000000000..d5898bc1ed
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_bug505915.html
@@ -0,0 +1,49 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=505915
+-->
+<head>
+ <title>Test for Bug 505915</title>
+ <script 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=505915">Mozilla Bug 505915</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 505915 **/
+window.addEventListener("message", function () {
+ ok(false, "should not receive message");
+});
+
+function go() {
+ var ifr = $('ifr');
+ try {
+ // NB: the contentDocument getter now returns null for cross-origin
+ // frames, so use SpecialPowers to get a security wrapper to the document.
+ var xdoc = SpecialPowers.unwrap(SpecialPowers.wrap(ifr).contentDocument)
+ document.createTreeWalker(xdoc, 0, null);
+ ok(false, "should have thrown a security exception");
+ } catch (e) {
+ ok(/TypeError: Document.createTreeWalker: Argument 1 does not implement interface Node/.test(e),
+ "threw a binding exception instead of an invalid child exception");
+ }
+
+ SimpleTest.finish();
+}
+
+SimpleTest.waitForExplicitFinish();
+
+</script>
+</pre>
+
+<iframe id="ifr" onload="go();" src="http://test1.mochi.test:8888/"></iframe>
+
+</body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/test_bug560351.html b/js/xpconnect/tests/mochitest/test_bug560351.html
new file mode 100644
index 0000000000..263e6850d7
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_bug560351.html
@@ -0,0 +1,36 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=560351
+-->
+<head>
+ <title>Test for Bug 560351</title>
+ <script 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=560351">Mozilla Bug 560351</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 560351 **/
+var pass = false;
+try {
+ document.body.__lookupGetter__("lastChild")();
+} catch (e) {
+ pass = true;
+}
+
+</script>
+<script>
+
+ok(pass, "pass was set to true");
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/test_bug585745.html b/js/xpconnect/tests/mochitest/test_bug585745.html
new file mode 100644
index 0000000000..758aeed30d
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_bug585745.html
@@ -0,0 +1,43 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=585745
+-->
+<head>
+ <title>Test for Bug 585745</title>
+ <script 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=585745">Mozilla Bug 585745</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 585745 **/
+
+ var a = document.createElementNS("http://www.w3.org/1998/Math/MathML", 'mrow');
+ var b = document.createElementNS("http://www.w3.org/1999/xhtml", 'span');
+ var htmlProto = Object.getPrototypeOf(b);
+ var mathMLProto = Object.getPrototypeOf(a);
+ // XXXbz once bug 560072 is fixed, we should be able to use
+ // getOwnPropertyDescriptor here.
+ Object.defineProperty(mathMLProto, "style", {
+ get: htmlProto.__lookupGetter__("style"),
+ });
+
+ var threw = false;
+ try {
+ a.style;
+ } catch(e) {
+ threw = true;
+ }
+ is(threw, true,
+ "Getting .style off a mathml element should throw in this case");
+</script>
+</pre>
+</body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/test_bug589028.html b/js/xpconnect/tests/mochitest/test_bug589028.html
new file mode 100644
index 0000000000..2cd0d15ebb
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_bug589028.html
@@ -0,0 +1,62 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=589028
+-->
+<head>
+ <title>Test for Bug 589028</title>
+ <script 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=589028">Mozilla Bug 589028</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+</div>
+<pre id="test">
+<script>
+
+/** Test for Bug 589028 **/
+SimpleTest.waitForExplicitFinish();
+var p = 0;
+function go() {
+ var ifr = $('ifr');
+ var ifrwin = ifr.contentWindow;
+ var ifrdoc = ifr.contentDocument;
+
+ o1 = new ifrwin.Option();
+ is(o1.ownerDocument, ifrdoc, "ownerDocument doesn't match iframe");
+
+ o2 = ifrwin.getMyOption();
+ is(o2.ownerDocument, ifrdoc, "ownerDocument doesn't match iframe");
+
+ o3 = ifrwin.getCallersOption(this);
+ is(o3.ownerDocument, document);
+
+ a1 = new ifrwin.Audio();
+ is(a1.ownerDocument, ifrdoc, "ownerDocument doesn't match iframe");
+
+ a2 = ifrwin.getMyAudio();
+ is(a2.ownerDocument, ifrdoc, "ownerDocument doesn't match iframe");
+
+ a3 = ifrwin.getCallersAudio(this);
+ is(a3.ownerDocument, document);
+
+ i1 = new ifrwin.Image();
+ is(i1.ownerDocument, ifrdoc, "ownerDocument doesn't match iframe");
+
+ i2 = ifrwin.getMyImage();
+ is(i2.ownerDocument, ifrdoc, "ownerDocument doesn't match iframe");
+
+ i3 = ifrwin.getCallersImage(this);
+ is(i3.ownerDocument, document);
+
+ SimpleTest.finish();
+}
+
+
+</script>
+</pre>
+<iframe src="bug589028_helper.html" id="ifr" onload="go()"></iframe>
+</body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/test_bug601299.html b/js/xpconnect/tests/mochitest/test_bug601299.html
new file mode 100644
index 0000000000..cd726d7974
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_bug601299.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=601299
+
+Trigger a fastnative from a frameless context.
+-->
+<head>
+ <title>Test for Bug 601299</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body onload="window.setTimeout(RegExp, 0); window.setTimeout(function() { ok(true); SimpleTest.finish(); }, 0);">
+<script>
+SimpleTest.waitForExplicitFinish();
+</script>
+</body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/test_bug605167.html b/js/xpconnect/tests/mochitest/test_bug605167.html
new file mode 100644
index 0000000000..ba625aa805
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_bug605167.html
@@ -0,0 +1,56 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=505915
+-->
+<head>
+ <title>Test for Bug 505915</title>
+ <script 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=505915">Mozilla Bug 505915</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 505915 **/
+var url = "file_bug605167.html";
+var targetUrl = "http://example.com";
+var f;
+
+var p = 0;
+function go() {
+ switch (++p) {
+ case 1:
+ frames[0].location = url;
+ break;
+ case 2:
+ frames[0].location = targetUrl;
+ break;
+ case 3:
+ try {
+ f().cross_origin_property;
+ ok(false, "should have thrown an exception");
+ } catch (e) {
+ ok(/Permission denied/.test(e) || /attempt to run compile-and-go script/.test(e),
+ "threw the correct exception");
+ }
+ SimpleTest.finish();
+ break;
+ }
+}
+
+
+SimpleTest.waitForExplicitFinish();
+
+</script>
+</pre>
+
+<iframe id="ifr" onload="go();"></iframe>
+
+</body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/test_bug618017.html b/js/xpconnect/tests/mochitest/test_bug618017.html
new file mode 100644
index 0000000000..8bfb428870
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_bug618017.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=618017
+
+Parsing XML must not override the version.
+-->
+<head>
+ <title>Test for Bug 618017</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+
+<script type='application/javascript'>
+let x = 12;
+function doLetEval() {
+ ok(eval('let x = 13; x') === 13, 'let statement is valid syntax in version 1.7');
+}
+</script>
+
+<script type='application/javascript'>
+doLetEval(); // Call to a function with a different version.
+</script>
+
+</body>
+</html>
+
diff --git a/js/xpconnect/tests/mochitest/test_bug623437.html b/js/xpconnect/tests/mochitest/test_bug623437.html
new file mode 100644
index 0000000000..0cea6f330b
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_bug623437.html
@@ -0,0 +1,43 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=623437
+-->
+<head>
+ <title>Test for Bug 623437</title>
+ <script 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=623437">Mozilla Bug 623437</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 623437 **/
+ var c = document.createElement("canvas").getContext("2d");
+ var seenArcToFirst;
+ var seenArc = false;
+ var seenArcTo = false;
+ for (var i in c) {
+ if (i == "arc") {
+ seenArc = true;
+ if (!seenArcTo)
+ seenArcToFirst = false;
+ }
+ if (i == "arcTo") {
+ seenArcTo = true;
+ if (!seenArc)
+ seenArcToFirst = true;
+ }
+ }
+ is(seenArc, true, "Should see arc");
+ is(seenArcTo, true, "Should see arcTo");
+ is(seenArcToFirst, true, "Should see arcTo before arc");
+</script>
+</pre>
+</body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/test_bug628410.html b/js/xpconnect/tests/mochitest/test_bug628410.html
new file mode 100644
index 0000000000..2aec713793
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_bug628410.html
@@ -0,0 +1,34 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=628410
+-->
+<head>
+ <title>Test for Bug 628410</title>
+ <script 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=628410">Mozilla Bug 628410</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+
+<pre id="test">
+<script type="application/javascript">
+
+window.toString();
+
+if (SpecialPowers.Services.prefs.getBoolPref("extensions.InstallTrigger.enabled") &&
+ SpecialPowers.Services.prefs.getBoolPref("extensions.InstallTriggerImpl.enabled")) {
+ InstallTrigger + "";
+}
+
+console + "";
+ok(true, "Things didn't throw");
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/test_bug628794.html b/js/xpconnect/tests/mochitest/test_bug628794.html
new file mode 100644
index 0000000000..9cbfe0f436
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_bug628794.html
@@ -0,0 +1,43 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=585745
+-->
+<head>
+ <title>Test for Bug 585745</title>
+ <script 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=585745">Mozilla Bug 585745</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 585745 **/
+
+ var a = document.createElementNS("http://www.w3.org/2000/svg", 'svg');
+ var b = document.createElementNS("http://www.w3.org/1999/xhtml", 'span');
+ var htmlProto = Object.getPrototypeOf(b);
+ var svgProto = Object.getPrototypeOf(a);
+ // XXXbz once bug 560072 is fixed, we should be able to use
+ // getOwnPropertyDescriptor here.
+ Object.defineProperty(svgProto, "style", {
+ get: htmlProto.__lookupGetter__("style"),
+ });
+
+ var threw = false;
+ try {
+ a.style;
+ } catch(e) {
+ threw = true;
+ }
+ is(threw, true,
+ "Getting .style off an svg element should throw in this case");
+</script>
+</pre>
+</body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/test_bug629227.html b/js/xpconnect/tests/mochitest/test_bug629227.html
new file mode 100644
index 0000000000..6d01c37ec0
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_bug629227.html
@@ -0,0 +1,47 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=629227
+-->
+<head>
+ <title>Test for Bug 629227</title>
+ <script 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=629227">Mozilla Bug 629227</a>
+<p id="display">
+ <iframe id="testTarget"></iframe>
+</p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 629227 **/
+SimpleTest.waitForExplicitFinish();
+
+$("testTarget").src =
+ "http://test1.example.org" +
+ location.pathname.replace(/test_bug629227.html/, "file1_bug629227.html");
+
+window.onmessage = function(ev) {
+ if (ev.data == "finish") {
+ SimpleTest.finish();
+ } else {
+ var data = JSON.parse(ev.data);
+ if ("ok" in data) {
+ ok(data.ok, data.reason);
+ }
+ }
+}
+
+addLoadEvent(function() {
+ $("testTarget").contentWindow.postMessage("start", "*");
+});
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/test_bug629331.html b/js/xpconnect/tests/mochitest/test_bug629331.html
new file mode 100644
index 0000000000..17520b187f
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_bug629331.html
@@ -0,0 +1,37 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=629331
+-->
+<head>
+ <title>Test for Bug 629331</title>
+ <script 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=629331">Mozilla Bug 629331</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+SimpleTest.waitForExplicitFinish();
+
+function handler(event) {
+ var obj = JSON.parse(event.data);
+ if (obj.fun == "finish") {
+ SimpleTest.finish();
+ } else {
+ is(obj.a, obj.b, obj.description);
+ }
+}
+
+window.addEventListener('message', handler);
+
+</script>
+<iframe src="http://test1.example.org/tests/js/xpconnect/tests/mochitest/test1_bug629331.html">
+</iframe>
+</pre>
+</body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/test_bug636097.html b/js/xpconnect/tests/mochitest/test_bug636097.html
new file mode 100644
index 0000000000..8ae8e4822e
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_bug636097.html
@@ -0,0 +1,62 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=504877
+test by moz_bug_r_a4@yahoo.com
+-->
+<head>
+ <title>Test for Bug 504877</title>
+ <script 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=504877">Mozilla Bug 504877</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 504877 **/
+SimpleTest.waitForExplicitFinish();
+
+var targetUrl = "http://example.com/";
+var l;
+
+function a() {
+ var r = "FAIL", s;
+ try {
+ s = l.toString();
+ }
+ catch (e) {
+ if (/denied|insecure/.test(e))
+ r = "PASS";
+ s = e;
+ }
+
+ is(r, "PASS", "should have thrown an exception");
+ SimpleTest.finish();
+}
+
+var p = 0;
+function b() {
+ switch (++p) {
+ case 1:
+ frames[0].location = "about:blank";
+ break;
+ case 2:
+ l = frames[0].location;
+ frames[0].location = targetUrl;
+ break;
+ case 3:
+ a();
+ break;
+ }
+}
+</script>
+
+</pre>
+<iframe onload="b()"></iframe>
+</body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/test_bug650273.html b/js/xpconnect/tests/mochitest/test_bug650273.html
new file mode 100644
index 0000000000..18e029982a
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_bug650273.html
@@ -0,0 +1,42 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=650273
+test by moz_bug_r_a4@yahoo.com
+-->
+<head>
+ <title>Test for Bug 650273</title>
+ <script 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=650273">Mozilla Bug 650273</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 504877 **/
+SimpleTest.waitForExplicitFinish();
+var count = 0;
+function done() {
+ if (++count == 2) {
+ try {
+ ok($('ifr').location.host === 'example.com', "shouldn't see this");
+ } catch (e) {
+ ok(true, "navigation successfully happened");
+ }
+ SimpleTest.finish();
+ }
+}
+
+</script>
+
+<iframe id="ifr" src="file_bug650273.html" onload="done()"></iframe>
+
+</pre>
+</body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/test_bug655297-1.html b/js/xpconnect/tests/mochitest/test_bug655297-1.html
new file mode 100644
index 0000000000..38ff528c5b
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_bug655297-1.html
@@ -0,0 +1,49 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=655297
+-->
+<head>
+ <title>Test for Bug 655297</title>
+ <script 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=655297">Mozilla Bug 655297</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+ <form>0</form> <form>1</form> <form>2</form> <form>3</form> <form>4</form>
+ <form>5</form> <form>6</form> <form>7</form> <form>8</form> <form>9</form>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 655297 **/
+
+var map = new WeakMap();
+function f() {
+ var paras = document.getElementsByTagName("form");
+ for (var i = 0; i < paras.length; i++)
+ map.set(paras[i], "ok");
+}
+function g() {
+ var paras = document.getElementsByTagName("form");
+ for (var i = 0; i < paras.length; i++) {
+ if (map.get(paras[i]) != "ok") {
+ return false;
+ }
+ }
+ return true;
+}
+
+f();
+SpecialPowers.forceGC();
+ok(g(), "Failed to keep XPCWrappedNative used as WeakMap key alive.");
+
+</script>
+
+
+</pre>
+</body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/test_bug655297-2.html b/js/xpconnect/tests/mochitest/test_bug655297-2.html
new file mode 100644
index 0000000000..67da7964bd
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_bug655297-2.html
@@ -0,0 +1,49 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=655297
+-->
+<head>
+ <title>Test for Bug 655297</title>
+ <script 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=655297">Mozilla Bug 655297</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+ <p>0</p> <p>1</p> <p>2</p> <p>3</p> <p>4</p>
+ <p>5</p> <p>6</p> <p>7</p> <p>8</p> <p>9</p>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 655297 **/
+
+var map = new WeakMap();
+function f() {
+ var paras = document.getElementsByTagName("p");
+ for (var i = 0; i < paras.length; i++)
+ map.set(paras[i], "ok");
+}
+function g() {
+ var paras = document.getElementsByTagName("p");
+ for (var i = 0; i < paras.length; i++) {
+ if (map.get(paras[i]) != "ok") {
+ return false;
+ }
+ }
+ return true;
+}
+
+f();
+SpecialPowers.forceGC();
+ok(g(), "Failed to keep XPCWrappedNative used as WeakMap key alive.");
+
+</script>
+
+
+</pre>
+</body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/test_bug661980.html b/js/xpconnect/tests/mochitest/test_bug661980.html
new file mode 100644
index 0000000000..afe62559a5
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_bug661980.html
@@ -0,0 +1,61 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=661980
+-->
+<head>
+ <title>Test for Bug 661980</title>
+ <script 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=661980">Mozilla Bug 661980</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 661980 **/
+
+// While not currently needed, make this as similar as possible to a real
+// EventTarget just to make sure that we're tripping on the wrapping and
+// nothing else.
+var fakeTarget = {
+ addEventListener: function() {},
+ removeEventListener: function() {},
+ dispatchEvent: function() {}
+}
+
+var mouseevent = document.createEvent("MouseEvent");
+var didThrow = false;
+dump("hello nurse\n");
+try {
+ mouseevent.initMouseEvent("mouseover",
+ false, false,
+ window,
+ 1, 2, 3, 4, 5,
+ false, false, false, false,
+ 0,
+ fakeTarget);
+}
+catch (ex) {
+ didThrow = true;
+}
+ok(didThrow, "should not be able to implement EventTarget using script");
+
+mouseevent.initMouseEvent("mouseout",
+ false, false,
+ window,
+ 1, 2, 3, 4, 5,
+ false, false, false, false,
+ 0,
+ document.body);
+is(mouseevent.type, "mouseout",
+ "should able to implement EventTarget using Element");
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/test_bug691059.html b/js/xpconnect/tests/mochitest/test_bug691059.html
new file mode 100644
index 0000000000..b00da02b0d
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_bug691059.html
@@ -0,0 +1,59 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=691059
+-->
+<head>
+ <title>Test for Bug 691059</title>
+ <script 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=691059">Mozilla Bug 691059</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+
+/** Test for Bug 691059 **/
+
+function f() {}
+
+function testEventTarget(obj) {
+ obj.onmouseenter = f;
+ is(obj.onmouseenter, f,
+ "onmouseenter should be settable");
+ obj.onmouseleave = f;
+ is(obj.onmouseleave, f,
+ "onmouseenter should be settable");
+}
+
+function testInterface(obj) {
+ try {
+ obj.prototype.onmouseenter = f;
+ is("onmouseenter" in obj, false,
+ "setting <Interface>.prototype.onmouseenter has no effect on the " +
+ "non-existent <Interface>.onmouseenter");
+ obj.prototype.onmouseleave = f;
+ is("onmouseleave" in obj, false,
+ "setting <Interface>.prototype.onmouseleave has no effect on the " +
+ "non-existent <Interface>.onmouseleave");
+ } catch(ex) {
+ ok(false, ex);
+ }
+}
+
+testEventTarget(window);
+testEventTarget(document);
+testEventTarget(document.documentElement);
+
+testInterface(Document);
+testInterface(HTMLElement);
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/test_bug720619.html b/js/xpconnect/tests/mochitest/test_bug720619.html
new file mode 100644
index 0000000000..804ec96d75
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_bug720619.html
@@ -0,0 +1,55 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=720619
+-->
+<head>
+ <title>Test for Bug 629227</title>
+ <script 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=720619">Mozilla Bug 720619</a>
+<p id="display">
+ <iframe id="testTarget"></iframe>
+</p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 720619 **/
+SimpleTest.waitForExplicitFinish();
+
+function checkThrows(f, exception) {
+ try {
+ f();
+ ok(false, "should have thrown: " + f);
+ } catch (e) {
+ ok(exception.test(e.toString()), "correctly threw");
+ }
+}
+
+function go() {
+ var loc = $('ifr').contentWindow.location;
+ checkThrows(function() {loc + '';}, /Permission denied/);
+ checkThrows(function() {'' + loc;}, /Permission denied/);
+ checkThrows(function() {String(loc);}, /Permission denied/);
+
+ var win = $('ifr').contentWindow;
+ checkThrows(function() {win + '';}, /Permission denied/);
+ checkThrows(function() {'' + win;}, /Permission denied/);
+ checkThrows(function() {String(win);}, /Permission denied/);
+
+ SimpleTest.finish();
+}
+
+</script>
+
+<iframe id="ifr" onload="go()"
+ src="http://example.org/tests/js/xpconnect/tests/mochitest/file_bug720619.html">
+</iframe>
+</pre>
+</body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/test_bug731471.html b/js/xpconnect/tests/mochitest/test_bug731471.html
new file mode 100644
index 0000000000..e74b07734a
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_bug731471.html
@@ -0,0 +1,42 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=731471
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 731471</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body onload="setTimeout(boom, 0);">
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=731471">Mozilla Bug 731471</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 731471. This is effectively a crashtest, but it uses window.open, which
+ doesn't work in the crashtest harness. **/
+SimpleTest.waitForExplicitFinish();
+SimpleTest.requestFlakyTimeout("untriaged");
+function boom()
+{
+ w = window.open("file_bug731471.html");
+ setTimeout(function() {
+ w.document.write("2");
+ w.document.close();
+ w.document.write("3 - Done");
+ w.document.close();
+ w.close();
+ ok(true, "Didn't assert!");
+ SimpleTest.finish();
+ }, 400);
+}
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/test_bug764389.html b/js/xpconnect/tests/mochitest/test_bug764389.html
new file mode 100644
index 0000000000..6e90dd448b
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_bug764389.html
@@ -0,0 +1,40 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=764389
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 764389</title>
+ <script 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=764389">Mozilla Bug 764389</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 764389 **/
+
+// This is basically a crash test, but we need to write a mochitest so that it
+// runs with http:// urls instead of file:// urls.
+SimpleTest.waitForExplicitFinish();
+
+function go() {
+ var ifr = document.getElementById('ifr');
+ ifr.contentDocument.open();
+ ok(true, "Didn't crash");
+ ifr.contentDocument.close();
+ SimpleTest.finish();
+}
+
+
+
+</script>
+<iframe id="ifr" onload="go();" src="file_empty.html">
+</pre>
+</body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/test_bug772288.html b/js/xpconnect/tests/mochitest/test_bug772288.html
new file mode 100644
index 0000000000..5af0f7d2d6
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_bug772288.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=772288
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 772288</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body onload="doTest()">
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=772288">Mozilla Bug 772288</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 772288 **/
+SimpleTest.waitForExplicitFinish();
+
+const Cu = SpecialPowers.Cu;
+
+function doTest() {
+ msg = "AppConstants should be imported on window";
+ try {
+ Cu.import("resource://gre/modules/AppConstants.jsm", window);
+ ok(AppConstants, msg);
+ } catch (ex) {
+ ok(false, msg + " : " + ex);
+ }
+
+ msg = "AppConstants should be imported on myObj";
+ try {
+ var myObj = {};
+ Cu.import("resource://gre/modules/AppConstants.jsm", myObj);
+ ok(myObj.AppConstants, msg);
+ } catch (ex) {
+ ok(false, msg + " : " + ex);
+ }
+
+ SimpleTest.finish();
+}
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/test_bug781476.html b/js/xpconnect/tests/mochitest/test_bug781476.html
new file mode 100644
index 0000000000..f9ab40d4d9
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_bug781476.html
@@ -0,0 +1,36 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=781476
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 781476</title>
+ <script 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=781476">Mozilla Bug 781476</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 781476 **/
+SimpleTest.waitForExplicitFinish();
+
+function go() {
+ var iwin = document.getElementById('ifr').contentWindow;
+ iwin.is = is;
+ var evt = iwin.makeEvent();
+ is(evt.expando, 42, "Expando properly visible in caller frame");
+ SimpleTest.finish();
+}
+
+
+</script>
+</pre>
+<iframe onload="go();" id="ifr" src="file_bug781476.html"></iframe>
+</body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/test_bug789713.html b/js/xpconnect/tests/mochitest/test_bug789713.html
new file mode 100644
index 0000000000..251ecf22c2
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_bug789713.html
@@ -0,0 +1,39 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=789713
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 789713</title>
+ <script 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=789713">Mozilla Bug 789713</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+<iframe id="ifr"></iframe>
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 789713 **/
+
+// We can't set document.domain on mochi.test, because it's forbidden to set
+// document.domain to a TLD.
+var ifr = document.getElementById('ifr');
+
+SimpleTest.waitForExplicitFinish();
+ifr.src = window.location.toString().replace("mochi.test:8888", "test1.example.org")
+ .replace("test_bug789713", "file_bug789713")
+ .split('?')[0];
+window.onmessage = function(message) {
+ ok(message.data, "Test succeeded and didn't crash");
+ SimpleTest.finish();
+}
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/test_bug790732.html b/js/xpconnect/tests/mochitest/test_bug790732.html
new file mode 100644
index 0000000000..c702273900
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_bug790732.html
@@ -0,0 +1,55 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=790732
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 790732</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript">
+SimpleTest.waitForExplicitFinish();
+
+async function doTest() {
+ await SpecialPowers.pushPrefEnv({set: [["dom.use_components_shim", true]]})
+
+ // Basic stuff
+ ok(Components, "Components shim exists!");
+ var Ci = Components.interfaces;
+ ok(Ci, "interfaces shim exists!");
+ is(typeof Components.classes, 'undefined', "Shouldn't have a Cc");
+
+ // Check each interface that we shim. We start by checking specific
+ // constants for a couple of interfaces, and then once it's pretty clear that
+ // it's working as intended we just check that the objects themselves are the
+ // same.
+ is(Ci.nsIXMLHttpRequest.HEADERS_RECEIVED, XMLHttpRequest.HEADERS_RECEIVED);
+ is(Ci.nsIDOMNode.DOCUMENT_NODE, Node.DOCUMENT_NODE);
+ is(Ci.nsIDOMKeyEvent, KeyEvent);
+ is(Ci.nsIDOMMouseEvent, MouseEvent);
+ is(Ci.nsIDOMMouseScrollEvent, MouseScrollEvent);
+ is(Ci.nsIDOMMutationEvent, MutationEvent);
+ is(Ci.nsIDOMUIEvent, UIEvent);
+ is(Ci.nsIDOMHTMLMediaElement, HTMLMediaElement);
+ is(Ci.nsIDOMRange, Range);
+ is(Ci.nsIDOMNodeFilter, NodeFilter);
+ is(Ci.nsIDOMXPathResult, XPathResult);
+
+ SimpleTest.finish();
+}
+
+doTest();
+ </script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=790732">Mozilla Bug 790732</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+</pre>
+<iframe id="ifr"></iframe>
+</body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/test_bug793969.html b/js/xpconnect/tests/mochitest/test_bug793969.html
new file mode 100644
index 0000000000..1d06d65904
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_bug793969.html
@@ -0,0 +1,53 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=793969
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 793969</title>
+ <script 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=793969">Mozilla Bug 793969</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 793969 **/
+function checkThrows(f, desc, skipMessageCheck) {
+ try {
+ f();
+ ok(false, "Should have thrown for " + desc);
+ } catch (e) {
+ ok(true, "threw correctly");
+ if (!skipMessageCheck)
+ ok(/denied/.exec(e) ||
+ /can't redefine non-configurable property/.exec(e),
+ "Correctly threw a security exception: " + e);
+ }
+}
+
+// NB: These sets will be no-ops (throw in strict mode) because setting an inherited readonly value prop has those semantics.
+checkThrows(function() { "use strict"; location.valueOf = 'hah'; }, 'Shadow with string', /* skipMessageCheck = */ true);
+checkThrows(function() { "use strict"; location.valueOf = function() { return {a: 'hah'};} }, 'Shadow with function', /* skipMessageCheck = */ true);
+checkThrows(function() { Object.defineProperty(location, 'valueOf', { value: function() { return 'hah'; } }); }, 'defineProperty with value');
+checkThrows(function() { delete location.valueOf; Object.defineProperty(location, 'valueOf', { value: function() { return 'hah'; } }); }, 'delete + defineProperty with value');
+checkThrows(function() { Object.defineProperty(location, 'valueOf', { get: function() { return 'hah'; } }); }, 'defineProperty with getter');
+checkThrows(function() { delete location.valueOf; Object.defineProperty(location, 'valueOf', { get: function() { return 'hah'; } }); }, 'delete + defineProperty with getter');
+
+Object.prototype.valueOf = function() { return 'hah'; };
+is(({}).valueOf(), 'hah', "Shadowing on Object.prototype works for vanilla objects");
+is(location.valueOf(), location, "Shadowing on Object.prototype and Location.prototype doesn't for location objects");
+
+location[Symbol.toPrimitive] = function() { return 'hah'; }
+is(location + "", location.toString(), "Should't be able to shadow with toPrimitive");
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/test_bug800864.html b/js/xpconnect/tests/mochitest/test_bug800864.html
new file mode 100644
index 0000000000..4acee755f5
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_bug800864.html
@@ -0,0 +1,51 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=800864
+-->
+<head>
+ <title>Test for Bug 800864</title>
+ <script 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=800864">Mozilla Bug 800864</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+SimpleTest.waitForExplicitFinish();
+
+function checkThrows(f) {
+ try {
+ f();
+ ok(false, "Didn't throw a security exception like we should");
+ } catch(e) {
+ ok(/denied|insecure/.exec(e), "Should throw security exception. Got: " + e);
+ }
+}
+
+function go() {
+ ifr = document.getElementById('ifr');
+ win = ifr.contentWindow;
+ loc = win.location;
+ ifr.onload = check;
+ win.location = 'http://test1.example.com';
+}
+
+function check() {
+ checkThrows(function() { loc.toString(); });
+ checkThrows(function() { loc.valueOf().toString(); });
+ checkThrows(function() { loc.href; });
+ checkThrows(function() { loc + ''; });
+ SimpleTest.finish();
+}
+
+</script>
+</pre>
+</body>
+<iframe id="ifr" onload="go()" src="file_empty.html"></iframe>
+</html>
diff --git a/js/xpconnect/tests/mochitest/test_bug802557.html b/js/xpconnect/tests/mochitest/test_bug802557.html
new file mode 100644
index 0000000000..4479986b8e
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_bug802557.html
@@ -0,0 +1,116 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=802557
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 802557</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript">
+
+ /** Test for Bug 802557 **/
+ SimpleTest.waitForExplicitFinish();
+
+ function checkThrows(fun, desc) {
+ try {
+ fun();
+ ok(false, "Didn't throw when " + desc);
+ } catch(e) {
+ ok(true, "Threw when " + desc + " " + e);
+ ok(/denied|insecure/.exec(e), "Should be security exception");
+ }
+ }
+
+ var loadCount = 0;
+ function go() {
+ ++loadCount;
+ window.ifr = document.getElementById('ifr');
+ window.iWin = ifr.contentWindow;
+
+ if (loadCount == 1) {
+ gLoc = iWin.location;
+ // Note that accessors pulled off Xrays are currently bound. This is bug 658909.
+ // [getter, description, locationObj, bound]
+ gGetters = [[ location.toString, 'toString from LW' ],
+ [ gLoc.toString, 'toString from XLW' ],
+ [ Object.__lookupGetter__.call(location, 'href'), 'href getter from LW' ],
+ [ Object.__lookupGetter__.call(gLoc, 'href'), 'href getter from XLW' ],
+ [ Object.getOwnPropertyDescriptor(location, 'href').get, 'href getter from location' ],
+ [ Object.getOwnPropertyDescriptor(gLoc, 'href').get, 'href getter from iWin.location' ],
+ [ function() { return this + ''; }, 'implicit conversion via [[DefaultValue]]', /* doMessageCheck = */ true ]];
+ gGetters.forEach(function(item) {
+ try {
+ is(item[0].call(location), location.toString(), 'Same-origin LW: ' + item[1]);
+ is(item[0].call(gLoc), gLoc.toString(), 'Same-origin XLW: ' + item[1]);
+ } catch (e) {
+ ok(false, "Threw while applying " + item[1] + " to same-origin location object: " + e);
+ }
+ });
+ ifr.src = "http://example.org/tests/js/xpconnect/tests/mochitest/file_empty.html";
+ }
+ else if (loadCount == 2) {
+ gGetters.forEach(function(item) {
+ checkThrows(function() { item[0].call(gLoc); },
+ 'call()ing ' + item[1] + ' after navigation cross-origin');
+ });
+ ifr.src = 'http://mochi.test:8888/tests/js/xpconnect/tests/mochitest/file_bug802557.html';
+ }
+ else if (loadCount == 3) {
+ gTestFunctions = ifr.contentWindow.getAllTests();
+ var win = ifr.contentWindow;
+ for (fun in gTestFunctions)
+ is(gTestFunctions[fun](), win.location.toString(), "allowed via " + fun);
+ win.location = 'http://example.org/tests/js/xpconnect/tests/mochitest/file_bug802557.html';
+ }
+ else if (loadCount == 4) {
+ for (fun in gTestFunctions) {
+ var f = gTestFunctions[fun];
+ checkThrows(f, "calling " + fun);
+ }
+
+ // Verify that URL.prototype.toString can't be applied to Location
+ var threw = false;
+ try {
+ URL.prototype.toString.call(location);
+ } catch (e) {
+ threw = true;
+ }
+ ok(threw,
+ "Should not be able to use URL.prototype.toString on a Location instance");
+
+ // Verify that URL.prototype.href getter can't be applied to Location
+ threw = false;
+ var reachedTest = false;
+ try {
+ var get = Object.getOwnPropertyDescriptor(URL.prototype, "href").get;
+ is(typeof(get), "function", "Should have an href getter on URL.prototype");
+ var reachedTest = true;
+ get.call(location);
+ } catch (e) {
+ threw = true;
+ }
+ ok(reachedTest,
+ "Should not be able to find URL.prototype.href getter");
+ ok(threw,
+ "Should not be able to use URL.prototype.href getter on a Location instance");
+ SimpleTest.finish();
+ }
+ }
+
+
+
+</script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=802557">Mozilla Bug 802557</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<iframe id="ifr" onload="go();" src="file_empty.html"></iframe>
+<pre id="test">
+</pre>
+</body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/test_bug803730.html b/js/xpconnect/tests/mochitest/test_bug803730.html
new file mode 100644
index 0000000000..88df8d5477
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_bug803730.html
@@ -0,0 +1,41 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=803730
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 803730</title>
+ <script 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=803730">Mozilla Bug 803730</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 803730 **/
+var foo = {
+ isNode: function(obj) {
+ return !!(obj instanceof Node);
+ }
+};
+
+var elem = document.createElement("span");
+var trueCount = 0,
+ falseCount = 0;
+for (var x = 0; x < 100000; x++) {
+ if (foo.isNode(elem))
+ trueCount++;
+ else
+ falseCount++;
+}
+is(falseCount, 0, "elem instanceof Node working correctly.");
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/test_bug809547.html b/js/xpconnect/tests/mochitest/test_bug809547.html
new file mode 100644
index 0000000000..17808867d6
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_bug809547.html
@@ -0,0 +1,42 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=809547
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 809547</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body onload="go()">
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=809547">Mozilla Bug 809547</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 809547 **/
+SimpleTest.waitForExplicitFinish();
+var gObj = {};
+function go() {
+ window.location.expando = gObj;
+ is(window.location.expando, gObj, "Expando appears");
+ SimpleTest.executeSoon(finish);
+}
+
+function finish() {
+ SpecialPowers.forceGC();
+ SpecialPowers.forceCC();
+ SpecialPowers.forceGC();
+ SpecialPowers.forceCC();
+ is(window.location.expando, gObj, "Expando preserved");
+ SimpleTest.finish();
+}
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/test_bug829872.html b/js/xpconnect/tests/mochitest/test_bug829872.html
new file mode 100644
index 0000000000..07e2a4ca77
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_bug829872.html
@@ -0,0 +1,52 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=829872
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 829872</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript">
+
+ /** Test for Bug 829872 and Bug 968003 **/
+ SimpleTest.waitForExplicitFinish();
+
+ var gLoadCount = 0;
+ function loaded() {
+ if (++gLoadCount == 3)
+ go();
+ }
+
+ async function check(elem, desc) {
+ is(elem.contentDocument, null, "null cross-origin contentDocument for " + desc);
+ ok(await SpecialPowers.spawn(elem, [], () => this.content.eval('frameElement === null;')),
+ "null cross-origin frameElement for " + desc);
+ if (!(elem instanceof elem.ownerDocument.defaultView.HTMLFrameElement))
+ is(elem.getSVGDocument(), null, "null cross-origin getSVGDocument() for " + desc);
+ }
+
+ async function go() {
+ ok(true, "Starting test");
+ await check($('ifr'), "iframe element");
+ await check($('obj'), "object element");
+ await check($('framesetholder').contentDocument.getElementById('fr'), "frameset frame");
+ SimpleTest.finish();
+ }
+
+ </script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=829872">Mozilla Bug 829872</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+</pre>
+<iframe id="ifr" onload="loaded();" src="http://example.org/tests/js/xpconnect/tests/mochitest/file_empty.html"></iframe>
+<object id="obj" onload="loaded();" data="http://example.org/tests/js/xpconnect/tests/mochitest/file_empty.html"></object>
+<iframe id="framesetholder" srcdoc="<html><head></head><frameset cols='100%'><frame id='fr' onload='parent.loaded();' src='http://example.org/tests/js/xpconnect/tests/mochitest/file_empty.html' /></frameset></html>"></iframe>
+</body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/test_bug862380.html b/js/xpconnect/tests/mochitest/test_bug862380.html
new file mode 100644
index 0000000000..d604e3d05f
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_bug862380.html
@@ -0,0 +1,54 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=862380
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 862380</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript">
+
+ /** Test for Bug 862380 **/
+ SimpleTest.waitForExplicitFinish();
+ function go() {
+ checkNotEnumerable($('ifr').contentWindow, true);
+ checkNotEnumerable($('ifr').contentWindow.location, false);
+ SimpleTest.finish();
+ }
+
+function checkNotEnumerable(obj, isWindow) {
+ try {
+ const expectedWindow = ["0"];
+ const expectedLocation = [];
+ const expected = isWindow ? expectedWindow : expectedLocation;
+ is(Object.keys(obj).length, expected.length,
+ "Object.keys gives right array length");
+ var actual = [];
+ for (var i in obj)
+ actual.push(i);
+ is(actual.length, expected.length,
+ "Enumeration sees the right number of props");
+ actual.sort();
+ expected.sort();
+ for (var i = 0; i < actual.length; ++i)
+ is(actual[i], expected[i], "Arrays should be the same " + i);
+ } catch (e) {
+ ok(false, "threw: " + e);
+ }
+ }
+
+ </script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=862380">Mozilla Bug 862380</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<iframe id="ifr" onload="go();" src="http://example.org/tests/js/xpconnect/tests/mochitest/file_empty.html"></iframe>
+<pre id="test">
+</pre>
+</body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/test_bug865260.html b/js/xpconnect/tests/mochitest/test_bug865260.html
new file mode 100644
index 0000000000..b09b488dcd
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_bug865260.html
@@ -0,0 +1,33 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=865260
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 865260</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript">
+
+ /** Test for Bug 865260 **/
+ SimpleTest.waitForExplicitFinish();
+ function go() {
+ var exn = "nothrow";
+ try { $('ifr').contentWindow['Date']; } catch (e) { exn = e; };
+ ok(!!/denied/.exec(exn), "Threw instead of crashing");
+ SimpleTest.finish();
+ }
+
+ </script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=865260">Mozilla Bug 865260</a>
+<p id="display"></p>
+<div id="content">
+<iframe id="ifr" onload="go();" src="http://example.org/tests/js/xpconnect/tests/mochitest/file_empty.html"></iframe>
+</div>
+<pre id="test">
+</pre>
+</body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/test_bug871887.html b/js/xpconnect/tests/mochitest/test_bug871887.html
new file mode 100644
index 0000000000..082b2ae746
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_bug871887.html
@@ -0,0 +1,43 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=871887
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 871887</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript">
+
+ /** Test for Bug 871887 **/
+ SimpleTest.waitForExplicitFinish();
+
+ // NB: onstart ends up getting invoked twice, for mysterious and potentially-
+ // IE6-related reasons.
+ function checkpoint(invocant) {
+ ok(true, "onstart called");
+ is(invocant, $('llama'), "this-binding is correct");
+ $('llama').loop = 1;
+ $('llama').scrollDelay = 1;
+ $('llama').scrollAmount = 500;
+ }
+
+ function done(invocant) {
+ is(invocant, $('llama'), "this-binding is correct");
+ ok(true, "onfinish called");
+ SimpleTest.finish();
+ }
+
+ </script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=871887">Mozilla Bug 871887</a>
+<p id="display"></p>
+<div id="content">
+<marquee id="llama" onstart="checkpoint(this);" onfinish="done(this);">Watch the Llama</marquee>
+</div>
+<pre id="test">
+</pre>
+</body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/test_bug912322.html b/js/xpconnect/tests/mochitest/test_bug912322.html
new file mode 100644
index 0000000000..84ec5f7bbc
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_bug912322.html
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=912322
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 912322</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript">
+
+ var { AppConstants } = SpecialPowers.ChromeUtils.importESModule(
+ "resource://gre/modules/AppConstants.sys.mjs"
+ );
+ // Test window.controllers.
+ if (AppConstants.RELEASE_OR_BETA) {
+ is(typeof window.controllers, 'object', "shimmed controllers should be available to content in beta and release");
+ } else {
+ is(typeof window.controllers, 'undefined', "controllers should not be available to content in Nightly");
+ }
+ is(typeof SpecialPowers.wrap(window).controllers, 'object', "controllers should be available over Xray");
+
+ </script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=912322">Mozilla Bug 912322</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+</pre>
+</body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/test_bug916945.html b/js/xpconnect/tests/mochitest/test_bug916945.html
new file mode 100644
index 0000000000..01c342eea1
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_bug916945.html
@@ -0,0 +1,78 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=916945
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 916945</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript">
+
+ /** Test for Bug 916945 **/
+ SimpleTest.waitForExplicitFinish();
+
+ var gLoadCount = 0;
+ function loaded() {
+ if (++gLoadCount == 2)
+ go();
+ }
+ async function go() {
+ // Both same-origin and cross-origin names should be visible if they're set
+ // on the iframe element.
+ ok('winA' in window, "same-origin named access works");
+ ok(winA instanceof winA.Window, "same-origin named access works");
+ ok('winB' in window, "cross-origin named access works when iframe name matches");
+ is(winB.parent, window, "cross-origin named access works when iframe name matches");
+
+ // Setting the 'name' attribute should propagate to the docshell.
+ var ifrB = document.getElementById('ifrB');
+ await SpecialPowers.spawn(ifrB, [], () => {
+ Assert.equal(this.content.name, 'winB',
+ 'initial attribute value propagates to the docshell');
+ });
+
+ ifrB.setAttribute('name', 'foo');
+ await SpecialPowers.spawn(ifrB, [], () => {
+ Assert.equal(this.content.name, 'foo',
+ 'attribute sets propagate to the docshell');
+ });
+ ok('foo' in window, "names are dynamic if updated via setAttribute");
+ is(foo.parent, window, "names are dynamic if updated via setAttribute");
+
+ // Setting window.name on the subframe should not propagate to the attribute.
+ await SpecialPowers.spawn(ifrB, [], () => {
+ this.content.name = "bar";
+ });
+ is(ifrB.getAttribute('name'), 'foo', 'docshell updates dont propagate to the attribute');
+
+ // When the frame element attribute and docshell name don't match, nothing is returned.
+ ok(!('foo' in window), "frame element name not resolved if it doesn't match the docshell");
+ ok(!('bar' in window), "docshell name not resolved if it doesn't match the frame element");
+
+ // This shouldn't assert.
+ function listener() {
+ document.body.appendChild(ifrA);
+ ifrA.name = "";
+ }
+ ifrA.addEventListener("DOMNodeInserted", listener, {once: true});
+ document.body.appendChild(ifrA);
+
+ SimpleTest.finish();
+ }
+
+ </script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=916945">Mozilla Bug 916945</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<iframe id="ifrA" name="winA" onload="loaded();" src="file_empty.html"></iframe>
+<iframe id="ifrB" name="winB" onload="loaded();" src="http://example.org/tests/js/xpconnect/tests/mochitest/file_empty.html"></iframe>
+<pre id="test">
+</pre>
+</body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/test_bug92773.html b/js/xpconnect/tests/mochitest/test_bug92773.html
new file mode 100644
index 0000000000..b1172f377e
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_bug92773.html
@@ -0,0 +1,43 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=92773
+-->
+<head>
+ <title>Test for Bug 92773</title>
+ <script 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=92773">Mozilla Bug 92773</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 92773 **/
+function go() {
+ try {
+ $('ifr').contentWindow.foo;
+ ok(false, "able to access cross-origin getter");
+ } catch (e) {
+ ok(/Permission denied/.exec(e), "unable to access cross-origin getter");
+ }
+
+ SimpleTest.finish();
+}
+SimpleTest.waitForExplicitFinish();
+
+</script>
+</pre>
+
+<iframe id='ifr'
+ src='http://example.com/tests/js/xpconnect/tests/mochitest/bug92773_helper.html'
+ onload="go()">
+</iframe>
+
+</body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/test_bug940783.html b/js/xpconnect/tests/mochitest/test_bug940783.html
new file mode 100644
index 0000000000..0c87e710c1
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_bug940783.html
@@ -0,0 +1,62 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=940783
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 940783</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript">
+
+ /** Test for Bug 940783 **/
+ SimpleTest.waitForExplicitFinish();
+
+ function checkHistoryThrows(hist) {
+ checkThrows(function() { hist.length; });
+ checkThrows(function() { hist.state; });
+ checkThrows(function() { hist.go(); });
+ checkThrows(function() { hist.back(); });
+ checkThrows(function() { hist.forward(); });
+ checkThrows(function() { hist.pushState({}, "foo"); });
+ checkThrows(function() { hist.replaceState({}, "foo"); });
+
+ }
+
+ window.gLoads = 0;
+ function load() {
+ var iwin = $('ifr').contentWindow;
+ ++gLoads;
+ if (gLoads == 1) {
+ window.gHist = iwin.history;
+ iwin.location = "file_empty.html";
+ } else if (gLoads == 2) {
+ checkHistoryThrows(gHist);
+ window.gHist = iwin.history;
+ iwin.location = "http://example.org/tests/js/xpconnect/tests/mochitest/file_empty.html";
+ } else {
+ checkHistoryThrows(gHist);
+ $('ifr').setAttribute('onload', null);
+ SimpleTest.finish();
+ }
+ }
+
+ function checkThrows(fn) {
+ try { fn(); ok(false, "Should have thrown: " + fn.toSource()); }
+ catch (e) { ok(!!/denied|insecure/.exec(e), "Threw correctly: " + e); }
+ }
+
+ </script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=940783">Mozilla Bug 940783</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+<iframe id="ifr" onload="load();" src="file_empty.html"></iframe>
+
+</div>
+<pre id="test">
+</pre>
+</body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/test_bug960820.html b/js/xpconnect/tests/mochitest/test_bug960820.html
new file mode 100644
index 0000000000..7667fde624
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_bug960820.html
@@ -0,0 +1,56 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=960820
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 960820</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript">
+
+ /** Test for exception stacks crossing **/
+
+ // Synchronous event dispatch creates a new script entry point. At the time
+ // of this writing, an event listener defined in a Sandbox will cause the
+ // SafeJSContext to be pushed to the cx stack, which differs from the JSContext
+ // associated with this DOM window. So we test both kinds of boundaries.
+ var sb = new SpecialPowers.Cu.Sandbox(SpecialPowers.Services.scriptSecurityManager.getSystemPrincipal());
+ sb.win = window;
+ SpecialPowers.Cu.evalInSandbox("win.document.addEventListener('click', " +
+ "function clickHandler() { win.wrappedJSObject.clickCallback(); });", sb);
+ function clickCallback() {
+ var stack = (new Error()).stack;
+ ok(true, "Invoked clickCallback. Stack: " + stack);
+ ok(/clickCallback/.test(stack), "clickCallback should be in the stack");
+ ok(!/clickHandler/.test(stack), "clickHandler should not be in the stack");
+ ok(/dispatchClick/.test(stack), "dispatchClick should be in the stack");
+
+ // Check Components.stack, but first filter through the SpecialPowers junk.
+ var stack = SpecialPowers.wrap(SpecialPowers.Components).stack;
+ while (/testing-common/.test(stack)) {
+ stack = stack.caller;
+ }
+ ok(/clickCallback/.test(stack), "clickCallback should be reachable via Components.stack");
+ ok(/clickHandler/.test(stack.caller), "clickHandler should be reachable via Components.stack");
+ ok(/dispatchClick/.test(stack.caller.caller), "dispatchClick hould be reachable via Components.stack");
+ }
+ function dispatchClick() {
+ document.dispatchEvent(new MouseEvent('click'));
+ }
+ dispatchClick();
+
+
+ </script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=960820">Mozilla Bug 960820</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+</pre>
+</body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/test_bug965082.html b/js/xpconnect/tests/mochitest/test_bug965082.html
new file mode 100644
index 0000000000..b2320b52c7
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_bug965082.html
@@ -0,0 +1,39 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=965082
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 965082</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript">
+
+ /** Test for Bug 965082 **/
+ SimpleTest.waitForExplicitFinish();
+
+ function checkThrows(f, msg) {
+ try { f(); ok(false, "Should have thrown: " + msg); }
+ catch (e) { ok(/denied|insecure|can't set prototype/.test(e), "Should throw security exception: " + e + " (" + msg + ")"); }
+ }
+
+ function go() {
+ var protoSetter = Object.getOwnPropertyDescriptor(Object.prototype, '__proto__').set;
+ checkThrows(function() { protoSetter.call(window[0], new Object()); }, "Setting cross-origin Window prototype");
+ checkThrows(function() { protoSetter.call(window[0].location, new Object()); }, "Setting cross-origin Location prototype");
+ SimpleTest.finish();
+ }
+
+ </script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=965082">Mozilla Bug 965082</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+</div>
+<iframe id="ifr" onload="go();" src="http://example.org/tests/js/xpconnect/tests/mochitest/file_empty.html"></iframe>
+<pre id="test">
+</pre>
+</body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/test_bug993423.html b/js/xpconnect/tests/mochitest/test_bug993423.html
new file mode 100644
index 0000000000..dbe4cef3cc
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_bug993423.html
@@ -0,0 +1,47 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=993423
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 993423</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript">
+
+ /** Test for Bug 993423 **/
+ SimpleTest.waitForExplicitFinish();
+
+ var sCallbackInvocations = 0;
+ function callback(handlerIsInXBLScope) {
+ ok(!handlerIsInXBLScope, "Event handler should not be in XBL scope");
+ if (++sCallbackInvocations == 2)
+ SimpleTest.finish();
+ }
+
+ function go() {
+ document.querySelector('use').setAttributeNS('http://www.w3.org/1999/xlink',
+ 'href', location.href + '#a');
+ }
+
+ </script>
+</head>
+<body onload="go()";>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=993423">Mozilla Bug 993423</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+</pre>
+<svg>
+ <symbol id="a">
+ <foreignObject>
+ <img src="about:logo" onload="var isInXBL = (function() { return this; })() != window; if (isInXBL) callback = window.wrappedJSObject.callback; callback(isInXBL);">
+ </foreignObject>
+ </symbol>
+ <use />
+</svg>
+</body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/test_class_static_block_worker.html b/js/xpconnect/tests/mochitest/test_class_static_block_worker.html
new file mode 100644
index 0000000000..e3ce063fe9
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_class_static_block_worker.html
@@ -0,0 +1,32 @@
+<!DOCTYPE HTML>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>Test class static fields</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript">
+ // Make sure static classes parse in regular context too:
+ class B {
+ static { this.x = 12; }
+ }
+ is(B.x, 12, "static block set class value");
+ console.log("script");
+ function go() {
+ SimpleTest.waitForExplicitFinish();
+
+ let worker = new Worker('class_static_worker.js');
+
+ console.log("message")
+ worker.onmessage = function(e) {
+
+ is(e.data, 12, "correctly allocated class-static containing-class in worker");
+ SimpleTest.finish();
+ }
+ worker.postMessage("get");
+ info("Messages posted");
+ }
+ go();
+ </script>
+ </head>
+
+</html> \ No newline at end of file
diff --git a/js/xpconnect/tests/mochitest/test_crosscompartment_weakmap.html b/js/xpconnect/tests/mochitest/test_crosscompartment_weakmap.html
new file mode 100644
index 0000000000..d7d364fdeb
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_crosscompartment_weakmap.html
@@ -0,0 +1,36 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Test Cross-Compartment DOM WeakMaps</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<p id="display"></p>
+<script type="application/javascript">
+
+var my_map = new WeakMap();
+
+function setup() {
+ var item = window.frames[0].document.querySelector("body");
+
+ my_map.set(item, "success_string");
+}
+
+function runTest() {
+ setup();
+ SpecialPowers.forceGC();
+ SpecialPowers.forceCC();
+ SpecialPowers.forceGC();
+ SpecialPowers.forceCC();
+ var item = window.frames[0].document.querySelector("body");
+ is(my_map.get(item), "success_string", "Preserve reflectors used cross-compartment as weak map keys.");
+}
+
+</script>
+<iframe src="file_crosscompartment_weakmap.html" onload="runTest()"></iframe>
+
+
+</pre>
+</body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/test_enable_privilege.html b/js/xpconnect/tests/mochitest/test_enable_privilege.html
new file mode 100644
index 0000000000..03043e9ce6
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_enable_privilege.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html lang="en" dir="ltr">
+ <head>
+ <title>Test page for enablePrivilege</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script>
+ function init() {
+ var result = document.getElementById("result");
+ try {
+ /* globals netscape */
+ netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
+ result.textContent = "FAIL";
+ } catch (ex) {
+ result.textContent = "PASS";
+ }
+ }
+ </script>
+ </head>
+ <body>
+ <p id="result"></p>
+ <script>
+ init();
+ is(result.textContent, "PASS", "enablePrivilege should be unavaillable");
+ </script>
+ </body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/test_finalizationRegistry.html b/js/xpconnect/tests/mochitest/test_finalizationRegistry.html
new file mode 100644
index 0000000000..9d9a798cdf
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_finalizationRegistry.html
@@ -0,0 +1,168 @@
+<!DOCTYPE HTML>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>Test FinalizationRegistry works in the browser</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript">
+ let registry1, holdings1;
+ let registry2, holdings2;
+ let registry3, holdings3;
+ let registry4, holdings4;
+ let registry5, holdings5;
+ let registry6, holdings6;
+ let registry7, holdings7;
+ let registry8, holdings8;
+ let registry9, holdings9;
+
+ let object4 = {};
+
+ function go() {
+ SimpleTest.waitForExplicitFinish();
+
+ // Registry with no registered objects.
+ holdings1 = [];
+ registry1 = new FinalizationRegistry(v => { holdings1.push(v); });
+
+ // Registry with three registered objects.
+ holdings2 = [];
+ registry2 = new FinalizationRegistry(v => { holdings2.push(v); });
+ registry2.register({}, 1);
+ registry2.register({}, 2);
+ registry2.register({}, 3);
+
+ // Registry with registered object that is then unregistered.
+ holdings3 = [];
+ registry3 = new FinalizationRegistry(v => { holdings3.push(v); });
+ let token3 = {}
+ registry3.register({}, 1, token3);
+ registry3.unregister(token3);
+
+ // Registry with registered object that doesn't die.
+ holdings4 = [];
+ registry4 = new FinalizationRegistry(v => { holdings4.push(v); });
+ registry4.register(object4, 1);
+
+ // Registry observing cyclic JS data structure.
+ holdings5 = [];
+ registry5 = new FinalizationRegistry(v => { holdings5.push(v); });
+ registry5.register(makeJSCycle(4), 5);
+
+ // Registry observing DOM object without preserved wrappers.
+ holdings6 = [];
+ registry6 = new FinalizationRegistry(v => { holdings6.push(v); });
+ registry6.register(document.createElement("div"), 6);
+
+ // Registry observing DOM object with preserved wrappers.
+ holdings7 = [];
+ registry7 = new FinalizationRegistry(v => { holdings7.push(v); });
+ let object = document.createElement("div");
+ object.someProperty = true;
+ registry7.register(object, 7);
+ object = null;
+
+ // Registry observing reachable DOM object without preserved wrappers.
+ holdings8 = [];
+ registry8 = new FinalizationRegistry(v => { holdings8.push(v); });
+ document.body.appendChild(document.createElement("div"));
+ registry8.register(document.body.lastChild, 8);
+
+ // Registry observing cyclic DOM/JS data structure.
+ holdings9 = [];
+ registry9 = new FinalizationRegistry(v => { holdings9.push(v); });
+ registry9.register(makeDOMCycle(4), 9);
+
+ // Need to run full GC/CC/GC cycle to collect cyclic garbage through DOM
+ // and JS heaps.
+ SpecialPowers.DOMWindowUtils.garbageCollect();
+ SpecialPowers.DOMWindowUtils.cycleCollect();
+ SpecialPowers.DOMWindowUtils.garbageCollect();
+
+ // Microtasks are run before cleanup callbacks.
+ Promise.resolve().then(() => {
+ is(holdings1.length, 0);
+ is(holdings2.length, 0);
+ is(holdings3.length, 0);
+ is(holdings4.length, 0);
+ is(holdings5.length, 0);
+ is(holdings6.length, 0);
+ is(holdings7.length, 0);
+ is(holdings8.length, 0);
+ is(holdings9.length, 0);
+ });
+
+ // setTimeout queues a task which will run after cleanup callbacks.
+ setTimeout(task2, 0);
+ }
+
+ function task2() {
+ is(holdings1.length, 0);
+
+ let result = holdings2.sort((a, b) => a - b);
+ is(result.length, 3);
+ is(result[0], 1);
+ is(result[1], 2);
+ is(result[2], 3);
+
+ is(holdings3.length, 0);
+ is(holdings4.length, 0);
+
+ is(holdings5.length, 1);
+ is(holdings5[0], 5);
+
+ is(holdings6.length, 1);
+ is(holdings6[0], 6);
+
+ is(holdings7.length, 1);
+ is(holdings7[0], 7);
+
+ is(holdings8.length, 0);
+
+ is(holdings9.length, 1);
+ is(holdings9[0], 9);
+
+ document.body.removeChild(document.body.lastChild);
+
+ SpecialPowers.DOMWindowUtils.garbageCollect();
+ SpecialPowers.DOMWindowUtils.cycleCollect();
+ SpecialPowers.DOMWindowUtils.garbageCollect();
+
+ setTimeout(task3, 0);
+ }
+
+ function task3() {
+ is(holdings8.length, 1);
+ is(holdings8[0], 8);
+
+ SimpleTest.finish();
+ }
+
+ function makeJSCycle(size) {
+ let first = {};
+ let current = first;
+ for (let i = 0; i < size; i++) {
+ current.next = {};
+ current = current.next;
+ }
+ current.next = first;
+ return first;
+ }
+
+ function makeDOMCycle(size) {
+ let first = {};
+ let current = first;
+ for (let i = 0; i < size; i++) {
+ if (i % 2 === 0) {
+ current.next = document.createElement("div");
+ } else {
+ current.next = {};
+ }
+ current = current.next;
+ }
+ current.next = first;
+ return first;
+ }
+ </script>
+ </head>
+ <body onload="go()"></body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/test_finalizationRegistryInWorker.html b/js/xpconnect/tests/mochitest/test_finalizationRegistryInWorker.html
new file mode 100644
index 0000000000..8393781ce1
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_finalizationRegistryInWorker.html
@@ -0,0 +1,40 @@
+<!DOCTYPE HTML>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>Test FinalizationRegistry works in workers</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript">
+ function go() {
+ SimpleTest.waitForExplicitFinish();
+
+ let worker = new Worker('finalizationRegistry_worker.js');
+
+ worker.onevent = (event) => {
+ console.log(event.message);
+ throw event.error;
+ };
+
+ worker.onmessage = (event) => {
+ switch (event.data) {
+ case 'started':
+ worker.postMessage('checkResults');
+ break;
+
+ case 'passed':
+ ok(true, "Tests passed");
+ SimpleTest.finish();
+ break;
+
+ default:
+ console.log(event.data);
+ break;
+ }
+ };
+
+ worker.postMessage('startTest');
+ }
+ </script>
+ </head>
+ <body onload="go()"></body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/test_finalizationRegistry_cleanupSome.html b/js/xpconnect/tests/mochitest/test_finalizationRegistry_cleanupSome.html
new file mode 100644
index 0000000000..d70cfa7172
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_finalizationRegistry_cleanupSome.html
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>Test FinalizationRegistry cleanupSome method is not exposed by default</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript">
+ let registry = new FinalizationRegistry(x => 1);
+ is(registry.cleanupSome, undefined,
+ "The cleanupSome method should not be exposed by default");
+ </script>
+ </head>
+</html>
diff --git a/js/xpconnect/tests/mochitest/test_finalizationRegistry_incumbent.html b/js/xpconnect/tests/mochitest/test_finalizationRegistry_incumbent.html
new file mode 100644
index 0000000000..8b6c71c9cf
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_finalizationRegistry_incumbent.html
@@ -0,0 +1,62 @@
+<!DOCTYPE HTML>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>Test FinalizationRegistry tracks its incumbent global</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript">
+ let resolvePromise, rejectPromise;
+
+ async function runTest(global, callback) {
+ let fr = new global.FinalizationRegistry(callback);
+ fr.register({}, undefined);
+
+ SpecialPowers.DOMWindowUtils.garbageCollect();
+
+ let promise = new Promise((resolve, reject) => {
+ resolvePromise = resolve;
+ rejectPromise = reject;
+ });
+
+ return promise;
+ }
+
+ function receiveMessage(event) {
+ resolvePromise(event.source.sourceName);
+ }
+
+ async function go() {
+ // This test uses FinalizationRegistry to trigger a callback and reports
+ // the incumbent global in the callback using postMessage. In all cases
+ // the author function that scheduled the callback is runTest(), so the
+ // incumbent global should be the main window.
+
+ SimpleTest.waitForExplicitFinish();
+
+ window.sourceName = "main";
+ window.addEventListener("message", receiveMessage, false);
+
+ let other = window.frames[0];
+ other.sourceName = "other";
+ other.addEventListener("message", receiveMessage, false);
+
+ is(await runTest(window, v => window.postMessage(v)), "main");
+ is(await runTest(window, window.postMessage.bind(window)), "main");
+ is(await runTest(other, v => other.postMessage(v)), "main");
+ is(await runTest(other, other.postMessage.bind(other)), "main");
+ is(await runTest(window, v => other.postMessage(v)), "main");
+ is(await runTest(window, other.postMessage.bind(other)), "main");
+ is(await runTest(other, v => window.postMessage(v)), "main");
+ is(await runTest(other, window.postMessage.bind(window)), "main");
+
+ SimpleTest.finish();
+ }
+ </script>
+ </head>
+ <body onload="go()">
+ <div style="display: none">
+ <!-- A subframe so we have another global to work with -->
+ <iframe></iframe>
+ </div>
+ </body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/test_frameWrapping.html b/js/xpconnect/tests/mochitest/test_frameWrapping.html
new file mode 100644
index 0000000000..4c8a6c428c
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_frameWrapping.html
@@ -0,0 +1,37 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+No bug.
+-->
+<head>
+ <title>Test for Bug </title>
+ <script 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=">Mozilla Bug </a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** No bug for this test **/
+
+function go() {
+ var win = frames[0];
+ (function() {
+ var utils = SpecialPowers.getDOMWindowUtils(window);
+ is(utils.getClassName(win), "Proxy", "correctly wrap frame elements");
+ })()
+ SimpleTest.finish();
+}
+
+SimpleTest.waitForExplicitFinish();
+
+</script>
+</pre>
+<iframe id="ifr" src="inner.html" onload="go()"></iframe>
+</body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/test_getWebIDLCaller.html b/js/xpconnect/tests/mochitest/test_getWebIDLCaller.html
new file mode 100644
index 0000000000..22a4ae1c3b
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_getWebIDLCaller.html
@@ -0,0 +1,49 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=968335
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 968335</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript">
+
+ /** Test for Cu.getCallerPrincipal (within JS-implemented WebIDL). **/
+
+ SimpleTest.waitForExplicitFinish();
+ SpecialPowers.pushPrefEnv({set: [['dom.expose_test_interfaces', true]]}, go);
+
+
+ function go() {
+ var t = new TestInterfaceJS();
+ is(t.getCallerPrincipal(), location.origin,
+ "Cu.getCallerPrincipal works right within JS-implemented WebIDL");
+
+ try {
+ SpecialPowers.Cu.getWebIDLCallerPrincipal();
+ ok(false, "Should have thrown");
+ } catch (e) {
+ ok(/NOT_AVAILABLE/.test(SpecialPowers.wrap(e)),
+ "API should throw when invoked outside of JS-implemented WebIDL");
+ }
+
+ SimpleTest.finish();
+ }
+
+
+
+
+ </script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=968335">Mozilla Bug 968335</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+</pre>
+</body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/test_getweakmapkeys.html b/js/xpconnect/tests/mochitest/test_getweakmapkeys.html
new file mode 100644
index 0000000000..7942d9b945
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_getweakmapkeys.html
@@ -0,0 +1,59 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=688277
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Tests for nondeterministicGetWeakMapKeys</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript">
+ /** Test for Bug 688277 **/
+
+ /* Fail gracefully if junk is passed in. */
+ is(SpecialPowers.nondeterministicGetWeakMapKeys(11), undefined,
+ "nondeterministicGetWeakMapKeys should return undefined for non-objects");
+ is(SpecialPowers.nondeterministicGetWeakMapKeys({}), undefined,
+ "nondeterministicGetWeakMapKeys should return undefined for non-weakmap objects");
+ is(SpecialPowers.nondeterministicGetWeakMapKeys(null), undefined,
+ "nondeterministicGetWeakMapKeys should return undefined for null");
+
+ /* return an empty array for an empty WeakMap */
+ let mempty = new WeakMap();
+ is(SpecialPowers.nondeterministicGetWeakMapKeys(mempty).length, 0,
+ "nondeterministicGetWeakMapKeys should return empty array for empty weakmap");
+
+ /* Test freeing/nonfreeing. */
+ let m = new WeakMap();
+ let liveKeys = new Array();
+
+ let add_elements = function () {
+ let k1 = {};
+ m.set(k1, "live1");
+ liveKeys.push(k1);
+
+ let k2 = {};
+ m.set(k2, "dead1");
+
+ let k = {};
+ m.set(k, k); /* simple cycle */
+ };
+
+ add_elements();
+
+ SpecialPowers.exactGC(function () {
+ let keys = SpecialPowers.nondeterministicGetWeakMapKeys(m);
+ is(liveKeys.length, 1, "Wrong number of live keys.");
+ is(keys.length, 1, "Should have one weak map key.");
+ is(m.get(keys[0]), "live1", "live1 should be live");
+ SimpleTest.finish();
+ });
+
+ SimpleTest.waitForExplicitFinish();
+ </script>
+</head>
+<body>
+<p id="display"></p>
+</body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/test_isRemoteProxy.html b/js/xpconnect/tests/mochitest/test_isRemoteProxy.html
new file mode 100644
index 0000000000..864407af9d
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_isRemoteProxy.html
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>Tests for Cu.isRemoteProxy</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<script>
+
+async function addFrame(url) {
+ let frame = document.createElement("iframe");
+ frame.src = url;
+ document.body.appendChild(frame);
+
+ await new Promise(resolve => {
+ frame.addEventListener("load", resolve, { once: true });
+ });
+
+ return frame;
+}
+
+add_task(async function() {
+ const { Cu } = SpecialPowers;
+
+ let localFrame = await addFrame("file_empty.html");
+ let remoteFrame = await addFrame(
+ SimpleTest.getTestFileURL("file_empty.html")
+ .replace("mochi.test:8888", "example.com"));
+
+ ok(frames[0] === localFrame.contentWindow, "frames[0] is localFrame");
+ ok(frames[1] === remoteFrame.contentWindow, "frames[1] is remoteFrame");
+
+ ok(!Cu.isRemoteProxy(window), "window is not a remote proxy");
+ ok(!Cu.isRemoteProxy(location), "location is not a remote proxy");
+
+ ok(!Cu.isRemoteProxy(frames[0]), "frames[0] is not a remote proxy");
+ ok(
+ !Cu.isRemoteProxy(frames[0].location),
+ "frames[0].location is not a remote proxy"
+ );
+
+ // The processes will be remote only with isolateEverything strategy
+ const expected = SpecialPowers.effectiveIsolationStrategy() == SpecialPowers.ISOLATION_STRATEGY.IsolateEverything;
+
+ is(Cu.isRemoteProxy(frames[1]), expected,
+ "frames[1] is a remote proxy if Fission is enabled and strategy is isolateEverything");
+ is(Cu.isRemoteProxy(frames[1].location), expected,
+ "frames[1].location is a remote proxy if Fission is enabled and strategy is isolateEverything");
+});
+
+</script>
+</body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/test_nukeContentWindow.html b/js/xpconnect/tests/mochitest/test_nukeContentWindow.html
new file mode 100644
index 0000000000..0db8749b59
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_nukeContentWindow.html
@@ -0,0 +1,75 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1322273
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1322273</title>
+ <script 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=1322273">Mozilla Bug 1322273</a>
+
+<iframe id="subframe"></iframe>
+
+<script type="application/javascript">
+"use strict";
+
+function waitForWindowDestroyed(winID, callback) {
+ let observer = {
+ observe: function(subject, topic, data) {
+ let id = subject.QueryInterface(SpecialPowers.Ci.nsISupportsPRUint64).data;
+ if (id != winID) {
+ return;
+ }
+ SpecialPowers.removeObserver(observer, "outer-window-nuked");
+ SpecialPowers.executeSoon(callback);
+ }
+ };
+ SpecialPowers.addObserver(observer, "outer-window-nuked");
+}
+
+add_task(async function() {
+ let frame = $('subframe');
+ frame.srcdoc = "foo";
+ await new Promise(resolve => frame.addEventListener("load", resolve, {once: true}));
+
+ let win = frame.contentWindow;
+ let winID = SpecialPowers.wrap(win).docShell.outerWindowID;
+
+ win.eval("obj = {}");
+ win.obj.foo = {bar: "baz"};
+
+ let obj = win.obj;
+
+ let system = SpecialPowers.Services.scriptSecurityManager.getSystemPrincipal()
+ let sandbox = SpecialPowers.Cu.Sandbox(system);
+
+ sandbox.obj = obj;
+
+ let isWrapperDead = SpecialPowers.Cu.evalInSandbox(`(${
+ function isWrapperDead() {
+ return Cu.isDeadWrapper(obj);
+ }
+ })`,
+ sandbox);
+
+ is(isWrapperDead(), false, "Sandbox wrapper for content window should not be dead");
+ is(obj.foo.bar, "baz", "Content wrappers into and out of content window should be alive");
+
+ // Remove the frame, which should nuke the content window.
+ info("Remove the content frame");
+ frame.remove();
+
+ // Give the nuke wrappers task a chance to run.
+ await new Promise(resolve => waitForWindowDestroyed(winID, resolve));
+
+ is(isWrapperDead(), true, "Sandbox wrapper for content window should be dead");
+ is(obj.foo.bar, "baz", "Content wrappers into and out of content window should be alive");
+});
+</script>
+
+</body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/test_paris_weakmap_keys.html b/js/xpconnect/tests/mochitest/test_paris_weakmap_keys.html
new file mode 100644
index 0000000000..1b786138d4
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_paris_weakmap_keys.html
@@ -0,0 +1,94 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=777385
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Tests for WebIDL objects as weak map keys</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript">
+
+ /** Test for Bug 777385 **/
+
+ SimpleTest.waitForExplicitFinish();
+
+ // We wait to run this until the load event because it needs to access an element.
+ function go() {
+
+ let live_map = new WeakMap;
+
+ let get_div_style = function () {
+ return document.getElementById("mydivname").style;
+ }
+
+ let make_live_map = function () {
+ let my_div_style = get_div_style();
+ let div_fail = false;
+ try {
+ live_map.set(my_div_style, 12345);
+ } catch (e) {
+ div_fail = true;
+ }
+ ok(!div_fail, "Using elem.style as a weak map key should not produce an exception.");
+
+ is(live_map.get(get_div_style()), 12345, "Live map should have live style with right value before GC.");
+
+ }
+
+ make_live_map();
+
+ let tf = new TestFunctions;
+
+ let add_non_isupports2 = function () {
+ let testKey = tf.wrapperCachedNonISupportsObject;
+
+ let testFail = false;
+ try {
+ live_map.set(testKey, 23456);
+ } catch (e) {
+ testFail = true;
+ }
+
+ ok(!testFail, "Using a wrapper cached non-nsISupports class as a weak map key should not produce an exception.");
+
+ is(live_map.get(testKey), 23456, "Live map should have wrapper cached non-nsISupports class right value before GC.");
+ }
+
+ add_non_isupports2();
+
+
+ /* Set up for running precise GC/CC then check the results. */
+
+ SpecialPowers.exactGC(function () {
+ SpecialPowers.forceCC();
+ SpecialPowers.forceGC();
+ SpecialPowers.forceGC();
+
+ is(SpecialPowers.nondeterministicGetWeakMapKeys(live_map).length, 2,
+ "Live WebIDL bindings keys should not be removed from a weak map.");
+
+ is(live_map.get(get_div_style()), 12345, "Live weak map should have live style with right value after GC.");
+ is(live_map.get(tf.wrapperCachedNonISupportsObject), 23456,
+ "Live weak map should have live wrapper cached non-nsISupports class with right value after GC.");
+
+ SimpleTest.finish();
+ });
+
+ }
+
+ SimpleTest.waitForExplicitFinish();
+
+ addLoadEvent(function() {
+ SpecialPowers.pushPrefEnv({set: [['dom.expose_test_interfaces', true]]},
+ go);
+ });
+ </script>
+</head>
+<div></div>
+<div id="mydivname"></div>
+<body>
+<p id="display"></p>
+</body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/test_private_field_dom.html b/js/xpconnect/tests/mochitest/test_private_field_dom.html
new file mode 100644
index 0000000000..4a50c7ca95
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_private_field_dom.html
@@ -0,0 +1,221 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=????
+-->
+
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug ????</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+ <iframe id="ifr"></iframe>
+</head>
+
+<body>
+ <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1094930">Mozilla Bug 1094930</a>
+ <p id="display"></p>
+ <div id="test_contents">
+ <!-- Extracted from nsHTMLTagList.h -->
+ <applet></applet>
+ <area></area>
+ <audio></audio>
+ <base>
+ </base>
+ <bgsound></bgsound>
+ <blockquote></blockquote>
+
+ <body></body>
+ <br></br>
+ <button></button>
+ <canvas></canvas>
+ <caption></caption>
+ <col>
+ </col>
+ <colgroup></colgroup>
+ <data></data>
+ <datalist></datalist>
+ <del></del>
+ <details></details>
+ <dialog></dialog>
+ <dir></dir>
+ <div></div>
+ <dl></dl>
+ <embed></embed>
+ <fieldset></fieldset>
+ <font></font>
+ <form></form>
+ <frame></frame>
+ <frameset></frameset>
+ <h1></h1>
+ <h2></h2>
+ <h3></h3>
+ <h4></h4>
+ <h5></h5>
+ <h6></h6>
+
+ <head></head>
+ <hr>
+ </hr>
+ <html>
+
+ </html>
+ <iframe></iframe>
+ <img></img>
+ <input></input>
+ <ins></ins>
+ <keygen></keygen>
+ <label></label>
+ <legend></legend>
+ <li></li>
+ <link>
+ </link>
+ <listing></listing>
+ <map></map>
+ <marquee></marquee>
+ <menu></menu>
+ <menuitem>
+ </menuitem>
+ <meta>
+ </meta>
+ <meter></meter>
+ <multicol></multicol>
+ <object></object>
+ <ol></ol>
+ <optgroup></optgroup>
+ <option></option>
+ <output></output>
+ <p></p>
+ <param>
+ </param>
+ <picture></picture>
+ <pre></pre>
+ <progress></progress>
+ <q></q>
+ <script></script>
+ <select></select>
+ <slot></slot>
+ <source>
+ </source>
+ <span></span>
+ <style></style>
+ <summary></summary>
+ <table></table>
+ <tbody></tbody>
+ <td></td>
+ <textarea></textarea>
+ <tfoot></tfoot>
+ <th></th>
+ <thead></thead>
+ <template></template>
+ <time></time>
+ <title></title>
+ <tr></tr>
+ <track>
+ </track>
+ <ul></ul>
+ <video></video>
+ <xmp></xmp>
+ </div>
+ <script type="application/javascript">
+ SimpleTest.waitForExplicitFinish();
+ info("running")
+
+
+ // Because private fields may not be enabled, we construct A via the below eval of an IFFE,
+ // and return early if it syntax errors.
+ var A = undefined;
+ try {
+ A = eval(`(function(){
+ class Base {
+ constructor(o) {
+ return o;
+ }
+ }
+
+ class A extends Base {
+ #x = 1;
+ static g(o) {
+ return o.#x;
+ }
+ static s(o, v) {
+ o.#x = v;
+ }
+ }
+
+ return A;
+ })();`);
+ } catch (e) {
+ is(e instanceof SyntaxError, true, "Threw Syntax Error, Private Fields Not Enabled");
+ is(/private fields are not currently supported/.test(e.message), true, "correct message");
+ }
+
+ if (A instanceof Function) {
+ function assertThrewInstance(f, error) {
+ var threw = true;
+ try {
+ f();
+ threw = false;
+ } catch (e) {
+ // info("Caught " + e.name);
+ is(e instanceof error, true, "Correct Error thrown");
+ }
+ is(threw, true, "Error was thrown");
+ }
+
+ function testNode(node) {
+ info("Testing node " + node.nodeName);
+
+ assertThrewInstance(() => A.g(node), TypeError);
+ assertThrewInstance(() => A.s(node, 'node'), TypeError);
+ // info("Stamping Node");
+ new A(node);
+ // info("Asserting read");
+ is(A.g(node), 1, "correct value read");
+ // info("Setting");
+ A.s(node, 'node');
+ // info("Verifing setter set the value");
+ is(A.g(node), 'node', "updated value read");
+ // info("Verifying we cannot double-init");
+ assertThrewInstance(() => new A(node), TypeError);
+ }
+
+ function testNodeRecursive(node) {
+ testNode(node);
+ for (c of node.children) {
+ testNodeRecursive(c)
+ }
+ }
+
+ const test_contents = document.getElementById('test_contents');
+ testNodeRecursive(test_contents);
+
+ info("Checking Window");
+ // Window itself isn't allowed to host private fields, because it's
+ // a cross-origin object
+ assertThrewInstance(() => A.g(window), TypeError)
+
+ info("Checking Window Prototype Chain")
+ // However, it's prototype chain can.
+ w = Object.getPrototypeOf(window);
+ while (w) {
+ testNode(w);
+ w = Object.getPrototypeOf(w);
+ }
+
+ info("Test Document")
+ testNode(document);
+
+
+ info("Test CSSRuleList")
+ testNode(document.styleSheets[0].cssRules)
+
+ info("Test DOMTokenList")
+ const div = document.createElement('div');
+ testNode(div.classList);
+ }
+ SimpleTest.finish();
+ </script>
+</body>
+
+</html> \ No newline at end of file
diff --git a/js/xpconnect/tests/mochitest/test_private_field_worker.html b/js/xpconnect/tests/mochitest/test_private_field_worker.html
new file mode 100644
index 0000000000..68351000c5
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_private_field_worker.html
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>Test Private Fields</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript">
+ function go() {
+ SimpleTest.waitForExplicitFinish();
+
+ let worker = new Worker('private_field_worker.js');
+
+ var allocated = 0;
+ worker.onmessage = function(e) {
+ is(e.data, allocated, "correctly allocated private field-containing-class");
+ SimpleTest.finish();
+ }
+
+ worker.postMessage("allocate"); allocated++;
+ worker.postMessage("count");
+ info("Messages posted");
+ }
+ go();
+ </script>
+ </head>
+
+</html> \ No newline at end of file
diff --git a/js/xpconnect/tests/mochitest/test_sameOriginPolicy.html b/js/xpconnect/tests/mochitest/test_sameOriginPolicy.html
new file mode 100644
index 0000000000..2393e3c24f
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_sameOriginPolicy.html
@@ -0,0 +1,109 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=801576
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 801576</title>
+ <script 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=801576">Mozilla Bug 801576</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for the same-origin policy. **/
+SimpleTest.waitForExplicitFinish();
+
+function check(obj, prop, allowed, write) {
+ var accessed = false;
+ try {
+ if (write) {
+ try {
+ obj[prop] = 2;
+ accessed = true;
+ } catch (e) {}
+ Object.defineProperty(obj, 'prop', {getter: function() {}, setter: null});
+ }
+ else
+ obj[prop];
+ accessed = true;
+ } catch (e) {}
+ is(accessed, allowed, prop + " is correctly (in)accessible for " + (write ? 'write' : 'read'));
+}
+
+var crossOriginReadableWindowProps = ['blur', 'close', 'closed', 'focus',
+ 'frames', 'location', 'length',
+ 'opener', 'parent', 'postMessage',
+ 'self', 'top', 'window',
+ /* indexed and named accessors */
+ '0', 'subframe'];
+
+function isCrossOriginReadable(obj, prop) {
+ if (obj == "Window")
+ return crossOriginReadableWindowProps.includes(prop);
+ if (obj == "Location")
+ return prop == 'replace';
+ return false;
+}
+
+function isCrossOriginWritable(obj, prop) {
+ if (obj == "Window")
+ return prop == 'location';
+ if (obj == "Location")
+ return prop == 'href';
+}
+
+// NB: we don't want to succeed with writes, so we only check them when it should be denied.
+function testAll(sameOrigin) {
+ var win = document.getElementById('ifr').contentWindow;
+
+ // Build a list of properties to check from the properties available on our
+ // window.
+ var props = [];
+ for (var prop in window) { props.push(prop); }
+
+ // On android, this appears to be on the window but not on the iframe. It's
+ // not really relevant to this test, so just skip it.
+ if (props.includes('crypto'))
+ props.splice(props.indexOf('crypto'), 1);
+
+ // Add the named grand-child, since that won't appear on our window.
+ props.push('subframe');
+
+ for (var prop of props) {
+ check(win, prop, sameOrigin || isCrossOriginReadable('Window', prop), /* write = */ false);
+ if (!sameOrigin && !isCrossOriginWritable('Window', prop))
+ check(win, prop, false, /* write = */ true);
+ }
+ for (var prop in window.location) {
+ check(win.location, prop, sameOrigin || isCrossOriginReadable('Location', prop));
+ if (!sameOrigin && !isCrossOriginWritable('Location', prop))
+ check(win.location, prop, false, /* write = */ true);
+ }
+}
+
+var loadCount = 0;
+function go() {
+ ++loadCount;
+ if (loadCount == 1) {
+ testAll(true);
+ document.getElementById('ifr').contentWindow.location = 'http://example.org/tests/js/xpconnect/tests/mochitest/file_empty.html';
+ }
+ else {
+ is(loadCount, 2);
+ testAll(false);
+ SimpleTest.finish();
+ }
+}
+
+</script>
+</pre>
+<iframe id="ifr" onload="go();" src="file_empty.html"></iframe>
+</body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/test_sandbox_fetch.html b/js/xpconnect/tests/mochitest/test_sandbox_fetch.html
new file mode 100644
index 0000000000..3b6cffed4e
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_sandbox_fetch.html
@@ -0,0 +1,54 @@
+<!doctype html>
+<html>
+<head>
+ <title>Fetch in JS Sandbox</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"></link>
+ <script src="test_fetch_basic.js"></script>
+</head>
+<body>
+<script type="application/javascript">
+
+SimpleTest.waitForExplicitFinish();
+
+function testHttpFetch(url) {
+ info('fetch: ' + url);
+ return fetch(new Request(url, { method: 'GET' }))
+ .then(response => {
+ is(response.status, 200, 'Response is 200');
+ is(response.url, url, 'Response URL matches');
+ });
+}
+
+function runSandboxTest(testFunc, argString) {
+ is(typeof testFunc, 'function');
+ var resolvePromise;
+ var testPromise = new Promise(r => resolvePromise = r);
+ var finishFuncName = 'finish_' + testFunc.name;
+ SpecialPowers.Cu.exportFunction(_ => resolvePromise(), sb,
+ { defineAs: finishFuncName });
+ SpecialPowers.Cu.evalInSandbox('(' + testFunc.toString() + ')' +
+ '(' + argString + ')' +
+ '.then(' + finishFuncName + ');', sb);
+ return testPromise;
+}
+
+var origin = document.location.origin;
+var properties = ['fetch', 'Blob', 'URL'];
+var sb = new SpecialPowers.Cu.Sandbox(origin,
+ { wantGlobalProperties: properties });
+
+sb.ok = SpecialPowers.Cu.exportFunction(ok, sb);
+sb.is = SpecialPowers.Cu.exportFunction(is, sb);
+sb.info = SpecialPowers.Cu.exportFunction(info, sb);
+
+Promise.resolve()
+ .then(_ => runSandboxTest(testHttpFetch, '"' + origin + window.location.pathname + '"'))
+ .then(_ => runSandboxTest(testAboutURL))
+ .then(_ => runSandboxTest(testDataURL))
+ .then(_ => runSandboxTest(testSameOriginBlobURL))
+ .then(_ => SimpleTest.finish());
+
+</script>
+</body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/test_shadowRealm.html b/js/xpconnect/tests/mochitest/test_shadowRealm.html
new file mode 100644
index 0000000000..311ce68107
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_shadowRealm.html
@@ -0,0 +1,34 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>Test for ShadowRealms</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+ <iframe id="ifr"></iframe>
+</head>
+
+<body>
+ <p id="display"></p>
+ <script type="application/javascript">
+ SimpleTest.waitForExplicitFinish();
+ info("running")
+
+ let realm = new ShadowRealm();
+
+ let install = (fun, internal_name) => {
+ let installer = realm.evaluate(`var ${internal_name}; (x) => { ${internal_name} = x}`);
+ installer(fun);
+ }
+
+ install(info, "log");
+ install(is, "is");
+ realm.evaluate(`is(true, true, 'inside realm')`);
+
+ is(realm.evaluate("10"), 10, "ten is ten");
+
+ SimpleTest.finish();
+ </script>
+</body>
+
+</html>
diff --git a/js/xpconnect/tests/mochitest/test_shadowRealm_worker.html b/js/xpconnect/tests/mochitest/test_shadowRealm_worker.html
new file mode 100644
index 0000000000..d26e665f8f
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_shadowRealm_worker.html
@@ -0,0 +1,63 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>Test for ShadowRealms</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+ <iframe id="ifr"></iframe>
+</head>
+
+<body>
+ <p id="display"></p>
+ <script type="application/javascript">
+ SimpleTest.waitForExplicitFinish();
+
+ var promise = (async ()=> {
+ var module = await import("./shadow_realm_module.js");
+ is(module.x, 1, "import works outside worker");
+
+ var sr = new ShadowRealm();
+ await sr.importValue("./shadow_realm_module.js", 'x').then((x) => is(x,1, "imported x and got 1"));
+ })();
+
+ promise.then(() => {
+ var worker = new Worker("shadow_realm_worker.js");
+
+ var expected = 0;
+ var recieved = 0;
+
+ function test(str) {
+ worker.postMessage(str);
+ expected++;
+ }
+
+ worker.onmessage = function(e) {
+ console.log("Received Message: "+e.data);
+ recieved++;
+
+ if (e.data == "finish") {
+ is(expected, recieved, "Got the appropriate Number of messages");
+ SimpleTest.finish();
+ return;
+ }
+
+ if (e.data.startsWith("PASS")) {
+ ok(true, e.data);
+ return;
+ }
+
+ ok(false, e.data);
+ };
+
+
+ test("evaluate");
+ test("import");
+
+
+ test("finish");
+ });
+ </script>
+</body>
+
+</html>
diff --git a/js/xpconnect/tests/mochitest/test_spectre_mitigations.html b/js/xpconnect/tests/mochitest/test_spectre_mitigations.html
new file mode 100644
index 0000000000..0340873243
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_spectre_mitigations.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>Tests for Spectre mitigations</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<script>
+add_task(async function() {
+ const { Cu } = SpecialPowers;
+ const options = Cu.getJSTestingFunctions().getJitCompilerOptions();
+
+ const testMitigation = function(name) {
+ let val = options[name];
+ ok(val === 0 || val === 1, "must be valid JitOption");
+ is(Boolean(val), !SpecialPowers.useRemoteSubframes, "must be enabled if Fission is disabled");
+ };
+
+ testMitigation("spectre.index-masking");
+ testMitigation("spectre.object-mitigations");
+ testMitigation("spectre.string-mitigations");
+ testMitigation("spectre.value-masking");
+});
+</script>
+</body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/test_weakRefs.html b/js/xpconnect/tests/mochitest/test_weakRefs.html
new file mode 100644
index 0000000000..331bb9bb69
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_weakRefs.html
@@ -0,0 +1,80 @@
+<!DOCTYPE HTML>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>Test WeakRef works in the browser</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript">
+ let wr1, wr2, wr3, wr4;
+
+ function go() {
+ SimpleTest.waitForExplicitFinish();
+
+ // 1. WeakRef with JS target.
+ wr1 = new WeakRef({});
+
+ // 2. WeakRef with DOM object target (without preserved wrapper).
+ wr2 = new WeakRef(document.createElement("div"));
+
+ // 3. WeakRef with DOM object target (with preserved wrapper).
+ let object = document.createElement("div");
+ object.someProperty = true;
+ wr3 = new WeakRef(object);
+ object = null
+
+ // 4. WeakRef with reachable DOM object target without preserved wrapper.
+ document.body.appendChild(document.createElement("div"));
+ wr4 = new WeakRef(document.body.lastChild);
+
+ // WeakRef should keep the target in the current task.
+ isnot(wr1.deref(), undefined, "deref() should return its target.");
+ isnot(wr2.deref(), undefined, "deref() should return its target.");
+ isnot(wr3.deref(), undefined, "deref() should return its target.");
+ isnot(wr4.deref(), undefined, "deref() should return its target.");
+
+ // WeakRef should keep the target until the end of current task, which
+ // includes promise microtasks.
+ Promise.resolve().then(() => {
+ isnot(wr1.deref(), undefined, "deref() should return its target.");
+ isnot(wr2.deref(), undefined, "deref() should return its target.");
+ isnot(wr3.deref(), undefined, "deref() should return its target.");
+ isnot(wr4.deref(), undefined, "deref() should return its target.");
+ });
+
+ // setTimeout will call its callback in a new task.
+ setTimeout(task2, 0);
+ }
+
+ function task2() {
+ // Trigger a full GC/CC/GC cycle to collect WeakRef targets.
+ SpecialPowers.DOMWindowUtils.garbageCollect();
+ SpecialPowers.DOMWindowUtils.cycleCollect();
+ SpecialPowers.DOMWindowUtils.garbageCollect();
+
+ is(wr1.deref(), undefined, "deref() should return undefined.");
+ is(wr2.deref(), undefined, "deref() should return undefined.");
+ is(wr3.deref(), undefined, "deref() should return undefined.");
+ isnot(wr4.deref(), undefined, "deref() should return its target.");
+
+ // setTimeout will call its callback in a new task.
+ setTimeout(task3, 0);
+ }
+
+ function task3() {
+ document.body.removeChild(document.body.lastChild);
+
+ SpecialPowers.DOMWindowUtils.garbageCollect();
+ SpecialPowers.DOMWindowUtils.cycleCollect();
+ SpecialPowers.DOMWindowUtils.garbageCollect();
+
+ is(wr1.deref(), undefined, "deref() should return undefined.");
+ is(wr2.deref(), undefined, "deref() should return undefined.");
+ is(wr3.deref(), undefined, "deref() should return undefined.");
+ is(wr4.deref(), undefined, "deref() should return undefined.");
+
+ SimpleTest.finish();
+ }
+ </script>
+ </head>
+ <body onload="go()"></body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/test_weakRefs_collected_wrapper.html b/js/xpconnect/tests/mochitest/test_weakRefs_collected_wrapper.html
new file mode 100644
index 0000000000..c7af313d96
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_weakRefs_collected_wrapper.html
@@ -0,0 +1,52 @@
+<!DOCTYPE HTML>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>Test WeakRefs with DOM wrappers that get cycle collected</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript">
+ let weakrefs = [];
+
+ function go() {
+ SimpleTest.waitForExplicitFinish();
+
+ // 1. nsISupports-derived object.
+ let doc = document.implementation.createHTMLDocument();
+ weakrefs.push(new WeakRef(doc));
+
+ // 2. non-nsISupports-derived object.
+ let buffer = new AudioBuffer({length: 1, sampleRate: 8000});
+ weakrefs.push(new WeakRef(buffer));
+
+ // 3. nsISupports non-wrapper-cached object.
+ let image = new ImageData(1, 1);
+ weakrefs.push(new WeakRef(image));
+
+ // 4. non-nsISupports non-wrapper-cached object.
+ let iterator = document.fonts.values();
+ weakrefs.push(new WeakRef(iterator));
+
+ for (let wr of weakrefs) {
+ isnot(wr.deref(), undefined, "Check that live wrapper is returned");
+ }
+
+ // setTimeout will call its callback in a new task.
+ setTimeout(task2, 0);
+ }
+
+ function task2() {
+ // Trigger a GC and CC to collect the DOM objects, but no GC to
+ // collect the wrappers.
+ SpecialPowers.DOMWindowUtils.garbageCollect();
+ SpecialPowers.DOMWindowUtils.cycleCollect();
+
+ for (let wr of weakrefs) {
+ is(wr.deref(), undefined, "Check that stale wrapper is not exposed");
+ }
+
+ SimpleTest.finish();
+ }
+ </script>
+ </head>
+ <body onload="go()"></body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/test_weakRefs_cross_compartment.html b/js/xpconnect/tests/mochitest/test_weakRefs_cross_compartment.html
new file mode 100644
index 0000000000..87e509b535
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_weakRefs_cross_compartment.html
@@ -0,0 +1,68 @@
+<!DOCTYPE HTML>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>Test WeakRef works when target is in different compartment in the browser</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript">
+ function go() {
+ SimpleTest.waitForExplicitFinish();
+
+ let Cu = SpecialPowers.Cu;
+ let isSameCompartment = Cu.getJSTestingFunctions().isSameCompartment;
+
+ // Open a new window, which will be from different compartment.
+ let win = window.open();
+ is(isSameCompartment(win, window), false,
+ "Test for opeing a window from a different compartment.");
+
+ let wr1, wr2, wr3;
+ {
+ let obj = {};
+
+ // WeakRef and target are both from different compartment.
+ wr1 = new win.WeakRef(new win.Object());
+
+ // WeakRef is same compartment, but target isn't.
+ wr2 = new WeakRef(new win.Object());
+
+ // WeakRef is in different compartment, but target is.
+ wr3 = new win.WeakRef(obj);
+
+ obj = null;
+ }
+
+ // WeakRef should keep the target in the current task.
+ isnot(wr1.deref(), undefined, "wr1.deref() should return its target.");
+ isnot(wr2.deref(), undefined, "wr2.deref() should return its target.");
+ isnot(wr3.deref(), undefined, "we3.deref() should return its target.");
+
+ // Weakref should keep the target until the end of current Job, that
+ // includes microtask(Promise).
+ Promise.resolve().then(() => {
+ isnot(wr1.deref(), undefined,
+ "wr1.deref() should return its target in promise");
+ isnot(wr2.deref(), undefined,
+ "wr2.deref() should return its target in promise");
+ isnot(wr3.deref(), undefined,
+ "wr3.deref() should return its target in promise");
+ });
+
+ // setTimeout will launch a new job and call ClearKeptObjects().
+ setTimeout(() => {
+ // Call gc() forcibly to clear the target of wr.
+ SpecialPowers.DOMWindowUtils.garbageCollect();
+
+ is(wr1.deref(), undefined, "wr1.deref() should return undefined in the new job.");
+ is(wr2.deref(), undefined, "wr2.deref() should return undefined in the new job.");
+ is(wr3.deref(), undefined, "wr3.deref() should return undefined in the new job.");
+
+ win.close();
+ SimpleTest.finish();
+ }, 0);
+ }
+
+ </script>
+ </head>
+ <body onload="go()"></body>
+</html>
diff --git a/js/xpconnect/tests/mochitest/test_weakmaps.html b/js/xpconnect/tests/mochitest/test_weakmaps.html
new file mode 100644
index 0000000000..5e00106fed
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/test_weakmaps.html
@@ -0,0 +1,264 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=668855
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test Cross-Compartment DOM WeakMaps</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+<script type="application/javascript">
+ /** Test for Bug 668855 **/
+
+ SimpleTest.waitForExplicitFinish();
+
+// We wait to run this until the load event because it needs to access an element.
+function go() {
+
+ /* Create a weak reference, with a single-element weak map. */
+ let make_weak_ref = function (obj) {
+ let m = new WeakMap;
+ m.set(obj, {});
+ return m;
+ };
+
+ /* Check to see if a weak reference is dead. */
+ let weak_ref_dead = function (r) {
+ return SpecialPowers.nondeterministicGetWeakMapKeys(r).length == 0;
+ }
+
+ /* Deterministically grab an arbitrary DOM element. */
+ let get_live_dom = function () {
+ let elems = document.getElementsByTagName("a");
+ return elems[0];
+ };
+
+
+ /* Test case from bug 653248, adapted into a standard test.
+
+ This is a dead cycle involving a DOM edge, so the cycle collector can free it. Keys and
+ values reachable only from XPConnect must be marked gray for this to work, and the cycle collector
+ must know the proper structure of the heap.
+
+ */
+ let make_gray_loop = function () {
+ let map = new WeakMap;
+ let div = document.createElement("div");
+ let key = {};
+ let obj = {m:map, k:key};
+ div.addEventListener("foo", function() {
+ // The code below doesn't matter (it won't run). Just pull a
+ // reference to obj.
+ obj.k = 1;
+ obj.m = "bar";
+ });
+ //div.entrain = {m:map, k:key}; This is not sufficient to cause a leak in Fx9
+ map.set(key, div);
+ return make_weak_ref(map);
+ };
+
+ let weakref = make_gray_loop();
+
+
+ /* Combinations of live and dead gray maps/keys. */
+ let basic_weak_ref = null;
+ let basic_map_weak_ref = null;
+ let black_map = new WeakMap;
+ let black_key = {};
+
+ let basic_unit_tests = function () {
+ let live_dom = get_live_dom();
+ let dead_dom = document.createElement("div");
+ let live_map = new WeakMap;
+ let dead_map = new WeakMap;
+ let live_key = {};
+ let dead_key = {};
+
+ // put the live/dead maps/keys into the appropriate DOM elements
+ live_dom.basic_unit_tests = {m:live_map, k:live_key};
+
+ let obj = {m:dead_map, k:dead_key};
+ // dead_dom.hook = {m:dead_map, k:dead_key};
+ dead_dom.addEventListener("foo", function() {
+ // The code below doesn't matter (it won't run). Just pull a
+ // reference to obj.
+ obj.m = 1;
+ obj.k = "2";
+ });
+
+ // Create a dead value, and a weak ref to it.
+ // The loop keeps dead_dom alive unless the CC is smart enough to kill it.
+ let dead_val = {loop:dead_dom};
+ basic_weak_ref = make_weak_ref(dead_val);
+ basic_map_weak_ref = make_weak_ref(dead_map);
+
+ // set up the actual entries. most will die.
+ live_map.set(live_key, {my_key:'live_live'});
+ live_map.set(dead_key, dead_val);
+ live_map.set(black_key, {my_key:'live_black'});
+
+ dead_map.set(live_key, dead_val);
+ dead_map.set(dead_key, dead_val);
+ dead_map.set(black_key, dead_val);
+
+ black_map.set(live_key, {my_key:'black_live'});
+ black_map.set(dead_key, dead_val);
+ black_map.set(black_key, {my_key:'black_black'});
+
+ };
+
+ basic_unit_tests();
+
+
+ let check_basic_unit = function () {
+ let live_dom = get_live_dom();
+ let live_map = live_dom.basic_unit_tests.m;
+ let live_key = live_dom.basic_unit_tests.k;
+
+ // check the dead elements
+ ok(weak_ref_dead(basic_weak_ref), "Dead value was kept alive.");
+ ok(weak_ref_dead(basic_map_weak_ref), "Dead map was kept alive.");
+
+ // check the live gray map
+ is(live_map.get(live_key).my_key, 'live_live',
+ "Live key should have the same value in live map.");
+ is(live_map.get(black_key).my_key, 'live_black',
+ "Black key should have the same value in live map.");
+ is(SpecialPowers.nondeterministicGetWeakMapKeys(live_map).length, 2,
+ "Live map should have two entries.");
+
+ // check the live black map
+ is(black_map.get(live_key).my_key, 'black_live',
+ "Live key should have the same value in black map.");
+ is(black_map.get(black_key).my_key, 'black_black',
+ "Black key should have the same value in black map.");
+ is(SpecialPowers.nondeterministicGetWeakMapKeys(black_map).length, 2,
+ "Black map should have two entries.");
+
+ };
+
+
+ /* live gray chained weak map entries, involving the cycle collector. */
+ let chainm = new WeakMap;
+ let num_chains = 5;
+
+ let nested_cc_maps = function () {
+ let dom = get_live_dom();
+ for(let i = 0; i < num_chains; i++) {
+ let k = {count:i};
+ dom.key = k;
+ dom0 = document.createElement("div");
+ chainm.set(k, {d:dom0});
+ dom = document.createElement("div");
+ dom0.appendChild(dom);
+ };
+ };
+
+ let check_nested_cc_maps = function () {
+ let dom = get_live_dom();
+ let all_ok = true;
+ for(let i = 0; i < num_chains; i++) {
+ let k = dom.key;
+ all_ok = all_ok && k.count == i;
+ dom = chainm.get(k).d.firstChild;
+ };
+ ok(all_ok, "Count was invalid on a key in chained weak map entries.");
+ };
+
+ nested_cc_maps();
+
+
+ /* black weak map, chained garbage cycle involving DOM */
+ let garbage_map = new WeakMap;
+
+ let chained_garbage_maps = function () {
+ let dom0 = document.createElement("div");
+ let dom = dom0;
+ for(let i = 0; i < num_chains; i++) {
+ let k = {};
+ dom.key = k;
+ let new_dom = document.createElement("div");
+ garbage_map.set(k, {val_child:new_dom});
+ dom = document.createElement("div");
+ new_dom.appendChild(dom);
+ };
+ // tie the knot
+ dom.appendChild(dom0);
+ };
+
+ chained_garbage_maps();
+
+
+ /* black weak map, chained garbage cycle involving DOM, XPCWN keys */
+ let wn_garbage_map = new WeakMap;
+
+ let wn_chained_garbage_maps = function () {
+ let dom0 = document.createElement("div");
+ let dom = dom0;
+ for(let i = 0; i < num_chains; i++) {
+ let new_dom = document.createElement("div");
+ wn_garbage_map.set(dom, {wn_val_child:new_dom});
+ dom = document.createElement("div");
+ new_dom.appendChild(dom);
+ };
+ // tie the knot
+ dom.appendChild(dom0);
+ };
+
+ wn_chained_garbage_maps();
+
+
+ /* The cycle collector shouldn't remove a live wrapped native key. */
+
+ let wn_live_map = new WeakMap;
+
+ let make_live_map = function () {
+ let live = get_live_dom();
+ wn_live_map.set(live, {});
+ ok(wn_live_map.has(get_live_dom()), "Live map should have live DOM node before GC.");
+ }
+
+ make_live_map();
+
+ // We're out of ideas for unpreservable natives, now that just about
+ // everything is on webidl, so just don't test those.
+
+ /* set up for running precise GC/CC then checking the results */
+
+ SpecialPowers.exactGC(function () {
+ SpecialPowers.forceCC();
+ SpecialPowers.forceGC();
+ SpecialPowers.forceGC();
+
+ ok(weak_ref_dead(weakref), "Garbage gray cycle should be collected.");
+
+ check_nested_cc_maps();
+
+ is(SpecialPowers.nondeterministicGetWeakMapKeys(garbage_map).length, 0, "Chained garbage weak map entries should not leak.");
+
+ check_basic_unit();
+
+ // fixed by Bug 680937
+ is(SpecialPowers.nondeterministicGetWeakMapKeys(wn_garbage_map).length, 0,
+ "Chained garbage WN weak map entries should not leak.");
+
+ // fixed by Bug 680937
+ is(SpecialPowers.nondeterministicGetWeakMapKeys(wn_live_map).length, 1,
+ "Live weak map wrapped native key should not be removed.");
+
+ ok(wn_live_map.has(get_live_dom()), "Live map should have live dom.");
+
+ SimpleTest.finish();
+ });
+
+}
+ </script>
+</head>
+<div></div>
+<div id="mydivname"></div>
+<body onload="go()";>
+<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=668855" target="_blank">Mozilla Bug 668855</a>
+<p id="display"></p>
+</body>
+</html>