Fix bug 236921. This makes the root node's style context have no parent, makes

computed style calculations properly parent the computed context, and fixes a
but with "border-color: inherit" on the root.  r=caillon, sr=dbaron, a=asa
This commit is contained in:
bzbarsky%mit.edu 2004-03-29 16:00:38 +00:00
parent eef0796b8a
commit 809c099e33
14 changed files with 128 additions and 118 deletions

View File

@ -3236,20 +3236,25 @@ nsRuleNode::ComputeBorderData(nsStyleStruct* aStartStruct,
FOR_CSS_SIDES(side) {
const nsCSSValue &value = ourBorderColor.*(nsCSSRect::sides[side]);
if (eCSSUnit_Inherit == value.GetUnit()) {
inherited = PR_TRUE;
parentBorder->GetBorderColor(side, borderColor,
transparent, foreground);
if (transparent)
border->SetBorderTransparent(side);
else if (foreground) {
// We want to inherit the color from the parent, not use the
// color on the element where this chunk of style data will be
// used. We can ensure that the data for the parent are fully
// computed (unlike for the element where this will be used, for
// which the color could be specified on a more specific rule).
border->SetBorderColor(side, parentContext->GetStyleColor()->mColor);
} else
border->SetBorderColor(side, borderColor);
if (parentContext) {
inherited = PR_TRUE;
parentBorder->GetBorderColor(side, borderColor,
transparent, foreground);
if (transparent)
border->SetBorderTransparent(side);
else if (foreground) {
// We want to inherit the color from the parent, not use the
// color on the element where this chunk of style data will be
// used. We can ensure that the data for the parent are fully
// computed (unlike for the element where this will be used, for
// which the color could be specified on a more specific rule).
border->SetBorderColor(side, parentContext->GetStyleColor()->mColor);
} else
border->SetBorderColor(side, borderColor);
} else {
// We're the root
border->SetBorderToForeground(side);
}
}
else if (SetColor(value, unused, mPresContext, borderColor, inherited)) {
border->SetBorderColor(side, borderColor);

View File

@ -61,6 +61,7 @@
#include "nsCSSPseudoElements.h"
#include "nsStyleSet.h"
#include "imgIRequest.h"
#include "nsInspectorCSSUtils.h"
#if defined(DEBUG_bzbarsky) || defined(DEBUG_caillon)
#define DEBUG_ComputedDOMStyle
@ -2909,21 +2910,12 @@ nsComputedDOMStyle::GetStyleData(nsStyleStructID aID,
NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE);
nsCOMPtr<nsIPresContext> pctx;
presShell->GetPresContext(getter_AddRefs(pctx));
if (pctx) {
nsStyleContext* sctx;
nsStyleSet *styleSet = presShell->StyleSet();
if (!mPseudo) {
sctx = styleSet->ResolveStyleFor(mContent, nsnull).get();
} else {
sctx = styleSet->ResolvePseudoStyleFor(mContent, mPseudo,
nsnull).get();
}
if (sctx) {
aStyleStruct = sctx->GetStyleData(aID);
}
mStyleContextHolder = dont_AddRef(sctx); // transfer ref from sctx
mStyleContextHolder =
nsInspectorCSSUtils::GetStyleContextForContent(mContent,
mPseudo,
presShell);
if (mStyleContextHolder) {
aStyleStruct = mStyleContextHolder->GetStyleData(aID);
}
}
NS_ASSERTION(aStyleStruct, "Failed to get a style struct");

View File

@ -117,6 +117,7 @@ nsInspectorCSSUtils::AdjustRectForMargins(nsIFrame* aFrame, nsRect& aRect)
return NS_OK;
}
/* static */
nsStyleContext*
nsInspectorCSSUtils::GetStyleContextForFrame(nsIFrame* aFrame)
{
@ -135,25 +136,30 @@ nsInspectorCSSUtils::GetStyleContextForFrame(nsIFrame* aFrame)
return styleContext;
}
/* static */
already_AddRefed<nsStyleContext>
nsInspectorCSSUtils::GetStyleContextForContent(nsIContent* aContent,
nsIAtom* aPseudo,
nsIPresShell* aPresShell)
{
nsIFrame* frame = nsnull;
aPresShell->GetPrimaryFrameFor(aContent, &frame);
if (frame) {
nsStyleContext* result = GetStyleContextForFrame(frame);
// this function returns an addrefed style context
if (result)
result->AddRef();
return result;
if (!aPseudo) {
nsIFrame* frame = nsnull;
aPresShell->GetPrimaryFrameFor(aContent, &frame);
if (frame) {
nsStyleContext* result = GetStyleContextForFrame(frame);
// this function returns an addrefed style context
if (result)
result->AddRef();
return result;
}
}
// No frame has been created, so resolve the style ourselves
// No frame has been created or we have a pseudo, so resolve the
// style ourselves
nsRefPtr<nsStyleContext> parentContext;
nsCOMPtr<nsIContent> parent = aContent->GetParent();
nsIContent* parent = aPseudo ? aContent : aContent->GetParent();
if (parent)
parentContext = GetStyleContextForContent(parent, aPresShell);
parentContext = GetStyleContextForContent(parent, nsnull, aPresShell);
nsCOMPtr<nsIPresContext> presContext;
aPresShell->GetPresContext(getter_AddRefs(presContext));
@ -162,10 +168,16 @@ nsInspectorCSSUtils::GetStyleContextForContent(nsIContent* aContent,
nsStyleSet *styleSet = aPresShell->StyleSet();
if (aContent->IsContentOfType(nsIContent::eELEMENT))
return styleSet->ResolveStyleFor(aContent, parentContext);
if (!aContent->IsContentOfType(nsIContent::eELEMENT)) {
NS_ASSERTION(!aPseudo, "Shouldn't have a pseudo for a non-element!");
return styleSet->ResolveStyleForNonElement(parentContext);
}
return styleSet->ResolveStyleForNonElement(parentContext);
if (aPseudo) {
return styleSet->ResolvePseudoStyleFor(aContent, aPseudo, parentContext);
}
return styleSet->ResolveStyleFor(aContent, parentContext);
}
NS_IMETHODIMP
@ -181,7 +193,7 @@ nsInspectorCSSUtils::GetRuleNodeForContent(nsIContent* aContent,
NS_ENSURE_TRUE(presShell, NS_ERROR_UNEXPECTED);
nsRefPtr<nsStyleContext> sContext =
GetStyleContextForContent(aContent, presShell);
GetStyleContextForContent(aContent, nsnull, presShell);
*aRuleNode = sContext->GetRuleNode();
return NS_OK;
}

View File

@ -63,12 +63,12 @@ public:
NS_IMETHOD AdjustRectForMargins(nsIFrame* aFrame, nsRect& aRect);
NS_IMETHOD GetRuleNodeForContent(nsIContent* aContent,
nsRuleNode** aRuleNode);
static already_AddRefed<nsStyleContext>
GetStyleContextForContent(nsIContent* aContent, nsIAtom* aPseudo,
nsIPresShell* aPresShell);
private:
already_AddRefed<nsStyleContext>
GetStyleContextForContent(nsIContent* aContent, nsIPresShell* aPresShell);
nsStyleContext* GetStyleContextForFrame(nsIFrame* aFrame);
static nsStyleContext* GetStyleContextForFrame(nsIFrame* aFrame);
};
#endif /* nsInspectorCSSUtils_h___ */

View File

@ -3233,7 +3233,6 @@ nsCSSFrameConstructor::ConstructDocElementFrame(nsIPresShell* aPresShell,
nsFrameConstructorState& aState,
nsIContent* aDocElement,
nsIFrame* aParentFrame,
nsStyleContext* aParentStyleContext,
nsIFrame*& aNewFrame)
{
// how the root frame hierarchy should look
@ -3293,7 +3292,7 @@ nsCSSFrameConstructor::ConstructDocElementFrame(nsIPresShell* aPresShell,
// --------- CREATE AREA OR BOX FRAME -------
nsRefPtr<nsStyleContext> styleContext;
styleContext = aPresShell->StyleSet()->ResolveStyleFor(aDocElement,
aParentStyleContext);
nsnull);
const nsStyleDisplay* display = styleContext->GetStyleDisplay();
@ -7206,11 +7205,8 @@ nsCSSFrameConstructor::ReconstructDocElementHierarchy(nsIPresContext* aPresConte
if (NS_SUCCEEDED(rv)) {
// Create the new document element hierarchy
nsIFrame* newChild;
nsStyleContext* rootPseudoStyle = docParentFrame->GetStyleContext();
rv = ConstructDocElementFrame(shell, aPresContext, state, rootContent,
docParentFrame, rootPseudoStyle,
newChild);
docParentFrame, newChild);
if (NS_SUCCEEDED(rv)) {
rv = state.mFrameManager->InsertFrames(docParentFrame, nsnull,
@ -8647,9 +8643,6 @@ nsCSSFrameConstructor::ContentInserted(nsIPresContext* aPresContext,
// just bail here because the root will really be built later during
// InitialReflow.
// Get the style context of the containing block frame
nsStyleContext* containerStyle = mDocElementContainingBlock->GetStyleContext();
// Create frames for the document element and its child elements
nsIFrame* docElementFrame;
nsFrameConstructorState state(aPresContext, mFixedContainingBlock, nsnull, nsnull, aFrameState);
@ -8657,7 +8650,6 @@ nsCSSFrameConstructor::ContentInserted(nsIPresContext* aPresContext,
state,
docElement,
mDocElementContainingBlock,
containerStyle,
docElementFrame);
// Set the initial child list for the parent

View File

@ -218,7 +218,6 @@ protected:
nsFrameConstructorState& aState,
nsIContent* aDocElement,
nsIFrame* aParentFrame,
nsStyleContext* aParentStyleContext,
nsIFrame*& aNewFrame);
nsresult ConstructDocElementTableFrame(nsIPresShell* aPresShell,

View File

@ -4390,6 +4390,11 @@ nsFrame::DoGetParentStyleContextFrame(nsIPresContext* aPresContext,
{
*aIsChild = PR_FALSE;
*aProviderFrame = nsnull;
if (mContent && !mContent->GetParent()) {
// we're a frame for the root. We have no style context parent.
return NS_OK;
}
if (!(mState & NS_FRAME_OUT_OF_FLOW)) {
/*
* If this frame is the anonymous block created when an inline

View File

@ -4390,6 +4390,11 @@ nsFrame::DoGetParentStyleContextFrame(nsIPresContext* aPresContext,
{
*aIsChild = PR_FALSE;
*aProviderFrame = nsnull;
if (mContent && !mContent->GetParent()) {
// we're a frame for the root. We have no style context parent.
return NS_OK;
}
if (!(mState & NS_FRAME_OUT_OF_FLOW)) {
/*
* If this frame is the anonymous block created when an inline

View File

@ -3233,7 +3233,6 @@ nsCSSFrameConstructor::ConstructDocElementFrame(nsIPresShell* aPresShell,
nsFrameConstructorState& aState,
nsIContent* aDocElement,
nsIFrame* aParentFrame,
nsStyleContext* aParentStyleContext,
nsIFrame*& aNewFrame)
{
// how the root frame hierarchy should look
@ -3293,7 +3292,7 @@ nsCSSFrameConstructor::ConstructDocElementFrame(nsIPresShell* aPresShell,
// --------- CREATE AREA OR BOX FRAME -------
nsRefPtr<nsStyleContext> styleContext;
styleContext = aPresShell->StyleSet()->ResolveStyleFor(aDocElement,
aParentStyleContext);
nsnull);
const nsStyleDisplay* display = styleContext->GetStyleDisplay();
@ -7206,11 +7205,8 @@ nsCSSFrameConstructor::ReconstructDocElementHierarchy(nsIPresContext* aPresConte
if (NS_SUCCEEDED(rv)) {
// Create the new document element hierarchy
nsIFrame* newChild;
nsStyleContext* rootPseudoStyle = docParentFrame->GetStyleContext();
rv = ConstructDocElementFrame(shell, aPresContext, state, rootContent,
docParentFrame, rootPseudoStyle,
newChild);
docParentFrame, newChild);
if (NS_SUCCEEDED(rv)) {
rv = state.mFrameManager->InsertFrames(docParentFrame, nsnull,
@ -8647,9 +8643,6 @@ nsCSSFrameConstructor::ContentInserted(nsIPresContext* aPresContext,
// just bail here because the root will really be built later during
// InitialReflow.
// Get the style context of the containing block frame
nsStyleContext* containerStyle = mDocElementContainingBlock->GetStyleContext();
// Create frames for the document element and its child elements
nsIFrame* docElementFrame;
nsFrameConstructorState state(aPresContext, mFixedContainingBlock, nsnull, nsnull, aFrameState);
@ -8657,7 +8650,6 @@ nsCSSFrameConstructor::ContentInserted(nsIPresContext* aPresContext,
state,
docElement,
mDocElementContainingBlock,
containerStyle,
docElementFrame);
// Set the initial child list for the parent

View File

@ -218,7 +218,6 @@ protected:
nsFrameConstructorState& aState,
nsIContent* aDocElement,
nsIFrame* aParentFrame,
nsStyleContext* aParentStyleContext,
nsIFrame*& aNewFrame);
nsresult ConstructDocElementTableFrame(nsIPresShell* aPresShell,

View File

@ -61,6 +61,7 @@
#include "nsCSSPseudoElements.h"
#include "nsStyleSet.h"
#include "imgIRequest.h"
#include "nsInspectorCSSUtils.h"
#if defined(DEBUG_bzbarsky) || defined(DEBUG_caillon)
#define DEBUG_ComputedDOMStyle
@ -2909,21 +2910,12 @@ nsComputedDOMStyle::GetStyleData(nsStyleStructID aID,
NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE);
nsCOMPtr<nsIPresContext> pctx;
presShell->GetPresContext(getter_AddRefs(pctx));
if (pctx) {
nsStyleContext* sctx;
nsStyleSet *styleSet = presShell->StyleSet();
if (!mPseudo) {
sctx = styleSet->ResolveStyleFor(mContent, nsnull).get();
} else {
sctx = styleSet->ResolvePseudoStyleFor(mContent, mPseudo,
nsnull).get();
}
if (sctx) {
aStyleStruct = sctx->GetStyleData(aID);
}
mStyleContextHolder = dont_AddRef(sctx); // transfer ref from sctx
mStyleContextHolder =
nsInspectorCSSUtils::GetStyleContextForContent(mContent,
mPseudo,
presShell);
if (mStyleContextHolder) {
aStyleStruct = mStyleContextHolder->GetStyleData(aID);
}
}
NS_ASSERTION(aStyleStruct, "Failed to get a style struct");

View File

@ -117,6 +117,7 @@ nsInspectorCSSUtils::AdjustRectForMargins(nsIFrame* aFrame, nsRect& aRect)
return NS_OK;
}
/* static */
nsStyleContext*
nsInspectorCSSUtils::GetStyleContextForFrame(nsIFrame* aFrame)
{
@ -135,25 +136,30 @@ nsInspectorCSSUtils::GetStyleContextForFrame(nsIFrame* aFrame)
return styleContext;
}
/* static */
already_AddRefed<nsStyleContext>
nsInspectorCSSUtils::GetStyleContextForContent(nsIContent* aContent,
nsIAtom* aPseudo,
nsIPresShell* aPresShell)
{
nsIFrame* frame = nsnull;
aPresShell->GetPrimaryFrameFor(aContent, &frame);
if (frame) {
nsStyleContext* result = GetStyleContextForFrame(frame);
// this function returns an addrefed style context
if (result)
result->AddRef();
return result;
if (!aPseudo) {
nsIFrame* frame = nsnull;
aPresShell->GetPrimaryFrameFor(aContent, &frame);
if (frame) {
nsStyleContext* result = GetStyleContextForFrame(frame);
// this function returns an addrefed style context
if (result)
result->AddRef();
return result;
}
}
// No frame has been created, so resolve the style ourselves
// No frame has been created or we have a pseudo, so resolve the
// style ourselves
nsRefPtr<nsStyleContext> parentContext;
nsCOMPtr<nsIContent> parent = aContent->GetParent();
nsIContent* parent = aPseudo ? aContent : aContent->GetParent();
if (parent)
parentContext = GetStyleContextForContent(parent, aPresShell);
parentContext = GetStyleContextForContent(parent, nsnull, aPresShell);
nsCOMPtr<nsIPresContext> presContext;
aPresShell->GetPresContext(getter_AddRefs(presContext));
@ -162,10 +168,16 @@ nsInspectorCSSUtils::GetStyleContextForContent(nsIContent* aContent,
nsStyleSet *styleSet = aPresShell->StyleSet();
if (aContent->IsContentOfType(nsIContent::eELEMENT))
return styleSet->ResolveStyleFor(aContent, parentContext);
if (!aContent->IsContentOfType(nsIContent::eELEMENT)) {
NS_ASSERTION(!aPseudo, "Shouldn't have a pseudo for a non-element!");
return styleSet->ResolveStyleForNonElement(parentContext);
}
return styleSet->ResolveStyleForNonElement(parentContext);
if (aPseudo) {
return styleSet->ResolvePseudoStyleFor(aContent, aPseudo, parentContext);
}
return styleSet->ResolveStyleFor(aContent, parentContext);
}
NS_IMETHODIMP
@ -181,7 +193,7 @@ nsInspectorCSSUtils::GetRuleNodeForContent(nsIContent* aContent,
NS_ENSURE_TRUE(presShell, NS_ERROR_UNEXPECTED);
nsRefPtr<nsStyleContext> sContext =
GetStyleContextForContent(aContent, presShell);
GetStyleContextForContent(aContent, nsnull, presShell);
*aRuleNode = sContext->GetRuleNode();
return NS_OK;
}

View File

@ -63,12 +63,12 @@ public:
NS_IMETHOD AdjustRectForMargins(nsIFrame* aFrame, nsRect& aRect);
NS_IMETHOD GetRuleNodeForContent(nsIContent* aContent,
nsRuleNode** aRuleNode);
static already_AddRefed<nsStyleContext>
GetStyleContextForContent(nsIContent* aContent, nsIAtom* aPseudo,
nsIPresShell* aPresShell);
private:
already_AddRefed<nsStyleContext>
GetStyleContextForContent(nsIContent* aContent, nsIPresShell* aPresShell);
nsStyleContext* GetStyleContextForFrame(nsIFrame* aFrame);
static nsStyleContext* GetStyleContextForFrame(nsIFrame* aFrame);
};
#endif /* nsInspectorCSSUtils_h___ */

View File

@ -3236,20 +3236,25 @@ nsRuleNode::ComputeBorderData(nsStyleStruct* aStartStruct,
FOR_CSS_SIDES(side) {
const nsCSSValue &value = ourBorderColor.*(nsCSSRect::sides[side]);
if (eCSSUnit_Inherit == value.GetUnit()) {
inherited = PR_TRUE;
parentBorder->GetBorderColor(side, borderColor,
transparent, foreground);
if (transparent)
border->SetBorderTransparent(side);
else if (foreground) {
// We want to inherit the color from the parent, not use the
// color on the element where this chunk of style data will be
// used. We can ensure that the data for the parent are fully
// computed (unlike for the element where this will be used, for
// which the color could be specified on a more specific rule).
border->SetBorderColor(side, parentContext->GetStyleColor()->mColor);
} else
border->SetBorderColor(side, borderColor);
if (parentContext) {
inherited = PR_TRUE;
parentBorder->GetBorderColor(side, borderColor,
transparent, foreground);
if (transparent)
border->SetBorderTransparent(side);
else if (foreground) {
// We want to inherit the color from the parent, not use the
// color on the element where this chunk of style data will be
// used. We can ensure that the data for the parent are fully
// computed (unlike for the element where this will be used, for
// which the color could be specified on a more specific rule).
border->SetBorderColor(side, parentContext->GetStyleColor()->mColor);
} else
border->SetBorderColor(side, borderColor);
} else {
// We're the root
border->SetBorderToForeground(side);
}
}
else if (SetColor(value, unused, mPresContext, borderColor, inherited)) {
border->SetBorderColor(side, borderColor);