mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-23 10:54:33 +00:00
bug 127286 (part II due to cvs problems) - Handle splitting of floaters when lines impacting them are outside the block containing the floaters. sr=kin, r=alexsavulov
This commit is contained in:
parent
fe81ae2252
commit
0f0042a430
@ -371,10 +371,10 @@ public:
|
||||
nsIAtom* aPropertyName,
|
||||
PRUint32 aOptions,
|
||||
void** aPropertyValue);
|
||||
NS_IMETHOD SetFrameProperty(nsIFrame* aFrame,
|
||||
nsIAtom* aPropertyName,
|
||||
void* aPropertyValue,
|
||||
NSFMPropertyDtorFunc aPropDtorFunc);
|
||||
NS_IMETHOD SetFrameProperty(nsIFrame* aFrame,
|
||||
nsIAtom* aPropertyName,
|
||||
void* aPropertyValue,
|
||||
NSFramePropertyDtorFunc aPropDtorFunc);
|
||||
NS_IMETHOD RemoveFrameProperty(nsIFrame* aFrame,
|
||||
nsIAtom* aPropertyName);
|
||||
|
||||
@ -383,13 +383,13 @@ public:
|
||||
#endif
|
||||
|
||||
struct PropertyList {
|
||||
nsCOMPtr<nsIAtom> mName; // property name
|
||||
PLDHashTable mFrameValueMap; // map of frame/value pairs
|
||||
NSFMPropertyDtorFunc mDtorFunc; // property specific value dtor function
|
||||
PropertyList* mNext;
|
||||
nsCOMPtr<nsIAtom> mName; // property name
|
||||
PLDHashTable mFrameValueMap; // map of frame/value pairs
|
||||
NSFramePropertyDtorFunc mDtorFunc; // property specific value dtor function
|
||||
PropertyList* mNext;
|
||||
|
||||
PropertyList(nsIAtom* aName,
|
||||
NSFMPropertyDtorFunc aDtorFunc);
|
||||
PropertyList(nsIAtom* aName,
|
||||
NSFramePropertyDtorFunc aDtorFunc);
|
||||
~PropertyList();
|
||||
|
||||
// Removes the property associated with the given frame, and destroys
|
||||
@ -2452,10 +2452,10 @@ FrameManager::GetFrameProperty(nsIFrame* aFrame,
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FrameManager::SetFrameProperty(nsIFrame* aFrame,
|
||||
nsIAtom* aPropertyName,
|
||||
void* aPropertyValue,
|
||||
NSFMPropertyDtorFunc aPropDtorFunc)
|
||||
FrameManager::SetFrameProperty(nsIFrame* aFrame,
|
||||
nsIAtom* aPropertyName,
|
||||
void* aPropertyValue,
|
||||
NSFramePropertyDtorFunc aPropDtorFunc)
|
||||
{
|
||||
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE);
|
||||
NS_PRECONDITION(aPropertyName && aFrame, "unexpected null param");
|
||||
@ -2667,8 +2667,8 @@ UndisplayedMap::Clear(void)
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
FrameManager::PropertyList::PropertyList(nsIAtom* aName,
|
||||
NSFMPropertyDtorFunc aDtorFunc)
|
||||
FrameManager::PropertyList::PropertyList(nsIAtom* aName,
|
||||
NSFramePropertyDtorFunc aDtorFunc)
|
||||
: mName(aName), mDtorFunc(aDtorFunc), mNext(nsnull)
|
||||
{
|
||||
PL_DHashTableInit(&mFrameValueMap, PL_DHashGetStubOps(), this,
|
||||
|
@ -90,6 +90,13 @@ struct nsRect;
|
||||
struct nsSize;
|
||||
struct nsMargin;
|
||||
|
||||
// Calback function used to destroy the value associated with a property.
|
||||
typedef void
|
||||
(*NSFramePropertyDtorFunc)(nsIPresContext* aPresContext,
|
||||
nsIFrame* aFrame,
|
||||
nsIAtom* aPropertyName,
|
||||
void* aPropertyValue);
|
||||
|
||||
// IID for the nsIFrame interface
|
||||
// a6cf9050-15b3-11d2-932e-00805f8add32
|
||||
#define NS_IFRAME_IID \
|
||||
@ -1158,6 +1165,14 @@ public:
|
||||
PRBool aIsPre,
|
||||
PRBool* aResult) = 0;
|
||||
|
||||
virtual void* GetProperty(nsIPresContext* aPresContext,
|
||||
nsIAtom* aPropertyName,
|
||||
PRBool aRemoveProperty) const = 0;
|
||||
|
||||
virtual nsresult SetProperty(nsIPresContext* aPresContext,
|
||||
nsIAtom* aPropertyName,
|
||||
void* aPropertyValue,
|
||||
NSFramePropertyDtorFunc aPropDtorFunc) = 0;
|
||||
#ifdef IBMBIDI
|
||||
/**
|
||||
* retrieve and set Bidi property of this frame
|
||||
|
@ -41,10 +41,10 @@
|
||||
#include "nsIStatefulFrame.h"
|
||||
#include "nsString.h"
|
||||
#include "nsChangeHint.h"
|
||||
#include "nsIFrame.h"
|
||||
|
||||
class nsIAtom;
|
||||
class nsIContent;
|
||||
class nsIFrame;
|
||||
class nsIPresContext;
|
||||
class nsIPresShell;
|
||||
class nsIStyleSet;
|
||||
@ -57,14 +57,6 @@ class nsPlaceholderFrame;
|
||||
{ 0xa6cf9107, 0x15b3, 0x11d2, \
|
||||
{0x93, 0x2e, 0x00, 0x80, 0x5f, 0x8a, 0xdd, 0x32} }
|
||||
|
||||
// Calback function used to destroy the value associated with a
|
||||
// given property. used by RemoveFrameProperty()
|
||||
typedef void
|
||||
(*NSFMPropertyDtorFunc)(nsIPresContext* aPresContext,
|
||||
nsIFrame* aFrame,
|
||||
nsIAtom* aPropertyName,
|
||||
void* aPropertyValue);
|
||||
|
||||
// Option flags for GetFrameProperty() member function
|
||||
#define NS_IFRAME_MGR_REMOVE_PROP 0x0001
|
||||
|
||||
@ -233,10 +225,10 @@ public:
|
||||
* NS_ERROR_INVALID_ARG if the dtor function does not match the
|
||||
* existing dtor function
|
||||
*/
|
||||
NS_IMETHOD SetFrameProperty(nsIFrame* aFrame,
|
||||
nsIAtom* aPropertyName,
|
||||
void* aPropertyValue,
|
||||
NSFMPropertyDtorFunc aPropertyDtorFunc) = 0;
|
||||
NS_IMETHOD SetFrameProperty(nsIFrame* aFrame,
|
||||
nsIAtom* aPropertyName,
|
||||
void* aPropertyValue,
|
||||
NSFramePropertyDtorFunc aPropertyDtorFunc) = 0;
|
||||
|
||||
/**
|
||||
* Removes a property and destroys its property value by calling the dtor
|
||||
|
@ -945,42 +945,78 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "reflow dirty lines failed");
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// Put continued floaters at the beginning of the first overflow line. If the first line
|
||||
// is a block then create a new line as the first line and put the floaters there. If there
|
||||
// are no overflow lines, then create one and put the floaters in it.
|
||||
if (state.mOverflowFloaters.NotEmpty()) {
|
||||
nsLineList* overflowLines = GetOverflowLines(aPresContext, PR_FALSE);
|
||||
if (overflowLines) {
|
||||
line_iterator firstLine = overflowLines->begin();
|
||||
if (firstLine->IsBlock()) { // floaters go on a new line before 1st overflow line
|
||||
nsLineBox* newLine = state.NewLineBox(state.mOverflowFloaters.FirstChild(),
|
||||
state.mOverflowFloaters.GetLength(), PR_FALSE);
|
||||
firstLine = mLines.before_insert(firstLine, newLine);
|
||||
}
|
||||
else { // floaters go on 1st overflow line
|
||||
nsIFrame* firstFrame = firstLine->mFirstChild;
|
||||
firstLine->mFirstChild = state.mOverflowFloaters.FirstChild();
|
||||
PRInt32 numOverflowFloaters = state.mOverflowFloaters.GetLength();
|
||||
// hook up the last placeholder with the original frames
|
||||
nsPlaceholderFrame* lastPlaceholder =
|
||||
(nsPlaceholderFrame*)state.mOverflowFloaters.LastChild();
|
||||
lastPlaceholder->SetNextSibling(firstFrame);
|
||||
NS_ASSERTION(firstFrame != lastPlaceholder, "trying to set next sibling to self");
|
||||
firstLine->SetChildCount(firstLine->GetChildCount() + numOverflowFloaters);
|
||||
// If the block is complete, put continuted floaters in the closest ancestor
|
||||
// block that uses the same space manager and leave the block complete; this
|
||||
// allows subsequent lines on the page to be impacted by floaters. If the
|
||||
// block is incomplete or there is no ancestor using the same space manager,
|
||||
// put continued floaters at the beginning of the first overflow line.
|
||||
nsFrameList* overflowPlace = nsnull;
|
||||
if ((NS_UNCONSTRAINEDSIZE != aReflowState.availableHeight) &&
|
||||
(overflowPlace = GetOverflowPlaceholders(aPresContext, PR_TRUE))) {
|
||||
PRBool gaveToAncestor = PR_FALSE;
|
||||
if (NS_FRAME_IS_COMPLETE(state.mReflowStatus)) {
|
||||
// find the nearest block ancestor that uses the same space manager
|
||||
for (const nsHTMLReflowState* ancestorRS = aReflowState.parentReflowState;
|
||||
ancestorRS;
|
||||
ancestorRS = ancestorRS->parentReflowState) {
|
||||
nsIFrame* ancestor = ancestorRS->frame;
|
||||
nsCOMPtr<nsIAtom> fType;
|
||||
ancestor->GetFrameType(getter_AddRefs(fType));
|
||||
if ((nsLayoutAtoms::blockFrame == fType) || (nsLayoutAtoms::areaFrame == fType)) {
|
||||
if (aReflowState.mSpaceManager == ancestorRS->mSpaceManager) {
|
||||
// Put the continued floaters in ancestor since it uses the same space manager
|
||||
nsFrameList* ancestorPlace =
|
||||
((nsBlockFrame*)ancestor)->GetOverflowPlaceholders(aPresContext, PR_FALSE);
|
||||
if (ancestorPlace) {
|
||||
ancestorPlace->AppendFrames(ancestor, overflowPlace->FirstChild());
|
||||
}
|
||||
else {
|
||||
ancestorPlace = new nsFrameList(overflowPlace->FirstChild());
|
||||
if (ancestorPlace) {
|
||||
((nsBlockFrame*)ancestor)->SetOverflowPlaceholders(aPresContext, ancestorPlace);
|
||||
}
|
||||
else
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
gaveToAncestor = PR_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Create a line, put the floaters in it, and then push.
|
||||
nsLineBox* newLine = state.NewLineBox(state.mOverflowFloaters.FirstChild(),
|
||||
state.mOverflowFloaters.GetLength(), PR_FALSE);
|
||||
if (!newLine)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
mLines.push_back(newLine);
|
||||
nsLineList::iterator nextToLastLine = ----end_lines();
|
||||
PushLines(state, nextToLastLine);
|
||||
if (!gaveToAncestor) {
|
||||
PRInt32 numOverflowPlace = overflowPlace->GetLength();
|
||||
nsLineList* overflowLines = GetOverflowLines(aPresContext, PR_FALSE);
|
||||
if (overflowLines) {
|
||||
line_iterator firstLine = overflowLines->begin();
|
||||
if (firstLine->IsBlock()) {
|
||||
// Create a new line as the first line and put the floaters there;
|
||||
nsLineBox* newLine = state.NewLineBox(overflowPlace->FirstChild(), numOverflowPlace, PR_FALSE);
|
||||
firstLine = mLines.before_insert(firstLine, newLine);
|
||||
}
|
||||
else { // floaters go on 1st overflow line
|
||||
nsIFrame* firstFrame = firstLine->mFirstChild;
|
||||
firstLine->mFirstChild = overflowPlace->FirstChild();
|
||||
// hook up the last placeholder with the original frames
|
||||
nsPlaceholderFrame* lastPlaceholder =
|
||||
(nsPlaceholderFrame*)overflowPlace->LastChild();
|
||||
lastPlaceholder->SetNextSibling(firstFrame);
|
||||
NS_ASSERTION(firstFrame != lastPlaceholder, "trying to set next sibling to self");
|
||||
firstLine->SetChildCount(firstLine->GetChildCount() + numOverflowPlace);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Create a line, put the floaters in it, and then push.
|
||||
nsLineBox* newLine = state.NewLineBox(overflowPlace->FirstChild(), numOverflowPlace, PR_FALSE);
|
||||
if (!newLine)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
mLines.push_back(newLine);
|
||||
nsLineList::iterator nextToLastLine = ----end_lines();
|
||||
PushLines(state, nextToLastLine);
|
||||
}
|
||||
state.mReflowStatus = NS_FRAME_NOT_COMPLETE;
|
||||
}
|
||||
state.mReflowStatus = NS_FRAME_NOT_COMPLETE;
|
||||
state.mOverflowFloaters.SetFrames(nsnull);
|
||||
delete overflowPlace;
|
||||
}
|
||||
|
||||
if (NS_FRAME_IS_NOT_COMPLETE(state.mReflowStatus)) {
|
||||
@ -3151,9 +3187,9 @@ nsBlockFrame::GetTopBlockChild(nsIPresContext* aPresContext)
|
||||
// If placeholders/floaters split during reflowing a line, but that line will
|
||||
// be put on the next page, then put the placeholders/floaters back the way
|
||||
// they were before the line was reflowed.
|
||||
static void
|
||||
UndoPlaceholders(nsBlockReflowState& aState,
|
||||
nsIFrame* aLastPlaceholder)
|
||||
void
|
||||
nsBlockFrame::UndoSplitPlaceholders(nsBlockReflowState& aState,
|
||||
nsIFrame* aLastPlaceholder)
|
||||
{
|
||||
nsIFrame* undoPlaceholder = nsnull;
|
||||
if (aLastPlaceholder) {
|
||||
@ -3161,8 +3197,9 @@ UndoPlaceholders(nsBlockReflowState& aState,
|
||||
aLastPlaceholder->SetNextSibling(nsnull);
|
||||
}
|
||||
else {
|
||||
undoPlaceholder = aState.mOverflowFloaters.FirstChild();
|
||||
aState.mOverflowFloaters.SetFrames(nsnull);
|
||||
// just remove the property
|
||||
nsFrameList* overflowPlace = GetOverflowPlaceholders(aState.mPresContext, PR_TRUE);
|
||||
delete overflowPlace;
|
||||
}
|
||||
// remove the next in flows of the placeholders that need to be removed
|
||||
for (nsIFrame* placeholder = undoPlaceholder; placeholder; ) {
|
||||
@ -3320,7 +3357,8 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState,
|
||||
}
|
||||
|
||||
// keep track of the last overflow floater in case we need to undo any new additions
|
||||
nsIFrame* lastPlaceholder = aState.mOverflowFloaters.LastChild();
|
||||
nsFrameList* overflowPlace = GetOverflowPlaceholders(aState.mPresContext, PR_FALSE);
|
||||
nsIFrame* lastPlaceholder = (overflowPlace) ? overflowPlace->LastChild() : nsnull;
|
||||
|
||||
// Reflow the block into the available space
|
||||
nsReflowStatus frameReflowStatus=NS_FRAME_COMPLETE;
|
||||
@ -3353,7 +3391,7 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState,
|
||||
|
||||
if (NS_INLINE_IS_BREAK_BEFORE(frameReflowStatus)) {
|
||||
// None of the child block fits.
|
||||
::UndoPlaceholders(aState, lastPlaceholder);
|
||||
UndoSplitPlaceholders(aState, lastPlaceholder);
|
||||
PushLines(aState, aLine.prev());
|
||||
*aKeepReflowGoing = PR_FALSE;
|
||||
aState.mReflowStatus = NS_FRAME_NOT_COMPLETE;
|
||||
@ -3530,7 +3568,7 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState,
|
||||
else {
|
||||
// Push the line that didn't fit and any lines that follow it
|
||||
// to our next-in-flow.
|
||||
::UndoPlaceholders(aState, lastPlaceholder);
|
||||
UndoSplitPlaceholders(aState, lastPlaceholder);
|
||||
PushLines(aState, aLine.prev());
|
||||
aState.mReflowStatus = NS_FRAME_NOT_COMPLETE;
|
||||
}
|
||||
@ -3644,7 +3682,7 @@ nsBlockFrame::PushTruncatedPlaceholderLine(nsBlockReflowState& aState,
|
||||
nsIFrame* aLastPlaceholder,
|
||||
PRBool& aKeepReflowGoing)
|
||||
{
|
||||
::UndoPlaceholders(aState, aLastPlaceholder);
|
||||
UndoSplitPlaceholders(aState, aLastPlaceholder);
|
||||
|
||||
line_iterator prevLine = aLine;
|
||||
--prevLine;
|
||||
@ -3716,7 +3754,8 @@ nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState& aState,
|
||||
}
|
||||
|
||||
// keep track of the last overflow floater in case we need to undo any new additions
|
||||
nsIFrame* lastPlaceholder = aState.mOverflowFloaters.LastChild();
|
||||
nsFrameList* overflowPlace = GetOverflowPlaceholders(aState.mPresContext, PR_FALSE);
|
||||
nsIFrame* lastPlaceholder = (overflowPlace) ? overflowPlace->LastChild() : nsnull;
|
||||
|
||||
// Reflow the frames that are already on the line first
|
||||
nsresult rv = NS_OK;
|
||||
@ -3814,7 +3853,7 @@ nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState& aState,
|
||||
// no point in placing the line.
|
||||
if (!NS_INLINE_IS_BREAK_BEFORE(aState.mReflowStatus)) {
|
||||
if (PlaceLine(aState, aLineLayout, aLine, aKeepReflowGoing, aUpdateMaximumWidth)) {
|
||||
::UndoPlaceholders(aState, lastPlaceholder); // undo since we pushed the current line
|
||||
UndoSplitPlaceholders(aState, lastPlaceholder); // undo since we pushed the current line
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3991,7 +4030,7 @@ nsBlockFrame::ReflowInlineFrame(nsBlockReflowState& aState,
|
||||
// frame may already have a continuation.
|
||||
PRBool madeContinuation;
|
||||
rv = (nsLayoutAtoms::placeholderFrame == frameType)
|
||||
? SplitPlaceholder(aState, *aFrame)
|
||||
? SplitPlaceholder(*aState.mPresContext, *aFrame)
|
||||
: CreateContinuationFor(aState, aLine, aFrame, madeContinuation);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
@ -4070,11 +4109,11 @@ nsBlockFrame::CreateContinuationFor(nsBlockReflowState& aState,
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsBlockFrame::SplitPlaceholder(nsBlockReflowState& aState,
|
||||
nsIFrame& aPlaceholder)
|
||||
nsBlockFrame::SplitPlaceholder(nsIPresContext& aPresContext,
|
||||
nsIFrame& aPlaceholder)
|
||||
{
|
||||
nsIFrame* nextInFlow;
|
||||
nsresult rv = CreateNextInFlow(aState.mPresContext, this, &aPlaceholder, nextInFlow);
|
||||
nsresult rv = CreateNextInFlow(&aPresContext, this, &aPlaceholder, nextInFlow);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
// put the sibling list back to what it was before the continuation was created
|
||||
@ -4084,7 +4123,17 @@ nsBlockFrame::SplitPlaceholder(nsBlockReflowState& aState,
|
||||
aPlaceholder.SetNextSibling(next);
|
||||
contFrame->SetNextSibling(nsnull);
|
||||
// add the placehoder to the overflow floaters
|
||||
aState.mOverflowFloaters.AppendFrames(this, contFrame);
|
||||
nsFrameList* overflowPlace = GetOverflowPlaceholders(&aPresContext, PR_FALSE);
|
||||
if (overflowPlace) {
|
||||
overflowPlace->AppendFrames(this, contFrame);
|
||||
}
|
||||
else {
|
||||
overflowPlace = new nsFrameList(contFrame);
|
||||
if (overflowPlace) {
|
||||
SetOverflowPlaceholders(&aPresContext, overflowPlace);
|
||||
}
|
||||
else return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -4415,7 +4464,8 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState,
|
||||
// Any below current line floaters to place?
|
||||
if (aState.mBelowCurrentLineFloaters.NotEmpty()) {
|
||||
// keep track of the last overflow floater in case we need to undo and push the line
|
||||
nsIFrame* lastPlaceholder = aState.mOverflowFloaters.LastChild();
|
||||
nsFrameList* overflowPlace = GetOverflowPlaceholders(aState.mPresContext, PR_FALSE);
|
||||
nsIFrame* lastPlaceholder = (overflowPlace) ? overflowPlace->LastChild() : nsnull;
|
||||
// Reflow the below-current-line floaters, then add them to the
|
||||
// lines floater list if there aren't any truncated floaters.
|
||||
if (aState.PlaceBelowCurrentLineFloaters(aState.mBelowCurrentLineFloaters)) {
|
||||
@ -4739,31 +4789,12 @@ nsLineList*
|
||||
nsBlockFrame::GetOverflowLines(nsIPresContext* aPresContext,
|
||||
PRBool aRemoveProperty) const
|
||||
{
|
||||
nsCOMPtr<nsIPresShell> presShell;
|
||||
aPresContext->GetShell(getter_AddRefs(presShell));
|
||||
|
||||
if (presShell) {
|
||||
nsCOMPtr<nsIFrameManager> frameManager;
|
||||
presShell->GetFrameManager(getter_AddRefs(frameManager));
|
||||
|
||||
if (frameManager) {
|
||||
PRUint32 options = 0;
|
||||
nsLineList* value;
|
||||
|
||||
if (aRemoveProperty) {
|
||||
options |= NS_IFRAME_MGR_REMOVE_PROP;
|
||||
}
|
||||
frameManager->GetFrameProperty(NS_CONST_CAST(nsBlockFrame*, this),
|
||||
nsLayoutAtoms::overflowLinesProperty,
|
||||
options,
|
||||
NS_REINTERPRET_CAST(void**, &value));
|
||||
NS_ASSERTION(!value || !value->empty(),
|
||||
"value should never be stored as empty");
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
return nsnull;
|
||||
nsLineList* lines =
|
||||
NS_STATIC_CAST(nsLineList*, GetProperty(aPresContext,
|
||||
nsLayoutAtoms::overflowLinesProperty,
|
||||
aRemoveProperty));
|
||||
NS_ASSERTION(!lines || !lines->empty(), "value should never be stored as empty");
|
||||
return lines;
|
||||
}
|
||||
|
||||
// Destructor function for the overflowLines frame property
|
||||
@ -4786,27 +4817,48 @@ nsresult
|
||||
nsBlockFrame::SetOverflowLines(nsIPresContext* aPresContext,
|
||||
nsLineList* aOverflowLines)
|
||||
{
|
||||
nsCOMPtr<nsIPresShell> presShell;
|
||||
nsresult rv = NS_ERROR_FAILURE;
|
||||
|
||||
NS_ASSERTION(aOverflowLines, "null lines");
|
||||
NS_ASSERTION(! aOverflowLines->empty(), "empty lines");
|
||||
NS_ASSERTION(!aOverflowLines->empty(), "empty lines");
|
||||
|
||||
aPresContext->GetShell(getter_AddRefs(presShell));
|
||||
if (presShell) {
|
||||
nsCOMPtr<nsIFrameManager> frameManager;
|
||||
presShell->GetFrameManager(getter_AddRefs(frameManager));
|
||||
|
||||
if (frameManager) {
|
||||
rv = frameManager->SetFrameProperty(this,
|
||||
nsLayoutAtoms::overflowLinesProperty,
|
||||
aOverflowLines,
|
||||
DestroyOverflowLines);
|
||||
nsresult rv = SetProperty(aPresContext, nsLayoutAtoms::overflowLinesProperty,
|
||||
aOverflowLines, DestroyOverflowLines);
|
||||
// Verify that we didn't overwrite an existing overflow list
|
||||
NS_ASSERTION(rv != NS_IFRAME_MGR_PROP_OVERWRITTEN, "existing overflow list");
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Verify that we didn't overwrite an existing overflow list
|
||||
NS_ASSERTION(rv != NS_IFRAME_MGR_PROP_OVERWRITTEN, "existing overflow list");
|
||||
}
|
||||
}
|
||||
nsFrameList*
|
||||
nsBlockFrame::GetOverflowPlaceholders(nsIPresContext* aPresContext,
|
||||
PRBool aRemoveProperty) const
|
||||
{
|
||||
nsFrameList* placeholders =
|
||||
NS_STATIC_CAST(nsFrameList*,
|
||||
GetProperty(aPresContext, nsLayoutAtoms::overflowPlaceholdersProperty,
|
||||
aRemoveProperty));
|
||||
return placeholders;
|
||||
}
|
||||
|
||||
// Destructor function for the overflowPlaceholders frame property
|
||||
static void
|
||||
DestroyOverflowPlaceholders(nsIPresContext* aPresContext,
|
||||
nsIFrame* aFrame,
|
||||
nsIAtom* aPropertyName,
|
||||
void* aPropertyValue)
|
||||
{
|
||||
nsFrameList* overflowPlace = NS_STATIC_CAST(nsFrameList*, aPropertyValue);
|
||||
delete overflowPlace;
|
||||
}
|
||||
|
||||
// This takes ownership of aOverflowLines.
|
||||
// XXX We should allocate overflowLines from presShell arena!
|
||||
nsresult
|
||||
nsBlockFrame::SetOverflowPlaceholders(nsIPresContext* aPresContext,
|
||||
nsFrameList* aOverflowPlaceholders)
|
||||
{
|
||||
nsresult rv = SetProperty(aPresContext, nsLayoutAtoms::overflowPlaceholdersProperty,
|
||||
aOverflowPlaceholders, DestroyOverflowPlaceholders);
|
||||
// Verify that we didn't overwrite an existing overflow list
|
||||
NS_ASSERTION(rv != NS_IFRAME_MGR_PROP_OVERWRITTEN, "existing overflow placeholder list");
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -201,9 +201,11 @@ public:
|
||||
|
||||
// Create a contination for aPlaceholder and its out of flow frame and
|
||||
// add it to the list of overflow floaters
|
||||
nsresult SplitPlaceholder(nsBlockReflowState& aState,
|
||||
nsIFrame& aPlaceholder);
|
||||
nsresult SplitPlaceholder(nsIPresContext& aPresContext, nsIFrame& aPlaceholder);
|
||||
|
||||
void UndoSplitPlaceholders(nsBlockReflowState& aState,
|
||||
nsIFrame* aLastPlaceholder);
|
||||
|
||||
protected:
|
||||
nsBlockFrame();
|
||||
virtual ~nsBlockFrame();
|
||||
@ -503,6 +505,12 @@ protected:
|
||||
nsresult SetOverflowLines(nsIPresContext* aPresContext,
|
||||
nsLineList* aOverflowLines);
|
||||
|
||||
nsFrameList* GetOverflowPlaceholders(nsIPresContext* aPresContext,
|
||||
PRBool aRemoveProperty) const;
|
||||
|
||||
nsresult SetOverflowPlaceholders(nsIPresContext* aPresContext,
|
||||
nsFrameList* aOverflowPlaceholders);
|
||||
|
||||
nsIFrame* LastChild();
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
|
@ -46,6 +46,7 @@
|
||||
#include "nsIPresContext.h"
|
||||
#include "nsLayoutAtoms.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsIFrameManager.h"
|
||||
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsHTMLAtoms.h"
|
||||
@ -124,7 +125,6 @@ nsBlockReflowState::nsBlockReflowState(const nsHTMLReflowState& aReflowState,
|
||||
}
|
||||
}
|
||||
mHaveRightFloaters = PR_FALSE;
|
||||
mOverflowFloaters.SetFrames(nsnull);
|
||||
|
||||
// Compute content area height. Unlike the width, if we have a
|
||||
// specified style height we ignore it since extra content is
|
||||
@ -847,7 +847,8 @@ nsBlockReflowState::FlowAndPlaceFloater(nsFloaterCache* aFloaterCache,
|
||||
// content.
|
||||
nscoord saveY = mY;
|
||||
|
||||
nsIFrame* floater = aFloaterCache->mPlaceholder->GetOutOfFlowFrame();
|
||||
nsPlaceholderFrame* placeholder = aFloaterCache->mPlaceholder;
|
||||
nsIFrame* floater = placeholder->GetOutOfFlowFrame();
|
||||
|
||||
// Grab the floater's display information
|
||||
const nsStyleDisplay* floaterDisplay;
|
||||
@ -879,8 +880,8 @@ nsBlockReflowState::FlowAndPlaceFloater(nsFloaterCache* aFloaterCache,
|
||||
}
|
||||
|
||||
// Reflow the floater
|
||||
mBlock->ReflowFloater(*this, aFloaterCache->mPlaceholder, aFloaterCache->mCombinedArea,
|
||||
aFloaterCache->mMargins, aFloaterCache->mOffsets, aReflowStatus);
|
||||
mBlock->ReflowFloater(*this, placeholder, aFloaterCache->mCombinedArea,
|
||||
aFloaterCache->mMargins, aFloaterCache->mOffsets, aReflowStatus);
|
||||
|
||||
// Get the floaters bounding box and margin information
|
||||
floater->GetRect(region);
|
||||
@ -963,7 +964,7 @@ nsBlockReflowState::FlowAndPlaceFloater(nsFloaterCache* aFloaterCache,
|
||||
mY += mAvailSpaceRect.height;
|
||||
GetAvailableSpace();
|
||||
// reflow the floater again now since we have more space
|
||||
mBlock->ReflowFloater(*this, aFloaterCache->mPlaceholder, aFloaterCache->mCombinedArea,
|
||||
mBlock->ReflowFloater(*this, placeholder, aFloaterCache->mCombinedArea,
|
||||
aFloaterCache->mMargins, aFloaterCache->mOffsets, aReflowStatus);
|
||||
// Get the floaters bounding box and margin information
|
||||
floater->GetRect(region);
|
||||
@ -974,12 +975,33 @@ nsBlockReflowState::FlowAndPlaceFloater(nsFloaterCache* aFloaterCache,
|
||||
|
||||
}
|
||||
}
|
||||
// If the floater is continued, it will get the same x value as its prev-in-flow
|
||||
nsRect prevInFlowRect(0,0,0,0);
|
||||
// If the floater is continued, it will get the same absolute x value as its prev-in-flow
|
||||
nsRect prevRect(0,0,0,0);
|
||||
nsIFrame* prevInFlow;
|
||||
floater->GetPrevInFlow(&prevInFlow);
|
||||
if (prevInFlow) {
|
||||
prevInFlow->GetRect(prevInFlowRect);
|
||||
prevInFlow->GetRect(prevRect);
|
||||
|
||||
nsCOMPtr<nsIPresShell> presShell;
|
||||
mPresContext->GetShell(getter_AddRefs(presShell));
|
||||
nsCOMPtr<nsIFrameManager> frameManager;
|
||||
presShell->GetFrameManager(getter_AddRefs(frameManager));
|
||||
|
||||
nsIFrame *placeParent, *placeParentPrev, *prevPlace, *prevPlaceParent;
|
||||
// If prevInFlow's placeholder is in a block that wasn't continued, we need to adjust
|
||||
// prevRect.x to account for the missing frame offsets.
|
||||
placeholder->GetParent(&placeParent);
|
||||
placeParent->GetPrevInFlow(&placeParentPrev);
|
||||
frameManager->GetPlaceholderFrameFor(prevInFlow, &prevPlace);
|
||||
prevPlace->GetParent(&prevPlaceParent);
|
||||
|
||||
for (nsIFrame* ancestor = prevPlaceParent;
|
||||
ancestor && (ancestor != placeParentPrev);
|
||||
ancestor->GetParent(&ancestor)) {
|
||||
nsRect rect;
|
||||
ancestor->GetRect(rect);
|
||||
prevRect.x += rect.x;
|
||||
}
|
||||
}
|
||||
// Assign an x and y coordinate to the floater. Note that the x,y
|
||||
// coordinates are computed <b>relative to the translation in the
|
||||
@ -989,7 +1011,7 @@ nsBlockReflowState::FlowAndPlaceFloater(nsFloaterCache* aFloaterCache,
|
||||
PRBool isLeftFloater;
|
||||
if (NS_STYLE_FLOAT_LEFT == floaterDisplay->mFloats) {
|
||||
isLeftFloater = PR_TRUE;
|
||||
region.x = (prevInFlow) ? prevInFlowRect.x : mAvailSpaceRect.x;
|
||||
region.x = (prevInFlow) ? prevRect.x : mAvailSpaceRect.x;
|
||||
}
|
||||
else {
|
||||
isLeftFloater = PR_FALSE;
|
||||
@ -997,7 +1019,7 @@ nsBlockReflowState::FlowAndPlaceFloater(nsFloaterCache* aFloaterCache,
|
||||
nsIFrame* prevInFlow;
|
||||
floater->GetPrevInFlow(&prevInFlow);
|
||||
if (prevInFlow) {
|
||||
region.x = prevInFlowRect.x;
|
||||
region.x = prevRect.x;
|
||||
}
|
||||
else if (!keepFloaterOnSameLine) {
|
||||
region.x = mAvailSpaceRect.XMost() - region.width;
|
||||
@ -1030,7 +1052,7 @@ nsBlockReflowState::FlowAndPlaceFloater(nsFloaterCache* aFloaterCache,
|
||||
// if the floater split, then take up all of the vertical height
|
||||
if (NS_FRAME_IS_NOT_COMPLETE(aReflowStatus) &&
|
||||
(NS_UNCONSTRAINEDSIZE != mContentArea.height)) {
|
||||
region.height += PR_MAX(region.height, mContentArea.height);
|
||||
region.height = PR_MAX(region.height, mContentArea.height);
|
||||
}
|
||||
#ifdef DEBUG
|
||||
nsresult rv =
|
||||
@ -1160,7 +1182,7 @@ nsBlockReflowState::PlaceBelowCurrentLineFloaters(nsFloaterCacheList& aList)
|
||||
}
|
||||
else if (NS_FRAME_IS_NOT_COMPLETE(reflowStatus)) {
|
||||
// Create a continuation for the incomplete floater and its placeholder.
|
||||
nsresult rv = mBlock->SplitPlaceholder(*this, *fc->mPlaceholder);
|
||||
nsresult rv = mBlock->SplitPlaceholder(*mPresContext, *fc->mPlaceholder);
|
||||
if (NS_FAILED(rv))
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
@ -199,9 +199,6 @@ public:
|
||||
|
||||
nsFloaterCacheFreeList mFloaterCacheFreeList;
|
||||
|
||||
// next-in-flows of incomplete floaters which get put into overflow lines
|
||||
nsFrameList mOverflowFloaters;
|
||||
|
||||
// Previous child. This is used when pulling up a frame to update
|
||||
// the sibling list.
|
||||
nsIFrame* mPrevChild;
|
||||
|
@ -4621,6 +4621,54 @@ nsFrame::IsMouseCaptured(nsIPresContext* aPresContext)
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsFrame::SetProperty(nsIPresContext* aPresContext,
|
||||
nsIAtom* aPropName,
|
||||
void* aPropValue,
|
||||
NSFramePropertyDtorFunc aPropDtorFunc)
|
||||
{
|
||||
nsCOMPtr<nsIPresShell> presShell;
|
||||
nsresult rv = NS_ERROR_FAILURE;
|
||||
|
||||
aPresContext->GetShell(getter_AddRefs(presShell));
|
||||
if (presShell) {
|
||||
nsCOMPtr<nsIFrameManager> frameManager;
|
||||
presShell->GetFrameManager(getter_AddRefs(frameManager));
|
||||
|
||||
if (frameManager) {
|
||||
rv = frameManager->SetFrameProperty(this, aPropName, aPropValue, aPropDtorFunc);
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
void*
|
||||
nsFrame::GetProperty(nsIPresContext* aPresContext,
|
||||
nsIAtom* aPropName,
|
||||
PRBool aRemoveProp) const
|
||||
{
|
||||
void* value = nsnull;
|
||||
|
||||
nsCOMPtr<nsIPresShell> presShell;
|
||||
aPresContext->GetShell(getter_AddRefs(presShell));
|
||||
|
||||
if (presShell) {
|
||||
nsCOMPtr<nsIFrameManager> frameManager;
|
||||
presShell->GetFrameManager(getter_AddRefs(frameManager));
|
||||
|
||||
if (frameManager) {
|
||||
PRUint32 options = 0;
|
||||
|
||||
if (aRemoveProp) {
|
||||
options |= NS_IFRAME_MGR_REMOVE_PROP;
|
||||
}
|
||||
frameManager->GetFrameProperty((nsIFrame*)this, aPropName, options, &value);
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
#ifdef IBMBIDI
|
||||
/**
|
||||
* retrieve Bidi property of this frame
|
||||
|
@ -386,6 +386,16 @@ public:
|
||||
//Mouse Capturing code used by the frames to tell the view to capture all the following events
|
||||
NS_IMETHOD CaptureMouse(nsIPresContext* aPresContext, PRBool aGrabMouseEvents);
|
||||
PRBool IsMouseCaptured(nsIPresContext* aPresContext);
|
||||
|
||||
virtual void* GetProperty(nsIPresContext* aPresContext,
|
||||
nsIAtom* aPropertyName,
|
||||
PRBool aRemoveProperty) const;
|
||||
|
||||
virtual nsresult SetProperty(nsIPresContext* aPresContext,
|
||||
nsIAtom* aPropertyName,
|
||||
void* aPropertyValue,
|
||||
NSFramePropertyDtorFunc aPropDtorFunc);
|
||||
|
||||
#ifdef IBMBIDI
|
||||
NS_IMETHOD GetBidiProperty(nsIPresContext* aPresContext,
|
||||
nsIAtom* aPropertyName,
|
||||
|
@ -90,6 +90,13 @@ struct nsRect;
|
||||
struct nsSize;
|
||||
struct nsMargin;
|
||||
|
||||
// Calback function used to destroy the value associated with a property.
|
||||
typedef void
|
||||
(*NSFramePropertyDtorFunc)(nsIPresContext* aPresContext,
|
||||
nsIFrame* aFrame,
|
||||
nsIAtom* aPropertyName,
|
||||
void* aPropertyValue);
|
||||
|
||||
// IID for the nsIFrame interface
|
||||
// a6cf9050-15b3-11d2-932e-00805f8add32
|
||||
#define NS_IFRAME_IID \
|
||||
@ -1158,6 +1165,14 @@ public:
|
||||
PRBool aIsPre,
|
||||
PRBool* aResult) = 0;
|
||||
|
||||
virtual void* GetProperty(nsIPresContext* aPresContext,
|
||||
nsIAtom* aPropertyName,
|
||||
PRBool aRemoveProperty) const = 0;
|
||||
|
||||
virtual nsresult SetProperty(nsIPresContext* aPresContext,
|
||||
nsIAtom* aPropertyName,
|
||||
void* aPropertyValue,
|
||||
NSFramePropertyDtorFunc aPropDtorFunc) = 0;
|
||||
#ifdef IBMBIDI
|
||||
/**
|
||||
* retrieve and set Bidi property of this frame
|
||||
|
@ -779,7 +779,7 @@ nsInlineFrame::ReflowInlineFrame(nsIPresContext* aPresContext,
|
||||
aFrame->GetFrameType(getter_AddRefs(frameType));
|
||||
if (nsLayoutAtoms::placeholderFrame == frameType) {
|
||||
nsBlockReflowState* blockRS = lineLayout->mBlockRS;
|
||||
blockRS->mBlock->SplitPlaceholder(*blockRS, *aFrame);
|
||||
blockRS->mBlock->SplitPlaceholder(*aPresContext, *aFrame);
|
||||
}
|
||||
else {
|
||||
nsIFrame* newFrame;
|
||||
|
@ -945,42 +945,78 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "reflow dirty lines failed");
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// Put continued floaters at the beginning of the first overflow line. If the first line
|
||||
// is a block then create a new line as the first line and put the floaters there. If there
|
||||
// are no overflow lines, then create one and put the floaters in it.
|
||||
if (state.mOverflowFloaters.NotEmpty()) {
|
||||
nsLineList* overflowLines = GetOverflowLines(aPresContext, PR_FALSE);
|
||||
if (overflowLines) {
|
||||
line_iterator firstLine = overflowLines->begin();
|
||||
if (firstLine->IsBlock()) { // floaters go on a new line before 1st overflow line
|
||||
nsLineBox* newLine = state.NewLineBox(state.mOverflowFloaters.FirstChild(),
|
||||
state.mOverflowFloaters.GetLength(), PR_FALSE);
|
||||
firstLine = mLines.before_insert(firstLine, newLine);
|
||||
}
|
||||
else { // floaters go on 1st overflow line
|
||||
nsIFrame* firstFrame = firstLine->mFirstChild;
|
||||
firstLine->mFirstChild = state.mOverflowFloaters.FirstChild();
|
||||
PRInt32 numOverflowFloaters = state.mOverflowFloaters.GetLength();
|
||||
// hook up the last placeholder with the original frames
|
||||
nsPlaceholderFrame* lastPlaceholder =
|
||||
(nsPlaceholderFrame*)state.mOverflowFloaters.LastChild();
|
||||
lastPlaceholder->SetNextSibling(firstFrame);
|
||||
NS_ASSERTION(firstFrame != lastPlaceholder, "trying to set next sibling to self");
|
||||
firstLine->SetChildCount(firstLine->GetChildCount() + numOverflowFloaters);
|
||||
// If the block is complete, put continuted floaters in the closest ancestor
|
||||
// block that uses the same space manager and leave the block complete; this
|
||||
// allows subsequent lines on the page to be impacted by floaters. If the
|
||||
// block is incomplete or there is no ancestor using the same space manager,
|
||||
// put continued floaters at the beginning of the first overflow line.
|
||||
nsFrameList* overflowPlace = nsnull;
|
||||
if ((NS_UNCONSTRAINEDSIZE != aReflowState.availableHeight) &&
|
||||
(overflowPlace = GetOverflowPlaceholders(aPresContext, PR_TRUE))) {
|
||||
PRBool gaveToAncestor = PR_FALSE;
|
||||
if (NS_FRAME_IS_COMPLETE(state.mReflowStatus)) {
|
||||
// find the nearest block ancestor that uses the same space manager
|
||||
for (const nsHTMLReflowState* ancestorRS = aReflowState.parentReflowState;
|
||||
ancestorRS;
|
||||
ancestorRS = ancestorRS->parentReflowState) {
|
||||
nsIFrame* ancestor = ancestorRS->frame;
|
||||
nsCOMPtr<nsIAtom> fType;
|
||||
ancestor->GetFrameType(getter_AddRefs(fType));
|
||||
if ((nsLayoutAtoms::blockFrame == fType) || (nsLayoutAtoms::areaFrame == fType)) {
|
||||
if (aReflowState.mSpaceManager == ancestorRS->mSpaceManager) {
|
||||
// Put the continued floaters in ancestor since it uses the same space manager
|
||||
nsFrameList* ancestorPlace =
|
||||
((nsBlockFrame*)ancestor)->GetOverflowPlaceholders(aPresContext, PR_FALSE);
|
||||
if (ancestorPlace) {
|
||||
ancestorPlace->AppendFrames(ancestor, overflowPlace->FirstChild());
|
||||
}
|
||||
else {
|
||||
ancestorPlace = new nsFrameList(overflowPlace->FirstChild());
|
||||
if (ancestorPlace) {
|
||||
((nsBlockFrame*)ancestor)->SetOverflowPlaceholders(aPresContext, ancestorPlace);
|
||||
}
|
||||
else
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
gaveToAncestor = PR_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Create a line, put the floaters in it, and then push.
|
||||
nsLineBox* newLine = state.NewLineBox(state.mOverflowFloaters.FirstChild(),
|
||||
state.mOverflowFloaters.GetLength(), PR_FALSE);
|
||||
if (!newLine)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
mLines.push_back(newLine);
|
||||
nsLineList::iterator nextToLastLine = ----end_lines();
|
||||
PushLines(state, nextToLastLine);
|
||||
if (!gaveToAncestor) {
|
||||
PRInt32 numOverflowPlace = overflowPlace->GetLength();
|
||||
nsLineList* overflowLines = GetOverflowLines(aPresContext, PR_FALSE);
|
||||
if (overflowLines) {
|
||||
line_iterator firstLine = overflowLines->begin();
|
||||
if (firstLine->IsBlock()) {
|
||||
// Create a new line as the first line and put the floaters there;
|
||||
nsLineBox* newLine = state.NewLineBox(overflowPlace->FirstChild(), numOverflowPlace, PR_FALSE);
|
||||
firstLine = mLines.before_insert(firstLine, newLine);
|
||||
}
|
||||
else { // floaters go on 1st overflow line
|
||||
nsIFrame* firstFrame = firstLine->mFirstChild;
|
||||
firstLine->mFirstChild = overflowPlace->FirstChild();
|
||||
// hook up the last placeholder with the original frames
|
||||
nsPlaceholderFrame* lastPlaceholder =
|
||||
(nsPlaceholderFrame*)overflowPlace->LastChild();
|
||||
lastPlaceholder->SetNextSibling(firstFrame);
|
||||
NS_ASSERTION(firstFrame != lastPlaceholder, "trying to set next sibling to self");
|
||||
firstLine->SetChildCount(firstLine->GetChildCount() + numOverflowPlace);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Create a line, put the floaters in it, and then push.
|
||||
nsLineBox* newLine = state.NewLineBox(overflowPlace->FirstChild(), numOverflowPlace, PR_FALSE);
|
||||
if (!newLine)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
mLines.push_back(newLine);
|
||||
nsLineList::iterator nextToLastLine = ----end_lines();
|
||||
PushLines(state, nextToLastLine);
|
||||
}
|
||||
state.mReflowStatus = NS_FRAME_NOT_COMPLETE;
|
||||
}
|
||||
state.mReflowStatus = NS_FRAME_NOT_COMPLETE;
|
||||
state.mOverflowFloaters.SetFrames(nsnull);
|
||||
delete overflowPlace;
|
||||
}
|
||||
|
||||
if (NS_FRAME_IS_NOT_COMPLETE(state.mReflowStatus)) {
|
||||
@ -3151,9 +3187,9 @@ nsBlockFrame::GetTopBlockChild(nsIPresContext* aPresContext)
|
||||
// If placeholders/floaters split during reflowing a line, but that line will
|
||||
// be put on the next page, then put the placeholders/floaters back the way
|
||||
// they were before the line was reflowed.
|
||||
static void
|
||||
UndoPlaceholders(nsBlockReflowState& aState,
|
||||
nsIFrame* aLastPlaceholder)
|
||||
void
|
||||
nsBlockFrame::UndoSplitPlaceholders(nsBlockReflowState& aState,
|
||||
nsIFrame* aLastPlaceholder)
|
||||
{
|
||||
nsIFrame* undoPlaceholder = nsnull;
|
||||
if (aLastPlaceholder) {
|
||||
@ -3161,8 +3197,9 @@ UndoPlaceholders(nsBlockReflowState& aState,
|
||||
aLastPlaceholder->SetNextSibling(nsnull);
|
||||
}
|
||||
else {
|
||||
undoPlaceholder = aState.mOverflowFloaters.FirstChild();
|
||||
aState.mOverflowFloaters.SetFrames(nsnull);
|
||||
// just remove the property
|
||||
nsFrameList* overflowPlace = GetOverflowPlaceholders(aState.mPresContext, PR_TRUE);
|
||||
delete overflowPlace;
|
||||
}
|
||||
// remove the next in flows of the placeholders that need to be removed
|
||||
for (nsIFrame* placeholder = undoPlaceholder; placeholder; ) {
|
||||
@ -3320,7 +3357,8 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState,
|
||||
}
|
||||
|
||||
// keep track of the last overflow floater in case we need to undo any new additions
|
||||
nsIFrame* lastPlaceholder = aState.mOverflowFloaters.LastChild();
|
||||
nsFrameList* overflowPlace = GetOverflowPlaceholders(aState.mPresContext, PR_FALSE);
|
||||
nsIFrame* lastPlaceholder = (overflowPlace) ? overflowPlace->LastChild() : nsnull;
|
||||
|
||||
// Reflow the block into the available space
|
||||
nsReflowStatus frameReflowStatus=NS_FRAME_COMPLETE;
|
||||
@ -3353,7 +3391,7 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState,
|
||||
|
||||
if (NS_INLINE_IS_BREAK_BEFORE(frameReflowStatus)) {
|
||||
// None of the child block fits.
|
||||
::UndoPlaceholders(aState, lastPlaceholder);
|
||||
UndoSplitPlaceholders(aState, lastPlaceholder);
|
||||
PushLines(aState, aLine.prev());
|
||||
*aKeepReflowGoing = PR_FALSE;
|
||||
aState.mReflowStatus = NS_FRAME_NOT_COMPLETE;
|
||||
@ -3530,7 +3568,7 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState,
|
||||
else {
|
||||
// Push the line that didn't fit and any lines that follow it
|
||||
// to our next-in-flow.
|
||||
::UndoPlaceholders(aState, lastPlaceholder);
|
||||
UndoSplitPlaceholders(aState, lastPlaceholder);
|
||||
PushLines(aState, aLine.prev());
|
||||
aState.mReflowStatus = NS_FRAME_NOT_COMPLETE;
|
||||
}
|
||||
@ -3644,7 +3682,7 @@ nsBlockFrame::PushTruncatedPlaceholderLine(nsBlockReflowState& aState,
|
||||
nsIFrame* aLastPlaceholder,
|
||||
PRBool& aKeepReflowGoing)
|
||||
{
|
||||
::UndoPlaceholders(aState, aLastPlaceholder);
|
||||
UndoSplitPlaceholders(aState, aLastPlaceholder);
|
||||
|
||||
line_iterator prevLine = aLine;
|
||||
--prevLine;
|
||||
@ -3716,7 +3754,8 @@ nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState& aState,
|
||||
}
|
||||
|
||||
// keep track of the last overflow floater in case we need to undo any new additions
|
||||
nsIFrame* lastPlaceholder = aState.mOverflowFloaters.LastChild();
|
||||
nsFrameList* overflowPlace = GetOverflowPlaceholders(aState.mPresContext, PR_FALSE);
|
||||
nsIFrame* lastPlaceholder = (overflowPlace) ? overflowPlace->LastChild() : nsnull;
|
||||
|
||||
// Reflow the frames that are already on the line first
|
||||
nsresult rv = NS_OK;
|
||||
@ -3814,7 +3853,7 @@ nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState& aState,
|
||||
// no point in placing the line.
|
||||
if (!NS_INLINE_IS_BREAK_BEFORE(aState.mReflowStatus)) {
|
||||
if (PlaceLine(aState, aLineLayout, aLine, aKeepReflowGoing, aUpdateMaximumWidth)) {
|
||||
::UndoPlaceholders(aState, lastPlaceholder); // undo since we pushed the current line
|
||||
UndoSplitPlaceholders(aState, lastPlaceholder); // undo since we pushed the current line
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3991,7 +4030,7 @@ nsBlockFrame::ReflowInlineFrame(nsBlockReflowState& aState,
|
||||
// frame may already have a continuation.
|
||||
PRBool madeContinuation;
|
||||
rv = (nsLayoutAtoms::placeholderFrame == frameType)
|
||||
? SplitPlaceholder(aState, *aFrame)
|
||||
? SplitPlaceholder(*aState.mPresContext, *aFrame)
|
||||
: CreateContinuationFor(aState, aLine, aFrame, madeContinuation);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
@ -4070,11 +4109,11 @@ nsBlockFrame::CreateContinuationFor(nsBlockReflowState& aState,
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsBlockFrame::SplitPlaceholder(nsBlockReflowState& aState,
|
||||
nsIFrame& aPlaceholder)
|
||||
nsBlockFrame::SplitPlaceholder(nsIPresContext& aPresContext,
|
||||
nsIFrame& aPlaceholder)
|
||||
{
|
||||
nsIFrame* nextInFlow;
|
||||
nsresult rv = CreateNextInFlow(aState.mPresContext, this, &aPlaceholder, nextInFlow);
|
||||
nsresult rv = CreateNextInFlow(&aPresContext, this, &aPlaceholder, nextInFlow);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
// put the sibling list back to what it was before the continuation was created
|
||||
@ -4084,7 +4123,17 @@ nsBlockFrame::SplitPlaceholder(nsBlockReflowState& aState,
|
||||
aPlaceholder.SetNextSibling(next);
|
||||
contFrame->SetNextSibling(nsnull);
|
||||
// add the placehoder to the overflow floaters
|
||||
aState.mOverflowFloaters.AppendFrames(this, contFrame);
|
||||
nsFrameList* overflowPlace = GetOverflowPlaceholders(&aPresContext, PR_FALSE);
|
||||
if (overflowPlace) {
|
||||
overflowPlace->AppendFrames(this, contFrame);
|
||||
}
|
||||
else {
|
||||
overflowPlace = new nsFrameList(contFrame);
|
||||
if (overflowPlace) {
|
||||
SetOverflowPlaceholders(&aPresContext, overflowPlace);
|
||||
}
|
||||
else return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -4415,7 +4464,8 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState,
|
||||
// Any below current line floaters to place?
|
||||
if (aState.mBelowCurrentLineFloaters.NotEmpty()) {
|
||||
// keep track of the last overflow floater in case we need to undo and push the line
|
||||
nsIFrame* lastPlaceholder = aState.mOverflowFloaters.LastChild();
|
||||
nsFrameList* overflowPlace = GetOverflowPlaceholders(aState.mPresContext, PR_FALSE);
|
||||
nsIFrame* lastPlaceholder = (overflowPlace) ? overflowPlace->LastChild() : nsnull;
|
||||
// Reflow the below-current-line floaters, then add them to the
|
||||
// lines floater list if there aren't any truncated floaters.
|
||||
if (aState.PlaceBelowCurrentLineFloaters(aState.mBelowCurrentLineFloaters)) {
|
||||
@ -4739,31 +4789,12 @@ nsLineList*
|
||||
nsBlockFrame::GetOverflowLines(nsIPresContext* aPresContext,
|
||||
PRBool aRemoveProperty) const
|
||||
{
|
||||
nsCOMPtr<nsIPresShell> presShell;
|
||||
aPresContext->GetShell(getter_AddRefs(presShell));
|
||||
|
||||
if (presShell) {
|
||||
nsCOMPtr<nsIFrameManager> frameManager;
|
||||
presShell->GetFrameManager(getter_AddRefs(frameManager));
|
||||
|
||||
if (frameManager) {
|
||||
PRUint32 options = 0;
|
||||
nsLineList* value;
|
||||
|
||||
if (aRemoveProperty) {
|
||||
options |= NS_IFRAME_MGR_REMOVE_PROP;
|
||||
}
|
||||
frameManager->GetFrameProperty(NS_CONST_CAST(nsBlockFrame*, this),
|
||||
nsLayoutAtoms::overflowLinesProperty,
|
||||
options,
|
||||
NS_REINTERPRET_CAST(void**, &value));
|
||||
NS_ASSERTION(!value || !value->empty(),
|
||||
"value should never be stored as empty");
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
return nsnull;
|
||||
nsLineList* lines =
|
||||
NS_STATIC_CAST(nsLineList*, GetProperty(aPresContext,
|
||||
nsLayoutAtoms::overflowLinesProperty,
|
||||
aRemoveProperty));
|
||||
NS_ASSERTION(!lines || !lines->empty(), "value should never be stored as empty");
|
||||
return lines;
|
||||
}
|
||||
|
||||
// Destructor function for the overflowLines frame property
|
||||
@ -4786,27 +4817,48 @@ nsresult
|
||||
nsBlockFrame::SetOverflowLines(nsIPresContext* aPresContext,
|
||||
nsLineList* aOverflowLines)
|
||||
{
|
||||
nsCOMPtr<nsIPresShell> presShell;
|
||||
nsresult rv = NS_ERROR_FAILURE;
|
||||
|
||||
NS_ASSERTION(aOverflowLines, "null lines");
|
||||
NS_ASSERTION(! aOverflowLines->empty(), "empty lines");
|
||||
NS_ASSERTION(!aOverflowLines->empty(), "empty lines");
|
||||
|
||||
aPresContext->GetShell(getter_AddRefs(presShell));
|
||||
if (presShell) {
|
||||
nsCOMPtr<nsIFrameManager> frameManager;
|
||||
presShell->GetFrameManager(getter_AddRefs(frameManager));
|
||||
|
||||
if (frameManager) {
|
||||
rv = frameManager->SetFrameProperty(this,
|
||||
nsLayoutAtoms::overflowLinesProperty,
|
||||
aOverflowLines,
|
||||
DestroyOverflowLines);
|
||||
nsresult rv = SetProperty(aPresContext, nsLayoutAtoms::overflowLinesProperty,
|
||||
aOverflowLines, DestroyOverflowLines);
|
||||
// Verify that we didn't overwrite an existing overflow list
|
||||
NS_ASSERTION(rv != NS_IFRAME_MGR_PROP_OVERWRITTEN, "existing overflow list");
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Verify that we didn't overwrite an existing overflow list
|
||||
NS_ASSERTION(rv != NS_IFRAME_MGR_PROP_OVERWRITTEN, "existing overflow list");
|
||||
}
|
||||
}
|
||||
nsFrameList*
|
||||
nsBlockFrame::GetOverflowPlaceholders(nsIPresContext* aPresContext,
|
||||
PRBool aRemoveProperty) const
|
||||
{
|
||||
nsFrameList* placeholders =
|
||||
NS_STATIC_CAST(nsFrameList*,
|
||||
GetProperty(aPresContext, nsLayoutAtoms::overflowPlaceholdersProperty,
|
||||
aRemoveProperty));
|
||||
return placeholders;
|
||||
}
|
||||
|
||||
// Destructor function for the overflowPlaceholders frame property
|
||||
static void
|
||||
DestroyOverflowPlaceholders(nsIPresContext* aPresContext,
|
||||
nsIFrame* aFrame,
|
||||
nsIAtom* aPropertyName,
|
||||
void* aPropertyValue)
|
||||
{
|
||||
nsFrameList* overflowPlace = NS_STATIC_CAST(nsFrameList*, aPropertyValue);
|
||||
delete overflowPlace;
|
||||
}
|
||||
|
||||
// This takes ownership of aOverflowLines.
|
||||
// XXX We should allocate overflowLines from presShell arena!
|
||||
nsresult
|
||||
nsBlockFrame::SetOverflowPlaceholders(nsIPresContext* aPresContext,
|
||||
nsFrameList* aOverflowPlaceholders)
|
||||
{
|
||||
nsresult rv = SetProperty(aPresContext, nsLayoutAtoms::overflowPlaceholdersProperty,
|
||||
aOverflowPlaceholders, DestroyOverflowPlaceholders);
|
||||
// Verify that we didn't overwrite an existing overflow list
|
||||
NS_ASSERTION(rv != NS_IFRAME_MGR_PROP_OVERWRITTEN, "existing overflow placeholder list");
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -201,9 +201,11 @@ public:
|
||||
|
||||
// Create a contination for aPlaceholder and its out of flow frame and
|
||||
// add it to the list of overflow floaters
|
||||
nsresult SplitPlaceholder(nsBlockReflowState& aState,
|
||||
nsIFrame& aPlaceholder);
|
||||
nsresult SplitPlaceholder(nsIPresContext& aPresContext, nsIFrame& aPlaceholder);
|
||||
|
||||
void UndoSplitPlaceholders(nsBlockReflowState& aState,
|
||||
nsIFrame* aLastPlaceholder);
|
||||
|
||||
protected:
|
||||
nsBlockFrame();
|
||||
virtual ~nsBlockFrame();
|
||||
@ -503,6 +505,12 @@ protected:
|
||||
nsresult SetOverflowLines(nsIPresContext* aPresContext,
|
||||
nsLineList* aOverflowLines);
|
||||
|
||||
nsFrameList* GetOverflowPlaceholders(nsIPresContext* aPresContext,
|
||||
PRBool aRemoveProperty) const;
|
||||
|
||||
nsresult SetOverflowPlaceholders(nsIPresContext* aPresContext,
|
||||
nsFrameList* aOverflowPlaceholders);
|
||||
|
||||
nsIFrame* LastChild();
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
|
@ -46,6 +46,7 @@
|
||||
#include "nsIPresContext.h"
|
||||
#include "nsLayoutAtoms.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsIFrameManager.h"
|
||||
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsHTMLAtoms.h"
|
||||
@ -124,7 +125,6 @@ nsBlockReflowState::nsBlockReflowState(const nsHTMLReflowState& aReflowState,
|
||||
}
|
||||
}
|
||||
mHaveRightFloaters = PR_FALSE;
|
||||
mOverflowFloaters.SetFrames(nsnull);
|
||||
|
||||
// Compute content area height. Unlike the width, if we have a
|
||||
// specified style height we ignore it since extra content is
|
||||
@ -847,7 +847,8 @@ nsBlockReflowState::FlowAndPlaceFloater(nsFloaterCache* aFloaterCache,
|
||||
// content.
|
||||
nscoord saveY = mY;
|
||||
|
||||
nsIFrame* floater = aFloaterCache->mPlaceholder->GetOutOfFlowFrame();
|
||||
nsPlaceholderFrame* placeholder = aFloaterCache->mPlaceholder;
|
||||
nsIFrame* floater = placeholder->GetOutOfFlowFrame();
|
||||
|
||||
// Grab the floater's display information
|
||||
const nsStyleDisplay* floaterDisplay;
|
||||
@ -879,8 +880,8 @@ nsBlockReflowState::FlowAndPlaceFloater(nsFloaterCache* aFloaterCache,
|
||||
}
|
||||
|
||||
// Reflow the floater
|
||||
mBlock->ReflowFloater(*this, aFloaterCache->mPlaceholder, aFloaterCache->mCombinedArea,
|
||||
aFloaterCache->mMargins, aFloaterCache->mOffsets, aReflowStatus);
|
||||
mBlock->ReflowFloater(*this, placeholder, aFloaterCache->mCombinedArea,
|
||||
aFloaterCache->mMargins, aFloaterCache->mOffsets, aReflowStatus);
|
||||
|
||||
// Get the floaters bounding box and margin information
|
||||
floater->GetRect(region);
|
||||
@ -963,7 +964,7 @@ nsBlockReflowState::FlowAndPlaceFloater(nsFloaterCache* aFloaterCache,
|
||||
mY += mAvailSpaceRect.height;
|
||||
GetAvailableSpace();
|
||||
// reflow the floater again now since we have more space
|
||||
mBlock->ReflowFloater(*this, aFloaterCache->mPlaceholder, aFloaterCache->mCombinedArea,
|
||||
mBlock->ReflowFloater(*this, placeholder, aFloaterCache->mCombinedArea,
|
||||
aFloaterCache->mMargins, aFloaterCache->mOffsets, aReflowStatus);
|
||||
// Get the floaters bounding box and margin information
|
||||
floater->GetRect(region);
|
||||
@ -974,12 +975,33 @@ nsBlockReflowState::FlowAndPlaceFloater(nsFloaterCache* aFloaterCache,
|
||||
|
||||
}
|
||||
}
|
||||
// If the floater is continued, it will get the same x value as its prev-in-flow
|
||||
nsRect prevInFlowRect(0,0,0,0);
|
||||
// If the floater is continued, it will get the same absolute x value as its prev-in-flow
|
||||
nsRect prevRect(0,0,0,0);
|
||||
nsIFrame* prevInFlow;
|
||||
floater->GetPrevInFlow(&prevInFlow);
|
||||
if (prevInFlow) {
|
||||
prevInFlow->GetRect(prevInFlowRect);
|
||||
prevInFlow->GetRect(prevRect);
|
||||
|
||||
nsCOMPtr<nsIPresShell> presShell;
|
||||
mPresContext->GetShell(getter_AddRefs(presShell));
|
||||
nsCOMPtr<nsIFrameManager> frameManager;
|
||||
presShell->GetFrameManager(getter_AddRefs(frameManager));
|
||||
|
||||
nsIFrame *placeParent, *placeParentPrev, *prevPlace, *prevPlaceParent;
|
||||
// If prevInFlow's placeholder is in a block that wasn't continued, we need to adjust
|
||||
// prevRect.x to account for the missing frame offsets.
|
||||
placeholder->GetParent(&placeParent);
|
||||
placeParent->GetPrevInFlow(&placeParentPrev);
|
||||
frameManager->GetPlaceholderFrameFor(prevInFlow, &prevPlace);
|
||||
prevPlace->GetParent(&prevPlaceParent);
|
||||
|
||||
for (nsIFrame* ancestor = prevPlaceParent;
|
||||
ancestor && (ancestor != placeParentPrev);
|
||||
ancestor->GetParent(&ancestor)) {
|
||||
nsRect rect;
|
||||
ancestor->GetRect(rect);
|
||||
prevRect.x += rect.x;
|
||||
}
|
||||
}
|
||||
// Assign an x and y coordinate to the floater. Note that the x,y
|
||||
// coordinates are computed <b>relative to the translation in the
|
||||
@ -989,7 +1011,7 @@ nsBlockReflowState::FlowAndPlaceFloater(nsFloaterCache* aFloaterCache,
|
||||
PRBool isLeftFloater;
|
||||
if (NS_STYLE_FLOAT_LEFT == floaterDisplay->mFloats) {
|
||||
isLeftFloater = PR_TRUE;
|
||||
region.x = (prevInFlow) ? prevInFlowRect.x : mAvailSpaceRect.x;
|
||||
region.x = (prevInFlow) ? prevRect.x : mAvailSpaceRect.x;
|
||||
}
|
||||
else {
|
||||
isLeftFloater = PR_FALSE;
|
||||
@ -997,7 +1019,7 @@ nsBlockReflowState::FlowAndPlaceFloater(nsFloaterCache* aFloaterCache,
|
||||
nsIFrame* prevInFlow;
|
||||
floater->GetPrevInFlow(&prevInFlow);
|
||||
if (prevInFlow) {
|
||||
region.x = prevInFlowRect.x;
|
||||
region.x = prevRect.x;
|
||||
}
|
||||
else if (!keepFloaterOnSameLine) {
|
||||
region.x = mAvailSpaceRect.XMost() - region.width;
|
||||
@ -1030,7 +1052,7 @@ nsBlockReflowState::FlowAndPlaceFloater(nsFloaterCache* aFloaterCache,
|
||||
// if the floater split, then take up all of the vertical height
|
||||
if (NS_FRAME_IS_NOT_COMPLETE(aReflowStatus) &&
|
||||
(NS_UNCONSTRAINEDSIZE != mContentArea.height)) {
|
||||
region.height += PR_MAX(region.height, mContentArea.height);
|
||||
region.height = PR_MAX(region.height, mContentArea.height);
|
||||
}
|
||||
#ifdef DEBUG
|
||||
nsresult rv =
|
||||
@ -1160,7 +1182,7 @@ nsBlockReflowState::PlaceBelowCurrentLineFloaters(nsFloaterCacheList& aList)
|
||||
}
|
||||
else if (NS_FRAME_IS_NOT_COMPLETE(reflowStatus)) {
|
||||
// Create a continuation for the incomplete floater and its placeholder.
|
||||
nsresult rv = mBlock->SplitPlaceholder(*this, *fc->mPlaceholder);
|
||||
nsresult rv = mBlock->SplitPlaceholder(*mPresContext, *fc->mPlaceholder);
|
||||
if (NS_FAILED(rv))
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
@ -199,9 +199,6 @@ public:
|
||||
|
||||
nsFloaterCacheFreeList mFloaterCacheFreeList;
|
||||
|
||||
// next-in-flows of incomplete floaters which get put into overflow lines
|
||||
nsFrameList mOverflowFloaters;
|
||||
|
||||
// Previous child. This is used when pulling up a frame to update
|
||||
// the sibling list.
|
||||
nsIFrame* mPrevChild;
|
||||
|
@ -4621,6 +4621,54 @@ nsFrame::IsMouseCaptured(nsIPresContext* aPresContext)
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsFrame::SetProperty(nsIPresContext* aPresContext,
|
||||
nsIAtom* aPropName,
|
||||
void* aPropValue,
|
||||
NSFramePropertyDtorFunc aPropDtorFunc)
|
||||
{
|
||||
nsCOMPtr<nsIPresShell> presShell;
|
||||
nsresult rv = NS_ERROR_FAILURE;
|
||||
|
||||
aPresContext->GetShell(getter_AddRefs(presShell));
|
||||
if (presShell) {
|
||||
nsCOMPtr<nsIFrameManager> frameManager;
|
||||
presShell->GetFrameManager(getter_AddRefs(frameManager));
|
||||
|
||||
if (frameManager) {
|
||||
rv = frameManager->SetFrameProperty(this, aPropName, aPropValue, aPropDtorFunc);
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
void*
|
||||
nsFrame::GetProperty(nsIPresContext* aPresContext,
|
||||
nsIAtom* aPropName,
|
||||
PRBool aRemoveProp) const
|
||||
{
|
||||
void* value = nsnull;
|
||||
|
||||
nsCOMPtr<nsIPresShell> presShell;
|
||||
aPresContext->GetShell(getter_AddRefs(presShell));
|
||||
|
||||
if (presShell) {
|
||||
nsCOMPtr<nsIFrameManager> frameManager;
|
||||
presShell->GetFrameManager(getter_AddRefs(frameManager));
|
||||
|
||||
if (frameManager) {
|
||||
PRUint32 options = 0;
|
||||
|
||||
if (aRemoveProp) {
|
||||
options |= NS_IFRAME_MGR_REMOVE_PROP;
|
||||
}
|
||||
frameManager->GetFrameProperty((nsIFrame*)this, aPropName, options, &value);
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
#ifdef IBMBIDI
|
||||
/**
|
||||
* retrieve Bidi property of this frame
|
||||
|
@ -386,6 +386,16 @@ public:
|
||||
//Mouse Capturing code used by the frames to tell the view to capture all the following events
|
||||
NS_IMETHOD CaptureMouse(nsIPresContext* aPresContext, PRBool aGrabMouseEvents);
|
||||
PRBool IsMouseCaptured(nsIPresContext* aPresContext);
|
||||
|
||||
virtual void* GetProperty(nsIPresContext* aPresContext,
|
||||
nsIAtom* aPropertyName,
|
||||
PRBool aRemoveProperty) const;
|
||||
|
||||
virtual nsresult SetProperty(nsIPresContext* aPresContext,
|
||||
nsIAtom* aPropertyName,
|
||||
void* aPropertyValue,
|
||||
NSFramePropertyDtorFunc aPropDtorFunc);
|
||||
|
||||
#ifdef IBMBIDI
|
||||
NS_IMETHOD GetBidiProperty(nsIPresContext* aPresContext,
|
||||
nsIAtom* aPropertyName,
|
||||
|
@ -371,10 +371,10 @@ public:
|
||||
nsIAtom* aPropertyName,
|
||||
PRUint32 aOptions,
|
||||
void** aPropertyValue);
|
||||
NS_IMETHOD SetFrameProperty(nsIFrame* aFrame,
|
||||
nsIAtom* aPropertyName,
|
||||
void* aPropertyValue,
|
||||
NSFMPropertyDtorFunc aPropDtorFunc);
|
||||
NS_IMETHOD SetFrameProperty(nsIFrame* aFrame,
|
||||
nsIAtom* aPropertyName,
|
||||
void* aPropertyValue,
|
||||
NSFramePropertyDtorFunc aPropDtorFunc);
|
||||
NS_IMETHOD RemoveFrameProperty(nsIFrame* aFrame,
|
||||
nsIAtom* aPropertyName);
|
||||
|
||||
@ -383,13 +383,13 @@ public:
|
||||
#endif
|
||||
|
||||
struct PropertyList {
|
||||
nsCOMPtr<nsIAtom> mName; // property name
|
||||
PLDHashTable mFrameValueMap; // map of frame/value pairs
|
||||
NSFMPropertyDtorFunc mDtorFunc; // property specific value dtor function
|
||||
PropertyList* mNext;
|
||||
nsCOMPtr<nsIAtom> mName; // property name
|
||||
PLDHashTable mFrameValueMap; // map of frame/value pairs
|
||||
NSFramePropertyDtorFunc mDtorFunc; // property specific value dtor function
|
||||
PropertyList* mNext;
|
||||
|
||||
PropertyList(nsIAtom* aName,
|
||||
NSFMPropertyDtorFunc aDtorFunc);
|
||||
PropertyList(nsIAtom* aName,
|
||||
NSFramePropertyDtorFunc aDtorFunc);
|
||||
~PropertyList();
|
||||
|
||||
// Removes the property associated with the given frame, and destroys
|
||||
@ -2452,10 +2452,10 @@ FrameManager::GetFrameProperty(nsIFrame* aFrame,
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FrameManager::SetFrameProperty(nsIFrame* aFrame,
|
||||
nsIAtom* aPropertyName,
|
||||
void* aPropertyValue,
|
||||
NSFMPropertyDtorFunc aPropDtorFunc)
|
||||
FrameManager::SetFrameProperty(nsIFrame* aFrame,
|
||||
nsIAtom* aPropertyName,
|
||||
void* aPropertyValue,
|
||||
NSFramePropertyDtorFunc aPropDtorFunc)
|
||||
{
|
||||
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_AVAILABLE);
|
||||
NS_PRECONDITION(aPropertyName && aFrame, "unexpected null param");
|
||||
@ -2667,8 +2667,8 @@ UndisplayedMap::Clear(void)
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
FrameManager::PropertyList::PropertyList(nsIAtom* aName,
|
||||
NSFMPropertyDtorFunc aDtorFunc)
|
||||
FrameManager::PropertyList::PropertyList(nsIAtom* aName,
|
||||
NSFramePropertyDtorFunc aDtorFunc)
|
||||
: mName(aName), mDtorFunc(aDtorFunc), mNext(nsnull)
|
||||
{
|
||||
PL_DHashTableInit(&mFrameValueMap, PL_DHashGetStubOps(), this,
|
||||
|
@ -779,7 +779,7 @@ nsInlineFrame::ReflowInlineFrame(nsIPresContext* aPresContext,
|
||||
aFrame->GetFrameType(getter_AddRefs(frameType));
|
||||
if (nsLayoutAtoms::placeholderFrame == frameType) {
|
||||
nsBlockReflowState* blockRS = lineLayout->mBlockRS;
|
||||
blockRS->mBlock->SplitPlaceholder(*blockRS, *aFrame);
|
||||
blockRS->mBlock->SplitPlaceholder(*aPresContext, *aFrame);
|
||||
}
|
||||
else {
|
||||
nsIFrame* newFrame;
|
||||
|
@ -7412,7 +7412,7 @@ nsTableFrame::GetProperty(nsIPresContext* aPresContext,
|
||||
// The property isn't set yet, so allocate a new value, set the property,
|
||||
// and return the newly allocated value
|
||||
void* value = nsnull;
|
||||
NSFMPropertyDtorFunc dtorFunc = nsnull;
|
||||
NSFramePropertyDtorFunc dtorFunc = nsnull;
|
||||
if (aPropertyName == nsLayoutAtoms::collapseOffsetProperty) {
|
||||
value = new nsPoint(0, 0);
|
||||
dtorFunc = DestroyPointFunc;
|
||||
|
@ -7412,7 +7412,7 @@ nsTableFrame::GetProperty(nsIPresContext* aPresContext,
|
||||
// The property isn't set yet, so allocate a new value, set the property,
|
||||
// and return the newly allocated value
|
||||
void* value = nsnull;
|
||||
NSFMPropertyDtorFunc dtorFunc = nsnull;
|
||||
NSFramePropertyDtorFunc dtorFunc = nsnull;
|
||||
if (aPropertyName == nsLayoutAtoms::collapseOffsetProperty) {
|
||||
value = new nsPoint(0, 0);
|
||||
dtorFunc = DestroyPointFunc;
|
||||
|
Loading…
x
Reference in New Issue
Block a user