blob: 2242897135c77d60ef011a8f103a0e4335102583 [file] [log] [blame]
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/renderer/core/script/pending_import_map.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/script/import_map.h"
#include "third_party/blink/renderer/core/script/modulator.h"
#include "third_party/blink/renderer/core/script/script_element_base.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
namespace blink {
PendingImportMap* PendingImportMap::CreateInline(ScriptElementBase& element,
const String& import_map_text,
const KURL& base_url) {
ExecutionContext* context = element.GetExecutionContext();
ScriptState* script_state =
ToScriptStateForMainWorld(To<LocalDOMWindow>(context)->GetFrame());
Modulator* modulator = Modulator::From(script_state);
ScriptValue error_to_rethrow;
ImportMap* import_map = ImportMap::Parse(
*modulator, import_map_text, base_url, *context, &error_to_rethrow);
return MakeGarbageCollected<PendingImportMap>(
script_state, element, import_map, error_to_rethrow, *context);
}
PendingImportMap::PendingImportMap(ScriptState* script_state,
ScriptElementBase& element,
ImportMap* import_map,
ScriptValue error_to_rethrow,
const ExecutionContext& original_context)
: element_(&element),
import_map_(import_map),
original_execution_context_(&original_context) {
if (!error_to_rethrow.IsEmpty()) {
ScriptState::Scope scope(script_state);
error_to_rethrow_.Set(script_state->GetIsolate(),
error_to_rethrow.V8Value());
}
}
// <specdef href="https://wicg.github.io/import-maps/#register-an-import-map">
// This is parallel to PendingScript::ExecuteScriptBlock().
void PendingImportMap::RegisterImportMap() const {
// <spec step="1">If element’s the script’s result is null, then fire an event
// named error at element, and return.</spec>
if (!import_map_) {
element_->DispatchErrorEvent();
return;
}
// <spec step="2">Let import map parse result be element’s the script’s
// result.</spec>
//
// This is |this|.
// <spec step="3">Assert: element’s the script’s type is "importmap".</spec>
//
// <spec step="4">Assert: import map parse result is an import map parse
// result.</spec>
//
// These are ensured by C++ type.
// <spec step="5">Let settings object be import map parse result’s settings
// object.</spec>
//
// <spec step="6">If element’s node document’s relevant settings object is not
// equal to settings object, then return. ...</spec>
ExecutionContext* context = element_->GetExecutionContext();
if (original_execution_context_ != context)
return;
// Steps 7 and 8.
LocalFrame* frame = To<LocalDOMWindow>(context)->GetFrame();
if (!frame)
return;
Modulator* modulator = Modulator::From(ToScriptStateForMainWorld(frame));
ScriptState* script_state = modulator->GetScriptState();
ScriptState::Scope scope(script_state);
ScriptValue error;
if (!error_to_rethrow_.IsEmpty()) {
error = ScriptValue(script_state->GetIsolate(),
error_to_rethrow_.Get(script_state));
}
modulator->RegisterImportMap(import_map_, error);
// <spec step="9">If element is from an external file, then fire an event
// named load at element.</spec>
//
// TODO(hiroshige): Implement this when external import maps are implemented.
}
void PendingImportMap::Trace(Visitor* visitor) const {
visitor->Trace(element_);
visitor->Trace(import_map_);
visitor->Trace(error_to_rethrow_);
visitor->Trace(original_execution_context_);
}
} // namespace blink