зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1572644 - Part 11-2: Preload localized error msg and format it when resolving failed. r=jonco,yulia
Depends on D166549 Differential Revision: https://phabricator.services.mozilla.com/D170161
This commit is contained in:
Родитель
c01828aba9
Коммит
a582a668da
|
@ -11,6 +11,9 @@
|
||||||
#include "mozilla/dom/WorkletImpl.h"
|
#include "mozilla/dom/WorkletImpl.h"
|
||||||
#include "xpcprivate.h"
|
#include "xpcprivate.h"
|
||||||
|
|
||||||
|
using JS::loader::ResolveError;
|
||||||
|
using JS::loader::ResolveErrorInfo;
|
||||||
|
|
||||||
namespace mozilla::dom {
|
namespace mozilla::dom {
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// Worklet
|
// Worklet
|
||||||
|
@ -52,12 +55,51 @@ JSObject* Worklet::WrapObject(JSContext* aCx,
|
||||||
return mImpl->WrapWorklet(aCx, this, aGivenProto);
|
return mImpl->WrapWorklet(aCx, this, aGivenProto);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool LoadLocalizedStrings(nsTArray<nsString>& aStrings) {
|
||||||
|
// All enumes in ResolveError.
|
||||||
|
ResolveError errors[] = {ResolveError::Failure,
|
||||||
|
ResolveError::FailureMayBeBare,
|
||||||
|
ResolveError::BlockedByNullEntry,
|
||||||
|
ResolveError::BlockedByAfterPrefix,
|
||||||
|
ResolveError::BlockedByBacktrackingPrefix,
|
||||||
|
ResolveError::InvalidBareSpecifier};
|
||||||
|
|
||||||
|
static_assert(
|
||||||
|
ArrayLength(errors) == static_cast<size_t>(ResolveError::Length),
|
||||||
|
"The array 'errors' has missing entries in the enum class ResolveError.");
|
||||||
|
|
||||||
|
for (auto i : errors) {
|
||||||
|
nsAutoString message;
|
||||||
|
nsresult rv = nsContentUtils::GetLocalizedString(
|
||||||
|
nsContentUtils::eDOM_PROPERTIES, ResolveErrorInfo::GetString(i),
|
||||||
|
message);
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
if (NS_WARN_IF(!aStrings.AppendElement(EmptyString(), fallible))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (NS_WARN_IF(!aStrings.AppendElement(message, fallible))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
already_AddRefed<Promise> Worklet::AddModule(JSContext* aCx,
|
already_AddRefed<Promise> Worklet::AddModule(JSContext* aCx,
|
||||||
const nsAString& aModuleURL,
|
const nsAString& aModuleURL,
|
||||||
const WorkletOptions& aOptions,
|
const WorkletOptions& aOptions,
|
||||||
CallerType aCallerType,
|
CallerType aCallerType,
|
||||||
ErrorResult& aRv) {
|
ErrorResult& aRv) {
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
if (mLocalizedStrings.IsEmpty()) {
|
||||||
|
bool result = LoadLocalizedStrings(mLocalizedStrings);
|
||||||
|
if (!result) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return WorkletFetchHandler::AddModule(this, aCx, aModuleURL, aOptions, aRv);
|
return WorkletFetchHandler::AddModule(this, aCx, aModuleURL, aOptions, aRv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -50,6 +50,10 @@ class Worklet final : public nsISupports, public nsWrapperCache {
|
||||||
|
|
||||||
WorkletImpl* Impl() const { return mImpl; }
|
WorkletImpl* Impl() const { return mImpl; }
|
||||||
|
|
||||||
|
const nsTArray<nsString>& GetLocalizedStrings() const {
|
||||||
|
return mLocalizedStrings;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
~Worklet();
|
~Worklet();
|
||||||
|
|
||||||
|
@ -65,6 +69,8 @@ class Worklet final : public nsISupports, public nsWrapperCache {
|
||||||
|
|
||||||
const RefPtr<WorkletImpl> mImpl;
|
const RefPtr<WorkletImpl> mImpl;
|
||||||
|
|
||||||
|
nsTArray<nsString> mLocalizedStrings;
|
||||||
|
|
||||||
friend class WorkletFetchHandler;
|
friend class WorkletFetchHandler;
|
||||||
friend class WorkletScriptHandler;
|
friend class WorkletScriptHandler;
|
||||||
};
|
};
|
||||||
|
|
|
@ -36,12 +36,14 @@ class StartModuleLoadRunnable final : public Runnable {
|
||||||
StartModuleLoadRunnable(
|
StartModuleLoadRunnable(
|
||||||
WorkletImpl* aWorkletImpl,
|
WorkletImpl* aWorkletImpl,
|
||||||
const nsMainThreadPtrHandle<WorkletFetchHandler>& aHandlerRef,
|
const nsMainThreadPtrHandle<WorkletFetchHandler>& aHandlerRef,
|
||||||
nsCOMPtr<nsIURI> aURI, nsIURI* aReferrer)
|
nsCOMPtr<nsIURI> aURI, nsIURI* aReferrer,
|
||||||
|
const nsTArray<nsString>& aLocalizedStrs)
|
||||||
: Runnable("Worklet::StartModuleLoadRunnable"),
|
: Runnable("Worklet::StartModuleLoadRunnable"),
|
||||||
mWorkletImpl(aWorkletImpl),
|
mWorkletImpl(aWorkletImpl),
|
||||||
mHandlerRef(aHandlerRef),
|
mHandlerRef(aHandlerRef),
|
||||||
mURI(std::move(aURI)),
|
mURI(std::move(aURI)),
|
||||||
mReferrer(aReferrer),
|
mReferrer(aReferrer),
|
||||||
|
mLocalizedStrs(aLocalizedStrs),
|
||||||
mParentRuntime(
|
mParentRuntime(
|
||||||
JS_GetParentRuntime(CycleCollectedJSContext::Get()->Context())) {
|
JS_GetParentRuntime(CycleCollectedJSContext::Get()->Context())) {
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
@ -59,6 +61,7 @@ class StartModuleLoadRunnable final : public Runnable {
|
||||||
nsMainThreadPtrHandle<WorkletFetchHandler> mHandlerRef;
|
nsMainThreadPtrHandle<WorkletFetchHandler> mHandlerRef;
|
||||||
nsCOMPtr<nsIURI> mURI;
|
nsCOMPtr<nsIURI> mURI;
|
||||||
nsIURI* mReferrer;
|
nsIURI* mReferrer;
|
||||||
|
const nsTArray<nsString>& mLocalizedStrs;
|
||||||
JSRuntime* mParentRuntime;
|
JSRuntime* mParentRuntime;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -93,6 +96,10 @@ NS_IMETHODIMP StartModuleLoadRunnable::RunOnWorkletThread() {
|
||||||
static_cast<WorkletModuleLoader*>(globalScope->GetModuleLoader());
|
static_cast<WorkletModuleLoader*>(globalScope->GetModuleLoader());
|
||||||
MOZ_ASSERT(moduleLoader);
|
MOZ_ASSERT(moduleLoader);
|
||||||
|
|
||||||
|
if (!moduleLoader->HasSetLocalizedStrings()) {
|
||||||
|
moduleLoader->SetLocalizedStrings(&mLocalizedStrs);
|
||||||
|
}
|
||||||
|
|
||||||
RefPtr<WorkletLoadContext> loadContext = new WorkletLoadContext(mHandlerRef);
|
RefPtr<WorkletLoadContext> loadContext = new WorkletLoadContext(mHandlerRef);
|
||||||
|
|
||||||
// Part of Step 2. This sets the Top-level flag to true
|
// Part of Step 2. This sets the Top-level flag to true
|
||||||
|
@ -297,7 +304,8 @@ already_AddRefed<Promise> WorkletFetchHandler::AddModule(
|
||||||
// Step 1.4. Let referrerSource be document’s URL.
|
// Step 1.4. Let referrerSource be document’s URL.
|
||||||
nsIURI* referrer = doc->GetDocumentURIAsReferrer();
|
nsIURI* referrer = doc->GetDocumentURIAsReferrer();
|
||||||
nsCOMPtr<nsIRunnable> runnable = new StartModuleLoadRunnable(
|
nsCOMPtr<nsIRunnable> runnable = new StartModuleLoadRunnable(
|
||||||
aWorklet->mImpl, handlerRef, std::move(resolvedURI), referrer);
|
aWorklet->mImpl, handlerRef, std::move(resolvedURI), referrer,
|
||||||
|
aWorklet->GetLocalizedStrings());
|
||||||
|
|
||||||
if (NS_FAILED(aWorklet->mImpl->SendControlMessage(runnable.forget()))) {
|
if (NS_FAILED(aWorklet->mImpl->SendControlMessage(runnable.forget()))) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
|
@ -12,8 +12,10 @@
|
||||||
#include "mozilla/ScopeExit.h"
|
#include "mozilla/ScopeExit.h"
|
||||||
#include "mozilla/dom/Worklet.h"
|
#include "mozilla/dom/Worklet.h"
|
||||||
#include "mozilla/dom/WorkletFetchHandler.h"
|
#include "mozilla/dom/WorkletFetchHandler.h"
|
||||||
|
#include "nsStringBundle.h"
|
||||||
|
|
||||||
using JS::loader::ModuleLoadRequest;
|
using JS::loader::ModuleLoadRequest;
|
||||||
|
using JS::loader::ResolveError;
|
||||||
|
|
||||||
namespace mozilla::dom::loader {
|
namespace mozilla::dom::loader {
|
||||||
|
|
||||||
|
@ -188,6 +190,26 @@ void WorkletModuleLoader::OnModuleLoadComplete(ModuleLoadRequest* aRequest) {
|
||||||
NS_DispatchToMainThread(runnable.forget());
|
NS_DispatchToMainThread(runnable.forget());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Bug 1808301: Call FormatLocalizedString from a worklet thread.
|
||||||
|
nsresult WorkletModuleLoader::GetResolveFailureMessage(
|
||||||
|
ResolveError aError, const nsAString& aSpecifier, nsAString& aResult) {
|
||||||
|
uint8_t index = static_cast<uint8_t>(aError);
|
||||||
|
MOZ_ASSERT(index < static_cast<uint8_t>(ResolveError::Length));
|
||||||
|
MOZ_ASSERT(mLocalizedStrs);
|
||||||
|
MOZ_ASSERT(!mLocalizedStrs->IsEmpty());
|
||||||
|
if (!mLocalizedStrs || NS_WARN_IF(mLocalizedStrs->IsEmpty())) {
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
const nsString& localizedStr = mLocalizedStrs->ElementAt(index);
|
||||||
|
|
||||||
|
AutoTArray<nsString, 1> params;
|
||||||
|
params.AppendElement(aSpecifier);
|
||||||
|
|
||||||
|
nsStringBundleBase::FormatString(localizedStr.get(), params, aResult);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
void WorkletModuleLoader::InsertRequest(nsIURI* aURI,
|
void WorkletModuleLoader::InsertRequest(nsIURI* aURI,
|
||||||
ModuleLoadRequest* aRequest) {
|
ModuleLoadRequest* aRequest) {
|
||||||
mFetchingRequests.InsertOrUpdate(aURI, aRequest);
|
mFetchingRequests.InsertOrUpdate(aURI, aRequest);
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
#include "js/loader/LoadContextBase.h"
|
#include "js/loader/LoadContextBase.h"
|
||||||
#include "js/loader/ModuleLoaderBase.h"
|
#include "js/loader/ModuleLoaderBase.h"
|
||||||
|
#include "js/loader/ResolveResult.h" // For ResolveError
|
||||||
#include "mozilla/dom/WorkletFetchHandler.h"
|
#include "mozilla/dom/WorkletFetchHandler.h"
|
||||||
|
|
||||||
namespace mozilla::dom {
|
namespace mozilla::dom {
|
||||||
|
@ -54,6 +55,11 @@ class WorkletModuleLoader : public JS::loader::ModuleLoaderBase {
|
||||||
void RemoveRequest(nsIURI* aURI);
|
void RemoveRequest(nsIURI* aURI);
|
||||||
JS::loader::ModuleLoadRequest* GetRequest(nsIURI* aURI) const;
|
JS::loader::ModuleLoadRequest* GetRequest(nsIURI* aURI) const;
|
||||||
|
|
||||||
|
bool HasSetLocalizedStrings() const { return (bool)mLocalizedStrs; }
|
||||||
|
void SetLocalizedStrings(const nsTArray<nsString>* aStrings) {
|
||||||
|
mLocalizedStrs = aStrings;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
~WorkletModuleLoader() = default;
|
~WorkletModuleLoader() = default;
|
||||||
|
|
||||||
|
@ -78,10 +84,18 @@ class WorkletModuleLoader : public JS::loader::ModuleLoaderBase {
|
||||||
|
|
||||||
void OnModuleLoadComplete(JS::loader::ModuleLoadRequest* aRequest) override;
|
void OnModuleLoadComplete(JS::loader::ModuleLoadRequest* aRequest) override;
|
||||||
|
|
||||||
|
nsresult GetResolveFailureMessage(JS::loader::ResolveError aError,
|
||||||
|
const nsAString& aSpecifier,
|
||||||
|
nsAString& aResult) override;
|
||||||
|
|
||||||
// A hashtable to map a nsIURI(from main thread) to a ModuleLoadRequest(in
|
// A hashtable to map a nsIURI(from main thread) to a ModuleLoadRequest(in
|
||||||
// worklet thread).
|
// worklet thread).
|
||||||
nsRefPtrHashtable<nsURIHashKey, JS::loader::ModuleLoadRequest>
|
nsRefPtrHashtable<nsURIHashKey, JS::loader::ModuleLoadRequest>
|
||||||
mFetchingRequests;
|
mFetchingRequests;
|
||||||
|
|
||||||
|
// We get the localized strings on the main thread, and pass it to
|
||||||
|
// WorkletModuleLoader.
|
||||||
|
const nsTArray<nsString>* mLocalizedStrs = nullptr;
|
||||||
};
|
};
|
||||||
} // namespace loader
|
} // namespace loader
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,8 @@ enum class ResolveError : uint8_t {
|
||||||
BlockedByNullEntry,
|
BlockedByNullEntry,
|
||||||
BlockedByAfterPrefix,
|
BlockedByAfterPrefix,
|
||||||
BlockedByBacktrackingPrefix,
|
BlockedByBacktrackingPrefix,
|
||||||
InvalidBareSpecifier
|
InvalidBareSpecifier,
|
||||||
|
Length
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ResolveErrorInfo {
|
struct ResolveErrorInfo {
|
||||||
|
|
Загрузка…
Ссылка в новой задаче