mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-07 18:04:46 +00:00
Bug 1309867 - Part 2: Lazily create FontFace::mLoaded; r=heycam
This commit is contained in:
parent
97a4ddfbdf
commit
9fd5d0bea3
@ -101,6 +101,7 @@ NS_IMPL_CYCLE_COLLECTING_RELEASE(FontFace)
|
||||
|
||||
FontFace::FontFace(nsISupports* aParent, FontFaceSet* aFontFaceSet)
|
||||
: mParent(aParent)
|
||||
, mLoadedRejection(NS_OK)
|
||||
, mStatus(FontFaceLoadStatus::Unloaded)
|
||||
, mSourceType(SourceType(0))
|
||||
, mSourceBuffer(nullptr)
|
||||
@ -109,16 +110,6 @@ FontFace::FontFace(nsISupports* aParent, FontFaceSet* aFontFaceSet)
|
||||
, mInFontFaceSet(false)
|
||||
{
|
||||
MOZ_COUNT_CTOR(FontFace);
|
||||
|
||||
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aParent);
|
||||
|
||||
// If the pref is not set, don't create the Promise (which the page wouldn't
|
||||
// be able to get to anyway) as it causes the window.FontFace constructor
|
||||
// to be created.
|
||||
if (global && FontFaceSet::PrefEnabled()) {
|
||||
ErrorResult rv;
|
||||
mLoaded = Promise::Create(global, rv);
|
||||
}
|
||||
}
|
||||
|
||||
FontFace::~FontFace()
|
||||
@ -198,13 +189,7 @@ FontFace::InitializeSource(const StringOrArrayBufferOrArrayBufferView& aSource)
|
||||
if (!ParseDescriptor(eCSSFontDesc_Src,
|
||||
aSource.GetAsString(),
|
||||
mDescriptors->mSrc)) {
|
||||
if (mLoaded) {
|
||||
// The SetStatus call we are about to do assumes that for
|
||||
// FontFace objects with sources other than ArrayBuffer(View)s, that the
|
||||
// mLoaded Promise is rejected with a network error. We get
|
||||
// in here beforehand to set it to the required syntax error.
|
||||
mLoaded->MaybeReject(NS_ERROR_DOM_SYNTAX_ERR);
|
||||
}
|
||||
Reject(NS_ERROR_DOM_SYNTAX_ERR);
|
||||
|
||||
SetStatus(FontFaceLoadStatus::Error);
|
||||
return;
|
||||
@ -378,6 +363,8 @@ FontFace::Load(ErrorResult& aRv)
|
||||
{
|
||||
mFontFaceSet->FlushUserFontSet();
|
||||
|
||||
EnsurePromise();
|
||||
|
||||
if (!mLoaded) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return nullptr;
|
||||
@ -433,6 +420,8 @@ FontFace::GetLoaded(ErrorResult& aRv)
|
||||
{
|
||||
mFontFaceSet->FlushUserFontSet();
|
||||
|
||||
EnsurePromise();
|
||||
|
||||
if (!mLoaded) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return nullptr;
|
||||
@ -467,17 +456,15 @@ FontFace::SetStatus(FontFaceLoadStatus aStatus)
|
||||
otherSet->OnFontFaceStatusChanged(this);
|
||||
}
|
||||
|
||||
if (!mLoaded) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mStatus == FontFaceLoadStatus::Loaded) {
|
||||
mLoaded->MaybeResolve(this);
|
||||
if (mLoaded) {
|
||||
mLoaded->MaybeResolve(this);
|
||||
}
|
||||
} else if (mStatus == FontFaceLoadStatus::Error) {
|
||||
if (mSourceType == eSourceType_Buffer) {
|
||||
mLoaded->MaybeReject(NS_ERROR_DOM_SYNTAX_ERR);
|
||||
Reject(NS_ERROR_DOM_SYNTAX_ERR);
|
||||
} else {
|
||||
mLoaded->MaybeReject(NS_ERROR_DOM_NETWORK_ERR);
|
||||
Reject(NS_ERROR_DOM_NETWORK_ERR);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -570,9 +557,7 @@ FontFace::SetDescriptors(const nsAString& aFamily,
|
||||
// on the FontFace.
|
||||
mDescriptors = new CSSFontFaceDescriptors;
|
||||
|
||||
if (mLoaded) {
|
||||
mLoaded->MaybeReject(NS_ERROR_DOM_SYNTAX_ERR);
|
||||
}
|
||||
Reject(NS_ERROR_DOM_SYNTAX_ERR);
|
||||
|
||||
SetStatus(FontFaceLoadStatus::Error);
|
||||
return false;
|
||||
@ -748,6 +733,40 @@ FontFace::RemoveFontFaceSet(FontFaceSet* aFontFaceSet)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
FontFace::Reject(nsresult aResult)
|
||||
{
|
||||
if (mLoaded) {
|
||||
mLoaded->MaybeReject(aResult);
|
||||
} else if (mLoadedRejection == NS_OK) {
|
||||
mLoadedRejection = aResult;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
FontFace::EnsurePromise()
|
||||
{
|
||||
if (mLoaded) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(mParent);
|
||||
|
||||
// If the pref is not set, don't create the Promise (which the page wouldn't
|
||||
// be able to get to anyway) as it causes the window.FontFace constructor
|
||||
// to be created.
|
||||
if (global && FontFaceSet::PrefEnabled()) {
|
||||
ErrorResult rv;
|
||||
mLoaded = Promise::Create(global, rv);
|
||||
|
||||
if (mStatus == FontFaceLoadStatus::Loaded) {
|
||||
mLoaded->MaybeResolve(this);
|
||||
} else if (mLoadedRejection != NS_OK) {
|
||||
mLoaded->MaybeReject(mLoadedRejection);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -- FontFace::Entry --------------------------------------------------------
|
||||
|
||||
/* virtual */ void
|
||||
|
@ -199,12 +199,24 @@ private:
|
||||
*/
|
||||
void TakeBuffer(uint8_t*& aBuffer, uint32_t& aLength);
|
||||
|
||||
// Acts like mLoaded->MaybeReject(aResult), except it doesn't create mLoaded
|
||||
// if it doesn't already exist.
|
||||
void Reject(nsresult aResult);
|
||||
|
||||
// Creates mLoaded if it doesn't already exist. It may immediately resolve or
|
||||
// reject mLoaded based on mStatus and mLoadedRejection.
|
||||
void EnsurePromise();
|
||||
|
||||
nsCOMPtr<nsISupports> mParent;
|
||||
|
||||
// A Promise that is fulfilled once the font represented by this FontFace
|
||||
// is loaded, and is rejected if the load fails.
|
||||
// A Promise that is fulfilled once the font represented by this FontFace is
|
||||
// loaded, and is rejected if the load fails. This promise is created lazily
|
||||
// when JS asks for it.
|
||||
RefPtr<mozilla::dom::Promise> mLoaded;
|
||||
|
||||
// Saves the rejection code for mLoaded if mLoaded hasn't been created yet.
|
||||
nsresult mLoadedRejection;
|
||||
|
||||
// The @font-face rule this FontFace object is reflecting, if it is a
|
||||
// rule backed FontFace.
|
||||
RefPtr<nsCSSFontFaceRule> mRule;
|
||||
|
Loading…
Reference in New Issue
Block a user