LCOV - code coverage report
Current view: top level - layout/style - PreloadedStyleSheet.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 32 49 65.3 %
Date: 2017-07-14 16:53:18 Functions: 7 15 46.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : // vim:cindent:tabstop=2:expandtab:shiftwidth=2:
       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           1 : PreloadedStyleSheet::PreloadedStyleSheet(nsIURI* aURI,
      19           1 :                                          css::SheetParsingMode aParsingMode)
      20             :   : mLoaded(false)
      21             :   , mURI(aURI)
      22           1 :   , mParsingMode(aParsingMode)
      23             : {
      24           1 : }
      25             : 
      26             : /* static */ nsresult
      27           1 : PreloadedStyleSheet::Create(nsIURI* aURI,
      28             :                             css::SheetParsingMode aParsingMode,
      29             :                             PreloadedStyleSheet** aResult)
      30             : {
      31           1 :   *aResult = nullptr;
      32             : 
      33             :   RefPtr<PreloadedStyleSheet> preloadedSheet =
      34           2 :     new PreloadedStyleSheet(aURI, aParsingMode);
      35             : 
      36           1 :   preloadedSheet.forget(aResult);
      37           2 :   return NS_OK;
      38             : }
      39             : 
      40          10 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(PreloadedStyleSheet)
      41           9 :   NS_INTERFACE_MAP_ENTRY(nsIPreloadedStyleSheet)
      42           7 :   NS_INTERFACE_MAP_ENTRY(nsISupports)
      43           6 : NS_INTERFACE_MAP_END
      44             : 
      45           5 : NS_IMPL_CYCLE_COLLECTING_ADDREF(PreloadedStyleSheet)
      46           3 : NS_IMPL_CYCLE_COLLECTING_RELEASE(PreloadedStyleSheet)
      47             : 
      48           0 : NS_IMPL_CYCLE_COLLECTION(PreloadedStyleSheet, mGecko, mServo)
      49             : 
      50             : nsresult
      51           2 : PreloadedStyleSheet::GetSheet(StyleBackendType aType, StyleSheet** aResult)
      52             : {
      53           2 :   *aResult = nullptr;
      54             : 
      55           2 :   MOZ_DIAGNOSTIC_ASSERT(mLoaded);
      56             : 
      57             :   RefPtr<StyleSheet>& sheet =
      58           2 :     aType == StyleBackendType::Gecko ? mGecko : mServo;
      59             : 
      60           2 :   if (!sheet) {
      61           2 :     RefPtr<css::Loader> loader = new css::Loader(aType, nullptr);
      62           1 :     nsresult rv = loader->LoadSheetSync(mURI, mParsingMode, true, &sheet);
      63           1 :     NS_ENSURE_SUCCESS(rv, rv);
      64           1 :     MOZ_ASSERT(sheet);
      65             :   }
      66             : 
      67           2 :   *aResult = sheet;
      68           2 :   return NS_OK;
      69             : }
      70             : 
      71             : nsresult
      72           1 : PreloadedStyleSheet::Preload()
      73             : {
      74           1 :   MOZ_DIAGNOSTIC_ASSERT(!mLoaded);
      75             : 
      76             :   // The nsIStyleSheetService.preloadSheet API doesn't tell us which backend
      77             :   // the sheet will be used with, and it seems wasteful to eagerly create
      78             :   // both a CSSStyleSheet and a ServoStyleSheet.  So instead, we guess that
      79             :   // the sheet type we will want matches the current value of the stylo pref,
      80             :   // and preload a sheet of that type.
      81             :   //
      82             :   // If we guess wrong, we will re-load the sheet later with the requested type,
      83             :   // and we won't really have front loaded the loading time as the name
      84             :   // "preload" might suggest.  Also, in theory we could get different data from
      85             :   // fetching the URL again, but for the usage patterns of this API this is
      86             :   // unlikely, and it doesn't seem worth trying to store the contents of the URL
      87             :   // and duplicating a bunch of css::Loader's logic.
      88           1 :   auto type = nsLayoutUtils::StyloEnabled() ? StyleBackendType::Servo
      89           1 :                                             : StyleBackendType::Gecko;
      90             : 
      91           1 :   mLoaded = true;
      92             : 
      93             :   StyleSheet* sheet;
      94           1 :   return GetSheet(type, &sheet);
      95             : }
      96             : 
      97           0 : NS_IMPL_ISUPPORTS(PreloadedStyleSheet::StylesheetPreloadObserver,
      98             :                   nsICSSLoaderObserver)
      99             : 
     100             : NS_IMETHODIMP
     101           0 : PreloadedStyleSheet::StylesheetPreloadObserver::StyleSheetLoaded(
     102             :   StyleSheet* aSheet, bool aWasAlternate, nsresult aStatus)
     103             : {
     104           0 :   MOZ_DIAGNOSTIC_ASSERT(!mPreloadedSheet->mLoaded);
     105           0 :   mPreloadedSheet->mLoaded = true;
     106             : 
     107           0 :   if (NS_FAILED(aStatus)) {
     108           0 :     mPromise->MaybeReject(aStatus);
     109             :   } else {
     110           0 :     mPromise->MaybeResolve(mPreloadedSheet);
     111             :   }
     112             : 
     113           0 :   return NS_OK;
     114             : }
     115             : 
     116             : // Note: After calling this method, the preloaded sheet *must not* be used
     117             : // until the observer is notified that the sheet has finished loading.
     118             : nsresult
     119           0 : PreloadedStyleSheet::PreloadAsync(NotNull<dom::Promise*> aPromise)
     120             : {
     121           0 :   MOZ_DIAGNOSTIC_ASSERT(!mLoaded);
     122             : 
     123             :   // As with the Preload() method, we can't be sure that the sheet will only be
     124             :   // used with the backend that we're preloading it for now. If it's used with
     125             :   // a different backend later, it will be synchronously loaded for that
     126             :   // backend the first time it's used.
     127           0 :   auto type = nsLayoutUtils::StyloEnabled() ? StyleBackendType::Servo
     128           0 :                                             : StyleBackendType::Gecko;
     129             : 
     130             :   RefPtr<StyleSheet>& sheet =
     131           0 :     type == StyleBackendType::Gecko ? mGecko : mServo;
     132             : 
     133           0 :   RefPtr<css::Loader> loader = new css::Loader(type, nullptr);
     134             : 
     135             :   RefPtr<StylesheetPreloadObserver> obs =
     136           0 :     new StylesheetPreloadObserver(aPromise, this);
     137             : 
     138           0 :   return loader->LoadSheet(mURI, mParsingMode, false, obs, &sheet);
     139             : }
     140             : 
     141             : } // namespace mozilla

Generated by: LCOV version 1.13