зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1440537 - Don't propagate flushes across docgroup boundaries. r=bzbarsky
We don't need to flush layout in the parent document if the parent and child documents can't observe each other. This will also match our behavior in a Fission world. I'm not attached to the name of the function, better ideas welcome. Differential Revision: https://phabricator.services.mozilla.com/D28217
This commit is contained in:
Родитель
337c7bf696
Коммит
7f4d653ea8
|
@ -3149,8 +3149,8 @@ void Document::SetPrincipals(nsIPrincipal* aNewPrincipal,
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
mozilla::dom::DocGroup* Document::GetDocGroup() const {
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
void Document::AssertDocGroupMatchesKey() const {
|
||||||
// Sanity check that we have an up-to-date and accurate docgroup
|
// Sanity check that we have an up-to-date and accurate docgroup
|
||||||
if (mDocGroup) {
|
if (mDocGroup) {
|
||||||
nsAutoCString docGroupKey;
|
nsAutoCString docGroupKey;
|
||||||
|
@ -3162,10 +3162,8 @@ mozilla::dom::DocGroup* Document::GetDocGroup() const {
|
||||||
}
|
}
|
||||||
// XXX: Check that the TabGroup is correct as well!
|
// XXX: Check that the TabGroup is correct as well!
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
return mDocGroup;
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
nsresult Document::Dispatch(TaskCategory aCategory,
|
nsresult Document::Dispatch(TaskCategory aCategory,
|
||||||
already_AddRefed<nsIRunnable>&& aRunnable) {
|
already_AddRefed<nsIRunnable>&& aRunnable) {
|
||||||
|
@ -7334,7 +7332,8 @@ void Document::FlushPendingNotifications(mozilla::ChangesToFlush aFlush) {
|
||||||
// affect style, we need to promote a style flush on ourself to a
|
// affect style, we need to promote a style flush on ourself to a
|
||||||
// layout flush on our parent, since we need our container to be the
|
// layout flush on our parent, since we need our container to be the
|
||||||
// correct size to determine the correct style.
|
// correct size to determine the correct style.
|
||||||
if (mParentDocument && IsSafeToFlush()) {
|
if (StyleOrLayoutObservablyDependsOnParentDocumentLayout() &&
|
||||||
|
IsSafeToFlush()) {
|
||||||
mozilla::ChangesToFlush parentFlush = aFlush;
|
mozilla::ChangesToFlush parentFlush = aFlush;
|
||||||
if (flushType >= FlushType::Style) {
|
if (flushType >= FlushType::Style) {
|
||||||
parentFlush.mFlushType = std::max(FlushType::Layout, flushType);
|
parentFlush.mFlushType = std::max(FlushType::Layout, flushType);
|
||||||
|
|
|
@ -2406,7 +2406,6 @@ class Document : public nsINode,
|
||||||
nsAtom* aAttrName,
|
nsAtom* aAttrName,
|
||||||
const nsAString& aAttrValue) const;
|
const nsAString& aAttrValue) const;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* To batch DOMSubtreeModified, document needs to be informed when
|
* To batch DOMSubtreeModified, document needs to be informed when
|
||||||
* a mutation event might be dispatched, even if the event isn't actually
|
* a mutation event might be dispatched, even if the event isn't actually
|
||||||
|
@ -3497,7 +3496,30 @@ class Document : public nsINode,
|
||||||
void ReportHasScrollLinkedEffect();
|
void ReportHasScrollLinkedEffect();
|
||||||
bool HasScrollLinkedEffect() const { return mHasScrollLinkedEffect; }
|
bool HasScrollLinkedEffect() const { return mHasScrollLinkedEffect; }
|
||||||
|
|
||||||
DocGroup* GetDocGroup() const;
|
#ifdef DEBUG
|
||||||
|
void AssertDocGroupMatchesKey() const;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
DocGroup* GetDocGroup() const {
|
||||||
|
#ifdef DEBUG
|
||||||
|
AssertDocGroupMatchesKey();
|
||||||
|
#endif
|
||||||
|
return mDocGroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If we're a sub-document, the parent document's layout can affect our style
|
||||||
|
* and layout (due to the viewport size, viewport units, media queries...).
|
||||||
|
*
|
||||||
|
* This function returns true if our parent document and our child document
|
||||||
|
* can observe each other. If they cannot, then we don't need to synchronously
|
||||||
|
* update the parent document layout every time the child document may need
|
||||||
|
* up-to-date layout information.
|
||||||
|
*/
|
||||||
|
bool StyleOrLayoutObservablyDependsOnParentDocumentLayout() const {
|
||||||
|
return GetParentDocument() &&
|
||||||
|
GetDocGroup() == GetParentDocument()->GetDocGroup();
|
||||||
|
}
|
||||||
|
|
||||||
void AddIntersectionObserver(DOMIntersectionObserver* aObserver) {
|
void AddIntersectionObserver(DOMIntersectionObserver* aObserver) {
|
||||||
MOZ_ASSERT(!mIntersectionObservers.Contains(aObserver),
|
MOZ_ASSERT(!mIntersectionObservers.Contains(aObserver),
|
||||||
|
|
|
@ -7366,16 +7366,12 @@ void nsGlobalWindowOuter::FlushPendingNotifications(FlushType aType) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void nsGlobalWindowOuter::EnsureSizeAndPositionUpToDate() {
|
void nsGlobalWindowOuter::EnsureSizeAndPositionUpToDate() {
|
||||||
// If we're a subframe, make sure our size is up to date. It's OK that this
|
// If we're a subframe, make sure our size is up to date. Make sure to go
|
||||||
// crosses the content/chrome boundary, since chrome can have pending reflows
|
// through the document chain rather than the window chain to not flush on
|
||||||
// too.
|
// detached iframes, see bug 1545516.
|
||||||
//
|
if (mDoc && mDoc->StyleOrLayoutObservablyDependsOnParentDocumentLayout()) {
|
||||||
// Make sure to go through the document chain rather than the window chain to
|
RefPtr<Document> parent = mDoc->GetParentDocument();
|
||||||
// not flush on detached iframes, see bug 1545516.
|
parent->FlushPendingNotifications(FlushType::Layout);
|
||||||
if (mDoc) {
|
|
||||||
if (RefPtr<Document> parent = mDoc->GetParentDocument()) {
|
|
||||||
parent->FlushPendingNotifications(FlushType::Layout);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -785,7 +785,8 @@ bool nsComputedDOMStyle::NeedsToFlush() const {
|
||||||
Document* doc = mElement->OwnerDoc();
|
Document* doc = mElement->OwnerDoc();
|
||||||
// If parent document is there, also needs to check if there is some change
|
// If parent document is there, also needs to check if there is some change
|
||||||
// that needs to flush this document (e.g. size change for iframe).
|
// that needs to flush this document (e.g. size change for iframe).
|
||||||
while (Document* parentDocument = doc->GetParentDocument()) {
|
while (doc->StyleOrLayoutObservablyDependsOnParentDocumentLayout()) {
|
||||||
|
Document* parentDocument = doc->GetParentDocument();
|
||||||
Element* element = parentDocument->FindContentForSubDocument(doc);
|
Element* element = parentDocument->FindContentForSubDocument(doc);
|
||||||
if (ElementNeedsRestyle(element, nullptr)) {
|
if (ElementNeedsRestyle(element, nullptr)) {
|
||||||
return true;
|
return true;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче