LibWeb/HTML: Implement the Origin interface
See: https://github.com/whatwg/html/commit/68909b2
This commit is contained in:
parent
2c11e03582
commit
f9a996650b
45 changed files with 770 additions and 1 deletions
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include <AK/Weakable.h>
|
||||
#include <LibJS/Runtime/Object.h>
|
||||
#include <LibURL/Origin.h>
|
||||
#include <LibWeb/Export.h>
|
||||
#include <LibWeb/Forward.h>
|
||||
|
||||
|
|
@ -45,6 +46,10 @@ public:
|
|||
|
||||
JS::ThrowCompletionOr<bool> is_named_property_exposed_on_object(JS::PropertyKey const&) const;
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/browsers.html#extract-an-origin
|
||||
// Platform objects have an extract an origin operation, which returns null unless otherwise specified.
|
||||
virtual Optional<URL::Origin> extract_an_origin() const { return {}; }
|
||||
|
||||
protected:
|
||||
explicit PlatformObject(JS::Realm&, MayInterfereWithIndexedPropertyAccess = MayInterfereWithIndexedPropertyAccess::No);
|
||||
explicit PlatformObject(JS::Object& prototype, MayInterfereWithIndexedPropertyAccess = MayInterfereWithIndexedPropertyAccess::No);
|
||||
|
|
|
|||
|
|
@ -350,6 +350,7 @@ set(SOURCES
|
|||
DOM/Utils.cpp
|
||||
DOM/XMLDocument.cpp
|
||||
DOMURL/DOMURL.cpp
|
||||
DOMURL/Origin.cpp
|
||||
DOMURL/URLSearchParams.cpp
|
||||
DOMURL/URLSearchParamsIterator.cpp
|
||||
Dump.cpp
|
||||
|
|
|
|||
|
|
@ -482,4 +482,11 @@ Optional<URL::URL> parse(StringView input, Optional<URL::URL const&> base_url, O
|
|||
return url.release_value();
|
||||
}
|
||||
|
||||
// FIXME: At time of writing, still open spec MR: https://github.com/whatwg/url/pull/892
|
||||
Optional<URL::Origin> DOMURL::extract_an_origin() const
|
||||
{
|
||||
// Objects implementing the URL interface's extract an origin steps are to return this's URL's origin. [[HTML]]
|
||||
return m_url.origin();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -81,6 +81,8 @@ public:
|
|||
Optional<String> const& query() const { return m_url.query(); }
|
||||
void set_query(Badge<URLSearchParams>, Optional<String> query) { m_url.set_query(move(query)); }
|
||||
|
||||
virtual Optional<URL::Origin> extract_an_origin() const override;
|
||||
|
||||
private:
|
||||
DOMURL(JS::Realm&, URL::URL, GC::Ref<URLSearchParams> query);
|
||||
|
||||
|
|
|
|||
97
Libraries/LibWeb/DOMURL/Origin.cpp
Normal file
97
Libraries/LibWeb/DOMURL/Origin.cpp
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
* Copyright (c) 2025, Shannon Booth <shannon@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibURL/Parser.h>
|
||||
#include <LibWeb/Bindings/Intrinsics.h>
|
||||
#include <LibWeb/Bindings/OriginPrototype.h>
|
||||
#include <LibWeb/DOMURL/Origin.h>
|
||||
|
||||
namespace Web::DOMURL {
|
||||
|
||||
GC_DEFINE_ALLOCATOR(Origin);
|
||||
|
||||
Origin::Origin(JS::Realm& realm, URL::Origin origin)
|
||||
: PlatformObject(realm)
|
||||
, m_origin(move(origin))
|
||||
{
|
||||
}
|
||||
|
||||
Origin::~Origin() = default;
|
||||
|
||||
void Origin::initialize(JS::Realm& realm)
|
||||
{
|
||||
WEB_SET_PROTOTYPE_FOR_INTERFACE(Origin);
|
||||
Base::initialize(realm);
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/browsers.html#dom-origin-constructor
|
||||
GC::Ref<Origin> Origin::construct_impl(JS::Realm& realm)
|
||||
{
|
||||
// The new Origin() constructor steps are to set this's origin to a unique opaque origin.
|
||||
return realm.create<Origin>(realm, URL::Origin::create_opaque());
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/browsers.html#dom-origin-from
|
||||
WebIDL::ExceptionOr<GC::Ref<Origin>> Origin::from(JS::VM& vm, JS::Value value)
|
||||
{
|
||||
auto& realm = *vm.current_realm();
|
||||
|
||||
// 1. If value is a platform object:
|
||||
if (auto* object = value.as_if<Bindings::PlatformObject>()) {
|
||||
// 1. Let origin be the result of executing value's extract an origin operation.
|
||||
auto origin = object->extract_an_origin();
|
||||
|
||||
// 2. If origin is not null, then return a new Origin object whose origin is origin.
|
||||
if (origin.has_value())
|
||||
return realm.create<Origin>(realm, origin.release_value());
|
||||
}
|
||||
// 2. If value is a string:
|
||||
else if (value.is_string()) {
|
||||
auto string = value.as_string().utf8_string_view();
|
||||
|
||||
// 1. Let parsedURL be the result of basic URL parsing value.
|
||||
auto parsed_url = URL::Parser::basic_parse(string);
|
||||
|
||||
// 2. If parsedURL is not failure, then return a new Origin object whose origin is set to parsedURL's origin.
|
||||
if (parsed_url.has_value())
|
||||
return realm.create<Origin>(realm, parsed_url->origin());
|
||||
}
|
||||
|
||||
// 3. Throw a TypeError.
|
||||
return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, "Value is not a valid Origin"sv };
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/browsers.html#dom-origin-opaque
|
||||
bool Origin::opaque() const
|
||||
{
|
||||
// The opaque getter steps are to return true if this's origin is an opaque origin; otherwise false.
|
||||
return m_origin.is_opaque();
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/browsers.html#dom-origin-issameorigin
|
||||
bool Origin::is_same_origin(Origin const& other) const
|
||||
{
|
||||
// The isSameOrigin(other) method steps are to return true if this's origin is same origin with other's origin;
|
||||
// otherwise false.
|
||||
return m_origin.is_same_origin(other.m_origin);
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/browsers.html#dom-origin-issamesite
|
||||
bool Origin::is_same_site(Origin const& other) const
|
||||
{
|
||||
// The isSameSite(other) method steps are to return true if this's origin is same site with other's origin;
|
||||
// otherwise false.
|
||||
return m_origin.is_same_site(other.m_origin);
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/browsers.html#extract-an-origin
|
||||
Optional<URL::Origin> Origin::extract_an_origin() const
|
||||
{
|
||||
// Objects implementing the Origin interface's extract an origin steps are to return this's origin.
|
||||
return m_origin;
|
||||
}
|
||||
|
||||
}
|
||||
40
Libraries/LibWeb/DOMURL/Origin.h
Normal file
40
Libraries/LibWeb/DOMURL/Origin.h
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright (c) 2025, Shannon Booth <shannon@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibURL/URL.h>
|
||||
#include <LibWeb/Bindings/PlatformObject.h>
|
||||
#include <LibWeb/WebIDL/ExceptionOr.h>
|
||||
|
||||
namespace Web::DOMURL {
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/browsers.html#dom-origin-interface
|
||||
class Origin : public Bindings::PlatformObject {
|
||||
WEB_PLATFORM_OBJECT(Origin, Bindings::PlatformObject);
|
||||
GC_DECLARE_ALLOCATOR(Origin);
|
||||
|
||||
public:
|
||||
static GC::Ref<Origin> construct_impl(JS::Realm&);
|
||||
static WebIDL::ExceptionOr<GC::Ref<Origin>> from(JS::VM&, JS::Value);
|
||||
|
||||
bool opaque() const;
|
||||
bool is_same_origin(Origin const&) const;
|
||||
bool is_same_site(Origin const&) const;
|
||||
virtual Optional<URL::Origin> extract_an_origin() const override;
|
||||
|
||||
virtual ~Origin() override;
|
||||
|
||||
private:
|
||||
Origin(JS::Realm&, URL::Origin);
|
||||
virtual void initialize(JS::Realm&) override;
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/browsers.html#concept-origin-origin
|
||||
// Origin objects have an associated origin, which holds an origin.
|
||||
URL::Origin m_origin;
|
||||
};
|
||||
|
||||
}
|
||||
12
Libraries/LibWeb/DOMURL/Origin.idl
Normal file
12
Libraries/LibWeb/DOMURL/Origin.idl
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
// https://html.spec.whatwg.org/multipage/browsers.html#dom-origin-interface
|
||||
[Exposed=*]
|
||||
interface Origin {
|
||||
constructor();
|
||||
|
||||
static Origin from(any value);
|
||||
|
||||
readonly attribute boolean opaque;
|
||||
|
||||
boolean isSameOrigin(Origin other);
|
||||
boolean isSameSite(Origin other);
|
||||
};
|
||||
|
|
@ -20,6 +20,8 @@ class HTMLAnchorElement final
|
|||
public:
|
||||
virtual ~HTMLAnchorElement() override;
|
||||
|
||||
virtual Optional<URL::Origin> extract_an_origin() const override { return hyperlink_element_utils_extract_an_origin(); }
|
||||
|
||||
String rel() const { return get_attribute_value(HTML::AttributeNames::rel); }
|
||||
String target() const { return get_attribute_value(HTML::AttributeNames::target); }
|
||||
String download() const { return get_attribute_value(HTML::AttributeNames::download); }
|
||||
|
|
|
|||
|
|
@ -30,6 +30,8 @@ private:
|
|||
virtual void initialize(JS::Realm&) override;
|
||||
virtual void visit_edges(Cell::Visitor&) override;
|
||||
|
||||
virtual Optional<URL::Origin> extract_an_origin() const final { return hyperlink_element_utils_extract_an_origin(); }
|
||||
|
||||
// ^DOM::Element
|
||||
virtual void attribute_changed(FlyString const& name, Optional<String> const& old_value, Optional<String> const& value, Optional<FlyString> const& namespace_) override;
|
||||
virtual i32 default_tab_index_value() const override;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2021, Andreas Kling <andreas@ladybird.org>
|
||||
* Copyright (c) 2024, Shannon Booth <shannon@ladybird.org>
|
||||
* Copyright (c) 2024-2025, Shannon Booth <shannon@ladybird.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
|
@ -524,4 +524,15 @@ void HTMLHyperlinkElementUtils::follow_the_hyperlink(Optional<String> hyperlink_
|
|||
MUST(target_navigable->navigate({ .url = url.release_value(), .source_document = hyperlink_element_utils_document(), .referrer_policy = referrer_policy, .user_involvement = user_involvement }));
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/links.html#api-for-a-and-area-elements:extract-an-origin
|
||||
Optional<URL::Origin> HTMLHyperlinkElementUtils::hyperlink_element_utils_extract_an_origin() const
|
||||
{
|
||||
// 1. If this's url is null, then return null.
|
||||
if (!m_url.has_value())
|
||||
return {};
|
||||
|
||||
// 2. Return this's url's origin.
|
||||
return m_url->origin();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,6 +63,8 @@ protected:
|
|||
|
||||
virtual void hyperlink_element_utils_queue_an_element_task(HTML::Task::Source source, Function<void()> steps) = 0;
|
||||
|
||||
Optional<URL::Origin> hyperlink_element_utils_extract_an_origin() const;
|
||||
|
||||
void set_the_url();
|
||||
void follow_the_hyperlink(Optional<String> hyperlink_suffix, UserNavigationInvolvement = UserNavigationInvolvement::None);
|
||||
|
||||
|
|
|
|||
|
|
@ -102,4 +102,11 @@ void MessageEvent::init_message_event(String const& type, bool bubbles, bool can
|
|||
}
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/comms.html#the-messageevent-interface:extract-an-origin
|
||||
Optional<URL::Origin> MessageEvent::extract_an_origin() const
|
||||
{
|
||||
// Objects implementing the MessageEvent interface's extract an origin steps are to return this's relevant settings object's origin.
|
||||
return relevant_settings_object(*this).origin();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,6 +41,8 @@ public:
|
|||
GC::Ref<JS::Object> ports() const;
|
||||
Variant<GC::Root<WindowProxy>, GC::Root<MessagePort>, Empty> source() const;
|
||||
|
||||
virtual Optional<URL::Origin> extract_an_origin() const override;
|
||||
|
||||
void init_message_event(String const& type, bool bubbles, bool cancelable, JS::Value data, String const& origin, String const& last_event_id, Optional<MessageEventSource> source, Vector<GC::Root<MessagePort>> const& ports);
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -100,6 +100,8 @@ public:
|
|||
// ^JS::Object
|
||||
virtual JS::ThrowCompletionOr<bool> internal_set_prototype_of(JS::Object* prototype) override;
|
||||
|
||||
virtual Optional<URL::Origin> extract_an_origin() const override { return window_or_worker_global_scope_extract_an_origin(); }
|
||||
|
||||
Page& page();
|
||||
Page const& page() const;
|
||||
|
||||
|
|
|
|||
|
|
@ -1277,4 +1277,17 @@ GC::Ref<TrustedTypes::TrustedTypePolicyFactory> WindowOrWorkerGlobalScopeMixin::
|
|||
return *m_trusted_type_policy_factory;
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/webappapis.html#windoworworkerglobalscope-mixin:extract-an-origin
|
||||
Optional<URL::Origin> WindowOrWorkerGlobalScopeMixin::window_or_worker_global_scope_extract_an_origin() const
|
||||
{
|
||||
auto relevant_origin = relevant_settings_object(this_impl()).origin();
|
||||
|
||||
// 1. If this's relevant settings object's origin is not same origin-domain with the entry settings object's origin, then return null.
|
||||
if (!relevant_origin.is_same_origin_domain(entry_settings_object().origin()))
|
||||
return {};
|
||||
|
||||
// 2. Return this's relevant settings object's origin.
|
||||
return relevant_origin;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -106,6 +106,8 @@ public:
|
|||
|
||||
[[nodiscard]] GC::Ref<TrustedTypes::TrustedTypePolicyFactory> trusted_types();
|
||||
|
||||
Optional<URL::Origin> window_or_worker_global_scope_extract_an_origin() const;
|
||||
|
||||
protected:
|
||||
void initialize(JS::Realm&);
|
||||
void visit_edges(JS::Cell::Visitor&);
|
||||
|
|
|
|||
|
|
@ -66,6 +66,8 @@ public:
|
|||
// https://html.spec.whatwg.org/multipage/workers.html#dom-workerglobalscope-self
|
||||
GC::Ref<WorkerGlobalScope const> self() const { return *this; }
|
||||
|
||||
virtual Optional<URL::Origin> extract_an_origin() const override { return window_or_worker_global_scope_extract_an_origin(); }
|
||||
|
||||
GC::Ref<WorkerLocation> location() const;
|
||||
GC::Ref<WorkerNavigator> navigator() const;
|
||||
WebIDL::ExceptionOr<void> import_scripts(Vector<String> const& urls, PerformTheFetchHook = nullptr);
|
||||
|
|
|
|||
|
|
@ -121,6 +121,7 @@ libweb_js_bindings(DOM/Text)
|
|||
libweb_js_bindings(DOM/TreeWalker)
|
||||
libweb_js_bindings(DOM/XMLDocument)
|
||||
libweb_js_bindings(DOMURL/DOMURL)
|
||||
libweb_js_bindings(DOMURL/Origin)
|
||||
libweb_js_bindings(DOMURL/URLSearchParams ITERABLE)
|
||||
libweb_js_bindings(Encoding/TextDecoder)
|
||||
libweb_js_bindings(Encoding/TextEncoder)
|
||||
|
|
|
|||
|
|
@ -105,6 +105,7 @@ static bool is_platform_object(Type const& type)
|
|||
"Node"sv,
|
||||
"OffscreenCanvas"sv,
|
||||
"OffscreenCanvasRenderingContext2D"sv,
|
||||
"Origin"sv,
|
||||
"PasswordCredential"sv,
|
||||
"Path2D"sv,
|
||||
"PerformanceEntry"sv,
|
||||
|
|
|
|||
|
|
@ -323,6 +323,7 @@ OfflineAudioContext
|
|||
OffscreenCanvas
|
||||
OffscreenCanvasRenderingContext2D
|
||||
Option
|
||||
Origin
|
||||
OscillatorNode
|
||||
PageTransitionEvent
|
||||
PannerNode
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
Harness status: OK
|
||||
|
||||
Found 3 tests
|
||||
|
||||
3 Pass
|
||||
Pass Comparison of opaque origins.
|
||||
Pass Comparison of tuple origins.
|
||||
Pass Comparisons are schemeful.
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
Harness status: OK
|
||||
|
||||
Found 1 tests
|
||||
|
||||
1 Pass
|
||||
Pass Origin.from(globalThis) is a tuple origin.
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
Harness status: OK
|
||||
|
||||
Found 54 tests
|
||||
|
||||
54 Pass
|
||||
Pass Origin.from(<a>) throws.
|
||||
Pass Origin.from(<area>) throws.
|
||||
Pass Origin.from(<a href="about:blank">) returns an opaque origin.
|
||||
Pass Origin.from(<area href="about:blank">) returns an opaque origin.
|
||||
Pass Origin.from(<a href="data:text/plain,opaque">) returns an opaque origin.
|
||||
Pass Origin.from(<area href="data:text/plain,opaque">) returns an opaque origin.
|
||||
Pass Origin.from(<a href="weird-protocol:whatever">) returns an opaque origin.
|
||||
Pass Origin.from(<area href="weird-protocol:whatever">) returns an opaque origin.
|
||||
Pass Origin.from(<a href="weird-hierarchical-protocol://host/path?etc">) returns an opaque origin.
|
||||
Pass Origin.from(<area href="weird-hierarchical-protocol://host/path?etc">) returns an opaque origin.
|
||||
Pass Origin.from(<a href="blob:weird-protocol:whatever">) returns an opaque origin.
|
||||
Pass Origin.from(<area href="blob:weird-protocol:whatever">) returns an opaque origin.
|
||||
Pass Origin.from(<a href="blob:weird-hierarchical-protocol://host/path?etc">) returns an opaque origin.
|
||||
Pass Origin.from(<area href="blob:weird-hierarchical-protocol://host/path?etc">) returns an opaque origin.
|
||||
Pass Origin.from(<a href="http://site.example">) returns a tuple origin.
|
||||
Pass Origin.from(<area href="http://site.example">) returns a tuple origin.
|
||||
Pass Origin.from(<a href="https://site.example">) returns a tuple origin.
|
||||
Pass Origin.from(<area href="https://site.example">) returns a tuple origin.
|
||||
Pass Origin.from(<a href="https://site.example:123">) returns a tuple origin.
|
||||
Pass Origin.from(<area href="https://site.example:123">) returns a tuple origin.
|
||||
Pass Origin.from(<a href="http://sub.site.example">) returns a tuple origin.
|
||||
Pass Origin.from(<area href="http://sub.site.example">) returns a tuple origin.
|
||||
Pass Origin.from(<a href="https://sub.site.example">) returns a tuple origin.
|
||||
Pass Origin.from(<area href="https://sub.site.example">) returns a tuple origin.
|
||||
Pass Origin.from(<a href="https://sub.site.example:123">) returns a tuple origin.
|
||||
Pass Origin.from(<area href="https://sub.site.example:123">) returns a tuple origin.
|
||||
Pass Origin.from(<a href="https://xn--mlauted-m2a.example">) returns a tuple origin.
|
||||
Pass Origin.from(<area href="https://xn--mlauted-m2a.example">) returns a tuple origin.
|
||||
Pass Origin.from(<a href="ftp://ftp.example">) returns a tuple origin.
|
||||
Pass Origin.from(<area href="ftp://ftp.example">) returns a tuple origin.
|
||||
Pass Origin.from(<a href="ws://ws.example">) returns a tuple origin.
|
||||
Pass Origin.from(<area href="ws://ws.example">) returns a tuple origin.
|
||||
Pass Origin.from(<a href="wss://wss.example">) returns a tuple origin.
|
||||
Pass Origin.from(<area href="wss://wss.example">) returns a tuple origin.
|
||||
Pass Origin.from(<a href="https://trailing.slash/">) returns a tuple origin.
|
||||
Pass Origin.from(<area href="https://trailing.slash/">) returns a tuple origin.
|
||||
Pass Origin.from(<a href="https://user:pass@site.example">) returns a tuple origin.
|
||||
Pass Origin.from(<area href="https://user:pass@site.example">) returns a tuple origin.
|
||||
Pass Origin.from(<a href="https://has.a.port:1234/and/path">) returns a tuple origin.
|
||||
Pass Origin.from(<area href="https://has.a.port:1234/and/path">) returns a tuple origin.
|
||||
Pass Origin.from(<a href="https://ümlauted.example">) returns a tuple origin.
|
||||
Pass Origin.from(<area href="https://ümlauted.example">) returns a tuple origin.
|
||||
Pass Origin.from(<a href="file:///path/to/a/file.txt">) returns a tuple origin.
|
||||
Pass Origin.from(<area href="file:///path/to/a/file.txt">) returns a tuple origin.
|
||||
Pass Origin.from(<a href="blob:https://example.com/some-guid">) returns a tuple origin.
|
||||
Pass Origin.from(<area href="blob:https://example.com/some-guid">) returns a tuple origin.
|
||||
Pass Origin.from(<a href="ftp://example.com/">) returns a tuple origin.
|
||||
Pass Origin.from(<area href="ftp://example.com/">) returns a tuple origin.
|
||||
Pass Origin.from(<a href="https://example.com/path?query#fragment">) returns a tuple origin.
|
||||
Pass Origin.from(<area href="https://example.com/path?query#fragment">) returns a tuple origin.
|
||||
Pass Origin.from(<a href="https://127.0.0.1/">) returns a tuple origin.
|
||||
Pass Origin.from(<area href="https://127.0.0.1/">) returns a tuple origin.
|
||||
Pass Origin.from(<a href="https://[::1]/">) returns a tuple origin.
|
||||
Pass Origin.from(<area href="https://[::1]/">) returns a tuple origin.
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
Harness status: OK
|
||||
|
||||
Found 2 tests
|
||||
|
||||
2 Pass
|
||||
Pass Origin.from(window.location) throws.
|
||||
Pass Origin.from(Location) throws for cross-origin frames.
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
Harness status: OK
|
||||
|
||||
Found 26 tests
|
||||
|
||||
26 Pass
|
||||
Pass Origin.from(Origin.from("about:blank")) is an opaque origin.
|
||||
Pass Origin.from(Origin.from("data:text/plain,opaque")) is an opaque origin.
|
||||
Pass Origin.from(Origin.from("weird-protocol:whatever")) is an opaque origin.
|
||||
Pass Origin.from(Origin.from("weird-hierarchical-protocol://host/path?etc")) is an opaque origin.
|
||||
Pass Origin.from(Origin.from("blob:weird-protocol:whatever")) is an opaque origin.
|
||||
Pass Origin.from(Origin.from("blob:weird-hierarchical-protocol://host/path?etc")) is an opaque origin.
|
||||
Pass Origin.from(Origin.from("http://site.example")) is an tuple origin.
|
||||
Pass Origin.from(Origin.from("https://site.example")) is an tuple origin.
|
||||
Pass Origin.from(Origin.from("https://site.example:123")) is an tuple origin.
|
||||
Pass Origin.from(Origin.from("http://sub.site.example")) is an tuple origin.
|
||||
Pass Origin.from(Origin.from("https://sub.site.example")) is an tuple origin.
|
||||
Pass Origin.from(Origin.from("https://sub.site.example:123")) is an tuple origin.
|
||||
Pass Origin.from(Origin.from("https://xn--mlauted-m2a.example")) is an tuple origin.
|
||||
Pass Origin.from(Origin.from("ftp://ftp.example")) is an tuple origin.
|
||||
Pass Origin.from(Origin.from("ws://ws.example")) is an tuple origin.
|
||||
Pass Origin.from(Origin.from("wss://wss.example")) is an tuple origin.
|
||||
Pass Origin.from(Origin.from("https://trailing.slash/")) is an tuple origin.
|
||||
Pass Origin.from(Origin.from("https://user:pass@site.example")) is an tuple origin.
|
||||
Pass Origin.from(Origin.from("https://has.a.port:1234/and/path")) is an tuple origin.
|
||||
Pass Origin.from(Origin.from("https://ümlauted.example")) is an tuple origin.
|
||||
Pass Origin.from(Origin.from("file:///path/to/a/file.txt")) is an tuple origin.
|
||||
Pass Origin.from(Origin.from("blob:https://example.com/some-guid")) is an tuple origin.
|
||||
Pass Origin.from(Origin.from("ftp://example.com/")) is an tuple origin.
|
||||
Pass Origin.from(Origin.from("https://example.com/path?query#fragment")) is an tuple origin.
|
||||
Pass Origin.from(Origin.from("https://127.0.0.1/")) is an tuple origin.
|
||||
Pass Origin.from(Origin.from("https://[::1]/")) is an tuple origin.
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
Harness status: OK
|
||||
|
||||
Found 28 tests
|
||||
|
||||
28 Pass
|
||||
Pass Origin.from("") throws a TypeError.
|
||||
Pass Origin.from("not-valid") throws a TypeError.
|
||||
Pass Origin.from("about:blank") is an opaque origin.
|
||||
Pass Origin.from("data:text/plain,opaque") is an opaque origin.
|
||||
Pass Origin.from("weird-protocol:whatever") is an opaque origin.
|
||||
Pass Origin.from("weird-hierarchical-protocol://host/path?etc") is an opaque origin.
|
||||
Pass Origin.from("blob:weird-protocol:whatever") is an opaque origin.
|
||||
Pass Origin.from("blob:weird-hierarchical-protocol://host/path?etc") is an opaque origin.
|
||||
Pass Origin.from("http://site.example") is an opaque origin.
|
||||
Pass Origin.from("https://site.example") is an opaque origin.
|
||||
Pass Origin.from("https://site.example:123") is an opaque origin.
|
||||
Pass Origin.from("http://sub.site.example") is an opaque origin.
|
||||
Pass Origin.from("https://sub.site.example") is an opaque origin.
|
||||
Pass Origin.from("https://sub.site.example:123") is an opaque origin.
|
||||
Pass Origin.from("https://xn--mlauted-m2a.example") is an opaque origin.
|
||||
Pass Origin.from("ftp://ftp.example") is an opaque origin.
|
||||
Pass Origin.from("ws://ws.example") is an opaque origin.
|
||||
Pass Origin.from("wss://wss.example") is an opaque origin.
|
||||
Pass Origin.from("https://trailing.slash/") is an opaque origin.
|
||||
Pass Origin.from("https://user:pass@site.example") is an opaque origin.
|
||||
Pass Origin.from("https://has.a.port:1234/and/path") is an opaque origin.
|
||||
Pass Origin.from("https://ümlauted.example") is an opaque origin.
|
||||
Pass Origin.from("file:///path/to/a/file.txt") is an opaque origin.
|
||||
Pass Origin.from("blob:https://example.com/some-guid") is an opaque origin.
|
||||
Pass Origin.from("ftp://example.com/") is an opaque origin.
|
||||
Pass Origin.from("https://example.com/path?query#fragment") is an opaque origin.
|
||||
Pass Origin.from("https://127.0.0.1/") is an opaque origin.
|
||||
Pass Origin.from("https://[::1]/") is an opaque origin.
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
Harness status: OK
|
||||
|
||||
Found 28 tests
|
||||
|
||||
28 Pass
|
||||
Pass Origin.from("") throws a TypeError.
|
||||
Pass Origin.from("not-valid") throws a TypeError.
|
||||
Pass Origin.from("about:blank") is an opaque origin.
|
||||
Pass Origin.from("data:text/plain,opaque") is an opaque origin.
|
||||
Pass Origin.from("weird-protocol:whatever") is an opaque origin.
|
||||
Pass Origin.from("weird-hierarchical-protocol://host/path?etc") is an opaque origin.
|
||||
Pass Origin.from("blob:weird-protocol:whatever") is an opaque origin.
|
||||
Pass Origin.from("blob:weird-hierarchical-protocol://host/path?etc") is an opaque origin.
|
||||
Pass Origin.from("http://site.example") is an opaque origin.
|
||||
Pass Origin.from("https://site.example") is an opaque origin.
|
||||
Pass Origin.from("https://site.example:123") is an opaque origin.
|
||||
Pass Origin.from("http://sub.site.example") is an opaque origin.
|
||||
Pass Origin.from("https://sub.site.example") is an opaque origin.
|
||||
Pass Origin.from("https://sub.site.example:123") is an opaque origin.
|
||||
Pass Origin.from("https://xn--mlauted-m2a.example") is an opaque origin.
|
||||
Pass Origin.from("ftp://ftp.example") is an opaque origin.
|
||||
Pass Origin.from("ws://ws.example") is an opaque origin.
|
||||
Pass Origin.from("wss://wss.example") is an opaque origin.
|
||||
Pass Origin.from("https://trailing.slash/") is an opaque origin.
|
||||
Pass Origin.from("https://user:pass@site.example") is an opaque origin.
|
||||
Pass Origin.from("https://has.a.port:1234/and/path") is an opaque origin.
|
||||
Pass Origin.from("https://ümlauted.example") is an opaque origin.
|
||||
Pass Origin.from("file:///path/to/a/file.txt") is an opaque origin.
|
||||
Pass Origin.from("blob:https://example.com/some-guid") is an opaque origin.
|
||||
Pass Origin.from("ftp://example.com/") is an opaque origin.
|
||||
Pass Origin.from("https://example.com/path?query#fragment") is an opaque origin.
|
||||
Pass Origin.from("https://127.0.0.1/") is an opaque origin.
|
||||
Pass Origin.from("https://[::1]/") is an opaque origin.
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
Harness status: OK
|
||||
|
||||
Found 9 tests
|
||||
|
||||
9 Pass
|
||||
Pass Origin.from(null) throws a TypeError.
|
||||
Pass Origin.from(undefined) throws a TypeError.
|
||||
Pass Origin.from(1) throws a TypeError.
|
||||
Pass Origin.from(1.1) throws a TypeError.
|
||||
Pass Origin.from(true) throws a TypeError.
|
||||
Pass Origin.from([object Object]) throws a TypeError.
|
||||
Pass Origin.from(function Object() { [native code] }) throws a TypeError.
|
||||
Pass Origin.from(function Origin() { [native code] }) throws a TypeError.
|
||||
Pass Origin.from(function from() { [native code] }) throws a TypeError.
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
<!doctype html>
|
||||
<meta charset=utf-8>
|
||||
<title>`Origin` comparison</title>
|
||||
<script>
|
||||
self.GLOBAL = {
|
||||
isWindow: function() { return true; },
|
||||
isWorker: function() { return false; },
|
||||
isShadowRealm: function() { return false; },
|
||||
};
|
||||
</script>
|
||||
<script src="../../../../resources/testharness.js"></script>
|
||||
<script src="../../../../resources/testharnessreport.js"></script>
|
||||
|
||||
<div id=log></div>
|
||||
<script src="../../../../html/browsers/origin/api/origin-comparison.any.js"></script>
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
// META: title=`Origin` comparison
|
||||
|
||||
test(t => {
|
||||
const opaqueA = new Origin();
|
||||
const opaqueB = new Origin();
|
||||
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.");
|
||||
}, "Comparison of opaque origins.");
|
||||
|
||||
test(t => {
|
||||
const a = Origin.from("https://a.example");
|
||||
const a_a = Origin.from("https://a.a.example");
|
||||
const b_a = Origin.from("https://b.a.example");
|
||||
const b = Origin.from("https://b.example");
|
||||
const b_b = Origin.from("https://b.b.example");
|
||||
|
||||
assert_true(a.isSameOrigin(a), "Origin should be same-origin with itself.");
|
||||
assert_false(a.isSameOrigin(a_a), "Origins with different subdomains should not be same-origin.");
|
||||
assert_false(a.isSameOrigin(b_a), "Origins with different subdomains should not be same-origin.");
|
||||
assert_false(a.isSameOrigin(b), "Origins with different domains should not be same-origin.");
|
||||
assert_false(a.isSameOrigin(b_b), "Origins with different domains should not be same-origin.");
|
||||
|
||||
assert_true(a.isSameSite(a), "Origin should be same-site with itself.");
|
||||
assert_true(a.isSameSite(a_a), "Origins with same registrable domain should be same-site.");
|
||||
assert_true(a.isSameSite(b_a), "Origins with same registrable domain should be same-site.");
|
||||
assert_false(a.isSameSite(b), "Origins with different registrable domains should not be same-site.");
|
||||
assert_false(a.isSameSite(b_b), "Origins with different registrable domains should not be same-site.");
|
||||
|
||||
assert_true(a_a.isSameSite(a), "Origins with same registrable domain should be same-site.");
|
||||
assert_true(a_a.isSameSite(a_a), "Origin should be same-site with itself.");
|
||||
assert_true(a_a.isSameSite(b_a), "Origins with same registrable domain should be same-site.");
|
||||
assert_false(a_a.isSameSite(b), "Origins with different registrable domains should not be same-site.");
|
||||
assert_false(a_a.isSameSite(b_b), "Origins with different registrable domains should not be same-site.");
|
||||
}, "Comparison of tuple origins.");
|
||||
|
||||
test(t => {
|
||||
const http = Origin.from("http://a.example");
|
||||
const https = Origin.from("https://a.example");
|
||||
|
||||
assert_false(http.isSameOrigin(https), "http is not same-site with https");
|
||||
assert_false(https.isSameOrigin(http), "https is not same-site with http");
|
||||
|
||||
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.");
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
<!doctype html>
|
||||
<meta charset=utf-8>
|
||||
<title>`Origin.from(WindowOrWorkerGlobalScope)`</title>
|
||||
<script>
|
||||
self.GLOBAL = {
|
||||
isWindow: function() { return true; },
|
||||
isWorker: function() { return false; },
|
||||
isShadowRealm: function() { return false; },
|
||||
};
|
||||
</script>
|
||||
<script src="../../../../resources/testharness.js"></script>
|
||||
<script src="../../../../resources/testharnessreport.js"></script>
|
||||
<script src="../../../../common/get-host-info.sub.js"></script>
|
||||
<div id=log></div>
|
||||
<script src="../../../../html/browsers/origin/api/origin-from-global.any.js"></script>
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
// META: title=`Origin.from(WindowOrWorkerGlobalScope)`
|
||||
// META: global=window,worker
|
||||
// META: script=/common/get-host-info.sub.js
|
||||
|
||||
test(t => {
|
||||
const origin = Origin.from(globalThis);
|
||||
assert_true(!!origin);
|
||||
assert_false(origin.opaque, "Origin should not be opaque.");
|
||||
assert_true(origin.isSameOrigin(Origin.from(get_host_info().ORIGIN)));
|
||||
}, `Origin.from(globalThis) is a tuple origin.`);
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
<!doctype html>
|
||||
<meta charset=utf-8>
|
||||
<title>`Origin.from(HTMLHyperlinkElementUtils)`</title>
|
||||
<script src="../../../../resources/testharness.js"></script>
|
||||
<script src="../../../../resources/testharnessreport.js"></script>
|
||||
<script src="resources/serializations.js"></script>
|
||||
<div id=log></div>
|
||||
<script src="../../../../html/browsers/origin/api/origin-from-htmlhyperlinkelementutils.window.js"></script>
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
// META: title=`Origin.from(HTMLHyperlinkElementUtils)`
|
||||
// META: script=resources/serializations.js
|
||||
|
||||
test(t => {
|
||||
const invalid = document.createElement("a");
|
||||
assert_throws_js(TypeError, _ => Origin.from(invalid));
|
||||
}, `Origin.from(<a>) throws.`);
|
||||
|
||||
test(t => {
|
||||
const invalid = document.createElement("area");
|
||||
assert_throws_js(TypeError, _ => Origin.from(invalid));
|
||||
}, `Origin.from(<area>) throws.`);
|
||||
|
||||
for (const opaque of urls.opaque) {
|
||||
// <a>
|
||||
test(t => {
|
||||
const a = document.createElement("a");
|
||||
a.href = opaque;
|
||||
const origin = Origin.from(a);
|
||||
assert_true(!!origin);
|
||||
assert_true(origin.opaque);
|
||||
}, `Origin.from(<a href="${opaque}">) returns an opaque origin.`);
|
||||
|
||||
// <area>
|
||||
test(t => {
|
||||
const area = document.createElement("area");
|
||||
area.href = opaque;
|
||||
const origin = Origin.from(area);
|
||||
assert_true(!!origin);
|
||||
assert_true(origin.opaque);
|
||||
}, `Origin.from(<area href="${opaque}">) returns an opaque origin.`);
|
||||
}
|
||||
|
||||
for (const tuple of urls.tuple) {
|
||||
// <a>
|
||||
test(t => {
|
||||
const a = document.createElement("a");
|
||||
a.href = tuple;
|
||||
const origin = Origin.from(a);
|
||||
assert_true(!!origin);
|
||||
assert_false(origin.opaque);
|
||||
}, `Origin.from(<a href="${tuple}">) returns a tuple origin.`);
|
||||
|
||||
// <area>
|
||||
test(t => {
|
||||
const area = document.createElement("area");
|
||||
area.href = tuple;
|
||||
const origin = Origin.from(area);
|
||||
assert_true(!!origin);
|
||||
assert_false(origin.opaque);
|
||||
}, `Origin.from(<area href="${tuple}">) returns a tuple origin.`);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
<!doctype html>
|
||||
<meta charset=utf-8>
|
||||
<title>`Origin.from(Location)`</title>
|
||||
<script src="../../../../resources/testharness.js"></script>
|
||||
<script src="../../../../resources/testharnessreport.js"></script>
|
||||
<script src="../../../../common/get-host-info.sub.js"></script>
|
||||
<div id=log></div>
|
||||
<script src="../../../../html/browsers/origin/api/origin-from-location.window.js"></script>
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
// META: title=`Origin.from(Location)`
|
||||
// META: script=/common/get-host-info.sub.js
|
||||
|
||||
test(t => {
|
||||
assert_throws_js(TypeError, _ => Origin.from(window.location));
|
||||
}, `Origin.from(window.location) throws.`);
|
||||
|
||||
async_test(t => {
|
||||
const el = document.createElement('iframe');
|
||||
el.src = get_host_info().REMOTE_ORIGIN + "/common/blank.html";
|
||||
el.onload = t.step_func_done(_ => {
|
||||
assert_throws_js(TypeError, _ => Origin.from(el.contentWindow.location));
|
||||
});
|
||||
document.body.appendChild(el);
|
||||
}, `Origin.from(Location) throws for cross-origin frames.`);
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
<!doctype html>
|
||||
<meta charset=utf-8>
|
||||
<title>`Origin.from(URL)`</title>
|
||||
<script>
|
||||
self.GLOBAL = {
|
||||
isWindow: function() { return true; },
|
||||
isWorker: function() { return false; },
|
||||
isShadowRealm: function() { return false; },
|
||||
};
|
||||
</script>
|
||||
<script src="../../../../resources/testharness.js"></script>
|
||||
<script src="../../../../resources/testharnessreport.js"></script>
|
||||
<script src="resources/serializations.js"></script>
|
||||
<div id=log></div>
|
||||
<script src="../../../../html/browsers/origin/api/origin-from-origin.any.js"></script>
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
// META: title=`Origin.from(URL)`
|
||||
// META: script=resources/serializations.js
|
||||
|
||||
for (const opaque of urls.opaque) {
|
||||
test(t => {
|
||||
const originFromString = Origin.from(opaque);
|
||||
const origin = Origin.from(originFromString);
|
||||
assert_true(!!origin);
|
||||
assert_true(origin.opaque, "Origin should be opaque.");
|
||||
assert_true(origin.isSameOrigin(originFromString));
|
||||
}, `Origin.from(Origin.from(${JSON.stringify(opaque)})) is an opaque origin.`);
|
||||
}
|
||||
|
||||
for (const tuple of urls.tuple) {
|
||||
test(t => {
|
||||
const originFromString = Origin.from(tuple);
|
||||
const origin = Origin.from(originFromString);
|
||||
assert_true(!!origin);
|
||||
assert_false(origin.opaque, "Origin should be opaque.");
|
||||
assert_true(origin.isSameOrigin(originFromString));
|
||||
}, `Origin.from(Origin.from(${JSON.stringify(tuple)})) is an tuple origin.`);
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
<!doctype html>
|
||||
<meta charset=utf-8>
|
||||
<title>`Origin.from(String)`</title>
|
||||
<script>
|
||||
self.GLOBAL = {
|
||||
isWindow: function() { return true; },
|
||||
isWorker: function() { return false; },
|
||||
isShadowRealm: function() { return false; },
|
||||
};
|
||||
</script>
|
||||
<script src="../../../../resources/testharness.js"></script>
|
||||
<script src="../../../../resources/testharnessreport.js"></script>
|
||||
<script src="resources/serializations.js"></script>
|
||||
<div id=log></div>
|
||||
<script src="../../../../html/browsers/origin/api/origin-from-string.any.js"></script>
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
// META: title=`Origin.from(String)`
|
||||
// META: script=resources/serializations.js
|
||||
|
||||
for (const invalid of urls.invalid) {
|
||||
test(t => {
|
||||
assert_throws_js(TypeError, _ => Origin.from(invalid));
|
||||
}, `Origin.from(${JSON.stringify(invalid)}) throws a TypeError.`);
|
||||
}
|
||||
|
||||
for (const opaque of urls.opaque) {
|
||||
test(t => {
|
||||
const origin = Origin.from(opaque);
|
||||
assert_true(!!origin);
|
||||
assert_true(origin.opaque, "Origin should be opaque.");
|
||||
}, `Origin.from(${JSON.stringify(opaque)}) is an opaque origin.`);
|
||||
}
|
||||
|
||||
for (const tuple of urls.tuple) {
|
||||
test(t => {
|
||||
const origin = Origin.from(tuple);
|
||||
assert_true(!!origin);
|
||||
assert_false(origin.opaque, "Origin should not be opaque.");
|
||||
}, `Origin.from(${JSON.stringify(tuple)}) is an opaque origin.`);
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
<!doctype html>
|
||||
<meta charset=utf-8>
|
||||
<title>`Origin.from(URL)`</title>
|
||||
<script>
|
||||
self.GLOBAL = {
|
||||
isWindow: function() { return true; },
|
||||
isWorker: function() { return false; },
|
||||
isShadowRealm: function() { return false; },
|
||||
};
|
||||
</script>
|
||||
<script src="../../../../resources/testharness.js"></script>
|
||||
<script src="../../../../resources/testharnessreport.js"></script>
|
||||
<script src="resources/serializations.js"></script>
|
||||
<div id=log></div>
|
||||
<script src="../../../../html/browsers/origin/api/origin-from-url.any.js"></script>
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
// META: title=`Origin.from(URL)`
|
||||
// META: script=resources/serializations.js
|
||||
|
||||
for (const invalid of urls.invalid) {
|
||||
test(t => {
|
||||
assert_throws_js(TypeError, _ => Origin.from(new URL(invalid)));
|
||||
}, `Origin.from(${JSON.stringify(invalid)}) throws a TypeError.`);
|
||||
}
|
||||
|
||||
for (const opaque of urls.opaque) {
|
||||
test(t => {
|
||||
const origin = Origin.from(new URL(opaque));
|
||||
assert_true(!!origin);
|
||||
assert_true(origin.opaque, "Origin should be opaque.");
|
||||
}, `Origin.from(${JSON.stringify(opaque)}) is an opaque origin.`);
|
||||
}
|
||||
|
||||
for (const tuple of urls.tuple) {
|
||||
test(t => {
|
||||
const origin = Origin.from(new URL(tuple));
|
||||
assert_true(!!origin);
|
||||
assert_false(origin.opaque, "Origin should not be opaque.");
|
||||
}, `Origin.from(${JSON.stringify(tuple)}) is an opaque origin.`);
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
<!doctype html>
|
||||
<meta charset=utf-8>
|
||||
<title>`Origin.from()`</title>
|
||||
<script>
|
||||
self.GLOBAL = {
|
||||
isWindow: function() { return true; },
|
||||
isWorker: function() { return false; },
|
||||
isShadowRealm: function() { return false; },
|
||||
};
|
||||
</script>
|
||||
<script src="../../../../resources/testharness.js"></script>
|
||||
<script src="../../../../resources/testharnessreport.js"></script>
|
||||
<script src="resources/serializations.js"></script>
|
||||
<div id=log></div>
|
||||
<script src="../../../../html/browsers/origin/api/origin-from.any.js"></script>
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
// META: title=`Origin.from()`
|
||||
// META: script=resources/serializations.js
|
||||
|
||||
//
|
||||
// Invalid Inputs: `null`, `undefined`, invalid URL strings, random objects.
|
||||
//
|
||||
const invalidInputs = [
|
||||
null,
|
||||
undefined,
|
||||
1,
|
||||
1.1,
|
||||
true,
|
||||
{},
|
||||
Object,
|
||||
Origin,
|
||||
Origin.from,
|
||||
];
|
||||
|
||||
for (const invalid of invalidInputs) {
|
||||
test(t => {
|
||||
assert_throws_js(TypeError, _ => Origin.from(invalid));
|
||||
}, `Origin.from(${invalid}) throws a TypeError.`);
|
||||
}
|
||||
|
||||
// Specific object types are tested in `origin-from-*.js` in this directory.
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
const urls = {
|
||||
invalid: [
|
||||
"",
|
||||
"not-valid",
|
||||
],
|
||||
opaque: [
|
||||
"about:blank",
|
||||
"data:text/plain,opaque",
|
||||
"weird-protocol:whatever",
|
||||
"weird-hierarchical-protocol://host/path?etc",
|
||||
"blob:weird-protocol:whatever",
|
||||
"blob:weird-hierarchical-protocol://host/path?etc",
|
||||
],
|
||||
tuple: [
|
||||
"http://site.example",
|
||||
"https://site.example",
|
||||
"https://site.example:123",
|
||||
"http://sub.site.example",
|
||||
"https://sub.site.example",
|
||||
"https://sub.site.example:123",
|
||||
"https://xn--mlauted-m2a.example",
|
||||
"ftp://ftp.example",
|
||||
"ws://ws.example",
|
||||
"wss://wss.example",
|
||||
"https://trailing.slash/",
|
||||
"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",
|
||||
"https://127.0.0.1/",
|
||||
"https://[::1]/",
|
||||
],
|
||||
};
|
||||
Loading…
Reference in a new issue