Attachment #8392929: 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 2930-2938   RestyleManager::ComputeStyleChangeFor(ns Link Here 
2930
        NS_ASSERTION(!cont->GetPrevContinuation(),
2930
        NS_ASSERTION(!cont->GetPrevContinuation(),
2931
                     "continuing frame had more severe impact than first-in-flow");
2931
                     "continuing frame had more severe impact than first-in-flow");
2932
        return;
2932
        return;
2933
      }
2933
      }
2934
    }
2934
    }
2935
  }
2935
  }
2936
}
2936
}
2937
2937
2938
AutoDisplayContentsAncestorPusher::AutoDisplayContentsAncestorPusher(
2939
  TreeMatchContext& aTreeMatchContext, nsPresContext* aPresContext,
2940
  nsIContent* aParent)
2941
  : mTreeMatchContext(aTreeMatchContext)
2942
  , mPresContext(aPresContext)
2943
{
2944
  if (aParent && mTreeMatchContext.mAncestorFilter.HasFilter()) {
2945
    nsFrameManager* fm = mPresContext->FrameManager();
2946
    // Push display:contents mAncestors onto mTreeMatchContext.
2947
    for (nsIContent* p = aParent; p && fm->GetDisplayContents(p);
2948
         p = p->GetParent()) {
2949
      mAncestors.AppendElement(p->AsElement());
2950
    }
2951
    nsTArray<mozilla::dom::Element*>::size_type i = mAncestors.Length();
2952
    while (i--) {
2953
      mTreeMatchContext.mAncestorFilter.PushAncestor(mAncestors[i]);
2954
      mTreeMatchContext.PushStyleScope(mAncestors[i]);
2955
    }
2956
  }
2957
2958
}
2959
2960
AutoDisplayContentsAncestorPusher::~AutoDisplayContentsAncestorPusher()
2961
{
2962
  // Pop the ancestors we pushed in the CTOR, if any.
2963
  nsTArray<mozilla::dom::Element*>::size_type i = mAncestors.Length();
2964
  while (i--) {
2965
    mTreeMatchContext.mAncestorFilter.PopAncestor();
2966
    mTreeMatchContext.PopStyleScope(mAncestors[i]);
2967
  }
2968
}
2969
2938
} // namespace mozilla
2970
} // namespace mozilla
(-)a/layout/base/RestyleManager.h (-2 / +22 lines)
Line     Link Here 
 Lines 21-37   class nsIFrame; Link Here 
21
struct TreeMatchContext;
21
struct TreeMatchContext;
22
22
23
namespace mozilla {
23
namespace mozilla {
24
24
25
namespace dom {
25
namespace dom {
26
  class Element;
26
  class Element;
27
} // namespace dom
27
} // namespace dom
28
28
29
class RestyleManager MOZ_FINAL {
29
class RestyleManager MOZ_FINAL
30
{
30
public:
31
public:
31
  friend class ::nsRefreshDriver;
32
  friend class ::nsRefreshDriver;
32
  friend class RestyleTracker;
33
  friend class RestyleTracker;
33
34
34
  typedef mozilla::dom::Element Element;
35
  typedef mozilla::dom::Element Element;
35
36
36
  RestyleManager(nsPresContext* aPresContext);
37
  RestyleManager(nsPresContext* aPresContext);
37
38
 Lines 261-277   private: Link Here 
261
  RestyleTracker mPendingRestyles;
262
  RestyleTracker mPendingRestyles;
262
  RestyleTracker mPendingAnimationRestyles;
263
  RestyleTracker mPendingAnimationRestyles;
263
};
264
};
264
265
265
/**
266
/**
266
 * An ElementRestyler is created for *each* element in a subtree that we
267
 * An ElementRestyler is created for *each* element in a subtree that we
267
 * recompute styles for.
268
 * recompute styles for.
268
 */
269
 */
269
class ElementRestyler MOZ_FINAL {
270
class ElementRestyler MOZ_FINAL
271
{
270
public:
272
public:
271
  typedef mozilla::dom::Element Element;
273
  typedef mozilla::dom::Element Element;
272
274
273
  // Construct for the root of the subtree that we're restyling.
275
  // Construct for the root of the subtree that we're restyling.
274
  ElementRestyler(nsPresContext* aPresContext,
276
  ElementRestyler(nsPresContext* aPresContext,
275
                  nsIFrame* aFrame,
277
                  nsIFrame* aFrame,
276
                  nsStyleChangeList* aChangeList,
278
                  nsStyleChangeList* aChangeList,
277
                  nsChangeHint aHintsHandledByAncestors,
279
                  nsChangeHint aHintsHandledByAncestors,
 Lines 387-397   private: Link Here 
387
  const DesiredA11yNotifications mDesiredA11yNotifications;
389
  const DesiredA11yNotifications mDesiredA11yNotifications;
388
  DesiredA11yNotifications mKidsDesiredA11yNotifications;
390
  DesiredA11yNotifications mKidsDesiredA11yNotifications;
389
  A11yNotificationType mOurA11yNotification;
391
  A11yNotificationType mOurA11yNotification;
390
  nsTArray<nsIContent*>& mVisibleKidsOfHiddenElement;
392
  nsTArray<nsIContent*>& mVisibleKidsOfHiddenElement;
391
  bool mWasFrameVisible;
393
  bool mWasFrameVisible;
392
#endif
394
#endif
393
};
395
};
394
396
397
/**
398
 * This pushes any display:contents nodes onto a TreeMatchContext.
399
 */
400
class MOZ_STACK_CLASS AutoDisplayContentsAncestorPusher MOZ_FINAL
401
{
402
 public:
403
  typedef mozilla::dom::Element Element;
404
  AutoDisplayContentsAncestorPusher(TreeMatchContext& aTreeMatchContext,
405
                                    nsPresContext*    aPresContext,
406
                                    nsIContent*       aParent);
407
  ~AutoDisplayContentsAncestorPusher();
408
  bool IsEmpty() const { return mAncestors.Length() == 0; }
409
private:
410
  TreeMatchContext& mTreeMatchContext;
411
  nsPresContext* const mPresContext;
412
  nsAutoTArray<mozilla::dom::Element*, 4> mAncestors;
413
};
414
395
} // namespace mozilla
415
} // namespace mozilla
396
416
397
#endif /* mozilla_RestyleManager_h */
417
#endif /* mozilla_RestyleManager_h */
(-)a/layout/base/RestyleTracker.cpp (-1 / +3 lines)
Line     Link Here 
 Lines 71-87   CollectRestyles(nsISupports* aElement, Link Here 
71
      !element->HasFlag(collector->tracker->RestyleBit())) {
71
      !element->HasFlag(collector->tracker->RestyleBit())) {
72
    return PL_DHASH_NEXT;
72
    return PL_DHASH_NEXT;
73
  }
73
  }
74
74
75
  NS_ASSERTION(!element->HasFlag(collector->tracker->RootBit()) ||
75
  NS_ASSERTION(!element->HasFlag(collector->tracker->RootBit()) ||
76
               // Maybe we're just not reachable via the frame tree?
76
               // Maybe we're just not reachable via the frame tree?
77
               (element->GetFlattenedTreeParent() &&
77
               (element->GetFlattenedTreeParent() &&
78
                (!element->GetFlattenedTreeParent()->GetPrimaryFrame()||
78
                (!element->GetFlattenedTreeParent()->GetPrimaryFrame()||
79
                 element->GetFlattenedTreeParent()->GetPrimaryFrame()->IsLeaf())) ||
79
                 element->GetFlattenedTreeParent()->GetPrimaryFrame()->IsLeaf()||
80
                 element->GetCurrentDoc()->GetShell()->FrameManager()
81
                   ->GetDisplayContents(element))) ||
80
               // Or not reachable due to an async reinsert we have
82
               // Or not reachable due to an async reinsert we have
81
               // pending?  If so, we'll have a reframe hint around.
83
               // pending?  If so, we'll have a reframe hint around.
82
               // That incidentally makes it safe that we still have
84
               // That incidentally makes it safe that we still have
83
               // the bit, since any descendants that didn't get added
85
               // the bit, since any descendants that didn't get added
84
               // to the roots list because we had the bits will be
86
               // to the roots list because we had the bits will be
85
               // completely restyled in a moment.
87
               // completely restyled in a moment.
86
               (aData.mChangeHint & nsChangeHint_ReconstructFrame),
88
               (aData.mChangeHint & nsChangeHint_ReconstructFrame),
87
               "Why did this not get handled while processing mRestyleRoots?");
89
               "Why did this not get handled while processing mRestyleRoots?");
(-)a/layout/base/nsCSSFrameConstructor.cpp (-67 / +195 lines)
Line     Link Here 
 Lines 3568-3596   nsCSSFrameConstructor::ConstructFrameFro Link Here 
3568
3568
3569
  // Don't create a subdocument frame for iframes if we're creating extra frames
3569
  // Don't create a subdocument frame for iframes if we're creating extra frames
3570
  if (aState.mCreatingExtraFrames && aItem.mContent->IsHTML() &&
3570
  if (aState.mCreatingExtraFrames && aItem.mContent->IsHTML() &&
3571
      aItem.mContent->Tag() == nsGkAtoms::iframe)
3571
      aItem.mContent->Tag() == nsGkAtoms::iframe)
3572
  {
3572
  {
3573
    return;
3573
    return;
3574
  }
3574
  }
3575
3575
3576
  nsStyleContext* const styleContext = aItem.mStyleContext;
3577
  const nsStyleDisplay* display = styleContext->StyleDisplay();
3578
  nsIContent* const content = aItem.mContent;
3576
  nsIContent* const content = aItem.mContent;
3577
  nsIContent* parent = content->GetParent();
3578
3579
  // Push display:contents ancestors.
3580
  AutoDisplayContentsAncestorPusher adcp(aState.mTreeMatchContext,
3581
                                         aState.mPresContext,
3582
                                         parent);
3579
3583
3580
  // Get the parent of the content and check if it is a XBL children element.
3584
  // Get the parent of the content and check if it is a XBL children element.
3581
  // Push the children element as an ancestor here because it does
3585
  // Push the children element as an ancestor here because it does
3582
  // not have a frame and would not otherwise be pushed as an ancestor. It is
3586
  // not have a frame and would not otherwise be pushed as an ancestor. It is
3583
  // necessary to do so in order to correctly handle style resolution on
3587
  // necessary to do so in order to correctly handle style resolution on
3584
  // descendants.
3588
  // descendants.
3585
  nsIContent* parent = content->GetParent();
3586
  TreeMatchContext::AutoAncestorPusher
3589
  TreeMatchContext::AutoAncestorPusher
3587
    insertionPointPusher(aState.mTreeMatchContext);
3590
    insertionPointPusher(aState.mTreeMatchContext);
3588
  if (parent && nsContentUtils::IsContentInsertionPoint(parent)) {
3591
  if (adcp.IsEmpty() && parent && nsContentUtils::IsContentInsertionPoint(parent)) {
3589
    if (aState.mTreeMatchContext.mAncestorFilter.HasFilter()) {
3592
    if (aState.mTreeMatchContext.mAncestorFilter.HasFilter()) {
3590
      insertionPointPusher.PushAncestorAndStyleScope(parent);
3593
      insertionPointPusher.PushAncestorAndStyleScope(parent);
3591
    } else {
3594
    } else {
3592
      insertionPointPusher.PushStyleScope(parent);
3595
      insertionPointPusher.PushStyleScope(parent);
3593
    }
3596
    }
3594
  }
3597
  }
3595
3598
3596
  // Push the content as a style ancestor now, so we don't have to do
3599
  // Push the content as a style ancestor now, so we don't have to do
 Lines 3606-3621   nsCSSFrameConstructor::ConstructFrameFro Link Here 
3606
  if (aState.mTreeMatchContext.mAncestorFilter.HasFilter()) {
3609
  if (aState.mTreeMatchContext.mAncestorFilter.HasFilter()) {
3607
    ancestorPusher.PushAncestorAndStyleScope(content);
3610
    ancestorPusher.PushAncestorAndStyleScope(content);
3608
  } else {
3611
  } else {
3609
    ancestorPusher.PushStyleScope(content);
3612
    ancestorPusher.PushStyleScope(content);
3610
  }
3613
  }
3611
3614
3612
  nsIFrame* newFrame;
3615
  nsIFrame* newFrame;
3613
  nsIFrame* primaryFrame;
3616
  nsIFrame* primaryFrame;
3617
  nsStyleContext* const styleContext = aItem.mStyleContext;
3618
  const nsStyleDisplay* display = styleContext->StyleDisplay();
3614
  if (bits & FCDATA_FUNC_IS_FULL_CTOR) {
3619
  if (bits & FCDATA_FUNC_IS_FULL_CTOR) {
3615
    newFrame =
3620
    newFrame =
3616
      (this->*(data->mFullConstructor))(aState, aItem, aParentFrame,
3621
      (this->*(data->mFullConstructor))(aState, aItem, aParentFrame,
3617
                                        display, aFrameItems);
3622
                                        display, aFrameItems);
3618
    MOZ_ASSERT(newFrame, "Full constructor failed");
3623
    MOZ_ASSERT(newFrame, "Full constructor failed");
3619
    primaryFrame = newFrame;
3624
    primaryFrame = newFrame;
3620
  } else {
3625
  } else {
3621
    newFrame =
3626
    newFrame =
 Lines 4457-4473   nsCSSFrameConstructor::FindDisplayData(c Link Here 
4457
                       &nsCSSFrameConstructor::ConstructTableCol) },
4462
                       &nsCSSFrameConstructor::ConstructTableCol) },
4458
    { NS_STYLE_DISPLAY_TABLE_ROW,
4463
    { NS_STYLE_DISPLAY_TABLE_ROW,
4459
      FULL_CTOR_FCDATA(FCDATA_IS_TABLE_PART |
4464
      FULL_CTOR_FCDATA(FCDATA_IS_TABLE_PART |
4460
                       FCDATA_DESIRED_PARENT_TYPE_TO_BITS(eTypeRowGroup),
4465
                       FCDATA_DESIRED_PARENT_TYPE_TO_BITS(eTypeRowGroup),
4461
                       &nsCSSFrameConstructor::ConstructTableRowOrRowGroup) },
4466
                       &nsCSSFrameConstructor::ConstructTableRowOrRowGroup) },
4462
    { NS_STYLE_DISPLAY_TABLE_CELL,
4467
    { NS_STYLE_DISPLAY_TABLE_CELL,
4463
      FULL_CTOR_FCDATA(FCDATA_IS_TABLE_PART |
4468
      FULL_CTOR_FCDATA(FCDATA_IS_TABLE_PART |
4464
                       FCDATA_DESIRED_PARENT_TYPE_TO_BITS(eTypeRow),
4469
                       FCDATA_DESIRED_PARENT_TYPE_TO_BITS(eTypeRow),
4465
                       &nsCSSFrameConstructor::ConstructTableCell) }
4470
                       &nsCSSFrameConstructor::ConstructTableCell) },
4471
    { NS_STYLE_DISPLAY_CONTENTS,
4472
      FULL_CTOR_FCDATA(FCDATA_IS_CONTENTS, nullptr/*never called*/) }
4466
  };
4473
  };
4467
4474
4468
  return FindDataByInt(aDisplay->mDisplay,
4475
  return FindDataByInt(aDisplay->mDisplay,
4469
                       aElement, aStyleContext, sDisplayData,
4476
                       aElement, aStyleContext, sDisplayData,
4470
                       ArrayLength(sDisplayData));
4477
                       ArrayLength(sDisplayData));
4471
}
4478
}
4472
4479
4473
nsIFrame*
4480
nsIFrame*
 Lines 4576-4606   nsCSSFrameConstructor::InitAndRestoreFra Link Here 
4576
  }
4583
  }
4577
}
4584
}
4578
4585
4579
already_AddRefed<nsStyleContext>
4586
already_AddRefed<nsStyleContext>
4580
nsCSSFrameConstructor::ResolveStyleContext(nsIFrame*         aParentFrame,
4587
nsCSSFrameConstructor::ResolveStyleContext(nsIFrame*         aParentFrame,
4581
                                           nsIContent*       aContent,
4588
                                           nsIContent*       aContent,
4582
                                           nsFrameConstructorState* aState)
4589
                                           nsFrameConstructorState* aState)
4583
{
4590
{
4584
  nsStyleContext* parentStyleContext = nullptr;
4591
  nsIContent* container = aContent->GetParent();
4585
  NS_ASSERTION(aContent->GetParent(), "Must have parent here");
4592
  NS_ASSERTION(container, "Must have parent here");
4586
4593
  nsStyleContext* parentStyleContext = GetDisplayContents(container);
4587
  aParentFrame = nsFrame::CorrectStyleParentFrame(aParentFrame, nullptr);
4594
  if (MOZ_LIKELY(!parentStyleContext)) {
4588
4595
    aParentFrame = nsFrame::CorrectStyleParentFrame(aParentFrame, nullptr);
4589
  if (aParentFrame) {
4596
    if (aParentFrame) {
4590
    // Resolve the style context based on the content object and the parent
4597
      // Resolve the style context based on the content object and the parent
4591
    // style context
4598
      // style context
4592
    parentStyleContext = aParentFrame->StyleContext();
4599
      parentStyleContext = aParentFrame->StyleContext();
4593
  } else {
4600
    } else {
4594
    // Perhaps aParentFrame is a canvasFrame and we're replicating
4601
      // Perhaps aParentFrame is a canvasFrame and we're replicating
4595
    // fixed-pos frames.
4602
      // fixed-pos frames.
4596
    // XXX should we create a way to tell ConstructFrame which style
4603
      // XXX should we create a way to tell ConstructFrame which style
4597
    // context to use, and pass it the style context for the
4604
      // context to use, and pass it the style context for the
4598
    // previous page's fixed-pos frame?
4605
      // previous page's fixed-pos frame?
4606
    }
4599
  }
4607
  }
4600
4608
4601
  return ResolveStyleContext(parentStyleContext, aContent, aState);
4609
  return ResolveStyleContext(parentStyleContext, aContent, aState);
4602
}
4610
}
4603
4611
4604
already_AddRefed<nsStyleContext>
4612
already_AddRefed<nsStyleContext>
4605
nsCSSFrameConstructor::ResolveStyleContext(nsStyleContext* aParentStyleContext,
4613
nsCSSFrameConstructor::ResolveStyleContext(nsStyleContext* aParentStyleContext,
4606
                                           nsIContent* aContent,
4614
                                           nsIContent* aContent,
 Lines 5359-5374   nsCSSFrameConstructor::AddFrameConstruct Link Here 
5359
    !display->IsAbsolutelyPositionedStyle() &&
5367
    !display->IsAbsolutelyPositionedStyle() &&
5360
    !(bits & FCDATA_IS_TABLE_PART) &&
5368
    !(bits & FCDATA_IS_TABLE_PART) &&
5361
    !(bits & FCDATA_IS_SVG_TEXT);
5369
    !(bits & FCDATA_IS_SVG_TEXT);
5362
5370
5363
  if (canHavePageBreak && display->mBreakBefore) {
5371
  if (canHavePageBreak && display->mBreakBefore) {
5364
    AddPageBreakItem(aContent, aStyleContext, aItems);
5372
    AddPageBreakItem(aContent, aStyleContext, aItems);
5365
  }
5373
  }
5366
5374
5375
  if (MOZ_UNLIKELY(bits & FCDATA_IS_CONTENTS)) {
5376
    if (!GetDisplayContents(aContent)) {
5377
      if (styleContext->GetPseudo()) {
5378
        if (isGeneratedContent) {
5379
          aContent->UnbindFromTree();
5380
        }
5381
      } else {
5382
        MOZ_ASSERT(!isGeneratedContent, "Should have had pseudo type");
5383
        aState.mFrameManager->SetDisplayContents(aContent, styleContext);
5384
      }
5385
    } else {
5386
      aState.mFrameManager->ChangeDisplayContents(aContent, styleContext);
5387
    }
5388
5389
    TreeMatchContext::AutoAncestorPusher ancestorPusher(aState.mTreeMatchContext);
5390
    if (aState.mTreeMatchContext.mAncestorFilter.HasFilter()) {
5391
      ancestorPusher.PushAncestorAndStyleScope(aContent->AsElement());
5392
    } else {
5393
      ancestorPusher.PushStyleScope(aContent->AsElement());
5394
    }
5395
5396
    if (aParentFrame) {
5397
      aParentFrame->AddStateBits(NS_FRAME_MAY_HAVE_GENERATED_CONTENT);
5398
    }
5399
    CreateGeneratedContentItem(aState, aParentFrame, aContent, styleContext,
5400
                               nsCSSPseudoElements::ePseudo_before, aItems);
5401
5402
    FlattenedChildIterator iter(aContent);
5403
    for (nsIContent* child = iter.GetNextChild(); child; child = iter.GetNextChild()) {
5404
      nsRefPtr<nsStyleContext> childContext =
5405
        ResolveStyleContext(styleContext, child, nullptr);
5406
      AddFrameConstructionItemsInternal(aState, child, aParentFrame,
5407
                                        child->Tag(), child->GetNameSpaceID(),
5408
                                        aSuppressWhiteSpaceOptimizations,
5409
                                        childContext, aFlags,
5410
                                        aAnonChildren, aItems);
5411
    }
5412
5413
    CreateGeneratedContentItem(aState, aParentFrame, aContent, styleContext,
5414
                               nsCSSPseudoElements::ePseudo_after, aItems);
5415
    if (canHavePageBreak && display->mBreakAfter) {
5416
      AddPageBreakItem(aContent, aStyleContext, aItems);
5417
    }
5418
    return;
5419
  }
5420
5367
  FrameConstructionItem* item =
5421
  FrameConstructionItem* item =
5368
    aItems.AppendItem(data, aContent, aTag, aNameSpaceID,
5422
    aItems.AppendItem(data, aContent, aTag, aNameSpaceID,
5369
                      pendingBinding, styleContext.forget(),
5423
                      pendingBinding, styleContext.forget(),
5370
                      aSuppressWhiteSpaceOptimizations, aAnonChildren);
5424
                      aSuppressWhiteSpaceOptimizations, aAnonChildren);
5371
  if (!item) {
5425
  if (!item) {
5372
    if (isGeneratedContent) {
5426
    if (isGeneratedContent) {
5373
      aContent->UnbindFromTree();
5427
      aContent->UnbindFromTree();
5374
    }
5428
    }
 Lines 5622-5650   nsCSSFrameConstructor::ReconstructDocEle Link Here 
5622
  if (!rootElement) {
5676
  if (!rootElement) {
5623
    /* nothing to do */
5677
    /* nothing to do */
5624
    return NS_OK;
5678
    return NS_OK;
5625
  }
5679
  }
5626
  return RecreateFramesForContent(rootElement, false);
5680
  return RecreateFramesForContent(rootElement, false);
5627
}
5681
}
5628
5682
5629
nsIFrame*
5683
nsIFrame*
5630
nsCSSFrameConstructor::GetFrameFor(nsIContent* aContent)
5684
nsCSSFrameConstructor::GetInsertionFrameFor(nsIContent* aContent)
5631
{
5685
{
5632
  // Get the primary frame associated with the content
5686
  // Get the primary frame associated with the content
5633
  nsIFrame* frame = aContent->GetPrimaryFrame();
5687
  nsIFrame* frame = aContent->GetPrimaryFrame();
5634
5688
5635
  if (!frame)
5689
  if (!frame) {
5636
    return nullptr;
5690
    if (GetDisplayContents(aContent)) {
5637
5691
      nsIContent* parent = aContent->GetParent();
5638
  // If the content of the frame is not the desired content then this is not
5692
      frame = parent ? GetInsertionFrameFor(parent) : nullptr;
5639
  // really a frame for the desired content.
5693
    }
5640
  // XXX This check is needed due to bug 135040. Remove it once that's fixed.
5694
    if (!frame) {
5641
  if (frame->GetContent() != aContent) {
5695
      return nullptr;
5642
    return nullptr;
5696
    }
5697
  } else {
5698
    // If the content of the frame is not the desired content then this is not
5699
    // really a frame for the desired content.
5700
    // XXX This check is needed due to bug 135040. Remove it once that's fixed.
5701
    if (frame->GetContent() != aContent) {
5702
      return nullptr;
5703
    }
5643
  }
5704
  }
5644
5705
5645
  nsIFrame* insertionFrame = frame->GetContentInsertionFrame();
5706
  nsIFrame* insertionFrame = frame->GetContentInsertionFrame();
5646
5707
5647
  NS_ASSERTION(insertionFrame == frame || !frame->IsLeaf(),
5708
  NS_ASSERTION(insertionFrame == frame || !frame->IsLeaf(),
5648
    "The insertion frame is the primary frame or the primary frame isn't a leaf");
5709
    "The insertion frame is the primary frame or the primary frame isn't a leaf");
5649
5710
5650
  return insertionFrame;
5711
  return insertionFrame;
 Lines 5742-5772   nsCSSFrameConstructor::GetFloatContainin Link Here 
5742
5803
5743
/**
5804
/**
5744
 * This function will check whether aContainer has :after generated content.
5805
 * This function will check whether aContainer has :after generated content.
5745
 * If so, appending to it should actually insert.  The return value is the
5806
 * If so, appending to it should actually insert.  The return value is the
5746
 * parent to use for newly-appended content.  *aAfterFrame points to the :after
5807
 * parent to use for newly-appended content.  *aAfterFrame points to the :after
5747
 * frame before which appended content should go, if there is one.
5808
 * frame before which appended content should go, if there is one.
5748
 */
5809
 */
5749
static nsIFrame*
5810
static nsIFrame*
5750
AdjustAppendParentForAfterContent(nsPresContext* aPresContext,
5811
AdjustAppendParentForAfterContent(nsFrameManager* aFrameManager,
5751
                                  nsIContent* aContainer,
5812
                                  nsIContent* aContainer,
5752
                                  nsIFrame* aParentFrame,
5813
                                  nsIFrame* aParentFrame,
5814
                                  nsIContent* aChild,
5753
                                  nsIFrame** aAfterFrame)
5815
                                  nsIFrame** aAfterFrame)
5754
{
5816
{
5755
  // See if the parent has an :after pseudo-element.  Check for the presence
5817
  // If the parent frame has any pseudo-elements or aContainer is a
5756
  // of style first, since nsLayoutUtils::GetAfterFrame is sorta expensive.
5818
  // display:contents node then we need to walk through the child
5757
  nsStyleContext* parentStyle = aParentFrame->StyleContext();
5819
  // frames to find the first one that is either a ::after frame for an
5758
  if (nsLayoutUtils::HasPseudoStyle(aContainer, parentStyle,
5820
  // ancestor of aChild or a frame that is for a node later in the
5821
  // document than aChild and return that in aAfterFrame.
5822
  if (nsLayoutUtils::HasPseudoStyle(aContainer, aParentFrame->StyleContext(),
5759
                                    nsCSSPseudoElements::ePseudo_after,
5823
                                    nsCSSPseudoElements::ePseudo_after,
5760
                                    aPresContext)) {
5824
                                    aParentFrame->PresContext()) ||
5761
    // Ensure that the :after frame is on the principal child list.
5825
      GetGenConPseudos(aParentFrame) ||
5762
    aParentFrame->DrainSelfOverflowList();
5826
      aFrameManager->GetDisplayContents(aContainer)) {
5763
5827
    nsIFrame* afterFrame = nullptr;
5764
    nsIFrame* afterFrame = nsLayoutUtils::GetAfterFrame(aParentFrame);
5828
    nsIFrame* parent = aParentFrame->LastContinuation();
5829
    bool done = false;
5830
    while (!done && parent) {
5831
      // Ensure that all normal flow children are on the principal child list.
5832
      parent->DrainSelfOverflowList();
5833
5834
      nsIFrame* child = parent->GetLastChild(nsIFrame::kPrincipalList);
5835
      if (child && child->IsPseudoFrame(aContainer) &&
5836
          !child->IsGeneratedContentFrame()) {
5837
        // Drill down into non-generated pseudo frames of aContainer.
5838
        parent = nsLayoutUtils::LastContinuationWithChild(child);
5839
        continue;
5840
      }
5841
5842
      for (; child; child = child->GetPrevSibling()) {
5843
        nsIContent* c = child->GetContent();
5844
        if (child->IsGeneratedContentFrame()) {
5845
          nsIContent* p = c->GetParent();
5846
          if (c->Tag() == nsGkAtoms::mozgeneratedcontentafter) {
5847
            if (!nsContentUtils::ContentIsDescendantOf(aChild, p) &&
5848
                (!c->IsInAnonymousSubtree() || c->GetBindingParent() != aContainer) &&
5849
                nsContentUtils::PositionIsBefore(p, aChild)) {
5850
              // ::after generated content for content earlier in the doc and not
5851
              // for an ancestor.
5852
              done = true;
5853
              break;
5854
            }
5855
          } else if (nsContentUtils::PositionIsBefore(p, aChild)) {
5856
            // Non-::after generated content for content earlier in the doc.
5857
            done = true;
5858
            break;
5859
          }
5860
        } else if (nsContentUtils::PositionIsBefore(c, aChild)) {
5861
          // Content is before aChild.
5862
          done = true;
5863
          break;
5864
        }
5865
        afterFrame = child;
5866
      }
5867
5868
      parent = parent->GetPrevContinuation();
5869
    }
5765
    if (afterFrame) {
5870
    if (afterFrame) {
5766
      *aAfterFrame = afterFrame;
5871
      *aAfterFrame = afterFrame;
5767
      return afterFrame->GetParent();
5872
      return afterFrame->GetParent();
5768
    }
5873
    }
5769
  }
5874
  }
5770
5875
5771
  *aAfterFrame = nullptr;
5876
  *aAfterFrame = nullptr;
5772
5877
 Lines 6132-6148   nsCSSFrameConstructor::GetInsertionPrevS Link Here 
6132
  *aIsAppend = false;
6237
  *aIsAppend = false;
6133
6238
6134
  // Find the frame that precedes the insertion point. Walk backwards
6239
  // Find the frame that precedes the insertion point. Walk backwards
6135
  // from the parent frame to get the parent content, because if an
6240
  // from the parent frame to get the parent content, because if an
6136
  // XBL insertion point is involved, we'll need to use _that_ to find
6241
  // XBL insertion point is involved, we'll need to use _that_ to find
6137
  // the preceding frame.
6242
  // the preceding frame.
6138
6243
6139
  NS_PRECONDITION(aParentFrame, "Must have parent frame to start with");
6244
  NS_PRECONDITION(aParentFrame, "Must have parent frame to start with");
6140
  nsIContent* container = aParentFrame->GetContent();
6245
  const bool boxContents = GetDisplayContents(aContainer);
6246
  nsIContent* container = boxContents ? aContainer : aParentFrame->GetContent();
6141
6247
6142
  FlattenedChildIterator iter(container);
6248
  FlattenedChildIterator iter(container);
6143
  bool xblCase = iter.XBLInvolved() || container != aContainer;
6249
  bool xblCase = iter.XBLInvolved() || container != aContainer;
6144
  if (xblCase || !aChild->IsRootOfAnonymousSubtree()) {
6250
  if (xblCase || !aChild->IsRootOfAnonymousSubtree()) {
6145
    // The check for IsRootOfAnonymousSubtree() is because editor is
6251
    // The check for IsRootOfAnonymousSubtree() is because editor is
6146
    // severely broken and calls us directly for native anonymous
6252
    // severely broken and calls us directly for native anonymous
6147
    // nodes that it creates.
6253
    // nodes that it creates.
6148
    if (aStartSkipChild) {
6254
    if (aStartSkipChild) {
 Lines 6162-6190   nsCSSFrameConstructor::GetInsertionPrevS Link Here 
6162
  uint8_t childDisplay = UNSET_DISPLAY;
6268
  uint8_t childDisplay = UNSET_DISPLAY;
6163
  nsIFrame* prevSibling = FindPreviousSibling(iter, childDisplay);
6269
  nsIFrame* prevSibling = FindPreviousSibling(iter, childDisplay);
6164
6270
6165
  // Now, find the geometric parent so that we can handle
6271
  // Now, find the geometric parent so that we can handle
6166
  // continuations properly. Use the prev sibling if we have it;
6272
  // continuations properly. Use the prev sibling if we have it;
6167
  // otherwise use the next sibling.
6273
  // otherwise use the next sibling.
6168
  if (prevSibling) {
6274
  if (prevSibling) {
6169
    aParentFrame = prevSibling->GetParent()->GetContentInsertionFrame();
6275
    aParentFrame = prevSibling->GetParent()->GetContentInsertionFrame();
6170
  }
6276
  } else {
6171
  else {
6172
    // If there is no previous sibling, then find the frame that follows
6277
    // If there is no previous sibling, then find the frame that follows
6173
    if (aEndSkipChild) {
6278
    if (aEndSkipChild) {
6174
      iter.Seek(aEndSkipChild);
6279
      iter.Seek(aEndSkipChild);
6175
      iter.GetPreviousChild();
6280
      iter.GetPreviousChild();
6176
    }
6281
    }
6177
    nsIFrame* nextSibling = FindNextSibling(iter, childDisplay);
6282
    nsIFrame* nextSibling = FindNextSibling(iter, childDisplay);
6178
6283
    if (boxContents) {
6284
      if (nextSibling) {
6285
        aParentFrame = nextSibling->GetParent()->GetContentInsertionFrame();
6286
        return nextSibling->GetPrevSibling();
6287
      }
6288
      return GetInsertionPrevSibling(aParentFrame, aContainer->GetParent(),
6289
                                     aContainer, aIsAppend,
6290
                                     aIsRangeInsertSafe, nullptr, nullptr);
6291
    }
6179
    if (nextSibling) {
6292
    if (nextSibling) {
6180
      aParentFrame = nextSibling->GetParent()->GetContentInsertionFrame();
6293
      aParentFrame = nextSibling->GetParent()->GetContentInsertionFrame();
6181
    }
6294
    } else {
6182
    else {
6183
      // No previous or next sibling, so treat this like an appended frame.
6295
      // No previous or next sibling, so treat this like an appended frame.
6184
      *aIsAppend = true;
6296
      *aIsAppend = true;
6185
      if (IsFramePartOfIBSplit(aParentFrame)) {
6297
      if (IsFramePartOfIBSplit(aParentFrame)) {
6186
        // Since we're appending, we'll walk to the last anonymous frame
6298
        // Since we're appending, we'll walk to the last anonymous frame
6187
        // that was created for the broken inline frame.  But don't walk
6299
        // that was created for the broken inline frame.  But don't walk
6188
        // to the trailing inline if it's empty; stop at the block.
6300
        // to the trailing inline if it's empty; stop at the block.
6189
        aParentFrame = GetLastIBSplitSibling(aParentFrame, false);
6301
        aParentFrame = GetLastIBSplitSibling(aParentFrame, false);
6190
      }
6302
      }
 Lines 6192-6210   nsCSSFrameConstructor::GetInsertionPrevS Link Here 
6192
      // before the AdjustAppendParentForAfterContent call.
6304
      // before the AdjustAppendParentForAfterContent call.
6193
      aParentFrame = nsLayoutUtils::LastContinuationWithChild(aParentFrame);
6305
      aParentFrame = nsLayoutUtils::LastContinuationWithChild(aParentFrame);
6194
      // Deal with fieldsets
6306
      // Deal with fieldsets
6195
      aParentFrame = ::GetAdjustedParentFrame(aParentFrame,
6307
      aParentFrame = ::GetAdjustedParentFrame(aParentFrame,
6196
                                              aParentFrame->GetType(),
6308
                                              aParentFrame->GetType(),
6197
                                              aChild);
6309
                                              aChild);
6198
      nsIFrame* appendAfterFrame;
6310
      nsIFrame* appendAfterFrame;
6199
      aParentFrame =
6311
      aParentFrame =
6200
        ::AdjustAppendParentForAfterContent(mPresShell->GetPresContext(),
6312
        ::AdjustAppendParentForAfterContent(this, container, aParentFrame,
6201
                                            container, aParentFrame,
6313
                                            aChild, &appendAfterFrame);
6202
                                            &appendAfterFrame);
6203
      prevSibling = ::FindAppendPrevSibling(aParentFrame, appendAfterFrame);
6314
      prevSibling = ::FindAppendPrevSibling(aParentFrame, appendAfterFrame);
6204
    }
6315
    }
6205
  }
6316
  }
6206
6317
6207
  *aIsRangeInsertSafe = (childDisplay == UNSET_DISPLAY);
6318
  *aIsRangeInsertSafe = (childDisplay == UNSET_DISPLAY);
6208
  return prevSibling;
6319
  return prevSibling;
6209
}
6320
}
6210
6321
 Lines 6339-6354   nsCSSFrameConstructor::MaybeConstructLaz Link Here 
6339
    }
6450
    }
6340
    if (!noPrimaryFrame && !content->GetPrimaryFrame()) {
6451
    if (!noPrimaryFrame && !content->GetPrimaryFrame()) {
6341
      noPrimaryFrame = true;
6452
      noPrimaryFrame = true;
6342
    }
6453
    }
6343
    if (!needsFrameBitSet && content->HasFlag(NODE_NEEDS_FRAME)) {
6454
    if (!needsFrameBitSet && content->HasFlag(NODE_NEEDS_FRAME)) {
6344
      needsFrameBitSet = true;
6455
      needsFrameBitSet = true;
6345
    }
6456
    }
6346
#endif
6457
#endif
6458
    // XXXmats no lazy frames for display:contents descendants yet (bug 979782).
6459
    if (GetDisplayContents(content)) {
6460
      return false;
6461
    }
6347
    content->SetFlags(NODE_DESCENDANTS_NEED_FRAMES);
6462
    content->SetFlags(NODE_DESCENDANTS_NEED_FRAMES);
6348
    content = content->GetFlattenedTreeParent();
6463
    content = content->GetFlattenedTreeParent();
6349
  }
6464
  }
6350
#ifdef DEBUG
6465
#ifdef DEBUG
6351
  if (content && content->GetPrimaryFrame() &&
6466
  if (content && content->GetPrimaryFrame() &&
6352
      content->GetPrimaryFrame()->IsLeaf()) {
6467
      content->GetPrimaryFrame()->IsLeaf()) {
6353
    noPrimaryFrame = needsFrameBitSet = false;
6468
    noPrimaryFrame = needsFrameBitSet = false;
6354
  }
6469
  }
 Lines 6461-6478   void Link Here 
6461
nsCSSFrameConstructor::IssueSingleInsertNofications(nsIContent* aContainer,
6576
nsCSSFrameConstructor::IssueSingleInsertNofications(nsIContent* aContainer,
6462
                                                    nsIContent* aStartChild,
6577
                                                    nsIContent* aStartChild,
6463
                                                    nsIContent* aEndChild,
6578
                                                    nsIContent* aEndChild,
6464
                                                    bool aAllowLazyConstruction)
6579
                                                    bool aAllowLazyConstruction)
6465
{
6580
{
6466
  for (nsIContent* child = aStartChild;
6581
  for (nsIContent* child = aStartChild;
6467
       child != aEndChild;
6582
       child != aEndChild;
6468
       child = child->GetNextSibling()) {
6583
       child = child->GetNextSibling()) {
6469
    if ((child->GetPrimaryFrame() ||
6584
    if ((child->GetPrimaryFrame() || GetUndisplayedContent(child) ||
6470
         GetUndisplayedContent(child))
6585
         GetDisplayContents(child))
6471
#ifdef MOZ_XUL
6586
#ifdef MOZ_XUL
6472
        //  Except listboxes suck, so do NOT skip anything here if
6587
        //  Except listboxes suck, so do NOT skip anything here if
6473
        //  we plan to notify a listbox.
6588
        //  we plan to notify a listbox.
6474
        && !MaybeGetListBoxBodyFrame(aContainer, child)
6589
        && !MaybeGetListBoxBodyFrame(aContainer, child)
6475
#endif
6590
#endif
6476
        ) {
6591
        ) {
6477
      // Already have a frame or undisplayed entry for this content; a
6592
      // Already have a frame or undisplayed entry for this content; a
6478
      // previous ContentInserted in this loop must have reconstructed
6593
      // previous ContentInserted in this loop must have reconstructed
 Lines 6621-6637   nsCSSFrameConstructor::ContentAppended(n Link Here 
6621
    nsIContent* bindingParent = aContainer->GetBindingParent();
6736
    nsIContent* bindingParent = aContainer->GetBindingParent();
6622
    LAYOUT_PHASE_TEMP_EXIT();
6737
    LAYOUT_PHASE_TEMP_EXIT();
6623
    nsresult rv = RecreateFramesForContent(bindingParent, false);
6738
    nsresult rv = RecreateFramesForContent(bindingParent, false);
6624
    LAYOUT_PHASE_TEMP_REENTER();
6739
    LAYOUT_PHASE_TEMP_REENTER();
6625
    return rv;
6740
    return rv;
6626
  }
6741
  }
6627
6742
6628
  // Get the frame associated with the content
6743
  // Get the frame associated with the content
6629
  nsIFrame* parentFrame = GetFrameFor(aContainer);
6744
  nsIFrame* parentFrame = GetInsertionFrameFor(aContainer);
6630
6745
6631
  // See comment in ContentRangeInserted for why this is necessary.
6746
  // See comment in ContentRangeInserted for why this is necessary.
6632
  if (!parentFrame && !aContainer->IsActiveChildrenElement()) {
6747
  if (!parentFrame && !aContainer->IsActiveChildrenElement()) {
6633
    return NS_OK;
6748
    return NS_OK;
6634
  }
6749
  }
6635
6750
6636
  if (aAllowLazyConstruction &&
6751
  if (aAllowLazyConstruction &&
6637
      MaybeConstructLazily(CONTENTAPPEND, aContainer, aFirstNewContent)) {
6752
      MaybeConstructLazily(CONTENTAPPEND, aContainer, aFirstNewContent)) {
 Lines 6694-6712   nsCSSFrameConstructor::ContentAppended(n Link Here 
6694
  // We should never get here with fieldsets, since they have multiple
6809
  // We should never get here with fieldsets, since they have multiple
6695
  // insertion points.
6810
  // insertion points.
6696
  NS_ASSERTION(parentFrame->GetType() != nsGkAtoms::fieldSetFrame,
6811
  NS_ASSERTION(parentFrame->GetType() != nsGkAtoms::fieldSetFrame,
6697
               "Unexpected parent");
6812
               "Unexpected parent");
6698
6813
6699
  // Deal with possible :after generated content on the parent
6814
  // Deal with possible :after generated content on the parent
6700
  nsIFrame* parentAfterFrame;
6815
  nsIFrame* parentAfterFrame;
6701
  parentFrame =
6816
  parentFrame =
6702
    ::AdjustAppendParentForAfterContent(mPresShell->GetPresContext(),
6817
    ::AdjustAppendParentForAfterContent(this, aContainer, parentFrame,
6703
                                        aContainer, parentFrame,
6818
                                        aFirstNewContent, &parentAfterFrame);
6704
                                        &parentAfterFrame);
6705
  
6819
  
6706
  // Create some new frames
6820
  // Create some new frames
6707
  nsFrameConstructorState state(mPresShell,
6821
  nsFrameConstructorState state(mPresShell,
6708
                                GetAbsoluteContainingBlock(parentFrame, FIXED_POS),
6822
                                GetAbsoluteContainingBlock(parentFrame, FIXED_POS),
6709
                                GetAbsoluteContainingBlock(parentFrame, ABS_POS),
6823
                                GetAbsoluteContainingBlock(parentFrame, ABS_POS),
6710
                                GetFloatContainingBlock(parentFrame));
6824
                                GetFloatContainingBlock(parentFrame));
6711
  state.mTreeMatchContext.InitAncestors(aContainer->AsElement());
6825
  state.mTreeMatchContext.InitAncestors(aContainer->AsElement());
6712
6826
 Lines 7054-7079   nsCSSFrameConstructor::ContentRangeInser Link Here 
7054
    // the children of the host.
7168
    // the children of the host.
7055
    nsIContent* bindingParent = aContainer->GetBindingParent();
7169
    nsIContent* bindingParent = aContainer->GetBindingParent();
7056
    LAYOUT_PHASE_TEMP_EXIT();
7170
    LAYOUT_PHASE_TEMP_EXIT();
7057
    nsresult rv = RecreateFramesForContent(bindingParent, false);
7171
    nsresult rv = RecreateFramesForContent(bindingParent, false);
7058
    LAYOUT_PHASE_TEMP_REENTER();
7172
    LAYOUT_PHASE_TEMP_REENTER();
7059
    return rv;
7173
    return rv;
7060
  }
7174
  }
7061
7175
7062
  nsIFrame* parentFrame = GetFrameFor(aContainer);
7176
  nsIFrame* parentFrame = GetInsertionFrameFor(aContainer);
7063
  // The xbl:children element won't have a frame, but default content can have the children as
7177
  // The xbl:children element won't have a frame, but default content can have the children as
7064
  // a parent. While its uncommon to change the structure of the default content itself, a label,
7178
  // a parent. While its uncommon to change the structure of the default content itself, a label,
7065
  // for example, can be reframed by having its value attribute set or removed.
7179
  // for example, can be reframed by having its value attribute set or removed.
7066
  if (!parentFrame && !aContainer->IsActiveChildrenElement()) {
7180
  if (!parentFrame && !aContainer->IsActiveChildrenElement()) {
7067
    return NS_OK;
7181
    return NS_OK;
7068
  }
7182
  }
7069
7183
7070
  // Otherwise, we've got parent content. Find its frame.
7184
  // Otherwise, we've got parent content. Find its frame.
7071
  NS_ASSERTION(!parentFrame || parentFrame->GetContent() == aContainer, "New XBL code is possibly wrong!");
7185
  NS_ASSERTION(!parentFrame || parentFrame->GetContent() == aContainer ||
7186
               GetDisplayContents(aContainer), "New XBL code is possibly wrong!");
7072
7187
7073
  if (aAllowLazyConstruction &&
7188
  if (aAllowLazyConstruction &&
7074
      MaybeConstructLazily(CONTENTINSERT, aContainer, aStartChild)) {
7189
      MaybeConstructLazily(CONTENTINSERT, aContainer, aStartChild)) {
7075
    return NS_OK;
7190
    return NS_OK;
7076
  }
7191
  }
7077
7192
7078
  if (isSingleInsert) {
7193
  if (isSingleInsert) {
7079
    // See if we have an XBL insertion point. If so, then that's our
7194
    // See if we have an XBL insertion point. If so, then that's our
 Lines 7350-7369   nsCSSFrameConstructor::ContentRangeInser Link Here 
7350
                 frame1->GetType() == nsGkAtoms::fieldSetFrame ||
7465
                 frame1->GetType() == nsGkAtoms::fieldSetFrame ||
7351
                 (frame1->GetParent() &&
7466
                 (frame1->GetParent() &&
7352
                  frame1->GetParent()->GetType() == nsGkAtoms::fieldSetFrame),
7467
                  frame1->GetParent()->GetType() == nsGkAtoms::fieldSetFrame),
7353
                 "Unexpected frame types");
7468
                 "Unexpected frame types");
7354
#endif
7469
#endif
7355
    isAppend = true;
7470
    isAppend = true;
7356
    nsIFrame* appendAfterFrame;
7471
    nsIFrame* appendAfterFrame;
7357
    parentFrame =
7472
    parentFrame =
7358
      ::AdjustAppendParentForAfterContent(mPresShell->GetPresContext(),
7473
      ::AdjustAppendParentForAfterContent(this, container,
7359
                                          container,
7360
                                          frameItems.FirstChild()->GetParent(),
7474
                                          frameItems.FirstChild()->GetParent(),
7361
                                          &appendAfterFrame);
7475
                                          aStartChild, &appendAfterFrame);
7362
    prevSibling = ::FindAppendPrevSibling(parentFrame, appendAfterFrame);
7476
    prevSibling = ::FindAppendPrevSibling(parentFrame, appendAfterFrame);
7363
  }
7477
  }
7364
7478
7365
  if (haveFirstLineStyle && parentFrame == containingBlock) {
7479
  if (haveFirstLineStyle && parentFrame == containingBlock) {
7366
    // It's possible that the new frame goes into a first-line
7480
    // It's possible that the new frame goes into a first-line
7367
    // frame. Look at it and see...
7481
    // frame. Look at it and see...
7368
    if (isAppend) {
7482
    if (isAppend) {
7369
      // Use append logic when appending
7483
      // Use append logic when appending
 Lines 7493-7520   nsCSSFrameConstructor::ContentRemoved(ns Link Here 
7493
           static_cast<void*>(aChild),
7607
           static_cast<void*>(aChild),
7494
           static_cast<void*>(aOldNextSibling));
7608
           static_cast<void*>(aOldNextSibling));
7495
    if (gReallyNoisyContentUpdates) {
7609
    if (gReallyNoisyContentUpdates) {
7496
      aContainer->List(stdout, 0);
7610
      aContainer->List(stdout, 0);
7497
    }
7611
    }
7498
  }
7612
  }
7499
#endif
7613
#endif
7500
7614
7501
  nsPresContext *presContext = mPresShell->GetPresContext();
7615
  nsresult rv = NS_OK;
7502
  nsresult                  rv = NS_OK;
7503
7504
  // Find the child frame that maps the content
7505
  nsIFrame* childFrame = aChild->GetPrimaryFrame();
7616
  nsIFrame* childFrame = aChild->GetPrimaryFrame();
7506
7507
  if (!childFrame || childFrame->GetContent() != aChild) {
7617
  if (!childFrame || childFrame->GetContent() != aChild) {
7508
    // XXXbz the GetContent() != aChild check is needed due to bug 135040.
7618
    // XXXbz the GetContent() != aChild check is needed due to bug 135040.
7509
    // Remove it once that's fixed.
7619
    // Remove it once that's fixed.
7510
    ClearUndisplayedContentIn(aChild, aContainer);
7620
    ClearUndisplayedContentIn(aChild, aContainer);
7511
  }
7621
  }
7512
7622
  MOZ_ASSERT(!childFrame || !GetDisplayContents(aChild),
7623
             "display:contents nodes shouldn't have a frame");
7624
  if (!childFrame && GetDisplayContents(aChild)) {
7625
    FlattenedChildIterator iter(aChild);
7626
    for (nsIContent* c = iter.GetNextChild(); c; c = iter.GetNextChild()) {
7627
      if (c->GetPrimaryFrame() || GetDisplayContents(c)) {
7628
        LAYOUT_PHASE_TEMP_EXIT();
7629
        rv = ContentRemoved(aChild, c, nullptr, aFlags, aDidReconstruct);
7630
        LAYOUT_PHASE_TEMP_REENTER();
7631
        NS_ENSURE_SUCCESS(rv, rv);
7632
        if (*aDidReconstruct) {
7633
          return rv;
7634
        }
7635
      }
7636
    }
7637
    ClearDisplayContentsIn(aChild, aContainer);
7638
  }
7639
7640
  nsPresContext* presContext = mPresShell->GetPresContext();
7513
#ifdef MOZ_XUL
7641
#ifdef MOZ_XUL
7514
  if (NotifyListBoxBody(presContext, aContainer, aChild, aOldNextSibling, 
7642
  if (NotifyListBoxBody(presContext, aContainer, aChild, aOldNextSibling, 
7515
                        mDocument, childFrame, CONTENT_REMOVED))
7643
                        mDocument, childFrame, CONTENT_REMOVED))
7516
    return NS_OK;
7644
    return NS_OK;
7517
7645
7518
#endif // MOZ_XUL
7646
#endif // MOZ_XUL
7519
7647
7520
  // If we're removing the root, then make sure to remove things starting at
7648
  // If we're removing the root, then make sure to remove things starting at
 Lines 8328-8344   nsCSSFrameConstructor::GetInsertionPoint Link Here 
8328
8456
8329
  nsIContent* insertionElement;
8457
  nsIContent* insertionElement;
8330
  if (aChildContent) {
8458
  if (aChildContent) {
8331
    // We've got an explicit insertion child. Check to see if it's
8459
    // We've got an explicit insertion child. Check to see if it's
8332
    // anonymous.
8460
    // anonymous.
8333
    if (aChildContent->GetBindingParent() == aContainer) {
8461
    if (aChildContent->GetBindingParent() == aContainer) {
8334
      // This child content is anonymous. Don't use the insertion
8462
      // This child content is anonymous. Don't use the insertion
8335
      // point, since that's only for the explicit kids.
8463
      // point, since that's only for the explicit kids.
8336
      return GetFrameFor(aContainer);
8464
      return GetInsertionFrameFor(aContainer);
8337
    }
8465
    }
8338
8466
8339
    insertionElement = bindingManager->FindNestedInsertionPoint(aContainer, aChildContent);
8467
    insertionElement = bindingManager->FindNestedInsertionPoint(aContainer, aChildContent);
8340
  }
8468
  }
8341
  else {
8469
  else {
8342
    bool multiple;
8470
    bool multiple;
8343
    insertionElement = bindingManager->FindNestedSingleInsertionPoint(aContainer, &multiple);
8471
    insertionElement = bindingManager->FindNestedSingleInsertionPoint(aContainer, &multiple);
8344
8472
 Lines 8349-8365   nsCSSFrameConstructor::GetInsertionPoint Link Here 
8349
      return nullptr;
8477
      return nullptr;
8350
    }
8478
    }
8351
  }
8479
  }
8352
8480
8353
  if (!insertionElement) {
8481
  if (!insertionElement) {
8354
    insertionElement = aContainer;
8482
    insertionElement = aContainer;
8355
  }
8483
  }
8356
8484
8357
  nsIFrame* insertionPoint = GetFrameFor(insertionElement);
8485
  nsIFrame* insertionPoint = GetInsertionFrameFor(insertionElement);
8358
8486
8359
  // fieldsets have multiple insertion points.  Note that we might
8487
  // fieldsets have multiple insertion points.  Note that we might
8360
  // have to look at insertionElement here...
8488
  // have to look at insertionElement here...
8361
  if (aMultiple && insertionElement->IsHTML(nsGkAtoms::fieldset)) {
8489
  if (aMultiple && insertionElement->IsHTML(nsGkAtoms::fieldset)) {
8362
    *aMultiple = true;
8490
    *aMultiple = true;
8363
  }
8491
  }
8364
8492
8365
  return insertionPoint;
8493
  return insertionPoint;
(-)a/layout/base/nsCSSFrameConstructor.h (-1 / +9 lines)
Line     Link Here 
 Lines 560-575   private: Link Here 
560
  /* If FCDATA_CREATE_BLOCK_WRAPPER_FOR_ALL_KIDS is set, then create a
560
  /* If FCDATA_CREATE_BLOCK_WRAPPER_FOR_ALL_KIDS is set, then create a
561
     block formatting context wrapper around the kids of this frame
561
     block formatting context wrapper around the kids of this frame
562
     using the FrameConstructionData's mPseudoAtom for its anonymous
562
     using the FrameConstructionData's mPseudoAtom for its anonymous
563
     box type. */
563
     box type. */
564
#define FCDATA_CREATE_BLOCK_WRAPPER_FOR_ALL_KIDS 0x40000
564
#define FCDATA_CREATE_BLOCK_WRAPPER_FOR_ALL_KIDS 0x40000
565
  /* If FCDATA_IS_SVG_TEXT is set, then this text frame is a descendant of
565
  /* If FCDATA_IS_SVG_TEXT is set, then this text frame is a descendant of
566
     an SVG text frame. */
566
     an SVG text frame. */
567
#define FCDATA_IS_SVG_TEXT 0x80000
567
#define FCDATA_IS_SVG_TEXT 0x80000
568
  /**
569
   * display:contents
570
   */
571
#define FCDATA_IS_CONTENTS 0x100000
568
572
569
  /* Structure representing information about how a frame should be
573
  /* Structure representing information about how a frame should be
570
     constructed.  */
574
     constructed.  */
571
  struct FrameConstructionData {
575
  struct FrameConstructionData {
572
    // Flag bits that can modify the way the construction happens
576
    // Flag bits that can modify the way the construction happens
573
    uint32_t mBits;
577
    uint32_t mBits;
574
    // We have exactly one of three types of functions, so use a union for
578
    // We have exactly one of three types of functions, so use a union for
575
    // better cache locality for the ones that aren't pointer-to-member.  That
579
    // better cache locality for the ones that aren't pointer-to-member.  That
 Lines 1368-1384   private: Link Here 
1368
                       nsStyleContext*          aStyleContext,
1372
                       nsStyleContext*          aStyleContext,
1369
                       nsIFrame*                aFrame,
1373
                       nsIFrame*                aFrame,
1370
                       const bool               aCanHaveGeneratedContent,
1374
                       const bool               aCanHaveGeneratedContent,
1371
                       nsFrameItems&            aFrameItems,
1375
                       nsFrameItems&            aFrameItems,
1372
                       const bool               aAllowBlockStyles,
1376
                       const bool               aAllowBlockStyles,
1373
                       PendingBinding*          aPendingBinding,
1377
                       PendingBinding*          aPendingBinding,
1374
                       nsIFrame*                aPossiblyLeafFrame = nullptr);
1378
                       nsIFrame*                aPossiblyLeafFrame = nullptr);
1375
1379
1376
  nsIFrame* GetFrameFor(nsIContent* aContent);
1380
  /**
1381
   * Return the insertion frame of the primary frame of aContent, or its nearest
1382
   * ancestor that isn't display:contents.
1383
   */
1384
  nsIFrame* GetInsertionFrameFor(nsIContent* aContent);
1377
1385
1378
  /**
1386
  /**
1379
   * These two functions are used when we start frame creation from a non-root
1387
   * These two functions are used when we start frame creation from a non-root
1380
   * element. They should recreate the same state that we would have
1388
   * element. They should recreate the same state that we would have
1381
   * arrived at if we had built frames from the root frame to aFrame.
1389
   * arrived at if we had built frames from the root frame to aFrame.
1382
   * Therefore, any calls to PushFloatContainingBlock and
1390
   * Therefore, any calls to PushFloatContainingBlock and
1383
   * PushAbsoluteContainingBlock during frame construction should get
1391
   * PushAbsoluteContainingBlock during frame construction should get
1384
   * corresponding logic in these functions.
1392
   * corresponding logic in these functions.

Return to bug 907396