Bug 1542807 part 4 - Exclude fonts loaded from User and UserAgent origin sheets from 'document.fonts'. r=jfkthame

Per https://github.com/w3c/csswg-drafts/issues/6126 these were
never intended to be included in the first place so this is just
fixing a bug.  Note that I'm leaving them in the mRuleFaces array
so that the font loading machinery works the same as before.
I'm just excluding them when queried by document.fonts.

Differential Revision: https://phabricator.services.mozilla.com/D111694
This commit is contained in:
Mats Palmgren 2021-06-14 01:22:06 +00:00
parent e4d7dd995a
commit 14bc280a27
3 changed files with 50 additions and 5 deletions

View File

@ -518,7 +518,11 @@ FontFace* FontFaceSet::GetFontFaceAt(uint32_t aIndex) {
FlushUserFontSet();
if (aIndex < mRuleFaces.Length()) {
return mRuleFaces[aIndex].mFontFace;
auto& entry = mRuleFaces[aIndex];
if (entry.mOrigin.value() != StyleOrigin::Author) {
return nullptr;
}
return entry.mFontFace;
}
aIndex -= mRuleFaces.Length();
@ -534,6 +538,20 @@ uint32_t FontFaceSet::Size() {
// Web IDL objects can only expose array index properties up to INT32_MAX.
size_t total = mNonRuleFaces.Length();
for (const auto& entry : mRuleFaces) {
if (entry.mOrigin.value() == StyleOrigin::Author) {
++total;
}
}
return std::min<size_t>(total, INT32_MAX);
}
uint32_t FontFaceSet::SizeIncludingNonAuthorOrigins() {
FlushUserFontSet();
// Web IDL objects can only expose array index properties up to INT32_MAX.
size_t total = mRuleFaces.Length() + mNonRuleFaces.Length();
return std::min<size_t>(total, INT32_MAX);
}
@ -551,8 +569,13 @@ already_AddRefed<FontFaceSetIterator> FontFaceSet::Values() {
void FontFaceSet::ForEach(JSContext* aCx, FontFaceSetForEachCallback& aCallback,
JS::Handle<JS::Value> aThisArg, ErrorResult& aRv) {
JS::Rooted<JS::Value> thisArg(aCx, aThisArg);
for (size_t i = 0; i < Size(); i++) {
for (size_t i = 0; i < SizeIncludingNonAuthorOrigins(); i++) {
RefPtr<FontFace> face = GetFontFaceAt(i);
if (!face) {
// The font at index |i| is a non-Author origin font, which we shouldn't
// expose per spec.
continue;
}
aCallback.Call(thisArg, *face, *face, *this, aRv);
if (aRv.Failed()) {
return;

View File

@ -158,8 +158,6 @@ class FontFaceSet final : public DOMEventTargetHelper,
NS_IMETHOD StyleSheetLoaded(StyleSheet* aSheet, bool aWasDeferred,
nsresult aStatus) override;
FontFace* GetFontFaceAt(uint32_t aIndex);
void FlushUserFontSet();
static nsPresContext* GetPresContextFor(gfxUserFontSet* aUserFontSet) {
@ -188,6 +186,10 @@ class FontFaceSet final : public DOMEventTargetHelper,
void Clear();
bool Delete(FontFace& aFontFace);
bool Has(FontFace& aFontFace);
/**
* This returns the number of Author origin fonts only.
* (see also SizeIncludingNonAuthorOrigins() below)
*/
uint32_t Size();
already_AddRefed<dom::FontFaceSetIterator> Entries();
already_AddRefed<dom::FontFaceSetIterator> Values();
@ -200,7 +202,14 @@ class FontFaceSet final : public DOMEventTargetHelper,
void MarkUserFontSetDirty();
/**
* Unlike Size(), this returns the size including non-Author origin fonts.
*/
uint32_t SizeIncludingNonAuthorOrigins();
private:
friend mozilla::dom::FontFaceSetIterator; // needs GetFontFaceAt()
~FontFaceSet();
/**
@ -239,6 +248,12 @@ class FontFaceSet final : public DOMEventTargetHelper,
*/
void CheckLoadingFinishedAfterDelay();
/**
* Returns the font at aIndex if it's an Author origin font, or nullptr
* otherwise.
*/
FontFace* GetFontFaceAt(uint32_t aIndex);
/**
* Dispatches a FontFaceSetLoadEvent to this object.
*/

View File

@ -42,7 +42,14 @@ void FontFaceSetIterator::Next(JSContext* aCx,
return;
}
FontFace* face = mFontFaceSet->GetFontFaceAt(mNextIndex++);
// Skip over non-Author origin fonts (GetFontFaceAt returns nullptr
// for those).
FontFace* face;
while (!(face = mFontFaceSet->GetFontFaceAt(mNextIndex++))) {
if (mNextIndex >= mFontFaceSet->SizeIncludingNonAuthorOrigins()) {
break; // this iterator is done
}
}
if (!face) {
aResult.mValue.setUndefined();