Created
January 17, 2019 18:29
-
-
Save zbraniecki/b9128f3ac439321da7b5e4581fb650f3 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| diff --git a/dom/base/Document.cpp b/dom/base/Document.cpp | |
| --- a/dom/base/Document.cpp | |
| +++ b/dom/base/Document.cpp | |
| @@ -1337,7 +1337,8 @@ Document::Document(const char* aContentT | |
| mThrowOnDynamicMarkupInsertionCounter(0), | |
| mIgnoreOpensDuringUnloadCounter(0), | |
| mDocLWTheme(Doc_Theme_Uninitialized), | |
| - mSavedResolution(1.0f) { | |
| + mSavedResolution(1.0f), | |
| + mPendingInitialTranslation(false) { | |
| MOZ_LOG(gDocumentLeakPRLog, LogLevel::Debug, ("DOCUMENT %p created", this)); | |
| SetIsInDocument(); | |
| @@ -3127,6 +3128,9 @@ void Document::LocalizationLinkAdded(Ele | |
| // will be resolved once the end of l10n resource | |
| // container is reached. | |
| mL10nResources.AppendElement(href); | |
| + | |
| + //printf("In Document::LocalizationLinkAdded, setting mPendingInitialTranslation to true.\n"); | |
| + mPendingInitialTranslation = true; | |
| } | |
| } | |
| @@ -3174,6 +3178,21 @@ void Document::TriggerInitialDocumentTra | |
| } | |
| } | |
| +void Document::InitialDocumentTranslationCompleted() { | |
| + //printf("Document::InitialDocumentTranslationCompleted.\n"); | |
| + mPendingInitialTranslation = false; | |
| + | |
| + nsCOMPtr<nsIContentSink> sink; | |
| + if (mParser) { | |
| + sink = mParser->GetContentSink(); | |
| + } else { | |
| + sink = do_QueryReferent(mWeakSink); | |
| + } | |
| + if (sink) { | |
| + sink->InitialDocumentTranslationCompleted(); | |
| + } | |
| +} | |
| + | |
| bool Document::IsWebAnimationsEnabled(JSContext* aCx, JSObject* /*unused*/) { | |
| MOZ_ASSERT(NS_IsMainThread()); | |
| @@ -8136,7 +8155,6 @@ void Document::SetReadyStateInternal(Rea | |
| mXULPersist->Init(); | |
| } | |
| } | |
| - TriggerInitialDocumentTranslation(); | |
| } | |
| RecordNavigationTiming(rs); | |
| diff --git a/dom/base/Document.h b/dom/base/Document.h | |
| --- a/dom/base/Document.h | |
| +++ b/dom/base/Document.h | |
| @@ -3394,7 +3394,6 @@ class Document : public nsINode, | |
| */ | |
| void LocalizationLinkRemoved(Element* aLinkElement); | |
| - protected: | |
| /** | |
| * This method should be collect as soon as the | |
| * parsing of the document is completed. | |
| @@ -3409,6 +3408,9 @@ class Document : public nsINode, | |
| */ | |
| void TriggerInitialDocumentTranslation(); | |
| + virtual void InitialDocumentTranslationCompleted(); | |
| + | |
| + protected: | |
| RefPtr<mozilla::dom::DocumentL10n> mDocumentL10n; | |
| private: | |
| @@ -4440,9 +4442,13 @@ class Document : public nsINode, | |
| // Pres shell resolution saved before entering fullscreen mode. | |
| float mSavedResolution; | |
| + bool mPendingInitialTranslation; | |
| + | |
| public: | |
| // Needs to be public because the bindings code pokes at it. | |
| js::ExpandoAndGeneration mExpandoAndGeneration; | |
| + | |
| + bool HasPendingInitialTranslation() { return mPendingInitialTranslation; } | |
| }; | |
| NS_DEFINE_STATIC_IID_ACCESSOR(Document, NS_IDOCUMENT_IID) | |
| diff --git a/dom/base/nsContentSink.cpp b/dom/base/nsContentSink.cpp | |
| --- a/dom/base/nsContentSink.cpp | |
| +++ b/dom/base/nsContentSink.cpp | |
| @@ -1170,8 +1170,10 @@ void nsContentSink::StartLayout(bool aIg | |
| mDeferredLayoutStart = true; | |
| - if (!aIgnorePendingSheets && WaitForPendingSheets()) { | |
| - // Bail out; we'll start layout when the sheets load | |
| + if (!aIgnorePendingSheets && | |
| + (WaitForPendingSheets() || | |
| + mDocument->HasPendingInitialTranslation())) { | |
| + // Bail out; we'll start layout when the sheets and l10n load | |
| return; | |
| } | |
| diff --git a/dom/xml/nsXMLContentSink.cpp b/dom/xml/nsXMLContentSink.cpp | |
| --- a/dom/xml/nsXMLContentSink.cpp | |
| +++ b/dom/xml/nsXMLContentSink.cpp | |
| @@ -1073,6 +1073,8 @@ nsresult nsXMLContentSink::HandleEndElem | |
| // probably need to deal here.... (and stop appending them on open). | |
| mState = eXMLContentSinkState_InEpilog; | |
| + mDocument->TriggerInitialDocumentTranslation(); | |
| + | |
| // We might have had no occasion to start layout yet. Do so now. | |
| MaybeStartLayout(false); | |
| } | |
| @@ -1407,6 +1409,10 @@ nsresult nsXMLContentSink::AddText(const | |
| return NS_OK; | |
| } | |
| +void nsXMLContentSink::InitialDocumentTranslationCompleted() { | |
| + StartLayout(false); | |
| +} | |
| + | |
| void nsXMLContentSink::FlushPendingNotifications(FlushType aType) { | |
| // Only flush tags if we're not doing the notification ourselves | |
| // (since we aren't reentrant) | |
| diff --git a/dom/xml/nsXMLContentSink.h b/dom/xml/nsXMLContentSink.h | |
| --- a/dom/xml/nsXMLContentSink.h | |
| +++ b/dom/xml/nsXMLContentSink.h | |
| @@ -67,6 +67,7 @@ class nsXMLContentSink : public nsConten | |
| NS_IMETHOD WillInterrupt(void) override; | |
| NS_IMETHOD WillResume(void) override; | |
| NS_IMETHOD SetParser(nsParserBase* aParser) override; | |
| + virtual void InitialDocumentTranslationCompleted() override; | |
| virtual void FlushPendingNotifications(mozilla::FlushType aType) override; | |
| virtual void SetDocumentCharset(NotNull<const Encoding*> aEncoding) override; | |
| virtual nsISupports* GetTarget() override; | |
| diff --git a/dom/xul/XULDocument.cpp b/dom/xul/XULDocument.cpp | |
| --- a/dom/xul/XULDocument.cpp | |
| +++ b/dom/xul/XULDocument.cpp | |
| @@ -449,6 +449,12 @@ void XULDocument::AddElementToDocumentPo | |
| } | |
| } | |
| +void XULDocument::InitialDocumentTranslationCompleted() { | |
| + //printf("XULDocument::InitialDocumentTranslationCompleted.\n"); | |
| + mPendingInitialTranslation = false; | |
| + DoneWalking(); | |
| +} | |
| + | |
| void XULDocument::AddSubtreeToDocument(nsIContent* aContent) { | |
| MOZ_ASSERT(aContent->GetComposedDoc() == this, "Element not in doc!"); | |
| @@ -971,7 +977,17 @@ nsresult XULDocument::DoneWalking() { | |
| // XXXldb This is where we should really be setting the chromehidden | |
| // attribute. | |
| + | |
| if (!mDocumentLoaded) { | |
| + //printf("In XULDocument::DoneWalking.\n"); | |
| + if (mPendingInitialTranslation) { | |
| + //printf("Document::mPendingInitialTranslation is true.\n"); | |
| + TriggerInitialDocumentTranslation(); | |
| + return NS_OK; | |
| + } else { | |
| + //printf("Document::mPendingInitialTranslation is false.\n"); | |
| + } | |
| + | |
| // Make sure we don't reenter here from StartLayout(). Note that | |
| // setting mDocumentLoaded to true here means that if StartLayout() | |
| // causes ResumeWalk() to be reentered, we'll take the other branch of | |
| @@ -983,18 +999,10 @@ nsresult XULDocument::DoneWalking() { | |
| NotifyPossibleTitleChange(false); | |
| - // For performance reasons, we want to trigger the DocumentL10n's | |
| - // `TriggerInitialDocumentTranslation` within the same microtask that will | |
| - // be created for a `MozBeforeInitialXULLayout` event listener. | |
| - AddEventListener(NS_LITERAL_STRING("MozBeforeInitialXULLayout"), | |
| - mDocumentL10n, true, false); | |
| - | |
| nsContentUtils::DispatchTrustedEvent( | |
| this, ToSupports(this), NS_LITERAL_STRING("MozBeforeInitialXULLayout"), | |
| CanBubble::eYes, Cancelable::eNo); | |
| - RemoveEventListener(NS_LITERAL_STRING("MozBeforeInitialXULLayout"), | |
| - mDocumentL10n, true); | |
| // Before starting layout, check whether we're a toplevel chrome | |
| // window. If we are, setup some state so that we don't have to restyle | |
| diff --git a/dom/xul/XULDocument.h b/dom/xul/XULDocument.h | |
| --- a/dom/xul/XULDocument.h | |
| +++ b/dom/xul/XULDocument.h | |
| @@ -76,6 +76,8 @@ class XULDocument final : public XMLDocu | |
| virtual void EndLoad() override; | |
| + virtual void InitialDocumentTranslationCompleted() override; | |
| + | |
| // nsIMutationObserver interface | |
| NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED | |
| NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED | |
| diff --git a/intl/l10n/DocumentL10n.cpp b/intl/l10n/DocumentL10n.cpp | |
| --- a/intl/l10n/DocumentL10n.cpp | |
| +++ b/intl/l10n/DocumentL10n.cpp | |
| @@ -312,13 +312,16 @@ class L10nReadyHandler final : public Pr | |
| NS_DECL_CYCLE_COLLECTING_ISUPPORTS | |
| NS_DECL_CYCLE_COLLECTION_CLASS(L10nReadyHandler) | |
| - explicit L10nReadyHandler(Promise* aPromise) : mPromise(aPromise) {} | |
| + explicit L10nReadyHandler(Promise* aPromise, Document* aDocument) | |
| + : mPromise(aPromise), mDocument(aDocument) {} | |
| void ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue) override { | |
| + mDocument->InitialDocumentTranslationCompleted(); | |
| mPromise->MaybeResolveWithUndefined(); | |
| } | |
| void RejectedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue) override { | |
| + mDocument->InitialDocumentTranslationCompleted(); | |
| mPromise->MaybeRejectWithUndefined(); | |
| } | |
| @@ -326,6 +329,7 @@ class L10nReadyHandler final : public Pr | |
| ~L10nReadyHandler() = default; | |
| RefPtr<Promise> mPromise; | |
| + RefPtr<Document> mDocument; | |
| }; | |
| NS_IMPL_CYCLE_COLLECTION(L10nReadyHandler, mPromise) | |
| @@ -351,7 +355,8 @@ void DocumentL10n::TriggerInitialDocumen | |
| RefPtr<Promise> promise; | |
| mDOMLocalization->TranslateRoots(getter_AddRefs(promise)); | |
| - RefPtr<PromiseNativeHandler> l10nReadyHandler = new L10nReadyHandler(mReady); | |
| + RefPtr<PromiseNativeHandler> l10nReadyHandler = | |
| + new L10nReadyHandler(mReady, mDocument); | |
| promise->AppendNativeHandler(l10nReadyHandler); | |
| } | |
| diff --git a/parser/html/nsHtml5TreeOpExecutor.cpp b/parser/html/nsHtml5TreeOpExecutor.cpp | |
| --- a/parser/html/nsHtml5TreeOpExecutor.cpp | |
| +++ b/parser/html/nsHtml5TreeOpExecutor.cpp | |
| @@ -170,6 +170,7 @@ nsHtml5TreeOpExecutor::DidBuildModel(boo | |
| } | |
| if (!destroying) { | |
| + mDocument->TriggerInitialDocumentTranslation(); | |
| nsContentSink::StartLayout(false); | |
| } | |
| } | |
| @@ -228,6 +229,10 @@ nsHtml5TreeOpExecutor::SetParser(nsParse | |
| return NS_OK; | |
| } | |
| +void nsHtml5TreeOpExecutor::InitialDocumentTranslationCompleted() { | |
| + nsContentSink::StartLayout(false); | |
| +} | |
| + | |
| void nsHtml5TreeOpExecutor::FlushPendingNotifications(FlushType aType) { | |
| if (aType >= FlushType::EnsurePresShellInitAndFrames) { | |
| // Bug 577508 / 253951 | |
| diff --git a/parser/html/nsHtml5TreeOpExecutor.h b/parser/html/nsHtml5TreeOpExecutor.h | |
| --- a/parser/html/nsHtml5TreeOpExecutor.h | |
| +++ b/parser/html/nsHtml5TreeOpExecutor.h | |
| @@ -136,6 +136,8 @@ class nsHtml5TreeOpExecutor final | |
| */ | |
| NS_IMETHOD WillResume() override; | |
| + virtual void InitialDocumentTranslationCompleted() override; | |
| + | |
| /** | |
| * Sets the parser. | |
| */ | |
| diff --git a/parser/htmlparser/nsIContentSink.h b/parser/htmlparser/nsIContentSink.h | |
| --- a/parser/htmlparser/nsIContentSink.h | |
| +++ b/parser/htmlparser/nsIContentSink.h | |
| @@ -130,6 +130,8 @@ class nsIContentSink : public nsISupport | |
| * Posts a runnable that continues parsing. | |
| */ | |
| virtual void ContinueInterruptedParsingAsync() {} | |
| + | |
| + virtual void InitialDocumentTranslationCompleted() {} | |
| }; | |
| NS_DEFINE_STATIC_IID_ACCESSOR(nsIContentSink, NS_ICONTENT_SINK_IID) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment