<!DOCTYPE html> <html> <head> <title>Test for sending IndexedDB Blobs through MessageManager</title> <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"> </script> <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> </head> <body onload="setup();"> <script type="application/javascript;version=1.7"> "use strict"; function childFrameScript() { "use strict"; const { classes: Cc, interfaces: Ci, utils: Cu } = Components; const mmName = "test:idb-and-mm"; const dbName = "test_message_manager_ipc.html - CHILD"; const dbVersion = 1; const objStoreName = "bar"; const key = 1; const blobData = ["So", " ", "many", " ", "blobs!"]; const blobText = blobData.join(""); const blobType = "text/plain"; Cu.importGlobalProperties(["indexedDB"]); function info(msg) { sendAsyncMessage(mmName, { op: "info", msg: msg }); } function ok(condition, name, diag) { sendAsyncMessage(mmName, { op: "ok", condition: condition, name: name, diag: diag }); } function is(a, b, name) { let pass = a == b; let diag = pass ? "" : "got " + a + ", expected " + b; ok(pass, name, diag); } function finish(result) { sendAsyncMessage(mmName, { op: "done", result: result }); } function grabAndContinue(arg) { testGenerator.send(arg); } function errorHandler(event) { ok(false, event.target + " received error event: '" + event.target.error.name + "'"); finish(); } function testSteps() { addMessageListener(mmName, grabAndContinue); let message = yield undefined; let blob = message.data; ok(blob instanceof Ci.nsIDOMBlob, "Message manager sent a blob"); is(blob.size, blobText.length, "Blob has correct length"); is(blob.type, blobType, "Blob has correct type"); info("Reading blob"); let reader = new FileReader(); reader.addEventListener("load", grabAndContinue); reader.readAsText(blob); yield undefined; is(reader.result, blobText, "Blob has correct data"); let slice = blob.slice(0, blobData[0].length, blobType); ok(slice instanceof Ci.nsIDOMBlob, "Slice returned a blob"); is(slice.size, blobData[0].length, "Slice has correct length"); is(slice.type, blobType, "Slice has correct type"); info("Reading slice"); reader = new FileReader(); reader.addEventListener("load", grabAndContinue); reader.readAsText(slice); yield undefined; is(reader.result, blobData[0], "Slice has correct data"); info("Deleting database"); let req = indexedDB.deleteDatabase(dbName); req.onerror = errorHandler; req.onsuccess = grabAndContinue; let event = yield undefined; is(event.type, "success", "Got success event"); info("Opening database"); req = indexedDB.open(dbName, dbVersion); req.onerror = errorHandler; req.onupgradeneeded = grabAndContinue; req.onsuccess = grabAndContinue; event = yield undefined; is(event.type, "upgradeneeded", "Got upgradeneeded event"); event.target.result.createObjectStore(objStoreName); event = yield undefined; is(event.type, "success", "Got success event"); let db = event.target.result; info("Storing blob from message manager in database"); let objectStore = db.transaction(objStoreName, "readwrite").objectStore(objStoreName); req = objectStore.add(blob, key); req.onerror = errorHandler; req.onsuccess = grabAndContinue; event = yield undefined; info("Getting blob from database"); objectStore = db.transaction(objStoreName).objectStore(objStoreName); req = objectStore.get(key); req.onerror = errorHandler; req.onsuccess = grabAndContinue; event = yield undefined; blob = event.target.result; ok(blob instanceof Ci.nsIDOMBlob, "Database gave us a blob"); is(blob.size, blobText.length, "Blob has correct length"); is(blob.type, blobType, "Blob has correct type"); info("Reading blob"); reader = new FileReader(); reader.addEventListener("load", grabAndContinue); reader.readAsText(blob); yield undefined; is(reader.result, blobText, "Blob has correct data"); info("Storing slice from message manager in database"); objectStore = db.transaction(objStoreName, "readwrite").objectStore(objStoreName); req = objectStore.put(slice, key); req.onerror = errorHandler; req.onsuccess = grabAndContinue; event = yield undefined; info("Getting slice from database"); objectStore = db.transaction(objStoreName).objectStore(objStoreName); req = objectStore.get(key); req.onerror = errorHandler; req.onsuccess = grabAndContinue; event = yield undefined; slice = event.target.result; ok(slice instanceof Ci.nsIDOMBlob, "Database gave us a blob"); is(slice.size, blobData[0].length, "Slice has correct length"); is(slice.type, blobType, "Slice has correct type"); info("Reading Slice"); reader = new FileReader(); reader.addEventListener("load", grabAndContinue); reader.readAsText(slice); yield undefined; is(reader.result, blobData[0], "Slice has correct data"); info("Sending blob and slice from database to message manager"); finish([blob, slice]); yield undefined; } let testGenerator = testSteps(); testGenerator.next(); } function parentFrameScript(mm) { const messageName = "test:idb-and-mm"; const blobData = ["So", " ", "many", " ", "blobs!"]; const blobText = blobData.join(""); const blobType = "text/plain"; const blob = new Blob(blobData, { type: blobType }); function grabAndContinue(arg) { testGenerator.send(arg); } function testSteps() { let result = yield undefined; is(Array.isArray(result), true, "Child delivered an array of results"); is(result.length, 2, "Child delivered two results"); let blob = result[0]; is(blob instanceof Blob, true, "Child delivered a blob"); is(blob.size, blobText.length, "Blob has correct size"); is(blob.type, blobType, "Blob has correct type"); let slice = result[1]; is(slice instanceof Blob, true, "Child delivered a slice"); is(slice.size, blobData[0].length, "Slice has correct size"); is(slice.type, blobType, "Slice has correct type"); info("Reading blob"); let reader = new FileReader(); reader.onload = grabAndContinue; reader.readAsText(blob); yield undefined; is(reader.result, blobText, "Blob has correct data"); info("Reading slice"); reader = new FileReader(); reader.onload = grabAndContinue; reader.readAsText(slice); yield undefined; is(reader.result, blobData[0], "Slice has correct data"); slice = blob.slice(0, blobData[0].length, blobType); is(slice instanceof Blob, true, "Made a new slice from blob"); is(slice.size, blobData[0].length, "Second slice has correct size"); is(slice.type, blobType, "Second slice has correct type"); info("Reading second slice"); reader = new FileReader(); reader.onload = grabAndContinue; reader.readAsText(slice); yield undefined; is(reader.result, blobData[0], "Second slice has correct data"); SimpleTest.finish(); yield undefined; } let testGenerator = testSteps(); testGenerator.next(); mm.addMessageListener(messageName, function(message) { let data = message.data; switch (data.op) { case "info": { info(data.msg); break; } case "ok": { ok(data.condition, data.name, data.diag); break; } case "done": { testGenerator.send(data.result); break; } default: { ok(false, "Unknown op: " + data.op); SimpleTest.finish(); } } }); mm.loadFrameScript("data:,(" + childFrameScript.toString() + ")();", false); mm.sendAsyncMessage(messageName, blob); } function setup() { info("Got load event"); SpecialPowers.pushPrefEnv( { set: [ ["dom.ipc.browser_frames.oop_by_default", true], ["dom.mozBrowserFramesEnabled", true], ["network.disable.ipc.security", true], ["browser.pagethumbnails.capturing_disabled", true] ] }, function() { info("Prefs set"); SpecialPowers.pushPermissions( [ { type: "browser", allow: true, context: document } ], function() { info("Permissions set"); let iframe = document.createElement("iframe"); SpecialPowers.wrap(iframe).mozbrowser = true; iframe.id = "iframe"; iframe.src = "data:text/html,<!DOCTYPE HTML><html><body></body></html>"; iframe.addEventListener("mozbrowserloadend", function() { info("Starting tests"); let mm = SpecialPowers.getBrowserFrameMessageManager(iframe) parentFrameScript(mm); }); document.body.appendChild(iframe); } ); } ); } SimpleTest.waitForExplicitFinish(); </script> </body> </html>