Attachment #8498181: part 2 of the Fctor changes - the main part, except XBL/Shadow tree fixes for bug #907396

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

(-)a/layout/base/RestyleManager.cpp (+38 lines)
Line     Link Here 
 Lines 3631-3646   RestyleManager::ComputeStyleChangeFor(ns Link Here 
3631
        NS_ASSERTION(!cont->GetPrevContinuation(),
3631
        NS_ASSERTION(!cont->GetPrevContinuation(),
3632
                     "continuing frame had more severe impact than first-in-flow");
3632
                     "continuing frame had more severe impact than first-in-flow");
3633
        return;
3633
        return;
3634
      }
3634
      }
3635
    }
3635
    }
3636
  }
3636
  }
3637
}
3637
}
3638
3638
3639
AutoDisplayContentsAncestorPusher::AutoDisplayContentsAncestorPusher(
3640
  TreeMatchContext& aTreeMatchContext, nsPresContext* aPresContext,
3641
  nsIContent* aParent)
3642
  : mTreeMatchContext(aTreeMatchContext)
3643
  , mPresContext(aPresContext)
3644
  , mPushedAncestors(false)
3645
{
3646
  if (aParent) {
3647
    nsFrameManager* fm = mPresContext->FrameManager();
3648
    // Push display:contents mAncestors onto mTreeMatchContext.
3649
    for (nsIContent* p = aParent; p && fm->GetDisplayContentsStyleFor(p);
3650
         p = p->GetParent()) {
3651
      mAncestors.AppendElement(p->AsElement());
3652
    }
3653
    mPushedAncestors = mTreeMatchContext.mAncestorFilter.HasFilter();
3654
    nsTArray<mozilla::dom::Element*>::size_type i = mAncestors.Length();
3655
    while (i--) {
3656
      if (mPushedAncestors) {
3657
        mTreeMatchContext.mAncestorFilter.PushAncestor(mAncestors[i]);
3658
      }
3659
      mTreeMatchContext.PushStyleScope(mAncestors[i]);
3660
    }
3661
  }
3662
3663
}
3664
3665
AutoDisplayContentsAncestorPusher::~AutoDisplayContentsAncestorPusher()
3666
{
3667
  // Pop the ancestors we pushed in the CTOR, if any.
3668
  nsTArray<mozilla::dom::Element*>::size_type i = mAncestors.Length();
3669
  while (i--) {
3670
    if (mPushedAncestors) {
3671
      mTreeMatchContext.mAncestorFilter.PopAncestor();
3672
    }
3673
    mTreeMatchContext.PopStyleScope(mAncestors[i]);
3674
  }
3675
}
3676
3639
#ifdef DEBUG
3677
#ifdef DEBUG
3640
/* static */ nsCString
3678
/* static */ nsCString
3641
RestyleManager::RestyleHintToString(nsRestyleHint aHint)
3679
RestyleManager::RestyleHintToString(nsRestyleHint aHint)
3642
{
3680
{
3643
  nsCString result;
3681
  nsCString result;
3644
  bool any = false;
3682
  bool any = false;
3645
  const char* names[] = { "Self", "Subtree", "LaterSiblings", "CSSTransitions",
3683
  const char* names[] = { "Self", "Subtree", "LaterSiblings", "CSSTransitions",
3646
                          "CSSAnimations", "SVGAttrAnimations", "StyleAttribute",
3684
                          "CSSAnimations", "SVGAttrAnimations", "StyleAttribute",
(-)a/layout/base/RestyleManager.h (-2 / +26 lines)
Line     Link Here 
 Lines 26-42   struct TreeMatchContext; Link Here 
26
26
27
namespace mozilla {
27
namespace mozilla {
28
  class EventStates;
28
  class EventStates;
29
29
30
namespace dom {
30
namespace dom {
31
  class Element;
31
  class Element;
32
} // namespace dom
32
} // namespace dom
33
33
34
class RestyleManager MOZ_FINAL {
34
class RestyleManager MOZ_FINAL
35
{
35
public:
36
public:
36
  friend class ::nsRefreshDriver;
37
  friend class ::nsRefreshDriver;
37
  friend class RestyleTracker;
38
  friend class RestyleTracker;
38
39
39
  typedef mozilla::dom::Element Element;
40
  typedef mozilla::dom::Element Element;
40
41
41
  explicit RestyleManager(nsPresContext* aPresContext);
42
  explicit RestyleManager(nsPresContext* aPresContext);
42
43
 Lines 437-453   private: Link Here 
437
  int32_t mLoggingDepth;
438
  int32_t mLoggingDepth;
438
#endif
439
#endif
439
};
440
};
440
441
441
/**
442
/**
442
 * An ElementRestyler is created for *each* element in a subtree that we
443
 * An ElementRestyler is created for *each* element in a subtree that we
443
 * recompute styles for.
444
 * recompute styles for.
444
 */
445
 */
445
class ElementRestyler MOZ_FINAL {
446
class ElementRestyler MOZ_FINAL
447
{
446
public:
448
public:
447
  typedef mozilla::dom::Element Element;
449
  typedef mozilla::dom::Element Element;
448
450
449
  // Construct for the root of the subtree that we're restyling.
451
  // Construct for the root of the subtree that we're restyling.
450
  ElementRestyler(nsPresContext* aPresContext,
452
  ElementRestyler(nsPresContext* aPresContext,
451
                  nsIFrame* aFrame,
453
                  nsIFrame* aFrame,
452
                  nsStyleChangeList* aChangeList,
454
                  nsStyleChangeList* aChangeList,
453
                  nsChangeHint aHintsHandledByAncestors,
455
                  nsChangeHint aHintsHandledByAncestors,
 Lines 604-614   private: Link Here 
604
  bool mWasFrameVisible;
606
  bool mWasFrameVisible;
605
#endif
607
#endif
606
608
607
#ifdef RESTYLE_LOGGING
609
#ifdef RESTYLE_LOGGING
608
  int32_t mLoggingDepth;
610
  int32_t mLoggingDepth;
609
#endif
611
#endif
610
};
612
};
611
613
614
/**
615
 * This pushes any display:contents nodes onto a TreeMatchContext.
616
 * Use it before resolving style for kids of aParent where aParent
617
 * (and further ancestors) may be display:contents nodes which have
618
 * not yet been pushed onto TreeMatchContext.
619
 */
620
class MOZ_STACK_CLASS AutoDisplayContentsAncestorPusher MOZ_FINAL
621
{
622
 public:
623
  typedef mozilla::dom::Element Element;
624
  AutoDisplayContentsAncestorPusher(TreeMatchContext& aTreeMatchContext,
625
                                    nsPresContext*    aPresContext,
626
                                    nsIContent*       aParent);
627
  ~AutoDisplayContentsAncestorPusher();
628
  bool IsEmpty() const { return mAncestors.Length() == 0; }
629
private:
630
  TreeMatchContext& mTreeMatchContext;
631
  nsPresContext* const mPresContext;
632
  nsAutoTArray<mozilla::dom::Element*, 4> mAncestors;
633
  bool mPushedAncestors;
634
};
635
612
} // namespace mozilla
636
} // namespace mozilla
613
637
614
#endif /* mozilla_RestyleManager_h */
638
#endif /* mozilla_RestyleManager_h */
(-)a/layout/base/RestyleTracker.cpp (-4 / +8 lines)
Line     Link Here 
 Lines 4-23    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 "GeckoProfiler.h"
14
#include "nsFrameManager.h"
15
#include "nsIDocument.h"
12
#include "nsStyleChangeList.h"
16
#include "nsStyleChangeList.h"
13
#include "RestyleManager.h"
17
#include "RestyleManager.h"
14
#include "GeckoProfiler.h"
15
#include "nsIDocument.h"
16
#include "RestyleTrackerInlines.h"
18
#include "RestyleTrackerInlines.h"
17
19
18
namespace mozilla {
20
namespace mozilla {
19
21
20
#ifdef RESTYLE_LOGGING
22
#ifdef RESTYLE_LOGGING
21
static nsCString
23
static nsCString
22
GetDocumentURI(nsIDocument* aDocument)
24
GetDocumentURI(nsIDocument* aDocument)
23
{
25
{
 Lines 109-126   CollectRestyles(nsISupports* aElement, Link Here 
109
                   "skipping pending restyle %s, already restyled or no longer "
111
                   "skipping pending restyle %s, already restyled or no longer "
110
                   "in the document", FrameTagToString(element).get());
112
                   "in the document", FrameTagToString(element).get());
111
    return PL_DHASH_NEXT;
113
    return PL_DHASH_NEXT;
112
  }
114
  }
113
115
114
  NS_ASSERTION(!element->HasFlag(collector->tracker->RootBit()) ||
116
  NS_ASSERTION(!element->HasFlag(collector->tracker->RootBit()) ||
115
               // Maybe we're just not reachable via the frame tree?
117
               // Maybe we're just not reachable via the frame tree?
116
               (element->GetFlattenedTreeParent() &&
118
               (element->GetFlattenedTreeParent() &&
117
                (!element->GetFlattenedTreeParent()->GetPrimaryFrame()||
119
                (!element->GetFlattenedTreeParent()->GetPrimaryFrame() ||
118
                 element->GetFlattenedTreeParent()->GetPrimaryFrame()->IsLeaf())) ||
120
                 element->GetFlattenedTreeParent()->GetPrimaryFrame()->IsLeaf() ||
121
                 element->GetCurrentDoc()->GetShell()->FrameManager()
122
                   ->GetDisplayContentsStyleFor(element))) ||
119
               // Or not reachable due to an async reinsert we have
123
               // Or not reachable due to an async reinsert we have
120
               // pending?  If so, we'll have a reframe hint around.
124
               // pending?  If so, we'll have a reframe hint around.
121
               // That incidentally makes it safe that we still have
125
               // That incidentally makes it safe that we still have
122
               // the bit, since any descendants that didn't get added
126
               // the bit, since any descendants that didn't get added
123
               // to the roots list because we had the bits will be
127
               // to the roots list because we had the bits will be
124
               // completely restyled in a moment.
128
               // completely restyled in a moment.
125
               (aData->mChangeHint & nsChangeHint_ReconstructFrame),
129
               (aData->mChangeHint & nsChangeHint_ReconstructFrame),
126
               "Why did this not get handled while processing mRestyleRoots?");
130
               "Why did this not get handled while processing mRestyleRoots?");
(-)a/layout/base/nsCSSFrameConstructor.cpp (-108 / +307 lines)
Line     Link Here 
 Lines 606-645   FindFirstNonBlock(const nsFrameList& aLi Link Here 
606
inline void
606
inline void
607
SetInitialSingleChild(nsContainerFrame* aParent, nsIFrame* aFrame)
607
SetInitialSingleChild(nsContainerFrame* aParent, nsIFrame* aFrame)
608
{
608
{
609
  NS_PRECONDITION(!aFrame->GetNextSibling(), "Should be using a frame list");
609
  NS_PRECONDITION(!aFrame->GetNextSibling(), "Should be using a frame list");
610
  nsFrameList temp(aFrame, aFrame);
610
  nsFrameList temp(aFrame, aFrame);
611
  aParent->SetInitialChildList(kPrincipalList, temp);
611
  aParent->SetInitialChildList(kPrincipalList, temp);
612
}
612
}
613
613
614
static nsContainerFrame*
615
GetContentInsertionFrameFor(nsIContent* aContent)
616
{
617
  // Get the primary frame associated with the content
618
  nsIFrame* frame = aContent->GetPrimaryFrame();
619
620
  if (!frame)
621
    return nullptr;
622
623
  // If the content of the frame is not the desired content then this is not
624
  // really a frame for the desired content.
625
  // XXX This check is needed due to bug 135040. Remove it once that's fixed.
626
  if (frame->GetContent() != aContent) {
627
    return nullptr;
628
  }
629
630
  nsContainerFrame* insertionFrame = frame->GetContentInsertionFrame();
631
632
  NS_ASSERTION(!insertionFrame || insertionFrame == frame || !frame->IsLeaf(),
633
    "The insertion frame is the primary frame or the primary frame isn't a leaf");
634
635
  return insertionFrame;
636
}
637
638
// -----------------------------------------------------------
614
// -----------------------------------------------------------
639
615
640
// Structure used when constructing formatting object trees.
616
// Structure used when constructing formatting object trees.
641
struct nsFrameItems : public nsFrameList
617
struct nsFrameItems : public nsFrameList
642
{
618
{
643
  // Appends the frame to the end of the list
619
  // Appends the frame to the end of the list
644
  void AddChild(nsIFrame* aChild);
620
  void AddChild(nsIFrame* aChild);
645
};
621
};
 Lines 2283-2300   NeedFrameFor(const nsFrameConstructorSta Link Here 
2283
  // whitespace.
2259
  // whitespace.
2284
2260
2285
  // We could handle all this in CreateNeededPseudos or some other place
2261
  // We could handle all this in CreateNeededPseudos or some other place
2286
  // after we build our frame construction items, but that would involve
2262
  // after we build our frame construction items, but that would involve
2287
  // creating frame construction items for whitespace kids of
2263
  // creating frame construction items for whitespace kids of
2288
  // eExcludesIgnorableWhitespace frames, where we know we'll be dropping them
2264
  // eExcludesIgnorableWhitespace frames, where we know we'll be dropping them
2289
  // all anyway, and involve an extra walk down the frame construction item
2265
  // all anyway, and involve an extra walk down the frame construction item
2290
  // list.
2266
  // list.
2291
  if (!aParentFrame->IsFrameOfType(nsIFrame::eExcludesIgnorableWhitespace) ||
2267
  if ((aParentFrame &&
2292
      aParentFrame->IsGeneratedContentFrame() ||
2268
       (!aParentFrame->IsFrameOfType(nsIFrame::eExcludesIgnorableWhitespace) ||
2269
        aParentFrame->IsGeneratedContentFrame())) ||
2293
      !aChildContent->IsNodeOfType(nsINode::eTEXT)) {
2270
      !aChildContent->IsNodeOfType(nsINode::eTEXT)) {
2294
    return true;
2271
    return true;
2295
  }
2272
  }
2296
2273
2297
  aChildContent->SetFlags(NS_CREATE_FRAME_IF_NON_WHITESPACE |
2274
  aChildContent->SetFlags(NS_CREATE_FRAME_IF_NON_WHITESPACE |
2298
                          NS_REFRAME_IF_WHITESPACE);
2275
                          NS_REFRAME_IF_WHITESPACE);
2299
  return !aChildContent->TextIsOnlyWhitespace();
2276
  return !aChildContent->TextIsOnlyWhitespace();
2300
}
2277
}
 Lines 2583-2599   nsCSSFrameConstructor::ConstructDocEleme Link Here 
2583
    // if the document is a table then just populate it.
2560
    // if the document is a table then just populate it.
2584
    contentFrame = static_cast<nsContainerFrame*>(
2561
    contentFrame = static_cast<nsContainerFrame*>(
2585
      ConstructTable(state, item, mDocElementContainingBlock,
2562
      ConstructTable(state, item, mDocElementContainingBlock,
2586
                     styleContext->StyleDisplay(),
2563
                     styleContext->StyleDisplay(),
2587
                     frameItems));
2564
                     frameItems));
2588
    newFrame = frameItems.FirstChild();
2565
    newFrame = frameItems.FirstChild();
2589
    NS_ASSERTION(frameItems.OnlyChild(), "multiple root element frames");
2566
    NS_ASSERTION(frameItems.OnlyChild(), "multiple root element frames");
2590
  } else {
2567
  } else {
2591
    MOZ_ASSERT(display->mDisplay == NS_STYLE_DISPLAY_BLOCK,
2568
    MOZ_ASSERT(display->mDisplay == NS_STYLE_DISPLAY_BLOCK ||
2569
               display->mDisplay == NS_STYLE_DISPLAY_CONTENTS,
2592
               "Unhandled display type for root element");
2570
               "Unhandled display type for root element");
2593
    contentFrame = NS_NewBlockFormattingContext(mPresShell, styleContext);
2571
    contentFrame = NS_NewBlockFormattingContext(mPresShell, styleContext);
2594
    nsFrameItems frameItems;
2572
    nsFrameItems frameItems;
2595
    // Use a null PendingBinding, since our binding is not in fact pending.
2573
    // Use a null PendingBinding, since our binding is not in fact pending.
2596
    ConstructBlock(state, display, aDocElement,
2574
    ConstructBlock(state, display, aDocElement,
2597
                   state.GetGeometricParent(display,
2575
                   state.GetGeometricParent(display,
2598
                                            mDocElementContainingBlock),
2576
                                            mDocElementContainingBlock),
2599
                   mDocElementContainingBlock, styleContext,
2577
                   mDocElementContainingBlock, styleContext,
 Lines 3690-3718   nsCSSFrameConstructor::ConstructFrameFro Link Here 
3690
3668
3691
  // Don't create a subdocument frame for iframes if we're creating extra frames
3669
  // Don't create a subdocument frame for iframes if we're creating extra frames
3692
  if (aState.mCreatingExtraFrames && aItem.mContent->IsHTML() &&
3670
  if (aState.mCreatingExtraFrames && aItem.mContent->IsHTML() &&
3693
      aItem.mContent->Tag() == nsGkAtoms::iframe)
3671
      aItem.mContent->Tag() == nsGkAtoms::iframe)
3694
  {
3672
  {
3695
    return;
3673
    return;
3696
  }
3674
  }
3697
3675
3698
  nsStyleContext* const styleContext = aItem.mStyleContext;
3699
  const nsStyleDisplay* display = styleContext->StyleDisplay();
3700
  nsIContent* const content = aItem.mContent;
3676
  nsIContent* const content = aItem.mContent;
3677
  nsIContent* parent = content->GetParent();
3678
3679
  // Push display:contents ancestors.
3680
  AutoDisplayContentsAncestorPusher adcp(aState.mTreeMatchContext,
3681
                                         aState.mPresContext, parent);
3701
3682
3702
  // Get the parent of the content and check if it is a XBL children element.
3683
  // Get the parent of the content and check if it is a XBL children element.
3703
  // Push the children element as an ancestor here because it does
3684
  // Push the children element as an ancestor here because it does
3704
  // not have a frame and would not otherwise be pushed as an ancestor. It is
3685
  // not have a frame and would not otherwise be pushed as an ancestor. It is
3705
  // necessary to do so in order to correctly handle style resolution on
3686
  // necessary to do so in order to correctly handle style resolution on
3706
  // descendants.
3687
  // descendants.  (If !adcp.IsEmpty() then it was already pushed by
3707
  nsIContent* parent = content->GetParent();
3688
  // AutoDisplayContentsAncestorPusher above.)
3708
  TreeMatchContext::AutoAncestorPusher
3689
  TreeMatchContext::AutoAncestorPusher
3709
    insertionPointPusher(aState.mTreeMatchContext);
3690
    insertionPointPusher(aState.mTreeMatchContext);
3710
  if (parent && nsContentUtils::IsContentInsertionPoint(parent)) {
3691
  if (adcp.IsEmpty() && parent && nsContentUtils::IsContentInsertionPoint(parent)) {
3711
    if (aState.mTreeMatchContext.mAncestorFilter.HasFilter()) {
3692
    if (aState.mTreeMatchContext.mAncestorFilter.HasFilter()) {
3712
      insertionPointPusher.PushAncestorAndStyleScope(parent);
3693
      insertionPointPusher.PushAncestorAndStyleScope(parent);
3713
    } else {
3694
    } else {
3714
      insertionPointPusher.PushStyleScope(parent);
3695
      insertionPointPusher.PushStyleScope(parent);
3715
    }
3696
    }
3716
  }
3697
  }
3717
3698
3718
  // Push the content as a style ancestor now, so we don't have to do
3699
  // Push the content as a style ancestor now, so we don't have to do
 Lines 3728-3743   nsCSSFrameConstructor::ConstructFrameFro Link Here 
3728
  if (aState.mTreeMatchContext.mAncestorFilter.HasFilter()) {
3709
  if (aState.mTreeMatchContext.mAncestorFilter.HasFilter()) {
3729
    ancestorPusher.PushAncestorAndStyleScope(content);
3710
    ancestorPusher.PushAncestorAndStyleScope(content);
3730
  } else {
3711
  } else {
3731
    ancestorPusher.PushStyleScope(content);
3712
    ancestorPusher.PushStyleScope(content);
3732
  }
3713
  }
3733
3714
3734
  nsIFrame* newFrame;
3715
  nsIFrame* newFrame;
3735
  nsIFrame* primaryFrame;
3716
  nsIFrame* primaryFrame;
3717
  nsStyleContext* const styleContext = aItem.mStyleContext;
3718
  const nsStyleDisplay* display = styleContext->StyleDisplay();
3736
  if (bits & FCDATA_FUNC_IS_FULL_CTOR) {
3719
  if (bits & FCDATA_FUNC_IS_FULL_CTOR) {
3737
    newFrame =
3720
    newFrame =
3738
      (this->*(data->mFullConstructor))(aState, aItem, aParentFrame,
3721
      (this->*(data->mFullConstructor))(aState, aItem, aParentFrame,
3739
                                        display, aFrameItems);
3722
                                        display, aFrameItems);
3740
    MOZ_ASSERT(newFrame, "Full constructor failed");
3723
    MOZ_ASSERT(newFrame, "Full constructor failed");
3741
    primaryFrame = newFrame;
3724
    primaryFrame = newFrame;
3742
  } else {
3725
  } else {
3743
    newFrame =
3726
    newFrame =
 Lines 4495-4511   nsCSSFrameConstructor::FindDisplayData(c Link Here 
4495
                                       nsStyleContext* aStyleContext)
4478
                                       nsStyleContext* aStyleContext)
4496
{
4479
{
4497
  PR_STATIC_ASSERT(eParentTypeCount < (1 << (32 - FCDATA_PARENT_TYPE_OFFSET)));
4480
  PR_STATIC_ASSERT(eParentTypeCount < (1 << (32 - FCDATA_PARENT_TYPE_OFFSET)));
4498
4481
4499
  // The style system ensures that floated and positioned frames are
4482
  // The style system ensures that floated and positioned frames are
4500
  // block-level.
4483
  // block-level.
4501
  NS_ASSERTION(!(aDisplay->IsFloatingStyle() ||
4484
  NS_ASSERTION(!(aDisplay->IsFloatingStyle() ||
4502
                 aDisplay->IsAbsolutelyPositionedStyle()) ||
4485
                 aDisplay->IsAbsolutelyPositionedStyle()) ||
4503
               aDisplay->IsBlockOutsideStyle(),
4486
               aDisplay->IsBlockOutsideStyle() ||
4487
               aDisplay->mDisplay == NS_STYLE_DISPLAY_CONTENTS,
4504
               "Style system did not apply CSS2.1 section 9.7 fixups");
4488
               "Style system did not apply CSS2.1 section 9.7 fixups");
4505
4489
4506
  // If this is "body", try propagating its scroll style to the viewport
4490
  // If this is "body", try propagating its scroll style to the viewport
4507
  // Note that we need to do this even if the body is NOT scrollable;
4491
  // Note that we need to do this even if the body is NOT scrollable;
4508
  // it might have dynamically changed from scrollable to not scrollable,
4492
  // it might have dynamically changed from scrollable to not scrollable,
4509
  // and that might need to be propagated.
4493
  // and that might need to be propagated.
4510
  // XXXbz is this the right place to do this?  If this code moves,
4494
  // XXXbz is this the right place to do this?  If this code moves,
4511
  // make this function static.
4495
  // make this function static.
 Lines 4636-4654   nsCSSFrameConstructor::FindDisplayData(c Link Here 
4636
                       &nsCSSFrameConstructor::ConstructTableCol) },
4620
                       &nsCSSFrameConstructor::ConstructTableCol) },
4637
    { NS_STYLE_DISPLAY_TABLE_ROW,
4621
    { NS_STYLE_DISPLAY_TABLE_ROW,
4638
      FULL_CTOR_FCDATA(FCDATA_IS_TABLE_PART |
4622
      FULL_CTOR_FCDATA(FCDATA_IS_TABLE_PART |
4639
                       FCDATA_DESIRED_PARENT_TYPE_TO_BITS(eTypeRowGroup),
4623
                       FCDATA_DESIRED_PARENT_TYPE_TO_BITS(eTypeRowGroup),
4640
                       &nsCSSFrameConstructor::ConstructTableRowOrRowGroup) },
4624
                       &nsCSSFrameConstructor::ConstructTableRowOrRowGroup) },
4641
    { NS_STYLE_DISPLAY_TABLE_CELL,
4625
    { NS_STYLE_DISPLAY_TABLE_CELL,
4642
      FULL_CTOR_FCDATA(FCDATA_IS_TABLE_PART |
4626
      FULL_CTOR_FCDATA(FCDATA_IS_TABLE_PART |
4643
                       FCDATA_DESIRED_PARENT_TYPE_TO_BITS(eTypeRow),
4627
                       FCDATA_DESIRED_PARENT_TYPE_TO_BITS(eTypeRow),
4644
                       &nsCSSFrameConstructor::ConstructTableCell) }
4628
                       &nsCSSFrameConstructor::ConstructTableCell) },
4629
    { NS_STYLE_DISPLAY_CONTENTS,
4630
      FULL_CTOR_FCDATA(FCDATA_IS_CONTENTS, nullptr/*never called*/) }
4645
  };
4631
  };
4646
4632
4633
  // See the mDisplay fixup code in nsRuleNode::ComputeDisplayData.
4634
  MOZ_ASSERT(aDisplay->mDisplay != NS_STYLE_DISPLAY_CONTENTS ||
4635
             !aElement->IsRootOfNativeAnonymousSubtree(),
4636
             "display:contents on anonymous content is unsupported");
4637
4647
  return FindDataByInt(aDisplay->mDisplay,
4638
  return FindDataByInt(aDisplay->mDisplay,
4648
                       aElement, aStyleContext, sDisplayData,
4639
                       aElement, aStyleContext, sDisplayData,
4649
                       ArrayLength(sDisplayData));
4640
                       ArrayLength(sDisplayData));
4650
}
4641
}
4651
4642
4652
nsIFrame*
4643
nsIFrame*
4653
nsCSSFrameConstructor::ConstructScrollableBlock(nsFrameConstructorState& aState,
4644
nsCSSFrameConstructor::ConstructScrollableBlock(nsFrameConstructorState& aState,
4654
                                                FrameConstructionItem&   aItem,
4645
                                                FrameConstructionItem&   aItem,
 Lines 4756-4786   nsCSSFrameConstructor::InitAndRestoreFra Link Here 
4756
}
4747
}
4757
4748
4758
already_AddRefed<nsStyleContext>
4749
already_AddRefed<nsStyleContext>
4759
nsCSSFrameConstructor::ResolveStyleContext(nsIFrame*         aParentFrame,
4750
nsCSSFrameConstructor::ResolveStyleContext(nsIFrame*         aParentFrame,
4760
                                           nsIContent*       aContainer,
4751
                                           nsIContent*       aContainer,
4761
                                           nsIContent*       aChild,
4752
                                           nsIContent*       aChild,
4762
                                           nsFrameConstructorState* aState)
4753
                                           nsFrameConstructorState* aState)
4763
{
4754
{
4764
  nsStyleContext* parentStyleContext = nullptr;
4755
  nsIContent* container = aChild->GetParent();
4765
  NS_ASSERTION(aChild->GetParent(), "Must have parent here");
4756
  NS_ASSERTION(container, "Must have parent here");
4766
4757
  nsStyleContext* parentStyleContext = GetDisplayContentsStyleFor(container);
4767
  aParentFrame = nsFrame::CorrectStyleParentFrame(aParentFrame, nullptr);
4758
  if (MOZ_LIKELY(!parentStyleContext)) {
4768
4759
    aParentFrame = nsFrame::CorrectStyleParentFrame(aParentFrame, nullptr);
4769
  if (aParentFrame) {
4760
    if (aParentFrame) {
4770
    // Resolve the style context based on the content object and the parent
4761
      // Resolve the style context based on the content object and the parent
4771
    // style context
4762
      // style context
4772
    parentStyleContext = aParentFrame->StyleContext();
4763
      parentStyleContext = aParentFrame->StyleContext();
4773
  } else {
4764
    } else {
4774
    // Perhaps aParentFrame is a canvasFrame and we're replicating
4765
      // Perhaps aParentFrame is a canvasFrame and we're replicating
4775
    // fixed-pos frames.
4766
      // fixed-pos frames.
4776
    // XXX should we create a way to tell ConstructFrame which style
4767
      // XXX should we create a way to tell ConstructFrame which style
4777
    // context to use, and pass it the style context for the
4768
      // context to use, and pass it the style context for the
4778
    // previous page's fixed-pos frame?
4769
      // previous page's fixed-pos frame?
4770
    }
4779
  }
4771
  }
4780
4772
4781
  return ResolveStyleContext(parentStyleContext, aChild, aState);
4773
  return ResolveStyleContext(parentStyleContext, aChild, aState);
4782
}
4774
}
4783
4775
4784
already_AddRefed<nsStyleContext>
4776
already_AddRefed<nsStyleContext>
4785
nsCSSFrameConstructor::ResolveStyleContext(nsIFrame*          aParentFrame,
4777
nsCSSFrameConstructor::ResolveStyleContext(nsIFrame*          aParentFrame,
4786
                                           nsIContent*              aChild,
4778
                                           nsIContent*              aChild,
 Lines 5308-5329   nsCSSFrameConstructor::AddPageBreakItem( Link Here 
5308
5300
5309
  // Lie about the tag and namespace so we don't trigger anything
5301
  // Lie about the tag and namespace so we don't trigger anything
5310
  // interesting during frame construction.
5302
  // interesting during frame construction.
5311
  aItems.AppendItem(&sPageBreakData, aContent, nsCSSAnonBoxes::pageBreak,
5303
  aItems.AppendItem(&sPageBreakData, aContent, nsCSSAnonBoxes::pageBreak,
5312
                    kNameSpaceID_None, nullptr, pseudoStyle.forget(),
5304
                    kNameSpaceID_None, nullptr, pseudoStyle.forget(),
5313
                    true, nullptr);
5305
                    true, nullptr);
5314
}
5306
}
5315
5307
5316
void
5308
bool
5317
nsCSSFrameConstructor::AddFrameConstructionItems(nsFrameConstructorState& aState,
5309
nsCSSFrameConstructor::ShouldCreateItemsForChild(nsFrameConstructorState& aState,
5318
                                                 nsIContent* aContent,
5310
                                                 nsIContent* aContent,
5319
                                                 bool aSuppressWhiteSpaceOptimizations,
5311
                                                 nsContainerFrame* aParentFrame)
5320
                                                 const InsertionPoint& aInsertion,
5321
                                                 FrameConstructionItemList& aItems)
5322
{
5312
{
5323
  aContent->UnsetFlags(NODE_DESCENDANTS_NEED_FRAMES | NODE_NEEDS_FRAME);
5313
  aContent->UnsetFlags(NODE_DESCENDANTS_NEED_FRAMES | NODE_NEEDS_FRAME);
5324
  if (aContent->IsElement()) {
5314
  if (aContent->IsElement()) {
5325
    // We can't just remove our pending restyle flags, since we may
5315
    // We can't just remove our pending restyle flags, since we may
5326
    // have restyle-later-siblings set on us.  But we _can_ remove the
5316
    // have restyle-later-siblings set on us.  But we _can_ remove the
5327
    // "is possible restyle root" flags, and need to.  Otherwise we can
5317
    // "is possible restyle root" flags, and need to.  Otherwise we can
5328
    // end up with stale such flags (e.g. if we used to have a
5318
    // end up with stale such flags (e.g. if we used to have a
5329
    // display:none parent when our last restyle was posted and
5319
    // display:none parent when our last restyle was posted and
 Lines 5334-5384   nsCSSFrameConstructor::AddFrameConstruct Link Here 
5334
5324
5335
  // XXX the GetContent() != aContent check is needed due to bug 135040.
5325
  // XXX the GetContent() != aContent check is needed due to bug 135040.
5336
  // Remove it once that's fixed.
5326
  // Remove it once that's fixed.
5337
  if (aContent->GetPrimaryFrame() &&
5327
  if (aContent->GetPrimaryFrame() &&
5338
      aContent->GetPrimaryFrame()->GetContent() == aContent &&
5328
      aContent->GetPrimaryFrame()->GetContent() == aContent &&
5339
      !aState.mCreatingExtraFrames) {
5329
      !aState.mCreatingExtraFrames) {
5340
    NS_ERROR("asked to create frame construction item for a node that already "
5330
    NS_ERROR("asked to create frame construction item for a node that already "
5341
             "has a frame");
5331
             "has a frame");
5342
    return;
5332
    return false;
5343
  }
5333
  }
5344
5334
5345
  // don't create a whitespace frame if aParent doesn't want it
5335
  // don't create a whitespace frame if aParent doesn't want it
5346
  nsContainerFrame* aParentFrame = aInsertion.mParentFrame;
5347
  if (!NeedFrameFor(aState, aParentFrame, aContent)) {
5336
  if (!NeedFrameFor(aState, aParentFrame, aContent)) {
5348
    return;
5337
    return false;
5349
  }
5338
  }
5350
5339
5351
  // never create frames for comments or PIs
5340
  // never create frames for comments or PIs
5352
  if (aContent->IsNodeOfType(nsINode::eCOMMENT) ||
5341
  if (aContent->IsNodeOfType(nsINode::eCOMMENT) ||
5353
      aContent->IsNodeOfType(nsINode::ePROCESSING_INSTRUCTION))
5342
      aContent->IsNodeOfType(nsINode::ePROCESSING_INSTRUCTION)) {
5354
    return;
5343
    return false;
5355
5344
  }
5356
  nsRefPtr<nsStyleContext> styleContext;
5345
5357
  styleContext = ResolveStyleContext(aParentFrame, aContent, &aState);
5346
  return true;
5358
5347
}
5348
5349
void
5350
nsCSSFrameConstructor::DoAddFrameConstructionItems(nsFrameConstructorState& aState,
5351
                                                   nsIContent* aContent,
5352
                                                   nsStyleContext* aStyleContext,
5353
                                                   bool aSuppressWhiteSpaceOptimizations,
5354
                                                   nsContainerFrame* aParentFrame,
5355
                                                   nsTArray<nsIAnonymousContentCreator::ContentInfo>* aAnonChildren,
5356
                                                   FrameConstructionItemList& aItems)
5357
{
5359
  uint32_t flags = ITEM_ALLOW_XBL_BASE | ITEM_ALLOW_PAGE_BREAK;
5358
  uint32_t flags = ITEM_ALLOW_XBL_BASE | ITEM_ALLOW_PAGE_BREAK;
5360
  if (aParentFrame->IsSVGText()) {
5359
  if (aParentFrame) {
5361
    flags |= ITEM_IS_WITHIN_SVG_TEXT;
5360
    if (aParentFrame->IsSVGText()) {
5362
  }
5361
      flags |= ITEM_IS_WITHIN_SVG_TEXT;
5363
  if (aParentFrame->GetType() == nsGkAtoms::blockFrame &&
5362
    }
5364
      aParentFrame->GetParent() &&
5363
    if (aParentFrame->GetType() == nsGkAtoms::blockFrame &&
5365
      aParentFrame->GetParent()->GetType() == nsGkAtoms::svgTextFrame) {
5364
        aParentFrame->GetParent() &&
5366
    flags |= ITEM_ALLOWS_TEXT_PATH_CHILD;
5365
        aParentFrame->GetParent()->GetType() == nsGkAtoms::svgTextFrame) {
5366
      flags |= ITEM_ALLOWS_TEXT_PATH_CHILD;
5367
    }
5367
  }
5368
  }
5368
  AddFrameConstructionItemsInternal(aState, aContent, aParentFrame,
5369
  AddFrameConstructionItemsInternal(aState, aContent, aParentFrame,
5369
                                    aContent->Tag(), aContent->GetNameSpaceID(),
5370
                                    aContent->Tag(), aContent->GetNameSpaceID(),
5370
                                    aSuppressWhiteSpaceOptimizations,
5371
                                    aSuppressWhiteSpaceOptimizations,
5371
                                    styleContext,
5372
                                    aStyleContext,
5372
                                    flags, nullptr,
5373
                                    flags, aAnonChildren,
5373
                                    aItems);
5374
                                    aItems);
5374
}
5375
}
5375
5376
5376
void
5377
void
5378
nsCSSFrameConstructor::AddFrameConstructionItems(nsFrameConstructorState& aState,
5379
                                                 nsIContent* aContent,
5380
                                                 bool aSuppressWhiteSpaceOptimizations,
5381
                                                 const InsertionPoint& aInsertion,
5382
                                                 FrameConstructionItemList& aItems)
5383
{
5384
  nsContainerFrame* parentFrame = aInsertion.mParentFrame;
5385
  if (!ShouldCreateItemsForChild(aState, aContent, parentFrame)) {
5386
    return;
5387
  }
5388
  nsRefPtr<nsStyleContext> styleContext =
5389
    ResolveStyleContext(parentFrame, aContent, &aState);
5390
  DoAddFrameConstructionItems(aState, aContent, styleContext,
5391
                              aSuppressWhiteSpaceOptimizations, parentFrame,
5392
                              nullptr, aItems);
5393
}
5394
5395
void
5377
nsCSSFrameConstructor::SetAsUndisplayedContent(nsFrameConstructorState& aState,
5396
nsCSSFrameConstructor::SetAsUndisplayedContent(nsFrameConstructorState& aState,
5378
                                               FrameConstructionItemList& aList,
5397
                                               FrameConstructionItemList& aList,
5379
                                               nsIContent* aContent,
5398
                                               nsIContent* aContent,
5380
                                               nsStyleContext* aStyleContext,
5399
                                               nsStyleContext* aStyleContext,
5381
                                               bool aIsGeneratedContent)
5400
                                               bool aIsGeneratedContent)
5382
{
5401
{
5383
  if (aStyleContext->GetPseudo()) {
5402
  if (aStyleContext->GetPseudo()) {
5384
    if (aIsGeneratedContent) {
5403
    if (aIsGeneratedContent) {
 Lines 5577-5592   nsCSSFrameConstructor::AddFrameConstruct Link Here 
5577
    !display->IsAbsolutelyPositionedStyle() &&
5596
    !display->IsAbsolutelyPositionedStyle() &&
5578
    !(bits & FCDATA_IS_TABLE_PART) &&
5597
    !(bits & FCDATA_IS_TABLE_PART) &&
5579
    !(bits & FCDATA_IS_SVG_TEXT);
5598
    !(bits & FCDATA_IS_SVG_TEXT);
5580
5599
5581
  if (canHavePageBreak && display->mBreakBefore) {
5600
  if (canHavePageBreak && display->mBreakBefore) {
5582
    AddPageBreakItem(aContent, aStyleContext, aItems);
5601
    AddPageBreakItem(aContent, aStyleContext, aItems);
5583
  }
5602
  }
5584
5603
5604
  if (MOZ_UNLIKELY(bits & FCDATA_IS_CONTENTS)) {
5605
    if (!GetDisplayContentsStyleFor(aContent)) {
5606
      MOZ_ASSERT(styleContext->GetPseudo() || !isGeneratedContent,
5607
                 "Should have had pseudo type");
5608
      aState.mFrameManager->SetDisplayContents(aContent, styleContext);
5609
    } else {
5610
      aState.mFrameManager->ChangeDisplayContents(aContent, styleContext);
5611
    }
5612
5613
    TreeMatchContext::AutoAncestorPusher ancestorPusher(aState.mTreeMatchContext);
5614
    if (aState.mTreeMatchContext.mAncestorFilter.HasFilter()) {
5615
      ancestorPusher.PushAncestorAndStyleScope(aContent->AsElement());
5616
    } else {
5617
      ancestorPusher.PushStyleScope(aContent->AsElement());
5618
    }
5619
5620
    if (aParentFrame) {
5621
      aParentFrame->AddStateBits(NS_FRAME_MAY_HAVE_GENERATED_CONTENT);
5622
    }
5623
    CreateGeneratedContentItem(aState, aParentFrame, aContent, styleContext,
5624
                               nsCSSPseudoElements::ePseudo_before, aItems);
5625
5626
    FlattenedChildIterator iter(aContent);
5627
    for (nsIContent* child = iter.GetNextChild(); child; child = iter.GetNextChild()) {
5628
      if (!ShouldCreateItemsForChild(aState, child, aParentFrame)) {
5629
        continue;
5630
      }
5631
5632
      // Get the parent of the content and check if it is a XBL children element
5633
      // (if the content is a children element then parent != aContent because the
5634
      // FlattenedChildIterator will transitively iterate through <xbl:children>
5635
      // for default content). Push the children element as an ancestor here because
5636
      // it does not have a frame and would not otherwise be pushed as an ancestor.
5637
      nsIContent* parent = child->GetParent();
5638
      MOZ_ASSERT(parent, "Parent must be non-null because we are iterating children.");
5639
      TreeMatchContext::AutoAncestorPusher ancestorPusher(aState.mTreeMatchContext);
5640
      if (parent != aContent && parent->IsElement()) {
5641
        if (aState.mTreeMatchContext.mAncestorFilter.HasFilter()) {
5642
          ancestorPusher.PushAncestorAndStyleScope(parent->AsElement());
5643
        } else {
5644
          ancestorPusher.PushStyleScope(parent->AsElement());
5645
        }
5646
      }
5647
5648
      nsRefPtr<nsStyleContext> childContext =
5649
        ResolveStyleContext(styleContext, child, &aState);
5650
      DoAddFrameConstructionItems(aState, child, childContext,
5651
                                  aSuppressWhiteSpaceOptimizations,
5652
                                  aParentFrame, aAnonChildren, aItems);
5653
    }
5654
    aItems.SetParentHasNoXBLChildren(!iter.XBLInvolved());
5655
5656
    CreateGeneratedContentItem(aState, aParentFrame, aContent, styleContext,
5657
                               nsCSSPseudoElements::ePseudo_after, aItems);
5658
    if (canHavePageBreak && display->mBreakAfter) {
5659
      AddPageBreakItem(aContent, aStyleContext, aItems);
5660
    }
5661
    return;
5662
  }
5663
5585
  FrameConstructionItem* item =
5664
  FrameConstructionItem* item =
5586
    aItems.AppendItem(data, aContent, aTag, aNameSpaceID,
5665
    aItems.AppendItem(data, aContent, aTag, aNameSpaceID,
5587
                      pendingBinding, styleContext.forget(),
5666
                      pendingBinding, styleContext.forget(),
5588
                      aSuppressWhiteSpaceOptimizations, aAnonChildren);
5667
                      aSuppressWhiteSpaceOptimizations, aAnonChildren);
5589
  if (!item) {
5668
  if (!item) {
5590
    if (isGeneratedContent) {
5669
    if (isGeneratedContent) {
5591
      aContent->UnbindFromTree();
5670
      aContent->UnbindFromTree();
5592
    }
5671
    }
 Lines 5939-5969   nsCSSFrameConstructor::GetFloatContainin Link Here 
5939
6018
5940
/**
6019
/**
5941
 * This function will check whether aContainer has :after generated content.
6020
 * This function will check whether aContainer has :after generated content.
5942
 * If so, appending to it should actually insert.  The return value is the
6021
 * If so, appending to it should actually insert.  The return value is the
5943
 * parent to use for newly-appended content.  *aAfterFrame points to the :after
6022
 * parent to use for newly-appended content.  *aAfterFrame points to the :after
5944
 * frame before which appended content should go, if there is one.
6023
 * frame before which appended content should go, if there is one.
5945
 */
6024
 */
5946
static nsContainerFrame*
6025
static nsContainerFrame*
5947
AdjustAppendParentForAfterContent(nsPresContext* aPresContext,
6026
AdjustAppendParentForAfterContent(nsFrameManager* aFrameManager,
5948
                                  nsIContent* aContainer,
6027
                                  nsIContent* aContainer,
5949
                                  nsContainerFrame* aParentFrame,
6028
                                  nsContainerFrame* aParentFrame,
6029
                                  nsIContent* aChild,
5950
                                  nsIFrame** aAfterFrame)
6030
                                  nsIFrame** aAfterFrame)
5951
{
6031
{
5952
  // See if the parent has an :after pseudo-element.  Check for the presence
6032
  // If the parent frame has any pseudo-elements or aContainer is a
5953
  // of style first, since nsLayoutUtils::GetAfterFrame is sorta expensive.
6033
  // display:contents node then we need to walk through the child
5954
  nsStyleContext* parentStyle = aParentFrame->StyleContext();
6034
  // frames to find the first one that is either a ::after frame for an
5955
  if (nsLayoutUtils::HasPseudoStyle(aContainer, parentStyle,
6035
  // ancestor of aChild or a frame that is for a node later in the
6036
  // document than aChild and return that in aAfterFrame.
6037
  if (GetGenConPseudos(aParentFrame) ||
6038
      nsLayoutUtils::HasPseudoStyle(aContainer, aParentFrame->StyleContext(),
5956
                                    nsCSSPseudoElements::ePseudo_after,
6039
                                    nsCSSPseudoElements::ePseudo_after,
5957
                                    aPresContext)) {
6040
                                    aParentFrame->PresContext()) ||
5958
    // Ensure that the :after frame is on the principal child list.
6041
      aFrameManager->GetDisplayContentsStyleFor(aContainer)) {
5959
    aParentFrame->DrainSelfOverflowList();
6042
    nsIFrame* afterFrame = nullptr;
5960
6043
    nsContainerFrame* parent =
5961
    nsIFrame* afterFrame = nsLayoutUtils::GetAfterFrame(aParentFrame);
6044
      static_cast<nsContainerFrame*>(aParentFrame->LastContinuation());
6045
    bool done = false;
6046
    while (!done && parent) {
6047
      // Ensure that all normal flow children are on the principal child list.
6048
      parent->DrainSelfOverflowList();
6049
6050
      nsIFrame* child = parent->GetLastChild(nsIFrame::kPrincipalList);
6051
      if (child && child->IsPseudoFrame(aContainer) &&
6052
          !child->IsGeneratedContentFrame()) {
6053
        // Drill down into non-generated pseudo frames of aContainer.
6054
        parent = nsLayoutUtils::LastContinuationWithChild(do_QueryFrame(child));
6055
        continue;
6056
      }
6057
6058
      for (; child; child = child->GetPrevSibling()) {
6059
        nsIContent* c = child->GetContent();
6060
        if (child->IsGeneratedContentFrame()) {
6061
          nsIContent* p = c->GetParent();
6062
          if (c->Tag() == nsGkAtoms::mozgeneratedcontentafter) {
6063
            if (!nsContentUtils::ContentIsDescendantOf(aChild, p) &&
6064
                p != aContainer &&
6065
                nsContentUtils::PositionIsBefore(p, aChild)) {
6066
              // ::after generated content for content earlier in the doc and not
6067
              // for an ancestor.  "p != aContainer" may seem redundant but it
6068
              // checks if the ::after belongs to the XBL insertion point we're
6069
              // inserting aChild into (in which case ContentIsDescendantOf is
6070
              // false even though p == aContainer).
6071
              // See layout/reftests/bugs/482592-1a.xhtml for an example of that.
6072
              done = true;
6073
              break;
6074
            }
6075
          } else if (nsContentUtils::PositionIsBefore(p, aChild)) {
6076
            // Non-::after generated content for content earlier in the doc.
6077
            done = true;
6078
            break;
6079
          }
6080
        } else if (nsContentUtils::PositionIsBefore(c, aChild)) {
6081
          // Content is before aChild.
6082
          done = true;
6083
          break;
6084
        }
6085
        afterFrame = child;
6086
      }
6087
6088
      parent = static_cast<nsContainerFrame*>(parent->GetPrevContinuation());
6089
    }
5962
    if (afterFrame) {
6090
    if (afterFrame) {
5963
      *aAfterFrame = afterFrame;
6091
      *aAfterFrame = afterFrame;
5964
      return afterFrame->GetParent();
6092
      return afterFrame->GetParent();
5965
    }
6093
    }
5966
  }
6094
  }
5967
6095
5968
  *aAfterFrame = nullptr;
6096
  *aAfterFrame = nullptr;
5969
6097
 Lines 6333-6349   nsCSSFrameConstructor::GetInsertionPrevS Link Here 
6333
  NS_PRECONDITION(aInsertion->mParentFrame, "Must have parent frame to start with");
6461
  NS_PRECONDITION(aInsertion->mParentFrame, "Must have parent frame to start with");
6334
6462
6335
  *aIsAppend = false;
6463
  *aIsAppend = false;
6336
6464
6337
  // Find the frame that precedes the insertion point. Walk backwards
6465
  // Find the frame that precedes the insertion point. Walk backwards
6338
  // from the parent frame to get the parent content, because if an
6466
  // from the parent frame to get the parent content, because if an
6339
  // XBL insertion point is involved, we'll need to use _that_ to find
6467
  // XBL insertion point is involved, we'll need to use _that_ to find
6340
  // the preceding frame.
6468
  // the preceding frame.
6341
  nsIContent* container = aInsertion->mParentFrame->GetContent();
6469
  const bool boxContents = GetDisplayContentsStyleFor(aInsertion->mContainer);
6470
  nsIContent* container = boxContents ? aInsertion->mContainer : aInsertion->mParentFrame->GetContent();
6342
6471
6343
  FlattenedChildIterator iter(container);
6472
  FlattenedChildIterator iter(container);
6344
  bool xblCase = iter.XBLInvolved() || container != aInsertion->mContainer;
6473
  bool xblCase = iter.XBLInvolved() || container != aInsertion->mContainer;
6345
  if (xblCase || !aChild->IsRootOfAnonymousSubtree()) {
6474
  if (xblCase || !aChild->IsRootOfAnonymousSubtree()) {
6346
    // The check for IsRootOfAnonymousSubtree() is because editor is
6475
    // The check for IsRootOfAnonymousSubtree() is because editor is
6347
    // severely broken and calls us directly for native anonymous
6476
    // severely broken and calls us directly for native anonymous
6348
    // nodes that it creates.
6477
    // nodes that it creates.
6349
    if (aStartSkipChild) {
6478
    if (aStartSkipChild) {
 Lines 6363-6391   nsCSSFrameConstructor::GetInsertionPrevS Link Here 
6363
  uint8_t childDisplay = UNSET_DISPLAY;
6492
  uint8_t childDisplay = UNSET_DISPLAY;
6364
  nsIFrame* prevSibling = FindPreviousSibling(iter, childDisplay);
6493
  nsIFrame* prevSibling = FindPreviousSibling(iter, childDisplay);
6365
6494
6366
  // Now, find the geometric parent so that we can handle
6495
  // Now, find the geometric parent so that we can handle
6367
  // continuations properly. Use the prev sibling if we have it;
6496
  // continuations properly. Use the prev sibling if we have it;
6368
  // otherwise use the next sibling.
6497
  // otherwise use the next sibling.
6369
  if (prevSibling) {
6498
  if (prevSibling) {
6370
    aInsertion->mParentFrame = prevSibling->GetParent()->GetContentInsertionFrame();
6499
    aInsertion->mParentFrame = prevSibling->GetParent()->GetContentInsertionFrame();
6371
  }
6500
  } else {
6372
  else {
6373
    // If there is no previous sibling, then find the frame that follows
6501
    // If there is no previous sibling, then find the frame that follows
6374
    if (aEndSkipChild) {
6502
    if (aEndSkipChild) {
6375
      iter.Seek(aEndSkipChild);
6503
      iter.Seek(aEndSkipChild);
6376
      iter.GetPreviousChild();
6504
      iter.GetPreviousChild();
6377
    }
6505
    }
6378
    nsIFrame* nextSibling = FindNextSibling(iter, childDisplay);
6506
    nsIFrame* nextSibling = FindNextSibling(iter, childDisplay);
6507
    if (boxContents) {
6508
      if (!nextSibling) {
6509
        // Our siblings (if any) does not have a frame to guide us.
6510
        // The frame for aChild should be inserted whereever a frame for
6511
        // the container would be inserted.  This is needed when inserting
6512
        // into nested display:contents nodes.
6513
        nsIContent* child = aInsertion->mContainer;
6514
        InsertionPoint fakeInsertion(aInsertion->mParentFrame, child->GetParent());
6515
        nsIFrame* result = GetInsertionPrevSibling(&fakeInsertion, child, aIsAppend,
6516
                                                   aIsRangeInsertSafe, nullptr, nullptr);
6517
        MOZ_ASSERT(aInsertion->mParentFrame == fakeInsertion.mParentFrame);
6518
        return result;
6519
      }
6520
6521
      prevSibling = nextSibling->GetPrevSibling();
6522
      if (prevSibling) {
6523
        // We have a prev-sibling frame that FindPreviousSibling veto'ed or
6524
        // it didn't find because it's not for a content sibling.
6525
        // Make a new check in case it's the latter case.
6526
        prevSibling =
6527
          FindFrameForContentSibling(prevSibling->GetContent(),
6528
                                     nextSibling->GetContent(),
6529
                                     childDisplay, true);        
6530
      }
6531
    }
6379
6532
6380
    if (nextSibling) {
6533
    if (nextSibling) {
6381
      aInsertion->mParentFrame = nextSibling->GetParent()->GetContentInsertionFrame();
6534
      aInsertion->mParentFrame = nextSibling->GetParent()->GetContentInsertionFrame();
6382
    }
6535
    } else {
6383
    else {
6384
      // No previous or next sibling, so treat this like an appended frame.
6536
      // No previous or next sibling, so treat this like an appended frame.
6385
      *aIsAppend = true;
6537
      *aIsAppend = true;
6386
      if (IsFramePartOfIBSplit(aInsertion->mParentFrame)) {
6538
      if (IsFramePartOfIBSplit(aInsertion->mParentFrame)) {
6387
        // Since we're appending, we'll walk to the last anonymous frame
6539
        // Since we're appending, we'll walk to the last anonymous frame
6388
        // that was created for the broken inline frame.  But don't walk
6540
        // that was created for the broken inline frame.  But don't walk
6389
        // to the trailing inline if it's empty; stop at the block.
6541
        // to the trailing inline if it's empty; stop at the block.
6390
        aInsertion->mParentFrame =
6542
        aInsertion->mParentFrame =
6391
          GetLastIBSplitSibling(aInsertion->mParentFrame, false);
6543
          GetLastIBSplitSibling(aInsertion->mParentFrame, false);
 Lines 6396-6422   nsCSSFrameConstructor::GetInsertionPrevS Link Here 
6396
        nsLayoutUtils::LastContinuationWithChild(aInsertion->mParentFrame);
6548
        nsLayoutUtils::LastContinuationWithChild(aInsertion->mParentFrame);
6397
      // Deal with fieldsets
6549
      // Deal with fieldsets
6398
      aInsertion->mParentFrame =
6550
      aInsertion->mParentFrame =
6399
        ::GetAdjustedParentFrame(aInsertion->mParentFrame,
6551
        ::GetAdjustedParentFrame(aInsertion->mParentFrame,
6400
                                 aInsertion->mParentFrame->GetType(),
6552
                                 aInsertion->mParentFrame->GetType(),
6401
                                 aChild);
6553
                                 aChild);
6402
      nsIFrame* appendAfterFrame;
6554
      nsIFrame* appendAfterFrame;
6403
      aInsertion->mParentFrame =
6555
      aInsertion->mParentFrame =
6404
        ::AdjustAppendParentForAfterContent(mPresShell->GetPresContext(),
6556
        ::AdjustAppendParentForAfterContent(this, container,
6405
                                            container, aInsertion->mParentFrame,
6557
                                            aInsertion->mParentFrame,
6406
                                            &appendAfterFrame);
6558
                                            aChild, &appendAfterFrame);
6407
      prevSibling = ::FindAppendPrevSibling(aInsertion->mParentFrame, appendAfterFrame);
6559
      prevSibling = ::FindAppendPrevSibling(aInsertion->mParentFrame, appendAfterFrame);
6408
    }
6560
    }
6409
  }
6561
  }
6410
6562
6411
  *aIsRangeInsertSafe = (childDisplay == UNSET_DISPLAY);
6563
  *aIsRangeInsertSafe = (childDisplay == UNSET_DISPLAY);
6412
  return prevSibling;
6564
  return prevSibling;
6413
}
6565
}
6414
6566
6567
nsContainerFrame*
6568
nsCSSFrameConstructor::GetContentInsertionFrameFor(nsIContent* aContent)
6569
{
6570
  // Get the primary frame associated with the content
6571
  nsIFrame* frame = aContent->GetPrimaryFrame();
6572
6573
  if (!frame) {
6574
    if (GetDisplayContentsStyleFor(aContent)) {
6575
      nsIContent* parent = aContent->GetParent();
6576
      frame = parent ? GetContentInsertionFrameFor(parent) : nullptr;
6577
    }
6578
    if (!frame) {
6579
      return nullptr;
6580
    }
6581
  } else {
6582
    // If the content of the frame is not the desired content then this is not
6583
    // really a frame for the desired content.
6584
    // XXX This check is needed due to bug 135040. Remove it once that's fixed.
6585
    if (frame->GetContent() != aContent) {
6586
      return nullptr;
6587
    }
6588
  }
6589
6590
  nsContainerFrame* insertionFrame = frame->GetContentInsertionFrame();
6591
6592
  NS_ASSERTION(!insertionFrame || insertionFrame == frame || !frame->IsLeaf(),
6593
    "The insertion frame is the primary frame or the primary frame isn't a leaf");
6594
6595
  return insertionFrame;
6596
}
6597
6415
static bool
6598
static bool
6416
IsSpecialFramesetChild(nsIContent* aContent)
6599
IsSpecialFramesetChild(nsIContent* aContent)
6417
{
6600
{
6418
  // IMPORTANT: This must match the conditions in nsHTMLFramesetFrame::Init.
6601
  // IMPORTANT: This must match the conditions in nsHTMLFramesetFrame::Init.
6419
  return aContent->IsHTML() &&
6602
  return aContent->IsHTML() &&
6420
    (aContent->Tag() == nsGkAtoms::frameset ||
6603
    (aContent->Tag() == nsGkAtoms::frameset ||
6421
     aContent->Tag() == nsGkAtoms::frame);
6604
     aContent->Tag() == nsGkAtoms::frame);
6422
}
6605
}
 Lines 6544-6559   nsCSSFrameConstructor::MaybeConstructLaz Link Here 
6544
    }
6727
    }
6545
    if (!noPrimaryFrame && !content->GetPrimaryFrame()) {
6728
    if (!noPrimaryFrame && !content->GetPrimaryFrame()) {
6546
      noPrimaryFrame = true;
6729
      noPrimaryFrame = true;
6547
    }
6730
    }
6548
    if (!needsFrameBitSet && content->HasFlag(NODE_NEEDS_FRAME)) {
6731
    if (!needsFrameBitSet && content->HasFlag(NODE_NEEDS_FRAME)) {
6549
      needsFrameBitSet = true;
6732
      needsFrameBitSet = true;
6550
    }
6733
    }
6551
#endif
6734
#endif
6735
    // XXXmats no lazy frames for display:contents descendants yet (bug 979782).
6736
    if (GetDisplayContentsStyleFor(content)) {
6737
      return false;
6738
    }
6552
    content->SetFlags(NODE_DESCENDANTS_NEED_FRAMES);
6739
    content->SetFlags(NODE_DESCENDANTS_NEED_FRAMES);
6553
    content = content->GetFlattenedTreeParent();
6740
    content = content->GetFlattenedTreeParent();
6554
  }
6741
  }
6555
#ifdef DEBUG
6742
#ifdef DEBUG
6556
  if (content && content->GetPrimaryFrame() &&
6743
  if (content && content->GetPrimaryFrame() &&
6557
      content->GetPrimaryFrame()->IsLeaf()) {
6744
      content->GetPrimaryFrame()->IsLeaf()) {
6558
    noPrimaryFrame = needsFrameBitSet = false;
6745
    noPrimaryFrame = needsFrameBitSet = false;
6559
  }
6746
  }
 Lines 6666-6683   void Link Here 
6666
nsCSSFrameConstructor::IssueSingleInsertNofications(nsIContent* aContainer,
6853
nsCSSFrameConstructor::IssueSingleInsertNofications(nsIContent* aContainer,
6667
                                                    nsIContent* aStartChild,
6854
                                                    nsIContent* aStartChild,
6668
                                                    nsIContent* aEndChild,
6855
                                                    nsIContent* aEndChild,
6669
                                                    bool aAllowLazyConstruction)
6856
                                                    bool aAllowLazyConstruction)
6670
{
6857
{
6671
  for (nsIContent* child = aStartChild;
6858
  for (nsIContent* child = aStartChild;
6672
       child != aEndChild;
6859
       child != aEndChild;
6673
       child = child->GetNextSibling()) {
6860
       child = child->GetNextSibling()) {
6674
    if ((child->GetPrimaryFrame() ||
6861
    if ((child->GetPrimaryFrame() || GetUndisplayedContent(child) ||
6675
         GetUndisplayedContent(child))
6862
         GetDisplayContentsStyleFor(child))
6676
#ifdef MOZ_XUL
6863
#ifdef MOZ_XUL
6677
        //  Except listboxes suck, so do NOT skip anything here if
6864
        //  Except listboxes suck, so do NOT skip anything here if
6678
        //  we plan to notify a listbox.
6865
        //  we plan to notify a listbox.
6679
        && !MaybeGetListBoxBodyFrame(aContainer, child)
6866
        && !MaybeGetListBoxBodyFrame(aContainer, child)
6680
#endif
6867
#endif
6681
        ) {
6868
        ) {
6682
      // Already have a frame or undisplayed entry for this content; a
6869
      // Already have a frame or undisplayed entry for this content; a
6683
      // previous ContentInserted in this loop must have reconstructed
6870
      // previous ContentInserted in this loop must have reconstructed
 Lines 6829-6845   nsCSSFrameConstructor::ContentAppended(n Link Here 
6829
    nsIContent* bindingParent = aContainer->GetBindingParent();
7016
    nsIContent* bindingParent = aContainer->GetBindingParent();
6830
    LAYOUT_PHASE_TEMP_EXIT();
7017
    LAYOUT_PHASE_TEMP_EXIT();
6831
    nsresult rv = RecreateFramesForContent(bindingParent, false);
7018
    nsresult rv = RecreateFramesForContent(bindingParent, false);
6832
    LAYOUT_PHASE_TEMP_REENTER();
7019
    LAYOUT_PHASE_TEMP_REENTER();
6833
    return rv;
7020
    return rv;
6834
  }
7021
  }
6835
7022
6836
  // See comment in ContentRangeInserted for why this is necessary.
7023
  // See comment in ContentRangeInserted for why this is necessary.
6837
  if (!::GetContentInsertionFrameFor(aContainer) &&
7024
  if (!GetContentInsertionFrameFor(aContainer) &&
6838
      !aContainer->IsActiveChildrenElement()) {
7025
      !aContainer->IsActiveChildrenElement()) {
6839
    return NS_OK;
7026
    return NS_OK;
6840
  }
7027
  }
6841
7028
6842
  if (aAllowLazyConstruction &&
7029
  if (aAllowLazyConstruction &&
6843
      MaybeConstructLazily(CONTENTAPPEND, aContainer, aFirstNewContent)) {
7030
      MaybeConstructLazily(CONTENTAPPEND, aContainer, aFirstNewContent)) {
6844
    return NS_OK;
7031
    return NS_OK;
6845
  }
7032
  }
 Lines 6901-6919   nsCSSFrameConstructor::ContentAppended(n Link Here 
6901
  // We should never get here with fieldsets, since they have multiple
7088
  // We should never get here with fieldsets, since they have multiple
6902
  // insertion points.
7089
  // insertion points.
6903
  NS_ASSERTION(parentFrame->GetType() != nsGkAtoms::fieldSetFrame,
7090
  NS_ASSERTION(parentFrame->GetType() != nsGkAtoms::fieldSetFrame,
6904
               "Unexpected parent");
7091
               "Unexpected parent");
6905
7092
6906
  // Deal with possible :after generated content on the parent
7093
  // Deal with possible :after generated content on the parent
6907
  nsIFrame* parentAfterFrame;
7094
  nsIFrame* parentAfterFrame;
6908
  parentFrame =
7095
  parentFrame =
6909
    ::AdjustAppendParentForAfterContent(mPresShell->GetPresContext(),
7096
    ::AdjustAppendParentForAfterContent(this, insertion.mContainer, parentFrame,
6910
                                        insertion.mContainer, parentFrame,
7097
                                        aFirstNewContent, &parentAfterFrame);
6911
                                        &parentAfterFrame);
6912
7098
6913
  // Create some new frames
7099
  // Create some new frames
6914
  nsFrameConstructorState state(mPresShell,
7100
  nsFrameConstructorState state(mPresShell,
6915
                                GetAbsoluteContainingBlock(parentFrame, FIXED_POS),
7101
                                GetAbsoluteContainingBlock(parentFrame, FIXED_POS),
6916
                                GetAbsoluteContainingBlock(parentFrame, ABS_POS),
7102
                                GetAbsoluteContainingBlock(parentFrame, ABS_POS),
6917
                                GetFloatContainingBlock(parentFrame));
7103
                                GetFloatContainingBlock(parentFrame));
6918
  state.mTreeMatchContext.InitAncestors(aContainer->AsElement());
7104
  state.mTreeMatchContext.InitAncestors(aContainer->AsElement());
6919
7105
 Lines 7268-7294   nsCSSFrameConstructor::ContentRangeInser Link Here 
7268
    nsresult rv = RecreateFramesForContent(bindingParent, false);
7454
    nsresult rv = RecreateFramesForContent(bindingParent, false);
7269
    LAYOUT_PHASE_TEMP_REENTER();
7455
    LAYOUT_PHASE_TEMP_REENTER();
7270
    return rv;
7456
    return rv;
7271
  }
7457
  }
7272
7458
7273
  // Put 'parentFrame' inside a scope so we don't confuse it with
7459
  // Put 'parentFrame' inside a scope so we don't confuse it with
7274
  // 'insertion.mParentFrame' later.
7460
  // 'insertion.mParentFrame' later.
7275
  {
7461
  {
7276
    nsContainerFrame* parentFrame = ::GetContentInsertionFrameFor(aContainer);
7462
    nsContainerFrame* parentFrame = GetContentInsertionFrameFor(aContainer);
7277
    // The xbl:children element won't have a frame, but default content can have the children as
7463
    // The xbl:children element won't have a frame, but default content can have the children as
7278
    // a parent. While its uncommon to change the structure of the default content itself, a label,
7464
    // a parent. While its uncommon to change the structure of the default content itself, a label,
7279
    // for example, can be reframed by having its value attribute set or removed.
7465
    // for example, can be reframed by having its value attribute set or removed.
7280
    if (!parentFrame && !aContainer->IsActiveChildrenElement()) {
7466
    if (!parentFrame && !aContainer->IsActiveChildrenElement()) {
7281
      return NS_OK;
7467
      return NS_OK;
7282
    }
7468
    }
7283
7469
7284
    // Otherwise, we've got parent content. Find its frame.
7470
    // Otherwise, we've got parent content. Find its frame.
7285
    NS_ASSERTION(!parentFrame || parentFrame->GetContent() == aContainer,
7471
    NS_ASSERTION(!parentFrame || parentFrame->GetContent() == aContainer ||
7286
                 "New XBL code is possibly wrong!");
7472
                 GetDisplayContentsStyleFor(aContainer), "New XBL code is possibly wrong!");
7287
7473
7288
    if (aAllowLazyConstruction &&
7474
    if (aAllowLazyConstruction &&
7289
        MaybeConstructLazily(CONTENTINSERT, aContainer, aStartChild)) {
7475
        MaybeConstructLazily(CONTENTINSERT, aContainer, aStartChild)) {
7290
      return NS_OK;
7476
      return NS_OK;
7291
    }
7477
    }
7292
  }
7478
  }
7293
7479
7294
  InsertionPoint insertion;
7480
  InsertionPoint insertion;
 Lines 7565-7584   nsCSSFrameConstructor::ContentRangeInser Link Here 
7565
                 frame1->GetType() == nsGkAtoms::fieldSetFrame ||
7751
                 frame1->GetType() == nsGkAtoms::fieldSetFrame ||
7566
                 (frame1->GetParent() &&
7752
                 (frame1->GetParent() &&
7567
                  frame1->GetParent()->GetType() == nsGkAtoms::fieldSetFrame),
7753
                  frame1->GetParent()->GetType() == nsGkAtoms::fieldSetFrame),
7568
                 "Unexpected frame types");
7754
                 "Unexpected frame types");
7569
#endif
7755
#endif
7570
    isAppend = true;
7756
    isAppend = true;
7571
    nsIFrame* appendAfterFrame;
7757
    nsIFrame* appendAfterFrame;
7572
    insertion.mParentFrame =
7758
    insertion.mParentFrame =
7573
      ::AdjustAppendParentForAfterContent(mPresShell->GetPresContext(),
7759
      ::AdjustAppendParentForAfterContent(this, container,
7574
                                          container,
7575
                                          frameItems.FirstChild()->GetParent(),
7760
                                          frameItems.FirstChild()->GetParent(),
7576
                                          &appendAfterFrame);
7761
                                          aStartChild, &appendAfterFrame);
7577
    prevSibling = ::FindAppendPrevSibling(insertion.mParentFrame, appendAfterFrame);
7762
    prevSibling = ::FindAppendPrevSibling(insertion.mParentFrame, appendAfterFrame);
7578
  }
7763
  }
7579
7764
7580
  if (haveFirstLineStyle && insertion.mParentFrame == containingBlock) {
7765
  if (haveFirstLineStyle && insertion.mParentFrame == containingBlock) {
7581
    // It's possible that the new frame goes into a first-line
7766
    // It's possible that the new frame goes into a first-line
7582
    // frame. Look at it and see...
7767
    // frame. Look at it and see...
7583
    if (isAppend) {
7768
    if (isAppend) {
7584
      // Use append logic when appending
7769
      // Use append logic when appending
 Lines 7709-7736   nsCSSFrameConstructor::ContentRemoved(ns Link Here 
7709
           static_cast<void*>(aChild),
7894
           static_cast<void*>(aChild),
7710
           static_cast<void*>(aOldNextSibling));
7895
           static_cast<void*>(aOldNextSibling));
7711
    if (gReallyNoisyContentUpdates) {
7896
    if (gReallyNoisyContentUpdates) {
7712
      aContainer->List(stdout, 0);
7897
      aContainer->List(stdout, 0);
7713
    }
7898
    }
7714
  }
7899
  }
7715
#endif
7900
#endif
7716
7901
7717
  nsPresContext *presContext = mPresShell->GetPresContext();
7902
  nsresult rv = NS_OK;
7718
  nsresult                  rv = NS_OK;
7719
7720
  // Find the child frame that maps the content
7721
  nsIFrame* childFrame = aChild->GetPrimaryFrame();
7903
  nsIFrame* childFrame = aChild->GetPrimaryFrame();
7722
7723
  if (!childFrame || childFrame->GetContent() != aChild) {
7904
  if (!childFrame || childFrame->GetContent() != aChild) {
7724
    // XXXbz the GetContent() != aChild check is needed due to bug 135040.
7905
    // XXXbz the GetContent() != aChild check is needed due to bug 135040.
7725
    // Remove it once that's fixed.
7906
    // Remove it once that's fixed.
7726
    ClearUndisplayedContentIn(aChild, aContainer);
7907
    ClearUndisplayedContentIn(aChild, aContainer);
7727
  }
7908
  }
7728
7909
  MOZ_ASSERT(!childFrame || !GetDisplayContentsStyleFor(aChild),
7910
             "display:contents nodes shouldn't have a frame");
7911
  if (!childFrame && GetDisplayContentsStyleFor(aChild)) {
7912
    FlattenedChildIterator iter(aChild);
7913
    for (nsIContent* c = iter.GetNextChild(); c; c = iter.GetNextChild()) {
7914
      if (c->GetPrimaryFrame() || GetDisplayContentsStyleFor(c)) {
7915
        LAYOUT_PHASE_TEMP_EXIT();
7916
        rv = ContentRemoved(aChild, c, nullptr, aFlags, aDidReconstruct);
7917
        LAYOUT_PHASE_TEMP_REENTER();
7918
        NS_ENSURE_SUCCESS(rv, rv);
7919
        if (*aDidReconstruct) {
7920
          return rv;
7921
        }
7922
      }
7923
    }
7924
    ClearDisplayContentsIn(aChild, aContainer);
7925
  }
7926
7927
  nsPresContext* presContext = mPresShell->GetPresContext();
7729
#ifdef MOZ_XUL
7928
#ifdef MOZ_XUL
7730
  if (NotifyListBoxBody(presContext, aContainer, aChild, aOldNextSibling,
7929
  if (NotifyListBoxBody(presContext, aContainer, aChild, aOldNextSibling,
7731
                        mDocument, childFrame, CONTENT_REMOVED))
7930
                        mDocument, childFrame, CONTENT_REMOVED))
7732
    return NS_OK;
7931
    return NS_OK;
7733
7932
7734
#endif // MOZ_XUL
7933
#endif // MOZ_XUL
7735
7934
7736
  // If we're removing the root, then make sure to remove things starting at
7935
  // If we're removing the root, then make sure to remove things starting at
(-)a/layout/base/nsCSSFrameConstructor.h (+27 lines)
Line     Link Here 
 Lines 338-353   private: Link Here 
338
  // may suppress the construction of white-space-only text frames
338
  // may suppress the construction of white-space-only text frames
339
  // must be skipped for these items and items around them.
339
  // must be skipped for these items and items around them.
340
  void AddFrameConstructionItems(nsFrameConstructorState& aState,
340
  void AddFrameConstructionItems(nsFrameConstructorState& aState,
341
                                 nsIContent*              aContent,
341
                                 nsIContent*              aContent,
342
                                 bool                     aSuppressWhiteSpaceOptimizations,
342
                                 bool                     aSuppressWhiteSpaceOptimizations,
343
                                 const InsertionPoint&    aInsertion,
343
                                 const InsertionPoint&    aInsertion,
344
                                 FrameConstructionItemList& aItems);
344
                                 FrameConstructionItemList& aItems);
345
345
346
  // Helper method for AddFrameConstructionItems etc.
347
  // Unsets the need-frame/restyle bits on aContent.
348
  // return true iff we should attempt to create frames for aContent.
349
  bool ShouldCreateItemsForChild(nsFrameConstructorState& aState,
350
                                 nsIContent* aContent,
351
                                 nsContainerFrame* aParentFrame);
352
353
  // Helper method for AddFrameConstructionItems etc.
354
  // Make sure ShouldCreateItemsForChild() returned true before calling this.
355
  void DoAddFrameConstructionItems(nsFrameConstructorState& aState,
356
                                   nsIContent* aContent,
357
                                   nsStyleContext* aStyleContext,
358
                                   bool aSuppressWhiteSpaceOptimizations,
359
                                   nsContainerFrame* aParentFrame,
360
                                   nsTArray<nsIAnonymousContentCreator::ContentInfo>* aAnonChildren,
361
                                   FrameConstructionItemList& aItems);
362
346
  // Construct the frames for the document element.  This can return null if the
363
  // Construct the frames for the document element.  This can return null if the
347
  // document element is display:none, or if the document element has a
364
  // document element is display:none, or if the document element has a
348
  // not-yet-loaded XBL binding, or if it's an SVG element that's not <svg>.
365
  // not-yet-loaded XBL binding, or if it's an SVG element that's not <svg>.
349
  nsIFrame* ConstructDocElementFrame(Element*                 aDocElement,
366
  nsIFrame* ConstructDocElementFrame(Element*                 aDocElement,
350
                                     nsILayoutHistoryState*   aFrameState);
367
                                     nsILayoutHistoryState*   aFrameState);
351
368
352
  // Set up our mDocElementContainingBlock correctly for the given root
369
  // Set up our mDocElementContainingBlock correctly for the given root
353
  // content.
370
  // content.
 Lines 629-644   private: Link Here 
629
  /* If FCDATA_CREATE_BLOCK_WRAPPER_FOR_ALL_KIDS is set, then create a
646
  /* If FCDATA_CREATE_BLOCK_WRAPPER_FOR_ALL_KIDS is set, then create a
630
     block formatting context wrapper around the kids of this frame
647
     block formatting context wrapper around the kids of this frame
631
     using the FrameConstructionData's mPseudoAtom for its anonymous
648
     using the FrameConstructionData's mPseudoAtom for its anonymous
632
     box type. */
649
     box type. */
633
#define FCDATA_CREATE_BLOCK_WRAPPER_FOR_ALL_KIDS 0x40000
650
#define FCDATA_CREATE_BLOCK_WRAPPER_FOR_ALL_KIDS 0x40000
634
  /* If FCDATA_IS_SVG_TEXT is set, then this text frame is a descendant of
651
  /* If FCDATA_IS_SVG_TEXT is set, then this text frame is a descendant of
635
     an SVG text frame. */
652
     an SVG text frame. */
636
#define FCDATA_IS_SVG_TEXT 0x80000
653
#define FCDATA_IS_SVG_TEXT 0x80000
654
  /**
655
   * display:contents
656
   */
657
#define FCDATA_IS_CONTENTS 0x100000
637
658
638
  /* Structure representing information about how a frame should be
659
  /* Structure representing information about how a frame should be
639
     constructed.  */
660
     constructed.  */
640
  struct FrameConstructionData {
661
  struct FrameConstructionData {
641
    // Flag bits that can modify the way the construction happens
662
    // Flag bits that can modify the way the construction happens
642
    uint32_t mBits;
663
    uint32_t mBits;
643
    // We have exactly one of three types of functions, so use a union for
664
    // We have exactly one of three types of functions, so use a union for
644
    // better cache locality for the ones that aren't pointer-to-member.  That
665
    // better cache locality for the ones that aren't pointer-to-member.  That
 Lines 1798-1813   private: Link Here 
1798
  // insertion points.
1819
  // insertion points.
1799
  nsIFrame* GetInsertionPrevSibling(InsertionPoint* aInsertion, // inout
1820
  nsIFrame* GetInsertionPrevSibling(InsertionPoint* aInsertion, // inout
1800
                                    nsIContent* aChild,
1821
                                    nsIContent* aChild,
1801
                                    bool* aIsAppend,
1822
                                    bool* aIsAppend,
1802
                                    bool* aIsRangeInsertSafe,
1823
                                    bool* aIsRangeInsertSafe,
1803
                                    nsIContent* aStartSkipChild = nullptr,
1824
                                    nsIContent* aStartSkipChild = nullptr,
1804
                                    nsIContent *aEndSkipChild = nullptr);
1825
                                    nsIContent *aEndSkipChild = nullptr);
1805
1826
1827
  /**
1828
   * Return the insertion frame of the primary frame of aContent, or its nearest
1829
   * ancestor that isn't display:contents.
1830
   */
1831
  nsContainerFrame* GetContentInsertionFrameFor(nsIContent* aContent);
1832
1806
  // see if aContent and aSibling are legitimate siblings due to restrictions
1833
  // see if aContent and aSibling are legitimate siblings due to restrictions
1807
  // imposed by table columns
1834
  // imposed by table columns
1808
  // XXXbz this code is generally wrong, since the frame for aContent
1835
  // XXXbz this code is generally wrong, since the frame for aContent
1809
  // may be constructed based on tag, not based on aDisplay!
1836
  // may be constructed based on tag, not based on aDisplay!
1810
  bool IsValidSibling(nsIFrame*              aSibling,
1837
  bool IsValidSibling(nsIFrame*              aSibling,
1811
                        nsIContent*            aContent,
1838
                        nsIContent*            aContent,
1812
                        uint8_t&               aDisplay);
1839
                        uint8_t&               aDisplay);
1813
1840

Return to bug 907396