1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla 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/MPL/
*
* 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.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsTableOuterFrame_h__
#define nsTableOuterFrame_h__
#include "nscore.h"
#include "nsHTMLContainerFrame.h"
#include "nsBlockFrame.h"
#include "nsITableLayout.h"
#ifdef DEBUG_TABLE_REFLOW_TIMING
class nsReflowTimer;
#endif
struct nsStyleTable;
class nsTableFrame;
class nsTableCaptionFrame : public nsBlockFrame
{
public:
// nsISupports
virtual nsIAtom* GetType() const;
friend nsresult NS_NewTableCaptionFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame);
protected:
nsTableCaptionFrame();
virtual ~nsTableCaptionFrame();
};
/* TODO
1. decide if we'll allow subclassing. If so, decide which methods really need to be virtual.
*/
/**
* main frame for an nsTable content object,
* the nsTableOuterFrame contains 0 or one caption frame, and a nsTableFrame
* pseudo-frame (referred to as the "inner frame').
*/
class nsTableOuterFrame : public nsHTMLContainerFrame, public nsITableLayout
{
public:
// nsISupports
NS_DECL_ISUPPORTS_INHERITED
/** instantiate a new instance of nsTableOuterFrame.
* @param aPresShell the presentation shell
* @param aResult the new object is returned in this out-param
*
* @return NS_OK if the frame was properly allocated, otherwise an error code
*/
friend nsresult NS_NewTableOuterFrame(nsIPresShell* aPresShell, nsIFrame** aResult);
// nsIFrame overrides - see there for a description
NS_IMETHOD Init(nsPresContext* aPresContext,
nsIContent* aContent,
nsIFrame* aParent,
nsStyleContext* aContext,
nsIFrame* aPrevInFlow);
NS_IMETHOD Destroy(nsPresContext* aPresContext);
virtual PRBool IsContainingBlock() const;
NS_IMETHOD SetInitialChildList(nsPresContext* aPresContext,
nsIAtom* aListName,
nsIFrame* aChildList);
virtual nsIFrame* GetFirstChild(nsIAtom* aListName) const;
virtual nsIAtom* GetAdditionalChildListName(PRInt32 aIndex) const;
NS_IMETHOD AppendFrames(nsIAtom* aListName,
nsIFrame* aFrameList);
NS_IMETHOD InsertFrames(nsIAtom* aListName,
nsIFrame* aPrevFrame,
nsIFrame* aFrameList);
NS_IMETHOD RemoveFrame(nsIAtom* aListName,
nsIFrame* aOldFrame);
virtual nsIFrame* GetContentInsertionFrame() {
return GetFirstChild(nsnull)->GetContentInsertionFrame();
}
#ifdef ACCESSIBILITY
NS_IMETHOD GetAccessible(nsIAccessible** aAccessible);
#endif
/** @see nsIFrame::Paint */
NS_IMETHOD Paint(nsPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer,
PRUint32 aFlags = 0);
// the outer table does not paint its entire background if it has margins and/or captions
virtual PRBool CanPaintBackground() { return PR_FALSE; }
NS_IMETHOD GetFrameForPoint(const nsPoint& aPoint,
nsFramePaintLayer aWhichLayer,
nsIFrame** aFrame);
/** process a reflow command for the table.
* This involves reflowing the caption and the inner table.
* @see nsIFrame::Reflow */
NS_IMETHOD Reflow(nsPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
/**
* Get the "type" of the frame
*
* @see nsLayoutAtoms::tableOuterFrame
*/
virtual nsIAtom* GetType() const;
#ifdef DEBUG
NS_IMETHOD GetFrameName(nsAString& aResult) const;
#endif
/** SetSelected needs to be overridden to talk to inner tableframe
*/
NS_IMETHOD SetSelected(nsPresContext* aPresContext,
nsIDOMRange *aRange,
PRBool aSelected,
nsSpread aSpread);
/** return the min width of the caption. Return 0 if there is no caption.
* The return value is only meaningful after the caption has had a pass1 reflow.
*/
nscoord GetMinCaptionWidth();
NS_IMETHOD GetParentStyleContextFrame(nsPresContext* aPresContext,
nsIFrame** aProviderFrame,
PRBool* aIsChild);
/*---------------- nsITableLayout methods ------------------------*/
/** @see nsITableFrame::GetCellDataAt */
NS_IMETHOD GetCellDataAt(PRInt32 aRowIndex, PRInt32 aColIndex,
nsIDOMElement* &aCell, //out params
PRInt32& aStartRowIndex, PRInt32& aStartColIndex,
PRInt32& aRowSpan, PRInt32& aColSpan,
PRInt32& aActualRowSpan, PRInt32& aActualColSpan,
PRBool& aIsSelected);
/** @see nsITableFrame::GetTableSize */
NS_IMETHOD GetTableSize(PRInt32& aRowCount, PRInt32& aColCount);
static void ZeroAutoMargin(nsHTMLReflowState& aReflowState,
nsMargin& aMargin);
PRBool IsNested(const nsHTMLReflowState& aReflowState) const;
static PRBool IsAutoWidth(nsIFrame& aTableOrCaption,
PRBool* aIsPctWidth = nsnull);
protected:
nsTableOuterFrame();
virtual ~nsTableOuterFrame();
void InitChildReflowState(nsPresContext& aPresContext,
nsHTMLReflowState& aReflowState);
/** Always returns 0, since the outer table frame has no border of its own
* The inner table frame can answer this question in a meaningful way.
* @see nsHTMLContainerFrame::GetSkipSides */
virtual PRIntn GetSkipSides() const;
/** overridden here to handle special caption-table relationship
* @see nsContainerFrame::VerifyTree
*/
NS_IMETHOD VerifyTree() const;
/**
* Remove and delete aChild's next-in-flow(s). Updates the sibling and flow
* pointers.
*
* Updates the child count and content offsets of all containers that are
* affected
*
* Overloaded here because nsContainerFrame makes assumptions about pseudo-frames
* that are not true for tables.
*
* @param aChild child this child's next-in-flow
* @return PR_TRUE if successful and PR_FALSE otherwise
*/
virtual void DeleteChildsNextInFlow(nsPresContext* aPresContext, nsIFrame* aChild);
// begin Incremental Reflow methods
/** process an incremental reflow command */
NS_IMETHOD IncrementalReflow(nsPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
/** process an incremental reflow command targeted at a child of this frame. */
NS_IMETHOD IR_TargetIsChild(nsPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus,
nsIFrame * aNextFrame);
/** process an incremental reflow command targeted at the table inner frame. */
NS_IMETHOD IR_TargetIsInnerTableFrame(nsPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
/** process an incremental reflow command targeted at the caption. */
NS_IMETHOD IR_TargetIsCaptionFrame(nsPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
/** process an incremental reflow command targeted at this frame.
* many incremental reflows that are targeted at this outer frame
* are actually handled by the inner frame. The logic to decide this
* is here.
*/
NS_IMETHOD IR_TargetIsMe(nsPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
/** pass along the incremental reflow command to the inner table. */
NS_IMETHOD IR_InnerTableReflow(nsPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
/** handle incremental reflow notification that a caption was inserted. */
NS_IMETHOD IR_CaptionInserted(nsPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
/** handle incremental reflow notification that we have dirty child frames */
NS_IMETHOD IR_ReflowDirty(nsPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
/** handle incremental reflow notification that the caption style was changed
* such that it is now left|right instead of top|bottom, or vice versa.
*/
PRBool IR_CaptionChangedAxis(const nsStyleTable* aOldStyle,
const nsStyleTable* aNewStyle) const;
// end Incremental Reflow methods
nscoord GetMaxElementWidth(PRUint8 aCaptionSide,
const nsMargin& aInnerMargin,
const nsMargin& aInnerPadding,
const nsMargin& aCaptionMargin);
nscoord GetMaxWidth(PRUint8 aCaptionSide,
const nsMargin& aInnerMargin,
const nsMargin& aCaptionMargin);
PRUint8 GetCaptionSide();
PRUint8 GetCaptionVerticalAlign();
void SetDesiredSize(PRUint8 aCaptionSide,
const nsMargin& aInnerMargin,
const nsMargin& aCaptionMargin,
nscoord aAvailWidth,
nscoord& aWidth,
nscoord& aHeight);
void PctAdjustMinCaptionWidth(nsPresContext* aPresContext,
const nsHTMLReflowState& aOuterRS,
PRUint8 aCaptionSide,
nscoord& capMin);
void BalanceLeftRightCaption(PRUint8 aCaptionSide,
const nsMargin& aInnerMargin,
const nsMargin& aCaptionMargin,
nscoord& aInnerWidth,
nscoord& aCaptionWidth);
NS_IMETHOD GetCaptionOrigin(nsPresContext* aPresContext,
PRUint32 aCaptionSide,
const nsSize& aContainBlockSize,
const nsSize& aInnerSize,
const nsMargin& aInnerMargin,
const nsSize& aCaptionSize,
nsMargin& aCaptionMargin,
nsPoint& aOrigin);
NS_IMETHOD GetInnerOrigin(nsPresContext* aPresContext,
PRUint32 aCaptionSide,
const nsSize& aContainBlockSize,
const nsSize& aCaptionSize,
const nsMargin& aCaptionMargin,
const nsSize& aInnerSize,
nsMargin& aInnerMargin,
nsPoint& aOrigin);
// Get the available width for the caption, aInnerMarginNoAuto is aInnerMargin, but with
// auto margins set to 0
nscoord GetCaptionAvailWidth(nsPresContext* aPresContext,
nsIFrame* aCaptionFrame,
const nsHTMLReflowState& aReflowState,
nsMargin& aCaptionMargin,
nsMargin& aCaptionPad,
nscoord* aInnerWidth = nsnull,
const nsMargin* aInnerMarginNoAuto = nsnull,
const nsMargin* aInnerMargin = nsnull);
nscoord GetInnerTableAvailWidth(nsPresContext* aPresContext,
nsIFrame* aInnerTable,
const nsHTMLReflowState& aOuterRS,
nscoord* aCaptionWidth,
nsMargin& aInnerMargin,
nsMargin& aInnerPadding);
// reflow the child (caption or innertable frame),aMarginNoAuto is aMargin,
// but with auto margins set to 0
NS_IMETHOD OuterReflowChild(nsPresContext* aPresContext,
nsIFrame* aChildFrame,
const nsHTMLReflowState& aOuterRS,
nsHTMLReflowMetrics& aMetrics,
nscoord aAvailWidth,
nsSize& aDesiredSize,
nsMargin& aMargin,
nsMargin& aMarginNoAuto,
nsMargin& aPadding,
nsReflowReason aReflowReason,
nsReflowStatus& aStatus,
PRBool* aNeedToReflowCaption = nsnull);
// Set the reflow metrics, aInnerMarginNoAuto is aInnerMargin, but with
// auto margins set to 0
// aCaptionMargionNoAuto is aCaptionMargin, but with auto margins set to 0
void UpdateReflowMetrics(PRUint8 aCaptionSide,
nsHTMLReflowMetrics& aMet,
const nsMargin& aInnerMargin,
const nsMargin& aInnerMarginNoAuto,
const nsMargin& aInnerPadding,
const nsMargin& aCaptionMargin,
const nsMargin& aCaptionMargionNoAuto,
const nscoord aAvailWidth);
void InvalidateDamage(PRUint8 aCaptionSide,
const nsSize& aOuterSize,
PRBool aInnerChanged,
PRBool aCaptionChanged,
nsRect* aOldOverflowArea);
// Get the margin and padding, aMarginNoAuto is aMargin, but with auto
// margins set to 0
void GetMarginPadding(nsPresContext* aPresContext,
const nsHTMLReflowState& aOuterRS,
nsIFrame* aChildFrame,
nscoord aAvailableWidth,
nsMargin& aMargin,
nsMargin& aMarginNoAuto,
nsMargin& aPadding);
private:
// used to keep track of this frame's children. They are redundant with mFrames, but more convient
nsTableFrame* mInnerTableFrame;
nsFrameList mCaptionFrames;
nsIFrame* mCaptionFrame;
// used to track caption max element size
PRInt32 mMinCaptionWidth;
nscoord mPriorAvailWidth;
#ifdef DEBUG_TABLE_REFLOW_TIMING
public:
nsReflowTimer* mTimer;
#endif
};
inline nscoord nsTableOuterFrame::GetMinCaptionWidth()
{ return mMinCaptionWidth; }
inline PRIntn nsTableOuterFrame::GetSkipSides() const
{ return 0; }
#endif
|