diff --git a/html/browsers/origin/api/file-scheme-origin.tentative.any.js b/html/browsers/origin/api/file-scheme-origin.tentative.any.js
new file mode 100644
index 00000000000000..c636cee965703d
--- /dev/null
+++ b/html/browsers/origin/api/file-scheme-origin.tentative.any.js
@@ -0,0 +1,15 @@
+// META: title=`Origin.from('file://')`
+
+test(t => {
+ const fileURL = "file:///path/to/a/file.txt";
+ const opaqueA = Origin.from(fileURL);
+ const opaqueB = Origin.from(fileURL);
+
+ assert_true(opaqueA.opaque);
+ assert_true(opaqueB.opaque);
+
+ assert_true(opaqueA.isSameOrigin(opaqueA), "Opaque origin should be same-origin with itself.");
+ assert_true(opaqueA.isSameSite(opaqueA), "Opaque origin should be same-site with itself.");
+ assert_false(opaqueA.isSameOrigin(opaqueB), "Opaque origin should not be same-origin with another opaque origin.");
+ assert_false(opaqueA.isSameSite(opaqueB), "Opaque origin should not be same-site with another opaque origin, even if created from same URL.");
+}, "`Origin.from('file://')` opaque origins.");
diff --git a/html/browsers/origin/api/origin-comparison.any.js b/html/browsers/origin/api/origin-comparison.any.js
index 06fe9befaf811c..e0ca06a536c32e 100644
--- a/html/browsers/origin/api/origin-comparison.any.js
+++ b/html/browsers/origin/api/origin-comparison.any.js
@@ -10,7 +10,7 @@ test(t => {
assert_true(opaqueA.isSameSite(opaqueA), "Opaque origin should be same-site with itself.");
assert_false(opaqueA.isSameOrigin(opaqueB), "Opaque origin should not be same-origin with another opaque origin.");
assert_false(opaqueA.isSameSite(opaqueB), "Opaque origin should not be same-site with another opaque origin.");
-}, "Comparison of opaque origins.");
+}, "Comparison of `new Origin()` opaque origins.");
test(t => {
const a = Origin.from("https://a.example");
@@ -48,3 +48,16 @@ test(t => {
assert_false(http.isSameSite(https), "http is not same-site with https");
assert_false(https.isSameSite(http), "https is not same-site with http");
}, "Comparisons are schemeful.");
+
+test(t => {
+ const dataURL = "data:text/plain,opaque";
+ const opaqueA = Origin.from(dataURL);
+ const opaqueB = Origin.from(dataURL);
+ assert_true(opaqueA.opaque);
+ assert_true(opaqueB.opaque);
+
+ assert_true(opaqueA.isSameOrigin(opaqueA), "Opaque origin should be same-origin with itself.");
+ assert_true(opaqueA.isSameSite(opaqueA), "Opaque origin should be same-site with itself.");
+ assert_false(opaqueA.isSameOrigin(opaqueB), "Opaque origin should not be same-origin with another opaque origin.");
+ assert_false(opaqueA.isSameSite(opaqueB), "Opaque origin should not be same-site with another opaque origin, even if created from same URL.");
+}, "Comparison of `Origin.from()` opaque origins.");
diff --git a/html/browsers/origin/api/origin-from-htmlhyperlinkelementutils.window.js b/html/browsers/origin/api/origin-from-htmlhyperlinkelementutils.window.js
index 3bb317a2cb482b..214a216360427d 100644
--- a/html/browsers/origin/api/origin-from-htmlhyperlinkelementutils.window.js
+++ b/html/browsers/origin/api/origin-from-htmlhyperlinkelementutils.window.js
@@ -19,6 +19,8 @@ for (const opaque of urls.opaque) {
const origin = Origin.from(a);
assert_true(!!origin);
assert_true(origin.opaque);
+ assert_true(origin.isSameOrigin(origin));
+ assert_false(origin.isSameOrigin(Origin.from(a)));
}, `Origin.from() returns an opaque origin.`);
//
@@ -28,6 +30,8 @@ for (const opaque of urls.opaque) {
const origin = Origin.from(area);
assert_true(!!origin);
assert_true(origin.opaque);
+ assert_true(origin.isSameOrigin(origin));
+ assert_false(origin.isSameOrigin(Origin.from(area)));
}, `Origin.from() returns an opaque origin.`);
}
@@ -39,6 +43,8 @@ for (const tuple of urls.tuple) {
const origin = Origin.from(a);
assert_true(!!origin);
assert_false(origin.opaque);
+ assert_true(origin.isSameOrigin(origin));
+ assert_true(origin.isSameOrigin(Origin.from(a)));
}, `Origin.from() returns a tuple origin.`);
//
@@ -48,7 +54,7 @@ for (const tuple of urls.tuple) {
const origin = Origin.from(area);
assert_true(!!origin);
assert_false(origin.opaque);
+ assert_true(origin.isSameOrigin(origin));
+ assert_true(origin.isSameOrigin(Origin.from(area)));
}, `Origin.from() returns a tuple origin.`);
}
-
-
diff --git a/html/browsers/origin/api/origin-from-window.window.js b/html/browsers/origin/api/origin-from-window.window.js
index 78543db246b8da..ca9309f405dbef 100644
--- a/html/browsers/origin/api/origin-from-window.window.js
+++ b/html/browsers/origin/api/origin-from-window.window.js
@@ -1,4 +1,4 @@
-// META: title=`Origin.from(Location)`
+// META: title=`Origin.from(Window)`
// META: script=/common/get-host-info.sub.js
test(t => {
@@ -62,3 +62,26 @@ async_test(t => {
}
}));
}, `Origin.from(Window) throws for cross-origin windows.`);
+
+async_test(t => {
+ const html = `
+`;
+
+ const el = document.createElement('iframe');
+ el.src = `data:text/html;base64,${btoa(html)}`;
+ window.addEventListener("message", t.step_func(e => {
+ if (e.source === el.contentWindow) {
+ assert_true(e.data.isOpaque, "Origin should be opaque.");
+ assert_true(e.data.sameOrigin, "Window's origin should be same-origin with itself.");
+ t.done();
+ }
+ }));
+ document.body.appendChild(el);
+}, `Origin.from(Window) returns an opaque origin for a data URL source.`);
diff --git a/html/browsers/origin/api/origin-from-worker.window.js b/html/browsers/origin/api/origin-from-worker.window.js
new file mode 100644
index 00000000000000..68495a855e5584
--- /dev/null
+++ b/html/browsers/origin/api/origin-from-worker.window.js
@@ -0,0 +1,29 @@
+// META: title=`Origin.from(Worker)`
+
+const src = `
+const originA = Origin.from(globalThis);
+const originB = Origin.from(globalThis);
+
+self.postMessage({
+ "isOpaque": originA.opaque,
+ "sameOrigin": originA.isSameOrigin(originB),
+});
+`;
+
+async_test(t => {
+ const dataURL = `data:text/html;base64,${btoa(src)}`;
+ const worker = new Worker(dataURL);
+ worker.onmessage = t.step_func_done(m => {
+ assert_true(m.data.isOpaque, "Origin created from data URL Worker should be an opaque origin.");
+ assert_true(m.data.sameOrigin, "Two data URL opaque origins should be same-origin with one another.");
+ });
+}, "Comparison of `Origin.from(Worker)` for opaque data URL origin.");
+
+async_test(t => {
+ const blob = new Blob([src], { type: 'application/javascript' });
+ const worker = new Worker(URL.createObjectURL(blob));
+ worker.onmessage = t.step_func_done(m => {
+ assert_false(m.data.isOpaque, "Origin created from Worker should be a tuple origin.");
+ assert_true(m.data.sameOrigin, "Two tuple origins should be same-origin with one another.");
+ });
+}, "Comparison of `Origin.from(Worker)` tuple origins.");
diff --git a/html/browsers/origin/api/resources/serializations.js b/html/browsers/origin/api/resources/serializations.js
index dec7fbdd1da7fe..8fd8fad2546c84 100644
--- a/html/browsers/origin/api/resources/serializations.js
+++ b/html/browsers/origin/api/resources/serializations.js
@@ -26,7 +26,6 @@ const urls = {
"https://user:pass@site.example",
"https://has.a.port:1234/and/path",
"https://ümlauted.example",
- "file:///path/to/a/file.txt",
"blob:https://example.com/some-guid",
"ftp://example.com/",
"https://example.com/path?query#fragment",