diff --git a/content/shared/public/nsXULAtomList.h b/content/shared/public/nsXULAtomList.h index 66904c922085..594ad394e4a4 100644 --- a/content/shared/public/nsXULAtomList.h +++ b/content/shared/public/nsXULAtomList.h @@ -104,6 +104,7 @@ XUL_ATOM(titledbox, "titledbox") XUL_ATOM(title, "title") XUL_ATOM(titledboxContentPseudo, ":titledbox-content") +XUL_ATOM(stack, "stack") XUL_ATOM(deck, "deck") XUL_ATOM(tabcontrol, "tabcontrol") XUL_ATOM(tab, "tab") @@ -124,6 +125,7 @@ XUL_ATOM(collapse, "collapse") XUL_ATOM(resizebefore, "resizebefore") XUL_ATOM(resizeafter, "resizeafter") XUL_ATOM(state, "state") +XUL_ATOM(debug, "debug") // toolbar & toolbar d&d atoms XUL_ATOM(ddDropLocation, "dd-droplocation") diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp index a0b2aab157a4..8bcf05c87484 100644 --- a/layout/base/nsCSSFrameConstructor.cpp +++ b/layout/base/nsCSSFrameConstructor.cpp @@ -146,6 +146,12 @@ NS_NewTabFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame ); nsresult NS_NewDeckFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame ); +nsresult +NS_NewSpringFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame ); + +nsresult +NS_NewStackFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame ); + nsresult NS_NewProgressMeterFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame ); @@ -165,7 +171,7 @@ nsresult NS_NewTitleFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame ); nsresult -NS_NewBoxFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame); +NS_NewBoxFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame, PRBool aIsRoot); nsresult NS_NewSliderFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame ); @@ -2080,7 +2086,11 @@ nsCSSFrameConstructor::TableIsValidCellContent(nsIPresContext* aPresContext, (nsXULAtoms::toolbox == tag.get()) || (nsXULAtoms::toolbar == tag.get()) || (nsXULAtoms::toolbaritem == tag.get()) || + (nsXULAtoms::stack == tag.get()) || (nsXULAtoms::deck == tag.get()) || + (nsXULAtoms::spring == tag.get()) || + (nsXULAtoms::title == tag.get()) || + (nsXULAtoms::titledbox == tag.get()) || (nsXULAtoms::tabcontrol == tag.get()) || (nsXULAtoms::tabbox == tag.get()) || (nsXULAtoms::tabpanel == tag.get()) || @@ -2323,7 +2333,7 @@ nsCSSFrameConstructor::ConstructDocElementFrame(nsIPresShell* aPresShell, PRInt32 nameSpaceID; if (NS_SUCCEEDED(aDocElement->GetNameSpaceID(nameSpaceID)) && nameSpaceID == nsXULAtoms::nameSpaceID) { - NS_NewBoxFrame(aPresShell, &contentFrame); + NS_NewBoxFrame(aPresShell, &contentFrame, PR_TRUE); } else { NS_NewDocumentElementFrame(aPresShell, &contentFrame); @@ -2982,6 +2992,10 @@ nsCSSFrameConstructor::ConstructSelectFrame(nsIPresShell* aPresShell, nsIComboboxControlFrame* comboBox = nsnull; if (NS_SUCCEEDED(comboboxFrame->QueryInterface(kIComboboxControlFrameIID, (void**)&comboBox))) { + + // XXX added for Rods code. -EDV + //comboBox->SetFrameConstructor(this); + // Create a listbox nsIFrame * listFrame; rv = NS_NewListControlFrame(aPresShell, &listFrame); @@ -4066,7 +4080,144 @@ nsCSSFrameConstructor::ConstructXULFrame(nsIPresShell* aPresShell, isAbsolutelyPositioned = PR_TRUE; // Create a frame based on the tag - if (aTag == nsXULAtoms::spinner) + // box is first because it is created the most. + // BOX CONSTRUCTION + if (aTag == nsXULAtoms::box || aTag == nsXULAtoms::tabbox || + aTag == nsXULAtoms::tabpage || aTag == nsXULAtoms::tabcontrol) { + processChildren = PR_TRUE; + isReplaced = PR_TRUE; + rv = NS_NewBoxFrame(aPresShell, &newFrame); + + const nsStyleDisplay* display = (const nsStyleDisplay*) + aStyleContext->GetStyleData(eStyleStruct_Display); + + // Boxes can scroll. + if (IsScrollable(aPresContext, display)) { + + // set the top to be the newly created scrollframe + BuildScrollFrame(aPresShell, aPresContext, aState, aContent, aStyleContext, newFrame, aParentFrame, + topFrame, aStyleContext); + + // we have a scrollframe so the parent becomes the scroll frame. + newFrame->GetParent(&aParentFrame); + + primaryFrameSet = PR_TRUE; + + frameHasBeenInitialized = PR_TRUE; + + } + } // End of BOX CONSTRUCTION logic + + // TITLED BUTTON CONSTRUCTION + else if (aTag == nsXULAtoms::titledbutton || + aTag == nsXULAtoms::image) { + + processChildren = PR_TRUE; + isReplaced = PR_TRUE; + rv = NS_NewTitledButtonFrame(aPresShell, &newFrame); + } + // End of TITLED BUTTON CONSTRUCTION logic + + else if (aTag == nsXULAtoms::spring) { + processChildren = PR_TRUE; + isReplaced = PR_TRUE; + rv = NS_NewSpringFrame(aPresShell, &newFrame); + } + // End of TITLED BUTTON CONSTRUCTION logic + + // TEXT CONSTRUCTION + else if (aTag == nsXULAtoms::text) { + processChildren = PR_TRUE; + isReplaced = PR_TRUE; + rv = NS_NewXULTextFrame(aPresShell, &newFrame); + } + // End of TEXT CONSTRUCTION logic + + // Menu Construction + else if (aTag == nsXULAtoms::menu || + aTag == nsXULAtoms::menuitem || + aTag == nsXULAtoms::menulist || + aTag == nsXULAtoms::menubutton) { + // A derived class box frame + // that has custom reflow to prevent menu children + // from becoming part of the flow. + processChildren = PR_TRUE; // Will need this to be custom. + isReplaced = PR_TRUE; + rv = NS_NewMenuFrame(aPresShell, &newFrame, (aTag != nsXULAtoms::menuitem)); + } + else if (aTag == nsXULAtoms::menubar) { +#ifdef XP_MAC // The Mac uses its native menu bar. + aHaltProcessing = PR_TRUE; + return NS_OK; +#else + processChildren = PR_TRUE; + rv = NS_NewMenuBarFrame(aPresShell, &newFrame); +#endif + } + else if (aTag == nsXULAtoms::popupset) { + // This frame contains child popups + processChildren = PR_TRUE; + isReplaced = PR_TRUE; + rv = NS_NewPopupSetFrame(aPresShell, &newFrame); + } + else if (aTag == nsXULAtoms::menupopup || aTag == nsXULAtoms::popup) { + // This is its own frame that derives from + // box. + processChildren = PR_TRUE; + isReplaced = PR_TRUE; + rv = NS_NewMenuPopupFrame(aPresShell, &newFrame); + } + else if (aTag == nsXULAtoms::title) { + processChildren = PR_TRUE; + isReplaced = PR_TRUE; + rv = NS_NewTitleFrame(aPresShell, &newFrame); + + const nsStyleDisplay* display = (const nsStyleDisplay*) + aStyleContext->GetStyleData(eStyleStruct_Display); + + // Boxes can scroll. + if (IsScrollable(aPresContext, display)) { + + // set the top to be the newly created scrollframe + BuildScrollFrame(aPresShell, aPresContext, aState, aContent, aStyleContext, newFrame, aParentFrame, + topFrame, aStyleContext); + + // we have a scrollframe so the parent becomes the scroll frame. + newFrame->GetParent(&aParentFrame); + + primaryFrameSet = PR_TRUE; + + frameHasBeenInitialized = PR_TRUE; + + } + } // End of BOX CONSTRUCTION logic + + else if (aTag == nsXULAtoms::titledbox) { + + ConstructTitledBoxFrame(aPresShell, aPresContext, aState, aContent, aParentFrame, aTag, aStyleContext, newFrame); + processChildren = PR_FALSE; + isReplaced = PR_TRUE; + + const nsStyleDisplay* display = (const nsStyleDisplay*) + aStyleContext->GetStyleData(eStyleStruct_Display); + + // Boxes can scroll. + if (IsScrollable(aPresContext, display)) { + + // set the top to be the newly created scrollframe + BuildScrollFrame(aPresShell, aPresContext, aState, aContent, aStyleContext, newFrame, aParentFrame, + topFrame, aStyleContext); + + // we have a scrollframe so the parent becomes the scroll frame. + newFrame->GetParent(&aParentFrame); + + primaryFrameSet = PR_TRUE; + + frameHasBeenInitialized = PR_TRUE; + } + } + + else if (aTag == nsXULAtoms::spinner) rv = NS_NewSpinnerFrame(aPresShell, &newFrame); else if (aTag == nsXULAtoms::colorpicker) rv = NS_NewColorPickerFrame(aPresShell, &newFrame); @@ -4222,129 +4373,7 @@ nsCSSFrameConstructor::ConstructXULFrame(nsIPresShell* aPresShell, rv = NS_NewProgressMeterFrame(aPresShell, &newFrame); } // End of PROGRESS METER CONSTRUCTION logic - - // Menu Construction - else if (aTag == nsXULAtoms::menu || - aTag == nsXULAtoms::menuitem || - aTag == nsXULAtoms::menulist || - aTag == nsXULAtoms::menubutton) { - // A derived class box frame - // that has custom reflow to prevent menu children - // from becoming part of the flow. - processChildren = PR_TRUE; // Will need this to be custom. - isReplaced = PR_TRUE; - rv = NS_NewMenuFrame(aPresShell, &newFrame, (aTag != nsXULAtoms::menuitem)); - } - else if (aTag == nsXULAtoms::menubar) { -#ifdef XP_MAC // The Mac uses its native menu bar. - aHaltProcessing = PR_TRUE; - return NS_OK; -#else - processChildren = PR_TRUE; - rv = NS_NewMenuBarFrame(aPresShell, &newFrame); -#endif - } - else if (aTag == nsXULAtoms::popupset) { - // This frame contains child popups - processChildren = PR_TRUE; - isReplaced = PR_TRUE; - rv = NS_NewPopupSetFrame(aPresShell, &newFrame); - } - else if (aTag == nsXULAtoms::menupopup || aTag == nsXULAtoms::popup) { - // This is its own frame that derives from - // box. - processChildren = PR_TRUE; - isReplaced = PR_TRUE; - rv = NS_NewMenuPopupFrame(aPresShell, &newFrame); - } - - // BOX CONSTRUCTION - else if (aTag == nsXULAtoms::box || aTag == nsXULAtoms::tabbox || - aTag == nsXULAtoms::tabpage || aTag == nsXULAtoms::tabcontrol) { - processChildren = PR_TRUE; - isReplaced = PR_TRUE; - rv = NS_NewBoxFrame(aPresShell, &newFrame); - - const nsStyleDisplay* display = (const nsStyleDisplay*) - aStyleContext->GetStyleData(eStyleStruct_Display); - - // Boxes can scroll. - if (IsScrollable(aPresContext, display)) { - - // set the top to be the newly created scrollframe - BuildScrollFrame(aPresShell, aPresContext, aState, aContent, aStyleContext, newFrame, aParentFrame, - topFrame, aStyleContext); - - // we have a scrollframe so the parent becomes the scroll frame. - newFrame->GetParent(&aParentFrame); - - primaryFrameSet = PR_TRUE; - - frameHasBeenInitialized = PR_TRUE; - - } - } // End of BOX CONSTRUCTION logic - - else if (aTag == nsXULAtoms::title) { - processChildren = PR_TRUE; - isReplaced = PR_TRUE; - rv = NS_NewTitleFrame(aPresShell, &newFrame); - - const nsStyleDisplay* display = (const nsStyleDisplay*) - aStyleContext->GetStyleData(eStyleStruct_Display); - - // Boxes can scroll. - if (IsScrollable(aPresContext, display)) { - - // set the top to be the newly created scrollframe - BuildScrollFrame(aPresShell, aPresContext, aState, aContent, aStyleContext, newFrame, aParentFrame, - topFrame, aStyleContext); - - // we have a scrollframe so the parent becomes the scroll frame. - newFrame->GetParent(&aParentFrame); - - primaryFrameSet = PR_TRUE; - - frameHasBeenInitialized = PR_TRUE; - - } - } // End of BOX CONSTRUCTION logic - - else if (aTag == nsXULAtoms::titledbox) { - - ConstructTitledBoxFrame(aPresShell, aPresContext, aState, aContent, aParentFrame, aTag, aStyleContext, newFrame); - processChildren = PR_FALSE; - isReplaced = PR_TRUE; - - const nsStyleDisplay* display = (const nsStyleDisplay*) - aStyleContext->GetStyleData(eStyleStruct_Display); - - // Boxes can scroll. - if (IsScrollable(aPresContext, display)) { - - // set the top to be the newly created scrollframe - BuildScrollFrame(aPresShell, aPresContext, aState, aContent, aStyleContext, newFrame, aParentFrame, - topFrame, aStyleContext); - - // we have a scrollframe so the parent becomes the scroll frame. - newFrame->GetParent(&aParentFrame); - - primaryFrameSet = PR_TRUE; - - frameHasBeenInitialized = PR_TRUE; - } - } - - // TITLED BUTTON CONSTRUCTION - else if (aTag == nsXULAtoms::titledbutton || - aTag == nsXULAtoms::image) { - - processChildren = PR_TRUE; - isReplaced = PR_TRUE; - rv = NS_NewTitledButtonFrame(aPresShell, &newFrame); - } - // End of TITLED BUTTON CONSTRUCTION logic - + // XULCHECKBOX CONSTRUCTION else if (aTag == nsXULAtoms::checkbox || aTag == nsXULAtoms::radio) { @@ -4354,13 +4383,13 @@ nsCSSFrameConstructor::ConstructXULFrame(nsIPresShell* aPresShell, } // End of XULCHECKBOX CONSTRUCTION logic - // TEXT CONSTRUCTION - else if (aTag == nsXULAtoms::text) { - processChildren = PR_TRUE; + // STACK CONSTRUCTION + else if (aTag == nsXULAtoms::stack) { + processChildren = PR_TRUE; isReplaced = PR_TRUE; - rv = NS_NewXULTextFrame(aPresShell, &newFrame); + rv = NS_NewStackFrame(aPresShell, &newFrame); } - // End of TEXT CONSTRUCTION logic + // End of STACK CONSTRUCTION logic // DECK CONSTRUCTION else if (aTag == nsXULAtoms::deck || aTag == nsXULAtoms::tabpanel) { diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp index b0d67818ffdc..4c2a5bab7f44 100644 --- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -141,7 +141,7 @@ static NS_DEFINE_CID(kCXIFConverterCID, NS_XIFFORMATCONVERTER_CID); static PRInt32 gMaxRCProcessingTime = -1; // Largest chunk size we recycle -static const size_t gMaxRecycledSize = 200; +static const size_t gMaxRecycledSize = 300; // Flag for enabling/disabling asynchronous reflow // Set via the "layout.reflow.async" pref diff --git a/layout/generic/nsGfxScrollFrame.cpp b/layout/generic/nsGfxScrollFrame.cpp index 0623d871cc3f..82af61be92a9 100644 --- a/layout/generic/nsGfxScrollFrame.cpp +++ b/layout/generic/nsGfxScrollFrame.cpp @@ -1465,8 +1465,6 @@ nsGfxScrollFrameInner::ReflowScrollArea( nsIPresContext* aPresContext, nsSize size; GetScrolledContentSize(aPresContext, size); - PRBool mustReflow = PR_FALSE; - // There are two cases to consider if (size.height <= scrollAreaSize.height || aReflowState.mStyleDisplay->mOverflow == NS_STYLE_OVERFLOW_SCROLLBARS_HORIZONTAL @@ -1488,6 +1486,13 @@ nsGfxScrollFrameInner::ReflowScrollArea( nsIPresContext* aPresContext, // Go ahead and reflow the child a second time if we added or removed the scrollbar if (mustReflow) { + + // make sure we mark it as dirty so it will reflow again. + nsFrameState childState; + mScrollAreaFrame->GetFrameState(&childState); + childState |= NS_FRAME_IS_DIRTY; + mScrollAreaFrame->SetFrameState(childState); + scrollAreaReflowSize.SizeTo(scrollAreaSize.width, scrollAreaSize.height); resized = PR_FALSE; @@ -1750,6 +1755,22 @@ nsGfxScrollFrame::InvalidateCache(nsIFrame* aChild) return NS_OK; } +NS_IMETHODIMP +nsGfxScrollFrame::SetDebug(nsIPresContext* aPresContext, PRBool aDebug) +{ + nsIFrame* kid = mFrames.FirstChild(); + while (nsnull != kid) { + nsIBox* ibox = nsnull; + if (NS_SUCCEEDED(kid->QueryInterface(NS_GET_IID(nsIBox), (void**)&ibox)) && ibox) { + ibox->SetDebug(aPresContext, aDebug); + } + + kid->GetNextSibling(&kid); + } + + return NS_OK; +} + NS_IMETHODIMP nsGfxScrollFrame::GetBoxInfo(nsIPresContext* aPresContext, const nsHTMLReflowState& aReflowState, nsBoxInfo& aSize) diff --git a/layout/generic/nsGfxScrollFrame.h b/layout/generic/nsGfxScrollFrame.h index b512e0665323..4e89b87eba81 100644 --- a/layout/generic/nsGfxScrollFrame.h +++ b/layout/generic/nsGfxScrollFrame.h @@ -53,6 +53,8 @@ public: nsIStyleContext* aContext, nsIFrame* aPrevInFlow); + NS_IMETHOD SetDebug(nsIPresContext* aPresContext, PRBool aDebug); + virtual ~nsGfxScrollFrame(); diff --git a/layout/html/base/src/nsGfxScrollFrame.cpp b/layout/html/base/src/nsGfxScrollFrame.cpp index 0623d871cc3f..82af61be92a9 100644 --- a/layout/html/base/src/nsGfxScrollFrame.cpp +++ b/layout/html/base/src/nsGfxScrollFrame.cpp @@ -1465,8 +1465,6 @@ nsGfxScrollFrameInner::ReflowScrollArea( nsIPresContext* aPresContext, nsSize size; GetScrolledContentSize(aPresContext, size); - PRBool mustReflow = PR_FALSE; - // There are two cases to consider if (size.height <= scrollAreaSize.height || aReflowState.mStyleDisplay->mOverflow == NS_STYLE_OVERFLOW_SCROLLBARS_HORIZONTAL @@ -1488,6 +1486,13 @@ nsGfxScrollFrameInner::ReflowScrollArea( nsIPresContext* aPresContext, // Go ahead and reflow the child a second time if we added or removed the scrollbar if (mustReflow) { + + // make sure we mark it as dirty so it will reflow again. + nsFrameState childState; + mScrollAreaFrame->GetFrameState(&childState); + childState |= NS_FRAME_IS_DIRTY; + mScrollAreaFrame->SetFrameState(childState); + scrollAreaReflowSize.SizeTo(scrollAreaSize.width, scrollAreaSize.height); resized = PR_FALSE; @@ -1750,6 +1755,22 @@ nsGfxScrollFrame::InvalidateCache(nsIFrame* aChild) return NS_OK; } +NS_IMETHODIMP +nsGfxScrollFrame::SetDebug(nsIPresContext* aPresContext, PRBool aDebug) +{ + nsIFrame* kid = mFrames.FirstChild(); + while (nsnull != kid) { + nsIBox* ibox = nsnull; + if (NS_SUCCEEDED(kid->QueryInterface(NS_GET_IID(nsIBox), (void**)&ibox)) && ibox) { + ibox->SetDebug(aPresContext, aDebug); + } + + kid->GetNextSibling(&kid); + } + + return NS_OK; +} + NS_IMETHODIMP nsGfxScrollFrame::GetBoxInfo(nsIPresContext* aPresContext, const nsHTMLReflowState& aReflowState, nsBoxInfo& aSize) diff --git a/layout/html/base/src/nsGfxScrollFrame.h b/layout/html/base/src/nsGfxScrollFrame.h index b512e0665323..4e89b87eba81 100644 --- a/layout/html/base/src/nsGfxScrollFrame.h +++ b/layout/html/base/src/nsGfxScrollFrame.h @@ -53,6 +53,8 @@ public: nsIStyleContext* aContext, nsIFrame* aPrevInFlow); + NS_IMETHOD SetDebug(nsIPresContext* aPresContext, PRBool aDebug); + virtual ~nsGfxScrollFrame(); diff --git a/layout/html/base/src/nsPresShell.cpp b/layout/html/base/src/nsPresShell.cpp index b0d67818ffdc..4c2a5bab7f44 100644 --- a/layout/html/base/src/nsPresShell.cpp +++ b/layout/html/base/src/nsPresShell.cpp @@ -141,7 +141,7 @@ static NS_DEFINE_CID(kCXIFConverterCID, NS_XIFFORMATCONVERTER_CID); static PRInt32 gMaxRCProcessingTime = -1; // Largest chunk size we recycle -static const size_t gMaxRecycledSize = 200; +static const size_t gMaxRecycledSize = 300; // Flag for enabling/disabling asynchronous reflow // Set via the "layout.reflow.async" pref diff --git a/layout/html/base/src/nsScrollPortFrame.cpp b/layout/html/base/src/nsScrollPortFrame.cpp index 870f4968671f..c0c0b8cc176a 100644 --- a/layout/html/base/src/nsScrollPortFrame.cpp +++ b/layout/html/base/src/nsScrollPortFrame.cpp @@ -76,6 +76,24 @@ NS_NewScrollPortFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame) return NS_OK; } +NS_IMETHODIMP +nsScrollPortFrame::SetDebug(nsIPresContext* aPresContext, PRBool aDebug) +{ + nsIFrame* kid = mFrames.FirstChild(); + while (nsnull != kid) { + nsIBox* ibox = nsnull; + if (NS_SUCCEEDED(kid->QueryInterface(NS_GET_IID(nsIBox), (void**)&ibox)) && ibox) { + ibox->SetDebug(aPresContext, aDebug); + } + + kid->GetNextSibling(&kid); + } + + mNeedsRecalc = PR_TRUE; + + return NS_OK; +} + nsScrollPortFrame::nsScrollPortFrame() { //mIncremental = PR_FALSE; @@ -424,12 +442,18 @@ nsScrollPortFrame::Reflow(nsIPresContext* aPresContext, nscoord theHeight; nsIBox* box; + nsReflowReason reason = aReflowState.reason; nsresult result = kidFrame->QueryInterface(NS_GET_IID(nsIBox), (void**)&box); - if (NS_SUCCEEDED(result)) + if (NS_SUCCEEDED(result)) theHeight = aReflowState.mComputedHeight; - else + else { theHeight = NS_INTRINSICSIZE; - + // html can't handle a reflow of dirty. Convert it to + // a resize reflow + if (reason == eReflowReason_Dirty) + reason = eReflowReason_Resize; + } + nsSize kidReflowSize(aReflowState.availableWidth, theHeight); nsHTMLReflowState kidReflowState(aPresContext, aReflowState, kidFrame, kidReflowSize); @@ -437,6 +461,7 @@ nsScrollPortFrame::Reflow(nsIPresContext* aPresContext, kidReflowState.mComputedWidth = aReflowState.mComputedWidth; kidReflowState.mComputedHeight = theHeight; + kidReflowState.reason = reason; nscoord pwidth = (kidReflowState.mComputedBorderPadding.left + kidReflowState.mComputedBorderPadding.right); nscoord pheight = (kidReflowState.mComputedBorderPadding.top + kidReflowState.mComputedBorderPadding.bottom); diff --git a/layout/html/base/src/nsScrollPortFrame.h b/layout/html/base/src/nsScrollPortFrame.h index 572a7a54599a..b728751b3b8d 100644 --- a/layout/html/base/src/nsScrollPortFrame.h +++ b/layout/html/base/src/nsScrollPortFrame.h @@ -44,6 +44,8 @@ public: nsIStyleContext* aContext, nsIFrame* aPrevInFlow); + NS_IMETHOD SetDebug(nsIPresContext* aPresContext, PRBool aDebug); + // Called to set the one and only child frame. Returns NS_ERROR_INVALID_ARG // if the child frame is NULL, and NS_ERROR_UNEXPECTED if the child list // contains more than one frame diff --git a/layout/html/style/src/nsCSSFrameConstructor.cpp b/layout/html/style/src/nsCSSFrameConstructor.cpp index a0b2aab157a4..8bcf05c87484 100644 --- a/layout/html/style/src/nsCSSFrameConstructor.cpp +++ b/layout/html/style/src/nsCSSFrameConstructor.cpp @@ -146,6 +146,12 @@ NS_NewTabFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame ); nsresult NS_NewDeckFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame ); +nsresult +NS_NewSpringFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame ); + +nsresult +NS_NewStackFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame ); + nsresult NS_NewProgressMeterFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame ); @@ -165,7 +171,7 @@ nsresult NS_NewTitleFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame ); nsresult -NS_NewBoxFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame); +NS_NewBoxFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame, PRBool aIsRoot); nsresult NS_NewSliderFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame ); @@ -2080,7 +2086,11 @@ nsCSSFrameConstructor::TableIsValidCellContent(nsIPresContext* aPresContext, (nsXULAtoms::toolbox == tag.get()) || (nsXULAtoms::toolbar == tag.get()) || (nsXULAtoms::toolbaritem == tag.get()) || + (nsXULAtoms::stack == tag.get()) || (nsXULAtoms::deck == tag.get()) || + (nsXULAtoms::spring == tag.get()) || + (nsXULAtoms::title == tag.get()) || + (nsXULAtoms::titledbox == tag.get()) || (nsXULAtoms::tabcontrol == tag.get()) || (nsXULAtoms::tabbox == tag.get()) || (nsXULAtoms::tabpanel == tag.get()) || @@ -2323,7 +2333,7 @@ nsCSSFrameConstructor::ConstructDocElementFrame(nsIPresShell* aPresShell, PRInt32 nameSpaceID; if (NS_SUCCEEDED(aDocElement->GetNameSpaceID(nameSpaceID)) && nameSpaceID == nsXULAtoms::nameSpaceID) { - NS_NewBoxFrame(aPresShell, &contentFrame); + NS_NewBoxFrame(aPresShell, &contentFrame, PR_TRUE); } else { NS_NewDocumentElementFrame(aPresShell, &contentFrame); @@ -2982,6 +2992,10 @@ nsCSSFrameConstructor::ConstructSelectFrame(nsIPresShell* aPresShell, nsIComboboxControlFrame* comboBox = nsnull; if (NS_SUCCEEDED(comboboxFrame->QueryInterface(kIComboboxControlFrameIID, (void**)&comboBox))) { + + // XXX added for Rods code. -EDV + //comboBox->SetFrameConstructor(this); + // Create a listbox nsIFrame * listFrame; rv = NS_NewListControlFrame(aPresShell, &listFrame); @@ -4066,7 +4080,144 @@ nsCSSFrameConstructor::ConstructXULFrame(nsIPresShell* aPresShell, isAbsolutelyPositioned = PR_TRUE; // Create a frame based on the tag - if (aTag == nsXULAtoms::spinner) + // box is first because it is created the most. + // BOX CONSTRUCTION + if (aTag == nsXULAtoms::box || aTag == nsXULAtoms::tabbox || + aTag == nsXULAtoms::tabpage || aTag == nsXULAtoms::tabcontrol) { + processChildren = PR_TRUE; + isReplaced = PR_TRUE; + rv = NS_NewBoxFrame(aPresShell, &newFrame); + + const nsStyleDisplay* display = (const nsStyleDisplay*) + aStyleContext->GetStyleData(eStyleStruct_Display); + + // Boxes can scroll. + if (IsScrollable(aPresContext, display)) { + + // set the top to be the newly created scrollframe + BuildScrollFrame(aPresShell, aPresContext, aState, aContent, aStyleContext, newFrame, aParentFrame, + topFrame, aStyleContext); + + // we have a scrollframe so the parent becomes the scroll frame. + newFrame->GetParent(&aParentFrame); + + primaryFrameSet = PR_TRUE; + + frameHasBeenInitialized = PR_TRUE; + + } + } // End of BOX CONSTRUCTION logic + + // TITLED BUTTON CONSTRUCTION + else if (aTag == nsXULAtoms::titledbutton || + aTag == nsXULAtoms::image) { + + processChildren = PR_TRUE; + isReplaced = PR_TRUE; + rv = NS_NewTitledButtonFrame(aPresShell, &newFrame); + } + // End of TITLED BUTTON CONSTRUCTION logic + + else if (aTag == nsXULAtoms::spring) { + processChildren = PR_TRUE; + isReplaced = PR_TRUE; + rv = NS_NewSpringFrame(aPresShell, &newFrame); + } + // End of TITLED BUTTON CONSTRUCTION logic + + // TEXT CONSTRUCTION + else if (aTag == nsXULAtoms::text) { + processChildren = PR_TRUE; + isReplaced = PR_TRUE; + rv = NS_NewXULTextFrame(aPresShell, &newFrame); + } + // End of TEXT CONSTRUCTION logic + + // Menu Construction + else if (aTag == nsXULAtoms::menu || + aTag == nsXULAtoms::menuitem || + aTag == nsXULAtoms::menulist || + aTag == nsXULAtoms::menubutton) { + // A derived class box frame + // that has custom reflow to prevent menu children + // from becoming part of the flow. + processChildren = PR_TRUE; // Will need this to be custom. + isReplaced = PR_TRUE; + rv = NS_NewMenuFrame(aPresShell, &newFrame, (aTag != nsXULAtoms::menuitem)); + } + else if (aTag == nsXULAtoms::menubar) { +#ifdef XP_MAC // The Mac uses its native menu bar. + aHaltProcessing = PR_TRUE; + return NS_OK; +#else + processChildren = PR_TRUE; + rv = NS_NewMenuBarFrame(aPresShell, &newFrame); +#endif + } + else if (aTag == nsXULAtoms::popupset) { + // This frame contains child popups + processChildren = PR_TRUE; + isReplaced = PR_TRUE; + rv = NS_NewPopupSetFrame(aPresShell, &newFrame); + } + else if (aTag == nsXULAtoms::menupopup || aTag == nsXULAtoms::popup) { + // This is its own frame that derives from + // box. + processChildren = PR_TRUE; + isReplaced = PR_TRUE; + rv = NS_NewMenuPopupFrame(aPresShell, &newFrame); + } + else if (aTag == nsXULAtoms::title) { + processChildren = PR_TRUE; + isReplaced = PR_TRUE; + rv = NS_NewTitleFrame(aPresShell, &newFrame); + + const nsStyleDisplay* display = (const nsStyleDisplay*) + aStyleContext->GetStyleData(eStyleStruct_Display); + + // Boxes can scroll. + if (IsScrollable(aPresContext, display)) { + + // set the top to be the newly created scrollframe + BuildScrollFrame(aPresShell, aPresContext, aState, aContent, aStyleContext, newFrame, aParentFrame, + topFrame, aStyleContext); + + // we have a scrollframe so the parent becomes the scroll frame. + newFrame->GetParent(&aParentFrame); + + primaryFrameSet = PR_TRUE; + + frameHasBeenInitialized = PR_TRUE; + + } + } // End of BOX CONSTRUCTION logic + + else if (aTag == nsXULAtoms::titledbox) { + + ConstructTitledBoxFrame(aPresShell, aPresContext, aState, aContent, aParentFrame, aTag, aStyleContext, newFrame); + processChildren = PR_FALSE; + isReplaced = PR_TRUE; + + const nsStyleDisplay* display = (const nsStyleDisplay*) + aStyleContext->GetStyleData(eStyleStruct_Display); + + // Boxes can scroll. + if (IsScrollable(aPresContext, display)) { + + // set the top to be the newly created scrollframe + BuildScrollFrame(aPresShell, aPresContext, aState, aContent, aStyleContext, newFrame, aParentFrame, + topFrame, aStyleContext); + + // we have a scrollframe so the parent becomes the scroll frame. + newFrame->GetParent(&aParentFrame); + + primaryFrameSet = PR_TRUE; + + frameHasBeenInitialized = PR_TRUE; + } + } + + else if (aTag == nsXULAtoms::spinner) rv = NS_NewSpinnerFrame(aPresShell, &newFrame); else if (aTag == nsXULAtoms::colorpicker) rv = NS_NewColorPickerFrame(aPresShell, &newFrame); @@ -4222,129 +4373,7 @@ nsCSSFrameConstructor::ConstructXULFrame(nsIPresShell* aPresShell, rv = NS_NewProgressMeterFrame(aPresShell, &newFrame); } // End of PROGRESS METER CONSTRUCTION logic - - // Menu Construction - else if (aTag == nsXULAtoms::menu || - aTag == nsXULAtoms::menuitem || - aTag == nsXULAtoms::menulist || - aTag == nsXULAtoms::menubutton) { - // A derived class box frame - // that has custom reflow to prevent menu children - // from becoming part of the flow. - processChildren = PR_TRUE; // Will need this to be custom. - isReplaced = PR_TRUE; - rv = NS_NewMenuFrame(aPresShell, &newFrame, (aTag != nsXULAtoms::menuitem)); - } - else if (aTag == nsXULAtoms::menubar) { -#ifdef XP_MAC // The Mac uses its native menu bar. - aHaltProcessing = PR_TRUE; - return NS_OK; -#else - processChildren = PR_TRUE; - rv = NS_NewMenuBarFrame(aPresShell, &newFrame); -#endif - } - else if (aTag == nsXULAtoms::popupset) { - // This frame contains child popups - processChildren = PR_TRUE; - isReplaced = PR_TRUE; - rv = NS_NewPopupSetFrame(aPresShell, &newFrame); - } - else if (aTag == nsXULAtoms::menupopup || aTag == nsXULAtoms::popup) { - // This is its own frame that derives from - // box. - processChildren = PR_TRUE; - isReplaced = PR_TRUE; - rv = NS_NewMenuPopupFrame(aPresShell, &newFrame); - } - - // BOX CONSTRUCTION - else if (aTag == nsXULAtoms::box || aTag == nsXULAtoms::tabbox || - aTag == nsXULAtoms::tabpage || aTag == nsXULAtoms::tabcontrol) { - processChildren = PR_TRUE; - isReplaced = PR_TRUE; - rv = NS_NewBoxFrame(aPresShell, &newFrame); - - const nsStyleDisplay* display = (const nsStyleDisplay*) - aStyleContext->GetStyleData(eStyleStruct_Display); - - // Boxes can scroll. - if (IsScrollable(aPresContext, display)) { - - // set the top to be the newly created scrollframe - BuildScrollFrame(aPresShell, aPresContext, aState, aContent, aStyleContext, newFrame, aParentFrame, - topFrame, aStyleContext); - - // we have a scrollframe so the parent becomes the scroll frame. - newFrame->GetParent(&aParentFrame); - - primaryFrameSet = PR_TRUE; - - frameHasBeenInitialized = PR_TRUE; - - } - } // End of BOX CONSTRUCTION logic - - else if (aTag == nsXULAtoms::title) { - processChildren = PR_TRUE; - isReplaced = PR_TRUE; - rv = NS_NewTitleFrame(aPresShell, &newFrame); - - const nsStyleDisplay* display = (const nsStyleDisplay*) - aStyleContext->GetStyleData(eStyleStruct_Display); - - // Boxes can scroll. - if (IsScrollable(aPresContext, display)) { - - // set the top to be the newly created scrollframe - BuildScrollFrame(aPresShell, aPresContext, aState, aContent, aStyleContext, newFrame, aParentFrame, - topFrame, aStyleContext); - - // we have a scrollframe so the parent becomes the scroll frame. - newFrame->GetParent(&aParentFrame); - - primaryFrameSet = PR_TRUE; - - frameHasBeenInitialized = PR_TRUE; - - } - } // End of BOX CONSTRUCTION logic - - else if (aTag == nsXULAtoms::titledbox) { - - ConstructTitledBoxFrame(aPresShell, aPresContext, aState, aContent, aParentFrame, aTag, aStyleContext, newFrame); - processChildren = PR_FALSE; - isReplaced = PR_TRUE; - - const nsStyleDisplay* display = (const nsStyleDisplay*) - aStyleContext->GetStyleData(eStyleStruct_Display); - - // Boxes can scroll. - if (IsScrollable(aPresContext, display)) { - - // set the top to be the newly created scrollframe - BuildScrollFrame(aPresShell, aPresContext, aState, aContent, aStyleContext, newFrame, aParentFrame, - topFrame, aStyleContext); - - // we have a scrollframe so the parent becomes the scroll frame. - newFrame->GetParent(&aParentFrame); - - primaryFrameSet = PR_TRUE; - - frameHasBeenInitialized = PR_TRUE; - } - } - - // TITLED BUTTON CONSTRUCTION - else if (aTag == nsXULAtoms::titledbutton || - aTag == nsXULAtoms::image) { - - processChildren = PR_TRUE; - isReplaced = PR_TRUE; - rv = NS_NewTitledButtonFrame(aPresShell, &newFrame); - } - // End of TITLED BUTTON CONSTRUCTION logic - + // XULCHECKBOX CONSTRUCTION else if (aTag == nsXULAtoms::checkbox || aTag == nsXULAtoms::radio) { @@ -4354,13 +4383,13 @@ nsCSSFrameConstructor::ConstructXULFrame(nsIPresShell* aPresShell, } // End of XULCHECKBOX CONSTRUCTION logic - // TEXT CONSTRUCTION - else if (aTag == nsXULAtoms::text) { - processChildren = PR_TRUE; + // STACK CONSTRUCTION + else if (aTag == nsXULAtoms::stack) { + processChildren = PR_TRUE; isReplaced = PR_TRUE; - rv = NS_NewXULTextFrame(aPresShell, &newFrame); + rv = NS_NewStackFrame(aPresShell, &newFrame); } - // End of TEXT CONSTRUCTION logic + // End of STACK CONSTRUCTION logic // DECK CONSTRUCTION else if (aTag == nsXULAtoms::deck || aTag == nsXULAtoms::tabpanel) { diff --git a/layout/macbuild/layout.mcp b/layout/macbuild/layout.mcp index 0d12f1b511b1..489cc631bf9b 100644 Binary files a/layout/macbuild/layout.mcp and b/layout/macbuild/layout.mcp differ diff --git a/layout/xul/base/src/Makefile.in b/layout/xul/base/src/Makefile.in index 3f98884cfe4e..4f6215fc297c 100644 --- a/layout/xul/base/src/Makefile.in +++ b/layout/xul/base/src/Makefile.in @@ -30,7 +30,10 @@ MODULE = layout LIBRARY_NAME = raptorxulbase_s CPPSRCS = \ - nsXULTextFrame.cpp \ + nsStackFrame.cpp \ + nsSpringFrame.cpp \ + nsXULLeafFrame.cpp \ + nsXULTextFrame.cpp \ nsTitledBoxFrame.cpp \ nsTitleFrame.cpp \ nsFrameNavigator.cpp \ diff --git a/layout/xul/base/src/makefile.win b/layout/xul/base/src/makefile.win index cc68f157c29a..50cc454ca122 100644 --- a/layout/xul/base/src/makefile.win +++ b/layout/xul/base/src/makefile.win @@ -28,6 +28,8 @@ REQUIRES=xpcom raptor pref DEFINES=-D_IMPL_NS_HTML -DWIN32_LEAN_AND_MEAN CPPSRCS= \ + nsSpringFrame.cpp \ + nsXULLeafFrame.cpp \ nsXULTextFrame.cpp \ nsTitleFrame.cpp \ nsTitledBoxFrame.cpp \ @@ -38,6 +40,7 @@ CPPSRCS= \ nsSplitterFrame.cpp \ nsGrippyFrame.cpp \ nsTabFrame.cpp \ + nsStackFrame.cpp \ nsDeckFrame.cpp \ nsBoxFrame.cpp \ nsProgressMeterFrame.cpp \ @@ -70,8 +73,10 @@ CPPSRCS= \ $(NULL) CPP_OBJS= \ - .\$(OBJDIR)\nsTitleFrame.obj \ + .\$(OBJDIR)\nsSpringFrame.obj \ + .\$(OBJDIR)\nsXULLeafFrame.obj \ .\$(OBJDIR)\nsXULTextFrame.obj \ + .\$(OBJDIR)\nsTitleFrame.obj \ .\$(OBJDIR)\nsTitledBoxFrame.obj \ .\$(OBJDIR)\nsFrameNavigator.obj \ .\$(OBJDIR)\nsRepeatService.obj \ @@ -81,6 +86,7 @@ CPP_OBJS= \ .\$(OBJDIR)\nsSplitterFrame.obj \ .\$(OBJDIR)\nsTabFrame.obj \ .\$(OBJDIR)\nsDeckFrame.obj \ + .\$(OBJDIR)\nsStackFrame.obj \ .\$(OBJDIR)\nsBoxFrame.obj \ .\$(OBJDIR)\nsProgressMeterFrame.obj \ .\$(OBJDIR)\nsTitledButtonFrame.obj \ diff --git a/layout/xul/base/src/nsBoxFrame.cpp b/layout/xul/base/src/nsBoxFrame.cpp index 30346bc823b7..2feeb5ee28a0 100644 --- a/layout/xul/base/src/nsBoxFrame.cpp +++ b/layout/xul/base/src/nsBoxFrame.cpp @@ -80,70 +80,66 @@ //#define TEST_SANITY - -#define NS_STATE_IS_HORIZONTAL 0x00400000 -#define NS_STATE_AUTO_STRETCH 0x00800000 -#define NS_STATE_IS_ROOT 0x01000000 - /** * Only created when the box is in debug mode */ -class nsBoxDebugInner +class nsBoxDebug { public: - nsBoxDebugInner(nsBoxFrame* aThis) - { - mOuter = aThis; - } - virtual ~nsBoxDebugInner() {} + nsBoxDebug(nsIPresContext* aPresContext, nsBoxFrame* aBoxFrame); -public: - nsBoxFrame* mOuter; + static void AddRef(nsIPresContext* aPresContext, nsBoxFrame* aBox); + static void Release(nsIPresContext* aPresContext); + static void GetPref(nsIPresContext* aPresContext); + + void GetValue(nsIPresContext* aPresContext, const nsSize& a, const nsSize& b, char* value); + void GetValue(nsIPresContext* aPresContext, PRInt32 a, PRInt32 b, char* value); + void DrawSpring(nsIPresContext* aPresContext, nsIRenderingContext& aRenderingContext, PRBool aHorizontal, PRInt32 flex, nscoord x, nscoord y, nscoord size, nscoord springSize); + void PaintSprings(nsIPresContext* aPresContext, nsBoxFrame* aBoxFrame, nsIRenderingContext& aRenderingContext, const nsRect& aDirtyRect); + void DrawLine(nsIRenderingContext& aRenderingContext, PRBool aHorizontal, nscoord x1, nscoord y1, nscoord x2, nscoord y2); + void FillRect(nsIRenderingContext& aRenderingContext, PRBool aHorizontal, nscoord x, nscoord y, nscoord width, nscoord height); - static nsIFrame* mDebugChild; - void GetValue(const nsSize& a, const nsSize& b, char* value); - void GetValue(PRInt32 a, PRInt32 b, char* value); - void DrawSpring( nsIPresContext* aPresContext, nsIRenderingContext& aRenderingContext, PRInt32 flex, nscoord x, nscoord y, nscoord size, nscoord springSize); - void PaintSprings(nsIPresContext* aPresContext, nsIRenderingContext& aRenderingContext, const nsRect& aDirtyRect); - void DrawLine(nsIRenderingContext& aRenderingContext, nscoord x1, nscoord y1, nscoord x2, nscoord y2); - void FillRect(nsIRenderingContext& aRenderingContext, nscoord x, nscoord y, nscoord width, nscoord height); + PRBool DisplayDebugInfoFor(nsIPresContext* aPresContext, + nsBoxFrame* aBoxFrame, + nsPoint& aPoint, + PRInt32& aCursor); - PRBool DisplayDebugInfoFor(nsIPresContext* aPresContext, - nsPoint& aPoint, - PRInt32& aCursor); + nsCOMPtr mHorizontalDebugStyle; + nsCOMPtr mVerticalDebugStyle; + PRInt32 mRefCount; + nsIFrame* mDebugChild; - - static nsIStyleContext* mHorizontalDebugStyle; - static nsIStyleContext* mVerticalDebugStyle; - static PRInt32 gDebug; - static float mP2t; + static PRBool gDebug; + static nsBoxDebug* gInstance; }; -nsIStyleContext* nsBoxDebugInner::mHorizontalDebugStyle; -nsIStyleContext* nsBoxDebugInner::mVerticalDebugStyle; - -PRInt32 nsBoxDebugInner::gDebug = 0; -float nsBoxDebugInner::mP2t = 0; +PRBool nsBoxDebug::gDebug = PR_FALSE; +nsBoxDebug* nsBoxDebug::gInstance = nsnull; class nsInfoListImpl: public nsInfoList { public: + void* operator new(size_t sz, nsIPresShell* aPresShell); + void operator delete(void* aPtr, size_t sz); + void Recycle(nsIPresShell* aShell); + nsInfoListImpl(); virtual ~nsInfoListImpl(); virtual nsCalculatedBoxInfo* GetFirst(); virtual nsCalculatedBoxInfo* GetLast(); virtual PRInt32 GetCount(); + virtual nsresult SetDebug(nsIPresContext* aPresContext, PRBool aDebug); - void Clear(); - PRInt32 CreateInfosFor(nsIFrame* aList, nsCalculatedBoxInfo*& first, nsCalculatedBoxInfo*& last); - void RemoveAfter(nsCalculatedBoxInfo* aPrev); - void Remove(nsIFrame* aChild); - void Prepend(nsIFrame* aList); - void Append(nsIFrame* aList); - void Insert(nsIFrame* aPrevFrame, nsIFrame* aList); - void InsertAfter(nsCalculatedBoxInfo* aPrev, nsIFrame* aList); - void Init(nsIFrame* aList); + void Clear(nsIPresShell* aShell); + PRInt32 CreateInfosFor(nsIPresShell* aShell, nsIFrame* aList, nsCalculatedBoxInfo*& first, nsCalculatedBoxInfo*& last); + void RemoveAfter(nsIPresShell* aShell, nsCalculatedBoxInfo* aPrev); + void Remove(nsIPresShell* aShell, nsIFrame* aChild); + void Prepend(nsIPresShell* aShell, nsIFrame* aList); + void Append(nsIPresShell* aShell, nsIFrame* aList); + void Insert(nsIPresShell* aShell, nsIFrame* aPrevFrame, nsIFrame* aList); + void InsertAfter(nsIPresShell* aShell, nsCalculatedBoxInfo* aPrev, nsIFrame* aList); + void Init(nsIPresShell* aShell, nsIFrame* aList); nsCalculatedBoxInfo* GetPrevious(nsIFrame* aChild); nsCalculatedBoxInfo* GetInfo(nsIFrame* aChild); void SanityCheck(nsFrameList& aFrameList); @@ -161,6 +157,9 @@ public: virtual ~nsCalculatedBoxInfoImpl(); nsCalculatedBoxInfoImpl(const nsBoxInfo& aInfo); virtual void Clear(); + void* operator new(size_t sz, nsIPresShell* aPresShell); + void operator delete(void* aPtr, size_t sz); + virtual void Recycle(nsIPresShell* aShell); }; /** @@ -169,20 +168,34 @@ public: class nsBoxFrameInner { public: - nsBoxFrameInner(nsBoxFrame* aThis) + nsBoxFrameInner(nsIPresShell* aPresShell, nsBoxFrame* aThis) { mOuter = aThis; - mDebugInner = nsnull; - mInfoList = new nsInfoListImpl(); + mInfoList = new (aPresShell) nsInfoListImpl(); } ~nsBoxFrameInner() { - delete mDebugInner; - delete mInfoList; } + void Recycle(nsIPresShell* aPresShell); + + // Overloaded new operator. Initializes the memory to 0 and relies on an arena + // (which comes from the presShell) to perform the allocation. + void* operator new(size_t sz, nsIPresShell* aPresShell); + + // Overridden to prevent the global delete from being called, since the memory + // came out of an nsIArena instead of the global delete operator's heap. + // XXX Would like to make this private some day, but our UNIX compilers can't + // deal with it. + void operator delete(void* aPtr, size_t sz); + + // helper methods + static void* Allocate(size_t sz, nsIPresShell* aPresShell); + static void Free(void* aPtr, size_t sz); + static void RecycleFreedMemory(nsIPresShell* aPresShell, void* mem); + void GetDebugInset(nsMargin& inset); void AdjustChildren(nsIPresContext* aPresContext, nsBoxFrame* aBox); nsresult GetContentOf(nsIFrame* aFrame, nsIContent** aContent); @@ -212,8 +225,6 @@ public: void PlaceChild(nsIPresContext* aPresContext, nsIFrame* aFrame, nscoord aX, nscoord aY); - void UpdatePseudoElements(nsIPresContext* aPresContext); - void TranslateEventCoords(nsIPresContext* aPresContext, const nsPoint& aPoint, nsPoint& aResult); @@ -222,6 +233,8 @@ public: static void InvalidateAllCachesBelow(nsIPresContext* aPresContext, nsIFrame* aTargetFrame); static PRBool AdjustTargetToScope(nsIFrame* aParent, nsIFrame*& aTargetFrame); + PRBool GetInitialDebug(PRBool& aDebug); + nsBoxFrame::Halignment GetHAlign(); nsBoxFrame::Valignment GetVAlign(); void InitializeReflowState(nsIPresContext* aPresContext, const nsCalculatedBoxInfo& aInfo, nsHTMLReflowState& aReflowState, const nsHTMLReflowState& aParentReflowState, nsIFrame* aFrame, const nsSize& aAvailSize, nsReflowReason reason); @@ -235,7 +248,6 @@ public: nsCOMPtr mSpaceManager; // We own this [OWNER]. nsBoxFrame* mOuter; - nsBoxDebugInner* mDebugInner; nsInfoListImpl* mInfoList; // XXX make these flags! @@ -250,22 +262,27 @@ public: }; +#ifdef DEBUG_REFLOW + +PRInt32 gIndent = 0; +PRInt32 gReflows = 0; + +#endif + #define GET_WIDTH(size) (IsHorizontal() ? size.width : size.height) #define GET_HEIGHT(size) (IsHorizontal() ? size.height : size.width) #define SET_WIDTH(size, coord) if (IsHorizontal()) { (size).width = (coord); } else { (size).height = (coord); } #define SET_HEIGHT(size, coord) if (IsHorizontal()) { (size).height = (coord); } else { (size).width = (coord); } -nsIFrame* nsBoxDebugInner::mDebugChild = nsnull; - nsresult -NS_NewBoxFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame) +NS_NewBoxFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame, PRBool aIsRoot) { NS_PRECONDITION(aNewFrame, "null OUT ptr"); if (nsnull == aNewFrame) { return NS_ERROR_NULL_POINTER; } - nsBoxFrame* it = new (aPresShell) nsBoxFrame(); + nsBoxFrame* it = new (aPresShell) nsBoxFrame(aPresShell, aIsRoot); if (nsnull == it) return NS_ERROR_OUT_OF_MEMORY; @@ -274,14 +291,17 @@ NS_NewBoxFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame) } // NS_NewBoxFrame -nsBoxFrame::nsBoxFrame() +nsBoxFrame::nsBoxFrame(nsIPresShell* aPresShell, PRBool aIsRoot) { - mInner = new nsBoxFrameInner(this); + mInner = new (aPresShell) nsBoxFrameInner(aPresShell, this); // if not otherwise specified boxes by default are horizontal. mState |= NS_STATE_IS_HORIZONTAL; mState |= NS_STATE_AUTO_STRETCH; + if (aIsRoot) + mState |= NS_STATE_IS_ROOT; + mInner->mValign = nsBoxFrame::vAlign_Top; mInner->mHalign = nsBoxFrame::hAlign_Left; mInner->mInnerSize = 0; @@ -291,9 +311,62 @@ nsBoxFrame::nsBoxFrame() #endif } +void* +nsBoxFrameInner::operator new(size_t sz, nsIPresShell* aPresShell) +{ + return nsBoxFrameInner::Allocate(sz,aPresShell); +} + +void +nsBoxFrameInner::Recycle(nsIPresShell* aPresShell) +{ + // recyle out info list. + mInfoList->Recycle(aPresShell); + delete this; + nsBoxFrameInner::RecycleFreedMemory(aPresShell, this); +} + +// Overridden to prevent the global delete from being called, since the memory +// came out of an nsIArena instead of the global delete operator's heap. +void +nsBoxFrameInner::operator delete(void* aPtr, size_t sz) +{ + nsBoxFrameInner::Free(aPtr, sz); +} + +void* +nsBoxFrameInner::Allocate(size_t sz, nsIPresShell* aPresShell) +{ + // Check the recycle list first. + void* result = nsnull; + aPresShell->AllocateFrame(sz, &result); + + if (result) { + nsCRT::zero(result, sz); + } + + return result; +} + +// Overridden to prevent the global delete from being called, since the memory +// came out of an nsIArena instead of the global delete operator's heap. +void +nsBoxFrameInner::Free(void* aPtr, size_t sz) +{ + // Don't let the memory be freed, since it will be recycled + // instead. Don't call the global operator delete. + + // Stash the size of the object in the first four bytes of the + // freed up memory. The Destroy method can then use this information + // to recycle the object. + size_t* szPtr = (size_t*)aPtr; + *szPtr = sz; +} + + nsBoxFrame::~nsBoxFrame() { - delete mInner; + NS_ASSERTION(mInner == nsnull,"Error Destroy was never called on this Frame!!!"); } @@ -331,9 +404,12 @@ nsBoxFrame::SetInitialChildList(nsIPresContext* aPresContext, mInner->SanityCheck(); nsresult r = nsHTMLContainerFrame::SetInitialChildList(aPresContext, aListName, aChildList); - + + nsCOMPtr shell; + aPresContext->GetShell(getter_AddRefs(shell)); + // initialize our list of infos. - mInner->mInfoList->Init(aChildList); + mInner->mInfoList->Init(shell, aChildList); mInner->SanityCheck(); @@ -385,6 +461,22 @@ nsBoxFrame::Init(nsIPresContext* aPresContext, mState &= ~NS_STATE_AUTO_STRETCH; + PRBool debug = mState & NS_STATE_SET_TO_DEBUG; + PRBool debugSet = mInner->GetInitialDebug(debug); + if (debugSet) { + mState |= NS_STATE_DEBUG_WAS_SET; + if (debug) + mState |= NS_STATE_SET_TO_DEBUG; + else + mState &= ~NS_STATE_SET_TO_DEBUG; + } else { + mState &= ~NS_STATE_DEBUG_WAS_SET; + } + + // if we are root and this + if (mState & NS_STATE_IS_ROOT) + nsBoxDebug::GetPref(aPresContext); + return rv; } @@ -395,6 +487,27 @@ nsBoxFrame::GetDefaultFlex(PRInt32& aFlex) return PR_TRUE; } +PRBool +nsBoxFrameInner::GetInitialDebug(PRBool& aDebug) +{ + nsString value; + + nsCOMPtr content; + GetContentOf(mOuter, getter_AddRefs(content)); + + if (NS_CONTENT_ATTR_HAS_VALUE == content->GetAttribute(kNameSpaceID_None, nsXULAtoms::debug, value)) { + if (value.EqualsIgnoreCase("true")) { + aDebug = PR_TRUE; + return PR_TRUE; + } else if (value.EqualsIgnoreCase("false")) { + aDebug = PR_FALSE; + return PR_TRUE; + } + } + + return PR_FALSE; +} + PRBool nsBoxFrame::GetInitialHAlignment(nsBoxFrame::Halignment& aHalign) { @@ -707,6 +820,10 @@ nsBoxFrame::GetRedefinedMinPrefMax(nsIPresContext* aPresContext, nsIFrame* aFra nsresult nsBoxFrame::GetChildBoxInfo(nsIPresContext* aPresContext, const nsHTMLReflowState& aReflowState, nsIFrame* aFrame, nsCalculatedBoxInfo& aSize) { +#ifdef DEBUG_REFLOW + gIndent++; +#endif + nsIFrame* incrementalChild; if (aReflowState.reason == eReflowReason_Incremental) { // then get the child we need to flow incrementally @@ -736,6 +853,10 @@ nsBoxFrame::GetChildBoxInfo(nsIPresContext* aPresContext, const nsHTMLReflowStat aSize.mFlags |= NS_FRAME_IS_BOX; // add in the border, padding, width, min, max GetRedefinedMinPrefMax(aPresContext, aFrame, aSize); + +#ifdef DEBUG_REFLOW + gIndent--; +#endif return NS_OK; } @@ -805,6 +926,11 @@ nsBoxFrame::GetChildBoxInfo(nsIPresContext* aPresContext, const nsHTMLReflowStat aSize.prefSize.height = desiredSize.height; aSize.ascent = desiredSize.ascent; +#ifdef DEBUG_REFLOW + mInner->AddIndents(); + printf("pref-size: (%d,%d)\n", aSize.prefSize.width, aSize.prefSize.height); +#endif + // aSize.prefSize.width = 0; // aSize.prefSize.height = 0; @@ -812,6 +938,10 @@ nsBoxFrame::GetChildBoxInfo(nsIPresContext* aPresContext, const nsHTMLReflowStat GetRedefinedMinPrefMax(aPresContext, aFrame, aSize); } +#ifdef DEBUG_REFLOW + gIndent--; +#endif + return NS_OK; } @@ -830,15 +960,8 @@ nsBoxFrame::ReflowDirtyChild(nsIPresShell* aPresShell, nsIFrame* aChild) return NS_OK; } -#ifdef DEBUG_REFLOW - -PRInt32 gIndent = 0; -PRInt32 gReflows = 0; - -#endif - - +/* void nsIBox::HandleRootBoxReflow(nsIPresContext* aPresContext, nsIFrame* aBox, @@ -865,6 +988,7 @@ nsIBox::HandleRootBoxReflow(nsIPresContext* aPresContext, } } } +*/ /** @@ -918,41 +1042,18 @@ nsBoxFrame::Reflow(nsIPresContext* aPresContext, //--------------------------------------------------------- nsIFrame* incrementalChild = nsnull; - if (mState & NS_FRAME_FIRST_REFLOW) { - // on the initial reflow see if we are the root box. - // the root box. - mState |= NS_STATE_IS_ROOT; - - // see if we are the root box - nsIFrame* parent = mParent; - while (parent) { - nsIBox* ibox = nsnull; - if (NS_SUCCEEDED(parent->QueryInterface(nsIBox::GetIID(), (void**)&ibox)) && ibox) { - mState &= ~NS_STATE_IS_ROOT; - break; - } - parent->GetParent(&parent); - } - - if (mState & NS_STATE_IS_ROOT) { - - // see if someone turned on debugging - PRBool debug = PR_FALSE; - nsCOMPtr pref; - aPresContext->GetPrefs(getter_AddRefs(pref)); - if (pref) { - pref->GetBoolPref("xul.debug.box", &debug); - } - - if (debug) - nsBoxDebugInner::gDebug++; - -#ifdef DEBUG_REFLOW - printf("-------- BOX IS ROOT --------\n"); -#endif - } + // update our debug state if it needs it. + // see if the debug was set. If it was then propagate it + // if it wasn't and we are root then get it from the global pref. + if (mState & NS_STATE_DEBUG_WAS_SET) { + if (mState & NS_STATE_SET_TO_DEBUG) + SetDebug(aPresContext, PR_TRUE); + else + SetDebug(aPresContext, PR_FALSE); + } else if (mState & NS_STATE_IS_ROOT) { + SetDebug(aPresContext, nsBoxDebug::gDebug); } - + if ( aReflowState.reason == eReflowReason_Incremental ) { nsIReflowCommand::ReflowType reflowType; aReflowState.reflowCommand->GetType(reflowType); @@ -1010,25 +1111,7 @@ nsBoxFrame::Reflow(nsIPresContext* aPresContext, // then get the child we need to flow incrementally //aReflowState.reflowCommand->GetNext(incrementalChild); - } - - - if (aReflowState.reason == eReflowReason_Initial ) - { - if (nsBoxDebugInner::gDebug > 0) { - if (!mInner->mDebugInner) { - mInner->mDebugInner = new nsBoxDebugInner(this); - mInner->UpdatePseudoElements(aPresContext); - } - } else { - if (mInner->mDebugInner) - { - delete mInner->mDebugInner; - mInner->mDebugInner = nsnull; - } - } - } - + } #ifdef DEBUG_REFLOW @@ -1069,9 +1152,9 @@ printf("\n"); nsMargin inset(0,0,0,0); GetInset(inset); - nsMargin debugInset(0,0,0,0); - mInner->GetDebugInset(debugInset); - inset += debugInset; + //nsMargin debugInset(0,0,0,0); + //mInner->GetDebugInset(debugInset); + //inset += debugInset; rect.Deflate(inset); @@ -1345,7 +1428,7 @@ nsBoxFrameInner::FlowChildren(nsIPresContext* aPresContext, // make collapsed children not show up if (info->mFlags & NS_FRAME_BOX_IS_COLLAPSED) { - + if (aReflowState.reason == eReflowReason_Initial) { FlowChildAt(childFrame, aPresContext, aDesiredSize, aReflowState, aStatus, *info, x, y, PR_TRUE, aIncrementalChild, redraw, reason); @@ -1926,6 +2009,9 @@ nsBoxFrameInner::FlowChildAt(nsIFrame* childFrame, PRBool& aRedraw, const nsString& aReason) { + // if (mOuter->mState & NS_STATE_CURRENTLY_IN_DEBUG) + // printf("in debug\n"); + aStatus = NS_FRAME_COMPLETE; PRBool needsReflow = PR_FALSE; nsReflowReason reason = aReflowState.reason; @@ -1999,7 +2085,7 @@ nsBoxFrameInner::FlowChildAt(nsIFrame* childFrame, return FlowChildAt(childFrame, aPresContext, desiredSize, state, aStatus, aInfo, aX, aY, aMoveFrame, aIncrementalChild, aRedraw, aReason); } } - + // get the frame state to see if it needs reflow needsReflow = (childState & NS_FRAME_IS_DIRTY) || (childState & NS_FRAME_HAS_DIRTY_CHILDREN); @@ -2140,9 +2226,14 @@ nsBoxFrameInner::FlowChildAt(nsIFrame* childFrame, char ch[100]; aReason.ToCString(ch,100); - printf(" reason=%s %s\n",reflowReasonString,ch); + printf(" reason=%s %s",reflowReasonString,ch); #endif + // only frames that implement nsIBox seem to be able to handle a reason of Dirty. For everyone else + // send down a resize. + if (!(aInfo.mFlags & NS_FRAME_IS_BOX) && reason == eReflowReason_Dirty) + reason = eReflowReason_Resize; + if (!(aInfo.mFlags & NS_FRAME_IS_BOX)) { nsHTMLReflowState reflowState(aPresContext, aReflowState, childFrame, nsSize(size.width, NS_INTRINSICSIZE)); reflowState.reason = reason; @@ -2155,6 +2246,9 @@ nsBoxFrameInner::FlowChildAt(nsIFrame* childFrame, reflowState.mComputedWidth = size.width; reflowState.mComputedHeight = size.height; +#ifdef DEBUG_REFLOW + printf(" Size=(%d,%d)\n",reflowState.mComputedWidth, reflowState.mComputedHeight); +#endif // place the child and reflow childFrame->WillReflow(aPresContext); @@ -2177,6 +2271,10 @@ nsBoxFrameInner::FlowChildAt(nsIFrame* childFrame, reflowState.mComputedWidth = size.width; reflowState.mComputedHeight = size.height; +#ifdef DEBUG_REFLOW + printf(" Size=(%d,%d)\n",reflowState.mComputedWidth, reflowState.mComputedHeight); +#endif + // place the child and reflow childFrame->WillReflow(aPresContext); @@ -2194,12 +2292,13 @@ nsBoxFrameInner::FlowChildAt(nsIFrame* childFrame, // printf("width: %d, height: %d\n", desiredSize.mCombinedArea.width, desiredSize.mCombinedArea.height); - if (kidState & NS_FRAME_OUTSIDE_CHILDREN) { - desiredSize.width = desiredSize.mOverflowArea.width; - desiredSize.height = desiredSize.mOverflowArea.height; - } - - + // XXX EDV hack to fix bug in block + if (reason != eReflowReason_Initial) { + if (kidState & NS_FRAME_OUTSIDE_CHILDREN) { + desiredSize.width = desiredSize.mOverflowArea.width; + desiredSize.height = desiredSize.mOverflowArea.height; + } + } // if (maxElementSize.width > desiredSize.width) // desiredSize.width = maxElementSize.width; @@ -2348,6 +2447,7 @@ nsBoxFrame::AddSize(const nsSize& a, nsSize& b, PRBool largest) void nsBoxFrame::GetInset(nsMargin& margin) { + mInner->GetDebugInset(margin); } @@ -2597,7 +2697,7 @@ nsBoxFrame::RemoveFrame(nsIPresContext* aPresContext, mInner->SanityCheck(); // remove child from our info list - mInner->mInfoList->Remove(aOldFrame); + mInner->mInfoList->Remove(&aPresShell, aOldFrame); // remove the child frame mFrames.DestroyFrame(aPresContext, aOldFrame); @@ -2611,23 +2711,64 @@ nsBoxFrame::RemoveFrame(nsIPresContext* aPresContext, NS_IMETHODIMP nsBoxFrame::Destroy(nsIPresContext* aPresContext) { - // if we are root remove 1 from the debug count. - if (mState & NS_STATE_IS_ROOT && nsBoxDebugInner::gDebug > 0) - { - nsBoxDebugInner::gDebug--; - if (nsBoxDebugInner::gDebug == 0) - { - NS_RELEASE(mInner->mDebugInner->mHorizontalDebugStyle); - NS_RELEASE(mInner->mDebugInner->mVerticalDebugStyle); - mInner->mDebugInner->mHorizontalDebugStyle = nsnull; - mInner->mDebugInner->mVerticalDebugStyle = nsnull; - } - } + if (mState & NS_STATE_IS_ROOT) + nsBoxDebug::GetPref(aPresContext); + + if (mState & NS_STATE_CURRENTLY_IN_DEBUG) + nsBoxDebug::Release(aPresContext); + + // recycle the Inner via the shell's arena. + nsCOMPtr shell; + aPresContext->GetShell(getter_AddRefs(shell)); + mInner->Recycle(shell); + mInner = nsnull; return nsHTMLContainerFrame::Destroy(aPresContext); } +void +nsBoxFrameInner::RecycleFreedMemory(nsIPresShell* aShell, void* aMem) +{ + size_t* sz = (size_t*)aMem; + aShell->FreeFrame(*sz, aMem); +} + +NS_IMETHODIMP +nsBoxFrame::SetDebug(nsIPresContext* aPresContext, PRBool aDebug) +{ + // see if our state matches the given debug state + PRBool debugSet = mState & NS_STATE_CURRENTLY_IN_DEBUG; + PRBool debugChanged = (!aDebug && debugSet) || (aDebug && !debugSet); + + // if it doesn't then tell each child below us the new debug state + if (debugChanged) + { + if (aDebug) { + mState |= NS_STATE_CURRENTLY_IN_DEBUG; + nsBoxDebug::AddRef(aPresContext, this); + } else { + mState &= ~NS_STATE_CURRENTLY_IN_DEBUG; + nsBoxDebug::Release(aPresContext); + } + + return mInner->mInfoList->SetDebug(aPresContext, aDebug); + } + + return NS_OK; +} + +void +nsBoxDebug::GetPref(nsIPresContext* aPresContext) +{ + gDebug = PR_FALSE; + nsCOMPtr pref; + aPresContext->GetPrefs(getter_AddRefs(pref)); + if (pref) { + pref->GetBoolPref("xul.debug.box", &gDebug); + } +} + NS_IMETHODIMP nsBoxFrame::InsertFrames(nsIPresContext* aPresContext, nsIPresShell& aPresShell, @@ -2638,11 +2779,15 @@ nsBoxFrame::InsertFrames(nsIPresContext* aPresContext, mInner->SanityCheck(); // insert the frames to our info list - mInner->mInfoList->Insert(aPrevFrame, aFrameList); + mInner->mInfoList->Insert(&aPresShell, aPrevFrame, aFrameList); // insert the frames in out regular frame list mFrames.InsertFrames(this, aPrevFrame, aFrameList); + // if we are in debug make sure our children are in debug as well. + if (mState & NS_STATE_CURRENTLY_IN_DEBUG) + mInner->mInfoList->SetDebug(aPresContext, PR_TRUE); + mInner->SanityCheck(); // mark us dirty and generate a reflow command @@ -2660,11 +2805,15 @@ nsBoxFrame::AppendFrames(nsIPresContext* aPresContext, mInner->SanityCheck(); // append them after - mInner->mInfoList->Append(aFrameList); + mInner->mInfoList->Append(&aPresShell,aFrameList); // append in regular frames mFrames.AppendFrames(this, aFrameList); + // if we are in debug make sure our children are in debug as well. + if (mState & NS_STATE_CURRENTLY_IN_DEBUG) + mInner->mInfoList->SetDebug(aPresContext, PR_TRUE); + mInner->SanityCheck(); // mark us dirty and generate a reflow command @@ -2691,7 +2840,7 @@ nsBoxFrame::AttributeChanged(nsIPresContext* aPresContext, aAttribute == nsXULAtoms::orient || aAttribute == nsXULAtoms::autostretch) { - if (aAttribute == nsXULAtoms::orient || aAttribute == nsHTMLAtoms::align || aAttribute == nsHTMLAtoms::valign) { + if (aAttribute == nsXULAtoms::orient || aAttribute == nsXULAtoms::debug || aAttribute == nsHTMLAtoms::align || aAttribute == nsHTMLAtoms::valign) { mInner->mValign = nsBoxFrame::vAlign_Top; mInner->mHalign = nsBoxFrame::hAlign_Left; @@ -2704,6 +2853,18 @@ nsBoxFrame::AttributeChanged(nsIPresContext* aPresContext, mState |= NS_STATE_IS_HORIZONTAL; else mState &= ~NS_STATE_IS_HORIZONTAL; + + PRBool debug = mState & NS_STATE_SET_TO_DEBUG; + PRBool debugSet = mInner->GetInitialDebug(debug); + if (debugSet) { + mState |= NS_STATE_DEBUG_WAS_SET; + if (debug) + mState |= NS_STATE_SET_TO_DEBUG; + else + mState &= ~NS_STATE_SET_TO_DEBUG; + } else { + mState &= ~NS_STATE_DEBUG_WAS_SET; + } PRBool autostretch = mState & NS_STATE_AUTO_STRETCH; @@ -2736,8 +2897,8 @@ nsBoxFrame::GetBoxInfo(nsIPresContext* aPresContext, const nsHTMLReflowState& aR aReflowState.reflowCommand->GetNext(incrementalChild, PR_FALSE); } - nsMargin debugInset(0,0,0,0); - mInner->GetDebugInset(debugInset); + //nsMargin debugInset(0,0,0,0); + //mInner->GetDebugInset(debugInset); nsresult rv; @@ -2751,24 +2912,46 @@ nsBoxFrame::GetBoxInfo(nsIPresContext* aPresContext, const nsHTMLReflowState& aR while (info) { - // if a child needs recalculation then ask it for its size. Otherwise - // just use the size we already have. - if (info->mFlags & NS_FRAME_BOX_NEEDS_RECALC || info->frame == incrementalChild) - { // see if the child is collapsed const nsStyleDisplay* disp; info->frame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)disp)); - // if collapsed then the child will have no size + PRBool collapsed = (info->mFlags & NS_FRAME_BOX_IS_COLLAPSED); + PRBool visibilityCollapsed = disp->mVisible == NS_STYLE_VISIBILITY_COLLAPSE; + PRBool collapsedChanged = (!collapsed && visibilityCollapsed) || (collapsed && !visibilityCollapsed); + + // if a child needs recalculation then ask it for its size. Otherwise + // just use the size we already have. + if ((info->mFlags & NS_FRAME_BOX_NEEDS_RECALC) || info->frame == incrementalChild || collapsedChanged) + { + // if collapsed then the child will have no size // don't unset needsRecalc - therefore cause us // to be recalculated when we are uncollapsed - if (disp->mVisible == NS_STYLE_VISIBILITY_COLLAPSE) - info->mFlags |= NS_FRAME_BOX_IS_COLLAPSED; - else { + if (visibilityCollapsed) { + // eat up any incremental reflows targets at + // a collapsed child + if (incrementalChild == info->frame) { + while(incrementalChild) + aReflowState.reflowCommand->GetNext(incrementalChild); + } + + if (collapsedChanged) { + info->mFlags |= NS_FRAME_BOX_IS_COLLAPSED; + } + + info->Clear(); + } else { + if (collapsedChanged) { + nsFrameState childState; + info->frame->GetFrameState(&childState); + childState |= NS_FRAME_IS_DIRTY; + info->frame->SetFrameState(childState); + } // get the size of the child. This is the min, max, preferred, and spring constant // it does not include its border. rv = GetChildBoxInfo(aPresContext, aReflowState, info->frame, *info); + /* // make sure we can see the debug info if (info->prefSize.width < debugInset.left) @@ -2840,7 +3023,7 @@ nsBoxFrame::GetBoxInfo(nsIPresContext* aPresContext, const nsHTMLReflowState& aR nsMargin inset(0,0,0,0); GetInset(inset); - inset += debugInset; + // inset += debugInset; nsSize in(inset.left+inset.right,inset.top+inset.bottom); aSize.minSize += in; @@ -2856,7 +3039,7 @@ nsBoxFrame::GetBoxInfo(nsIPresContext* aPresContext, const nsHTMLReflowState& aR */ aSize.ascent += inset.top; - aSize.ascent += debugInset.top; + //aSize.ascent += debugInset.top; return rv; } @@ -2903,8 +3086,8 @@ nsBoxFrame :: Paint ( nsIPresContext* aPresContext, aWhichLayer); if (NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer) { - if (mInner->mDebugInner) { - mInner->mDebugInner->PaintSprings(aPresContext, aRenderingContext, aDirtyRect); + if (mState & NS_STATE_CURRENTLY_IN_DEBUG) { + nsBoxDebug::gInstance->PaintSprings(aPresContext, this, aRenderingContext, aDirtyRect); } } @@ -2961,8 +3144,8 @@ nsBoxFrame::PaintChildren(nsIPresContext* aPresContext, // If overflow is hidden then set the clip rect so that children // don't leak out of us if (NS_STYLE_OVERFLOW_HIDDEN == disp->mOverflow) { - nsMargin dm(0,0,0,0); - mInner->GetDebugInset(dm); + //nsMargin dm(0,0,0,0); + //mInner->GetDebugInset(dm); nsMargin im(0,0,0,0); GetInset(im); nsMargin border(0,0,0,0); @@ -2970,7 +3153,7 @@ nsBoxFrame::PaintChildren(nsIPresContext* aPresContext, mStyleContext->GetStyleData(eStyleStruct_Spacing); spacing->GetBorderPadding(border); r.Deflate(im); - r.Deflate(dm); + //r.Deflate(dm); r.Deflate(border); } @@ -3002,12 +3185,15 @@ nsBoxFrame::PaintChildren(nsIPresContext* aPresContext, } void -nsBoxDebugInner::PaintSprings(nsIPresContext* aPresContext, nsIRenderingContext& aRenderingContext, const nsRect& aDirtyRect) +nsBoxDebug::PaintSprings(nsIPresContext* aPresContext, nsBoxFrame* aBoxFrame, + nsIRenderingContext& aRenderingContext, const nsRect& aDirtyRect) { + PRBool isHorizontal = aBoxFrame->mState & NS_STATE_IS_HORIZONTAL; + // remove our border const nsStyleSpacing* spacing; - mOuter->GetStyleData(eStyleStruct_Spacing, + aBoxFrame->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct*&) spacing); nsMargin border(0,0,0,0); @@ -3018,7 +3204,7 @@ nsBoxDebugInner::PaintSprings(nsIPresContext* aPresContext, nsIRenderingContext& nscoord onePixel = NSIntPixelsToTwips(1, p2t); nsIStyleContext* debugStyle; - if (mOuter->mState & NS_STATE_IS_HORIZONTAL) + if (aBoxFrame->mState & NS_STATE_IS_HORIZONTAL) debugStyle = mHorizontalDebugStyle; else debugStyle = mVerticalDebugStyle; @@ -3036,11 +3222,11 @@ nsBoxDebugInner::PaintSprings(nsIPresContext* aPresContext, nsIRenderingContext& border += margin; - nsRect inner(0,0,mOuter->mRect.width, mOuter->mRect.height); + nsRect inner(0,0,aBoxFrame->mRect.width, aBoxFrame->mRect.height); inner.Deflate(border); // paint our debug border - nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, mOuter, + nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, aBoxFrame, aDirtyRect, inner, *debugSpacing, debugStyle, 0); // get the debug border dimensions @@ -3055,7 +3241,7 @@ nsBoxDebugInner::PaintSprings(nsIPresContext* aPresContext, nsIRenderingContext& aRenderingContext.SetColor(debugColor->mColor); - if (mOuter->mState & NS_STATE_IS_HORIZONTAL) + if (isHorizontal) { x = inner.x; y = inner.y + onePixel; @@ -3068,11 +3254,11 @@ nsBoxDebugInner::PaintSprings(nsIPresContext* aPresContext, nsIRenderingContext& springSize = debugBorder.left - onePixel*4; } - nsCalculatedBoxInfo* info = mOuter->GetInfoList()->GetFirst(); + nsCalculatedBoxInfo* info = aBoxFrame->GetInfoList()->GetFirst(); while (info) { nsSize& size = info->calculatedSize; if (!(info->mFlags & NS_FRAME_BOX_IS_COLLAPSED)) { - if (mOuter->mState & NS_STATE_IS_HORIZONTAL) + if (isHorizontal) borderSize = size.width; else borderSize = size.height; @@ -3089,7 +3275,7 @@ nsBoxDebugInner::PaintSprings(nsIPresContext* aPresContext, nsIRenderingContext& } */ - DrawSpring(aPresContext, aRenderingContext, info->flex, x, y, borderSize, springSize); + DrawSpring(aPresContext, aRenderingContext, isHorizontal, info->flex, x, y, borderSize, springSize); x += borderSize; } info = info->next; @@ -3097,25 +3283,25 @@ nsBoxDebugInner::PaintSprings(nsIPresContext* aPresContext, nsIRenderingContext& } void -nsBoxDebugInner::DrawLine(nsIRenderingContext& aRenderingContext, nscoord x1, nscoord y1, nscoord x2, nscoord y2) +nsBoxDebug::DrawLine(nsIRenderingContext& aRenderingContext, PRBool aHorizontal, nscoord x1, nscoord y1, nscoord x2, nscoord y2) { - if (mOuter->mState & NS_STATE_IS_HORIZONTAL) + if (aHorizontal) aRenderingContext.DrawLine(x1,y1,x2,y2); else aRenderingContext.DrawLine(y1,x1,y2,x2); } void -nsBoxDebugInner::FillRect(nsIRenderingContext& aRenderingContext, nscoord x, nscoord y, nscoord width, nscoord height) +nsBoxDebug::FillRect(nsIRenderingContext& aRenderingContext, PRBool aHorizontal, nscoord x, nscoord y, nscoord width, nscoord height) { - if (mOuter->mState & NS_STATE_IS_HORIZONTAL) + if (aHorizontal) aRenderingContext.FillRect(x,y,width,height); else aRenderingContext.FillRect(y,x,height,width); } void -nsBoxDebugInner::DrawSpring(nsIPresContext* aPresContext, nsIRenderingContext& aRenderingContext, PRInt32 flex, nscoord x, nscoord y, nscoord size, nscoord springSize) +nsBoxDebug::DrawSpring(nsIPresContext* aPresContext, nsIRenderingContext& aRenderingContext, PRBool aHorizontal, PRInt32 flex, nscoord x, nscoord y, nscoord size, nscoord springSize) { float p2t; aPresContext->GetScaledPixelsToTwips(&p2t); @@ -3137,59 +3323,76 @@ nsBoxDebugInner::DrawSpring(nsIPresContext* aPresContext, nsIRenderingContext& a int halfCoilSize = coilSize/2; if (flex == 0) { - DrawLine(aRenderingContext, x,y + springSize/2, x + size, y + springSize/2); + DrawLine(aRenderingContext, aHorizontal, x,y + springSize/2, x + size, y + springSize/2); } else { for (int i=0; i < coils; i++) { - DrawLine(aRenderingContext, offset, center+halfSpring, offset+halfCoilSize, center-halfSpring); - DrawLine(aRenderingContext, offset+halfCoilSize, center-halfSpring, offset+coilSize, center+halfSpring); + DrawLine(aRenderingContext, aHorizontal, offset, center+halfSpring, offset+halfCoilSize, center-halfSpring); + DrawLine(aRenderingContext, aHorizontal, offset+halfCoilSize, center-halfSpring, offset+coilSize, center+halfSpring); offset += coilSize; } } - FillRect(aRenderingContext, x + size - springSize/2, y, springSize/2, springSize); - FillRect(aRenderingContext, x, y, springSize/2, springSize); + FillRect(aRenderingContext, aHorizontal, x + size - springSize/2, y, springSize/2, springSize); + FillRect(aRenderingContext, aHorizontal, x, y, springSize/2, springSize); //DrawKnob(aPresContext, aRenderingContext, x + size - springSize, y, springSize); } void -nsBoxFrameInner::UpdatePseudoElements(nsIPresContext* aPresContext) +nsBoxDebug::AddRef(nsIPresContext* aPresContext, nsBoxFrame* aBoxFrame) { - if (mDebugInner->mHorizontalDebugStyle || mDebugInner->mVerticalDebugStyle) - return; - - nsCOMPtr content; - GetContentOf(mOuter, getter_AddRefs(content)); - - nsCOMPtr atom ( getter_AddRefs(NS_NewAtom(":-moz-horizontal-box-debug")) ); - aPresContext->ProbePseudoStyleContextFor(content, atom, mOuter->mStyleContext, - PR_FALSE, - &mDebugInner->mHorizontalDebugStyle); - - atom = getter_AddRefs(NS_NewAtom(":-moz-vertical-box-debug")); - aPresContext->ProbePseudoStyleContextFor(content, atom, mOuter->mStyleContext, - PR_FALSE, - &mDebugInner->mVerticalDebugStyle); - - aPresContext->GetScaledPixelsToTwips(&mDebugInner->mP2t); + if (!gInstance) { + gInstance = new nsBoxDebug(aPresContext, aBoxFrame); + } + gInstance->mRefCount++; } +void +nsBoxDebug::Release(nsIPresContext* aPresContext) +{ + NS_ASSERTION(gInstance && gInstance->mRefCount > 0, "nsBoxDebug Realsed too may times!!"); + + gInstance->mRefCount--; + if (gInstance->mRefCount == 0) { + delete gInstance; + gInstance = nsnull; + } +} + +nsBoxDebug::nsBoxDebug(nsIPresContext* aPresContext, nsBoxFrame* aBoxFrame) +{ + nsCOMPtr content; + aBoxFrame->mInner->GetContentOf(aBoxFrame, getter_AddRefs(content)); + + nsCOMPtr atom ( getter_AddRefs(NS_NewAtom(":-moz-horizontal-box-debug")) ); + aPresContext->ProbePseudoStyleContextFor(content, atom, aBoxFrame->mStyleContext, + PR_FALSE, + getter_AddRefs(mHorizontalDebugStyle)); + + atom = getter_AddRefs(NS_NewAtom(":-moz-vertical-box-debug")); + aPresContext->ProbePseudoStyleContextFor(content, atom, aBoxFrame->mStyleContext, + PR_FALSE, + getter_AddRefs(mVerticalDebugStyle)); + + mDebugChild = nsnull; + mRefCount = 0; +} void nsBoxFrameInner::GetDebugInset(nsMargin& inset) { inset.SizeTo(0,0,0,0); - if (nsBoxDebugInner::gDebug > 0) + if (mOuter->mState & NS_STATE_CURRENTLY_IN_DEBUG) { nsIStyleContext* style; if (mOuter->mState & NS_STATE_IS_HORIZONTAL) - style = mDebugInner->mHorizontalDebugStyle; + style = nsBoxDebug::gInstance->mHorizontalDebugStyle; else - style = mDebugInner->mVerticalDebugStyle; + style = nsBoxDebug::gInstance->mVerticalDebugStyle; if (style == nsnull) return; @@ -3241,6 +3444,32 @@ nsBoxFrame::GetFrameName(nsString& aResult) const return NS_OK; } +void* +nsCalculatedBoxInfoImpl::operator new(size_t sz, nsIPresShell* aPresShell) +{ + return nsBoxFrameInner::Allocate(sz,aPresShell); +} + +void +nsCalculatedBoxInfo::Recycle(nsIPresShell* aShell) +{ +} + +void +nsCalculatedBoxInfoImpl::Recycle(nsIPresShell* aShell) +{ + delete this; + nsBoxFrameInner::RecycleFreedMemory(aShell, this); +} + +// Overridden to prevent the global delete from being called, since the memory +// came out of an nsIArena instead of the global delete operator's heap. +void +nsCalculatedBoxInfoImpl::operator delete(void* aPtr, size_t sz) +{ + nsBoxFrameInner::Free(aPtr, sz); +} + //static PRInt32 gBoxInfoCount = 0; nsCalculatedBoxInfoImpl::nsCalculatedBoxInfoImpl(nsIFrame* aFrame) @@ -3249,6 +3478,7 @@ nsCalculatedBoxInfoImpl::nsCalculatedBoxInfoImpl(nsIFrame* aFrame) // printf("created Info=%d\n",gBoxInfoCount); mFlags = NS_FRAME_BOX_NEEDS_RECALC; + next = nsnull; calculatedSize.width = 0; calculatedSize.height = 0; @@ -3289,25 +3519,89 @@ nsBoxFrame::GetFrameForPoint(nsIPresContext* aPresContext, const nsPoint& aPoint, nsIFrame** aFrame) { - nsresult rv = nsHTMLContainerFrame::GetFrameForPoint(aPresContext, aPoint, aFrame); - return rv; + return nsHTMLContainerFrame::GetFrameForPoint(aPresContext, aPoint, aFrame); + + /* + nsRect r(0,0,mRect.width, mRect.height); + + // if it is not inside us fail + if (!r.Contains(aPoint)) { + return NS_ERROR_FAILURE; + } + + // is it inside our border, padding, and debugborder or insets? + //nsMargin dm(0,0,0,0); + //mInner->GetDebugInset(dm); + nsMargin im(0,0,0,0); + GetInset(im); + nsMargin border(0,0,0,0); + const nsStyleSpacing* spacing = (const nsStyleSpacing*) + mStyleContext->GetStyleData(eStyleStruct_Spacing); + spacing->GetBorderPadding(border); + r.Deflate(im); + //r.Deflate(dm); + r.Deflate(border); + + // no? Then it must be in our border so return us. + if (!r.Contains(aPoint)) { + *aFrame = this; + return NS_OK; + } + + // ok lets look throught the children + nsCalculatedBoxInfo* info = mInner->mInfoList->GetFirst(); + nsRect kidRect; + while(info) + { + info->frame->GetRect(kidRect); + + // Do a quick check and see if the child frame contains the point + if (kidRect.Contains(aPoint)) { + nsPoint tmp; + tmp.MoveTo(aPoint.x - kidRect.x, aPoint.y - kidRect.y); + return info->frame->GetFrameForPoint(aPresContext, tmp, aFrame); + } + + info = info->next; + } + + const nsStyleColor* color = + (const nsStyleColor*)mStyleContext->GetStyleData(eStyleStruct_Color); + + PRBool transparentBG = NS_STYLE_BG_COLOR_TRANSPARENT == + (color->mBackgroundFlags & NS_STYLE_BG_COLOR_TRANSPARENT); + + PRBool backgroundImage = (color->mBackgroundImage.Length() > 0); + + if (!transparentBG || backgroundImage) + { + *aFrame = this; + return NS_OK; + } + + return NS_ERROR_FAILURE; + */ } + void -nsBoxDebugInner::GetValue(const nsSize& a, const nsSize& b, char* ch) +nsBoxDebug::GetValue(nsIPresContext* aPresContext, const nsSize& a, const nsSize& b, char* ch) { + float p2t; + aPresContext->GetScaledPixelsToTwips(&p2t); + char width[100]; char height[100]; if (a.width == NS_INTRINSICSIZE) sprintf(width,"%s","INF"); else - sprintf(width,"%d", nscoord(a.width/mP2t)); + sprintf(width,"%d", nscoord(a.width/*/p2t*/)); if (a.height == NS_INTRINSICSIZE) sprintf(height,"%s","INF"); else - sprintf(height,"%d", nscoord(a.height/mP2t)); + sprintf(height,"%d", nscoord(a.height/*/p2t*/)); sprintf(ch, "(%s%s, %s%s)", width, (b.width != NS_INTRINSICSIZE ? "[CSS]" : ""), @@ -3316,13 +3610,14 @@ nsBoxDebugInner::GetValue(const nsSize& a, const nsSize& b, char* ch) } void -nsBoxDebugInner::GetValue(PRInt32 a, PRInt32 b, char* ch) +nsBoxDebug::GetValue(nsIPresContext* aPresContext, PRInt32 a, PRInt32 b, char* ch) { sprintf(ch, "(%d)", a); } PRBool -nsBoxDebugInner::DisplayDebugInfoFor(nsIPresContext* aPresContext, +nsBoxDebug::DisplayDebugInfoFor(nsIPresContext* aPresContext, + nsBoxFrame* aBoxFrame, nsPoint& aPoint, PRInt32& aCursor) { @@ -3330,10 +3625,10 @@ nsBoxDebugInner::DisplayDebugInfoFor(nsIPresContext* aPresContext, nscoord y = aPoint.y; // get the area inside our border. - nsRect insideBorder(0,0,mOuter->mRect.width, mOuter->mRect.height); + nsRect insideBorder(0,0,aBoxFrame->mRect.width, aBoxFrame->mRect.height); const nsStyleSpacing* spacing; - nsresult rv = mOuter->GetStyleData(eStyleStruct_Spacing, + nsresult rv = aBoxFrame->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct*&) spacing); NS_ASSERTION(rv == NS_OK,"failed to get spacing"); @@ -3345,7 +3640,7 @@ nsBoxDebugInner::DisplayDebugInfoFor(nsIPresContext* aPresContext, insideBorder.Deflate(border); - PRBool isHorizontal = mOuter->mState & NS_STATE_IS_HORIZONTAL; + PRBool isHorizontal = aBoxFrame->mState & NS_STATE_IS_HORIZONTAL; if (!insideBorder.Contains(nsPoint(x,y))) return NS_OK; @@ -3353,10 +3648,10 @@ nsBoxDebugInner::DisplayDebugInfoFor(nsIPresContext* aPresContext, //printf("%%%%%% inside box %%%%%%%\n"); int count = 0; - nsCalculatedBoxInfo* info = mOuter->GetInfoList()->GetFirst(); + nsCalculatedBoxInfo* info = aBoxFrame->GetInfoList()->GetFirst(); nsMargin m; - mOuter->mInner->GetDebugInset(m); + aBoxFrame->mInner->GetDebugInset(m); if ((isHorizontal && y < insideBorder.y + m.top) || (!isHorizontal && x < insideBorder.x + m.left)) { @@ -3377,7 +3672,7 @@ nsBoxDebugInner::DisplayDebugInfoFor(nsIPresContext* aPresContext, nsCOMPtr content; - mOuter->mInner->GetContentOf(mOuter, getter_AddRefs(content)); + aBoxFrame->mInner->GetContentOf(aBoxFrame, getter_AddRefs(content)); nsString id; content->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::id, id); @@ -3399,7 +3694,7 @@ nsBoxDebugInner::DisplayDebugInfoFor(nsIPresContext* aPresContext, printf("----- "); #ifdef NS_DEBUG - nsFrame::ListTag(stdout, mOuter); + nsFrame::ListTag(stdout, aBoxFrame); #endif printf(" Tag='%s', id='%s' class='%s'---------------\n", tagValue, idValue, kClassValue); @@ -3535,11 +3830,11 @@ nsBoxDebugInner::DisplayDebugInfoFor(nsIPresContext* aPresContext, */ - GetValue(info->minSize, aSize.minSize, min); - GetValue(info->prefSize, aSize.prefSize, pref); - GetValue(info->maxSize, aSize.maxSize, max); - GetValue(info->calculatedSize, aSize.calculatedSize, calc); - GetValue(info->flex, aSize.flex, flex); + GetValue(aPresContext, info->minSize, aSize.minSize, min); + GetValue(aPresContext, info->prefSize, aSize.prefSize, pref); + GetValue(aPresContext, info->maxSize, aSize.maxSize, max); + GetValue(aPresContext, info->calculatedSize, aSize.calculatedSize, calc); + GetValue(aPresContext, info->flex, aSize.flex, flex); printf("min%s, pref%s, max%s, actual%s, flex=%s\n\n", @@ -3590,9 +3885,9 @@ nsBoxFrame::GetCursor(nsIPresContext* aPresContext, // if we are in debug and we are in the debug area // return our own cursor and dump the debug information. - if (mInner->mDebugInner) + if (mState & NS_STATE_CURRENTLY_IN_DEBUG) { - if (mInner->mDebugInner->DisplayDebugInfoFor(aPresContext, newPoint, aCursor)) + if (nsBoxDebug::gInstance->DisplayDebugInfoFor(aPresContext, this, newPoint, aCursor)) return NS_OK; } @@ -3671,6 +3966,30 @@ nsBoxFrameInner::SanityCheck() #endif } +void* +nsInfoListImpl::operator new(size_t sz, nsIPresShell* aPresShell) +{ + return nsBoxFrameInner::Allocate(sz,aPresShell); +} + +void +nsInfoListImpl::Recycle(nsIPresShell* aShell) +{ + // recycle all out box infos + Clear(aShell); + + delete this; + nsBoxFrameInner::RecycleFreedMemory(aShell, this); +} + +// Overridden to prevent the global delete from being called, since the memory +// came out of an nsIArena instead of the global delete operator's heap. +void +nsInfoListImpl::operator delete(void* aPtr, size_t sz) +{ + nsBoxFrameInner::Free(aPtr, sz); +} + nsInfoListImpl::nsInfoListImpl():mFirst(nsnull),mLast(nsnull),mCount(0) { @@ -3678,9 +3997,30 @@ nsInfoListImpl::nsInfoListImpl():mFirst(nsnull),mLast(nsnull),mCount(0) nsInfoListImpl::~nsInfoListImpl() { - Clear(); } +nsresult +nsInfoListImpl::SetDebug(nsIPresContext* aPresContext, PRBool aDebug) +{ + nsCalculatedBoxInfo* info = GetFirst(); + while (info) + { + nsIBox* ibox = nsnull; + if (NS_SUCCEEDED(info->frame->QueryInterface(NS_GET_IID(nsIBox), (void**)&ibox)) && ibox) { + ibox->SetDebug(aPresContext, aDebug); + } + + // make sure we recalculate our children's sizes + info->mFlags |= NS_FRAME_BOX_NEEDS_RECALC; + + info = info->next; + } + + + return NS_OK; +} + + nsCalculatedBoxInfo* nsInfoListImpl::GetFirst() { @@ -3694,13 +4034,13 @@ nsInfoListImpl::GetLast() } void -nsInfoListImpl::Clear() +nsInfoListImpl::Clear(nsIPresShell* aShell) { nsCalculatedBoxInfo* info = mFirst; while(info) { nsCalculatedBoxInfo* it = info; info = info->next; - delete it; + it->Recycle(aShell); } mFirst = nsnull; mLast = nsnull; @@ -3714,16 +4054,16 @@ nsInfoListImpl::GetCount() } PRInt32 -nsInfoListImpl::CreateInfosFor(nsIFrame* aList, nsCalculatedBoxInfo*& first, nsCalculatedBoxInfo*& last) +nsInfoListImpl::CreateInfosFor(nsIPresShell* aPresShell, nsIFrame* aList, nsCalculatedBoxInfo*& first, nsCalculatedBoxInfo*& last) { PRInt32 count = 0; if (aList) { - first = new nsCalculatedBoxInfoImpl(aList); + first = new (aPresShell) nsCalculatedBoxInfoImpl(aList); count++; last = first; aList->GetNextSibling(&aList); while(aList) { - last->next = new nsCalculatedBoxInfoImpl(aList); + last->next = new (aPresShell) nsCalculatedBoxInfoImpl(aList); count++; aList->GetNextSibling(&aList); last = last->next; @@ -3776,15 +4116,15 @@ nsInfoListImpl::GetInfo(nsIFrame* aFrame) } void -nsInfoListImpl::Remove(nsIFrame* aFrame) +nsInfoListImpl::Remove(nsIPresShell* aShell, nsIFrame* aFrame) { // get the info before the frame nsCalculatedBoxInfo* prevInfo = GetPrevious(aFrame); - RemoveAfter(prevInfo); + RemoveAfter(aShell, prevInfo); } void -nsInfoListImpl::Insert(nsIFrame* aPrevFrame, nsIFrame* aFrameList) +nsInfoListImpl::Insert(nsIPresShell* aShell, nsIFrame* aPrevFrame, nsIFrame* aFrameList) { nsCalculatedBoxInfo* prevInfo = GetInfo(aPrevFrame); @@ -3792,15 +4132,15 @@ nsInfoListImpl::Insert(nsIFrame* aPrevFrame, nsIFrame* aFrameList) // if no previous frame then we are inserting in front if (prevInfo == nsnull) { // prepend them - Prepend(aFrameList); + Prepend(aShell, aFrameList); } else { // insert insert after previous info - InsertAfter(prevInfo, aFrameList); + InsertAfter(aShell, prevInfo, aFrameList); } } void -nsInfoListImpl::RemoveAfter(nsCalculatedBoxInfo* aPrevious) +nsInfoListImpl::RemoveAfter(nsIPresShell* aPresShell, nsCalculatedBoxInfo* aPrevious) { nsCalculatedBoxInfo* toDelete = nsnull; @@ -3819,16 +4159,16 @@ nsInfoListImpl::RemoveAfter(nsCalculatedBoxInfo* aPrevious) mLast = aPrevious; } - delete toDelete; + toDelete->Recycle(aPresShell); mCount--; } void -nsInfoListImpl::Prepend(nsIFrame* aList) +nsInfoListImpl::Prepend(nsIPresShell* aPresShell, nsIFrame* aList) { nsCalculatedBoxInfo* first; nsCalculatedBoxInfo* last; - mCount += CreateInfosFor(aList, first, last); + mCount += CreateInfosFor(aPresShell, aList, first, last); if (!mFirst) mFirst = mLast = first; else { @@ -3838,11 +4178,11 @@ nsInfoListImpl::Prepend(nsIFrame* aList) } void -nsInfoListImpl::Append(nsIFrame* aList) +nsInfoListImpl::Append(nsIPresShell* aPresShell, nsIFrame* aList) { nsCalculatedBoxInfo* first; nsCalculatedBoxInfo* last; - mCount += CreateInfosFor(aList, first, last); + mCount += CreateInfosFor(aPresShell, aList, first, last); if (!mFirst) mFirst = first; else @@ -3852,11 +4192,11 @@ nsInfoListImpl::Append(nsIFrame* aList) } void -nsInfoListImpl::InsertAfter(nsCalculatedBoxInfo* aPrev, nsIFrame* aList) +nsInfoListImpl::InsertAfter(nsIPresShell* aPresShell, nsCalculatedBoxInfo* aPrev, nsIFrame* aList) { nsCalculatedBoxInfo* first; nsCalculatedBoxInfo* last; - mCount += CreateInfosFor(aList, first, last); + mCount += CreateInfosFor(aPresShell, aList, first, last); last->next = aPrev->next; aPrev->next = first; if (aPrev == mLast) @@ -3864,10 +4204,10 @@ nsInfoListImpl::InsertAfter(nsCalculatedBoxInfo* aPrev, nsIFrame* aList) } void -nsInfoListImpl::Init(nsIFrame* aList) +nsInfoListImpl::Init(nsIPresShell* aPresShell, nsIFrame* aList) { - Clear(); - mCount += CreateInfosFor(aList, mFirst, mLast); + Clear(aPresShell); + mCount += CreateInfosFor(aPresShell, aList, mFirst, mLast); } void @@ -3927,3 +4267,5 @@ nsBoxInfo::~nsBoxInfo() + + diff --git a/layout/xul/base/src/nsBoxFrame.h b/layout/xul/base/src/nsBoxFrame.h index 5e4c5ee861dd..766363ef4ff3 100644 --- a/layout/xul/base/src/nsBoxFrame.h +++ b/layout/xul/base/src/nsBoxFrame.h @@ -41,6 +41,7 @@ class nsBoxDebugInner; class nsHTMLReflowCommand; class nsHTMLInfo; +// flags for box info #define NS_FRAME_BOX_SIZE_VALID 0x0001 #define NS_FRAME_BOX_IS_COLLAPSED 0x0002 #define NS_FRAME_BOX_NEEDS_RECALC 0x0004 @@ -49,14 +50,11 @@ class nsHTMLInfo; class nsCalculatedBoxInfo : public nsBoxInfo { public: nsSize calculatedSize; - /* - PRBool sizeValid; - PRBool collapsed; - PRBool needsRecalc; - */ PRInt16 mFlags; nsCalculatedBoxInfo* next; nsIFrame* frame; + + virtual void Recycle(nsIPresShell* aShell); }; class nsInfoList @@ -67,11 +65,19 @@ public: virtual PRInt32 GetCount()=0; }; +// flags from box +#define NS_STATE_IS_HORIZONTAL 0x00400000 +#define NS_STATE_AUTO_STRETCH 0x00800000 +#define NS_STATE_IS_ROOT 0x01000000 +#define NS_STATE_CURRENTLY_IN_DEBUG 0x02000000 +#define NS_STATE_SET_TO_DEBUG 0x04000000 +#define NS_STATE_DEBUG_WAS_SET 0x08000000 + class nsBoxFrame : public nsHTMLContainerFrame, public nsIBox { public: - friend nsresult NS_NewBoxFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame); + friend nsresult NS_NewBoxFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame, PRBool aIsRoot = PR_FALSE); // gets the rect inside our border and debug border. If you wish to paint inside a box // call this method to get the rect so you don't draw on the debug border or outer border. @@ -149,22 +155,11 @@ public: virtual void GetChildBoxInfo(PRInt32 aIndex, nsBoxInfo& aSize); - // Paint one child frame - virtual void PaintChild(nsIPresContext* aPresContext, - nsIRenderingContext& aRenderingContext, - const nsRect& aDirtyRect, - nsIFrame* aFrame, - nsFramePaintLayer aWhichLayer); - - virtual void PaintChildren(nsIPresContext* aPresContext, - nsIRenderingContext& aRenderingContext, - const nsRect& aDirtyRect, - nsFramePaintLayer aWhichLayer); - // nsIBox methods NS_IMETHOD GetBoxInfo(nsIPresContext* aPresContext, const nsHTMLReflowState& aReflowState, nsBoxInfo& aSize); NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr); NS_IMETHOD InvalidateCache(nsIFrame* aChild); + NS_IMETHOD SetDebug(nsIPresContext* aPresContext, PRBool aDebug); enum Halignment { hAlign_Left, @@ -179,7 +174,19 @@ public: vAlign_Bottom }; protected: - nsBoxFrame(); + nsBoxFrame(nsIPresShell* aPresShell, PRBool aIsRoot = PR_FALSE); + + // Paint one child frame + virtual void PaintChild(nsIPresContext* aPresContext, + nsIRenderingContext& aRenderingContext, + const nsRect& aDirtyRect, + nsIFrame* aFrame, + nsFramePaintLayer aWhichLayer); + + virtual void PaintChildren(nsIPresContext* aPresContext, + nsIRenderingContext& aRenderingContext, + const nsRect& aDirtyRect, + nsFramePaintLayer aWhichLayer); virtual void GetRedefinedMinPrefMax(nsIPresContext* aPresContext, nsIFrame* aFrame, nsCalculatedBoxInfo& aSize); @@ -216,7 +223,7 @@ protected: private: friend class nsBoxFrameInner; - friend class nsBoxDebugInner; + friend class nsBoxDebug; nsBoxFrameInner* mInner; }; // class nsBoxFrame diff --git a/layout/xul/base/src/nsDeckFrame.cpp b/layout/xul/base/src/nsDeckFrame.cpp index 2376b7aa59ed..a6e4da78c021 100644 --- a/layout/xul/base/src/nsDeckFrame.cpp +++ b/layout/xul/base/src/nsDeckFrame.cpp @@ -52,7 +52,7 @@ NS_NewDeckFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame ) if (nsnull == aNewFrame) { return NS_ERROR_NULL_POINTER; } - nsDeckFrame* it = new (aPresShell) nsDeckFrame; + nsDeckFrame* it = new (aPresShell) nsDeckFrame(aPresShell); if (nsnull == it) return NS_ERROR_OUT_OF_MEMORY; @@ -61,19 +61,10 @@ NS_NewDeckFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame ) } // NS_NewDeckFrame -NS_IMETHODIMP -nsDeckFrame::Init(nsIPresContext* aPresContext, - nsIContent* aContent, - nsIFrame* aParent, - nsIStyleContext* aContext, - nsIFrame* aPrevInFlow) -{ - // Get the element's tag - nsresult rv = nsBoxFrame::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow); - //CreateViewForFrame(aPresContext,this,aContext,PR_TRUE); - return rv; -} +nsDeckFrame::nsDeckFrame(nsIPresShell* aPresShell):nsStackFrame(aPresShell) +{ +} NS_IMETHODIMP nsDeckFrame::AttributeChanged(nsIPresContext* aPresContext, @@ -82,22 +73,12 @@ nsDeckFrame::AttributeChanged(nsIPresContext* aPresContext, nsIAtom* aAttribute, PRInt32 aHint) { - nsresult rv = nsBoxFrame::AttributeChanged(aPresContext, aChild, + nsresult rv = nsStackFrame::AttributeChanged(aPresContext, aChild, aNameSpaceID, aAttribute, aHint); // if the index changed hide the old element and make the now element visible if (aAttribute == nsHTMLAtoms::index) { - /* - nsCOMPtr shell; - aPresContext->GetShell(getter_AddRefs(shell)); - - nsCOMPtr reflowCmd; - rv = NS_NewHTMLReflowCommand(getter_AddRefs(reflowCmd), this, - nsIReflowCommand::StyleChanged); - if (NS_SUCCEEDED(rv)) - shell->AppendReflowCommand(reflowCmd); - */ Invalidate(aPresContext, nsRect(0,0,mRect.width,mRect.height), PR_FALSE); @@ -230,87 +211,6 @@ NS_IMETHODIMP nsDeckFrame::GetFrameForPoint(nsIPresContext* aPresContext, return NS_OK; } - -NS_IMETHODIMP -nsDeckFrame::SetInitialChildList(nsIPresContext* aPresContext, - nsIAtom* aListName, - nsIFrame* aChildList) -{ - nsresult r = nsBoxFrame::SetInitialChildList(aPresContext, aListName, aChildList); - return r; -} - - - -void -nsDeckFrame::AddChildSize(nsBoxInfo& aInfo, nsBoxInfo& aChildInfo) -{ - // largest preferred size - if (aChildInfo.prefSize.width > aInfo.prefSize.width) - aInfo.prefSize.width = aChildInfo.prefSize.width; - - if (aChildInfo.prefSize.height > aInfo.prefSize.height) - aInfo.prefSize.height = aChildInfo.prefSize.height; - - // largest min size - if (aChildInfo.minSize.width > aInfo.minSize.width) - aInfo.minSize.width = aChildInfo.minSize.width; - - if (aChildInfo.minSize.height > aInfo.minSize.height) - aInfo.minSize.height = aChildInfo.minSize.height; - - // smallest max size - if (aChildInfo.maxSize.width < aInfo.maxSize.width) - aInfo.maxSize.width = aChildInfo.maxSize.width; - - if (aChildInfo.maxSize.height < aInfo.maxSize.height) - aInfo.maxSize.height = aChildInfo.maxSize.height; -} - - -void -nsDeckFrame::ComputeChildsNextPosition(nsCalculatedBoxInfo* aInfo, nscoord& aCurX, nscoord& aCurY, nscoord& aNextX, nscoord& aNextY, const nsSize& aCurrentChildSize, const nsRect& aBoxRect, nscoord aMaxAscent) -{ - // let everything layout on top of each other. - aCurX = aNextX = aBoxRect.x; - aCurY = aNextY = aBoxRect.y; -} - -/* -nsresult -nsDeckFrame::PlaceChildren(nsIPresContext* aPresContext, nsRect& boxRect) -{ - // ------- set the childs positions --------- - nsIFrame* childFrame = mFrames.FirstChild(); - nsInfoList* list = GetInfoList(); - nsCalculatedBoxInfo* info = list->GetFirst(); - - nscoord count = 0; - while (nsnull != childFrame) - { - nsresult rv; - // make collapsed children not show up - if (info->collapsed) { - //nsRect rect(0,0,0,0); - //childFrame->GetRect(rect); - //if (rect.width > 0 || rect.height > 0) { - // childFrame->SizeTo(0,0); - CollapseChild(aPresContext, childFrame, PR_TRUE); - //} - } else { - childFrame->MoveTo(aPresContext, boxRect.x, boxRect.y); - } - - rv = childFrame->GetNextSibling(&childFrame); - NS_ASSERTION(rv == NS_OK,"failed to get next child"); - info = info->next; - count++; - } - - return NS_OK; -} -*/ - NS_IMETHODIMP nsDeckFrame::DidReflow(nsIPresContext* aPresContext, nsDidReflowStatus aStatus) @@ -348,40 +248,3 @@ nsDeckFrame::DidReflow(nsIPresContext* aPresContext, return rv; } - -void -nsDeckFrame::ChildResized(nsIFrame* aFrame, nsHTMLReflowMetrics& aDesiredSize, nsRect& aRect, nscoord& aMaxAscent, nsCalculatedBoxInfo& aInfo, PRBool*& aResized, PRInt32 aInfoCount, nscoord& aChangedIndex, PRBool& aFinished, nscoord aIndex, nsString& aReason) -{ - if (aDesiredSize.width > aRect.width) { - aRect.width = aDesiredSize.width; - InvalidateChildren(); - LayoutChildrenInRect(aRect, aMaxAscent); - aReason = "child's width got bigger"; - aChangedIndex = aIndex; - aFinished = PR_FALSE; - } else if (aDesiredSize.height > aRect.height) { - aRect.height = aDesiredSize.height; - InvalidateChildren(); - LayoutChildrenInRect(aRect, aMaxAscent); - aReason = "child's height got bigger"; - aChangedIndex = aIndex; - aFinished = PR_FALSE; - } -} - -void -nsDeckFrame::LayoutChildrenInRect(nsRect& aGivenSize, nscoord& aMaxAscent) -{ - nsInfoList* list = GetInfoList(); - nsCalculatedBoxInfo* info = list->GetFirst(); - - while(info) { - info->calculatedSize.width = aGivenSize.width; - info->calculatedSize.height = aGivenSize.height; - info->mFlags |= NS_FRAME_BOX_SIZE_VALID; - info = info->next; - } - - aMaxAscent = 0; -} - diff --git a/layout/xul/base/src/nsDeckFrame.h b/layout/xul/base/src/nsDeckFrame.h index 1eb1216d26bc..01208fff8c3f 100644 --- a/layout/xul/base/src/nsDeckFrame.h +++ b/layout/xul/base/src/nsDeckFrame.h @@ -31,9 +31,9 @@ #ifndef nsDeckFrame_h___ #define nsDeckFrame_h___ -#include "nsBoxFrame.h" +#include "nsStackFrame.h" -class nsDeckFrame : public nsBoxFrame +class nsDeckFrame : public nsStackFrame { public: @@ -41,13 +41,6 @@ public: - NS_IMETHOD Init(nsIPresContext* aPresContext, - nsIContent* aContent, - nsIFrame* aParent, - nsIStyleContext* aContext, - nsIFrame* asPrevInFlow); - - NS_IMETHOD AttributeChanged(nsIPresContext* aPresContext, nsIContent* aChild, PRInt32 aNameSpaceID, @@ -63,17 +56,10 @@ public: nsFramePaintLayer aWhichLayer); - NS_IMETHOD SetInitialChildList(nsIPresContext* aPresContext, - nsIAtom* aListName, - nsIFrame* aChildList); - - NS_IMETHOD GetFrameForPoint(nsIPresContext* aPresContext, const nsPoint& aPoint, nsIFrame** aFrame); - virtual PRIntn GetSkipSides() const { return 0; } - NS_IMETHOD GetFrameName(nsString& aResult) const { aResult = "Deck"; @@ -82,13 +68,9 @@ public: protected: + nsDeckFrame(nsIPresShell* aPresShell); + virtual nsIFrame* GetSelectedFrame(); - virtual void ComputeChildsNextPosition( nsCalculatedBoxInfo* aInfo, nscoord& aCurX, nscoord& aCurY, nscoord& aNextX, nscoord& aNextY, const nsSize& aCurrentChildSize, const nsRect& aBoxRect, nscoord aMaxAscent); - virtual void ChildResized(nsIFrame* aFrame, nsHTMLReflowMetrics& aDesiredSize, nsRect& aRect, nscoord& aMaxAscent, nsCalculatedBoxInfo& aInfo, PRBool*& aResized, PRInt32 aInfoCount, nscoord& aChangedIndex, PRBool& aFinished, nscoord aIndex, nsString& aReason); - virtual void LayoutChildrenInRect(nsRect& aSize, nscoord& aMaxAscent); - virtual void AddChildSize(nsBoxInfo& aInfo, nsBoxInfo& aChildInfo); - - private: diff --git a/layout/xul/base/src/nsGroupBoxFrame.cpp b/layout/xul/base/src/nsGroupBoxFrame.cpp index ace27e48e527..b19d6011557c 100644 --- a/layout/xul/base/src/nsGroupBoxFrame.cpp +++ b/layout/xul/base/src/nsGroupBoxFrame.cpp @@ -53,7 +53,7 @@ class nsTitledBoxFrame : public nsBoxFrame { public: - nsTitledBoxFrame(); + nsTitledBoxFrame(nsIPresShell* aShell); NS_IMETHOD SetInitialChildList(nsIPresContext* aPresContext, nsIAtom* aListName, @@ -96,7 +96,7 @@ public: class nsTitledBoxInnerFrame : public nsBoxFrame { public: - nsTitledBoxInnerFrame() {} + nsTitledBoxInnerFrame(nsIPresShell* aShell):nsBoxFrame(aShell) {} #ifdef DEBUG @@ -117,7 +117,7 @@ NS_NewTitledBoxInnerFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame) if (nsnull == aNewFrame) { return NS_ERROR_NULL_POINTER; } - nsTitledBoxInnerFrame* it = new (aPresShell) nsTitledBoxInnerFrame; + nsTitledBoxInnerFrame* it = new (aPresShell) nsTitledBoxInnerFrame(aPresShell); if (!it) { return NS_ERROR_OUT_OF_MEMORY; } @@ -133,7 +133,7 @@ NS_NewTitledBoxFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame) if (nsnull == aNewFrame) { return NS_ERROR_NULL_POINTER; } - nsTitledBoxFrame* it = new (aPresShell) nsTitledBoxFrame; + nsTitledBoxFrame* it = new (aPresShell) nsTitledBoxFrame(aPresShell); if (!it) { return NS_ERROR_OUT_OF_MEMORY; } @@ -142,7 +142,7 @@ NS_NewTitledBoxFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame) return NS_OK; } -nsTitledBoxFrame::nsTitledBoxFrame() +nsTitledBoxFrame::nsTitledBoxFrame(nsIPresShell* aShell):nsBoxFrame(aShell) { } diff --git a/layout/xul/base/src/nsIBox.h b/layout/xul/base/src/nsIBox.h index 52fe136c78d9..d4fcf0171782 100644 --- a/layout/xul/base/src/nsIBox.h +++ b/layout/xul/base/src/nsIBox.h @@ -70,12 +70,8 @@ public: */ NS_IMETHOD InvalidateCache(nsIFrame* aChild)=0; - /** - * Helper method from doing box reflow - */ - static void HandleRootBoxReflow(nsIPresContext* aPresContext, - nsIFrame* aBox, - const nsHTMLReflowState& aReflowState); + + NS_IMETHOD SetDebug(nsIPresContext* aPresContext, PRBool aDebug)=0; }; diff --git a/layout/xul/base/src/nsMenuBarFrame.cpp b/layout/xul/base/src/nsMenuBarFrame.cpp index da6938630ca6..f29ffe9170fe 100644 --- a/layout/xul/base/src/nsMenuBarFrame.cpp +++ b/layout/xul/base/src/nsMenuBarFrame.cpp @@ -52,7 +52,7 @@ NS_NewMenuBarFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame) if (nsnull == aNewFrame) { return NS_ERROR_NULL_POINTER; } - nsMenuBarFrame* it = new (aPresShell) nsMenuBarFrame; + nsMenuBarFrame* it = new (aPresShell) nsMenuBarFrame (aPresShell); if ( !it ) return NS_ERROR_OUT_OF_MEMORY; *aNewFrame = it; @@ -83,8 +83,8 @@ NS_INTERFACE_MAP_END_INHERITING(nsToolbarFrame) // // nsMenuBarFrame cntr // -nsMenuBarFrame::nsMenuBarFrame() -:mIsActive(PR_FALSE), mTarget(nsnull), mKeyboardNavigator(nsnull), mMenuBarListener(nsnull) +nsMenuBarFrame::nsMenuBarFrame(nsIPresShell* aShell):nsToolbarFrame(aShell), +mIsActive(PR_FALSE), mTarget(nsnull), mKeyboardNavigator(nsnull), mMenuBarListener(nsnull) { } // cntr diff --git a/layout/xul/base/src/nsMenuBarFrame.h b/layout/xul/base/src/nsMenuBarFrame.h index 858390967b7d..c2a8fd7c0e01 100644 --- a/layout/xul/base/src/nsMenuBarFrame.h +++ b/layout/xul/base/src/nsMenuBarFrame.h @@ -45,7 +45,7 @@ nsresult NS_NewMenuBarFrame(nsIPresShell* aPresShell, nsIFrame** aResult) ; class nsMenuBarFrame : public nsToolbarFrame, public nsIMenuParent { public: - nsMenuBarFrame(); + nsMenuBarFrame(nsIPresShell* aShell); ~nsMenuBarFrame(); NS_DECL_ISUPPORTS diff --git a/layout/xul/base/src/nsMenuFrame.cpp b/layout/xul/base/src/nsMenuFrame.cpp index 6dc4494f52f3..014808fd7f1f 100644 --- a/layout/xul/base/src/nsMenuFrame.cpp +++ b/layout/xul/base/src/nsMenuFrame.cpp @@ -76,7 +76,7 @@ NS_NewMenuFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame, PRUint32 aFlags) if (nsnull == aNewFrame) { return NS_ERROR_NULL_POINTER; } - nsMenuFrame* it = new (aPresShell) nsMenuFrame; + nsMenuFrame* it = new (aPresShell) nsMenuFrame (aPresShell); if ( !it ) return NS_ERROR_OUT_OF_MEMORY; *aNewFrame = it; @@ -109,8 +109,8 @@ NS_INTERFACE_MAP_END_INHERITING(nsBoxFrame) // // nsMenuFrame cntr // -nsMenuFrame::nsMenuFrame() - : mIsMenu(PR_FALSE), +nsMenuFrame::nsMenuFrame(nsIPresShell* aShell):nsBoxFrame(aShell), + mIsMenu(PR_FALSE), mMenuOpen(PR_FALSE), mChecked(PR_FALSE), mType(eMenuType_Normal), @@ -808,6 +808,41 @@ nsMenuFrame::Reflow(nsIPresContext* aPresContext, return rv; } +NS_IMETHODIMP +nsMenuFrame::SetDebug(nsIPresContext* aPresContext, PRBool aDebug) +{ + // see if our state matches the given debug state + PRBool debugSet = mState & NS_STATE_CURRENTLY_IN_DEBUG; + PRBool debugChanged = (!aDebug && debugSet) || (aDebug && !debugSet); + + // if it doesn't then tell each child below us the new debug state + if (debugChanged) + { + nsBoxFrame::SetDebug(aPresContext, aDebug); + SetDebug(aPresContext, mPopupFrames.FirstChild(), aDebug); + } + + return NS_OK; +} + +nsresult +nsMenuFrame::SetDebug(nsIPresContext* aPresContext, nsIFrame* aList, PRBool aDebug) +{ + if (!aList) + return NS_OK; + + while (aList) { + nsIBox* ibox = nsnull; + if (NS_SUCCEEDED(aList->QueryInterface(NS_GET_IID(nsIBox), (void**)&ibox)) && ibox) { + ibox->SetDebug(aPresContext, aDebug); + } + + aList->GetNextSibling(&aList); + } + + return NS_OK; +} + NS_IMETHODIMP nsMenuFrame::DidReflow(nsIPresContext* aPresContext, @@ -1325,6 +1360,7 @@ nsMenuFrame::InsertFrames(nsIPresContext* aPresContext, frameChild->GetTag(*getter_AddRefs(tag)); if (tag && tag.get() == nsXULAtoms::menupopup) { mPopupFrames.InsertFrames(nsnull, nsnull, aFrameList); + SetDebug(aPresContext, aFrameList, mState & NS_STATE_CURRENTLY_IN_DEBUG); rv = GenerateDirtyReflowCommand(aPresContext, aPresShell); } else { rv = nsBoxFrame::InsertFrames(aPresContext, aPresShell, aListName, aPrevFrame, aFrameList); @@ -1351,6 +1387,7 @@ nsMenuFrame::AppendFrames(nsIPresContext* aPresContext, frameChild->GetTag(*getter_AddRefs(tag)); if (tag && tag.get() == nsXULAtoms::menupopup) { mPopupFrames.AppendFrames(nsnull, aFrameList); + SetDebug(aPresContext, aFrameList, mState & NS_STATE_CURRENTLY_IN_DEBUG); rv = GenerateDirtyReflowCommand(aPresContext, aPresShell); } else { rv = nsBoxFrame::AppendFrames(aPresContext, aPresShell, aListName, aFrameList); diff --git a/layout/xul/base/src/nsMenuFrame.h b/layout/xul/base/src/nsMenuFrame.h index 77f5fa9711f5..752c152bb9f7 100644 --- a/layout/xul/base/src/nsMenuFrame.h +++ b/layout/xul/base/src/nsMenuFrame.h @@ -54,7 +54,7 @@ class nsMenuFrame : public nsBoxFrame, public nsIAnonymousContentCreator { public: - nsMenuFrame(); + nsMenuFrame(nsIPresShell* aShell); NS_DECL_ISUPPORTS @@ -70,6 +70,8 @@ public: nsIStyleContext* aContext, nsIFrame* aPrevInFlow); + NS_IMETHOD SetDebug(nsIPresContext* aPresContext, PRBool aDebug); + NS_IMETHOD IsActive(PRBool& aResult) { aResult = PR_TRUE; return NS_OK; }; // The following four methods are all overridden so that the menu children @@ -187,6 +189,8 @@ protected: NS_IMETHOD GetBoxInfo(nsIPresContext* aPresContext, const nsHTMLReflowState& aReflowState, nsBoxInfo& aSize); protected: + nsresult SetDebug(nsIPresContext* aPresContext, nsIFrame* aList, PRBool aDebug); + nsFrameList mPopupFrames; PRPackedBool mIsMenu; // Whether or not we can even have children or not. PRPackedBool mMenuOpen; diff --git a/layout/xul/base/src/nsMenuPopupFrame.cpp b/layout/xul/base/src/nsMenuPopupFrame.cpp index 1d462aba41b5..4e0a15272de9 100644 --- a/layout/xul/base/src/nsMenuPopupFrame.cpp +++ b/layout/xul/base/src/nsMenuPopupFrame.cpp @@ -67,7 +67,7 @@ NS_NewMenuPopupFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame) if (nsnull == aNewFrame) { return NS_ERROR_NULL_POINTER; } - nsMenuPopupFrame* it = new (aPresShell) nsMenuPopupFrame; + nsMenuPopupFrame* it = new (aPresShell) nsMenuPopupFrame (aPresShell); if ( !it ) return NS_ERROR_OUT_OF_MEMORY; *aNewFrame = it; @@ -99,8 +99,8 @@ NS_INTERFACE_MAP_END_INHERITING(nsBoxFrame) // // nsMenuPopupFrame ctor // -nsMenuPopupFrame::nsMenuPopupFrame() - : mCurrentMenu(nsnull), mTimerMenu(nsnull), mCloseTimer(nsnull) +nsMenuPopupFrame::nsMenuPopupFrame(nsIPresShell* aShell):nsBoxFrame(aShell), +mCurrentMenu(nsnull), mTimerMenu(nsnull), mCloseTimer(nsnull) { SetIsContextMenu(PR_FALSE); // we're not a context menu by default diff --git a/layout/xul/base/src/nsMenuPopupFrame.h b/layout/xul/base/src/nsMenuPopupFrame.h index 75d122b70ec7..81193faa19b1 100644 --- a/layout/xul/base/src/nsMenuPopupFrame.h +++ b/layout/xul/base/src/nsMenuPopupFrame.h @@ -53,7 +53,7 @@ class nsIDOMXULDocument; class nsMenuPopupFrame : public nsBoxFrame, public nsIMenuParent, public nsITimerCallback { public: - nsMenuPopupFrame(); + nsMenuPopupFrame(nsIPresShell* aShell); NS_DECL_ISUPPORTS diff --git a/layout/xul/base/src/nsPopupSetFrame.cpp b/layout/xul/base/src/nsPopupSetFrame.cpp index 2d435fcea92d..c335f0689c04 100644 --- a/layout/xul/base/src/nsPopupSetFrame.cpp +++ b/layout/xul/base/src/nsPopupSetFrame.cpp @@ -63,7 +63,7 @@ NS_NewPopupSetFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame) if (nsnull == aNewFrame) { return NS_ERROR_NULL_POINTER; } - nsPopupSetFrame* it = new (aPresShell) nsPopupSetFrame; + nsPopupSetFrame* it = new (aPresShell) nsPopupSetFrame (aPresShell); if ( !it ) return NS_ERROR_OUT_OF_MEMORY; *aNewFrame = it; @@ -93,8 +93,8 @@ NS_INTERFACE_MAP_END_INHERITING(nsBoxFrame) // // nsPopupSetFrame cntr // -nsPopupSetFrame::nsPopupSetFrame() -:mPresContext(nsnull), mElementFrame(nsnull) +nsPopupSetFrame::nsPopupSetFrame(nsIPresShell* aShell):nsBoxFrame(aShell), +mPresContext(nsnull), mElementFrame(nsnull) { } // cntr @@ -265,6 +265,42 @@ nsPopupSetFrame::Reflow(nsIPresContext* aPresContext, return rv; } +NS_IMETHODIMP +nsPopupSetFrame::SetDebug(nsIPresContext* aPresContext, PRBool aDebug) +{ + // see if our state matches the given debug state + PRBool debugSet = mState & NS_STATE_CURRENTLY_IN_DEBUG; + PRBool debugChanged = (!aDebug && debugSet) || (aDebug && !debugSet); + + // if it doesn't then tell each child below us the new debug state + if (debugChanged) + { + nsBoxFrame::SetDebug(aPresContext, aDebug); + SetDebug(aPresContext, mPopupFrames.FirstChild(), aDebug); + } + + return NS_OK; +} + +nsresult +nsPopupSetFrame::SetDebug(nsIPresContext* aPresContext, nsIFrame* aList, PRBool aDebug) +{ + if (!aList) + return NS_OK; + + while (aList) { + nsIBox* ibox = nsnull; + if (NS_SUCCEEDED(aList->QueryInterface(NS_GET_IID(nsIBox), (void**)&ibox)) && ibox) { + ibox->SetDebug(aPresContext, aDebug); + } + + aList->GetNextSibling(&aList); + } + + return NS_OK; +} + + NS_IMETHODIMP nsPopupSetFrame::DidReflow(nsIPresContext* aPresContext, @@ -326,6 +362,7 @@ nsPopupSetFrame::InsertFrames(nsIPresContext* aPresContext, frameChild->GetTag(*getter_AddRefs(tag)); if (tag && tag.get() == nsXULAtoms::popup) { mPopupFrames.InsertFrames(nsnull, nsnull, aFrameList); + SetDebug(aPresContext, aFrameList, mState & NS_STATE_CURRENTLY_IN_DEBUG); rv = GenerateDirtyReflowCommand(aPresContext, aPresShell); } else { rv = nsBoxFrame::InsertFrames(aPresContext, aPresShell, aListName, aPrevFrame, aFrameList); @@ -352,6 +389,7 @@ nsPopupSetFrame::AppendFrames(nsIPresContext* aPresContext, frameChild->GetTag(*getter_AddRefs(tag)); if (tag && tag.get() == nsXULAtoms::popup) { mPopupFrames.AppendFrames(nsnull, aFrameList); + SetDebug(aPresContext, aFrameList, mState & NS_STATE_CURRENTLY_IN_DEBUG); rv = GenerateDirtyReflowCommand(aPresContext, aPresShell); } else { rv = nsBoxFrame::AppendFrames(aPresContext, aPresShell, aListName, aFrameList); diff --git a/layout/xul/base/src/nsPopupSetFrame.h b/layout/xul/base/src/nsPopupSetFrame.h index fae729fe3060..81a1329a407a 100644 --- a/layout/xul/base/src/nsPopupSetFrame.h +++ b/layout/xul/base/src/nsPopupSetFrame.h @@ -41,7 +41,7 @@ nsresult NS_NewPopupSetFrame(nsIPresShell* aPresShell, nsIFrame** aResult) ; class nsPopupSetFrame : public nsBoxFrame, public nsIPopupSetFrame { public: - nsPopupSetFrame(); + nsPopupSetFrame(nsIPresShell* aShell); NS_DECL_ISUPPORTS @@ -51,6 +51,8 @@ public: nsIStyleContext* aContext, nsIFrame* aPrevInFlow); + NS_IMETHOD SetDebug(nsIPresContext* aPresContext, PRBool aDebug); + // The following four methods are all overridden so that the menu children // can be stored in a separate list (so that they don't impact reflow of the // actual menu item at all). @@ -117,6 +119,8 @@ protected: void UpdateDismissalListener(nsIMenuParent* aMenuParent); protected: + nsresult SetDebug(nsIPresContext* aPresContext, nsIFrame* aList, PRBool aDebug); + nsFrameList mPopupFrames; nsIPresContext* mPresContext; // Our pres context. diff --git a/layout/xul/base/src/nsProgressMeterFrame.h b/layout/xul/base/src/nsProgressMeterFrame.h index 8abdfaf666ed..f3eb253c6329 100644 --- a/layout/xul/base/src/nsProgressMeterFrame.h +++ b/layout/xul/base/src/nsProgressMeterFrame.h @@ -70,6 +70,9 @@ public: NS_IMETHOD InvalidateCache(nsIFrame* aChild); + NS_IMETHOD SetDebug(nsIPresContext* aPresContext, PRBool aDebug) { return NS_OK; } + + // nsIHTMLReflow overrides NS_IMETHOD Reflow(nsIPresContext* aPresContext, nsHTMLReflowMetrics& aDesiredSize, diff --git a/layout/xul/base/src/nsScrollbarFrame.cpp b/layout/xul/base/src/nsScrollbarFrame.cpp index e5455a60dfff..0a25b6d45605 100644 --- a/layout/xul/base/src/nsScrollbarFrame.cpp +++ b/layout/xul/base/src/nsScrollbarFrame.cpp @@ -242,7 +242,7 @@ NS_NewScrollbarFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame ) if (nsnull == aNewFrame) { return NS_ERROR_NULL_POINTER; } - nsScrollbarFrame* it = new (aPresShell) nsScrollbarFrame; + nsScrollbarFrame* it = new (aPresShell) nsScrollbarFrame (aPresShell); if (nsnull == it) return NS_ERROR_OUT_OF_MEMORY; diff --git a/layout/xul/base/src/nsScrollbarFrame.h b/layout/xul/base/src/nsScrollbarFrame.h index 2a0cd66dc7bf..d36a1c550a93 100644 --- a/layout/xul/base/src/nsScrollbarFrame.h +++ b/layout/xul/base/src/nsScrollbarFrame.h @@ -39,7 +39,7 @@ class nsScrollbarFrame : public nsBoxFrame, public nsIAnonymousContentCreator { public: - nsScrollbarFrame() {} + nsScrollbarFrame(nsIPresShell* aShell):nsBoxFrame(aShell) {} #ifdef DEBUG NS_IMETHOD GetFrameName(nsString& aResult) const { diff --git a/layout/xul/base/src/nsSplitterFrame.cpp b/layout/xul/base/src/nsSplitterFrame.cpp index 28ce417cf9c6..f3bcfdf947a6 100644 --- a/layout/xul/base/src/nsSplitterFrame.cpp +++ b/layout/xul/base/src/nsSplitterFrame.cpp @@ -213,7 +213,7 @@ NS_NewSplitterFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame ) if (nsnull == aNewFrame) { return NS_ERROR_NULL_POINTER; } - nsSplitterFrame* it = new (aPresShell) nsSplitterFrame; + nsSplitterFrame* it = new (aPresShell) nsSplitterFrame(aPresShell); if (nsnull == it) return NS_ERROR_OUT_OF_MEMORY; @@ -222,7 +222,7 @@ NS_NewSplitterFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame ) } // NS_NewSplitterFrame -nsSplitterFrame::nsSplitterFrame() +nsSplitterFrame::nsSplitterFrame(nsIPresShell* aPresShell):nsBoxFrame(aPresShell) { mInner = new nsSplitterFrameInner(this); mInner->AddRef(); diff --git a/layout/xul/base/src/nsSplitterFrame.h b/layout/xul/base/src/nsSplitterFrame.h index ccb744b713ed..ee3eeb5fe2f4 100644 --- a/layout/xul/base/src/nsSplitterFrame.h +++ b/layout/xul/base/src/nsSplitterFrame.h @@ -39,7 +39,7 @@ nsresult NS_NewSplitterFrame(nsIPresShell* aPresShell, nsIFrame** aResult) ; class nsSplitterFrame : public nsBoxFrame, public nsIAnonymousContentCreator { public: - nsSplitterFrame(); + nsSplitterFrame(nsIPresShell* aPresShell); ~nsSplitterFrame(); #ifdef DEBUG diff --git a/layout/xul/base/src/nsSpringFrame.cpp b/layout/xul/base/src/nsSpringFrame.cpp new file mode 100644 index 000000000000..a248cd2cc468 --- /dev/null +++ b/layout/xul/base/src/nsSpringFrame.cpp @@ -0,0 +1,58 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Communicator client code. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + */ + +// +// Eric Vaughan +// Netscape Communications +// +// See documentation in associated header file +// + +#include "nsSpringFrame.h" + +nsresult +NS_NewSpringFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame ) +{ + NS_PRECONDITION(aNewFrame, "null OUT ptr"); + if (nsnull == aNewFrame) { + return NS_ERROR_NULL_POINTER; + } + nsSpringFrame* it = new (aPresShell) nsSpringFrame; + if (nsnull == it) + return NS_ERROR_OUT_OF_MEMORY; + + *aNewFrame = it; + return NS_OK; + +} // NS_NewSpringFrame + +NS_IMETHODIMP nsSpringFrame::GetFrameForPoint(nsIPresContext* aPresContext, + const nsPoint& aPoint, + nsIFrame** aFrame) +{ + *aFrame = this; + return NS_OK; + /* + // clicks just go right through springs. + return NS_ERROR_FAILURE; + */ +} diff --git a/layout/xul/base/src/nsSpringFrame.h b/layout/xul/base/src/nsSpringFrame.h new file mode 100644 index 000000000000..1cda0ceb915a --- /dev/null +++ b/layout/xul/base/src/nsSpringFrame.h @@ -0,0 +1,57 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Communicator client code. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + */ + +/** + + Eric D Vaughan + A frame that can have multiple children. Only one child may be displayed at one time. So the + can be flipped though like a deck of cards. + +**/ + +#ifndef nsSpringFrame_h___ +#define nsSpringFrame_h___ + +#include "nsXULLeafFrame.h" + +class nsSpringFrame : public nsXULLeafFrame +{ +public: + + friend nsresult NS_NewSpringFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame); + + + NS_IMETHOD GetFrameForPoint(nsIPresContext* aPresContext, + const nsPoint& aPoint, + nsIFrame** aFrame); + + NS_IMETHOD GetFrameName(nsString& aResult) const + { + aResult = "Spring"; + return NS_OK; + } +}; // class nsSpringFrame + + + +#endif + diff --git a/layout/xul/base/src/nsStackFrame.cpp b/layout/xul/base/src/nsStackFrame.cpp new file mode 100644 index 000000000000..98f4dfef09b3 --- /dev/null +++ b/layout/xul/base/src/nsStackFrame.cpp @@ -0,0 +1,285 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Communicator client code. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + */ + +// +// Eric Vaughan +// Netscape Communications +// +// See documentation in associated header file +// + +#include "nsStackFrame.h" +#include "nsIStyleContext.h" +#include "nsIPresContext.h" +#include "nsIContent.h" +#include "nsCOMPtr.h" +#include "nsHTMLIIDs.h" +#include "nsUnitConversion.h" +#include "nsINameSpaceManager.h" +#include "nsXULAtoms.h" +#include "nsHTMLAtoms.h" +#include "nsIReflowCommand.h" +#include "nsHTMLParts.h" +#include "nsIPresShell.h" +#include "nsStyleChangeList.h" +#include "nsCSSRendering.h" +#include "nsIViewManager.h" + + +nsresult +NS_NewStackFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame ) +{ + NS_PRECONDITION(aNewFrame, "null OUT ptr"); + if (nsnull == aNewFrame) { + return NS_ERROR_NULL_POINTER; + } + nsStackFrame* it = new (aPresShell) nsStackFrame(aPresShell); + if (nsnull == it) + return NS_ERROR_OUT_OF_MEMORY; + + *aNewFrame = it; + return NS_OK; + +} // NS_NewDeckFrame + +nsStackFrame::nsStackFrame(nsIPresShell* aPresShell):nsBoxFrame(aPresShell) +{ +} + + +NS_IMETHODIMP +nsStackFrame::Init(nsIPresContext* aPresContext, + nsIContent* aContent, + nsIFrame* aParent, + nsIStyleContext* aContext, + nsIFrame* aPrevInFlow) +{ + // Get the element's tag + nsresult rv = nsBoxFrame::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow); + return rv; +} + +void +nsStackFrame::AddChildSize(nsBoxInfo& aInfo, nsBoxInfo& aChildInfo) +{ + // largest preferred size + if (aChildInfo.prefSize.width > aInfo.prefSize.width) + aInfo.prefSize.width = aChildInfo.prefSize.width; + + if (aChildInfo.prefSize.height > aInfo.prefSize.height) + aInfo.prefSize.height = aChildInfo.prefSize.height; + + // largest min size + if (aChildInfo.minSize.width > aInfo.minSize.width) + aInfo.minSize.width = aChildInfo.minSize.width; + + if (aChildInfo.minSize.height > aInfo.minSize.height) + aInfo.minSize.height = aChildInfo.minSize.height; + + // smallest max size + if (aChildInfo.maxSize.width < aInfo.maxSize.width) + aInfo.maxSize.width = aChildInfo.maxSize.width; + + if (aChildInfo.maxSize.height < aInfo.maxSize.height) + aInfo.maxSize.height = aChildInfo.maxSize.height; +} + + +void +nsStackFrame::ComputeChildsNextPosition(nsCalculatedBoxInfo* aInfo, nscoord& aCurX, nscoord& aCurY, nscoord& aNextX, nscoord& aNextY, const nsSize& aCurrentChildSize, const nsRect& aBoxRect, nscoord aMaxAscent) +{ + // let everything layout on top of each other. + aCurX = aNextX = aBoxRect.x; + aCurY = aNextY = aBoxRect.y; +} + +void +nsStackFrame::ChildResized(nsIFrame* aFrame, nsHTMLReflowMetrics& aDesiredSize, nsRect& aRect, nscoord& aMaxAscent, nsCalculatedBoxInfo& aInfo, PRBool*& aResized, PRInt32 aInfoCount, nscoord& aChangedIndex, PRBool& aFinished, nscoord aIndex, nsString& aReason) +{ + if (aDesiredSize.width > aRect.width) { + aRect.width = aDesiredSize.width; + InvalidateChildren(); + LayoutChildrenInRect(aRect, aMaxAscent); + aReason = "child's width got bigger"; + aChangedIndex = aIndex; + aFinished = PR_FALSE; + } else if (aDesiredSize.height > aRect.height) { + aRect.height = aDesiredSize.height; + InvalidateChildren(); + LayoutChildrenInRect(aRect, aMaxAscent); + aReason = "child's height got bigger"; + aChangedIndex = aIndex; + aFinished = PR_FALSE; + } +} + +void +nsStackFrame::LayoutChildrenInRect(nsRect& aGivenSize, nscoord& aMaxAscent) +{ + nsInfoList* list = GetInfoList(); + nsCalculatedBoxInfo* info = list->GetFirst(); + + while(info) { + info->calculatedSize.width = aGivenSize.width; + info->calculatedSize.height = aGivenSize.height; + info->mFlags |= NS_FRAME_BOX_SIZE_VALID; + info = info->next; + } + + aMaxAscent = 0; +} + +NS_IMETHODIMP +nsStackFrame::GetFrameForPoint(nsIPresContext* aPresContext, + const nsPoint& aPoint, + nsIFrame** aFrame) +{ + nsRect r(0,0,mRect.width, mRect.height); + + // if it is not inside us fail + if (!r.Contains(aPoint)) { + return NS_ERROR_FAILURE; + } + + // is it inside our border, padding, and debugborder or insets? + nsMargin im(0,0,0,0); + GetInset(im); + nsMargin border(0,0,0,0); + const nsStyleSpacing* spacing = (const nsStyleSpacing*) + mStyleContext->GetStyleData(eStyleStruct_Spacing); + spacing->GetBorderPadding(border); + r.Deflate(im); + r.Deflate(border); + + // no? Then it must be in our border so return us. + if (!r.Contains(aPoint)) { + *aFrame = this; + return NS_OK; + } + +// nsPoint tmp; + //tmp.MoveTo(aPoint.x - r.x, aPoint.y - r.y); + + nsIFrame* first = mFrames.FirstChild(); + + + + // look at the children in reverse order + nsresult rv; + + if (first) + rv = GetStackedFrameForPoint(aPresContext, first, nsRect(0,0,mRect.width, mRect.height), aPoint, aFrame); + else + rv = NS_ERROR_FAILURE; + + if (!NS_SUCCEEDED(rv)) { + const nsStyleColor* color = + (const nsStyleColor*)mStyleContext->GetStyleData(eStyleStruct_Color); + + PRBool transparentBG = NS_STYLE_BG_COLOR_TRANSPARENT == + (color->mBackgroundFlags & NS_STYLE_BG_COLOR_TRANSPARENT); + + PRBool backgroundImage = (color->mBackgroundImage.Length() > 0); + + if (!transparentBG || backgroundImage) + { + *aFrame = this; + rv = NS_OK; + } + } + + #ifdef NS_DEBUG + printf("\n------------"); + + if (*aFrame) + nsFrame::ListTag(stdout, *aFrame); + printf("--------------\n"); + #endif + + return rv; + +} + + +nsresult +nsStackFrame::GetStackedFrameForPoint(nsIPresContext* aPresContext, + nsIFrame* aChild, + const nsRect& aRect, + const nsPoint& aPoint, + nsIFrame** aFrame) +{ + // look at all the children is reverse order. Use the stack to do + // this. + nsIFrame* next; + aChild->GetNextSibling(&next); + if (next != nsnull) { + nsresult rv = GetStackedFrameForPoint(aPresContext, next, aRect, aPoint, aFrame); + if (NS_SUCCEEDED(rv) && *aFrame) + return rv; + } + + nsRect childRect; + aChild->GetRect(childRect); + + if (childRect.Contains(aPoint)) { + nsPoint tmp; + tmp.MoveTo(aPoint.x - childRect.x, aPoint.y - childRect.y); + + return aChild->GetFrameForPoint(aPresContext, tmp, aFrame); + } + + return NS_ERROR_FAILURE; +} + +void +nsStackFrame::PaintChildren(nsIPresContext* aPresContext, + nsIRenderingContext& aRenderingContext, + const nsRect& aDirtyRect, + nsFramePaintLayer aWhichLayer) +{ + // we need to make sure we paint background then foreground of each child because they + // are stacked. Otherwise the foreground of the first child could be on the top of the + // background of the second. + if (aWhichLayer == NS_FRAME_PAINT_LAYER_BACKGROUND) + { + nsBoxFrame::PaintChildren(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer); + } +} + +// Paint one child frame +void +nsStackFrame::PaintChild(nsIPresContext* aPresContext, + nsIRenderingContext& aRenderingContext, + const nsRect& aDirtyRect, + nsIFrame* aFrame, + nsFramePaintLayer aWhichLayer) +{ + // we need to make sure we paint background then foreground of each child because they + // are stacked. Otherwise the foreground of the first child could be on the top of the + // background of the second. + if (aWhichLayer == NS_FRAME_PAINT_LAYER_BACKGROUND) + { + nsBoxFrame::PaintChild(aPresContext, aRenderingContext, aDirtyRect, aFrame, NS_FRAME_PAINT_LAYER_BACKGROUND); + nsBoxFrame::PaintChild(aPresContext, aRenderingContext, aDirtyRect, aFrame, NS_FRAME_PAINT_LAYER_FOREGROUND); + } +} + diff --git a/layout/xul/base/src/nsStackFrame.h b/layout/xul/base/src/nsStackFrame.h new file mode 100644 index 000000000000..68179d72fc33 --- /dev/null +++ b/layout/xul/base/src/nsStackFrame.h @@ -0,0 +1,94 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Communicator client code. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + */ + +/** + + Eric D Vaughan + A frame that can have multiple children. Only one child may be displayed at one time. So the + can be flipped though like a deck of cards. + +**/ + +#ifndef nsStackFrame_h___ +#define nsStackFrame_h___ + +#include "nsBoxFrame.h" + +class nsStackFrame : public nsBoxFrame +{ +public: + + friend nsresult NS_NewStackFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame); + + + + NS_IMETHOD Init(nsIPresContext* aPresContext, + nsIContent* aContent, + nsIFrame* aParent, + nsIStyleContext* aContext, + nsIFrame* asPrevInFlow); + + NS_IMETHOD GetFrameForPoint(nsIPresContext* aPresContext, + const nsPoint& aPoint, + nsIFrame** aFrame); + + NS_IMETHOD GetFrameName(nsString& aResult) const + { + aResult = "Stack"; + return NS_OK; + } + + + + +protected: + + nsStackFrame(nsIPresShell* aShell); + + // Paint one child frame + virtual void PaintChild(nsIPresContext* aPresContext, + nsIRenderingContext& aRenderingContext, + const nsRect& aDirtyRect, + nsIFrame* aFrame, + nsFramePaintLayer aWhichLayer); + + virtual void PaintChildren(nsIPresContext* aPresContext, + nsIRenderingContext& aRenderingContext, + const nsRect& aDirtyRect, + nsFramePaintLayer aWhichLayer); + virtual void ComputeChildsNextPosition( nsCalculatedBoxInfo* aInfo, nscoord& aCurX, nscoord& aCurY, nscoord& aNextX, nscoord& aNextY, const nsSize& aCurrentChildSize, const nsRect& aBoxRect, nscoord aMaxAscent); + virtual void ChildResized(nsIFrame* aFrame, nsHTMLReflowMetrics& aDesiredSize, nsRect& aRect, nscoord& aMaxAscent, nsCalculatedBoxInfo& aInfo, PRBool*& aResized, PRInt32 aInfoCount, nscoord& aChangedIndex, PRBool& aFinished, nscoord aIndex, nsString& aReason); + virtual void LayoutChildrenInRect(nsRect& aSize, nscoord& aMaxAscent); + virtual void AddChildSize(nsBoxInfo& aInfo, nsBoxInfo& aChildInfo); + +private: + virtual nsresult GetStackedFrameForPoint(nsIPresContext* aPresContext, + nsIFrame* aChild, + const nsRect& aRect, + const nsPoint& aPoint, + nsIFrame** aFrame); +}; // class nsStackFrame + + + +#endif + diff --git a/layout/xul/base/src/nsTitleFrame.cpp b/layout/xul/base/src/nsTitleFrame.cpp index bb658b667029..41b658dfa5c5 100644 --- a/layout/xul/base/src/nsTitleFrame.cpp +++ b/layout/xul/base/src/nsTitleFrame.cpp @@ -50,7 +50,7 @@ NS_NewTitleFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame) if (nsnull == aNewFrame) { return NS_ERROR_NULL_POINTER; } - nsTitleFrame* it = new (aPresShell) nsTitleFrame; + nsTitleFrame* it = new (aPresShell) nsTitleFrame(aPresShell); if (!it) { return NS_ERROR_OUT_OF_MEMORY; } @@ -58,7 +58,7 @@ NS_NewTitleFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame) return NS_OK; } -nsTitleFrame::nsTitleFrame() +nsTitleFrame::nsTitleFrame(nsIPresShell* aPresShell):nsBoxFrame(aPresShell) { } diff --git a/layout/xul/base/src/nsTitleFrame.h b/layout/xul/base/src/nsTitleFrame.h index b89abf9fea23..d0a617c39727 100644 --- a/layout/xul/base/src/nsTitleFrame.h +++ b/layout/xul/base/src/nsTitleFrame.h @@ -31,7 +31,7 @@ class nsTitleFrame : public nsBoxFrame { public: - nsTitleFrame(); + nsTitleFrame(nsIPresShell* aShell); virtual ~nsTitleFrame(); NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr); diff --git a/layout/xul/base/src/nsTitledBoxFrame.cpp b/layout/xul/base/src/nsTitledBoxFrame.cpp index ace27e48e527..b19d6011557c 100644 --- a/layout/xul/base/src/nsTitledBoxFrame.cpp +++ b/layout/xul/base/src/nsTitledBoxFrame.cpp @@ -53,7 +53,7 @@ class nsTitledBoxFrame : public nsBoxFrame { public: - nsTitledBoxFrame(); + nsTitledBoxFrame(nsIPresShell* aShell); NS_IMETHOD SetInitialChildList(nsIPresContext* aPresContext, nsIAtom* aListName, @@ -96,7 +96,7 @@ public: class nsTitledBoxInnerFrame : public nsBoxFrame { public: - nsTitledBoxInnerFrame() {} + nsTitledBoxInnerFrame(nsIPresShell* aShell):nsBoxFrame(aShell) {} #ifdef DEBUG @@ -117,7 +117,7 @@ NS_NewTitledBoxInnerFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame) if (nsnull == aNewFrame) { return NS_ERROR_NULL_POINTER; } - nsTitledBoxInnerFrame* it = new (aPresShell) nsTitledBoxInnerFrame; + nsTitledBoxInnerFrame* it = new (aPresShell) nsTitledBoxInnerFrame(aPresShell); if (!it) { return NS_ERROR_OUT_OF_MEMORY; } @@ -133,7 +133,7 @@ NS_NewTitledBoxFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame) if (nsnull == aNewFrame) { return NS_ERROR_NULL_POINTER; } - nsTitledBoxFrame* it = new (aPresShell) nsTitledBoxFrame; + nsTitledBoxFrame* it = new (aPresShell) nsTitledBoxFrame(aPresShell); if (!it) { return NS_ERROR_OUT_OF_MEMORY; } @@ -142,7 +142,7 @@ NS_NewTitledBoxFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame) return NS_OK; } -nsTitledBoxFrame::nsTitledBoxFrame() +nsTitledBoxFrame::nsTitledBoxFrame(nsIPresShell* aShell):nsBoxFrame(aShell) { } diff --git a/layout/xul/base/src/nsTitledButtonFrame.cpp b/layout/xul/base/src/nsTitledButtonFrame.cpp index dbb006cf918f..3ba61441bc02 100644 --- a/layout/xul/base/src/nsTitledButtonFrame.cpp +++ b/layout/xul/base/src/nsTitledButtonFrame.cpp @@ -233,7 +233,7 @@ nsTitledButtonFrame::Destroy(nsIPresContext* aPresContext) // Release image loader first so that it's refcnt can go to zero mImageLoader.StopAllLoadImages(aPresContext); - return nsLeafFrame::Destroy(aPresContext); + return nsXULLeafFrame::Destroy(aPresContext); } @@ -244,7 +244,7 @@ nsTitledButtonFrame::Init(nsIPresContext* aPresContext, nsIStyleContext* aContext, nsIFrame* aPrevInFlow) { - nsresult rv = nsLeafFrame::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow); + nsresult rv = nsXULLeafFrame::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow); mRenderer->SetNameSpace(kNameSpaceID_None); mRenderer->SetFrame(this,aPresContext); @@ -822,7 +822,7 @@ nsTitledButtonFrame::PaintTitle(nsIPresContext* aPresContext, const nsRect& aDirtyRect, nsFramePaintLayer aWhichLayer) { - if (eFramePaintLayer_Content == aWhichLayer) { + if (NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer) { if (mTitle.Length() == 0) return NS_OK; @@ -915,7 +915,7 @@ nsTitledButtonFrame::PaintImage(nsIPresContext* aPresContext, if (!mHasImage || !aDirtyRect.Intersects(mImageRect)) return NS_OK; - if (eFramePaintLayer_Content != aWhichLayer) + if (NS_FRAME_PAINT_LAYER_FOREGROUND != aWhichLayer) return NS_OK; nsCOMPtr image ( dont_AddRef(mImageLoader.GetImage()) ); @@ -945,68 +945,14 @@ nsTitledButtonFrame::Reflow(nsIPresContext* aPresContext, const nsHTMLReflowState& aReflowState, nsReflowStatus& aStatus) { - // redraw us if we are flowed incremental and we are targeted or we are dirty. - mNeedsAccessUpdate = PR_TRUE; - if (eReflowReason_Incremental == aReflowState.reason) { - nsIFrame* targetFrame; - - // See if it's targeted at us - aReflowState.reflowCommand->GetTarget(targetFrame); - if (this == targetFrame) { - Invalidate(aPresContext, nsRect(0,0,mRect.width,mRect.height), PR_FALSE); - } - } else if (eReflowReason_Dirty == aReflowState.reason) { - Invalidate(aPresContext, nsRect(0,0,mRect.width,mRect.height), PR_FALSE); - } - mNeedsLayout = PR_TRUE; - nsresult result = nsLeafFrame::Reflow(aPresContext, aMetrics, aReflowState, aStatus); - if (aReflowState.mComputedWidth != NS_INTRINSICSIZE) - NS_ASSERTION(aMetrics.width == aReflowState.mComputedWidth + aReflowState.mComputedBorderPadding.left + aReflowState.mComputedBorderPadding.right, - "TitledButtons width is wrong!!!"); - - if (aReflowState.mComputedHeight != NS_INTRINSICSIZE) - NS_ASSERTION(aMetrics.height == aReflowState.mComputedHeight + aReflowState.mComputedBorderPadding.top + aReflowState.mComputedBorderPadding.bottom, - "TitledButtons height is wrong!!!"); + nsresult result = nsXULLeafFrame::Reflow(aPresContext, aMetrics, aReflowState, aStatus); return result; } -void -nsTitledButtonFrame::GetDesiredSize(nsIPresContext* aPresContext, - const nsHTMLReflowState& aReflowState, - nsHTMLReflowMetrics& aDesiredSize) -{ - // get our info object. - nsBoxInfo info; - info.Clear(); - - GetBoxInfo(aPresContext, aReflowState, info); - - // size is our preferred unless calculated. - aDesiredSize.width = info.prefSize.width; - aDesiredSize.height = info.prefSize.height; - - // if either the width or the height was not computed use our intrinsic size - if (aReflowState.mComputedWidth != NS_INTRINSICSIZE) - aDesiredSize.width = aReflowState.mComputedWidth; - - if (aReflowState.mComputedHeight != NS_INTRINSICSIZE) { - aDesiredSize.height = aReflowState.mComputedHeight; - nscoord descent = info.prefSize.height - info.ascent; - aDesiredSize.ascent = aDesiredSize.height - descent; - if (aDesiredSize.ascent < 0) - aDesiredSize.ascent = 0; - } else { - aDesiredSize.ascent = info.ascent; - } - - -} - - struct nsTitleRecessedBorder : public nsStyleSpacing { nsTitleRecessedBorder(nscoord aBorderWidth) : nsStyleSpacing() @@ -1258,7 +1204,7 @@ nsTitledButtonFrame::HandleEvent(nsIPresContext* aPresContext, break; } - return nsLeafFrame::HandleEvent(aPresContext, aEvent, aEventStatus); + return nsXULLeafFrame::HandleEvent(aPresContext, aEvent, aEventStatus); } // @@ -1437,12 +1383,6 @@ nsTitledButtonFrame::GetImageSize(nsIPresContext* aPresContext) } -NS_IMETHODIMP -nsTitledButtonFrame::InvalidateCache(nsIFrame* aChild) -{ - // we don't cache any information - return NS_OK; -} /** * Ok return our dimensions @@ -1526,43 +1466,6 @@ nsTitledButtonFrame::GetBoxInfo(nsIPresContext* aPresContext, const nsHTMLReflow return NS_OK; } -/** - * We can be a nsIBox - */ -NS_IMETHODIMP -nsTitledButtonFrame::QueryInterface(REFNSIID aIID, void** aInstancePtr) -{ - if (NULL == aInstancePtr) { - return NS_ERROR_NULL_POINTER; - } - - *aInstancePtr = NULL; - - if (aIID.Equals(NS_GET_IID(nsIBox))) { - *aInstancePtr = (void*)(nsIBox*) this; - NS_ADDREF_THIS(); - return NS_OK; - } - - return nsLeafFrame::QueryInterface(aIID, aInstancePtr); -} - -/* - * We are a frame and we do not maintain a ref count - */ -NS_IMETHODIMP_(nsrefcnt) -nsTitledButtonFrame::AddRef(void) -{ - return NS_OK; -} - -NS_IMETHODIMP_(nsrefcnt) -nsTitledButtonFrame::Release(void) -{ - return NS_OK; -} - - NS_IMETHODIMP nsTitledButtonFrame::GetFrameName(nsString& aResult) const { @@ -1571,15 +1474,3 @@ nsTitledButtonFrame::GetFrameName(nsString& aResult) const aResult += "]"; return NS_OK; } - -NS_IMETHODIMP -nsTitledButtonFrame::ContentChanged(nsIPresContext* aPresContext, - nsIContent* aChild, - nsISupports* aSubContent) -{ - nsCOMPtr shell; - aPresContext->GetShell(getter_AddRefs(shell)); - mState |= NS_FRAME_IS_DIRTY; - return mParent->ReflowDirtyChild(shell, this); - -} diff --git a/layout/xul/base/src/nsTitledButtonFrame.h b/layout/xul/base/src/nsTitledButtonFrame.h index 99c412eb4939..d2952db7bdd3 100644 --- a/layout/xul/base/src/nsTitledButtonFrame.h +++ b/layout/xul/base/src/nsTitledButtonFrame.h @@ -23,13 +23,12 @@ #define nsTitledButtonFrame_h___ #include "nsHTMLImageLoader.h" -#include "nsLeafFrame.h" -#include "nsIBox.h" +#include "nsXULLeafFrame.h" class nsIPopUpMenu; class nsTitledButtonRenderer; -class nsTitledButtonFrame : public nsLeafFrame, public nsIBox +class nsTitledButtonFrame : public nsXULLeafFrame { public: @@ -39,9 +38,8 @@ public: // nsIBox frame interface NS_IMETHOD GetBoxInfo(nsIPresContext* aPresContext, const nsHTMLReflowState& aReflowState, nsBoxInfo& aSize); - NS_IMETHOD InvalidateCache(nsIFrame* aChild); - NS_DECL_ISUPPORTS + NS_IMETHOD SetDebug(nsIPresContext* aPresContext, PRBool aDebug) { return NS_OK; } NS_IMETHOD Init(nsIPresContext* aPresContext, nsIContent* aContent, @@ -111,10 +109,6 @@ protected: const nsRect& aDirtyRect, nsFramePaintLayer aWhichLayer); - virtual void GetDesiredSize(nsIPresContext* aPresContext, - const nsHTMLReflowState& aReflowState, - nsHTMLReflowMetrics& aDesiredSize); - void DisplayAltFeedback(nsIPresContext* aPresContext, nsIRenderingContext& aRenderingContext, @@ -148,11 +142,6 @@ protected: virtual void GetImageSize(nsIPresContext* aPresContext); - NS_IMETHOD ContentChanged(nsIPresContext* aPresContext, - nsIContent* aChild, - nsISupports* aSubContent); - - private: // tri state methods diff --git a/layout/xul/base/src/nsToolbarFrame.cpp b/layout/xul/base/src/nsToolbarFrame.cpp index dd5f8879ae10..44e003bbb064 100644 --- a/layout/xul/base/src/nsToolbarFrame.cpp +++ b/layout/xul/base/src/nsToolbarFrame.cpp @@ -140,7 +140,7 @@ NS_NewToolbarFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame ) if (nsnull == aNewFrame) { return NS_ERROR_NULL_POINTER; } - nsToolbarFrame* it = new (aPresShell) nsToolbarFrame; + nsToolbarFrame* it = new (aPresShell) nsToolbarFrame (aPresShell); if (nsnull == it) return NS_ERROR_OUT_OF_MEMORY; @@ -156,8 +156,8 @@ NS_NewToolbarFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame ) // // Most of the work need to be delayed until Init(). Lame! // -nsToolbarFrame :: nsToolbarFrame ( ) - : mXDropLoc ( -1 ) +nsToolbarFrame :: nsToolbarFrame (nsIPresShell* aShell):nsBoxFrame(aShell), + mXDropLoc ( -1 ) { } diff --git a/layout/xul/base/src/nsToolbarFrame.h b/layout/xul/base/src/nsToolbarFrame.h index 9a91b4e1530b..7067534f4098 100644 --- a/layout/xul/base/src/nsToolbarFrame.h +++ b/layout/xul/base/src/nsToolbarFrame.h @@ -108,7 +108,7 @@ public: protected: - nsToolbarFrame(); + nsToolbarFrame(nsIPresShell* aShell); virtual ~nsToolbarFrame(); // pass-by-value not allowed for a coordinator because it corresponds 1-to-1 diff --git a/layout/xul/base/src/nsToolbarItemFrame.cpp b/layout/xul/base/src/nsToolbarItemFrame.cpp index 564d9072cca9..82f84e48535b 100644 --- a/layout/xul/base/src/nsToolbarItemFrame.cpp +++ b/layout/xul/base/src/nsToolbarItemFrame.cpp @@ -44,7 +44,7 @@ NS_NewToolbarItemFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame ) if ( !aNewFrame ) return NS_ERROR_NULL_POINTER; - nsToolbarItemFrame* it = new (aPresShell) nsToolbarItemFrame; + nsToolbarItemFrame* it = new (aPresShell) nsToolbarItemFrame(aPresShell); if ( !it ) return NS_ERROR_OUT_OF_MEMORY; @@ -57,7 +57,7 @@ NS_NewToolbarItemFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame ) // // nsToolbarItemFrame ctor and dtor // -nsToolbarItemFrame::nsToolbarItemFrame() +nsToolbarItemFrame::nsToolbarItemFrame(nsIPresShell* aPresShell):nsBoxFrame(aPresShell) { } diff --git a/layout/xul/base/src/nsToolbarItemFrame.h b/layout/xul/base/src/nsToolbarItemFrame.h index cd219d5c50e7..1a906fae9038 100644 --- a/layout/xul/base/src/nsToolbarItemFrame.h +++ b/layout/xul/base/src/nsToolbarItemFrame.h @@ -35,7 +35,7 @@ class nsToolbarItemFrame : public nsBoxFrame { public: - nsToolbarItemFrame(); + nsToolbarItemFrame(nsIPresShell* aShell); ~nsToolbarItemFrame(); friend nsresult NS_NewToolbarItemFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame); diff --git a/layout/xul/base/src/nsToolboxFrame.cpp b/layout/xul/base/src/nsToolboxFrame.cpp index 5e6a36a57326..7c433bf1286f 100644 --- a/layout/xul/base/src/nsToolboxFrame.cpp +++ b/layout/xul/base/src/nsToolboxFrame.cpp @@ -82,7 +82,7 @@ NS_NewToolboxFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame ) if (nsnull == aNewFrame) { return NS_ERROR_NULL_POINTER; } - nsToolboxFrame* it = new (aPresShell) nsToolboxFrame; + nsToolboxFrame* it = new (aPresShell) nsToolboxFrame (aPresShell); if (nsnull == it) return NS_ERROR_OUT_OF_MEMORY; @@ -98,8 +98,8 @@ NS_NewToolboxFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame ) // // Init, if necessary // -nsToolboxFrame :: nsToolboxFrame ( ) - : mSumOfToolbarHeights(0), mNumToolbars(0), +nsToolboxFrame :: nsToolboxFrame (nsIPresShell* aShell):nsBoxFrame(aShell) + , mSumOfToolbarHeights(0), mNumToolbars(0), mGrippyHilighted(kNoGrippyHilighted), kCollapsedAtom(dont_AddRef( NS_NewAtom("collapsed"))), kHiddenAtom(dont_AddRef( NS_NewAtom("hidden"))), @@ -571,7 +571,8 @@ nsToolboxFrame :: ClearGrippyList ( nsVoidArray & inList ) void nsToolboxFrame::GetInset(nsMargin& margin) { - margin = mInset; + nsBoxFrame::GetInset(margin); + margin += mInset; } diff --git a/layout/xul/base/src/nsToolboxFrame.h b/layout/xul/base/src/nsToolboxFrame.h index ab32191ba6e2..9e06cf661826 100644 --- a/layout/xul/base/src/nsToolboxFrame.h +++ b/layout/xul/base/src/nsToolboxFrame.h @@ -125,7 +125,7 @@ protected: PRBool mCollapsed; }; - nsToolboxFrame(); + nsToolboxFrame(nsIPresShell* aShell); virtual ~nsToolboxFrame(); virtual PRBool GetInitialOrientation(PRBool& aIsHorizontal); diff --git a/layout/xul/base/src/nsTreeOuterFrame.h b/layout/xul/base/src/nsTreeOuterFrame.h index 048bd7da826e..ddcaa23fe4f4 100644 --- a/layout/xul/base/src/nsTreeOuterFrame.h +++ b/layout/xul/base/src/nsTreeOuterFrame.h @@ -21,7 +21,6 @@ */ #include "nsTableOuterFrame.h" -#include "nsIBox.h" #include "nsISelfScrollingFrame.h" #include "nsITreeFrame.h" diff --git a/layout/xul/base/src/nsXULLeafFrame.cpp b/layout/xul/base/src/nsXULLeafFrame.cpp new file mode 100644 index 000000000000..7cc5157f23f3 --- /dev/null +++ b/layout/xul/base/src/nsXULLeafFrame.cpp @@ -0,0 +1,211 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Communicator client code. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + */ + +// +// Eric Vaughan +// Netscape Communications +// +// See documentation in associated header file +// + +#include "nsXULLeafFrame.h" +#include "nsCOMPtr.h" +#include "nsIDeviceContext.h" +#include "nsIFontMetrics.h" +#include "nsHTMLAtoms.h" +#include "nsXULAtoms.h" +#include "nsIPresContext.h" +#include "nsIRenderingContext.h" +#include "nsIStyleContext.h" +#include "nsIContent.h" +#include "nsINameSpaceManager.h" + +// +// NS_NewToolbarFrame +// +// Creates a new Toolbar frame and returns it in |aNewFrame| +// +nsresult +NS_NewXULLeafFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame ) +{ + NS_PRECONDITION(aNewFrame, "null OUT ptr"); + if (nsnull == aNewFrame) { + return NS_ERROR_NULL_POINTER; + } + nsXULLeafFrame* it = new (aPresShell) nsXULLeafFrame; + if (nsnull == it) + return NS_ERROR_OUT_OF_MEMORY; + + // it->SetFlags(aFlags); + *aNewFrame = it; + return NS_OK; + +} // NS_NewTextFrame + + + +NS_IMETHODIMP +nsXULLeafFrame::Reflow(nsIPresContext* aPresContext, + nsHTMLReflowMetrics& aMetrics, + const nsHTMLReflowState& aReflowState, + nsReflowStatus& aStatus) +{ + + if (eReflowReason_Incremental == aReflowState.reason) { + nsIFrame* targetFrame; + + // See if it's targeted at us + aReflowState.reflowCommand->GetTarget(targetFrame); + if (this == targetFrame) { + Invalidate(aPresContext, nsRect(0,0,mRect.width,mRect.height), PR_FALSE); + } + } else if (eReflowReason_Dirty == aReflowState.reason) { + Invalidate(aPresContext, nsRect(0,0,mRect.width,mRect.height), PR_FALSE); + } + + + nsresult result = nsLeafFrame::Reflow(aPresContext, aMetrics, aReflowState, aStatus); + + if (aReflowState.mComputedWidth != NS_INTRINSICSIZE) + NS_ASSERTION(aMetrics.width == aReflowState.mComputedWidth + aReflowState.mComputedBorderPadding.left + aReflowState.mComputedBorderPadding.right, + "Text width is wrong!!!"); + + if (aReflowState.mComputedHeight != NS_INTRINSICSIZE) + NS_ASSERTION(aMetrics.height == aReflowState.mComputedHeight + aReflowState.mComputedBorderPadding.top + aReflowState.mComputedBorderPadding.bottom, + "Text height is wrong!!!"); + + return result; +} + +void +nsXULLeafFrame::GetDesiredSize(nsIPresContext* aPresContext, + const nsHTMLReflowState& aReflowState, + nsHTMLReflowMetrics& aDesiredSize) +{ + // get our info object. + nsBoxInfo info; + info.Clear(); + + GetBoxInfo(aPresContext, aReflowState, info); + + // size is our preferred unless calculated. + aDesiredSize.width = info.prefSize.width; + aDesiredSize.height = info.prefSize.height; + + // if either the width or the height was not computed use our intrinsic size + if (aReflowState.mComputedWidth != NS_INTRINSICSIZE) + aDesiredSize.width = aReflowState.mComputedWidth; + + if (aReflowState.mComputedHeight != NS_INTRINSICSIZE) { + aDesiredSize.height = aReflowState.mComputedHeight; + nscoord descent = info.prefSize.height - info.ascent; + aDesiredSize.ascent = aDesiredSize.height - descent; + if (aDesiredSize.ascent < 0) + aDesiredSize.ascent = 0; + } else { + aDesiredSize.ascent = info.ascent; + } + + +} + + + +NS_IMETHODIMP +nsXULLeafFrame::InvalidateCache(nsIFrame* aChild) +{ + // we don't cache any information + return NS_OK; +} + +/** + * Ok return our dimensions + */ +NS_IMETHODIMP +nsXULLeafFrame::GetBoxInfo(nsIPresContext* aPresContext, const nsHTMLReflowState& aReflowState, nsBoxInfo& aSize) +{ + aSize.prefSize.width = 0; + aSize.prefSize.height = 0; + aSize.minSize.width = 0; + aSize.minSize.height = 0; + aSize.maxSize.width = NS_INTRINSICSIZE; + aSize.maxSize.height = NS_INTRINSICSIZE; + aSize.ascent = 0; + return NS_OK; +} + +/** + * We can be a nsIBox + */ +NS_IMETHODIMP +nsXULLeafFrame::QueryInterface(REFNSIID aIID, void** aInstancePtr) +{ + if (NULL == aInstancePtr) { + return NS_ERROR_NULL_POINTER; + } + + *aInstancePtr = NULL; + + if (aIID.Equals(NS_GET_IID(nsIBox))) { + *aInstancePtr = (void*)(nsIBox*) this; + NS_ADDREF_THIS(); + return NS_OK; + } + + return nsLeafFrame::QueryInterface(aIID, aInstancePtr); +} + +/* + * We are a frame and we do not maintain a ref count + */ +NS_IMETHODIMP_(nsrefcnt) +nsXULLeafFrame::AddRef(void) +{ + return NS_OK; +} + +NS_IMETHODIMP_(nsrefcnt) +nsXULLeafFrame::Release(void) +{ + return NS_OK; +} + + +NS_IMETHODIMP +nsXULLeafFrame::GetFrameName(nsString& aResult) const +{ + aResult = "Leaf"; + return NS_OK; +} + +NS_IMETHODIMP +nsXULLeafFrame::ContentChanged(nsIPresContext* aPresContext, + nsIContent* aChild, + nsISupports* aSubContent) +{ + nsCOMPtr shell; + aPresContext->GetShell(getter_AddRefs(shell)); + mState |= NS_FRAME_IS_DIRTY; + return mParent->ReflowDirtyChild(shell, this); + +} + diff --git a/layout/xul/base/src/nsXULLeafFrame.h b/layout/xul/base/src/nsXULLeafFrame.h new file mode 100644 index 000000000000..f919e9c35004 --- /dev/null +++ b/layout/xul/base/src/nsXULLeafFrame.h @@ -0,0 +1,70 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Communicator client code. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + */ +#ifndef nsXULLeafFrame_h___ +#define nsXULLeafFrame_h___ + +#include "nsLeafFrame.h" +#include "nsIBox.h" + +class nsAccessKeyInfo; + +class nsXULLeafFrame : public nsLeafFrame, public nsIBox +{ +public: + + friend nsresult NS_NewXULLeafFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame); + + // nsIBox frame interface + NS_IMETHOD GetBoxInfo(nsIPresContext* aPresContext, const nsHTMLReflowState& aReflowState, nsBoxInfo& aSize); + NS_IMETHOD InvalidateCache(nsIFrame* aChild); + NS_IMETHOD SetDebug(nsIPresContext* aPresContext, PRBool aDebug) { return NS_OK; } + + NS_DECL_ISUPPORTS + + + NS_IMETHOD GetFrameName(nsString& aResult) const; + + // nsIHTMLReflow overrides + NS_IMETHOD Reflow(nsIPresContext* aPresContext, + nsHTMLReflowMetrics& aDesiredSize, + const nsHTMLReflowState& aReflowState, + nsReflowStatus& aStatus); + + NS_IMETHOD ContentChanged(nsIPresContext* aPresContext, + nsIContent* aChild, + nsISupports* aSubContent); + + +protected: + + virtual void GetDesiredSize(nsIPresContext* aPresContext, + const nsHTMLReflowState& aReflowState, + nsHTMLReflowMetrics& aDesiredSize); + + + nsXULLeafFrame() {} + +private: + +}; // class nsXULLeafFrame + +#endif /* nsXULLeafFrame_h___ */ diff --git a/layout/xul/base/src/nsXULTextFrame.cpp b/layout/xul/base/src/nsXULTextFrame.cpp index c4ac2f1d667e..6e6a2189e435 100644 --- a/layout/xul/base/src/nsXULTextFrame.cpp +++ b/layout/xul/base/src/nsXULTextFrame.cpp @@ -39,45 +39,6 @@ #include "nsIContent.h" #include "nsINameSpaceManager.h" -/* -#include "nsButtonFrameRenderer.h" -#include "nsHTMLAtoms.h" -#include "nsIStyleContext.h" -#include "nsStyleConsts.h" -#include "nsIPresContext.h" -#include "nsButtonFrameRenderer.h" - -#include "nsHTMLParts.h" -#include "nsString.h" -#include "nsLeafFrame.h" -#include "nsIPresShell.h" -#include "nsHTMLIIDs.h" -#include "nsIImage.h" -#include "nsIWidget.h" -#include "nsIHTMLAttributes.h" -#include "nsIDocument.h" -#include "nsIHTMLDocument.h" -#include "nsIStyleContext.h" -#include "nsStyleConsts.h" -#include "nsImageMap.h" -#include "nsILinkHandler.h" -#include "nsIURL.h" -#include "nsIView.h" -#include "nsIViewManager.h" -#include "nsHTMLContainerFrame.h" -#include "prprf.h" -#include "nsISizeOfHandler.h" -#include "nsIFontMetrics.h" -#include "nsCSSRendering.h" -#include "nsIDOMHTMLImageElement.h" -#include "nsIDeviceContext.h" -#include "nsTextFragment.h" -#include "nsIDOMHTMLMapElement.h" -#include "nsIStyleSet.h" - -#include "nsFormControlHelper.h" -*/ - #define ELIPSIS "..." #define CROP_LEFT "left" @@ -165,7 +126,7 @@ nsXULTextFrame::Init(nsIPresContext* aPresContext, nsIStyleContext* aContext, nsIFrame* aPrevInFlow) { - nsresult rv = nsLeafFrame::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow); + nsresult rv = nsXULLeafFrame::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow); PRBool a,b,c; UpdateAttributes(aPresContext, nsnull, a, b, c /* all */); @@ -271,7 +232,7 @@ nsXULTextFrame::Paint(nsIPresContext* aPresContext, if (!disp->mVisible) return NS_OK; - if (eFramePaintLayer_Content == aWhichLayer) { + if (NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer) { // remove the border and padding const nsStyleSpacing* spacing = (const nsStyleSpacing*)mStyleContext->GetStyleData(eStyleStruct_Spacing); @@ -603,75 +564,9 @@ nsXULTextFrame::Reflow(nsIPresContext* aPresContext, const nsHTMLReflowState& aReflowState, nsReflowStatus& aStatus) { - - if (eReflowReason_Incremental == aReflowState.reason) { - nsIFrame* targetFrame; - - // See if it's targeted at us - aReflowState.reflowCommand->GetTarget(targetFrame); - if (this == targetFrame) { - Invalidate(aPresContext, nsRect(0,0,mRect.width,mRect.height), PR_FALSE); - } - } else if (eReflowReason_Dirty == aReflowState.reason) { - Invalidate(aPresContext, nsRect(0,0,mRect.width,mRect.height), PR_FALSE); - } - - - mState |= NS_STATE_NEED_LAYOUT; - nsresult result = nsLeafFrame::Reflow(aPresContext, aMetrics, aReflowState, aStatus); - - if (aReflowState.mComputedWidth != NS_INTRINSICSIZE) - NS_ASSERTION(aMetrics.width == aReflowState.mComputedWidth + aReflowState.mComputedBorderPadding.left + aReflowState.mComputedBorderPadding.right, - "Text width is wrong!!!"); - - if (aReflowState.mComputedHeight != NS_INTRINSICSIZE) - NS_ASSERTION(aMetrics.height == aReflowState.mComputedHeight + aReflowState.mComputedBorderPadding.top + aReflowState.mComputedBorderPadding.bottom, - "Text height is wrong!!!"); - - return result; -} - -void -nsXULTextFrame::GetDesiredSize(nsIPresContext* aPresContext, - const nsHTMLReflowState& aReflowState, - nsHTMLReflowMetrics& aDesiredSize) -{ - // get our info object. - nsBoxInfo info; - info.Clear(); - - GetBoxInfo(aPresContext, aReflowState, info); - - // size is our preferred unless calculated. - aDesiredSize.width = info.prefSize.width; - aDesiredSize.height = info.prefSize.height; - - // if either the width or the height was not computed use our intrinsic size - if (aReflowState.mComputedWidth != NS_INTRINSICSIZE) - aDesiredSize.width = aReflowState.mComputedWidth; - - if (aReflowState.mComputedHeight != NS_INTRINSICSIZE) { - aDesiredSize.height = aReflowState.mComputedHeight; - nscoord descent = info.prefSize.height - info.ascent; - aDesiredSize.ascent = aDesiredSize.height - descent; - if (aDesiredSize.ascent < 0) - aDesiredSize.ascent = 0; - } else { - aDesiredSize.ascent = info.ascent; - } - - -} - - - -NS_IMETHODIMP -nsXULTextFrame::InvalidateCache(nsIFrame* aChild) -{ - // we don't cache any information - return NS_OK; + return nsXULLeafFrame::Reflow(aPresContext, aMetrics, aReflowState, aStatus); } /** @@ -697,43 +592,6 @@ nsXULTextFrame::GetBoxInfo(nsIPresContext* aPresContext, const nsHTMLReflowState return NS_OK; } -/** - * We can be a nsIBox - */ -NS_IMETHODIMP -nsXULTextFrame::QueryInterface(REFNSIID aIID, void** aInstancePtr) -{ - if (NULL == aInstancePtr) { - return NS_ERROR_NULL_POINTER; - } - - *aInstancePtr = NULL; - - if (aIID.Equals(NS_GET_IID(nsIBox))) { - *aInstancePtr = (void*)(nsIBox*) this; - NS_ADDREF_THIS(); - return NS_OK; - } - - return nsLeafFrame::QueryInterface(aIID, aInstancePtr); -} - -/* - * We are a frame and we do not maintain a ref count - */ -NS_IMETHODIMP_(nsrefcnt) -nsXULTextFrame::AddRef(void) -{ - return NS_OK; -} - -NS_IMETHODIMP_(nsrefcnt) -nsXULTextFrame::Release(void) -{ - return NS_OK; -} - - NS_IMETHODIMP nsXULTextFrame::GetFrameName(nsString& aResult) const { diff --git a/layout/xul/base/src/nsXULTextFrame.h b/layout/xul/base/src/nsXULTextFrame.h index 63e3ab1a5fd1..1aa91ebfe3d7 100644 --- a/layout/xul/base/src/nsXULTextFrame.h +++ b/layout/xul/base/src/nsXULTextFrame.h @@ -22,12 +22,11 @@ #ifndef nsXULTextFrame_h___ #define nsXULTextFrame_h___ -#include "nsLeafFrame.h" -#include "nsIBox.h" +#include "nsXULLeafFrame.h" class nsAccessKeyInfo; -class nsXULTextFrame : public nsLeafFrame, public nsIBox +class nsXULTextFrame : public nsXULLeafFrame { public: @@ -37,9 +36,6 @@ public: // nsIBox frame interface NS_IMETHOD GetBoxInfo(nsIPresContext* aPresContext, const nsHTMLReflowState& aReflowState, nsBoxInfo& aSize); - NS_IMETHOD InvalidateCache(nsIFrame* aChild); - - NS_DECL_ISUPPORTS NS_IMETHOD Init(nsIPresContext* aPresContext, nsIContent* aContent, @@ -86,10 +82,6 @@ protected: nsFramePaintLayer aWhichLayer, const nsRect& aTextRect); - virtual void GetDesiredSize(nsIPresContext* aPresContext, - const nsHTMLReflowState& aReflowState, - nsHTMLReflowMetrics& aDesiredSize); - nsXULTextFrame(); @@ -105,4 +97,4 @@ private: nsAccessKeyInfo* mAccessKeyInfo; }; // class nsXULTextFrame -#endif /* nsTitledButtonFrame_h___ */ +#endif /* nsXULTextFrame_h___ */ diff --git a/layout/xul/content/src/nsXULAtomList.h b/layout/xul/content/src/nsXULAtomList.h index 66904c922085..594ad394e4a4 100644 --- a/layout/xul/content/src/nsXULAtomList.h +++ b/layout/xul/content/src/nsXULAtomList.h @@ -104,6 +104,7 @@ XUL_ATOM(titledbox, "titledbox") XUL_ATOM(title, "title") XUL_ATOM(titledboxContentPseudo, ":titledbox-content") +XUL_ATOM(stack, "stack") XUL_ATOM(deck, "deck") XUL_ATOM(tabcontrol, "tabcontrol") XUL_ATOM(tab, "tab") @@ -124,6 +125,7 @@ XUL_ATOM(collapse, "collapse") XUL_ATOM(resizebefore, "resizebefore") XUL_ATOM(resizeafter, "resizeafter") XUL_ATOM(state, "state") +XUL_ATOM(debug, "debug") // toolbar & toolbar d&d atoms XUL_ATOM(ddDropLocation, "dd-droplocation") diff --git a/xpfe/browser/resources/content/navigator.xul b/xpfe/browser/resources/content/navigator.xul index 0885d862390b..c2707ca151a2 100644 --- a/xpfe/browser/resources/content/navigator.xul +++ b/xpfe/browser/resources/content/navigator.xul @@ -28,7 +28,7 @@ Contributor(s): ______________________________________. --> -