This commit is contained in:
Cameron Kaiser 2020-02-17 21:46:37 -08:00
parent fae264c819
commit cfb43390a9
5 changed files with 41 additions and 72 deletions

View File

@ -10005,36 +10005,12 @@ nsGlobalWindow::GetComputedStyleHelperOuter(Element& aElt,
{ {
MOZ_RELEASE_ASSERT(IsOuterWindow()); MOZ_RELEASE_ASSERT(IsOuterWindow());
if (!mDocShell) { if (!mDoc) {
return nullptr; return nullptr;
} }
nsCOMPtr<nsIPresShell> presShell = mDocShell->GetPresShell();
if (!presShell) {
// Try flushing frames on our parent in case there's a pending
// style change that will create the presshell.
nsGlobalWindow *parent =
static_cast<nsGlobalWindow *>(GetPrivateParent());
if (!parent) {
return nullptr;
}
parent->FlushPendingNotifications(Flush_Frames);
// Might have killed mDocShell
if (!mDocShell) {
return nullptr;
}
presShell = mDocShell->GetPresShell();
if (!presShell) {
return nullptr;
}
}
RefPtr<nsComputedDOMStyle> compStyle = RefPtr<nsComputedDOMStyle> compStyle =
NS_NewComputedDOMStyle(&aElt, aPseudoElt, presShell, NS_NewComputedDOMStyle(&aElt, aPseudoElt, mDoc,
aDefaultStylesOnly ? nsComputedDOMStyle::eDefaultOnly : aDefaultStylesOnly ? nsComputedDOMStyle::eDefaultOnly :
nsComputedDOMStyle::eAll); nsComputedDOMStyle::eAll);

View File

@ -38,14 +38,8 @@ GetCSSComputedValue(Element* aElem,
return false; return false;
} }
nsIPresShell* shell = doc->GetShell();
if (!shell) {
NS_WARNING("Unable to look up computed style -- no pres shell");
return false;
}
RefPtr<nsComputedDOMStyle> computedStyle = RefPtr<nsComputedDOMStyle> computedStyle =
NS_NewComputedDOMStyle(aElem, EmptyString(), shell); NS_NewComputedDOMStyle(aElem, EmptyString(), doc);
computedStyle->GetPropertyValue(aPropID, aResult); computedStyle->GetPropertyValue(aPropID, aResult);
return true; return true;

View File

@ -537,11 +537,8 @@ nsHTMLCSSUtils::GetComputedStyle(dom::Element* aElement)
nsIDocument* doc = aElement->GetCurrentDoc(); nsIDocument* doc = aElement->GetCurrentDoc();
NS_ENSURE_TRUE(doc, nullptr); NS_ENSURE_TRUE(doc, nullptr);
nsIPresShell* presShell = doc->GetShell();
NS_ENSURE_TRUE(presShell, nullptr);
RefPtr<nsComputedDOMStyle> style = RefPtr<nsComputedDOMStyle> style =
NS_NewComputedDOMStyle(aElement, EmptyString(), presShell); NS_NewComputedDOMStyle(aElement, EmptyString(), doc);
return style.forget(); return style.forget();
} }

View File

@ -63,13 +63,13 @@ using namespace mozilla::dom;
*/ */
already_AddRefed<nsComputedDOMStyle> already_AddRefed<nsComputedDOMStyle>
NS_NewComputedDOMStyle(dom::Element* aElement, const nsAString& aPseudoElt, NS_NewComputedDOMStyle(dom::Element* aElement,
nsIPresShell* aPresShell, const nsAString& aPseudoElt,
nsIDocument* aDocument,
nsComputedDOMStyle::StyleType aStyleType) nsComputedDOMStyle::StyleType aStyleType)
{ {
RefPtr<nsComputedDOMStyle> computedStyle; RefPtr<nsComputedDOMStyle> computedStyle;
computedStyle = new nsComputedDOMStyle(aElement, aPseudoElt, aPresShell, computedStyle = new nsComputedDOMStyle(aElement, aPseudoElt, aDocument, aStyleType);
aStyleType);
return computedStyle.forget(); return computedStyle.forget();
} }
@ -219,7 +219,7 @@ nsComputedStyleMap::Update()
nsComputedDOMStyle::nsComputedDOMStyle(dom::Element* aElement, nsComputedDOMStyle::nsComputedDOMStyle(dom::Element* aElement,
const nsAString& aPseudoElt, const nsAString& aPseudoElt,
nsIPresShell* aPresShell, nsIDocument* aDocument,
StyleType aStyleType) StyleType aStyleType)
: mDocumentWeak(nullptr), mOuterFrame(nullptr), : mDocumentWeak(nullptr), mOuterFrame(nullptr),
mInnerFrame(nullptr), mPresShell(nullptr), mInnerFrame(nullptr), mPresShell(nullptr),
@ -228,11 +228,13 @@ nsComputedDOMStyle::nsComputedDOMStyle(dom::Element* aElement,
mExposeVisitedStyle(false), mExposeVisitedStyle(false),
mResolvedStyleContext(false) mResolvedStyleContext(false)
{ {
MOZ_ASSERT(aElement && aPresShell); MOZ_ASSERT(aElement);
MOZ_ASSERT(aDocument);
// TODO(emilio, bug 548397, https://github.com/w3c/csswg-drafts/issues/2403):
// Should use aElement->OwnerDoc() instead.
mDocumentWeak = do_GetWeakReference(aDocument);
mDocumentWeak = do_GetWeakReference(aPresShell->GetDocument()); mElement = aElement;
mContent = aElement;
if (!DOMStringIsNull(aPseudoElt) && !aPseudoElt.IsEmpty() && if (!DOMStringIsNull(aPseudoElt) && !aPseudoElt.IsEmpty() &&
aPseudoElt.First() == char16_t(':')) { aPseudoElt.First() == char16_t(':')) {
@ -259,11 +261,8 @@ nsComputedDOMStyle::nsComputedDOMStyle(dom::Element* aElement,
mPseudo = nullptr; mPseudo = nullptr;
} }
} }
MOZ_ASSERT(aPresShell->GetPresContext());
} }
nsComputedDOMStyle::~nsComputedDOMStyle() nsComputedDOMStyle::~nsComputedDOMStyle()
{ {
ClearStyleContext(); ClearStyleContext();
@ -272,13 +271,13 @@ nsComputedDOMStyle::~nsComputedDOMStyle()
NS_IMPL_CYCLE_COLLECTION_CLASS(nsComputedDOMStyle) NS_IMPL_CYCLE_COLLECTION_CLASS(nsComputedDOMStyle)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsComputedDOMStyle) NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsComputedDOMStyle)
tmp->ClearStyleContext(); // remove observer before clearing mContent tmp->ClearStyleContext(); // remove observer before clearing mElement
NS_IMPL_CYCLE_COLLECTION_UNLINK(mContent) NS_IMPL_CYCLE_COLLECTION_UNLINK(mElement)
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsComputedDOMStyle) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsComputedDOMStyle)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mContent) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mElement)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
@ -345,8 +344,6 @@ nsComputedDOMStyle::SetCssText(const nsAString& aCssText)
NS_IMETHODIMP NS_IMETHODIMP
nsComputedDOMStyle::GetLength(uint32_t* aLength) nsComputedDOMStyle::GetLength(uint32_t* aLength)
{ {
NS_PRECONDITION(aLength, "Null aLength! Prepare to die!");
uint32_t length = GetComputedStyleMap()->Length(); uint32_t length = GetComputedStyleMap()->Length();
// Make sure we have up to date style so that we can include custom // Make sure we have up to date style so that we can include custom
@ -354,6 +351,8 @@ nsComputedDOMStyle::GetLength(uint32_t* aLength)
UpdateCurrentStyleSources(false); UpdateCurrentStyleSources(false);
if (mStyleContext) { if (mStyleContext) {
length += StyleVariables()->mVariables.Count(); length += StyleVariables()->mVariables.Count();
} else {
length = 0;
} }
*aLength = length; *aLength = length;
@ -599,7 +598,7 @@ nsComputedDOMStyle::ClearStyleContext()
{ {
if (mResolvedStyleContext) { if (mResolvedStyleContext) {
mResolvedStyleContext = false; mResolvedStyleContext = false;
mContent->RemoveMutationObserver(this); mElement->RemoveMutationObserver(this);
} }
mStyleContext = nullptr; mStyleContext = nullptr;
} }
@ -609,7 +608,7 @@ nsComputedDOMStyle::SetResolvedStyleContext(RefPtr<nsStyleContext>&& aContext)
{ {
if (!mResolvedStyleContext) { if (!mResolvedStyleContext) {
mResolvedStyleContext = true; mResolvedStyleContext = true;
mContent->AddMutationObserver(this); mElement->AddMutationObserver(this);
} }
mStyleContext = aContext; mStyleContext = aContext;
} }
@ -634,7 +633,7 @@ nsComputedDOMStyle::UpdateCurrentStyleSources(bool aNeedsLayoutFlush)
// Flush _before_ getting the presshell, since that could create a new // Flush _before_ getting the presshell, since that could create a new
// presshell. Also note that we want to flush the style on the document // presshell. Also note that we want to flush the style on the document
// we're computing style in, not on the document mContent is in -- the two // we're computing style in, not on the document mElement is in -- the two
// may be different. // may be different.
document->FlushPendingNotifications( document->FlushPendingNotifications(
aNeedsLayoutFlush ? Flush_Layout : Flush_Style); aNeedsLayoutFlush ? Flush_Layout : Flush_Style);
@ -642,7 +641,7 @@ nsComputedDOMStyle::UpdateCurrentStyleSources(bool aNeedsLayoutFlush)
mFlushedPendingReflows = aNeedsLayoutFlush; mFlushedPendingReflows = aNeedsLayoutFlush;
#endif #endif
nsCOMPtr<nsIPresShell> presShellForContent = GetPresShellForContent(mContent); nsCOMPtr<nsIPresShell> presShellForContent = GetPresShellForContent(mElement);
if (presShellForContent && presShellForContent != mPresShell) { if (presShellForContent && presShellForContent != mPresShell) {
presShellForContent->FlushPendingNotifications(Flush_Style); presShellForContent->FlushPendingNotifications(Flush_Style);
} }
@ -657,7 +656,11 @@ nsComputedDOMStyle::UpdateCurrentStyleSources(bool aNeedsLayoutFlush)
mPresShell->GetPresContext()->GetRestyleGeneration(); mPresShell->GetPresContext()->GetRestyleGeneration();
if (mStyleContext) { if (mStyleContext) {
if (mStyleContextGeneration == currentGeneration) { // We can't rely on the undisplayed restyle generation if mElement is
// out-of-document, since that generation is not incremented for DOM changes
// on out-of-document elements.
if (mStyleContextGeneration == currentGeneration &&
mElement->IsInComposedDoc()) {
// Our cached style context is still valid. // Our cached style context is still valid.
return; return;
} }
@ -666,12 +669,12 @@ nsComputedDOMStyle::UpdateCurrentStyleSources(bool aNeedsLayoutFlush)
mStyleContext = nullptr; mStyleContext = nullptr;
} }
// XXX the !mContent->IsHTMLElement(nsGkAtoms::area) // XXX the !mElement->IsHTMLElement(nsGkAtoms::area)
// check is needed due to bug 135040 (to avoid using // check is needed due to bug 135040 (to avoid using
// mPrimaryFrame). Remove it once that's fixed. // mPrimaryFrame). Remove it once that's fixed.
if (!mPseudo && mStyleType == eAll && if (!mPseudo && mStyleType == eAll &&
!mContent->IsHTMLElement(nsGkAtoms::area)) { !mElement->IsHTMLElement(nsGkAtoms::area)) {
mOuterFrame = mContent->GetPrimaryFrame(); mOuterFrame = mElement->GetPrimaryFrame();
mInnerFrame = mOuterFrame; mInnerFrame = mOuterFrame;
if (mOuterFrame) { if (mOuterFrame) {
nsIAtom* type = mOuterFrame->GetType(); nsIAtom* type = mOuterFrame->GetType();
@ -715,7 +718,7 @@ nsComputedDOMStyle::UpdateCurrentStyleSources(bool aNeedsLayoutFlush)
// Need to resolve a style context // Need to resolve a style context
RefPtr<nsStyleContext> resolvedStyleContext = RefPtr<nsStyleContext> resolvedStyleContext =
nsComputedDOMStyle::GetStyleContextForElementNoFlush( nsComputedDOMStyle::GetStyleContextForElementNoFlush(
mContent->AsElement(), mElement,
mPseudo, mPseudo,
presShellForContent ? presShellForContent.get() : mPresShell, presShellForContent ? presShellForContent.get() : mPresShell,
mStyleType); mStyleType);
@ -808,7 +811,6 @@ nsComputedDOMStyle::GetPropertyCSSValue(const nsAString& aPropertyName, ErrorRes
UpdateCurrentStyleSources(needsLayoutFlush); UpdateCurrentStyleSources(needsLayoutFlush);
if (!mStyleContext) { if (!mStyleContext) {
aRv.Throw(NS_ERROR_NOT_AVAILABLE);
return nullptr; return nullptr;
} }
@ -4866,7 +4868,7 @@ nsComputedDOMStyle::GetLineHeightCoord(nscoord& aCoord)
// lie about font size inflation since we lie about font size (since // lie about font size inflation since we lie about font size (since
// the inflation only applies to text) // the inflation only applies to text)
aCoord = nsHTMLReflowState::CalcLineHeight(mContent, mStyleContext, aCoord = nsHTMLReflowState::CalcLineHeight(mElement, mStyleContext,
blockHeight, 1.0f); blockHeight, 1.0f);
// CalcLineHeight uses font->mFont.size, but we want to use // CalcLineHeight uses font->mFont.size, but we want to use
@ -6228,7 +6230,7 @@ nsComputedDOMStyle::DoGetCustomProperty(const nsAString& aPropertyName)
void void
nsComputedDOMStyle::ParentChainChanged(nsIContent* aContent) nsComputedDOMStyle::ParentChainChanged(nsIContent* aContent)
{ {
NS_ASSERTION(mContent == aContent, "didn't we register mContent?"); NS_ASSERTION(mElement == aContent, "didn't we register mElement?");
NS_ASSERTION(mResolvedStyleContext, NS_ASSERTION(mResolvedStyleContext,
"should have only registered an observer when " "should have only registered an observer when "
"mResolvedStyleContext is true"); "mResolvedStyleContext is true");

View File

@ -70,12 +70,12 @@ public:
nsComputedDOMStyle(mozilla::dom::Element* aElement, nsComputedDOMStyle(mozilla::dom::Element* aElement,
const nsAString& aPseudoElt, const nsAString& aPseudoElt,
nsIPresShell* aPresShell, nsIDocument* aDocument,
StyleType aStyleType); StyleType aStyleType);
virtual nsINode *GetParentObject() override nsINode *GetParentObject() override
{ {
return mContent; return mElement;
} }
static already_AddRefed<nsStyleContext> static already_AddRefed<nsStyleContext>
@ -614,9 +614,9 @@ private:
// We don't really have a good immutable representation of "presentation". // We don't really have a good immutable representation of "presentation".
// Given the way GetComputedStyle is currently used, we should just grab the // Given the way GetComputedStyle is currently used, we should just grab the
// 0th presshell, if any, from the document. // presshell, if any, from the document.
nsWeakPtr mDocumentWeak; nsWeakPtr mDocumentWeak;
nsCOMPtr<nsIContent> mContent; RefPtr<mozilla::dom::Element> mElement;
/** /**
* Strong reference to the style context we access data from. This can be * Strong reference to the style context we access data from. This can be
@ -682,7 +682,7 @@ private:
already_AddRefed<nsComputedDOMStyle> already_AddRefed<nsComputedDOMStyle>
NS_NewComputedDOMStyle(mozilla::dom::Element* aElement, NS_NewComputedDOMStyle(mozilla::dom::Element* aElement,
const nsAString& aPseudoElt, const nsAString& aPseudoElt,
nsIPresShell* aPresShell, nsIDocument* aDocument,
nsComputedDOMStyle::StyleType aStyleType = nsComputedDOMStyle::StyleType aStyleType =
nsComputedDOMStyle::eAll); nsComputedDOMStyle::eAll);