Commit 6c688717 authored by Katie Dillon's avatar Katie Dillon Committed by Commit Bot

Exposing navigator.language to web workers.

navigator.language should be supported in workers according to
specifications.

This CL adds a virtual function for retrieving the accept_language
to navigator_language which is then overridden by navigator, who gets
the languages from the frame, and woker_navigator, who gets the languages
from renderer preferences. From there, navigator_language parses the
string and returns either the top prefered language or a vector of all
of the preferred languages.

In addition, any changes to the language fires an event that notifies all
of the worker threads to the change, as per specification.

Based on this CL: https://chromium-review.googlesource.com/c/chromium/src/+/1136794

Bug: 276159, 655458
Change-Id: I53bd454f10b5b9b9dc8fd3afa82415b6e93698ca
Reviewed-on: https://chromium-review.googlesource.com/c/1255151
Commit-Queue: Ojan Vafai <ojan@chromium.org>
Reviewed-by: default avatarOjan Vafai <ojan@chromium.org>
Reviewed-by: default avatarTsuyoshi Horo <horo@chromium.org>
Reviewed-by: default avatarDmitry Gozman <dgozman@chromium.org>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Cr-Commit-Position: refs/heads/master@{#613381}
parent f08835e6
...@@ -230,7 +230,8 @@ WebWorkerFetchContextImpl::CloneForNestedWorker() { ...@@ -230,7 +230,8 @@ WebWorkerFetchContextImpl::CloneForNestedWorker() {
return new_context; return new_context;
} }
void WebWorkerFetchContextImpl::InitializeOnWorkerThread() { void WebWorkerFetchContextImpl::InitializeOnWorkerThread(
blink::AcceptLanguagesWatcher* watcher) {
DCHECK(!resource_dispatcher_); DCHECK(!resource_dispatcher_);
DCHECK(!binding_.is_bound()); DCHECK(!binding_.is_bound());
DCHECK(!preference_watcher_binding_.is_bound()); DCHECK(!preference_watcher_binding_.is_bound());
...@@ -262,6 +263,7 @@ void WebWorkerFetchContextImpl::InitializeOnWorkerThread() { ...@@ -262,6 +263,7 @@ void WebWorkerFetchContextImpl::InitializeOnWorkerThread() {
base::RefCountedData<blink::mojom::BlobRegistryPtr>>( base::RefCountedData<blink::mojom::BlobRegistryPtr>>(
std::move(blob_registry_ptr)); std::move(blob_registry_ptr));
} }
accept_languages_watcher_ = watcher;
DCHECK(loader_factory_); DCHECK(loader_factory_);
DCHECK(!web_loader_factory_); DCHECK(!web_loader_factory_);
...@@ -465,6 +467,9 @@ void WebWorkerFetchContextImpl::ResetServiceWorkerURLLoaderFactory() { ...@@ -465,6 +467,9 @@ void WebWorkerFetchContextImpl::ResetServiceWorkerURLLoaderFactory() {
void WebWorkerFetchContextImpl::NotifyUpdate( void WebWorkerFetchContextImpl::NotifyUpdate(
const RendererPreferences& new_prefs) { const RendererPreferences& new_prefs) {
if (accept_languages_watcher_ &&
renderer_preferences_.accept_languages != new_prefs.accept_languages)
accept_languages_watcher_->NotifyUpdate();
renderer_preferences_ = new_prefs; renderer_preferences_ = new_prefs;
child_preference_watchers_.ForAllPtrs( child_preference_watchers_.ForAllPtrs(
[&new_prefs](mojom::RendererPreferenceWatcher* watcher) { [&new_prefs](mojom::RendererPreferenceWatcher* watcher) {
...@@ -472,4 +477,8 @@ void WebWorkerFetchContextImpl::NotifyUpdate( ...@@ -472,4 +477,8 @@ void WebWorkerFetchContextImpl::NotifyUpdate(
}); });
} }
blink::WebString WebWorkerFetchContextImpl::GetAcceptLanguages() const {
return blink::WebString::FromUTF8(renderer_preferences_.accept_languages);
}
} // namespace content } // namespace content
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include "third_party/blink/public/mojom/blob/blob_registry.mojom.h" #include "third_party/blink/public/mojom/blob/blob_registry.mojom.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_object.mojom.h" #include "third_party/blink/public/mojom/service_worker/service_worker_object.mojom.h"
#include "third_party/blink/public/platform/web_application_cache_host.h" #include "third_party/blink/public/platform/web_application_cache_host.h"
#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/public/platform/web_worker_fetch_context.h" #include "third_party/blink/public/platform/web_worker_fetch_context.h"
#include "url/gurl.h" #include "url/gurl.h"
...@@ -84,7 +85,7 @@ class CONTENT_EXPORT WebWorkerFetchContextImpl ...@@ -84,7 +85,7 @@ class CONTENT_EXPORT WebWorkerFetchContextImpl
// blink::WebWorkerFetchContext implementation: // blink::WebWorkerFetchContext implementation:
scoped_refptr<blink::WebWorkerFetchContext> CloneForNestedWorker() override; scoped_refptr<blink::WebWorkerFetchContext> CloneForNestedWorker() override;
void SetTerminateSyncLoadEvent(base::WaitableEvent*) override; void SetTerminateSyncLoadEvent(base::WaitableEvent*) override;
void InitializeOnWorkerThread() override; void InitializeOnWorkerThread(blink::AcceptLanguagesWatcher*) override;
blink::WebURLLoaderFactory* GetURLLoaderFactory() override; blink::WebURLLoaderFactory* GetURLLoaderFactory() override;
std::unique_ptr<blink::WebURLLoaderFactory> WrapURLLoaderFactory( std::unique_ptr<blink::WebURLLoaderFactory> WrapURLLoaderFactory(
mojo::ScopedMessagePipeHandle url_loader_factory_handle) override; mojo::ScopedMessagePipeHandle url_loader_factory_handle) override;
...@@ -131,6 +132,8 @@ class CONTENT_EXPORT WebWorkerFetchContextImpl ...@@ -131,6 +132,8 @@ class CONTENT_EXPORT WebWorkerFetchContextImpl
using RewriteURLFunction = blink::WebURL (*)(const std::string&, bool); using RewriteURLFunction = blink::WebURL (*)(const std::string&, bool);
static void InstallRewriteURLFunction(RewriteURLFunction rewrite_url); static void InstallRewriteURLFunction(RewriteURLFunction rewrite_url);
blink::WebString GetAcceptLanguages() const override;
private: private:
class Factory; class Factory;
...@@ -239,6 +242,8 @@ class CONTENT_EXPORT WebWorkerFetchContextImpl ...@@ -239,6 +242,8 @@ class CONTENT_EXPORT WebWorkerFetchContextImpl
websocket_handshake_throttle_provider_; websocket_handshake_throttle_provider_;
std::unique_ptr<service_manager::Connector> service_manager_connection_; std::unique_ptr<service_manager::Connector> service_manager_connection_;
blink::AcceptLanguagesWatcher* accept_languages_watcher_ = nullptr;
}; };
} // namespace content } // namespace content
......
...@@ -49,7 +49,8 @@ void ServiceWorkerFetchContextImpl::SetTerminateSyncLoadEvent( ...@@ -49,7 +49,8 @@ void ServiceWorkerFetchContextImpl::SetTerminateSyncLoadEvent(
terminate_sync_load_event_ = terminate_sync_load_event; terminate_sync_load_event_ = terminate_sync_load_event;
} }
void ServiceWorkerFetchContextImpl::InitializeOnWorkerThread() { void ServiceWorkerFetchContextImpl::InitializeOnWorkerThread(
blink::AcceptLanguagesWatcher* watcher) {
resource_dispatcher_ = std::make_unique<ResourceDispatcher>(); resource_dispatcher_ = std::make_unique<ResourceDispatcher>();
resource_dispatcher_->set_terminate_sync_load_event( resource_dispatcher_->set_terminate_sync_load_event(
terminate_sync_load_event_); terminate_sync_load_event_);
...@@ -67,6 +68,8 @@ void ServiceWorkerFetchContextImpl::InitializeOnWorkerThread() { ...@@ -67,6 +68,8 @@ void ServiceWorkerFetchContextImpl::InitializeOnWorkerThread() {
network::SharedURLLoaderFactory::Create( network::SharedURLLoaderFactory::Create(
std::move(script_loader_factory_info_))); std::move(script_loader_factory_info_)));
} }
accept_languages_watcher_ = watcher;
} }
blink::WebURLLoaderFactory* blink::WebURLLoaderFactory*
...@@ -135,7 +138,14 @@ ServiceWorkerFetchContextImpl::CreateWebSocketHandshakeThrottle() { ...@@ -135,7 +138,14 @@ ServiceWorkerFetchContextImpl::CreateWebSocketHandshakeThrottle() {
void ServiceWorkerFetchContextImpl::NotifyUpdate( void ServiceWorkerFetchContextImpl::NotifyUpdate(
const RendererPreferences& new_prefs) { const RendererPreferences& new_prefs) {
DCHECK(accept_languages_watcher_);
if (renderer_preferences_.accept_languages != new_prefs.accept_languages)
accept_languages_watcher_->NotifyUpdate();
renderer_preferences_ = new_prefs; renderer_preferences_ = new_prefs;
} }
blink::WebString ServiceWorkerFetchContextImpl::GetAcceptLanguages() const {
return blink::WebString::FromUTF8(renderer_preferences_.accept_languages);
}
} // namespace content } // namespace content
...@@ -43,7 +43,7 @@ class ServiceWorkerFetchContextImpl final ...@@ -43,7 +43,7 @@ class ServiceWorkerFetchContextImpl final
// blink::WebWorkerFetchContext implementation: // blink::WebWorkerFetchContext implementation:
void SetTerminateSyncLoadEvent(base::WaitableEvent*) override; void SetTerminateSyncLoadEvent(base::WaitableEvent*) override;
void InitializeOnWorkerThread() override; void InitializeOnWorkerThread(blink::AcceptLanguagesWatcher*) override;
blink::WebURLLoaderFactory* GetURLLoaderFactory() override; blink::WebURLLoaderFactory* GetURLLoaderFactory() override;
std::unique_ptr<blink::WebURLLoaderFactory> WrapURLLoaderFactory( std::unique_ptr<blink::WebURLLoaderFactory> WrapURLLoaderFactory(
mojo::ScopedMessagePipeHandle url_loader_factory_handle) override; mojo::ScopedMessagePipeHandle url_loader_factory_handle) override;
...@@ -54,6 +54,7 @@ class ServiceWorkerFetchContextImpl final ...@@ -54,6 +54,7 @@ class ServiceWorkerFetchContextImpl final
blink::WebURL SiteForCookies() const override; blink::WebURL SiteForCookies() const override;
std::unique_ptr<blink::WebSocketHandshakeThrottle> std::unique_ptr<blink::WebSocketHandshakeThrottle>
CreateWebSocketHandshakeThrottle() override; CreateWebSocketHandshakeThrottle() override;
blink::WebString GetAcceptLanguages() const override;
private: private:
~ServiceWorkerFetchContextImpl() override; ~ServiceWorkerFetchContextImpl() override;
...@@ -90,6 +91,8 @@ class ServiceWorkerFetchContextImpl final ...@@ -90,6 +91,8 @@ class ServiceWorkerFetchContextImpl final
// This is owned by ThreadedMessagingProxyBase on the main thread. // This is owned by ThreadedMessagingProxyBase on the main thread.
base::WaitableEvent* terminate_sync_load_event_ = nullptr; base::WaitableEvent* terminate_sync_load_event_ = nullptr;
blink::AcceptLanguagesWatcher* accept_languages_watcher_ = nullptr;
}; };
} // namespace content } // namespace content
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include "third_party/blink/public/platform/web_application_cache_host.h" #include "third_party/blink/public/platform/web_application_cache_host.h"
#include "third_party/blink/public/platform/web_document_subresource_filter.h" #include "third_party/blink/public/platform/web_document_subresource_filter.h"
#include "third_party/blink/public/platform/web_security_origin.h" #include "third_party/blink/public/platform/web_security_origin.h"
#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/public/platform/web_url.h" #include "third_party/blink/public/platform/web_url.h"
#include "third_party/blink/public/platform/web_url_loader_factory.h" #include "third_party/blink/public/platform/web_url_loader_factory.h"
#include "third_party/blink/public/platform/websocket_handshake_throttle.h" #include "third_party/blink/public/platform/websocket_handshake_throttle.h"
...@@ -27,6 +28,13 @@ namespace blink { ...@@ -27,6 +28,13 @@ namespace blink {
class WebURLRequest; class WebURLRequest;
class WebDocumentSubresourceFilter; class WebDocumentSubresourceFilter;
// Helper class allowing WebWorkerFetchContextImpl to notify blink upon an
// accept languages update. This class will be extended by WorkerNavigator.
class AcceptLanguagesWatcher {
public:
virtual void NotifyUpdate() = 0;
};
// WebWorkerFetchContext is a per-worker object created on the main thread, // WebWorkerFetchContext is a per-worker object created on the main thread,
// passed to a worker (dedicated, shared and service worker) and initialized on // passed to a worker (dedicated, shared and service worker) and initialized on
// the worker thread by InitializeOnWorkerThread(). It contains information // the worker thread by InitializeOnWorkerThread(). It contains information
...@@ -58,7 +66,7 @@ class WebWorkerFetchContext : public base::RefCounted<WebWorkerFetchContext> { ...@@ -58,7 +66,7 @@ class WebWorkerFetchContext : public base::RefCounted<WebWorkerFetchContext> {
// pointer is valid throughout the lifetime of this context. // pointer is valid throughout the lifetime of this context.
virtual void SetTerminateSyncLoadEvent(base::WaitableEvent*) = 0; virtual void SetTerminateSyncLoadEvent(base::WaitableEvent*) = 0;
virtual void InitializeOnWorkerThread() = 0; virtual void InitializeOnWorkerThread(AcceptLanguagesWatcher*) = 0;
// Returns a WebURLLoaderFactory which is associated with the worker context. // Returns a WebURLLoaderFactory which is associated with the worker context.
// The returned WebURLLoaderFactory is owned by |this|. // The returned WebURLLoaderFactory is owned by |this|.
...@@ -133,6 +141,9 @@ class WebWorkerFetchContext : public base::RefCounted<WebWorkerFetchContext> { ...@@ -133,6 +141,9 @@ class WebWorkerFetchContext : public base::RefCounted<WebWorkerFetchContext> {
CreateWebSocketHandshakeThrottle() { CreateWebSocketHandshakeThrottle() {
return nullptr; return nullptr;
} }
// Returns the current list of user prefered languages.
virtual blink::WebString GetAcceptLanguages() const = 0;
}; };
} // namespace blink } // namespace blink
......
...@@ -282,7 +282,7 @@ void LocalDOMWindow::ClearDocument() { ...@@ -282,7 +282,7 @@ void LocalDOMWindow::ClearDocument() {
void LocalDOMWindow::AcceptLanguagesChanged() { void LocalDOMWindow::AcceptLanguagesChanged() {
if (navigator_) if (navigator_)
navigator_->SetLanguagesChanged(); navigator_->SetLanguagesDirty();
DispatchEvent(*Event::Create(event_type_names::kLanguagechange)); DispatchEvent(*Event::Create(event_type_names::kLanguagechange));
} }
......
...@@ -32,13 +32,13 @@ ...@@ -32,13 +32,13 @@
#include "third_party/blink/renderer/core/loader/frame_loader.h" #include "third_party/blink/renderer/core/loader/frame_loader.h"
#include "third_party/blink/renderer/core/page/chrome_client.h" #include "third_party/blink/renderer/core/page/chrome_client.h"
#include "third_party/blink/renderer/core/page/page.h" #include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/core/probe/core_probes.h"
#include "third_party/blink/renderer/platform/language.h" #include "third_party/blink/renderer/platform/language.h"
#include "third_party/blink/renderer/platform/memory_coordinator.h" #include "third_party/blink/renderer/platform/memory_coordinator.h"
namespace blink { namespace blink {
Navigator::Navigator(LocalFrame* frame) : DOMWindowClient(frame) {} Navigator::Navigator(LocalFrame* frame)
: NavigatorLanguage(frame->GetDocument()), DOMWindowClient(frame) {}
String Navigator::productSub() const { String Navigator::productSub() const {
return "20030107"; return "20030107";
...@@ -83,38 +83,21 @@ bool Navigator::cookieEnabled() const { ...@@ -83,38 +83,21 @@ bool Navigator::cookieEnabled() const {
return CookiesEnabled(GetFrame()->GetDocument()); return CookiesEnabled(GetFrame()->GetDocument());
} }
Vector<String> Navigator::languages() { String Navigator::GetAcceptLanguages() {
languages_changed_ = false;
String accept_languages; String accept_languages;
if (GetFrame() && GetFrame()->GetPage()) { if (GetFrame() && GetFrame()->GetPage()) {
accept_languages = accept_languages =
GetFrame()->GetPage()->GetChromeClient().AcceptLanguages(); GetFrame()->GetPage()->GetChromeClient().AcceptLanguages();
} else {
accept_languages = DefaultLanguage();
} }
probe::applyAcceptLanguageOverride(GetFrame(), &accept_languages); return accept_languages;
Vector<String> languages;
accept_languages.Split(',', languages);
// Sanitizing tokens. We could do that more extensively but we should assume
// that the accept languages are already sane and support BCP47. It is
// likely a waste of time to make sure the tokens matches that spec here.
for (wtf_size_t i = 0; i < languages.size(); ++i) {
String& token = languages[i];
token = token.StripWhiteSpace();
if (token.length() >= 3 && token[2] == '_')
token.replace(2, 1, "-");
}
if (languages.IsEmpty())
languages.push_back(DefaultLanguage());
return languages;
} }
void Navigator::Trace(blink::Visitor* visitor) { void Navigator::Trace(blink::Visitor* visitor) {
ScriptWrappable::Trace(visitor); ScriptWrappable::Trace(visitor);
NavigatorLanguage::Trace(visitor);
DOMWindowClient::Trace(visitor); DOMWindowClient::Trace(visitor);
Supplementable<Navigator>::Trace(visitor); Supplementable<Navigator>::Trace(visitor);
} }
......
...@@ -66,8 +66,7 @@ class CORE_EXPORT Navigator final : public ScriptWrappable, ...@@ -66,8 +66,7 @@ class CORE_EXPORT Navigator final : public ScriptWrappable,
String platform() const override; String platform() const override;
String userAgent() const override; String userAgent() const override;
// NavigatorLanguage String GetAcceptLanguages() override;
Vector<String> languages() override;
void Trace(blink::Visitor*) override; void Trace(blink::Visitor*) override;
}; };
......
...@@ -4,22 +4,65 @@ ...@@ -4,22 +4,65 @@
#include "third_party/blink/renderer/core/frame/navigator_language.h" #include "third_party/blink/renderer/core/frame/navigator_language.h"
#include "third_party/blink/renderer/core/probe/core_probes.h"
#include "third_party/blink/renderer/platform/language.h" #include "third_party/blink/renderer/platform/language.h"
namespace blink { namespace blink {
NavigatorLanguage::NavigatorLanguage() = default; Vector<String> ParseAndSanitize(const String& accept_languages) {
Vector<String> languages;
accept_languages.Split(',', languages);
// Sanitizing tokens. We could do that more extensively but we should assume
// that the accept languages are already sane and support BCP47. It is
// likely a waste of time to make sure the tokens matches that spec here.
for (size_t i = 0; i < languages.size(); ++i) {
String& token = languages[i];
token = token.StripWhiteSpace();
if (token.length() >= 3 && token[2] == '_')
token.replace(2, 1, "-");
}
if (languages.IsEmpty())
languages.push_back(DefaultLanguage());
return languages;
}
NavigatorLanguage::NavigatorLanguage(ExecutionContext* context)
: context_(context) {}
AtomicString NavigatorLanguage::language() { AtomicString NavigatorLanguage::language() {
return AtomicString(languages().front()); return AtomicString(languages().front());
} }
bool NavigatorLanguage::hasLanguagesChanged() const { const Vector<String>& NavigatorLanguage::languages() {
return languages_changed_; if (languages_dirty_) {
String accept_languages_override;
probe::applyAcceptLanguageOverride(context_, &accept_languages_override);
if (!accept_languages_override.IsNull()) {
languages_ = ParseAndSanitize(accept_languages_override);
} else {
languages_ = ParseAndSanitize(GetAcceptLanguages());
}
languages_dirty_ = false;
}
return languages_;
}
bool NavigatorLanguage::IsLanguagesDirty() const {
return languages_dirty_;
}
void NavigatorLanguage::SetLanguagesDirty() {
languages_dirty_ = true;
languages_.clear();
} }
void NavigatorLanguage::SetLanguagesChanged() { void NavigatorLanguage::Trace(blink::Visitor* visitor) {
languages_changed_ = true; visitor->Trace(context_);
} }
} // namespace blink } // namespace blink
...@@ -6,21 +6,29 @@ ...@@ -6,21 +6,29 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_NAVIGATOR_LANGUAGE_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_NAVIGATOR_LANGUAGE_H_
#include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h" #include "third_party/blink/renderer/platform/wtf/text/atomic_string.h"
namespace blink { namespace blink {
class CORE_EXPORT NavigatorLanguage { class CORE_EXPORT NavigatorLanguage : public GarbageCollectedMixin {
public: public:
NavigatorLanguage(); explicit NavigatorLanguage(ExecutionContext*);
AtomicString language(); AtomicString language();
virtual Vector<String> languages() = 0; const Vector<String>& languages();
bool hasLanguagesChanged() const; bool IsLanguagesDirty() const;
void SetLanguagesChanged(); void SetLanguagesDirty();
void Trace(blink::Visitor*) override;
protected: protected:
bool languages_changed_ = true; bool languages_dirty_ = true;
WeakMember<ExecutionContext> context_;
virtual String GetAcceptLanguages() = 0;
private:
Vector<String> languages_;
}; };
} // namespace blink } // namespace blink
......
...@@ -9,5 +9,5 @@ ...@@ -9,5 +9,5 @@
Exposed=(Window,Worker) Exposed=(Window,Worker)
] interface NavigatorLanguage { ] interface NavigatorLanguage {
readonly attribute DOMString language; readonly attribute DOMString language;
[CachedAttribute=hasLanguagesChanged] readonly attribute FrozenArray<DOMString> languages; [CachedAttribute=IsLanguagesDirty] readonly attribute FrozenArray<DOMString> languages;
}; };
...@@ -110,7 +110,7 @@ void WorkerInspectorController::AttachSession(DevToolsSession* session, ...@@ -110,7 +110,7 @@ void WorkerInspectorController::AttachSession(DevToolsSession* session,
session->Append(MakeGarbageCollected<InspectorLogAgent>( session->Append(MakeGarbageCollected<InspectorLogAgent>(
thread_->GetConsoleMessageStorage(), nullptr, session->V8Session())); thread_->GetConsoleMessageStorage(), nullptr, session->V8Session()));
if (auto* scope = DynamicTo<WorkerGlobalScope>(thread_->GlobalScope())) { if (auto* scope = DynamicTo<WorkerGlobalScope>(thread_->GlobalScope())) {
DCHECK(scope->EnsureFetcher()); scope->EnsureFetcher();
session->Append(MakeGarbageCollected<InspectorNetworkAgent>( session->Append(MakeGarbageCollected<InspectorNetworkAgent>(
inspected_frames_.Get(), scope, session->V8Session())); inspected_frames_.Get(), scope, session->V8Session()));
session->Append(MakeGarbageCollected<InspectorEmulationAgent>(nullptr)); session->Append(MakeGarbageCollected<InspectorEmulationAgent>(nullptr));
......
...@@ -87,7 +87,7 @@ interface CoreProbes { ...@@ -87,7 +87,7 @@ interface CoreProbes {
void didFireWebGLErrorOrWarning(Element*, const String& message); void didFireWebGLErrorOrWarning(Element*, const String& message);
void didResizeMainFrame(LocalFrame*); void didResizeMainFrame(LocalFrame*);
void didPaint(LocalFrame*, const GraphicsLayer*, GraphicsContext&, const LayoutRect&); void didPaint(LocalFrame*, const GraphicsLayer*, GraphicsContext&, const LayoutRect&);
void applyAcceptLanguageOverride(LocalFrame*, String* acceptLanguage); void applyAcceptLanguageOverride(ExecutionContext*, String* acceptLanguage);
void applyUserAgentOverride(ExecutionContext*, String* userAgent); void applyUserAgentOverride(ExecutionContext*, String* userAgent);
void didBlockRequest([Keep] ExecutionContext*, const ResourceRequest&, DocumentLoader*, const FetchInitiatorInfo&, ResourceRequestBlockedReason, ResourceType); void didBlockRequest([Keep] ExecutionContext*, const ResourceRequest&, DocumentLoader*, const FetchInitiatorInfo&, ResourceRequestBlockedReason, ResourceType);
void didChangeResourcePriority(LocalFrame*, DocumentLoader*, unsigned long identifier, ResourceLoadPriority loadPriority); void didChangeResourcePriority(LocalFrame*, DocumentLoader*, unsigned long identifier, ResourceLoadPriority loadPriority);
......
...@@ -123,7 +123,7 @@ WorkerLocation* WorkerGlobalScope::location() const { ...@@ -123,7 +123,7 @@ WorkerLocation* WorkerGlobalScope::location() const {
WorkerNavigator* WorkerGlobalScope::navigator() const { WorkerNavigator* WorkerGlobalScope::navigator() const {
if (!navigator_) if (!navigator_)
navigator_ = WorkerNavigator::Create(user_agent_); navigator_ = WorkerNavigator::Create(user_agent_, GetExecutionContext());
return navigator_.Get(); return navigator_.Get();
} }
......
...@@ -93,7 +93,7 @@ class CORE_EXPORT WorkerGlobalScope ...@@ -93,7 +93,7 @@ class CORE_EXPORT WorkerGlobalScope
// WorkerGlobalScope // WorkerGlobalScope
WorkerGlobalScope* self() { return this; } WorkerGlobalScope* self() { return this; }
WorkerLocation* location() const; WorkerLocation* location() const;
WorkerNavigator* navigator() const; WorkerNavigator* navigator() const override;
void close(); void close();
bool isSecureContextForBindings() const { bool isSecureContextForBindings() const {
return ExecutionContext::IsSecureContext(); return ExecutionContext::IsSecureContext();
...@@ -102,6 +102,7 @@ class CORE_EXPORT WorkerGlobalScope ...@@ -102,6 +102,7 @@ class CORE_EXPORT WorkerGlobalScope
String origin() const; String origin() const;
DEFINE_ATTRIBUTE_EVENT_LISTENER(error, kError); DEFINE_ATTRIBUTE_EVENT_LISTENER(error, kError);
DEFINE_ATTRIBUTE_EVENT_LISTENER(languagechange, kLanguagechange);
DEFINE_ATTRIBUTE_EVENT_LISTENER(rejectionhandled, kRejectionhandled); DEFINE_ATTRIBUTE_EVENT_LISTENER(rejectionhandled, kRejectionhandled);
DEFINE_ATTRIBUTE_EVENT_LISTENER(unhandledrejection, kUnhandledrejection); DEFINE_ATTRIBUTE_EVENT_LISTENER(unhandledrejection, kUnhandledrejection);
......
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
// TODO(foolip): onerror should be an OnErrorEventHandler. // TODO(foolip): onerror should be an OnErrorEventHandler.
attribute EventHandler onerror; attribute EventHandler onerror;
// attribute EventHandler onlanguagechange; attribute EventHandler onlanguagechange;
// attribute EventHandler onoffline; // attribute EventHandler onoffline;
// attribute EventHandler ononline; // attribute EventHandler ononline;
......
...@@ -25,11 +25,20 @@ ...@@ -25,11 +25,20 @@
*/ */
#include "third_party/blink/renderer/core/workers/worker_navigator.h" #include "third_party/blink/renderer/core/workers/worker_navigator.h"
#include "third_party/blink/public/platform/web_worker_fetch_context.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/core/dom/events/event_target.h"
#include "third_party/blink/renderer/core/loader/worker_fetch_context.h"
#include "third_party/blink/renderer/core/workers/worker_global_scope.h"
#include "third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.h"
#include "third_party/blink/renderer/core/workers/worker_thread.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h"
namespace blink { namespace blink {
WorkerNavigator::WorkerNavigator(const String& user_agent) WorkerNavigator::WorkerNavigator(const String& user_agent,
: user_agent_(user_agent) {} ExecutionContext* context)
: NavigatorLanguage(context), user_agent_(user_agent) {}
WorkerNavigator::~WorkerNavigator() = default; WorkerNavigator::~WorkerNavigator() = default;
...@@ -37,8 +46,27 @@ String WorkerNavigator::userAgent() const { ...@@ -37,8 +46,27 @@ String WorkerNavigator::userAgent() const {
return user_agent_; return user_agent_;
} }
String WorkerNavigator::GetAcceptLanguages() {
WorkerOrWorkletGlobalScope* global_scope =
To<WorkerOrWorkletGlobalScope>(context_.Get());
WebWorkerFetchContext* worker_fetch_context =
static_cast<WorkerFetchContext*>(
(&global_scope->EnsureFetcher()->Context()))
->GetWebWorkerFetchContext();
return worker_fetch_context->GetAcceptLanguages();
}
void WorkerNavigator::NotifyUpdate() {
SetLanguagesDirty();
WorkerOrWorkletGlobalScope* global_scope =
To<WorkerOrWorkletGlobalScope>(context_.Get());
global_scope->DispatchEvent(
*Event::Create(event_type_names::kLanguagechange));
}
void WorkerNavigator::Trace(blink::Visitor* visitor) { void WorkerNavigator::Trace(blink::Visitor* visitor) {
ScriptWrappable::Trace(visitor); ScriptWrappable::Trace(visitor);
NavigatorLanguage::Trace(visitor);
Supplementable<WorkerNavigator>::Trace(visitor); Supplementable<WorkerNavigator>::Trace(visitor);
} }
......
...@@ -26,10 +26,13 @@ ...@@ -26,10 +26,13 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_WORKERS_WORKER_NAVIGATOR_H_ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_WORKERS_WORKER_NAVIGATOR_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_WORKERS_WORKER_NAVIGATOR_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_WORKERS_WORKER_NAVIGATOR_H_
#include "third_party/blink/public/platform/web_worker_fetch_context.h"
#include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/frame/navigator_concurrent_hardware.h" #include "third_party/blink/renderer/core/frame/navigator_concurrent_hardware.h"
#include "third_party/blink/renderer/core/frame/navigator_device_memory.h" #include "third_party/blink/renderer/core/frame/navigator_device_memory.h"
#include "third_party/blink/renderer/core/frame/navigator_id.h" #include "third_party/blink/renderer/core/frame/navigator_id.h"
#include "third_party/blink/renderer/core/frame/navigator_language.h"
#include "third_party/blink/renderer/core/frame/navigator_on_line.h" #include "third_party/blink/renderer/core/frame/navigator_on_line.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/heap/handle.h"
...@@ -40,24 +43,34 @@ namespace blink { ...@@ -40,24 +43,34 @@ namespace blink {
class CORE_EXPORT WorkerNavigator final class CORE_EXPORT WorkerNavigator final
: public ScriptWrappable, : public ScriptWrappable,
public AcceptLanguagesWatcher,
public NavigatorConcurrentHardware, public NavigatorConcurrentHardware,
public NavigatorDeviceMemory, public NavigatorDeviceMemory,
public NavigatorID, public NavigatorID,
public NavigatorLanguage,
public NavigatorOnLine, public NavigatorOnLine,
public Supplementable<WorkerNavigator> { public Supplementable<WorkerNavigator> {
DEFINE_WRAPPERTYPEINFO(); DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(WorkerNavigator); USING_GARBAGE_COLLECTED_MIXIN(WorkerNavigator);
public: public:
static WorkerNavigator* Create(const String& user_agent) { static WorkerNavigator* Create(const String& user_agent,
return MakeGarbageCollected<WorkerNavigator>(user_agent); ExecutionContext* context) {
return MakeGarbageCollected<WorkerNavigator>(user_agent, context);
} }
explicit WorkerNavigator(const String&); explicit WorkerNavigator(const String&, ExecutionContext* context);
~WorkerNavigator() override; ~WorkerNavigator() override;
// NavigatorID override
String userAgent() const override; String userAgent() const override;
// NavigatorLanguage override
String GetAcceptLanguages() override;
// AcceptLanguagesWatcher override
void NotifyUpdate() override;
void Trace(blink::Visitor*) override; void Trace(blink::Visitor*) override;
private: private:
......
...@@ -36,5 +36,5 @@ ...@@ -36,5 +36,5 @@
WorkerNavigator implements NavigatorConcurrentHardware; WorkerNavigator implements NavigatorConcurrentHardware;
WorkerNavigator implements NavigatorDeviceMemory; WorkerNavigator implements NavigatorDeviceMemory;
WorkerNavigator implements NavigatorID; WorkerNavigator implements NavigatorID;
// TODO(foolip): WorkerNavigator implements NavigatorLanguage; WorkerNavigator implements NavigatorLanguage;
WorkerNavigator implements NavigatorOnLine; WorkerNavigator implements NavigatorOnLine;
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include "third_party/blink/renderer/core/loader/worker_fetch_context.h" #include "third_party/blink/renderer/core/loader/worker_fetch_context.h"
#include "third_party/blink/renderer/core/probe/core_probes.h" #include "third_party/blink/renderer/core/probe/core_probes.h"
#include "third_party/blink/renderer/core/script/fetch_client_settings_object_impl.h" #include "third_party/blink/renderer/core/script/fetch_client_settings_object_impl.h"
#include "third_party/blink/renderer/core/workers/worker_global_scope.h"
#include "third_party/blink/renderer/core/workers/worker_reporting_proxy.h" #include "third_party/blink/renderer/core/workers/worker_reporting_proxy.h"
#include "third_party/blink/renderer/core/workers/worker_thread.h" #include "third_party/blink/renderer/core/workers/worker_thread.h"
#include "third_party/blink/renderer/platform/cross_thread_functional.h" #include "third_party/blink/renderer/platform/cross_thread_functional.h"
...@@ -108,7 +109,7 @@ void WorkerOrWorkletGlobalScope::InitializeWebFetchContextIfNeeded() { ...@@ -108,7 +109,7 @@ void WorkerOrWorkletGlobalScope::InitializeWebFetchContextIfNeeded() {
return; return;
DCHECK(!subresource_filter_); DCHECK(!subresource_filter_);
web_worker_fetch_context_->InitializeOnWorkerThread(); web_worker_fetch_context_->InitializeOnWorkerThread(navigator());
std::unique_ptr<blink::WebDocumentSubresourceFilter> web_filter = std::unique_ptr<blink::WebDocumentSubresourceFilter> web_filter =
web_worker_fetch_context_->TakeSubresourceFilter(); web_worker_fetch_context_->TakeSubresourceFilter();
if (web_filter) { if (web_filter) {
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include "third_party/blink/renderer/core/frame/web_feature_forward.h" #include "third_party/blink/renderer/core/frame/web_feature_forward.h"
#include "third_party/blink/renderer/core/script/modulator.h" #include "third_party/blink/renderer/core/script/modulator.h"
#include "third_party/blink/renderer/core/workers/worker_clients.h" #include "third_party/blink/renderer/core/workers/worker_clients.h"
#include "third_party/blink/renderer/core/workers/worker_navigator.h"
#include "third_party/blink/renderer/platform/scheduler/public/worker_scheduler.h" #include "third_party/blink/renderer/platform/scheduler/public/worker_scheduler.h"
#include "third_party/blink/renderer/platform/wtf/bit_vector.h" #include "third_party/blink/renderer/platform/wtf/bit_vector.h"
#include "third_party/blink/renderer/platform/wtf/casting.h" #include "third_party/blink/renderer/platform/wtf/casting.h"
...@@ -91,6 +92,9 @@ class CORE_EXPORT WorkerOrWorkletGlobalScope : public EventTargetWithInlineData, ...@@ -91,6 +92,9 @@ class CORE_EXPORT WorkerOrWorkletGlobalScope : public EventTargetWithInlineData,
// WorkletGlobalScope for the main thread) or after Dispose() is called. // WorkletGlobalScope for the main thread) or after Dispose() is called.
virtual WorkerThread* GetThread() const = 0; virtual WorkerThread* GetThread() const = 0;
// Returns nullptr if this global scope is a WorkletGlobalScope
virtual WorkerNavigator* navigator() const { return nullptr; }
ResourceFetcher* Fetcher() const override; ResourceFetcher* Fetcher() const override;
ResourceFetcher* EnsureFetcher(); ResourceFetcher* EnsureFetcher();
......
...@@ -41,6 +41,7 @@ ...@@ -41,6 +41,7 @@
#include "third_party/blink/renderer/core/frame/csp/content_security_policy.h" #include "third_party/blink/renderer/core/frame/csp/content_security_policy.h"
#include "third_party/blink/renderer/core/workers/parent_execution_context_task_runners.h" #include "third_party/blink/renderer/core/workers/parent_execution_context_task_runners.h"
#include "third_party/blink/renderer/core/workers/worker_backing_thread_startup_data.h" #include "third_party/blink/renderer/core/workers/worker_backing_thread_startup_data.h"
#include "third_party/blink/renderer/platform/cross_thread_functional.h"
#include "third_party/blink/renderer/platform/scheduler/public/post_cancellable_task.h" #include "third_party/blink/renderer/platform/scheduler/public/post_cancellable_task.h"
#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h" #include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
#include "third_party/blink/renderer/platform/scheduler/public/thread.h" #include "third_party/blink/renderer/platform/scheduler/public/thread.h"
......
...@@ -4160,6 +4160,8 @@ crbug.com/655458 virtual/omt-worker-fetch/external/wpt/workers/constructors/Shar ...@@ -4160,6 +4160,8 @@ crbug.com/655458 virtual/omt-worker-fetch/external/wpt/workers/constructors/Shar
crbug.com/655458 virtual/omt-worker-fetch/external/wpt/workers/constructors/SharedWorker/unresolvable-url.html [ Failure ] crbug.com/655458 virtual/omt-worker-fetch/external/wpt/workers/constructors/SharedWorker/unresolvable-url.html [ Failure ]
crbug.com/655458 virtual/omt-worker-fetch/external/wpt/workers/semantics/multiple-workers/007.html [ Timeout ] crbug.com/655458 virtual/omt-worker-fetch/external/wpt/workers/semantics/multiple-workers/007.html [ Timeout ]
crbug.com/910709 navigator_language/worker_navigator_language.html [ Timeout ]
# Off-the-main-thread classic worker script fetch. # Off-the-main-thread classic worker script fetch.
# This fails because running a worker on an opaque origin is blocked. # This fails because running a worker on an opaque origin is blocked.
crbug.com/835717 virtual/omt-worker-fetch/external/wpt/workers/opaque-origin.html [ Timeout ] crbug.com/835717 virtual/omt-worker-fetch/external/wpt/workers/opaque-origin.html [ Timeout ]
......
This is a testharness.js-based test. This is a testharness.js-based test.
Found 161 tests; 151 PASS, 10 FAIL, 0 TIMEOUT, 0 NOTRUN. Found 161 tests; 157 PASS, 4 FAIL, 0 TIMEOUT, 0 NOTRUN.
PASS EventTarget interface: existence and properties of interface object PASS EventTarget interface: existence and properties of interface object
PASS EventTarget interface object length PASS EventTarget interface object length
PASS EventTarget interface object name PASS EventTarget interface object name
...@@ -21,7 +21,7 @@ PASS WorkerGlobalScope interface: attribute location ...@@ -21,7 +21,7 @@ PASS WorkerGlobalScope interface: attribute location
PASS WorkerGlobalScope interface: attribute navigator PASS WorkerGlobalScope interface: attribute navigator
PASS WorkerGlobalScope interface: operation importScripts(USVString) PASS WorkerGlobalScope interface: operation importScripts(USVString)
PASS WorkerGlobalScope interface: attribute onerror PASS WorkerGlobalScope interface: attribute onerror
FAIL WorkerGlobalScope interface: attribute onlanguagechange assert_true: The prototype object must have a property "onlanguagechange" expected true got false PASS WorkerGlobalScope interface: attribute onlanguagechange
FAIL WorkerGlobalScope interface: attribute onoffline assert_true: The prototype object must have a property "onoffline" expected true got false FAIL WorkerGlobalScope interface: attribute onoffline assert_true: The prototype object must have a property "onoffline" expected true got false
FAIL WorkerGlobalScope interface: attribute ononline assert_true: The prototype object must have a property "ononline" expected true got false FAIL WorkerGlobalScope interface: attribute ononline assert_true: The prototype object must have a property "ononline" expected true got false
PASS WorkerGlobalScope interface: attribute onrejectionhandled PASS WorkerGlobalScope interface: attribute onrejectionhandled
...@@ -72,7 +72,7 @@ PASS WorkerGlobalScope interface: self must inherit property "navigator" with th ...@@ -72,7 +72,7 @@ PASS WorkerGlobalScope interface: self must inherit property "navigator" with th
PASS WorkerGlobalScope interface: self must inherit property "importScripts(USVString)" with the proper type PASS WorkerGlobalScope interface: self must inherit property "importScripts(USVString)" with the proper type
PASS WorkerGlobalScope interface: calling importScripts(USVString) on self with too few arguments must throw TypeError PASS WorkerGlobalScope interface: calling importScripts(USVString) on self with too few arguments must throw TypeError
PASS WorkerGlobalScope interface: self must inherit property "onerror" with the proper type PASS WorkerGlobalScope interface: self must inherit property "onerror" with the proper type
FAIL WorkerGlobalScope interface: self must inherit property "onlanguagechange" with the proper type assert_inherits: property "onlanguagechange" not found in prototype chain PASS WorkerGlobalScope interface: self must inherit property "onlanguagechange" with the proper type
FAIL WorkerGlobalScope interface: self must inherit property "onoffline" with the proper type assert_inherits: property "onoffline" not found in prototype chain FAIL WorkerGlobalScope interface: self must inherit property "onoffline" with the proper type assert_inherits: property "onoffline" not found in prototype chain
FAIL WorkerGlobalScope interface: self must inherit property "ononline" with the proper type assert_inherits: property "ononline" not found in prototype chain FAIL WorkerGlobalScope interface: self must inherit property "ononline" with the proper type assert_inherits: property "ononline" not found in prototype chain
PASS WorkerGlobalScope interface: self must inherit property "onrejectionhandled" with the proper type PASS WorkerGlobalScope interface: self must inherit property "onrejectionhandled" with the proper type
...@@ -115,8 +115,8 @@ PASS WorkerNavigator interface: member productSub ...@@ -115,8 +115,8 @@ PASS WorkerNavigator interface: member productSub
PASS WorkerNavigator interface: attribute userAgent PASS WorkerNavigator interface: attribute userAgent
PASS WorkerNavigator interface: member vendor PASS WorkerNavigator interface: member vendor
PASS WorkerNavigator interface: member vendorSub PASS WorkerNavigator interface: member vendorSub
FAIL WorkerNavigator interface: attribute language assert_true: The prototype object must have a property "language" expected true got false PASS WorkerNavigator interface: attribute language
FAIL WorkerNavigator interface: attribute languages assert_true: The prototype object must have a property "languages" expected true got false PASS WorkerNavigator interface: attribute languages
PASS WorkerNavigator interface: attribute onLine PASS WorkerNavigator interface: attribute onLine
PASS WorkerNavigator interface: attribute hardwareConcurrency PASS WorkerNavigator interface: attribute hardwareConcurrency
PASS WorkerNavigator must be primary interface of self.navigator PASS WorkerNavigator must be primary interface of self.navigator
...@@ -130,8 +130,8 @@ PASS WorkerNavigator interface: self.navigator must not have property "productSu ...@@ -130,8 +130,8 @@ PASS WorkerNavigator interface: self.navigator must not have property "productSu
PASS WorkerNavigator interface: self.navigator must inherit property "userAgent" with the proper type PASS WorkerNavigator interface: self.navigator must inherit property "userAgent" with the proper type
PASS WorkerNavigator interface: self.navigator must not have property "vendor" PASS WorkerNavigator interface: self.navigator must not have property "vendor"
PASS WorkerNavigator interface: self.navigator must not have property "vendorSub" PASS WorkerNavigator interface: self.navigator must not have property "vendorSub"
FAIL WorkerNavigator interface: self.navigator must inherit property "language" with the proper type assert_inherits: property "language" not found in prototype chain PASS WorkerNavigator interface: self.navigator must inherit property "language" with the proper type
FAIL WorkerNavigator interface: self.navigator must inherit property "languages" with the proper type assert_inherits: property "languages" not found in prototype chain PASS WorkerNavigator interface: self.navigator must inherit property "languages" with the proper type
PASS WorkerNavigator interface: self.navigator must inherit property "onLine" with the proper type PASS WorkerNavigator interface: self.navigator must inherit property "onLine" with the proper type
PASS WorkerNavigator interface: self.navigator must inherit property "hardwareConcurrency" with the proper type PASS WorkerNavigator interface: self.navigator must inherit property "hardwareConcurrency" with the proper type
PASS WorkerLocation interface: existence and properties of interface object PASS WorkerLocation interface: existence and properties of interface object
......
...@@ -2,6 +2,7 @@ Tests emulation of the user agent. ...@@ -2,6 +2,7 @@ Tests emulation of the user agent.
navigator.userAgent == Test UA navigator.userAgent == Test UA
User-Agent: Test UA User-Agent: Test UA
navigator.language == ko navigator.language == ko
workerNavigator.language == ko
Accept-Language: ko, en;q=0.9, zh-CN;q=0.8, zh-HK;q=0.7, en-US;q=0.6, en-GB;q=0.5 Accept-Language: ko, en;q=0.9, zh-CN;q=0.8, zh-HK;q=0.7, en-US;q=0.6, en-GB;q=0.5
accept-language: ko accept-language: ko
navigator.platform == new_platform navigator.platform == new_platform
......
...@@ -9,6 +9,18 @@ ...@@ -9,6 +9,18 @@
// Accept Language // Accept Language
await dp.Emulation.setUserAgentOverride({userAgent: '', acceptLanguage: 'ko, en, zh-CN, zh-HK, en-US, en-GB'}); await dp.Emulation.setUserAgentOverride({userAgent: '', acceptLanguage: 'ko, en, zh-CN, zh-HK, en-US, en-GB'});
testRunner.log('navigator.language == ' + await session.evaluate('navigator.language')); testRunner.log('navigator.language == ' + await session.evaluate('navigator.language'));
// Worker Accept Language
await dp.Target.setAutoAttach({autoAttach: true, waitForDebuggerOnStart: false});
await session.evaluate(`var w = new Worker('${testRunner.url('resources/worker.js')}')`);
let event = await dp.Target.onceAttachedToTarget();
const worker = new WorkerProtocol(dp, event.params.sessionId);
await worker.dp.Emulation.setUserAgentOverride({userAgent: '', acceptLanguage: 'ko, en, zh-CN, zh-HK, en-US, en-GB'});
testRunner.log('workerNavigator.language == ' + await session.evaluateAsync(`
w.postMessage('ping!');
new Promise(resolve => w.onmessage = e => resolve(e.data.language))`));
await dp.Target.onceDetachedFromTarget();
await printHeader('Accept-Language'); await printHeader('Accept-Language');
// Do not override explicit Accept-Language header. // Do not override explicit Accept-Language header.
......
onmessage = function(e) {
postMessage({'language': navigator.language});
close();
};
...@@ -3446,6 +3446,7 @@ interface WorkerGlobalScope : EventTarget ...@@ -3446,6 +3446,7 @@ interface WorkerGlobalScope : EventTarget
getter location getter location
getter navigator getter navigator
getter onerror getter onerror
getter onlanguagechange
getter onrejectionhandled getter onrejectionhandled
getter onunhandledrejection getter onunhandledrejection
getter origin getter origin
...@@ -3465,6 +3466,7 @@ interface WorkerGlobalScope : EventTarget ...@@ -3465,6 +3466,7 @@ interface WorkerGlobalScope : EventTarget
method setInterval method setInterval
method setTimeout method setTimeout
setter onerror setter onerror
setter onlanguagechange
setter onrejectionhandled setter onrejectionhandled
setter onunhandledrejection setter onunhandledrejection
setter origin setter origin
...@@ -3490,6 +3492,8 @@ interface WorkerNavigator ...@@ -3490,6 +3492,8 @@ interface WorkerNavigator
getter connection getter connection
getter deviceMemory getter deviceMemory
getter hardwareConcurrency getter hardwareConcurrency
getter language
getter languages
getter locks getter locks
getter onLine getter onLine
getter permissions getter permissions
......
onmessage = function(evt)
{
postMessage(navigator.language);
}
onlanguagechange = function(evt)
{
postMessage('language event fired');
}
<!DOCTYPE html>
<html>
<body>
<script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script>
<script>
async_test(function() {
var worker = new Worker("resources/worker_language.js");
worker.onmessage = this.step_func_done(function(e) {
assert_equals(e.data, 'klingon');
});
testRunner.setAcceptLanguages('klingon');
worker.postMessage("langauge changed");
done();
}, "Test changing the language on worker threads.");
async_test(function() {
var worker = new Worker("resources/worker_language_event.js");
worker.onmessage = this.step_func_done(function(e) {
assert_equals(e.data, 'language event fired');
});
testRunner.setAcceptLanguages('fr-FR');
done();
}, "Test the language change event fires on worker threads.");
async_test(function() {
var worker = new Worker("resources/worker_language.js");
var previous = navigator.languages
worker.onmessage = this.step_func_done(function(e) {
assert_equals(e.data, previous);
});
worker.postMessage("same language");
worker.onmessage = this.step_func_done(function(e) {
assert_not_equals(e.data, previous);
});
testRunner.setAcceptLanguages('fr-FR');
worker.postMessage("different language");
done();
}, "Test caching behavior on worker threads");
</script>
</body>
</html>
...@@ -2447,6 +2447,7 @@ interface WorkerGlobalScope : EventTarget ...@@ -2447,6 +2447,7 @@ interface WorkerGlobalScope : EventTarget
getter location getter location
getter navigator getter navigator
getter onerror getter onerror
getter onlanguagechange
getter onrejectionhandled getter onrejectionhandled
getter onunhandledrejection getter onunhandledrejection
getter origin getter origin
...@@ -2466,6 +2467,7 @@ interface WorkerGlobalScope : EventTarget ...@@ -2466,6 +2467,7 @@ interface WorkerGlobalScope : EventTarget
method setInterval method setInterval
method setTimeout method setTimeout
setter onerror setter onerror
setter onlanguagechange
setter onrejectionhandled setter onrejectionhandled
setter onunhandledrejection setter onunhandledrejection
setter origin setter origin
...@@ -2491,6 +2493,8 @@ interface WorkerNavigator ...@@ -2491,6 +2493,8 @@ interface WorkerNavigator
getter connection getter connection
getter deviceMemory getter deviceMemory
getter hardwareConcurrency getter hardwareConcurrency
getter language
getter languages
getter locks getter locks
getter onLine getter onLine
getter permissions getter permissions
......
...@@ -2491,6 +2491,7 @@ Starting worker: resources/global-interface-listing-worker.js ...@@ -2491,6 +2491,7 @@ Starting worker: resources/global-interface-listing-worker.js
[Worker] getter location [Worker] getter location
[Worker] getter navigator [Worker] getter navigator
[Worker] getter onerror [Worker] getter onerror
[Worker] getter onlanguagechange
[Worker] getter onrejectionhandled [Worker] getter onrejectionhandled
[Worker] getter onunhandledrejection [Worker] getter onunhandledrejection
[Worker] getter origin [Worker] getter origin
...@@ -2510,6 +2511,7 @@ Starting worker: resources/global-interface-listing-worker.js ...@@ -2510,6 +2511,7 @@ Starting worker: resources/global-interface-listing-worker.js
[Worker] method setInterval [Worker] method setInterval
[Worker] method setTimeout [Worker] method setTimeout
[Worker] setter onerror [Worker] setter onerror
[Worker] setter onlanguagechange
[Worker] setter onrejectionhandled [Worker] setter onrejectionhandled
[Worker] setter onunhandledrejection [Worker] setter onunhandledrejection
[Worker] setter origin [Worker] setter origin
...@@ -2535,6 +2537,8 @@ Starting worker: resources/global-interface-listing-worker.js ...@@ -2535,6 +2537,8 @@ Starting worker: resources/global-interface-listing-worker.js
[Worker] getter connection [Worker] getter connection
[Worker] getter deviceMemory [Worker] getter deviceMemory
[Worker] getter hardwareConcurrency [Worker] getter hardwareConcurrency
[Worker] getter language
[Worker] getter languages
[Worker] getter locks [Worker] getter locks
[Worker] getter onLine [Worker] getter onLine
[Worker] getter permissions [Worker] getter permissions
......
...@@ -2378,6 +2378,7 @@ Starting worker: resources/global-interface-listing-worker.js ...@@ -2378,6 +2378,7 @@ Starting worker: resources/global-interface-listing-worker.js
[Worker] getter location [Worker] getter location
[Worker] getter navigator [Worker] getter navigator
[Worker] getter onerror [Worker] getter onerror
[Worker] getter onlanguagechange
[Worker] getter onrejectionhandled [Worker] getter onrejectionhandled
[Worker] getter onunhandledrejection [Worker] getter onunhandledrejection
[Worker] getter origin [Worker] getter origin
...@@ -2397,6 +2398,7 @@ Starting worker: resources/global-interface-listing-worker.js ...@@ -2397,6 +2398,7 @@ Starting worker: resources/global-interface-listing-worker.js
[Worker] method setInterval [Worker] method setInterval
[Worker] method setTimeout [Worker] method setTimeout
[Worker] setter onerror [Worker] setter onerror
[Worker] setter onlanguagechange
[Worker] setter onrejectionhandled [Worker] setter onrejectionhandled
[Worker] setter onunhandledrejection [Worker] setter onunhandledrejection
[Worker] setter origin [Worker] setter origin
...@@ -2422,6 +2424,8 @@ Starting worker: resources/global-interface-listing-worker.js ...@@ -2422,6 +2424,8 @@ Starting worker: resources/global-interface-listing-worker.js
[Worker] getter connection [Worker] getter connection
[Worker] getter deviceMemory [Worker] getter deviceMemory
[Worker] getter hardwareConcurrency [Worker] getter hardwareConcurrency
[Worker] getter language
[Worker] getter languages
[Worker] getter locks [Worker] getter locks
[Worker] getter onLine [Worker] getter onLine
[Worker] getter permissions [Worker] getter permissions
......
...@@ -3476,6 +3476,7 @@ Starting worker: resources/global-interface-listing-worker.js ...@@ -3476,6 +3476,7 @@ Starting worker: resources/global-interface-listing-worker.js
[Worker] getter location [Worker] getter location
[Worker] getter navigator [Worker] getter navigator
[Worker] getter onerror [Worker] getter onerror
[Worker] getter onlanguagechange
[Worker] getter onrejectionhandled [Worker] getter onrejectionhandled
[Worker] getter onunhandledrejection [Worker] getter onunhandledrejection
[Worker] getter origin [Worker] getter origin
...@@ -3495,6 +3496,7 @@ Starting worker: resources/global-interface-listing-worker.js ...@@ -3495,6 +3496,7 @@ Starting worker: resources/global-interface-listing-worker.js
[Worker] method setInterval [Worker] method setInterval
[Worker] method setTimeout [Worker] method setTimeout
[Worker] setter onerror [Worker] setter onerror
[Worker] setter onlanguagechange
[Worker] setter onrejectionhandled [Worker] setter onrejectionhandled
[Worker] setter onunhandledrejection [Worker] setter onunhandledrejection
[Worker] setter origin [Worker] setter origin
...@@ -3520,6 +3522,8 @@ Starting worker: resources/global-interface-listing-worker.js ...@@ -3520,6 +3522,8 @@ Starting worker: resources/global-interface-listing-worker.js
[Worker] getter connection [Worker] getter connection
[Worker] getter deviceMemory [Worker] getter deviceMemory
[Worker] getter hardwareConcurrency [Worker] getter hardwareConcurrency
[Worker] getter language
[Worker] getter languages
[Worker] getter locks [Worker] getter locks
[Worker] getter onLine [Worker] getter onLine
[Worker] getter permissions [Worker] getter permissions
......
...@@ -3348,6 +3348,7 @@ Starting worker: resources/global-interface-listing-worker.js ...@@ -3348,6 +3348,7 @@ Starting worker: resources/global-interface-listing-worker.js
[Worker] getter location [Worker] getter location
[Worker] getter navigator [Worker] getter navigator
[Worker] getter onerror [Worker] getter onerror
[Worker] getter onlanguagechange
[Worker] getter onrejectionhandled [Worker] getter onrejectionhandled
[Worker] getter onunhandledrejection [Worker] getter onunhandledrejection
[Worker] getter origin [Worker] getter origin
...@@ -3367,6 +3368,7 @@ Starting worker: resources/global-interface-listing-worker.js ...@@ -3367,6 +3368,7 @@ Starting worker: resources/global-interface-listing-worker.js
[Worker] method setInterval [Worker] method setInterval
[Worker] method setTimeout [Worker] method setTimeout
[Worker] setter onerror [Worker] setter onerror
[Worker] setter onlanguagechange
[Worker] setter onrejectionhandled [Worker] setter onrejectionhandled
[Worker] setter onunhandledrejection [Worker] setter onunhandledrejection
[Worker] setter origin [Worker] setter origin
...@@ -3392,6 +3394,8 @@ Starting worker: resources/global-interface-listing-worker.js ...@@ -3392,6 +3394,8 @@ Starting worker: resources/global-interface-listing-worker.js
[Worker] getter connection [Worker] getter connection
[Worker] getter deviceMemory [Worker] getter deviceMemory
[Worker] getter hardwareConcurrency [Worker] getter hardwareConcurrency
[Worker] getter language
[Worker] getter languages
[Worker] getter locks [Worker] getter locks
[Worker] getter onLine [Worker] getter onLine
[Worker] getter permissions [Worker] getter permissions
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment