LCOV - code coverage report
Current view: top level - dom/script - ScriptLoader.h (source / functions) Hit Total Coverage
Test: output.info Lines: 28 78 35.9 %
Date: 2017-07-14 16:53:18 Functions: 12 31 38.7 %
Legend: Lines: hit not hit

          Line data    Source code
       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             : #ifndef mozilla_dom_ScriptLoader_h
       8             : #define mozilla_dom_ScriptLoader_h
       9             : 
      10             : #include "nsCOMPtr.h"
      11             : #include "nsRefPtrHashtable.h"
      12             : #include "mozilla/Encoding.h"
      13             : #include "nsIScriptElement.h"
      14             : #include "nsCOMArray.h"
      15             : #include "nsCycleCollectionParticipant.h"
      16             : #include "nsTArray.h"
      17             : #include "nsAutoPtr.h"
      18             : #include "nsICacheInfoChannel.h"
      19             : #include "nsIDocument.h"
      20             : #include "nsIIncrementalStreamLoader.h"
      21             : #include "nsURIHashKey.h"
      22             : #include "mozilla/CORSMode.h"
      23             : #include "mozilla/dom/ScriptLoadRequest.h"
      24             : #include "mozilla/dom/SRIMetadata.h"
      25             : #include "mozilla/dom/SRICheck.h"
      26             : #include "mozilla/MozPromise.h"
      27             : #include "mozilla/net/ReferrerPolicy.h"
      28             : #include "mozilla/Vector.h"
      29             : 
      30             : class nsIURI;
      31             : 
      32             : namespace JS {
      33             :   class SourceBufferHolder;
      34             : } // namespace JS
      35             : 
      36             : namespace mozilla {
      37             : namespace dom {
      38             : 
      39             : class AutoJSAPI;
      40             : class ModuleLoadRequest;
      41             : class ModuleScript;
      42             : class ScriptLoadHandler;
      43             : class ScriptRequestProcessor;
      44             : 
      45             : //////////////////////////////////////////////////////////////
      46             : // Script loader implementation
      47             : //////////////////////////////////////////////////////////////
      48             : 
      49             : class ScriptLoader final : public nsISupports
      50             : {
      51             :   class MOZ_STACK_CLASS AutoCurrentScriptUpdater
      52             :   {
      53             :   public:
      54           5 :     AutoCurrentScriptUpdater(ScriptLoader* aScriptLoader,
      55             :                              nsIScriptElement* aCurrentScript)
      56           5 :       : mOldScript(aScriptLoader->mCurrentScript)
      57           5 :       , mScriptLoader(aScriptLoader)
      58             :     {
      59           5 :       mScriptLoader->mCurrentScript = aCurrentScript;
      60           5 :     }
      61             : 
      62           5 :     ~AutoCurrentScriptUpdater()
      63           5 :     {
      64           5 :       mScriptLoader->mCurrentScript.swap(mOldScript);
      65           5 :     }
      66             : 
      67             :   private:
      68             :     nsCOMPtr<nsIScriptElement> mOldScript;
      69             :     ScriptLoader* mScriptLoader;
      70             :   };
      71             : 
      72             :   friend class ModuleLoadRequest;
      73             :   friend class ScriptRequestProcessor;
      74             :   friend class ScriptLoadHandler;
      75             :   friend class AutoCurrentScriptUpdater;
      76             : 
      77             : public:
      78             :   explicit ScriptLoader(nsIDocument* aDocument);
      79             : 
      80             :   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
      81         168 :   NS_DECL_CYCLE_COLLECTION_CLASS(ScriptLoader)
      82             : 
      83             :   /**
      84             :    * The loader maintains a weak reference to the document with
      85             :    * which it is initialized. This call forces the reference to
      86             :    * be dropped.
      87             :    */
      88           0 :   void DropDocumentReference()
      89             :   {
      90           0 :     mDocument = nullptr;
      91           0 :   }
      92             : 
      93             :   /**
      94             :    * Add an observer for all scripts loaded through this loader.
      95             :    *
      96             :    * @param aObserver observer for all script processing.
      97             :    */
      98           0 :   nsresult AddObserver(nsIScriptLoaderObserver* aObserver)
      99             :   {
     100           0 :     return mObservers.AppendObject(aObserver) ? NS_OK :
     101           0 :       NS_ERROR_OUT_OF_MEMORY;
     102             :   }
     103             : 
     104             :   /**
     105             :    * Remove an observer.
     106             :    *
     107             :    * @param aObserver observer to be removed
     108             :    */
     109           0 :   void RemoveObserver(nsIScriptLoaderObserver* aObserver)
     110             :   {
     111           0 :     mObservers.RemoveObject(aObserver);
     112           0 :   }
     113             : 
     114             :   /**
     115             :    * Process a script element. This will include both loading the
     116             :    * source of the element if it is not inline and evaluating
     117             :    * the script itself.
     118             :    *
     119             :    * If the script is an inline script that can be executed immediately
     120             :    * (i.e. there are no other scripts pending) then ScriptAvailable
     121             :    * and ScriptEvaluated will be called before the function returns.
     122             :    *
     123             :    * If true is returned the script could not be executed immediately.
     124             :    * In this case ScriptAvailable is guaranteed to be called at a later
     125             :    * point (as well as possibly ScriptEvaluated).
     126             :    *
     127             :    * @param aElement The element representing the script to be loaded and
     128             :    *        evaluated.
     129             :    */
     130             :   bool ProcessScriptElement(nsIScriptElement* aElement);
     131             : 
     132             :   /**
     133             :    * Gets the currently executing script. This is useful if you want to
     134             :    * generate a unique key based on the currently executing script.
     135             :    */
     136          62 :   nsIScriptElement* GetCurrentScript()
     137             :   {
     138          62 :     return mCurrentScript;
     139             :   }
     140             : 
     141           0 :   nsIScriptElement* GetCurrentParserInsertedScript()
     142             :   {
     143           0 :     return mCurrentParserInsertedScript;
     144             :   }
     145             : 
     146             :   /**
     147             :    * Whether the loader is enabled or not.
     148             :    * When disabled, processing of new script elements is disabled.
     149             :    * Any call to ProcessScriptElement() will return false. Note that
     150             :    * this DOES NOT disable currently loading or executing scripts.
     151             :    */
     152           0 :   bool GetEnabled()
     153             :   {
     154           0 :     return mEnabled;
     155             :   }
     156             : 
     157          21 :   void SetEnabled(bool aEnabled)
     158             :   {
     159          21 :     if (!mEnabled && aEnabled) {
     160           0 :       ProcessPendingRequestsAsync();
     161             :     }
     162          21 :     mEnabled = aEnabled;
     163          21 :   }
     164             : 
     165             :   /**
     166             :    * Add/remove a blocker for parser-blocking scripts (and XSLT
     167             :    * scripts). Blockers will stop such scripts from executing, but not from
     168             :    * loading.
     169             :    */
     170           0 :   void AddParserBlockingScriptExecutionBlocker()
     171             :   {
     172           0 :     ++mParserBlockingBlockerCount;
     173           0 :   }
     174             : 
     175           0 :   void RemoveParserBlockingScriptExecutionBlocker()
     176             :   {
     177           0 :     if (!--mParserBlockingBlockerCount && ReadyToExecuteScripts()) {
     178           0 :       ProcessPendingRequestsAsync();
     179             :     }
     180           0 :   }
     181             : 
     182             :   /**
     183             :    * Add/remove a blocker for execution of all scripts.  Blockers will stop
     184             :    * scripts from executing, but not from loading.
     185             :    */
     186           0 :   void AddExecuteBlocker()
     187             :   {
     188           0 :     ++mBlockerCount;
     189           0 :   }
     190             : 
     191           0 :   void RemoveExecuteBlocker()
     192             :   {
     193           0 :     MOZ_ASSERT(mBlockerCount);
     194           0 :     if (!--mBlockerCount) {
     195           0 :       ProcessPendingRequestsAsync();
     196             :     }
     197           0 :   }
     198             : 
     199             :   /**
     200             :    * Convert the given buffer to a UTF-16 string.
     201             :    * @param aChannel     Channel corresponding to the data. May be null.
     202             :    * @param aData        The data to convert
     203             :    * @param aLength      Length of the data
     204             :    * @param aHintCharset Hint for the character set (e.g., from a charset
     205             :    *                     attribute). May be the empty string.
     206             :    * @param aDocument    Document which the data is loaded for. Must not be
     207             :    *                     null.
     208             :    * @param aBufOut      [out] char16_t array allocated by ConvertToUTF16 and
     209             :    *                     containing data converted to unicode.  Caller must
     210             :    *                     js_free() this data when no longer needed.
     211             :    * @param aLengthOut   [out] Length of array returned in aBufOut in number
     212             :    *                     of char16_t code units.
     213             :    */
     214             :   static nsresult ConvertToUTF16(nsIChannel* aChannel, const uint8_t* aData,
     215             :                                  uint32_t aLength,
     216             :                                  const nsAString& aHintCharset,
     217             :                                  nsIDocument* aDocument,
     218             :                                  char16_t*& aBufOut, size_t& aLengthOut);
     219             : 
     220             :   static inline nsresult
     221           0 :   ConvertToUTF16(nsIChannel* aChannel, const uint8_t* aData,
     222             :                  uint32_t aLength, const nsAString& aHintCharset,
     223             :                  nsIDocument* aDocument,
     224             :                  JS::UniqueTwoByteChars& aBufOut, size_t& aLengthOut)
     225             :   {
     226             :     char16_t* bufOut;
     227             :     nsresult rv = ConvertToUTF16(aChannel, aData, aLength, aHintCharset,
     228           0 :                                  aDocument, bufOut, aLengthOut);
     229           0 :     if (NS_SUCCEEDED(rv)) {
     230           0 :       aBufOut.reset(bufOut);
     231             :     }
     232           0 :     return rv;
     233             :   };
     234             : 
     235             :   /**
     236             :    * Handle the completion of a stream.  This is called by the
     237             :    * ScriptLoadHandler object which observes the IncrementalStreamLoader
     238             :    * loading the script. The streamed content is expected to be stored on the
     239             :    * aRequest argument.
     240             :    */
     241             :   nsresult OnStreamComplete(nsIIncrementalStreamLoader* aLoader,
     242             :                             ScriptLoadRequest* aRequest,
     243             :                             nsresult aChannelStatus,
     244             :                             nsresult aSRIStatus,
     245             :                             mozilla::dom::SRICheckDataVerifier* aSRIDataVerifier);
     246             : 
     247             :   /**
     248             :    * Returns wether any request is queued, and not executed yet.
     249             :    */
     250             :   bool HasPendingRequests();
     251             : 
     252             :   /**
     253             :    * Processes any pending requests that are ready for processing.
     254             :    */
     255             :   void ProcessPendingRequests();
     256             : 
     257             :   /**
     258             :    * Starts deferring deferred scripts and puts them in the mDeferredRequests
     259             :    * queue instead.
     260             :    */
     261          25 :   void BeginDeferringScripts()
     262             :   {
     263          25 :     mDeferEnabled = true;
     264          25 :     if (mDocument) {
     265          25 :       mDocument->BlockOnload();
     266             :     }
     267          25 :   }
     268             : 
     269             :   /**
     270             :    * Notifies the script loader that parsing is done.  If aTerminated is true,
     271             :    * this will drop any pending scripts that haven't run yet.  Otherwise, it
     272             :    * will stops deferring scripts and immediately processes the
     273             :    * mDeferredRequests queue.
     274             :    *
     275             :    * WARNING: This function will synchronously execute content scripts, so be
     276             :    * prepared that the world might change around you.
     277             :    */
     278             :   void ParsingComplete(bool aTerminated);
     279             : 
     280             :   /**
     281             :    * Returns the number of pending scripts, deferred or not.
     282             :    */
     283             :   uint32_t HasPendingOrCurrentScripts()
     284             :   {
     285             :     return mCurrentScript || mParserBlockingRequest;
     286             :   }
     287             : 
     288             :   /**
     289             :    * Adds aURI to the preload list and starts loading it.
     290             :    *
     291             :    * @param aURI The URI of the external script.
     292             :    * @param aCharset The charset parameter for the script.
     293             :    * @param aType The type parameter for the script.
     294             :    * @param aCrossOrigin The crossorigin attribute for the script.
     295             :    *                     Void if not present.
     296             :    * @param aIntegrity The expect hash url, if avail, of the request
     297             :    * @param aScriptFromHead Whether or not the script was a child of head
     298             :    */
     299             :   virtual void PreloadURI(nsIURI* aURI, const nsAString& aCharset,
     300             :                           const nsAString& aType,
     301             :                           const nsAString& aCrossOrigin,
     302             :                           const nsAString& aIntegrity,
     303             :                           bool aScriptFromHead,
     304             :                           const mozilla::net::ReferrerPolicy aReferrerPolicy);
     305             : 
     306             :   /**
     307             :    * Process a request that was deferred so that the script could be compiled
     308             :    * off thread.
     309             :    */
     310             :   nsresult ProcessOffThreadRequest(ScriptLoadRequest* aRequest);
     311             : 
     312           0 :   bool AddPendingChildLoader(ScriptLoader* aChild)
     313             :   {
     314           0 :     return mPendingChildLoaders.AppendElement(aChild) != nullptr;
     315             :   }
     316             : 
     317           0 :   mozilla::dom::DocGroup* GetDocGroup() const
     318             :   {
     319           0 :     return mDocument->GetDocGroup();
     320             :   }
     321             : 
     322             :   /**
     323             :    * Register the fact that we saw the load event, and that we need to save the
     324             :    * bytecode at the next loop cycle unless new scripts are waiting in the
     325             :    * pipeline.
     326             :    */
     327             :   void LoadEventFired();
     328             : 
     329             : private:
     330             :   virtual ~ScriptLoader();
     331             : 
     332             :   ScriptLoadRequest* CreateLoadRequest(ScriptKind aKind,
     333             :                                        nsIScriptElement* aElement,
     334             :                                        uint32_t aVersion,
     335             :                                        mozilla::CORSMode aCORSMode,
     336             :                                        const mozilla::dom::SRIMetadata& aIntegrity);
     337             : 
     338             :   /**
     339             :    * Unblocks the creator parser of the parser-blocking scripts.
     340             :    */
     341             :   void UnblockParser(ScriptLoadRequest* aParserBlockingRequest);
     342             : 
     343             :   /**
     344             :    * Asynchronously resumes the creator parser of the parser-blocking scripts.
     345             :    */
     346             :   void ContinueParserAsync(ScriptLoadRequest* aParserBlockingRequest);
     347             : 
     348             : 
     349             :   /**
     350             :    * Helper function to check the content policy for a given request.
     351             :    */
     352             :   static nsresult CheckContentPolicy(nsIDocument* aDocument,
     353             :                                      nsISupports* aContext,
     354             :                                      nsIURI* aURI,
     355             :                                      const nsAString& aType,
     356             :                                      bool aIsPreLoad);
     357             : 
     358             :   /**
     359             :    * Start a load for aRequest's URI.
     360             :    */
     361             :   nsresult StartLoad(ScriptLoadRequest* aRequest);
     362             : 
     363             :   /**
     364             :    * Abort the current stream, and re-start with a new load request from scratch
     365             :    * without requesting any alternate data. Returns NS_BINDING_RETARGETED on
     366             :    * success, as this error code is used to abort the input stream.
     367             :    */
     368             :   nsresult RestartLoad(ScriptLoadRequest* aRequest);
     369             : 
     370             :   /**
     371             :    * Process any pending requests asynchronously (i.e. off an event) if there
     372             :    * are any. Note that this is a no-op if there aren't any currently pending
     373             :    * requests.
     374             :    *
     375             :    * This function is virtual to allow cross-library calls to SetEnabled()
     376             :    */
     377             :   virtual void ProcessPendingRequestsAsync();
     378             : 
     379             :   /**
     380             :    * If true, the loader is ready to execute parser-blocking scripts, and so are
     381             :    * all its ancestors.  If the loader itself is ready but some ancestor is not,
     382             :    * this function will add an execute blocker and ask the ancestor to remove it
     383             :    * once it becomes ready.
     384             :    */
     385             :   bool ReadyToExecuteParserBlockingScripts();
     386             : 
     387             :   /**
     388             :    * Return whether just this loader is ready to execute parser-blocking
     389             :    * scripts.
     390             :    */
     391          48 :   bool SelfReadyToExecuteParserBlockingScripts()
     392             :   {
     393          48 :     return ReadyToExecuteScripts() && !mParserBlockingBlockerCount;
     394             :   }
     395             : 
     396             :   /**
     397             :    * Return whether this loader is ready to execute scripts in general.
     398             :    */
     399         131 :   bool ReadyToExecuteScripts()
     400             :   {
     401         131 :     return mEnabled && !mBlockerCount;
     402             :   }
     403             : 
     404             :   nsresult AttemptAsyncScriptCompile(ScriptLoadRequest* aRequest);
     405             :   nsresult ProcessRequest(ScriptLoadRequest* aRequest);
     406             :   nsresult CompileOffThreadOrProcessRequest(ScriptLoadRequest* aRequest);
     407             :   void FireScriptAvailable(nsresult aResult,
     408             :                            ScriptLoadRequest* aRequest);
     409             :   void FireScriptEvaluated(nsresult aResult,
     410             :                            ScriptLoadRequest* aRequest);
     411             :   nsresult EvaluateScript(ScriptLoadRequest* aRequest);
     412             : 
     413             :   /**
     414             :    * Queue the current script load request to be saved, when the page
     415             :    * initialization ends. The page initialization end is defined as being the
     416             :    * time when the load event got received, and when no more scripts are waiting
     417             :    * to be executed.
     418             :    */
     419             :   void RegisterForBytecodeEncoding(ScriptLoadRequest* aRequest);
     420             : 
     421             :   /**
     422             :    * Check if all conditions are met, i-e that the onLoad event fired and that
     423             :    * no more script have to be processed.  If all conditions are met, queue an
     424             :    * event to encode all the bytecode and save them on the cache.
     425             :    */
     426             :   void MaybeTriggerBytecodeEncoding();
     427             : 
     428             :   /**
     429             :    * Iterate over all script load request and save the bytecode of executed
     430             :    * functions on the cache provided by the channel.
     431             :    */
     432             :   void EncodeBytecode();
     433             :   void EncodeRequestBytecode(JSContext* aCx, ScriptLoadRequest* aRequest);
     434             : 
     435             :   void GiveUpBytecodeEncoding();
     436             : 
     437             :   already_AddRefed<nsIScriptGlobalObject> GetScriptGlobalObject();
     438             :   nsresult FillCompileOptionsForRequest(const mozilla::dom::AutoJSAPI& jsapi,
     439             :                                         ScriptLoadRequest* aRequest,
     440             :                                         JS::Handle<JSObject*> aScopeChain,
     441             :                                         JS::CompileOptions* aOptions);
     442             : 
     443             :   uint32_t NumberOfProcessors();
     444             :   nsresult PrepareLoadedRequest(ScriptLoadRequest* aRequest,
     445             :                                 nsIIncrementalStreamLoader* aLoader,
     446             :                                 nsresult aStatus);
     447             : 
     448             :   void AddDeferRequest(ScriptLoadRequest* aRequest);
     449             :   bool MaybeRemovedDeferRequests();
     450             : 
     451             :   void MaybeMoveToLoadedList(ScriptLoadRequest* aRequest);
     452             : 
     453             :   JS::SourceBufferHolder GetScriptSource(ScriptLoadRequest* aRequest,
     454             :                                          nsAutoString& inlineData);
     455             : 
     456             :   bool ModuleScriptsEnabled();
     457             : 
     458             :   void SetModuleFetchStarted(ModuleLoadRequest *aRequest);
     459             :   void SetModuleFetchFinishedAndResumeWaitingRequests(ModuleLoadRequest* aRequest,
     460             :                                                       nsresult aResult);
     461             : 
     462             :   bool IsFetchingModule(ModuleLoadRequest* aRequest) const;
     463             : 
     464             :   bool ModuleMapContainsModule(ModuleLoadRequest* aRequest) const;
     465             :   RefPtr<mozilla::GenericPromise> WaitForModuleFetch(ModuleLoadRequest* aRequest);
     466             :   ModuleScript* GetFetchedModule(nsIURI* aURL) const;
     467             : 
     468             :   friend bool
     469             :   HostResolveImportedModule(JSContext* aCx, unsigned argc, JS::Value* vp);
     470             : 
     471             :   // Returns wether we should save the bytecode of this script after the
     472             :   // execution of the script.
     473             :   static bool
     474             :   ShouldCacheBytecode(ScriptLoadRequest* aRequest);
     475             : 
     476             :   nsresult CreateModuleScript(ModuleLoadRequest* aRequest);
     477             :   nsresult ProcessFetchedModuleSource(ModuleLoadRequest* aRequest);
     478             :   void ProcessLoadedModuleTree(ModuleLoadRequest* aRequest);
     479             :   bool InstantiateModuleTree(ModuleLoadRequest* aRequest);
     480             :   void StartFetchingModuleDependencies(ModuleLoadRequest* aRequest);
     481             : 
     482             :   RefPtr<mozilla::GenericPromise>
     483             :   StartFetchingModuleAndDependencies(ModuleLoadRequest* aRequest, nsIURI* aURI);
     484             : 
     485             :   nsIDocument* mDocument;                   // [WEAK]
     486             :   nsCOMArray<nsIScriptLoaderObserver> mObservers;
     487             :   ScriptLoadRequestList mNonAsyncExternalScriptInsertedRequests;
     488             :   // mLoadingAsyncRequests holds async requests while they're loading; when they
     489             :   // have been loaded they are moved to mLoadedAsyncRequests.
     490             :   ScriptLoadRequestList mLoadingAsyncRequests;
     491             :   ScriptLoadRequestList mLoadedAsyncRequests;
     492             :   ScriptLoadRequestList mDeferRequests;
     493             :   ScriptLoadRequestList mXSLTRequests;
     494             :   RefPtr<ScriptLoadRequest> mParserBlockingRequest;
     495             : 
     496             :   // List of script load request that are holding a buffer which has to be saved
     497             :   // on the cache.
     498             :   ScriptLoadRequestList mBytecodeEncodingQueue;
     499             : 
     500             :   // In mRequests, the additional information here is stored by the element.
     501           8 :   struct PreloadInfo
     502             :   {
     503             :     RefPtr<ScriptLoadRequest> mRequest;
     504             :     nsString mCharset;
     505             :   };
     506             : 
     507             :   friend void ImplCycleCollectionUnlink(ScriptLoader::PreloadInfo& aField);
     508             :   friend void ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback,
     509             :                                           ScriptLoader::PreloadInfo& aField,
     510             :                                           const char* aName, uint32_t aFlags);
     511             : 
     512             :   struct PreloadRequestComparator
     513             :   {
     514           7 :     bool Equals(const PreloadInfo& aPi, ScriptLoadRequest* const& aRequest) const
     515             :     {
     516           7 :       return aRequest == aPi.mRequest;
     517             :     }
     518             :   };
     519             : 
     520             :   struct PreloadURIComparator
     521             :   {
     522             :     bool Equals(const PreloadInfo& aPi, nsIURI* const &aURI) const;
     523             :   };
     524             : 
     525             :   nsTArray<PreloadInfo> mPreloads;
     526             : 
     527             :   nsCOMPtr<nsIScriptElement> mCurrentScript;
     528             :   nsCOMPtr<nsIScriptElement> mCurrentParserInsertedScript;
     529             :   nsTArray< RefPtr<ScriptLoader> > mPendingChildLoaders;
     530             :   uint32_t mParserBlockingBlockerCount;
     531             :   uint32_t mBlockerCount;
     532             :   uint32_t mNumberOfProcessors;
     533             :   bool mEnabled;
     534             :   bool mDeferEnabled;
     535             :   bool mDocumentParsingDone;
     536             :   bool mBlockingDOMContentLoaded;
     537             :   bool mLoadEventFired;
     538             : 
     539             :   // Module map
     540             :   nsRefPtrHashtable<nsURIHashKey, mozilla::GenericPromise::Private> mFetchingModules;
     541             :   nsRefPtrHashtable<nsURIHashKey, ModuleScript> mFetchedModules;
     542             : 
     543             :   nsCOMPtr<nsIConsoleReportCollector> mReporter;
     544             : 
     545             :   // Logging
     546             :   static LazyLogModule gCspPRLog;
     547             :   static LazyLogModule gScriptLoaderLog;
     548             : };
     549             : 
     550             : class nsAutoScriptLoaderDisabler
     551             : {
     552             : public:
     553           0 :   explicit nsAutoScriptLoaderDisabler(nsIDocument* aDoc)
     554           0 :   {
     555           0 :     mLoader = aDoc->ScriptLoader();
     556           0 :     mWasEnabled = mLoader->GetEnabled();
     557           0 :     if (mWasEnabled) {
     558           0 :       mLoader->SetEnabled(false);
     559             :     }
     560           0 :   }
     561             : 
     562           0 :   ~nsAutoScriptLoaderDisabler()
     563           0 :   {
     564           0 :     if (mWasEnabled) {
     565           0 :       mLoader->SetEnabled(true);
     566             :     }
     567           0 :   }
     568             : 
     569             :   bool mWasEnabled;
     570             :   RefPtr<ScriptLoader> mLoader;
     571             : };
     572             : 
     573             : } // namespace dom
     574             : } // namespace mozilla
     575             : 
     576             : #endif // mozilla_dom_ScriptLoader_h

Generated by: LCOV version 1.13