Attachment #8442176: 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 2965-2973   RestyleManager::ComputeStyleChangeFor(ns Link Here 
2965
        NS_ASSERTION(!cont->GetPrevContinuation(),
2965
        NS_ASSERTION(!cont->GetPrevContinuation(),
2966
                     "continuing frame had more severe impact than first-in-flow");
2966
                     "continuing frame had more severe impact than first-in-flow");
2967
        return;
2967
        return;
2968
      }
2968
      }
2969
    }
2969
    }
2970
  }
2970
  }
2971
}
2971
}
2972
2972
2973
AutoDisplayContentsAncestorPusher::AutoDisplayContentsAncestorPusher(
2974
  TreeMatchContext& aTreeMatchContext, nsPresContext* aPresContext,
2975
  nsIContent* aParent)
2976
  : mTreeMatchContext(aTreeMatchContext)
2977
  , mPresContext(aPresContext)
2978
{
2979
  if (aParent && mTreeMatchContext.mAncestorFilter.HasFilter()) {
2980
    nsFrameManager* fm = mPresContext->FrameManager();
2981
    // Push display:contents mAncestors onto mTreeMatchContext.
2982
    for (nsIContent* p = aParent; p && fm->GetDisplayContents(p);
2983
         p = p->GetParent()) {
2984
      mAncestors.AppendElement(p->AsElement());
2985
    }
2986
    nsTArray<mozilla::dom::Element*>::size_type i = mAncestors.Length();
2987
    while (i--) {
2988
      mTreeMatchContext.mAncestorFilter.PushAncestor(mAncestors[i]);
2989
      mTreeMatchContext.PushStyleScope(mAncestors[i]);
2990
    }
2991
  }
2992
2993
}
2994
2995
AutoDisplayContentsAncestorPusher::~AutoDisplayContentsAncestorPusher()
2996
{
2997
  // Pop the ancestors we pushed in the CTOR, if any.
2998
  nsTArray<mozilla::dom::Element*>::size_type i = mAncestors.Length();
2999
  while (i--) {
3000
    mTreeMatchContext.mAncestorFilter.PopAncestor();
3001
    mTreeMatchContext.PopStyleScope(mAncestors[i]);
3002
  }
3003
}
3004
2973
} // namespace mozilla
3005
} // 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 270-286   private: Link Here 
270
  RestyleTracker mPendingRestyles;
271
  RestyleTracker mPendingRestyles;
271
  RestyleTracker mPendingAnimationRestyles;
272
  RestyleTracker mPendingAnimationRestyles;
272
};
273
};
273
274
274
/**
275
/**
275
 * An ElementRestyler is created for *each* element in a subtree that we
276
 * An ElementRestyler is created for *each* element in a subtree that we
276
 * recompute styles for.
277
 * recompute styles for.
277
 */
278
 */
278
class ElementRestyler MOZ_FINAL {
279
class ElementRestyler MOZ_FINAL
280
{
279
public:
281
public:
280
  typedef mozilla::dom::Element Element;
282
  typedef mozilla::dom::Element Element;
281
283
282
  // Construct for the root of the subtree that we're restyling.
284
  // Construct for the root of the subtree that we're restyling.
283
  ElementRestyler(nsPresContext* aPresContext,
285
  ElementRestyler(nsPresContext* aPresContext,
284
                  nsIFrame* aFrame,
286
                  nsIFrame* aFrame,
285
                  nsStyleChangeList* aChangeList,
287
                  nsStyleChangeList* aChangeList,
286
                  nsChangeHint aHintsHandledByAncestors,
288
                  nsChangeHint aHintsHandledByAncestors,
 Lines 396-406   private: Link Here 
396
  const DesiredA11yNotifications mDesiredA11yNotifications;
398
  const DesiredA11yNotifications mDesiredA11yNotifications;
397
  DesiredA11yNotifications mKidsDesiredA11yNotifications;
399
  DesiredA11yNotifications mKidsDesiredA11yNotifications;
398
  A11yNotificationType mOurA11yNotification;
400
  A11yNotificationType mOurA11yNotification;
399
  nsTArray<nsIContent*>& mVisibleKidsOfHiddenElement;
401
  nsTArray<nsIContent*>& mVisibleKidsOfHiddenElement;
400
  bool mWasFrameVisible;
402
  bool mWasFrameVisible;
401
#endif
403
#endif
402
};
404
};
403
405
406
/**
407
 * This pushes any display:contents nodes onto a TreeMatchContext.
408
 * Use it before resolving style for kids of aParent where aParent
409
 * (and further ancestors) may be display:contents nodes which have
410
 * not yet been pushed onto TreeMatchContext.
411
 */
412
class MOZ_STACK_CLASS AutoDisplayContentsAncestorPusher MOZ_FINAL
413
{
414
 public:
415
  typedef mozilla::dom::Element Element;
416
  AutoDisplayContentsAncestorPusher(TreeMatchContext& aTreeMatchContext,
417
                                    nsPresContext*    aPresContext,
418
                                    nsIContent*       aParent);
419
  ~AutoDisplayContentsAncestorPusher();
420
  bool IsEmpty() const { return mAncestors.Length() == 0; }
421
private:
422
  TreeMatchContext& mTreeMatchContext;
423
  nsPresContext* const mPresContext;
424
  nsAutoTArray<mozilla::dom::Element*, 4> mAncestors;
425
};
426
404
} // namespace mozilla
427
} // namespace mozilla
405
428
406
#endif /* mozilla_RestyleManager_h */
429
#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 / +282 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 4563-4579   nsCSSFrameConstructor::FindDisplayData(c Link Here 
4563
                       &nsCSSFrameConstructor::ConstructTableCol) },
4545
                       &nsCSSFrameConstructor::ConstructTableCol) },
4564
    { NS_STYLE_DISPLAY_TABLE_ROW,
4546
    { NS_STYLE_DISPLAY_TABLE_ROW,
4565
      FULL_CTOR_FCDATA(FCDATA_IS_TABLE_PART |
4547
      FULL_CTOR_FCDATA(FCDATA_IS_TABLE_PART |
4566
                       FCDATA_DESIRED_PARENT_TYPE_TO_BITS(eTypeRowGroup),
4548
                       FCDATA_DESIRED_PARENT_TYPE_TO_BITS(eTypeRowGroup),
4567
                       &nsCSSFrameConstructor::ConstructTableRowOrRowGroup) },
4549
                       &nsCSSFrameConstructor::ConstructTableRowOrRowGroup) },
4568
    { NS_STYLE_DISPLAY_TABLE_CELL,
4550
    { NS_STYLE_DISPLAY_TABLE_CELL,
4569
      FULL_CTOR_FCDATA(FCDATA_IS_TABLE_PART |
4551
      FULL_CTOR_FCDATA(FCDATA_IS_TABLE_PART |
4570
                       FCDATA_DESIRED_PARENT_TYPE_TO_BITS(eTypeRow),
4552
                       FCDATA_DESIRED_PARENT_TYPE_TO_BITS(eTypeRow),
4571
                       &nsCSSFrameConstructor::ConstructTableCell) }
4553
                       &nsCSSFrameConstructor::ConstructTableCell) },
4554
    { NS_STYLE_DISPLAY_CONTENTS,
4555
      FULL_CTOR_FCDATA(FCDATA_IS_CONTENTS, nullptr/*never called*/) }
4572
  };
4556
  };
4573
4557
4574
  return FindDataByInt(aDisplay->mDisplay,
4558
  return FindDataByInt(aDisplay->mDisplay,
4575
                       aElement, aStyleContext, sDisplayData,
4559
                       aElement, aStyleContext, sDisplayData,
4576
                       ArrayLength(sDisplayData));
4560
                       ArrayLength(sDisplayData));
4577
}
4561
}
4578
4562
4579
nsIFrame*
4563
nsIFrame*
 Lines 4682-4712   nsCSSFrameConstructor::InitAndRestoreFra Link Here 
4682
  }
4666
  }
4683
}
4667
}
4684
4668
4685
already_AddRefed<nsStyleContext>
4669
already_AddRefed<nsStyleContext>
4686
nsCSSFrameConstructor::ResolveStyleContext(nsIFrame*         aParentFrame,
4670
nsCSSFrameConstructor::ResolveStyleContext(nsIFrame*         aParentFrame,
4687
                                           nsIContent*       aContent,
4671
                                           nsIContent*       aContent,
4688
                                           nsFrameConstructorState* aState)
4672
                                           nsFrameConstructorState* aState)
4689
{
4673
{
4690
  nsStyleContext* parentStyleContext = nullptr;
4674
  nsIContent* container = aContent->GetParent();
4691
  NS_ASSERTION(aContent->GetParent(), "Must have parent here");
4675
  NS_ASSERTION(container, "Must have parent here");
4692
4676
  nsStyleContext* parentStyleContext = GetDisplayContents(container);
4693
  aParentFrame = nsFrame::CorrectStyleParentFrame(aParentFrame, nullptr);
4677
  if (MOZ_LIKELY(!parentStyleContext)) {
4694
4678
    aParentFrame = nsFrame::CorrectStyleParentFrame(aParentFrame, nullptr);
4695
  if (aParentFrame) {
4679
    if (aParentFrame) {
4696
    // Resolve the style context based on the content object and the parent
4680
      // Resolve the style context based on the content object and the parent
4697
    // style context
4681
      // style context
4698
    parentStyleContext = aParentFrame->StyleContext();
4682
      parentStyleContext = aParentFrame->StyleContext();
4699
  } else {
4683
    } else {
4700
    // Perhaps aParentFrame is a canvasFrame and we're replicating
4684
      // Perhaps aParentFrame is a canvasFrame and we're replicating
4701
    // fixed-pos frames.
4685
      // fixed-pos frames.
4702
    // XXX should we create a way to tell ConstructFrame which style
4686
      // XXX should we create a way to tell ConstructFrame which style
4703
    // context to use, and pass it the style context for the
4687
      // context to use, and pass it the style context for the
4704
    // previous page's fixed-pos frame?
4688
      // previous page's fixed-pos frame?
4689
    }
4705
  }
4690
  }
4706
4691
4707
  return ResolveStyleContext(parentStyleContext, aContent, aState);
4692
  return ResolveStyleContext(parentStyleContext, aContent, aState);
4708
}
4693
}
4709
4694
4710
already_AddRefed<nsStyleContext>
4695
already_AddRefed<nsStyleContext>
4711
nsCSSFrameConstructor::ResolveStyleContext(nsStyleContext* aParentStyleContext,
4696
nsCSSFrameConstructor::ResolveStyleContext(nsStyleContext* aParentStyleContext,
4712
                                           nsIContent* aContent,
4697
                                           nsIContent* aContent,
 Lines 5202-5223   nsCSSFrameConstructor::AddPageBreakItem( Link Here 
5202
5187
5203
  // Lie about the tag and namespace so we don't trigger anything
5188
  // Lie about the tag and namespace so we don't trigger anything
5204
  // interesting during frame construction.
5189
  // interesting during frame construction.
5205
  aItems.AppendItem(&sPageBreakData, aContent, nsCSSAnonBoxes::pageBreak,
5190
  aItems.AppendItem(&sPageBreakData, aContent, nsCSSAnonBoxes::pageBreak,
5206
                    kNameSpaceID_None, nullptr, pseudoStyle.forget(),
5191
                    kNameSpaceID_None, nullptr, pseudoStyle.forget(),
5207
                    true, nullptr);
5192
                    true, nullptr);
5208
}
5193
}
5209
5194
5210
void
5195
bool
5211
nsCSSFrameConstructor::AddFrameConstructionItems(nsFrameConstructorState& aState,
5196
nsCSSFrameConstructor::ShouldCreateItemsForChild(nsFrameConstructorState& aState,
5212
                                                 nsIContent* aContent,
5197
                                                 nsIContent* aContent,
5213
                                                 bool aSuppressWhiteSpaceOptimizations,
5198
                                                 nsContainerFrame* aParentFrame)
5214
                                                 nsContainerFrame* aParentFrame,
5215
                                                 FrameConstructionItemList& aItems)
5216
{
5199
{
5217
  aContent->UnsetFlags(NODE_DESCENDANTS_NEED_FRAMES | NODE_NEEDS_FRAME);
5200
  aContent->UnsetFlags(NODE_DESCENDANTS_NEED_FRAMES | NODE_NEEDS_FRAME);
5218
  if (aContent->IsElement()) {
5201
  if (aContent->IsElement()) {
5219
    // We can't just remove our pending restyle flags, since we may
5202
    // We can't just remove our pending restyle flags, since we may
5220
    // have restyle-later-siblings set on us.  But we _can_ remove the
5203
    // have restyle-later-siblings set on us.  But we _can_ remove the
5221
    // "is possible restyle root" flags, and need to.  Otherwise we can
5204
    // "is possible restyle root" flags, and need to.  Otherwise we can
5222
    // end up with stale such flags (e.g. if we used to have a
5205
    // end up with stale such flags (e.g. if we used to have a
5223
    // display:none parent when our last restyle was posted and
5206
    // display:none parent when our last restyle was posted and
 Lines 5228-5275   nsCSSFrameConstructor::AddFrameConstruct Link Here 
5228
5211
5229
  // XXX the GetContent() != aContent check is needed due to bug 135040.
5212
  // XXX the GetContent() != aContent check is needed due to bug 135040.
5230
  // Remove it once that's fixed.
5213
  // Remove it once that's fixed.
5231
  if (aContent->GetPrimaryFrame() &&
5214
  if (aContent->GetPrimaryFrame() &&
5232
      aContent->GetPrimaryFrame()->GetContent() == aContent &&
5215
      aContent->GetPrimaryFrame()->GetContent() == aContent &&
5233
      !aState.mCreatingExtraFrames) {
5216
      !aState.mCreatingExtraFrames) {
5234
    NS_ERROR("asked to create frame construction item for a node that already "
5217
    NS_ERROR("asked to create frame construction item for a node that already "
5235
             "has a frame");
5218
             "has a frame");
5236
    return;
5219
    return false;
5237
  }
5220
  }
5238
5221
5239
  // don't create a whitespace frame if aParent doesn't want it
5222
  // don't create a whitespace frame if aParent doesn't want it
5240
  if (!NeedFrameFor(aState, aParentFrame, aContent)) {
5223
  if (!NeedFrameFor(aState, aParentFrame, aContent)) {
5241
    return;
5224
    return false;
5242
  }
5225
  }
5243
5226
5244
  // never create frames for comments or PIs
5227
  // never create frames for comments or PIs
5245
  if (aContent->IsNodeOfType(nsINode::eCOMMENT) ||
5228
  if (aContent->IsNodeOfType(nsINode::eCOMMENT) ||
5246
      aContent->IsNodeOfType(nsINode::ePROCESSING_INSTRUCTION))
5229
      aContent->IsNodeOfType(nsINode::ePROCESSING_INSTRUCTION)) {
5247
    return;
5230
    return false;
5248
5231
  }
5249
  nsRefPtr<nsStyleContext> styleContext;
5232
5250
  styleContext = ResolveStyleContext(aParentFrame, aContent, &aState);
5233
  return true;
5251
5234
}
5235
5236
void
5237
nsCSSFrameConstructor::DoAddFrameConstructionItems(nsFrameConstructorState& aState,
5238
                                                   nsIContent* aContent,
5239
                                                   nsStyleContext* aStyleContext,
5240
                                                   bool aSuppressWhiteSpaceOptimizations,
5241
                                                   nsContainerFrame* aParentFrame,
5242
                                                   nsTArray<nsIAnonymousContentCreator::ContentInfo>* aAnonChildren,
5243
                                                   FrameConstructionItemList& aItems)
5244
{
5252
  uint32_t flags = ITEM_ALLOW_XBL_BASE | ITEM_ALLOW_PAGE_BREAK;
5245
  uint32_t flags = ITEM_ALLOW_XBL_BASE | ITEM_ALLOW_PAGE_BREAK;
5253
  if (aParentFrame->IsSVGText()) {
5246
  if (aParentFrame) {
5254
    flags |= ITEM_IS_WITHIN_SVG_TEXT;
5247
    if (aParentFrame->IsSVGText()) {
5255
  }
5248
      flags |= ITEM_IS_WITHIN_SVG_TEXT;
5256
  if (aParentFrame->GetType() == nsGkAtoms::blockFrame &&
5249
    }
5257
      aParentFrame->GetParent() &&
5250
    if (aParentFrame->GetType() == nsGkAtoms::blockFrame &&
5258
      aParentFrame->GetParent()->GetType() == nsGkAtoms::svgTextFrame) {
5251
        aParentFrame->GetParent() &&
5259
    flags |= ITEM_ALLOWS_TEXT_PATH_CHILD;
5252
        aParentFrame->GetParent()->GetType() == nsGkAtoms::svgTextFrame) {
5253
      flags |= ITEM_ALLOWS_TEXT_PATH_CHILD;
5254
    }
5260
  }
5255
  }
5261
  AddFrameConstructionItemsInternal(aState, aContent, aParentFrame,
5256
  AddFrameConstructionItemsInternal(aState, aContent, aParentFrame,
5262
                                    aContent->Tag(), aContent->GetNameSpaceID(),
5257
                                    aContent->Tag(), aContent->GetNameSpaceID(),
5263
                                    aSuppressWhiteSpaceOptimizations,
5258
                                    aSuppressWhiteSpaceOptimizations,
5264
                                    styleContext,
5259
                                    aStyleContext,
5265
                                    flags, nullptr,
5260
                                    flags, aAnonChildren,
5266
                                    aItems);
5261
                                    aItems);
5267
}
5262
}
5263
  
5264
void
5265
nsCSSFrameConstructor::AddFrameConstructionItems(nsFrameConstructorState& aState,
5266
                                                 nsIContent* aContent,
5267
                                                 bool aSuppressWhiteSpaceOptimizations,
5268
                                                 nsContainerFrame* aParentFrame,
5269
                                                 FrameConstructionItemList& aItems)
5270
{
5271
  if (!ShouldCreateItemsForChild(aState, aContent, aParentFrame)) {
5272
    return;
5273
  }
5274
  nsRefPtr<nsStyleContext> styleContext =
5275
    ResolveStyleContext(aParentFrame, aContent, &aState);
5276
  DoAddFrameConstructionItems(aState, aContent, styleContext,
5277
                              aSuppressWhiteSpaceOptimizations, aParentFrame,
5278
                              nullptr, aItems);
5279
}
5268
5280
5269
/* static */ void
5281
/* static */ void
5270
nsCSSFrameConstructor::SetAsUndisplayedContent(FrameConstructionItemList& aList,
5282
nsCSSFrameConstructor::SetAsUndisplayedContent(FrameConstructionItemList& aList,
5271
                                               nsIContent* aContent,
5283
                                               nsIContent* aContent,
5272
                                               nsStyleContext* aStyleContext,
5284
                                               nsStyleContext* aStyleContext,
5273
                                               bool aIsGeneratedContent)
5285
                                               bool aIsGeneratedContent)
5274
{
5286
{
5275
  if (aStyleContext->GetPseudo()) {
5287
  if (aStyleContext->GetPseudo()) {
 Lines 5464-5479   nsCSSFrameConstructor::AddFrameConstruct Link Here 
5464
    !display->IsAbsolutelyPositionedStyle() &&
5476
    !display->IsAbsolutelyPositionedStyle() &&
5465
    !(bits & FCDATA_IS_TABLE_PART) &&
5477
    !(bits & FCDATA_IS_TABLE_PART) &&
5466
    !(bits & FCDATA_IS_SVG_TEXT);
5478
    !(bits & FCDATA_IS_SVG_TEXT);
5467
5479
5468
  if (canHavePageBreak && display->mBreakBefore) {
5480
  if (canHavePageBreak && display->mBreakBefore) {
5469
    AddPageBreakItem(aContent, aStyleContext, aItems);
5481
    AddPageBreakItem(aContent, aStyleContext, aItems);
5470
  }
5482
  }
5471
5483
5484
  if (MOZ_UNLIKELY(bits & FCDATA_IS_CONTENTS)) {
5485
    if (!GetDisplayContents(aContent)) {
5486
      if (styleContext->GetPseudo()) {
5487
        if (isGeneratedContent) {
5488
          aContent->UnbindFromTree();
5489
        }
5490
      } else {
5491
        MOZ_ASSERT(!isGeneratedContent, "Should have had pseudo type");
5492
        aState.mFrameManager->SetDisplayContents(aContent, styleContext);
5493
      }
5494
    } else {
5495
      aState.mFrameManager->ChangeDisplayContents(aContent, styleContext);
5496
    }
5497
5498
    TreeMatchContext::AutoAncestorPusher ancestorPusher(aState.mTreeMatchContext);
5499
    if (aState.mTreeMatchContext.mAncestorFilter.HasFilter()) {
5500
      ancestorPusher.PushAncestorAndStyleScope(aContent->AsElement());
5501
    } else {
5502
      ancestorPusher.PushStyleScope(aContent->AsElement());
5503
    }
5504
5505
    if (aParentFrame) {
5506
      aParentFrame->AddStateBits(NS_FRAME_MAY_HAVE_GENERATED_CONTENT);
5507
    }
5508
    CreateGeneratedContentItem(aState, aParentFrame, aContent, styleContext,
5509
                               nsCSSPseudoElements::ePseudo_before, aItems);
5510
5511
    FlattenedChildIterator iter(aContent);
5512
    for (nsIContent* child = iter.GetNextChild(); child; child = iter.GetNextChild()) {
5513
      if (!ShouldCreateItemsForChild(aState, child, aParentFrame)) {
5514
        continue;
5515
      }
5516
5517
      // Get the parent of the content and check if it is a XBL children element
5518
      // (if the content is a children element then parent != aContent because the
5519
      // FlattenedChildIterator will transitively iterate through <xbl:children>
5520
      // for default content). Push the children element as an ancestor here because
5521
      // it does not have a frame and would not otherwise be pushed as an ancestor.
5522
      nsIContent* parent = child->GetParent();
5523
      MOZ_ASSERT(parent, "Parent must be non-null because we are iterating children.");
5524
      TreeMatchContext::AutoAncestorPusher ancestorPusher(aState.mTreeMatchContext);
5525
      if (parent != aContent && parent->IsElement()) {
5526
        if (aState.mTreeMatchContext.mAncestorFilter.HasFilter()) {
5527
          ancestorPusher.PushAncestorAndStyleScope(parent->AsElement());
5528
        } else {
5529
          ancestorPusher.PushStyleScope(parent->AsElement());
5530
        }
5531
      }
5532
5533
      nsRefPtr<nsStyleContext> childContext =
5534
        ResolveStyleContext(styleContext, child, nullptr);
5535
      DoAddFrameConstructionItems(aState, child, childContext,
5536
                                  aSuppressWhiteSpaceOptimizations,
5537
                                  aParentFrame, aAnonChildren, aItems);
5538
    }
5539
    aItems.SetParentHasNoXBLChildren(!iter.XBLInvolved());
5540
5541
    CreateGeneratedContentItem(aState, aParentFrame, aContent, styleContext,
5542
                               nsCSSPseudoElements::ePseudo_after, aItems);
5543
    if (canHavePageBreak && display->mBreakAfter) {
5544
      AddPageBreakItem(aContent, aStyleContext, aItems);
5545
    }
5546
    return;
5547
  }
5548
5472
  FrameConstructionItem* item =
5549
  FrameConstructionItem* item =
5473
    aItems.AppendItem(data, aContent, aTag, aNameSpaceID,
5550
    aItems.AppendItem(data, aContent, aTag, aNameSpaceID,
5474
                      pendingBinding, styleContext.forget(),
5551
                      pendingBinding, styleContext.forget(),
5475
                      aSuppressWhiteSpaceOptimizations, aAnonChildren);
5552
                      aSuppressWhiteSpaceOptimizations, aAnonChildren);
5476
  if (!item) {
5553
  if (!item) {
5477
    if (isGeneratedContent) {
5554
    if (isGeneratedContent) {
5478
      aContent->UnbindFromTree();
5555
      aContent->UnbindFromTree();
5479
    }
5556
    }
 Lines 5826-5856   nsCSSFrameConstructor::GetFloatContainin Link Here 
5826
5903
5827
/**
5904
/**
5828
 * This function will check whether aContainer has :after generated content.
5905
 * This function will check whether aContainer has :after generated content.
5829
 * If so, appending to it should actually insert.  The return value is the
5906
 * If so, appending to it should actually insert.  The return value is the
5830
 * parent to use for newly-appended content.  *aAfterFrame points to the :after
5907
 * parent to use for newly-appended content.  *aAfterFrame points to the :after
5831
 * frame before which appended content should go, if there is one.
5908
 * frame before which appended content should go, if there is one.
5832
 */
5909
 */
5833
static nsContainerFrame*
5910
static nsContainerFrame*
5834
AdjustAppendParentForAfterContent(nsPresContext* aPresContext,
5911
AdjustAppendParentForAfterContent(nsFrameManager* aFrameManager,
5835
                                  nsIContent* aContainer,
5912
                                  nsIContent* aContainer,
5836
                                  nsContainerFrame* aParentFrame,
5913
                                  nsContainerFrame* aParentFrame,
5914
                                  nsIContent* aChild,
5837
                                  nsIFrame** aAfterFrame)
5915
                                  nsIFrame** aAfterFrame)
5838
{
5916
{
5839
  // See if the parent has an :after pseudo-element.  Check for the presence
5917
  // If the parent frame has any pseudo-elements or aContainer is a
5840
  // of style first, since nsLayoutUtils::GetAfterFrame is sorta expensive.
5918
  // display:contents node then we need to walk through the child
5841
  nsStyleContext* parentStyle = aParentFrame->StyleContext();
5919
  // frames to find the first one that is either a ::after frame for an
5842
  if (nsLayoutUtils::HasPseudoStyle(aContainer, parentStyle,
5920
  // ancestor of aChild or a frame that is for a node later in the
5921
  // document than aChild and return that in aAfterFrame.
5922
  if (nsLayoutUtils::HasPseudoStyle(aContainer, aParentFrame->StyleContext(),
5843
                                    nsCSSPseudoElements::ePseudo_after,
5923
                                    nsCSSPseudoElements::ePseudo_after,
5844
                                    aPresContext)) {
5924
                                    aParentFrame->PresContext()) ||
5845
    // Ensure that the :after frame is on the principal child list.
5925
      GetGenConPseudos(aParentFrame) ||
5846
    aParentFrame->DrainSelfOverflowList();
5926
      aFrameManager->GetDisplayContents(aContainer)) {
5847
5927
    nsIFrame* afterFrame = nullptr;
5848
    nsIFrame* afterFrame = nsLayoutUtils::GetAfterFrame(aParentFrame);
5928
    nsContainerFrame* parent =
5929
      static_cast<nsContainerFrame*>(aParentFrame->LastContinuation());
5930
    bool done = false;
5931
    while (!done && parent) {
5932
      // Ensure that all normal flow children are on the principal child list.
5933
      parent->DrainSelfOverflowList();
5934
5935
      nsIFrame* child = parent->GetLastChild(nsIFrame::kPrincipalList);
5936
      if (child && child->IsPseudoFrame(aContainer) &&
5937
          !child->IsGeneratedContentFrame()) {
5938
        // Drill down into non-generated pseudo frames of aContainer.
5939
        parent = nsLayoutUtils::LastContinuationWithChild(do_QueryFrame(child));
5940
        continue;
5941
      }
5942
5943
      for (; child; child = child->GetPrevSibling()) {
5944
        nsIContent* c = child->GetContent();
5945
        if (child->IsGeneratedContentFrame()) {
5946
          nsIContent* p = c->GetParent();
5947
          if (c->Tag() == nsGkAtoms::mozgeneratedcontentafter) {
5948
            if (!nsContentUtils::ContentIsDescendantOf(aChild, p) &&
5949
                c->GetBindingParent() != aContainer &&
5950
                nsContentUtils::PositionIsBefore(p, aChild)) {
5951
              // ::after generated content for content earlier in the doc and not
5952
              // for an ancestor.
5953
              done = true;
5954
              break;
5955
            }
5956
          } else if (nsContentUtils::PositionIsBefore(p, aChild)) {
5957
            // Non-::after generated content for content earlier in the doc.
5958
            done = true;
5959
            break;
5960
          }
5961
        } else if (nsContentUtils::PositionIsBefore(c, aChild)) {
5962
          // Content is before aChild.
5963
          done = true;
5964
          break;
5965
        }
5966
        afterFrame = child;
5967
      }
5968
5969
      parent = static_cast<nsContainerFrame*>(parent->GetPrevContinuation());
5970
    }
5849
    if (afterFrame) {
5971
    if (afterFrame) {
5850
      *aAfterFrame = afterFrame;
5972
      *aAfterFrame = afterFrame;
5851
      return afterFrame->GetParent();
5973
      return afterFrame->GetParent();
5852
    }
5974
    }
5853
  }
5975
  }
5854
5976
5855
  *aAfterFrame = nullptr;
5977
  *aAfterFrame = nullptr;
5856
5978
 Lines 6221-6237   nsCSSFrameConstructor::GetInsertionPrevS Link Here 
6221
  *aIsAppend = false;
6343
  *aIsAppend = false;
6222
6344
6223
  // Find the frame that precedes the insertion point. Walk backwards
6345
  // Find the frame that precedes the insertion point. Walk backwards
6224
  // from the parent frame to get the parent content, because if an
6346
  // from the parent frame to get the parent content, because if an
6225
  // XBL insertion point is involved, we'll need to use _that_ to find
6347
  // XBL insertion point is involved, we'll need to use _that_ to find
6226
  // the preceding frame.
6348
  // the preceding frame.
6227
6349
6228
  NS_PRECONDITION(aParentFrame, "Must have parent frame to start with");
6350
  NS_PRECONDITION(aParentFrame, "Must have parent frame to start with");
6229
  nsIContent* container = aParentFrame->GetContent();
6351
  const bool boxContents = GetDisplayContents(aContainer);
6352
  nsIContent* container = boxContents ? aContainer : aParentFrame->GetContent();
6230
6353
6231
  FlattenedChildIterator iter(container);
6354
  FlattenedChildIterator iter(container);
6232
  bool xblCase = iter.XBLInvolved() || container != aContainer;
6355
  bool xblCase = iter.XBLInvolved() || container != aContainer;
6233
  if (xblCase || !aChild->IsRootOfAnonymousSubtree()) {
6356
  if (xblCase || !aChild->IsRootOfAnonymousSubtree()) {
6234
    // The check for IsRootOfAnonymousSubtree() is because editor is
6357
    // The check for IsRootOfAnonymousSubtree() is because editor is
6235
    // severely broken and calls us directly for native anonymous
6358
    // severely broken and calls us directly for native anonymous
6236
    // nodes that it creates.
6359
    // nodes that it creates.
6237
    if (aStartSkipChild) {
6360
    if (aStartSkipChild) {
 Lines 6251-6279   nsCSSFrameConstructor::GetInsertionPrevS Link Here 
6251
  uint8_t childDisplay = UNSET_DISPLAY;
6374
  uint8_t childDisplay = UNSET_DISPLAY;
6252
  nsIFrame* prevSibling = FindPreviousSibling(iter, childDisplay);
6375
  nsIFrame* prevSibling = FindPreviousSibling(iter, childDisplay);
6253
6376
6254
  // Now, find the geometric parent so that we can handle
6377
  // Now, find the geometric parent so that we can handle
6255
  // continuations properly. Use the prev sibling if we have it;
6378
  // continuations properly. Use the prev sibling if we have it;
6256
  // otherwise use the next sibling.
6379
  // otherwise use the next sibling.
6257
  if (prevSibling) {
6380
  if (prevSibling) {
6258
    aParentFrame = prevSibling->GetParent()->GetContentInsertionFrame();
6381
    aParentFrame = prevSibling->GetParent()->GetContentInsertionFrame();
6259
  }
6382
  } else {
6260
  else {
6261
    // If there is no previous sibling, then find the frame that follows
6383
    // If there is no previous sibling, then find the frame that follows
6262
    if (aEndSkipChild) {
6384
    if (aEndSkipChild) {
6263
      iter.Seek(aEndSkipChild);
6385
      iter.Seek(aEndSkipChild);
6264
      iter.GetPreviousChild();
6386
      iter.GetPreviousChild();
6265
    }
6387
    }
6266
    nsIFrame* nextSibling = FindNextSibling(iter, childDisplay);
6388
    nsIFrame* nextSibling = FindNextSibling(iter, childDisplay);
6267
6389
    if (boxContents) {
6390
      if (nextSibling) {
6391
        aParentFrame = nextSibling->GetParent()->GetContentInsertionFrame();
6392
        return nextSibling->GetPrevSibling();
6393
      }
6394
      return GetInsertionPrevSibling(aParentFrame, aContainer->GetParent(),
6395
                                     aContainer, aIsAppend,
6396
                                     aIsRangeInsertSafe, nullptr, nullptr);
6397
    }
6268
    if (nextSibling) {
6398
    if (nextSibling) {
6269
      aParentFrame = nextSibling->GetParent()->GetContentInsertionFrame();
6399
      aParentFrame = nextSibling->GetParent()->GetContentInsertionFrame();
6270
    }
6400
    } else {
6271
    else {
6272
      // No previous or next sibling, so treat this like an appended frame.
6401
      // No previous or next sibling, so treat this like an appended frame.
6273
      *aIsAppend = true;
6402
      *aIsAppend = true;
6274
      if (IsFramePartOfIBSplit(aParentFrame)) {
6403
      if (IsFramePartOfIBSplit(aParentFrame)) {
6275
        // Since we're appending, we'll walk to the last anonymous frame
6404
        // Since we're appending, we'll walk to the last anonymous frame
6276
        // that was created for the broken inline frame.  But don't walk
6405
        // that was created for the broken inline frame.  But don't walk
6277
        // to the trailing inline if it's empty; stop at the block.
6406
        // to the trailing inline if it's empty; stop at the block.
6278
        aParentFrame = GetLastIBSplitSibling(aParentFrame, false);
6407
        aParentFrame = GetLastIBSplitSibling(aParentFrame, false);
6279
      }
6408
      }
 Lines 6281-6307   nsCSSFrameConstructor::GetInsertionPrevS Link Here 
6281
      // before the AdjustAppendParentForAfterContent call.
6410
      // before the AdjustAppendParentForAfterContent call.
6282
      aParentFrame = nsLayoutUtils::LastContinuationWithChild(aParentFrame);
6411
      aParentFrame = nsLayoutUtils::LastContinuationWithChild(aParentFrame);
6283
      // Deal with fieldsets
6412
      // Deal with fieldsets
6284
      aParentFrame = ::GetAdjustedParentFrame(aParentFrame,
6413
      aParentFrame = ::GetAdjustedParentFrame(aParentFrame,
6285
                                              aParentFrame->GetType(),
6414
                                              aParentFrame->GetType(),
6286
                                              aChild);
6415
                                              aChild);
6287
      nsIFrame* appendAfterFrame;
6416
      nsIFrame* appendAfterFrame;
6288
      aParentFrame =
6417
      aParentFrame =
6289
        ::AdjustAppendParentForAfterContent(mPresShell->GetPresContext(),
6418
        ::AdjustAppendParentForAfterContent(this, container, aParentFrame,
6290
                                            container, aParentFrame,
6419
                                            aChild, &appendAfterFrame);
6291
                                            &appendAfterFrame);
6292
      prevSibling = ::FindAppendPrevSibling(aParentFrame, appendAfterFrame);
6420
      prevSibling = ::FindAppendPrevSibling(aParentFrame, appendAfterFrame);
6293
    }
6421
    }
6294
  }
6422
  }
6295
6423
6296
  *aIsRangeInsertSafe = (childDisplay == UNSET_DISPLAY);
6424
  *aIsRangeInsertSafe = (childDisplay == UNSET_DISPLAY);
6297
  return prevSibling;
6425
  return prevSibling;
6298
}
6426
}
6299
6427
6428
nsContainerFrame*
6429
nsCSSFrameConstructor::GetContentInsertionFrameFor(nsIContent* aContent)
6430
{
6431
  // Get the primary frame associated with the content
6432
  nsIFrame* frame = aContent->GetPrimaryFrame();
6433
6434
  if (!frame) {
6435
    if (GetDisplayContents(aContent)) {
6436
      nsIContent* parent = aContent->GetParent();
6437
      frame = parent ? GetContentInsertionFrameFor(parent) : nullptr;
6438
    }
6439
    if (!frame) {
6440
      return nullptr;
6441
    }
6442
  } else {
6443
    // If the content of the frame is not the desired content then this is not
6444
    // really a frame for the desired content.
6445
    // XXX This check is needed due to bug 135040. Remove it once that's fixed.
6446
    if (frame->GetContent() != aContent) {
6447
      return nullptr;
6448
    }
6449
  }
6450
6451
  nsContainerFrame* insertionFrame = frame->GetContentInsertionFrame();
6452
6453
  NS_ASSERTION(!insertionFrame || insertionFrame == frame || !frame->IsLeaf(),
6454
    "The insertion frame is the primary frame or the primary frame isn't a leaf");
6455
6456
  return insertionFrame;
6457
}
6458
6300
static bool
6459
static bool
6301
IsSpecialFramesetChild(nsIContent* aContent)
6460
IsSpecialFramesetChild(nsIContent* aContent)
6302
{
6461
{
6303
  // IMPORTANT: This must match the conditions in nsHTMLFramesetFrame::Init.
6462
  // IMPORTANT: This must match the conditions in nsHTMLFramesetFrame::Init.
6304
  return aContent->IsHTML() &&
6463
  return aContent->IsHTML() &&
6305
    (aContent->Tag() == nsGkAtoms::frameset ||
6464
    (aContent->Tag() == nsGkAtoms::frameset ||
6306
     aContent->Tag() == nsGkAtoms::frame);
6465
     aContent->Tag() == nsGkAtoms::frame);
6307
}
6466
}
 Lines 6428-6443   nsCSSFrameConstructor::MaybeConstructLaz Link Here 
6428
    }
6587
    }
6429
    if (!noPrimaryFrame && !content->GetPrimaryFrame()) {
6588
    if (!noPrimaryFrame && !content->GetPrimaryFrame()) {
6430
      noPrimaryFrame = true;
6589
      noPrimaryFrame = true;
6431
    }
6590
    }
6432
    if (!needsFrameBitSet && content->HasFlag(NODE_NEEDS_FRAME)) {
6591
    if (!needsFrameBitSet && content->HasFlag(NODE_NEEDS_FRAME)) {
6433
      needsFrameBitSet = true;
6592
      needsFrameBitSet = true;
6434
    }
6593
    }
6435
#endif
6594
#endif
6595
    // XXXmats no lazy frames for display:contents descendants yet (bug 979782).
6596
    if (GetDisplayContents(content)) {
6597
      return false;
6598
    }
6436
    content->SetFlags(NODE_DESCENDANTS_NEED_FRAMES);
6599
    content->SetFlags(NODE_DESCENDANTS_NEED_FRAMES);
6437
    content = content->GetFlattenedTreeParent();
6600
    content = content->GetFlattenedTreeParent();
6438
  }
6601
  }
6439
#ifdef DEBUG
6602
#ifdef DEBUG
6440
  if (content && content->GetPrimaryFrame() &&
6603
  if (content && content->GetPrimaryFrame() &&
6441
      content->GetPrimaryFrame()->IsLeaf()) {
6604
      content->GetPrimaryFrame()->IsLeaf()) {
6442
    noPrimaryFrame = needsFrameBitSet = false;
6605
    noPrimaryFrame = needsFrameBitSet = false;
6443
  }
6606
  }
 Lines 6550-6567   void Link Here 
6550
nsCSSFrameConstructor::IssueSingleInsertNofications(nsIContent* aContainer,
6713
nsCSSFrameConstructor::IssueSingleInsertNofications(nsIContent* aContainer,
6551
                                                    nsIContent* aStartChild,
6714
                                                    nsIContent* aStartChild,
6552
                                                    nsIContent* aEndChild,
6715
                                                    nsIContent* aEndChild,
6553
                                                    bool aAllowLazyConstruction)
6716
                                                    bool aAllowLazyConstruction)
6554
{
6717
{
6555
  for (nsIContent* child = aStartChild;
6718
  for (nsIContent* child = aStartChild;
6556
       child != aEndChild;
6719
       child != aEndChild;
6557
       child = child->GetNextSibling()) {
6720
       child = child->GetNextSibling()) {
6558
    if ((child->GetPrimaryFrame() ||
6721
    if ((child->GetPrimaryFrame() || GetUndisplayedContent(child) ||
6559
         GetUndisplayedContent(child))
6722
         GetDisplayContents(child))
6560
#ifdef MOZ_XUL
6723
#ifdef MOZ_XUL
6561
        //  Except listboxes suck, so do NOT skip anything here if
6724
        //  Except listboxes suck, so do NOT skip anything here if
6562
        //  we plan to notify a listbox.
6725
        //  we plan to notify a listbox.
6563
        && !MaybeGetListBoxBodyFrame(aContainer, child)
6726
        && !MaybeGetListBoxBodyFrame(aContainer, child)
6564
#endif
6727
#endif
6565
        ) {
6728
        ) {
6566
      // Already have a frame or undisplayed entry for this content; a
6729
      // Already have a frame or undisplayed entry for this content; a
6567
      // previous ContentInserted in this loop must have reconstructed
6730
      // previous ContentInserted in this loop must have reconstructed
 Lines 6710-6726   nsCSSFrameConstructor::ContentAppended(n Link Here 
6710
    nsIContent* bindingParent = aContainer->GetBindingParent();
6873
    nsIContent* bindingParent = aContainer->GetBindingParent();
6711
    LAYOUT_PHASE_TEMP_EXIT();
6874
    LAYOUT_PHASE_TEMP_EXIT();
6712
    nsresult rv = RecreateFramesForContent(bindingParent, false);
6875
    nsresult rv = RecreateFramesForContent(bindingParent, false);
6713
    LAYOUT_PHASE_TEMP_REENTER();
6876
    LAYOUT_PHASE_TEMP_REENTER();
6714
    return rv;
6877
    return rv;
6715
  }
6878
  }
6716
6879
6717
  // Get the frame associated with the content
6880
  // Get the frame associated with the content
6718
  nsContainerFrame* parentFrame = ::GetContentInsertionFrameFor(aContainer);
6881
  nsContainerFrame* parentFrame = GetContentInsertionFrameFor(aContainer);
6719
6882
6720
  // See comment in ContentRangeInserted for why this is necessary.
6883
  // See comment in ContentRangeInserted for why this is necessary.
6721
  if (!parentFrame && !aContainer->IsActiveChildrenElement()) {
6884
  if (!parentFrame && !aContainer->IsActiveChildrenElement()) {
6722
    return NS_OK;
6885
    return NS_OK;
6723
  }
6886
  }
6724
6887
6725
  if (aAllowLazyConstruction &&
6888
  if (aAllowLazyConstruction &&
6726
      MaybeConstructLazily(CONTENTAPPEND, aContainer, aFirstNewContent)) {
6889
      MaybeConstructLazily(CONTENTAPPEND, aContainer, aFirstNewContent)) {
 Lines 6783-6801   nsCSSFrameConstructor::ContentAppended(n Link Here 
6783
  // We should never get here with fieldsets, since they have multiple
6946
  // We should never get here with fieldsets, since they have multiple
6784
  // insertion points.
6947
  // insertion points.
6785
  NS_ASSERTION(parentFrame->GetType() != nsGkAtoms::fieldSetFrame,
6948
  NS_ASSERTION(parentFrame->GetType() != nsGkAtoms::fieldSetFrame,
6786
               "Unexpected parent");
6949
               "Unexpected parent");
6787
6950
6788
  // Deal with possible :after generated content on the parent
6951
  // Deal with possible :after generated content on the parent
6789
  nsIFrame* parentAfterFrame;
6952
  nsIFrame* parentAfterFrame;
6790
  parentFrame =
6953
  parentFrame =
6791
    ::AdjustAppendParentForAfterContent(mPresShell->GetPresContext(),
6954
    ::AdjustAppendParentForAfterContent(this, aContainer, parentFrame,
6792
                                        aContainer, parentFrame,
6955
                                        aFirstNewContent, &parentAfterFrame);
6793
                                        &parentAfterFrame);
6794
6956
6795
  // Create some new frames
6957
  // Create some new frames
6796
  nsFrameConstructorState state(mPresShell,
6958
  nsFrameConstructorState state(mPresShell,
6797
                                GetAbsoluteContainingBlock(parentFrame, FIXED_POS),
6959
                                GetAbsoluteContainingBlock(parentFrame, FIXED_POS),
6798
                                GetAbsoluteContainingBlock(parentFrame, ABS_POS),
6960
                                GetAbsoluteContainingBlock(parentFrame, ABS_POS),
6799
                                GetFloatContainingBlock(parentFrame));
6961
                                GetFloatContainingBlock(parentFrame));
6800
  state.mTreeMatchContext.InitAncestors(aContainer->AsElement());
6962
  state.mTreeMatchContext.InitAncestors(aContainer->AsElement());
6801
6963
 Lines 7143-7168   nsCSSFrameConstructor::ContentRangeInser Link Here 
7143
    // the children of the host.
7305
    // the children of the host.
7144
    nsIContent* bindingParent = aContainer->GetBindingParent();
7306
    nsIContent* bindingParent = aContainer->GetBindingParent();
7145
    LAYOUT_PHASE_TEMP_EXIT();
7307
    LAYOUT_PHASE_TEMP_EXIT();
7146
    nsresult rv = RecreateFramesForContent(bindingParent, false);
7308
    nsresult rv = RecreateFramesForContent(bindingParent, false);
7147
    LAYOUT_PHASE_TEMP_REENTER();
7309
    LAYOUT_PHASE_TEMP_REENTER();
7148
    return rv;
7310
    return rv;
7149
  }
7311
  }
7150
7312
7151
  nsContainerFrame* parentFrame = ::GetContentInsertionFrameFor(aContainer);
7313
  nsContainerFrame* parentFrame = GetContentInsertionFrameFor(aContainer);
7152
  // The xbl:children element won't have a frame, but default content can have the children as
7314
  // The xbl:children element won't have a frame, but default content can have the children as
7153
  // a parent. While its uncommon to change the structure of the default content itself, a label,
7315
  // a parent. While its uncommon to change the structure of the default content itself, a label,
7154
  // for example, can be reframed by having its value attribute set or removed.
7316
  // for example, can be reframed by having its value attribute set or removed.
7155
  if (!parentFrame && !aContainer->IsActiveChildrenElement()) {
7317
  if (!parentFrame && !aContainer->IsActiveChildrenElement()) {
7156
    return NS_OK;
7318
    return NS_OK;
7157
  }
7319
  }
7158
7320
7159
  // Otherwise, we've got parent content. Find its frame.
7321
  // Otherwise, we've got parent content. Find its frame.
7160
  NS_ASSERTION(!parentFrame || parentFrame->GetContent() == aContainer, "New XBL code is possibly wrong!");
7322
  NS_ASSERTION(!parentFrame || parentFrame->GetContent() == aContainer ||
7323
               GetDisplayContents(aContainer), "New XBL code is possibly wrong!");
7161
7324
7162
  if (aAllowLazyConstruction &&
7325
  if (aAllowLazyConstruction &&
7163
      MaybeConstructLazily(CONTENTINSERT, aContainer, aStartChild)) {
7326
      MaybeConstructLazily(CONTENTINSERT, aContainer, aStartChild)) {
7164
    return NS_OK;
7327
    return NS_OK;
7165
  }
7328
  }
7166
7329
7167
  if (isSingleInsert) {
7330
  if (isSingleInsert) {
7168
    // See if we have an XBL insertion point. If so, then that's our
7331
    // See if we have an XBL insertion point. If so, then that's our
 Lines 7439-7458   nsCSSFrameConstructor::ContentRangeInser Link Here 
7439
                 frame1->GetType() == nsGkAtoms::fieldSetFrame ||
7602
                 frame1->GetType() == nsGkAtoms::fieldSetFrame ||
7440
                 (frame1->GetParent() &&
7603
                 (frame1->GetParent() &&
7441
                  frame1->GetParent()->GetType() == nsGkAtoms::fieldSetFrame),
7604
                  frame1->GetParent()->GetType() == nsGkAtoms::fieldSetFrame),
7442
                 "Unexpected frame types");
7605
                 "Unexpected frame types");
7443
#endif
7606
#endif
7444
    isAppend = true;
7607
    isAppend = true;
7445
    nsIFrame* appendAfterFrame;
7608
    nsIFrame* appendAfterFrame;
7446
    parentFrame =
7609
    parentFrame =
7447
      ::AdjustAppendParentForAfterContent(mPresShell->GetPresContext(),
7610
      ::AdjustAppendParentForAfterContent(this, container,
7448
                                          container,
7449
                                          frameItems.FirstChild()->GetParent(),
7611
                                          frameItems.FirstChild()->GetParent(),
7450
                                          &appendAfterFrame);
7612
                                          aStartChild, &appendAfterFrame);
7451
    prevSibling = ::FindAppendPrevSibling(parentFrame, appendAfterFrame);
7613
    prevSibling = ::FindAppendPrevSibling(parentFrame, appendAfterFrame);
7452
  }
7614
  }
7453
7615
7454
  if (haveFirstLineStyle && parentFrame == containingBlock) {
7616
  if (haveFirstLineStyle && parentFrame == containingBlock) {
7455
    // It's possible that the new frame goes into a first-line
7617
    // It's possible that the new frame goes into a first-line
7456
    // frame. Look at it and see...
7618
    // frame. Look at it and see...
7457
    if (isAppend) {
7619
    if (isAppend) {
7458
      // Use append logic when appending
7620
      // Use append logic when appending
 Lines 7582-7609   nsCSSFrameConstructor::ContentRemoved(ns Link Here 
7582
           static_cast<void*>(aChild),
7744
           static_cast<void*>(aChild),
7583
           static_cast<void*>(aOldNextSibling));
7745
           static_cast<void*>(aOldNextSibling));
7584
    if (gReallyNoisyContentUpdates) {
7746
    if (gReallyNoisyContentUpdates) {
7585
      aContainer->List(stdout, 0);
7747
      aContainer->List(stdout, 0);
7586
    }
7748
    }
7587
  }
7749
  }
7588
#endif
7750
#endif
7589
7751
7590
  nsPresContext *presContext = mPresShell->GetPresContext();
7752
  nsresult rv = NS_OK;
7591
  nsresult                  rv = NS_OK;
7592
7593
  // Find the child frame that maps the content
7594
  nsIFrame* childFrame = aChild->GetPrimaryFrame();
7753
  nsIFrame* childFrame = aChild->GetPrimaryFrame();
7595
7596
  if (!childFrame || childFrame->GetContent() != aChild) {
7754
  if (!childFrame || childFrame->GetContent() != aChild) {
7597
    // XXXbz the GetContent() != aChild check is needed due to bug 135040.
7755
    // XXXbz the GetContent() != aChild check is needed due to bug 135040.
7598
    // Remove it once that's fixed.
7756
    // Remove it once that's fixed.
7599
    ClearUndisplayedContentIn(aChild, aContainer);
7757
    ClearUndisplayedContentIn(aChild, aContainer);
7600
  }
7758
  }
7601
7759
  MOZ_ASSERT(!childFrame || !GetDisplayContents(aChild),
7760
             "display:contents nodes shouldn't have a frame");
7761
  if (!childFrame && GetDisplayContents(aChild)) {
7762
    FlattenedChildIterator iter(aChild);
7763
    for (nsIContent* c = iter.GetNextChild(); c; c = iter.GetNextChild()) {
7764
      if (c->GetPrimaryFrame() || GetDisplayContents(c)) {
7765
        LAYOUT_PHASE_TEMP_EXIT();
7766
        rv = ContentRemoved(aChild, c, nullptr, aFlags, aDidReconstruct);
7767
        LAYOUT_PHASE_TEMP_REENTER();
7768
        NS_ENSURE_SUCCESS(rv, rv);
7769
        if (*aDidReconstruct) {
7770
          return rv;
7771
        }
7772
      }
7773
    }
7774
    ClearDisplayContentsIn(aChild, aContainer);
7775
  }
7776
7777
  nsPresContext* presContext = mPresShell->GetPresContext();
7602
#ifdef MOZ_XUL
7778
#ifdef MOZ_XUL
7603
  if (NotifyListBoxBody(presContext, aContainer, aChild, aOldNextSibling,
7779
  if (NotifyListBoxBody(presContext, aContainer, aChild, aOldNextSibling,
7604
                        mDocument, childFrame, CONTENT_REMOVED))
7780
                        mDocument, childFrame, CONTENT_REMOVED))
7605
    return NS_OK;
7781
    return NS_OK;
7606
7782
7607
#endif // MOZ_XUL
7783
#endif // MOZ_XUL
7608
7784
7609
  // If we're removing the root, then make sure to remove things starting at
7785
  // If we're removing the root, then make sure to remove things starting at
 Lines 8429-8445   nsCSSFrameConstructor::GetInsertionPoint Link Here 
8429
8605
8430
  nsIContent* insertionElement;
8606
  nsIContent* insertionElement;
8431
  if (aChildContent) {
8607
  if (aChildContent) {
8432
    // We've got an explicit insertion child. Check to see if it's
8608
    // We've got an explicit insertion child. Check to see if it's
8433
    // anonymous.
8609
    // anonymous.
8434
    if (aChildContent->GetBindingParent() == aContainer) {
8610
    if (aChildContent->GetBindingParent() == aContainer) {
8435
      // This child content is anonymous. Don't use the insertion
8611
      // This child content is anonymous. Don't use the insertion
8436
      // point, since that's only for the explicit kids.
8612
      // point, since that's only for the explicit kids.
8437
      return ::GetContentInsertionFrameFor(aContainer);
8613
      return GetContentInsertionFrameFor(aContainer);
8438
    }
8614
    }
8439
8615
8440
    insertionElement = bindingManager->FindNestedInsertionPoint(aContainer, aChildContent);
8616
    insertionElement = bindingManager->FindNestedInsertionPoint(aContainer, aChildContent);
8441
  }
8617
  }
8442
  else {
8618
  else {
8443
    bool multiple;
8619
    bool multiple;
8444
    insertionElement = bindingManager->FindNestedSingleInsertionPoint(aContainer, &multiple);
8620
    insertionElement = bindingManager->FindNestedSingleInsertionPoint(aContainer, &multiple);
8445
8621
 Lines 8450-8467   nsCSSFrameConstructor::GetInsertionPoint Link Here 
8450
      return nullptr;
8626
      return nullptr;
8451
    }
8627
    }
8452
  }
8628
  }
8453
8629
8454
  if (!insertionElement) {
8630
  if (!insertionElement) {
8455
    insertionElement = aContainer;
8631
    insertionElement = aContainer;
8456
  }
8632
  }
8457
8633
8458
  nsContainerFrame* insertionPoint =
8634
  nsContainerFrame* insertionPoint = GetContentInsertionFrameFor(insertionElement);
8459
    ::GetContentInsertionFrameFor(insertionElement);
8460
8635
8461
  // fieldsets have multiple insertion points.  Note that we might
8636
  // fieldsets have multiple insertion points.  Note that we might
8462
  // have to look at insertionElement here...
8637
  // have to look at insertionElement here...
8463
  if (aMultiple && insertionElement->IsHTML(nsGkAtoms::fieldset)) {
8638
  if (aMultiple && insertionElement->IsHTML(nsGkAtoms::fieldset)) {
8464
    *aMultiple = true;
8639
    *aMultiple = true;
8465
  }
8640
  }
8466
8641
8467
  return insertionPoint;
8642
  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