Upload Kmake

This commit is contained in:
Gorochu
2026-05-26 23:36:42 -07:00
parent ba051b2f74
commit 555ec72358
41615 changed files with 13344630 additions and 1 deletions

View File

@ -0,0 +1,62 @@
<!doctype html>
<meta charset="utf-8">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/common/get-host-info.sub.js"></script>
<body>
<script>
async_test(t => {
const blob_contents = 'test blob contents';
const blob = new Blob([blob_contents]);
const url = URL.createObjectURL(blob);
const frame = document.createElement('iframe');
frame.setAttribute('style', 'display:none;');
frame.src = 'resources/revoke-helper.html';
document.body.appendChild(frame);
frame.onload = t.step_func(e => {
frame.contentWindow.postMessage({url: url}, '*');
});
self.addEventListener('message', t.step_func(e => {
if (e.source !== frame.contentWindow) return;
assert_equals(e.data, 'revoked');
promise_rejects_js(t, TypeError, fetch(url)).then(t.step_func_done());
}));
}, 'It is possible to revoke same-origin blob URLs from different frames.');
async_test(t => {
const blob_contents = 'test blob contents';
const blob = new Blob([blob_contents]);
const url = URL.createObjectURL(blob);
const worker = new Worker('resources/revoke-helper.js');
worker.onmessage = t.step_func(e => {
assert_equals(e.data, 'revoked');
promise_rejects_js(t, TypeError, fetch(url)).then(t.step_func_done());
});
worker.postMessage({url: url});
}, 'It is possible to revoke same-origin blob URLs from a different worker global.');
async_test(t => {
const blob_contents = 'test blob contents';
const blob = new Blob([blob_contents]);
const url = URL.createObjectURL(blob);
const frame = document.createElement('iframe');
frame.setAttribute('style', 'display:none;');
frame.src = get_host_info().HTTP_REMOTE_ORIGIN + '/FileAPI/url/resources/revoke-helper.html';
document.body.appendChild(frame);
frame.onload = t.step_func(e => {
frame.contentWindow.postMessage({url: url}, '*');
});
self.addEventListener('message', t.step_func(e => {
if (e.source !== frame.contentWindow) return;
assert_equals(e.data, 'revoked');
fetch(url).then(response => response.text()).then(t.step_func_done(text => {
assert_equals(text, blob_contents);
}), t.unreached_func('Unexpected promise rejection'));
}));
}, 'It is not possible to revoke cross-origin blob URLs.');
</script>

View File

@ -0,0 +1,26 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>Blob URL serialization (specifically the origin) in multi-global situations</title>
<link rel="help" href="https://w3c.github.io/FileAPI/#unicodeBlobURL">
<link rel="author" title="Domenic Denicola" href="mailto:d@domenic.me">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<!-- this page is the entry global -->
<iframe src="//{{domains[www]}}:{{location[port]}}/FileAPI/support/incumbent.sub.html"></iframe>
<script>
"use strict";
setup({ single_test: true });
document.domain = "{{host}}";
window.onload = () => {
const url = frames[0].createBlobURL();
const desired = "blob:{{location[scheme]}}://www1";
assert_equals(url.substring(0, desired.length), desired,
"Origin should contain www1, from the current settings object");
done();
};
</script>

View File

@ -0,0 +1,7 @@
<!doctype html>
<script>
self.addEventListener('message', e => {
let url = URL.createObjectURL(e.data.blob);
e.source.postMessage({url: url}, '*');
});
</script>

View File

@ -0,0 +1,4 @@
self.addEventListener('message', e => {
let url = URL.createObjectURL(e.data.blob);
self.postMessage({url: url});
});

View File

@ -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');
}
}

View File

@ -0,0 +1,7 @@
<!doctype html>
<script>
self.addEventListener('message', e => {
URL.revokeObjectURL(e.data.url);
e.source.postMessage('revoked', '*');
});
</script>

View File

@ -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');
});

View File

@ -0,0 +1,32 @@
<!doctype html>
<meta charset="utf-8">
<title>FileAPI Test: Verify behavior of Blob URL in unique origins</title>
<meta name="timeout" content="long">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<iframe id="sandboxed-iframe" sandbox="allow-scripts"></iframe>
<script>
const iframe_scripts = [
'resources/fetch-tests.js',
'url-format.any.js',
'url-in-tags.window.js',
'url-with-xhr.any.js',
'url-with-fetch.any.js',
];
let html = '<!doctype html>\n<meta charset="utf-8">\n<body>\n';
html = html + '<script src="/resources/testharness.js"></' + 'script>\n';
html = html + '<script>setup({"explicit_timeout": true});</' + 'script>\n';
for (const script of iframe_scripts)
html = html + '<script src="' + script + '"></' + 'script>\n';
const frame = document.querySelector('#sandboxed-iframe');
frame.setAttribute('srcdoc', html);
frame.setAttribute('style', 'display:none;');
fetch_tests_from_window(frame.contentWindow);
</script>

View File

@ -0,0 +1,23 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>FileAPI Test: Verify origin of Blob URL</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<body>
<script>
async_test(t => {
const frame = document.createElement('iframe');
self.addEventListener('message', t.step_func(e => {
if (e.source != frame.contentWindow) return;
const url = e.data.url;
assert_false(url.includes('天気の良い日'),
'Origin should be ascii rather than unicode');
assert_equals(new URL(url).origin, e.origin,
'Origin of URL should match origin of frame');
assert_true(url.startsWith('blob:{{location[scheme]}}://xn--'));
t.done();
}));
frame.src = '{{location[scheme]}}://{{domains[天気の良い日]}}:{{location[port]}}/FileAPI/support/url-origin.html';
document.body.appendChild(frame);
}, 'Verify serialization of non-ascii origin in Blob URLs');
</script>

View File

@ -0,0 +1,34 @@
async_test(t => {
// This could be detected as ISO-2022-JP, in which case there would be no
// <textarea>, and thus the script inside would be interpreted as actual
// script.
const blob = new Blob(
[
`aaa\u001B$@<textarea>\u001B(B<script>/* xss */<\/script></textarea>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(
[`<!doctype html>\n<meta charset="ISO-8859-1">`],
{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 <meta charset>.');

View File

@ -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');

View File

@ -0,0 +1,115 @@
// META: timeout=long
async_test(t => {
const run_result = 'test_frame_OK';
const blob_contents = '<!doctype html>\n<meta charset="utf-8">\n' +
'<script>window.test_result = "' + run_result + '";</script>';
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 = '<!doctype html>\n<meta charset="utf-8">\n' +
'<script>window.test_result = "' + run_result + '";</script>';
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 = '<!doctype html>\n<meta charset="utf-8">\n' +
'<script>window.test_result = "' + run_result + '";</script>';
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 '<!doctype html>\n' +
'<script>\n' +
'new BroadcastChannel("' + channel_name + '").postMessage("foobar");\n' +
'self.close();\n' +
'</script>';
}
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 <script> tags.');
async_test(t => {
const channel_name = 'a-click-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 anchor = document.createElement('a');
anchor.href = url;
anchor.target = '_blank';
document.body.appendChild(anchor);
anchor.click();
URL.revokeObjectURL(url);
}, 'Opening a blob URL in a new window by clicking an <a> tag works immediately before revoking the URL.');

View File

@ -0,0 +1,48 @@
async_test(t => {
const run_result = 'test_script_OK';
const blob_contents = 'window.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.test_result, run_result);
});
document.body.appendChild(e);
}, 'Blob URLs can be used in <script> tags');
async_test(t => {
const run_result = 'test_frame_OK';
const blob_contents = '<!doctype html>\n<meta charset="utf-8">\n' +
'<script>window.test_result = "' + run_result + '";</script>';
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 = '<!doctype html>\n<meta charset="utf-8">\n' +
'<style>body { margin: 0; } .block { height: 5000px; }</style>\n' +
'<body>\n' +
'<a id="block1"></a><div class="block"></div>\n' +
'<a id="block2"></a><div class="block"></div>';
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.');

View File

@ -0,0 +1,56 @@
<!doctype html>
<meta charset="utf-8">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<body>
<script>
promise_test(t => {
const blob_contents = 'test blob contents';
const blob = new Blob([blob_contents]);
const worker = new Worker('resources/create-helper.js');
let url;
return new Promise(resolve => {
worker.onmessage = e => resolve(e.data);
worker.postMessage({blob: blob});
}).then(data => {
url = data.url;
let result = fetch(url);
worker.terminate();
return result;
}).then(response => response.text()).then(text => {
assert_equals(text, blob_contents);
return new Promise(resolve => t.step_timeout(resolve, 100));
}).then(() => promise_rejects_js(t, TypeError, fetch(url)));
}, 'Terminating worker revokes its URLs');
promise_test(t => {
const blob_contents = 'test blob contents';
const blob = new Blob([blob_contents]);
const frame = document.createElement('iframe');
frame.setAttribute('style', 'display:none;');
frame.src = 'resources/create-helper.html';
document.body.appendChild(frame);
let url;
return new Promise(resolve => {
frame.onload = t.step_func(e => {
resolve(e);
});
}).then(e => {
frame.contentWindow.postMessage({blob: blob}, '*');
return new Promise(resolve => {
self.addEventListener('message', t.step_func(e => {
if (e.source === frame.contentWindow) resolve(e);
}));
});
}).then(e => {
url = e.data.url;
let fetch_result = fetch(url);
document.body.removeChild(frame);
return fetch_result;
}).then(response => response.text()).then(text => {
assert_equals(text, blob_contents);
return new Promise(resolve => t.step_timeout(resolve, 100));
}).then(() => promise_rejects_js(t, TypeError, fetch(url)));
}, 'Removing an iframe revokes its URLs');
</script>

View File

@ -0,0 +1,36 @@
function blob_url_reload_test(t, revoke_before_reload) {
const run_result = 'test_frame_OK';
const blob_contents = '<!doctype html>\n<meta charset="utf-8">\n' +
'<script>window.test_result = "' + run_result + '";</script>';
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.');

View File

@ -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');

View File

@ -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');

View File

@ -0,0 +1,45 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>FileAPI Test: Creating Blob URL with File</title>
<link rel="author" title="Intel" href="http://www.intel.com">
<link rel="author" title="JunChen Xia" href="mailto:xjconlyme@gmail.com">
<meta name="timeout" content="long">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div>
<p>Test steps:</p>
<ol>
<li>Download <a href="/images/blue96x96.png">blue96x96.png</a> to local.</li>
<li>Select the local file (blue96x96.png) to run the test.</li>
</ol>
</div>
<form name="uploadData">
<input type="file" id="fileChooser">
</form>
<div id="log"></div>
<script>
async_test(function(t) {
var fileInput = document.querySelector('#fileChooser');
fileInput.onchange = t.step_func(function(e) {
var blobURL, file = fileInput.files[0];
test(function() {
assert_true(file instanceof File, "FileList contains File");
}, "Check if FileList contains File");
test(function() {
blobURL = window.URL.createObjectURL(file);
assert_equals(typeof blobURL, "string", "Blob URL is type of string");
assert_equals(blobURL.indexOf("blob"), 0, "Blob URL's scheme is blob");
}, "Check if URL.createObjectURL(File) returns a Blob URL");
t.done();
});
});
</script>

View File

@ -0,0 +1,28 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>FileAPI Test: Creating Blob URL with File as image source</title>
<link rel="author" title="Intel" href="http://www.intel.com">
<link rel="author" title="JunChen Xia" href="mailto:xjconlyme@gmail.com">
<div>
<p>Test steps:</p>
<ol>
<li>Download <a href="/images/blue96x96.png">blue96x96.png</a> to local.</li>
<li>Select the local file (blue96x96.png) to run the test.</li>
</ol>
<p>Pass/fail criteria:</p>
<p>Test passes if there is a filled blue square.</p>
<p><input type="file" accept="image/*" id="fileChooser"></p>
<p><img id="displayImage"></img></p>
</div>
<script>
var fileInput = document.querySelector("#fileChooser");
var img = document.querySelector("#displayImage");
fileInput.addEventListener("change", function(evt) {
img.src = window.URL.createObjectURL(fileInput.files[0]);
}, false);
</script>

View File

@ -0,0 +1,12 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>FileAPI Reference File</title>
<link rel="author" title="Intel" href="http://www.intel.com">
<link rel="author" title="JunChen Xia" href="mailto:xjconlyme@gmail.com">
<p>Test passes if there is a filled blue square.</p>
<p>
<img id="fileDisplay" src="/images/blue96x96.png">
</p>

View File

@ -0,0 +1,27 @@
<!DOCTYPE html>
<html class="reftest-wait">
<meta charset="utf-8">
<title>FileAPI Test: Creating Blob URL via XMLHttpRequest as image source</title>
<link rel="author" title="Intel" href="http://www.intel.com">
<link rel="author" title="JunChen Xia" href="mailto:xjconlyme@gmail.com">
<link rel="match" href="url_xmlhttprequest_img-ref.html">
<p>Test passes if there is a filled blue square.</p>
<p>
<img id="fileDisplay">
</p>
<script src="/common/reftest-wait.js"></script>
<script>
var http = new XMLHttpRequest();
http.open("GET", "/images/blue96x96.png", true);
http.responseType = "blob";
http.onloadend = function() {
var fileDisplay = document.querySelector("#fileDisplay");
fileDisplay.src = window.URL.createObjectURL(http.response);
fileDisplay.onload = takeScreenshot;
};
http.send();
</script>
</html>