UIDirectionManager.cpp (2832B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "mozilla/dom/UIDirectionManager.h" 8 9 #include "mozilla/Preferences.h" 10 #include "mozilla/Services.h" 11 #include "mozilla/SimpleEnumerator.h" 12 #include "mozilla/dom/Document.h" 13 #include "nsDocShell.h" 14 #include "nsIObserverService.h" 15 #include "nsIWindowMediator.h" 16 #include "nsServiceManagerUtils.h" 17 18 namespace mozilla::dom { 19 20 NS_IMPL_ISUPPORTS(UIDirectionManager, nsIObserver) 21 22 /* static */ 23 NS_IMETHODIMP 24 UIDirectionManager::Observe(nsISupports* aSubject, const char* aTopic, 25 const char16_t* aData) { 26 NS_ENSURE_FALSE(strcmp(aTopic, "intl:app-locales-changed"), NS_ERROR_FAILURE); 27 28 // Iterate over all of the windows and notify them of the direction change. 29 nsCOMPtr<nsIWindowMediator> windowMediator = 30 do_GetService(NS_WINDOWMEDIATOR_CONTRACTID); 31 NS_ENSURE_TRUE(windowMediator, NS_ERROR_FAILURE); 32 33 nsCOMPtr<nsISimpleEnumerator> windowEnumerator; 34 windowMediator->GetEnumerator(nullptr, getter_AddRefs(windowEnumerator)); 35 NS_ENSURE_TRUE(windowEnumerator, NS_ERROR_FAILURE); 36 37 for (auto& elements : SimpleEnumerator<nsISupports>(windowEnumerator)) { 38 nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryInterface(elements); 39 if (window->Closed()) { 40 continue; 41 } 42 43 RefPtr<BrowsingContext> context = window->GetBrowsingContext(); 44 MOZ_DIAGNOSTIC_ASSERT(context); 45 46 if (context->IsDiscarded()) { 47 continue; 48 } 49 50 context->PreOrderWalk([](BrowsingContext* aContext) { 51 if (dom::Document* doc = aContext->GetDocument()) { 52 doc->ResetDocumentDirection(); 53 } 54 }); 55 } 56 return NS_OK; 57 } 58 59 /* static */ 60 void UIDirectionManager::Initialize() { 61 MOZ_ASSERT(!gUIDirectionManager); 62 MOZ_ASSERT(NS_IsMainThread()); 63 64 RefPtr<UIDirectionManager> observer = new UIDirectionManager(); 65 66 nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService(); 67 if (NS_WARN_IF(!obs)) { 68 return; 69 } 70 obs->AddObserver(observer, "intl:app-locales-changed", false); 71 72 gUIDirectionManager = observer; 73 } 74 75 /* static */ 76 void UIDirectionManager::Shutdown() { 77 MOZ_ASSERT(NS_IsMainThread()); 78 if (!gUIDirectionManager) { 79 return; 80 } 81 RefPtr<UIDirectionManager> observer = gUIDirectionManager; 82 gUIDirectionManager = nullptr; 83 84 nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService(); 85 if (!obs) { 86 return; 87 } 88 89 obs->RemoveObserver(observer, "intl:app-locales-changed"); 90 } 91 92 mozilla::StaticRefPtr<UIDirectionManager> 93 UIDirectionManager::gUIDirectionManager; 94 95 } // namespace mozilla::dom