From 0b6210cd37b68b94252cb798598b12974a20e1c1 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Tue, 21 May 2024 22:56:19 +0200 Subject: Adding upstream version 5.28.2+dfsg1+~cs23.11.12.3. Signed-off-by: Daniel Baumann --- .../tests/FileAPI/url/cross-global-revoke.sub.html | 62 +++++++++++ .../url/multi-global-origin-serialization.sub.html | 26 +++++ .../tests/FileAPI/url/resources/create-helper.html | 7 ++ .../tests/FileAPI/url/resources/create-helper.js | 4 + .../wpt/tests/FileAPI/url/resources/fetch-tests.js | 71 +++++++++++++ .../tests/FileAPI/url/resources/revoke-helper.html | 7 ++ .../tests/FileAPI/url/resources/revoke-helper.js | 9 ++ test/wpt/tests/FileAPI/url/sandboxed-iframe.html | 32 ++++++ test/wpt/tests/FileAPI/url/unicode-origin.sub.html | 23 +++++ test/wpt/tests/FileAPI/url/url-charset.window.js | 34 ++++++ test/wpt/tests/FileAPI/url/url-format.any.js | 70 +++++++++++++ .../tests/FileAPI/url/url-in-tags-revoke.window.js | 115 +++++++++++++++++++++ test/wpt/tests/FileAPI/url/url-in-tags.window.js | 48 +++++++++ test/wpt/tests/FileAPI/url/url-lifetime.html | 56 ++++++++++ test/wpt/tests/FileAPI/url/url-reload.window.js | 36 +++++++ test/wpt/tests/FileAPI/url/url-with-fetch.any.js | 72 +++++++++++++ test/wpt/tests/FileAPI/url/url-with-xhr.any.js | 68 ++++++++++++ .../url/url_createobjecturl_file-manual.html | 45 ++++++++ .../url/url_createobjecturl_file_img-manual.html | 28 +++++ .../FileAPI/url/url_xmlhttprequest_img-ref.html | 12 +++ .../tests/FileAPI/url/url_xmlhttprequest_img.html | 27 +++++ 21 files changed, 852 insertions(+) create mode 100644 test/wpt/tests/FileAPI/url/cross-global-revoke.sub.html create mode 100644 test/wpt/tests/FileAPI/url/multi-global-origin-serialization.sub.html create mode 100644 test/wpt/tests/FileAPI/url/resources/create-helper.html create mode 100644 test/wpt/tests/FileAPI/url/resources/create-helper.js create mode 100644 test/wpt/tests/FileAPI/url/resources/fetch-tests.js create mode 100644 test/wpt/tests/FileAPI/url/resources/revoke-helper.html create mode 100644 test/wpt/tests/FileAPI/url/resources/revoke-helper.js create mode 100644 test/wpt/tests/FileAPI/url/sandboxed-iframe.html create mode 100644 test/wpt/tests/FileAPI/url/unicode-origin.sub.html create mode 100644 test/wpt/tests/FileAPI/url/url-charset.window.js create mode 100644 test/wpt/tests/FileAPI/url/url-format.any.js create mode 100644 test/wpt/tests/FileAPI/url/url-in-tags-revoke.window.js create mode 100644 test/wpt/tests/FileAPI/url/url-in-tags.window.js create mode 100644 test/wpt/tests/FileAPI/url/url-lifetime.html create mode 100644 test/wpt/tests/FileAPI/url/url-reload.window.js create mode 100644 test/wpt/tests/FileAPI/url/url-with-fetch.any.js create mode 100644 test/wpt/tests/FileAPI/url/url-with-xhr.any.js create mode 100644 test/wpt/tests/FileAPI/url/url_createobjecturl_file-manual.html create mode 100644 test/wpt/tests/FileAPI/url/url_createobjecturl_file_img-manual.html create mode 100644 test/wpt/tests/FileAPI/url/url_xmlhttprequest_img-ref.html create mode 100644 test/wpt/tests/FileAPI/url/url_xmlhttprequest_img.html (limited to 'test/wpt/tests/FileAPI/url') diff --git a/test/wpt/tests/FileAPI/url/cross-global-revoke.sub.html b/test/wpt/tests/FileAPI/url/cross-global-revoke.sub.html new file mode 100644 index 0000000..ce9d680 --- /dev/null +++ b/test/wpt/tests/FileAPI/url/cross-global-revoke.sub.html @@ -0,0 +1,62 @@ + + + + + + + diff --git a/test/wpt/tests/FileAPI/url/multi-global-origin-serialization.sub.html b/test/wpt/tests/FileAPI/url/multi-global-origin-serialization.sub.html new file mode 100644 index 0000000..0052b26 --- /dev/null +++ b/test/wpt/tests/FileAPI/url/multi-global-origin-serialization.sub.html @@ -0,0 +1,26 @@ + + +Blob URL serialization (specifically the origin) in multi-global situations + + + + + + + + + + + diff --git a/test/wpt/tests/FileAPI/url/resources/create-helper.html b/test/wpt/tests/FileAPI/url/resources/create-helper.html new file mode 100644 index 0000000..fa6cf4e --- /dev/null +++ b/test/wpt/tests/FileAPI/url/resources/create-helper.html @@ -0,0 +1,7 @@ + + \ No newline at end of file diff --git a/test/wpt/tests/FileAPI/url/resources/create-helper.js b/test/wpt/tests/FileAPI/url/resources/create-helper.js new file mode 100644 index 0000000..e6344f7 --- /dev/null +++ b/test/wpt/tests/FileAPI/url/resources/create-helper.js @@ -0,0 +1,4 @@ +self.addEventListener('message', e => { + let url = URL.createObjectURL(e.data.blob); + self.postMessage({url: url}); +}); diff --git a/test/wpt/tests/FileAPI/url/resources/fetch-tests.js b/test/wpt/tests/FileAPI/url/resources/fetch-tests.js new file mode 100644 index 0000000..a81ea1e --- /dev/null +++ b/test/wpt/tests/FileAPI/url/resources/fetch-tests.js @@ -0,0 +1,71 @@ +// This method generates a number of tests verifying fetching of blob URLs, +// allowing the same tests to be used both with fetch() and XMLHttpRequest. +// +// |fetch_method| is only used in test names, and should describe the +// (javascript) method being used by the other two arguments (i.e. 'fetch' or 'XHR'). +// +// |fetch_should_succeed| is a callback that is called with the Test and a URL. +// Fetching the URL is expected to succeed. The callback should return a promise +// resolved with whatever contents were fetched. +// +// |fetch_should_fail| similarly is a callback that is called with the Test, a URL +// to fetch, and optionally a method to use to do the fetch. If no method is +// specified the callback should use the 'GET' method. Fetching of these URLs is +// expected to fail, and the callback should return a promise that resolves iff +// fetching did indeed fail. +function fetch_tests(fetch_method, fetch_should_succeed, fetch_should_fail) { + const blob_contents = 'test blob contents'; + const blob = new Blob([blob_contents]); + + promise_test(t => { + const url = URL.createObjectURL(blob); + + return fetch_should_succeed(t, url).then(text => { + assert_equals(text, blob_contents); + }); + }, 'Blob URLs can be used in ' + fetch_method); + + promise_test(t => { + const url = URL.createObjectURL(blob); + + return fetch_should_succeed(t, url + '#fragment').then(text => { + assert_equals(text, blob_contents); + }); + }, fetch_method + ' with a fragment should succeed'); + + promise_test(t => { + const url = URL.createObjectURL(blob); + URL.revokeObjectURL(url); + + return fetch_should_fail(t, url); + }, fetch_method + ' of a revoked URL should fail'); + + promise_test(t => { + const url = URL.createObjectURL(blob); + URL.revokeObjectURL(url + '#fragment'); + + return fetch_should_succeed(t, url).then(text => { + assert_equals(text, blob_contents); + }); + }, 'Only exact matches should revoke URLs, using ' + fetch_method); + + promise_test(t => { + const url = URL.createObjectURL(blob); + + return fetch_should_fail(t, url + '?querystring'); + }, 'Appending a query string should cause ' + fetch_method + ' to fail'); + + promise_test(t => { + const url = URL.createObjectURL(blob); + + return fetch_should_fail(t, url + '/path'); + }, 'Appending a path should cause ' + fetch_method + ' to fail'); + + for (const method of ['HEAD', 'POST', 'DELETE', 'OPTIONS', 'PUT', 'CUSTOM']) { + const url = URL.createObjectURL(blob); + + promise_test(t => { + return fetch_should_fail(t, url, method); + }, fetch_method + ' with method "' + method + '" should fail'); + } +} \ No newline at end of file diff --git a/test/wpt/tests/FileAPI/url/resources/revoke-helper.html b/test/wpt/tests/FileAPI/url/resources/revoke-helper.html new file mode 100644 index 0000000..adf5a01 --- /dev/null +++ b/test/wpt/tests/FileAPI/url/resources/revoke-helper.html @@ -0,0 +1,7 @@ + + \ No newline at end of file diff --git a/test/wpt/tests/FileAPI/url/resources/revoke-helper.js b/test/wpt/tests/FileAPI/url/resources/revoke-helper.js new file mode 100644 index 0000000..c3e05b6 --- /dev/null +++ b/test/wpt/tests/FileAPI/url/resources/revoke-helper.js @@ -0,0 +1,9 @@ +self.addEventListener('message', e => { + URL.revokeObjectURL(e.data.url); + // Registering a new object URL will make absolutely sure that the revocation + // has propagated. Without this at least in chrome it is possible for the + // below postMessage to arrive at its destination before the revocation has + // been fully processed. + URL.createObjectURL(new Blob([])); + self.postMessage('revoked'); +}); diff --git a/test/wpt/tests/FileAPI/url/sandboxed-iframe.html b/test/wpt/tests/FileAPI/url/sandboxed-iframe.html new file mode 100644 index 0000000..a52939a --- /dev/null +++ b/test/wpt/tests/FileAPI/url/sandboxed-iframe.html @@ -0,0 +1,32 @@ + + +FileAPI Test: Verify behavior of Blob URL in unique origins + + + + + + + diff --git a/test/wpt/tests/FileAPI/url/unicode-origin.sub.html b/test/wpt/tests/FileAPI/url/unicode-origin.sub.html new file mode 100644 index 0000000..2c4921c --- /dev/null +++ b/test/wpt/tests/FileAPI/url/unicode-origin.sub.html @@ -0,0 +1,23 @@ + + +FileAPI Test: Verify origin of Blob URL + + + + diff --git a/test/wpt/tests/FileAPI/url/url-charset.window.js b/test/wpt/tests/FileAPI/url/url-charset.window.js new file mode 100644 index 0000000..777709b --- /dev/null +++ b/test/wpt/tests/FileAPI/url/url-charset.window.js @@ -0,0 +1,34 @@ +async_test(t => { + // This could be detected as ISO-2022-JP, in which case there would be no + // bbb` + ], + {type: 'text/html;charset=utf-8'}); + const url = URL.createObjectURL(blob); + const win = window.open(url); + t.add_cleanup(() => { + win.close(); + }); + + win.onload = t.step_func_done(() => { + assert_equals(win.document.charset, 'UTF-8'); + }); +}, 'Blob charset should override any auto-detected charset.'); + +async_test(t => { + const blob = new Blob( + [`\n`], + {type: 'text/html;charset=utf-8'}); + const url = URL.createObjectURL(blob); + const win = window.open(url); + t.add_cleanup(() => { + win.close(); + }); + + win.onload = t.step_func_done(() => { + assert_equals(win.document.charset, 'UTF-8'); + }); +}, 'Blob charset should override .'); diff --git a/test/wpt/tests/FileAPI/url/url-format.any.js b/test/wpt/tests/FileAPI/url/url-format.any.js new file mode 100644 index 0000000..69c5111 --- /dev/null +++ b/test/wpt/tests/FileAPI/url/url-format.any.js @@ -0,0 +1,70 @@ +// META: timeout=long +const blob = new Blob(['test']); +const file = new File(['test'], 'name'); + +test(t => { + const url_count = 5000; + let list = []; + + t.add_cleanup(() => { + for (let url of list) { + URL.revokeObjectURL(url); + } + }); + + for (let i = 0; i < url_count; ++i) + list.push(URL.createObjectURL(blob)); + + list.sort(); + + for (let i = 1; i < list.length; ++i) + assert_not_equals(list[i], list[i-1], 'generated Blob URLs should be unique'); +}, 'Generated Blob URLs are unique'); + +test(() => { + const url = URL.createObjectURL(blob); + assert_equals(typeof url, 'string'); + assert_true(url.startsWith('blob:')); +}, 'Blob URL starts with "blob:"'); + +test(() => { + const url = URL.createObjectURL(file); + assert_equals(typeof url, 'string'); + assert_true(url.startsWith('blob:')); +}, 'Blob URL starts with "blob:" for Files'); + +test(() => { + const url = URL.createObjectURL(blob); + assert_equals(new URL(url).origin, location.origin); + if (location.origin !== 'null') { + assert_true(url.includes(location.origin)); + assert_true(url.startsWith('blob:' + location.protocol)); + } +}, 'Origin of Blob URL matches our origin'); + +test(() => { + const url = URL.createObjectURL(blob); + const url_record = new URL(url); + assert_equals(url_record.protocol, 'blob:'); + assert_equals(url_record.origin, location.origin); + assert_equals(url_record.host, '', 'host should be an empty string'); + assert_equals(url_record.port, '', 'port should be an empty string'); + const uuid_path_re = /\/[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i; + assert_true(uuid_path_re.test(url_record.pathname), 'Path must end with a valid UUID'); + if (location.origin !== 'null') { + const nested_url = new URL(url_record.pathname); + assert_equals(nested_url.origin, location.origin); + assert_equals(nested_url.pathname.search(uuid_path_re), 0, 'Path must be a valid UUID'); + assert_true(url.includes(location.origin)); + assert_true(url.startsWith('blob:' + location.protocol)); + } +}, 'Blob URL parses correctly'); + +test(() => { + const url = URL.createObjectURL(file); + assert_equals(new URL(url).origin, location.origin); + if (location.origin !== 'null') { + assert_true(url.includes(location.origin)); + assert_true(url.startsWith('blob:' + location.protocol)); + } +}, 'Origin of Blob URL matches our origin for Files'); diff --git a/test/wpt/tests/FileAPI/url/url-in-tags-revoke.window.js b/test/wpt/tests/FileAPI/url/url-in-tags-revoke.window.js new file mode 100644 index 0000000..1cdad79 --- /dev/null +++ b/test/wpt/tests/FileAPI/url/url-in-tags-revoke.window.js @@ -0,0 +1,115 @@ +// META: timeout=long +async_test(t => { + const run_result = 'test_frame_OK'; + const blob_contents = '\n\n' + + ''; + const blob = new Blob([blob_contents], {type: 'text/html'}); + const url = URL.createObjectURL(blob); + + const frame = document.createElement('iframe'); + frame.setAttribute('src', url); + frame.setAttribute('style', 'display:none;'); + document.body.appendChild(frame); + URL.revokeObjectURL(url); + + frame.onload = t.step_func_done(() => { + assert_equals(frame.contentWindow.test_result, run_result); + }); +}, 'Fetching a blob URL immediately before revoking it works in an iframe.'); + +async_test(t => { + const run_result = 'test_frame_OK'; + const blob_contents = '\n\n' + + ''; + const blob = new Blob([blob_contents], {type: 'text/html'}); + const url = URL.createObjectURL(blob); + + const frame = document.createElement('iframe'); + frame.setAttribute('src', '/common/blank.html'); + frame.setAttribute('style', 'display:none;'); + document.body.appendChild(frame); + + frame.onload = t.step_func(() => { + frame.contentWindow.location = url; + URL.revokeObjectURL(url); + frame.onload = t.step_func_done(() => { + assert_equals(frame.contentWindow.test_result, run_result); + }); + }); +}, 'Fetching a blob URL immediately before revoking it works in an iframe navigation.'); + +async_test(t => { + const run_result = 'test_frame_OK'; + const blob_contents = '\n\n' + + ''; + const blob = new Blob([blob_contents], {type: 'text/html'}); + const url = URL.createObjectURL(blob); + const win = window.open(url); + URL.revokeObjectURL(url); + add_completion_callback(() => { win.close(); }); + + win.onload = t.step_func_done(() => { + assert_equals(win.test_result, run_result); + }); +}, 'Opening a blob URL in a new window immediately before revoking it works.'); + +function receive_message_on_channel(t, channel_name) { + const channel = new BroadcastChannel(channel_name); + return new Promise(resolve => { + channel.addEventListener('message', t.step_func(e => { + resolve(e.data); + })); + }); +} + +function window_contents_for_channel(channel_name) { + return '\n' + + ''; +} + +async_test(t => { + const channel_name = 'noopener-window-test'; + const blob = new Blob([window_contents_for_channel(channel_name)], {type: 'text/html'}); + receive_message_on_channel(t, channel_name).then(t.step_func_done(t => { + assert_equals(t, 'foobar'); + })); + const url = URL.createObjectURL(blob); + const win = window.open(); + win.opener = null; + win.location = url; + URL.revokeObjectURL(url); +}, 'Opening a blob URL in a noopener about:blank window immediately before revoking it works.'); + +async_test(t => { + const run_result = 'test_script_OK'; + const blob_contents = 'window.script_test_result = "' + run_result + '";'; + const blob = new Blob([blob_contents]); + const url = URL.createObjectURL(blob); + + const e = document.createElement('script'); + e.setAttribute('src', url); + e.onload = t.step_func_done(() => { + assert_equals(window.script_test_result, run_result); + }); + + document.body.appendChild(e); + URL.revokeObjectURL(url); +}, 'Fetching a blob URL immediately before revoking it works in '; + const blob = new Blob([blob_contents], {type: 'text/html'}); + const url = URL.createObjectURL(blob); + + const frame = document.createElement('iframe'); + frame.setAttribute('src', url); + frame.setAttribute('style', 'display:none;'); + document.body.appendChild(frame); + + frame.onload = t.step_func_done(() => { + assert_equals(frame.contentWindow.test_result, run_result); + }); +}, 'Blob URLs can be used in iframes, and are treated same origin'); + +async_test(t => { + const blob_contents = '\n\n' + + '\n' + + '\n' + + '
\n' + + '
'; + const blob = new Blob([blob_contents], {type: 'text/html'}); + const url = URL.createObjectURL(blob); + + const frame = document.createElement('iframe'); + frame.setAttribute('src', url + '#block2'); + document.body.appendChild(frame); + frame.contentWindow.onscroll = t.step_func_done(() => { + assert_equals(frame.contentWindow.scrollY, 5000); + }); +}, 'Blob URL fragment is implemented.'); diff --git a/test/wpt/tests/FileAPI/url/url-lifetime.html b/test/wpt/tests/FileAPI/url/url-lifetime.html new file mode 100644 index 0000000..ad5d667 --- /dev/null +++ b/test/wpt/tests/FileAPI/url/url-lifetime.html @@ -0,0 +1,56 @@ + + + + + + \ No newline at end of file diff --git a/test/wpt/tests/FileAPI/url/url-reload.window.js b/test/wpt/tests/FileAPI/url/url-reload.window.js new file mode 100644 index 0000000..d333b3a --- /dev/null +++ b/test/wpt/tests/FileAPI/url/url-reload.window.js @@ -0,0 +1,36 @@ +function blob_url_reload_test(t, revoke_before_reload) { + const run_result = 'test_frame_OK'; + const blob_contents = '\n\n' + + ''; + const blob = new Blob([blob_contents], {type: 'text/html'}); + const url = URL.createObjectURL(blob); + + const frame = document.createElement('iframe'); + frame.setAttribute('src', url); + frame.setAttribute('style', 'display:none;'); + document.body.appendChild(frame); + + frame.onload = t.step_func(() => { + if (revoke_before_reload) + URL.revokeObjectURL(url); + assert_equals(frame.contentWindow.test_result, run_result); + frame.contentWindow.test_result = null; + frame.onload = t.step_func_done(() => { + assert_equals(frame.contentWindow.test_result, run_result); + }); + // Slight delay before reloading to ensure revoke actually has had a chance + // to be processed. + t.step_timeout(() => { + frame.contentWindow.location.reload(); + }, 250); + }); +} + +async_test(t => { + blob_url_reload_test(t, false); +}, 'Reloading a blob URL succeeds.'); + + +async_test(t => { + blob_url_reload_test(t, true); +}, 'Reloading a blob URL succeeds even if the URL was revoked.'); diff --git a/test/wpt/tests/FileAPI/url/url-with-fetch.any.js b/test/wpt/tests/FileAPI/url/url-with-fetch.any.js new file mode 100644 index 0000000..54e6a3d --- /dev/null +++ b/test/wpt/tests/FileAPI/url/url-with-fetch.any.js @@ -0,0 +1,72 @@ +// META: script=resources/fetch-tests.js +// META: script=/common/gc.js + +function fetch_should_succeed(test, request) { + return fetch(request).then(response => response.text()); +} + +function fetch_should_fail(test, url, method = 'GET') { + return promise_rejects_js(test, TypeError, fetch(url, {method: method})); +} + +fetch_tests('fetch', fetch_should_succeed, fetch_should_fail); + +promise_test(t => { + const blob_contents = 'test blob contents'; + const blob_type = 'image/png'; + const blob = new Blob([blob_contents], {type: blob_type}); + const url = URL.createObjectURL(blob); + + return fetch(url).then(response => { + assert_equals(response.headers.get('Content-Type'), blob_type); + }); +}, 'fetch should return Content-Type from Blob'); + +promise_test(t => { + const blob_contents = 'test blob contents'; + const blob = new Blob([blob_contents]); + const url = URL.createObjectURL(blob); + const request = new Request(url); + + // Revoke the object URL. Request should take a reference to the blob as + // soon as it receives it in open(), so the request succeeds even though we + // revoke the URL before calling fetch(). + URL.revokeObjectURL(url); + + return fetch_should_succeed(t, request).then(text => { + assert_equals(text, blob_contents); + }); +}, 'Revoke blob URL after creating Request, will fetch'); + +promise_test(async t => { + const blob_contents = 'test blob contents'; + const blob = new Blob([blob_contents]); + const url = URL.createObjectURL(blob); + let request = new Request(url); + + // Revoke the object URL. Request should take a reference to the blob as + // soon as it receives it in open(), so the request succeeds even though we + // revoke the URL before calling fetch(). + URL.revokeObjectURL(url); + + request = request.clone(); + await garbageCollect(); + + const text = await fetch_should_succeed(t, request); + assert_equals(text, blob_contents); +}, 'Revoke blob URL after creating Request, then clone Request, will fetch'); + +promise_test(function(t) { + const blob_contents = 'test blob contents'; + const blob = new Blob([blob_contents]); + const url = URL.createObjectURL(blob); + + const result = fetch_should_succeed(t, url).then(text => { + assert_equals(text, blob_contents); + }); + + // Revoke the object URL. fetch should have already resolved the blob URL. + URL.revokeObjectURL(url); + + return result; +}, 'Revoke blob URL after calling fetch, fetch should succeed'); diff --git a/test/wpt/tests/FileAPI/url/url-with-xhr.any.js b/test/wpt/tests/FileAPI/url/url-with-xhr.any.js new file mode 100644 index 0000000..29d8308 --- /dev/null +++ b/test/wpt/tests/FileAPI/url/url-with-xhr.any.js @@ -0,0 +1,68 @@ +// META: script=resources/fetch-tests.js + +function xhr_should_succeed(test, url) { + return new Promise((resolve, reject) => { + const xhr = new XMLHttpRequest(); + xhr.open('GET', url); + xhr.onload = test.step_func(() => { + assert_equals(xhr.status, 200); + assert_equals(xhr.statusText, 'OK'); + resolve(xhr.response); + }); + xhr.onerror = () => reject('Got unexpected error event'); + xhr.send(); + }); +} + +function xhr_should_fail(test, url, method = 'GET') { + const xhr = new XMLHttpRequest(); + xhr.open(method, url); + const result1 = new Promise((resolve, reject) => { + xhr.onload = () => reject('Got unexpected load event'); + xhr.onerror = resolve; + }); + const result2 = new Promise(resolve => { + xhr.onreadystatechange = test.step_func(() => { + if (xhr.readyState !== xhr.DONE) return; + assert_equals(xhr.status, 0); + resolve(); + }); + }); + xhr.send(); + return Promise.all([result1, result2]); +} + +fetch_tests('XHR', xhr_should_succeed, xhr_should_fail); + +async_test(t => { + const blob_contents = 'test blob contents'; + const blob_type = 'image/png'; + const blob = new Blob([blob_contents], {type: blob_type}); + const url = URL.createObjectURL(blob); + const xhr = new XMLHttpRequest(); + xhr.open('GET', url); + xhr.onloadend = t.step_func_done(() => { + assert_equals(xhr.getResponseHeader('Content-Type'), blob_type); + }); + xhr.send(); +}, 'XHR should return Content-Type from Blob'); + +async_test(t => { + const blob_contents = 'test blob contents'; + const blob = new Blob([blob_contents]); + const url = URL.createObjectURL(blob); + const xhr = new XMLHttpRequest(); + xhr.open('GET', url); + + // Revoke the object URL. XHR should take a reference to the blob as soon as + // it receives it in open(), so the request succeeds even though we revoke the + // URL before calling send(). + URL.revokeObjectURL(url); + + xhr.onload = t.step_func_done(() => { + assert_equals(xhr.response, blob_contents); + }); + xhr.onerror = t.unreached_func('Got unexpected error event'); + + xhr.send(); +}, 'Revoke blob URL after open(), will fetch'); diff --git a/test/wpt/tests/FileAPI/url/url_createobjecturl_file-manual.html b/test/wpt/tests/FileAPI/url/url_createobjecturl_file-manual.html new file mode 100644 index 0000000..7ae3251 --- /dev/null +++ b/test/wpt/tests/FileAPI/url/url_createobjecturl_file-manual.html @@ -0,0 +1,45 @@ + + +FileAPI Test: Creating Blob URL with File + + + + + + +
+

Test steps:

+
    +
  1. Download blue96x96.png to local.
  2. +
  3. Select the local file (blue96x96.png) to run the test.
  4. +
+
+ +
+ +
+ +
+ + + diff --git a/test/wpt/tests/FileAPI/url/url_createobjecturl_file_img-manual.html b/test/wpt/tests/FileAPI/url/url_createobjecturl_file_img-manual.html new file mode 100644 index 0000000..534c1de --- /dev/null +++ b/test/wpt/tests/FileAPI/url/url_createobjecturl_file_img-manual.html @@ -0,0 +1,28 @@ + + +FileAPI Test: Creating Blob URL with File as image source + + + +
+

Test steps:

+
    +
  1. Download blue96x96.png to local.
  2. +
  3. Select the local file (blue96x96.png) to run the test.
  4. +
+

Pass/fail criteria:

+

Test passes if there is a filled blue square.

+ +

+

+
+ + + diff --git a/test/wpt/tests/FileAPI/url/url_xmlhttprequest_img-ref.html b/test/wpt/tests/FileAPI/url/url_xmlhttprequest_img-ref.html new file mode 100644 index 0000000..7d73904 --- /dev/null +++ b/test/wpt/tests/FileAPI/url/url_xmlhttprequest_img-ref.html @@ -0,0 +1,12 @@ + + +FileAPI Reference File + + + +

Test passes if there is a filled blue square.

+ +

+ +

+ diff --git a/test/wpt/tests/FileAPI/url/url_xmlhttprequest_img.html b/test/wpt/tests/FileAPI/url/url_xmlhttprequest_img.html new file mode 100644 index 0000000..468dcb0 --- /dev/null +++ b/test/wpt/tests/FileAPI/url/url_xmlhttprequest_img.html @@ -0,0 +1,27 @@ + + + +FileAPI Test: Creating Blob URL via XMLHttpRequest as image source + + + + +

Test passes if there is a filled blue square.

+ +

+ +

+ + + + -- cgit v1.2.3