This commit is contained in:
peterl%netscape.com 1999-09-03 23:35:41 +00:00
Родитель 09ea141535
Коммит b5b37d859e
23 изменённых файлов: 447 добавлений и 68 удалений

Просмотреть файл

@ -80,6 +80,11 @@ public:
nsIStyleContext* aParentContext,
PRBool aForceUnique = PR_FALSE);
NS_IMETHOD ReParentStyleContext(nsIPresContext* aPresContext,
nsIStyleContext* aStyleContext,
nsIStyleContext* aNewParentContext,
nsIStyleContext** aNewStyleContext);
NS_IMETHOD HasStateDependentStyle(nsIPresContext* aPresContext,
nsIContent* aContent);
@ -726,6 +731,64 @@ nsIStyleContext* StyleSetImpl::ProbePseudoStyleFor(nsIPresContext* aPresContext,
return result;
}
NS_IMETHODIMP
StyleSetImpl::ReParentStyleContext(nsIPresContext* aPresContext,
nsIStyleContext* aStyleContext,
nsIStyleContext* aNewParentContext,
nsIStyleContext** aNewStyleContext)
{
NS_ASSERTION(aPresContext, "must have pres context");
NS_ASSERTION(aPresContext, "must have pres context");
NS_ASSERTION(aPresContext, "must have pres context");
nsresult result = NS_ERROR_NULL_POINTER;
if (aPresContext && aStyleContext && aNewStyleContext) {
nsIStyleContext* oldParent = aStyleContext->GetParent();
if (oldParent == aNewParentContext) {
result = NS_OK;
NS_ADDREF(aStyleContext); // for return
*aNewStyleContext = aStyleContext;
}
else { // really a new parent
nsIStyleContext* newChild = nsnull;
nsIAtom* pseudoTag = nsnull;
aStyleContext->GetPseudoType(pseudoTag);
nsISupportsArray* rules = aStyleContext->GetStyleRules();
if (aNewParentContext) {
result = aNewParentContext->FindChildWithRules(pseudoTag, rules, newChild);
}
if (newChild) { // new parent already has one
*aNewStyleContext = newChild;
}
else { // need to make one in the new parent
nsISupportsArray* newRules = nsnull;
if (rules) {
newRules = mRecycler;
mRecycler = nsnull;
if (! newRules) {
result = NS_NewISupportsArray(&newRules);
}
if (newRules) {
newRules->AppendElements(rules);
}
}
result = NS_NewStyleContext(aNewStyleContext, aNewParentContext, pseudoTag,
newRules, aPresContext);
NS_IF_RELEASE(newRules);
}
NS_IF_RELEASE(rules);
NS_IF_RELEASE(pseudoTag);
}
NS_IF_RELEASE(oldParent);
}
return result;
}
struct StatefulData {
StatefulData(nsIPresContext* aPresContext, nsIContent* aContent)
: mPresContext(aPresContext),

Просмотреть файл

@ -20,6 +20,7 @@
#include "nsIPresContext.h"
#include "nsIPresShell.h"
#include "nsIStyleSet.h"
#include "nsIStyleContext.h"
#include "nsIEventQueueService.h"
#include "nsIServiceManager.h"
#include "nsCOMPtr.h"
@ -137,10 +138,13 @@ public:
NS_IMETHOD NotifyDestroyingFrame(nsIFrame* aFrame);
NS_IMETHOD ReParentStyleContext(nsIPresContext& aPresContext,
nsIFrame* aFrame,
nsIStyleContext* aNewParentContext);
NS_IMETHOD CaptureFrameState(nsIFrame* aFrame, nsILayoutHistoryState* aState);
NS_IMETHOD RestoreFrameState(nsIFrame* aFrame, nsILayoutHistoryState* aState);
private:
nsIPresShell* mPresShell; // weak link, because the pres shell owns us
nsIStyleSet* mStyleSet; // weak link. pres shell holds a reference
@ -564,6 +568,71 @@ FrameManager::CantRenderReplacedElement(nsIPresContext* aPresContext,
return rv;
}
NS_IMETHODIMP
FrameManager::ReParentStyleContext(nsIPresContext& aPresContext,
nsIFrame* aFrame,
nsIStyleContext* aNewParentContext)
{
nsresult result = NS_ERROR_NULL_POINTER;
if (aFrame) {
nsIStyleContext* oldContext = nsnull;
aFrame->GetStyleContext(&oldContext);
if (oldContext) {
nsIStyleContext* newContext = nsnull;
result = mStyleSet->ReParentStyleContext(&aPresContext,
oldContext, aNewParentContext,
&newContext);
if (NS_SUCCEEDED(result) && newContext) {
if (newContext != oldContext) {
PRInt32 listIndex = 0;
nsIAtom* childList = nsnull;
nsIFrame* child;
do {
child = nsnull;
result = aFrame->FirstChild(childList, &child);
while ((NS_SUCCEEDED(result)) && child) {
result = ReParentStyleContext(aPresContext, child, newContext);
child->GetNextSibling(&child);
}
NS_IF_RELEASE(childList);
aFrame->GetAdditionalChildListName(listIndex++, &childList);
} while (childList);
aFrame->SetStyleContext(&aPresContext, newContext);
// do additional contexts
PRInt32 contextIndex = -1;
while (1 == 1) {
nsIStyleContext* oldExtraContext = nsnull;
aFrame->GetAdditionalStyleContext(++contextIndex, &oldExtraContext);
if (oldExtraContext) {
nsIStyleContext* newExtraContext = nsnull;
result = mStyleSet->ReParentStyleContext(&aPresContext,
oldExtraContext, newContext,
&newExtraContext);
if (NS_SUCCEEDED(result) && newExtraContext) {
aFrame->SetAdditionalStyleContext(contextIndex, newExtraContext);
NS_RELEASE(newExtraContext);
}
NS_RELEASE(oldExtraContext);
}
else {
break;
}
}
}
NS_RELEASE(newContext);
}
NS_RELEASE(oldContext);
}
}
return result;
}
NS_IMETHODIMP
FrameManager::CaptureFrameState(nsIFrame* aFrame, nsILayoutHistoryState* aState)
{
@ -598,6 +667,7 @@ FrameManager::CaptureFrameState(nsIFrame* aFrame, nsILayoutHistoryState* aState)
// XXX We are only going through the principal child list right now.
// Need to talk to Troy to find out about other kinds of
// child lists and whether they will contain stateful frames.
// (psl) YES, you need to iterate ALL child lists
// Capture frame state for the first child
nsIFrame* child = nsnull;
@ -649,6 +719,7 @@ FrameManager::RestoreFrameState(nsIFrame* aFrame, nsILayoutHistoryState* aState)
// XXX We are only going through the principal child list right now.
// Need to talk to Troy to find out about other kinds of
// child lists and whether they will contain stateful frames.
// (psl) YES, you need to iterate ALL child lists
// Capture frame state for the first child
nsIFrame* child = nsnull;

Просмотреть файл

@ -22,6 +22,7 @@
#include "nsILinkHandler.h"
#include "nsIStyleSet.h"
#include "nsFrameImageLoader.h"
#include "nsIFrameManager.h"
#include "nsIImageGroup.h"
#include "nsIFrame.h"
#include "nsIRenderingContext.h"
@ -454,6 +455,24 @@ nsPresContext::ProbePseudoStyleContextFor(nsIContent* aParentContent,
return rv;
}
NS_IMETHODIMP
nsPresContext::ReParentStyleContext(nsIFrame* aFrame,
nsIStyleContext* aNewParentContext)
{
NS_PRECONDITION(aFrame, "null ptr");
if (! aFrame) {
return NS_ERROR_NULL_POINTER;
}
nsCOMPtr<nsIFrameManager> manager;
nsresult rv = mShell->GetFrameManager(getter_AddRefs(manager));
if (NS_SUCCEEDED(rv) && manager) {
rv = manager->ReParentStyleContext(*this, aFrame, aNewParentContext);
}
return rv;
}
NS_IMETHODIMP
nsPresContext::GetMetricsFor(const nsFont& aFont, nsIFontMetrics** aResult)
{

Просмотреть файл

@ -150,6 +150,14 @@ public:
PRBool aForceUnique,
nsIStyleContext** aResult) = 0;
/**
* For a given frame tree, get a new style context that is the equivalent
* but within a new parent
*/
NS_IMETHOD ReParentStyleContext(nsIFrame* aFrame,
nsIStyleContext* aNewParentContext) = 0;
/**
* Get the font metrics for a given font.
*/

Просмотреть файл

@ -27,6 +27,7 @@ class nsIFrame;
class nsIPresContext;
class nsIPresShell;
class nsIStyleSet;
class nsIStyleContext;
class nsILayoutHistoryState;
#define NS_IFRAMEMANAGER_IID \
@ -93,6 +94,12 @@ public:
// references to the frame to be cleaned up
NS_IMETHOD NotifyDestroyingFrame(nsIFrame* aFrame) = 0;
// reparent the style contexts of this frame sub tree to live under the
// new given parent style context
NS_IMETHOD ReParentStyleContext(nsIPresContext& aPresContext,
nsIFrame* aFrame,
nsIStyleContext* aNewParentContext) = 0;
/**
* Capture/restore frame state for the frame subtree rooted at aFrame.
* aState is the document state storage object onto which each frame

Просмотреть файл

@ -150,6 +150,14 @@ public:
PRBool aForceUnique,
nsIStyleContext** aResult) = 0;
/**
* For a given frame tree, get a new style context that is the equivalent
* but within a new parent
*/
NS_IMETHOD ReParentStyleContext(nsIFrame* aFrame,
nsIStyleContext* aNewParentContext) = 0;
/**
* Get the font metrics for a given font.
*/

Просмотреть файл

@ -89,6 +89,13 @@ public:
nsIStyleContext* aParentContext,
PRBool aForceUnique = PR_FALSE) = 0;
// Get a new style context that lives in a different parent
// The new context will be the same as the old if the new parent == the old parent
NS_IMETHOD ReParentStyleContext(nsIPresContext* aPresContext,
nsIStyleContext* aStyleContext,
nsIStyleContext* aNewParentContext,
nsIStyleContext** aNewStyleContext) = 0;
// Test if style is dependent on content state
NS_IMETHOD HasStateDependentStyle(nsIPresContext* aPresContext,
nsIContent* aContent) = 0;

Просмотреть файл

@ -150,6 +150,14 @@ public:
PRBool aForceUnique,
nsIStyleContext** aResult) = 0;
/**
* For a given frame tree, get a new style context that is the equivalent
* but within a new parent
*/
NS_IMETHOD ReParentStyleContext(nsIFrame* aFrame,
nsIStyleContext* aNewParentContext) = 0;
/**
* Get the font metrics for a given font.
*/

Просмотреть файл

@ -22,6 +22,7 @@
#include "nsILinkHandler.h"
#include "nsIStyleSet.h"
#include "nsFrameImageLoader.h"
#include "nsIFrameManager.h"
#include "nsIImageGroup.h"
#include "nsIFrame.h"
#include "nsIRenderingContext.h"
@ -454,6 +455,24 @@ nsPresContext::ProbePseudoStyleContextFor(nsIContent* aParentContent,
return rv;
}
NS_IMETHODIMP
nsPresContext::ReParentStyleContext(nsIFrame* aFrame,
nsIStyleContext* aNewParentContext)
{
NS_PRECONDITION(aFrame, "null ptr");
if (! aFrame) {
return NS_ERROR_NULL_POINTER;
}
nsCOMPtr<nsIFrameManager> manager;
nsresult rv = mShell->GetFrameManager(getter_AddRefs(manager));
if (NS_SUCCEEDED(rv) && manager) {
rv = manager->ReParentStyleContext(*this, aFrame, aNewParentContext);
}
return rv;
}
NS_IMETHODIMP
nsPresContext::GetMetricsFor(const nsFont& aFont, nsIFontMetrics** aResult)
{

Просмотреть файл

@ -64,6 +64,8 @@ public:
nsIStyleContext* aParentContext,
PRBool aForceUnique,
nsIStyleContext** aResult);
NS_IMETHOD ReParentStyleContext(nsIFrame* aFrame,
nsIStyleContext* aNewParentContext);
NS_IMETHOD GetMetricsFor(const nsFont& aFont, nsIFontMetrics** aResult);
NS_IMETHOD GetDefaultFont(nsFont& aResult);
NS_IMETHOD SetDefaultFont(nsFont& aFont);

Просмотреть файл

@ -80,6 +80,11 @@ public:
nsIStyleContext* aParentContext,
PRBool aForceUnique = PR_FALSE);
NS_IMETHOD ReParentStyleContext(nsIPresContext* aPresContext,
nsIStyleContext* aStyleContext,
nsIStyleContext* aNewParentContext,
nsIStyleContext** aNewStyleContext);
NS_IMETHOD HasStateDependentStyle(nsIPresContext* aPresContext,
nsIContent* aContent);
@ -726,6 +731,64 @@ nsIStyleContext* StyleSetImpl::ProbePseudoStyleFor(nsIPresContext* aPresContext,
return result;
}
NS_IMETHODIMP
StyleSetImpl::ReParentStyleContext(nsIPresContext* aPresContext,
nsIStyleContext* aStyleContext,
nsIStyleContext* aNewParentContext,
nsIStyleContext** aNewStyleContext)
{
NS_ASSERTION(aPresContext, "must have pres context");
NS_ASSERTION(aPresContext, "must have pres context");
NS_ASSERTION(aPresContext, "must have pres context");
nsresult result = NS_ERROR_NULL_POINTER;
if (aPresContext && aStyleContext && aNewStyleContext) {
nsIStyleContext* oldParent = aStyleContext->GetParent();
if (oldParent == aNewParentContext) {
result = NS_OK;
NS_ADDREF(aStyleContext); // for return
*aNewStyleContext = aStyleContext;
}
else { // really a new parent
nsIStyleContext* newChild = nsnull;
nsIAtom* pseudoTag = nsnull;
aStyleContext->GetPseudoType(pseudoTag);
nsISupportsArray* rules = aStyleContext->GetStyleRules();
if (aNewParentContext) {
result = aNewParentContext->FindChildWithRules(pseudoTag, rules, newChild);
}
if (newChild) { // new parent already has one
*aNewStyleContext = newChild;
}
else { // need to make one in the new parent
nsISupportsArray* newRules = nsnull;
if (rules) {
newRules = mRecycler;
mRecycler = nsnull;
if (! newRules) {
result = NS_NewISupportsArray(&newRules);
}
if (newRules) {
newRules->AppendElements(rules);
}
}
result = NS_NewStyleContext(aNewStyleContext, aNewParentContext, pseudoTag,
newRules, aPresContext);
NS_IF_RELEASE(newRules);
}
NS_IF_RELEASE(rules);
NS_IF_RELEASE(pseudoTag);
}
NS_IF_RELEASE(oldParent);
}
return result;
}
struct StatefulData {
StatefulData(nsIPresContext* aPresContext, nsIContent* aContent)
: mPresContext(aPresContext),

Просмотреть файл

@ -4308,10 +4308,8 @@ nsBlockFrame::FixParentAndView(nsIPresContext* aPresContext, nsIFrame* aFrame)
aFrame->SetParent(this);
if (this != oldParent) {
nsHTMLContainerFrame::ReparentFrameView(aFrame, oldParent, this);
aPresContext->ReParentStyleContext(aFrame, mStyleContext);
}
aFrame->ReResolveStyleContext(aPresContext, mStyleContext,
NS_STYLE_HINT_REFLOW,
nsnull, nsnull);
aFrame->GetNextSibling(&aFrame);
}
}

Просмотреть файл

@ -4308,10 +4308,8 @@ nsBlockFrame::FixParentAndView(nsIPresContext* aPresContext, nsIFrame* aFrame)
aFrame->SetParent(this);
if (this != oldParent) {
nsHTMLContainerFrame::ReparentFrameView(aFrame, oldParent, this);
aPresContext->ReParentStyleContext(aFrame, mStyleContext);
}
aFrame->ReResolveStyleContext(aPresContext, mStyleContext,
NS_STYLE_HINT_REFLOW,
nsnull, nsnull);
aFrame->GetNextSibling(&aFrame);
}
}

Просмотреть файл

@ -4308,10 +4308,8 @@ nsBlockFrame::FixParentAndView(nsIPresContext* aPresContext, nsIFrame* aFrame)
aFrame->SetParent(this);
if (this != oldParent) {
nsHTMLContainerFrame::ReparentFrameView(aFrame, oldParent, this);
aPresContext->ReParentStyleContext(aFrame, mStyleContext);
}
aFrame->ReResolveStyleContext(aPresContext, mStyleContext,
NS_STYLE_HINT_REFLOW,
nsnull, nsnull);
aFrame->GetNextSibling(&aFrame);
}
}

Просмотреть файл

@ -139,9 +139,7 @@ nsFirstLetterFrame::SetInitialChildList(nsIPresContext& aPresContext,
nsIFrame* aChildList)
{
mFrames.SetFrames(aChildList);
aChildList->ReResolveStyleContext(&aPresContext, mStyleContext,
NS_STYLE_HINT_REFLOW,
nsnull, nsnull);
aPresContext.ReParentStyleContext(aChildList, mStyleContext); // XXX only first frame?
return NS_OK;
}
@ -290,11 +288,9 @@ nsFirstLetterFrame::DrainOverflowFrames(nsIPresContext* aPresContext)
mFrames.AppendFrames(nsnull, mOverflowFrames);
}
// Now repair our first frames style context
// Now repair our first frames style context XXX only first frame?
nsIFrame* kid = mFrames.FirstChild();
if (kid) {
kid->ReResolveStyleContext(aPresContext, mStyleContext,
NS_STYLE_HINT_REFLOW,
nsnull, nsnull);
aPresContext->ReParentStyleContext(kid, mStyleContext);
}
}

Просмотреть файл

@ -1896,15 +1896,13 @@ nsInlineFrame::GetSkipSides() const
// nsLineFrame implementation
static void
ReResolveChildList(nsIPresContext* aPresContext,
nsIStyleContext* aParentStyleContext,
nsFrameList& aFrameList)
ReParentChildListStyle(nsIPresContext* aPresContext,
nsIStyleContext* aParentStyleContext,
nsFrameList& aFrameList)
{
nsIFrame* kid = aFrameList.FirstChild();
while (nsnull != kid) {
kid->ReResolveStyleContext(aPresContext, aParentStyleContext,
NS_STYLE_HINT_REFLOW,
nsnull, nsnull);
aPresContext->ReParentStyleContext(kid, aParentStyleContext);
kid->GetNextSibling(&kid);
}
}
@ -2002,7 +2000,7 @@ nsFirstLineFrame::AppendFrames2(nsIPresContext* aPresContext,
nsIFrame* aFrameList)
{
nsFrameList frames(aFrameList);
ReResolveChildList(aPresContext, mStyleContext, frames);
ReParentChildListStyle(aPresContext, mStyleContext, frames);
// XXX ReparentFrameView
mFrames.AppendFrames(this, aFrameList);
return NS_OK;
@ -2014,7 +2012,7 @@ nsFirstLineFrame::InsertFrames2(nsIPresContext* aPresContext,
nsIFrame* aFrameList)
{
nsFrameList frames(aFrameList);
ReResolveChildList(aPresContext, mStyleContext, frames);
ReParentChildListStyle(aPresContext, mStyleContext, frames);
// XXX ReparentFrameView
mFrames.InsertFrames(this, aPrevFrame, aFrameList);
return NS_OK;
@ -2056,8 +2054,7 @@ nsFirstLineFrame::PullInlineFrame(nsIPresContext* aPresContext,
if (frame && !mPrevInFlow) {
// We are a first-line frame. Fixup the child frames
// style-context that we just pulled.
frame->ReResolveStyleContext(aPresContext, mStyleContext,
NS_STYLE_HINT_REFLOW, nsnull, nsnull);
aPresContext->ReParentStyleContext(frame, mStyleContext);
}
return frame;
}
@ -2069,8 +2066,8 @@ nsFirstLineFrame::DrainOverflow(nsIPresContext* aPresContext)
nsFirstLineFrame* prevInFlow = (nsFirstLineFrame*)mPrevInFlow;
if (nsnull != prevInFlow) {
if (prevInFlow->mOverflowFrames.NotEmpty()) {
ReResolveChildList(aPresContext, mStyleContext,
prevInFlow->mOverflowFrames);
ReParentChildListStyle(aPresContext, mStyleContext,
prevInFlow->mOverflowFrames);
mFrames.InsertFrames(this, nsnull, prevInFlow->mOverflowFrames);
}
}
@ -2078,7 +2075,7 @@ nsFirstLineFrame::DrainOverflow(nsIPresContext* aPresContext)
// It's also possible that we have an overflow list for ourselves
if (mOverflowFrames.NotEmpty()) {
NS_ASSERTION(mFrames.NotEmpty(), "overflow list w/o frames");
ReResolveChildList(aPresContext, mStyleContext, mOverflowFrames);
ReParentChildListStyle(aPresContext, mStyleContext, mOverflowFrames);
mFrames.AppendFrames(nsnull, mOverflowFrames);
}
}
@ -2149,9 +2146,7 @@ nsFirstLineFrame::Reflow(nsIPresContext& aPresContext,
// Fixup style of frame just pulled up
nsIFrame* firstFrame = mFrames.FirstChild();
if (firstFrame) {
firstFrame->ReResolveStyleContext(&aPresContext, mStyleContext,
NS_STYLE_HINT_REFLOW, nsnull,
nsnull);
aPresContext.ReParentStyleContext(firstFrame, mStyleContext);
}
}
if (nsnull == mPrevInFlow) {
@ -2201,7 +2196,7 @@ nsFirstLineFrame::Reflow(nsIPresContext& aPresContext,
SetStyleContext(&aPresContext, newSC);
// Re-resolve all children
ReResolveChildList(&aPresContext, mStyleContext, mFrames);
ReParentChildListStyle(&aPresContext, mStyleContext, mFrames);
NS_RELEASE(newSC);
}

Просмотреть файл

@ -4308,10 +4308,8 @@ nsBlockFrame::FixParentAndView(nsIPresContext* aPresContext, nsIFrame* aFrame)
aFrame->SetParent(this);
if (this != oldParent) {
nsHTMLContainerFrame::ReparentFrameView(aFrame, oldParent, this);
aPresContext->ReParentStyleContext(aFrame, mStyleContext);
}
aFrame->ReResolveStyleContext(aPresContext, mStyleContext,
NS_STYLE_HINT_REFLOW,
nsnull, nsnull);
aFrame->GetNextSibling(&aFrame);
}
}

Просмотреть файл

@ -4308,10 +4308,8 @@ nsBlockFrame::FixParentAndView(nsIPresContext* aPresContext, nsIFrame* aFrame)
aFrame->SetParent(this);
if (this != oldParent) {
nsHTMLContainerFrame::ReparentFrameView(aFrame, oldParent, this);
aPresContext->ReParentStyleContext(aFrame, mStyleContext);
}
aFrame->ReResolveStyleContext(aPresContext, mStyleContext,
NS_STYLE_HINT_REFLOW,
nsnull, nsnull);
aFrame->GetNextSibling(&aFrame);
}
}

Просмотреть файл

@ -4308,10 +4308,8 @@ nsBlockFrame::FixParentAndView(nsIPresContext* aPresContext, nsIFrame* aFrame)
aFrame->SetParent(this);
if (this != oldParent) {
nsHTMLContainerFrame::ReparentFrameView(aFrame, oldParent, this);
aPresContext->ReParentStyleContext(aFrame, mStyleContext);
}
aFrame->ReResolveStyleContext(aPresContext, mStyleContext,
NS_STYLE_HINT_REFLOW,
nsnull, nsnull);
aFrame->GetNextSibling(&aFrame);
}
}

Просмотреть файл

@ -139,9 +139,7 @@ nsFirstLetterFrame::SetInitialChildList(nsIPresContext& aPresContext,
nsIFrame* aChildList)
{
mFrames.SetFrames(aChildList);
aChildList->ReResolveStyleContext(&aPresContext, mStyleContext,
NS_STYLE_HINT_REFLOW,
nsnull, nsnull);
aPresContext.ReParentStyleContext(aChildList, mStyleContext); // XXX only first frame?
return NS_OK;
}
@ -290,11 +288,9 @@ nsFirstLetterFrame::DrainOverflowFrames(nsIPresContext* aPresContext)
mFrames.AppendFrames(nsnull, mOverflowFrames);
}
// Now repair our first frames style context
// Now repair our first frames style context XXX only first frame?
nsIFrame* kid = mFrames.FirstChild();
if (kid) {
kid->ReResolveStyleContext(aPresContext, mStyleContext,
NS_STYLE_HINT_REFLOW,
nsnull, nsnull);
aPresContext->ReParentStyleContext(kid, mStyleContext);
}
}

Просмотреть файл

@ -20,6 +20,7 @@
#include "nsIPresContext.h"
#include "nsIPresShell.h"
#include "nsIStyleSet.h"
#include "nsIStyleContext.h"
#include "nsIEventQueueService.h"
#include "nsIServiceManager.h"
#include "nsCOMPtr.h"
@ -137,10 +138,13 @@ public:
NS_IMETHOD NotifyDestroyingFrame(nsIFrame* aFrame);
NS_IMETHOD ReParentStyleContext(nsIPresContext& aPresContext,
nsIFrame* aFrame,
nsIStyleContext* aNewParentContext);
NS_IMETHOD CaptureFrameState(nsIFrame* aFrame, nsILayoutHistoryState* aState);
NS_IMETHOD RestoreFrameState(nsIFrame* aFrame, nsILayoutHistoryState* aState);
private:
nsIPresShell* mPresShell; // weak link, because the pres shell owns us
nsIStyleSet* mStyleSet; // weak link. pres shell holds a reference
@ -564,6 +568,71 @@ FrameManager::CantRenderReplacedElement(nsIPresContext* aPresContext,
return rv;
}
NS_IMETHODIMP
FrameManager::ReParentStyleContext(nsIPresContext& aPresContext,
nsIFrame* aFrame,
nsIStyleContext* aNewParentContext)
{
nsresult result = NS_ERROR_NULL_POINTER;
if (aFrame) {
nsIStyleContext* oldContext = nsnull;
aFrame->GetStyleContext(&oldContext);
if (oldContext) {
nsIStyleContext* newContext = nsnull;
result = mStyleSet->ReParentStyleContext(&aPresContext,
oldContext, aNewParentContext,
&newContext);
if (NS_SUCCEEDED(result) && newContext) {
if (newContext != oldContext) {
PRInt32 listIndex = 0;
nsIAtom* childList = nsnull;
nsIFrame* child;
do {
child = nsnull;
result = aFrame->FirstChild(childList, &child);
while ((NS_SUCCEEDED(result)) && child) {
result = ReParentStyleContext(aPresContext, child, newContext);
child->GetNextSibling(&child);
}
NS_IF_RELEASE(childList);
aFrame->GetAdditionalChildListName(listIndex++, &childList);
} while (childList);
aFrame->SetStyleContext(&aPresContext, newContext);
// do additional contexts
PRInt32 contextIndex = -1;
while (1 == 1) {
nsIStyleContext* oldExtraContext = nsnull;
aFrame->GetAdditionalStyleContext(++contextIndex, &oldExtraContext);
if (oldExtraContext) {
nsIStyleContext* newExtraContext = nsnull;
result = mStyleSet->ReParentStyleContext(&aPresContext,
oldExtraContext, newContext,
&newExtraContext);
if (NS_SUCCEEDED(result) && newExtraContext) {
aFrame->SetAdditionalStyleContext(contextIndex, newExtraContext);
NS_RELEASE(newExtraContext);
}
NS_RELEASE(oldExtraContext);
}
else {
break;
}
}
}
NS_RELEASE(newContext);
}
NS_RELEASE(oldContext);
}
}
return result;
}
NS_IMETHODIMP
FrameManager::CaptureFrameState(nsIFrame* aFrame, nsILayoutHistoryState* aState)
{
@ -598,6 +667,7 @@ FrameManager::CaptureFrameState(nsIFrame* aFrame, nsILayoutHistoryState* aState)
// XXX We are only going through the principal child list right now.
// Need to talk to Troy to find out about other kinds of
// child lists and whether they will contain stateful frames.
// (psl) YES, you need to iterate ALL child lists
// Capture frame state for the first child
nsIFrame* child = nsnull;
@ -649,6 +719,7 @@ FrameManager::RestoreFrameState(nsIFrame* aFrame, nsILayoutHistoryState* aState)
// XXX We are only going through the principal child list right now.
// Need to talk to Troy to find out about other kinds of
// child lists and whether they will contain stateful frames.
// (psl) YES, you need to iterate ALL child lists
// Capture frame state for the first child
nsIFrame* child = nsnull;

Просмотреть файл

@ -1896,15 +1896,13 @@ nsInlineFrame::GetSkipSides() const
// nsLineFrame implementation
static void
ReResolveChildList(nsIPresContext* aPresContext,
nsIStyleContext* aParentStyleContext,
nsFrameList& aFrameList)
ReParentChildListStyle(nsIPresContext* aPresContext,
nsIStyleContext* aParentStyleContext,
nsFrameList& aFrameList)
{
nsIFrame* kid = aFrameList.FirstChild();
while (nsnull != kid) {
kid->ReResolveStyleContext(aPresContext, aParentStyleContext,
NS_STYLE_HINT_REFLOW,
nsnull, nsnull);
aPresContext->ReParentStyleContext(kid, aParentStyleContext);
kid->GetNextSibling(&kid);
}
}
@ -2002,7 +2000,7 @@ nsFirstLineFrame::AppendFrames2(nsIPresContext* aPresContext,
nsIFrame* aFrameList)
{
nsFrameList frames(aFrameList);
ReResolveChildList(aPresContext, mStyleContext, frames);
ReParentChildListStyle(aPresContext, mStyleContext, frames);
// XXX ReparentFrameView
mFrames.AppendFrames(this, aFrameList);
return NS_OK;
@ -2014,7 +2012,7 @@ nsFirstLineFrame::InsertFrames2(nsIPresContext* aPresContext,
nsIFrame* aFrameList)
{
nsFrameList frames(aFrameList);
ReResolveChildList(aPresContext, mStyleContext, frames);
ReParentChildListStyle(aPresContext, mStyleContext, frames);
// XXX ReparentFrameView
mFrames.InsertFrames(this, aPrevFrame, aFrameList);
return NS_OK;
@ -2056,8 +2054,7 @@ nsFirstLineFrame::PullInlineFrame(nsIPresContext* aPresContext,
if (frame && !mPrevInFlow) {
// We are a first-line frame. Fixup the child frames
// style-context that we just pulled.
frame->ReResolveStyleContext(aPresContext, mStyleContext,
NS_STYLE_HINT_REFLOW, nsnull, nsnull);
aPresContext->ReParentStyleContext(frame, mStyleContext);
}
return frame;
}
@ -2069,8 +2066,8 @@ nsFirstLineFrame::DrainOverflow(nsIPresContext* aPresContext)
nsFirstLineFrame* prevInFlow = (nsFirstLineFrame*)mPrevInFlow;
if (nsnull != prevInFlow) {
if (prevInFlow->mOverflowFrames.NotEmpty()) {
ReResolveChildList(aPresContext, mStyleContext,
prevInFlow->mOverflowFrames);
ReParentChildListStyle(aPresContext, mStyleContext,
prevInFlow->mOverflowFrames);
mFrames.InsertFrames(this, nsnull, prevInFlow->mOverflowFrames);
}
}
@ -2078,7 +2075,7 @@ nsFirstLineFrame::DrainOverflow(nsIPresContext* aPresContext)
// It's also possible that we have an overflow list for ourselves
if (mOverflowFrames.NotEmpty()) {
NS_ASSERTION(mFrames.NotEmpty(), "overflow list w/o frames");
ReResolveChildList(aPresContext, mStyleContext, mOverflowFrames);
ReParentChildListStyle(aPresContext, mStyleContext, mOverflowFrames);
mFrames.AppendFrames(nsnull, mOverflowFrames);
}
}
@ -2149,9 +2146,7 @@ nsFirstLineFrame::Reflow(nsIPresContext& aPresContext,
// Fixup style of frame just pulled up
nsIFrame* firstFrame = mFrames.FirstChild();
if (firstFrame) {
firstFrame->ReResolveStyleContext(&aPresContext, mStyleContext,
NS_STYLE_HINT_REFLOW, nsnull,
nsnull);
aPresContext.ReParentStyleContext(firstFrame, mStyleContext);
}
}
if (nsnull == mPrevInFlow) {
@ -2201,7 +2196,7 @@ nsFirstLineFrame::Reflow(nsIPresContext& aPresContext,
SetStyleContext(&aPresContext, newSC);
// Re-resolve all children
ReResolveChildList(&aPresContext, mStyleContext, mFrames);
ReParentChildListStyle(&aPresContext, mStyleContext, mFrames);
NS_RELEASE(newSC);
}

Просмотреть файл

@ -80,6 +80,11 @@ public:
nsIStyleContext* aParentContext,
PRBool aForceUnique = PR_FALSE);
NS_IMETHOD ReParentStyleContext(nsIPresContext* aPresContext,
nsIStyleContext* aStyleContext,
nsIStyleContext* aNewParentContext,
nsIStyleContext** aNewStyleContext);
NS_IMETHOD HasStateDependentStyle(nsIPresContext* aPresContext,
nsIContent* aContent);
@ -726,6 +731,64 @@ nsIStyleContext* StyleSetImpl::ProbePseudoStyleFor(nsIPresContext* aPresContext,
return result;
}
NS_IMETHODIMP
StyleSetImpl::ReParentStyleContext(nsIPresContext* aPresContext,
nsIStyleContext* aStyleContext,
nsIStyleContext* aNewParentContext,
nsIStyleContext** aNewStyleContext)
{
NS_ASSERTION(aPresContext, "must have pres context");
NS_ASSERTION(aPresContext, "must have pres context");
NS_ASSERTION(aPresContext, "must have pres context");
nsresult result = NS_ERROR_NULL_POINTER;
if (aPresContext && aStyleContext && aNewStyleContext) {
nsIStyleContext* oldParent = aStyleContext->GetParent();
if (oldParent == aNewParentContext) {
result = NS_OK;
NS_ADDREF(aStyleContext); // for return
*aNewStyleContext = aStyleContext;
}
else { // really a new parent
nsIStyleContext* newChild = nsnull;
nsIAtom* pseudoTag = nsnull;
aStyleContext->GetPseudoType(pseudoTag);
nsISupportsArray* rules = aStyleContext->GetStyleRules();
if (aNewParentContext) {
result = aNewParentContext->FindChildWithRules(pseudoTag, rules, newChild);
}
if (newChild) { // new parent already has one
*aNewStyleContext = newChild;
}
else { // need to make one in the new parent
nsISupportsArray* newRules = nsnull;
if (rules) {
newRules = mRecycler;
mRecycler = nsnull;
if (! newRules) {
result = NS_NewISupportsArray(&newRules);
}
if (newRules) {
newRules->AppendElements(rules);
}
}
result = NS_NewStyleContext(aNewStyleContext, aNewParentContext, pseudoTag,
newRules, aPresContext);
NS_IF_RELEASE(newRules);
}
NS_IF_RELEASE(rules);
NS_IF_RELEASE(pseudoTag);
}
NS_IF_RELEASE(oldParent);
}
return result;
}
struct StatefulData {
StatefulData(nsIPresContext* aPresContext, nsIContent* aContent)
: mPresContext(aPresContext),