r=troy. Siblings of frames get traversed iteratively during capturing/restoring of state. Earlier they were traversed recursively which was causing the call stack to grow too large.

This commit is contained in:
nisheeth%netscape.com 1999-10-23 01:43:49 +00:00
Родитель 1f43c92e4f
Коммит 2b68bfc6a2
2 изменённых файлов: 118 добавлений и 82 удалений

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

@ -1349,14 +1349,16 @@ FrameManager::ComputeStyleChangeFor(nsIPresContext& aPresContext,
} }
NS_IMETHODIMP static nsresult
FrameManager::CaptureFrameState(nsIFrame* aFrame, nsILayoutHistoryState* aState) CaptureFrameStateFor(nsIFrame* aFrame, nsILayoutHistoryState* aState)
{ {
nsresult rv = NS_OK; nsresult rv = NS_OK;
NS_PRECONDITION(nsnull != aFrame && nsnull != aState, "null parameters passed in"); NS_PRECONDITION(nsnull != aFrame && nsnull != aState, "null parameters passed in");
// See if the frame is stateful. // See if the frame is stateful.
nsCOMPtr<nsIStatefulFrame> statefulFrame = do_QueryInterface(aFrame); // Frames are not ref-counted so no addref/release is required on statefulFrame.
nsIStatefulFrame* statefulFrame = nsnull;
aFrame->QueryInterface(nsIStatefulFrame::GetIID(), (void**) &statefulFrame);
if (nsnull != statefulFrame) { if (nsnull != statefulFrame) {
// If so, get the content ID, state type and the state and // If so, get the content ID, state type and the state and
// add an association between (ID, type) and (state) to the // add an association between (ID, type) and (state) to the
@ -1380,36 +1382,45 @@ 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;
rv = aFrame->FirstChild(nsnull, &child);
if (NS_SUCCEEDED(rv) && nsnull != child) {
rv = CaptureFrameState(child, aState);
}
// Capture frame state for the next sibling
nsIFrame* sibling = nsnull;
rv = aFrame->GetNextSibling(&sibling);
if (NS_SUCCEEDED(rv) && nsnull != sibling) {
rv = CaptureFrameState(sibling, aState);
}
return rv; return rv;
} }
NS_IMETHODIMP NS_IMETHODIMP
FrameManager::RestoreFrameState(nsIFrame* aFrame, nsILayoutHistoryState* aState) FrameManager::CaptureFrameState(nsIFrame* aFrame, nsILayoutHistoryState* aState)
{
nsresult rv = NS_OK;
NS_PRECONDITION(nsnull != aFrame && nsnull != aState, "null parameters passed in");
rv = CaptureFrameStateFor(aFrame, aState);
// Now capture state recursively for the frame hierarchy rooted at aFrame
nsIAtom* childListName = nsnull;
PRInt32 childListIndex = 0;
do {
nsIFrame* childFrame;
aFrame->FirstChild(childListName, &childFrame);
while (childFrame) {
rv = CaptureFrameState(childFrame, aState);
// Get the next sibling child frame
childFrame->GetNextSibling(&childFrame);
}
NS_IF_RELEASE(childListName);
aFrame->GetAdditionalChildListName(childListIndex++, &childListName);
} while (childListName);
return rv;
}
static nsresult
RestoreFrameStateFor(nsIFrame* aFrame, nsILayoutHistoryState* aState)
{ {
nsresult rv = NS_OK; nsresult rv = NS_OK;
NS_PRECONDITION(nsnull != aFrame && nsnull != aState, "null parameters passed in"); NS_PRECONDITION(nsnull != aFrame && nsnull != aState, "null parameters passed in");
// See if the frame is stateful. // See if the frame is stateful.
nsCOMPtr<nsIStatefulFrame> statefulFrame = do_QueryInterface(aFrame); // Frames are not ref-counted so no addref/release is required on statefulFrame.
nsIStatefulFrame* statefulFrame = nsnull;
aFrame->QueryInterface(nsIStatefulFrame::GetIID(), (void**) &statefulFrame);
if (nsnull != statefulFrame) { if (nsnull != statefulFrame) {
// If so, get the content ID, state type and the frame state and // If so, get the content ID, state type and the frame state and
// ask the frame object to restore its state. // ask the frame object to restore its state.
@ -1430,26 +1441,33 @@ FrameManager::RestoreFrameState(nsIFrame* aFrame, nsILayoutHistoryState* aState)
} }
} }
} }
} }
// XXX We are only going through the principal child list right now. return rv;
// 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 NS_IMETHODIMP
nsIFrame* child = nsnull; FrameManager::RestoreFrameState(nsIFrame* aFrame, nsILayoutHistoryState* aState)
rv = aFrame->FirstChild(nsnull, &child); {
if (NS_SUCCEEDED(rv) && nsnull != child) { nsresult rv = NS_OK;
rv = RestoreFrameState(child, aState); NS_PRECONDITION(nsnull != aFrame && nsnull != aState, "null parameters passed in");
}
rv = RestoreFrameStateFor(aFrame, aState);
// Capture frame state for the next sibling // Now restore state recursively for the frame hierarchy rooted at aFrame
nsIFrame* sibling = nsnull; nsIAtom* childListName = nsnull;
rv = aFrame->GetNextSibling(&sibling); PRInt32 childListIndex = 0;
if (NS_SUCCEEDED(rv) && nsnull != sibling) { do {
rv = RestoreFrameState(sibling, aState); nsIFrame* childFrame;
} aFrame->FirstChild(childListName, &childFrame);
while (childFrame) {
rv = RestoreFrameState(childFrame, aState);
// Get the next sibling child frame
childFrame->GetNextSibling(&childFrame);
}
NS_IF_RELEASE(childListName);
aFrame->GetAdditionalChildListName(childListIndex++, &childListName);
} while (childListName);
return rv; return rv;
} }

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

@ -1349,14 +1349,16 @@ FrameManager::ComputeStyleChangeFor(nsIPresContext& aPresContext,
} }
NS_IMETHODIMP static nsresult
FrameManager::CaptureFrameState(nsIFrame* aFrame, nsILayoutHistoryState* aState) CaptureFrameStateFor(nsIFrame* aFrame, nsILayoutHistoryState* aState)
{ {
nsresult rv = NS_OK; nsresult rv = NS_OK;
NS_PRECONDITION(nsnull != aFrame && nsnull != aState, "null parameters passed in"); NS_PRECONDITION(nsnull != aFrame && nsnull != aState, "null parameters passed in");
// See if the frame is stateful. // See if the frame is stateful.
nsCOMPtr<nsIStatefulFrame> statefulFrame = do_QueryInterface(aFrame); // Frames are not ref-counted so no addref/release is required on statefulFrame.
nsIStatefulFrame* statefulFrame = nsnull;
aFrame->QueryInterface(nsIStatefulFrame::GetIID(), (void**) &statefulFrame);
if (nsnull != statefulFrame) { if (nsnull != statefulFrame) {
// If so, get the content ID, state type and the state and // If so, get the content ID, state type and the state and
// add an association between (ID, type) and (state) to the // add an association between (ID, type) and (state) to the
@ -1380,36 +1382,45 @@ 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;
rv = aFrame->FirstChild(nsnull, &child);
if (NS_SUCCEEDED(rv) && nsnull != child) {
rv = CaptureFrameState(child, aState);
}
// Capture frame state for the next sibling
nsIFrame* sibling = nsnull;
rv = aFrame->GetNextSibling(&sibling);
if (NS_SUCCEEDED(rv) && nsnull != sibling) {
rv = CaptureFrameState(sibling, aState);
}
return rv; return rv;
} }
NS_IMETHODIMP NS_IMETHODIMP
FrameManager::RestoreFrameState(nsIFrame* aFrame, nsILayoutHistoryState* aState) FrameManager::CaptureFrameState(nsIFrame* aFrame, nsILayoutHistoryState* aState)
{
nsresult rv = NS_OK;
NS_PRECONDITION(nsnull != aFrame && nsnull != aState, "null parameters passed in");
rv = CaptureFrameStateFor(aFrame, aState);
// Now capture state recursively for the frame hierarchy rooted at aFrame
nsIAtom* childListName = nsnull;
PRInt32 childListIndex = 0;
do {
nsIFrame* childFrame;
aFrame->FirstChild(childListName, &childFrame);
while (childFrame) {
rv = CaptureFrameState(childFrame, aState);
// Get the next sibling child frame
childFrame->GetNextSibling(&childFrame);
}
NS_IF_RELEASE(childListName);
aFrame->GetAdditionalChildListName(childListIndex++, &childListName);
} while (childListName);
return rv;
}
static nsresult
RestoreFrameStateFor(nsIFrame* aFrame, nsILayoutHistoryState* aState)
{ {
nsresult rv = NS_OK; nsresult rv = NS_OK;
NS_PRECONDITION(nsnull != aFrame && nsnull != aState, "null parameters passed in"); NS_PRECONDITION(nsnull != aFrame && nsnull != aState, "null parameters passed in");
// See if the frame is stateful. // See if the frame is stateful.
nsCOMPtr<nsIStatefulFrame> statefulFrame = do_QueryInterface(aFrame); // Frames are not ref-counted so no addref/release is required on statefulFrame.
nsIStatefulFrame* statefulFrame = nsnull;
aFrame->QueryInterface(nsIStatefulFrame::GetIID(), (void**) &statefulFrame);
if (nsnull != statefulFrame) { if (nsnull != statefulFrame) {
// If so, get the content ID, state type and the frame state and // If so, get the content ID, state type and the frame state and
// ask the frame object to restore its state. // ask the frame object to restore its state.
@ -1430,26 +1441,33 @@ FrameManager::RestoreFrameState(nsIFrame* aFrame, nsILayoutHistoryState* aState)
} }
} }
} }
} }
// XXX We are only going through the principal child list right now. return rv;
// 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 NS_IMETHODIMP
nsIFrame* child = nsnull; FrameManager::RestoreFrameState(nsIFrame* aFrame, nsILayoutHistoryState* aState)
rv = aFrame->FirstChild(nsnull, &child); {
if (NS_SUCCEEDED(rv) && nsnull != child) { nsresult rv = NS_OK;
rv = RestoreFrameState(child, aState); NS_PRECONDITION(nsnull != aFrame && nsnull != aState, "null parameters passed in");
}
rv = RestoreFrameStateFor(aFrame, aState);
// Capture frame state for the next sibling // Now restore state recursively for the frame hierarchy rooted at aFrame
nsIFrame* sibling = nsnull; nsIAtom* childListName = nsnull;
rv = aFrame->GetNextSibling(&sibling); PRInt32 childListIndex = 0;
if (NS_SUCCEEDED(rv) && nsnull != sibling) { do {
rv = RestoreFrameState(sibling, aState); nsIFrame* childFrame;
} aFrame->FirstChild(childListName, &childFrame);
while (childFrame) {
rv = RestoreFrameState(childFrame, aState);
// Get the next sibling child frame
childFrame->GetNextSibling(&childFrame);
}
NS_IF_RELEASE(childListName);
aFrame->GetAdditionalChildListName(childListIndex++, &childListName);
} while (childListName);
return rv; return rv;
} }