/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "mozilla/dom/BrowsingContext.h" #include "mozilla/dom/CanonicalBrowsingContext.h" #include "mozilla/dom/Document.h" #include "mozilla/dom/WindowGlobalChild.h" #include "mozilla/dom/WindowGlobalParent.h" #include "mozilla/Services.h" #include "nsIObserverService.h" #include "nsIURI.h" #include "nsNetUtil.h" #include "nsPIDOMWindow.h" #include "nsReadableUtils.h" #include "nsThreadUtils.h" #include "RestoreTabContentObserver.h" using namespace mozilla::dom; NS_IMPL_ISUPPORTS(RestoreTabContentObserver, nsIObserver) const char* const kAboutReaderTopic = "AboutReader:Ready"; const char* const kContentDocumentLoaded = "content-document-loaded"; const char* const kChromeDocumentLoaded = "chrome-document-loaded"; /* static */ void RestoreTabContentObserver::Initialize() { MOZ_ASSERT(!gRestoreTabContentObserver); MOZ_ASSERT(NS_IsMainThread()); RefPtr observer = new RestoreTabContentObserver(); nsCOMPtr obs = mozilla::services::GetObserverService(); if (NS_WARN_IF(!obs)) { return; } obs->AddObserver(observer, kAboutReaderTopic, false); obs->AddObserver(observer, kContentDocumentLoaded, false); obs->AddObserver(observer, kChromeDocumentLoaded, false); gRestoreTabContentObserver = observer; } /* static */ void RestoreTabContentObserver::Shutdown() { MOZ_ASSERT(NS_IsMainThread()); if (!gRestoreTabContentObserver) { return; } RefPtr observer = gRestoreTabContentObserver; gRestoreTabContentObserver = nullptr; nsCOMPtr obs = mozilla::services::GetObserverService(); if (!obs) { return; } obs->RemoveObserver(observer, kAboutReaderTopic); obs->RemoveObserver(observer, kContentDocumentLoaded); obs->RemoveObserver(observer, kChromeDocumentLoaded); } NS_IMETHODIMP RestoreTabContentObserver::Observe(nsISupports* aSubject, const char* aTopic, const char16_t* aData) { nsCOMPtr inner; if (!strcmp(aTopic, kAboutReaderTopic)) { inner = do_QueryInterface(aSubject); } else if (!strcmp(aTopic, kContentDocumentLoaded) || !strcmp(aTopic, kChromeDocumentLoaded)) { nsCOMPtr doc = do_QueryInterface(aSubject); inner = doc ? doc->GetInnerWindow() : nullptr; } if (!inner) { return NS_OK; } nsCOMPtr uri = inner->GetDocumentURI(); if (!uri) { return NS_OK; } // We'll handle loading about:reader with "AboutReader:Ready" // rather than "content-document-loaded". if (uri->SchemeIs("about") && StringBeginsWith(uri->GetSpecOrDefault(), "about:reader"_ns) && strcmp(aTopic, kAboutReaderTopic) != 0) { return NS_OK; } RefPtr bc = inner->GetBrowsingContext(); if (!bc || !bc->Top()->GetHasRestoreData()) { return NS_OK; } if (XRE_IsParentProcess()) { if (WindowGlobalParent* wgp = bc->Canonical()->GetCurrentWindowGlobal()) { bc->Canonical()->Top()->RequestRestoreTabContent(wgp); } } else if (WindowContext* windowContext = bc->GetCurrentWindowContext()) { if (WindowGlobalChild* wgc = windowContext->GetWindowGlobalChild()) { wgc->SendRequestRestoreTabContent(); } } return NS_OK; } mozilla::StaticRefPtr RestoreTabContentObserver::gRestoreTabContentObserver;