summaryrefslogtreecommitdiffstats
path: root/dom/tests/mochitest/whatwg/postMessage_structured_clone_helper.html
blob: 2b6e9d1f46dc56e0a3101c7933675763efb7b7f5 (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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
<!DOCTYPE html>
<html>
<head>
  <title>postMessage structured clone page</title>
  <script type="application/javascript"
          src="postMessage_structured_clone_helper.js"></script>
  <script type="application/javascript">
    var generator = getTestContent()

    function isClone(a, b) {
        window.dump("Object a: " + a + "\n");
        window.dump("Object b: " + b + "\n");
        var stack = [[a, b]];
        var memory = new WeakMap();
        var rmemory = new WeakMap();

        while (stack.length) {
            var pair = stack.pop();
            var x = pair[0], y = pair[1];
            if (typeof x !== "object" || x === null) {
                // x is primitive.
                if (x !== y) {
                    window.dump("Primitives not equal!\n");
                    return false;
                }
            } else if (x instanceof Date) {
                if (x.getTime() == y.getTime())
                    return true;
                window.dump("Dates not equal!\n");
                return false;
            } else if (memory.has(x)) {
                // x is an object we have seen before in a.
                if (y !== memory.get(x)) {
                    window.dump("Already seen!?\n");
                    return false;
                }
                if (!(rmemory.get(y) == x)) {
                    window.dump("Not equal??\n");
                    return false;
                }
            } else {
                // x is an object we have not seen before.
                // Check that we have not seen y before either.
                if (rmemory.has(y)) {
                    // If we have seen y before, the only possible outcome
                    // is that x and y are literally the same object.
                    if (y == x)
                        continue;
                    window.dump("Already seen y!?\n");
                    window.dump(y.toString() + "\n");
                    return false;
                }

                // x and y must be of the same [[Class]].
                var xcls = Object.prototype.toString.call(x);
                var ycls = Object.prototype.toString.call(y);
                if (xcls !== ycls) {
                    window.dump("Failing on proto\n");
                    return false;
                }

                // This function is only designed to check Objects and Arrays.
                if (!(xcls === "[object Object]" || xcls === "[object Array]")) {
                    window.dump("Not an object!\n");
                    window.dump(xcls + "\n");
                    return false;
                }

                // Compare objects.
                var xk = Object.keys(x), yk = Object.keys(y);
                if (xk.length !== yk.length) {
                    window.dump("Length mismatch!\n");
                    return false;
                }
                for (var i = 0; i < xk.length; i++) {
                    // We must see the same property names in the same order.
                    if (xk[i] !== yk[i]) {
                        window.dump("wrong order\n");
                        return false;
                    }

                    // Put the property values on the stack to compare later.
                    stack.push([x[xk[i]], y[yk[i]]]);
                }

                // Record that we have seen this pair of objects.
                memory.set(x, y);
                rmemory.set(y, x);
            }
        }
        return true;
    }

    function receiveMessage(evt)
    {
      if (isClone(evt.data, generator.next().value))
        window.parent.postMessage("TEST-PASS", "*");
      else
        window.parent.postMessage("TEST-FAIL", "*");
    }
    window.addEventListener("message", receiveMessage);
  </script>
</head>
<body>
</body>
</html>