diff --git a/Libraries/LibWeb/HTML/Navigable.cpp b/Libraries/LibWeb/HTML/Navigable.cpp index a579aad692e..0ee4e46da5c 100644 --- a/Libraries/LibWeb/HTML/Navigable.cpp +++ b/Libraries/LibWeb/HTML/Navigable.cpp @@ -934,8 +934,49 @@ static WebIDL::ExceptionOr create_navigation // 19. While true: while (true) { - // FIXME: 1. If request's reserved client is not null and currentURL's origin is not the same as request's reserved client's creation URL's origin, then: - // FIXME: 2. If request's reserved client is null, then: + // 1. If request's reserved client is not null and currentURL's origin is not the same as request's reserved client's creation URL's origin, then: + if (request->reserved_client() && !current_url.origin().is_same_origin(request->reserved_client()->creation_url.origin())) { + // 1. Run the environment discarding steps for request's reserved client. + request->reserved_client()->discard_environment(); + + // 2. Set request's reserved client to null. + request->set_reserved_client(nullptr); + + // 3. Set commitEarlyHints to null. + commit_early_hints = nullptr; + } + + // 2. If request's reserved client is null, then: + if (!request->reserved_client()) { + // 1. Let topLevelCreationURL be currentURL. + auto top_level_creation_url = current_url; + + // 2. Let topLevelOrigin be null. + URL::Origin top_level_origin; + + // 3. If navigable is not a top-level traversable, then: + if (!navigable->is_top_level_traversable()) { + // 1. Let parentEnvironment be navigable's parent's active document's relevant settings object. + auto& parent_environment = navigable->parent()->active_document()->relevant_settings_object(); + + // 2. Set topLevelCreationURL to parentEnvironment's top-level creation URL. + top_level_creation_url = parent_environment.top_level_creation_url; + + // 3. Set topLevelOrigin to parentEnvironment's top-level origin. + top_level_origin = parent_environment.top_level_origin; + } + + // 4. Set request's reserved client to a new environment whose id is a unique opaque string, + // target browsing context is navigable's active browsing context, + // creation URL is currentURL, + // top-level creation URL is topLevelCreationURL, + // and top-level origin is topLevelOrigin. + // FIXME: Make this a proper unique opaque string. + static int next_id = 1; + auto id_string = MUST(String::formatted("create-by-fetching-{}", next_id++)); + request->set_reserved_client(realm.create(id_string, current_url, top_level_creation_url, top_level_origin, navigable->active_browsing_context())); + } + // FIXME: 3. If the result of should navigation request of type be blocked by Content Security Policy? given request and cspNavigationType is "Blocked", then set response to a network error and break. [CSP] // 4. Set response to null. diff --git a/Libraries/LibWeb/HTML/Scripting/Environments.h b/Libraries/LibWeb/HTML/Scripting/Environments.h index 21879f1dfb3..e97d0a4334d 100644 --- a/Libraries/LibWeb/HTML/Scripting/Environments.h +++ b/Libraries/LibWeb/HTML/Scripting/Environments.h @@ -50,6 +50,15 @@ public: virtual void discard_environment() { } protected: + Environment() = default; + Environment(String id, URL::URL creation_url, URL::URL top_level_creation_url, URL::Origin top_level_origin, GC::Ptr target_browsing_context) + : id(move(id)) + , creation_url(move(creation_url)) + , top_level_creation_url(move(top_level_creation_url)) + , top_level_origin(move(top_level_origin)) + , target_browsing_context(move(target_browsing_context)) + { + } virtual void visit_edges(Cell::Visitor&) override; };