|
1 <!DOCTYPE html> |
|
2 <html> |
|
3 <head> |
|
4 <title>postMessage structured clone page</title> |
|
5 <script type="application/javascript;version=1.7" |
|
6 src="postMessage_structured_clone_helper.js"></script> |
|
7 <script type="application/javascript;version=1.7"> |
|
8 var generator = new getTestContent() |
|
9 |
|
10 function isClone(a, b) { |
|
11 window.dump("Object a: " + a + "\n"); |
|
12 window.dump("Object b: " + b + "\n"); |
|
13 var stack = [[a, b]]; |
|
14 var memory = new WeakMap(); |
|
15 var rmemory = new WeakMap(); |
|
16 |
|
17 while (stack.length > 0) { |
|
18 var pair = stack.pop(); |
|
19 var x = pair[0], y = pair[1]; |
|
20 if (typeof x !== "object" || x === null) { |
|
21 // x is primitive. |
|
22 if (x !== y) { |
|
23 window.dump("Primitives not equal!\n"); |
|
24 return false; |
|
25 } |
|
26 } else if (x instanceof Date) { |
|
27 if (x.getTime() == y.getTime()) |
|
28 return true; |
|
29 window.dump("Dates not equal!\n"); |
|
30 return false; |
|
31 } else if (memory.has(x)) { |
|
32 // x is an object we have seen before in a. |
|
33 if (y !== memory.get(x)) { |
|
34 window.dump("Already seen!?\n"); |
|
35 return false; |
|
36 } |
|
37 if (!(rmemory.get(y) == x)) { |
|
38 window.dump("Not equal??\n"); |
|
39 return false; |
|
40 } |
|
41 } else { |
|
42 // x is an object we have not seen before. |
|
43 // Check that we have not seen y before either. |
|
44 if (rmemory.has(y)) { |
|
45 // If we have seen y before, the only possible outcome |
|
46 // is that x and y are literally the same object. |
|
47 if (y == x) |
|
48 continue; |
|
49 window.dump("Already seen y!?\n"); |
|
50 window.dump(y.toString() + "\n"); |
|
51 return false; |
|
52 } |
|
53 |
|
54 // x and y must be of the same [[Class]]. |
|
55 var xcls = Object.prototype.toString.call(x); |
|
56 var ycls = Object.prototype.toString.call(y); |
|
57 if (xcls !== ycls) { |
|
58 window.dump("Failing on proto\n"); |
|
59 return false; |
|
60 } |
|
61 |
|
62 // This function is only designed to check Objects and Arrays. |
|
63 if (!(xcls === "[object Object]" || xcls === "[object Array]")) { |
|
64 window.dump("Not an object!\n"); |
|
65 window.dump(xcls + "\n"); |
|
66 return false; |
|
67 } |
|
68 |
|
69 // Compare objects. |
|
70 var xk = Object.keys(x), yk = Object.keys(y); |
|
71 if (xk.length !== yk.length) { |
|
72 window.dump("Length mismatch!\n"); |
|
73 return false; |
|
74 } |
|
75 for (var i = 0; i < xk.length; i++) { |
|
76 // We must see the same property names in the same order. |
|
77 if (xk[i] !== yk[i]) { |
|
78 window.dump("wrong order\n"); |
|
79 return false; |
|
80 } |
|
81 |
|
82 // Put the property values on the stack to compare later. |
|
83 stack.push([x[xk[i]], y[yk[i]]]); |
|
84 } |
|
85 |
|
86 // Record that we have seen this pair of objects. |
|
87 memory.set(x, y); |
|
88 rmemory.set(y, x); |
|
89 } |
|
90 } |
|
91 return true; |
|
92 } |
|
93 |
|
94 function receiveMessage(evt) |
|
95 { |
|
96 if (isClone(evt.data, generator.next())) |
|
97 window.parent.postMessage("TEST-PASS", "*"); |
|
98 else |
|
99 window.parent.postMessage("TEST-FAIL", "*"); |
|
100 } |
|
101 window.addEventListener("message", receiveMessage, false); |
|
102 </script> |
|
103 </head> |
|
104 <body> |
|
105 </body> |
|
106 </html> |