Attachment #8455502: Rollup patch of all changes including bug 917313 for bug #907396

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

(-)a/editor/libeditor/base/nsEditor.cpp (-2 / +2 lines)
Line     Link Here 
 Lines 3536-3559   IsElementVisible(dom::Element* aElement) Link Here 
3536
3536
3537
      // Otherwise, we might end up with a frame when that lazy bit is
3537
      // Otherwise, we might end up with a frame when that lazy bit is
3538
      // processed.  Figure out our actual style.
3538
      // processed.  Figure out our actual style.
3539
      break;
3539
      break;
3540
    }
3540
    }
3541
  }
3541
  }
3542
3542
3543
  // Now it might be that we have no frame because we're in a
3543
  // Now it might be that we have no frame because we're in a
3544
  // display:none subtree, or it might be that we're just dealing with
3544
  // display-box:none subtree, or it might be that we're just dealing with
3545
  // lazy frame construction and it hasn't happened yet.  Check which
3545
  // lazy frame construction and it hasn't happened yet.  Check which
3546
  // one it is.
3546
  // one it is.
3547
  nsRefPtr<nsStyleContext> styleContext =
3547
  nsRefPtr<nsStyleContext> styleContext =
3548
    nsComputedDOMStyle::GetStyleContextForElementNoFlush(aElement,
3548
    nsComputedDOMStyle::GetStyleContextForElementNoFlush(aElement,
3549
                                                         nullptr, nullptr);
3549
                                                         nullptr, nullptr);
3550
  if (styleContext) {
3550
  if (styleContext) {
3551
    return styleContext->StyleDisplay()->mDisplay != NS_STYLE_DISPLAY_NONE;
3551
    return styleContext->StyleDisplay()->mDisplayBox != NS_STYLE_DISPLAY_BOX_NONE;
3552
  }
3552
  }
3553
  return false;
3553
  return false;
3554
}
3554
}
3555
3555
3556
bool 
3556
bool 
3557
nsEditor::IsEditable(nsIDOMNode *aNode)
3557
nsEditor::IsEditable(nsIDOMNode *aNode)
3558
{
3558
{
3559
  nsCOMPtr<nsIContent> content = do_QueryInterface(aNode);
3559
  nsCOMPtr<nsIContent> content = do_QueryInterface(aNode);
(-)a/layout/base/RestyleManager.cpp (-135 / +313 lines)
Line     Link Here 
 Lines 69-84   RestyleManager::NotifyDestroyingFrame(ns Link Here 
69
}
69
}
70
70
71
#ifdef DEBUG
71
#ifdef DEBUG
72
  // To ensure that the functions below are only called within
72
  // To ensure that the functions below are only called within
73
  // |ApplyRenderingChangeToTree|.
73
  // |ApplyRenderingChangeToTree|.
74
static bool gInApplyRenderingChangeToTree = false;
74
static bool gInApplyRenderingChangeToTree = false;
75
#endif
75
#endif
76
76
77
static nsIFrame*
78
GetNearestAncestorFrame(nsIContent* aContent)
79
{
80
  nsIFrame* ancestorFrame = nullptr;
81
  for (nsIContent* ancestor = aContent->GetParent();
82
       ancestor && !ancestorFrame;
83
       ancestor = ancestor->GetParent()) {
84
    ancestorFrame = ancestor->GetPrimaryFrame();
85
  }
86
  return ancestorFrame;
87
}
88
89
77
static void
90
static void
78
DoApplyRenderingChangeToTree(nsIFrame* aFrame,
91
DoApplyRenderingChangeToTree(nsIFrame* aFrame,
79
                             nsChangeHint aChange);
92
                             nsChangeHint aChange);
80
93
81
/**
94
/**
82
 * Sync views on aFrame and all of aFrame's descendants (following placeholders),
95
 * Sync views on aFrame and all of aFrame's descendants (following placeholders),
83
 * if aChange has nsChangeHint_SyncFrameView.
96
 * if aChange has nsChangeHint_SyncFrameView.
84
 * Calls DoApplyRenderingChangeToTree on all aFrame's out-of-flow descendants
97
 * Calls DoApplyRenderingChangeToTree on all aFrame's out-of-flow descendants
 Lines 885-901   RestyleManager::RestyleElement(Element* Link Here 
885
    FrameConstructor()->RecreateFramesForContent(aElement, false);
898
    FrameConstructor()->RecreateFramesForContent(aElement, false);
886
  } else if (aPrimaryFrame) {
899
  } else if (aPrimaryFrame) {
887
    nsStyleChangeList changeList;
900
    nsStyleChangeList changeList;
888
    ComputeStyleChangeFor(aPrimaryFrame, &changeList, aMinHint,
901
    ComputeStyleChangeFor(aPrimaryFrame, &changeList, aMinHint,
889
                          aRestyleTracker, aRestyleHint);
902
                          aRestyleTracker, aRestyleHint);
890
    ProcessRestyledFrames(changeList);
903
    ProcessRestyledFrames(changeList);
891
  } else {
904
  } else {
892
    // no frames, reconstruct for content
905
    // no frames, reconstruct for content
893
    FrameConstructor()->MaybeRecreateFramesForElement(aElement);
906
    nsStyleContext* newContext =
907
      FrameConstructor()->MaybeRecreateFramesForElement(aElement);
908
    if (newContext &&
909
        newContext->StyleDisplay()->mDisplayBox == NS_STYLE_DISPLAY_BOX_CONTENTS) {
910
      // Style change for a display-box:contents node that did not recreate frames.
911
      nsIFrame* frame = GetNearestAncestorFrame(aElement);
912
      MOZ_ASSERT(frame, "display-box:contents node in map although "
913
                        "it's a display:none descendant?");
914
      TreeMatchContext treeMatchContext(true,
915
                                        nsRuleWalker::eRelevantLinkUnvisited,
916
                                        frame->PresContext()->Document());
917
      nsIContent* parent = aElement->GetParent();
918
      Element* parentElement =
919
        parent && parent->IsElement() ? parent->AsElement() : nullptr;
920
      treeMatchContext.InitAncestors(parentElement);
921
      nsTArray<nsIContent*> visibleKidsOfHiddenElement;
922
      nsStyleChangeList changeList;
923
      ElementRestyler r(frame->PresContext(), aElement, &changeList,
924
                        aMinHint, aRestyleTracker, treeMatchContext,
925
                        visibleKidsOfHiddenElement);
926
      r.RestyleChildrenOfDisplayBoxContentsElement(frame, newContext,
927
                                                   aMinHint, aRestyleTracker,
928
                                                   aRestyleHint, this);
929
      ProcessRestyledFrames(changeList);
930
    }
894
  }
931
  }
895
}
932
}
896
933
897
static inline dom::Element*
934
static inline dom::Element*
898
ElementForStyleContext(nsIContent* aParentContent,
935
ElementForStyleContext(nsIContent* aParentContent,
899
                       nsIFrame* aFrame,
936
                       nsIFrame* aFrame,
900
                       nsCSSPseudoElements::Type aPseudoType);
937
                       nsCSSPseudoElements::Type aPseudoType);
901
938
 Lines 1626-1649   VerifyContextParent(nsPresContext* aPres Link Here 
1626
                    nsStyleContext* aContext, nsStyleContext* aParentContext)
1663
                    nsStyleContext* aContext, nsStyleContext* aParentContext)
1627
{
1664
{
1628
  // get the contexts not provided
1665
  // get the contexts not provided
1629
  if (!aContext) {
1666
  if (!aContext) {
1630
    aContext = aFrame->StyleContext();
1667
    aContext = aFrame->StyleContext();
1631
  }
1668
  }
1632
1669
1633
  if (!aParentContext) {
1670
  if (!aParentContext) {
1634
    // Get the correct parent context from the frame
1671
    nsIFrame* providerFrame;
1635
    //  - if the frame is a placeholder, we get the out of flow frame's context
1672
    aParentContext = aFrame->GetParentStyleContext(&providerFrame);
1636
    //    as the parent context instead of asking the frame
1637
1638
    // get the parent context from the frame (indirectly)
1639
    nsIFrame* providerFrame = aFrame->GetParentStyleContextFrame();
1640
    if (providerFrame)
1641
      aParentContext = providerFrame->StyleContext();
1642
    // aParentContext could still be null
1673
    // aParentContext could still be null
1643
  }
1674
  }
1644
1675
1645
  NS_ASSERTION(aContext, "Failure to get required contexts");
1676
  NS_ASSERTION(aContext, "Failure to get required contexts");
1646
  nsStyleContext* actualParentContext = aContext->GetParent();
1677
  nsStyleContext* actualParentContext = aContext->GetParent();
1647
1678
1648
  if (aParentContext) {
1679
  if (aParentContext) {
1649
    if (aParentContext != actualParentContext) {
1680
    if (aParentContext != actualParentContext) {
 Lines 1959-1988   RestyleManager::ReparentStyleContext(nsI Link Here 
1959
    } while ((outOfFlow = outOfFlow->GetNextContinuation()));
1990
    } while ((outOfFlow = outOfFlow->GetNextContinuation()));
1960
  }
1991
  }
1961
1992
1962
  // DO NOT verify the style tree before reparenting.  The frame
1993
  // DO NOT verify the style tree before reparenting.  The frame
1963
  // tree has already been changed, so this check would just fail.
1994
  // tree has already been changed, so this check would just fail.
1964
  nsStyleContext* oldContext = aFrame->StyleContext();
1995
  nsStyleContext* oldContext = aFrame->StyleContext();
1965
1996
1966
  nsRefPtr<nsStyleContext> newContext;
1997
  nsRefPtr<nsStyleContext> newContext;
1967
  nsIFrame* providerFrame = aFrame->GetParentStyleContextFrame();
1998
  nsIFrame* providerFrame;
1999
  nsStyleContext* newParentContext = aFrame->GetParentStyleContext(&providerFrame);
1968
  bool isChild = providerFrame && providerFrame->GetParent() == aFrame;
2000
  bool isChild = providerFrame && providerFrame->GetParent() == aFrame;
1969
  nsStyleContext* newParentContext = nullptr;
1970
  nsIFrame* providerChild = nullptr;
2001
  nsIFrame* providerChild = nullptr;
1971
  if (isChild) {
2002
  if (isChild) {
1972
    ReparentStyleContext(providerFrame);
2003
    ReparentStyleContext(providerFrame);
2004
    // Get the style context again after ReparentStyleContext() which might have
2005
    // changed it.
1973
    newParentContext = providerFrame->StyleContext();
2006
    newParentContext = providerFrame->StyleContext();
1974
    providerChild = providerFrame;
2007
    providerChild = providerFrame;
1975
  } else if (providerFrame) {
1976
    newParentContext = providerFrame->StyleContext();
1977
  } else {
1978
    NS_NOTREACHED("Reparenting something that has no usable parent? "
1979
                  "Shouldn't happen!");
1980
  }
2008
  }
2009
  NS_ASSERTION(newParentContext, "Reparenting something that has no usable"
2010
               " parent? Shouldn't happen!");
1981
  // XXX need to do something here to produce the correct style context for
2011
  // XXX need to do something here to produce the correct style context for
1982
  // an IB split whose first inline part is inside a first-line frame.
2012
  // an IB split whose first inline part is inside a first-line frame.
1983
  // Currently the first IB anonymous block's style context takes the first
2013
  // Currently the first IB anonymous block's style context takes the first
1984
  // part's style context as parent, which is wrong since first-line style
2014
  // part's style context as parent, which is wrong since first-line style
1985
  // should not apply to the anonymous block.
2015
  // should not apply to the anonymous block.
1986
2016
1987
#ifdef DEBUG
2017
#ifdef DEBUG
1988
  {
2018
  {
 Lines 2231-2246   ElementRestyler::ElementRestyler(ParentC Link Here 
2231
  , mDesiredA11yNotifications(aParentRestyler.mDesiredA11yNotifications)
2261
  , mDesiredA11yNotifications(aParentRestyler.mDesiredA11yNotifications)
2232
  , mKidsDesiredA11yNotifications(mDesiredA11yNotifications)
2262
  , mKidsDesiredA11yNotifications(mDesiredA11yNotifications)
2233
  , mOurA11yNotification(eDontNotify)
2263
  , mOurA11yNotification(eDontNotify)
2234
  , mVisibleKidsOfHiddenElement(aParentRestyler.mVisibleKidsOfHiddenElement)
2264
  , mVisibleKidsOfHiddenElement(aParentRestyler.mVisibleKidsOfHiddenElement)
2235
#endif
2265
#endif
2236
{
2266
{
2237
}
2267
}
2238
2268
2269
ElementRestyler::ElementRestyler(nsPresContext* aPresContext,
2270
                                 nsIContent* aContent,
2271
                                 nsStyleChangeList* aChangeList,
2272
                                 nsChangeHint aHintsHandledByAncestors,
2273
                                 RestyleTracker& aRestyleTracker,
2274
                                 TreeMatchContext& aTreeMatchContext,
2275
                                 nsTArray<nsIContent*>&
2276
                                 aVisibleKidsOfHiddenElement)
2277
  : mPresContext(aPresContext)
2278
  , mFrame(nullptr)
2279
  , mParentContent(nullptr)
2280
  , mContent(aContent)
2281
  , mChangeList(aChangeList)
2282
  , mHintsHandled(NS_SubtractHint(aHintsHandledByAncestors,
2283
                  NS_HintsNotHandledForDescendantsIn(aHintsHandledByAncestors)))
2284
  , mParentFrameHintsNotHandledForDescendants(nsChangeHint(0))
2285
  , mHintsNotHandledForDescendants(nsChangeHint(0))
2286
  , mRestyleTracker(aRestyleTracker)
2287
  , mTreeMatchContext(aTreeMatchContext)
2288
  , mResolvedChild(nullptr)
2289
#ifdef ACCESSIBILITY
2290
  , mDesiredA11yNotifications(eSendAllNotifications)
2291
  , mKidsDesiredA11yNotifications(mDesiredA11yNotifications)
2292
  , mOurA11yNotification(eDontNotify)
2293
  , mVisibleKidsOfHiddenElement(aVisibleKidsOfHiddenElement)
2294
#endif
2295
{
2296
}
2297
2239
void
2298
void
2240
ElementRestyler::CaptureChange(nsStyleContext* aOldContext,
2299
ElementRestyler::CaptureChange(nsStyleContext* aOldContext,
2241
                               nsStyleContext* aNewContext,
2300
                               nsStyleContext* aNewContext,
2242
                               nsChangeHint aChangeToAssume)
2301
                               nsChangeHint aChangeToAssume)
2243
{
2302
{
2244
  // Check some invariants about replacing one style context with another.
2303
  // Check some invariants about replacing one style context with another.
2245
  NS_ASSERTION(aOldContext->GetPseudo() == aNewContext->GetPseudo(),
2304
  NS_ASSERTION(aOldContext->GetPseudo() == aNewContext->GetPseudo(),
2246
               "old and new style contexts should have the same pseudo");
2305
               "old and new style contexts should have the same pseudo");
 Lines 2299-2314   ElementRestyler::Restyle(nsRestyleHint a Link Here 
2299
               "frame must have content (unless at the top of the tree)");
2358
               "frame must have content (unless at the top of the tree)");
2300
2359
2301
  NS_ASSERTION(!GetPrevContinuationWithSameStyle(mFrame),
2360
  NS_ASSERTION(!GetPrevContinuationWithSameStyle(mFrame),
2302
               "should not be trying to restyle this frame separately");
2361
               "should not be trying to restyle this frame separately");
2303
2362
2304
  MOZ_ASSERT(!(aRestyleHint & eRestyle_LaterSiblings),
2363
  MOZ_ASSERT(!(aRestyleHint & eRestyle_LaterSiblings),
2305
             "eRestyle_LaterSiblings must not be part of aRestyleHint");
2364
             "eRestyle_LaterSiblings must not be part of aRestyleHint");
2306
2365
2366
  AutoDisplayBoxContentsAncestorPusher adcp(mTreeMatchContext, mFrame->PresContext(),
2367
      mFrame->GetContent() ? mFrame->GetContent()->GetParent() : nullptr);
2368
2307
  if (mContent && mContent->IsElement()) {
2369
  if (mContent && mContent->IsElement()) {
2308
    mContent->OwnerDoc()->FlushPendingLinkUpdates();
2370
    mContent->OwnerDoc()->FlushPendingLinkUpdates();
2309
    RestyleTracker::RestyleData restyleData;
2371
    RestyleTracker::RestyleData restyleData;
2310
    if (mRestyleTracker.GetRestyleData(mContent->AsElement(), &restyleData)) {
2372
    if (mRestyleTracker.GetRestyleData(mContent->AsElement(), &restyleData)) {
2311
      if (NS_UpdateHint(mHintsHandled, restyleData.mChangeHint)) {
2373
      if (NS_UpdateHint(mHintsHandled, restyleData.mChangeHint)) {
2312
        mChangeList->AppendChange(mFrame, mContent, restyleData.mChangeHint);
2374
        mChangeList->AppendChange(mFrame, mContent, restyleData.mChangeHint);
2313
      }
2375
      }
2314
      aRestyleHint = nsRestyleHint(aRestyleHint | restyleData.mRestyleHint);
2376
      aRestyleHint = nsRestyleHint(aRestyleHint | restyleData.mRestyleHint);
 Lines 2328-2344   ElementRestyler::Restyle(nsRestyleHint a Link Here 
2328
    // continuation or block-in-inline sibling.
2390
    // continuation or block-in-inline sibling.
2329
2391
2330
    for (nsIFrame* f = mFrame; f;
2392
    for (nsIFrame* f = mFrame; f;
2331
         f = GetNextContinuationWithSameStyle(f, oldContext)) {
2393
         f = GetNextContinuationWithSameStyle(f, oldContext)) {
2332
      RestyleSelf(f, aRestyleHint);
2394
      RestyleSelf(f, aRestyleHint);
2333
    }
2395
    }
2334
  }
2396
  }
2335
2397
2336
  RestyleChildren(childRestyleHint);
2398
  // No need to do this if we're planning to reframe already.
2399
  // It's also important to check mHintsHandled since we use
2400
  // mFrame->StyleContext(), which is out of date if mHintsHandled
2401
  // has a ReconstructFrame hint.  Using an out of date style
2402
  // context could trigger assertions about mismatched rule trees.
2403
  if (!(mHintsHandled & nsChangeHint_ReconstructFrame)) {
2404
    RestyleChildren(childRestyleHint);
2405
  }
2337
}
2406
}
2338
2407
2339
void
2408
void
2340
ElementRestyler::RestyleSelf(nsIFrame* aSelf, nsRestyleHint aRestyleHint)
2409
ElementRestyler::RestyleSelf(nsIFrame* aSelf, nsRestyleHint aRestyleHint)
2341
{
2410
{
2342
  MOZ_ASSERT(!(aRestyleHint & eRestyle_LaterSiblings),
2411
  MOZ_ASSERT(!(aRestyleHint & eRestyle_LaterSiblings),
2343
             "eRestyle_LaterSiblings must not be part of aRestyleHint");
2412
             "eRestyle_LaterSiblings must not be part of aRestyleHint");
2344
2413
 Lines 2357-2386   ElementRestyler::RestyleSelf(nsIFrame* a Link Here 
2357
#ifdef ACCESSIBILITY
2426
#ifdef ACCESSIBILITY
2358
  mWasFrameVisible = nsIPresShell::IsAccessibilityActive() ?
2427
  mWasFrameVisible = nsIPresShell::IsAccessibilityActive() ?
2359
    oldContext->StyleVisibility()->IsVisible() : false;
2428
    oldContext->StyleVisibility()->IsVisible() : false;
2360
#endif
2429
#endif
2361
2430
2362
  nsIAtom* const pseudoTag = oldContext->GetPseudo();
2431
  nsIAtom* const pseudoTag = oldContext->GetPseudo();
2363
  const nsCSSPseudoElements::Type pseudoType = oldContext->GetPseudoType();
2432
  const nsCSSPseudoElements::Type pseudoType = oldContext->GetPseudoType();
2364
2433
2365
  nsStyleContext* parentContext;
2366
  // Get the frame providing the parent style context.  If it is a
2434
  // Get the frame providing the parent style context.  If it is a
2367
  // child, then resolve the provider first.
2435
  // child, then resolve the provider first.
2368
  nsIFrame* providerFrame = aSelf->GetParentStyleContextFrame();
2436
  nsIFrame* providerFrame;
2437
  nsStyleContext* parentContext = mFrame->GetParentStyleContext(&providerFrame);
2369
  bool isChild = providerFrame && providerFrame->GetParent() == aSelf;
2438
  bool isChild = providerFrame && providerFrame->GetParent() == aSelf;
2370
  if (!isChild) {
2439
  if (isChild) {
2371
    if (providerFrame)
2372
      parentContext = providerFrame->StyleContext();
2373
    else
2374
      parentContext = nullptr;
2375
  }
2376
  else {
2377
    MOZ_ASSERT(providerFrame->GetContent() == aSelf->GetContent(),
2440
    MOZ_ASSERT(providerFrame->GetContent() == aSelf->GetContent(),
2378
               "Postcondition for GetParentStyleContextFrame() violated. "
2441
               "Postcondition for GetParentStyleContext() violated. "
2379
               "That means we need to add the current element to the "
2442
               "That means we need to add the current element to the "
2380
               "ancestor filter.");
2443
               "ancestor filter.");
2381
2444
2382
    // resolve the provider here (before aSelf below).
2445
    // resolve the provider here (before aSelf below).
2383
2446
2384
    // assumeDifferenceHint forces the parent's change to be also
2447
    // assumeDifferenceHint forces the parent's change to be also
2385
    // applied to this frame, no matter what
2448
    // applied to this frame, no matter what
2386
    // nsStyleContext::CalcStyleDifference says. CalcStyleDifference
2449
    // nsStyleContext::CalcStyleDifference says. CalcStyleDifference
 Lines 2568-2584   ElementRestyler::RestyleSelf(nsIFrame* a Link Here 
2568
      }
2631
      }
2569
    }
2632
    }
2570
  }
2633
  }
2571
}
2634
}
2572
2635
2573
void
2636
void
2574
ElementRestyler::RestyleChildren(nsRestyleHint aChildRestyleHint)
2637
ElementRestyler::RestyleChildren(nsRestyleHint aChildRestyleHint)
2575
{
2638
{
2576
  RestyleUndisplayedChildren(aChildRestyleHint);
2639
  MOZ_ASSERT(!(mHintsHandled & nsChangeHint_ReconstructFrame),
2640
             "No need to do this if we're planning to reframe already.");
2641
2642
  RestyleUndisplayedDescendants(aChildRestyleHint);
2577
2643
2578
  // Check whether we might need to create a new ::before frame.
2644
  // Check whether we might need to create a new ::before frame.
2579
  // There's no need to do this if we're planning to reframe already
2645
  // There's no need to do this if we're planning to reframe already
2580
  // or if we're not forcing restyles on kids.
2646
  // or if we're not forcing restyles on kids.
2581
  // It's also important to check mHintsHandled since we use
2647
  // It's also important to check mHintsHandled since we use
2582
  // mFrame->StyleContext(), which is out of date if mHintsHandled has a
2648
  // mFrame->StyleContext(), which is out of date if mHintsHandled has a
2583
  // ReconstructFrame hint.  Using an out of date style context could
2649
  // ReconstructFrame hint.  Using an out of date style context could
2584
  // trigger assertions about mismatched rule trees.
2650
  // trigger assertions about mismatched rule trees.
 Lines 2593-2609   ElementRestyler::RestyleChildren(nsResty Link Here 
2593
  // descendants anyway, so we want to avoid wasting time processing
2659
  // descendants anyway, so we want to avoid wasting time processing
2594
  // style contexts that we're just going to throw away anyway. - dwh
2660
  // style contexts that we're just going to throw away anyway. - dwh
2595
  // It's also important to check mHintsHandled since reresolving the
2661
  // It's also important to check mHintsHandled since reresolving the
2596
  // kids would use mFrame->StyleContext(), which is out of date if
2662
  // kids would use mFrame->StyleContext(), which is out of date if
2597
  // mHintsHandled has a ReconstructFrame hint; doing this could trigger
2663
  // mHintsHandled has a ReconstructFrame hint; doing this could trigger
2598
  // assertions about mismatched rule trees.
2664
  // assertions about mismatched rule trees.
2599
  nsIFrame *lastContinuation;
2665
  nsIFrame *lastContinuation;
2600
  if (!(mHintsHandled & nsChangeHint_ReconstructFrame)) {
2666
  if (!(mHintsHandled & nsChangeHint_ReconstructFrame)) {
2601
    InitializeAccessibilityNotifications();
2667
    InitializeAccessibilityNotifications(mFrame->StyleContext());
2602
2668
2603
    for (nsIFrame* f = mFrame; f;
2669
    for (nsIFrame* f = mFrame; f;
2604
         f = GetNextContinuationWithSameStyle(f, f->StyleContext())) {
2670
         f = GetNextContinuationWithSameStyle(f, f->StyleContext())) {
2605
      lastContinuation = f;
2671
      lastContinuation = f;
2606
      RestyleContentChildren(f, aChildRestyleHint);
2672
      RestyleContentChildren(f, aChildRestyleHint);
2607
    }
2673
    }
2608
2674
2609
    SendAccessibilityNotifications();
2675
    SendAccessibilityNotifications();
 Lines 2613-2790   ElementRestyler::RestyleChildren(nsResty Link Here 
2613
  // See comments above regarding :before.
2679
  // See comments above regarding :before.
2614
  if (!(mHintsHandled & nsChangeHint_ReconstructFrame) &&
2680
  if (!(mHintsHandled & nsChangeHint_ReconstructFrame) &&
2615
      aChildRestyleHint) {
2681
      aChildRestyleHint) {
2616
    RestyleAfterPseudo(lastContinuation);
2682
    RestyleAfterPseudo(lastContinuation);
2617
  }
2683
  }
2618
}
2684
}
2619
2685
2620
void
2686
void
2621
ElementRestyler::RestyleUndisplayedChildren(nsRestyleHint aChildRestyleHint)
2687
ElementRestyler::RestyleChildrenOfDisplayBoxContentsElement(
2688
  nsIFrame*       aParentFrame,
2689
  nsStyleContext* aNewContext,
2690
  nsChangeHint    aMinHint,
2691
  RestyleTracker& aRestyleTracker,
2692
  nsRestyleHint   aRestyleHint,
2693
  RestyleManager* aRestyleManager)
2694
{
2695
  InitializeAccessibilityNotifications(aNewContext);
2696
  DoRestyleUndisplayedDescendants(nsRestyleHint(0), mContent, aNewContext);
2697
  if (!(mHintsHandled & nsChangeHint_ReconstructFrame)) {
2698
    RestyleBeforePseudo(aParentFrame, nullptr, mContent, aNewContext);
2699
  }
2700
  if (!(mHintsHandled & nsChangeHint_ReconstructFrame)) {
2701
    RestyleAfterPseudo(aParentFrame, nullptr, mContent, aNewContext);
2702
  }
2703
  if (!(mHintsHandled & nsChangeHint_ReconstructFrame)) {
2704
    // Then process child frames for content that is a descendant of mContent.
2705
    // XXX perhaps it's better to walk child frames (before reresolving
2706
    // XXX undisplayed contexts above) and mark those that has a stylecontext
2707
    // XXX leading up to mContent's old context? (instead of the
2708
    // XXX ContentIsDescendantOf check below)
2709
    nsIFrame::ChildListIterator lists(aParentFrame);
2710
    for ( ; !lists.IsDone(); lists.Next()) {
2711
      nsFrameList::Enumerator childFrames(lists.CurrentList());
2712
      for (; !childFrames.AtEnd(); childFrames.Next()) {
2713
        nsIFrame* f = childFrames.get();
2714
        nsIContent* c = f->GetContent();
2715
        if (nsContentUtils::ContentIsDescendantOf(c, mContent) &&
2716
            !f->GetPrevContinuation()) {
2717
          if (!(f->GetStateBits() & NS_FRAME_OUT_OF_FLOW)) {
2718
            aRestyleManager->ComputeStyleChangeFor(f, mChangeList, aMinHint,
2719
                                                   aRestyleTracker,
2720
                                                   aRestyleHint);
2721
          }
2722
        }
2723
      }
2724
    }
2725
  }
2726
  if (!(mHintsHandled & nsChangeHint_ReconstructFrame)) {
2727
    SendAccessibilityNotifications();
2728
  }
2729
}
2730
2731
void
2732
ElementRestyler::RestyleUndisplayedDescendants(nsRestyleHint aChildRestyleHint)
2622
{
2733
{
2623
  // When the root element is display:none, we still construct *some*
2734
  // When the root element is display:none, we still construct *some*
2624
  // frames that have the root element as their mContent, down to the
2735
  // frames that have the root element as their mContent, down to the
2625
  // DocElementContainingBlock.
2736
  // DocElementContainingBlock.
2626
  bool checkUndisplayed;
2737
  bool checkUndisplayed;
2627
  nsIContent* undisplayedParent;
2738
  nsIContent* undisplayedParent;
2628
  nsCSSFrameConstructor* frameConstructor = mPresContext->FrameConstructor();
2629
  if (mFrame->StyleContext()->GetPseudo()) {
2739
  if (mFrame->StyleContext()->GetPseudo()) {
2630
    checkUndisplayed = mFrame == frameConstructor->
2740
    checkUndisplayed = mFrame == mPresContext->FrameConstructor()->
2631
                                   GetDocElementContainingBlock();
2741
                                   GetDocElementContainingBlock();
2632
    undisplayedParent = nullptr;
2742
    undisplayedParent = nullptr;
2633
  } else {
2743
  } else {
2634
    checkUndisplayed = !!mFrame->GetContent();
2744
    checkUndisplayed = !!mFrame->GetContent();
2635
    undisplayedParent = mFrame->GetContent();
2745
    undisplayedParent = mFrame->GetContent();
2636
  }
2746
  }
2637
  if (checkUndisplayed &&
2747
  if (checkUndisplayed) {
2638
      // No need to do this if we're planning to reframe already.
2748
    DoRestyleUndisplayedDescendants(aChildRestyleHint, undisplayedParent,
2639
      // It's also important to check mHintsHandled since we use
2749
                                    mFrame->StyleContext());
2640
      // mFrame->StyleContext(), which is out of date if mHintsHandled
2750
  }
2641
      // has a ReconstructFrame hint.  Using an out of date style
2751
}
2642
      // context could trigger assertions about mismatched rule trees.
2752
2643
      !(mHintsHandled & nsChangeHint_ReconstructFrame)) {
2753
void
2644
    UndisplayedNode* undisplayed =
2754
ElementRestyler::DoRestyleUndisplayedDescendants(nsRestyleHint aChildRestyleHint,
2645
      frameConstructor->GetAllUndisplayedContentIn(undisplayedParent);
2755
                                                 nsIContent* aParent,
2646
    TreeMatchContext::AutoAncestorPusher pusher(mTreeMatchContext);
2756
                                                 nsStyleContext* aParentContext)
2647
    if (undisplayed) {
2757
{
2648
      pusher.PushAncestorAndStyleScope(undisplayedParent);
2758
  nsCSSFrameConstructor* fc = mPresContext->FrameConstructor();
2759
  UndisplayedNode* nodes = fc->GetAllUndisplayedContentIn(aParent);
2760
  RestyleUndisplayedNodes(aChildRestyleHint, nodes, aParent,
2761
                          aParentContext, NS_STYLE_DISPLAY_BOX_NONE);
2762
  nodes = fc->GetAllDisplayBoxContentsIn(aParent);
2763
  RestyleUndisplayedNodes(aChildRestyleHint, nodes, aParent,
2764
                          aParentContext, NS_STYLE_DISPLAY_BOX_CONTENTS);
2765
}
2766
2767
void
2768
ElementRestyler::RestyleUndisplayedNodes(nsRestyleHint    aChildRestyleHint,
2769
                                         UndisplayedNode* aUndisplayed,
2770
                                         nsIContent*      aUndisplayedParent,
2771
                                         nsStyleContext*  aParentContext,
2772
                                         const uint8_t    aDisplayBoxStyle)
2773
{
2774
  nsIContent* undisplayedParent = aUndisplayedParent;
2775
  UndisplayedNode* undisplayed = aUndisplayed;
2776
  TreeMatchContext::AutoAncestorPusher pusher(mTreeMatchContext);
2777
  if (undisplayed) {
2778
    pusher.PushAncestorAndStyleScope(undisplayedParent);
2779
  }
2780
  for (; undisplayed; undisplayed = undisplayed->mNext) {
2781
    NS_ASSERTION(undisplayedParent ||
2782
                 undisplayed->mContent ==
2783
                   mPresContext->Document()->GetRootElement(),
2784
                 "undisplayed node child of null must be root");
2785
    NS_ASSERTION(!undisplayed->mStyle->GetPseudo(),
2786
                 "Shouldn't have random pseudo style contexts in the "
2787
                 "undisplayed map");
2788
2789
    // Get the parent of the undisplayed content and check if it is a XBL
2790
    // children element. Push the children element as an ancestor here because it does
2791
    // not have a frame and would not otherwise be pushed as an ancestor.
2792
    nsIContent* parent = undisplayed->mContent->GetParent();
2793
    TreeMatchContext::AutoAncestorPusher insertionPointPusher(mTreeMatchContext);
2794
    if (parent && parent->IsActiveChildrenElement()) {
2795
      insertionPointPusher.PushAncestorAndStyleScope(parent);
2649
    }
2796
    }
2650
    for (; undisplayed; undisplayed = undisplayed->mNext) {
2651
      NS_ASSERTION(undisplayedParent ||
2652
                   undisplayed->mContent ==
2653
                     mPresContext->Document()->GetRootElement(),
2654
                   "undisplayed node child of null must be root");
2655
      NS_ASSERTION(!undisplayed->mStyle->GetPseudo(),
2656
                   "Shouldn't have random pseudo style contexts in the "
2657
                   "undisplayed map");
2658
2797
2659
      // Get the parent of the undisplayed content and check if it is a XBL
2798
    nsRestyleHint thisChildHint = aChildRestyleHint;
2660
      // children element. Push the children element as an ancestor here because it does
2799
    RestyleTracker::RestyleData undisplayedRestyleData;
2661
      // not have a frame and would not otherwise be pushed as an ancestor.
2800
    if (mRestyleTracker.GetRestyleData(undisplayed->mContent->AsElement(),
2662
      nsIContent* parent = undisplayed->mContent->GetParent();
2801
                                       &undisplayedRestyleData)) {
2663
      TreeMatchContext::AutoAncestorPusher insertionPointPusher(mTreeMatchContext);
2802
      thisChildHint =
2664
      if (parent && nsContentUtils::IsContentInsertionPoint(parent)) {
2803
        nsRestyleHint(thisChildHint | undisplayedRestyleData.mRestyleHint);
2665
        insertionPointPusher.PushAncestorAndStyleScope(parent);
2804
    }
2666
      }
2805
    nsRefPtr<nsStyleContext> undisplayedContext;
2806
    nsStyleSet* styleSet = mPresContext->StyleSet();
2807
    if (thisChildHint) {
2808
      undisplayedContext =
2809
        styleSet->ResolveStyleFor(undisplayed->mContent->AsElement(),
2810
                                  aParentContext,
2811
                                  mTreeMatchContext);
2812
    } else {
2813
      undisplayedContext =
2814
        styleSet->ReparentStyleContext(undisplayed->mStyle,
2815
                                       aParentContext,
2816
                                       undisplayed->mContent->AsElement());
2817
    }
2818
    const nsStyleDisplay* display = undisplayedContext->StyleDisplay();
2819
    if (display->mDisplayBox != aDisplayBoxStyle) {
2820
      NS_ASSERTION(undisplayed->mContent, "Must have undisplayed content");
2821
      mChangeList->AppendChange(nullptr, undisplayed->mContent,
2822
                                NS_STYLE_HINT_FRAMECHANGE);
2823
      // The node should be removed from the undisplayed map when
2824
      // we reframe it.
2825
    } else {
2826
      // update the undisplayed node with the new context
2827
      undisplayed->mStyle = undisplayedContext;
2667
2828
2668
      nsRestyleHint thisChildHint = aChildRestyleHint;
2829
      if (aDisplayBoxStyle == NS_STYLE_DISPLAY_BOX_CONTENTS) {
2669
      RestyleTracker::RestyleData undisplayedRestyleData;
2830
        DoRestyleUndisplayedDescendants(aChildRestyleHint, undisplayed->mContent,
2670
      if (mRestyleTracker.GetRestyleData(undisplayed->mContent->AsElement(),
2831
                                        undisplayed->mStyle);
2671
                                         &undisplayedRestyleData)) {
2672
        thisChildHint =
2673
          nsRestyleHint(thisChildHint | undisplayedRestyleData.mRestyleHint);
2674
      }
2675
      nsRefPtr<nsStyleContext> undisplayedContext;
2676
      nsStyleSet* styleSet = mPresContext->StyleSet();
2677
      if (thisChildHint) {
2678
        undisplayedContext =
2679
          styleSet->ResolveStyleFor(undisplayed->mContent->AsElement(),
2680
                                    mFrame->StyleContext(),
2681
                                    mTreeMatchContext);
2682
      } else {
2683
        undisplayedContext =
2684
          styleSet->ReparentStyleContext(undisplayed->mStyle,
2685
                                         mFrame->StyleContext(),
2686
                                         undisplayed->mContent->AsElement());
2687
      }
2688
      const nsStyleDisplay* display = undisplayedContext->StyleDisplay();
2689
      if (display->mDisplay != NS_STYLE_DISPLAY_NONE) {
2690
        NS_ASSERTION(undisplayed->mContent,
2691
                     "Must have undisplayed content");
2692
        mChangeList->AppendChange(nullptr, undisplayed->mContent,
2693
                                  NS_STYLE_HINT_FRAMECHANGE);
2694
        // The node should be removed from the undisplayed map when
2695
        // we reframe it.
2696
      } else {
2697
        // update the undisplayed node with the new context
2698
        undisplayed->mStyle = undisplayedContext;
2699
      }
2832
      }
2700
    }
2833
    }
2701
  }
2834
  }
2702
}
2835
}
2703
2836
2704
void
2837
void
2705
ElementRestyler::RestyleBeforePseudo()
2838
ElementRestyler::RestyleBeforePseudo()
2706
{
2839
{
2840
  RestyleBeforePseudo(mFrame, mFrame, mFrame->GetContent(),
2841
                      mFrame->StyleContext());
2842
}
2843
2844
void
2845
ElementRestyler::RestyleBeforePseudo(nsIFrame* aGenConParentFrame,
2846
                                     nsIFrame* aFrame,
2847
                                     nsIContent* aContent,
2848
                                     nsStyleContext* aStyleContext)
2849
{
2707
  // Make sure not to do this for pseudo-frames or frames that
2850
  // Make sure not to do this for pseudo-frames or frames that
2708
  // can't have generated content.
2851
  // can't have generated content.
2709
  nsContainerFrame* cif;
2852
  nsContainerFrame* cif;
2710
  if (!mFrame->StyleContext()->GetPseudo() &&
2853
  if (!aStyleContext->GetPseudo() &&
2711
      ((mFrame->GetStateBits() & NS_FRAME_MAY_HAVE_GENERATED_CONTENT) ||
2854
      ((aGenConParentFrame->GetStateBits() & NS_FRAME_MAY_HAVE_GENERATED_CONTENT) ||
2712
       // Our content insertion frame might have gotten flagged
2855
       // Our content insertion frame might have gotten flagged.
2713
       ((cif = mFrame->GetContentInsertionFrame()) &&
2856
       ((cif = aGenConParentFrame->GetContentInsertionFrame()) &&
2714
        (cif->GetStateBits() & NS_FRAME_MAY_HAVE_GENERATED_CONTENT)))) {
2857
        (cif->GetStateBits() & NS_FRAME_MAY_HAVE_GENERATED_CONTENT)))) {
2715
    // Check for a new :before pseudo and an existing :before
2858
    // Check for a ::before pseudo style and the absence of a ::before content,
2716
    // frame, but only if the frame is the first continuation.
2859
    // but only if aFrame is null or is the first continuation.
2717
    nsIFrame* prevContinuation = mFrame->GetPrevContinuation();
2860
    if (!aFrame || !aFrame->GetPrevContinuation()) {
2718
    if (!prevContinuation) {
2861
      if (!nsLayoutUtils::GetBeforeFrameForContent(aGenConParentFrame, aContent) &&
2719
      // Checking for a :before frame is cheaper than getting the
2862
          nsLayoutUtils::HasPseudoStyle(aContent, aStyleContext,
2720
      // :before style context.
2721
      if (!nsLayoutUtils::GetBeforeFrame(mFrame) &&
2722
          nsLayoutUtils::HasPseudoStyle(mFrame->GetContent(),
2723
                                        mFrame->StyleContext(),
2724
                                        nsCSSPseudoElements::ePseudo_before,
2863
                                        nsCSSPseudoElements::ePseudo_before,
2725
                                        mPresContext)) {
2864
                                        mPresContext)) {
2726
        // Have to create the new :before frame
2865
        // Have to create the new ::before frame.
2727
        NS_UpdateHint(mHintsHandled, nsChangeHint_ReconstructFrame);
2866
        NS_UpdateHint(mHintsHandled, nsChangeHint_ReconstructFrame);
2728
        mChangeList->AppendChange(mFrame, mContent,
2867
        mChangeList->AppendChange(aFrame, aContent,
2729
                                  nsChangeHint_ReconstructFrame);
2868
                                  nsChangeHint_ReconstructFrame);
2730
      }
2869
      }
2731
    }
2870
    }
2732
  }
2871
  }
2733
}
2872
}
2734
2873
2735
/**
2874
/**
2736
 * aFrame is the last continuation or block-in-inline sibling that this
2875
 * aFrame is the last continuation or block-in-inline sibling that this
2737
 * ElementRestyler is restyling.
2876
 * ElementRestyler is restyling.
2738
 */
2877
 */
2739
void
2878
void
2740
ElementRestyler::RestyleAfterPseudo(nsIFrame* aFrame)
2879
ElementRestyler::RestyleAfterPseudo(nsIFrame* aFrame)
2741
{
2880
{
2881
  MOZ_ASSERT(aFrame);
2882
  RestyleAfterPseudo(aFrame, aFrame, aFrame->GetContent(),
2883
                     aFrame->StyleContext());
2884
}
2885
2886
void
2887
ElementRestyler::RestyleAfterPseudo(nsIFrame* aGenConParentFrame,
2888
                                    nsIFrame* aFrame,
2889
                                    nsIContent* aContent,
2890
                                    nsStyleContext* aStyleContext)
2891
{
2742
  // Make sure not to do this for pseudo-frames or frames that
2892
  // Make sure not to do this for pseudo-frames or frames that
2743
  // can't have generated content.
2893
  // can't have generated content.
2744
  nsContainerFrame* cif;
2894
  nsContainerFrame* cif;
2745
  if (!aFrame->StyleContext()->GetPseudo() &&
2895
  if (!aStyleContext->GetPseudo() &&
2746
      ((aFrame->GetStateBits() & NS_FRAME_MAY_HAVE_GENERATED_CONTENT) ||
2896
      ((aGenConParentFrame->GetStateBits() & NS_FRAME_MAY_HAVE_GENERATED_CONTENT) ||
2747
       // Our content insertion frame might have gotten flagged
2897
       // Our content insertion frame might have gotten flagged.
2748
       ((cif = aFrame->GetContentInsertionFrame()) &&
2898
       ((cif = aGenConParentFrame->GetContentInsertionFrame()) &&
2749
        (cif->GetStateBits() & NS_FRAME_MAY_HAVE_GENERATED_CONTENT)))) {
2899
        (cif->GetStateBits() & NS_FRAME_MAY_HAVE_GENERATED_CONTENT)))) {
2750
    // Check for new :after content, but only if the frame is the
2900
    // Check for an ::after pseudo style and the absence of an ::after content,
2751
    // last continuation.
2901
    // but only if aFrame is null or is the last continuation.
2752
    nsIFrame* nextContinuation = aFrame->GetNextContinuation();
2902
    if (!aFrame || !aFrame->GetNextContinuation()) {
2753
2903
      if (!nsLayoutUtils::GetAfterFrameForContent(aGenConParentFrame, aContent) &&
2754
    if (!nextContinuation) {
2904
          nsLayoutUtils::HasPseudoStyle(aContent, aStyleContext,
2755
      // Getting the :after frame is more expensive than getting the pseudo
2756
      // context, so get the pseudo context first.
2757
      if (nsLayoutUtils::HasPseudoStyle(aFrame->GetContent(),
2758
                                        aFrame->StyleContext(),
2759
                                        nsCSSPseudoElements::ePseudo_after,
2905
                                        nsCSSPseudoElements::ePseudo_after,
2760
                                        mPresContext) &&
2906
                                        mPresContext)) {
2761
          !nsLayoutUtils::GetAfterFrame(aFrame)) {
2907
        // Have to create the new ::after frame.
2762
        // have to create the new :after frame
2763
        NS_UpdateHint(mHintsHandled, nsChangeHint_ReconstructFrame);
2908
        NS_UpdateHint(mHintsHandled, nsChangeHint_ReconstructFrame);
2764
        mChangeList->AppendChange(aFrame, mContent,
2909
        mChangeList->AppendChange(aFrame, mContent,
2765
                                  nsChangeHint_ReconstructFrame);
2910
                                  nsChangeHint_ReconstructFrame);
2766
      }
2911
      }
2767
    }
2912
    }
2768
  }
2913
  }
2769
}
2914
}
2770
2915
2771
void
2916
void
2772
ElementRestyler::InitializeAccessibilityNotifications()
2917
ElementRestyler::InitializeAccessibilityNotifications(nsStyleContext* aNewContext)
2773
{
2918
{
2774
#ifdef ACCESSIBILITY
2919
#ifdef ACCESSIBILITY
2775
  // Notify a11y for primary frame only if it's a root frame of visibility
2920
  // Notify a11y for primary frame only if it's a root frame of visibility
2776
  // changes or its parent frame was hidden while it stays visible and
2921
  // changes or its parent frame was hidden while it stays visible and
2777
  // it is not inside a {ib} split or is the first frame of {ib} split.
2922
  // it is not inside a {ib} split or is the first frame of {ib} split.
2778
  if (nsIPresShell::IsAccessibilityActive() &&
2923
  if (nsIPresShell::IsAccessibilityActive() &&
2779
      !mFrame->GetPrevContinuation() &&
2924
      (!mFrame ||
2780
      !mFrame->FrameIsNonFirstInIBSplit()) {
2925
       (!mFrame->GetPrevContinuation() &&
2926
        !mFrame->FrameIsNonFirstInIBSplit()))) {
2781
    if (mDesiredA11yNotifications == eSendAllNotifications) {
2927
    if (mDesiredA11yNotifications == eSendAllNotifications) {
2782
      bool isFrameVisible = mFrame->StyleVisibility()->IsVisible();
2928
      bool isFrameVisible = aNewContext->StyleVisibility()->IsVisible();
2783
      if (isFrameVisible != mWasFrameVisible) {
2929
      if (isFrameVisible != mWasFrameVisible) {
2784
        if (isFrameVisible) {
2930
        if (isFrameVisible) {
2785
          // Notify a11y the element (perhaps with its children) was shown.
2931
          // Notify a11y the element (perhaps with its children) was shown.
2786
          // We don't fall into this case if this element gets or stays shown
2932
          // We don't fall into this case if this element gets or stays shown
2787
          // while its parent becomes hidden.
2933
          // while its parent becomes hidden.
2788
          mKidsDesiredA11yNotifications = eSkipNotifications;
2934
          mKidsDesiredA11yNotifications = eSkipNotifications;
2789
          mOurA11yNotification = eNotifyShown;
2935
          mOurA11yNotification = eNotifyShown;
2790
        } else {
2936
        } else {
 Lines 2793-2812   ElementRestyler::InitializeAccessibility Link Here 
2793
          // visible children then we should notify a11y about that as if
2939
          // visible children then we should notify a11y about that as if
2794
          // they were inserted into tree. Notify a11y this element was
2940
          // they were inserted into tree. Notify a11y this element was
2795
          // hidden.
2941
          // hidden.
2796
          mKidsDesiredA11yNotifications = eNotifyIfShown;
2942
          mKidsDesiredA11yNotifications = eNotifyIfShown;
2797
          mOurA11yNotification = eNotifyHidden;
2943
          mOurA11yNotification = eNotifyHidden;
2798
        }
2944
        }
2799
      }
2945
      }
2800
    } else if (mDesiredA11yNotifications == eNotifyIfShown &&
2946
    } else if (mDesiredA11yNotifications == eNotifyIfShown &&
2801
               mFrame->StyleVisibility()->IsVisible()) {
2947
               aNewContext->StyleVisibility()->IsVisible()) {
2802
      // Notify a11y that element stayed visible while its parent was
2948
      // Notify a11y that element stayed visible while its parent was hidden.
2803
      // hidden.
2949
      nsIContent* c = mFrame ? mFrame->GetContent() : mContent;
2804
      mVisibleKidsOfHiddenElement.AppendElement(mFrame->GetContent());
2950
      mVisibleKidsOfHiddenElement.AppendElement(c);
2805
      mKidsDesiredA11yNotifications = eSkipNotifications;
2951
      mKidsDesiredA11yNotifications = eSkipNotifications;
2806
    }
2952
    }
2807
  }
2953
  }
2808
#endif
2954
#endif
2809
}
2955
}
2810
2956
2811
void
2957
void
2812
ElementRestyler::RestyleContentChildren(nsIFrame* aParent,
2958
ElementRestyler::RestyleContentChildren(nsIFrame* aParent,
 Lines 2842-2858   ElementRestyler::RestyleContentChildren( Link Here 
2842
        if (nsGkAtoms::placeholderFrame == child->GetType()) { // placeholder
2988
        if (nsGkAtoms::placeholderFrame == child->GetType()) { // placeholder
2843
          // get out of flow frame and recur there
2989
          // get out of flow frame and recur there
2844
          nsIFrame* outOfFlowFrame =
2990
          nsIFrame* outOfFlowFrame =
2845
            nsPlaceholderFrame::GetRealFrameForPlaceholder(child);
2991
            nsPlaceholderFrame::GetRealFrameForPlaceholder(child);
2846
          NS_ASSERTION(outOfFlowFrame, "no out-of-flow frame");
2992
          NS_ASSERTION(outOfFlowFrame, "no out-of-flow frame");
2847
          NS_ASSERTION(outOfFlowFrame != mResolvedChild,
2993
          NS_ASSERTION(outOfFlowFrame != mResolvedChild,
2848
                       "out-of-flow frame not a true descendant");
2994
                       "out-of-flow frame not a true descendant");
2849
2995
2850
          // |nsFrame::GetParentStyleContextFrame| checks being out
2996
          // |nsFrame::GetParentStyleContext| checks being out
2851
          // of flow so that this works correctly.
2997
          // of flow so that this works correctly.
2852
          do {
2998
          do {
2853
            if (GetPrevContinuationWithSameStyle(outOfFlowFrame)) {
2999
            if (GetPrevContinuationWithSameStyle(outOfFlowFrame)) {
2854
              // Later continuations are likely restyled as a result of
3000
              // Later continuations are likely restyled as a result of
2855
              // the restyling of the previous continuation.
3001
              // the restyling of the previous continuation.
2856
              // (Currently that's always true, but it's likely to
3002
              // (Currently that's always true, but it's likely to
2857
              // change if we implement overflow:fragments or similar.)
3003
              // change if we implement overflow:fragments or similar.)
2858
              continue;
3004
              continue;
 Lines 2882-2909   ElementRestyler::RestyleContentChildren( Link Here 
2882
void
3028
void
2883
ElementRestyler::SendAccessibilityNotifications()
3029
ElementRestyler::SendAccessibilityNotifications()
2884
{
3030
{
2885
#ifdef ACCESSIBILITY
3031
#ifdef ACCESSIBILITY
2886
  // Send notifications about visibility changes.
3032
  // Send notifications about visibility changes.
2887
  if (mOurA11yNotification == eNotifyShown) {
3033
  if (mOurA11yNotification == eNotifyShown) {
2888
    nsAccessibilityService* accService = nsIPresShell::AccService();
3034
    nsAccessibilityService* accService = nsIPresShell::AccService();
2889
    if (accService) {
3035
    if (accService) {
2890
      nsIPresShell* presShell = mFrame->PresContext()->GetPresShell();
3036
      nsIPresShell* presShell = mPresContext->GetPresShell();
2891
      nsIContent* content = mFrame->GetContent();
3037
      nsIContent* content = mFrame ? mFrame->GetContent() : mContent;
2892
3038
2893
      accService->ContentRangeInserted(presShell, content->GetParent(),
3039
      accService->ContentRangeInserted(presShell, content->GetParent(),
2894
                                       content,
3040
                                       content,
2895
                                       content->GetNextSibling());
3041
                                       content->GetNextSibling());
2896
    }
3042
    }
2897
  } else if (mOurA11yNotification == eNotifyHidden) {
3043
  } else if (mOurA11yNotification == eNotifyHidden) {
2898
    nsAccessibilityService* accService = nsIPresShell::AccService();
3044
    nsAccessibilityService* accService = nsIPresShell::AccService();
2899
    if (accService) {
3045
    if (accService) {
2900
      nsIPresShell* presShell = mFrame->PresContext()->GetPresShell();
3046
      nsIPresShell* presShell = mPresContext->GetPresShell();
2901
      nsIContent* content = mFrame->GetContent();
3047
      nsIContent* content = mFrame ? mFrame->GetContent() : mContent;
2902
      accService->ContentRemoved(presShell, content->GetParent(), content);
3048
      accService->ContentRemoved(presShell, content->GetParent(), content);
2903
3049
2904
      // Process children staying shown.
3050
      // Process children staying shown.
2905
      uint32_t visibleContentCount = mVisibleKidsOfHiddenElement.Length();
3051
      uint32_t visibleContentCount = mVisibleKidsOfHiddenElement.Length();
2906
      for (uint32_t idx = 0; idx < visibleContentCount; idx++) {
3052
      for (uint32_t idx = 0; idx < visibleContentCount; idx++) {
2907
        nsIContent* childContent = mVisibleKidsOfHiddenElement[idx];
3053
        nsIContent* childContent = mVisibleKidsOfHiddenElement[idx];
2908
        accService->ContentRangeInserted(presShell, childContent->GetParent(),
3054
        accService->ContentRangeInserted(presShell, childContent->GetParent(),
2909
                                         childContent,
3055
                                         childContent,
 Lines 2993-3001   RestyleManager::ComputeStyleChangeFor(ns Link Here 
2993
        NS_ASSERTION(!cont->GetPrevContinuation(),
3139
        NS_ASSERTION(!cont->GetPrevContinuation(),
2994
                     "continuing frame had more severe impact than first-in-flow");
3140
                     "continuing frame had more severe impact than first-in-flow");
2995
        return;
3141
        return;
2996
      }
3142
      }
2997
    }
3143
    }
2998
  }
3144
  }
2999
}
3145
}
3000
3146
3147
AutoDisplayBoxContentsAncestorPusher::AutoDisplayBoxContentsAncestorPusher(
3148
  TreeMatchContext& aTreeMatchContext, nsPresContext* aPresContext,
3149
  nsIContent* aParent)
3150
  : mTreeMatchContext(aTreeMatchContext)
3151
  , mPresContext(aPresContext)
3152
{
3153
  if (aParent && mTreeMatchContext.mAncestorFilter.HasFilter()) {
3154
    nsFrameManager* fm = mPresContext->FrameManager();
3155
    // Push display-box:contents mAncestors onto mTreeMatchContext.
3156
    for (nsIContent* p = aParent; p && fm->GetDisplayBoxContentsStyleFor(p);
3157
         p = p->GetParent()) {
3158
      mAncestors.AppendElement(p->AsElement());
3159
    }
3160
    nsTArray<mozilla::dom::Element*>::size_type i = mAncestors.Length();
3161
    while (i--) {
3162
      mTreeMatchContext.mAncestorFilter.PushAncestor(mAncestors[i]);
3163
      mTreeMatchContext.PushStyleScope(mAncestors[i]);
3164
    }
3165
  }
3166
3167
}
3168
3169
AutoDisplayBoxContentsAncestorPusher::~AutoDisplayBoxContentsAncestorPusher()
3170
{
3171
  // Pop the ancestors we pushed in the CTOR, if any.
3172
  nsTArray<mozilla::dom::Element*>::size_type i = mAncestors.Length();
3173
  while (i--) {
3174
    mTreeMatchContext.mAncestorFilter.PopAncestor();
3175
    mTreeMatchContext.PopStyleScope(mAncestors[i]);
3176
  }
3177
}
3178
3001
} // namespace mozilla
3179
} // namespace mozilla
(-)a/layout/base/RestyleManager.h (-4 / +63 lines)
Line     Link Here 
 Lines 18-39    Link Here 
18
18
19
class nsIFrame;
19
class nsIFrame;
20
class nsRefreshDriver;
20
class nsRefreshDriver;
21
class nsStyleChangeList;
21
class nsStyleChangeList;
22
struct TreeMatchContext;
22
struct TreeMatchContext;
23
23
24
namespace mozilla {
24
namespace mozilla {
25
  class EventStates;
25
  class EventStates;
26
  struct UndisplayedNode;
26
27
27
namespace dom {
28
namespace dom {
28
  class Element;
29
  class Element;
29
} // namespace dom
30
} // namespace dom
30
31
31
class RestyleManager MOZ_FINAL {
32
class RestyleManager MOZ_FINAL
33
{
32
public:
34
public:
33
  friend class ::nsRefreshDriver;
35
  friend class ::nsRefreshDriver;
34
  friend class RestyleTracker;
36
  friend class RestyleTracker;
35
37
36
  typedef mozilla::dom::Element Element;
38
  typedef mozilla::dom::Element Element;
37
39
38
  RestyleManager(nsPresContext* aPresContext);
40
  RestyleManager(nsPresContext* aPresContext);
39
41
 Lines 273-289   private: Link Here 
273
  RestyleTracker mPendingRestyles;
275
  RestyleTracker mPendingRestyles;
274
  RestyleTracker mPendingAnimationRestyles;
276
  RestyleTracker mPendingAnimationRestyles;
275
};
277
};
276
278
277
/**
279
/**
278
 * An ElementRestyler is created for *each* element in a subtree that we
280
 * An ElementRestyler is created for *each* element in a subtree that we
279
 * recompute styles for.
281
 * recompute styles for.
280
 */
282
 */
281
class ElementRestyler MOZ_FINAL {
283
class ElementRestyler MOZ_FINAL
284
{
282
public:
285
public:
283
  typedef mozilla::dom::Element Element;
286
  typedef mozilla::dom::Element Element;
284
287
285
  // Construct for the root of the subtree that we're restyling.
288
  // Construct for the root of the subtree that we're restyling.
286
  ElementRestyler(nsPresContext* aPresContext,
289
  ElementRestyler(nsPresContext* aPresContext,
287
                  nsIFrame* aFrame,
290
                  nsIFrame* aFrame,
288
                  nsStyleChangeList* aChangeList,
291
                  nsStyleChangeList* aChangeList,
289
                  nsChangeHint aHintsHandledByAncestors,
292
                  nsChangeHint aHintsHandledByAncestors,
 Lines 305-320   public: Link Here 
305
  // as the parent style context for their outer table frame (table
308
  // as the parent style context for their outer table frame (table
306
  // wrapper frame).  We should probably try to get rid of this
309
  // wrapper frame).  We should probably try to get rid of this
307
  // exception and have the inheritance go the other way.)
310
  // exception and have the inheritance go the other way.)
308
  enum ParentContextFromChildFrame { PARENT_CONTEXT_FROM_CHILD_FRAME };
311
  enum ParentContextFromChildFrame { PARENT_CONTEXT_FROM_CHILD_FRAME };
309
  ElementRestyler(ParentContextFromChildFrame,
312
  ElementRestyler(ParentContextFromChildFrame,
310
                  const ElementRestyler& aParentFrameRestyler,
313
                  const ElementRestyler& aParentFrameRestyler,
311
                  nsIFrame* aFrame);
314
                  nsIFrame* aFrame);
312
315
316
  // For restyling undisplayed content only (mFrame==null).
317
  ElementRestyler(nsPresContext* aPresContext,
318
                  nsIContent* aContent,
319
                  nsStyleChangeList* aChangeList,
320
                  nsChangeHint aHintsHandledByAncestors,
321
                  RestyleTracker& aRestyleTracker,
322
                  TreeMatchContext& aTreeMatchContext,
323
                  nsTArray<nsIContent*>& aVisibleKidsOfHiddenElement);
324
313
  /**
325
  /**
314
   * Restyle our frame's element and its subtree.
326
   * Restyle our frame's element and its subtree.
315
   *
327
   *
316
   * Use eRestyle_Self for the aRestyleHint argument to mean
328
   * Use eRestyle_Self for the aRestyleHint argument to mean
317
   * "reresolve our style context but not kids", use eRestyle_Subtree
329
   * "reresolve our style context but not kids", use eRestyle_Subtree
318
   * to mean "reresolve our style context and kids", and use
330
   * to mean "reresolve our style context and kids", and use
319
   * nsRestyleHint(0) to mean recompute a new style context for our
331
   * nsRestyleHint(0) to mean recompute a new style context for our
320
   * current parent and existing rulenode, and the same for kids.
332
   * current parent and existing rulenode, and the same for kids.
 Lines 325-340   public: Link Here 
325
   * mHintsHandled changes over time; it starts off as the hints that
337
   * mHintsHandled changes over time; it starts off as the hints that
326
   * have been handled by ancestors, and by the end of Restyle it
338
   * have been handled by ancestors, and by the end of Restyle it
327
   * represents the hints that have been handled for this frame.  This
339
   * represents the hints that have been handled for this frame.  This
328
   * method is intended to be called after Restyle, to find out what
340
   * method is intended to be called after Restyle, to find out what
329
   * hints have been handled for this frame.
341
   * hints have been handled for this frame.
330
   */
342
   */
331
  nsChangeHint HintsHandledForFrame() { return mHintsHandled; }
343
  nsChangeHint HintsHandledForFrame() { return mHintsHandled; }
332
344
345
  /**
346
   * Called from RestyleManager::RestyleElement to restyle children of
347
   * a display-box:contents element.
348
   */
349
  void RestyleChildrenOfDisplayBoxContentsElement(nsIFrame* aParentFrame,
350
                                                  nsStyleContext* aNewContext,
351
                                                  nsChangeHint    aMinHint,
352
                                                  RestyleTracker& aRestyleTracker,
353
                                                  nsRestyleHint   aRestyleHint,
354
                                                  RestyleManager* aRestyleManager);
333
private:
355
private:
334
  /**
356
  /**
335
   * First half of Restyle().
357
   * First half of Restyle().
336
   */
358
   */
337
  void RestyleSelf(nsIFrame* aSelf, nsRestyleHint aRestyleHint);
359
  void RestyleSelf(nsIFrame* aSelf, nsRestyleHint aRestyleHint);
338
360
339
  /**
361
  /**
340
   * Restyle the children of this frame (and, in turn, their children).
362
   * Restyle the children of this frame (and, in turn, their children).
 Lines 348-369   private: Link Here 
348
   */
370
   */
349
  void CaptureChange(nsStyleContext* aOldContext,
371
  void CaptureChange(nsStyleContext* aOldContext,
350
                     nsStyleContext* aNewContext,
372
                     nsStyleContext* aNewContext,
351
                     nsChangeHint aChangeToAssume);
373
                     nsChangeHint aChangeToAssume);
352
374
353
  /**
375
  /**
354
   * Helpers for RestyleChildren().
376
   * Helpers for RestyleChildren().
355
   */
377
   */
356
  void RestyleUndisplayedChildren(nsRestyleHint aChildRestyleHint);
378
  void RestyleUndisplayedDescendants(nsRestyleHint aChildRestyleHint);
379
  void DoRestyleUndisplayedDescendants(nsRestyleHint aChildRestyleHint,
380
                                       nsIContent* aParent,
381
                                       nsStyleContext* aParentStyleContext);
382
  void RestyleUndisplayedNodes(nsRestyleHint    aChildRestyleHint,
383
                               UndisplayedNode* aUndisplayed,
384
                               nsIContent*      aUndisplayedParent,
385
                               nsStyleContext*  aParentStyleContext,
386
                               const uint8_t    aDisplayBoxStyle);
357
  void RestyleBeforePseudo();
387
  void RestyleBeforePseudo();
388
  void RestyleBeforePseudo(nsIFrame* aGenConParentFrame,
389
                           nsIFrame* aFrame,
390
                           nsIContent* aContent,
391
                           nsStyleContext* aStyleContext);
358
  void RestyleAfterPseudo(nsIFrame* aFrame);
392
  void RestyleAfterPseudo(nsIFrame* aFrame);
393
  void RestyleAfterPseudo(nsIFrame* aGenConParentFrame,
394
                          nsIFrame* aFrame,
395
                          nsIContent* aContent,
396
                          nsStyleContext* aStyleContext);
359
  void RestyleContentChildren(nsIFrame* aParent,
397
  void RestyleContentChildren(nsIFrame* aParent,
360
                              nsRestyleHint aChildRestyleHint);
398
                              nsRestyleHint aChildRestyleHint);
361
  void InitializeAccessibilityNotifications();
399
  void InitializeAccessibilityNotifications(nsStyleContext* aNewContext);
362
  void SendAccessibilityNotifications();
400
  void SendAccessibilityNotifications();
363
401
364
  enum DesiredA11yNotifications {
402
  enum DesiredA11yNotifications {
365
    eSkipNotifications,
403
    eSkipNotifications,
366
    eSendAllNotifications,
404
    eSendAllNotifications,
367
    eNotifyIfShown
405
    eNotifyIfShown
368
  };
406
  };
369
407
 Lines 399-409   private: Link Here 
399
  const DesiredA11yNotifications mDesiredA11yNotifications;
437
  const DesiredA11yNotifications mDesiredA11yNotifications;
400
  DesiredA11yNotifications mKidsDesiredA11yNotifications;
438
  DesiredA11yNotifications mKidsDesiredA11yNotifications;
401
  A11yNotificationType mOurA11yNotification;
439
  A11yNotificationType mOurA11yNotification;
402
  nsTArray<nsIContent*>& mVisibleKidsOfHiddenElement;
440
  nsTArray<nsIContent*>& mVisibleKidsOfHiddenElement;
403
  bool mWasFrameVisible;
441
  bool mWasFrameVisible;
404
#endif
442
#endif
405
};
443
};
406
444
445
/**
446
 * This pushes any display-box:contents nodes onto a TreeMatchContext.
447
 * Use it before resolving style for kids of aParent where aParent
448
 * (and further ancestors) may be display:contents nodes which have
449
 * not yet been pushed onto TreeMatchContext.
450
 */
451
class MOZ_STACK_CLASS AutoDisplayBoxContentsAncestorPusher MOZ_FINAL
452
{
453
 public:
454
  typedef mozilla::dom::Element Element;
455
  AutoDisplayBoxContentsAncestorPusher(TreeMatchContext& aTreeMatchContext,
456
                                       nsPresContext*    aPresContext,
457
                                       nsIContent*       aParent);
458
  ~AutoDisplayBoxContentsAncestorPusher();
459
  bool IsEmpty() const { return mAncestors.Length() == 0; }
460
private:
461
  TreeMatchContext& mTreeMatchContext;
462
  nsPresContext* const mPresContext;
463
  nsAutoTArray<mozilla::dom::Element*, 4> mAncestors;
464
};
465
407
} // namespace mozilla
466
} // namespace mozilla
408
467
409
#endif /* mozilla_RestyleManager_h */
468
#endif /* mozilla_RestyleManager_h */
(-)a/layout/base/RestyleTracker.cpp (-2 / +6 lines)
Line     Link Here 
 Lines 4-19    Link Here 
4
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
5
6
/**
6
/**
7
 * A class which manages pending restyles.  This handles keeping track
7
 * A class which manages pending restyles.  This handles keeping track
8
 * of what nodes restyles need to happen on and so forth.
8
 * of what nodes restyles need to happen on and so forth.
9
 */
9
 */
10
10
11
#include "RestyleTracker.h"
11
#include "RestyleTracker.h"
12
13
#include "nsFrameManager.h"
12
#include "nsStyleChangeList.h"
14
#include "nsStyleChangeList.h"
13
#include "RestyleManager.h"
15
#include "RestyleManager.h"
14
#include "GeckoProfiler.h"
16
#include "GeckoProfiler.h"
15
17
16
namespace mozilla {
18
namespace mozilla {
17
19
18
inline nsIDocument*
20
inline nsIDocument*
19
RestyleTracker::Document() const {
21
RestyleTracker::Document() const {
 Lines 70-87   CollectRestyles(nsISupports* aElement, Link Here 
70
  if (element->GetCrossShadowCurrentDoc() != collector->tracker->Document() ||
72
  if (element->GetCrossShadowCurrentDoc() != collector->tracker->Document() ||
71
      !element->HasFlag(collector->tracker->RestyleBit())) {
73
      !element->HasFlag(collector->tracker->RestyleBit())) {
72
    return PL_DHASH_NEXT;
74
    return PL_DHASH_NEXT;
73
  }
75
  }
74
76
75
  NS_ASSERTION(!element->HasFlag(collector->tracker->RootBit()) ||
77
  NS_ASSERTION(!element->HasFlag(collector->tracker->RootBit()) ||
76
               // Maybe we're just not reachable via the frame tree?
78
               // Maybe we're just not reachable via the frame tree?
77
               (element->GetFlattenedTreeParent() &&
79
               (element->GetFlattenedTreeParent() &&
78
                (!element->GetFlattenedTreeParent()->GetPrimaryFrame()||
80
                (!element->GetFlattenedTreeParent()->GetPrimaryFrame() ||
79
                 element->GetFlattenedTreeParent()->GetPrimaryFrame()->IsLeaf())) ||
81
                 element->GetFlattenedTreeParent()->GetPrimaryFrame()->IsLeaf() ||
82
                 element->GetCurrentDoc()->GetShell()->FrameManager()
83
                   ->GetDisplayBoxContentsStyleFor(element))) ||
80
               // Or not reachable due to an async reinsert we have
84
               // Or not reachable due to an async reinsert we have
81
               // pending?  If so, we'll have a reframe hint around.
85
               // pending?  If so, we'll have a reframe hint around.
82
               // That incidentally makes it safe that we still have
86
               // That incidentally makes it safe that we still have
83
               // the bit, since any descendants that didn't get added
87
               // the bit, since any descendants that didn't get added
84
               // to the roots list because we had the bits will be
88
               // to the roots list because we had the bits will be
85
               // completely restyled in a moment.
89
               // completely restyled in a moment.
86
               (aData.mChangeHint & nsChangeHint_ReconstructFrame),
90
               (aData.mChangeHint & nsChangeHint_ReconstructFrame),
87
               "Why did this not get handled while processing mRestyleRoots?");
91
               "Why did this not get handled while processing mRestyleRoots?");
(-)a/layout/base/nsCSSFrameConstructor.cpp (-148 / +353 lines)
Line     Link Here 
 Lines 601-640   FindFirstNonBlock(const nsFrameList& aLi Link Here 
601
inline void
601
inline void
602
SetInitialSingleChild(nsContainerFrame* aParent, nsIFrame* aFrame)
602
SetInitialSingleChild(nsContainerFrame* aParent, nsIFrame* aFrame)
603
{
603
{
604
  NS_PRECONDITION(!aFrame->GetNextSibling(), "Should be using a frame list");
604
  NS_PRECONDITION(!aFrame->GetNextSibling(), "Should be using a frame list");
605
  nsFrameList temp(aFrame, aFrame);
605
  nsFrameList temp(aFrame, aFrame);
606
  aParent->SetInitialChildList(kPrincipalList, temp);
606
  aParent->SetInitialChildList(kPrincipalList, temp);
607
}
607
}
608
608
609
static nsContainerFrame*
610
GetContentInsertionFrameFor(nsIContent* aContent)
611
{
612
  // Get the primary frame associated with the content
613
  nsIFrame* frame = aContent->GetPrimaryFrame();
614
615
  if (!frame)
616
    return nullptr;
617
618
  // If the content of the frame is not the desired content then this is not
619
  // really a frame for the desired content.
620
  // XXX This check is needed due to bug 135040. Remove it once that's fixed.
621
  if (frame->GetContent() != aContent) {
622
    return nullptr;
623
  }
624
625
  nsContainerFrame* insertionFrame = frame->GetContentInsertionFrame();
626
627
  NS_ASSERTION(!insertionFrame || insertionFrame == frame || !frame->IsLeaf(),
628
    "The insertion frame is the primary frame or the primary frame isn't a leaf");
629
630
  return insertionFrame;
631
}
632
633
// -----------------------------------------------------------
609
// -----------------------------------------------------------
634
610
635
// Structure used when constructing formatting object trees.
611
// Structure used when constructing formatting object trees.
636
struct nsFrameItems : public nsFrameList
612
struct nsFrameItems : public nsFrameList
637
{
613
{
638
  // Appends the frame to the end of the list
614
  // Appends the frame to the end of the list
639
  void AddChild(nsIFrame* aChild);
615
  void AddChild(nsIFrame* aChild);
640
};
616
};
 Lines 2252-2269   NeedFrameFor(const nsFrameConstructorSta Link Here 
2252
  // whitespace.
2228
  // whitespace.
2253
2229
2254
  // We could handle all this in CreateNeededTablePseudos or some other place
2230
  // We could handle all this in CreateNeededTablePseudos or some other place
2255
  // after we build our frame construction items, but that would involve
2231
  // after we build our frame construction items, but that would involve
2256
  // creating frame construction items for whitespace kids of
2232
  // creating frame construction items for whitespace kids of
2257
  // eExcludesIgnorableWhitespace frames, where we know we'll be dropping them
2233
  // eExcludesIgnorableWhitespace frames, where we know we'll be dropping them
2258
  // all anyway, and involve an extra walk down the frame construction item
2234
  // all anyway, and involve an extra walk down the frame construction item
2259
  // list.
2235
  // list.
2260
  if (!aParentFrame->IsFrameOfType(nsIFrame::eExcludesIgnorableWhitespace) ||
2236
  if ((aParentFrame &&
2261
      aParentFrame->IsGeneratedContentFrame() ||
2237
       (!aParentFrame->IsFrameOfType(nsIFrame::eExcludesIgnorableWhitespace) ||
2238
        aParentFrame->IsGeneratedContentFrame())) ||
2262
      !aChildContent->IsNodeOfType(nsINode::eTEXT)) {
2239
      !aChildContent->IsNodeOfType(nsINode::eTEXT)) {
2263
    return true;
2240
    return true;
2264
  }
2241
  }
2265
2242
2266
  aChildContent->SetFlags(NS_CREATE_FRAME_IF_NON_WHITESPACE |
2243
  aChildContent->SetFlags(NS_CREATE_FRAME_IF_NON_WHITESPACE |
2267
                          NS_REFRAME_IF_WHITESPACE);
2244
                          NS_REFRAME_IF_WHITESPACE);
2268
  return !aChildContent->TextIsOnlyWhitespace();
2245
  return !aChildContent->TextIsOnlyWhitespace();
2269
}
2246
}
 Lines 2436-2452   nsCSSFrameConstructor::ConstructDocEleme Link Here 
2436
2413
2437
#ifdef DEBUG
2414
#ifdef DEBUG
2438
  NS_ASSERTION(!display->IsScrollableOverflow() ||
2415
  NS_ASSERTION(!display->IsScrollableOverflow() ||
2439
               state.mPresContext->IsPaginated() ||
2416
               state.mPresContext->IsPaginated() ||
2440
               propagatedScrollFrom == aDocElement,
2417
               propagatedScrollFrom == aDocElement,
2441
               "Scrollbars should have been propagated to the viewport");
2418
               "Scrollbars should have been propagated to the viewport");
2442
#endif
2419
#endif
2443
2420
2444
  if (MOZ_UNLIKELY(display->mDisplay == NS_STYLE_DISPLAY_NONE)) {
2421
  if (MOZ_UNLIKELY(display->mDisplayBox == NS_STYLE_DISPLAY_BOX_NONE)) {
2445
    SetUndisplayedContent(aDocElement, styleContext);
2422
    SetUndisplayedContent(aDocElement, styleContext);
2446
    return nullptr;
2423
    return nullptr;
2447
  }
2424
  }
2448
2425
2449
  TreeMatchContext::AutoAncestorPusher ancestorPusher(state.mTreeMatchContext);
2426
  TreeMatchContext::AutoAncestorPusher ancestorPusher(state.mTreeMatchContext);
2450
  ancestorPusher.PushAncestorAndStyleScope(aDocElement);
2427
  ancestorPusher.PushAncestorAndStyleScope(aDocElement);
2451
2428
2452
  // Make sure to start any background image loads for the root element now.
2429
  // Make sure to start any background image loads for the root element now.
 Lines 2572-2588   nsCSSFrameConstructor::ConstructDocEleme Link Here 
2572
  NS_ASSERTION(processChildren ? !mRootElementFrame :
2549
  NS_ASSERTION(processChildren ? !mRootElementFrame :
2573
                 mRootElementFrame == contentFrame,
2550
                 mRootElementFrame == contentFrame,
2574
               "unexpected mRootElementFrame");
2551
               "unexpected mRootElementFrame");
2575
  mRootElementFrame = contentFrame;
2552
  mRootElementFrame = contentFrame;
2576
2553
2577
  // Figure out which frame has the main style for the document element,
2554
  // Figure out which frame has the main style for the document element,
2578
  // assigning it to mRootElementStyleFrame.
2555
  // assigning it to mRootElementStyleFrame.
2579
  // Backgrounds should be propagated from that frame to the viewport.
2556
  // Backgrounds should be propagated from that frame to the viewport.
2580
  mRootElementStyleFrame = contentFrame->GetParentStyleContextFrame();
2557
  contentFrame->GetParentStyleContext(&mRootElementStyleFrame);
2581
  bool isChild = mRootElementStyleFrame &&
2558
  bool isChild = mRootElementStyleFrame &&
2582
                 mRootElementStyleFrame->GetParent() == contentFrame;
2559
                 mRootElementStyleFrame->GetParent() == contentFrame;
2583
  if (!isChild) {
2560
  if (!isChild) {
2584
    mRootElementStyleFrame = mRootElementFrame;
2561
    mRootElementStyleFrame = mRootElementFrame;
2585
  }
2562
  }
2586
2563
2587
  if (processChildren) {
2564
  if (processChildren) {
2588
    // Still need to process the child content
2565
    // Still need to process the child content
 Lines 3407-3422   IsFrameForFieldSet(nsIFrame* aFrame, nsI Link Here 
3407
/* static */
3384
/* static */
3408
const nsCSSFrameConstructor::FrameConstructionData*
3385
const nsCSSFrameConstructor::FrameConstructionData*
3409
nsCSSFrameConstructor::FindHTMLData(Element* aElement,
3386
nsCSSFrameConstructor::FindHTMLData(Element* aElement,
3410
                                    nsIAtom* aTag,
3387
                                    nsIAtom* aTag,
3411
                                    int32_t aNameSpaceID,
3388
                                    int32_t aNameSpaceID,
3412
                                    nsIFrame* aParentFrame,
3389
                                    nsIFrame* aParentFrame,
3413
                                    nsStyleContext* aStyleContext)
3390
                                    nsStyleContext* aStyleContext)
3414
{
3391
{
3392
  MOZ_ASSERT(aStyleContext->StyleDisplay()->mDisplayBox != NS_STYLE_DISPLAY_BOX_NONE);
3393
3415
  // Ignore the tag if it's not HTML content and if it doesn't extend (via XBL)
3394
  // Ignore the tag if it's not HTML content and if it doesn't extend (via XBL)
3416
  // a valid HTML namespace.  This check must match the one in
3395
  // a valid HTML namespace.  This check must match the one in
3417
  // ShouldHaveFirstLineStyle.
3396
  // ShouldHaveFirstLineStyle.
3418
  if (aNameSpaceID != kNameSpaceID_XHTML) {
3397
  if (aNameSpaceID != kNameSpaceID_XHTML) {
3419
    return nullptr;
3398
    return nullptr;
3420
  }
3399
  }
3421
3400
3422
  NS_ASSERTION(!aParentFrame ||
3401
  NS_ASSERTION(!aParentFrame ||
 Lines 3652-3680   nsCSSFrameConstructor::ConstructFrameFro Link Here 
3652
3631
3653
  // Don't create a subdocument frame for iframes if we're creating extra frames
3632
  // Don't create a subdocument frame for iframes if we're creating extra frames
3654
  if (aState.mCreatingExtraFrames && aItem.mContent->IsHTML() &&
3633
  if (aState.mCreatingExtraFrames && aItem.mContent->IsHTML() &&
3655
      aItem.mContent->Tag() == nsGkAtoms::iframe)
3634
      aItem.mContent->Tag() == nsGkAtoms::iframe)
3656
  {
3635
  {
3657
    return;
3636
    return;
3658
  }
3637
  }
3659
3638
3660
  nsStyleContext* const styleContext = aItem.mStyleContext;
3661
  const nsStyleDisplay* display = styleContext->StyleDisplay();
3662
  nsIContent* const content = aItem.mContent;
3639
  nsIContent* const content = aItem.mContent;
3640
  nsIContent* parent = content->GetParent();
3641
3642
  // Push display-box:contents ancestors.
3643
  AutoDisplayBoxContentsAncestorPusher adcp(aState.mTreeMatchContext,
3644
                                            aState.mPresContext,
3645
                                            parent);
3663
3646
3664
  // Get the parent of the content and check if it is a XBL children element.
3647
  // Get the parent of the content and check if it is a XBL children element.
3665
  // Push the children element as an ancestor here because it does
3648
  // Push the children element as an ancestor here because it does
3666
  // not have a frame and would not otherwise be pushed as an ancestor. It is
3649
  // not have a frame and would not otherwise be pushed as an ancestor. It is
3667
  // necessary to do so in order to correctly handle style resolution on
3650
  // necessary to do so in order to correctly handle style resolution on
3668
  // descendants.
3651
  // descendants.
3669
  nsIContent* parent = content->GetParent();
3670
  TreeMatchContext::AutoAncestorPusher
3652
  TreeMatchContext::AutoAncestorPusher
3671
    insertionPointPusher(aState.mTreeMatchContext);
3653
    insertionPointPusher(aState.mTreeMatchContext);
3672
  if (parent && nsContentUtils::IsContentInsertionPoint(parent)) {
3654
  if (adcp.IsEmpty() && parent && nsContentUtils::IsContentInsertionPoint(parent)) {
3673
    if (aState.mTreeMatchContext.mAncestorFilter.HasFilter()) {
3655
    if (aState.mTreeMatchContext.mAncestorFilter.HasFilter()) {
3674
      insertionPointPusher.PushAncestorAndStyleScope(parent);
3656
      insertionPointPusher.PushAncestorAndStyleScope(parent);
3675
    } else {
3657
    } else {
3676
      insertionPointPusher.PushStyleScope(parent);
3658
      insertionPointPusher.PushStyleScope(parent);
3677
    }
3659
    }
3678
  }
3660
  }
3679
3661
3680
  // Push the content as a style ancestor now, so we don't have to do
3662
  // Push the content as a style ancestor now, so we don't have to do
 Lines 3690-3705   nsCSSFrameConstructor::ConstructFrameFro Link Here 
3690
  if (aState.mTreeMatchContext.mAncestorFilter.HasFilter()) {
3672
  if (aState.mTreeMatchContext.mAncestorFilter.HasFilter()) {
3691
    ancestorPusher.PushAncestorAndStyleScope(content);
3673
    ancestorPusher.PushAncestorAndStyleScope(content);
3692
  } else {
3674
  } else {
3693
    ancestorPusher.PushStyleScope(content);
3675
    ancestorPusher.PushStyleScope(content);
3694
  }
3676
  }
3695
3677
3696
  nsIFrame* newFrame;
3678
  nsIFrame* newFrame;
3697
  nsIFrame* primaryFrame;
3679
  nsIFrame* primaryFrame;
3680
  nsStyleContext* const styleContext = aItem.mStyleContext;
3681
  const nsStyleDisplay* display = styleContext->StyleDisplay();
3698
  if (bits & FCDATA_FUNC_IS_FULL_CTOR) {
3682
  if (bits & FCDATA_FUNC_IS_FULL_CTOR) {
3699
    newFrame =
3683
    newFrame =
3700
      (this->*(data->mFullConstructor))(aState, aItem, aParentFrame,
3684
      (this->*(data->mFullConstructor))(aState, aItem, aParentFrame,
3701
                                        display, aFrameItems);
3685
                                        display, aFrameItems);
3702
    MOZ_ASSERT(newFrame, "Full constructor failed");
3686
    MOZ_ASSERT(newFrame, "Full constructor failed");
3703
    primaryFrame = newFrame;
3687
    primaryFrame = newFrame;
3704
  } else {
3688
  } else {
3705
    newFrame =
3689
    newFrame =
 Lines 4452-4475   nsCSSFrameConstructor::BuildScrollFrame( Link Here 
4452
4436
4453
const nsCSSFrameConstructor::FrameConstructionData*
4437
const nsCSSFrameConstructor::FrameConstructionData*
4454
nsCSSFrameConstructor::FindDisplayData(const nsStyleDisplay* aDisplay,
4438
nsCSSFrameConstructor::FindDisplayData(const nsStyleDisplay* aDisplay,
4455
                                       Element* aElement,
4439
                                       Element* aElement,
4456
                                       nsIFrame* aParentFrame,
4440
                                       nsIFrame* aParentFrame,
4457
                                       nsStyleContext* aStyleContext)
4441
                                       nsStyleContext* aStyleContext)
4458
{
4442
{
4459
  PR_STATIC_ASSERT(eParentTypeCount < (1 << (32 - FCDATA_PARENT_TYPE_OFFSET)));
4443
  PR_STATIC_ASSERT(eParentTypeCount < (1 << (32 - FCDATA_PARENT_TYPE_OFFSET)));
4444
  MOZ_ASSERT(aDisplay->mDisplayBox != NS_STYLE_DISPLAY_BOX_NONE);
4460
4445
4461
  // The style system ensures that floated and positioned frames are
4446
  // The style system ensures that floated and positioned frames are
4462
  // block-level.
4447
  // block-level.
4463
  NS_ASSERTION(!(aDisplay->IsFloatingStyle() ||
4448
  NS_ASSERTION(!(aDisplay->IsFloatingStyle() ||
4464
                 aDisplay->IsAbsolutelyPositionedStyle()) ||
4449
                 aDisplay->IsAbsolutelyPositionedStyle()) ||
4465
               aDisplay->IsBlockOutsideStyle(),
4450
               aDisplay->IsBlockOutsideStyle(),
4466
               "Style system did not apply CSS2.1 section 9.7 fixups");
4451
               "Style system did not apply CSS2.1 section 9.7 fixups");
4467
4452
4453
  if (aDisplay->mDisplayBox == NS_STYLE_DISPLAY_BOX_CONTENTS) {
4454
    // See the mDisplay/Box fixup code in nsRuleNode::ComputeDisplayData.
4455
    MOZ_ASSERT(!aElement->IsRootOfNativeAnonymousSubtree(),
4456
               "display-box:contents on anonymous content is unsupported");
4457
    static const FrameConstructionData sDisplayBoxContentsData =
4458
      FULL_CTOR_FCDATA(FCDATA_IS_CONTENTS, nullptr/*never called*/);
4459
    return &sDisplayBoxContentsData;
4460
  }
4461
4468
  // If this is "body", try propagating its scroll style to the viewport
4462
  // If this is "body", try propagating its scroll style to the viewport
4469
  // Note that we need to do this even if the body is NOT scrollable;
4463
  // Note that we need to do this even if the body is NOT scrollable;
4470
  // it might have dynamically changed from scrollable to not scrollable,
4464
  // it might have dynamically changed from scrollable to not scrollable,
4471
  // and that might need to be propagated.
4465
  // and that might need to be propagated.
4472
  // XXXbz is this the right place to do this?  If this code moves,
4466
  // XXXbz is this the right place to do this?  If this code moves,
4473
  // make this function static.
4467
  // make this function static.
4474
  bool propagatedScrollToViewport = false;
4468
  bool propagatedScrollToViewport = false;
4475
  if (aElement->IsHTML(nsGkAtoms::body)) {
4469
  if (aElement->IsHTML(nsGkAtoms::body)) {
 Lines 4683-4713   nsCSSFrameConstructor::InitAndRestoreFra Link Here 
4683
  }
4677
  }
4684
}
4678
}
4685
4679
4686
already_AddRefed<nsStyleContext>
4680
already_AddRefed<nsStyleContext>
4687
nsCSSFrameConstructor::ResolveStyleContext(nsIFrame*         aParentFrame,
4681
nsCSSFrameConstructor::ResolveStyleContext(nsIFrame*         aParentFrame,
4688
                                           nsIContent*       aContent,
4682
                                           nsIContent*       aContent,
4689
                                           nsFrameConstructorState* aState)
4683
                                           nsFrameConstructorState* aState)
4690
{
4684
{
4691
  nsStyleContext* parentStyleContext = nullptr;
4685
  nsIContent* container = aContent->GetParent();
4692
  NS_ASSERTION(aContent->GetParent(), "Must have parent here");
4686
  NS_ASSERTION(container, "Must have parent here");
4693
4687
  nsStyleContext* parentStyleContext = GetDisplayBoxContentsStyleFor(container);
4694
  aParentFrame = nsFrame::CorrectStyleParentFrame(aParentFrame, nullptr);
4688
  if (MOZ_LIKELY(!parentStyleContext)) {
4695
4689
    aParentFrame = nsFrame::CorrectStyleParentFrame(aParentFrame, nullptr);
4696
  if (aParentFrame) {
4690
    if (aParentFrame) {
4697
    // Resolve the style context based on the content object and the parent
4691
      // Resolve the style context based on the content object and the parent
4698
    // style context
4692
      // style context
4699
    parentStyleContext = aParentFrame->StyleContext();
4693
      parentStyleContext = aParentFrame->StyleContext();
4700
  } else {
4694
    } else {
4701
    // Perhaps aParentFrame is a canvasFrame and we're replicating
4695
      // Perhaps aParentFrame is a canvasFrame and we're replicating
4702
    // fixed-pos frames.
4696
      // fixed-pos frames.
4703
    // XXX should we create a way to tell ConstructFrame which style
4697
      // XXX should we create a way to tell ConstructFrame which style
4704
    // context to use, and pass it the style context for the
4698
      // context to use, and pass it the style context for the
4705
    // previous page's fixed-pos frame?
4699
      // previous page's fixed-pos frame?
4700
    }
4706
  }
4701
  }
4707
4702
4708
  return ResolveStyleContext(parentStyleContext, aContent, aState);
4703
  return ResolveStyleContext(parentStyleContext, aContent, aState);
4709
}
4704
}
4710
4705
4711
already_AddRefed<nsStyleContext>
4706
already_AddRefed<nsStyleContext>
4712
nsCSSFrameConstructor::ResolveStyleContext(nsStyleContext* aParentStyleContext,
4707
nsCSSFrameConstructor::ResolveStyleContext(nsStyleContext* aParentStyleContext,
4713
                                           nsIContent* aContent,
4708
                                           nsIContent* aContent,
 Lines 5203-5224   nsCSSFrameConstructor::AddPageBreakItem( Link Here 
5203
5198
5204
  // Lie about the tag and namespace so we don't trigger anything
5199
  // Lie about the tag and namespace so we don't trigger anything
5205
  // interesting during frame construction.
5200
  // interesting during frame construction.
5206
  aItems.AppendItem(&sPageBreakData, aContent, nsCSSAnonBoxes::pageBreak,
5201
  aItems.AppendItem(&sPageBreakData, aContent, nsCSSAnonBoxes::pageBreak,
5207
                    kNameSpaceID_None, nullptr, pseudoStyle.forget(),
5202
                    kNameSpaceID_None, nullptr, pseudoStyle.forget(),
5208
                    true, nullptr);
5203
                    true, nullptr);
5209
}
5204
}
5210
5205
5211
void
5206
bool
5212
nsCSSFrameConstructor::AddFrameConstructionItems(nsFrameConstructorState& aState,
5207
nsCSSFrameConstructor::ShouldCreateItemsForChild(nsFrameConstructorState& aState,
5213
                                                 nsIContent* aContent,
5208
                                                 nsIContent* aContent,
5214
                                                 bool aSuppressWhiteSpaceOptimizations,
5209
                                                 nsContainerFrame* aParentFrame)
5215
                                                 nsContainerFrame* aParentFrame,
5216
                                                 FrameConstructionItemList& aItems)
5217
{
5210
{
5218
  aContent->UnsetFlags(NODE_DESCENDANTS_NEED_FRAMES | NODE_NEEDS_FRAME);
5211
  aContent->UnsetFlags(NODE_DESCENDANTS_NEED_FRAMES | NODE_NEEDS_FRAME);
5219
  if (aContent->IsElement()) {
5212
  if (aContent->IsElement()) {
5220
    // We can't just remove our pending restyle flags, since we may
5213
    // We can't just remove our pending restyle flags, since we may
5221
    // have restyle-later-siblings set on us.  But we _can_ remove the
5214
    // have restyle-later-siblings set on us.  But we _can_ remove the
5222
    // "is possible restyle root" flags, and need to.  Otherwise we can
5215
    // "is possible restyle root" flags, and need to.  Otherwise we can
5223
    // end up with stale such flags (e.g. if we used to have a
5216
    // end up with stale such flags (e.g. if we used to have a
5224
    // display:none parent when our last restyle was posted and
5217
    // display:none parent when our last restyle was posted and
 Lines 5229-5276   nsCSSFrameConstructor::AddFrameConstruct Link Here 
5229
5222
5230
  // XXX the GetContent() != aContent check is needed due to bug 135040.
5223
  // XXX the GetContent() != aContent check is needed due to bug 135040.
5231
  // Remove it once that's fixed.
5224
  // Remove it once that's fixed.
5232
  if (aContent->GetPrimaryFrame() &&
5225
  if (aContent->GetPrimaryFrame() &&
5233
      aContent->GetPrimaryFrame()->GetContent() == aContent &&
5226
      aContent->GetPrimaryFrame()->GetContent() == aContent &&
5234
      !aState.mCreatingExtraFrames) {
5227
      !aState.mCreatingExtraFrames) {
5235
    NS_ERROR("asked to create frame construction item for a node that already "
5228
    NS_ERROR("asked to create frame construction item for a node that already "
5236
             "has a frame");
5229
             "has a frame");
5237
    return;
5230
    return false;
5238
  }
5231
  }
5239
5232
5240
  // don't create a whitespace frame if aParent doesn't want it
5233
  // don't create a whitespace frame if aParent doesn't want it
5241
  if (!NeedFrameFor(aState, aParentFrame, aContent)) {
5234
  if (!NeedFrameFor(aState, aParentFrame, aContent)) {
5242
    return;
5235
    return false;
5243
  }
5236
  }
5244
5237
5245
  // never create frames for comments or PIs
5238
  // never create frames for comments or PIs
5246
  if (aContent->IsNodeOfType(nsINode::eCOMMENT) ||
5239
  if (aContent->IsNodeOfType(nsINode::eCOMMENT) ||
5247
      aContent->IsNodeOfType(nsINode::ePROCESSING_INSTRUCTION))
5240
      aContent->IsNodeOfType(nsINode::ePROCESSING_INSTRUCTION)) {
5248
    return;
5241
    return false;
5249
5242
  }
5250
  nsRefPtr<nsStyleContext> styleContext;
5243
5251
  styleContext = ResolveStyleContext(aParentFrame, aContent, &aState);
5244
  return true;
5252
5245
}
5246
5247
void
5248
nsCSSFrameConstructor::DoAddFrameConstructionItems(nsFrameConstructorState& aState,
5249
                                                   nsIContent* aContent,
5250
                                                   nsStyleContext* aStyleContext,
5251
                                                   bool aSuppressWhiteSpaceOptimizations,
5252
                                                   nsContainerFrame* aParentFrame,
5253
                                                   nsTArray<nsIAnonymousContentCreator::ContentInfo>* aAnonChildren,
5254
                                                   FrameConstructionItemList& aItems)
5255
{
5253
  uint32_t flags = ITEM_ALLOW_XBL_BASE | ITEM_ALLOW_PAGE_BREAK;
5256
  uint32_t flags = ITEM_ALLOW_XBL_BASE | ITEM_ALLOW_PAGE_BREAK;
5254
  if (aParentFrame->IsSVGText()) {
5257
  if (aParentFrame) {
5255
    flags |= ITEM_IS_WITHIN_SVG_TEXT;
5258
    if (aParentFrame->IsSVGText()) {
5256
  }
5259
      flags |= ITEM_IS_WITHIN_SVG_TEXT;
5257
  if (aParentFrame->GetType() == nsGkAtoms::blockFrame &&
5260
    }
5258
      aParentFrame->GetParent() &&
5261
    if (aParentFrame->GetType() == nsGkAtoms::blockFrame &&
5259
      aParentFrame->GetParent()->GetType() == nsGkAtoms::svgTextFrame) {
5262
        aParentFrame->GetParent() &&
5260
    flags |= ITEM_ALLOWS_TEXT_PATH_CHILD;
5263
        aParentFrame->GetParent()->GetType() == nsGkAtoms::svgTextFrame) {
5264
      flags |= ITEM_ALLOWS_TEXT_PATH_CHILD;
5265
    }
5261
  }
5266
  }
5262
  AddFrameConstructionItemsInternal(aState, aContent, aParentFrame,
5267
  AddFrameConstructionItemsInternal(aState, aContent, aParentFrame,
5263
                                    aContent->Tag(), aContent->GetNameSpaceID(),
5268
                                    aContent->Tag(), aContent->GetNameSpaceID(),
5264
                                    aSuppressWhiteSpaceOptimizations,
5269
                                    aSuppressWhiteSpaceOptimizations,
5265
                                    styleContext,
5270
                                    aStyleContext,
5266
                                    flags, nullptr,
5271
                                    flags, aAnonChildren,
5267
                                    aItems);
5272
                                    aItems);
5268
}
5273
}
5274
  
5275
void
5276
nsCSSFrameConstructor::AddFrameConstructionItems(nsFrameConstructorState& aState,
5277
                                                 nsIContent* aContent,
5278
                                                 bool aSuppressWhiteSpaceOptimizations,
5279
                                                 nsContainerFrame* aParentFrame,
5280
                                                 FrameConstructionItemList& aItems)
5281
{
5282
  if (!ShouldCreateItemsForChild(aState, aContent, aParentFrame)) {
5283
    return;
5284
  }
5285
  nsRefPtr<nsStyleContext> styleContext =
5286
    ResolveStyleContext(aParentFrame, aContent, &aState);
5287
  DoAddFrameConstructionItems(aState, aContent, styleContext,
5288
                              aSuppressWhiteSpaceOptimizations, aParentFrame,
5289
                              nullptr, aItems);
5290
}
5269
5291
5270
/* static */ void
5292
/* static */ void
5271
nsCSSFrameConstructor::SetAsUndisplayedContent(FrameConstructionItemList& aList,
5293
nsCSSFrameConstructor::SetAsUndisplayedContent(FrameConstructionItemList& aList,
5272
                                               nsIContent* aContent,
5294
                                               nsIContent* aContent,
5273
                                               nsStyleContext* aStyleContext,
5295
                                               nsStyleContext* aStyleContext,
5274
                                               bool aIsGeneratedContent)
5296
                                               bool aIsGeneratedContent)
5275
{
5297
{
5276
  if (aStyleContext->GetPseudo()) {
5298
  if (aStyleContext->GetPseudo()) {
 Lines 5338-5356   nsCSSFrameConstructor::AddFrameConstruct Link Here 
5338
      aStyleContext = styleContext;
5360
      aStyleContext = styleContext;
5339
    }
5361
    }
5340
5362
5341
    aTag = mDocument->BindingManager()->ResolveTag(aContent, &aNameSpaceID);
5363
    aTag = mDocument->BindingManager()->ResolveTag(aContent, &aNameSpaceID);
5342
  }
5364
  }
5343
5365
5344
  bool isGeneratedContent = ((aFlags & ITEM_IS_GENERATED_CONTENT) != 0);
5366
  bool isGeneratedContent = ((aFlags & ITEM_IS_GENERATED_CONTENT) != 0);
5345
5367
5346
  // Pre-check for display "none" - if we find that, don't create
5368
  // Pre-check for display-box:none - if we find that, don't create any frame at all.
5347
  // any frame at all
5369
  if (NS_STYLE_DISPLAY_BOX_NONE == display->mDisplayBox) {
5348
  if (NS_STYLE_DISPLAY_NONE == display->mDisplay) {
5349
    SetAsUndisplayedContent(aItems, aContent, styleContext, isGeneratedContent);
5370
    SetAsUndisplayedContent(aItems, aContent, styleContext, isGeneratedContent);
5350
    return;
5371
    return;
5351
  }
5372
  }
5352
5373
5353
  bool isText = !aContent->IsElement();
5374
  bool isText = !aContent->IsElement();
5354
5375
5355
  // never create frames for non-option/optgroup kids of <select> and
5376
  // never create frames for non-option/optgroup kids of <select> and
5356
  // non-option kids of <optgroup> inside a <select>.
5377
  // non-option kids of <optgroup> inside a <select>.
 Lines 5465-5480   nsCSSFrameConstructor::AddFrameConstruct Link Here 
5465
    !display->IsAbsolutelyPositionedStyle() &&
5486
    !display->IsAbsolutelyPositionedStyle() &&
5466
    !(bits & FCDATA_IS_TABLE_PART) &&
5487
    !(bits & FCDATA_IS_TABLE_PART) &&
5467
    !(bits & FCDATA_IS_SVG_TEXT);
5488
    !(bits & FCDATA_IS_SVG_TEXT);
5468
5489
5469
  if (canHavePageBreak && display->mBreakBefore) {
5490
  if (canHavePageBreak && display->mBreakBefore) {
5470
    AddPageBreakItem(aContent, aStyleContext, aItems);
5491
    AddPageBreakItem(aContent, aStyleContext, aItems);
5471
  }
5492
  }
5472
5493
5494
  if (MOZ_UNLIKELY(bits & FCDATA_IS_CONTENTS)) {
5495
    if (!GetDisplayBoxContentsStyleFor(aContent)) {
5496
      MOZ_ASSERT(styleContext->GetPseudo() || !isGeneratedContent,
5497
                 "Should have had pseudo type");
5498
      aState.mFrameManager->SetDisplayBoxContents(aContent, styleContext);
5499
    } else {
5500
      aState.mFrameManager->ChangeDisplayBoxContents(aContent, styleContext);
5501
    }
5502
5503
    TreeMatchContext::AutoAncestorPusher ancestorPusher(aState.mTreeMatchContext);
5504
    if (aState.mTreeMatchContext.mAncestorFilter.HasFilter()) {
5505
      ancestorPusher.PushAncestorAndStyleScope(aContent->AsElement());
5506
    } else {
5507
      ancestorPusher.PushStyleScope(aContent->AsElement());
5508
    }
5509
5510
    if (aParentFrame) {
5511
      aParentFrame->AddStateBits(NS_FRAME_MAY_HAVE_GENERATED_CONTENT);
5512
    }
5513
    CreateGeneratedContentItem(aState, aParentFrame, aContent, styleContext,
5514
                               nsCSSPseudoElements::ePseudo_before, aItems);
5515
5516
    FlattenedChildIterator iter(aContent);
5517
    for (nsIContent* child = iter.GetNextChild(); child; child = iter.GetNextChild()) {
5518
      if (!ShouldCreateItemsForChild(aState, child, aParentFrame)) {
5519
        continue;
5520
      }
5521
5522
      // Get the parent of the content and check if it is a XBL children element
5523
      // (if the content is a children element then parent != aContent because the
5524
      // FlattenedChildIterator will transitively iterate through <xbl:children>
5525
      // for default content). Push the children element as an ancestor here because
5526
      // it does not have a frame and would not otherwise be pushed as an ancestor.
5527
      nsIContent* parent = child->GetParent();
5528
      MOZ_ASSERT(parent, "Parent must be non-null because we are iterating children.");
5529
      TreeMatchContext::AutoAncestorPusher ancestorPusher(aState.mTreeMatchContext);
5530
      if (parent != aContent && parent->IsElement()) {
5531
        if (aState.mTreeMatchContext.mAncestorFilter.HasFilter()) {
5532
          ancestorPusher.PushAncestorAndStyleScope(parent->AsElement());
5533
        } else {
5534
          ancestorPusher.PushStyleScope(parent->AsElement());
5535
        }
5536
      }
5537
5538
      nsRefPtr<nsStyleContext> childContext =
5539
        ResolveStyleContext(styleContext, child, nullptr);
5540
      DoAddFrameConstructionItems(aState, child, childContext,
5541
                                  aSuppressWhiteSpaceOptimizations,
5542
                                  aParentFrame, aAnonChildren, aItems);
5543
    }
5544
    aItems.SetParentHasNoXBLChildren(!iter.XBLInvolved());
5545
5546
    CreateGeneratedContentItem(aState, aParentFrame, aContent, styleContext,
5547
                               nsCSSPseudoElements::ePseudo_after, aItems);
5548
    if (canHavePageBreak && display->mBreakAfter) {
5549
      AddPageBreakItem(aContent, aStyleContext, aItems);
5550
    }
5551
    return;
5552
  }
5553
5473
  FrameConstructionItem* item =
5554
  FrameConstructionItem* item =
5474
    aItems.AppendItem(data, aContent, aTag, aNameSpaceID,
5555
    aItems.AppendItem(data, aContent, aTag, aNameSpaceID,
5475
                      pendingBinding, styleContext.forget(),
5556
                      pendingBinding, styleContext.forget(),
5476
                      aSuppressWhiteSpaceOptimizations, aAnonChildren);
5557
                      aSuppressWhiteSpaceOptimizations, aAnonChildren);
5477
  if (!item) {
5558
  if (!item) {
5478
    if (isGeneratedContent) {
5559
    if (isGeneratedContent) {
5479
      aContent->UnbindFromTree();
5560
      aContent->UnbindFromTree();
5480
    }
5561
    }
 Lines 5571-5604   nsCSSFrameConstructor::AddFrameConstruct Link Here 
5571
      ((bits & FCDATA_DISALLOW_OUT_OF_FLOW) ||
5652
      ((bits & FCDATA_DISALLOW_OUT_OF_FLOW) ||
5572
       !aState.GetGeometricParent(display, nullptr))) {
5653
       !aState.GetGeometricParent(display, nullptr))) {
5573
    item->mIsLineParticipant = true;
5654
    item->mIsLineParticipant = true;
5574
    aItems.LineParticipantItemAdded();
5655
    aItems.LineParticipantItemAdded();
5575
  }
5656
  }
5576
}
5657
}
5577
5658
5578
static void
5659
static void
5579
DestroyContent(void* aPropertyValue)
5660
AddGenConPseudoToFrame(nsIFrame* aOwnerFrame, nsIContent* aContent)
5580
{
5661
{
5581
  nsIContent* content = static_cast<nsIContent*>(aPropertyValue);
5662
  typedef nsAutoTArray<nsIContent*, 2> T;
5582
  content->UnbindFromTree();
5663
  const FramePropertyDescriptor* prop = nsIFrame::GenConProperty();
5583
  NS_RELEASE(content);
5664
  FrameProperties props = aOwnerFrame->Properties();
5584
}
5665
  T* value = static_cast<T*>(props.Get(prop));
5585
5666
  if (!value) {
5586
NS_DECLARE_FRAME_PROPERTY(BeforeProperty, DestroyContent)
5667
    value = new T;
5587
NS_DECLARE_FRAME_PROPERTY(AfterProperty, DestroyContent)
5668
    props.Set(prop, value);
5588
5669
  }
5589
static const FramePropertyDescriptor*
5670
  value->AppendElement(aContent);
5590
GenConPseudoToProperty(nsIAtom* aPseudo)
5591
{
5592
  NS_ASSERTION(aPseudo == nsCSSPseudoElements::before ||
5593
               aPseudo == nsCSSPseudoElements::after,
5594
               "Bad gen-con pseudo");
5595
  return aPseudo == nsCSSPseudoElements::before ? BeforeProperty()
5596
      : AfterProperty();
5597
}
5671
}
5598
5672
5599
/**
5673
/**
5600
 * Return true if the frame construction item pointed to by aIter will
5674
 * Return true if the frame construction item pointed to by aIter will
5601
 * create a frame adjacent to a line boundary in the frame tree, and that
5675
 * create a frame adjacent to a line boundary in the frame tree, and that
5602
 * line boundary is induced by a content node adjacent to the frame's
5676
 * line boundary is induced by a content node adjacent to the frame's
5603
 * content node in the content tree. The latter condition is necessary so
5677
 * content node in the content tree. The latter condition is necessary so
5604
 * that ContentAppended/ContentInserted/ContentRemoved can easily find any
5678
 * that ContentAppended/ContentInserted/ContentRemoved can easily find any
 Lines 5692-5709   nsCSSFrameConstructor::ConstructFramesFr Link Here 
5692
    // NS_FRAME_GENERATED_CONTENT.
5766
    // NS_FRAME_GENERATED_CONTENT.
5693
    aState.mAdditionalStateBits |= NS_FRAME_GENERATED_CONTENT;
5767
    aState.mAdditionalStateBits |= NS_FRAME_GENERATED_CONTENT;
5694
5768
5695
    // Note that we're not necessarily setting this property on the primary
5769
    // Note that we're not necessarily setting this property on the primary
5696
    // frame for the content for which this is generated content.  We might be
5770
    // frame for the content for which this is generated content.  We might be
5697
    // setting it on a table pseudo-frame inserted under that instead.  That's
5771
    // setting it on a table pseudo-frame inserted under that instead.  That's
5698
    // OK, though; we just need to do the property set so that the content will
5772
    // OK, though; we just need to do the property set so that the content will
5699
    // get cleaned up when the frame is destroyed.
5773
    // get cleaned up when the frame is destroyed.
5700
    aParentFrame->Properties().Set(GenConPseudoToProperty(styleContext->GetPseudo()),
5774
    ::AddGenConPseudoToFrame(aParentFrame, item.mContent);
5701
                                   item.mContent);
5702
5775
5703
    // Now that we've passed ownership of item.mContent to the frame, unset
5776
    // Now that we've passed ownership of item.mContent to the frame, unset
5704
    // our generated content flag so we don't release or unbind it ourselves.
5777
    // our generated content flag so we don't release or unbind it ourselves.
5705
    item.mIsGeneratedContent = false;
5778
    item.mIsGeneratedContent = false;
5706
  }
5779
  }
5707
5780
5708
  // XXXbz maybe just inline ConstructFrameFromItemInternal here or something?
5781
  // XXXbz maybe just inline ConstructFrameFromItemInternal here or something?
5709
  ConstructFrameFromItemInternal(item, aState, adjParentFrame, aFrameItems);
5782
  ConstructFrameFromItemInternal(item, aState, adjParentFrame, aFrameItems);
 Lines 5827-5857   nsCSSFrameConstructor::GetFloatContainin Link Here 
5827
5900
5828
/**
5901
/**
5829
 * This function will check whether aContainer has :after generated content.
5902
 * This function will check whether aContainer has :after generated content.
5830
 * If so, appending to it should actually insert.  The return value is the
5903
 * If so, appending to it should actually insert.  The return value is the
5831
 * parent to use for newly-appended content.  *aAfterFrame points to the :after
5904
 * parent to use for newly-appended content.  *aAfterFrame points to the :after
5832
 * frame before which appended content should go, if there is one.
5905
 * frame before which appended content should go, if there is one.
5833
 */
5906
 */
5834
static nsContainerFrame*
5907
static nsContainerFrame*
5835
AdjustAppendParentForAfterContent(nsPresContext* aPresContext,
5908
AdjustAppendParentForAfterContent(nsFrameManager* aFrameManager,
5836
                                  nsIContent* aContainer,
5909
                                  nsIContent* aContainer,
5837
                                  nsContainerFrame* aParentFrame,
5910
                                  nsContainerFrame* aParentFrame,
5911
                                  nsIContent* aChild,
5838
                                  nsIFrame** aAfterFrame)
5912
                                  nsIFrame** aAfterFrame)
5839
{
5913
{
5840
  // See if the parent has an :after pseudo-element.  Check for the presence
5914
  // If the parent frame has any pseudo-elements or aContainer is a
5841
  // of style first, since nsLayoutUtils::GetAfterFrame is sorta expensive.
5915
  // display-box:contents node then we need to walk through the child
5842
  nsStyleContext* parentStyle = aParentFrame->StyleContext();
5916
  // frames to find the first one that is either a ::after frame for an
5843
  if (nsLayoutUtils::HasPseudoStyle(aContainer, parentStyle,
5917
  // ancestor of aChild or a frame that is for a node later in the
5918
  // document than aChild and return that in aAfterFrame.
5919
  if (aParentFrame->GetGenConPseudos() ||
5920
      nsLayoutUtils::HasPseudoStyle(aContainer, aParentFrame->StyleContext(),
5844
                                    nsCSSPseudoElements::ePseudo_after,
5921
                                    nsCSSPseudoElements::ePseudo_after,
5845
                                    aPresContext)) {
5922
                                    aParentFrame->PresContext()) ||
5846
    // Ensure that the :after frame is on the principal child list.
5923
      aFrameManager->GetDisplayBoxContentsStyleFor(aContainer)) {
5847
    aParentFrame->DrainSelfOverflowList();
5924
    nsIFrame* afterFrame = nullptr;
5848
5925
    nsContainerFrame* parent =
5849
    nsIFrame* afterFrame = nsLayoutUtils::GetAfterFrame(aParentFrame);
5926
      static_cast<nsContainerFrame*>(aParentFrame->LastContinuation());
5927
    bool done = false;
5928
    while (!done && parent) {
5929
      // Ensure that all normal flow children are on the principal child list.
5930
      parent->DrainSelfOverflowList();
5931
5932
      nsIFrame* child = parent->GetLastChild(nsIFrame::kPrincipalList);
5933
      if (child && child->IsPseudoFrame(aContainer) &&
5934
          !child->IsGeneratedContentFrame()) {
5935
        // Drill down into non-generated pseudo frames of aContainer.
5936
        parent = nsLayoutUtils::LastContinuationWithChild(do_QueryFrame(child));
5937
        continue;
5938
      }
5939
5940
      for (; child; child = child->GetPrevSibling()) {
5941
        nsIContent* c = child->GetContent();
5942
        if (child->IsGeneratedContentFrame()) {
5943
          nsIContent* p = c->GetParent();
5944
          if (c->Tag() == nsGkAtoms::mozgeneratedcontentafter) {
5945
            if (!nsContentUtils::ContentIsDescendantOf(aChild, p) &&
5946
                c->GetBindingParent() != aContainer &&
5947
                nsContentUtils::PositionIsBefore(p, aChild)) {
5948
              // ::after generated content for content earlier in the doc and not
5949
              // for an ancestor.
5950
              done = true;
5951
              break;
5952
            }
5953
          } else if (nsContentUtils::PositionIsBefore(p, aChild)) {
5954
            // Non-::after generated content for content earlier in the doc.
5955
            done = true;
5956
            break;
5957
          }
5958
        } else if (nsContentUtils::PositionIsBefore(c, aChild)) {
5959
          // Content is before aChild.
5960
          done = true;
5961
          break;
5962
        }
5963
        afterFrame = child;
5964
      }
5965
5966
      parent = static_cast<nsContainerFrame*>(parent->GetPrevContinuation());
5967
    }
5850
    if (afterFrame) {
5968
    if (afterFrame) {
5851
      *aAfterFrame = afterFrame;
5969
      *aAfterFrame = afterFrame;
5852
      return afterFrame->GetParent();
5970
      return afterFrame->GetParent();
5853
    }
5971
    }
5854
  }
5972
  }
5855
5973
5856
  *aAfterFrame = nullptr;
5974
  *aAfterFrame = nullptr;
5857
5975
 Lines 6036-6060   nsCSSFrameConstructor::IsValidSibling(ns Link Here 
6036
      (NS_STYLE_DISPLAY_TABLE_COLUMN       == siblingDisplay) ||
6154
      (NS_STYLE_DISPLAY_TABLE_COLUMN       == siblingDisplay) ||
6037
      (NS_STYLE_DISPLAY_TABLE_CAPTION      == siblingDisplay) ||
6155
      (NS_STYLE_DISPLAY_TABLE_CAPTION      == siblingDisplay) ||
6038
      (NS_STYLE_DISPLAY_TABLE_HEADER_GROUP == siblingDisplay) ||
6156
      (NS_STYLE_DISPLAY_TABLE_HEADER_GROUP == siblingDisplay) ||
6039
      (NS_STYLE_DISPLAY_TABLE_ROW_GROUP    == siblingDisplay) ||
6157
      (NS_STYLE_DISPLAY_TABLE_ROW_GROUP    == siblingDisplay) ||
6040
      (NS_STYLE_DISPLAY_TABLE_FOOTER_GROUP == siblingDisplay) ||
6158
      (NS_STYLE_DISPLAY_TABLE_FOOTER_GROUP == siblingDisplay) ||
6041
      nsGkAtoms::menuFrame == parentType) {
6159
      nsGkAtoms::menuFrame == parentType) {
6042
    // if we haven't already, construct a style context to find the display type of aContent
6160
    // if we haven't already, construct a style context to find the display type of aContent
6043
    if (UNSET_DISPLAY == aDisplay) {
6161
    if (UNSET_DISPLAY == aDisplay) {
6044
      nsRefPtr<nsStyleContext> styleContext;
6162
      nsIFrame* styleParent;
6045
      nsIFrame* styleParent = aSibling->GetParentStyleContextFrame();
6163
      aSibling->GetParentStyleContext(&styleParent);
6164
      if (!styleParent) {
6165
        styleParent = aSibling->GetParent();
6166
      }
6046
      if (!styleParent) {
6167
      if (!styleParent) {
6047
        NS_NOTREACHED("Shouldn't happen");
6168
        NS_NOTREACHED("Shouldn't happen");
6048
        return false;
6169
        return false;
6049
      }
6170
      }
6050
      // XXXbz when this code is killed, the state argument to
6171
      // XXXbz when this code is killed, the state argument to
6051
      // ResolveStyleContext can be made non-optional.
6172
      // ResolveStyleContext can be made non-optional.
6052
      styleContext = ResolveStyleContext(styleParent, aContent, nullptr);
6173
      nsRefPtr<nsStyleContext> styleContext =
6174
        ResolveStyleContext(styleParent, aContent, nullptr);
6053
      const nsStyleDisplay* display = styleContext->StyleDisplay();
6175
      const nsStyleDisplay* display = styleContext->StyleDisplay();
6054
      aDisplay = display->mDisplay;
6176
      aDisplay = display->mDisplay;
6055
    }
6177
    }
6056
    if (nsGkAtoms::menuFrame == parentType) {
6178
    if (nsGkAtoms::menuFrame == parentType) {
6057
      return
6179
      return
6058
        (NS_STYLE_DISPLAY_POPUP == aDisplay) ==
6180
        (NS_STYLE_DISPLAY_POPUP == aDisplay) ==
6059
        (NS_STYLE_DISPLAY_POPUP == siblingDisplay);
6181
        (NS_STYLE_DISPLAY_POPUP == siblingDisplay);
6060
    }
6182
    }
 Lines 6222-6238   nsCSSFrameConstructor::GetInsertionPrevS Link Here 
6222
  *aIsAppend = false;
6344
  *aIsAppend = false;
6223
6345
6224
  // Find the frame that precedes the insertion point. Walk backwards
6346
  // Find the frame that precedes the insertion point. Walk backwards
6225
  // from the parent frame to get the parent content, because if an
6347
  // from the parent frame to get the parent content, because if an
6226
  // XBL insertion point is involved, we'll need to use _that_ to find
6348
  // XBL insertion point is involved, we'll need to use _that_ to find
6227
  // the preceding frame.
6349
  // the preceding frame.
6228
6350
6229
  NS_PRECONDITION(aParentFrame, "Must have parent frame to start with");
6351
  NS_PRECONDITION(aParentFrame, "Must have parent frame to start with");
6230
  nsIContent* container = aParentFrame->GetContent();
6352
  const bool boxContents = GetDisplayBoxContentsStyleFor(aContainer);
6353
  nsIContent* container = boxContents ? aContainer : aParentFrame->GetContent();
6231
6354
6232
  FlattenedChildIterator iter(container);
6355
  FlattenedChildIterator iter(container);
6233
  bool xblCase = iter.XBLInvolved() || container != aContainer;
6356
  bool xblCase = iter.XBLInvolved() || container != aContainer;
6234
  if (xblCase || !aChild->IsRootOfAnonymousSubtree()) {
6357
  if (xblCase || !aChild->IsRootOfAnonymousSubtree()) {
6235
    // The check for IsRootOfAnonymousSubtree() is because editor is
6358
    // The check for IsRootOfAnonymousSubtree() is because editor is
6236
    // severely broken and calls us directly for native anonymous
6359
    // severely broken and calls us directly for native anonymous
6237
    // nodes that it creates.
6360
    // nodes that it creates.
6238
    if (aStartSkipChild) {
6361
    if (aStartSkipChild) {
 Lines 6252-6280   nsCSSFrameConstructor::GetInsertionPrevS Link Here 
6252
  uint8_t childDisplay = UNSET_DISPLAY;
6375
  uint8_t childDisplay = UNSET_DISPLAY;
6253
  nsIFrame* prevSibling = FindPreviousSibling(iter, childDisplay);
6376
  nsIFrame* prevSibling = FindPreviousSibling(iter, childDisplay);
6254
6377
6255
  // Now, find the geometric parent so that we can handle
6378
  // Now, find the geometric parent so that we can handle
6256
  // continuations properly. Use the prev sibling if we have it;
6379
  // continuations properly. Use the prev sibling if we have it;
6257
  // otherwise use the next sibling.
6380
  // otherwise use the next sibling.
6258
  if (prevSibling) {
6381
  if (prevSibling) {
6259
    aParentFrame = prevSibling->GetParent()->GetContentInsertionFrame();
6382
    aParentFrame = prevSibling->GetParent()->GetContentInsertionFrame();
6260
  }
6383
  } else {
6261
  else {
6262
    // If there is no previous sibling, then find the frame that follows
6384
    // If there is no previous sibling, then find the frame that follows
6263
    if (aEndSkipChild) {
6385
    if (aEndSkipChild) {
6264
      iter.Seek(aEndSkipChild);
6386
      iter.Seek(aEndSkipChild);
6265
      iter.GetPreviousChild();
6387
      iter.GetPreviousChild();
6266
    }
6388
    }
6267
    nsIFrame* nextSibling = FindNextSibling(iter, childDisplay);
6389
    nsIFrame* nextSibling = FindNextSibling(iter, childDisplay);
6268
6390
    if (boxContents) {
6391
      if (nextSibling) {
6392
        aParentFrame = nextSibling->GetParent()->GetContentInsertionFrame();
6393
        return nextSibling->GetPrevSibling();
6394
      }
6395
      return GetInsertionPrevSibling(aParentFrame, aContainer->GetParent(),
6396
                                     aContainer, aIsAppend,
6397
                                     aIsRangeInsertSafe, nullptr, nullptr);
6398
    }
6269
    if (nextSibling) {
6399
    if (nextSibling) {
6270
      aParentFrame = nextSibling->GetParent()->GetContentInsertionFrame();
6400
      aParentFrame = nextSibling->GetParent()->GetContentInsertionFrame();
6271
    }
6401
    } else {
6272
    else {
6273
      // No previous or next sibling, so treat this like an appended frame.
6402
      // No previous or next sibling, so treat this like an appended frame.
6274
      *aIsAppend = true;
6403
      *aIsAppend = true;
6275
      if (IsFramePartOfIBSplit(aParentFrame)) {
6404
      if (IsFramePartOfIBSplit(aParentFrame)) {
6276
        // Since we're appending, we'll walk to the last anonymous frame
6405
        // Since we're appending, we'll walk to the last anonymous frame
6277
        // that was created for the broken inline frame.  But don't walk
6406
        // that was created for the broken inline frame.  But don't walk
6278
        // to the trailing inline if it's empty; stop at the block.
6407
        // to the trailing inline if it's empty; stop at the block.
6279
        aParentFrame = GetLastIBSplitSibling(aParentFrame, false);
6408
        aParentFrame = GetLastIBSplitSibling(aParentFrame, false);
6280
      }
6409
      }
 Lines 6282-6308   nsCSSFrameConstructor::GetInsertionPrevS Link Here 
6282
      // before the AdjustAppendParentForAfterContent call.
6411
      // before the AdjustAppendParentForAfterContent call.
6283
      aParentFrame = nsLayoutUtils::LastContinuationWithChild(aParentFrame);
6412
      aParentFrame = nsLayoutUtils::LastContinuationWithChild(aParentFrame);
6284
      // Deal with fieldsets
6413
      // Deal with fieldsets
6285
      aParentFrame = ::GetAdjustedParentFrame(aParentFrame,
6414
      aParentFrame = ::GetAdjustedParentFrame(aParentFrame,
6286
                                              aParentFrame->GetType(),
6415
                                              aParentFrame->GetType(),
6287
                                              aChild);
6416
                                              aChild);
6288
      nsIFrame* appendAfterFrame;
6417
      nsIFrame* appendAfterFrame;
6289
      aParentFrame =
6418
      aParentFrame =
6290
        ::AdjustAppendParentForAfterContent(mPresShell->GetPresContext(),
6419
        ::AdjustAppendParentForAfterContent(this, container, aParentFrame,
6291
                                            container, aParentFrame,
6420
                                            aChild, &appendAfterFrame);
6292
                                            &appendAfterFrame);
6293
      prevSibling = ::FindAppendPrevSibling(aParentFrame, appendAfterFrame);
6421
      prevSibling = ::FindAppendPrevSibling(aParentFrame, appendAfterFrame);
6294
    }
6422
    }
6295
  }
6423
  }
6296
6424
6297
  *aIsRangeInsertSafe = (childDisplay == UNSET_DISPLAY);
6425
  *aIsRangeInsertSafe = (childDisplay == UNSET_DISPLAY);
6298
  return prevSibling;
6426
  return prevSibling;
6299
}
6427
}
6300
6428
6429
nsContainerFrame*
6430
nsCSSFrameConstructor::GetContentInsertionFrameFor(nsIContent* aContent)
6431
{
6432
  // Get the primary frame associated with the content
6433
  nsIFrame* frame = aContent->GetPrimaryFrame();
6434
6435
  if (!frame) {
6436
    if (GetDisplayBoxContentsStyleFor(aContent)) {
6437
      nsIContent* parent = aContent->GetParent();
6438
      frame = parent ? GetContentInsertionFrameFor(parent) : nullptr;
6439
    }
6440
    if (!frame) {
6441
      return nullptr;
6442
    }
6443
  } else {
6444
    // If the content of the frame is not the desired content then this is not
6445
    // really a frame for the desired content.
6446
    // XXX This check is needed due to bug 135040. Remove it once that's fixed.
6447
    if (frame->GetContent() != aContent) {
6448
      return nullptr;
6449
    }
6450
  }
6451
6452
  nsContainerFrame* insertionFrame = frame->GetContentInsertionFrame();
6453
6454
  NS_ASSERTION(!insertionFrame || insertionFrame == frame || !frame->IsLeaf(),
6455
    "The insertion frame is the primary frame or the primary frame isn't a leaf");
6456
6457
  return insertionFrame;
6458
}
6459
6301
static bool
6460
static bool
6302
IsSpecialFramesetChild(nsIContent* aContent)
6461
IsSpecialFramesetChild(nsIContent* aContent)
6303
{
6462
{
6304
  // IMPORTANT: This must match the conditions in nsHTMLFramesetFrame::Init.
6463
  // IMPORTANT: This must match the conditions in nsHTMLFramesetFrame::Init.
6305
  return aContent->IsHTML() &&
6464
  return aContent->IsHTML() &&
6306
    (aContent->Tag() == nsGkAtoms::frameset ||
6465
    (aContent->Tag() == nsGkAtoms::frameset ||
6307
     aContent->Tag() == nsGkAtoms::frame);
6466
     aContent->Tag() == nsGkAtoms::frame);
6308
}
6467
}
 Lines 6429-6444   nsCSSFrameConstructor::MaybeConstructLaz Link Here 
6429
    }
6588
    }
6430
    if (!noPrimaryFrame && !content->GetPrimaryFrame()) {
6589
    if (!noPrimaryFrame && !content->GetPrimaryFrame()) {
6431
      noPrimaryFrame = true;
6590
      noPrimaryFrame = true;
6432
    }
6591
    }
6433
    if (!needsFrameBitSet && content->HasFlag(NODE_NEEDS_FRAME)) {
6592
    if (!needsFrameBitSet && content->HasFlag(NODE_NEEDS_FRAME)) {
6434
      needsFrameBitSet = true;
6593
      needsFrameBitSet = true;
6435
    }
6594
    }
6436
#endif
6595
#endif
6596
    // XXX no lazy frames for display-box:contents descendants yet (bug 979782).
6597
    if (GetDisplayBoxContentsStyleFor(content)) {
6598
      return false;
6599
    }
6437
    content->SetFlags(NODE_DESCENDANTS_NEED_FRAMES);
6600
    content->SetFlags(NODE_DESCENDANTS_NEED_FRAMES);
6438
    content = content->GetFlattenedTreeParent();
6601
    content = content->GetFlattenedTreeParent();
6439
  }
6602
  }
6440
#ifdef DEBUG
6603
#ifdef DEBUG
6441
  if (content && content->GetPrimaryFrame() &&
6604
  if (content && content->GetPrimaryFrame() &&
6442
      content->GetPrimaryFrame()->IsLeaf()) {
6605
      content->GetPrimaryFrame()->IsLeaf()) {
6443
    noPrimaryFrame = needsFrameBitSet = false;
6606
    noPrimaryFrame = needsFrameBitSet = false;
6444
  }
6607
  }
 Lines 6551-6568   void Link Here 
6551
nsCSSFrameConstructor::IssueSingleInsertNofications(nsIContent* aContainer,
6714
nsCSSFrameConstructor::IssueSingleInsertNofications(nsIContent* aContainer,
6552
                                                    nsIContent* aStartChild,
6715
                                                    nsIContent* aStartChild,
6553
                                                    nsIContent* aEndChild,
6716
                                                    nsIContent* aEndChild,
6554
                                                    bool aAllowLazyConstruction)
6717
                                                    bool aAllowLazyConstruction)
6555
{
6718
{
6556
  for (nsIContent* child = aStartChild;
6719
  for (nsIContent* child = aStartChild;
6557
       child != aEndChild;
6720
       child != aEndChild;
6558
       child = child->GetNextSibling()) {
6721
       child = child->GetNextSibling()) {
6559
    if ((child->GetPrimaryFrame() ||
6722
    if ((child->GetPrimaryFrame() || GetUndisplayedContent(child) ||
6560
         GetUndisplayedContent(child))
6723
         GetDisplayBoxContentsStyleFor(child))
6561
#ifdef MOZ_XUL
6724
#ifdef MOZ_XUL
6562
        //  Except listboxes suck, so do NOT skip anything here if
6725
        //  Except listboxes suck, so do NOT skip anything here if
6563
        //  we plan to notify a listbox.
6726
        //  we plan to notify a listbox.
6564
        && !MaybeGetListBoxBodyFrame(aContainer, child)
6727
        && !MaybeGetListBoxBodyFrame(aContainer, child)
6565
#endif
6728
#endif
6566
        ) {
6729
        ) {
6567
      // Already have a frame or undisplayed entry for this content; a
6730
      // Already have a frame or undisplayed entry for this content; a
6568
      // previous ContentInserted in this loop must have reconstructed
6731
      // previous ContentInserted in this loop must have reconstructed
 Lines 6711-6727   nsCSSFrameConstructor::ContentAppended(n Link Here 
6711
    nsIContent* bindingParent = aContainer->GetBindingParent();
6874
    nsIContent* bindingParent = aContainer->GetBindingParent();
6712
    LAYOUT_PHASE_TEMP_EXIT();
6875
    LAYOUT_PHASE_TEMP_EXIT();
6713
    nsresult rv = RecreateFramesForContent(bindingParent, false);
6876
    nsresult rv = RecreateFramesForContent(bindingParent, false);
6714
    LAYOUT_PHASE_TEMP_REENTER();
6877
    LAYOUT_PHASE_TEMP_REENTER();
6715
    return rv;
6878
    return rv;
6716
  }
6879
  }
6717
6880
6718
  // Get the frame associated with the content
6881
  // Get the frame associated with the content
6719
  nsContainerFrame* parentFrame = ::GetContentInsertionFrameFor(aContainer);
6882
  nsContainerFrame* parentFrame = GetContentInsertionFrameFor(aContainer);
6720
6883
6721
  // See comment in ContentRangeInserted for why this is necessary.
6884
  // See comment in ContentRangeInserted for why this is necessary.
6722
  if (!parentFrame && !aContainer->IsActiveChildrenElement()) {
6885
  if (!parentFrame && !aContainer->IsActiveChildrenElement()) {
6723
    return NS_OK;
6886
    return NS_OK;
6724
  }
6887
  }
6725
6888
6726
  if (aAllowLazyConstruction &&
6889
  if (aAllowLazyConstruction &&
6727
      MaybeConstructLazily(CONTENTAPPEND, aContainer, aFirstNewContent)) {
6890
      MaybeConstructLazily(CONTENTAPPEND, aContainer, aFirstNewContent)) {
 Lines 6784-6802   nsCSSFrameConstructor::ContentAppended(n Link Here 
6784
  // We should never get here with fieldsets, since they have multiple
6947
  // We should never get here with fieldsets, since they have multiple
6785
  // insertion points.
6948
  // insertion points.
6786
  NS_ASSERTION(parentFrame->GetType() != nsGkAtoms::fieldSetFrame,
6949
  NS_ASSERTION(parentFrame->GetType() != nsGkAtoms::fieldSetFrame,
6787
               "Unexpected parent");
6950
               "Unexpected parent");
6788
6951
6789
  // Deal with possible :after generated content on the parent
6952
  // Deal with possible :after generated content on the parent
6790
  nsIFrame* parentAfterFrame;
6953
  nsIFrame* parentAfterFrame;
6791
  parentFrame =
6954
  parentFrame =
6792
    ::AdjustAppendParentForAfterContent(mPresShell->GetPresContext(),
6955
    ::AdjustAppendParentForAfterContent(this, aContainer, parentFrame,
6793
                                        aContainer, parentFrame,
6956
                                        aFirstNewContent, &parentAfterFrame);
6794
                                        &parentAfterFrame);
6795
6957
6796
  // Create some new frames
6958
  // Create some new frames
6797
  nsFrameConstructorState state(mPresShell,
6959
  nsFrameConstructorState state(mPresShell,
6798
                                GetAbsoluteContainingBlock(parentFrame, FIXED_POS),
6960
                                GetAbsoluteContainingBlock(parentFrame, FIXED_POS),
6799
                                GetAbsoluteContainingBlock(parentFrame, ABS_POS),
6961
                                GetAbsoluteContainingBlock(parentFrame, ABS_POS),
6800
                                GetFloatContainingBlock(parentFrame));
6962
                                GetFloatContainingBlock(parentFrame));
6801
  state.mTreeMatchContext.InitAncestors(aContainer->AsElement());
6963
  state.mTreeMatchContext.InitAncestors(aContainer->AsElement());
6802
6964
 Lines 7144-7169   nsCSSFrameConstructor::ContentRangeInser Link Here 
7144
    // the children of the host.
7306
    // the children of the host.
7145
    nsIContent* bindingParent = aContainer->GetBindingParent();
7307
    nsIContent* bindingParent = aContainer->GetBindingParent();
7146
    LAYOUT_PHASE_TEMP_EXIT();
7308
    LAYOUT_PHASE_TEMP_EXIT();
7147
    nsresult rv = RecreateFramesForContent(bindingParent, false);
7309
    nsresult rv = RecreateFramesForContent(bindingParent, false);
7148
    LAYOUT_PHASE_TEMP_REENTER();
7310
    LAYOUT_PHASE_TEMP_REENTER();
7149
    return rv;
7311
    return rv;
7150
  }
7312
  }
7151
7313
7152
  nsContainerFrame* parentFrame = ::GetContentInsertionFrameFor(aContainer);
7314
  nsContainerFrame* parentFrame = GetContentInsertionFrameFor(aContainer);
7153
  // The xbl:children element won't have a frame, but default content can have the children as
7315
  // The xbl:children element won't have a frame, but default content can have the children as
7154
  // a parent. While its uncommon to change the structure of the default content itself, a label,
7316
  // a parent. While its uncommon to change the structure of the default content itself, a label,
7155
  // for example, can be reframed by having its value attribute set or removed.
7317
  // for example, can be reframed by having its value attribute set or removed.
7156
  if (!parentFrame && !aContainer->IsActiveChildrenElement()) {
7318
  if (!parentFrame && !aContainer->IsActiveChildrenElement()) {
7157
    return NS_OK;
7319
    return NS_OK;
7158
  }
7320
  }
7159
7321
7160
  // Otherwise, we've got parent content. Find its frame.
7322
  // Otherwise, we've got parent content. Find its frame.
7161
  NS_ASSERTION(!parentFrame || parentFrame->GetContent() == aContainer, "New XBL code is possibly wrong!");
7323
  NS_ASSERTION(!parentFrame || parentFrame->GetContent() == aContainer ||
7324
               GetDisplayBoxContentsStyleFor(aContainer), "New XBL code is possibly wrong!");
7162
7325
7163
  if (aAllowLazyConstruction &&
7326
  if (aAllowLazyConstruction &&
7164
      MaybeConstructLazily(CONTENTINSERT, aContainer, aStartChild)) {
7327
      MaybeConstructLazily(CONTENTINSERT, aContainer, aStartChild)) {
7165
    return NS_OK;
7328
    return NS_OK;
7166
  }
7329
  }
7167
7330
7168
  if (isSingleInsert) {
7331
  if (isSingleInsert) {
7169
    // See if we have an XBL insertion point. If so, then that's our
7332
    // See if we have an XBL insertion point. If so, then that's our
 Lines 7440-7459   nsCSSFrameConstructor::ContentRangeInser Link Here 
7440
                 frame1->GetType() == nsGkAtoms::fieldSetFrame ||
7603
                 frame1->GetType() == nsGkAtoms::fieldSetFrame ||
7441
                 (frame1->GetParent() &&
7604
                 (frame1->GetParent() &&
7442
                  frame1->GetParent()->GetType() == nsGkAtoms::fieldSetFrame),
7605
                  frame1->GetParent()->GetType() == nsGkAtoms::fieldSetFrame),
7443
                 "Unexpected frame types");
7606
                 "Unexpected frame types");
7444
#endif
7607
#endif
7445
    isAppend = true;
7608
    isAppend = true;
7446
    nsIFrame* appendAfterFrame;
7609
    nsIFrame* appendAfterFrame;
7447
    parentFrame =
7610
    parentFrame =
7448
      ::AdjustAppendParentForAfterContent(mPresShell->GetPresContext(),
7611
      ::AdjustAppendParentForAfterContent(this, container,
7449
                                          container,
7450
                                          frameItems.FirstChild()->GetParent(),
7612
                                          frameItems.FirstChild()->GetParent(),
7451
                                          &appendAfterFrame);
7613
                                          aStartChild, &appendAfterFrame);
7452
    prevSibling = ::FindAppendPrevSibling(parentFrame, appendAfterFrame);
7614
    prevSibling = ::FindAppendPrevSibling(parentFrame, appendAfterFrame);
7453
  }
7615
  }
7454
7616
7455
  if (haveFirstLineStyle && parentFrame == containingBlock) {
7617
  if (haveFirstLineStyle && parentFrame == containingBlock) {
7456
    // It's possible that the new frame goes into a first-line
7618
    // It's possible that the new frame goes into a first-line
7457
    // frame. Look at it and see...
7619
    // frame. Look at it and see...
7458
    if (isAppend) {
7620
    if (isAppend) {
7459
      // Use append logic when appending
7621
      // Use append logic when appending
 Lines 7583-7610   nsCSSFrameConstructor::ContentRemoved(ns Link Here 
7583
           static_cast<void*>(aChild),
7745
           static_cast<void*>(aChild),
7584
           static_cast<void*>(aOldNextSibling));
7746
           static_cast<void*>(aOldNextSibling));
7585
    if (gReallyNoisyContentUpdates) {
7747
    if (gReallyNoisyContentUpdates) {
7586
      aContainer->List(stdout, 0);
7748
      aContainer->List(stdout, 0);
7587
    }
7749
    }
7588
  }
7750
  }
7589
#endif
7751
#endif
7590
7752
7591
  nsPresContext *presContext = mPresShell->GetPresContext();
7753
  nsresult rv = NS_OK;
7592
  nsresult                  rv = NS_OK;
7593
7594
  // Find the child frame that maps the content
7595
  nsIFrame* childFrame = aChild->GetPrimaryFrame();
7754
  nsIFrame* childFrame = aChild->GetPrimaryFrame();
7596
7597
  if (!childFrame || childFrame->GetContent() != aChild) {
7755
  if (!childFrame || childFrame->GetContent() != aChild) {
7598
    // XXXbz the GetContent() != aChild check is needed due to bug 135040.
7756
    // XXXbz the GetContent() != aChild check is needed due to bug 135040.
7599
    // Remove it once that's fixed.
7757
    // Remove it once that's fixed.
7600
    ClearUndisplayedContentIn(aChild, aContainer);
7758
    ClearUndisplayedContentIn(aChild, aContainer);
7601
  }
7759
  }
7602
7760
  MOZ_ASSERT(!childFrame || !GetDisplayBoxContentsStyleFor(aChild),
7761
             "display-box:contents nodes shouldn't have a frame");
7762
  if (!childFrame && GetDisplayBoxContentsStyleFor(aChild)) {
7763
    nsIFrame* ancestorFrame = nullptr;
7764
    nsIContent* ancestor = aContainer;
7765
    for (; ancestor; ancestor = ancestor->GetParent()) {
7766
      ancestorFrame = ancestor->GetPrimaryFrame();
7767
      if (ancestorFrame) {
7768
        break;
7769
      }
7770
    }
7771
    if (ancestorFrame) {
7772
      nsTArray<nsIContent*>* generated = ancestorFrame->GetGenConPseudos();
7773
      if (generated) {
7774
        LAYOUT_PHASE_TEMP_EXIT();
7775
        // XXXmats Can we recreate frames only for the ::after/::before content?
7776
        // XXX Perhaps even only those that belong to the aChild sub-tree?
7777
        RecreateFramesForContent(ancestor, false);
7778
        LAYOUT_PHASE_TEMP_REENTER();
7779
        *aDidReconstruct = true;
7780
        return NS_OK;
7781
      }
7782
    }
7783
7784
    FlattenedChildIterator iter(aChild);
7785
    for (nsIContent* c = iter.GetNextChild(); c; c = iter.GetNextChild()) {
7786
      if (c->GetPrimaryFrame() || GetDisplayBoxContentsStyleFor(c)) {
7787
        LAYOUT_PHASE_TEMP_EXIT();
7788
        rv = ContentRemoved(aChild, c, nullptr, aFlags, aDidReconstruct);
7789
        LAYOUT_PHASE_TEMP_REENTER();
7790
        NS_ENSURE_SUCCESS(rv, rv);
7791
        if (*aDidReconstruct) {
7792
          return rv;
7793
        }
7794
      }
7795
    }
7796
    ClearDisplayBoxContentsIn(aChild, aContainer);
7797
  }
7798
7799
  nsPresContext* presContext = mPresShell->GetPresContext();
7603
#ifdef MOZ_XUL
7800
#ifdef MOZ_XUL
7604
  if (NotifyListBoxBody(presContext, aContainer, aChild, aOldNextSibling,
7801
  if (NotifyListBoxBody(presContext, aContainer, aChild, aOldNextSibling,
7605
                        mDocument, childFrame, CONTENT_REMOVED))
7802
                        mDocument, childFrame, CONTENT_REMOVED))
7606
    return NS_OK;
7803
    return NS_OK;
7607
7804
7608
#endif // MOZ_XUL
7805
#endif // MOZ_XUL
7609
7806
7610
  // If we're removing the root, then make sure to remove things starting at
7807
  // If we're removing the root, then make sure to remove things starting at
 Lines 8431-8447   nsCSSFrameConstructor::GetInsertionPoint Link Here 
8431
8628
8432
  nsIContent* insertionElement;
8629
  nsIContent* insertionElement;
8433
  if (aChildContent) {
8630
  if (aChildContent) {
8434
    // We've got an explicit insertion child. Check to see if it's
8631
    // We've got an explicit insertion child. Check to see if it's
8435
    // anonymous.
8632
    // anonymous.
8436
    if (aChildContent->GetBindingParent() == aContainer) {
8633
    if (aChildContent->GetBindingParent() == aContainer) {
8437
      // This child content is anonymous. Don't use the insertion
8634
      // This child content is anonymous. Don't use the insertion
8438
      // point, since that's only for the explicit kids.
8635
      // point, since that's only for the explicit kids.
8439
      return ::GetContentInsertionFrameFor(aContainer);
8636
      return GetContentInsertionFrameFor(aContainer);
8440
    }
8637
    }
8441
8638
8442
    insertionElement = bindingManager->FindNestedInsertionPoint(aContainer, aChildContent);
8639
    insertionElement = bindingManager->FindNestedInsertionPoint(aContainer, aChildContent);
8443
  }
8640
  }
8444
  else {
8641
  else {
8445
    bool multiple;
8642
    bool multiple;
8446
    insertionElement = bindingManager->FindNestedSingleInsertionPoint(aContainer, &multiple);
8643
    insertionElement = bindingManager->FindNestedSingleInsertionPoint(aContainer, &multiple);
8447
8644
 Lines 8452-8469   nsCSSFrameConstructor::GetInsertionPoint Link Here 
8452
      return nullptr;
8649
      return nullptr;
8453
    }
8650
    }
8454
  }
8651
  }
8455
8652
8456
  if (!insertionElement) {
8653
  if (!insertionElement) {
8457
    insertionElement = aContainer;
8654
    insertionElement = aContainer;
8458
  }
8655
  }
8459
8656
8460
  nsContainerFrame* insertionPoint =
8657
  nsContainerFrame* insertionPoint = GetContentInsertionFrameFor(insertionElement);
8461
    ::GetContentInsertionFrameFor(insertionElement);
8462
8658
8463
  // fieldsets have multiple insertion points.  Note that we might
8659
  // fieldsets have multiple insertion points.  Note that we might
8464
  // have to look at insertionElement here...
8660
  // have to look at insertionElement here...
8465
  if (aMultiple && insertionElement->IsHTML(nsGkAtoms::fieldset)) {
8661
  if (aMultiple && insertionElement->IsHTML(nsGkAtoms::fieldset)) {
8466
    *aMultiple = true;
8662
    *aMultiple = true;
8467
  }
8663
  }
8468
8664
8469
  return insertionPoint;
8665
  return insertionPoint;
 Lines 8490-8534   nsCSSFrameConstructor::CaptureStateForFr Link Here 
8490
8686
8491
static bool EqualURIs(mozilla::css::URLValue *aURI1,
8687
static bool EqualURIs(mozilla::css::URLValue *aURI1,
8492
                      mozilla::css::URLValue *aURI2)
8688
                      mozilla::css::URLValue *aURI2)
8493
{
8689
{
8494
  return aURI1 == aURI2 ||    // handle null==null, and optimize
8690
  return aURI1 == aURI2 ||    // handle null==null, and optimize
8495
         (aURI1 && aURI2 && aURI1->URIEquals(*aURI2));
8691
         (aURI1 && aURI2 && aURI1->URIEquals(*aURI2));
8496
}
8692
}
8497
8693
8498
nsresult
8694
nsStyleContext*
8499
nsCSSFrameConstructor::MaybeRecreateFramesForElement(Element* aElement)
8695
nsCSSFrameConstructor::MaybeRecreateFramesForElement(Element* aElement)
8500
{
8696
{
8501
  nsRefPtr<nsStyleContext> oldContext = GetUndisplayedContent(aElement);
8697
  nsRefPtr<nsStyleContext> oldContext = GetUndisplayedContent(aElement);
8698
  uint8_t oldDisplayBoxStyle = NS_STYLE_DISPLAY_BOX_NONE;
8502
  if (!oldContext) {
8699
  if (!oldContext) {
8503
    return NS_OK;
8700
    oldContext = GetDisplayBoxContentsStyleFor(aElement);
8701
    if (!oldContext) {
8702
      return nullptr;
8703
    }
8704
    oldDisplayBoxStyle = NS_STYLE_DISPLAY_BOX_CONTENTS;
8504
  }
8705
  }
8505
8706
8506
  // The parent has a frame, so try resolving a new context.
8707
  // The parent has a frame, so try resolving a new context.
8507
  nsRefPtr<nsStyleContext> newContext = mPresShell->StyleSet()->
8708
  nsRefPtr<nsStyleContext> newContext = mPresShell->StyleSet()->
8508
    ResolveStyleFor(aElement, oldContext->GetParent());
8709
    ResolveStyleFor(aElement, oldContext->GetParent());
8509
8710
8510
  ChangeUndisplayedContent(aElement, newContext);
8711
  if (oldDisplayBoxStyle == NS_STYLE_DISPLAY_BOX_NONE) {
8712
    ChangeUndisplayedContent(aElement, newContext);
8713
  } else {
8714
    ChangeDisplayBoxContents(aElement, newContext);
8715
  }
8716
8511
  const nsStyleDisplay* disp = newContext->StyleDisplay();
8717
  const nsStyleDisplay* disp = newContext->StyleDisplay();
8512
  if (disp->mDisplay == NS_STYLE_DISPLAY_NONE) {
8718
  if (oldDisplayBoxStyle == disp->mDisplayBox) {
8513
    // We can skip trying to recreate frames here, but only if our style
8719
    // We can skip trying to recreate frames here, but only if our style
8514
    // context does not have a binding URI that differs from our old one.
8720
    // context does not have a binding URI that differs from our old one.
8515
    // Otherwise, we should try to recreate, because we may want to apply the
8721
    // Otherwise, we should try to recreate, because we may want to apply the
8516
    // new binding
8722
    // new binding
8517
    if (!disp->mBinding) {
8723
    if (!disp->mBinding) {
8518
      return NS_OK;
8724
      return newContext;
8519
    }
8725
    }
8520
    const nsStyleDisplay* oldDisp = oldContext->PeekStyleDisplay();
8726
    const nsStyleDisplay* oldDisp = oldContext->PeekStyleDisplay();
8521
    if (oldDisp && EqualURIs(disp->mBinding, oldDisp->mBinding)) {
8727
    if (oldDisp && EqualURIs(disp->mBinding, oldDisp->mBinding)) {
8522
      return NS_OK;
8728
      return newContext;
8523
    }
8729
    }
8524
  }
8730
  }
8525
8731
8526
  return RecreateFramesForContent(aElement, false);
8732
  RecreateFramesForContent(aElement, false);
8733
  return nullptr;
8527
}
8734
}
8528
8735
8529
static nsIFrame*
8736
static nsIFrame*
8530
FindFirstNonWhitespaceChild(nsIFrame* aParentFrame)
8737
FindFirstNonWhitespaceChild(nsIFrame* aParentFrame)
8531
{
8738
{
8532
  nsIFrame* f = aParentFrame->GetFirstPrincipalChild();
8739
  nsIFrame* f = aParentFrame->GetFirstPrincipalChild();
8533
  while (f && f->GetType() == nsGkAtoms::textFrame &&
8740
  while (f && f->GetType() == nsGkAtoms::textFrame &&
8534
         f->GetContent()->TextIsOnlyWhitespace()) {
8741
         f->GetContent()->TextIsOnlyWhitespace()) {
 Lines 10410-10430   nsCSSFrameConstructor::CreateListBoxCont Link Here 
10410
                                  mTempFrameTreeState);
10617
                                  mTempFrameTreeState);
10411
10618
10412
    // If we ever initialize the ancestor filter on |state|, make sure
10619
    // If we ever initialize the ancestor filter on |state|, make sure
10413
    // to push the right parent!
10620
    // to push the right parent!
10414
10621
10415
    nsRefPtr<nsStyleContext> styleContext;
10622
    nsRefPtr<nsStyleContext> styleContext;
10416
    styleContext = ResolveStyleContext(aParentFrame, aChild, &state);
10623
    styleContext = ResolveStyleContext(aParentFrame, aChild, &state);
10417
10624
10418
    // Pre-check for display "none" - only if we find that, do we create
10625
    // Pre-check for display-box:none - if we find that, don't create any frame at all.
10419
    // any frame at all
10420
    const nsStyleDisplay* display = styleContext->StyleDisplay();
10626
    const nsStyleDisplay* display = styleContext->StyleDisplay();
10421
10627
    if (NS_STYLE_DISPLAY_BOX_NONE == display->mDisplayBox) {
10422
    if (NS_STYLE_DISPLAY_NONE == display->mDisplay) {
10423
      *aNewFrame = nullptr;
10628
      *aNewFrame = nullptr;
10424
      return NS_OK;
10629
      return NS_OK;
10425
    }
10630
    }
10426
10631
10427
    BeginUpdate();
10632
    BeginUpdate();
10428
10633
10429
    FrameConstructionItemList items;
10634
    FrameConstructionItemList items;
10430
    AddFrameConstructionItemsInternal(state, aChild, aParentFrame,
10635
    AddFrameConstructionItemsInternal(state, aChild, aParentFrame,
(-)a/layout/base/nsCSSFrameConstructor.h (-1 / +35 lines)
Line     Link Here 
 Lines 296-311   private: Link Here 
296
  // may suppress the construction of white-space-only text frames
296
  // may suppress the construction of white-space-only text frames
297
  // must be skipped for these items and items around them.
297
  // must be skipped for these items and items around them.
298
  void AddFrameConstructionItems(nsFrameConstructorState& aState,
298
  void AddFrameConstructionItems(nsFrameConstructorState& aState,
299
                                 nsIContent*              aContent,
299
                                 nsIContent*              aContent,
300
                                 bool                     aSuppressWhiteSpaceOptimizations,
300
                                 bool                     aSuppressWhiteSpaceOptimizations,
301
                                 nsContainerFrame*        aParentFrame,
301
                                 nsContainerFrame*        aParentFrame,
302
                                 FrameConstructionItemList& aItems);
302
                                 FrameConstructionItemList& aItems);
303
303
304
  // Helper method for AddFrameConstructionItems etc.
305
  // Unsets the need-frame/restyle bits on aContent.
306
  // return true iff we should attempt to create frames for aContent.
307
  bool ShouldCreateItemsForChild(nsFrameConstructorState& aState,
308
                                 nsIContent* aContent,
309
                                 nsContainerFrame* aParentFrame);
310
311
  // Helper method for AddFrameConstructionItems etc.
312
  // Make sure ShouldCreateItemsForChild() returned true before calling this.
313
  void DoAddFrameConstructionItems(nsFrameConstructorState& aState,
314
                                   nsIContent* aContent,
315
                                   nsStyleContext* aStyleContext,
316
                                   bool aSuppressWhiteSpaceOptimizations,
317
                                   nsContainerFrame* aParentFrame,
318
                                   nsTArray<nsIAnonymousContentCreator::ContentInfo>* aAnonChildren,
319
                                   FrameConstructionItemList& aItems);
320
304
  // Construct the frames for the document element.  This can return null if the
321
  // Construct the frames for the document element.  This can return null if the
305
  // document element is display:none, or if the document element has a
322
  // document element is display:none, or if the document element has a
306
  // not-yet-loaded XBL binding, or if it's an SVG element that's not <svg>.
323
  // not-yet-loaded XBL binding, or if it's an SVG element that's not <svg>.
307
  nsIFrame* ConstructDocElementFrame(Element*                 aDocElement,
324
  nsIFrame* ConstructDocElementFrame(Element*                 aDocElement,
308
                                     nsILayoutHistoryState*   aFrameState);
325
                                     nsILayoutHistoryState*   aFrameState);
309
326
310
  // Set up our mDocElementContainingBlock correctly for the given root
327
  // Set up our mDocElementContainingBlock correctly for the given root
311
  // content.
328
  // content.
 Lines 566-581   private: Link Here 
566
  /* If FCDATA_CREATE_BLOCK_WRAPPER_FOR_ALL_KIDS is set, then create a
583
  /* If FCDATA_CREATE_BLOCK_WRAPPER_FOR_ALL_KIDS is set, then create a
567
     block formatting context wrapper around the kids of this frame
584
     block formatting context wrapper around the kids of this frame
568
     using the FrameConstructionData's mPseudoAtom for its anonymous
585
     using the FrameConstructionData's mPseudoAtom for its anonymous
569
     box type. */
586
     box type. */
570
#define FCDATA_CREATE_BLOCK_WRAPPER_FOR_ALL_KIDS 0x40000
587
#define FCDATA_CREATE_BLOCK_WRAPPER_FOR_ALL_KIDS 0x40000
571
  /* If FCDATA_IS_SVG_TEXT is set, then this text frame is a descendant of
588
  /* If FCDATA_IS_SVG_TEXT is set, then this text frame is a descendant of
572
     an SVG text frame. */
589
     an SVG text frame. */
573
#define FCDATA_IS_SVG_TEXT 0x80000
590
#define FCDATA_IS_SVG_TEXT 0x80000
591
  /**
592
   * display-box:contents
593
   */
594
#define FCDATA_IS_CONTENTS 0x100000
574
595
575
  /* Structure representing information about how a frame should be
596
  /* Structure representing information about how a frame should be
576
     constructed.  */
597
     constructed.  */
577
  struct FrameConstructionData {
598
  struct FrameConstructionData {
578
    // Flag bits that can modify the way the construction happens
599
    // Flag bits that can modify the way the construction happens
579
    uint32_t mBits;
600
    uint32_t mBits;
580
    // We have exactly one of three types of functions, so use a union for
601
    // We have exactly one of three types of functions, so use a union for
581
    // better cache locality for the ones that aren't pointer-to-member.  That
602
    // better cache locality for the ones that aren't pointer-to-member.  That
 Lines 1437-1453   private: Link Here 
1437
                        nsContainerFrame*        aScrolledFrame,
1458
                        nsContainerFrame*        aScrolledFrame,
1438
                        nsIContent*              aContent,
1459
                        nsIContent*              aContent,
1439
                        nsContainerFrame*        aParentFrame,
1460
                        nsContainerFrame*        aParentFrame,
1440
                        nsStyleContext*          aStyleContext,
1461
                        nsStyleContext*          aStyleContext,
1441
                        bool                     aBuildCombobox,
1462
                        bool                     aBuildCombobox,
1442
                        PendingBinding*          aPendingBinding,
1463
                        PendingBinding*          aPendingBinding,
1443
                        nsFrameItems&            aFrameItems);
1464
                        nsFrameItems&            aFrameItems);
1444
1465
1445
  nsresult MaybeRecreateFramesForElement(Element* aElement);
1466
  /**
1467
   * ReResolve style for aElement then recreate frames if required.
1468
   * Do nothing for other types of style changes, except for undisplayed nodes
1469
   * (display:none/contents) which will have their style context updated in the
1470
   * frame manager undisplayed maps.
1471
   * @return null if frames were recreated, the new style context otherwise
1472
   */
1473
  nsStyleContext* MaybeRecreateFramesForElement(Element* aElement);
1446
1474
1447
  // If aAsyncInsert is true then a restyle event will be posted to handle the
1475
  // If aAsyncInsert is true then a restyle event will be posted to handle the
1448
  // required ContentInserted call instead of doing it immediately.
1476
  // required ContentInserted call instead of doing it immediately.
1449
  nsresult RecreateFramesForContent(nsIContent* aContent, bool aAsyncInsert);
1477
  nsresult RecreateFramesForContent(nsIContent* aContent, bool aAsyncInsert);
1450
1478
1451
  // If removal of aFrame from the frame tree requires reconstruction of some
1479
  // If removal of aFrame from the frame tree requires reconstruction of some
1452
  // containing block (either of aFrame or of its parent) due to {ib} splits or
1480
  // containing block (either of aFrame or of its parent) due to {ib} splits or
1453
  // table pseudo-frames, recreate the relevant frame subtree.  The return value
1481
  // table pseudo-frames, recreate the relevant frame subtree.  The return value
 Lines 1736-1751   private: Link Here 
1736
  nsIFrame* GetInsertionPrevSibling(nsContainerFrame*& aParentFrame, /* inout */
1764
  nsIFrame* GetInsertionPrevSibling(nsContainerFrame*& aParentFrame, /* inout */
1737
                                    nsIContent* aContainer,
1765
                                    nsIContent* aContainer,
1738
                                    nsIContent* aChild,
1766
                                    nsIContent* aChild,
1739
                                    bool* aIsAppend,
1767
                                    bool* aIsAppend,
1740
                                    bool* aIsRangeInsertSafe,
1768
                                    bool* aIsRangeInsertSafe,
1741
                                    nsIContent* aStartSkipChild = nullptr,
1769
                                    nsIContent* aStartSkipChild = nullptr,
1742
                                    nsIContent *aEndSkipChild = nullptr);
1770
                                    nsIContent *aEndSkipChild = nullptr);
1743
1771
1772
  /**
1773
   * Return the insertion frame of the primary frame of aContent, or its nearest
1774
   * ancestor that isn't display-box:contents.
1775
   */
1776
  nsContainerFrame* GetContentInsertionFrameFor(nsIContent* aContent);
1777
1744
  // see if aContent and aSibling are legitimate siblings due to restrictions
1778
  // see if aContent and aSibling are legitimate siblings due to restrictions
1745
  // imposed by table columns
1779
  // imposed by table columns
1746
  // XXXbz this code is generally wrong, since the frame for aContent
1780
  // XXXbz this code is generally wrong, since the frame for aContent
1747
  // may be constructed based on tag, not based on aDisplay!
1781
  // may be constructed based on tag, not based on aDisplay!
1748
  bool IsValidSibling(nsIFrame*              aSibling,
1782
  bool IsValidSibling(nsIFrame*              aSibling,
1749
                        nsIContent*            aContent,
1783
                        nsIContent*            aContent,
1750
                        uint8_t&               aDisplay);
1784
                        uint8_t&               aDisplay);
1751
1785
(-)a/layout/base/nsDisplayList.cpp (-4 / +11 lines)
Line     Link Here 
 Lines 4468-4488   nsDisplayTransform::GetDeltaToPerspectiv Link Here 
4468
4468
4469
  /* For both of the coordinates, if the value of -moz-perspective-origin is a
4469
  /* For both of the coordinates, if the value of -moz-perspective-origin is a
4470
   * percentage, it's relative to the size of the frame.  Otherwise, if it's
4470
   * percentage, it's relative to the size of the frame.  Otherwise, if it's
4471
   * a distance, it's already computed for us!
4471
   * a distance, it's already computed for us!
4472
   */
4472
   */
4473
4473
4474
  //TODO: Should this be using our bounds or the parent's bounds?
4474
  //TODO: Should this be using our bounds or the parent's bounds?
4475
  // How do we handle aBoundsOverride in the latter case?
4475
  // How do we handle aBoundsOverride in the latter case?
4476
  nsIFrame* parent = aFrame->GetParentStyleContextFrame();
4476
  nsIFrame* parent;
4477
  nsStyleContext* psc = aFrame->GetParentStyleContext(&parent);
4478
  if (!psc) {
4479
    return gfxPoint3D();
4480
  }
4477
  if (!parent) {
4481
  if (!parent) {
4478
    return gfxPoint3D();
4482
    parent = aFrame->GetParent();
4479
  }
4483
    if (!parent) {
4480
  const nsStyleDisplay* display = parent->StyleDisplay();
4484
      return gfxPoint3D();
4485
    }
4486
  }
4487
  const nsStyleDisplay* display = psc->StyleDisplay();
4481
  nsRect boundingRect = nsDisplayTransform::GetFrameBoundsForTransform(parent);
4488
  nsRect boundingRect = nsDisplayTransform::GetFrameBoundsForTransform(parent);
4482
4489
4483
  /* Allows us to access named variables by index. */
4490
  /* Allows us to access named variables by index. */
4484
  gfxPoint3D result;
4491
  gfxPoint3D result;
4485
  result.z = 0.0f;
4492
  result.z = 0.0f;
4486
  gfxFloat* coords[2] = {&result.x, &result.y};
4493
  gfxFloat* coords[2] = {&result.x, &result.y};
4487
  const nscoord* dimensions[2] =
4494
  const nscoord* dimensions[2] =
4488
    {&boundingRect.width, &boundingRect.height};
4495
    {&boundingRect.width, &boundingRect.height};
(-)a/layout/base/nsFrameManager.cpp (-34 / +153 lines)
Line     Link Here 
 Lines 35-52    Link Here 
35
35
36
#include "nsFrameManager.h"
36
#include "nsFrameManager.h"
37
#include "GeckoProfiler.h"
37
#include "GeckoProfiler.h"
38
#include "nsIStatefulFrame.h"
38
#include "nsIStatefulFrame.h"
39
#include "nsContainerFrame.h"
39
#include "nsContainerFrame.h"
40
40
41
  #ifdef DEBUG
41
  #ifdef DEBUG
42
    //#define DEBUG_UNDISPLAYED_MAP
42
    //#define DEBUG_UNDISPLAYED_MAP
43
    //#define DEBUG_DISPLAY_BOX_CONTENTS_MAP
43
  #else
44
  #else
44
    #undef DEBUG_UNDISPLAYED_MAP
45
    #undef DEBUG_UNDISPLAYED_MAP
46
    #undef DEBUG_DISPLAY_BOX_CONTENTS_MAP
45
  #endif
47
  #endif
46
48
47
using namespace mozilla;
49
using namespace mozilla;
48
using namespace mozilla::dom;
50
using namespace mozilla::dom;
49
51
50
//----------------------------------------------------------------------
52
//----------------------------------------------------------------------
51
53
52
struct PlaceholderMapEntry : public PLDHashEntryHdr {
54
struct PlaceholderMapEntry : public PLDHashEntryHdr {
 Lines 91-106   public: Link Here 
91
93
92
  nsresult AddNodeFor(nsIContent* aParentContent,
94
  nsresult AddNodeFor(nsIContent* aParentContent,
93
                                  nsIContent* aChild, nsStyleContext* aStyle);
95
                                  nsIContent* aChild, nsStyleContext* aStyle);
94
96
95
  void RemoveNodeFor(nsIContent* aParentContent,
97
  void RemoveNodeFor(nsIContent* aParentContent,
96
                                 UndisplayedNode* aNode);
98
                                 UndisplayedNode* aNode);
97
99
98
  void RemoveNodesFor(nsIContent* aParentContent);
100
  void RemoveNodesFor(nsIContent* aParentContent);
101
  UndisplayedNode* UnlinkNodesFor(nsIContent* aParentContent);
99
102
100
  // Removes all entries from the hash table
103
  // Removes all entries from the hash table
101
  void  Clear(void);
104
  void  Clear(void);
102
105
103
protected:
106
protected:
104
  /**
107
  /**
105
   * Gets the entry for the provided parent content. If the content
108
   * Gets the entry for the provided parent content. If the content
106
   * is a <xbl:children> element, |**aParentContent| is set to
109
   * is a <xbl:children> element, |**aParentContent| is set to
 Lines 134-149   nsFrameManager::Destroy() Link Here 
134
137
135
  if (mRootFrame) {
138
  if (mRootFrame) {
136
    mRootFrame->Destroy();
139
    mRootFrame->Destroy();
137
    mRootFrame = nullptr;
140
    mRootFrame = nullptr;
138
  }
141
  }
139
  
142
  
140
  delete mUndisplayedMap;
143
  delete mUndisplayedMap;
141
  mUndisplayedMap = nullptr;
144
  mUndisplayedMap = nullptr;
145
  delete mDisplayBoxContentsMap;
146
  mDisplayBoxContentsMap = nullptr;
142
147
143
  mPresShell = nullptr;
148
  mPresShell = nullptr;
144
}
149
}
145
150
146
//----------------------------------------------------------------------
151
//----------------------------------------------------------------------
147
152
148
// Placeholder frame functions
153
// Placeholder frame functions
149
nsPlaceholderFrame*
154
nsPlaceholderFrame*
 Lines 215-301   nsFrameManager::ClearPlaceholderFrameMap Link Here 
215
    PL_DHashTableEnumerate(&mPlaceholderMap, UnregisterPlaceholders, nullptr);
220
    PL_DHashTableEnumerate(&mPlaceholderMap, UnregisterPlaceholders, nullptr);
216
    PL_DHashTableFinish(&mPlaceholderMap);
221
    PL_DHashTableFinish(&mPlaceholderMap);
217
    mPlaceholderMap.ops = nullptr;
222
    mPlaceholderMap.ops = nullptr;
218
  }
223
  }
219
}
224
}
220
225
221
//----------------------------------------------------------------------
226
//----------------------------------------------------------------------
222
227
223
nsStyleContext*
228
/* static */ nsStyleContext*
224
nsFrameManager::GetUndisplayedContent(nsIContent* aContent)
229
nsFrameManager::GetStyleContextInMap(UndisplayedMap* aMap, nsIContent* aContent)
225
{
230
{
226
  if (!aContent || !mUndisplayedMap)
231
  if (!aContent) {
227
    return nullptr;
232
    return nullptr;
228
233
  }
229
  nsIContent* parent = aContent->GetParent();
234
  nsIContent* parent = aContent->GetParent();
230
  for (UndisplayedNode* node = mUndisplayedMap->GetFirstNode(parent);
235
  for (UndisplayedNode* node = aMap->GetFirstNode(parent);
231
         node; node = node->mNext) {
236
         node; node = node->mNext) {
232
    if (node->mContent == aContent)
237
    if (node->mContent == aContent)
233
      return node->mStyle;
238
      return node->mStyle;
234
  }
239
  }
235
240
236
  return nullptr;
241
  return nullptr;
237
}
242
}
238
243
244
/* static */ UndisplayedNode*
245
nsFrameManager::GetAllUndisplayedNodesInMapFor(UndisplayedMap* aMap,
246
                                               nsIContent* aParentContent)
247
{
248
  return aMap ? aMap->GetFirstNode(aParentContent) : nullptr;
249
}
250
239
UndisplayedNode*
251
UndisplayedNode*
240
nsFrameManager::GetAllUndisplayedContentIn(nsIContent* aParentContent)
252
nsFrameManager::GetAllUndisplayedContentIn(nsIContent* aParentContent)
241
{
253
{
242
  if (!mUndisplayedMap)
254
  return GetAllUndisplayedNodesInMapFor(mUndisplayedMap, aParentContent);
243
    return nullptr;
244
245
  return mUndisplayedMap->GetFirstNode(aParentContent);
246
}
255
}
247
256
248
void
257
/* static */ void
249
nsFrameManager::SetUndisplayedContent(nsIContent* aContent, 
258
nsFrameManager::SetStyleContextInMap(UndisplayedMap* aMap,
250
                                      nsStyleContext* aStyleContext)
259
                                     nsIContent* aContent,
260
                                     nsStyleContext* aStyleContext)
251
{
261
{
252
  NS_PRECONDITION(!aStyleContext->GetPseudo(),
262
  NS_PRECONDITION(!aStyleContext->GetPseudo(),
253
                  "Should only have actual elements here");
263
                  "Should only have actual elements here");
254
264
255
#ifdef DEBUG_UNDISPLAYED_MAP
265
#if defined(DEBUG_UNDISPLAYED_MAP) || defined(DEBUG_DISPLAY_BOX_CONTENTS_MAP)
256
  static int i = 0;
266
  static int i = 0;
257
  printf("SetUndisplayedContent(%d): p=%p \n", i++, (void *)aContent);
267
  printf("SetStyleContextInMap(%d): p=%p \n", i++, (void *)aContent);
258
#endif
268
#endif
259
269
260
  NS_ASSERTION(!GetUndisplayedContent(aContent),
270
  NS_ASSERTION(!GetStyleContextInMap(aMap, aContent),
261
               "Already have an undisplayed context entry for aContent");
271
               "Already have an entry for aContent");
262
272
263
  if (! mUndisplayedMap) {
264
    mUndisplayedMap = new UndisplayedMap;
265
  }
266
  nsIContent* parent = aContent->GetParent();
273
  nsIContent* parent = aContent->GetParent();
267
  NS_ASSERTION(parent || (mPresShell && mPresShell->GetDocument() &&
274
#ifdef DEBUG
268
               mPresShell->GetDocument()->GetRootElement() == aContent),
275
  nsIPresShell* shell = aStyleContext->PresContext()->PresShell();
276
  NS_ASSERTION(parent || (shell && shell->GetDocument() &&
277
                          shell->GetDocument()->GetRootElement() == aContent),
269
               "undisplayed content must have a parent, unless it's the root "
278
               "undisplayed content must have a parent, unless it's the root "
270
               "element");
279
               "element");
271
  mUndisplayedMap->AddNodeFor(parent, aContent, aStyleContext);
280
#endif
281
  aMap->AddNodeFor(parent, aContent, aStyleContext);
272
}
282
}
273
283
274
void
284
void
275
nsFrameManager::ChangeUndisplayedContent(nsIContent* aContent, 
285
nsFrameManager::SetUndisplayedContent(nsIContent* aContent,
276
                                         nsStyleContext* aStyleContext)
286
                                      nsStyleContext* aStyleContext)
277
{
287
{
278
  NS_ASSERTION(mUndisplayedMap, "no existing undisplayed content");
288
  if (!mUndisplayedMap) {
279
  
289
    mUndisplayedMap = new UndisplayedMap;
280
#ifdef DEBUG_UNDISPLAYED_MAP
290
  }
291
  SetStyleContextInMap(mUndisplayedMap, aContent, aStyleContext);
292
}
293
294
/* static */ void
295
nsFrameManager::ChangeStyleContextInMap(UndisplayedMap* aMap,
296
                                        nsIContent* aContent,
297
                                        nsStyleContext* aStyleContext)
298
{
299
  MOZ_ASSERT(aMap, "expecting a map");
300
301
#if defined(DEBUG_UNDISPLAYED_MAP) || defined(DEBUG_DISPLAY_BOX_CONTENTS_MAP)
281
   static int i = 0;
302
   static int i = 0;
282
   printf("ChangeUndisplayedContent(%d): p=%p \n", i++, (void *)aContent);
303
   printf("ChangeStyleContextInMap(%d): p=%p \n", i++, (void *)aContent);
283
#endif
304
#endif
284
305
285
  for (UndisplayedNode* node = mUndisplayedMap->GetFirstNode(aContent->GetParent());
306
  for (UndisplayedNode* node = aMap->GetFirstNode(aContent->GetParent());
286
         node; node = node->mNext) {
307
         node; node = node->mNext) {
287
    if (node->mContent == aContent) {
308
    if (node->mContent == aContent) {
288
      node->mStyle = aStyleContext;
309
      node->mStyle = aStyleContext;
289
      return;
310
      return;
290
    }
311
    }
291
  }
312
  }
292
313
293
  NS_NOTREACHED("no existing undisplayed content");
314
  MOZ_CRASH("couldn't find the entry to change");
294
}
315
}
295
316
296
void
317
void
297
nsFrameManager::ClearUndisplayedContentIn(nsIContent* aContent,
318
nsFrameManager::ClearUndisplayedContentIn(nsIContent* aContent,
298
                                          nsIContent* aParentContent)
319
                                          nsIContent* aParentContent)
299
{
320
{
300
#ifdef DEBUG_UNDISPLAYED_MAP
321
#ifdef DEBUG_UNDISPLAYED_MAP
301
  static int i = 0;
322
  static int i = 0;
 Lines 316-331   nsFrameManager::ClearUndisplayedContentI Link Here 
316
        nsStyleContext *context = GetUndisplayedContent(aContent);
337
        nsStyleContext *context = GetUndisplayedContent(aContent);
317
        NS_ASSERTION(context == nullptr, "Found more undisplayed content data after removal");
338
        NS_ASSERTION(context == nullptr, "Found more undisplayed content data after removal");
318
#endif
339
#endif
319
        return;
340
        return;
320
      }
341
      }
321
      node = node->mNext;
342
      node = node->mNext;
322
    }
343
    }
323
  }
344
  }
345
#ifdef DEBUG_UNDISPLAYED_MAP
346
  printf( "not found.\n");
347
#endif
324
}
348
}
325
349
326
void
350
void
327
nsFrameManager::ClearAllUndisplayedContentIn(nsIContent* aParentContent)
351
nsFrameManager::ClearAllUndisplayedContentIn(nsIContent* aParentContent)
328
{
352
{
329
#ifdef DEBUG_UNDISPLAYED_MAP
353
#ifdef DEBUG_UNDISPLAYED_MAP
330
  static int i = 0;
354
  static int i = 0;
331
  printf("ClearAllUndisplayedContentIn(%d): parent=%p \n", i++, (void*)aParentContent);
355
  printf("ClearAllUndisplayedContentIn(%d): parent=%p \n", i++, (void*)aParentContent);
 Lines 343-358   nsFrameManager::ClearAllUndisplayedConte Link Here 
343
  for (nsIContent* child = iter.GetNextChild(); child; child = iter.GetNextChild()) {
367
  for (nsIContent* child = iter.GetNextChild(); child; child = iter.GetNextChild()) {
344
    if (child->GetParent() != aParentContent) {
368
    if (child->GetParent() != aParentContent) {
345
      ClearUndisplayedContentIn(child, child->GetParent());
369
      ClearUndisplayedContentIn(child, child->GetParent());
346
    }
370
    }
347
  }
371
  }
348
}
372
}
349
373
350
//----------------------------------------------------------------------
374
//----------------------------------------------------------------------
375
376
void
377
nsFrameManager::SetDisplayBoxContents(nsIContent* aContent,
378
                                      nsStyleContext* aStyleContext)
379
{
380
  if (!mDisplayBoxContentsMap) {
381
    mDisplayBoxContentsMap = new UndisplayedMap;
382
  }
383
  SetStyleContextInMap(mDisplayBoxContentsMap, aContent, aStyleContext);
384
}
385
386
UndisplayedNode*
387
nsFrameManager::GetAllDisplayBoxContentsIn(nsIContent* aParentContent)
388
{
389
  return GetAllUndisplayedNodesInMapFor(mDisplayBoxContentsMap, aParentContent);
390
}
391
392
void
393
nsFrameManager::ClearDisplayBoxContentsIn(nsIContent* aContent,
394
                                          nsIContent* aParentContent)
395
{
396
#ifdef DEBUG_DISPLAY_BOX_CONTENTS_MAP
397
  static int i = 0;
398
  printf("ClearDisplayBoxContents(%d): content=%p parent=%p --> ", i++, (void *)aContent, (void*)aParentContent);
399
#endif
400
  
401
  if (mDisplayBoxContentsMap) {
402
    UndisplayedNode* node = mDisplayBoxContentsMap->GetFirstNode(aParentContent);
403
    while (node) {
404
      if (node->mContent == aContent) {
405
        mDisplayBoxContentsMap->RemoveNodeFor(aParentContent, node);
406
407
#ifdef DEBUG_DISPLAY_BOX_CONTENTS_MAP
408
        printf( "REMOVED!\n");
409
#endif
410
#ifdef DEBUG
411
        // make sure that there are no more entries for the same content
412
        nsStyleContext* context = GetDisplayBoxContentsStyleFor(aContent);
413
        NS_ASSERTION(context == nullptr, "Found more entries for aContent after removal");
414
#endif
415
        ClearAllDisplayBoxContentsIn(aContent);
416
        ClearAllUndisplayedContentIn(aContent);
417
        return;
418
      }
419
      node = node->mNext;
420
    }
421
  }
422
#ifdef DEBUG_DISPLAY_BOX_CONTENTS_MAP
423
  printf( "not found.\n");
424
#endif
425
}
426
427
void
428
nsFrameManager::ClearAllDisplayBoxContentsIn(nsIContent* aParentContent)
429
{
430
#ifdef DEBUG_DISPLAY_BOX_CONTENTS_MAP
431
  static int i = 0;
432
  printf("ClearAllDisplayBoxContentsIn(%d): parent=%p \n", i++, (void*)aParentContent);
433
#endif
434
435
  if (mDisplayBoxContentsMap) {
436
    UndisplayedNode* cur = mDisplayBoxContentsMap->UnlinkNodesFor(aParentContent);
437
    while (cur) {
438
      UndisplayedNode* next = cur->mNext;
439
      cur->mNext = nullptr;
440
      ClearAllDisplayBoxContentsIn(cur->mContent);
441
      ClearAllUndisplayedContentIn(cur->mContent);
442
      delete cur;
443
      cur = next;
444
    }
445
  }
446
447
  // Need to look at aParentContent's content list due to XBL insertions.
448
  // Nodes in aParentContent's content list do not have aParentContent as a
449
  // parent, but are treated as children of aParentContent. We iterate over
450
  // the flattened content list and just ignore any nodes we don't care about.
451
  FlattenedChildIterator iter(aParentContent);
452
  for (nsIContent* child = iter.GetNextChild(); child; child = iter.GetNextChild()) {
453
    if (child->GetParent() != aParentContent) {
454
      ClearDisplayBoxContentsIn(child, child->GetParent());
455
      ClearUndisplayedContentIn(child, child->GetParent());
456
    }
457
  }
458
}
459
460
//----------------------------------------------------------------------
351
void
461
void
352
nsFrameManager::AppendFrames(nsContainerFrame* aParentFrame,
462
nsFrameManager::AppendFrames(nsContainerFrame* aParentFrame,
353
                             ChildListID       aListID,
463
                             ChildListID       aListID,
354
                             nsFrameList&      aFrameList)
464
                             nsFrameList&      aFrameList)
355
{
465
{
356
  if (aParentFrame->IsAbsoluteContainer() &&
466
  if (aParentFrame->IsAbsoluteContainer() &&
357
      aListID == aParentFrame->GetAbsoluteListID()) {
467
      aListID == aParentFrame->GetAbsoluteListID()) {
358
    aParentFrame->GetAbsoluteContainingBlock()->
468
    aParentFrame->GetAbsoluteContainingBlock()->
 Lines 419-434   nsFrameManager::RemoveFrame(ChildListID Link Here 
419
//----------------------------------------------------------------------
529
//----------------------------------------------------------------------
420
530
421
void
531
void
422
nsFrameManager::NotifyDestroyingFrame(nsIFrame* aFrame)
532
nsFrameManager::NotifyDestroyingFrame(nsIFrame* aFrame)
423
{
533
{
424
  nsIContent* content = aFrame->GetContent();
534
  nsIContent* content = aFrame->GetContent();
425
  if (content && content->GetPrimaryFrame() == aFrame) {
535
  if (content && content->GetPrimaryFrame() == aFrame) {
426
    ClearAllUndisplayedContentIn(content);
536
    ClearAllUndisplayedContentIn(content);
537
    ClearAllDisplayBoxContentsIn(content);
427
  }
538
  }
428
}
539
}
429
540
430
// Capture state for a given frame.
541
// Capture state for a given frame.
431
// Accept a content id here, in some cases we may not have content (scroll position)
542
// Accept a content id here, in some cases we may not have content (scroll position)
432
void
543
void
433
nsFrameManager::CaptureFrameStateFor(nsIFrame* aFrame,
544
nsFrameManager::CaptureFrameStateFor(nsIFrame* aFrame,
434
                                     nsILayoutHistoryState* aState)
545
                                     nsILayoutHistoryState* aState)
 Lines 695-722   nsFrameManagerBase::UndisplayedMap::Remo Link Here 
695
        }
806
        }
696
        node = node->mNext;
807
        node = node->mNext;
697
      }
808
      }
698
    }
809
    }
699
  }
810
  }
700
  delete aNode;
811
  delete aNode;
701
}
812
}
702
813
703
void
814
704
nsFrameManagerBase::UndisplayedMap::RemoveNodesFor(nsIContent* aParentContent)
815
UndisplayedNode*
816
nsFrameManagerBase::UndisplayedMap::UnlinkNodesFor(nsIContent* aParentContent)
705
{
817
{
706
  PLHashEntry** entry = GetEntryFor(&aParentContent);
818
  PLHashEntry** entry = GetEntryFor(&aParentContent);
707
  NS_ASSERTION(entry, "content not in map");
819
  NS_ASSERTION(entry, "content not in map");
708
  if (*entry) {
820
  if (*entry) {
709
    UndisplayedNode*  node = (UndisplayedNode*)((*entry)->value);
821
    UndisplayedNode* node = (UndisplayedNode*)((*entry)->value);
710
    NS_ASSERTION(node, "null node for non-null entry in UndisplayedMap");
822
    NS_ASSERTION(node, "null node for non-null entry in UndisplayedMap");
711
    delete node;
712
    PL_HashTableRawRemove(mTable, entry, *entry);
823
    PL_HashTableRawRemove(mTable, entry, *entry);
713
    mLastLookup = nullptr; // hashtable may have shifted bucket out from under us
824
    mLastLookup = nullptr; // hashtable may have shifted bucket out from under us
825
    return node;
714
  }
826
  }
827
  return nullptr;
828
}
829
830
void
831
nsFrameManagerBase::UndisplayedMap::RemoveNodesFor(nsIContent* aParentContent)
832
{
833
  delete UnlinkNodesFor(aParentContent);
715
}
834
}
716
835
717
static int
836
static int
718
RemoveUndisplayedEntry(PLHashEntry* he, int i, void* arg)
837
RemoveUndisplayedEntry(PLHashEntry* he, int i, void* arg)
719
{
838
{
720
  UndisplayedNode*  node = (UndisplayedNode*)(he->value);
839
  UndisplayedNode*  node = (UndisplayedNode*)(he->value);
721
  delete node;
840
  delete node;
722
  // Remove and free this entry and continue enumerating
841
  // Remove and free this entry and continue enumerating
(-)a/layout/base/nsFrameManager.h (-4 / +71 lines)
Line     Link Here 
 Lines 103-129   public: Link Here 
103
    RegisterPlaceholderFrame(nsPlaceholderFrame* aPlaceholderFrame);
103
    RegisterPlaceholderFrame(nsPlaceholderFrame* aPlaceholderFrame);
104
104
105
  void
105
  void
106
    UnregisterPlaceholderFrame(nsPlaceholderFrame* aPlaceholderFrame);
106
    UnregisterPlaceholderFrame(nsPlaceholderFrame* aPlaceholderFrame);
107
107
108
  void      ClearPlaceholderFrameMap();
108
  void      ClearPlaceholderFrameMap();
109
109
110
  // Mapping undisplayed content
110
  // Mapping undisplayed content
111
  nsStyleContext* GetUndisplayedContent(nsIContent* aContent);
111
  nsStyleContext* GetUndisplayedContent(nsIContent* aContent)
112
  {
113
    if (!mUndisplayedMap) {
114
      return nullptr;
115
    }
116
    return GetStyleContextInMap(mUndisplayedMap, aContent);
117
  }
112
  mozilla::UndisplayedNode*
118
  mozilla::UndisplayedNode*
113
    GetAllUndisplayedContentIn(nsIContent* aParentContent);
119
    GetAllUndisplayedContentIn(nsIContent* aParentContent);
114
  void SetUndisplayedContent(nsIContent* aContent,
120
  void SetUndisplayedContent(nsIContent* aContent,
115
                                         nsStyleContext* aStyleContext);
121
                             nsStyleContext* aStyleContext);
116
  void ChangeUndisplayedContent(nsIContent* aContent,
122
  void ChangeUndisplayedContent(nsIContent* aContent,
117
                                            nsStyleContext* aStyleContext);
123
                                nsStyleContext* aStyleContext)
124
  {
125
    ChangeStyleContextInMap(mUndisplayedMap, aContent, aStyleContext);
126
  }
127
118
  void ClearUndisplayedContentIn(nsIContent* aContent,
128
  void ClearUndisplayedContentIn(nsIContent* aContent,
119
                                             nsIContent* aParentContent);
129
                                 nsIContent* aParentContent);
120
  void ClearAllUndisplayedContentIn(nsIContent* aParentContent);
130
  void ClearAllUndisplayedContentIn(nsIContent* aParentContent);
121
131
132
  // display-box:contents related methods:
133
  /**
134
   * Return the registered display-box:contents style context for aContent, if any.
135
   */
136
  nsStyleContext* GetDisplayBoxContentsStyleFor(nsIContent* aContent)
137
  {
138
    if (!mDisplayBoxContentsMap) {
139
      return nullptr;
140
    }
141
    return GetStyleContextInMap(mDisplayBoxContentsMap, aContent);
142
  }
143
144
  /**
145
   * Return the linked list of UndisplayedNodes containing the registered
146
   * display-box:contents children of aParentContent, if any.
147
   */
148
  mozilla::UndisplayedNode*
149
    GetAllDisplayBoxContentsIn(nsIContent* aParentContent);
150
  /**
151
   * Register aContent having a display-box:contents style context.
152
   */
153
  void SetDisplayBoxContents(nsIContent* aContent,
154
                             nsStyleContext* aStyleContext);
155
  /**
156
   * Change the registered style context for aContent to aStyleContext.
157
   */
158
  void ChangeDisplayBoxContents(nsIContent* aContent,
159
                                nsStyleContext* aStyleContext)
160
  {
161
    ChangeStyleContextInMap(mDisplayBoxContentsMap, aContent, aStyleContext);
162
  }
163
164
  /**
165
   * Unregister the display-box:contents style context for aContent, if any.
166
   * If found, then also unregister any display-box:contents and display:none
167
   * style contexts for its descendants.
168
   */
169
  void ClearDisplayBoxContentsIn(nsIContent* aContent,
170
                                 nsIContent* aParentContent);
171
  /**
172
   * Unregister display-box:contents and display:none style contexts for all
173
   * descendants of aParentContent.
174
   */
175
  void ClearAllDisplayBoxContentsIn(nsIContent* aParentContent);
176
122
  // Functions for manipulating the frame model
177
  // Functions for manipulating the frame model
123
  void AppendFrames(nsContainerFrame* aParentFrame,
178
  void AppendFrames(nsContainerFrame* aParentFrame,
124
                    ChildListID       aListID,
179
                    ChildListID       aListID,
125
                    nsFrameList&      aFrameList);
180
                    nsFrameList&      aFrameList);
126
181
127
  void InsertFrames(nsContainerFrame* aParentFrame,
182
  void InsertFrames(nsContainerFrame* aParentFrame,
128
                    ChildListID       aListID,
183
                    ChildListID       aListID,
129
                    nsIFrame*         aPrevFrame,
184
                    nsIFrame*         aPrevFrame,
 Lines 156-166   public: Link Here 
156
  /*
211
  /*
157
   * Add/restore state for one frame
212
   * Add/restore state for one frame
158
   */
213
   */
159
  void CaptureFrameStateFor(nsIFrame*              aFrame,
214
  void CaptureFrameStateFor(nsIFrame*              aFrame,
160
                                        nsILayoutHistoryState* aState);
215
                                        nsILayoutHistoryState* aState);
161
216
162
  void RestoreFrameStateFor(nsIFrame*              aFrame,
217
  void RestoreFrameStateFor(nsIFrame*              aFrame,
163
                                        nsILayoutHistoryState* aState);
218
                                        nsILayoutHistoryState* aState);
219
protected:
220
  static nsStyleContext* GetStyleContextInMap(UndisplayedMap* aMap,
221
                                              nsIContent* aContent);
222
  static mozilla::UndisplayedNode*
223
    GetAllUndisplayedNodesInMapFor(UndisplayedMap* aMap,
224
                                   nsIContent* aParentContent);
225
  static void SetStyleContextInMap(UndisplayedMap* aMap,
226
                                   nsIContent* aContent,
227
                                   nsStyleContext* aStyleContext);
228
  static void ChangeStyleContextInMap(UndisplayedMap* aMap,
229
                                      nsIContent* aContent,
230
                                      nsStyleContext* aStyleContext);
164
};
231
};
165
232
166
#endif
233
#endif
(-)a/layout/base/nsFrameManagerBase.h (+2 lines)
Line     Link Here 
 Lines 29-44   class nsStyleSet; Link Here 
29
class nsFrameManagerBase
29
class nsFrameManagerBase
30
{
30
{
31
public:
31
public:
32
  nsFrameManagerBase()
32
  nsFrameManagerBase()
33
    : mPresShell(nullptr)
33
    : mPresShell(nullptr)
34
    , mStyleSet(nullptr)
34
    , mStyleSet(nullptr)
35
    , mRootFrame(nullptr)
35
    , mRootFrame(nullptr)
36
    , mUndisplayedMap(nullptr)
36
    , mUndisplayedMap(nullptr)
37
    , mDisplayBoxContentsMap(nullptr)
37
    , mIsDestroyingFrames(false)
38
    , mIsDestroyingFrames(false)
38
  {
39
  {
39
    mPlaceholderMap.ops = nullptr;
40
    mPlaceholderMap.ops = nullptr;
40
  }
41
  }
41
42
42
  bool IsDestroyingFrames() { return mIsDestroyingFrames; }
43
  bool IsDestroyingFrames() { return mIsDestroyingFrames; }
43
44
44
  /*
45
  /*
 Lines 60-75   protected: Link Here 
60
61
61
  // weak link, because the pres shell owns us
62
  // weak link, because the pres shell owns us
62
  nsIPresShell*                   mPresShell;
63
  nsIPresShell*                   mPresShell;
63
  // the pres shell owns the style set
64
  // the pres shell owns the style set
64
  nsStyleSet*                     mStyleSet;
65
  nsStyleSet*                     mStyleSet;
65
  nsIFrame*                       mRootFrame;
66
  nsIFrame*                       mRootFrame;
66
  PLDHashTable                    mPlaceholderMap;
67
  PLDHashTable                    mPlaceholderMap;
67
  UndisplayedMap*                 mUndisplayedMap;
68
  UndisplayedMap*                 mUndisplayedMap;
69
  UndisplayedMap*                 mDisplayBoxContentsMap;
68
  bool                            mIsDestroyingFrames;  // The frame manager is destroying some frame(s).
70
  bool                            mIsDestroyingFrames;  // The frame manager is destroying some frame(s).
69
71
70
  // The frame tree generation number
72
  // The frame tree generation number
71
  // We use this to avoid unnecessary screenshotting
73
  // We use this to avoid unnecessary screenshotting
72
  // on Android. Unfortunately, this is static to match
74
  // on Android. Unfortunately, this is static to match
73
  // the single consumer which is also static. Keeping
75
  // the single consumer which is also static. Keeping
74
  // this the same greatly simplifies lifetime issues and
76
  // this the same greatly simplifies lifetime issues and
75
  // makes sure we always using the correct number.
77
  // makes sure we always using the correct number.
(-)a/layout/base/nsLayoutUtils.cpp (-96 / +64 lines)
Line     Link Here 
 Lines 903-985   nsLayoutUtils::LastContinuationWithChild Link Here 
903
  NS_PRECONDITION(aFrame, "NULL frame pointer");
903
  NS_PRECONDITION(aFrame, "NULL frame pointer");
904
  nsIFrame* f = aFrame->LastContinuation();
904
  nsIFrame* f = aFrame->LastContinuation();
905
  while (!f->GetFirstPrincipalChild() && f->GetPrevContinuation()) {
905
  while (!f->GetFirstPrincipalChild() && f->GetPrevContinuation()) {
906
    f = f->GetPrevContinuation();
906
    f = f->GetPrevContinuation();
907
  }
907
  }
908
  return static_cast<nsContainerFrame*>(f);
908
  return static_cast<nsContainerFrame*>(f);
909
}
909
}
910
910
911
/**
912
 * GetFirstChildFrame returns the first "real" child frame of a
913
 * given frame.  It will descend down into pseudo-frames (unless the
914
 * pseudo-frame is the :before generated frame).
915
 * @param aFrame the frame
916
 * @param aFrame the frame's content node
917
 */
918
static nsIFrame*
919
GetFirstChildFrame(nsIFrame*       aFrame,
920
                   nsIContent*     aContent)
921
{
922
  NS_PRECONDITION(aFrame, "NULL frame pointer");
923
924
  // Get the first child frame
925
  nsIFrame* childFrame = aFrame->GetFirstPrincipalChild();
926
927
  // If the child frame is a pseudo-frame, then return its first child.
928
  // Note that the frame we create for the generated content is also a
929
  // pseudo-frame and so don't drill down in that case
930
  if (childFrame &&
931
      childFrame->IsPseudoFrame(aContent) &&
932
      !childFrame->IsGeneratedContentFrame()) {
933
    return GetFirstChildFrame(childFrame, aContent);
934
  }
935
936
  return childFrame;
937
}
938
939
/**
940
 * GetLastChildFrame returns the last "real" child frame of a
941
 * given frame.  It will descend down into pseudo-frames (unless the
942
 * pseudo-frame is the :after generated frame).
943
 * @param aFrame the frame
944
 * @param aFrame the frame's content node
945
 */
946
static nsIFrame*
947
GetLastChildFrame(nsContainerFrame* aFrame,
948
                  nsIContent*       aContent)
949
{
950
  NS_PRECONDITION(aFrame, "NULL frame pointer");
951
952
  // Get the last continuation frame that's a parent
953
  nsContainerFrame* lastParentContinuation =
954
    nsLayoutUtils::LastContinuationWithChild(aFrame);
955
  nsIFrame* lastChildFrame =
956
    lastParentContinuation->GetLastChild(nsIFrame::kPrincipalList);
957
  if (lastChildFrame) {
958
    // Get the frame's first continuation. This matters in case the frame has
959
    // been continued across multiple lines or split by BiDi resolution.
960
    lastChildFrame = lastChildFrame->FirstContinuation();
961
962
    // If the last child frame is a pseudo-frame, then return its last child.
963
    // Note that the frame we create for the generated content is also a
964
    // pseudo-frame and so don't drill down in that case
965
    if (lastChildFrame &&
966
        lastChildFrame->IsPseudoFrame(aContent) &&
967
        !lastChildFrame->IsGeneratedContentFrame()) {
968
      return GetLastChildFrame(static_cast<nsContainerFrame*>(lastChildFrame),
969
                               aContent);
970
    }
971
972
    return lastChildFrame;
973
  }
974
975
  return nullptr;
976
}
977
978
//static
911
//static
979
FrameChildListID
912
FrameChildListID
980
nsLayoutUtils::GetChildListNameFor(nsIFrame* aChildFrame)
913
nsLayoutUtils::GetChildListNameFor(nsIFrame* aChildFrame)
981
{
914
{
982
  nsIFrame::ChildListID id = nsIFrame::kPrincipalList;
915
  nsIFrame::ChildListID id = nsIFrame::kPrincipalList;
983
916
984
  if (aChildFrame->GetStateBits() & NS_FRAME_IS_OVERFLOW_CONTAINER) {
917
  if (aChildFrame->GetStateBits() & NS_FRAME_IS_OVERFLOW_CONTAINER) {
985
    nsIFrame* pif = aChildFrame->GetPrevInFlow();
918
    nsIFrame* pif = aChildFrame->GetPrevInFlow();
 Lines 1068-1121   nsLayoutUtils::GetChildListNameFor(nsIFr Link Here 
1068
    // else it's positioned and should have been on the 'id' child list.
1001
    // else it's positioned and should have been on the 'id' child list.
1069
    NS_POSTCONDITION(found, "not in child list");
1002
    NS_POSTCONDITION(found, "not in child list");
1070
  }
1003
  }
1071
#endif
1004
#endif
1072
1005
1073
  return id;
1006
  return id;
1074
}
1007
}
1075
1008
1076
// static
1009
/*static*/ nsIFrame*
1077
nsIFrame*
1010
nsLayoutUtils::GetBeforeFrameForContent(nsIFrame* aFrame,
1011
                                        nsIContent* aContent)
1012
{
1013
  nsContainerFrame* genConParentFrame = aFrame->GetContentInsertionFrame();
1014
  if (!genConParentFrame) {
1015
    return nullptr;
1016
  }
1017
  nsTArray<nsIContent*>* prop = genConParentFrame->GetGenConPseudos();
1018
  if (prop) {
1019
    const nsTArray<nsIContent*>& pseudos(*prop);
1020
    for (uint32_t i = 0; i < pseudos.Length(); ++i) {
1021
      if (pseudos[i]->GetParent() == aContent &&
1022
          pseudos[i]->Tag() == nsGkAtoms::mozgeneratedcontentbefore) {
1023
        return pseudos[i]->GetPrimaryFrame();
1024
      }
1025
    }
1026
  }
1027
  // If the first child frame is a pseudo-frame, then try that.
1028
  // Note that the frame we create for the generated content is also a
1029
  // pseudo-frame and so don't drill down in that case.
1030
  nsIFrame* childFrame = genConParentFrame->GetFirstPrincipalChild();
1031
  if (childFrame &&
1032
      childFrame->IsPseudoFrame(aContent) &&
1033
      !childFrame->IsGeneratedContentFrame()) {
1034
    return GetBeforeFrameForContent(childFrame, aContent);
1035
  }
1036
  return nullptr;
1037
}
1038
1039
/*static*/ nsIFrame*
1078
nsLayoutUtils::GetBeforeFrame(nsIFrame* aFrame)
1040
nsLayoutUtils::GetBeforeFrame(nsIFrame* aFrame)
1079
{
1041
{
1080
  NS_PRECONDITION(aFrame, "NULL frame pointer");
1042
  return GetBeforeFrameForContent(aFrame, aFrame->GetContent());
1081
  NS_ASSERTION(!aFrame->GetPrevContinuation(),
1043
}
1082
               "aFrame must be first continuation");
1044
1083
1045
/*static*/ nsIFrame*
1084
  nsIFrame* cif = aFrame->GetContentInsertionFrame();
1046
nsLayoutUtils::GetAfterFrameForContent(nsIFrame* aFrame,
1085
  if (!cif) {
1047
                                       nsIContent* aContent)
1048
{
1049
  nsContainerFrame* genConParentFrame = aFrame->GetContentInsertionFrame();
1050
  if (!genConParentFrame) {
1086
    return nullptr;
1051
    return nullptr;
1087
  }
1052
  }
1088
  nsIFrame* firstFrame = GetFirstChildFrame(cif, aFrame->GetContent());
1053
  nsTArray<nsIContent*>* prop = genConParentFrame->GetGenConPseudos();
1089
  if (firstFrame && IsGeneratedContentFor(nullptr, firstFrame,
1054
  if (prop) {
1090
                                          nsCSSPseudoElements::before)) {
1055
    const nsTArray<nsIContent*>& pseudos(*prop);
1091
    return firstFrame;
1056
    for (uint32_t i = 0; i < pseudos.Length(); ++i) {
1092
  }
1057
      if (pseudos[i]->GetParent() == aContent &&
1093
1058
          pseudos[i]->Tag() == nsGkAtoms::mozgeneratedcontentafter) {
1059
        return pseudos[i]->GetPrimaryFrame();
1060
      }
1061
    }
1062
  }
1063
  // If the last child frame is a pseudo-frame, then try that.
1064
  // Note that the frame we create for the generated content is also a
1065
  // pseudo-frame and so don't drill down in that case.
1066
  nsIFrame* lastParentContinuation =
1067
    nsLayoutUtils::LastContinuationWithChild(genConParentFrame);
1068
  nsIFrame* childFrame =
1069
    lastParentContinuation->GetLastChild(nsIFrame::kPrincipalList);
1070
  if (childFrame &&
1071
      childFrame->IsPseudoFrame(aContent) &&
1072
      !childFrame->IsGeneratedContentFrame()) {
1073
    return GetAfterFrameForContent(childFrame->FirstContinuation(), aContent);
1074
  }
1094
  return nullptr;
1075
  return nullptr;
1095
}
1076
}
1096
1077
1097
// static
1078
/*static*/ nsIFrame*
1098
nsIFrame*
1099
nsLayoutUtils::GetAfterFrame(nsIFrame* aFrame)
1079
nsLayoutUtils::GetAfterFrame(nsIFrame* aFrame)
1100
{
1080
{
1101
  NS_PRECONDITION(aFrame, "NULL frame pointer");
1081
  return GetAfterFrameForContent(aFrame, aFrame->GetContent());
1102
1103
  nsContainerFrame* cif = aFrame->GetContentInsertionFrame();
1104
  if (!cif) {
1105
    return nullptr;
1106
  }
1107
  nsIFrame* lastFrame = GetLastChildFrame(cif, aFrame->GetContent());
1108
  if (lastFrame && IsGeneratedContentFor(nullptr, lastFrame,
1109
                                         nsCSSPseudoElements::after)) {
1110
    return lastFrame;
1111
  }
1112
1113
  return nullptr;
1114
}
1082
}
1115
1083
1116
// static
1084
// static
1117
nsIFrame*
1085
nsIFrame*
1118
nsLayoutUtils::GetClosestFrameOfType(nsIFrame* aFrame, nsIAtom* aFrameType)
1086
nsLayoutUtils::GetClosestFrameOfType(nsIFrame* aFrame, nsIAtom* aFrameType)
1119
{
1087
{
1120
  for (nsIFrame* frame = aFrame; frame; frame = frame->GetParent()) {
1088
  for (nsIFrame* frame = aFrame; frame; frame = frame->GetParent()) {
1121
    if (frame->GetType() == aFrameType) {
1089
    if (frame->GetType() == aFrameType) {
(-)a/layout/base/nsLayoutUtils.h (-4 / +29 lines)
Line     Link Here 
 Lines 199-230   public: Link Here 
199
199
200
  /**
200
  /**
201
   * Use heuristics to figure out the child list that
201
   * Use heuristics to figure out the child list that
202
   * aChildFrame is currently in.
202
   * aChildFrame is currently in.
203
   */
203
   */
204
  static mozilla::layout::FrameChildListID GetChildListNameFor(nsIFrame* aChildFrame);
204
  static mozilla::layout::FrameChildListID GetChildListNameFor(nsIFrame* aChildFrame);
205
205
206
  /**
206
  /**
207
   * GetBeforeFrame returns the outermost :before frame of the given frame, if
207
   * GetBeforeFrameForContent returns the ::before frame for aContent, if
208
   * one exists.  This is typically O(1).  The frame passed in must be
208
   * one exists.  This is typically O(1).  The frame passed in must be
209
   * the first-in-flow.
209
   * the first-in-flow.
210
   *
210
   *
211
   * @param aFrame the frame whose :before is wanted
211
   * @param aGenConParentFrame an ancestor of the ::before frame
212
   * @param aContent the content whose ::before is wanted
213
   * @return the ::before frame or nullptr if there isn't one
214
   */
215
  static nsIFrame* GetBeforeFrameForContent(nsIFrame* aGenConParentFrame,
216
                                            nsIContent* aContent);
217
218
  /**
219
   * GetBeforeFrame returns the outermost ::before frame of the given frame, if
220
   * one exists.  This is typically O(1).  The frame passed in must be
221
   * the first-in-flow.
222
   *
223
   * @param aFrame the frame whose ::before is wanted
212
   * @return the :before frame or nullptr if there isn't one
224
   * @return the :before frame or nullptr if there isn't one
213
   */
225
   */
214
  static nsIFrame* GetBeforeFrame(nsIFrame* aFrame);
226
  static nsIFrame* GetBeforeFrame(nsIFrame* aFrame);
215
227
216
  /**
228
  /**
217
   * GetAfterFrame returns the outermost :after frame of the given frame, if one
229
   * GetAfterFrameForContent returns the ::after frame for aContent, if one
230
   * exists.  This will walk the in-flow chain of aGenConParentFrame to the
231
   * last-in-flow if needed.  This function is typically O(N) in the number
232
   * of child frames, following in-flows, etc.
233
   *
234
   * @param aGenConParentFrame an ancestor of the ::after frame
235
   * @param aContent the content whose ::after is wanted
236
   * @return the ::after frame or nullptr if there isn't one
237
   */
238
  static nsIFrame* GetAfterFrameForContent(nsIFrame* aGenConParentFrame,
239
                                           nsIContent* aContent);
240
241
  /**
242
   * GetAfterFrame returns the outermost ::after frame of the given frame, if one
218
   * exists.  This will walk the in-flow chain to the last-in-flow if
243
   * exists.  This will walk the in-flow chain to the last-in-flow if
219
   * needed.  This function is typically O(N) in the number of child
244
   * needed.  This function is typically O(N) in the number of child
220
   * frames, following in-flows, etc.
245
   * frames, following in-flows, etc.
221
   *
246
   *
222
   * @param aFrame the frame whose :after is wanted
247
   * @param aFrame the frame whose ::after is wanted
223
   * @return the :after frame or nullptr if there isn't one
248
   * @return the :after frame or nullptr if there isn't one
224
   */
249
   */
225
  static nsIFrame* GetAfterFrame(nsIFrame* aFrame);
250
  static nsIFrame* GetAfterFrame(nsIFrame* aFrame);
226
251
227
  /**
252
  /**
228
   * Given a frame, search up the frame tree until we find an
253
   * Given a frame, search up the frame tree until we find an
229
   * ancestor that (or the frame itself) is of type aFrameType, if any.
254
   * ancestor that (or the frame itself) is of type aFrameType, if any.
230
   *
255
   *
(-)a/layout/base/nsStyleChangeList.cpp (-2 / +8 lines)
Line     Link Here 
 Lines 5-20    Link Here 
5
5
6
/*
6
/*
7
 * a list of the recomputation that needs to be done in response to a
7
 * a list of the recomputation that needs to be done in response to a
8
 * style change
8
 * style change
9
 */
9
 */
10
10
11
#include "nsStyleChangeList.h"
11
#include "nsStyleChangeList.h"
12
#include "nsIContent.h"
12
#include "nsIContent.h"
13
#include "nsIFrame.h"
14
#include "nsFrameManager.h"
13
15
14
static const uint32_t kGrowArrayBy = 10;
16
static const uint32_t kGrowArrayBy = 10;
15
17
16
nsStyleChangeList::nsStyleChangeList()
18
nsStyleChangeList::nsStyleChangeList()
17
  : mArray(mBuffer),
19
  : mArray(mBuffer),
18
    mArraySize(kStyleChangeBufferSize),
20
    mArraySize(kStyleChangeBufferSize),
19
    mCount(0)
21
    mCount(0)
20
{
22
{
 Lines 53-70   nsStyleChangeList::ChangeAt(int32_t aInd Link Here 
53
nsresult 
55
nsresult 
54
nsStyleChangeList::AppendChange(nsIFrame* aFrame, nsIContent* aContent, nsChangeHint aHint)
56
nsStyleChangeList::AppendChange(nsIFrame* aFrame, nsIContent* aContent, nsChangeHint aHint)
55
{
57
{
56
  NS_ASSERTION(aFrame || (aHint & nsChangeHint_ReconstructFrame),
58
  NS_ASSERTION(aFrame || (aHint & nsChangeHint_ReconstructFrame),
57
               "must have frame");
59
               "must have frame");
58
  NS_ASSERTION(aContent || !(aHint & nsChangeHint_ReconstructFrame),
60
  NS_ASSERTION(aContent || !(aHint & nsChangeHint_ReconstructFrame),
59
               "must have content");
61
               "must have content");
60
  // XXXbz we should make this take Element instead of nsIContent
62
  // XXXbz we should make this take Element instead of nsIContent
61
  NS_ASSERTION(!aContent || aContent->IsElement(),
63
  NS_ASSERTION(!aContent || aContent->IsElement() ||
62
               "Shouldn't be trying to restyle non-elements directly");
64
               // display-box:contents elements posts the changes for their children:
65
               (aFrame && aContent->GetParent() &&
66
                aFrame->PresContext()->FrameManager()->GetDisplayBoxContentsStyleFor(aContent->GetParent())),
67
               "Shouldn't be trying to restyle non-elements directly, "
68
               "except if it's a display-box:contents child");
63
  NS_ASSERTION(!(aHint & nsChangeHint_AllReflowHints) ||
69
  NS_ASSERTION(!(aHint & nsChangeHint_AllReflowHints) ||
64
               (aHint & nsChangeHint_NeedReflow),
70
               (aHint & nsChangeHint_NeedReflow),
65
               "Reflow hint bits set without actually asking for a reflow");
71
               "Reflow hint bits set without actually asking for a reflow");
66
72
67
  if ((0 < mCount) && (aHint & nsChangeHint_ReconstructFrame)) { // filter out all other changes for same content
73
  if ((0 < mCount) && (aHint & nsChangeHint_ReconstructFrame)) { // filter out all other changes for same content
68
    if (aContent) {
74
    if (aContent) {
69
      for (int32_t index = mCount - 1; index >= 0; --index) {
75
      for (int32_t index = mCount - 1; index >= 0; --index) {
70
        if (aContent == mArray[index].mContent) { // remove this change
76
        if (aContent == mArray[index].mContent) { // remove this change
(-)a/layout/generic/nsFrame.cpp (-18 / +57 lines)
Line     Link Here 
 Lines 5483-5500   nsIFrame::ListGeneric(nsACString& aTo, c Link Here 
5483
  aTo += nsPrintfCString(" [sc=%p", static_cast<void*>(mStyleContext));
5483
  aTo += nsPrintfCString(" [sc=%p", static_cast<void*>(mStyleContext));
5484
  if (mStyleContext) {
5484
  if (mStyleContext) {
5485
    nsIAtom* pseudoTag = mStyleContext->GetPseudo();
5485
    nsIAtom* pseudoTag = mStyleContext->GetPseudo();
5486
    if (pseudoTag) {
5486
    if (pseudoTag) {
5487
      nsAutoString atomString;
5487
      nsAutoString atomString;
5488
      pseudoTag->ToString(atomString);
5488
      pseudoTag->ToString(atomString);
5489
      aTo += nsPrintfCString("%s", NS_LossyConvertUTF16toASCII(atomString).get());
5489
      aTo += nsPrintfCString("%s", NS_LossyConvertUTF16toASCII(atomString).get());
5490
    }
5490
    }
5491
    if (GetParent() && mStyleContext->GetParent() != GetParent()->StyleContext()) {
5491
    if (!mStyleContext->GetParent() ||
5492
      aTo += nsPrintfCString(",parent=%p", mStyleContext->GetParent());
5492
        (GetParent() && GetParent()->StyleContext() != mStyleContext->GetParent())) {
5493
      aTo += nsPrintfCString("^%p", mStyleContext->GetParent());
5494
      if (mStyleContext->GetParent()) {
5495
        aTo += nsPrintfCString("^%p", mStyleContext->GetParent()->GetParent());
5496
        if (mStyleContext->GetParent()->GetParent()) {
5497
          aTo += nsPrintfCString("^%p", mStyleContext->GetParent()->GetParent()->GetParent());
5498
        }
5499
      }
5493
    }
5500
    }
5494
  }
5501
  }
5495
  aTo += "]";
5502
  aTo += "]";
5496
}
5503
}
5497
5504
5498
void
5505
void
5499
nsIFrame::List(FILE* out, const char* aPrefix, uint32_t aFlags) const
5506
nsIFrame::List(FILE* out, const char* aPrefix, uint32_t aFlags) const
5500
{
5507
{
 Lines 7619-7672   nsFrame::CorrectStyleParentFrame(nsIFram Link Here 
7619
  // We can get here if the root element is absolutely positioned.
7626
  // We can get here if the root element is absolutely positioned.
7620
  // We can't test for this very accurately, but it can only happen
7627
  // We can't test for this very accurately, but it can only happen
7621
  // when the prospective parent is a canvas frame.
7628
  // when the prospective parent is a canvas frame.
7622
  NS_ASSERTION(aProspectiveParent->GetType() == nsGkAtoms::canvasFrame,
7629
  NS_ASSERTION(aProspectiveParent->GetType() == nsGkAtoms::canvasFrame,
7623
               "Should have found a parent before this");
7630
               "Should have found a parent before this");
7624
  return nullptr;
7631
  return nullptr;
7625
}
7632
}
7626
7633
7627
nsIFrame*
7634
nsStyleContext*
7628
nsFrame::DoGetParentStyleContextFrame() const
7635
nsFrame::DoGetParentStyleContext(nsIFrame** aProviderFrame) const
7629
{
7636
{
7630
  if (mContent && !mContent->GetParent() &&
7637
  *aProviderFrame = nullptr;
7631
      !StyleContext()->GetPseudo()) {
7638
  nsFrameManager* fm = PresContext()->FrameManager();
7632
    // we're a frame for the root.  We have no style context parent.
7639
  if (MOZ_LIKELY(mContent)) {
7633
    return nullptr;
7640
    nsIContent* parentContent = mContent->GetParent();
7634
  }
7641
    if (MOZ_LIKELY(parentContent)) {
7635
  
7642
      nsIAtom* pseudo = StyleContext()->GetPseudo();
7643
      if (!pseudo || !mContent->IsElement() ||
7644
          !nsCSSAnonBoxes::IsAnonBox(pseudo) ||
7645
          /* if next is true then it's really a request for the table frame's
7646
             parent context, see nsTable[Outer]Frame::GetParentStyleContext. */
7647
          pseudo == nsCSSAnonBoxes::tableOuter) {
7648
        nsStyleContext* sc = fm->GetDisplayBoxContentsStyleFor(parentContent);
7649
        if (MOZ_UNLIKELY(sc)) {
7650
          return sc;
7651
        }
7652
      }
7653
    } else {
7654
      if (!StyleContext()->GetPseudo()) {
7655
        // we're a frame for the root.  We have no style context parent.
7656
        return nullptr;
7657
      }
7658
    }
7659
  }
7660
7636
  if (!(mState & NS_FRAME_OUT_OF_FLOW)) {
7661
  if (!(mState & NS_FRAME_OUT_OF_FLOW)) {
7637
    /*
7662
    /*
7638
     * If this frame is an anonymous block created when an inline with a block
7663
     * If this frame is an anonymous block created when an inline with a block
7639
     * inside it got split, then the parent style context is on its preceding
7664
     * inside it got split, then the parent style context is on its preceding
7640
     * inline. We can get to it using GetIBSplitSiblingForAnonymousBlock.
7665
     * inline. We can get to it using GetIBSplitSiblingForAnonymousBlock.
7641
     */
7666
     */
7642
    if (mState & NS_FRAME_PART_OF_IBSPLIT) {
7667
    if (mState & NS_FRAME_PART_OF_IBSPLIT) {
7643
      nsIFrame* ibSplitSibling = GetIBSplitSiblingForAnonymousBlock(this);
7668
      nsIFrame* ibSplitSibling = GetIBSplitSiblingForAnonymousBlock(this);
7644
      if (ibSplitSibling) {
7669
      if (ibSplitSibling) {
7645
        return ibSplitSibling;
7670
        return (*aProviderFrame = ibSplitSibling)->StyleContext();
7646
      }
7671
      }
7647
    }
7672
    }
7648
7673
7649
    // If this frame is one of the blocks that split an inline, we must
7674
    // If this frame is one of the blocks that split an inline, we must
7650
    // return the "special" inline parent, i.e., the parent that this
7675
    // return the "special" inline parent, i.e., the parent that this
7651
    // frame would have if we didn't mangle the frame structure.
7676
    // frame would have if we didn't mangle the frame structure.
7652
    return GetCorrectedParent(this);
7677
    *aProviderFrame = GetCorrectedParent(this);
7678
    return *aProviderFrame ? (*aProviderFrame)->StyleContext() : nullptr;
7653
  }
7679
  }
7654
7680
7655
  // We're an out-of-flow frame.  For out-of-flow frames, we must
7681
  // We're an out-of-flow frame.  For out-of-flow frames, we must
7656
  // resolve underneath the placeholder's parent.  The placeholder is
7682
  // resolve underneath the placeholder's parent.  The placeholder is
7657
  // reached from the first-in-flow.
7683
  // reached from the first-in-flow.
7658
  nsIFrame* placeholder = PresContext()->FrameManager()->
7684
  nsIFrame* placeholder = fm->GetPlaceholderFrameFor(FirstInFlow());
7659
                            GetPlaceholderFrameFor(FirstInFlow());
7660
  if (!placeholder) {
7685
  if (!placeholder) {
7661
    NS_NOTREACHED("no placeholder frame for out-of-flow frame");
7686
    NS_NOTREACHED("no placeholder frame for out-of-flow frame");
7662
    return GetCorrectedParent(this);
7687
    *aProviderFrame = GetCorrectedParent(this);
7663
  }
7688
    return *aProviderFrame ? (*aProviderFrame)->StyleContext() : nullptr;
7664
  return placeholder->GetParentStyleContextFrame();
7689
  }
7690
  return placeholder->GetParentStyleContext(aProviderFrame);
7665
}
7691
}
7666
7692
7667
void
7693
void
7668
nsFrame::GetLastLeaf(nsPresContext* aPresContext, nsIFrame **aFrame)
7694
nsFrame::GetLastLeaf(nsPresContext* aPresContext, nsIFrame **aFrame)
7669
{
7695
{
7670
  if (!aFrame || !*aFrame)
7696
  if (!aFrame || !*aFrame)
7671
    return;
7697
    return;
7672
  nsIFrame *child = *aFrame;
7698
  nsIFrame *child = *aFrame;
 Lines 8514-8529   nsIFrame::DestroyDT(void* aPropertyValue Link Here 
8514
}
8540
}
8515
8541
8516
void
8542
void
8517
nsIFrame::DestroyRegion(void* aPropertyValue)
8543
nsIFrame::DestroyRegion(void* aPropertyValue)
8518
{
8544
{
8519
  delete static_cast<nsRegion*>(aPropertyValue);
8545
  delete static_cast<nsRegion*>(aPropertyValue);
8520
}
8546
}
8521
8547
8548
/*static*/ void
8549
nsIFrame::DestroyContentArray(void* aPropertyValue)
8550
{
8551
  typedef nsTArray<nsIContent*> T;
8552
  T* arr = static_cast<T*>(aPropertyValue);
8553
  for (T::size_type i = 0; i < arr->Length(); ++i) {
8554
    nsIContent* content = (*arr)[i];
8555
    content->UnbindFromTree();
8556
    NS_RELEASE(content);
8557
  }
8558
  delete arr;
8559
}
8560
8522
bool
8561
bool
8523
nsIFrame::IsPseudoStackingContextFromStyle() {
8562
nsIFrame::IsPseudoStackingContextFromStyle() {
8524
  const nsStyleDisplay* disp = StyleDisplay();
8563
  const nsStyleDisplay* disp = StyleDisplay();
8525
  // If you change this, also change the computation of pseudoStackingContext
8564
  // If you change this, also change the computation of pseudoStackingContext
8526
  // in BuildDisplayListForChild()
8565
  // in BuildDisplayListForChild()
8527
  return disp->mOpacity != 1.0f ||
8566
  return disp->mOpacity != 1.0f ||
8528
         disp->IsPositioned(this) ||
8567
         disp->IsPositioned(this) ||
8529
         disp->IsFloating(this) ||
8568
         disp->IsFloating(this) ||
(-)a/layout/generic/nsFrame.h (-4 / +10 lines)
Line     Link Here 
 Lines 216-243   public: Link Here 
216
216
217
  virtual nsresult  GetOffsets(int32_t &aStart, int32_t &aEnd) const MOZ_OVERRIDE;
217
  virtual nsresult  GetOffsets(int32_t &aStart, int32_t &aEnd) const MOZ_OVERRIDE;
218
  virtual void ChildIsDirty(nsIFrame* aChild) MOZ_OVERRIDE;
218
  virtual void ChildIsDirty(nsIFrame* aChild) MOZ_OVERRIDE;
219
219
220
#ifdef ACCESSIBILITY
220
#ifdef ACCESSIBILITY
221
  virtual mozilla::a11y::AccType AccessibleType() MOZ_OVERRIDE;
221
  virtual mozilla::a11y::AccType AccessibleType() MOZ_OVERRIDE;
222
#endif
222
#endif
223
223
224
  virtual nsIFrame* GetParentStyleContextFrame() const MOZ_OVERRIDE {
224
  virtual nsStyleContext* GetParentStyleContext(nsIFrame** aProviderFrame) const MOZ_OVERRIDE {
225
    return DoGetParentStyleContextFrame();
225
    return DoGetParentStyleContext(aProviderFrame);
226
  }
226
  }
227
227
228
  /**
228
  /**
229
   * Do the work for getting the parent style context frame so that
229
   * Do the work for getting the parent style context frame so that
230
   * other frame's |GetParentStyleContextFrame| methods can call this
230
   * other frame's |GetParentStyleContext| methods can call this
231
   * method on *another* frame.  (This function handles out-of-flow
231
   * method on *another* frame.  (This function handles out-of-flow
232
   * frames by using the frame manager's placeholder map and it also
232
   * frames by using the frame manager's placeholder map and it also
233
   * handles block-within-inline and generated content wrappers.)
233
   * handles block-within-inline and generated content wrappers.)
234
   *
235
   * @param aProviderFrame (out) the frame associated with the returned value
236
   *     or null if the style context is for display-box:contents content.
237
   * @return The style context that should be the parent of this frame's
238
   *         style context.  Null is permitted, and means that this frame's
239
   *         style context should be the root of the style context tree.
234
   */
240
   */
235
  nsIFrame* DoGetParentStyleContextFrame() const;
241
  nsStyleContext* DoGetParentStyleContext(nsIFrame** aProviderFrame) const;
236
242
237
  virtual bool IsEmpty() MOZ_OVERRIDE;
243
  virtual bool IsEmpty() MOZ_OVERRIDE;
238
  virtual bool IsSelfEmpty() MOZ_OVERRIDE;
244
  virtual bool IsSelfEmpty() MOZ_OVERRIDE;
239
245
240
  virtual void MarkIntrinsicWidthsDirty() MOZ_OVERRIDE;
246
  virtual void MarkIntrinsicWidthsDirty() MOZ_OVERRIDE;
241
  virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
247
  virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
242
  virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
248
  virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
243
  virtual void AddInlineMinWidth(nsRenderingContext *aRenderingContext,
249
  virtual void AddInlineMinWidth(nsRenderingContext *aRenderingContext,
(-)a/layout/generic/nsIFrame.h (-2 / +12 lines)
Line     Link Here 
 Lines 766-781   public: Link Here 
766
766
767
  static void DestroyOverflowAreas(void* aPropertyValue)
767
  static void DestroyOverflowAreas(void* aPropertyValue)
768
  {
768
  {
769
    delete static_cast<nsOverflowAreas*>(aPropertyValue);
769
    delete static_cast<nsOverflowAreas*>(aPropertyValue);
770
  }
770
  }
771
771
772
  static void DestroySurface(void* aPropertyValue);
772
  static void DestroySurface(void* aPropertyValue);
773
  static void DestroyDT(void* aPropertyValue);
773
  static void DestroyDT(void* aPropertyValue);
774
  static void DestroyContentArray(void* aPropertyValue);
774
775
775
#ifdef _MSC_VER
776
#ifdef _MSC_VER
776
// XXX Workaround MSVC issue by making the static FramePropertyDescriptor
777
// XXX Workaround MSVC issue by making the static FramePropertyDescriptor
777
// non-const.  See bug 555727.
778
// non-const.  See bug 555727.
778
#define NS_PROPERTY_DESCRIPTOR_CONST
779
#define NS_PROPERTY_DESCRIPTOR_CONST
779
#else
780
#else
780
#define NS_PROPERTY_DESCRIPTOR_CONST const
781
#define NS_PROPERTY_DESCRIPTOR_CONST const
781
#endif
782
#endif
 Lines 825-840   public: Link Here 
825
826
826
  NS_DECLARE_FRAME_PROPERTY(CachedBackgroundImage, DestroySurface)
827
  NS_DECLARE_FRAME_PROPERTY(CachedBackgroundImage, DestroySurface)
827
  NS_DECLARE_FRAME_PROPERTY(CachedBackgroundImageDT, DestroyDT)
828
  NS_DECLARE_FRAME_PROPERTY(CachedBackgroundImageDT, DestroyDT)
828
829
829
  NS_DECLARE_FRAME_PROPERTY(InvalidationRect, DestroyRect)
830
  NS_DECLARE_FRAME_PROPERTY(InvalidationRect, DestroyRect)
830
831
831
  NS_DECLARE_FRAME_PROPERTY(RefusedAsyncAnimation, nullptr)
832
  NS_DECLARE_FRAME_PROPERTY(RefusedAsyncAnimation, nullptr)
832
833
834
  NS_DECLARE_FRAME_PROPERTY(GenConProperty, DestroyContentArray)
835
836
  nsTArray<nsIContent*>* GetGenConPseudos() {
837
    const FramePropertyDescriptor* prop = GenConProperty();
838
    return static_cast<nsTArray<nsIContent*>*>(Properties().Get(prop));
839
  }
840
833
  /**
841
  /**
834
   * Return the distance between the border edge of the frame and the
842
   * Return the distance between the border edge of the frame and the
835
   * margin edge of the frame.  Like GetRect(), returns the dimensions
843
   * margin edge of the frame.  Like GetRect(), returns the dimensions
836
   * as of the most recent reflow.
844
   * as of the most recent reflow.
837
   *
845
   *
838
   * This doesn't include any margin collapsing that may have occurred.
846
   * This doesn't include any margin collapsing that may have occurred.
839
   *
847
   *
840
   * It also treats 'auto' margins as zero, and treats any margins that
848
   * It also treats 'auto' margins as zero, and treats any margins that
 Lines 2417-2437   public: Link Here 
2417
  /**
2425
  /**
2418
   * Get the frame whose style context should be the parent of this
2426
   * Get the frame whose style context should be the parent of this
2419
   * frame's style context (i.e., provide the parent style context).
2427
   * frame's style context (i.e., provide the parent style context).
2420
   * This frame must either be an ancestor of this frame or a child.  If
2428
   * This frame must either be an ancestor of this frame or a child.  If
2421
   * this returns a child frame, then the child frame must be sure to
2429
   * this returns a child frame, then the child frame must be sure to
2422
   * return a grandparent or higher!  Furthermore, if a child frame is
2430
   * return a grandparent or higher!  Furthermore, if a child frame is
2423
   * returned it must have the same GetContent() as this frame.
2431
   * returned it must have the same GetContent() as this frame.
2424
   *
2432
   *
2425
   * @return The frame whose style context should be the parent of this frame's
2433
   * @param aProviderFrame (out) the frame associated with the returned value
2434
   *     or nullptr if the style context is for display-box:contents content.
2435
   * @return The style context that should be the parent of this frame's
2426
   *         style context.  Null is permitted, and means that this frame's
2436
   *         style context.  Null is permitted, and means that this frame's
2427
   *         style context should be the root of the style context tree.
2437
   *         style context should be the root of the style context tree.
2428
   */
2438
   */
2429
  virtual nsIFrame* GetParentStyleContextFrame() const = 0;
2439
  virtual nsStyleContext* GetParentStyleContext(nsIFrame** aProviderFrame) const = 0;
2430
2440
2431
  /**
2441
  /**
2432
   * Determines whether a frame is visible for painting;
2442
   * Determines whether a frame is visible for painting;
2433
   * taking into account whether it is painting a selection or printing.
2443
   * taking into account whether it is painting a selection or printing.
2434
   */
2444
   */
2435
  bool IsVisibleForPainting(nsDisplayListBuilder* aBuilder);
2445
  bool IsVisibleForPainting(nsDisplayListBuilder* aBuilder);
2436
  /**
2446
  /**
2437
   * Determines whether a frame is visible for painting or collapsed;
2447
   * Determines whether a frame is visible for painting or collapsed;
(-)a/layout/generic/nsPlaceholderFrame.cpp (-3 / +14 lines)
Line     Link Here 
 Lines 180-204   nsPlaceholderFrame::CanContinueTextRun() Link Here 
180
  if (!mOutOfFlowFrame) {
180
  if (!mOutOfFlowFrame) {
181
    return false;
181
    return false;
182
  }
182
  }
183
  // first-letter frames can continue text runs, and placeholders for floated
183
  // first-letter frames can continue text runs, and placeholders for floated
184
  // first-letter frames can too
184
  // first-letter frames can too
185
  return mOutOfFlowFrame->CanContinueTextRun();
185
  return mOutOfFlowFrame->CanContinueTextRun();
186
}
186
}
187
187
188
nsIFrame*
188
nsStyleContext*
189
nsPlaceholderFrame::GetParentStyleContextFrame() const
189
nsPlaceholderFrame::GetParentStyleContext(nsIFrame** aProviderFrame) const
190
{
190
{
191
  NS_PRECONDITION(GetParent(), "How can we not have a parent here?");
191
  NS_PRECONDITION(GetParent(), "How can we not have a parent here?");
192
192
193
  nsIContent* parentContent = mContent ? mContent->GetParent() : nullptr;
194
  if (parentContent) {
195
    nsStyleContext* sc =
196
      PresContext()->FrameManager()->GetDisplayBoxContentsStyleFor(parentContent);
197
    if (sc) {
198
      *aProviderFrame = nullptr;
199
      return sc;
200
    }
201
  }
202
193
  // Lie about our pseudo so we can step out of all anon boxes and
203
  // Lie about our pseudo so we can step out of all anon boxes and
194
  // pseudo-elements.  The other option would be to reimplement the
204
  // pseudo-elements.  The other option would be to reimplement the
195
  // {ib} split gunk here.
205
  // {ib} split gunk here.
196
  return CorrectStyleParentFrame(GetParent(), nsGkAtoms::placeholderFrame);
206
  *aProviderFrame = CorrectStyleParentFrame(GetParent(), nsGkAtoms::placeholderFrame);
207
  return *aProviderFrame ? (*aProviderFrame)->StyleContext() : nullptr;
197
}
208
}
198
209
199
210
200
#ifdef DEBUG
211
#ifdef DEBUG
201
static void
212
static void
202
PaintDebugPlaceholder(nsIFrame* aFrame, nsRenderingContext* aCtx,
213
PaintDebugPlaceholder(nsIFrame* aFrame, nsRenderingContext* aCtx,
203
                      const nsRect& aDirtyRect, nsPoint aPt)
214
                      const nsRect& aDirtyRect, nsPoint aPt)
204
{
215
{
(-)a/layout/generic/nsPlaceholderFrame.h (-1 / +1 lines)
Line     Link Here 
 Lines 130-146   public: Link Here 
130
  virtual mozilla::a11y::AccType AccessibleType() MOZ_OVERRIDE
130
  virtual mozilla::a11y::AccType AccessibleType() MOZ_OVERRIDE
131
  {
131
  {
132
    nsIFrame* realFrame = GetRealFrameForPlaceholder(this);
132
    nsIFrame* realFrame = GetRealFrameForPlaceholder(this);
133
    return realFrame ? realFrame->AccessibleType() :
133
    return realFrame ? realFrame->AccessibleType() :
134
                       nsFrame::AccessibleType();
134
                       nsFrame::AccessibleType();
135
  }
135
  }
136
#endif
136
#endif
137
137
138
  virtual nsIFrame* GetParentStyleContextFrame() const MOZ_OVERRIDE;
138
  virtual nsStyleContext* GetParentStyleContext(nsIFrame** aProviderFrame) const MOZ_OVERRIDE;
139
139
140
  /**
140
  /**
141
   * @return the out-of-flow for aFrame if aFrame is a placeholder; otherwise
141
   * @return the out-of-flow for aFrame if aFrame is a placeholder; otherwise
142
   * aFrame
142
   * aFrame
143
   */
143
   */
144
  static nsIFrame* GetRealFrameFor(nsIFrame* aFrame) {
144
  static nsIFrame* GetRealFrameFor(nsIFrame* aFrame) {
145
    NS_PRECONDITION(aFrame, "Must have a frame to work with");
145
    NS_PRECONDITION(aFrame, "Must have a frame to work with");
146
    if (aFrame->GetType() == nsGkAtoms::placeholderFrame) {
146
    if (aFrame->GetType() == nsGkAtoms::placeholderFrame) {
(-)a/layout/reftests/css-display/display-box-contents-495385-2d-ref.html (+19 lines)
Line     Link Here 
Line 0    Link Here 
1
<!DOCTYPE HTML>
2
<html>
3
<head>
4
<style>
5
body > div { border:1px solid black; margin:1em;
6
             font-family:sans-serif; letter-spacing:2px; }
7
</style>
8
</head>
9
<body>
10
  <div><span>Hello</span> <span>Kitty</span></div>
11
  <div><span>Hello</span> <span>Kitty</span></div>
12
  <div><span>Hello</span> <span>Kitty</span></div>
13
  <div><span>Hello</span> <span>Kitty</span></div>
14
  <div><span>Hello</span> <span>Kitty</span></div>
15
  <div><span>Hello</span> <span>Kitty</span></div>
16
  <div><span>Hello</span> <span>Kitty</span></div>
17
  <div><span>Hello</span> <span>Kitty</span></div>
18
</body>
19
</html>
(-)a/layout/reftests/css-display/display-box-contents-495385-2d.html (+44 lines)
Line     Link Here 
Line 0    Link Here 
1
<!DOCTYPE HTML>
2
<html>
3
<head>
4
<!-- Test that before/after generated content stops suppression correctly,
5
     both statically and dynamically -->
6
<style>
7
body > div { border:1px solid black; margin:1em;
8
             font-family:sans-serif; letter-spacing:2px; }
9
#d1:before { content:"Hello"; }
10
#d2:after { content:"Kitty"; }
11
#d3.c:before { content:"Hello"; }
12
#d4.c:after { content:"Kitty"; }
13
#d5.c:before { content:"Hello"; }
14
#d6.c:after { content:"Kitty"; }
15
#d7.c:after { content:"Kitty"; }
16
#d8.c:before { content:"Hello"; }
17
#d5,#d6 { overflow:hidden; }
18
#d1,#d2,#d3,#d4 { display-box:contents; }
19
x { display:table; }
20
y { display:table-outer; }
21
</style>
22
<script>
23
function loaded() {
24
  document.body.offsetHeight;
25
  document.getElementById("d3").setAttribute("class", "c");
26
  document.getElementById("d4").setAttribute("class", "c");
27
  document.getElementById("d5").setAttribute("class", "c");
28
  document.getElementById("d6").setAttribute("class", "c");
29
  document.getElementById("d7").setAttribute("class", "c");
30
  document.getElementById("d8").setAttribute("class", "c");
31
}
32
</script>
33
</head>
34
<body onload="loaded()">
35
  <div><div id="d1"> <span>Kitty</span></div></div>
36
  <div><div id="d2"><span>Hello</span> </div></div>
37
  <div><div id="d3"> <span>Kitty</span></div></div>
38
  <div><div id="d4"><span>Hello</span> </div></div>
39
  <div><div id="d5"> <span>Kitty</span></div></div>
40
  <div><div id="d6"><span>Hello</span> </div></div>
41
  <div><x id="d7"><span>Hello</span> </div></x>
42
  <div><x id="d8"> <span>Kitty</span> </div></x>
43
</body>
44
</html>
(-)a/layout/reftests/css-display/display-box-contents-acid-dyn-1.html (+45 lines)
Line     Link Here 
Line 0    Link Here 
1
<!DOCTYPE html>
2
<html lang="en-US">
3
<head>
4
  <meta charset="UTF-8">
5
  <title>CSS Test: CSS display-box:contents</title>
6
  <link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=907396">
7
  <link rel="help" href="http://dev.w3.org/csswg/css-display">
8
<style type="text/css">
9
10
        html,body {
11
            color:black; background-color:white; height:100%; font-size:16px; padding:0; margin:0;
12
        }
13
14
iframe { padding:0;margin:0;border-width:0;width:100%;height:90%; color:red; }
15
16
    </style>
17
<script>
18
function runTest(iframe) {
19
  var win = iframe.contentWindow;
20
  var doc = iframe.contentDocument;
21
  doc.body.offsetHeight
22
  var e = doc.querySelectorAll('*');
23
  var contents = new Array;
24
  for (i=0; i < e.length; ++i) {
25
    var elm = e[i];
26
    if (win.getComputedStyle(elm).displayBox == 'contents') {
27
      contents.push(elm);
28
      elm.style.displayBox='none';
29
    }
30
  }
31
  doc.body.offsetHeight;
32
  for (i=0; i < contents.length; ++i) {
33
    elm = contents[i];
34
    elm.style.displayBox='contents';
35
  }
36
  doc.body.offsetHeight;
37
}
38
</script>
39
</head>
40
<body>
41
42
<iframe src="display-box-contents-acid.html" frameborder=0 onload="runTest(this)"></iframe>
43
44
</body>
45
</html>
(-)a/layout/reftests/css-display/display-box-contents-acid-dyn-2.html (+45 lines)
Line     Link Here 
Line 0    Link Here 
1
<!DOCTYPE html>
2
<html lang="en-US">
3
<head>
4
  <meta charset="UTF-8">
5
  <title>CSS Test: CSS display-box:contents</title>
6
  <link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=907396">
7
  <link rel="help" href="http://dev.w3.org/csswg/css-display">
8
<style type="text/css">
9
10
        html,body {
11
            color:black; background-color:white; height:100%; font-size:16px; padding:0; margin:0;
12
        }
13
14
iframe { padding:0;margin:0;border-width:0;width:100%;height:90%; color:red; }
15
16
    </style>
17
<script>
18
function runTest(iframe) {
19
  var win = iframe.contentWindow;
20
  var doc = iframe.contentDocument;
21
  doc.body.offsetHeight
22
  var e = doc.querySelectorAll('*');
23
  var contents = new Array;
24
  for (i=0; i < e.length; ++i) {
25
    var elm = e[i];
26
    if (win.getComputedStyle(elm).displayBox == 'contents') {
27
      contents.push(elm);
28
      elm.style.displayBox='inline';
29
    }
30
  }
31
  doc.body.offsetHeight;
32
  for (i=0; i < contents.length; ++i) {
33
    elm = contents[i];
34
    elm.style.displayBox='contents';
35
  }
36
  doc.body.offsetHeight;
37
}
38
</script>
39
</head>
40
<body>
41
42
<iframe src="display-box-contents-acid.html" frameborder=0 onload="runTest(this)"></iframe>
43
44
</body>
45
</html>
(-)a/layout/reftests/css-display/display-box-contents-acid-dyn-3.html (+46 lines)
Line     Link Here 
Line 0    Link Here 
1
<!DOCTYPE html>
2
<html lang="en-US">
3
<head>
4
  <meta charset="UTF-8">
5
  <title>CSS Test: CSS display-box:contents</title>
6
  <link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=907396">
7
  <link rel="help" href="http://dev.w3.org/csswg/css-display">
8
<style type="text/css">
9
10
        html,body {
11
            color:black; background-color:white; height:100%; font-size:16px; padding:0; margin:0;
12
        }
13
14
iframe { padding:0;margin:0;border-width:0;width:100%;height:90%; color:red; }
15
16
    </style>
17
<script>
18
function runTest(iframe) {
19
  var win = iframe.contentWindow;
20
  var doc = iframe.contentDocument;
21
  doc.body.offsetHeight
22
  var e = doc.querySelectorAll('*');
23
  var contents = new Array;
24
  for (i=0; i < e.length; ++i) {
25
    var elm = e[i];
26
    if (win.getComputedStyle(elm).displayBox == 'contents') {
27
      contents.push([ elm, elm.nextSibling, elm.parentNode ]);
28
      elm.parentNode.removeChild(elm);
29
    }
30
  }
31
  doc.body.offsetHeight;
32
  var i = contents.length;
33
  while(i--) {
34
    var arr = contents[i];
35
    arr[2].insertBefore(arr[0], arr[1]);
36
  }
37
  doc.body.offsetHeight;
38
}
39
</script>
40
</head>
41
<body>
42
43
<iframe src="display-box-contents-acid.html" frameborder=0 onload="runTest(this)"></iframe>
44
45
</body>
46
</html>
(-)a/layout/reftests/css-display/display-box-contents-acid-ref.html (+180 lines)
Line     Link Here 
Line 0    Link Here 
1
<!DOCTYPE html>
2
<html lang="en-US">
3
<head>
4
  <meta charset="UTF-8">
5
  <title>CSS Test: CSS display-box:contents</title>
6
  <link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=907396">
7
<style type="text/css">
8
9
        html,body {
10
            color:black; background-color:white; font-size:16px; padding:0; margin:0;
11
        }
12
	
13
.table   { display:table; border-collapse:collapse; border: blue solid 1pt;}
14
.itable  { display:inline-table; }
15
.caption { display:table-caption; }
16
.cell    { display:table-cell; border:inherit; }
17
.row     { display:table-row; border: green dashed 1pt; }
18
.rowg    { display:table-row-group; }
19
.head    { display:table-header-group; }
20
.foot    { display:table-footer-group; }
21
.col     { display:table-column; }
22
.colg    { display:table-column-group; }
23
.flex    { display:flex; }
24
.iflex   { display:inline-flex; }
25
.li      { display:list-item; }
26
.ib      { display:inline-block; }
27
.inline  { display:inline; }
28
.columns  { -moz-columns:2; columns:2; height:4em; }
29
30
31
32
.c1 { color:lime; }
33
.c2 { color:pink; }
34
.c3 { color:teal; }
35
.c4 { color:green; }
36
.c5 { color:silver; }
37
.c6 { color:cyan; }
38
.c7 { color:magenta; }
39
.c8 { color:yellow; }
40
.c9 { color:grey; }
41
.c10{ color:black; }
42
43
.b { background:blue; }
44
    </style>
45
</head>
46
<body style="color:red">
47
48
<div class="caption c2">1<span>1</span></div>
49
<div class="row c2">2a<div class="cell">2<div class="inline c2">b<span class="b">b</span></div></div></div>
50
<div class="cell c3">3</div>
51
<div class="rowg c4">4</div>
52
<div class="cell c5">5a</div>
53
<div class="cell c5">5b</div>
54
<div class="head c6">6</div>
55
<div class="cell c7"><div class="inline c2">7<span class="b">a</span></div></div>
56
<div class="cell c8">7b</div>
57
<div class="foot c9">8</div>
58
<div class="foot c9">9<div class="inline c2">a<span class="b">b</span>c</div></div>
59
<div class="cell c10">10</div>
60
61
<div class="table" style="float:right">
62
<div class="caption c2">1<span>1</span></div>
63
<div class="row c2">2a<div class="cell">2<div class="inline c2">b<span class="b">b</span></div></div></div>
64
<div class="cell c3" style="border:none">3</div>
65
<div class="rowg c4">4</div>
66
<div class="cell c5" style="border:none">5a</div>
67
<div class="cell c5">5b</div>
68
<div class="head c6">6</div>
69
<div class="cell c7" style="border:none"><div class="inline c2">7<span class="b">a</span></div></div>
70
<div class="cell c8" style="border:none">7b</div>
71
<div class="foot c9" style="border:none">8</div>
72
<div class="foot c9">9<div class="inline c2">a<span class="b">b</span>c</div></div>
73
<div class="cell c10" style="border:none">10</div>
74
</div>
75
76
<div class="flex c1">
77
0&nbsp;
78
<div class="inline c1">x&nbsp;</div>
79
<div class="inline c1"><div class="inline c2">y</div></div>
80
<div class="inline c1"><div class="inline c2"><div class="">1<span>1</span></div></div></div>
81
<div class="inline c2"><div class="inline">2a<div class="">2<div class="inline c2">b<span class="b">b</span></div></div></div></div>
82
<div class="c3">3</div>
83
<div class="inline"><div class="inline c4">4</div></div>
84
<div class=""><div class="inline c5">5a</div></div>
85
<div class=" c5">5b</div>
86
<div class="inline c6"><div class="">6</div></div>
87
<div class="ib"><div class="inline c7"><div class="inline c2">7<span class="b">a</span></div></div></div>
88
<div class="inline c9"><div class="">8</div></div>
89
<div class="inline c9"><div class="inline">9<div class="inline c2">a</div></div></div>
90
<span class="c2 b">b</span>
91
<div class="inline c2">c</div>
92
<div class="inline c10"><div class="">10</div></div>
93
</div>
94
95
<div class="flex c1">
96
<div class="inline c2">0&nbsp;</div>
97
<div class="inline c1">x&nbsp;</div>
98
<div class="inline c1"><div class="inline c2">y</div></div>
99
<div class="inline c1"><div class="inline c2"><div class="">1<span>1</span></div></div></div>
100
<div class="c2"><div class="inline">2a<div>2<div class="inline c2">b<span class="b">b</span></div></div></div></div>
101
<div class="c3">3</div>
102
<div class="inline"><div class="inline c4">4</div></div>
103
<div class=""><div class="inline c5">5a</div></div>
104
<div class=" c5">5b</div>
105
<div class="inline c6"><div class="">6</div></div>
106
<div class="ib"><div class="inline c7"><div class="inline c2">7<span class="b">a</span></div></div></div>
107
<div class="inline c9"><div class="">8</div></div>
108
<div class="inline c9"><div class="inline">9<div class="inline c2">a</div></div></div>
109
<span class="c2 b">b</span>
110
<div class="inline c2">c</div>
111
<div class="inline c10"><div class="">10</div></div>
112
</div>
113
114
115
<div class="iflex"><div class="contents c2">
116
0
117
</div></div>
118
<div class="iflex"><div class="contents c2">
119
0
120
<div class="inline c1">1</div>
121
2
122
</div></div>
123
<div class="iflex"><div class="contents c2">
124
0<div class="inline c1">1</div>2
125
</div></div>
126
<div class="iflex c3">
127
0<div class="inline c2"><div class="c1">1</div></div>2
128
</div>
129
<div class="iflex c3">
130
<div class="inline c2">0</div><div class="inline c2"><div class="c1">1</div></div><div class="inline c2">2</div>
131
</div>
132
<div class="iflex c3">
133
<div class="inline">0</div>
134
<div class="inline"><div class="inline c1">1</div></div>
135
<div class="inline">2</div>
136
</div>
137
138
<ul><li class="c1"><div class="inline c2">
139
0
140
<div class="inline c1">x</div>
141
<div class="inline c1"><div class="inline c2">y</div></div>
142
<div class="inline c1"><div class="inline c2"><div class="">1<span>1</span></div></div></div>
143
<div class="inline c2"><div class="inline">2a<div class="">2<div class="inline c2">b<span class="b">b</span></div></div></div></div>
144
<div class="inline c3"><div class="inline">3</div></div>
145
<div class="inline"><div class="inline c4">4</div></div>
146
<div class=""><div class="inline c5">5a</div></div>
147
<div class=" c5">5b</div>
148
<div class="inline c6"><div class="">6</div></div>
149
<div class="ib"><div class="inline c7"><div class="inline c2">7<span class="b">a</span></div></div></div>
150
<div class="inline c9"><div class="">8</div></div>
151
<div class="inline c9"><div class="inline">9<div class="inline c2">a<span class="b">b</span>c</div></div></div>
152
<div class="inline c10"><div class="">10</div></div>
153
</div></li>
154
</ul>
155
156
<div class="columns">
157
<div class="contents c1"><div class="contents c2"><div>1<span>1</span></div></div></div>
158
<div class="contents c2"><div>2</div></div>
159
<div class="contents c3"><div>3</div></div>
160
</div>
161
162
<div class="columns">
163
<div class="contents c1"><div class="contents c2"><div>1<span>1</span></div></div></div>
164
<div class="contents c2"><div>2</div></div>
165
<div class="contents c3"><div>3</div></div>
166
</div>
167
168
<span class="c2 b"><legend class="inline c1">Legend</legend><legend class="inline c1">Legend</legend></span>
169
<br clear="all">
170
<span class="c3">x<div class="inline c1">float:left</div></span>
171
<span class="c3">y<div class="inline c1">position:absolute</div></span>
172
173
<!--  -->
174
175
<fieldset class="c1"><legend>Legend</legend>fieldset</fieldset>
176
<button class="c1">but<span>ton</span></button>
177
<select class="c1"><option>select</select>
178
179
</body>
180
</html>
(-)a/layout/reftests/css-display/display-box-contents-acid.html (+187 lines)
Line     Link Here 
Line 0    Link Here 
1
<!DOCTYPE html>
2
<html lang="en-US">
3
<head>
4
  <meta charset="UTF-8">
5
  <title>CSS Test: CSS display-box:contents</title>
6
  <link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=907396">
7
  <link rel="help" href="http://dev.w3.org/csswg/css-display">
8
<style type="text/css">
9
10
        html,body {
11
            color:black; background-color:white; font-size:16px; padding:0; margin:0;
12
        }
13
	
14
.table   { display:table; border-collapse:collapse; border: blue solid 1pt;}
15
.itable  { display:inline-table; }
16
.caption { display:table-caption; }
17
.cell    { display:table-cell; border:inherit; }
18
.row     { display:table-row; border: green dashed 1pt; }
19
.rowg    { display:table-row-group; }
20
.head    { display:table-header-group; }
21
.foot    { display:table-footer-group; }
22
.col     { display:table-column; }
23
.colg    { display:table-column-group; }
24
.flex    { display:flex; }
25
.iflex   { display:inline-flex; }
26
.li      { display:list-item; }
27
.ib      { display:inline-block; }
28
.inline  { display:inline; }
29
.columns  { -moz-columns:2; columns:2; height:4em; }
30
31
.contents { display-box:contents; }
32
33
.c1 { color:lime; }
34
.c2 { background:blue; color:pink; }
35
.c3 { color:teal; }
36
.c4 { color:green; }
37
.c5 { color:silver; }
38
.c6 { color:cyan; }
39
.c7 { color:magenta; }
40
.c8 { color:yellow; }
41
.c9 { color:grey; }
42
.c10{ color:black; }
43
44
.b { background:inherit; }
45
    </style>
46
</head>
47
<body style="color:red">
48
49
<div class="contents c1"><div class="contents c2"><div class="caption">1<span class="b">1</span></div></div></div>
50
<div class="contents c2"><div class="row">2a<div class="cell">2<div class="contents c2">b<span class="b">b</span></div></div></div></div>
51
<div class="contents c3"><div class="cell">3</div></div>
52
<div class="contents c4"><div class="rowg">4</div></div>
53
<div class="contents c5"><div class="cell">5a</div></div>
54
<div class="cell c5">5b</div>
55
<div class="contents c6"><div class="head">6</div></div>
56
<div class="contents c7"><div class="cell"><div class="contents c2">7<span class="b">a</span></div></div></div>
57
<div class="contents c8"><div class="cell">7b</div></div>
58
<div class="contents c9"><div class="foot">8</div></div>
59
<div class="contents c9"><div class="foot">9<div class="contents c2">a<span class="b">b</span>c</div></div></div>
60
<div class="contents c10"><div class="cell">10</div></div>
61
62
<div class="table" style="float:right">
63
<div class="contents c1"><div class="contents c2"><div class="caption">1<span class="b">1</span></div></div></div>
64
<div class="contents c2"><div class="row">2a<div class="cell">2<div class="contents c2">b<span class="b">b</span></div></div></div></div>
65
<div class="contents c3"><div class="cell">3</div></div>
66
<div class="contents c4"><div class="rowg">4</div></div>
67
<div class="contents c5"><div class="cell">5a</div></div>
68
<div class="cell c5">5b</div>
69
<div class="contents c6"><div class="head">6</div></div>
70
<div class="contents c7"><div class="cell"><div class="contents c2">7<span class="b">a</span></div></div></div>
71
<div class="contents c8"><div class="cell">7b</div></div>
72
<div class="contents c9"><div class="foot">8</div></div>
73
<div class="contents c9"><div class="foot">9<div class="contents c2">a<span class="b">b</span>c</div></div></div>
74
<div class="contents c10"><div class="cell">10</div></div>
75
</div>
76
77
<div class="flex c1">
78
0
79
<div class="contents c1">x</div>
80
<div class="contents c1"><div class="contents c2">y</div></div>
81
<div class="contents c1"><div class="contents c2"><div class="">1<span class="b">1</span></div></div></div>
82
<div class="contents c2"><div class="inline">2a<div class="">2<div class="contents c2">b<span class="b">b</span></div></div></div></div>
83
<div class="contents c3"><div class="inline">3</div></div>
84
<div class="inline"><div class="contents c4">4</div></div>
85
<div class=""><div class="contents c5">5a</div></div>
86
<div class=" c5">5b</div>
87
<div class="contents c6"><div class="">6</div></div>
88
<div class="ib"><div class="contents c7"><div class="contents c2">7<span class="b">a</span></div></div></div>
89
<div class="contents c9"><div class="">8</div></div>
90
<div class="contents c9"><div class="contents">9<div class="contents c2">a<span class="b">b</span>c</div></div></div>
91
<div class="contents c10"><div class="">10</div></div>
92
</div>
93
94
<div class="flex"><div class="contents c2">
95
0
96
<div class="contents c1">x</div>
97
<div class="contents c1"><div class="contents c2">y</div></div>
98
<div class="contents c1"><div class="contents c2"><div class="">1<span class="b">1</span></div></div></div>
99
<div class="contents c2"><div class="inline">2a<div class="">2<div class="contents c2">b<span class="b">b</span></div></div></div></div>
100
<div class="contents c3"><div class="inline">3</div></div>
101
<div class=""><div class="contents c4">4</div></div>
102
<div class=""><div class="contents c5">5a</div></div>
103
<div class=" c5">5b</div>
104
<div class="contents c6"><div class="">6</div></div>
105
<div class="ib"><div class="contents c7"><div class="contents c2">7<span class="b">a</span></div></div></div>
106
<div class="contents c9"><div class="">8</div></div>
107
<div class="contents c9"><div class="contents">9<div class="contents c2">a<span class="b">b</span>c</div></div></div>
108
<div class="contents c10"><div class="">10</div></div>
109
</div></div>
110
111
<div class="iflex"><div class="contents c2">
112
0
113
</div></div>
114
<div class="iflex"><div class="contents c2">
115
0
116
<div class="contents c1">1</div>
117
2
118
</div></div>
119
<div class="iflex"><div class="contents c2">
120
0
121
<div class="c1">1</div>
122
2
123
</div></div>
124
<div class="iflex c3">
125
0
126
<div class="contents c2"><div class="c1">1</div></div>
127
2
128
</div>
129
<div class="iflex c3">
130
<div class="contents c2">0</div>
131
<div class="contents c2"><div class="c1">1</div></div>
132
<div class="contents c2">2</div>
133
</div>
134
<div class="iflex c3">
135
<div class="inline">0</div>
136
<div class="contents"><div class="inline c1">1</div></div>
137
<div class="inline">2</div>
138
</div>
139
140
<ul><li class="c1"><div class="contents c2">
141
0
142
<div class="contents c1">x</div>
143
<div class="contents c1"><div class="contents c2">y</div></div>
144
<div class="contents c1"><div class="contents c2"><div class="">1<span class="b">1</span></div></div></div>
145
<div class="contents c2"><div class="inline">2a<div class="">2<div class="contents c2">b<span class="b">b</span></div></div></div></div>
146
<div class="contents c3"><div class="inline">3</div></div>
147
<div class="inline"><div class="contents c4">4</div></div>
148
<div class=""><div class="contents c5">5a</div></div>
149
<div class=" c5">5b</div>
150
<div class="contents c6"><div class="">6</div></div>
151
<div class="ib"><div class="contents c7"><div class="contents c2">7<span class="b">a</span></div></div></div>
152
<div class="contents c9"><div class="">8</div></div>
153
<div class="contents c9"><div class="contents">9<div class="contents c2">a<span class="b">b</span>c</div></div></div>
154
<div class="contents c10"><div class="">10</div></div>
155
</div></li>
156
</ul>
157
158
<div class="columns">
159
<div class="contents c1"><div class="contents c2"><div>1<span class="b">1</span></div></div></div>
160
<div class="contents c2"><div>2</div></div>
161
<div class="contents c3"><div>3</div></div>
162
</div>
163
164
<div class="columns">
165
<div class="columns contents">
166
<div class="contents c1"><div class="contents c2"><div>1<span class="b">1</span></div></div></div>
167
<div class="contents c2"><div>2</div></div>
168
<div class="contents c3"><div>3</div></div>
169
</div>
170
</div>
171
172
<div class="contents c3"><!-- comment node --></div>
173
<div class="contents c3"><?PI ?></div>
174
175
<span class="c2"><legend class="contents c1">Legend</legend><legend class="contents c1">Legend</legend></span>
176
<br clear="all">
177
<span class="c3">x<div class="contents c1" style="float:left">float:left</div></span>
178
<span class="c3">y<div class="contents c1" style="position:absolute">position:absolute</div></span>
179
180
<!-- Stuff below should simply ignore having display-box:contents -->
181
182
<fieldset class="contents c1"><legend class="contents">Legend</legend>fieldset</fieldset>
183
<button class="contents c1">but<span>ton</span></button>
184
<select class="contents c1"><option>select</select>
185
186
</body>
187
</html>
(-)a/layout/reftests/css-display/display-box-contents-generated-content-2.html (+236 lines)
Line     Link Here 
Line 0    Link Here 
1
<!DOCTYPE html>
2
<html lang="en-US" class="reftest-wait">
3
<head>
4
  <meta charset="UTF-8">
5
  <title>CSS Test: CSS display-box:contents; generated content</title>
6
  <link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=907396">
7
  <link rel="help" href="http://dev.w3.org/csswg/css-display">
8
<style type="text/css">
9
body,html { color:black; background-color:white; }
10
div { display:inline; }
11
12
.test {
13
  display-box: contents;
14
  content: "content";
15
  color: lime;
16
}
17
.contents {
18
  display-box: contents;
19
  color: green;
20
}
21
.s1 {display: none;}
22
.s2 {display: none;}
23
.s3 {display-box: contents;}
24
.s5 {display-box: contents;}
25
.s7 {display: none;}
26
.s8 {display: none;}
27
.s9 {display-box: contents;}
28
.s11 {display-box: contents;}
29
.before::before {
30
  display-box: contents;
31
  content:"before";
32
}
33
.after::after {
34
  display-box: contents;
35
  content:"after";
36
}
37
</style>
38
<script>
39
40
function setup() {
41
  document.body.offsetHeight;
42
  document.querySelector('.t1').className = 'contents';
43
  document.body.offsetHeight;
44
  document.querySelector('.t2').style.display = 'none';
45
  document.body.offsetHeight;
46
  document.querySelector('.t3').className = 'contents';
47
  document.body.offsetHeight;
48
  document.querySelector('.t4').style.displayBox = 'none';
49
  document.body.offsetHeight;
50
  document.querySelector('.t5').className = 'contents';
51
  document.body.offsetHeight;
52
  document.querySelector('.t6').style.display = 'none';
53
  document.body.offsetHeight;
54
  document.querySelector('.t7').className = 'contents';
55
  document.body.offsetHeight;
56
  document.querySelector('.t8').style.displayBox = 'none';
57
  document.body.offsetHeight;
58
  document.querySelector('.t9').className = 'contents';
59
  document.body.offsetHeight;
60
  document.querySelector('.t10').style.display = 'none';
61
  document.body.offsetHeight;
62
  document.querySelector('.t11').className = 'contents';
63
  document.body.offsetHeight;
64
  document.querySelector('.t12').style.displayBox = 'none';
65
  document.body.offsetHeight;
66
  document.querySelector('.t13').className = 'contents';
67
  document.body.offsetHeight;
68
  document.querySelector('.s1').className = 'contents';
69
  document.body.offsetHeight;
70
  document.querySelector('.s2').style.display = 'inline';
71
  document.body.offsetHeight;
72
  document.querySelector('.s3').style.displayBox = 'normal';
73
  document.body.offsetHeight;
74
  document.querySelector('.s4').className = 'contents';
75
  document.body.offsetHeight;
76
  document.querySelector('.s5').style.display = 'none';
77
  document.body.offsetHeight;
78
  document.querySelector('.s6').style.displayBox = 'none';
79
  document.body.offsetHeight;
80
  document.querySelector('.s7').className = 'contents';
81
  document.body.offsetHeight;
82
  document.querySelector('.s8').style.display = 'inline';
83
  document.body.offsetHeight;
84
  document.querySelector('.s9').style.displayBox = 'normal';
85
  document.body.offsetHeight;
86
  document.querySelector('.s10').className = 'contents';
87
  document.body.offsetHeight;
88
  document.querySelector('.s11').style.display = 'none';
89
  document.body.offsetHeight;
90
  document.querySelector('.s12').style.displayBox = 'none';
91
  document.body.offsetHeight;
92
}
93
94
function runTest() {
95
  var doc = document;
96
  var win = window;
97
  setup();
98
  var e = doc.querySelectorAll('*');
99
  for (i=0; i < e.length; ++i) {
100
    var elm = e[i];
101
    if (win.getComputedStyle(elm).displayBox == 'contents') {
102
      var c = elm.childNodes[0];
103
      if (c) {
104
        var next = c.nextSibling;
105
        elm.removeChild(c);
106
        elm.insertBefore(c,next);
107
      }
108
      var c = elm.childNodes[1];
109
      if (c) {
110
        var next = c.nextSibling;
111
        elm.removeChild(c);
112
        elm.insertBefore(c,next);
113
      }
114
      var c = elm.childNodes.length ? elm.childNodes[elm.childNodes.length-1] : null;
115
      if (c) {
116
        elm.removeChild(c);
117
        elm.appendChild(c);
118
      }
119
    }
120
  }
121
122
  document.documentElement.className = '';
123
}
124
125
</script>
126
</head>
127
<body onload="runTest()">
128
129
<div class="test"><span>A a</span></div>
130
<div class="test"><span class="t1">t1</span></div>
131
<div class="test"><span class="t2">t2</span></div>
132
<div class="contents before">1<span>B b</span>2</div>
133
<div class="contents after">1<span>C c</span>2</div>
134
<div class="contents before after">1<span>D d</span>2</div>
135
<div class="contents before">1<span class="t5">B b</span>2</div>
136
<div class="contents after">1<span class="t6">C c</span>2</div>
137
<div class="contents before after">1<span class="t7">D d</span>2</div>
138
139
<div class="contents">
140
  <div class="test"><span>span</span></div>
141
  <div class="test"><span class="t3">t3</span></div>
142
  <div class="test"><span class="t4">t4</span></div>
143
  <div class="contents before">1<span>span</span>2</div>
144
  <div class="contents after">1<span>span</span>2</div>
145
  <div class="contents before after">1<span>span</span>2</div>
146
  <div class="contents before">1<span class="t8">span</span>2</div>
147
  <div class="contents after">1<span class="t9">span</span>2</div>
148
  <div class="contents before after">1<span class="t10">span</span>2</div>
149
  <div class="contents before">1<span class="t11">span</span>2</div>
150
  <div class="contents after">1<span class="t12">span</span>2</div>
151
  <div class="contents before after">1<span class="t13">span</span>2</div>
152
</div>
153
154
<div class="contents"><span class="s1">
155
  <div class="test"><span>span</span></div>
156
  <div class="contents before">1<span>span</span>2</div>
157
  <div class="contents after">1<span>span</span>2</div>
158
  <div class="contents before after">1<span>span</span>2</div>
159
</span></div>
160
161
<div class="contents"><span class="s2">
162
  <div class="test"><span>span</span></div>
163
  <div class="contents before">1<span>span</span>2</div>
164
  <div class="contents after">1<span>span</span>2</div>
165
  <div class="contents before after">1<span>span</span>2</div>
166
</span></div>
167
168
<div class="contents"><span class="s3">
169
  <div class="test"><span>span</span></div>
170
  <div class="contents before">1<span>span</span>2</div>
171
  <div class="contents after">1<span>span</span>2</div>
172
  <div class="contents before after">1<span>span</span>2</div>
173
</span></div>
174
175
<div class="contents"><span class="s4">
176
  <div class="test"><span>span</span></div>
177
  <div class="contents before">1<span>span</span>2</div>
178
  <div class="contents after">1<span>span</span>2</div>
179
  <div class="contents before after">1<span>span</span>2</div>
180
</span></div>
181
182
<div class="contents"><span class="s5">
183
  <div class="test"><span>span</span></div>
184
  <div class="contents before">1<span>span</span>2</div>
185
  <div class="contents after">1<span>span</span>2</div>
186
  <div class="contents before after">1<span>span</span>2</div>
187
</span></div>
188
189
<div class="contents"><span class="s6">
190
  <div class="test"><span>span</span></div>
191
  <div class="contents before">1<span>span</span>2</div>
192
  <div class="contents after">1<span>span</span>2</div>
193
  <div class="contents before after">1<span>span</span>2</div>
194
</span></div>
195
196
<div class="contents before"><span class="s7">
197
  <div class="contents before">1<span>span</span>2</div>
198
  <div class="contents after">1<span>span</span>2</div>
199
  <div class="contents before after">1<span>span</span>2</div>
200
</span></div>
201
202
<div class="contents after"><span class="s8">
203
  <div class="contents before">1<span>span</span>2</div>
204
  <div class="contents after">1<span>span</span>2</div>
205
  <div class="contents before after">1<span>span</span>2</div>
206
</span></div>
207
208
<div class="contents"><span class="s9">
209
  <div class="contents before">1<span>span</span>2</div>
210
  <div class="contents after">1<span>span</span>2</div>
211
  <div class="contents before after">1<span>span</span>2</div>
212
</span></div>
213
214
<div class="contents before after"><span class="s10">
215
  <div class="test"><span>span</span></div>
216
  <div class="contents before">1<span>span</span>2</div>
217
  <div class="contents after">1<span>span</span>2</div>
218
  <div class="contents before after">1<span>span</span>2</div>
219
</span></div>
220
221
<div class="contents before"><span class="s11">
222
  <div class="test"><span>span</span></div>
223
  <div class="contents before">1<span>span</span>2</div>
224
  <div class="contents after">1<span>span</span>2</div>
225
  <div class="contents before after">1<span>span</span>2</div>
226
</span></div>
227
228
<div class="contents after"><span class="s12">
229
  <div class="test"><span>span</span></div>
230
  <div class="contents before">1<span>span</span>2</div>
231
  <div class="contents after">1<span>span</span>2</div>
232
  <div class="contents before after">1<span>span</span>2</div>
233
</span></div>
234
235
</body>
236
</html>
(-)a/layout/reftests/css-display/display-box-contents-generated-content-ref.html (+119 lines)
Line     Link Here 
Line 0    Link Here 
1
<!DOCTYPE html>
2
<html lang="en-US">
3
<head>
4
  <meta charset="UTF-8">
5
  <title>CSS Test: CSS display-box:contents; generated content</title>
6
  <link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=907396">
7
  <link rel="help" href="http://dev.w3.org/csswg/css-display">
8
<style type="text/css">
9
body,html { color:black; background-color:white; }
10
11
.test {
12
  display: inline;
13
  content: "content";
14
  color: lime;
15
}
16
.contents {
17
  display: inline;
18
  color: green;
19
}
20
.before::before {
21
  display: inline;
22
  content:"before";
23
}
24
.after::after {
25
  display: inline;
26
  content:"after";
27
}
28
</style>
29
</head>
30
<body>
31
32
<div class="test"><span>A a</span></div>
33
<div class="test"><span class="contents">t1</span></div>
34
<div class="test"></div>
35
<div class="contents before">1<span>B b</span>2</div>
36
<div class="contents after">1<span>C c</span>2</div>
37
<div class="contents before after">1<span>D d</span>2</div>
38
<div class="contents before">1<span class="t5">B b</span>2</div>
39
<div class="contents after">12</div>
40
<div class="contents before after">1<span class="t7">D d</span>2</div>
41
42
<div class="contents">
43
  <div class="test"><span>span</span></div>
44
  <div class="test"><span class="contents">t3</span></div>
45
  <div class="test"></div>
46
  <div class="contents before">1<span>span</span>2</div>
47
  <div class="contents after">1<span>span</span>2</div>
48
  <div class="contents before after">1<span>span</span>2</div>
49
  <div class="contents before">12</div>
50
  <div class="contents after">1<span class="t9">span</span>2</div>
51
  <div class="contents before after">12</div>
52
  <div class="contents before">1<span class="t11">span</span>2</div>
53
  <div class="contents after">12</div>
54
  <div class="contents before after">1<span class="t13">span</span>2</div>
55
</div>
56
57
<div class="contents"><span class="s1">
58
  <div class="test"><span>span</span></div>
59
  <div class="contents before">1<span>span</span>2</div>
60
  <div class="contents after">1<span>span</span>2</div>
61
  <div class="contents before after">1<span>span</span>2</div>
62
</span></div>
63
64
<div class="contents"><span class="s2">
65
  <div class="test"><span>span</span></div>
66
  <div class="contents before">1<span>span</span>2</div>
67
  <div class="contents after">1<span>span</span>2</div>
68
  <div class="contents before after">1<span>span</span>2</div>
69
</span></div>
70
71
<div class="contents"><span class="s3">
72
  <div class="test"><span>span</span></div>
73
  <div class="contents before">1<span>span</span>2</div>
74
  <div class="contents after">1<span>span</span>2</div>
75
  <div class="contents before after">1<span>span</span>2</div>
76
</span></div>
77
78
<div class="contents"><span class="s4">
79
  <div class="test"><span>span</span></div>
80
  <div class="contents before">1<span>span</span>2</div>
81
  <div class="contents after">1<span>span</span>2</div>
82
  <div class="contents before after">1<span>span</span>2</div>
83
</span></div>
84
85
<div class="contents"></div>
86
87
<div class="contents"></div>
88
89
<div class="contents before"><span class="s7">
90
  <div class="contents before">1<span>span</span>2</div>
91
  <div class="contents after">1<span>span</span>2</div>
92
  <div class="contents before after">1<span>span</span>2</div>
93
</span></div>
94
95
<div class="contents after"><span class="s8">
96
  <div class="contents before">1<span>span</span>2</div>
97
  <div class="contents after">1<span>span</span>2</div>
98
  <div class="contents before after">1<span>span</span>2</div>
99
</span></div>
100
101
<div class="contents"><span class="s9">
102
  <div class="contents before">1<span>span</span>2</div>
103
  <div class="contents after">1<span>span</span>2</div>
104
  <div class="contents before after">1<span>span</span>2</div>
105
</span></div>
106
107
<div class="contents before after"><span class="s10">
108
  <div class="test"><span>span</span></div>
109
  <div class="contents before">1<span>span</span>2</div>
110
  <div class="contents after">1<span>span</span>2</div>
111
  <div class="contents before after">1<span>span</span>2</div>
112
</span></div>
113
114
<div class="contents before"></div>
115
116
<div class="contents after"></div>
117
118
</body>
119
</html>
(-)a/layout/reftests/css-display/display-box-contents-generated-content.html (+207 lines)
Line     Link Here 
Line 0    Link Here 
1
<!DOCTYPE html>
2
<html lang="en-US" class="reftest-wait">
3
<head>
4
  <meta charset="UTF-8">
5
  <title>CSS Test: CSS display-box:contents; generated content</title>
6
  <link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=907396">
7
  <link rel="help" href="http://dev.w3.org/csswg/css-display">
8
<style type="text/css">
9
body,html { color:black; background-color:white; }
10
div { display:inline; }
11
12
.test {
13
  display-box: contents;
14
  content: "content";
15
  color: lime;
16
}
17
.contents {
18
  display-box: contents;
19
  color: green;
20
}
21
.s1 {display: none;}
22
.s2 {display: none;}
23
.s3 {display-box: contents;}
24
.s5 {display-box: contents;}
25
.s7 {display: none;}
26
.s8 {display: none;}
27
.s9 {display-box: contents;}
28
.s11 {display-box: contents;}
29
.before::before {
30
  display-box: contents;
31
  content:"before";
32
}
33
.after::after {
34
  display-box: contents;
35
  content:"after";
36
}
37
</style>
38
<script>
39
40
function runTest() {
41
  document.body.offsetHeight;
42
  document.querySelector('.t1').className = 'contents';
43
  document.body.offsetHeight;
44
  document.querySelector('.t2').style.display = 'none';
45
  document.body.offsetHeight;
46
  document.querySelector('.t3').className = 'contents';
47
  document.body.offsetHeight;
48
  document.querySelector('.t4').style.displayBox = 'none';
49
  document.body.offsetHeight;
50
  document.querySelector('.t5').className = 'contents';
51
  document.body.offsetHeight;
52
  document.querySelector('.t6').style.display = 'none';
53
  document.body.offsetHeight;
54
  document.querySelector('.t7').className = 'contents';
55
  document.body.offsetHeight;
56
  document.querySelector('.t8').style.displayBox = 'none';
57
  document.body.offsetHeight;
58
  document.querySelector('.t9').className = 'contents';
59
  document.body.offsetHeight;
60
  document.querySelector('.t10').style.display = 'none';
61
  document.body.offsetHeight;
62
  document.querySelector('.t11').className = 'contents';
63
  document.body.offsetHeight;
64
  document.querySelector('.t12').style.displayBox = 'none';
65
  document.body.offsetHeight;
66
  document.querySelector('.t13').className = 'contents';
67
  document.body.offsetHeight;
68
  document.querySelector('.s1').className = 'contents';
69
  document.body.offsetHeight;
70
  document.querySelector('.s2').style.display = 'inline';
71
  document.body.offsetHeight;
72
  document.querySelector('.s3').style.displayBox = 'normal';
73
  document.body.offsetHeight;
74
  document.querySelector('.s4').className = 'contents';
75
  document.body.offsetHeight;
76
  document.querySelector('.s5').style.display = 'none';
77
  document.body.offsetHeight;
78
  document.querySelector('.s6').style.displayBox = 'none';
79
  document.body.offsetHeight;
80
  document.querySelector('.s7').className = 'contents';
81
  document.body.offsetHeight;
82
  document.querySelector('.s8').style.display = 'inline';
83
  document.body.offsetHeight;
84
  document.querySelector('.s9').style.displayBox = 'normal';
85
  document.body.offsetHeight;
86
  document.querySelector('.s10').className = 'contents';
87
  document.body.offsetHeight;
88
  document.querySelector('.s11').style.display = 'none';
89
  document.body.offsetHeight;
90
  document.querySelector('.s12').style.displayBox = 'none';
91
  document.body.offsetHeight;
92
93
  document.documentElement.className = '';
94
}
95
96
</script>
97
</head>
98
<body onload="runTest()">
99
100
<div class="test"><span>A a</span></div>
101
<div class="test"><span class="t1">t1</span></div>
102
<div class="test"><span class="t2">t2</span></div>
103
<div class="contents before">1<span>B b</span>2</div>
104
<div class="contents after">1<span>C c</span>2</div>
105
<div class="contents before after">1<span>D d</span>2</div>
106
<div class="contents before">1<span class="t5">B b</span>2</div>
107
<div class="contents after">1<span class="t6">C c</span>2</div>
108
<div class="contents before after">1<span class="t7">D d</span>2</div>
109
110
<div class="contents">
111
  <div class="test"><span>span</span></div>
112
  <div class="test"><span class="t3">t3</span></div>
113
  <div class="test"><span class="t4">t4</span></div>
114
  <div class="contents before">1<span>span</span>2</div>
115
  <div class="contents after">1<span>span</span>2</div>
116
  <div class="contents before after">1<span>span</span>2</div>
117
  <div class="contents before">1<span class="t8">span</span>2</div>
118
  <div class="contents after">1<span class="t9">span</span>2</div>
119
  <div class="contents before after">1<span class="t10">span</span>2</div>
120
  <div class="contents before">1<span class="t11">span</span>2</div>
121
  <div class="contents after">1<span class="t12">span</span>2</div>
122
  <div class="contents before after">1<span class="t13">span</span>2</div>
123
</div>
124
125
<div class="contents"><span class="s1">
126
  <div class="test"><span>span</span></div>
127
  <div class="contents before">1<span>span</span>2</div>
128
  <div class="contents after">1<span>span</span>2</div>
129
  <div class="contents before after">1<span>span</span>2</div>
130
</span></div>
131
132
<div class="contents"><span class="s2">
133
  <div class="test"><span>span</span></div>
134
  <div class="contents before">1<span>span</span>2</div>
135
  <div class="contents after">1<span>span</span>2</div>
136
  <div class="contents before after">1<span>span</span>2</div>
137
</span></div>
138
139
<div class="contents"><span class="s3">
140
  <div class="test"><span>span</span></div>
141
  <div class="contents before">1<span>span</span>2</div>
142
  <div class="contents after">1<span>span</span>2</div>
143
  <div class="contents before after">1<span>span</span>2</div>
144
</span></div>
145
146
<div class="contents"><span class="s4">
147
  <div class="test"><span>span</span></div>
148
  <div class="contents before">1<span>span</span>2</div>
149
  <div class="contents after">1<span>span</span>2</div>
150
  <div class="contents before after">1<span>span</span>2</div>
151
</span></div>
152
153
<div class="contents"><span class="s5">
154
  <div class="test"><span>span</span></div>
155
  <div class="contents before">1<span>span</span>2</div>
156
  <div class="contents after">1<span>span</span>2</div>
157
  <div class="contents before after">1<span>span</span>2</div>
158
</span></div>
159
160
<div class="contents"><span class="s6">
161
  <div class="test"><span>span</span></div>
162
  <div class="contents before">1<span>span</span>2</div>
163
  <div class="contents after">1<span>span</span>2</div>
164
  <div class="contents before after">1<span>span</span>2</div>
165
</span></div>
166
167
<div class="contents before"><span class="s7">
168
  <div class="contents before">1<span>span</span>2</div>
169
  <div class="contents after">1<span>span</span>2</div>
170
  <div class="contents before after">1<span>span</span>2</div>
171
</span></div>
172
173
<div class="contents after"><span class="s8">
174
  <div class="contents before">1<span>span</span>2</div>
175
  <div class="contents after">1<span>span</span>2</div>
176
  <div class="contents before after">1<span>span</span>2</div>
177
</span></div>
178
179
<div class="contents"><span class="s9">
180
  <div class="contents before">1<span>span</span>2</div>
181
  <div class="contents after">1<span>span</span>2</div>
182
  <div class="contents before after">1<span>span</span>2</div>
183
</span></div>
184
185
<div class="contents before after"><span class="s10">
186
  <div class="test"><span>span</span></div>
187
  <div class="contents before">1<span>span</span>2</div>
188
  <div class="contents after">1<span>span</span>2</div>
189
  <div class="contents before after">1<span>span</span>2</div>
190
</span></div>
191
192
<div class="contents before"><span class="s11">
193
  <div class="test"><span>span</span></div>
194
  <div class="contents before">1<span>span</span>2</div>
195
  <div class="contents after">1<span>span</span>2</div>
196
  <div class="contents before after">1<span>span</span>2</div>
197
</span></div>
198
199
<div class="contents after"><span class="s12">
200
  <div class="test"><span>span</span></div>
201
  <div class="contents before">1<span>span</span>2</div>
202
  <div class="contents after">1<span>span</span>2</div>
203
  <div class="contents before after">1<span>span</span>2</div>
204
</span></div>
205
206
</body>
207
</html>
(-)a/layout/reftests/css-display/display-box-contents-style-inheritance-1-dom-mutations.html (+123 lines)
Line     Link Here 
Line 0    Link Here 
1
<!DOCTYPE html>
2
<html lang="en-US" class="reftest-wait">
3
<head>
4
  <meta charset="utf-8">
5
  <title>CSS Test: CSS display-box:contents; style inheritance, DOM mutations</title>
6
  <link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=907396">
7
  <link rel="help" href="http://dev.w3.org/csswg/css-display">
8
<style type="text/css">
9
body,span { color:black; background-color:white; }
10
.test { display-box:contents; }
11
.green { color:green; }
12
.border { border-left:1px solid green; }
13
b { border:inherit; font-weight:normal; }
14
</style>
15
<script>
16
function $(id) { return document.getElementById(id); }
17
function text(s) { return document.createTextNode(s); }
18
function b(s) { var e = document.createElement('b'); e.appendChild(document.createTextNode(s)); return e; }
19
function div(s) { var e = document.createElement('div'); e.setAttribute('class','test'); e.appendChild(document.createTextNode(s)); return e; }
20
function runTest() {
21
  var e = $('t1');
22
  var c = e.firstChild;
23
  e.insertBefore(text('g'), c);
24
  e.insertBefore(text('r'), c);
25
  e.appendChild(text('n'));
26
27
  var e = $('t1b');
28
  var c = e.firstChild;
29
  e.insertBefore(text('g'), c);
30
  e.insertBefore(text('r'), c);
31
  e.appendChild(text('n'));
32
33
  var e = $('t2');
34
  var c = e.firstChild;
35
  e.insertBefore(text('gr'), c);
36
  e.appendChild(text('n'));
37
38
  var e = $('t2b');
39
  var c = e.firstChild;
40
  e.insertBefore(text('gr'), c);
41
  e.appendChild(text('n'));
42
43
  var e = $('t3');
44
  var c = e.firstChild;
45
  e.insertBefore(text('n'), c);
46
  e.insertBefore(text('o'), c);
47
  e.appendChild(text('er'));
48
49
  var e = $('t4');
50
  var c = e.firstChild;
51
  e.insertBefore(text('n'), c);
52
  e.insertBefore(text('o'), c);
53
  e.appendChild(text('er'));
54
55
  var e = $('t5');
56
  var c = e.firstChild;
57
  e.insertBefore(b('1px green left '), c);
58
  e.appendChild(text('er'));
59
60
  var e = $('t6');
61
  e.appendChild(b('2px green left border'));
62
63
  var e = $('t7');
64
  e.appendChild(div('green'));
65
66
  var e = $('t8');
67
  e.appendChild(div('green'));
68
69
  var e = $('t9');
70
  var c = b("1px green left border");
71
  var d = div('');
72
  d.appendChild(c);
73
  e.appendChild(d);
74
75
  var e = $('t10');
76
  var c = b("1px green left border");
77
  var d = div('');
78
  d.setAttribute('style','border:inherit');
79
  d.appendChild(c);
80
  e.appendChild(d);
81
82
  var e = $('t11');
83
  var c = b("2px green left border");
84
  var d = div('');
85
  d.setAttribute('style','border:inherit');
86
  d.appendChild(c);
87
  e.appendChild(d);
88
89
  var e = $('t12');
90
  var c = e.firstChild;
91
  e.insertBefore(text("This text"), c);
92
  e.insertBefore(b(" should be"), c);
93
  e.appendChild(text(" green"));
94
95
  document.documentElement.className = '';
96
}
97
</script>
98
</head>
99
<body onload="runTest()">
100
101
<span class="green"><div class="test" id="t1">ee</div></span>
102
<span class="green"><div class="test" id="t1b">ee</div>x</span>
103
<span><div class="test green" id="t2">ee</div></span>
104
<span><div class="test green" id="t2b">ee</div>x</span>
105
<br>
106
<span><div class="test border" id="t3"> bord</div></span>
107
<span><div class="test border" id="t4"><span> bord</span></div></span>
108
<span class="border"><div class="test" id="t5">bord</div></span>
109
<span class="border"><div class="test" style="border:inherit" id="t6"></div></span>
110
<br>
111
112
<span class="green"><div class="test" id="t7"></div></span>
113
<span><div class="test green" id="t8"></div></span>
114
<br>
115
<span class="border"><div class="test" id="t9"></div></span>
116
<span class="border"><div class="test" id="t10"></div></span>
117
<span class="border"><div class="test" style="border:inherit" id="t11"></div></span>
118
<br>
119
120
<span style="color:red"><div class="test green" id="t12"></div></span>
121
122
</body>
123
</html>
(-)a/layout/reftests/css-display/display-box-contents-style-inheritance-1-ref.html (+38 lines)
Line     Link Here 
Line 0    Link Here 
1
<!DOCTYPE html>
2
<html lang="en-US">
3
<head>
4
  <meta charset="utf-8">
5
  <title>CSS Test: CSS display-box:contents; style inheritance</title>
6
  <link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=907396">
7
<style type="text/css">
8
body,span { color:black; background-color:white; }
9
.test { display:inline; }
10
.green { color:green; }
11
.border { border-left:1px solid green; }
12
b { font-weight:normal; }
13
</style>
14
</head>
15
<body>
16
<span class="green"><div class="test">green</div></span>
17
<span class="green"><div class="test">green</div>x</span>
18
<span><div class="test green">green</div></span>
19
<span><div class="test green">green</div>x</span>
20
<br>
21
<span><div class="test">no border</div></span>
22
<span><div class="test">no border</div></span>
23
<span class="border"><div class="test"><b>1px green left border</b></div></span>
24
<span class="border"><div class="test" style="border:inherit"><b>2px green left border</b></div></span>
25
<br>
26
27
<span class="green"><div class="test"><div class="test">green</div></div></span>
28
<span><div class="test green"><div class="test">green</div></div></span>
29
<br>
30
<span class="border"><div class="test"><div class="test"><b>1px green left border</b></div></div></span>
31
<span class="border"><div class="test"><div class="test" style="border:inherit"><b>1px green left border</b></div></div></span>
32
<span class="border"><div class="test" style="border:inherit"><div class="test"><b>2px green left border</b></div></div></span>
33
<br>
34
35
<span><div class="green" id="t12">This text should be green</div></span>
36
37
</body>
38
</html>
(-)a/layout/reftests/css-display/display-box-contents-style-inheritance-1-stylechange.html (+54 lines)
Line     Link Here 
Line 0    Link Here 
1
<!DOCTYPE html>
2
<html lang="en-US" class="reftest-wait">
3
<head>
4
  <meta charset="utf-8">
5
  <title>CSS Test: CSS display-box:contents; style inheritance, style changes</title>
6
  <link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=907396">
7
  <link rel="help" href="http://dev.w3.org/csswg/css-display">
8
<style type="text/css">
9
body,span { color:black; background-color:white; }
10
.test { display-box:contents; border:10px solid black; }
11
.test2 { display-box:contents; border-style:none; }
12
.test3:not(:lang(foo)) { display-box:contents; color:cyan; }
13
.green { color:green; }
14
.border { border-left:1px solid green; }
15
b { border:inherit; font-weight:normal; }
16
</style>
17
<script>
18
function runTest() {
19
  var elms = document.querySelectorAll('.test')
20
  for (i=0; i < elms.length; ++i) {
21
    elms[i].classList.remove('test');
22
    elms[i].classList.add('test2');
23
  }
24
  document.body.lang = 'foo';
25
  document.body.offsetWidth;
26
27
  document.documentElement.className = '';
28
}
29
</script>
30
</head>
31
<body onload="setTimeout(runTest,0)">
32
<span class="green"><div class="test">green</div></span>
33
<span class="green"><div class="test">green</div>x</span>
34
<span><div class="test green">green</div></span>
35
<span><div class="test green">green</div>x</span>
36
<br>
37
<span><div class="test border">no border</div></span>
38
<span><div class="test border"><span>no border</span></div></span>
39
<span class="border"><div class="test"><b>1px green left border</b></div></span>
40
<span class="border"><div class="test" style="border:inherit"><b>2px green left border</b></div></span>
41
<br>
42
43
<span class="green"><div class="test"><div class="test">green</div></div></span>
44
<span><div class="test green"><div class="test">green</div></div></span>
45
<br>
46
<span class="border"><div class="test"><div class="test"><b>1px green left border</b></div></div></span>
47
<span class="border"><div class="test"><div class="test" style="border:inherit"><b>1px green left border</b></div></div></span>
48
<span class="border"><div class="test" style="border:inherit"><div class="test" style="border:inherit"><b>2px green left border</b></div></div></span>
49
<br>
50
51
<span style="color:red"><div class="test3 green">This text should be green</div></span>
52
53
</body>
54
</html>
(-)a/layout/reftests/css-display/display-box-contents-style-inheritance-1.html (+39 lines)
Line     Link Here 
Line 0    Link Here 
1
<!DOCTYPE html>
2
<html lang="en-US">
3
<head>
4
  <meta charset="utf-8">
5
  <title>CSS Test: CSS display-box:contents; style inheritance</title>
6
  <link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=907396">
7
  <link rel="help" href="http://dev.w3.org/csswg/css-display">
8
<style type="text/css">
9
body,span { color:black; background-color:white; }
10
.test { display-box:contents; }
11
.green { color:green; }
12
.border { border-left:1px solid green; }
13
b { border:inherit; font-weight:normal; }
14
</style>
15
</head>
16
<body>
17
<span class="green"><div class="test">green</div></span>
18
<span class="green"><div class="test">green</div>x</span>
19
<span><div class="test green">green</div></span>
20
<span><div class="test green">green</div>x</span>
21
<br>
22
<span><div class="test border">no border</div></span>
23
<span><div class="test border"><span>no border</span></div></span>
24
<span class="border"><div class="test"><b>1px green left border</b></div></span>
25
<span class="border"><div class="test" style="border:inherit"><b>2px green left border</b></div></span>
26
<br>
27
28
<span class="green"><div class="test"><div class="test">green</div></div></span>
29
<span><div class="test green"><div class="test">green</div></div></span>
30
<br>
31
<span class="border"><div class="test"><div class="test"><b>1px green left border</b></div></div></span>
32
<span class="border"><div class="test"><div class="test" style="border:inherit"><b>1px green left border</b></div></div></span>
33
<span class="border"><div class="test" style="border:inherit"><div class="test" style="border:inherit"><b>2px green left border</b></div></div></span>
34
<br>
35
36
<span style="color:red"><div class="test green">This text should be green</div></span>
37
38
</body>
39
</html>
(-)a/layout/reftests/css-display/display-box-contents-tables-2.xhtml (+14 lines)
Line     Link Here 
Line 0    Link Here 
1
<?xml version="1.0" encoding="UTF-8"?>
2
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US">
3
<head>
4
  <title>CSS Test: CSS display-box:contents; tables</title>
5
  <link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=907396"/>
6
  <link rel="help" href="http://dev.w3.org/csswg/css-display"/>
7
<style type="text/css">
8
html { color:red; background-color:white; }
9
body { color:white; background-color:pink; width:0; }
10
.test { display-box:contents; color:white; background-color:lime; }
11
td { background-color:inherit; }
12
</style>
13
</head>
14
<body><div class="test"><td>green</td></div><td>pink</td></body></html>
(-)a/layout/reftests/css-display/display-box-contents-tables-3-ref.xhtml (+12 lines)
Line     Link Here 
Line 0    Link Here 
1
<?xml version="1.0" encoding="UTF-8"?>
2
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US">
3
<head>
4
  <title>CSS Test: CSS display-box:contents; tables</title>
5
  <link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=907396"/>
6
<style type="text/css">
7
body { color:red; background-color:white; }
8
.test { float:left; color:white; background-color:lime; }
9
td { background-color:inherit; }
10
</style>
11
</head>
12
<body><div class="test"><td>green</td></div></body></html>
(-)a/layout/reftests/css-display/display-box-contents-tables-3.xhtml (+13 lines)
Line     Link Here 
Line 0    Link Here 
1
<?xml version="1.0" encoding="UTF-8"?>
2
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US">
3
<head>
4
  <title>CSS Test: CSS display-box:contents; tables</title>
5
  <link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=907396"/>
6
  <link rel="help" href="http://dev.w3.org/csswg/css-display"/>
7
<style type="text/css">
8
body { color:red; background-color:white; }
9
.test { display-box:contents; color:white; background-color:lime; }
10
td { background-color:inherit; }
11
</style>
12
</head>
13
<body><div class="test"><td>green</td></div></body></html>
(-)a/layout/reftests/css-display/display-box-contents-tables-ref.xhtml (+12 lines)
Line     Link Here 
Line 0    Link Here 
1
<?xml version="1.0" encoding="UTF-8"?>
2
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US">
3
<head>
4
  <title>CSS Test: CSS display-box:contents; tables</title>
5
  <link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=907396"/>
6
<style type="text/css">
7
body { color:red; background-color:white; }
8
td { color:white; background-color:lime; }
9
.pink { background-color:pink; }
10
</style>
11
</head>
12
<body><td>green</td><td class="pink">pink</td></body></html>
(-)a/layout/reftests/css-display/display-box-contents-tables.xhtml (+13 lines)
Line     Link Here 
Line 0    Link Here 
1
<?xml version="1.0" encoding="UTF-8"?>
2
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US">
3
<head>
4
  <title>CSS Test: CSS display-box:contents; tables</title>
5
  <link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=907396"/>
6
  <link rel="help" href="http://dev.w3.org/csswg/css-display"/>
7
<style type="text/css">
8
body { color:red; background-color:white; }
9
.test { display-box:contents; color:white; background-color:lime; }
10
td { background-color:inherit; }
11
</style>
12
</head>
13
<body><div class="test"><td>green</td></div><div class="test" style="background-color:pink"><td>pink</td></div></body></html>
(-)a/layout/reftests/css-display/display-box-contents-visibility-hidden-2.html (+20 lines)
Line     Link Here 
Line 0    Link Here 
1
<!DOCTYPE html>
2
<html lang="en-US" class="reftest-wait">
3
<head>
4
  <meta charset="UTF-8">
5
  <title>CSS Test: CSS display-box:contents; visibility:hidden</title>
6
  <link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=907396">
7
  <link rel="help" href="http://dev.w3.org/csswg/css-display">
8
</head>
9
<body style="color: red">
10
  <div id="x" style="display-box:contents; visibility: hidden; color: green">
11
    Line 1
12
  </div><script type="text/javascript">
13
    document.body.offsetWidth;
14
    document.getElementById("x").style.visibility = "visible";
15
    document.body.offsetWidth;
16
17
    document.documentElement.className = '';
18
  </script>
19
</body>
20
</html>
(-)a/layout/reftests/css-display/display-box-contents-visibility-hidden-ref.html (+14 lines)
Line     Link Here 
Line 0    Link Here 
1
<!DOCTYPE html>
2
<html lang="en-US">
3
<head>
4
  <meta charset="UTF-8">
5
  <title>CSS Test: CSS display-box:contents; visibility:hidden</title>
6
  <link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=907396">
7
</head>
8
<body>
9
  <div id="x" style="color:green">
10
    Line 1
11
  </div>
12
13
</body>
14
</html>
(-)a/layout/reftests/css-display/display-box-contents-visibility-hidden.html (+22 lines)
Line     Link Here 
Line 0    Link Here 
1
<!DOCTYPE html>
2
<html lang="en-US" class="reftest-wait">
3
<head>
4
  <meta charset="UTF-8">
5
  <title>CSS Test: CSS display-box:contents; visibility:hidden</title>
6
  <link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=907396">
7
  <link rel="help" href="http://dev.w3.org/csswg/css-display">
8
</head>
9
<body>
10
  <div id="x" style="display-box:contents; visibility: hidden">
11
    Line 1
12
  </div><script type="text/javascript">
13
    document.body.offsetWidth;
14
    document.getElementById("x").style.visibility = "visible";
15
    document.body.style.color = "green";
16
    document.body.offsetWidth;
17
18
    document.documentElement.className = '';
19
  </script>
20
21
</body>
22
</html>
(-)a/layout/reftests/css-display/reftest.list (+18 lines)
Line     Link Here 
Line 0    Link Here 
1
# Tests for CSS Display spec features.
2
# http://dev.w3.org/csswg/css-display
3
4
pref(layout.css.display-box.enabled,true) == display-box-contents-acid.html display-box-contents-acid-ref.html
5
pref(layout.css.display-box.enabled,true) == display-box-contents-acid-dyn-1.html display-box-contents-acid-ref.html
6
pref(layout.css.display-box.enabled,true) == display-box-contents-acid-dyn-2.html display-box-contents-acid-ref.html
7
pref(layout.css.display-box.enabled,true) == display-box-contents-acid-dyn-3.html display-box-contents-acid-ref.html
8
pref(layout.css.display-box.enabled,true) == display-box-contents-generated-content.html display-box-contents-generated-content-ref.html
9
pref(layout.css.display-box.enabled,true) == display-box-contents-generated-content-2.html display-box-contents-generated-content-ref.html
10
pref(layout.css.display-box.enabled,true) == display-box-contents-style-inheritance-1.html display-box-contents-style-inheritance-1-ref.html
11
pref(layout.css.display-box.enabled,true) == display-box-contents-style-inheritance-1-stylechange.html display-box-contents-style-inheritance-1-ref.html
12
pref(layout.css.display-box.enabled,true) fuzzy-if(d2d,2,100) == display-box-contents-style-inheritance-1-dom-mutations.html display-box-contents-style-inheritance-1-ref.html
13
pref(layout.css.display-box.enabled,true) == display-box-contents-tables.xhtml display-box-contents-tables-ref.xhtml
14
pref(layout.css.display-box.enabled,true) == display-box-contents-tables-2.xhtml display-box-contents-tables-ref.xhtml
15
pref(layout.css.display-box.enabled,true) == display-box-contents-tables-3.xhtml display-box-contents-tables-3-ref.xhtml
16
pref(layout.css.display-box.enabled,true) == display-box-contents-visibility-hidden.html display-box-contents-visibility-hidden-ref.html
17
pref(layout.css.display-box.enabled,true) == display-box-contents-visibility-hidden-2.html display-box-contents-visibility-hidden-ref.html
18
pref(layout.css.display-box.enabled,true) == display-box-contents-495385-2d.html display-box-contents-495385-2d-ref.html
(-)a/layout/reftests/reftest.list (+3 lines)
Line     Link Here 
 Lines 63-78   include css-break/reftest.list Link Here 
63
include css-calc/reftest.list
63
include css-calc/reftest.list
64
64
65
# css character encoding tests
65
# css character encoding tests
66
include css-charset/reftest.list
66
include css-charset/reftest.list
67
67
68
# css default pseudo class tests
68
# css default pseudo class tests
69
include css-default/reftest.list
69
include css-default/reftest.list
70
70
71
# css-display spec tests
72
include css-display/reftest.list
73
71
# css :disable tests
74
# css :disable tests
72
include css-disabled/reftest.list
75
include css-disabled/reftest.list
73
76
74
# css :enable tests
77
# css :enable tests
75
include css-enabled/reftest.list
78
include css-enabled/reftest.list
76
79
77
# css @import tests
80
# css @import tests
78
include css-import/reftest.list
81
include css-import/reftest.list
(-)a/layout/style/nsCSSKeywordList.h (+1 lines)
Line     Link Here 
 Lines 188-203   CSS_KEY(color, color) Link Here 
188
CSS_KEY(color-burn, color_burn)
188
CSS_KEY(color-burn, color_burn)
189
CSS_KEY(color-dodge, color_dodge)
189
CSS_KEY(color-dodge, color_dodge)
190
CSS_KEY(common-ligatures, common_ligatures)
190
CSS_KEY(common-ligatures, common_ligatures)
191
CSS_KEY(column, column)
191
CSS_KEY(column, column)
192
CSS_KEY(column-reverse, column_reverse)
192
CSS_KEY(column-reverse, column_reverse)
193
CSS_KEY(condensed, condensed)
193
CSS_KEY(condensed, condensed)
194
CSS_KEY(contain, contain)
194
CSS_KEY(contain, contain)
195
CSS_KEY(content-box, content_box)
195
CSS_KEY(content-box, content_box)
196
CSS_KEY(contents, contents)
196
CSS_KEY(context-fill, context_fill)
197
CSS_KEY(context-fill, context_fill)
197
CSS_KEY(context-fill-opacity, context_fill_opacity)
198
CSS_KEY(context-fill-opacity, context_fill_opacity)
198
CSS_KEY(context-menu, context_menu)
199
CSS_KEY(context-menu, context_menu)
199
CSS_KEY(context-stroke, context_stroke)
200
CSS_KEY(context-stroke, context_stroke)
200
CSS_KEY(context-stroke-opacity, context_stroke_opacity)
201
CSS_KEY(context-stroke-opacity, context_stroke_opacity)
201
CSS_KEY(context-value, context_value)
202
CSS_KEY(context-value, context_value)
202
CSS_KEY(continuous, continuous)
203
CSS_KEY(continuous, continuous)
203
CSS_KEY(contrast, contrast)
204
CSS_KEY(contrast, contrast)
(-)a/layout/style/nsCSSPropList.h (+10 lines)
Line     Link Here 
 Lines 1594-1609   CSS_PROP_DISPLAY( Link Here 
1594
        // pseudo-element an inline-block in the UA stylesheet. It is a block
1594
        // pseudo-element an inline-block in the UA stylesheet. It is a block
1595
        // by default.
1595
        // by default.
1596
        CSS_PROPERTY_APPLIES_TO_PLACEHOLDER,
1596
        CSS_PROPERTY_APPLIES_TO_PLACEHOLDER,
1597
    "",
1597
    "",
1598
    VARIANT_HK,
1598
    VARIANT_HK,
1599
    kDisplayKTable,
1599
    kDisplayKTable,
1600
    offsetof(nsStyleDisplay, mDisplay),
1600
    offsetof(nsStyleDisplay, mDisplay),
1601
    eStyleAnimType_EnumU8)
1601
    eStyleAnimType_EnumU8)
1602
CSS_PROP_DISPLAY(
1603
    display-box,
1604
    display_box,
1605
    DisplayBox,
1606
    CSS_PROPERTY_PARSE_VALUE,
1607
    "layout.css.display-box.enabled",
1608
    VARIANT_HK,
1609
    kDisplayBoxKTable,
1610
    offsetof(nsStyleDisplay, mDisplayBox),
1611
    eStyleAnimType_EnumU8)
1602
CSS_PROP_TABLEBORDER(
1612
CSS_PROP_TABLEBORDER(
1603
    empty-cells,
1613
    empty-cells,
1604
    empty_cells,
1614
    empty_cells,
1605
    EmptyCells,
1615
    EmptyCells,
1606
    CSS_PROPERTY_PARSE_VALUE,
1616
    CSS_PROPERTY_PARSE_VALUE,
1607
    "",
1617
    "",
1608
    VARIANT_HK,
1618
    VARIANT_HK,
1609
    kEmptyCellsKTable,
1619
    kEmptyCellsKTable,
(-)a/layout/style/nsCSSProps.cpp (+7 lines)
Line     Link Here 
 Lines 856-871   const KTableValue nsCSSProps::kBorderSty Link Here 
856
856
857
const KTableValue nsCSSProps::kBorderWidthKTable[] = {
857
const KTableValue nsCSSProps::kBorderWidthKTable[] = {
858
  eCSSKeyword_thin, NS_STYLE_BORDER_WIDTH_THIN,
858
  eCSSKeyword_thin, NS_STYLE_BORDER_WIDTH_THIN,
859
  eCSSKeyword_medium, NS_STYLE_BORDER_WIDTH_MEDIUM,
859
  eCSSKeyword_medium, NS_STYLE_BORDER_WIDTH_MEDIUM,
860
  eCSSKeyword_thick, NS_STYLE_BORDER_WIDTH_THICK,
860
  eCSSKeyword_thick, NS_STYLE_BORDER_WIDTH_THICK,
861
  eCSSKeyword_UNKNOWN,-1
861
  eCSSKeyword_UNKNOWN,-1
862
};
862
};
863
863
864
const KTableValue nsCSSProps::kDisplayBoxKTable[] = {
865
  eCSSKeyword_normal,       NS_STYLE_DISPLAY_BOX_NORMAL,
866
  eCSSKeyword_none,         NS_STYLE_DISPLAY_BOX_NONE,
867
  eCSSKeyword_contents,     NS_STYLE_DISPLAY_BOX_CONTENTS,
868
  eCSSKeyword_UNKNOWN,-1
869
};
870
864
const KTableValue nsCSSProps::kBoxPropSourceKTable[] = {
871
const KTableValue nsCSSProps::kBoxPropSourceKTable[] = {
865
  eCSSKeyword_physical,     NS_BOXPROP_SOURCE_PHYSICAL,
872
  eCSSKeyword_physical,     NS_BOXPROP_SOURCE_PHYSICAL,
866
  eCSSKeyword_logical,      NS_BOXPROP_SOURCE_LOGICAL,
873
  eCSSKeyword_logical,      NS_BOXPROP_SOURCE_LOGICAL,
867
  eCSSKeyword_UNKNOWN,-1
874
  eCSSKeyword_UNKNOWN,-1
868
};
875
};
869
876
870
const KTableValue nsCSSProps::kBoxDecorationBreakKTable[] = {
877
const KTableValue nsCSSProps::kBoxDecorationBreakKTable[] = {
871
  eCSSKeyword_slice, NS_STYLE_BOX_DECORATION_BREAK_SLICE,
878
  eCSSKeyword_slice, NS_STYLE_BOX_DECORATION_BREAK_SLICE,
(-)a/layout/style/nsCSSProps.h (+1 lines)
Line     Link Here 
 Lines 543-558   public: Link Here 
543
  static const KTableValue kStrokeLinecapKTable[];
543
  static const KTableValue kStrokeLinecapKTable[];
544
  static const KTableValue kStrokeLinejoinKTable[];
544
  static const KTableValue kStrokeLinejoinKTable[];
545
  static const KTableValue kStrokeContextValueKTable[];
545
  static const KTableValue kStrokeContextValueKTable[];
546
  static const KTableValue kVectorEffectKTable[];
546
  static const KTableValue kVectorEffectKTable[];
547
  static const KTableValue kTextAnchorKTable[];
547
  static const KTableValue kTextAnchorKTable[];
548
  static const KTableValue kTextRenderingKTable[];
548
  static const KTableValue kTextRenderingKTable[];
549
  static const KTableValue kColorInterpolationKTable[];
549
  static const KTableValue kColorInterpolationKTable[];
550
  static const KTableValue kColumnFillKTable[];
550
  static const KTableValue kColumnFillKTable[];
551
  static const KTableValue kDisplayBoxKTable[];
551
  static const KTableValue kBoxPropSourceKTable[];
552
  static const KTableValue kBoxPropSourceKTable[];
552
  static const KTableValue kBoxShadowTypeKTable[];
553
  static const KTableValue kBoxShadowTypeKTable[];
553
  static const KTableValue kBoxSizingKTable[];
554
  static const KTableValue kBoxSizingKTable[];
554
  static const KTableValue kCaptionSideKTable[];
555
  static const KTableValue kCaptionSideKTable[];
555
  static const KTableValue kClearKTable[];
556
  static const KTableValue kClearKTable[];
556
  static const KTableValue kColorKTable[];
557
  static const KTableValue kColorKTable[];
557
  static const KTableValue kContentKTable[];
558
  static const KTableValue kContentKTable[];
558
  static const KTableValue kControlCharacterVisibilityKTable[];
559
  static const KTableValue kControlCharacterVisibilityKTable[];
(-)a/layout/style/nsComputedDOMStyle.cpp (+9 lines)
Line     Link Here 
 Lines 3786-3801   nsComputedDOMStyle::DoGetUserSelect() Link Here 
3786
  nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue;
3786
  nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue;
3787
  val->SetIdent(
3787
  val->SetIdent(
3788
    nsCSSProps::ValueToKeywordEnum(StyleUIReset()->mUserSelect,
3788
    nsCSSProps::ValueToKeywordEnum(StyleUIReset()->mUserSelect,
3789
                                   nsCSSProps::kUserSelectKTable));
3789
                                   nsCSSProps::kUserSelectKTable));
3790
  return val;
3790
  return val;
3791
}
3791
}
3792
3792
3793
CSSValue*
3793
CSSValue*
3794
nsComputedDOMStyle::DoGetDisplayBox()
3795
{
3796
  nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue;
3797
  val->SetIdent(nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mDisplayBox,
3798
                                               nsCSSProps::kDisplayBoxKTable));
3799
  return val;
3800
}
3801
3802
CSSValue*
3794
nsComputedDOMStyle::DoGetDisplay()
3803
nsComputedDOMStyle::DoGetDisplay()
3795
{
3804
{
3796
  nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue;
3805
  nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue;
3797
  val->SetIdent(nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mDisplay,
3806
  val->SetIdent(nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mDisplay,
3798
                                               nsCSSProps::kDisplayKTable));
3807
                                               nsCSSProps::kDisplayKTable));
3799
  return val;
3808
  return val;
3800
}
3809
}
3801
3810
(-)a/layout/style/nsComputedDOMStyle.h (+1 lines)
Line     Link Here 
 Lines 399-414   private: Link Here 
399
  mozilla::dom::CSSValue* DoGetWritingMode();
399
  mozilla::dom::CSSValue* DoGetWritingMode();
400
400
401
  /* Direction properties */
401
  /* Direction properties */
402
  mozilla::dom::CSSValue* DoGetDirection();
402
  mozilla::dom::CSSValue* DoGetDirection();
403
  mozilla::dom::CSSValue* DoGetUnicodeBidi();
403
  mozilla::dom::CSSValue* DoGetUnicodeBidi();
404
404
405
  /* Display properties */
405
  /* Display properties */
406
  mozilla::dom::CSSValue* DoGetBinding();
406
  mozilla::dom::CSSValue* DoGetBinding();
407
  mozilla::dom::CSSValue* DoGetDisplayBox();
407
  mozilla::dom::CSSValue* DoGetClear();
408
  mozilla::dom::CSSValue* DoGetClear();
408
  mozilla::dom::CSSValue* DoGetFloat();
409
  mozilla::dom::CSSValue* DoGetFloat();
409
  mozilla::dom::CSSValue* DoGetDisplay();
410
  mozilla::dom::CSSValue* DoGetDisplay();
410
  mozilla::dom::CSSValue* DoGetPosition();
411
  mozilla::dom::CSSValue* DoGetPosition();
411
  mozilla::dom::CSSValue* DoGetClip();
412
  mozilla::dom::CSSValue* DoGetClip();
412
  mozilla::dom::CSSValue* DoGetImageOrientation();
413
  mozilla::dom::CSSValue* DoGetImageOrientation();
413
  mozilla::dom::CSSValue* DoGetWillChange();
414
  mozilla::dom::CSSValue* DoGetWillChange();
414
  mozilla::dom::CSSValue* DoGetOverflow();
415
  mozilla::dom::CSSValue* DoGetOverflow();
(-)a/layout/style/nsComputedDOMStylePropertyList.h (+1 lines)
Line     Link Here 
 Lines 103-118   COMPUTED_STYLE_PROP(clear, Link Here 
103
COMPUTED_STYLE_PROP(clip,                          Clip)
103
COMPUTED_STYLE_PROP(clip,                          Clip)
104
COMPUTED_STYLE_PROP(color,                         Color)
104
COMPUTED_STYLE_PROP(color,                         Color)
105
COMPUTED_STYLE_PROP(content,                       Content)
105
COMPUTED_STYLE_PROP(content,                       Content)
106
COMPUTED_STYLE_PROP(counter_increment,             CounterIncrement)
106
COMPUTED_STYLE_PROP(counter_increment,             CounterIncrement)
107
COMPUTED_STYLE_PROP(counter_reset,                 CounterReset)
107
COMPUTED_STYLE_PROP(counter_reset,                 CounterReset)
108
COMPUTED_STYLE_PROP(cursor,                        Cursor)
108
COMPUTED_STYLE_PROP(cursor,                        Cursor)
109
COMPUTED_STYLE_PROP(direction,                     Direction)
109
COMPUTED_STYLE_PROP(direction,                     Direction)
110
COMPUTED_STYLE_PROP(display,                       Display)
110
COMPUTED_STYLE_PROP(display,                       Display)
111
COMPUTED_STYLE_PROP(display_box,                   DisplayBox)
111
COMPUTED_STYLE_PROP(empty_cells,                   EmptyCells)
112
COMPUTED_STYLE_PROP(empty_cells,                   EmptyCells)
112
COMPUTED_STYLE_PROP(flex_basis,                    FlexBasis)
113
COMPUTED_STYLE_PROP(flex_basis,                    FlexBasis)
113
COMPUTED_STYLE_PROP(flex_direction,                FlexDirection)
114
COMPUTED_STYLE_PROP(flex_direction,                FlexDirection)
114
COMPUTED_STYLE_PROP(flex_grow,                     FlexGrow)
115
COMPUTED_STYLE_PROP(flex_grow,                     FlexGrow)
115
COMPUTED_STYLE_PROP(flex_shrink,                   FlexShrink)
116
COMPUTED_STYLE_PROP(flex_shrink,                   FlexShrink)
116
COMPUTED_STYLE_PROP(flex_wrap,                     FlexWrap)
117
COMPUTED_STYLE_PROP(flex_wrap,                     FlexWrap)
117
COMPUTED_STYLE_PROP(float,                         Float)
118
COMPUTED_STYLE_PROP(float,                         Float)
118
//// COMPUTED_STYLE_PROP(font,                     Font)
119
//// COMPUTED_STYLE_PROP(font,                     Font)
(-)a/layout/style/nsRuleNode.cpp (+25 lines)
Line     Link Here 
 Lines 5191-5206   nsRuleNode::ComputeDisplayData(void* aSt Link Here 
5191
            SETFCT_OPACITY | SETFCT_UNSET_INITIAL);
5191
            SETFCT_OPACITY | SETFCT_UNSET_INITIAL);
5192
5192
5193
  // display: enum, inherit, initial
5193
  // display: enum, inherit, initial
5194
  SetDiscrete(*aRuleData->ValueForDisplay(), display->mDisplay, canStoreInRuleTree,
5194
  SetDiscrete(*aRuleData->ValueForDisplay(), display->mDisplay, canStoreInRuleTree,
5195
              SETDSC_ENUMERATED | SETDSC_UNSET_INITIAL,
5195
              SETDSC_ENUMERATED | SETDSC_UNSET_INITIAL,
5196
              parentDisplay->mDisplay,
5196
              parentDisplay->mDisplay,
5197
              NS_STYLE_DISPLAY_INLINE, 0, 0, 0, 0);
5197
              NS_STYLE_DISPLAY_INLINE, 0, 0, 0, 0);
5198
5198
5199
  // display-box: enum, inherit, initial
5200
  if (display->mDisplay == NS_STYLE_DISPLAY_NONE) {
5201
    // display:none implies display-box:none.
5202
    display->mDisplayBox = NS_STYLE_DISPLAY_BOX_NONE;
5203
    canStoreInRuleTree = false;
5204
  } else {
5205
    SetDiscrete(*aRuleData->ValueForDisplayBox(), display->mDisplayBox, canStoreInRuleTree,
5206
                SETDSC_ENUMERATED | SETDSC_UNSET_INITIAL, parentDisplay->mDisplayBox,
5207
                NS_STYLE_DISPLAY_BOX_NORMAL, 0, 0, 0, 0);
5208
  }
5209
5199
  // mix-blend-mode: enum, inherit, initial
5210
  // mix-blend-mode: enum, inherit, initial
5200
  SetDiscrete(*aRuleData->ValueForMixBlendMode(), display->mMixBlendMode,
5211
  SetDiscrete(*aRuleData->ValueForMixBlendMode(), display->mMixBlendMode,
5201
              canStoreInRuleTree,
5212
              canStoreInRuleTree,
5202
              SETDSC_ENUMERATED | SETDSC_UNSET_INITIAL,
5213
              SETDSC_ENUMERATED | SETDSC_UNSET_INITIAL,
5203
              parentDisplay->mMixBlendMode, NS_STYLE_BLEND_NORMAL,
5214
              parentDisplay->mMixBlendMode, NS_STYLE_BLEND_NORMAL,
5204
              0, 0, 0, 0);
5215
              0, 0, 0, 0);
5205
5216
5206
  // Backup original display value for calculation of a hypothetical
5217
  // Backup original display value for calculation of a hypothetical
 Lines 5437-5452   nsRuleNode::ComputeDisplayData(void* aSt Link Here 
5437
    NS_ABORT_IF_FALSE(false, "unrecognized clip unit");
5448
    NS_ABORT_IF_FALSE(false, "unrecognized clip unit");
5438
  }
5449
  }
5439
5450
5440
  if (display->mDisplay != NS_STYLE_DISPLAY_NONE) {
5451
  if (display->mDisplay != NS_STYLE_DISPLAY_NONE) {
5441
    // CSS2 9.7 specifies display type corrections dealing with 'float'
5452
    // CSS2 9.7 specifies display type corrections dealing with 'float'
5442
    // and 'position'.  Since generated content can't be floated or
5453
    // and 'position'.  Since generated content can't be floated or
5443
    // positioned, we can deal with it here.
5454
    // positioned, we can deal with it here.
5444
5455
5456
    if (display->mDisplayBox == NS_STYLE_DISPLAY_BOX_CONTENTS && aContext->GetPseudo()) {
5457
      // We don't want to create frames for anonymous content using a parent
5458
      // frame that is for content above the root of the anon tree.
5459
      // (XXX what we realy should check here is not GetPseudo() but if there's
5460
      //  a 'content' property value that implies anon content but we can't
5461
      //  check that here since that's a different struct(?))
5462
      // We might get display-box:contents to work for CSS_PSEUDO_ELEMENT_CONTAINS_ELEMENTS
5463
      // pseudos (:first-letter etc) in the future, but those have a lot of
5464
      // special handling in frame construction so they are also unsupported
5465
      // for now.
5466
      display->mDisplayBox = NS_STYLE_DISPLAY_BOX_NORMAL;
5467
      canStoreInRuleTree = false;
5468
    }
5469
5445
    if (nsCSSPseudoElements::firstLetter == aContext->GetPseudo()) {
5470
    if (nsCSSPseudoElements::firstLetter == aContext->GetPseudo()) {
5446
      // a non-floating first-letter must be inline
5471
      // a non-floating first-letter must be inline
5447
      // XXX this fix can go away once bug 103189 is fixed correctly
5472
      // XXX this fix can go away once bug 103189 is fixed correctly
5448
      // Note that we reset mOriginalDisplay to enforce the invariant that it equals mDisplay if we're not positioned or floating.
5473
      // Note that we reset mOriginalDisplay to enforce the invariant that it equals mDisplay if we're not positioned or floating.
5449
      display->mOriginalDisplay = display->mDisplay = NS_STYLE_DISPLAY_INLINE;
5474
      display->mOriginalDisplay = display->mDisplay = NS_STYLE_DISPLAY_INLINE;
5450
5475
5451
      // We can't cache the data in the rule tree since if a more specific
5476
      // We can't cache the data in the rule tree since if a more specific
5452
      // rule has 'float: left' we'll end up with the wrong 'display'
5477
      // rule has 'float: left' we'll end up with the wrong 'display'
(-)a/layout/style/nsStyleConsts.h (+5 lines)
Line     Link Here 
 Lines 412-427   static inline mozilla::css::Side operato Link Here 
412
#define NS_STYLE_DISPLAY_POPUP                  27
412
#define NS_STYLE_DISPLAY_POPUP                  27
413
#define NS_STYLE_DISPLAY_GROUPBOX               28
413
#define NS_STYLE_DISPLAY_GROUPBOX               28
414
#endif
414
#endif
415
#define NS_STYLE_DISPLAY_FLEX                   29
415
#define NS_STYLE_DISPLAY_FLEX                   29
416
#define NS_STYLE_DISPLAY_INLINE_FLEX            30
416
#define NS_STYLE_DISPLAY_INLINE_FLEX            30
417
#define NS_STYLE_DISPLAY_GRID                   31
417
#define NS_STYLE_DISPLAY_GRID                   31
418
#define NS_STYLE_DISPLAY_INLINE_GRID            32
418
#define NS_STYLE_DISPLAY_INLINE_GRID            32
419
419
420
// See nsStyleDisplay
421
#define NS_STYLE_DISPLAY_BOX_NORMAL             0
422
#define NS_STYLE_DISPLAY_BOX_NONE               1
423
#define NS_STYLE_DISPLAY_BOX_CONTENTS           2
424
420
// See nsStylePosition
425
// See nsStylePosition
421
#define NS_STYLE_ALIGN_CONTENT_FLEX_START       0
426
#define NS_STYLE_ALIGN_CONTENT_FLEX_START       0
422
#define NS_STYLE_ALIGN_CONTENT_FLEX_END         1
427
#define NS_STYLE_ALIGN_CONTENT_FLEX_END         1
423
#define NS_STYLE_ALIGN_CONTENT_CENTER           2
428
#define NS_STYLE_ALIGN_CONTENT_CENTER           2
424
#define NS_STYLE_ALIGN_CONTENT_SPACE_BETWEEN    3
429
#define NS_STYLE_ALIGN_CONTENT_SPACE_BETWEEN    3
425
#define NS_STYLE_ALIGN_CONTENT_SPACE_AROUND     4
430
#define NS_STYLE_ALIGN_CONTENT_SPACE_AROUND     4
426
#define NS_STYLE_ALIGN_CONTENT_STRETCH          5
431
#define NS_STYLE_ALIGN_CONTENT_STRETCH          5
427
432
(-)a/layout/style/nsStyleContext.cpp (-5 / +18 lines)
Line     Link Here 
 Lines 352-372   nsStyleContext::ApplyStyleFixups(bool aS Link Here 
352
  }
352
  }
353
353
354
  // Adjust the "display" values of flex and grid items (but not for raw text,
354
  // Adjust the "display" values of flex and grid items (but not for raw text,
355
  // placeholders, or table-parts). CSS3 Flexbox section 4 says:
355
  // placeholders, or table-parts). CSS3 Flexbox section 4 says:
356
  //   # The computed 'display' of a flex item is determined
356
  //   # The computed 'display' of a flex item is determined
357
  //   # by applying the table in CSS 2.1 Chapter 9.7.
357
  //   # by applying the table in CSS 2.1 Chapter 9.7.
358
  // ...which converts inline-level elements to their block-level equivalents.
358
  // ...which converts inline-level elements to their block-level equivalents.
359
  if (!aSkipParentDisplayBasedStyleFixup && mParent) {
359
  if (!aSkipParentDisplayBasedStyleFixup && mParent) {
360
    const nsStyleDisplay* parentDisp = mParent->StyleDisplay();
360
    // Skip display-box:contents ancestors to reach the potential container.
361
    if ((parentDisp->mDisplay == NS_STYLE_DISPLAY_FLEX ||
361
    // (If there are only display-box:contents ancestors between this node and
362
         parentDisp->mDisplay == NS_STYLE_DISPLAY_INLINE_FLEX ||
362
    // a flex/grid container ancestor, then this node is a flex/grid item, since
363
         parentDisp->mDisplay == NS_STYLE_DISPLAY_GRID ||
363
    // its parent *in the frame tree* will be the flex/grid container. So we treat
364
         parentDisp->mDisplay == NS_STYLE_DISPLAY_INLINE_GRID) &&
364
    // it like a flex/grid item here.)
365
    nsStyleContext* containerContext = mParent;
366
    const nsStyleDisplay* containerDisp = containerContext->StyleDisplay();
367
    while (containerDisp->mDisplayBox == NS_STYLE_DISPLAY_BOX_CONTENTS) {
368
      if (!containerContext->GetParent()) {
369
        break;
370
      }
371
      containerContext = containerContext->GetParent();
372
      containerDisp = containerContext->StyleDisplay();
373
    }
374
    if ((containerDisp->mDisplay == NS_STYLE_DISPLAY_FLEX ||
375
         containerDisp->mDisplay == NS_STYLE_DISPLAY_INLINE_FLEX ||
376
         containerDisp->mDisplay == NS_STYLE_DISPLAY_GRID ||
377
         containerDisp->mDisplay == NS_STYLE_DISPLAY_INLINE_GRID) &&
365
        GetPseudo() != nsCSSAnonBoxes::mozNonElement) {
378
        GetPseudo() != nsCSSAnonBoxes::mozNonElement) {
366
      uint8_t displayVal = disp->mDisplay;
379
      uint8_t displayVal = disp->mDisplay;
367
      // Skip table parts.
380
      // Skip table parts.
368
      // NOTE: This list needs to be kept in sync with
381
      // NOTE: This list needs to be kept in sync with
369
      // nsCSSFrameConstructor.cpp's "sDisplayData" array -- specifically,
382
      // nsCSSFrameConstructor.cpp's "sDisplayData" array -- specifically,
370
      // this should be the list of display-values that have
383
      // this should be the list of display-values that have
371
      // FCDATA_DESIRED_PARENT_TYPE_TO_BITS specified in that array.
384
      // FCDATA_DESIRED_PARENT_TYPE_TO_BITS specified in that array.
372
      if (NS_STYLE_DISPLAY_TABLE_CAPTION      != displayVal &&
385
      if (NS_STYLE_DISPLAY_TABLE_CAPTION      != displayVal &&
(-)a/layout/style/nsStyleSet.cpp (-1 / +1 lines)
Line     Link Here 
 Lines 1477-1493   nsStyleSet::ProbePseudoElementStyle(Elem Link Here 
1477
  // 'content' property is equivalent to not having the pseudo-element
1477
  // 'content' property is equivalent to not having the pseudo-element
1478
  // at all.
1478
  // at all.
1479
  if (result &&
1479
  if (result &&
1480
      (pseudoTag == nsCSSPseudoElements::before ||
1480
      (pseudoTag == nsCSSPseudoElements::before ||
1481
       pseudoTag == nsCSSPseudoElements::after)) {
1481
       pseudoTag == nsCSSPseudoElements::after)) {
1482
    const nsStyleDisplay *display = result->StyleDisplay();
1482
    const nsStyleDisplay *display = result->StyleDisplay();
1483
    const nsStyleContent *content = result->StyleContent();
1483
    const nsStyleContent *content = result->StyleContent();
1484
    // XXXldb What is contentCount for |content: ""|?
1484
    // XXXldb What is contentCount for |content: ""|?
1485
    if (display->mDisplay == NS_STYLE_DISPLAY_NONE ||
1485
    if (display->mDisplayBox == NS_STYLE_DISPLAY_BOX_NONE ||
1486
        content->ContentCount() == 0) {
1486
        content->ContentCount() == 0) {
1487
      result = nullptr;
1487
      result = nullptr;
1488
    }
1488
    }
1489
  }
1489
  }
1490
1490
1491
  return result.forget();
1491
  return result.forget();
1492
}
1492
}
1493
1493
(-)a/layout/style/nsStyleStruct.cpp (-5 / +8 lines)
Line     Link Here 
 Lines 2368-2383   mozilla::StyleAnimation::SetInitialValue Link Here 
2368
  mIterationCount = 1.0f;
2368
  mIterationCount = 1.0f;
2369
}
2369
}
2370
2370
2371
nsStyleDisplay::nsStyleDisplay()
2371
nsStyleDisplay::nsStyleDisplay()
2372
  : mWillChangeBitField(0)
2372
  : mWillChangeBitField(0)
2373
{
2373
{
2374
  MOZ_COUNT_CTOR(nsStyleDisplay);
2374
  MOZ_COUNT_CTOR(nsStyleDisplay);
2375
  mAppearance = NS_THEME_NONE;
2375
  mAppearance = NS_THEME_NONE;
2376
  mDisplayBox = NS_STYLE_DISPLAY_BOX_NORMAL;
2376
  mDisplay = NS_STYLE_DISPLAY_INLINE;
2377
  mDisplay = NS_STYLE_DISPLAY_INLINE;
2377
  mOriginalDisplay = mDisplay;
2378
  mOriginalDisplay = mDisplay;
2378
  mPosition = NS_STYLE_POSITION_STATIC;
2379
  mPosition = NS_STYLE_POSITION_STATIC;
2379
  mFloats = NS_STYLE_FLOAT_NONE;
2380
  mFloats = NS_STYLE_FLOAT_NONE;
2380
  mOriginalFloats = mFloats;
2381
  mOriginalFloats = mFloats;
2381
  mBreakType = NS_STYLE_CLEAR_NONE;
2382
  mBreakType = NS_STYLE_CLEAR_NONE;
2382
  mBreakInside = NS_STYLE_PAGE_BREAK_AUTO;
2383
  mBreakInside = NS_STYLE_PAGE_BREAK_AUTO;
2383
  mBreakBefore = false;
2384
  mBreakBefore = false;
 Lines 2424-2439   nsStyleDisplay::nsStyleDisplay() Link Here 
2424
  mAnimationPlayStateCount = 1;
2425
  mAnimationPlayStateCount = 1;
2425
  mAnimationIterationCountCount = 1;
2426
  mAnimationIterationCountCount = 1;
2426
}
2427
}
2427
2428
2428
nsStyleDisplay::nsStyleDisplay(const nsStyleDisplay& aSource)
2429
nsStyleDisplay::nsStyleDisplay(const nsStyleDisplay& aSource)
2429
  : mBinding(aSource.mBinding)
2430
  : mBinding(aSource.mBinding)
2430
  , mClip(aSource.mClip)
2431
  , mClip(aSource.mClip)
2431
  , mOpacity(aSource.mOpacity)
2432
  , mOpacity(aSource.mOpacity)
2433
  , mDisplayBox(aSource.mDisplayBox)
2432
  , mDisplay(aSource.mDisplay)
2434
  , mDisplay(aSource.mDisplay)
2433
  , mOriginalDisplay(aSource.mOriginalDisplay)
2435
  , mOriginalDisplay(aSource.mOriginalDisplay)
2434
  , mAppearance(aSource.mAppearance)
2436
  , mAppearance(aSource.mAppearance)
2435
  , mPosition(aSource.mPosition)
2437
  , mPosition(aSource.mPosition)
2436
  , mFloats(aSource.mFloats)
2438
  , mFloats(aSource.mFloats)
2437
  , mOriginalFloats(aSource.mOriginalFloats)
2439
  , mOriginalFloats(aSource.mOriginalFloats)
2438
  , mBreakType(aSource.mBreakType)
2440
  , mBreakType(aSource.mBreakType)
2439
  , mBreakInside(aSource.mBreakInside)
2441
  , mBreakInside(aSource.mBreakInside)
 Lines 2475-2501   nsStyleDisplay::nsStyleDisplay(const nsS Link Here 
2475
  mTransformOrigin[1] = aSource.mTransformOrigin[1];
2477
  mTransformOrigin[1] = aSource.mTransformOrigin[1];
2476
  mTransformOrigin[2] = aSource.mTransformOrigin[2];
2478
  mTransformOrigin[2] = aSource.mTransformOrigin[2];
2477
  mPerspectiveOrigin[0] = aSource.mPerspectiveOrigin[0];
2479
  mPerspectiveOrigin[0] = aSource.mPerspectiveOrigin[0];
2478
  mPerspectiveOrigin[1] = aSource.mPerspectiveOrigin[1];
2480
  mPerspectiveOrigin[1] = aSource.mPerspectiveOrigin[1];
2479
}
2481
}
2480
2482
2481
nsChangeHint nsStyleDisplay::CalcDifference(const nsStyleDisplay& aOther) const
2483
nsChangeHint nsStyleDisplay::CalcDifference(const nsStyleDisplay& aOther) const
2482
{
2484
{
2483
  nsChangeHint hint = nsChangeHint(0);
2484
2485
  if (!EqualURIs(mBinding, aOther.mBinding)
2485
  if (!EqualURIs(mBinding, aOther.mBinding)
2486
      || mPosition != aOther.mPosition
2486
      || mPosition != aOther.mPosition
2487
      || mDisplay != aOther.mDisplay
2487
      || mDisplay != aOther.mDisplay
2488
      || (mFloats == NS_STYLE_FLOAT_NONE) != (aOther.mFloats == NS_STYLE_FLOAT_NONE)
2488
      || (mFloats == NS_STYLE_FLOAT_NONE) != (aOther.mFloats == NS_STYLE_FLOAT_NONE)
2489
      || mOverflowX != aOther.mOverflowX
2489
      || mOverflowX != aOther.mOverflowX
2490
      || mOverflowY != aOther.mOverflowY
2490
      || mOverflowY != aOther.mOverflowY
2491
      || mResize != aOther.mResize)
2491
      || mResize != aOther.mResize
2492
    NS_UpdateHint(hint, nsChangeHint_ReconstructFrame);
2492
      || mDisplayBox != aOther.mDisplayBox) {
2493
2493
    return nsChangeHint_ReconstructFrame;
2494
  }
2495
2496
  nsChangeHint hint = nsChangeHint(0);
2494
  if ((mAppearance == NS_THEME_TEXTFIELD &&
2497
  if ((mAppearance == NS_THEME_TEXTFIELD &&
2495
       aOther.mAppearance != NS_THEME_TEXTFIELD) ||
2498
       aOther.mAppearance != NS_THEME_TEXTFIELD) ||
2496
      (mAppearance != NS_THEME_TEXTFIELD &&
2499
      (mAppearance != NS_THEME_TEXTFIELD &&
2497
       aOther.mAppearance == NS_THEME_TEXTFIELD)) {
2500
       aOther.mAppearance == NS_THEME_TEXTFIELD)) {
2498
    // This is for <input type=number> where we allow authors to specify a
2501
    // This is for <input type=number> where we allow authors to specify a
2499
    // |-moz-appearance:textfield| to get a control without a spinner. (The
2502
    // |-moz-appearance:textfield| to get a control without a spinner. (The
2500
    // spinner is present for |-moz-appearance:number-input| but also other
2503
    // spinner is present for |-moz-appearance:number-input| but also other
2501
    // values such as 'none'.) We need to reframe since we want to use
2504
    // values such as 'none'.) We need to reframe since we want to use
(-)a/layout/style/nsStyleStruct.h (+1 lines)
Line     Link Here 
 Lines 1926-1941   struct nsStyleDisplay { Link Here 
1926
    return nsChangeHint(0);
1926
    return nsChangeHint(0);
1927
  }
1927
  }
1928
1928
1929
  // We guarantee that if mBinding is non-null, so are mBinding->GetURI() and
1929
  // We guarantee that if mBinding is non-null, so are mBinding->GetURI() and
1930
  // mBinding->mOriginPrincipal.
1930
  // mBinding->mOriginPrincipal.
1931
  nsRefPtr<mozilla::css::URLValue> mBinding;    // [reset]
1931
  nsRefPtr<mozilla::css::URLValue> mBinding;    // [reset]
1932
  nsRect  mClip;                // [reset] offsets from upper-left border edge
1932
  nsRect  mClip;                // [reset] offsets from upper-left border edge
1933
  float   mOpacity;             // [reset]
1933
  float   mOpacity;             // [reset]
1934
  uint8_t mDisplayBox;          // [reset] NS_STYLE_DISPLAY_BOX_NORMAL/NONE/CONTENTS
1934
  uint8_t mDisplay;             // [reset] see nsStyleConsts.h NS_STYLE_DISPLAY_*
1935
  uint8_t mDisplay;             // [reset] see nsStyleConsts.h NS_STYLE_DISPLAY_*
1935
  uint8_t mOriginalDisplay;     // [reset] saved mDisplay for position:absolute/fixed
1936
  uint8_t mOriginalDisplay;     // [reset] saved mDisplay for position:absolute/fixed
1936
                                //         and float:left/right; otherwise equal
1937
                                //         and float:left/right; otherwise equal
1937
                                //         to mDisplay
1938
                                //         to mDisplay
1938
  uint8_t mAppearance;          // [reset]
1939
  uint8_t mAppearance;          // [reset]
1939
  uint8_t mPosition;            // [reset] see nsStyleConsts.h
1940
  uint8_t mPosition;            // [reset] see nsStyleConsts.h
1940
  uint8_t mFloats;              // [reset] see nsStyleConsts.h NS_STYLE_FLOAT_*
1941
  uint8_t mFloats;              // [reset] see nsStyleConsts.h NS_STYLE_FLOAT_*
1941
  uint8_t mOriginalFloats;      // [reset] saved mFloats for position:absolute/fixed;
1942
  uint8_t mOriginalFloats;      // [reset] saved mFloats for position:absolute/fixed;
(-)a/layout/style/nsStyleStructInlines.h (-2 / +1 lines)
Line     Link Here 
 Lines 95-112   nsStyleDisplay::IsOriginalDisplayInlineO Link Here 
95
  }
95
  }
96
  return IsOriginalDisplayInlineOutsideStyle();
96
  return IsOriginalDisplayInlineOutsideStyle();
97
}
97
}
98
98
99
uint8_t
99
uint8_t
100
nsStyleDisplay::GetDisplay(const nsIFrame* aContextFrame) const
100
nsStyleDisplay::GetDisplay(const nsIFrame* aContextFrame) const
101
{
101
{
102
  NS_ASSERTION(aContextFrame->StyleDisplay() == this, "unexpected aContextFrame");
102
  NS_ASSERTION(aContextFrame->StyleDisplay() == this, "unexpected aContextFrame");
103
  if (aContextFrame->IsSVGText() &&
103
  if (aContextFrame->IsSVGText() && mDisplayBox != NS_STYLE_DISPLAY_BOX_NONE) {
104
      mDisplay != NS_STYLE_DISPLAY_NONE) {
105
    return aContextFrame->GetType() == nsGkAtoms::blockFrame ?
104
    return aContextFrame->GetType() == nsGkAtoms::blockFrame ?
106
             NS_STYLE_DISPLAY_BLOCK :
105
             NS_STYLE_DISPLAY_BLOCK :
107
             NS_STYLE_DISPLAY_INLINE;
106
             NS_STYLE_DISPLAY_INLINE;
108
  }
107
  }
109
  return mDisplay;
108
  return mDisplay;
110
}
109
}
111
110
112
bool
111
bool
(-)a/layout/style/test/property_database.js (+11 lines)
Line     Link Here 
 Lines 5361-5376   if (SpecialPowers.getBoolPref("layout.cs Link Here 
5361
    inherited: false,
5361
    inherited: false,
5362
    type: CSS_TYPE_LONGHAND,
5362
    type: CSS_TYPE_LONGHAND,
5363
    initial_values: [ "padding-box" ],
5363
    initial_values: [ "padding-box" ],
5364
    other_values: [ "content-box" ],
5364
    other_values: [ "content-box" ],
5365
    invalid_values: [ "none", "auto", "border-box", "0" ]
5365
    invalid_values: [ "none", "auto", "border-box", "0" ]
5366
  };
5366
  };
5367
}
5367
}
5368
5368
5369
if (SpecialPowers.getBoolPref("layout.css.display-box.enabled")) {
5370
  gCSSProperties["display-box"] = {
5371
    domProp: "displayBox",
5372
    inherited: false,
5373
    type: CSS_TYPE_LONGHAND,
5374
    initial_values: [ "normal" ],
5375
    other_values: [ "none", "contents" ],
5376
    invalid_values: [ "auto", "0" ]
5377
  };
5378
}
5379
5369
if (SpecialPowers.getBoolPref("layout.css.box-decoration-break.enabled")) {
5380
if (SpecialPowers.getBoolPref("layout.css.box-decoration-break.enabled")) {
5370
  gCSSProperties["box-decoration-break"] = {
5381
  gCSSProperties["box-decoration-break"] = {
5371
    domProp: "boxDecorationBreak",
5382
    domProp: "boxDecorationBreak",
5372
    inherited: false,
5383
    inherited: false,
5373
    type: CSS_TYPE_LONGHAND,
5384
    type: CSS_TYPE_LONGHAND,
5374
    initial_values: [ "slice" ],
5385
    initial_values: [ "slice" ],
5375
    other_values: [ "clone" ],
5386
    other_values: [ "clone" ],
5376
    invalid_values: [ "auto",  "none",  "1px" ]
5387
    invalid_values: [ "auto",  "none",  "1px" ]
(-)a/layout/tables/nsTableColGroupFrame.cpp (-3 / +3 lines)
Line     Link Here 
 Lines 290-308   nsTableColGroupFrame::RemoveFrame(ChildL Link Here 
290
    nsTableColFrame* colFrame = (nsTableColFrame*)aOldFrame;
290
    nsTableColFrame* colFrame = (nsTableColFrame*)aOldFrame;
291
    if (colFrame->GetColType() == eColContent) {
291
    if (colFrame->GetColType() == eColContent) {
292
      contentRemoval = true;
292
      contentRemoval = true;
293
      // Remove any anonymous column frames this <col> produced via a colspan
293
      // Remove any anonymous column frames this <col> produced via a colspan
294
      nsTableColFrame* col = colFrame->GetNextCol();
294
      nsTableColFrame* col = colFrame->GetNextCol();
295
      nsTableColFrame* nextCol;
295
      nsTableColFrame* nextCol;
296
      while (col && col->GetColType() == eColAnonymousCol) {
296
      while (col && col->GetColType() == eColAnonymousCol) {
297
#ifdef DEBUG
297
#ifdef DEBUG
298
        nsIFrame* providerFrame = colFrame->GetParentStyleContextFrame();
298
        nsIFrame* providerFrame;
299
        if (colFrame->StyleContext()->GetParent() ==
299
        nsStyleContext* psc = colFrame->GetParentStyleContext(&providerFrame);
300
            providerFrame->StyleContext()) {
300
        if (colFrame->StyleContext()->GetParent() == psc) {
301
          NS_ASSERTION(col->StyleContext() == colFrame->StyleContext() &&
301
          NS_ASSERTION(col->StyleContext() == colFrame->StyleContext() &&
302
                       col->GetContent() == colFrame->GetContent(),
302
                       col->GetContent() == colFrame->GetContent(),
303
                       "How did that happen??");
303
                       "How did that happen??");
304
        }
304
        }
305
        // else colFrame is being removed because of a frame
305
        // else colFrame is being removed because of a frame
306
        // reconstruct on it, and its style context is still the old
306
        // reconstruct on it, and its style context is still the old
307
        // one, so we can't assert anything about how it compares to
307
        // one, so we can't assert anything about how it compares to
308
        // col's style context.
308
        // col's style context.
(-)a/layout/tables/nsTableFrame.cpp (-3 / +4 lines)
Line     Link Here 
 Lines 129-157   struct BCPropertyData Link Here 
129
  BCPixelSize mTopBorderWidth;
129
  BCPixelSize mTopBorderWidth;
130
  BCPixelSize mRightBorderWidth;
130
  BCPixelSize mRightBorderWidth;
131
  BCPixelSize mBottomBorderWidth;
131
  BCPixelSize mBottomBorderWidth;
132
  BCPixelSize mLeftBorderWidth;
132
  BCPixelSize mLeftBorderWidth;
133
  BCPixelSize mLeftCellBorderWidth;
133
  BCPixelSize mLeftCellBorderWidth;
134
  BCPixelSize mRightCellBorderWidth;
134
  BCPixelSize mRightCellBorderWidth;
135
};
135
};
136
136
137
nsIFrame*
137
nsStyleContext*
138
nsTableFrame::GetParentStyleContextFrame() const
138
nsTableFrame::GetParentStyleContext(nsIFrame** aProviderFrame) const
139
{
139
{
140
  // Since our parent, the table outer frame, returned this frame, we
140
  // Since our parent, the table outer frame, returned this frame, we
141
  // must return whatever our parent would normally have returned.
141
  // must return whatever our parent would normally have returned.
142
142
143
  NS_PRECONDITION(GetParent(), "table constructed without outer table");
143
  NS_PRECONDITION(GetParent(), "table constructed without outer table");
144
  if (!mContent->GetParent() && !StyleContext()->GetPseudo()) {
144
  if (!mContent->GetParent() && !StyleContext()->GetPseudo()) {
145
    // We're the root.  We have no style context parent.
145
    // We're the root.  We have no style context parent.
146
    *aProviderFrame = nullptr;
146
    return nullptr;
147
    return nullptr;
147
  }
148
  }
148
149
149
  return GetParent()->DoGetParentStyleContextFrame();
150
  return GetParent()->DoGetParentStyleContext(aProviderFrame);
150
}
151
}
151
152
152
153
153
nsIAtom*
154
nsIAtom*
154
nsTableFrame::GetType() const
155
nsTableFrame::GetType() const
155
{
156
{
156
  return nsGkAtoms::tableFrame;
157
  return nsGkAtoms::tableFrame;
157
}
158
}
(-)a/layout/tables/nsTableFrame.h (-1 / +2 lines)
Line     Link Here 
 Lines 343-359   public: Link Here 
343
  void ReflowTable(nsHTMLReflowMetrics&     aDesiredSize,
343
  void ReflowTable(nsHTMLReflowMetrics&     aDesiredSize,
344
                   const nsHTMLReflowState& aReflowState,
344
                   const nsHTMLReflowState& aReflowState,
345
                   nscoord                  aAvailHeight,
345
                   nscoord                  aAvailHeight,
346
                   nsIFrame*&               aLastChildReflowed,
346
                   nsIFrame*&               aLastChildReflowed,
347
                   nsReflowStatus&          aStatus);
347
                   nsReflowStatus&          aStatus);
348
348
349
  nsFrameList& GetColGroups();
349
  nsFrameList& GetColGroups();
350
350
351
  virtual nsIFrame* GetParentStyleContextFrame() const MOZ_OVERRIDE;
351
  virtual nsStyleContext*
352
  GetParentStyleContext(nsIFrame** aProviderFrame) const MOZ_OVERRIDE;
352
353
353
  /**
354
  /**
354
   * Get the "type" of the frame
355
   * Get the "type" of the frame
355
   *
356
   *
356
   * @see nsGkAtoms::tableFrame
357
   * @see nsGkAtoms::tableFrame
357
   */
358
   */
358
  virtual nsIAtom* GetType() const MOZ_OVERRIDE;
359
  virtual nsIAtom* GetType() const MOZ_OVERRIDE;
359
360
(-)a/layout/tables/nsTableOuterFrame.cpp (-10 / +20 lines)
Line     Link Here 
 Lines 1-13    Link Here 
1
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
1
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* This Source Code Form is subject to the terms of the Mozilla Public
2
/* This Source Code Form is subject to the terms of the Mozilla Public
3
 * License, v. 2.0. If a copy of the MPL was not distributed with this
3
 * License, v. 2.0. If a copy of the MPL was not distributed with this
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
#include "nsTableOuterFrame.h"
6
#include "nsTableOuterFrame.h"
7
8
#include "nsFrameManager.h"
6
#include "nsTableFrame.h"
9
#include "nsTableFrame.h"
7
#include "nsTableCellFrame.h"
10
#include "nsTableCellFrame.h"
8
#include "nsStyleContext.h"
11
#include "nsStyleContext.h"
9
#include "nsStyleConsts.h"
12
#include "nsStyleConsts.h"
10
#include "nsPresContext.h"
13
#include "nsPresContext.h"
11
#include "nsCSSRendering.h"
14
#include "nsCSSRendering.h"
12
#include "nsIContent.h"
15
#include "nsIContent.h"
13
#include "prinrval.h"
16
#include "prinrval.h"
 Lines 87-121   nsTableCaptionFrame::ComputeAutoSize(nsR Link Here 
87
    if (min > aCBSize.width)
90
    if (min > aCBSize.width)
88
      min = aCBSize.width;
91
      min = aCBSize.width;
89
    if (min > result.width)
92
    if (min > result.width)
90
      result.width = min;
93
      result.width = min;
91
  }
94
  }
92
  return result;
95
  return result;
93
}
96
}
94
97
95
nsIFrame*
98
nsStyleContext*
96
nsTableCaptionFrame::GetParentStyleContextFrame() const
99
nsTableCaptionFrame::GetParentStyleContext(nsIFrame** aProviderFrame) const
97
{
100
{
98
  NS_PRECONDITION(mContent->GetParent(),
101
  MOZ_ASSERT(GetContent()->GetParent(), "How could we not have a parent here?");
99
                  "How could we not have a parent here?");
100
    
102
    
103
  nsStyleContext* sc =
104
    PresContext()->FrameManager()->GetDisplayBoxContentsStyleFor(GetContent()->GetParent());
105
  if (sc) {
106
    *aProviderFrame = nullptr;
107
    return sc;
108
  }
109
101
  // The caption's style context parent is the inner frame, unless
110
  // The caption's style context parent is the inner frame, unless
102
  // it's anonymous.
111
  // it's anonymous.
103
  nsIFrame* outerFrame = GetParent();
112
  nsIFrame* outerFrame = GetParent();
104
  if (outerFrame && outerFrame->GetType() == nsGkAtoms::tableOuterFrame) {
113
  if (outerFrame && outerFrame->GetType() == nsGkAtoms::tableOuterFrame) {
105
    nsIFrame* innerFrame = outerFrame->GetFirstPrincipalChild();
114
    nsIFrame* innerFrame = outerFrame->GetFirstPrincipalChild();
106
    if (innerFrame) {
115
    if (innerFrame) {
107
      return nsFrame::CorrectStyleParentFrame(innerFrame,
116
      *aProviderFrame = nsFrame::CorrectStyleParentFrame(innerFrame,
108
                                              StyleContext()->GetPseudo());
117
                                   StyleContext()->GetPseudo());
118
      return *aProviderFrame ? (*aProviderFrame)->StyleContext() : nullptr;
109
    }
119
    }
110
  }
120
  }
111
121
112
  NS_NOTREACHED("Where is our inner table frame?");
122
  NS_NOTREACHED("Where is our inner table frame?");
113
  return nsBlockFrame::GetParentStyleContextFrame();
123
  return nsBlockFrame::GetParentStyleContext(aProviderFrame);
114
}
124
}
115
125
116
#ifdef ACCESSIBILITY
126
#ifdef ACCESSIBILITY
117
a11y::AccType
127
a11y::AccType
118
nsTableCaptionFrame::AccessibleType()
128
nsTableCaptionFrame::AccessibleType()
119
{
129
{
120
  if (!GetRect().IsEmpty()) {
130
  if (!GetRect().IsEmpty()) {
121
    return a11y::eHTMLCaptionType;
131
    return a11y::eHTMLCaptionType;
 Lines 309-338   nsTableOuterFrame::BuildDisplayListForIn Link Here 
309
  nsIFrame* kid = mFrames.FirstChild();
319
  nsIFrame* kid = mFrames.FirstChild();
310
  // The children should be in content order
320
  // The children should be in content order
311
  while (kid) {
321
  while (kid) {
312
    BuildDisplayListForChild(aBuilder, kid, aDirtyRect, aLists);
322
    BuildDisplayListForChild(aBuilder, kid, aDirtyRect, aLists);
313
    kid = kid->GetNextSibling();
323
    kid = kid->GetNextSibling();
314
  }
324
  }
315
}
325
}
316
326
317
nsIFrame*
327
nsStyleContext*
318
nsTableOuterFrame::GetParentStyleContextFrame() const
328
nsTableOuterFrame::GetParentStyleContext(nsIFrame** aProviderFrame) const
319
{
329
{
320
  // The table outer frame and the (inner) table frame split the style
330
  // The table outer frame and the (inner) table frame split the style
321
  // data by giving the table frame the style context associated with
331
  // data by giving the table frame the style context associated with
322
  // the table content node and creating a style context for the outer
332
  // the table content node and creating a style context for the outer
323
  // frame that is a *child* of the table frame's style context,
333
  // frame that is a *child* of the table frame's style context,
324
  // matching the ::-moz-table-outer pseudo-element.  html.css has a
334
  // matching the ::-moz-table-outer pseudo-element.  html.css has a
325
  // rule that causes that pseudo-element (and thus the outer table)
335
  // rule that causes that pseudo-element (and thus the outer table)
326
  // to inherit *some* style properties from the table frame.  The
336
  // to inherit *some* style properties from the table frame.  The
327
  // children of the table inherit directly from the inner table, and
337
  // children of the table inherit directly from the inner table, and
328
  // the outer table's style context is a leaf.
338
  // the outer table's style context is a leaf.
329
339
330
  return InnerTableFrame();
340
  return (*aProviderFrame = InnerTableFrame())->StyleContext();
331
}
341
}
332
342
333
// INCREMENTAL REFLOW HELPER FUNCTIONS 
343
// INCREMENTAL REFLOW HELPER FUNCTIONS 
334
344
335
void
345
void
336
nsTableOuterFrame::InitChildReflowState(nsPresContext&    aPresContext,                     
346
nsTableOuterFrame::InitChildReflowState(nsPresContext&    aPresContext,                     
337
                                        nsHTMLReflowState& aReflowState)
347
                                        nsHTMLReflowState& aReflowState)
338
                                    
348
                                    
(-)a/layout/tables/nsTableOuterFrame.h (-2 / +2 lines)
Line     Link Here 
 Lines 22-38   public: Link Here 
22
  // nsIFrame
22
  // nsIFrame
23
  virtual nsIAtom* GetType() const MOZ_OVERRIDE;
23
  virtual nsIAtom* GetType() const MOZ_OVERRIDE;
24
24
25
  virtual nsSize ComputeAutoSize(nsRenderingContext *aRenderingContext,
25
  virtual nsSize ComputeAutoSize(nsRenderingContext *aRenderingContext,
26
                                 nsSize aCBSize, nscoord aAvailableWidth,
26
                                 nsSize aCBSize, nscoord aAvailableWidth,
27
                                 nsSize aMargin, nsSize aBorder,
27
                                 nsSize aMargin, nsSize aBorder,
28
                                 nsSize aPadding, bool aShrinkWrap) MOZ_OVERRIDE;
28
                                 nsSize aPadding, bool aShrinkWrap) MOZ_OVERRIDE;
29
29
30
  virtual nsIFrame* GetParentStyleContextFrame() const MOZ_OVERRIDE;
30
  virtual nsStyleContext* GetParentStyleContext(nsIFrame** aProviderFrame) const MOZ_OVERRIDE;
31
31
32
#ifdef ACCESSIBILITY
32
#ifdef ACCESSIBILITY
33
  virtual mozilla::a11y::AccType AccessibleType() MOZ_OVERRIDE;
33
  virtual mozilla::a11y::AccType AccessibleType() MOZ_OVERRIDE;
34
#endif
34
#endif
35
35
36
#ifdef DEBUG_FRAME_DUMP
36
#ifdef DEBUG_FRAME_DUMP
37
  virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE;
37
  virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE;
38
#endif
38
#endif
 Lines 120-136   public: Link Here 
120
   * @see nsGkAtoms::tableOuterFrame
120
   * @see nsGkAtoms::tableOuterFrame
121
   */
121
   */
122
  virtual nsIAtom* GetType() const MOZ_OVERRIDE;
122
  virtual nsIAtom* GetType() const MOZ_OVERRIDE;
123
123
124
#ifdef DEBUG_FRAME_DUMP
124
#ifdef DEBUG_FRAME_DUMP
125
  virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE;
125
  virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE;
126
#endif
126
#endif
127
127
128
  virtual nsIFrame* GetParentStyleContextFrame() const MOZ_OVERRIDE;
128
  virtual nsStyleContext* GetParentStyleContext(nsIFrame** aProviderFrame) const MOZ_OVERRIDE;
129
129
130
  /**
130
  /**
131
   * Return the content for the cell at the given row and column.
131
   * Return the content for the cell at the given row and column.
132
   */
132
   */
133
  nsIContent* GetCellAt(uint32_t aRowIdx, uint32_t aColIdx) const;
133
  nsIContent* GetCellAt(uint32_t aRowIdx, uint32_t aColIdx) const;
134
134
135
  /**
135
  /**
136
   * Return the number of rows in the table.
136
   * Return the number of rows in the table.
(-)a/modules/libpref/src/init/all.js (+3 lines)
Line     Link Here 
 Lines 1978-1993   pref("layout.css.overflow-clip-box.enabl Link Here 
1978
pref("layout.css.grid.enabled", false);
1978
pref("layout.css.grid.enabled", false);
1979
1979
1980
// Is support for CSS box-decoration-break enabled?
1980
// Is support for CSS box-decoration-break enabled?
1981
pref("layout.css.box-decoration-break.enabled", true);
1981
pref("layout.css.box-decoration-break.enabled", true);
1982
1982
1983
// Is layout of CSS outline-style:auto enabled?
1983
// Is layout of CSS outline-style:auto enabled?
1984
pref("layout.css.outline-style-auto.enabled", false);
1984
pref("layout.css.outline-style-auto.enabled", false);
1985
1985
1986
// Is support for the CSS display-box property enabled?
1987
pref("layout.css.display-box.enabled", false);
1988
1986
// pref for which side vertical scrollbars should be on
1989
// pref for which side vertical scrollbars should be on
1987
// 0 = end-side in UI direction
1990
// 0 = end-side in UI direction
1988
// 1 = end-side in document/content direction
1991
// 1 = end-side in document/content direction
1989
// 2 = right
1992
// 2 = right
1990
// 3 = left
1993
// 3 = left
1991
pref("layout.scrollbar.side", 0);
1994
pref("layout.scrollbar.side", 0);
1992
1995
1993
// pref to stop overlay scrollbars from fading out, for testing purposes
1996
// pref to stop overlay scrollbars from fading out, for testing purposes

Return to bug 907396