// Copyright 2014 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "cobalt/dom/html_script_element.h"

#include <deque>
#include <memory>
#include <utility>

#include "base/bind.h"
#include "base/compiler_specific.h"
#include "base/strings/string_util.h"
#include "base/trace_event/trace_event.h"
#include "cobalt/base/console_log.h"
#include "cobalt/base/tokens.h"
#include "cobalt/dom/csp_delegate.h"
#include "cobalt/dom/document.h"
#include "cobalt/dom/global_stats.h"
#include "cobalt/dom/html_element_context.h"
#include "cobalt/loader/decoder.h"
#include "cobalt/loader/fetcher_factory.h"
#include "cobalt/loader/sync_loader.h"
#include "cobalt/loader/text_decoder.h"
#include "cobalt/script/global_environment.h"
#include "cobalt/script/script_runner.h"
#include "nb/memory_scope.h"
#include "url/gurl.h"

namespace cobalt {
namespace dom {

namespace {

bool PermitAnyURL(const GURL&, bool) { return true; }

loader::RequestMode GetRequestMode(
    const base::Optional<std::string>& cross_origin_attribute) {
  // https://html.spec.whatwg.org/#cors-settings-attribute
  if (cross_origin_attribute) {
    if (*cross_origin_attribute == "use-credentials") {
      return loader::kCORSModeIncludeCredentials;
    } else {
      // The invalid value default of crossorigin is Anonymous state, leading to
      // "same-origin" credentials mode.
      return loader::kCORSModeSameOriginCredentials;
    }
  }
  // crossorigin attribute's missing value default is No CORS state, leading to
  // "no-cors" request mode.
  return loader::kNoCORSMode;
}
}  // namespace

// static
const char HTMLScriptElement::kTagName[] = "script";

HTMLScriptElement::HTMLScriptElement(Document* document)
    : HTMLElement(document, base::Token(kTagName)),
      is_already_started_(false),
      is_parser_inserted_(false),
      is_ready_(false),
      load_option_(0),
      inline_script_location_(GetSourceLocationName(), 1, 1),
      is_sync_load_successful_(false),
      should_execute_(true),
      synchronous_loader_interrupt_(
          document->html_element_context()->synchronous_loader_interrupt()) {
  DCHECK(document->html_element_context()->script_runner());
}

base::Optional<std::string> HTMLScriptElement::cross_origin() const {
  base::Optional<std::string> cross_origin_attribute =
      GetAttribute("crossOrigin");
  if (cross_origin_attribute &&
      (*cross_origin_attribute != "anonymous" &&
       *cross_origin_attribute != "use-credentials")) {
    return std::string();
  }
  return cross_origin_attribute;
}

void HTMLScriptElement::set_cross_origin(
    const base::Optional<std::string>& value) {
  if (value) {
    SetAttribute("crossOrigin", *value);
  } else {
    RemoveAttribute("crossOrigin");
  }
}

void HTMLScriptElement::OnInsertedIntoDocument() {
  HTMLElement::OnInsertedIntoDocument();
  if (!is_parser_inserted_) {
    Prepare();
  }
}

void HTMLScriptElement::OnParserStartTag(
    const base::SourceLocation& opening_tag_location) {
  inline_script_location_ = opening_tag_location;
  ++inline_script_location_.column_number;  // JavaScript code starts after ">".
  is_parser_inserted_ = true;
}

void HTMLScriptElement::OnParserEndTag() { Prepare(); }

scoped_refptr<HTMLScriptElement> HTMLScriptElement::AsHTMLScriptElement() {
  return this;
}

scoped_refptr<Node> HTMLScriptElement::Duplicate() const {
  // The cloning steps for script elements must set the "already started" flag
  // on the copy if it is set on the element being cloned.
  //   https://www.w3.org/TR/html5/scripting-1.html#already-started
  scoped_refptr<HTMLScriptElement> new_script = HTMLElement::Duplicate()
                                                    ->AsElement()
                                                    ->AsHTMLElement()
                                                    ->AsHTMLScriptElement();
  new_script->is_already_started_ = is_already_started_;
  return new_script;
}

HTMLScriptElement::~HTMLScriptElement() {
  // Remove the script from the list of scripts that will execute in order as
  // soon as possible associated with the Document, only if the document still
  // exists when the script element is destroyed.
  // NOTE: While the garbage collection prevention logic will typically protect
  // from this, it is still possible during shutdown.
  if (node_document()) {
    std::deque<HTMLScriptElement*>* scripts_to_be_executed =
        node_document()->scripts_to_be_executed();

    std::deque<HTMLScriptElement*>::iterator it = std::find(
        scripts_to_be_executed->begin(), scripts_to_be_executed->end(), this);
    if (it != scripts_to_be_executed->end()) {
      scripts_to_be_executed->erase(it);
    }
  }
}

// Algorithm for Prepare:
//   https://www.w3.org/TR/html5/scripting-1.html#prepare-a-script
void HTMLScriptElement::Prepare() {
  TRACK_MEMORY_SCOPE("DOM");
  // Custom, not in any spec.
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  DCHECK(base::MessageLoop::current());
  DCHECK(!loader_ || is_already_started_);
  TRACE_EVENT0("cobalt::dom", "HTMLScriptElement::Prepare()");

  // If the script element is marked as having "already started", then the user
  // agent must abort these steps at this point. The script is not executed.
  if (is_already_started_) {
    return;
  }

  // 2. 3. 4. Not needed by Cobalt.

  // 5. If the element is not in a Document, then the user agent must abort
  // these steps at this point. The script is not executed.
  if (!node_document()) {
    return;
  }
  document_ = base::AsWeakPtr<Document>(node_document());

  // 6. If either:
  //    the script element has a type attribute and its value is the empty
  //      string, or
  //    the script element has no type attribute but it has a language attribute
  //      and that attribute's value is the empty string, or
  //    the script element has neither a type attribute nor a language
  //      attribute, then
  // ...let the script block's type for this script element be
  // "text/javascript".
  // Otherwise, if the script element has a type attribute, let the script
  // block's type for this script element be the value of that attribute with
  // any leading or trailing sequences of space characters removed.
  // Otherwise, the element has a non-empty language attribute; let the script
  // block's type for this script element be the concatenation of the string
  // "text/" followed by the value of the language attribute.
  if (type() == "") {
    set_type("text/javascript");
  } else {
    std::string trimmed_type;
    TrimWhitespaceASCII(type(), base::TRIM_ALL, &trimmed_type);
    set_type(trimmed_type);
  }

  // 7. If the user agent does not support the scripting language given by the
  // script block's type for this script element, then the user agent must abort
  // these steps at this point. The script is not executed.
  if (type() != "text/javascript") return;

  // 8. Not needed by Cobalt.

  // 9. The user agent must set the element's "already started" flag.
  is_already_started_ = true;

  // 10. ~ 13. Not needed by Cobalt.

  // 14. If the element has a src content attribute, run these substeps:
  //   1. Let src be the value of the element's src attribute.
  //   2. If src is the empty string, queue a task to fire a simple event
  // named error at the element, and abort these steps.
  if (HasAttribute("src") && src() == "") {
    LOG(WARNING) << "src attribute of script element is empty.";

    PreventGarbageCollectionAndPostToDispatchEvent(
        FROM_HERE, base::Tokens::error(),
        &prevent_gc_until_error_event_dispatch_);
    return;
  }

  //   3. Resolve src relative to the element.
  //   4. If the previous step failed, queue a task to fire a simple event named
  // error at the element, and abort these steps.
  const GURL& base_url = document_->url_as_gurl();
  url_ = base_url.Resolve(src());
  if (!url_.is_valid()) {
    LOG(WARNING) << src() << " cannot be resolved based on " << base_url << ".";

    PreventGarbageCollectionAndPostToDispatchEvent(
        FROM_HERE, base::Tokens::error(),
        &prevent_gc_until_error_event_dispatch_);
    return;
  }

  //   5. Do a potentially CORS-enabled fetch of the resulting absolute URL,
  // with the mode being the current state of the element's crossorigin
  // content attribute, the origin being the origin of the script element's
  // Document, and the default origin behaviour set to taint.

  // 15. Then, the first of the following options that describes the situation
  // must be followed:

  // Option 1 and Option 3 are not needed by Cobalt.
  if (HasAttribute("src") && is_parser_inserted_ && !async()) {
    // Option 2
    // If the element has a src attribute, and the element has been flagged as
    // "parser-inserted", and the element does not have an async attribute.

    if (owner_document()
            ->html_element_context()
            ->enable_inline_script_warnings()) {
      CLOG(WARNING, debugger_hooks())
          << "A request to synchronously load a script is being made as "
             "a result of a non-async <script> tag inlined within HTML. "
             "You should avoid this in Cobalt because if the app is "
             "suspended while loading the script, Cobalt's current "
             "logic is to abort the load and without any retries or "
             "signals. To avoid difficult to diagnose suspend/resume "
             "bugs, it is recommended to use JavaScript to create a "
             "script element and load it async. The <script> reference "
             "appears at: \""
          << inline_script_location_ << "\" and its src is \"" << src() << "\"";
    }

    load_option_ = 2;
  } else if (HasAttribute("src") && !async()) {
    // Option 4
    // If the element has a src attribute, does not have an async attribute, and
    // does not have the "force-async" flag set.
    load_option_ = 4;
  } else if (HasAttribute("src")) {
    // Option 5
    // If the element has a src attribute.
    load_option_ = 5;
  } else {
    // Option 6
    // Otherwise.
    load_option_ = 6;
  }

  // https://www.w3.org/TR/CSP2/#directive-script-src

  CspDelegate* csp_delegate = document_->csp_delegate();
  // If the script element has a valid nonce, we always permit it, regardless
  // of its URL or inline nature.
  const bool bypass_csp =
      csp_delegate->IsValidNonce(CspDelegate::kScript, nonce());

  csp::SecurityCallback csp_callback;
  if (bypass_csp) {
    csp_callback = base::Bind(&PermitAnyURL);
  } else {
    csp_callback =
        base::Bind(&CspDelegate::CanLoad, base::Unretained(csp_delegate),
                   CspDelegate::kScript);
  }

  // Clear fetched resource's origin before start.
  fetched_last_url_origin_ = loader::Origin();

  // Determine request mode from crossorigin attribute.
  request_mode_ = GetRequestMode(GetAttribute("crossOrigin"));

  switch (load_option_) {
    case 2: {
      // If the element has a src attribute, and the element has been flagged as
      // "parser-inserted", and the element does not have an async attribute.

      // The element is the pending parsing-blocking script of the Document of
      // the parser that created the element. (There can only be one such script
      // per Document at a time.)

      // This variable will be set to true in the completion callback for the
      // loader below.  If that completion callback never fires, the variable
      // will stay false.  This can happen if the loader was interrupted, or
      // failed for another reason.
      is_sync_load_successful_ = false;

      loader::LoadSynchronously(
          html_element_context()->sync_load_thread()->message_loop(),
          synchronous_loader_interrupt_,
          base::Bind(
              &loader::FetcherFactory::CreateSecureFetcher,
              base::Unretained(html_element_context()->fetcher_factory()), url_,
              csp_callback, request_mode_,
              document_->location() ? document_->location()->GetOriginAsObject()
                                    : loader::Origin()),
          base::Bind(&loader::TextDecoder::Create,
                     base::Bind(&HTMLScriptElement::OnSyncContentProduced,
                                base::Unretained(this)),
                     loader::Decoder::OnCompleteFunction()),
          base::Bind(&HTMLScriptElement::OnSyncLoadingComplete,
                     base::Unretained(this)));

      if (is_sync_load_successful_) {
        script::GlobalEnvironment::ScopedPreventGarbageCollection
            scoped_prevent_gc(
                html_element_context()->script_runner()->GetGlobalEnvironment(),
                this);
        ExecuteExternal();
        // Release the content string now that we're finished with it.
        content_.reset();
      } else {
        // Executing the script block must just consist of firing a simple event
        // named error at the element.
        DispatchEvent(new Event(base::Tokens::error()));
      }
    } break;
    case 4: {
      // This is an asynchronous script. Prevent garbage collection until
      // loading completes and the script potentially executes.
      PreventGCUntilLoadComplete();

      // If the element has a src attribute, does not have an async attribute,
      // and does not have the "force-async" flag set.

      // The element must be added to the end of the list of scripts that will
      // execute in order as soon as possible associated with the Document of
      // the script element at the time the prepare a script algorithm started.
      std::deque<HTMLScriptElement*>* scripts_to_be_executed =
          document_->scripts_to_be_executed();
      scripts_to_be_executed->push_back(this);

      // Fetching an external script must delay the load event of the element's
      // document until the task that is queued by the networking task source
      // once the resource has been fetched (defined above) has been run.
      document_->IncreaseLoadingCounter();

      loader::Origin origin = document_->location()
                                  ? document_->location()->GetOriginAsObject()
                                  : loader::Origin();

      loader_ = html_element_context()->loader_factory()->CreateScriptLoader(
          url_, origin, csp_callback,
          base::Bind(&HTMLScriptElement::OnContentProduced,
                     base::Unretained(this)),
          base::Bind(&HTMLScriptElement::OnLoadingComplete,
                     base::Unretained(this)));
    } break;
    case 5: {
      // This is an asynchronous script. Prevent garbage collection until
      // loading completes and the script potentially executes.
      PreventGCUntilLoadComplete();

      // If the element has a src attribute.

      // Fetching an external script must delay the load event of the element's
      // document until the task that is queued by the networking task source
      // once the resource has been fetched (defined above) has been run.
      document_->IncreaseLoadingCounter();

      // The element must be added to the set of scripts that will execute as
      // soon as possible of the Document of the script element at the time the
      // prepare a script algorithm started.
      DCHECK(!loader_);

      loader::Origin origin = document_->location()
                                  ? document_->location()->GetOriginAsObject()
                                  : loader::Origin();

      loader_ = html_element_context()->loader_factory()->CreateScriptLoader(
          url_, origin, csp_callback,
          base::Bind(&HTMLScriptElement::OnContentProduced,
                     base::Unretained(this)),
          base::Bind(&HTMLScriptElement::OnLoadingComplete,
                     base::Unretained(this)));
    } break;
    case 6: {
      // Otherwise.

      // The user agent must immediately execute the script block, even if other
      // scripts are already executing.
      base::Optional<std::string> content = text_content();
      const std::string& text = content.value_or(base::EmptyString());
      if (bypass_csp || text.empty() ||
          csp_delegate->AllowInline(CspDelegate::kScript,
                                    inline_script_location_, text)) {
        fetched_last_url_origin_ = document_->location()->GetOriginAsObject();
        ExecuteInternal();
      } else {
        PreventGarbageCollectionAndPostToDispatchEvent(
            FROM_HERE, base::Tokens::error(),
            &prevent_gc_until_error_event_dispatch_);
      }
    } break;
    default: { NOTREACHED(); }
  }
}

void HTMLScriptElement::OnSyncContentProduced(
    const loader::Origin& last_url_origin,
    std::unique_ptr<std::string> content) {
  TRACE_EVENT0("cobalt::dom", "HTMLScriptElement::OnSyncContentProduced()");
  fetched_last_url_origin_ = last_url_origin;
  content_ = std::move(content);
  is_sync_load_successful_ = true;
}

void HTMLScriptElement::OnSyncLoadingComplete(
    const base::Optional<std::string>& error) {
  if (!error) return;

  TRACE_EVENT0("cobalt::dom", "HTMLScriptElement::OnSyncLoadingComplete()");
  LOG(ERROR) << "Error during synchronous script load referenced from \""
             << inline_script_location_ << "\" : " << *error;
}

// Algorithm for OnContentProduced:
//   https://www.w3.org/TR/html5/scripting-1.html#prepare-a-script
void HTMLScriptElement::OnContentProduced(
    const loader::Origin& last_url_origin,
    std::unique_ptr<std::string> content) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  DCHECK(load_option_ == 4 || load_option_ == 5);
  DCHECK(content);
  TRACE_EVENT0("cobalt::dom", "HTMLScriptElement::OnContentProduced()");
  if (!document_) {
    AllowGCAfterLoadComplete();
    return;
  }

  fetched_last_url_origin_ = last_url_origin;
  content_ = std::move(content);

  switch (load_option_) {
    case 4: {
      // If the element has a src attribute, does not have an async attribute,
      // and does not have the "force-async" flag set.

      // The task that the networking task source places on the task queue once
      // the fetching algorithm has completed must run the following steps:
      //   1. If the element is not now the first element in the list of scripts
      //   that will execute in order as soon as possible to which it was added
      //   above, then mark the element as ready but abort these steps without
      //   executing the script yet.
      std::deque<HTMLScriptElement*>* scripts_to_be_executed =
          document_->scripts_to_be_executed();
      if (scripts_to_be_executed->front() != this) {
        is_ready_ = true;
        return;
      }
      while (true) {
        // 2. Execution: Execute the script block corresponding to the first
        // script element in this list of scripts that will execute in order as
        // soon as possible.
        HTMLScriptElement* script = scripts_to_be_executed->front();
        script->ExecuteExternal();

        // NOTE: Must disable warning 6011 on Windows. It mysteriously believes
        // that a NULL pointer is being dereferenced with this comparison.
        MSVC_PUSH_DISABLE_WARNING(6011);
        // If this script isn't the current object, then allow it to be garbage
        // collected now that it has executed.
        if (script != this) {
          script->AllowGCAfterLoadComplete();
        }
        MSVC_POP_WARNING();

        // 3. Remove the first element from this list of scripts that will
        // execute in order as soon as possible.
        scripts_to_be_executed->pop_front();

        // Fetching an external script must delay the load event of the
        //  element's document until the task that is queued by the networking
        // task source once the resource has been fetched (defined above)
        // has been run.
        document_->DecreaseLoadingCounterAndMaybeDispatchLoadEvent();

        // 4. If this list of scripts that will execute in order as soon as
        // possible is still not empty and the first entry has already been
        // marked
        // as ready, then jump back to the step labeled execution.
        if (scripts_to_be_executed->empty() ||
            !scripts_to_be_executed->front()->is_ready_) {
          break;
        }
      }
      // Allow garbage collection on the current script object now that it has
      // finished executing both itself and other pending scripts.
      AllowGCAfterLoadComplete();
    } break;
    case 5: {
      // If the element has a src attribute.

      // The task that the networking task source places on the task queue once
      // the fetching algorithm has completed must execute the script block and
      // then remove the element from the set of scripts that will execute as
      // soon as possible.
      ExecuteExternal();

      // Allow garbage collection on the current object now that it has finished
      // executing.
      AllowGCAfterLoadComplete();

      // Fetching an external script must delay the load event of the element's
      // document until the task that is queued by the networking task source
      // once the resource has been fetched (defined above) has been run.
      document_->DecreaseLoadingCounterAndMaybeDispatchLoadEvent();
    } break;
  }

  // Release the content string now that we're finished with it.
  content_.reset();

  // Post a task to release the loader.
  base::MessageLoop::current()->task_runner()->PostTask(
      FROM_HERE, base::Bind(&HTMLScriptElement::ReleaseLoader, this));
}

// Algorithm for OnLoadingComplete:
//   https://www.w3.org/TR/html5/scripting-1.html#prepare-a-script
void HTMLScriptElement::OnLoadingComplete(
    const base::Optional<std::string>& error) {
  if (!error) return;

  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  DCHECK(load_option_ == 4 || load_option_ == 5);
  TRACE_EVENT0("cobalt::dom", "HTMLScriptElement::OnLoadingComplete()");

  if (!document_) {
    AllowGCAfterLoadComplete();
    return;
  }

  LOG(ERROR) << *error;

  // Executing the script block must just consist of firing a simple event
  // named error at the element.
  DispatchEvent(new Event(base::Tokens::error()));
  AllowGCAfterLoadComplete();

  switch (load_option_) {
    case 4: {
      // If the element has a src attribute, does not have an async attribute,
      // and does not have the "force-async" flag set.
      std::deque<HTMLScriptElement*>* scripts_to_be_executed =
          document_->scripts_to_be_executed();

      std::deque<HTMLScriptElement*>::iterator it = std::find(
          scripts_to_be_executed->begin(), scripts_to_be_executed->end(), this);
      if (it != scripts_to_be_executed->end()) {
        scripts_to_be_executed->erase(it);
      }
    } break;
    case 5: {
      // If the element has a src attribute.
    } break;
  }

  // Fetching an external script must delay the load event of the element's
  // document until the task that is queued by the networking task source
  // once the resource has been fetched (defined above) has been run.
  document_->DecreaseLoadingCounterAndMaybeDispatchLoadEvent();

  // Post a task to release the loader.
  base::MessageLoop::current()->task_runner()->PostTask(
      FROM_HERE, base::Bind(&HTMLScriptElement::ReleaseLoader, this));
}

void HTMLScriptElement::ExecuteExternal() {
  DCHECK(content_);
  Execute(*content_, base::SourceLocation(url_.spec(), 1, 1), true);
}

void HTMLScriptElement::ExecuteInternal() {
  Execute(text_content().value(), inline_script_location_, false);
}

// Algorithm for Execute:
//   https://www.w3.org/TR/html5/scripting-1.html#execute-the-script-block
void HTMLScriptElement::Execute(const std::string& content,
                                const base::SourceLocation& script_location,
                                bool is_external) {
  TRACK_MEMORY_SCOPE("DOM");
  // If should_execute_ is set to false for whatever reason, then we
  // immediately exit.
  // When inserted using the document.write() method, script elements execute
  // (typically synchronously), but when inserted using innerHTML and
  // outerHTML attributes, they do not execute at all.
  // https://www.w3.org/TR/html5/scripting-1.html#the-script-element.
  if (!should_execute_) {
    return;
  }

  // The script is now being run. Track it in the global stats.
  GlobalStats::GetInstance()->StartJavaScriptEvent();

  TRACE_EVENT2("cobalt::dom", "HTMLScriptElement::Execute()", "file_path",
               script_location.file_path, "line_number",
               script_location.line_number);
  // Since error is already handled, it is guaranteed the load is successful.

  // 1. 2. 3. Not needed by Cobalt.

  // 4. Create a script, using the script block's source, the URL from which the
  // script was obtained, the script block's type as the scripting language, and
  // the script settings object of the script element's Document's Window
  // object.
  bool mute_errors =
      request_mode_ == loader::kNoCORSMode &&
      fetched_last_url_origin_ != document_->location()->GetOriginAsObject();
  html_element_context()->script_runner()->Execute(
      content, script_location, mute_errors, NULL /*out_succeeded*/);

  // 5. 6. Not needed by Cobalt.

  // 7. If the script is from an external file, fire a simple event named load
  // at the script element.
  // Otherwise, the script is internal; queue a task to fire a simple event
  // named load at the script element.
  // TODO: Remove the firing of readystatechange once we support Promise.
  if (is_external) {
    DispatchEvent(new Event(base::Tokens::load()));
    DispatchEvent(new Event(base::Tokens::readystatechange()));
  } else {
    PreventGarbageCollectionAndPostToDispatchEvent(
        FROM_HERE, base::Tokens::load(),
        &prevent_gc_until_load_event_dispatch_);
    PreventGarbageCollectionAndPostToDispatchEvent(
        FROM_HERE, base::Tokens::readystatechange(),
        &prevent_gc_until_ready_event_dispatch_);
  }

  // The script is done running. Stop tracking it in the global stats.
  GlobalStats::GetInstance()->StopJavaScriptEvent();

  // Notify the DomStatTracker of the execution.
  dom_stat_tracker_->OnHtmlScriptElementExecuted(content.size());
}

void HTMLScriptElement::PreventGarbageCollectionAndPostToDispatchEvent(
    const base::Location& location, const base::Token& token,
    std::unique_ptr<script::GlobalEnvironment::ScopedPreventGarbageCollection>*
        scoped_prevent_gc) {
  // Ensure that this HTMLScriptElement is not garbage collected until the event
  // has been processed.
  DCHECK(!(*scoped_prevent_gc));
  scoped_prevent_gc->reset(
      new script::GlobalEnvironment::ScopedPreventGarbageCollection(
          html_element_context()->script_runner()->GetGlobalEnvironment(),
          this));
  PostToDispatchEventNameAndRunCallback(
      location, token,
      base::Bind(&HTMLScriptElement::AllowGCAfterEventDispatch, this,
                 scoped_prevent_gc));
}

void HTMLScriptElement::AllowGCAfterEventDispatch(
    std::unique_ptr<script::GlobalEnvironment::ScopedPreventGarbageCollection>*
        scoped_prevent_gc) {
  scoped_prevent_gc->reset();
}

void HTMLScriptElement::PreventGCUntilLoadComplete() {
  DCHECK(!prevent_gc_until_load_complete_);
  prevent_gc_until_load_complete_.reset(
      new script::GlobalEnvironment::ScopedPreventGarbageCollection(
          html_element_context()->script_runner()->GetGlobalEnvironment(),
          this));
}

void HTMLScriptElement::AllowGCAfterLoadComplete() {
  prevent_gc_until_load_complete_.reset();
}

void HTMLScriptElement::ReleaseLoader() {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  DCHECK(loader_);
  loader_.reset();
}

}  // namespace dom
}  // namespace cobalt
