Attachment #8455290: Frame constructor changes for display:contents. for bug #907396

View | Details | Raw Unified | Return to bug 907396
Collapse All | Expand All

(-)a/layout/base/RestyleManager.cpp (+32 lines)
Line     Link Here 
 Lines 2993-3001   RestyleManager::ComputeStyleChangeFor(ns Link Here 
2993
        NS_ASSERTION(!cont->GetPrevContinuation(),
2993
        NS_ASSERTION(!cont->GetPrevContinuation(),
2994
                     "continuing frame had more severe impact than first-in-flow");
2994
                     "continuing frame had more severe impact than first-in-flow");
2995
        return;
2995
        return;
2996
      }
2996
      }
2997
    }
2997
    }
2998
  }
2998
  }
2999
}
2999
}
3000
3000
3001
AutoDisplayContentsAncestorPusher::AutoDisplayContentsAncestorPusher(
3002
  TreeMatchContext& aTreeMatchContext, nsPresContext* aPresContext,
3003
  nsIContent* aParent)
3004
  : mTreeMatchContext(aTreeMatchContext)
3005
  , mPresContext(aPresContext)
3006
{
3007
  if (aParent && mTreeMatchContext.mAncestorFilter.HasFilter()) {
3008
    nsFrameManager* fm = mPresContext->FrameManager();
3009
    // Push display:contents mAncestors onto mTreeMatchContext.
3010
    for (nsIContent* p = aParent; p && fm->GetDisplayContents(p);
3011
         p = p->GetParent()) {
3012
      mAncestors.AppendElement(p->AsElement());
3013
    }
3014
    nsTArray<mozilla::dom::Element*>::size_type i = mAncestors.Length();
3015
    while (i--) {
3016
      mTreeMatchContext.mAncestorFilter.PushAncestor(mAncestors[i]);
3017
      mTreeMatchContext.PushStyleScope(mAncestors[i]);
3018
    }
3019
  }
3020
3021
}
3022
3023
AutoDisplayContentsAncestorPusher::~AutoDisplayContentsAncestorPusher()
3024
{
3025
  // Pop the ancestors we pushed in the CTOR, if any.
3026
  nsTArray<mozilla::dom::Element*>::size_type i = mAncestors.Length();
3027
  while (i--) {
3028
    mTreeMatchContext.mAncestorFilter.PopAncestor();
3029
    mTreeMatchContext.PopStyleScope(mAncestors[i]);
3030
  }
3031
}
3032
3001
} // namespace mozilla
3033
} // namespace mozilla
(-)a/layout/base/RestyleManager.h (-2 / +25 lines)
Line     Link Here 
 Lines 23-39   struct TreeMatchContext; Link Here 
23
23
24
namespace mozilla {
24
namespace mozilla {
25
  class EventStates;
25
  class EventStates;
26
26
27
namespace dom {
27
namespace dom {
28
  class Element;
28
  class Element;
29
} // namespace dom
29
} // namespace dom
30
30
31
class RestyleManager MOZ_FINAL {
31
class RestyleManager MOZ_FINAL
32
{
32
public:
33
public:
33
  friend class ::nsRefreshDriver;
34
  friend class ::nsRefreshDriver;
34
  friend class RestyleTracker;
35
  friend class RestyleTracker;
35
36
36
  typedef mozilla::dom::Element Element;
37
  typedef mozilla::dom::Element Element;
37
38
38
  RestyleManager(nsPresContext* aPresContext);
39
  RestyleManager(nsPresContext* aPresContext);
39
40
 Lines 273-289   private: Link Here 
273
  RestyleTracker mPendingRestyles;
274
  RestyleTracker mPendingRestyles;
274
  RestyleTracker mPendingAnimationRestyles;
275
  RestyleTracker mPendingAnimationRestyles;
275
};
276
};
276
277
277
/**
278
/**
278
 * An ElementRestyler is created for *each* element in a subtree that we
279
 * An ElementRestyler is created for *each* element in a subtree that we
279
 * recompute styles for.
280
 * recompute styles for.
280
 */
281
 */
281
class ElementRestyler MOZ_FINAL {
282
class ElementRestyler MOZ_FINAL
283
{
282
public:
284
public:
283
  typedef mozilla::dom::Element Element;
285
  typedef mozilla::dom::Element Element;
284
286
285
  // Construct for the root of the subtree that we're restyling.
287
  // Construct for the root of the subtree that we're restyling.
286
  ElementRestyler(nsPresContext* aPresContext,
288
  ElementRestyler(nsPresContext* aPresContext,
287
                  nsIFrame* aFrame,
289
                  nsIFrame* aFrame,
288
                  nsStyleChangeList* aChangeList,
290
                  nsStyleChangeList* aChangeList,
289
                  nsChangeHint aHintsHandledByAncestors,
291
                  nsChangeHint aHintsHandledByAncestors,
 Lines 399-409   private: Link Here 
399
  const DesiredA11yNotifications mDesiredA11yNotifications;
401
  const DesiredA11yNotifications mDesiredA11yNotifications;
400
  DesiredA11yNotifications mKidsDesiredA11yNotifications;
402
  DesiredA11yNotifications mKidsDesiredA11yNotifications;
401
  A11yNotificationType mOurA11yNotification;
403
  A11yNotificationType mOurA11yNotification;
402
  nsTArray<nsIContent*>& mVisibleKidsOfHiddenElement;
404
  nsTArray<nsIContent*>& mVisibleKidsOfHiddenElement;
403
  bool mWasFrameVisible;
405
  bool mWasFrameVisible;
404
#endif
406
#endif
405
};
407
};
406
408
409
/**
410
 * This pushes any display:contents nodes onto a TreeMatchContext.
411
 * Use it before resolving style for kids of aParent where aParent
412
 * (and further ancestors) may be display:contents nodes which have
413
 * not yet been pushed onto TreeMatchContext.
414
 */
415
class MOZ_STACK_CLASS AutoDisplayContentsAncestorPusher MOZ_FINAL
416
{
417
 public:
418
  typedef mozilla::dom::Element Element;
419
  AutoDisplayContentsAncestorPusher(TreeMatchContext& aTreeMatchContext,
420
                                    nsPresContext*    aPresContext,
421
                                    nsIContent*       aParent);
422
  ~AutoDisplayContentsAncestorPusher();
423
  bool IsEmpty() const { return mAncestors.Length() == 0; }
424
private:
425
  TreeMatchContext& mTreeMatchContext;
426
  nsPresContext* const mPresContext;
427
  nsAutoTArray<mozilla::dom::Element*, 4> mAncestors;
428
};
429
407
} // namespace mozilla
430
} // namespace mozilla
408
431
409
#endif /* mozilla_RestyleManager_h */
432
#endif /* mozilla_RestyleManager_h */
(-)a/layout/base/RestyleTracker.cpp (-2 / +6 lines)
Line     Link Here 
 Lines 4-19    Link Here 
4
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
5
6
/**
6
/**
7
 * A class which manages pending restyles.  This handles keeping track
7
 * A class which manages pending restyles.  This handles keeping track
8
 * of what nodes restyles need to happen on and so forth.
8
 * of what nodes restyles need to happen on and so forth.
9
 */
9
 */
10
10
11
#include "RestyleTracker.h"
11
#include "RestyleTracker.h"
12
13
#include "nsFrameManager.h"
12
#include "nsStyleChangeList.h"
14
#include "nsStyleChangeList.h"
13
#include "RestyleManager.h"
15
#include "RestyleManager.h"
14
#include "GeckoProfiler.h"
16
#include "GeckoProfiler.h"
15
17
16
namespace mozilla {
18
namespace mozilla {
17
19
18
inline nsIDocument*
20
inline nsIDocument*
19
RestyleTracker::Document() const {
21
RestyleTracker::Document() const {
 Lines 70-87   CollectRestyles(nsISupports* aElement, Link Here 
70
  if (element->GetCrossShadowCurrentDoc() != collector->tracker->Document() ||
72
  if (element->GetCrossShadowCurrentDoc() != collector->tracker->Document() ||
71
      !element->HasFlag(collector->tracker->RestyleBit())) {
73
      !element->HasFlag(collector->tracker->RestyleBit())) {
72
    return PL_DHASH_NEXT;
74
    return PL_DHASH_NEXT;
73
  }
75
  }
74
76
75
  NS_ASSERTION(!element->HasFlag(collector->tracker->RootBit()) ||
77
  NS_ASSERTION(!element->HasFlag(collector->tracker->RootBit()) ||
76
               // Maybe we're just not reachable via the frame tree?
78
               // Maybe we're just not reachable via the frame tree?
77
               (element->GetFlattenedTreeParent() &&
79
               (element->GetFlattenedTreeParent() &&
78
                (!element->GetFlattenedTreeParent()->GetPrimaryFrame()||
80
                (!element->GetFlattenedTreeParent()->GetPrimaryFrame() ||
79
                 element->GetFlattenedTreeParent()->GetPrimaryFrame()->IsLeaf())) ||
81
                 element->GetFlattenedTreeParent()->GetPrimaryFrame()->IsLeaf() ||
82
                 element->GetCurrentDoc()->GetShell()->FrameManager()
83
                   ->GetDisplayContents(element))) ||
80
               // Or not reachable due to an async reinsert we have
84
               // Or not reachable due to an async reinsert we have
81
               // pending?  If so, we'll have a reframe hint around.
85
               // pending?  If so, we'll have a reframe hint around.
82
               // That incidentally makes it safe that we still have
86
               // That incidentally makes it safe that we still have
83
               // the bit, since any descendants that didn't get added
87
               // the bit, since any descendants that didn't get added
84
               // to the roots list because we had the bits will be
88
               // to the roots list because we had the bits will be
85
               // completely restyled in a moment.
89
               // completely restyled in a moment.
86
               (aData.mChangeHint & nsChangeHint_ReconstructFrame),
90
               (aData.mChangeHint & nsChangeHint_ReconstructFrame),
87
               "Why did this not get handled while processing mRestyleRoots?");
91
               "Why did this not get handled while processing mRestyleRoots?");
(-)a/layout/base/nsCSSFrameConstructor.cpp (-107 / +277 lines)
Line     Link Here 
 Lines 601-640   FindFirstNonBlock(const nsFrameList& aLi Link Here 
601
inline void
601
inline void
602
SetInitialSingleChild(nsContainerFrame* aParent, nsIFrame* aFrame)
602
SetInitialSingleChild(nsContainerFrame* aParent, nsIFrame* aFrame)
603
{
603
{
604
  NS_PRECONDITION(!aFrame->GetNextSibling(), "Should be using a frame list");
604
  NS_PRECONDITION(!aFrame->GetNextSibling(), "Should be using a frame list");
605
  nsFrameList temp(aFrame, aFrame);
605
  nsFrameList temp(aFrame, aFrame);
606
  aParent->SetInitialChildList(kPrincipalList, temp);
606
  aParent->SetInitialChildList(kPrincipalList, temp);
607
}
607
}
608
608
609
static nsContainerFrame*
610
GetContentInsertionFrameFor(nsIContent* aContent)
611
{
612
  // Get the primary frame associated with the content
613
  nsIFrame* frame = aContent->GetPrimaryFrame();
614
615
  if (!frame)
616
    return nullptr;
617
618
  // If the content of the frame is not the desired content then this is not
619
  // really a frame for the desired content.
620
  // XXX This check is needed due to bug 135040. Remove it once that's fixed.
621
  if (frame->GetContent() != aContent) {
622
    return nullptr;
623
  }
624
625
  nsContainerFrame* insertionFrame = frame->GetContentInsertionFrame();
626
627
  NS_ASSERTION(!insertionFrame || insertionFrame == frame || !frame->IsLeaf(),
628
    "The insertion frame is the primary frame or the primary frame isn't a leaf");
629
630
  return insertionFrame;
631
}
632
633
// -----------------------------------------------------------
609
// -----------------------------------------------------------
634
610
635
// Structure used when constructing formatting object trees.
611
// Structure used when constructing formatting object trees.
636
struct nsFrameItems : public nsFrameList
612
struct nsFrameItems : public nsFrameList
637
{
613
{
638
  // Appends the frame to the end of the list
614
  // Appends the frame to the end of the list
639
  void AddChild(nsIFrame* aChild);
615
  void AddChild(nsIFrame* aChild);
640
};
616
};
 Lines 2252-2269   NeedFrameFor(const nsFrameConstructorSta Link Here 
2252
  // whitespace.
2228
  // whitespace.
2253
2229
2254
  // We could handle all this in CreateNeededTablePseudos or some other place
2230
  // We could handle all this in CreateNeededTablePseudos or some other place
2255
  // after we build our frame construction items, but that would involve
2231
  // after we build our frame construction items, but that would involve
2256
  // creating frame construction items for whitespace kids of
2232
  // creating frame construction items for whitespace kids of
2257
  // eExcludesIgnorableWhitespace frames, where we know we'll be dropping them
2233
  // eExcludesIgnorableWhitespace frames, where we know we'll be dropping them
2258
  // all anyway, and involve an extra walk down the frame construction item
2234
  // all anyway, and involve an extra walk down the frame construction item
2259
  // list.
2235
  // list.
2260
  if (!aParentFrame->IsFrameOfType(nsIFrame::eExcludesIgnorableWhitespace) ||
2236
  if ((aParentFrame &&
2261
      aParentFrame->IsGeneratedContentFrame() ||
2237
       (!aParentFrame->IsFrameOfType(nsIFrame::eExcludesIgnorableWhitespace) ||
2238
        aParentFrame->IsGeneratedContentFrame())) ||
2262
      !aChildContent->IsNodeOfType(nsINode::eTEXT)) {
2239
      !aChildContent->IsNodeOfType(nsINode::eTEXT)) {
2263
    return true;
2240
    return true;
2264
  }
2241
  }
2265
2242
2266
  aChildContent->SetFlags(NS_CREATE_FRAME_IF_NON_WHITESPACE |
2243
  aChildContent->SetFlags(NS_CREATE_FRAME_IF_NON_WHITESPACE |
2267
                          NS_REFRAME_IF_WHITESPACE);
2244
                          NS_REFRAME_IF_WHITESPACE);
2268
  return !aChildContent->TextIsOnlyWhitespace();
2245
  return !aChildContent->TextIsOnlyWhitespace();
2269
}
2246
}
 Lines 3652-3680   nsCSSFrameConstructor::ConstructFrameFro Link Here 
3652
3629
3653
  // Don't create a subdocument frame for iframes if we're creating extra frames
3630
  // Don't create a subdocument frame for iframes if we're creating extra frames
3654
  if (aState.mCreatingExtraFrames && aItem.mContent->IsHTML() &&
3631
  if (aState.mCreatingExtraFrames && aItem.mContent->IsHTML() &&
3655
      aItem.mContent->Tag() == nsGkAtoms::iframe)
3632
      aItem.mContent->Tag() == nsGkAtoms::iframe)
3656
  {
3633
  {
3657
    return;
3634
    return;
3658
  }
3635
  }
3659
3636
3660
  nsStyleContext* const styleContext = aItem.mStyleContext;
3661
  const nsStyleDisplay* display = styleContext->StyleDisplay();
3662
  nsIContent* const content = aItem.mContent;
3637
  nsIContent* const content = aItem.mContent;
3638
  nsIContent* parent = content->GetParent();
3639
3640
  // Push display:contents ancestors.
3641
  AutoDisplayContentsAncestorPusher adcp(aState.mTreeMatchContext,
3642
                                         aState.mPresContext,
3643
                                         parent);
3663
3644
3664
  // Get the parent of the content and check if it is a XBL children element.
3645
  // Get the parent of the content and check if it is a XBL children element.
3665
  // Push the children element as an ancestor here because it does
3646
  // Push the children element as an ancestor here because it does
3666
  // not have a frame and would not otherwise be pushed as an ancestor. It is
3647
  // not have a frame and would not otherwise be pushed as an ancestor. It is
3667
  // necessary to do so in order to correctly handle style resolution on
3648
  // necessary to do so in order to correctly handle style resolution on
3668
  // descendants.
3649
  // descendants.
3669
  nsIContent* parent = content->GetParent();
3670
  TreeMatchContext::AutoAncestorPusher
3650
  TreeMatchContext::AutoAncestorPusher
3671
    insertionPointPusher(aState.mTreeMatchContext);
3651
    insertionPointPusher(aState.mTreeMatchContext);
3672
  if (parent && nsContentUtils::IsContentInsertionPoint(parent)) {
3652
  if (adcp.IsEmpty() && parent && nsContentUtils::IsContentInsertionPoint(parent)) {
3673
    if (aState.mTreeMatchContext.mAncestorFilter.HasFilter()) {
3653
    if (aState.mTreeMatchContext.mAncestorFilter.HasFilter()) {
3674
      insertionPointPusher.PushAncestorAndStyleScope(parent);
3654
      insertionPointPusher.PushAncestorAndStyleScope(parent);
3675
    } else {
3655
    } else {
3676
      insertionPointPusher.PushStyleScope(parent);
3656
      insertionPointPusher.PushStyleScope(parent);
3677
    }
3657
    }
3678
  }
3658
  }
3679
3659
3680
  // Push the content as a style ancestor now, so we don't have to do
3660
  // Push the content as a style ancestor now, so we don't have to do
 Lines 3690-3705   nsCSSFrameConstructor::ConstructFrameFro Link Here 
3690
  if (aState.mTreeMatchContext.mAncestorFilter.HasFilter()) {
3670
  if (aState.mTreeMatchContext.mAncestorFilter.HasFilter()) {
3691
    ancestorPusher.PushAncestorAndStyleScope(content);
3671
    ancestorPusher.PushAncestorAndStyleScope(content);
3692
  } else {
3672
  } else {
3693
    ancestorPusher.PushStyleScope(content);
3673
    ancestorPusher.PushStyleScope(content);
3694
  }
3674
  }
3695
3675
3696
  nsIFrame* newFrame;
3676
  nsIFrame* newFrame;
3697
  nsIFrame* primaryFrame;
3677
  nsIFrame* primaryFrame;
3678
  nsStyleContext* const styleContext = aItem.mStyleContext;
3679
  const nsStyleDisplay* display = styleContext->StyleDisplay();
3698
  if (bits & FCDATA_FUNC_IS_FULL_CTOR) {
3680
  if (bits & FCDATA_FUNC_IS_FULL_CTOR) {
3699
    newFrame =
3681
    newFrame =
3700
      (this->*(data->mFullConstructor))(aState, aItem, aParentFrame,
3682
      (this->*(data->mFullConstructor))(aState, aItem, aParentFrame,
3701
                                        display, aFrameItems);
3683
                                        display, aFrameItems);
3702
    MOZ_ASSERT(newFrame, "Full constructor failed");
3684
    MOZ_ASSERT(newFrame, "Full constructor failed");
3703
    primaryFrame = newFrame;
3685
    primaryFrame = newFrame;
3704
  } else {
3686
  } else {
3705
    newFrame =
3687
    newFrame =
 Lines 4564-4580   nsCSSFrameConstructor::FindDisplayData(c Link Here 
4564
                       &nsCSSFrameConstructor::ConstructTableCol) },
4546
                       &nsCSSFrameConstructor::ConstructTableCol) },
4565
    { NS_STYLE_DISPLAY_TABLE_ROW,
4547
    { NS_STYLE_DISPLAY_TABLE_ROW,
4566
      FULL_CTOR_FCDATA(FCDATA_IS_TABLE_PART |
4548
      FULL_CTOR_FCDATA(FCDATA_IS_TABLE_PART |
4567
                       FCDATA_DESIRED_PARENT_TYPE_TO_BITS(eTypeRowGroup),
4549
                       FCDATA_DESIRED_PARENT_TYPE_TO_BITS(eTypeRowGroup),
4568
                       &nsCSSFrameConstructor::ConstructTableRowOrRowGroup) },
4550
                       &nsCSSFrameConstructor::ConstructTableRowOrRowGroup) },
4569
    { NS_STYLE_DISPLAY_TABLE_CELL,
4551
    { NS_STYLE_DISPLAY_TABLE_CELL,
4570
      FULL_CTOR_FCDATA(FCDATA_IS_TABLE_PART |
4552
      FULL_CTOR_FCDATA(FCDATA_IS_TABLE_PART |
4571
                       FCDATA_DESIRED_PARENT_TYPE_TO_BITS(eTypeRow),
4553
                       FCDATA_DESIRED_PARENT_TYPE_TO_BITS(eTypeRow),
4572
                       &nsCSSFrameConstructor::ConstructTableCell) }
4554
                       &nsCSSFrameConstructor::ConstructTableCell) },
4555
    { NS_STYLE_DISPLAY_CONTENTS,
4556
      FULL_CTOR_FCDATA(FCDATA_IS_CONTENTS, nullptr/*never called*/) }
4573
  };
4557
  };
4574
4558
4575
  return FindDataByInt(aDisplay->mDisplay,
4559
  return FindDataByInt(aDisplay->mDisplay,
4576
                       aElement, aStyleContext, sDisplayData,
4560
                       aElement, aStyleContext, sDisplayData,
4577
                       ArrayLength(sDisplayData));
4561
                       ArrayLength(sDisplayData));
4578
}
4562
}
4579
4563
4580
nsIFrame*
4564
nsIFrame*
 Lines 4683-4713   nsCSSFrameConstructor::InitAndRestoreFra Link Here 
4683
  }
4667
  }
4684
}
4668
}
4685
4669
4686
already_AddRefed<nsStyleContext>
4670
already_AddRefed<nsStyleContext>
4687
nsCSSFrameConstructor::ResolveStyleContext(nsIFrame*         aParentFrame,
4671
nsCSSFrameConstructor::ResolveStyleContext(nsIFrame*         aParentFrame,
4688
                                           nsIContent*       aContent,
4672
                                           nsIContent*       aContent,
4689
                                           nsFrameConstructorState* aState)
4673
                                           nsFrameConstructorState* aState)
4690
{
4674
{
4691
  nsStyleContext* parentStyleContext = nullptr;
4675
  nsIContent* container = aContent->GetParent();
4692
  NS_ASSERTION(aContent->GetParent(), "Must have parent here");
4676
  NS_ASSERTION(container, "Must have parent here");
4693
4677
  nsStyleContext* parentStyleContext = GetDisplayContents(container);
4694
  aParentFrame = nsFrame::CorrectStyleParentFrame(aParentFrame, nullptr);
4678
  if (MOZ_LIKELY(!parentStyleContext)) {
4695
4679
    aParentFrame = nsFrame::CorrectStyleParentFrame(aParentFrame, nullptr);
4696
  if (aParentFrame) {
4680
    if (aParentFrame) {
4697
    // Resolve the style context based on the content object and the parent
4681
      // Resolve the style context based on the content object and the parent
4698
    // style context
4682
      // style context
4699
    parentStyleContext = aParentFrame->StyleContext();
4683
      parentStyleContext = aParentFrame->StyleContext();
4700
  } else {
4684
    } else {
4701
    // Perhaps aParentFrame is a canvasFrame and we're replicating
4685
      // Perhaps aParentFrame is a canvasFrame and we're replicating
4702
    // fixed-pos frames.
4686
      // fixed-pos frames.
4703
    // XXX should we create a way to tell ConstructFrame which style
4687
      // XXX should we create a way to tell ConstructFrame which style
4704
    // context to use, and pass it the style context for the
4688
      // context to use, and pass it the style context for the
4705
    // previous page's fixed-pos frame?
4689
      // previous page's fixed-pos frame?
4690
    }
4706
  }
4691
  }
4707
4692
4708
  return ResolveStyleContext(parentStyleContext, aContent, aState);
4693
  return ResolveStyleContext(parentStyleContext, aContent, aState);
4709
}
4694
}
4710
4695
4711
already_AddRefed<nsStyleContext>
4696
already_AddRefed<nsStyleContext>
4712
nsCSSFrameConstructor::ResolveStyleContext(nsStyleContext* aParentStyleContext,
4697
nsCSSFrameConstructor::ResolveStyleContext(nsStyleContext* aParentStyleContext,
4713
                                           nsIContent* aContent,
4698
                                           nsIContent* aContent,
 Lines 5203-5224   nsCSSFrameConstructor::AddPageBreakItem( Link Here 
5203
5188
5204
  // Lie about the tag and namespace so we don't trigger anything
5189
  // Lie about the tag and namespace so we don't trigger anything
5205
  // interesting during frame construction.
5190
  // interesting during frame construction.
5206
  aItems.AppendItem(&sPageBreakData, aContent, nsCSSAnonBoxes::pageBreak,
5191
  aItems.AppendItem(&sPageBreakData, aContent, nsCSSAnonBoxes::pageBreak,
5207
                    kNameSpaceID_None, nullptr, pseudoStyle.forget(),
5192
                    kNameSpaceID_None, nullptr, pseudoStyle.forget(),
5208
                    true, nullptr);
5193
                    true, nullptr);
5209
}
5194
}
5210
5195
5211
void
5196
bool
5212
nsCSSFrameConstructor::AddFrameConstructionItems(nsFrameConstructorState& aState,
5197
nsCSSFrameConstructor::ShouldCreateItemsForChild(nsFrameConstructorState& aState,
5213
                                                 nsIContent* aContent,
5198
                                                 nsIContent* aContent,
5214
                                                 bool aSuppressWhiteSpaceOptimizations,
5199
                                                 nsContainerFrame* aParentFrame)
5215
                                                 nsContainerFrame* aParentFrame,
5216
                                                 FrameConstructionItemList& aItems)
5217
{
5200
{
5218
  aContent->UnsetFlags(NODE_DESCENDANTS_NEED_FRAMES | NODE_NEEDS_FRAME);
5201
  aContent->UnsetFlags(NODE_DESCENDANTS_NEED_FRAMES | NODE_NEEDS_FRAME);
5219
  if (aContent->IsElement()) {
5202
  if (aContent->IsElement()) {
5220
    // We can't just remove our pending restyle flags, since we may
5203
    // We can't just remove our pending restyle flags, since we may
5221
    // have restyle-later-siblings set on us.  But we _can_ remove the
5204
    // have restyle-later-siblings set on us.  But we _can_ remove the
5222
    // "is possible restyle root" flags, and need to.  Otherwise we can
5205
    // "is possible restyle root" flags, and need to.  Otherwise we can
5223
    // end up with stale such flags (e.g. if we used to have a
5206
    // end up with stale such flags (e.g. if we used to have a
5224
    // display:none parent when our last restyle was posted and
5207
    // display:none parent when our last restyle was posted and
 Lines 5229-5276   nsCSSFrameConstructor::AddFrameConstruct Link Here 
5229
5212
5230
  // XXX the GetContent() != aContent check is needed due to bug 135040.
5213
  // XXX the GetContent() != aContent check is needed due to bug 135040.
5231
  // Remove it once that's fixed.
5214
  // Remove it once that's fixed.
5232
  if (aContent->GetPrimaryFrame() &&
5215
  if (aContent->GetPrimaryFrame() &&
5233
      aContent->GetPrimaryFrame()->GetContent() == aContent &&
5216
      aContent->GetPrimaryFrame()->GetContent() == aContent &&
5234
      !aState.mCreatingExtraFrames) {
5217
      !aState.mCreatingExtraFrames) {
5235
    NS_ERROR("asked to create frame construction item for a node that already "
5218
    NS_ERROR("asked to create frame construction item for a node that already "
5236
             "has a frame");
5219
             "has a frame");
5237
    return;
5220
    return false;
5238
  }
5221
  }
5239
5222
5240
  // don't create a whitespace frame if aParent doesn't want it
5223
  // don't create a whitespace frame if aParent doesn't want it
5241
  if (!NeedFrameFor(aState, aParentFrame, aContent)) {
5224
  if (!NeedFrameFor(aState, aParentFrame, aContent)) {
5242
    return;
5225
    return false;
5243
  }
5226
  }
5244
5227
5245
  // never create frames for comments or PIs
5228
  // never create frames for comments or PIs
5246
  if (aContent->IsNodeOfType(nsINode::eCOMMENT) ||
5229
  if (aContent->IsNodeOfType(nsINode::eCOMMENT) ||
5247
      aContent->IsNodeOfType(nsINode::ePROCESSING_INSTRUCTION))
5230
      aContent->IsNodeOfType(nsINode::ePROCESSING_INSTRUCTION)) {
5248
    return;
5231
    return false;
5249
5232
  }
5250
  nsRefPtr<nsStyleContext> styleContext;
5233
5251
  styleContext = ResolveStyleContext(aParentFrame, aContent, &aState);
5234
  return true;
5252
5235
}
5236
5237
void
5238
nsCSSFrameConstructor::DoAddFrameConstructionItems(nsFrameConstructorState& aState,
5239
                                                   nsIContent* aContent,
5240
                                                   nsStyleContext* aStyleContext,
5241
                                                   bool aSuppressWhiteSpaceOptimizations,
5242
                                                   nsContainerFrame* aParentFrame,
5243
                                                   nsTArray<nsIAnonymousContentCreator::ContentInfo>* aAnonChildren,
5244
                                                   FrameConstructionItemList& aItems)
5245
{
5253
  uint32_t flags = ITEM_ALLOW_XBL_BASE | ITEM_ALLOW_PAGE_BREAK;
5246
  uint32_t flags = ITEM_ALLOW_XBL_BASE | ITEM_ALLOW_PAGE_BREAK;
5254
  if (aParentFrame->IsSVGText()) {
5247
  if (aParentFrame) {
5255
    flags |= ITEM_IS_WITHIN_SVG_TEXT;
5248
    if (aParentFrame->IsSVGText()) {
5256
  }
5249
      flags |= ITEM_IS_WITHIN_SVG_TEXT;
5257
  if (aParentFrame->GetType() == nsGkAtoms::blockFrame &&
5250
    }
5258
      aParentFrame->GetParent() &&
5251
    if (aParentFrame->GetType() == nsGkAtoms::blockFrame &&
5259
      aParentFrame->GetParent()->GetType() == nsGkAtoms::svgTextFrame) {
5252
        aParentFrame->GetParent() &&
5260
    flags |= ITEM_ALLOWS_TEXT_PATH_CHILD;
5253
        aParentFrame->GetParent()->GetType() == nsGkAtoms::svgTextFrame) {
5254
      flags |= ITEM_ALLOWS_TEXT_PATH_CHILD;
5255
    }
5261
  }
5256
  }
5262
  AddFrameConstructionItemsInternal(aState, aContent, aParentFrame,
5257
  AddFrameConstructionItemsInternal(aState, aContent, aParentFrame,
5263
                                    aContent->Tag(), aContent->GetNameSpaceID(),
5258
                                    aContent->Tag(), aContent->GetNameSpaceID(),
5264
                                    aSuppressWhiteSpaceOptimizations,
5259
                                    aSuppressWhiteSpaceOptimizations,
5265
                                    styleContext,
5260
                                    aStyleContext,
5266
                                    flags, nullptr,
5261
                                    flags, aAnonChildren,
5267
                                    aItems);
5262
                                    aItems);
5268
}
5263
}
5264
  
5265
void
5266
nsCSSFrameConstructor::AddFrameConstructionItems(nsFrameConstructorState& aState,
5267
                                                 nsIContent* aContent,
5268
                                                 bool aSuppressWhiteSpaceOptimizations,
5269
                                                 nsContainerFrame* aParentFrame,
5270
                                                 FrameConstructionItemList& aItems)
5271
{
5272
  if (!ShouldCreateItemsForChild(aState, aContent, aParentFrame)) {
5273
    return;
5274
  }
5275
  nsRefPtr<nsStyleContext> styleContext =
5276
    ResolveStyleContext(aParentFrame, aContent, &aState);
5277
  DoAddFrameConstructionItems(aState, aContent, styleContext,
5278
                              aSuppressWhiteSpaceOptimizations, aParentFrame,
5279
                              nullptr, aItems);
5280
}
5269
5281
5270
/* static */ void
5282
/* static */ void
5271
nsCSSFrameConstructor::SetAsUndisplayedContent(FrameConstructionItemList& aList,
5283
nsCSSFrameConstructor::SetAsUndisplayedContent(FrameConstructionItemList& aList,
5272
                                               nsIContent* aContent,
5284
                                               nsIContent* aContent,
5273
                                               nsStyleContext* aStyleContext,
5285
                                               nsStyleContext* aStyleContext,
5274
                                               bool aIsGeneratedContent)
5286
                                               bool aIsGeneratedContent)
5275
{
5287
{
5276
  if (aStyleContext->GetPseudo()) {
5288
  if (aStyleContext->GetPseudo()) {
 Lines 5465-5480   nsCSSFrameConstructor::AddFrameConstruct Link Here 
5465
    !display->IsAbsolutelyPositionedStyle() &&
5477
    !display->IsAbsolutelyPositionedStyle() &&
5466
    !(bits & FCDATA_IS_TABLE_PART) &&
5478
    !(bits & FCDATA_IS_TABLE_PART) &&
5467
    !(bits & FCDATA_IS_SVG_TEXT);
5479
    !(bits & FCDATA_IS_SVG_TEXT);
5468
5480
5469
  if (canHavePageBreak && display->mBreakBefore) {
5481
  if (canHavePageBreak && display->mBreakBefore) {
5470
    AddPageBreakItem(aContent, aStyleContext, aItems);
5482
    AddPageBreakItem(aContent, aStyleContext, aItems);
5471
  }
5483
  }
5472
5484
5485
  if (MOZ_UNLIKELY(bits & FCDATA_IS_CONTENTS)) {
5486
    if (!GetDisplayContents(aContent)) {
5487
      MOZ_ASSERT(styleContext->GetPseudo() || !isGeneratedContent,
5488
                 "Should have had pseudo type");
5489
      aState.mFrameManager->SetDisplayContents(aContent, styleContext);
5490
    } else {
5491
      aState.mFrameManager->ChangeDisplayContents(aContent, styleContext);
5492
    }
5493
5494
    TreeMatchContext::AutoAncestorPusher ancestorPusher(aState.mTreeMatchContext);
5495
    if (aState.mTreeMatchContext.mAncestorFilter.HasFilter()) {
5496
      ancestorPusher.PushAncestorAndStyleScope(aContent->AsElement());
5497
    } else {
5498
      ancestorPusher.PushStyleScope(aContent->AsElement());
5499
    }
5500
5501
    if (aParentFrame) {
5502
      aParentFrame->AddStateBits(NS_FRAME_MAY_HAVE_GENERATED_CONTENT);
5503
    }
5504
    CreateGeneratedContentItem(aState, aParentFrame, aContent, styleContext,
5505
                               nsCSSPseudoElements::ePseudo_before, aItems);
5506
5507
    FlattenedChildIterator iter(aContent);
5508
    for (nsIContent* child = iter.GetNextChild(); child; child = iter.GetNextChild()) {
5509
      if (!ShouldCreateItemsForChild(aState, child, aParentFrame)) {
5510
        continue;
5511
      }
5512
5513
      // Get the parent of the content and check if it is a XBL children element
5514
      // (if the content is a children element then parent != aContent because the
5515
      // FlattenedChildIterator will transitively iterate through <xbl:children>
5516
      // for default content). Push the children element as an ancestor here because
5517
      // it does not have a frame and would not otherwise be pushed as an ancestor.
5518
      nsIContent* parent = child->GetParent();
5519
      MOZ_ASSERT(parent, "Parent must be non-null because we are iterating children.");
5520
      TreeMatchContext::AutoAncestorPusher ancestorPusher(aState.mTreeMatchContext);
5521
      if (parent != aContent && parent->IsElement()) {
5522
        if (aState.mTreeMatchContext.mAncestorFilter.HasFilter()) {
5523
          ancestorPusher.PushAncestorAndStyleScope(parent->AsElement());
5524
        } else {
5525
          ancestorPusher.PushStyleScope(parent->AsElement());
5526
        }
5527
      }
5528
5529
      nsRefPtr<nsStyleContext> childContext =
5530
        ResolveStyleContext(styleContext, child, nullptr);
5531
      DoAddFrameConstructionItems(aState, child, childContext,
5532
                                  aSuppressWhiteSpaceOptimizations,
5533
                                  aParentFrame, aAnonChildren, aItems);
5534
    }
5535
    aItems.SetParentHasNoXBLChildren(!iter.XBLInvolved());
5536
5537
    CreateGeneratedContentItem(aState, aParentFrame, aContent, styleContext,
5538
                               nsCSSPseudoElements::ePseudo_after, aItems);
5539
    if (canHavePageBreak && display->mBreakAfter) {
5540
      AddPageBreakItem(aContent, aStyleContext, aItems);
5541
    }
5542
    return;
5543
  }
5544
5473
  FrameConstructionItem* item =
5545
  FrameConstructionItem* item =
5474
    aItems.AppendItem(data, aContent, aTag, aNameSpaceID,
5546
    aItems.AppendItem(data, aContent, aTag, aNameSpaceID,
5475
                      pendingBinding, styleContext.forget(),
5547
                      pendingBinding, styleContext.forget(),
5476
                      aSuppressWhiteSpaceOptimizations, aAnonChildren);
5548
                      aSuppressWhiteSpaceOptimizations, aAnonChildren);
5477
  if (!item) {
5549
  if (!item) {
5478
    if (isGeneratedContent) {
5550
    if (isGeneratedContent) {
5479
      aContent->UnbindFromTree();
5551
      aContent->UnbindFromTree();
5480
    }
5552
    }
 Lines 5827-5857   nsCSSFrameConstructor::GetFloatContainin Link Here 
5827
5899
5828
/**
5900
/**
5829
 * This function will check whether aContainer has :after generated content.
5901
 * This function will check whether aContainer has :after generated content.
5830
 * If so, appending to it should actually insert.  The return value is the
5902
 * If so, appending to it should actually insert.  The return value is the
5831
 * parent to use for newly-appended content.  *aAfterFrame points to the :after
5903
 * parent to use for newly-appended content.  *aAfterFrame points to the :after
5832
 * frame before which appended content should go, if there is one.
5904
 * frame before which appended content should go, if there is one.
5833
 */
5905
 */
5834
static nsContainerFrame*
5906
static nsContainerFrame*
5835
AdjustAppendParentForAfterContent(nsPresContext* aPresContext,
5907
AdjustAppendParentForAfterContent(nsFrameManager* aFrameManager,
5836
                                  nsIContent* aContainer,
5908
                                  nsIContent* aContainer,
5837
                                  nsContainerFrame* aParentFrame,
5909
                                  nsContainerFrame* aParentFrame,
5910
                                  nsIContent* aChild,
5838
                                  nsIFrame** aAfterFrame)
5911
                                  nsIFrame** aAfterFrame)
5839
{
5912
{
5840
  // See if the parent has an :after pseudo-element.  Check for the presence
5913
  // If the parent frame has any pseudo-elements or aContainer is a
5841
  // of style first, since nsLayoutUtils::GetAfterFrame is sorta expensive.
5914
  // display:contents node then we need to walk through the child
5842
  nsStyleContext* parentStyle = aParentFrame->StyleContext();
5915
  // frames to find the first one that is either a ::after frame for an
5843
  if (nsLayoutUtils::HasPseudoStyle(aContainer, parentStyle,
5916
  // ancestor of aChild or a frame that is for a node later in the
5917
  // document than aChild and return that in aAfterFrame.
5918
  if (GetGenConPseudos(aParentFrame) ||
5919
      nsLayoutUtils::HasPseudoStyle(aContainer, aParentFrame->StyleContext(),
5844
                                    nsCSSPseudoElements::ePseudo_after,
5920
                                    nsCSSPseudoElements::ePseudo_after,
5845
                                    aPresContext)) {
5921
                                    aParentFrame->PresContext()) ||
5846
    // Ensure that the :after frame is on the principal child list.
5922
      aFrameManager->GetDisplayContents(aContainer)) {
5847
    aParentFrame->DrainSelfOverflowList();
5923
    nsIFrame* afterFrame = nullptr;
5848
5924
    nsContainerFrame* parent =
5849
    nsIFrame* afterFrame = nsLayoutUtils::GetAfterFrame(aParentFrame);
5925
      static_cast<nsContainerFrame*>(aParentFrame->LastContinuation());
5926
    bool done = false;
5927
    while (!done && parent) {
5928
      // Ensure that all normal flow children are on the principal child list.
5929
      parent->DrainSelfOverflowList();
5930
5931
      nsIFrame* child = parent->GetLastChild(nsIFrame::kPrincipalList);
5932
      if (child && child->IsPseudoFrame(aContainer) &&
5933
          !child->IsGeneratedContentFrame()) {
5934
        // Drill down into non-generated pseudo frames of aContainer.
5935
        parent = nsLayoutUtils::LastContinuationWithChild(do_QueryFrame(child));
5936
        continue;
5937
      }
5938
5939
      for (; child; child = child->GetPrevSibling()) {
5940
        nsIContent* c = child->GetContent();
5941
        if (child->IsGeneratedContentFrame()) {
5942
          nsIContent* p = c->GetParent();
5943
          if (c->Tag() == nsGkAtoms::mozgeneratedcontentafter) {
5944
            if (!nsContentUtils::ContentIsDescendantOf(aChild, p) &&
5945
                c->GetBindingParent() != aContainer &&
5946
                nsContentUtils::PositionIsBefore(p, aChild)) {
5947
              // ::after generated content for content earlier in the doc and not
5948
              // for an ancestor.
5949
              done = true;
5950
              break;
5951
            }
5952
          } else if (nsContentUtils::PositionIsBefore(p, aChild)) {
5953
            // Non-::after generated content for content earlier in the doc.
5954
            done = true;
5955
            break;
5956
          }
5957
        } else if (nsContentUtils::PositionIsBefore(c, aChild)) {
5958
          // Content is before aChild.
5959
          done = true;
5960
          break;
5961
        }
5962
        afterFrame = child;
5963
      }
5964
5965
      parent = static_cast<nsContainerFrame*>(parent->GetPrevContinuation());
5966
    }
5850
    if (afterFrame) {
5967
    if (afterFrame) {
5851
      *aAfterFrame = afterFrame;
5968
      *aAfterFrame = afterFrame;
5852
      return afterFrame->GetParent();
5969
      return afterFrame->GetParent();
5853
    }
5970
    }
5854
  }
5971
  }
5855
5972
5856
  *aAfterFrame = nullptr;
5973
  *aAfterFrame = nullptr;
5857
5974
 Lines 6222-6238   nsCSSFrameConstructor::GetInsertionPrevS Link Here 
6222
  *aIsAppend = false;
6339
  *aIsAppend = false;
6223
6340
6224
  // Find the frame that precedes the insertion point. Walk backwards
6341
  // Find the frame that precedes the insertion point. Walk backwards
6225
  // from the parent frame to get the parent content, because if an
6342
  // from the parent frame to get the parent content, because if an
6226
  // XBL insertion point is involved, we'll need to use _that_ to find
6343
  // XBL insertion point is involved, we'll need to use _that_ to find
6227
  // the preceding frame.
6344
  // the preceding frame.
6228
6345
6229
  NS_PRECONDITION(aParentFrame, "Must have parent frame to start with");
6346
  NS_PRECONDITION(aParentFrame, "Must have parent frame to start with");
6230
  nsIContent* container = aParentFrame->GetContent();
6347
  const bool boxContents = GetDisplayContents(aContainer);
6348
  nsIContent* container = boxContents ? aContainer : aParentFrame->GetContent();
6231
6349
6232
  FlattenedChildIterator iter(container);
6350
  FlattenedChildIterator iter(container);
6233
  bool xblCase = iter.XBLInvolved() || container != aContainer;
6351
  bool xblCase = iter.XBLInvolved() || container != aContainer;
6234
  if (xblCase || !aChild->IsRootOfAnonymousSubtree()) {
6352
  if (xblCase || !aChild->IsRootOfAnonymousSubtree()) {
6235
    // The check for IsRootOfAnonymousSubtree() is because editor is
6353
    // The check for IsRootOfAnonymousSubtree() is because editor is
6236
    // severely broken and calls us directly for native anonymous
6354
    // severely broken and calls us directly for native anonymous
6237
    // nodes that it creates.
6355
    // nodes that it creates.
6238
    if (aStartSkipChild) {
6356
    if (aStartSkipChild) {
 Lines 6252-6280   nsCSSFrameConstructor::GetInsertionPrevS Link Here 
6252
  uint8_t childDisplay = UNSET_DISPLAY;
6370
  uint8_t childDisplay = UNSET_DISPLAY;
6253
  nsIFrame* prevSibling = FindPreviousSibling(iter, childDisplay);
6371
  nsIFrame* prevSibling = FindPreviousSibling(iter, childDisplay);
6254
6372
6255
  // Now, find the geometric parent so that we can handle
6373
  // Now, find the geometric parent so that we can handle
6256
  // continuations properly. Use the prev sibling if we have it;
6374
  // continuations properly. Use the prev sibling if we have it;
6257
  // otherwise use the next sibling.
6375
  // otherwise use the next sibling.
6258
  if (prevSibling) {
6376
  if (prevSibling) {
6259
    aParentFrame = prevSibling->GetParent()->GetContentInsertionFrame();
6377
    aParentFrame = prevSibling->GetParent()->GetContentInsertionFrame();
6260
  }
6378
  } else {
6261
  else {
6262
    // If there is no previous sibling, then find the frame that follows
6379
    // If there is no previous sibling, then find the frame that follows
6263
    if (aEndSkipChild) {
6380
    if (aEndSkipChild) {
6264
      iter.Seek(aEndSkipChild);
6381
      iter.Seek(aEndSkipChild);
6265
      iter.GetPreviousChild();
6382
      iter.GetPreviousChild();
6266
    }
6383
    }
6267
    nsIFrame* nextSibling = FindNextSibling(iter, childDisplay);
6384
    nsIFrame* nextSibling = FindNextSibling(iter, childDisplay);
6268
6385
    if (boxContents) {
6386
      if (nextSibling) {
6387
        aParentFrame = nextSibling->GetParent()->GetContentInsertionFrame();
6388
        return nextSibling->GetPrevSibling();
6389
      }
6390
      return GetInsertionPrevSibling(aParentFrame, aContainer->GetParent(),
6391
                                     aContainer, aIsAppend,
6392
                                     aIsRangeInsertSafe, nullptr, nullptr);
6393
    }
6269
    if (nextSibling) {
6394
    if (nextSibling) {
6270
      aParentFrame = nextSibling->GetParent()->GetContentInsertionFrame();
6395
      aParentFrame = nextSibling->GetParent()->GetContentInsertionFrame();
6271
    }
6396
    } else {
6272
    else {
6273
      // No previous or next sibling, so treat this like an appended frame.
6397
      // No previous or next sibling, so treat this like an appended frame.
6274
      *aIsAppend = true;
6398
      *aIsAppend = true;
6275
      if (IsFramePartOfIBSplit(aParentFrame)) {
6399
      if (IsFramePartOfIBSplit(aParentFrame)) {
6276
        // Since we're appending, we'll walk to the last anonymous frame
6400
        // Since we're appending, we'll walk to the last anonymous frame
6277
        // that was created for the broken inline frame.  But don't walk
6401
        // that was created for the broken inline frame.  But don't walk
6278
        // to the trailing inline if it's empty; stop at the block.
6402
        // to the trailing inline if it's empty; stop at the block.
6279
        aParentFrame = GetLastIBSplitSibling(aParentFrame, false);
6403
        aParentFrame = GetLastIBSplitSibling(aParentFrame, false);
6280
      }
6404
      }
 Lines 6282-6308   nsCSSFrameConstructor::GetInsertionPrevS Link Here 
6282
      // before the AdjustAppendParentForAfterContent call.
6406
      // before the AdjustAppendParentForAfterContent call.
6283
      aParentFrame = nsLayoutUtils::LastContinuationWithChild(aParentFrame);
6407
      aParentFrame = nsLayoutUtils::LastContinuationWithChild(aParentFrame);
6284
      // Deal with fieldsets
6408
      // Deal with fieldsets
6285
      aParentFrame = ::GetAdjustedParentFrame(aParentFrame,
6409
      aParentFrame = ::GetAdjustedParentFrame(aParentFrame,
6286
                                              aParentFrame->GetType(),
6410
                                              aParentFrame->GetType(),
6287
                                              aChild);
6411
                                              aChild);
6288
      nsIFrame* appendAfterFrame;
6412
      nsIFrame* appendAfterFrame;
6289
      aParentFrame =
6413
      aParentFrame =
6290
        ::AdjustAppendParentForAfterContent(mPresShell->GetPresContext(),
6414
        ::AdjustAppendParentForAfterContent(this, container, aParentFrame,
6291
                                            container, aParentFrame,
6415
                                            aChild, &appendAfterFrame);
6292
                                            &appendAfterFrame);
6293
      prevSibling = ::FindAppendPrevSibling(aParentFrame, appendAfterFrame);
6416
      prevSibling = ::FindAppendPrevSibling(aParentFrame, appendAfterFrame);
6294
    }
6417
    }
6295
  }
6418
  }
6296
6419
6297
  *aIsRangeInsertSafe = (childDisplay == UNSET_DISPLAY);
6420
  *aIsRangeInsertSafe = (childDisplay == UNSET_DISPLAY);
6298
  return prevSibling;
6421
  return prevSibling;
6299
}
6422
}
6300
6423
6424
nsContainerFrame*
6425
nsCSSFrameConstructor::GetContentInsertionFrameFor(nsIContent* aContent)
6426
{
6427
  // Get the primary frame associated with the content
6428
  nsIFrame* frame = aContent->GetPrimaryFrame();
6429
6430
  if (!frame) {
6431
    if (GetDisplayContents(aContent)) {
6432
      nsIContent* parent = aContent->GetParent();
6433
      frame = parent ? GetContentInsertionFrameFor(parent) : nullptr;
6434
    }
6435
    if (!frame) {
6436
      return nullptr;
6437
    }
6438
  } else {
6439
    // If the content of the frame is not the desired content then this is not
6440
    // really a frame for the desired content.
6441
    // XXX This check is needed due to bug 135040. Remove it once that's fixed.
6442
    if (frame->GetContent() != aContent) {
6443
      return nullptr;
6444
    }
6445
  }
6446
6447
  nsContainerFrame* insertionFrame = frame->GetContentInsertionFrame();
6448
6449
  NS_ASSERTION(!insertionFrame || insertionFrame == frame || !frame->IsLeaf(),
6450
    "The insertion frame is the primary frame or the primary frame isn't a leaf");
6451
6452
  return insertionFrame;
6453
}
6454
6301
static bool
6455
static bool
6302
IsSpecialFramesetChild(nsIContent* aContent)
6456
IsSpecialFramesetChild(nsIContent* aContent)
6303
{
6457
{
6304
  // IMPORTANT: This must match the conditions in nsHTMLFramesetFrame::Init.
6458
  // IMPORTANT: This must match the conditions in nsHTMLFramesetFrame::Init.
6305
  return aContent->IsHTML() &&
6459
  return aContent->IsHTML() &&
6306
    (aContent->Tag() == nsGkAtoms::frameset ||
6460
    (aContent->Tag() == nsGkAtoms::frameset ||
6307
     aContent->Tag() == nsGkAtoms::frame);
6461
     aContent->Tag() == nsGkAtoms::frame);
6308
}
6462
}
 Lines 6429-6444   nsCSSFrameConstructor::MaybeConstructLaz Link Here 
6429
    }
6583
    }
6430
    if (!noPrimaryFrame && !content->GetPrimaryFrame()) {
6584
    if (!noPrimaryFrame && !content->GetPrimaryFrame()) {
6431
      noPrimaryFrame = true;
6585
      noPrimaryFrame = true;
6432
    }
6586
    }
6433
    if (!needsFrameBitSet && content->HasFlag(NODE_NEEDS_FRAME)) {
6587
    if (!needsFrameBitSet && content->HasFlag(NODE_NEEDS_FRAME)) {
6434
      needsFrameBitSet = true;
6588
      needsFrameBitSet = true;
6435
    }
6589
    }
6436
#endif
6590
#endif
6591
    // XXXmats no lazy frames for display:contents descendants yet (bug 979782).
6592
    if (GetDisplayContents(content)) {
6593
      return false;
6594
    }
6437
    content->SetFlags(NODE_DESCENDANTS_NEED_FRAMES);
6595
    content->SetFlags(NODE_DESCENDANTS_NEED_FRAMES);
6438
    content = content->GetFlattenedTreeParent();
6596
    content = content->GetFlattenedTreeParent();
6439
  }
6597
  }
6440
#ifdef DEBUG
6598
#ifdef DEBUG
6441
  if (content && content->GetPrimaryFrame() &&
6599
  if (content && content->GetPrimaryFrame() &&
6442
      content->GetPrimaryFrame()->IsLeaf()) {
6600
      content->GetPrimaryFrame()->IsLeaf()) {
6443
    noPrimaryFrame = needsFrameBitSet = false;
6601
    noPrimaryFrame = needsFrameBitSet = false;
6444
  }
6602
  }
 Lines 6551-6568   void Link Here 
6551
nsCSSFrameConstructor::IssueSingleInsertNofications(nsIContent* aContainer,
6709
nsCSSFrameConstructor::IssueSingleInsertNofications(nsIContent* aContainer,
6552
                                                    nsIContent* aStartChild,
6710
                                                    nsIContent* aStartChild,
6553
                                                    nsIContent* aEndChild,
6711
                                                    nsIContent* aEndChild,
6554
                                                    bool aAllowLazyConstruction)
6712
                                                    bool aAllowLazyConstruction)
6555
{
6713
{
6556
  for (nsIContent* child = aStartChild;
6714
  for (nsIContent* child = aStartChild;
6557
       child != aEndChild;
6715
       child != aEndChild;
6558
       child = child->GetNextSibling()) {
6716
       child = child->GetNextSibling()) {
6559
    if ((child->GetPrimaryFrame() ||
6717
    if ((child->GetPrimaryFrame() || GetUndisplayedContent(child) ||
6560
         GetUndisplayedContent(child))
6718
         GetDisplayContents(child))
6561
#ifdef MOZ_XUL
6719
#ifdef MOZ_XUL
6562
        //  Except listboxes suck, so do NOT skip anything here if
6720
        //  Except listboxes suck, so do NOT skip anything here if
6563
        //  we plan to notify a listbox.
6721
        //  we plan to notify a listbox.
6564
        && !MaybeGetListBoxBodyFrame(aContainer, child)
6722
        && !MaybeGetListBoxBodyFrame(aContainer, child)
6565
#endif
6723
#endif
6566
        ) {
6724
        ) {
6567
      // Already have a frame or undisplayed entry for this content; a
6725
      // Already have a frame or undisplayed entry for this content; a
6568
      // previous ContentInserted in this loop must have reconstructed
6726
      // previous ContentInserted in this loop must have reconstructed
 Lines 6711-6727   nsCSSFrameConstructor::ContentAppended(n Link Here 
6711
    nsIContent* bindingParent = aContainer->GetBindingParent();
6869
    nsIContent* bindingParent = aContainer->GetBindingParent();
6712
    LAYOUT_PHASE_TEMP_EXIT();
6870
    LAYOUT_PHASE_TEMP_EXIT();
6713
    nsresult rv = RecreateFramesForContent(bindingParent, false);
6871
    nsresult rv = RecreateFramesForContent(bindingParent, false);
6714
    LAYOUT_PHASE_TEMP_REENTER();
6872
    LAYOUT_PHASE_TEMP_REENTER();
6715
    return rv;
6873
    return rv;
6716
  }
6874
  }
6717
6875
6718
  // Get the frame associated with the content
6876
  // Get the frame associated with the content
6719
  nsContainerFrame* parentFrame = ::GetContentInsertionFrameFor(aContainer);
6877
  nsContainerFrame* parentFrame = GetContentInsertionFrameFor(aContainer);
6720
6878
6721
  // See comment in ContentRangeInserted for why this is necessary.
6879
  // See comment in ContentRangeInserted for why this is necessary.
6722
  if (!parentFrame && !aContainer->IsActiveChildrenElement()) {
6880
  if (!parentFrame && !aContainer->IsActiveChildrenElement()) {
6723
    return NS_OK;
6881
    return NS_OK;
6724
  }
6882
  }
6725
6883
6726
  if (aAllowLazyConstruction &&
6884
  if (aAllowLazyConstruction &&
6727
      MaybeConstructLazily(CONTENTAPPEND, aContainer, aFirstNewContent)) {
6885
      MaybeConstructLazily(CONTENTAPPEND, aContainer, aFirstNewContent)) {
 Lines 6784-6802   nsCSSFrameConstructor::ContentAppended(n Link Here 
6784
  // We should never get here with fieldsets, since they have multiple
6942
  // We should never get here with fieldsets, since they have multiple
6785
  // insertion points.
6943
  // insertion points.
6786
  NS_ASSERTION(parentFrame->GetType() != nsGkAtoms::fieldSetFrame,
6944
  NS_ASSERTION(parentFrame->GetType() != nsGkAtoms::fieldSetFrame,
6787
               "Unexpected parent");
6945
               "Unexpected parent");
6788
6946
6789
  // Deal with possible :after generated content on the parent
6947
  // Deal with possible :after generated content on the parent
6790
  nsIFrame* parentAfterFrame;
6948
  nsIFrame* parentAfterFrame;
6791
  parentFrame =
6949
  parentFrame =
6792
    ::AdjustAppendParentForAfterContent(mPresShell->GetPresContext(),
6950
    ::AdjustAppendParentForAfterContent(this, aContainer, parentFrame,
6793
                                        aContainer, parentFrame,
6951
                                        aFirstNewContent, &parentAfterFrame);
6794
                                        &parentAfterFrame);
6795
6952
6796
  // Create some new frames
6953
  // Create some new frames
6797
  nsFrameConstructorState state(mPresShell,
6954
  nsFrameConstructorState state(mPresShell,
6798
                                GetAbsoluteContainingBlock(parentFrame, FIXED_POS),
6955
                                GetAbsoluteContainingBlock(parentFrame, FIXED_POS),
6799
                                GetAbsoluteContainingBlock(parentFrame, ABS_POS),
6956
                                GetAbsoluteContainingBlock(parentFrame, ABS_POS),
6800
                                GetFloatContainingBlock(parentFrame));
6957
                                GetFloatContainingBlock(parentFrame));
6801
  state.mTreeMatchContext.InitAncestors(aContainer->AsElement());
6958
  state.mTreeMatchContext.InitAncestors(aContainer->AsElement());
6802
6959
 Lines 7144-7169   nsCSSFrameConstructor::ContentRangeInser Link Here 
7144
    // the children of the host.
7301
    // the children of the host.
7145
    nsIContent* bindingParent = aContainer->GetBindingParent();
7302
    nsIContent* bindingParent = aContainer->GetBindingParent();
7146
    LAYOUT_PHASE_TEMP_EXIT();
7303
    LAYOUT_PHASE_TEMP_EXIT();
7147
    nsresult rv = RecreateFramesForContent(bindingParent, false);
7304
    nsresult rv = RecreateFramesForContent(bindingParent, false);
7148
    LAYOUT_PHASE_TEMP_REENTER();
7305
    LAYOUT_PHASE_TEMP_REENTER();
7149
    return rv;
7306
    return rv;
7150
  }
7307
  }
7151
7308
7152
  nsContainerFrame* parentFrame = ::GetContentInsertionFrameFor(aContainer);
7309
  nsContainerFrame* parentFrame = GetContentInsertionFrameFor(aContainer);
7153
  // The xbl:children element won't have a frame, but default content can have the children as
7310
  // The xbl:children element won't have a frame, but default content can have the children as
7154
  // a parent. While its uncommon to change the structure of the default content itself, a label,
7311
  // a parent. While its uncommon to change the structure of the default content itself, a label,
7155
  // for example, can be reframed by having its value attribute set or removed.
7312
  // for example, can be reframed by having its value attribute set or removed.
7156
  if (!parentFrame && !aContainer->IsActiveChildrenElement()) {
7313
  if (!parentFrame && !aContainer->IsActiveChildrenElement()) {
7157
    return NS_OK;
7314
    return NS_OK;
7158
  }
7315
  }
7159
7316
7160
  // Otherwise, we've got parent content. Find its frame.
7317
  // Otherwise, we've got parent content. Find its frame.
7161
  NS_ASSERTION(!parentFrame || parentFrame->GetContent() == aContainer, "New XBL code is possibly wrong!");
7318
  NS_ASSERTION(!parentFrame || parentFrame->GetContent() == aContainer ||
7319
               GetDisplayContents(aContainer), "New XBL code is possibly wrong!");
7162
7320
7163
  if (aAllowLazyConstruction &&
7321
  if (aAllowLazyConstruction &&
7164
      MaybeConstructLazily(CONTENTINSERT, aContainer, aStartChild)) {
7322
      MaybeConstructLazily(CONTENTINSERT, aContainer, aStartChild)) {
7165
    return NS_OK;
7323
    return NS_OK;
7166
  }
7324
  }
7167
7325
7168
  if (isSingleInsert) {
7326
  if (isSingleInsert) {
7169
    // See if we have an XBL insertion point. If so, then that's our
7327
    // See if we have an XBL insertion point. If so, then that's our
 Lines 7440-7459   nsCSSFrameConstructor::ContentRangeInser Link Here 
7440
                 frame1->GetType() == nsGkAtoms::fieldSetFrame ||
7598
                 frame1->GetType() == nsGkAtoms::fieldSetFrame ||
7441
                 (frame1->GetParent() &&
7599
                 (frame1->GetParent() &&
7442
                  frame1->GetParent()->GetType() == nsGkAtoms::fieldSetFrame),
7600
                  frame1->GetParent()->GetType() == nsGkAtoms::fieldSetFrame),
7443
                 "Unexpected frame types");
7601
                 "Unexpected frame types");
7444
#endif
7602
#endif
7445
    isAppend = true;
7603
    isAppend = true;
7446
    nsIFrame* appendAfterFrame;
7604
    nsIFrame* appendAfterFrame;
7447
    parentFrame =
7605
    parentFrame =
7448
      ::AdjustAppendParentForAfterContent(mPresShell->GetPresContext(),
7606
      ::AdjustAppendParentForAfterContent(this, container,
7449
                                          container,
7450
                                          frameItems.FirstChild()->GetParent(),
7607
                                          frameItems.FirstChild()->GetParent(),
7451
                                          &appendAfterFrame);
7608
                                          aStartChild, &appendAfterFrame);
7452
    prevSibling = ::FindAppendPrevSibling(parentFrame, appendAfterFrame);
7609
    prevSibling = ::FindAppendPrevSibling(parentFrame, appendAfterFrame);
7453
  }
7610
  }
7454
7611
7455
  if (haveFirstLineStyle && parentFrame == containingBlock) {
7612
  if (haveFirstLineStyle && parentFrame == containingBlock) {
7456
    // It's possible that the new frame goes into a first-line
7613
    // It's possible that the new frame goes into a first-line
7457
    // frame. Look at it and see...
7614
    // frame. Look at it and see...
7458
    if (isAppend) {
7615
    if (isAppend) {
7459
      // Use append logic when appending
7616
      // Use append logic when appending
 Lines 7583-7610   nsCSSFrameConstructor::ContentRemoved(ns Link Here 
7583
           static_cast<void*>(aChild),
7740
           static_cast<void*>(aChild),
7584
           static_cast<void*>(aOldNextSibling));
7741
           static_cast<void*>(aOldNextSibling));
7585
    if (gReallyNoisyContentUpdates) {
7742
    if (gReallyNoisyContentUpdates) {
7586
      aContainer->List(stdout, 0);
7743
      aContainer->List(stdout, 0);
7587
    }
7744
    }
7588
  }
7745
  }
7589
#endif
7746
#endif
7590
7747
7591
  nsPresContext *presContext = mPresShell->GetPresContext();
7748
  nsresult rv = NS_OK;
7592
  nsresult                  rv = NS_OK;
7593
7594
  // Find the child frame that maps the content
7595
  nsIFrame* childFrame = aChild->GetPrimaryFrame();
7749
  nsIFrame* childFrame = aChild->GetPrimaryFrame();
7596
7597
  if (!childFrame || childFrame->GetContent() != aChild) {
7750
  if (!childFrame || childFrame->GetContent() != aChild) {
7598
    // XXXbz the GetContent() != aChild check is needed due to bug 135040.
7751
    // XXXbz the GetContent() != aChild check is needed due to bug 135040.
7599
    // Remove it once that's fixed.
7752
    // Remove it once that's fixed.
7600
    ClearUndisplayedContentIn(aChild, aContainer);
7753
    ClearUndisplayedContentIn(aChild, aContainer);
7601
  }
7754
  }
7602
7755
  MOZ_ASSERT(!childFrame || !GetDisplayContents(aChild),
7756
             "display:contents nodes shouldn't have a frame");
7757
  if (!childFrame && GetDisplayContents(aChild)) {
7758
    FlattenedChildIterator iter(aChild);
7759
    for (nsIContent* c = iter.GetNextChild(); c; c = iter.GetNextChild()) {
7760
      if (c->GetPrimaryFrame() || GetDisplayContents(c)) {
7761
        LAYOUT_PHASE_TEMP_EXIT();
7762
        rv = ContentRemoved(aChild, c, nullptr, aFlags, aDidReconstruct);
7763
        LAYOUT_PHASE_TEMP_REENTER();
7764
        NS_ENSURE_SUCCESS(rv, rv);
7765
        if (*aDidReconstruct) {
7766
          return rv;
7767
        }
7768
      }
7769
    }
7770
    ClearDisplayContentsIn(aChild, aContainer);
7771
  }
7772
7773
  nsPresContext* presContext = mPresShell->GetPresContext();
7603
#ifdef MOZ_XUL
7774
#ifdef MOZ_XUL
7604
  if (NotifyListBoxBody(presContext, aContainer, aChild, aOldNextSibling,
7775
  if (NotifyListBoxBody(presContext, aContainer, aChild, aOldNextSibling,
7605
                        mDocument, childFrame, CONTENT_REMOVED))
7776
                        mDocument, childFrame, CONTENT_REMOVED))
7606
    return NS_OK;
7777
    return NS_OK;
7607
7778
7608
#endif // MOZ_XUL
7779
#endif // MOZ_XUL
7609
7780
7610
  // If we're removing the root, then make sure to remove things starting at
7781
  // If we're removing the root, then make sure to remove things starting at
 Lines 8431-8447   nsCSSFrameConstructor::GetInsertionPoint Link Here 
8431
8602
8432
  nsIContent* insertionElement;
8603
  nsIContent* insertionElement;
8433
  if (aChildContent) {
8604
  if (aChildContent) {
8434
    // We've got an explicit insertion child. Check to see if it's
8605
    // We've got an explicit insertion child. Check to see if it's
8435
    // anonymous.
8606
    // anonymous.
8436
    if (aChildContent->GetBindingParent() == aContainer) {
8607
    if (aChildContent->GetBindingParent() == aContainer) {
8437
      // This child content is anonymous. Don't use the insertion
8608
      // This child content is anonymous. Don't use the insertion
8438
      // point, since that's only for the explicit kids.
8609
      // point, since that's only for the explicit kids.
8439
      return ::GetContentInsertionFrameFor(aContainer);
8610
      return GetContentInsertionFrameFor(aContainer);
8440
    }
8611
    }
8441
8612
8442
    insertionElement = bindingManager->FindNestedInsertionPoint(aContainer, aChildContent);
8613
    insertionElement = bindingManager->FindNestedInsertionPoint(aContainer, aChildContent);
8443
  }
8614
  }
8444
  else {
8615
  else {
8445
    bool multiple;
8616
    bool multiple;
8446
    insertionElement = bindingManager->FindNestedSingleInsertionPoint(aContainer, &multiple);
8617
    insertionElement = bindingManager->FindNestedSingleInsertionPoint(aContainer, &multiple);
8447
8618
 Lines 8452-8469   nsCSSFrameConstructor::GetInsertionPoint Link Here 
8452
      return nullptr;
8623
      return nullptr;
8453
    }
8624
    }
8454
  }
8625
  }
8455
8626
8456
  if (!insertionElement) {
8627
  if (!insertionElement) {
8457
    insertionElement = aContainer;
8628
    insertionElement = aContainer;
8458
  }
8629
  }
8459
8630
8460
  nsContainerFrame* insertionPoint =
8631
  nsContainerFrame* insertionPoint = GetContentInsertionFrameFor(insertionElement);
8461
    ::GetContentInsertionFrameFor(insertionElement);
8462
8632
8463
  // fieldsets have multiple insertion points.  Note that we might
8633
  // fieldsets have multiple insertion points.  Note that we might
8464
  // have to look at insertionElement here...
8634
  // have to look at insertionElement here...
8465
  if (aMultiple && insertionElement->IsHTML(nsGkAtoms::fieldset)) {
8635
  if (aMultiple && insertionElement->IsHTML(nsGkAtoms::fieldset)) {
8466
    *aMultiple = true;
8636
    *aMultiple = true;
8467
  }
8637
  }
8468
8638
8469
  return insertionPoint;
8639
  return insertionPoint;
(-)a/layout/base/nsCSSFrameConstructor.h (+27 lines)
Line     Link Here 
 Lines 296-311   private: Link Here 
296
  // may suppress the construction of white-space-only text frames
296
  // may suppress the construction of white-space-only text frames
297
  // must be skipped for these items and items around them.
297
  // must be skipped for these items and items around them.
298
  void AddFrameConstructionItems(nsFrameConstructorState& aState,
298
  void AddFrameConstructionItems(nsFrameConstructorState& aState,
299
                                 nsIContent*              aContent,
299
                                 nsIContent*              aContent,
300
                                 bool                     aSuppressWhiteSpaceOptimizations,
300
                                 bool                     aSuppressWhiteSpaceOptimizations,
301
                                 nsContainerFrame*        aParentFrame,
301
                                 nsContainerFrame*        aParentFrame,
302
                                 FrameConstructionItemList& aItems);
302
                                 FrameConstructionItemList& aItems);
303
303
304
  // Helper method for AddFrameConstructionItems etc.
305
  // Unsets the need-frame/restyle bits on aContent.
306
  // return true iff we should attempt to create frames for aContent.
307
  bool ShouldCreateItemsForChild(nsFrameConstructorState& aState,
308
                                 nsIContent* aContent,
309
                                 nsContainerFrame* aParentFrame);
310
311
  // Helper method for AddFrameConstructionItems etc.
312
  // Make sure ShouldCreateItemsForChild() returned true before calling this.
313
  void DoAddFrameConstructionItems(nsFrameConstructorState& aState,
314
                                   nsIContent* aContent,
315
                                   nsStyleContext* aStyleContext,
316
                                   bool aSuppressWhiteSpaceOptimizations,
317
                                   nsContainerFrame* aParentFrame,
318
                                   nsTArray<nsIAnonymousContentCreator::ContentInfo>* aAnonChildren,
319
                                   FrameConstructionItemList& aItems);
320
304
  // Construct the frames for the document element.  This can return null if the
321
  // Construct the frames for the document element.  This can return null if the
305
  // document element is display:none, or if the document element has a
322
  // document element is display:none, or if the document element has a
306
  // not-yet-loaded XBL binding, or if it's an SVG element that's not <svg>.
323
  // not-yet-loaded XBL binding, or if it's an SVG element that's not <svg>.
307
  nsIFrame* ConstructDocElementFrame(Element*                 aDocElement,
324
  nsIFrame* ConstructDocElementFrame(Element*                 aDocElement,
308
                                     nsILayoutHistoryState*   aFrameState);
325
                                     nsILayoutHistoryState*   aFrameState);
309
326
310
  // Set up our mDocElementContainingBlock correctly for the given root
327
  // Set up our mDocElementContainingBlock correctly for the given root
311
  // content.
328
  // content.
 Lines 566-581   private: Link Here 
566
  /* If FCDATA_CREATE_BLOCK_WRAPPER_FOR_ALL_KIDS is set, then create a
583
  /* If FCDATA_CREATE_BLOCK_WRAPPER_FOR_ALL_KIDS is set, then create a
567
     block formatting context wrapper around the kids of this frame
584
     block formatting context wrapper around the kids of this frame
568
     using the FrameConstructionData's mPseudoAtom for its anonymous
585
     using the FrameConstructionData's mPseudoAtom for its anonymous
569
     box type. */
586
     box type. */
570
#define FCDATA_CREATE_BLOCK_WRAPPER_FOR_ALL_KIDS 0x40000
587
#define FCDATA_CREATE_BLOCK_WRAPPER_FOR_ALL_KIDS 0x40000
571
  /* If FCDATA_IS_SVG_TEXT is set, then this text frame is a descendant of
588
  /* If FCDATA_IS_SVG_TEXT is set, then this text frame is a descendant of
572
     an SVG text frame. */
589
     an SVG text frame. */
573
#define FCDATA_IS_SVG_TEXT 0x80000
590
#define FCDATA_IS_SVG_TEXT 0x80000
591
  /**
592
   * display:contents
593
   */
594
#define FCDATA_IS_CONTENTS 0x100000
574
595
575
  /* Structure representing information about how a frame should be
596
  /* Structure representing information about how a frame should be
576
     constructed.  */
597
     constructed.  */
577
  struct FrameConstructionData {
598
  struct FrameConstructionData {
578
    // Flag bits that can modify the way the construction happens
599
    // Flag bits that can modify the way the construction happens
579
    uint32_t mBits;
600
    uint32_t mBits;
580
    // We have exactly one of three types of functions, so use a union for
601
    // We have exactly one of three types of functions, so use a union for
581
    // better cache locality for the ones that aren't pointer-to-member.  That
602
    // better cache locality for the ones that aren't pointer-to-member.  That
 Lines 1736-1751   private: Link Here 
1736
  nsIFrame* GetInsertionPrevSibling(nsContainerFrame*& aParentFrame, /* inout */
1757
  nsIFrame* GetInsertionPrevSibling(nsContainerFrame*& aParentFrame, /* inout */
1737
                                    nsIContent* aContainer,
1758
                                    nsIContent* aContainer,
1738
                                    nsIContent* aChild,
1759
                                    nsIContent* aChild,
1739
                                    bool* aIsAppend,
1760
                                    bool* aIsAppend,
1740
                                    bool* aIsRangeInsertSafe,
1761
                                    bool* aIsRangeInsertSafe,
1741
                                    nsIContent* aStartSkipChild = nullptr,
1762
                                    nsIContent* aStartSkipChild = nullptr,
1742
                                    nsIContent *aEndSkipChild = nullptr);
1763
                                    nsIContent *aEndSkipChild = nullptr);
1743
1764
1765
  /**
1766
   * Return the insertion frame of the primary frame of aContent, or its nearest
1767
   * ancestor that isn't display-box:contents.
1768
   */
1769
  nsContainerFrame* GetContentInsertionFrameFor(nsIContent* aContent);
1770
1744
  // see if aContent and aSibling are legitimate siblings due to restrictions
1771
  // see if aContent and aSibling are legitimate siblings due to restrictions
1745
  // imposed by table columns
1772
  // imposed by table columns
1746
  // XXXbz this code is generally wrong, since the frame for aContent
1773
  // XXXbz this code is generally wrong, since the frame for aContent
1747
  // may be constructed based on tag, not based on aDisplay!
1774
  // may be constructed based on tag, not based on aDisplay!
1748
  bool IsValidSibling(nsIFrame*              aSibling,
1775
  bool IsValidSibling(nsIFrame*              aSibling,
1749
                        nsIContent*            aContent,
1776
                        nsIContent*            aContent,
1750
                        uint8_t&               aDisplay);
1777
                        uint8_t&               aDisplay);
1751
1778

Return to bug 907396