summaryrefslogtreecommitdiffstats
path: root/js/xpconnect/tests/mochitest/test_weakRefs.html
blob: 331bb9bb6983364880b2adb382a0662933636238 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
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>