diff --git a/content/base/src/nsGkAtomList.h b/content/base/src/nsGkAtomList.h index c887a8545be..61c05906eb9 100644 --- a/content/base/src/nsGkAtomList.h +++ b/content/base/src/nsGkAtomList.h @@ -747,7 +747,6 @@ GK_ATOM(oninvalid, "oninvalid") GK_ATOM(onkeydown, "onkeydown") GK_ATOM(onkeypress, "onkeypress") GK_ATOM(onkeyup, "onkeyup") -GK_ATOM(onlanguagechange, "onlanguagechange") GK_ATOM(onlevelchange, "onlevelchange") GK_ATOM(onLoad, "onLoad") GK_ATOM(onload, "onload") diff --git a/dom/base/Navigator.cpp b/dom/base/Navigator.cpp index e8dd0d08327..cd625615ef6 100644 --- a/dom/base/Navigator.cpp +++ b/dom/base/Navigator.cpp @@ -351,87 +351,59 @@ Navigator::GetAppName(nsAString& aAppName) } /** - * Returns the value of Accept-Languages (HTTP header) as a nsTArray of - * languages. The value is set in the preference by the user ("Content - * Languages"). + * JS property navigator.language, exposed to web content. + * Take first value from Accept-Languages (HTTP header), which is + * the "content language" freely set by the user in the Pref window. * - * "en", "en-US" and "i-cherokee" and "" are valid languages tokens. + * Do not use UI language (chosen app locale) here. + * See RFC 2616, Section 15.1.4 "Privacy Issues Connected to Accept Headers" * - * An empty array will be returned if there is no valid languages. + * "en", "en-US" and "i-cherokee" and "" are valid. + * Fallback in case of invalid pref should be "" (empty string), to + * let site do fallback, e.g. to site's local language. */ -void -Navigator::GetAcceptLanguages(nsTArray& aLanguages) +NS_IMETHODIMP +Navigator::GetLanguage(nsAString& aLanguage) { // E.g. "de-de, en-us,en". const nsAdoptingString& acceptLang = Preferences::GetLocalizedString("intl.accept_languages"); - // Split values on commas. + // Take everything before the first "," or ";", without trailing space. nsCharSeparatedTokenizer langTokenizer(acceptLang, ','); - while (langTokenizer.hasMoreTokens()) { - nsDependentSubstring lang = langTokenizer.nextToken(); + const nsSubstring &firstLangPart = langTokenizer.nextToken(); + nsCharSeparatedTokenizer qTokenizer(firstLangPart, ';'); + aLanguage.Assign(qTokenizer.nextToken()); - // Replace "_" with "-" to avoid POSIX/Windows "en_US" notation. - // NOTE: we should probably rely on the pref being set correctly. - if (lang.Length() > 2 && lang[2] == char16_t('_')) { - lang.Replace(2, 1, char16_t('-')); - } - - // Use uppercase for country part, e.g. "en-US", not "en-us", see BCP47 - // only uppercase 2-letter country codes, not "zh-Hant", "de-DE-x-goethe". - // NOTE: we should probably rely on the pref being set correctly. - if (lang.Length() > 2) { - nsCharSeparatedTokenizer localeTokenizer(lang, '-'); - int32_t pos = 0; - bool first = true; - while (localeTokenizer.hasMoreTokens()) { - const nsSubstring& code = localeTokenizer.nextToken(); - - if (code.Length() == 2 && !first) { - nsAutoString upper(code); - ToUpperCase(upper); - lang.Replace(pos, code.Length(), upper); - } - - pos += code.Length() + 1; // 1 is the separator - first = false; - } - } - - aLanguages.AppendElement(lang); - } -} - -/** - * Do not use UI language (chosen app locale) here but the first value set in - * the Accept Languages header, see ::GetAcceptLanguages(). - * - * See RFC 2616, Section 15.1.4 "Privacy Issues Connected to Accept Headers" for - * the reasons why. - */ -NS_IMETHODIMP -Navigator::GetLanguage(nsAString& aLanguage) -{ - nsTArray languages; - GetLanguages(languages); - if (languages.Length() >= 1) { - aLanguage.Assign(languages[0]); - } else { - aLanguage.Truncate(); + // Checks and fixups: + // replace "_" with "-" to avoid POSIX/Windows "en_US" notation. + if (aLanguage.Length() > 2 && aLanguage[2] == char16_t('_')) { + aLanguage.Replace(2, 1, char16_t('-')); // TODO replace all } + // Use uppercase for country part, e.g. "en-US", not "en-us", see BCP47 + // only uppercase 2-letter country codes, not "zh-Hant", "de-DE-x-goethe". + if (aLanguage.Length() <= 2) { return NS_OK; -} + } -void -Navigator::GetLanguages(nsTArray& aLanguages) -{ - GetAcceptLanguages(aLanguages); + nsCharSeparatedTokenizer localeTokenizer(aLanguage, '-'); + int32_t pos = 0; + bool first = true; + while (localeTokenizer.hasMoreTokens()) { + const nsSubstring& code = localeTokenizer.nextToken(); - // The returned value is cached by the binding code. The window listen to the - // accept languages change and will clear the cache when needed. It has to - // take care of dispatching the DOM event already and the invalidation and the - // event has to be timed correctly. + if (code.Length() == 2 && !first) { + nsAutoString upper(code); + ToUpperCase(upper); + aLanguage.Replace(pos, code.Length(), upper); + } + + pos += code.Length() + 1; // 1 is the separator + first = false; + } + + return NS_OK; } NS_IMETHODIMP diff --git a/dom/base/Navigator.h b/dom/base/Navigator.h index 0fef4cb8afc..c586b2e0561 100644 --- a/dom/base/Navigator.h +++ b/dom/base/Navigator.h @@ -251,8 +251,6 @@ public: JS::MutableHandle aDesc); void GetOwnPropertyNames(JSContext* aCx, nsTArray& aNames, ErrorResult& aRv); - void GetLanguages(nsTArray& aLanguages); - void GetAcceptLanguages(nsTArray& aLanguages); // WebIDL helper methods static bool HasBatterySupport(JSContext* /* unused*/, JSObject* /*unused */); diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp index c42670bffbd..a9e1f502a88 100644 --- a/dom/base/nsGlobalWindow.cpp +++ b/dom/base/nsGlobalWindow.cpp @@ -218,7 +218,6 @@ #include "nsITabChild.h" #include "mozilla/dom/MediaQueryList.h" #include "mozilla/dom/ScriptSettings.h" -#include "mozilla/dom/NavigatorBinding.h" #ifdef HAVE_SIDEBAR #include "mozilla/dom/ExternalBinding.h" #endif @@ -1138,8 +1137,6 @@ nsGlobalWindow::nsGlobalWindow(nsGlobalWindow *aOuterWindow) // events. Use a strong reference. os->AddObserver(mObserver, "dom-storage2-changed", false); } - - Preferences::AddStrongObserver(mObserver, "intl.accept_languages"); } } else { // |this| is an outer window. Outer windows start out frozen and @@ -1422,8 +1419,6 @@ nsGlobalWindow::CleanUp() mIdleService->RemoveIdleObserver(mObserver, MIN_IDLE_NOTIFICATION_TIME_S); } - Preferences::RemoveObserver(mObserver, "intl.accept_languages"); - // Drop its reference to this dying window, in case for some bogus reason // the object stays around. mObserver->Forget(); @@ -11213,32 +11208,6 @@ nsGlobalWindow::Observe(nsISupports* aSubject, const char* aTopic, } #endif // MOZ_B2G - if (!nsCRT::strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID)) { - MOZ_ASSERT(!nsCRT::strcmp(aData, "intl.accept_languages")); - MOZ_ASSERT(IsInnerWindow()); - - // The user preferred languages have changed, we need to fire an event on - // Window object and invalidate the cache for navigator.languages. It is - // done for every change which can be a waste of cycles but those should be - // fairly rare. - // We MUST invalidate navigator.languages before sending the event in the - // very likely situation where an event handler will try to read its value. - - if (mNavigator) { - NavigatorBinding::ClearCachedLanguagesValue(mNavigator); - } - - nsCOMPtr event; - NS_NewDOMEvent(getter_AddRefs(event), this, nullptr, nullptr); - nsresult rv = event->InitEvent(NS_LITERAL_STRING("languagechange"), false, false); - NS_ENSURE_SUCCESS(rv, rv); - - event->SetTrusted(true); - - bool dummy; - return DispatchEvent(event, &dummy); - } - NS_WARNING("unrecognized topic in nsGlobalWindow::Observe"); return NS_ERROR_FAILURE; } diff --git a/dom/base/test/mochitest.ini b/dom/base/test/mochitest.ini index 6f431c9f543..e77a9d1db63 100644 --- a/dom/base/test/mochitest.ini +++ b/dom/base/test/mochitest.ini @@ -44,7 +44,6 @@ support-files = [test_messageChannel_unshipped.html] [test_named_frames.html] [test_navigator_resolve_identity.html] -[test_navigator_language.html] [test_nondomexception.html] [test_openDialogChromeOnly.html] [test_postMessage_solidus.html] diff --git a/dom/base/test/test_navigator_language.html b/dom/base/test/test_navigator_language.html deleted file mode 100644 index f468cb1b1c6..00000000000 --- a/dom/base/test/test_navigator_language.html +++ /dev/null @@ -1,227 +0,0 @@ - - - - - - Test for NavigatorLanguage - - - - -Mozilla Bug 889335 -

- -
-
- - - diff --git a/dom/events/EventNameList.h b/dom/events/EventNameList.h index 83702a6dfe8..cbb6f54efda 100644 --- a/dom/events/EventNameList.h +++ b/dom/events/EventNameList.h @@ -464,10 +464,6 @@ WINDOW_EVENT(hashchange, NS_HASHCHANGE, EventNameType_XUL | EventNameType_HTMLBodyOrFramesetOnly, NS_EVENT) -WINDOW_EVENT(languagechange, - NS_LANGUAGECHANGE, - EventNameType_HTMLBodyOrFramesetOnly, - NS_EVENT) // XXXbz Should the onmessage attribute on really not work? If so, do we // need a different macro to flag things like that (IDL, but not content // attributes on body/frameset), or is just using EventNameType_None enough? diff --git a/dom/interfaces/base/nsIDOMWindow.idl b/dom/interfaces/base/nsIDOMWindow.idl index e8d844ea670..a66afbe08cc 100644 --- a/dom/interfaces/base/nsIDOMWindow.idl +++ b/dom/interfaces/base/nsIDOMWindow.idl @@ -24,7 +24,7 @@ interface nsIVariant; * @see */ -[scriptable, uuid(fbefa573-0ba2-4d15-befb-d60277643a0b)] +[scriptable, uuid(8c115ab3-cf96-492c-850c-3b18056b45e2)] interface nsIDOMWindow : nsISupports { // the current browsing context @@ -478,7 +478,6 @@ interface nsIDOMWindow : nsISupports [implicit_jscontext] attribute jsval onbeforeprint; [implicit_jscontext] attribute jsval onbeforeunload; [implicit_jscontext] attribute jsval onhashchange; - [implicit_jscontext] attribute jsval onlanguagechange; [implicit_jscontext] attribute jsval onmessage; [implicit_jscontext] attribute jsval onoffline; [implicit_jscontext] attribute jsval ononline; diff --git a/dom/webidl/EventHandler.webidl b/dom/webidl/EventHandler.webidl index 5ad29bec157..216ddd686da 100644 --- a/dom/webidl/EventHandler.webidl +++ b/dom/webidl/EventHandler.webidl @@ -123,7 +123,6 @@ interface WindowEventHandlers { attribute EventHandler onbeforeprint; attribute OnBeforeUnloadEventHandler onbeforeunload; attribute EventHandler onhashchange; - attribute EventHandler onlanguagechange; attribute EventHandler onmessage; attribute EventHandler onoffline; attribute EventHandler ononline; diff --git a/dom/webidl/Navigator.webidl b/dom/webidl/Navigator.webidl index 79b4c939abe..0634130a845 100644 --- a/dom/webidl/Navigator.webidl +++ b/dom/webidl/Navigator.webidl @@ -52,7 +52,6 @@ interface NavigatorID { [NoInterfaceObject] interface NavigatorLanguage { readonly attribute DOMString? language; - [Pure, Cached, Frozen] readonly attribute sequence languages; }; [NoInterfaceObject] diff --git a/widget/BasicEvents.h b/widget/BasicEvents.h index 0f4ec9102f8..1505217502e 100644 --- a/widget/BasicEvents.h +++ b/widget/BasicEvents.h @@ -120,8 +120,6 @@ enum nsEventStructType // HiDPI mode. #define NS_PLUGIN_RESOLUTION_CHANGED (NS_WINDOW_START + 69) -#define NS_LANGUAGECHANGE (NS_WINDOW_START + 70) - #define NS_MOUSE_MESSAGE_START 300 #define NS_MOUSE_MOVE (NS_MOUSE_MESSAGE_START) #define NS_MOUSE_BUTTON_UP (NS_MOUSE_MESSAGE_START + 1)