nsIScriptElement.cpp (3274B)
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 "nsIScriptElement.h" 8 9 #include "js/loader/ScriptKind.h" 10 #include "mozilla/dom/Document.h" 11 #include "mozilla/dom/ReferrerPolicyBinding.h" 12 #include "nsIParser.h" 13 #include "nsIWeakReference.h" 14 15 using JS::loader::ScriptKind; 16 17 bool nsIScriptElement::IsClassicNonAsyncDefer() { 18 return mKind == ScriptKind::eClassic && !mAsync && !mDefer; 19 } 20 21 void nsIScriptElement::SetCreatorParser(nsIParser* aParser) { 22 mCreatorParser = do_GetWeakReference(aParser); 23 } 24 25 void nsIScriptElement::UnblockParser() { 26 if (!IsClassicNonAsyncDefer()) { 27 MOZ_ASSERT_UNREACHABLE( 28 "Tried to unblock parser for a script type that cannot block " 29 "the parser."); 30 return; 31 } 32 nsCOMPtr<nsIParser> parser = do_QueryReferent(mCreatorParser); 33 if (parser) { 34 parser->UnblockParser(); 35 } 36 } 37 38 void nsIScriptElement::ContinueParserAsync() { 39 if (!IsClassicNonAsyncDefer()) { 40 MOZ_ASSERT_UNREACHABLE( 41 "Tried to continue after a script type that cannot block the parser."); 42 return; 43 } 44 nsCOMPtr<nsIParser> parser = do_QueryReferent(mCreatorParser); 45 if (parser) { 46 parser->ContinueInterruptedParsingAsync(); 47 } 48 } 49 50 void nsIScriptElement::BeginEvaluating() { 51 if (!IsClassicNonAsyncDefer()) { 52 return; 53 } 54 nsCOMPtr<nsIParser> parser = do_QueryReferent(mCreatorParser); 55 if (parser) { 56 parser->IncrementScriptNestingLevel(); 57 } 58 } 59 60 void nsIScriptElement::EndEvaluating() { 61 if (!IsClassicNonAsyncDefer()) { 62 return; 63 } 64 nsCOMPtr<nsIParser> parser = do_QueryReferent(mCreatorParser); 65 if (parser) { 66 parser->DecrementScriptNestingLevel(); 67 } 68 } 69 70 already_AddRefed<nsIParser> nsIScriptElement::GetCreatorParser() { 71 nsCOMPtr<nsIParser> parser = do_QueryReferent(mCreatorParser); 72 return parser.forget(); 73 } 74 75 bool nsIScriptElement::AttemptToExecute(nsCOMPtr<nsIParser> aParser) { 76 mDoneAddingChildren = true; 77 bool block = MaybeProcessScript(aParser); 78 if (!mAlreadyStarted) { 79 // Need to lose parser-insertedness here to allow another script to cause 80 // execution later. 81 LoseParserInsertedness(); 82 } 83 return block; 84 } 85 86 mozilla::dom::ReferrerPolicy nsIScriptElement::GetReferrerPolicy() { 87 return mozilla::dom::ReferrerPolicy::_empty; 88 } 89 90 void nsIScriptElement::DetermineKindFromType( 91 const mozilla::dom::Document* aOwnerDoc) { 92 MOZ_ASSERT((mKind != ScriptKind::eModule) && 93 (mKind != ScriptKind::eImportMap) && !mAsync && !mDefer && 94 !mExternal); 95 96 nsAutoString type; 97 GetScriptType(type); 98 99 if (!type.IsEmpty()) { 100 if (type.LowerCaseEqualsASCII("module")) { 101 mKind = ScriptKind::eModule; 102 } 103 104 // https://html.spec.whatwg.org/multipage/scripting.html#prepare-the-script-element 105 // Step 11. Otherwise, if the script block's type string is an ASCII 106 // case-insensitive match for the string "importmap", then set el's type to 107 // "importmap". 108 if (type.LowerCaseEqualsASCII("importmap")) { 109 mKind = ScriptKind::eImportMap; 110 } 111 } 112 }