Wed, 31 Dec 2014 13:27:57 +0100
Ignore runtime configuration files generated during quality assurance.
michael@0 | 1 | /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
michael@0 | 2 | /* This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 5 | #include "nsTableColGroupFrame.h" |
michael@0 | 6 | #include "nsTableColFrame.h" |
michael@0 | 7 | #include "nsTableFrame.h" |
michael@0 | 8 | #include "nsStyleContext.h" |
michael@0 | 9 | #include "nsStyleConsts.h" |
michael@0 | 10 | #include "nsPresContext.h" |
michael@0 | 11 | #include "nsHTMLParts.h" |
michael@0 | 12 | #include "nsGkAtoms.h" |
michael@0 | 13 | #include "nsCOMPtr.h" |
michael@0 | 14 | #include "nsCSSRendering.h" |
michael@0 | 15 | #include "nsIPresShell.h" |
michael@0 | 16 | |
michael@0 | 17 | #define COL_GROUP_TYPE_BITS (NS_FRAME_STATE_BIT(30) | \ |
michael@0 | 18 | NS_FRAME_STATE_BIT(31)) |
michael@0 | 19 | #define COL_GROUP_TYPE_OFFSET 30 |
michael@0 | 20 | |
michael@0 | 21 | nsTableColGroupType |
michael@0 | 22 | nsTableColGroupFrame::GetColType() const |
michael@0 | 23 | { |
michael@0 | 24 | return (nsTableColGroupType)((mState & COL_GROUP_TYPE_BITS) >> COL_GROUP_TYPE_OFFSET); |
michael@0 | 25 | } |
michael@0 | 26 | |
michael@0 | 27 | void nsTableColGroupFrame::SetColType(nsTableColGroupType aType) |
michael@0 | 28 | { |
michael@0 | 29 | NS_ASSERTION(GetColType() == eColGroupContent, |
michael@0 | 30 | "should only call nsTableColGroupFrame::SetColType with aType " |
michael@0 | 31 | "!= eColGroupContent once"); |
michael@0 | 32 | uint32_t type = aType - eColGroupContent; |
michael@0 | 33 | RemoveStateBits(COL_GROUP_TYPE_BITS); |
michael@0 | 34 | AddStateBits(nsFrameState(type << COL_GROUP_TYPE_OFFSET)); |
michael@0 | 35 | } |
michael@0 | 36 | |
michael@0 | 37 | void nsTableColGroupFrame::ResetColIndices(nsIFrame* aFirstColGroup, |
michael@0 | 38 | int32_t aFirstColIndex, |
michael@0 | 39 | nsIFrame* aStartColFrame) |
michael@0 | 40 | { |
michael@0 | 41 | nsTableColGroupFrame* colGroupFrame = (nsTableColGroupFrame*)aFirstColGroup; |
michael@0 | 42 | int32_t colIndex = aFirstColIndex; |
michael@0 | 43 | while (colGroupFrame) { |
michael@0 | 44 | if (nsGkAtoms::tableColGroupFrame == colGroupFrame->GetType()) { |
michael@0 | 45 | // reset the starting col index for the first cg only if we should reset |
michael@0 | 46 | // the whole colgroup (aStartColFrame defaults to nullptr) or if |
michael@0 | 47 | // aFirstColIndex is smaller than the existing starting col index |
michael@0 | 48 | if ((colIndex != aFirstColIndex) || |
michael@0 | 49 | (colIndex < colGroupFrame->GetStartColumnIndex()) || |
michael@0 | 50 | !aStartColFrame) { |
michael@0 | 51 | colGroupFrame->SetStartColumnIndex(colIndex); |
michael@0 | 52 | } |
michael@0 | 53 | nsIFrame* colFrame = aStartColFrame; |
michael@0 | 54 | if (!colFrame || (colIndex != aFirstColIndex)) { |
michael@0 | 55 | colFrame = colGroupFrame->GetFirstPrincipalChild(); |
michael@0 | 56 | } |
michael@0 | 57 | while (colFrame) { |
michael@0 | 58 | if (nsGkAtoms::tableColFrame == colFrame->GetType()) { |
michael@0 | 59 | ((nsTableColFrame*)colFrame)->SetColIndex(colIndex); |
michael@0 | 60 | colIndex++; |
michael@0 | 61 | } |
michael@0 | 62 | colFrame = colFrame->GetNextSibling(); |
michael@0 | 63 | } |
michael@0 | 64 | } |
michael@0 | 65 | colGroupFrame = static_cast<nsTableColGroupFrame*> |
michael@0 | 66 | (colGroupFrame->GetNextSibling()); |
michael@0 | 67 | } |
michael@0 | 68 | } |
michael@0 | 69 | |
michael@0 | 70 | |
michael@0 | 71 | nsresult |
michael@0 | 72 | nsTableColGroupFrame::AddColsToTable(int32_t aFirstColIndex, |
michael@0 | 73 | bool aResetSubsequentColIndices, |
michael@0 | 74 | const nsFrameList::Slice& aCols) |
michael@0 | 75 | { |
michael@0 | 76 | nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(this); |
michael@0 | 77 | |
michael@0 | 78 | tableFrame->InvalidateFrameSubtree(); |
michael@0 | 79 | |
michael@0 | 80 | // set the col indices of the col frames and and add col info to the table |
michael@0 | 81 | int32_t colIndex = aFirstColIndex; |
michael@0 | 82 | nsFrameList::Enumerator e(aCols); |
michael@0 | 83 | for (; !e.AtEnd(); e.Next()) { |
michael@0 | 84 | ((nsTableColFrame*)e.get())->SetColIndex(colIndex); |
michael@0 | 85 | mColCount++; |
michael@0 | 86 | tableFrame->InsertCol((nsTableColFrame &)*e.get(), colIndex); |
michael@0 | 87 | colIndex++; |
michael@0 | 88 | } |
michael@0 | 89 | |
michael@0 | 90 | for (nsFrameList::Enumerator eTail = e.GetUnlimitedEnumerator(); |
michael@0 | 91 | !eTail.AtEnd(); |
michael@0 | 92 | eTail.Next()) { |
michael@0 | 93 | ((nsTableColFrame*)eTail.get())->SetColIndex(colIndex); |
michael@0 | 94 | colIndex++; |
michael@0 | 95 | } |
michael@0 | 96 | |
michael@0 | 97 | // We have already set the colindex for all the colframes in this |
michael@0 | 98 | // colgroup that come after the first inserted colframe, but there could |
michael@0 | 99 | // be other colgroups following this one and their colframes need |
michael@0 | 100 | // correct colindices too. |
michael@0 | 101 | if (aResetSubsequentColIndices && GetNextSibling()) { |
michael@0 | 102 | ResetColIndices(GetNextSibling(), colIndex); |
michael@0 | 103 | } |
michael@0 | 104 | |
michael@0 | 105 | return NS_OK; |
michael@0 | 106 | } |
michael@0 | 107 | |
michael@0 | 108 | |
michael@0 | 109 | nsTableColGroupFrame* |
michael@0 | 110 | nsTableColGroupFrame::GetLastRealColGroup(nsTableFrame* aTableFrame) |
michael@0 | 111 | { |
michael@0 | 112 | nsFrameList colGroups = aTableFrame->GetColGroups(); |
michael@0 | 113 | |
michael@0 | 114 | nsIFrame* nextToLastColGroup = nullptr; |
michael@0 | 115 | nsFrameList::FrameLinkEnumerator link(colGroups); |
michael@0 | 116 | for ( ; !link.AtEnd(); link.Next()) { |
michael@0 | 117 | nextToLastColGroup = link.PrevFrame(); |
michael@0 | 118 | } |
michael@0 | 119 | |
michael@0 | 120 | if (!link.PrevFrame()) { |
michael@0 | 121 | return nullptr; // there are no col group frames |
michael@0 | 122 | } |
michael@0 | 123 | |
michael@0 | 124 | nsTableColGroupType lastColGroupType = |
michael@0 | 125 | static_cast<nsTableColGroupFrame*>(link.PrevFrame())->GetColType(); |
michael@0 | 126 | if (eColGroupAnonymousCell == lastColGroupType) { |
michael@0 | 127 | return static_cast<nsTableColGroupFrame*>(nextToLastColGroup); |
michael@0 | 128 | } |
michael@0 | 129 | |
michael@0 | 130 | return static_cast<nsTableColGroupFrame*>(link.PrevFrame()); |
michael@0 | 131 | } |
michael@0 | 132 | |
michael@0 | 133 | // don't set mColCount here, it is done in AddColsToTable |
michael@0 | 134 | nsresult |
michael@0 | 135 | nsTableColGroupFrame::SetInitialChildList(ChildListID aListID, |
michael@0 | 136 | nsFrameList& aChildList) |
michael@0 | 137 | { |
michael@0 | 138 | if (!mFrames.IsEmpty()) { |
michael@0 | 139 | // We already have child frames which means we've already been |
michael@0 | 140 | // initialized |
michael@0 | 141 | NS_NOTREACHED("unexpected second call to SetInitialChildList"); |
michael@0 | 142 | return NS_ERROR_UNEXPECTED; |
michael@0 | 143 | } |
michael@0 | 144 | if (aListID != kPrincipalList) { |
michael@0 | 145 | // All we know about is the principal child list. |
michael@0 | 146 | NS_NOTREACHED("unknown frame list"); |
michael@0 | 147 | return NS_ERROR_INVALID_ARG; |
michael@0 | 148 | } |
michael@0 | 149 | nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(this); |
michael@0 | 150 | if (aChildList.IsEmpty()) { |
michael@0 | 151 | tableFrame->AppendAnonymousColFrames(this, GetSpan(), eColAnonymousColGroup, |
michael@0 | 152 | false); |
michael@0 | 153 | return NS_OK; |
michael@0 | 154 | } |
michael@0 | 155 | |
michael@0 | 156 | mFrames.AppendFrames(this, aChildList); |
michael@0 | 157 | return NS_OK; |
michael@0 | 158 | } |
michael@0 | 159 | |
michael@0 | 160 | /* virtual */ void |
michael@0 | 161 | nsTableColGroupFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext) |
michael@0 | 162 | { |
michael@0 | 163 | nsContainerFrame::DidSetStyleContext(aOldStyleContext); |
michael@0 | 164 | |
michael@0 | 165 | if (!aOldStyleContext) //avoid this on init |
michael@0 | 166 | return; |
michael@0 | 167 | |
michael@0 | 168 | nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(this); |
michael@0 | 169 | if (tableFrame->IsBorderCollapse() && |
michael@0 | 170 | tableFrame->BCRecalcNeeded(aOldStyleContext, StyleContext())) { |
michael@0 | 171 | int32_t colCount = GetColCount(); |
michael@0 | 172 | if (!colCount) |
michael@0 | 173 | return; // this is a degenerated colgroup |
michael@0 | 174 | nsIntRect damageArea(GetFirstColumn()->GetColIndex(), 0, colCount, |
michael@0 | 175 | tableFrame->GetRowCount()); |
michael@0 | 176 | tableFrame->AddBCDamageArea(damageArea); |
michael@0 | 177 | } |
michael@0 | 178 | } |
michael@0 | 179 | |
michael@0 | 180 | nsresult |
michael@0 | 181 | nsTableColGroupFrame::AppendFrames(ChildListID aListID, |
michael@0 | 182 | nsFrameList& aFrameList) |
michael@0 | 183 | { |
michael@0 | 184 | NS_ASSERTION(aListID == kPrincipalList, "unexpected child list"); |
michael@0 | 185 | |
michael@0 | 186 | nsTableColFrame* col = GetFirstColumn(); |
michael@0 | 187 | nsTableColFrame* nextCol; |
michael@0 | 188 | while (col && col->GetColType() == eColAnonymousColGroup) { |
michael@0 | 189 | // this colgroup spans one or more columns but now that there is a |
michael@0 | 190 | // real column below, spanned anonymous columns should be removed, |
michael@0 | 191 | // since the HTML spec says to ignore the span of a colgroup if it |
michael@0 | 192 | // has content columns in it. |
michael@0 | 193 | nextCol = col->GetNextCol(); |
michael@0 | 194 | RemoveFrame(kPrincipalList, col); |
michael@0 | 195 | col = nextCol; |
michael@0 | 196 | } |
michael@0 | 197 | |
michael@0 | 198 | const nsFrameList::Slice& newFrames = |
michael@0 | 199 | mFrames.AppendFrames(this, aFrameList); |
michael@0 | 200 | InsertColsReflow(GetStartColumnIndex() + mColCount, newFrames); |
michael@0 | 201 | return NS_OK; |
michael@0 | 202 | } |
michael@0 | 203 | |
michael@0 | 204 | nsresult |
michael@0 | 205 | nsTableColGroupFrame::InsertFrames(ChildListID aListID, |
michael@0 | 206 | nsIFrame* aPrevFrame, |
michael@0 | 207 | nsFrameList& aFrameList) |
michael@0 | 208 | { |
michael@0 | 209 | NS_ASSERTION(aListID == kPrincipalList, "unexpected child list"); |
michael@0 | 210 | NS_ASSERTION(!aPrevFrame || aPrevFrame->GetParent() == this, |
michael@0 | 211 | "inserting after sibling frame with different parent"); |
michael@0 | 212 | |
michael@0 | 213 | nsTableColFrame* col = GetFirstColumn(); |
michael@0 | 214 | nsTableColFrame* nextCol; |
michael@0 | 215 | while (col && col->GetColType() == eColAnonymousColGroup) { |
michael@0 | 216 | // this colgroup spans one or more columns but now that there is a |
michael@0 | 217 | // real column below, spanned anonymous columns should be removed, |
michael@0 | 218 | // since the HTML spec says to ignore the span of a colgroup if it |
michael@0 | 219 | // has content columns in it. |
michael@0 | 220 | nextCol = col->GetNextCol(); |
michael@0 | 221 | if (col == aPrevFrame) { |
michael@0 | 222 | // This can happen when we're being appended to |
michael@0 | 223 | NS_ASSERTION(!nextCol || nextCol->GetColType() != eColAnonymousColGroup, |
michael@0 | 224 | "Inserting in the middle of our anonymous cols?"); |
michael@0 | 225 | // We'll want to insert at the beginning |
michael@0 | 226 | aPrevFrame = nullptr; |
michael@0 | 227 | } |
michael@0 | 228 | RemoveFrame(kPrincipalList, col); |
michael@0 | 229 | col = nextCol; |
michael@0 | 230 | } |
michael@0 | 231 | |
michael@0 | 232 | NS_ASSERTION(!aPrevFrame || aPrevFrame == aPrevFrame->LastContinuation(), |
michael@0 | 233 | "Prev frame should be last in continuation chain"); |
michael@0 | 234 | NS_ASSERTION(!aPrevFrame || !GetNextColumn(aPrevFrame) || |
michael@0 | 235 | GetNextColumn(aPrevFrame)->GetColType() != eColAnonymousCol, |
michael@0 | 236 | "Shouldn't be inserting before a spanned colframe"); |
michael@0 | 237 | |
michael@0 | 238 | const nsFrameList::Slice& newFrames = |
michael@0 | 239 | mFrames.InsertFrames(this, aPrevFrame, aFrameList); |
michael@0 | 240 | nsIFrame* prevFrame = nsTableFrame::GetFrameAtOrBefore(this, aPrevFrame, |
michael@0 | 241 | nsGkAtoms::tableColFrame); |
michael@0 | 242 | |
michael@0 | 243 | int32_t colIndex = (prevFrame) ? ((nsTableColFrame*)prevFrame)->GetColIndex() + 1 : GetStartColumnIndex(); |
michael@0 | 244 | InsertColsReflow(colIndex, newFrames); |
michael@0 | 245 | |
michael@0 | 246 | return NS_OK; |
michael@0 | 247 | } |
michael@0 | 248 | |
michael@0 | 249 | void |
michael@0 | 250 | nsTableColGroupFrame::InsertColsReflow(int32_t aColIndex, |
michael@0 | 251 | const nsFrameList::Slice& aCols) |
michael@0 | 252 | { |
michael@0 | 253 | AddColsToTable(aColIndex, true, aCols); |
michael@0 | 254 | |
michael@0 | 255 | PresContext()->PresShell()->FrameNeedsReflow(this, |
michael@0 | 256 | nsIPresShell::eTreeChange, |
michael@0 | 257 | NS_FRAME_HAS_DIRTY_CHILDREN); |
michael@0 | 258 | } |
michael@0 | 259 | |
michael@0 | 260 | void |
michael@0 | 261 | nsTableColGroupFrame::RemoveChild(nsTableColFrame& aChild, |
michael@0 | 262 | bool aResetSubsequentColIndices) |
michael@0 | 263 | { |
michael@0 | 264 | int32_t colIndex = 0; |
michael@0 | 265 | nsIFrame* nextChild = nullptr; |
michael@0 | 266 | if (aResetSubsequentColIndices) { |
michael@0 | 267 | colIndex = aChild.GetColIndex(); |
michael@0 | 268 | nextChild = aChild.GetNextSibling(); |
michael@0 | 269 | } |
michael@0 | 270 | mFrames.DestroyFrame(&aChild); |
michael@0 | 271 | mColCount--; |
michael@0 | 272 | if (aResetSubsequentColIndices) { |
michael@0 | 273 | if (nextChild) { // reset inside this and all following colgroups |
michael@0 | 274 | ResetColIndices(this, colIndex, nextChild); |
michael@0 | 275 | } |
michael@0 | 276 | else { |
michael@0 | 277 | nsIFrame* nextGroup = GetNextSibling(); |
michael@0 | 278 | if (nextGroup) // reset next and all following colgroups |
michael@0 | 279 | ResetColIndices(nextGroup, colIndex); |
michael@0 | 280 | } |
michael@0 | 281 | } |
michael@0 | 282 | |
michael@0 | 283 | PresContext()->PresShell()->FrameNeedsReflow(this, |
michael@0 | 284 | nsIPresShell::eTreeChange, |
michael@0 | 285 | NS_FRAME_HAS_DIRTY_CHILDREN); |
michael@0 | 286 | } |
michael@0 | 287 | |
michael@0 | 288 | nsresult |
michael@0 | 289 | nsTableColGroupFrame::RemoveFrame(ChildListID aListID, |
michael@0 | 290 | nsIFrame* aOldFrame) |
michael@0 | 291 | { |
michael@0 | 292 | NS_ASSERTION(aListID == kPrincipalList, "unexpected child list"); |
michael@0 | 293 | |
michael@0 | 294 | if (!aOldFrame) return NS_OK; |
michael@0 | 295 | bool contentRemoval = false; |
michael@0 | 296 | |
michael@0 | 297 | if (nsGkAtoms::tableColFrame == aOldFrame->GetType()) { |
michael@0 | 298 | nsTableColFrame* colFrame = (nsTableColFrame*)aOldFrame; |
michael@0 | 299 | if (colFrame->GetColType() == eColContent) { |
michael@0 | 300 | contentRemoval = true; |
michael@0 | 301 | // Remove any anonymous column frames this <col> produced via a colspan |
michael@0 | 302 | nsTableColFrame* col = colFrame->GetNextCol(); |
michael@0 | 303 | nsTableColFrame* nextCol; |
michael@0 | 304 | while (col && col->GetColType() == eColAnonymousCol) { |
michael@0 | 305 | #ifdef DEBUG |
michael@0 | 306 | nsIFrame* providerFrame = colFrame->GetParentStyleContextFrame(); |
michael@0 | 307 | if (colFrame->StyleContext()->GetParent() == |
michael@0 | 308 | providerFrame->StyleContext()) { |
michael@0 | 309 | NS_ASSERTION(col->StyleContext() == colFrame->StyleContext() && |
michael@0 | 310 | col->GetContent() == colFrame->GetContent(), |
michael@0 | 311 | "How did that happen??"); |
michael@0 | 312 | } |
michael@0 | 313 | // else colFrame is being removed because of a frame |
michael@0 | 314 | // reconstruct on it, and its style context is still the old |
michael@0 | 315 | // one, so we can't assert anything about how it compares to |
michael@0 | 316 | // col's style context. |
michael@0 | 317 | #endif |
michael@0 | 318 | nextCol = col->GetNextCol(); |
michael@0 | 319 | RemoveFrame(kPrincipalList, col); |
michael@0 | 320 | col = nextCol; |
michael@0 | 321 | } |
michael@0 | 322 | } |
michael@0 | 323 | |
michael@0 | 324 | int32_t colIndex = colFrame->GetColIndex(); |
michael@0 | 325 | // The RemoveChild call handles calling FrameNeedsReflow on us. |
michael@0 | 326 | RemoveChild(*colFrame, true); |
michael@0 | 327 | |
michael@0 | 328 | nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(this); |
michael@0 | 329 | tableFrame->RemoveCol(this, colIndex, true, true); |
michael@0 | 330 | if (mFrames.IsEmpty() && contentRemoval && |
michael@0 | 331 | GetColType() == eColGroupContent) { |
michael@0 | 332 | tableFrame->AppendAnonymousColFrames(this, GetSpan(), |
michael@0 | 333 | eColAnonymousColGroup, true); |
michael@0 | 334 | } |
michael@0 | 335 | } |
michael@0 | 336 | else { |
michael@0 | 337 | mFrames.DestroyFrame(aOldFrame); |
michael@0 | 338 | } |
michael@0 | 339 | |
michael@0 | 340 | return NS_OK; |
michael@0 | 341 | } |
michael@0 | 342 | |
michael@0 | 343 | int |
michael@0 | 344 | nsTableColGroupFrame::GetLogicalSkipSides(const nsHTMLReflowState* aReflowState) const |
michael@0 | 345 | { |
michael@0 | 346 | int skip = 0; |
michael@0 | 347 | if (nullptr != GetPrevInFlow()) { |
michael@0 | 348 | skip |= 1 << LOGICAL_SIDE_B_START; |
michael@0 | 349 | } |
michael@0 | 350 | if (nullptr != GetNextInFlow()) { |
michael@0 | 351 | skip |= 1 << LOGICAL_SIDE_B_END; |
michael@0 | 352 | } |
michael@0 | 353 | return skip; |
michael@0 | 354 | } |
michael@0 | 355 | |
michael@0 | 356 | nsresult nsTableColGroupFrame::Reflow(nsPresContext* aPresContext, |
michael@0 | 357 | nsHTMLReflowMetrics& aDesiredSize, |
michael@0 | 358 | const nsHTMLReflowState& aReflowState, |
michael@0 | 359 | nsReflowStatus& aStatus) |
michael@0 | 360 | { |
michael@0 | 361 | DO_GLOBAL_REFLOW_COUNT("nsTableColGroupFrame"); |
michael@0 | 362 | DISPLAY_REFLOW(aPresContext, this, aReflowState, aDesiredSize, aStatus); |
michael@0 | 363 | NS_ASSERTION(nullptr!=mContent, "bad state -- null content for frame"); |
michael@0 | 364 | nsresult rv=NS_OK; |
michael@0 | 365 | |
michael@0 | 366 | const nsStyleVisibility* groupVis = StyleVisibility(); |
michael@0 | 367 | bool collapseGroup = (NS_STYLE_VISIBILITY_COLLAPSE == groupVis->mVisible); |
michael@0 | 368 | if (collapseGroup) { |
michael@0 | 369 | nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(this); |
michael@0 | 370 | tableFrame->SetNeedToCollapse(true); |
michael@0 | 371 | } |
michael@0 | 372 | // for every content child that (is a column thingy and does not already have a frame) |
michael@0 | 373 | // create a frame and adjust it's style |
michael@0 | 374 | |
michael@0 | 375 | for (nsIFrame *kidFrame = mFrames.FirstChild(); kidFrame; |
michael@0 | 376 | kidFrame = kidFrame->GetNextSibling()) { |
michael@0 | 377 | // Give the child frame a chance to reflow, even though we know it'll have 0 size |
michael@0 | 378 | nsHTMLReflowMetrics kidSize(aReflowState); |
michael@0 | 379 | nsHTMLReflowState kidReflowState(aPresContext, aReflowState, kidFrame, |
michael@0 | 380 | nsSize(0,0)); |
michael@0 | 381 | |
michael@0 | 382 | nsReflowStatus status; |
michael@0 | 383 | ReflowChild(kidFrame, aPresContext, kidSize, kidReflowState, 0, 0, 0, status); |
michael@0 | 384 | FinishReflowChild(kidFrame, aPresContext, kidSize, nullptr, 0, 0, 0); |
michael@0 | 385 | } |
michael@0 | 386 | |
michael@0 | 387 | aDesiredSize.Width() = 0; |
michael@0 | 388 | aDesiredSize.Height() = 0; |
michael@0 | 389 | aStatus = NS_FRAME_COMPLETE; |
michael@0 | 390 | NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); |
michael@0 | 391 | return rv; |
michael@0 | 392 | } |
michael@0 | 393 | |
michael@0 | 394 | nsTableColFrame * nsTableColGroupFrame::GetFirstColumn() |
michael@0 | 395 | { |
michael@0 | 396 | return GetNextColumn(nullptr); |
michael@0 | 397 | } |
michael@0 | 398 | |
michael@0 | 399 | nsTableColFrame * nsTableColGroupFrame::GetNextColumn(nsIFrame *aChildFrame) |
michael@0 | 400 | { |
michael@0 | 401 | nsTableColFrame *result = nullptr; |
michael@0 | 402 | nsIFrame *childFrame = aChildFrame; |
michael@0 | 403 | if (!childFrame) { |
michael@0 | 404 | childFrame = mFrames.FirstChild(); |
michael@0 | 405 | } |
michael@0 | 406 | else { |
michael@0 | 407 | childFrame = childFrame->GetNextSibling(); |
michael@0 | 408 | } |
michael@0 | 409 | while (childFrame) |
michael@0 | 410 | { |
michael@0 | 411 | if (NS_STYLE_DISPLAY_TABLE_COLUMN == |
michael@0 | 412 | childFrame->StyleDisplay()->mDisplay) |
michael@0 | 413 | { |
michael@0 | 414 | result = (nsTableColFrame *)childFrame; |
michael@0 | 415 | break; |
michael@0 | 416 | } |
michael@0 | 417 | childFrame = childFrame->GetNextSibling(); |
michael@0 | 418 | } |
michael@0 | 419 | return result; |
michael@0 | 420 | } |
michael@0 | 421 | |
michael@0 | 422 | int32_t nsTableColGroupFrame::GetSpan() |
michael@0 | 423 | { |
michael@0 | 424 | return StyleTable()->mSpan; |
michael@0 | 425 | } |
michael@0 | 426 | |
michael@0 | 427 | void nsTableColGroupFrame::SetContinuousBCBorderWidth(uint8_t aForSide, |
michael@0 | 428 | BCPixelSize aPixelValue) |
michael@0 | 429 | { |
michael@0 | 430 | switch (aForSide) { |
michael@0 | 431 | case NS_SIDE_TOP: |
michael@0 | 432 | mTopContBorderWidth = aPixelValue; |
michael@0 | 433 | return; |
michael@0 | 434 | case NS_SIDE_BOTTOM: |
michael@0 | 435 | mBottomContBorderWidth = aPixelValue; |
michael@0 | 436 | return; |
michael@0 | 437 | default: |
michael@0 | 438 | NS_ERROR("invalid side arg"); |
michael@0 | 439 | } |
michael@0 | 440 | } |
michael@0 | 441 | |
michael@0 | 442 | void nsTableColGroupFrame::GetContinuousBCBorderWidth(nsMargin& aBorder) |
michael@0 | 443 | { |
michael@0 | 444 | int32_t aPixelsToTwips = nsPresContext::AppUnitsPerCSSPixel(); |
michael@0 | 445 | nsTableFrame* table = nsTableFrame::GetTableFrame(this); |
michael@0 | 446 | nsTableColFrame* col = table->GetColFrame(mStartColIndex + mColCount - 1); |
michael@0 | 447 | col->GetContinuousBCBorderWidth(aBorder); |
michael@0 | 448 | aBorder.top = BC_BORDER_BOTTOM_HALF_COORD(aPixelsToTwips, |
michael@0 | 449 | mTopContBorderWidth); |
michael@0 | 450 | aBorder.bottom = BC_BORDER_TOP_HALF_COORD(aPixelsToTwips, |
michael@0 | 451 | mBottomContBorderWidth); |
michael@0 | 452 | } |
michael@0 | 453 | |
michael@0 | 454 | /* ----- global methods ----- */ |
michael@0 | 455 | |
michael@0 | 456 | nsIFrame* |
michael@0 | 457 | NS_NewTableColGroupFrame(nsIPresShell* aPresShell, nsStyleContext* aContext) |
michael@0 | 458 | { |
michael@0 | 459 | return new (aPresShell) nsTableColGroupFrame(aContext); |
michael@0 | 460 | } |
michael@0 | 461 | |
michael@0 | 462 | NS_IMPL_FRAMEARENA_HELPERS(nsTableColGroupFrame) |
michael@0 | 463 | |
michael@0 | 464 | nsIAtom* |
michael@0 | 465 | nsTableColGroupFrame::GetType() const |
michael@0 | 466 | { |
michael@0 | 467 | return nsGkAtoms::tableColGroupFrame; |
michael@0 | 468 | } |
michael@0 | 469 | |
michael@0 | 470 | void |
michael@0 | 471 | nsTableColGroupFrame::InvalidateFrame(uint32_t aDisplayItemKey) |
michael@0 | 472 | { |
michael@0 | 473 | nsIFrame::InvalidateFrame(aDisplayItemKey); |
michael@0 | 474 | GetParent()->InvalidateFrameWithRect(GetVisualOverflowRect() + GetPosition(), aDisplayItemKey); |
michael@0 | 475 | } |
michael@0 | 476 | |
michael@0 | 477 | void |
michael@0 | 478 | nsTableColGroupFrame::InvalidateFrameWithRect(const nsRect& aRect, uint32_t aDisplayItemKey) |
michael@0 | 479 | { |
michael@0 | 480 | nsIFrame::InvalidateFrameWithRect(aRect, aDisplayItemKey); |
michael@0 | 481 | // If we have filters applied that would affects our bounds, then |
michael@0 | 482 | // we get an inactive layer created and this is computed |
michael@0 | 483 | // within FrameLayerBuilder |
michael@0 | 484 | GetParent()->InvalidateFrameWithRect(aRect + GetPosition(), aDisplayItemKey); |
michael@0 | 485 | } |
michael@0 | 486 | |
michael@0 | 487 | #ifdef DEBUG_FRAME_DUMP |
michael@0 | 488 | nsresult |
michael@0 | 489 | nsTableColGroupFrame::GetFrameName(nsAString& aResult) const |
michael@0 | 490 | { |
michael@0 | 491 | return MakeFrameName(NS_LITERAL_STRING("TableColGroup"), aResult); |
michael@0 | 492 | } |
michael@0 | 493 | |
michael@0 | 494 | void nsTableColGroupFrame::Dump(int32_t aIndent) |
michael@0 | 495 | { |
michael@0 | 496 | char* indent = new char[aIndent + 1]; |
michael@0 | 497 | if (!indent) return; |
michael@0 | 498 | for (int32_t i = 0; i < aIndent + 1; i++) { |
michael@0 | 499 | indent[i] = ' '; |
michael@0 | 500 | } |
michael@0 | 501 | indent[aIndent] = 0; |
michael@0 | 502 | |
michael@0 | 503 | printf("%s**START COLGROUP DUMP**\n%s startcolIndex=%d colcount=%d span=%d coltype=", |
michael@0 | 504 | indent, indent, GetStartColumnIndex(), GetColCount(), GetSpan()); |
michael@0 | 505 | nsTableColGroupType colType = GetColType(); |
michael@0 | 506 | switch (colType) { |
michael@0 | 507 | case eColGroupContent: |
michael@0 | 508 | printf(" content "); |
michael@0 | 509 | break; |
michael@0 | 510 | case eColGroupAnonymousCol: |
michael@0 | 511 | printf(" anonymous-column "); |
michael@0 | 512 | break; |
michael@0 | 513 | case eColGroupAnonymousCell: |
michael@0 | 514 | printf(" anonymous-cell "); |
michael@0 | 515 | break; |
michael@0 | 516 | } |
michael@0 | 517 | // verify the colindices |
michael@0 | 518 | int32_t j = GetStartColumnIndex(); |
michael@0 | 519 | nsTableColFrame* col = GetFirstColumn(); |
michael@0 | 520 | while (col) { |
michael@0 | 521 | NS_ASSERTION(j == col->GetColIndex(), "wrong colindex on col frame"); |
michael@0 | 522 | col = col->GetNextCol(); |
michael@0 | 523 | j++; |
michael@0 | 524 | } |
michael@0 | 525 | NS_ASSERTION((j - GetStartColumnIndex()) == GetColCount(), |
michael@0 | 526 | "number of cols out of sync"); |
michael@0 | 527 | printf("\n%s**END COLGROUP DUMP** ", indent); |
michael@0 | 528 | delete [] indent; |
michael@0 | 529 | } |
michael@0 | 530 | #endif |