Source code
Revision control
Copy as Markdown
Other Tools
<!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>