Bug 1161413 - Part 1: Create FontFaceSet with a document rather than a pres context. r=jdaggett

This commit is contained in:
Cameron McCormack 2015-06-27 11:39:54 +10:00
parent 9041635577
commit c05d48f6d0
3 changed files with 70 additions and 65 deletions

View File

@ -2177,7 +2177,7 @@ nsPresContext::FlushUserFontSet()
bool changed = false;
if (!mFontFaceSet && !rules.IsEmpty()) {
mFontFaceSet = new FontFaceSet(mDocument->GetInnerWindow(), this);
mFontFaceSet = new FontFaceSet(mDocument->GetInnerWindow(), mDocument);
}
if (mFontFaceSet) {
changed = mFontFaceSet->UpdateRules(rules);
@ -2274,7 +2274,7 @@ FontFaceSet*
nsPresContext::Fonts()
{
if (!mFontFaceSet) {
mFontFaceSet = new FontFaceSet(mDocument->GetInnerWindow(), this);
mFontFaceSet = new FontFaceSet(mDocument->GetInnerWindow(), mDocument);
GetUserFontSet(); // this will cause the user font set to be created/updated
}
return mFontFaceSet;

View File

@ -83,10 +83,9 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(FontFaceSet)
NS_INTERFACE_MAP_ENTRY(nsICSSLoaderObserver)
NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
FontFaceSet::FontFaceSet(nsPIDOMWindow* aWindow, nsPresContext* aPresContext)
FontFaceSet::FontFaceSet(nsPIDOMWindow* aWindow, nsIDocument* aDocument)
: DOMEventTargetHelper(aWindow)
, mPresContext(aPresContext)
, mDocument(aPresContext->Document())
, mDocument(aDocument)
, mStatus(FontFaceSetLoadStatus::Loaded)
, mNonRuleFacesDirty(false)
, mHasLoadingFontFaces(false)
@ -182,14 +181,14 @@ FontFaceSet::GetReady(ErrorResult& aRv)
return nullptr;
}
mPresContext->FlushUserFontSet();
FlushUserFontSet();
return mReady;
}
FontFaceSetLoadStatus
FontFaceSet::Status()
{
mPresContext->FlushUserFontSet();
FlushUserFontSet();
return mStatus;
}
@ -209,7 +208,7 @@ FontFaceSet::HasRuleFontFace(FontFace* aFontFace)
FontFaceSet*
FontFaceSet::Add(FontFace& aFontFace, ErrorResult& aRv)
{
mPresContext->FlushUserFontSet();
FlushUserFontSet();
// We currently only support FontFace objects being in a single FontFaceSet,
// and we also restrict the FontFaceSet to contain only FontFaces created
@ -250,7 +249,7 @@ FontFaceSet::Add(FontFace& aFontFace, ErrorResult& aRv)
aFontFace.Status() == FontFaceLoadStatus::Loading;
mNonRuleFacesDirty = true;
mPresContext->RebuildUserFontSet();
RebuildUserFontSet();
mHasLoadingFontFacesIsDirty = true;
CheckLoadingStarted();
return this;
@ -259,7 +258,7 @@ FontFaceSet::Add(FontFace& aFontFace, ErrorResult& aRv)
void
FontFaceSet::Clear()
{
mPresContext->FlushUserFontSet();
FlushUserFontSet();
if (mNonRuleFaces.IsEmpty()) {
return;
@ -277,7 +276,7 @@ FontFaceSet::Clear()
mNonRuleFaces.Clear();
mNonRuleFacesDirty = true;
mPresContext->RebuildUserFontSet();
RebuildUserFontSet();
mHasLoadingFontFacesIsDirty = true;
CheckLoadingFinished();
}
@ -285,7 +284,7 @@ FontFaceSet::Clear()
bool
FontFaceSet::Delete(FontFace& aFontFace)
{
mPresContext->FlushUserFontSet();
FlushUserFontSet();
if (aFontFace.HasRule()) {
return false;
@ -311,7 +310,7 @@ FontFaceSet::Delete(FontFace& aFontFace)
mUnavailableFaces.AppendElement(&aFontFace);
mNonRuleFacesDirty = true;
mPresContext->RebuildUserFontSet();
RebuildUserFontSet();
mHasLoadingFontFacesIsDirty = true;
CheckLoadingFinished();
return true;
@ -327,7 +326,7 @@ FontFaceSet::HasAvailableFontFace(FontFace* aFontFace)
bool
FontFaceSet::Has(FontFace& aFontFace)
{
mPresContext->FlushUserFontSet();
FlushUserFontSet();
return HasAvailableFontFace(&aFontFace);
}
@ -335,7 +334,7 @@ FontFaceSet::Has(FontFace& aFontFace)
FontFace*
FontFaceSet::GetFontFaceAt(uint32_t aIndex)
{
mPresContext->FlushUserFontSet();
FlushUserFontSet();
if (aIndex < mRuleFaces.Length()) {
return mRuleFaces[aIndex].mFontFace;
@ -352,7 +351,7 @@ FontFaceSet::GetFontFaceAt(uint32_t aIndex)
uint32_t
FontFaceSet::Size()
{
mPresContext->FlushUserFontSet();
FlushUserFontSet();
// Web IDL objects can only expose array index properties up to INT32_MAX.
@ -400,7 +399,6 @@ FontFaceSet::DestroyUserFontSet()
{
Disconnect();
mDocument = nullptr;
mPresContext = nullptr;
mLoaders.EnumerateEntries(DestroyIterator, nullptr);
for (size_t i = 0; i < mRuleFaces.Length(); i++) {
mRuleFaces[i].mFontFace->DisconnectFromRule();
@ -434,12 +432,8 @@ FontFaceSet::StartLoad(gfxUserFontEntry* aUserFontEntry,
{
nsresult rv;
nsIPresShell* ps = mPresContext->PresShell();
if (!ps)
return NS_ERROR_FAILURE;
nsCOMPtr<nsIStreamLoader> streamLoader;
nsCOMPtr<nsILoadGroup> loadGroup(ps->GetDocument()->GetDocumentLoadGroup());
nsCOMPtr<nsILoadGroup> loadGroup(mDocument->GetDocumentLoadGroup());
nsCOMPtr<nsIChannel> channel;
// Note we are calling NS_NewChannelWithTriggeringPrincipal() with both a
@ -448,7 +442,7 @@ FontFaceSet::StartLoad(gfxUserFontEntry* aUserFontEntry,
// stylesheet that initiated the font load.
rv = NS_NewChannelWithTriggeringPrincipal(getter_AddRefs(channel),
aFontFaceSrc->mURI,
ps->GetDocument(),
mDocument,
aUserFontEntry->GetPrincipal(),
nsILoadInfo::SEC_NORMAL,
nsIContentPolicy::TYPE_FONT,
@ -472,7 +466,7 @@ FontFaceSet::StartLoad(gfxUserFontEntry* aUserFontEntry,
nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(channel));
if (httpChannel) {
httpChannel->SetReferrerWithPolicy(aFontFaceSrc->mReferrer,
ps->GetDocument()->GetReferrerPolicy());
mDocument->GetReferrerPolicy());
nsAutoCString accept("application/font-woff;q=0.9,*/*;q=0.8");
if (Preferences::GetBool(GFX_PREF_WOFF2_ENABLED)) {
accept.Insert(NS_LITERAL_CSTRING("application/font-woff2;q=1.0,"), 0);
@ -495,8 +489,7 @@ FontFaceSet::StartLoad(gfxUserFontEntry* aUserFontEntry,
rv = NS_NewStreamLoader(getter_AddRefs(streamLoader), fontLoader);
NS_ENSURE_SUCCESS(rv, rv);
nsIDocument *document = ps->GetDocument();
mozilla::net::PredictorLearn(aFontFaceSrc->mURI, document->GetDocumentURI(),
mozilla::net::PredictorLearn(aFontFaceSrc->mURI, mDocument->GetDocumentURI(),
nsINetworkPredictor::LEARN_LOAD_SUBRESOURCE,
loadGroup);
@ -1148,7 +1141,7 @@ FontFaceSet::LogMessage(gfxUserFontEntry* aUserFontEntry,
do_CreateInstance(NS_SCRIPTERROR_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
uint64_t innerWindowID = GetPresContext()->Document()->InnerWindowID();
uint64_t innerWindowID = mDocument->InnerWindowID();
rv = scriptError->InitWithWindowID(NS_ConvertUTF8toUTF16(message),
href, // file
text, // src line
@ -1169,14 +1162,12 @@ FontFaceSet::CheckFontLoad(const gfxFontFaceSrc* aFontFaceSrc,
nsIPrincipal** aPrincipal,
bool* aBypassCache)
{
// check same-site origin
nsIPresShell* ps = mPresContext->PresShell();
if (!ps)
return NS_ERROR_FAILURE;
NS_ASSERTION(aFontFaceSrc &&
aFontFaceSrc->mSourceType == gfxFontFaceSrc::eSourceType_URL,
"bad font face url passed to fontloader");
// check same-site origin
NS_ASSERTION(aFontFaceSrc->mURI, "null font uri");
if (!aFontFaceSrc->mURI)
return NS_ERROR_FAILURE;
@ -1184,7 +1175,7 @@ FontFaceSet::CheckFontLoad(const gfxFontFaceSrc* aFontFaceSrc,
// use document principal, original principal if flag set
// this enables user stylesheets to load font files via
// @font-face rules
*aPrincipal = ps->GetDocument()->NodePrincipal();
*aPrincipal = mDocument->NodePrincipal();
NS_ASSERTION(aFontFaceSrc->mOriginPrincipal,
"null origin principal in @font-face rule");
@ -1194,14 +1185,14 @@ FontFaceSet::CheckFontLoad(const gfxFontFaceSrc* aFontFaceSrc,
nsresult rv = nsFontFaceLoader::CheckLoadAllowed(*aPrincipal,
aFontFaceSrc->mURI,
ps->GetDocument());
mDocument);
if (NS_FAILED(rv)) {
return rv;
}
*aBypassCache = false;
nsCOMPtr<nsIDocShell> docShell = ps->GetDocument()->GetDocShell();
nsCOMPtr<nsIDocShell> docShell = mDocument->GetDocShell();
if (docShell) {
uint32_t loadType;
if (NS_SUCCEEDED(docShell->GetLoadType(&loadType))) {
@ -1223,17 +1214,13 @@ FontFaceSet::SyncLoadFontData(gfxUserFontEntry* aFontToLoad,
nsresult rv;
nsCOMPtr<nsIChannel> channel;
nsIPresShell* ps = mPresContext->PresShell();
if (!ps) {
return NS_ERROR_FAILURE;
}
// Note we are calling NS_NewChannelWithTriggeringPrincipal() with both a
// node and a principal. This is because the document where the font is
// being loaded might have a different origin from the principal of the
// stylesheet that initiated the font load.
rv = NS_NewChannelWithTriggeringPrincipal(getter_AddRefs(channel),
aFontFaceSrc->mURI,
ps->GetDocument(),
mDocument,
aFontToLoad->GetPrincipal(),
nsILoadInfo::SEC_NORMAL,
nsIContentPolicy::TYPE_FONT);
@ -1296,28 +1283,10 @@ FontFaceSet::SyncLoadFontData(gfxUserFontEntry* aFontToLoad,
bool
FontFaceSet::GetPrivateBrowsing()
{
nsIPresShell* ps = mPresContext->PresShell();
if (!ps) {
return false;
}
nsCOMPtr<nsILoadContext> loadContext = ps->GetDocument()->GetLoadContext();
nsCOMPtr<nsILoadContext> loadContext = mDocument->GetLoadContext();
return loadContext && loadContext->UsePrivateBrowsing();
}
void
FontFaceSet::DoRebuildUserFontSet()
{
if (!mPresContext) {
// AFAICS, this can only happen if someone has already called Destroy() on
// this font-set, which means it is in the process of being torn down --
// so there's no point trying to update its rules.
return;
}
mPresContext->RebuildUserFontSet();
}
void
FontFaceSet::AddUnavailableFontFace(FontFace* aFontFace)
{
@ -1452,7 +1421,8 @@ FontFaceSet::MightHavePendingFontLoads()
// Check for pending restyles or reflows, as they might cause fonts to
// load as new styles apply and text runs are rebuilt.
if (mPresContext && mPresContext->HasPendingRestyleOrReflow()) {
nsPresContext* presContext = GetPresContext();
if (presContext && presContext->HasPendingRestyleOrReflow()) {
return true;
}
@ -1595,6 +1565,40 @@ FontFaceSet::StyleSheetLoaded(mozilla::CSSStyleSheet* aSheet,
return NS_OK;
}
void
FontFaceSet::FlushUserFontSet()
{
nsPresContext* presContext = GetPresContext();
if (presContext) {
presContext->FlushUserFontSet();
}
}
void
FontFaceSet::RebuildUserFontSet()
{
nsPresContext* presContext = GetPresContext();
if (!presContext) {
// AFAICS, this can only happen if someone has already called Destroy() on
// this font-set, which means it is in the process of being torn down --
// so there's no point trying to update its rules.
return;
}
presContext->RebuildUserFontSet();
}
nsPresContext*
FontFaceSet::GetPresContext()
{
if (!mDocument) {
return nullptr;
}
nsIPresShell* shell = mDocument->GetShell();
return shell ? shell->GetPresContext() : nullptr;
}
// -- FontFaceSet::UserFontSet ------------------------------------------------
/* virtual */ nsresult
@ -1655,7 +1659,7 @@ FontFaceSet::UserFontSet::DoRebuildUserFontSet()
if (!mFontFaceSet) {
return;
}
mFontFaceSet->DoRebuildUserFontSet();
mFontFaceSet->RebuildUserFontSet();
}
/* virtual */ already_AddRefed<gfxUserFontEntry>

View File

@ -93,7 +93,7 @@ public:
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(FontFaceSet, DOMEventTargetHelper)
NS_DECL_NSIDOMEVENTLISTENER
FontFaceSet(nsPIDOMWindow* aWindow, nsPresContext* aPresContext);
FontFaceSet(nsPIDOMWindow* aWindow, nsIDocument* aDocument);
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
@ -108,7 +108,7 @@ public:
bool UpdateRules(const nsTArray<nsFontFaceRuleContainer>& aRules);
nsPresContext* GetPresContext() { return mPresContext; }
nsPresContext* GetPresContext();
// search for @font-face rule that matches a platform font entry
nsCSSFontFaceRule* FindRuleForEntry(gfxFontEntry* aFontEntry);
@ -159,6 +159,8 @@ public:
FontFace* GetFontFaceAt(uint32_t aIndex);
void FlushUserFontSet();
// -- Web IDL --------------------------------------------------------------
IMPL_EVENT_HANDLER(loading)
@ -265,7 +267,7 @@ private:
const char* aMessage,
uint32_t aFlags,
nsresult aStatus);
void DoRebuildUserFontSet();
void RebuildUserFontSet();
void InsertRuleFontFace(FontFace* aFontFace, uint8_t aSheetType,
nsTArray<FontFaceRecord>& aOldRecords,
@ -285,7 +287,6 @@ private:
void UpdateHasLoadingFontFaces();
nsRefPtr<UserFontSet> mUserFontSet;
nsPresContext* mPresContext;
// The document this is a FontFaceSet for.
nsCOMPtr<nsIDocument> mDocument;