Bug 54488 - "[Mac] Non-draggable widgets in background windows should look disabled...
[mozilla-central.git] / layout / generic / nsFrameSetFrame.cpp
blob459c236b2a8025aac20e0b479565997142b85e03
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
3 * ***** BEGIN LICENSE BLOCK *****
4 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6 * The contents of this file are subject to the Mozilla Public License Version
7 * 1.1 (the "License"); you may not use this file except in compliance with
8 * the License. You may obtain a copy of the License at
9 * http://www.mozilla.org/MPL/
11 * Software distributed under the License is distributed on an "AS IS" basis,
12 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 * for the specific language governing rights and limitations under the
14 * License.
16 * The Original Code is mozilla.org code.
18 * The Initial Developer of the Original Code is
19 * Netscape Communications Corporation.
20 * Portions created by the Initial Developer are Copyright (C) 1998
21 * the Initial Developer. All Rights Reserved.
23 * Contributor(s):
25 * Alternatively, the contents of this file may be used under the terms of
26 * either of the GNU General Public License Version 2 or later (the "GPL"),
27 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 * in which case the provisions of the GPL or the LGPL are applicable instead
29 * of those above. If you wish to allow use of your version of this file only
30 * under the terms of either the GPL or the LGPL, and not to allow others to
31 * use your version of this file under the terms of the MPL, indicate your
32 * decision by deleting the provisions above and replace them with the notice
33 * and other provisions required by the GPL or the LGPL. If you do not delete
34 * the provisions above, a recipient may use your version of this file under
35 * the terms of any one of the MPL, the GPL or the LGPL.
37 * ***** END LICENSE BLOCK ***** */
39 /* rendering object for HTML <frameset> elements */
41 #include "nsCOMPtr.h"
42 #include "nsFrameSetFrame.h"
43 #include "nsContentUtils.h"
44 #include "nsGenericHTMLElement.h"
45 #include "nsLeafFrame.h"
46 #include "nsHTMLContainerFrame.h"
47 #include "nsPresContext.h"
48 #include "nsIPresShell.h"
49 #include "nsIComponentManager.h"
50 #include "nsIStreamListener.h"
51 #include "nsIURL.h"
52 #include "nsIDocument.h"
53 #include "nsINodeInfo.h"
54 #include "nsIView.h"
55 #include "nsIViewManager.h"
56 #include "nsWidgetsCID.h"
57 #include "nsGkAtoms.h"
58 #include "nsIScrollableView.h"
59 #include "nsStyleCoord.h"
60 #include "nsStyleConsts.h"
61 #include "nsStyleContext.h"
62 #include "nsHTMLParts.h"
63 #include "nsILookAndFeel.h"
64 #include "nsWidgetsCID.h"
65 #include "nsIComponentManager.h"
66 #include "nsGUIEvent.h"
67 #include "nsIRenderingContext.h"
68 #include "nsIServiceManager.h"
69 #include "nsIDOMMutationEvent.h"
70 #include "nsINameSpaceManager.h"
71 #include "nsCSSPseudoElements.h"
72 #include "nsCSSAnonBoxes.h"
73 #include "nsAutoPtr.h"
74 #include "nsStyleSet.h"
75 #include "nsIContent.h"
76 #include "nsDisplayList.h"
77 #include "nsNodeUtils.h"
78 #include "mozAutoDocUpdate.h"
80 // masks for mEdgeVisibility
81 #define LEFT_VIS 0x0001
82 #define RIGHT_VIS 0x0002
83 #define TOP_VIS 0x0004
84 #define BOTTOM_VIS 0x0008
85 #define ALL_VIS 0x000F
86 #define NONE_VIS 0x0000
88 static NS_DEFINE_CID(kLookAndFeelCID, NS_LOOKANDFEEL_CID);
90 /*******************************************************************************
91 * nsFramesetDrag
92 ******************************************************************************/
93 nsFramesetDrag::nsFramesetDrag()
95 UnSet();
98 nsFramesetDrag::nsFramesetDrag(PRBool aVertical,
99 PRInt32 aIndex,
100 PRInt32 aChange,
101 nsHTMLFramesetFrame* aSource)
103 mVertical = aVertical;
104 mIndex = aIndex;
105 mChange = aChange;
106 mSource = aSource;
108 void nsFramesetDrag::Reset(PRBool aVertical,
109 PRInt32 aIndex,
110 PRInt32 aChange,
111 nsHTMLFramesetFrame* aSource)
113 mVertical = aVertical;
114 mIndex = aIndex;
115 mChange = aChange;
116 mSource = aSource;
117 mActive = PR_TRUE;
120 void nsFramesetDrag::UnSet()
122 mVertical = PR_TRUE;
123 mIndex = -1;
124 mChange = 0;
125 mSource = nsnull;
126 mActive = PR_FALSE;
129 /*******************************************************************************
130 * nsHTMLFramesetBorderFrame
131 ******************************************************************************/
132 class nsHTMLFramesetBorderFrame : public nsLeafFrame {
134 public:
135 #ifdef DEBUG
136 NS_IMETHOD GetFrameName(nsAString& aResult) const;
137 #endif
139 NS_IMETHOD HandleEvent(nsPresContext* aPresContext,
140 nsGUIEvent* aEvent,
141 nsEventStatus* aEventStatus);
143 NS_IMETHOD GetCursor(const nsPoint& aPoint,
144 nsIFrame::Cursor& aCursor);
146 NS_IMETHOD BuildDisplayList(nsDisplayListBuilder* aBuilder,
147 const nsRect& aDirtyRect,
148 const nsDisplayListSet& aLists);
150 NS_IMETHOD Reflow(nsPresContext* aPresContext,
151 nsHTMLReflowMetrics& aDesiredSize,
152 const nsHTMLReflowState& aReflowState,
153 nsReflowStatus& aStatus);
155 PRBool GetVisibility() { return mVisibility || mVisibilityOverride; }
156 void SetVisibility(PRBool aVisibility);
157 void SetColor(nscolor aColor);
159 void PaintBorder(nsIRenderingContext& aRenderingContext, nsPoint aPt);
161 protected:
162 nsHTMLFramesetBorderFrame(nsStyleContext* aContext, PRInt32 aWidth, PRBool aVertical, PRBool aVisible);
163 virtual ~nsHTMLFramesetBorderFrame();
164 virtual nscoord GetIntrinsicWidth();
166 PRInt32 mWidth;
167 PRPackedBool mVertical;
168 PRPackedBool mVisibility;
169 PRPackedBool mVisibilityOverride;
170 nscolor mColor;
171 // the prev and next neighbors are indexes into the row (for a horizontal border) or col (for
172 // a vertical border) of nsHTMLFramesetFrames or nsHTMLFrames
173 PRInt32 mPrevNeighbor;
174 PRInt32 mNextNeighbor;
175 PRBool mCanResize;
176 friend class nsHTMLFramesetFrame;
178 /*******************************************************************************
179 * nsHTMLFramesetBlankFrame
180 ******************************************************************************/
181 class nsHTMLFramesetBlankFrame : public nsLeafFrame {
183 public:
184 #ifdef DEBUG
185 NS_IMETHOD List(FILE* out = stdout, PRInt32 aIndent = 0) const;
186 #endif
188 NS_IMETHOD BuildDisplayList(nsDisplayListBuilder* aBuilder,
189 const nsRect& aDirtyRect,
190 const nsDisplayListSet& aLists);
192 NS_IMETHOD Reflow(nsPresContext* aPresContext,
193 nsHTMLReflowMetrics& aDesiredSize,
194 const nsHTMLReflowState& aReflowState,
195 nsReflowStatus& aStatus);
197 protected:
198 nsHTMLFramesetBlankFrame(nsStyleContext* aContext) : nsLeafFrame(aContext) {}
199 virtual ~nsHTMLFramesetBlankFrame();
200 virtual nscoord GetIntrinsicWidth();
202 friend class nsHTMLFramesetFrame;
203 friend class nsHTMLFrameset;
206 /*******************************************************************************
207 * nsHTMLFramesetFrame
208 ******************************************************************************/
209 PRBool nsHTMLFramesetFrame::gDragInProgress = PR_FALSE;
210 #define kFrameResizePref "layout.frames.force_resizability"
211 #define DEFAULT_BORDER_WIDTH_PX 6
213 nsHTMLFramesetFrame::nsHTMLFramesetFrame(nsStyleContext* aContext)
214 : nsHTMLContainerFrame(aContext)
216 mNumRows = 0;
217 mRowSizes = nsnull;
218 mNumCols = 0;
219 mColSizes = nsnull;
220 mEdgeVisibility = 0;
221 mParentFrameborder = eFrameborder_Yes; // default
222 mParentBorderWidth = -1; // default not set
223 mParentBorderColor = NO_COLOR; // default not set
224 mFirstDragPoint.x = mFirstDragPoint.y = 0;
225 mMinDrag = nsPresContext::CSSPixelsToAppUnits(2);
226 mNonBorderChildCount = 0;
227 mNonBlankChildCount = 0;
228 mDragger = nsnull;
229 mChildCount = 0;
230 mTopLevelFrameset = nsnull;
231 mEdgeColors.Set(NO_COLOR);
232 mVerBorders = nsnull;
233 mHorBorders = nsnull;
234 mChildTypes = nsnull;
235 mChildFrameborder = nsnull;
236 mChildBorderColors = nsnull;
237 mForceFrameResizability = PR_FALSE;
240 nsHTMLFramesetFrame::~nsHTMLFramesetFrame()
242 delete[] mRowSizes;
243 delete[] mColSizes;
244 delete[] mVerBorders;
245 delete[] mHorBorders;
246 delete[] mChildTypes;
247 delete[] mChildFrameborder;
248 delete[] mChildBorderColors;
250 nsContentUtils::UnregisterPrefCallback(kFrameResizePref,
251 FrameResizePrefCallback, this);
254 NS_IMETHODIMP
255 nsHTMLFramesetFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr)
257 NS_PRECONDITION(aInstancePtr, "null out param");
259 if (aIID.Equals(NS_GET_IID(nsHTMLFramesetFrame))) {
260 *aInstancePtr = (void*)this;
261 return NS_OK;
264 return nsHTMLContainerFrame::QueryInterface(aIID, aInstancePtr);
267 // static
269 nsHTMLFramesetFrame::FrameResizePrefCallback(const char* aPref, void* aClosure)
271 nsHTMLFramesetFrame *frame =
272 reinterpret_cast<nsHTMLFramesetFrame *>(aClosure);
274 nsIDocument* doc = frame->mContent->GetDocument();
275 mozAutoDocUpdate updateBatch(doc, UPDATE_CONTENT_MODEL, PR_TRUE);
276 if (doc) {
277 doc->AttributeWillChange(frame->mContent,
278 kNameSpaceID_None,
279 nsGkAtoms::frameborder);
282 frame->mForceFrameResizability =
283 nsContentUtils::GetBoolPref(kFrameResizePref,
284 frame->mForceFrameResizability);
286 frame->RecalculateBorderResize();
287 if (doc) {
288 nsNodeUtils::AttributeChanged(frame->GetContent(),
289 kNameSpaceID_None,
290 nsGkAtoms::frameborder,
291 nsIDOMMutationEvent::MODIFICATION, 0);
294 return 0;
297 #define FRAMESET 0
298 #define FRAME 1
299 #define BLANK 2
301 NS_IMETHODIMP
302 nsHTMLFramesetFrame::Init(nsIContent* aContent,
303 nsIFrame* aParent,
304 nsIFrame* aPrevInFlow)
306 nsHTMLContainerFrame::Init(aContent, aParent, aPrevInFlow);
307 // find the highest ancestor that is a frameset
308 nsresult rv = NS_OK;
309 nsIFrame* parentFrame = GetParent();
310 mTopLevelFrameset = (nsHTMLFramesetFrame*)this;
311 while (parentFrame) {
312 nsHTMLFramesetFrame* frameset = nsnull;
313 CallQueryInterface(parentFrame, &frameset);
315 if (frameset) {
316 mTopLevelFrameset = frameset;
317 parentFrame = parentFrame->GetParent();
318 } else {
319 break;
323 nsPresContext* aPresContext = PresContext();
325 // create the view. a view is needed since it needs to be a mouse grabber
326 nsIViewManager* viewMan = aPresContext->GetViewManager();
328 nsIView *parView = GetAncestorWithView()->GetView();
329 nsRect boundBox(0, 0, 0, 0);
330 nsIView* view = viewMan->CreateView(boundBox, parView);
331 if (!view)
332 return NS_ERROR_OUT_OF_MEMORY;
334 // XXX Put it last in document order until we can do better
335 viewMan->InsertChild(parView, view, nsnull, PR_TRUE);
336 SetView(view);
338 nsIPresShell *shell = aPresContext->PresShell();
340 nsFrameborder frameborder = GetFrameBorder();
341 PRInt32 borderWidth = GetBorderWidth(aPresContext, PR_FALSE);
342 nscolor borderColor = GetBorderColor();
344 // Get the rows= cols= data
345 nsCOMPtr<nsIFrameSetElement> ourContent(do_QueryInterface(mContent));
346 NS_ASSERTION(ourContent, "Someone gave us a broken frameset element!");
347 const nsFramesetSpec* rowSpecs = nsnull;
348 const nsFramesetSpec* colSpecs = nsnull;
349 nsresult result = ourContent->GetRowSpec(&mNumRows, &rowSpecs);
350 NS_ENSURE_SUCCESS(result, result);
351 result = ourContent->GetColSpec(&mNumCols, &colSpecs);
352 NS_ENSURE_SUCCESS(result, result);
353 mRowSizes = new nscoord[mNumRows];
354 mColSizes = new nscoord[mNumCols];
355 if (!mRowSizes || !mColSizes)
356 return NS_ERROR_OUT_OF_MEMORY;
358 PRInt32 numCells = mNumRows*mNumCols;
360 mVerBorders = new nsHTMLFramesetBorderFrame*[mNumCols]; // 1 more than number of ver borders
361 if (!mVerBorders)
362 return NS_ERROR_OUT_OF_MEMORY;
364 for (int verX = 0; verX < mNumCols; verX++)
365 mVerBorders[verX] = nsnull;
367 mHorBorders = new nsHTMLFramesetBorderFrame*[mNumRows]; // 1 more than number of hor borders
368 if (!mHorBorders)
369 return NS_ERROR_OUT_OF_MEMORY;
371 for (int horX = 0; horX < mNumRows; horX++)
372 mHorBorders[horX] = nsnull;
374 mChildTypes = new PRInt32[numCells];
375 mChildFrameborder = new nsFrameborder[numCells];
376 mChildBorderColors = new nsBorderColor[numCells];
377 if (!mChildTypes || !mChildFrameborder || !mChildBorderColors)
378 return NS_ERROR_OUT_OF_MEMORY;
380 // create the children frames; skip content which isn't <frameset> or <frame>
381 nsIFrame* lastChild = nsnull;
382 mChildCount = 0; // number of <frame> or <frameset> children
383 nsIFrame* frame;
385 // number of any type of children
386 PRUint32 numChildren = mContent->GetChildCount();
388 for (PRUint32 childX = 0; childX < numChildren; childX++) {
389 if (mChildCount == numCells) { // we have more <frame> or <frameset> than cells
390 break;
392 nsIContent *child = mContent->GetChildAt(childX);
394 // IMPORTANT: This must match the conditions in
395 // nsCSSFrameConstructor::ContentAppended/Inserted/Removed
396 if (!child->IsNodeOfType(nsINode::eHTML))
397 continue;
399 nsIAtom *tag = child->Tag();
400 if (tag == nsGkAtoms::frameset || tag == nsGkAtoms::frame) {
401 nsRefPtr<nsStyleContext> kidSC;
402 nsresult result;
404 kidSC = shell->StyleSet()->ResolveStyleFor(child, mStyleContext);
405 if (tag == nsGkAtoms::frameset) {
406 frame = NS_NewHTMLFramesetFrame(shell, kidSC);
407 if (NS_UNLIKELY(!frame))
408 return NS_ERROR_OUT_OF_MEMORY;
410 mChildTypes[mChildCount] = FRAMESET;
411 nsHTMLFramesetFrame* childFrame = (nsHTMLFramesetFrame*)frame;
412 childFrame->SetParentFrameborder(frameborder);
413 childFrame->SetParentBorderWidth(borderWidth);
414 childFrame->SetParentBorderColor(borderColor);
415 result = frame->Init(child, this, nsnull);
416 if (NS_FAILED(result)) {
417 frame->Destroy();
418 return result;
421 mChildBorderColors[mChildCount].Set(childFrame->GetBorderColor());
422 } else { // frame
423 frame = NS_NewSubDocumentFrame(shell, kidSC);
424 if (NS_UNLIKELY(!frame))
425 return NS_ERROR_OUT_OF_MEMORY;
427 result = frame->Init(child, this, nsnull);
428 if (NS_FAILED(result)) {
429 frame->Destroy();
430 return result;
433 mChildTypes[mChildCount] = FRAME;
435 mChildFrameborder[mChildCount] = GetFrameBorder(child);
436 mChildBorderColors[mChildCount].Set(GetBorderColor(child));
439 if (NS_FAILED(result))
440 return result;
442 if (lastChild)
443 lastChild->SetNextSibling(frame);
444 else
445 mFrames.SetFrames(frame);
447 lastChild = frame;
448 mChildCount++;
452 mNonBlankChildCount = mChildCount;
453 // add blank frames for frameset cells that had no content provided
454 for (int blankX = mChildCount; blankX < numCells; blankX++) {
455 nsRefPtr<nsStyleContext> pseudoStyleContext;
456 pseudoStyleContext = shell->StyleSet()->
457 ResolvePseudoStyleFor(nsnull, nsCSSAnonBoxes::framesetBlank, mStyleContext);
458 if (!pseudoStyleContext) {
459 return NS_ERROR_OUT_OF_MEMORY;
462 // XXX the blank frame is using the content of its parent - at some point it
463 // should just have null content, if we support that
464 nsHTMLFramesetBlankFrame* blankFrame = new (shell) nsHTMLFramesetBlankFrame(pseudoStyleContext);
465 if (!blankFrame)
466 return NS_ERROR_OUT_OF_MEMORY;
468 result = blankFrame->Init(mContent, this, nsnull);
469 if (NS_FAILED(result)) {
470 blankFrame->Destroy();
471 return result;
474 if (lastChild)
475 lastChild->SetNextSibling(blankFrame);
476 else
477 mFrames.SetFrames(blankFrame);
479 lastChild = blankFrame;
480 mChildTypes[mChildCount] = BLANK;
481 mChildBorderColors[mChildCount].Set(NO_COLOR);
482 mChildCount++;
485 mNonBorderChildCount = mChildCount;
486 return rv;
489 // XXX should this try to allocate twips based on an even pixel boundary?
490 void nsHTMLFramesetFrame::Scale(nscoord aDesired,
491 PRInt32 aNumIndicies,
492 PRInt32* aIndicies,
493 PRInt32 aNumItems,
494 PRInt32* aItems)
496 PRInt32 actual = 0;
497 PRInt32 i, j;
498 // get the actual total
499 for (i = 0; i < aNumIndicies; i++) {
500 j = aIndicies[i];
501 actual += aItems[j];
504 if (actual > 0) {
505 float factor = (float)aDesired / (float)actual;
506 actual = 0;
507 // scale the items up or down
508 for (i = 0; i < aNumIndicies; i++) {
509 j = aIndicies[i];
510 aItems[j] = NSToCoordRound((float)aItems[j] * factor);
511 actual += aItems[j];
513 } else if (aNumIndicies != 0) {
514 // All the specs say zero width, but we have to fill up space
515 // somehow. Distribute it equally.
516 nscoord width = NSToCoordRound((float)aDesired / (float)aNumIndicies);
517 actual = width * aNumIndicies;
518 for (i = 0; i < aNumIndicies; i++) {
519 aItems[aIndicies[i]] = width;
523 if (aNumIndicies > 0 && aDesired != actual) {
524 PRInt32 unit = (aDesired > actual) ? 1 : -1;
525 for (i=0; (i < aNumIndicies) && (aDesired != actual); i++) {
526 j = aIndicies[i];
527 if (j < aNumItems) {
528 aItems[j] += unit;
529 actual += unit;
537 * Translate the rows/cols specs into an array of integer sizes for
538 * each cell in the frameset. Sizes are allocated based on the priorities of the
539 * specifier - fixed sizes have the highest priority, percentage sizes have the next
540 * highest priority and relative sizes have the lowest.
542 void nsHTMLFramesetFrame::CalculateRowCol(nsPresContext* aPresContext,
543 nscoord aSize,
544 PRInt32 aNumSpecs,
545 const nsFramesetSpec* aSpecs,
546 nscoord* aValues)
548 PRInt32 fixedTotal = 0;
549 PRInt32 numFixed = 0;
550 nsAutoArrayPtr<PRInt32> fixed(new PRInt32[aNumSpecs]);
551 PRInt32 numPercent = 0;
552 nsAutoArrayPtr<PRInt32> percent(new PRInt32[aNumSpecs]);
553 PRInt32 relativeSums = 0;
554 PRInt32 numRelative = 0;
555 nsAutoArrayPtr<PRInt32> relative(new PRInt32[aNumSpecs]);
557 if (NS_UNLIKELY(!fixed || !percent || !relative)) {
558 return; // NS_ERROR_OUT_OF_MEMORY
561 PRInt32 i, j;
563 // initialize the fixed, percent, relative indices, allocate the fixed sizes and zero the others
564 for (i = 0; i < aNumSpecs; i++) {
565 aValues[i] = 0;
566 switch (aSpecs[i].mUnit) {
567 case eFramesetUnit_Fixed:
568 aValues[i] = nsPresContext::CSSPixelsToAppUnits(aSpecs[i].mValue);
569 fixedTotal += aValues[i];
570 fixed[numFixed] = i;
571 numFixed++;
572 break;
573 case eFramesetUnit_Percent:
574 percent[numPercent] = i;
575 numPercent++;
576 break;
577 case eFramesetUnit_Relative:
578 relative[numRelative] = i;
579 numRelative++;
580 relativeSums += aSpecs[i].mValue;
581 break;
585 // scale the fixed sizes if they total too much (or too little and there aren't any percent or relative)
586 if ((fixedTotal > aSize) || ((fixedTotal < aSize) && (0 == numPercent) && (0 == numRelative))) {
587 Scale(aSize, numFixed, fixed, aNumSpecs, aValues);
588 return;
591 PRInt32 percentMax = aSize - fixedTotal;
592 PRInt32 percentTotal = 0;
593 // allocate the percentage sizes from what is left over from the fixed allocation
594 for (i = 0; i < numPercent; i++) {
595 j = percent[i];
596 aValues[j] = NSToCoordRound((float)aSpecs[j].mValue * (float)aSize / 100.0f);
597 percentTotal += aValues[j];
600 // scale the percent sizes if they total too much (or too little and there aren't any relative)
601 if ((percentTotal > percentMax) || ((percentTotal < percentMax) && (0 == numRelative))) {
602 Scale(percentMax, numPercent, percent, aNumSpecs, aValues);
603 return;
606 PRInt32 relativeMax = percentMax - percentTotal;
607 PRInt32 relativeTotal = 0;
608 // allocate the relative sizes from what is left over from the percent allocation
609 for (i = 0; i < numRelative; i++) {
610 j = relative[i];
611 aValues[j] = NSToCoordRound((float)aSpecs[j].mValue * (float)relativeMax / (float)relativeSums);
612 relativeTotal += aValues[j];
615 // scale the relative sizes if they take up too much or too little
616 if (relativeTotal != relativeMax) {
617 Scale(relativeMax, numRelative, relative, aNumSpecs, aValues);
623 * Translate the rows/cols integer sizes into an array of specs for
624 * each cell in the frameset. Reverse of CalculateRowCol() behaviour.
625 * This allows us to maintain the user size info through reflows.
627 void nsHTMLFramesetFrame::GenerateRowCol(nsPresContext* aPresContext,
628 nscoord aSize,
629 PRInt32 aNumSpecs,
630 const nsFramesetSpec* aSpecs,
631 nscoord* aValues,
632 nsString& aNewAttr)
634 PRInt32 i;
636 for (i = 0; i < aNumSpecs; i++) {
637 if (!aNewAttr.IsEmpty())
638 aNewAttr.Append(PRUnichar(','));
640 switch (aSpecs[i].mUnit) {
641 case eFramesetUnit_Fixed:
642 aNewAttr.AppendInt(nsPresContext::AppUnitsToIntCSSPixels(aValues[i]));
643 break;
644 case eFramesetUnit_Percent: // XXX Only accurate to 1%, need 1 pixel
645 case eFramesetUnit_Relative:
646 // Add 0.5 to the percentage to make rounding work right.
647 aNewAttr.AppendInt(PRUint32((100.0*aValues[i])/aSize + 0.5));
648 aNewAttr.Append(PRUnichar('%'));
649 break;
654 PRInt32 nsHTMLFramesetFrame::GetBorderWidth(nsPresContext* aPresContext,
655 PRBool aTakeForcingIntoAccount)
657 PRBool forcing = mForceFrameResizability && aTakeForcingIntoAccount;
659 if (!forcing) {
660 nsFrameborder frameborder = GetFrameBorder();
661 if (frameborder == eFrameborder_No) {
662 return 0;
665 nsGenericHTMLElement *content = nsGenericHTMLElement::FromContent(mContent);
667 if (content) {
668 const nsAttrValue* attr = content->GetParsedAttr(nsGkAtoms::border);
669 if (attr) {
670 PRInt32 intVal = 0;
671 if (attr->Type() == nsAttrValue::eInteger) {
672 intVal = attr->GetIntegerValue();
673 if (intVal < 0) {
674 intVal = 0;
678 if (forcing && intVal == 0) {
679 intVal = DEFAULT_BORDER_WIDTH_PX;
681 return nsPresContext::CSSPixelsToAppUnits(intVal);
685 if (mParentBorderWidth > 0 ||
686 (mParentBorderWidth == 0 && !forcing)) {
687 return mParentBorderWidth;
690 return nsPresContext::CSSPixelsToAppUnits(DEFAULT_BORDER_WIDTH_PX);
694 PRIntn
695 nsHTMLFramesetFrame::GetSkipSides() const
697 return 0;
700 void
701 nsHTMLFramesetFrame::GetDesiredSize(nsPresContext* aPresContext,
702 const nsHTMLReflowState& aReflowState,
703 nsHTMLReflowMetrics& aDesiredSize)
705 nsHTMLFramesetFrame* framesetParent = GetFramesetParent(this);
706 if (nsnull == framesetParent) {
707 if (aPresContext->IsPaginated()) {
708 // XXX This needs to be changed when framesets paginate properly
709 aDesiredSize.width = aReflowState.availableWidth;
710 aDesiredSize.height = aReflowState.availableHeight;
711 } else {
712 nsRect area = aPresContext->GetVisibleArea();
714 aDesiredSize.width = area.width;
715 aDesiredSize.height= area.height;
717 } else {
718 nsSize size;
719 framesetParent->GetSizeOfChild(this, size);
720 aDesiredSize.width = size.width;
721 aDesiredSize.height = size.height;
726 nsHTMLFramesetFrame* nsHTMLFramesetFrame::GetFramesetParent(nsIFrame* aChild)
728 nsHTMLFramesetFrame* parent = nsnull;
729 nsIContent* content = aChild->GetContent();
731 if (content) {
732 nsCOMPtr<nsIContent> contentParent = content->GetParent();
734 if (contentParent && contentParent->IsNodeOfType(nsINode::eHTML) &&
735 contentParent->Tag() == nsGkAtoms::frameset) {
736 nsIFrame* fptr = aChild->GetParent();
737 parent = (nsHTMLFramesetFrame*) fptr;
741 return parent;
744 // only valid for non border children
745 void nsHTMLFramesetFrame::GetSizeOfChildAt(PRInt32 aIndexInParent,
746 nsSize& aSize,
747 nsPoint& aCellIndex)
749 PRInt32 row = aIndexInParent / mNumCols;
750 PRInt32 col = aIndexInParent - (row * mNumCols); // remainder from dividing index by mNumCols
751 if ((row < mNumRows) && (col < mNumCols)) {
752 aSize.width = mColSizes[col];
753 aSize.height = mRowSizes[row];
754 aCellIndex.x = col;
755 aCellIndex.y = row;
756 } else {
757 aSize.width = aSize.height = aCellIndex.x = aCellIndex.y = 0;
761 // only valid for non border children
762 void nsHTMLFramesetFrame::GetSizeOfChild(nsIFrame* aChild,
763 nsSize& aSize)
765 // Reflow only creates children frames for <frameset> and <frame> content.
766 // this assumption is used here
767 int i = 0;
768 for (nsIFrame* child = mFrames.FirstChild(); child;
769 child = child->GetNextSibling()) {
770 if (aChild == child) {
771 nsPoint ignore;
772 GetSizeOfChildAt(i, aSize, ignore);
773 return;
775 i++;
777 aSize.width = 0;
778 aSize.height = 0;
782 NS_METHOD nsHTMLFramesetFrame::HandleEvent(nsPresContext* aPresContext,
783 nsGUIEvent* aEvent,
784 nsEventStatus* aEventStatus)
786 NS_ENSURE_ARG_POINTER(aEventStatus);
787 if (mDragger) {
788 // the nsFramesetBorderFrame has captured NS_MOUSE_DOWN
789 switch (aEvent->message) {
790 case NS_MOUSE_MOVE:
791 MouseDrag(aPresContext, aEvent);
792 break;
793 case NS_MOUSE_BUTTON_UP:
794 if (aEvent->eventStructType == NS_MOUSE_EVENT &&
795 static_cast<nsMouseEvent*>(aEvent)->button ==
796 nsMouseEvent::eLeftButton) {
797 EndMouseDrag(aPresContext);
799 break;
801 *aEventStatus = nsEventStatus_eConsumeNoDefault;
802 } else {
803 *aEventStatus = nsEventStatus_eIgnore;
805 return NS_OK;
808 #if 0
809 PRBool
810 nsHTMLFramesetFrame::IsGrabbingMouse()
812 PRBool result = PR_FALSE;
813 nsIView* view = GetView();
814 if (view) {
815 nsIViewManager* viewMan = view->GetViewManager();
816 if (viewMan) {
817 nsIView* grabber;
818 viewMan->GetMouseEventGrabber(grabber);
819 if (grabber == view) {
820 // the nsFramesetBorderFrame has captured NS_MOUSE_DOWN
821 result = PR_TRUE;
823 NS_RELEASE(viewMan);
826 return result;
828 #endif
830 NS_IMETHODIMP
831 nsHTMLFramesetFrame::GetCursor(const nsPoint& aPoint,
832 nsIFrame::Cursor& aCursor)
834 if (mDragger) {
835 aCursor.mCursor = (mDragger->mVertical) ? NS_STYLE_CURSOR_W_RESIZE : NS_STYLE_CURSOR_N_RESIZE;
836 } else {
837 aCursor.mCursor = NS_STYLE_CURSOR_DEFAULT;
839 return NS_OK;
842 NS_IMETHODIMP
843 nsHTMLFramesetFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
844 const nsRect& aDirtyRect,
845 const nsDisplayListSet& aLists)
847 nsresult rv = nsHTMLContainerFrame::BuildDisplayList(aBuilder, aDirtyRect, aLists);
848 NS_ENSURE_SUCCESS(rv, rv);
850 if (mDragger && aBuilder->IsForEventDelivery()) {
851 // REVIEW: GetFrameForPoint would always target ourselves if mDragger set
852 nsDisplayItem* item = new (aBuilder) nsDisplayEventReceiver(this);
853 if (!item)
854 return NS_ERROR_OUT_OF_MEMORY;
855 aLists.Content()->AppendToTop(item);
857 return rv;
860 void
861 nsHTMLFramesetFrame::ReflowPlaceChild(nsIFrame* aChild,
862 nsPresContext* aPresContext,
863 const nsHTMLReflowState& aReflowState,
864 nsPoint& aOffset,
865 nsSize& aSize,
866 nsPoint* aCellIndex)
868 // reflow the child
869 nsHTMLReflowState reflowState(aPresContext, aReflowState, aChild, aSize);
870 nsHTMLReflowMetrics metrics;
871 metrics.width = aSize.width;
872 metrics.height= aSize.height;
873 nsReflowStatus status;
875 ReflowChild(aChild, aPresContext, metrics, reflowState, aOffset.x,
876 aOffset.y, 0, status);
877 NS_ASSERTION(NS_FRAME_IS_COMPLETE(status), "bad status");
879 // Place and size the child
880 metrics.width = aSize.width;
881 metrics.height = aSize.height;
882 FinishReflowChild(aChild, aPresContext, nsnull, metrics, aOffset.x, aOffset.y, 0);
885 static
886 nsFrameborder GetFrameBorderHelper(nsGenericHTMLElement* aContent)
888 if (nsnull != aContent) {
889 const nsAttrValue* attr = aContent->GetParsedAttr(nsGkAtoms::frameborder);
890 if (attr && attr->Type() == nsAttrValue::eEnum) {
891 switch (attr->GetEnumValue())
893 case NS_STYLE_FRAME_YES:
894 case NS_STYLE_FRAME_1:
895 return eFrameborder_Yes;
896 break;
898 case NS_STYLE_FRAME_NO:
899 case NS_STYLE_FRAME_0:
900 return eFrameborder_No;
901 break;
905 return eFrameborder_Notset;
908 nsFrameborder nsHTMLFramesetFrame::GetFrameBorder()
910 nsFrameborder result = eFrameborder_Notset;
911 nsGenericHTMLElement *content = nsGenericHTMLElement::FromContent(mContent);
913 if (content) {
914 result = GetFrameBorderHelper(content);
916 if (eFrameborder_Notset == result) {
917 return mParentFrameborder;
919 return result;
922 nsFrameborder nsHTMLFramesetFrame::GetFrameBorder(nsIContent* aContent)
924 nsFrameborder result = eFrameborder_Notset;
926 nsGenericHTMLElement *content = nsGenericHTMLElement::FromContent(aContent);
928 if (content) {
929 result = GetFrameBorderHelper(content);
931 if (eFrameborder_Notset == result) {
932 return GetFrameBorder();
934 return result;
937 nscolor nsHTMLFramesetFrame::GetBorderColor()
939 nsGenericHTMLElement *content = nsGenericHTMLElement::FromContent(mContent);
941 if (content) {
942 const nsAttrValue* attr = content->GetParsedAttr(nsGkAtoms::bordercolor);
943 if (attr) {
944 nscolor color;
945 if (attr->GetColorValue(color)) {
946 return color;
951 return mParentBorderColor;
954 nscolor nsHTMLFramesetFrame::GetBorderColor(nsIContent* aContent)
956 nsGenericHTMLElement *content = nsGenericHTMLElement::FromContent(aContent);
958 if (content) {
959 const nsAttrValue* attr = content->GetParsedAttr(nsGkAtoms::bordercolor);
960 if (attr) {
961 nscolor color;
962 if (attr->GetColorValue(color)) {
963 return color;
967 return GetBorderColor();
970 NS_IMETHODIMP
971 nsHTMLFramesetFrame::Reflow(nsPresContext* aPresContext,
972 nsHTMLReflowMetrics& aDesiredSize,
973 const nsHTMLReflowState& aReflowState,
974 nsReflowStatus& aStatus)
976 DO_GLOBAL_REFLOW_COUNT("nsHTMLFramesetFrame");
977 DISPLAY_REFLOW(aPresContext, this, aReflowState, aDesiredSize, aStatus);
978 nsIPresShell *shell = aPresContext->PresShell();
979 nsStyleSet *styleSet = shell->StyleSet();
981 mParent->AddStateBits(NS_FRAME_CONTAINS_RELATIVE_HEIGHT);
983 //printf("FramesetFrame2::Reflow %X (%d,%d) \n", this, aReflowState.availableWidth, aReflowState.availableHeight);
984 // Always get the size so that the caller knows how big we are
985 GetDesiredSize(aPresContext, aReflowState, aDesiredSize);
987 nscoord width = (aDesiredSize.width <= aReflowState.availableWidth)
988 ? aDesiredSize.width : aReflowState.availableWidth;
989 nscoord height = (aDesiredSize.height <= aReflowState.availableHeight)
990 ? aDesiredSize.height : aReflowState.availableHeight;
992 PRBool firstTime = (GetStateBits() & NS_FRAME_FIRST_REFLOW) != 0;
993 if (firstTime) {
994 nsContentUtils::RegisterPrefCallback(kFrameResizePref,
995 FrameResizePrefCallback, this);
996 mForceFrameResizability =
997 nsContentUtils::GetBoolPref(kFrameResizePref);
1000 // subtract out the width of all of the potential borders. There are
1001 // only borders between <frame>s. There are none on the edges (e.g the
1002 // leftmost <frame> has no left border).
1003 PRInt32 borderWidth = GetBorderWidth(aPresContext, PR_TRUE);
1005 width -= (mNumCols - 1) * borderWidth;
1006 if (width < 0) width = 0;
1008 height -= (mNumRows - 1) * borderWidth;
1009 if (height < 0) height = 0;
1011 nsCOMPtr<nsIFrameSetElement> ourContent(do_QueryInterface(mContent));
1012 NS_ASSERTION(ourContent, "Someone gave us a broken frameset element!");
1013 const nsFramesetSpec* rowSpecs = nsnull;
1014 const nsFramesetSpec* colSpecs = nsnull;
1015 PRInt32 rows = 0;
1016 PRInt32 cols = 0;
1017 ourContent->GetRowSpec(&rows, &rowSpecs);
1018 ourContent->GetColSpec(&cols, &colSpecs);
1019 // If the number of cols or rows has changed, the frame for the frameset
1020 // will be re-created.
1021 if (mNumRows != rows || mNumCols != cols) {
1022 aStatus = NS_FRAME_COMPLETE;
1023 mDrag.UnSet();
1024 NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
1025 return NS_OK;
1028 if (!mDrag.mActive) {
1029 CalculateRowCol(aPresContext, width, mNumCols, colSpecs, mColSizes);
1030 CalculateRowCol(aPresContext, height, mNumRows, rowSpecs, mRowSizes);
1033 nsAutoArrayPtr<PRBool> verBordersVis; // vertical borders visibility
1034 nsAutoArrayPtr<nscolor> verBorderColors;
1035 nsAutoArrayPtr<PRBool> horBordersVis; // horizontal borders visibility
1036 nsAutoArrayPtr<nscolor> horBorderColors;
1037 nscolor borderColor = GetBorderColor();
1038 nsFrameborder frameborder = GetFrameBorder();
1040 if (firstTime) {
1041 verBordersVis = new PRBool[mNumCols];
1042 NS_ENSURE_TRUE(verBordersVis, NS_ERROR_OUT_OF_MEMORY);
1043 verBorderColors = new nscolor[mNumCols];
1044 NS_ENSURE_TRUE(verBorderColors, NS_ERROR_OUT_OF_MEMORY);
1045 for (int verX = 0; verX < mNumCols; verX++) {
1046 verBordersVis[verX] = PR_FALSE;
1047 verBorderColors[verX] = NO_COLOR;
1050 horBordersVis = new PRBool[mNumRows];
1051 NS_ENSURE_TRUE(horBordersVis, NS_ERROR_OUT_OF_MEMORY);
1052 horBorderColors = new nscolor[mNumRows];
1053 NS_ENSURE_TRUE(horBorderColors, NS_ERROR_OUT_OF_MEMORY);
1054 for (int horX = 0; horX < mNumRows; horX++) {
1055 horBordersVis[horX] = PR_FALSE;
1056 horBorderColors[horX] = NO_COLOR;
1060 // reflow the children
1061 PRInt32 lastRow = 0;
1062 PRInt32 lastCol = 0;
1063 PRInt32 borderChildX = mNonBorderChildCount; // index of border children
1064 nsHTMLFramesetBorderFrame* borderFrame = nsnull;
1065 nsPoint offset(0,0);
1066 nsSize size, lastSize;
1067 nsIFrame* child = mFrames.FirstChild();
1068 nsIFrame* lastChild = mFrames.LastChild();
1070 for (PRInt32 childX = 0; childX < mNonBorderChildCount; childX++) {
1071 nsPoint cellIndex;
1072 GetSizeOfChildAt(childX, size, cellIndex);
1074 if (lastRow != cellIndex.y) { // changed to next row
1075 offset.x = 0;
1076 offset.y += lastSize.height;
1077 if (firstTime) { // create horizontal border
1079 nsRefPtr<nsStyleContext> pseudoStyleContext;
1080 pseudoStyleContext = styleSet->ResolvePseudoStyleFor(mContent,
1081 nsCSSPseudoElements::horizontalFramesetBorder,
1082 mStyleContext);
1084 borderFrame = new (shell) nsHTMLFramesetBorderFrame(pseudoStyleContext,
1085 borderWidth,
1086 PR_FALSE,
1087 PR_FALSE);
1088 if (NS_LIKELY(borderFrame != nsnull)) {
1089 borderFrame->Init(mContent, this, nsnull);
1090 mChildCount++;
1091 lastChild->SetNextSibling(borderFrame);
1092 lastChild = borderFrame;
1093 mHorBorders[cellIndex.y-1] = borderFrame;
1094 // set the neighbors for determining drag boundaries
1095 borderFrame->mPrevNeighbor = lastRow;
1096 borderFrame->mNextNeighbor = cellIndex.y;
1098 } else {
1099 borderFrame = (nsHTMLFramesetBorderFrame*)mFrames.FrameAt(borderChildX);
1100 if (NS_LIKELY(borderFrame != nsnull)) {
1101 borderFrame->mWidth = borderWidth;
1102 borderChildX++;
1105 if (NS_LIKELY(borderFrame != nsnull)) {
1106 nsSize borderSize(aDesiredSize.width, borderWidth);
1107 ReflowPlaceChild(borderFrame, aPresContext, aReflowState, offset, borderSize);
1108 borderFrame = nsnull;
1110 offset.y += borderWidth;
1111 } else {
1112 if (cellIndex.x > 0) { // moved to next col in same row
1113 if (0 == cellIndex.y) { // in 1st row
1114 if (firstTime) { // create vertical border
1116 nsRefPtr<nsStyleContext> pseudoStyleContext;
1117 pseudoStyleContext = styleSet->ResolvePseudoStyleFor(mContent,
1118 nsCSSPseudoElements::verticalFramesetBorder,
1119 mStyleContext);
1121 borderFrame = new (shell) nsHTMLFramesetBorderFrame(pseudoStyleContext,
1122 borderWidth,
1123 PR_TRUE,
1124 PR_FALSE);
1125 if (NS_LIKELY(borderFrame != nsnull)) {
1126 borderFrame->Init(mContent, this, nsnull);
1127 mChildCount++;
1128 lastChild->SetNextSibling(borderFrame);
1129 lastChild = borderFrame;
1130 mVerBorders[cellIndex.x-1] = borderFrame;
1131 // set the neighbors for determining drag boundaries
1132 borderFrame->mPrevNeighbor = lastCol;
1133 borderFrame->mNextNeighbor = cellIndex.x;
1135 } else {
1136 borderFrame = (nsHTMLFramesetBorderFrame*)mFrames.FrameAt(borderChildX);
1137 if (NS_LIKELY(borderFrame != nsnull)) {
1138 borderFrame->mWidth = borderWidth;
1139 borderChildX++;
1142 if (NS_LIKELY(borderFrame != nsnull)) {
1143 nsSize borderSize(borderWidth, aDesiredSize.height);
1144 ReflowPlaceChild(borderFrame, aPresContext, aReflowState, offset, borderSize);
1145 borderFrame = nsnull;
1148 offset.x += borderWidth;
1152 ReflowPlaceChild(child, aPresContext, aReflowState, offset, size, &cellIndex);
1154 if (firstTime) {
1155 PRInt32 childVis;
1156 if (FRAMESET == mChildTypes[childX]) {
1157 nsHTMLFramesetFrame* childFS = (nsHTMLFramesetFrame*)child;
1158 childVis = childFS->mEdgeVisibility;
1159 mChildBorderColors[childX] = childFS->mEdgeColors;
1160 } else if (FRAME == mChildTypes[childX]) {
1161 if (eFrameborder_Yes == mChildFrameborder[childX]) {
1162 childVis = ALL_VIS;
1163 } else if (eFrameborder_No == mChildFrameborder[childX]) {
1164 childVis = NONE_VIS;
1165 } else { // notset
1166 childVis = (eFrameborder_No == frameborder) ? NONE_VIS : ALL_VIS;
1168 } else { // blank
1169 childVis = NONE_VIS;
1171 nsBorderColor childColors = mChildBorderColors[childX];
1172 // set the visibility, color of our edge borders based on children
1173 if (0 == cellIndex.x) {
1174 if (!(mEdgeVisibility & LEFT_VIS)) {
1175 mEdgeVisibility |= (LEFT_VIS & childVis);
1177 if (NO_COLOR == mEdgeColors.mLeft) {
1178 mEdgeColors.mLeft = childColors.mLeft;
1181 if (0 == cellIndex.y) {
1182 if (!(mEdgeVisibility & TOP_VIS)) {
1183 mEdgeVisibility |= (TOP_VIS & childVis);
1185 if (NO_COLOR == mEdgeColors.mTop) {
1186 mEdgeColors.mTop = childColors.mTop;
1189 if (mNumCols-1 == cellIndex.x) {
1190 if (!(mEdgeVisibility & RIGHT_VIS)) {
1191 mEdgeVisibility |= (RIGHT_VIS & childVis);
1193 if (NO_COLOR == mEdgeColors.mRight) {
1194 mEdgeColors.mRight = childColors.mRight;
1197 if (mNumRows-1 == cellIndex.y) {
1198 if (!(mEdgeVisibility & BOTTOM_VIS)) {
1199 mEdgeVisibility |= (BOTTOM_VIS & childVis);
1201 if (NO_COLOR == mEdgeColors.mBottom) {
1202 mEdgeColors.mBottom = childColors.mBottom;
1205 // set the visibility of borders that the child may affect
1206 if (childVis & RIGHT_VIS) {
1207 verBordersVis[cellIndex.x] = PR_TRUE;
1209 if (childVis & BOTTOM_VIS) {
1210 horBordersVis[cellIndex.y] = PR_TRUE;
1212 if ((cellIndex.x > 0) && (childVis & LEFT_VIS)) {
1213 verBordersVis[cellIndex.x-1] = PR_TRUE;
1215 if ((cellIndex.y > 0) && (childVis & TOP_VIS)) {
1216 horBordersVis[cellIndex.y-1] = PR_TRUE;
1218 // set the colors of borders that the child may affect
1219 if (NO_COLOR == verBorderColors[cellIndex.x]) {
1220 verBorderColors[cellIndex.x] = mChildBorderColors[childX].mRight;
1222 if (NO_COLOR == horBorderColors[cellIndex.y]) {
1223 horBorderColors[cellIndex.y] = mChildBorderColors[childX].mBottom;
1225 if ((cellIndex.x > 0) && (NO_COLOR == verBorderColors[cellIndex.x-1])) {
1226 verBorderColors[cellIndex.x-1] = mChildBorderColors[childX].mLeft;
1228 if ((cellIndex.y > 0) && (NO_COLOR == horBorderColors[cellIndex.y-1])) {
1229 horBorderColors[cellIndex.y-1] = mChildBorderColors[childX].mTop;
1232 lastRow = cellIndex.y;
1233 lastCol = cellIndex.x;
1234 lastSize = size;
1235 offset.x += size.width;
1236 child = child->GetNextSibling();
1239 if (firstTime) {
1240 nscolor childColor;
1241 // set the visibility, color, mouse sensitivity of borders
1242 for (int verX = 0; verX < mNumCols-1; verX++) {
1243 if (mVerBorders[verX]) {
1244 mVerBorders[verX]->SetVisibility(verBordersVis[verX]);
1245 if (mForceFrameResizability) {
1246 mVerBorders[verX]->mVisibilityOverride = PR_TRUE;
1247 } else {
1248 SetBorderResize(mChildTypes, mVerBorders[verX]);
1250 childColor = (NO_COLOR == verBorderColors[verX]) ? borderColor : verBorderColors[verX];
1251 mVerBorders[verX]->SetColor(childColor);
1254 for (int horX = 0; horX < mNumRows-1; horX++) {
1255 if (mHorBorders[horX]) {
1256 mHorBorders[horX]->SetVisibility(horBordersVis[horX]);
1257 if (mForceFrameResizability) {
1258 mHorBorders[horX]->mVisibilityOverride = PR_TRUE;
1259 } else {
1260 SetBorderResize(mChildTypes, mHorBorders[horX]);
1262 childColor = (NO_COLOR == horBorderColors[horX]) ? borderColor : horBorderColors[horX];
1263 mHorBorders[horX]->SetColor(childColor);
1267 delete[] mChildTypes;
1268 delete[] mChildFrameborder;
1269 delete[] mChildBorderColors;
1271 mChildTypes = nsnull;
1272 mChildFrameborder = nsnull;
1273 mChildBorderColors = nsnull;
1276 aStatus = NS_FRAME_COMPLETE;
1277 mDrag.UnSet();
1279 aDesiredSize.mOverflowArea = nsRect(0, 0,
1280 aDesiredSize.width, aDesiredSize.height);
1282 NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
1283 return NS_OK;
1286 nsIAtom*
1287 nsHTMLFramesetFrame::GetType() const
1289 return nsGkAtoms::frameSetFrame;
1292 #ifdef DEBUG
1293 NS_IMETHODIMP
1294 nsHTMLFramesetFrame::GetFrameName(nsAString& aResult) const
1296 return MakeFrameName(NS_LITERAL_STRING("Frameset"), aResult);
1298 #endif
1300 PRBool
1301 nsHTMLFramesetFrame::IsLeaf() const
1303 // We handle constructing our kids manually
1304 return PR_TRUE;
1307 PRBool
1308 nsHTMLFramesetFrame::ChildIsFrameset(nsIFrame* aChild)
1310 nsIFrame* childFrame = nsnull;
1311 aChild->QueryInterface(NS_GET_IID(nsHTMLFramesetFrame), (void**)&childFrame);
1312 if (childFrame) {
1313 return PR_TRUE;
1315 return PR_FALSE;
1319 PRBool
1320 nsHTMLFramesetFrame::CanResize(PRBool aVertical,
1321 PRBool aLeft)
1323 nsIFrame* child;
1324 PRInt32 childX;
1325 PRInt32 startX;
1326 if (aVertical) {
1327 startX = (aLeft) ? 0 : mNumCols-1;
1328 for (childX = startX; childX < mNonBorderChildCount; childX += mNumCols) {
1329 child = mFrames.FrameAt(childX);
1330 if (!CanChildResize(aVertical, aLeft, childX, ChildIsFrameset(child))) {
1331 return PR_FALSE;
1334 } else {
1335 startX = (aLeft) ? 0 : (mNumRows - 1) * mNumCols;
1336 PRInt32 endX = startX + mNumCols;
1337 for (childX = startX; childX < endX; childX++) {
1338 child = mFrames.FrameAt(childX);
1339 if (!CanChildResize(aVertical, aLeft, childX, ChildIsFrameset(child))) {
1340 return PR_FALSE;
1344 return PR_TRUE;
1347 PRBool
1348 nsHTMLFramesetFrame::GetNoResize(nsIFrame* aChildFrame)
1350 nsIContent* content = aChildFrame->GetContent();
1352 return content && content->HasAttr(kNameSpaceID_None, nsGkAtoms::noresize);
1355 PRBool
1356 nsHTMLFramesetFrame::CanChildResize(PRBool aVertical,
1357 PRBool aLeft,
1358 PRInt32 aChildX,
1359 PRBool aFrameset)
1361 nsIFrame* child = mFrames.FrameAt(aChildX);
1362 if (aFrameset) {
1363 NS_ASSERTION(ChildIsFrameset(child), "Child frame is not a frameset!");
1364 return ((nsHTMLFramesetFrame*)child)->CanResize(aVertical, aLeft);
1365 } else {
1366 return !GetNoResize(child);
1370 // This calculates and sets the resizability of all border frames
1372 void
1373 nsHTMLFramesetFrame::RecalculateBorderResize()
1375 if (!mContent) {
1376 return;
1379 PRInt32 numCells = mNumRows * mNumCols; // max number of cells
1380 nsAutoArrayPtr<PRInt32> childTypes(new PRInt32[numCells]);
1381 if (NS_UNLIKELY(!childTypes)) {
1382 return;
1384 PRUint32 childIndex, childTypeIndex = 0;
1386 // number of any type of children
1387 PRUint32 numChildren = mContent->GetChildCount();
1388 for (childIndex = 0; childIndex < numChildren; childIndex++) {
1389 nsIContent *child = mContent->GetChildAt(childIndex);
1391 if (child->IsNodeOfType(nsINode::eHTML)) {
1392 nsINodeInfo *ni = child->NodeInfo();
1394 if (ni->Equals(nsGkAtoms::frameset)) {
1395 childTypes[childTypeIndex++] = FRAMESET;
1396 } else if (ni->Equals(nsGkAtoms::frame)) {
1397 childTypes[childTypeIndex++] = FRAME;
1399 // Don't overflow childTypes array
1400 if (((PRInt32)childTypeIndex) >= numCells) {
1401 break;
1405 for (; childTypeIndex < numCells; ++childTypeIndex) {
1406 childTypes[childTypeIndex] = BLANK;
1409 // set the visibility and mouse sensitivity of borders
1410 PRInt32 verX;
1411 for (verX = 0; verX < mNumCols-1; verX++) {
1412 if (mVerBorders[verX]) {
1413 mVerBorders[verX]->mCanResize = PR_TRUE;
1414 if (mForceFrameResizability) {
1415 mVerBorders[verX]->mVisibilityOverride = PR_TRUE;
1416 } else {
1417 mVerBorders[verX]->mVisibilityOverride = PR_FALSE;
1418 SetBorderResize(childTypes, mVerBorders[verX]);
1422 PRInt32 horX;
1423 for (horX = 0; horX < mNumRows-1; horX++) {
1424 if (mHorBorders[horX]) {
1425 mHorBorders[horX]->mCanResize = PR_TRUE;
1426 if (mForceFrameResizability) {
1427 mHorBorders[horX]->mVisibilityOverride = PR_TRUE;
1428 } else {
1429 mHorBorders[horX]->mVisibilityOverride = PR_FALSE;
1430 SetBorderResize(childTypes, mHorBorders[horX]);
1436 void
1437 nsHTMLFramesetFrame::SetBorderResize(PRInt32* aChildTypes,
1438 nsHTMLFramesetBorderFrame* aBorderFrame)
1440 if (aBorderFrame->mVertical) {
1441 for (int rowX = 0; rowX < mNumRows; rowX++) {
1442 PRInt32 childX = aBorderFrame->mPrevNeighbor + (rowX * mNumCols);
1443 if (!CanChildResize(PR_TRUE, PR_FALSE, childX, (FRAMESET == aChildTypes[childX])) ||
1444 !CanChildResize(PR_TRUE, PR_TRUE, childX+1,(FRAMESET == aChildTypes[childX+1]))) {
1445 aBorderFrame->mCanResize = PR_FALSE;
1448 } else {
1449 PRInt32 childX = aBorderFrame->mPrevNeighbor * mNumCols;
1450 PRInt32 endX = childX + mNumCols;
1451 for (; childX < endX; childX++) {
1452 if (!CanChildResize(PR_FALSE, PR_FALSE, childX, (FRAMESET == aChildTypes[childX]))) {
1453 aBorderFrame->mCanResize = PR_FALSE;
1456 endX = endX + mNumCols;
1457 for (; childX < endX; childX++) {
1458 if (!CanChildResize(PR_FALSE, PR_TRUE, childX, (FRAMESET == aChildTypes[childX]))) {
1459 aBorderFrame->mCanResize = PR_FALSE;
1466 NS_IMETHODIMP
1467 nsHTMLFramesetFrame::VerifyTree() const
1469 // XXX Completely disabled for now; once pseud-frames are reworked
1470 // then we can turn it back on.
1471 return NS_OK;
1474 void
1475 nsHTMLFramesetFrame::StartMouseDrag(nsPresContext* aPresContext,
1476 nsHTMLFramesetBorderFrame* aBorder,
1477 nsGUIEvent* aEvent)
1479 #if 0
1480 PRInt32 index;
1481 IndexOf(aBorder, index);
1482 NS_ASSERTION((nsnull != aBorder) && (index >= 0), "invalid dragger");
1483 #endif
1484 nsIView* view = GetView();
1485 if (view) {
1486 nsIViewManager* viewMan = view->GetViewManager();
1487 if (viewMan) {
1488 PRBool ignore;
1489 viewMan->GrabMouseEvents(view, ignore);
1490 mDragger = aBorder;
1492 mFirstDragPoint = aEvent->refPoint;
1494 // Store the original frame sizes
1495 if (mDragger->mVertical) {
1496 mPrevNeighborOrigSize = mColSizes[mDragger->mPrevNeighbor];
1497 mNextNeighborOrigSize = mColSizes[mDragger->mNextNeighbor];
1498 } else {
1499 mPrevNeighborOrigSize = mRowSizes[mDragger->mPrevNeighbor];
1500 mNextNeighborOrigSize = mRowSizes[mDragger->mNextNeighbor];
1503 gDragInProgress = PR_TRUE;
1509 void
1510 nsHTMLFramesetFrame::MouseDrag(nsPresContext* aPresContext,
1511 nsGUIEvent* aEvent)
1513 PRInt32 change; // measured positive from left-to-right or top-to-bottom
1514 nsWeakFrame weakFrame(this);
1515 if (mDragger->mVertical) {
1516 change = aPresContext->DevPixelsToAppUnits(aEvent->refPoint.x - mFirstDragPoint.x);
1517 if (change > mNextNeighborOrigSize - mMinDrag) {
1518 change = mNextNeighborOrigSize - mMinDrag;
1519 } else if (change <= mMinDrag - mPrevNeighborOrigSize) {
1520 change = mMinDrag - mPrevNeighborOrigSize;
1522 mColSizes[mDragger->mPrevNeighbor] = mPrevNeighborOrigSize + change;
1523 mColSizes[mDragger->mNextNeighbor] = mNextNeighborOrigSize - change;
1525 if (change != 0) {
1526 // Recompute the specs from the new sizes.
1527 nscoord width = mRect.width - (mNumCols - 1) * GetBorderWidth(aPresContext, PR_TRUE);
1528 nsCOMPtr<nsIFrameSetElement> ourContent(do_QueryInterface(mContent));
1529 NS_ASSERTION(ourContent, "Someone gave us a broken frameset element!");
1530 const nsFramesetSpec* colSpecs = nsnull;
1531 ourContent->GetColSpec(&mNumCols, &colSpecs);
1532 nsAutoString newColAttr;
1533 GenerateRowCol(aPresContext, width, mNumCols, colSpecs, mColSizes,
1534 newColAttr);
1535 // Setting the attr will trigger a reflow
1536 mContent->SetAttr(kNameSpaceID_None, nsGkAtoms::cols, newColAttr, PR_TRUE);
1538 } else {
1539 change = aPresContext->DevPixelsToAppUnits(aEvent->refPoint.y - mFirstDragPoint.y);
1540 if (change > mNextNeighborOrigSize - mMinDrag) {
1541 change = mNextNeighborOrigSize - mMinDrag;
1542 } else if (change <= mMinDrag - mPrevNeighborOrigSize) {
1543 change = mMinDrag - mPrevNeighborOrigSize;
1545 mRowSizes[mDragger->mPrevNeighbor] = mPrevNeighborOrigSize + change;
1546 mRowSizes[mDragger->mNextNeighbor] = mNextNeighborOrigSize - change;
1548 if (change != 0) {
1549 // Recompute the specs from the new sizes.
1550 nscoord height = mRect.height - (mNumRows - 1) * GetBorderWidth(aPresContext, PR_TRUE);
1551 nsCOMPtr<nsIFrameSetElement> ourContent(do_QueryInterface(mContent));
1552 NS_ASSERTION(ourContent, "Someone gave us a broken frameset element!");
1553 const nsFramesetSpec* rowSpecs = nsnull;
1554 ourContent->GetRowSpec(&mNumRows, &rowSpecs);
1555 nsAutoString newRowAttr;
1556 GenerateRowCol(aPresContext, height, mNumRows, rowSpecs, mRowSizes,
1557 newRowAttr);
1558 // Setting the attr will trigger a reflow
1559 mContent->SetAttr(kNameSpaceID_None, nsGkAtoms::rows, newRowAttr, PR_TRUE);
1563 ENSURE_TRUE(weakFrame.IsAlive());
1564 if (change != 0) {
1565 mDrag.Reset(mDragger->mVertical, mDragger->mPrevNeighbor, change, this);
1566 nsIFrame* parentFrame = GetParent();
1567 if (!parentFrame) {
1568 return;
1571 // Update the view immediately (make drag appear snappier)
1572 nsIViewManager* vm = aPresContext->GetViewManager();
1573 if (vm) {
1574 nsIView* root;
1575 vm->GetRootView(root);
1576 if (root) {
1577 vm->UpdateView(root, NS_VMREFRESH_IMMEDIATE);
1583 void
1584 nsHTMLFramesetFrame::EndMouseDrag(nsPresContext* aPresContext)
1586 nsIView* view = GetView();
1587 if (view) {
1588 nsIViewManager* viewMan = view->GetViewManager();
1589 if (viewMan) {
1590 mDragger = nsnull;
1591 PRBool ignore;
1592 viewMan->GrabMouseEvents(nsnull, ignore);
1595 gDragInProgress = PR_FALSE;
1598 nsIFrame*
1599 NS_NewHTMLFramesetFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
1601 return new (aPresShell) nsHTMLFramesetFrame(aContext);
1604 /*******************************************************************************
1605 * nsHTMLFramesetBorderFrame
1606 ******************************************************************************/
1607 nsHTMLFramesetBorderFrame::nsHTMLFramesetBorderFrame(nsStyleContext* aContext,
1608 PRInt32 aWidth,
1609 PRBool aVertical,
1610 PRBool aVisibility)
1611 : nsLeafFrame(aContext), mWidth(aWidth), mVertical(aVertical), mVisibility(aVisibility)
1613 mVisibilityOverride = PR_FALSE;
1614 mCanResize = PR_TRUE;
1615 mColor = NO_COLOR;
1616 mPrevNeighbor = 0;
1617 mNextNeighbor = 0;
1620 nsHTMLFramesetBorderFrame::~nsHTMLFramesetBorderFrame()
1622 //printf("nsHTMLFramesetBorderFrame destructor %p \n", this);
1625 nscoord nsHTMLFramesetBorderFrame::GetIntrinsicWidth()
1627 // No intrinsic width
1628 return 0;
1631 void nsHTMLFramesetBorderFrame::SetVisibility(PRBool aVisibility)
1633 mVisibility = aVisibility;
1636 void nsHTMLFramesetBorderFrame::SetColor(nscolor aColor)
1638 mColor = aColor;
1642 NS_IMETHODIMP
1643 nsHTMLFramesetBorderFrame::Reflow(nsPresContext* aPresContext,
1644 nsHTMLReflowMetrics& aDesiredSize,
1645 const nsHTMLReflowState& aReflowState,
1646 nsReflowStatus& aStatus)
1648 DO_GLOBAL_REFLOW_COUNT("nsHTMLFramesetBorderFrame");
1649 DISPLAY_REFLOW(aPresContext, this, aReflowState, aDesiredSize, aStatus);
1651 // Override Reflow(), since we don't want to deal with what our
1652 // computed values are.
1653 SizeToAvailSize(aReflowState, aDesiredSize);
1655 aDesiredSize.mOverflowArea = nsRect(0, 0,
1656 aDesiredSize.width, aDesiredSize.height);
1657 aStatus = NS_FRAME_COMPLETE;
1658 return NS_OK;
1661 class nsDisplayFramesetBorder : public nsDisplayItem {
1662 public:
1663 nsDisplayFramesetBorder(nsHTMLFramesetBorderFrame* aFrame)
1664 : nsDisplayItem(aFrame) {
1665 MOZ_COUNT_CTOR(nsDisplayFramesetBorder);
1667 #ifdef NS_BUILD_REFCNT_LOGGING
1668 virtual ~nsDisplayFramesetBorder() {
1669 MOZ_COUNT_DTOR(nsDisplayFramesetBorder);
1671 #endif
1673 // REVIEW: see old GetFrameForPoint
1674 // Receives events in its bounds
1675 virtual nsIFrame* HitTest(nsDisplayListBuilder* aBuilder, nsPoint aPt,
1676 HitTestState* aState) { return mFrame; }
1677 virtual void Paint(nsDisplayListBuilder* aBuilder, nsIRenderingContext* aCtx,
1678 const nsRect& aDirtyRect);
1679 NS_DISPLAY_DECL_NAME("FramesetBorder")
1682 void nsDisplayFramesetBorder::Paint(nsDisplayListBuilder* aBuilder,
1683 nsIRenderingContext* aCtx, const nsRect& aDirtyRect)
1685 static_cast<nsHTMLFramesetBorderFrame*>(mFrame)->
1686 PaintBorder(*aCtx, aBuilder->ToReferenceFrame(mFrame));
1689 NS_IMETHODIMP
1690 nsHTMLFramesetBorderFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
1691 const nsRect& aDirtyRect,
1692 const nsDisplayListSet& aLists)
1694 nsDisplayItem* item = new (aBuilder) nsDisplayFramesetBorder(this);
1695 if (!item)
1696 return NS_ERROR_OUT_OF_MEMORY;
1697 aLists.Content()->AppendToTop(item);
1698 return NS_OK;
1701 void nsHTMLFramesetBorderFrame::PaintBorder(nsIRenderingContext& aRenderingContext,
1702 nsPoint aPt)
1704 nscolor WHITE = NS_RGB(255, 255, 255);
1705 nscolor bgColor = NS_RGB(200,200,200);
1706 nscolor fgColor = NS_RGB(0,0,0);
1707 nscolor hltColor = NS_RGB(255,255,255);
1708 nscolor sdwColor = NS_RGB(128,128,128);
1710 nsIRenderingContext::AutoPushTranslation
1711 translate(&aRenderingContext, aPt.x, aPt.y);
1714 nsCOMPtr<nsILookAndFeel> lookAndFeel = do_GetService(kLookAndFeelCID);
1715 if (lookAndFeel) {
1716 lookAndFeel->GetColor(nsILookAndFeel::eColor_WidgetBackground, bgColor);
1717 lookAndFeel->GetColor(nsILookAndFeel::eColor_WidgetForeground, fgColor);
1718 lookAndFeel->GetColor(nsILookAndFeel::eColor_Widget3DShadow, sdwColor);
1719 lookAndFeel->GetColor(nsILookAndFeel::eColor_Widget3DHighlight, hltColor);
1723 nscoord widthInPixels = nsPresContext::AppUnitsToIntCSSPixels(mWidth);
1724 nscoord pixelWidth = nsPresContext::CSSPixelsToAppUnits(1);
1726 if (widthInPixels <= 0)
1727 return;
1729 nscoord x0 = 0;
1730 nscoord y0 = 0;
1731 nscoord x1 = (mVertical) ? 0 : mRect.width;
1732 nscoord y1 = (mVertical) ? mRect.height : 0;
1734 nscolor color = WHITE;
1735 if (mVisibility || mVisibilityOverride) {
1736 color = (NO_COLOR == mColor) ? bgColor : mColor;
1738 aRenderingContext.SetColor(color);
1739 // draw grey or white first
1740 for (int i = 0; i < widthInPixels; i++) {
1741 aRenderingContext.DrawLine (x0, y0, x1, y1);
1742 if (mVertical) {
1743 x0 += pixelWidth;
1744 x1 = x0;
1745 } else {
1746 y0 += pixelWidth;
1747 y1 = y0;
1751 if (!mVisibility && !mVisibilityOverride)
1752 return;
1754 if (widthInPixels >= 5) {
1755 aRenderingContext.SetColor(hltColor);
1756 x0 = (mVertical) ? pixelWidth : 0;
1757 y0 = (mVertical) ? 0 : pixelWidth;
1758 x1 = (mVertical) ? x0 : mRect.width;
1759 y1 = (mVertical) ? mRect.height : y0;
1760 aRenderingContext.DrawLine(x0, y0, x1, y1);
1763 if (widthInPixels >= 2) {
1764 aRenderingContext.SetColor(sdwColor);
1765 x0 = (mVertical) ? mRect.width - (2 * pixelWidth) : 0;
1766 y0 = (mVertical) ? 0 : mRect.height - (2 * pixelWidth);
1767 x1 = (mVertical) ? x0 : mRect.width;
1768 y1 = (mVertical) ? mRect.height : y0;
1769 aRenderingContext.DrawLine(x0, y0, x1, y1);
1772 if (widthInPixels >= 1) {
1773 aRenderingContext.SetColor(fgColor);
1774 x0 = (mVertical) ? mRect.width - pixelWidth : 0;
1775 y0 = (mVertical) ? 0 : mRect.height - pixelWidth;
1776 x1 = (mVertical) ? x0 : mRect.width;
1777 y1 = (mVertical) ? mRect.height : y0;
1778 aRenderingContext.DrawLine(x0, y0, x1, y1);
1783 NS_IMETHODIMP
1784 nsHTMLFramesetBorderFrame::HandleEvent(nsPresContext* aPresContext,
1785 nsGUIEvent* aEvent,
1786 nsEventStatus* aEventStatus)
1788 NS_ENSURE_ARG_POINTER(aEventStatus);
1789 *aEventStatus = nsEventStatus_eIgnore;
1791 //XXX Mouse setting logic removed. The remaining logic should also move.
1792 if (!mCanResize) {
1793 return NS_OK;
1796 if (aEvent->eventStructType == NS_MOUSE_EVENT &&
1797 aEvent->message == NS_MOUSE_BUTTON_DOWN &&
1798 static_cast<nsMouseEvent*>(aEvent)->button == nsMouseEvent::eLeftButton) {
1799 nsHTMLFramesetFrame* parentFrame;
1800 nsIFrame* fptr = GetParent();
1801 parentFrame = (nsHTMLFramesetFrame*) fptr;
1802 parentFrame->StartMouseDrag(aPresContext, this, aEvent);
1803 *aEventStatus = nsEventStatus_eConsumeNoDefault;
1805 return NS_OK;
1808 NS_IMETHODIMP
1809 nsHTMLFramesetBorderFrame::GetCursor(const nsPoint& aPoint,
1810 nsIFrame::Cursor& aCursor)
1812 if (!mCanResize) {
1813 aCursor.mCursor = NS_STYLE_CURSOR_DEFAULT;
1814 } else {
1815 aCursor.mCursor = (mVertical) ? NS_STYLE_CURSOR_W_RESIZE : NS_STYLE_CURSOR_N_RESIZE;
1817 return NS_OK;
1820 #ifdef DEBUG
1821 NS_IMETHODIMP nsHTMLFramesetBorderFrame::GetFrameName(nsAString& aResult) const
1823 return MakeFrameName(NS_LITERAL_STRING("FramesetBorder"), aResult);
1825 #endif
1827 /*******************************************************************************
1828 * nsHTMLFramesetBlankFrame
1829 ******************************************************************************/
1831 nsHTMLFramesetBlankFrame::~nsHTMLFramesetBlankFrame()
1833 //printf("nsHTMLFramesetBlankFrame destructor %p \n", this);
1836 nscoord nsHTMLFramesetBlankFrame::GetIntrinsicWidth()
1838 // No intrinsic width
1839 return 0;
1842 NS_IMETHODIMP
1843 nsHTMLFramesetBlankFrame::Reflow(nsPresContext* aPresContext,
1844 nsHTMLReflowMetrics& aDesiredSize,
1845 const nsHTMLReflowState& aReflowState,
1846 nsReflowStatus& aStatus)
1848 DO_GLOBAL_REFLOW_COUNT("nsHTMLFramesetBlankFrame");
1850 // Override Reflow(), since we don't want to deal with what our
1851 // computed values are.
1852 SizeToAvailSize(aReflowState, aDesiredSize);
1854 aDesiredSize.mOverflowArea = nsRect(0, 0,
1855 aDesiredSize.width, aDesiredSize.height);
1856 aStatus = NS_FRAME_COMPLETE;
1857 return NS_OK;
1860 class nsDisplayFramesetBlank : public nsDisplayItem {
1861 public:
1862 nsDisplayFramesetBlank(nsIFrame* aFrame) : nsDisplayItem(aFrame) {
1863 MOZ_COUNT_CTOR(nsDisplayFramesetBlank);
1865 #ifdef NS_BUILD_REFCNT_LOGGING
1866 virtual ~nsDisplayFramesetBlank() {
1867 MOZ_COUNT_DTOR(nsDisplayFramesetBlank);
1869 #endif
1871 virtual void Paint(nsDisplayListBuilder* aBuilder, nsIRenderingContext* aCtx,
1872 const nsRect& aDirtyRect);
1873 NS_DISPLAY_DECL_NAME("FramesetBlank")
1875 void nsDisplayFramesetBlank::Paint(nsDisplayListBuilder* aBuilder,
1876 nsIRenderingContext* aCtx, const nsRect& aDirtyRect)
1878 nscolor white = NS_RGB(255,255,255);
1879 aCtx->SetColor (white);
1880 aCtx->FillRect (nsRect(aBuilder->ToReferenceFrame(mFrame), mFrame->GetSize()));
1883 #ifdef DEBUG
1884 NS_IMETHODIMP nsHTMLFramesetBlankFrame::List(FILE* out,
1885 PRInt32 aIndent) const
1887 for (PRInt32 i = aIndent; --i >= 0; ) fputs(" ", out); // Indent
1888 fprintf(out, "%p BLANK \n", (void*)this);
1889 return nsLeafFrame::List(out, aIndent);
1891 #endif
1893 NS_IMETHODIMP
1894 nsHTMLFramesetBlankFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
1895 const nsRect& aDirtyRect,
1896 const nsDisplayListSet& aLists)
1898 nsDisplayItem* item = new (aBuilder) nsDisplayFramesetBlank(this);
1899 if (!item)
1900 return NS_ERROR_OUT_OF_MEMORY;
1901 aLists.Content()->AppendToTop(item);
1902 return NS_OK;