PreloadedStyleSheet.cpp (2668B)
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 /* a CSS style sheet returned from nsIStyleSheetService.preloadSheet */ 8 9 #include "PreloadedStyleSheet.h" 10 11 #include "mozilla/css/Loader.h" 12 #include "mozilla/dom/Promise.h" 13 #include "nsICSSLoaderObserver.h" 14 #include "nsLayoutUtils.h" 15 16 namespace mozilla { 17 18 PreloadedStyleSheet::PreloadedStyleSheet(nsIURI* aURI, 19 css::SheetParsingMode aParsingMode) 20 : mLoaded(false), mURI(aURI), mParsingMode(aParsingMode) {} 21 22 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(PreloadedStyleSheet) 23 NS_INTERFACE_MAP_ENTRY(nsIPreloadedStyleSheet) 24 NS_INTERFACE_MAP_ENTRY(nsISupports) 25 NS_INTERFACE_MAP_END 26 27 NS_IMPL_CYCLE_COLLECTING_ADDREF(PreloadedStyleSheet) 28 NS_IMPL_CYCLE_COLLECTING_RELEASE(PreloadedStyleSheet) 29 30 NS_IMPL_CYCLE_COLLECTION(PreloadedStyleSheet, mSheet) 31 32 Result<StyleSheet*, nsresult> PreloadedStyleSheet::GetSheet() { 33 MOZ_DIAGNOSTIC_ASSERT(mLoaded); 34 35 if (!mSheet) { 36 auto loader = MakeRefPtr<css::Loader>(); 37 mSheet = MOZ_TRY(loader->LoadSheetSync( 38 mURI, mParsingMode, css::Loader::UseSystemPrincipal::Yes)); 39 } 40 return {mSheet.get()}; 41 } 42 43 nsresult PreloadedStyleSheet::Preload() { 44 MOZ_DIAGNOSTIC_ASSERT(!mLoaded); 45 mLoaded = true; 46 MOZ_TRY(GetSheet()); 47 return NS_OK; 48 } 49 50 NS_IMPL_ISUPPORTS(PreloadedStyleSheet::StylesheetPreloadObserver, 51 nsICSSLoaderObserver) 52 53 NS_IMETHODIMP 54 PreloadedStyleSheet::StylesheetPreloadObserver::StyleSheetLoaded( 55 StyleSheet* aSheet, bool aWasDeferred, nsresult aStatus) { 56 MOZ_DIAGNOSTIC_ASSERT(!mPreloadedSheet->mLoaded); 57 mPreloadedSheet->mLoaded = true; 58 59 if (NS_FAILED(aStatus)) { 60 mPromise->MaybeReject(aStatus); 61 } else { 62 mPromise->MaybeResolve(mPreloadedSheet); 63 } 64 65 return NS_OK; 66 } 67 68 // Note: After calling this method, the preloaded sheet *must not* be used 69 // until the observer is notified that the sheet has finished loading. 70 nsresult PreloadedStyleSheet::PreloadAsync(NotNull<dom::Promise*> aPromise) { 71 MOZ_DIAGNOSTIC_ASSERT(!mLoaded); 72 73 auto loader = MakeRefPtr<css::Loader>(); 74 auto obs = MakeRefPtr<StylesheetPreloadObserver>(aPromise, this); 75 auto result = loader->LoadSheet(mURI, mParsingMode, 76 css::Loader::UseSystemPrincipal::No, obs); 77 if (result.isErr()) { 78 return result.unwrapErr(); 79 } 80 mSheet = result.unwrap(); 81 return NS_OK; 82 } 83 84 } // namespace mozilla