"use strict"; const { XPCShellContentUtils } = ChromeUtils.importESModule( "resource://testing-common/XPCShellContentUtils.sys.mjs" ); XPCShellContentUtils.init(this); function childFrameScript() { /* eslint-env mozilla/frame-script */ const messageName = "test:blob-slice-test"; const blobData = ["So", " ", "many", " ", "blobs!"]; const blobText = blobData.join(""); const blobType = "text/plain"; const sliceText = "an"; function info(msg) { sendAsyncMessage(messageName, { op: "info", msg }); } function ok(condition, name, diag) { sendAsyncMessage(messageName, { op: "ok", condition, name, 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(messageName, { op: "done", result }); } function grabAndContinue(arg) { testGenerator.next(arg); } function* testSteps() { addMessageListener(messageName, grabAndContinue); let message = yield undefined; let blob = message.data; ok(Blob.isInstance(blob), "Received 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 firstSliceStart = blobData[0].length + blobData[1].length; let firstSliceEnd = firstSliceStart + blobData[2].length; let slice = blob.slice(firstSliceStart, firstSliceEnd, blobType); ok(Blob.isInstance(slice), "Slice returned a Blob"); is(slice.size, blobData[2].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[2], "Slice has correct data"); let secondSliceStart = blobData[2].indexOf("a"); let secondSliceEnd = secondSliceStart + sliceText.length; slice = slice.slice(secondSliceStart, secondSliceEnd, blobType); ok(Blob.isInstance(slice), "Second slice returned a Blob"); is(slice.size, sliceText.length, "Second slice has correct length"); is(slice.type, blobType, "Second slice has correct type"); info("Sending second slice"); finish(slice); } let testGenerator = testSteps(); testGenerator.next(); } add_task(async function test() { let page = await XPCShellContentUtils.loadContentPage( "data:text/html,", { remote: true, } ); page.loadFrameScript(childFrameScript); const messageName = "test:blob-slice-test"; const blobData = ["So", " ", "many", " ", "blobs!"]; const blobType = "text/plain"; const sliceText = "an"; await new Promise(resolve => { function grabAndContinue(arg) { testGenerator.next(arg); } function* testSteps() { let slice = yield undefined; ok(Blob.isInstance(slice), "Received a Blob"); equal(slice.size, sliceText.length, "Slice has correct size"); equal(slice.type, blobType, "Slice has correct type"); let reader = new FileReader(); reader.onload = grabAndContinue; reader.readAsText(slice); yield undefined; equal(reader.result, sliceText, "Slice has correct data"); resolve(); } let testGenerator = testSteps(); testGenerator.next(); let mm = page.browser.messageManager; 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.next(data.result); break; } default: { ok(false, "Unknown op: " + data.op); resolve(); } } }); let blob = new Blob(blobData, { type: blobType }); mm.sendAsyncMessage(messageName, blob); }); await page.close(); });