Attachment #8492600: Make RestyleManager::RestyleElement and nsCSSFrameConstructor::MaybeRecreateFramesForElement deal with display:contents elements. for bug #907396

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

(-)a/layout/base/RestyleManager.cpp (-56 / +188 lines)
Line     Link Here 
 Lines 72-87   RestyleManager::NotifyDestroyingFrame(ns Link Here 
72
}
72
}
73
73
74
#ifdef DEBUG
74
#ifdef DEBUG
75
  // To ensure that the functions below are only called within
75
  // To ensure that the functions below are only called within
76
  // |ApplyRenderingChangeToTree|.
76
  // |ApplyRenderingChangeToTree|.
77
static bool gInApplyRenderingChangeToTree = false;
77
static bool gInApplyRenderingChangeToTree = false;
78
#endif
78
#endif
79
79
80
static nsIFrame*
81
GetNearestAncestorFrame(nsIContent* aContent)
82
{
83
  nsIFrame* ancestorFrame = nullptr;
84
  for (nsIContent* ancestor = aContent->GetParent();
85
       ancestor && !ancestorFrame;
86
       ancestor = ancestor->GetParent()) {
87
    ancestorFrame = ancestor->GetPrimaryFrame();
88
  }
89
  return ancestorFrame;
90
}
91
92
80
static void
93
static void
81
DoApplyRenderingChangeToTree(nsIFrame* aFrame,
94
DoApplyRenderingChangeToTree(nsIFrame* aFrame,
82
                             nsChangeHint aChange);
95
                             nsChangeHint aChange);
83
96
84
/**
97
/**
85
 * Sync views on aFrame and all of aFrame's descendants (following placeholders),
98
 * Sync views on aFrame and all of aFrame's descendants (following placeholders),
86
 * if aChange has nsChangeHint_SyncFrameView.
99
 * if aChange has nsChangeHint_SyncFrameView.
87
 * Calls DoApplyRenderingChangeToTree on all aFrame's out-of-flow descendants
100
 * Calls DoApplyRenderingChangeToTree on all aFrame's out-of-flow descendants
 Lines 912-928   RestyleManager::RestyleElement(Element* Link Here 
912
    // We're restyling an element with no frame, so we should try to
925
    // We're restyling an element with no frame, so we should try to
913
    // make one if its new style says it should have one.  But in order
926
    // make one if its new style says it should have one.  But in order
914
    // to try to honor the restyle hint (which we'd like to do so that,
927
    // to try to honor the restyle hint (which we'd like to do so that,
915
    // for example, an animation-only style flush doesn't flush other
928
    // for example, an animation-only style flush doesn't flush other
916
    // buffered style changes), we only do this if the restyle hint says
929
    // buffered style changes), we only do this if the restyle hint says
917
    // we have *some* restyling for this frame.  This means we'll
930
    // we have *some* restyling for this frame.  This means we'll
918
    // potentially get ahead of ourselves in that case, but not as much
931
    // potentially get ahead of ourselves in that case, but not as much
919
    // as we would if we didn't check the restyle hint.
932
    // as we would if we didn't check the restyle hint.
920
    FrameConstructor()->MaybeRecreateFramesForElement(aElement);
933
    nsStyleContext* newContext =
934
      FrameConstructor()->MaybeRecreateFramesForElement(aElement);
935
    if (newContext &&
936
        newContext->StyleDisplay()->mDisplay == NS_STYLE_DISPLAY_CONTENTS) {
937
      // Style change for a display:contents node that did not recreate frames.
938
      nsIFrame* frame = GetNearestAncestorFrame(aElement);
939
      MOZ_ASSERT(frame, "display:contents node in map although it's a "
940
                        "display:none descendant?");
941
      TreeMatchContext treeMatchContext(true,
942
                                        nsRuleWalker::eRelevantLinkUnvisited,
943
                                        frame->PresContext()->Document());
944
      nsIContent* parent = aElement->GetParent();
945
      Element* parentElement =
946
        parent && parent->IsElement() ? parent->AsElement() : nullptr;
947
      treeMatchContext.InitAncestors(parentElement);
948
      nsTArray<nsIContent*> visibleKidsOfHiddenElement;
949
      nsStyleChangeList changeList;
950
      ElementRestyler r(frame->PresContext(), aElement, &changeList,
951
                        aMinHint, aRestyleTracker, treeMatchContext,
952
                        visibleKidsOfHiddenElement);
953
      r.RestyleChildrenOfDisplayContentsElement(frame, newContext,
954
                                                aMinHint, aRestyleTracker,
955
                                                aRestyleHint, this);
956
      ProcessRestyledFrames(changeList);
957
    }
921
  }
958
  }
922
}
959
}
923
960
924
static inline dom::Element*
961
static inline dom::Element*
925
ElementForStyleContext(nsIContent* aParentContent,
962
ElementForStyleContext(nsIContent* aParentContent,
926
                       nsIFrame* aFrame,
963
                       nsIFrame* aFrame,
927
                       nsCSSPseudoElements::Type aPseudoType);
964
                       nsCSSPseudoElements::Type aPseudoType);
928
965
 Lines 2316-2331   ElementRestyler::ElementRestyler(ParentC Link Here 
2316
  , mDesiredA11yNotifications(aParentRestyler.mDesiredA11yNotifications)
2353
  , mDesiredA11yNotifications(aParentRestyler.mDesiredA11yNotifications)
2317
  , mKidsDesiredA11yNotifications(mDesiredA11yNotifications)
2354
  , mKidsDesiredA11yNotifications(mDesiredA11yNotifications)
2318
  , mOurA11yNotification(eDontNotify)
2355
  , mOurA11yNotification(eDontNotify)
2319
  , mVisibleKidsOfHiddenElement(aParentRestyler.mVisibleKidsOfHiddenElement)
2356
  , mVisibleKidsOfHiddenElement(aParentRestyler.mVisibleKidsOfHiddenElement)
2320
#endif
2357
#endif
2321
{
2358
{
2322
}
2359
}
2323
2360
2361
ElementRestyler::ElementRestyler(nsPresContext* aPresContext,
2362
                                 nsIContent* aContent,
2363
                                 nsStyleChangeList* aChangeList,
2364
                                 nsChangeHint aHintsHandledByAncestors,
2365
                                 RestyleTracker& aRestyleTracker,
2366
                                 TreeMatchContext& aTreeMatchContext,
2367
                                 nsTArray<nsIContent*>&
2368
                                 aVisibleKidsOfHiddenElement)
2369
  : mPresContext(aPresContext)
2370
  , mFrame(nullptr)
2371
  , mParentContent(nullptr)
2372
  , mContent(aContent)
2373
  , mChangeList(aChangeList)
2374
  , mHintsHandled(NS_SubtractHint(aHintsHandledByAncestors,
2375
                  NS_HintsNotHandledForDescendantsIn(aHintsHandledByAncestors)))
2376
  , mParentFrameHintsNotHandledForDescendants(nsChangeHint(0))
2377
  , mHintsNotHandledForDescendants(nsChangeHint(0))
2378
  , mRestyleTracker(aRestyleTracker)
2379
  , mTreeMatchContext(aTreeMatchContext)
2380
  , mResolvedChild(nullptr)
2381
#ifdef ACCESSIBILITY
2382
  , mDesiredA11yNotifications(eSendAllNotifications)
2383
  , mKidsDesiredA11yNotifications(mDesiredA11yNotifications)
2384
  , mOurA11yNotification(eDontNotify)
2385
  , mVisibleKidsOfHiddenElement(aVisibleKidsOfHiddenElement)
2386
#endif
2387
{
2388
}
2389
2324
void
2390
void
2325
ElementRestyler::CaptureChange(nsStyleContext* aOldContext,
2391
ElementRestyler::CaptureChange(nsStyleContext* aOldContext,
2326
                               nsStyleContext* aNewContext,
2392
                               nsStyleContext* aNewContext,
2327
                               nsChangeHint aChangeToAssume,
2393
                               nsChangeHint aChangeToAssume,
2328
                               uint32_t* aEqualStructs)
2394
                               uint32_t* aEqualStructs)
2329
{
2395
{
2330
  static_assert(nsStyleStructID_Length <= 32,
2396
  static_assert(nsStyleStructID_Length <= 32,
2331
                "aEqualStructs is not big enough");
2397
                "aEqualStructs is not big enough");
 Lines 2499-2515   ElementRestyler::Restyle(nsRestyleHint a Link Here 
2499
      // left on mFrame.  Since we ended up restyling our parent, change
2565
      // left on mFrame.  Since we ended up restyling our parent, change
2500
      // this old style context to point to its new parent.
2566
      // this old style context to point to its new parent.
2501
      oldContext->MoveTo(parentContext);
2567
      oldContext->MoveTo(parentContext);
2502
    }
2568
    }
2503
2569
2504
    // Send the accessibility notifications that RestyleChildren otherwise
2570
    // Send the accessibility notifications that RestyleChildren otherwise
2505
    // would have sent.
2571
    // would have sent.
2506
    if (!(mHintsHandled & nsChangeHint_ReconstructFrame)) {
2572
    if (!(mHintsHandled & nsChangeHint_ReconstructFrame)) {
2507
      InitializeAccessibilityNotifications();
2573
      InitializeAccessibilityNotifications(mFrame->StyleContext());
2508
      SendAccessibilityNotifications();
2574
      SendAccessibilityNotifications();
2509
    }
2575
    }
2510
2576
2511
    mRestyleTracker.AddRestyleRootsIfAwaitingRestyle(descendants);
2577
    mRestyleTracker.AddRestyleRootsIfAwaitingRestyle(descendants);
2512
    return;
2578
    return;
2513
  }
2579
  }
2514
2580
2515
  if (!swappedStructs) {
2581
  if (!swappedStructs) {
 Lines 3088-3104   ElementRestyler::RestyleChildren(nsResty Link Here 
3088
  // descendants anyway, so we want to avoid wasting time processing
3154
  // descendants anyway, so we want to avoid wasting time processing
3089
  // style contexts that we're just going to throw away anyway. - dwh
3155
  // style contexts that we're just going to throw away anyway. - dwh
3090
  // It's also important to check mHintsHandled since reresolving the
3156
  // It's also important to check mHintsHandled since reresolving the
3091
  // kids would use mFrame->StyleContext(), which is out of date if
3157
  // kids would use mFrame->StyleContext(), which is out of date if
3092
  // mHintsHandled has a ReconstructFrame hint; doing this could trigger
3158
  // mHintsHandled has a ReconstructFrame hint; doing this could trigger
3093
  // assertions about mismatched rule trees.
3159
  // assertions about mismatched rule trees.
3094
  nsIFrame *lastContinuation;
3160
  nsIFrame *lastContinuation;
3095
  if (!(mHintsHandled & nsChangeHint_ReconstructFrame)) {
3161
  if (!(mHintsHandled & nsChangeHint_ReconstructFrame)) {
3096
    InitializeAccessibilityNotifications();
3162
    InitializeAccessibilityNotifications(mFrame->StyleContext());
3097
3163
3098
    for (nsIFrame* f = mFrame; f;
3164
    for (nsIFrame* f = mFrame; f;
3099
         f = GetNextContinuationWithSameStyle(f, f->StyleContext())) {
3165
         f = GetNextContinuationWithSameStyle(f, f->StyleContext())) {
3100
      lastContinuation = f;
3166
      lastContinuation = f;
3101
      RestyleContentChildren(f, aChildRestyleHint);
3167
      RestyleContentChildren(f, aChildRestyleHint);
3102
    }
3168
    }
3103
3169
3104
    SendAccessibilityNotifications();
3170
    SendAccessibilityNotifications();
 Lines 3108-3160   ElementRestyler::RestyleChildren(nsResty Link Here 
3108
  // See comments above regarding :before.
3174
  // See comments above regarding :before.
3109
  if (!(mHintsHandled & nsChangeHint_ReconstructFrame) &&
3175
  if (!(mHintsHandled & nsChangeHint_ReconstructFrame) &&
3110
      mightReframePseudos) {
3176
      mightReframePseudos) {
3111
    MaybeReframeForAfterPseudo(lastContinuation);
3177
    MaybeReframeForAfterPseudo(lastContinuation);
3112
  }
3178
  }
3113
}
3179
}
3114
3180
3115
void
3181
void
3182
ElementRestyler::RestyleChildrenOfDisplayContentsElement(
3183
  nsIFrame*       aParentFrame,
3184
  nsStyleContext* aNewContext,
3185
  nsChangeHint    aMinHint,
3186
  RestyleTracker& aRestyleTracker,
3187
  nsRestyleHint   aRestyleHint,
3188
  RestyleManager* aRestyleManager)
3189
{
3190
  const bool mightReframePseudos = aRestyleHint & eRestyle_Subtree;
3191
  InitializeAccessibilityNotifications(aNewContext);
3192
  DoRestyleUndisplayedDescendants(nsRestyleHint(0), mContent, aNewContext);
3193
  if (!(mHintsHandled & nsChangeHint_ReconstructFrame) &&
3194
      mightReframePseudos) {
3195
    MaybeReframeForBeforePseudo(aParentFrame, nullptr, mContent, aNewContext);
3196
  }
3197
  if (!(mHintsHandled & nsChangeHint_ReconstructFrame) &&
3198
      mightReframePseudos) {
3199
    MaybeReframeForAfterPseudo(aParentFrame, nullptr, mContent, aNewContext);
3200
  }
3201
  if (!(mHintsHandled & nsChangeHint_ReconstructFrame)) {
3202
    // Then process child frames for content that is a descendant of mContent.
3203
    // XXX perhaps it's better to walk child frames (before reresolving
3204
    // XXX undisplayed contexts above) and mark those that has a stylecontext
3205
    // XXX leading up to mContent's old context? (instead of the
3206
    // XXX ContentIsDescendantOf check below)
3207
    nsIFrame::ChildListIterator lists(aParentFrame);
3208
    for ( ; !lists.IsDone(); lists.Next()) {
3209
      nsFrameList::Enumerator childFrames(lists.CurrentList());
3210
      for (; !childFrames.AtEnd(); childFrames.Next()) {
3211
        nsIFrame* f = childFrames.get();
3212
        if (nsContentUtils::ContentIsDescendantOf(f->GetContent(), mContent) &&
3213
            !f->GetPrevContinuation()) {
3214
          if (!(f->GetStateBits() & NS_FRAME_OUT_OF_FLOW)) {
3215
            aRestyleManager->ComputeStyleChangeFor(f, mChangeList, aMinHint,
3216
                                                   aRestyleTracker,
3217
                                                   aRestyleHint);
3218
          }
3219
        }
3220
      }
3221
    }
3222
  }
3223
  if (!(mHintsHandled & nsChangeHint_ReconstructFrame)) {
3224
    SendAccessibilityNotifications();
3225
  }
3226
}
3227
3228
void
3116
ElementRestyler::RestyleUndisplayedDescendants(nsRestyleHint aChildRestyleHint)
3229
ElementRestyler::RestyleUndisplayedDescendants(nsRestyleHint aChildRestyleHint)
3117
{
3230
{
3118
  // When the root element is display:none, we still construct *some*
3231
  // When the root element is display:none, we still construct *some*
3119
  // frames that have the root element as their mContent, down to the
3232
  // frames that have the root element as their mContent, down to the
3120
  // DocElementContainingBlock.
3233
  // DocElementContainingBlock.
3121
  bool checkUndisplayed;
3234
  bool checkUndisplayed;
3122
  nsIContent* undisplayedParent;
3235
  nsIContent* undisplayedParent;
3123
  if (mFrame->StyleContext()->GetPseudo()) {
3236
  if (mFrame->StyleContext()->GetPseudo()) {
3124
    checkUndisplayed = mFrame == mPresContext->FrameConstructor()->
3237
    checkUndisplayed = mFrame == mPresContext->FrameConstructor()->
3125
                                   GetDocElementContainingBlock();
3238
                                   GetDocElementContainingBlock();
3126
    undisplayedParent = nullptr;
3239
    undisplayedParent = nullptr;
3127
  } else {
3240
  } else {
3128
    checkUndisplayed = !!mFrame->GetContent();
3241
    checkUndisplayed = !!mFrame->GetContent();
3129
    undisplayedParent = mFrame->GetContent();
3242
    undisplayedParent = mFrame->GetContent();
3130
  }
3243
  }
3131
  if (checkUndisplayed) {
3244
  if (checkUndisplayed) {
3132
    DoRestyleUndisplayedDescendants(aChildRestyleHint, undisplayedParent);
3245
    DoRestyleUndisplayedDescendants(aChildRestyleHint, undisplayedParent,
3246
                                    mFrame->StyleContext());
3133
  }
3247
  }
3134
}
3248
}
3135
3249
3136
void
3250
void
3137
ElementRestyler::DoRestyleUndisplayedDescendants(nsRestyleHint aChildRestyleHint,
3251
ElementRestyler::DoRestyleUndisplayedDescendants(nsRestyleHint aChildRestyleHint,
3138
                                                 nsIContent* aParent)
3252
                                                 nsIContent* aParent,
3253
                                                 nsStyleContext* aParentContext)
3139
{
3254
{
3140
  nsCSSFrameConstructor* fc = mPresContext->FrameConstructor();
3255
  nsCSSFrameConstructor* fc = mPresContext->FrameConstructor();
3141
  UndisplayedNode* nodes = fc->GetAllUndisplayedContentIn(aParent);
3256
  UndisplayedNode* nodes = fc->GetAllUndisplayedContentIn(aParent);
3142
  RestyleUndisplayedNodes(aChildRestyleHint, nodes, aParent,
3257
  RestyleUndisplayedNodes(aChildRestyleHint, nodes, aParent,
3143
                          NS_STYLE_DISPLAY_NONE);
3258
                          aParentContext, NS_STYLE_DISPLAY_NONE);
3144
  nodes = fc->GetAllDisplayContentsIn(aParent);
3259
  nodes = fc->GetAllDisplayContentsIn(aParent);
3145
  RestyleUndisplayedNodes(aChildRestyleHint, nodes, aParent,
3260
  RestyleUndisplayedNodes(aChildRestyleHint, nodes, aParent,
3146
                          NS_STYLE_DISPLAY_CONTENTS);
3261
                          aParentContext, NS_STYLE_DISPLAY_CONTENTS);
3147
}
3262
}
3148
3263
3149
void
3264
void
3150
ElementRestyler::RestyleUndisplayedNodes(nsRestyleHint    aChildRestyleHint,
3265
ElementRestyler::RestyleUndisplayedNodes(nsRestyleHint    aChildRestyleHint,
3151
                                         UndisplayedNode* aUndisplayed,
3266
                                         UndisplayedNode* aUndisplayed,
3152
                                         nsIContent*      aUndisplayedParent,
3267
                                         nsIContent*      aUndisplayedParent,
3268
                                         nsStyleContext*  aParentContext,
3153
                                         const uint8_t    aDisplay)
3269
                                         const uint8_t    aDisplay)
3154
{
3270
{
3155
  nsIContent* undisplayedParent = aUndisplayedParent;
3271
  nsIContent* undisplayedParent = aUndisplayedParent;
3156
  UndisplayedNode* undisplayed = aUndisplayed;
3272
  UndisplayedNode* undisplayed = aUndisplayed;
3157
  TreeMatchContext::AutoAncestorPusher pusher(mTreeMatchContext);
3273
  TreeMatchContext::AutoAncestorPusher pusher(mTreeMatchContext);
3158
  if (undisplayed) {
3274
  if (undisplayed) {
3159
    pusher.PushAncestorAndStyleScope(undisplayedParent);
3275
    pusher.PushAncestorAndStyleScope(undisplayedParent);
3160
  }
3276
  }
 Lines 3183-3316   ElementRestyler::RestyleUndisplayedNodes Link Here 
3183
                                       undisplayedRestyleData)) {
3299
                                       undisplayedRestyleData)) {
3184
      thisChildHint =
3300
      thisChildHint =
3185
        nsRestyleHint(thisChildHint | undisplayedRestyleData->mRestyleHint);
3301
        nsRestyleHint(thisChildHint | undisplayedRestyleData->mRestyleHint);
3186
    }
3302
    }
3187
    nsRefPtr<nsStyleContext> undisplayedContext;
3303
    nsRefPtr<nsStyleContext> undisplayedContext;
3188
    nsStyleSet* styleSet = mPresContext->StyleSet();
3304
    nsStyleSet* styleSet = mPresContext->StyleSet();
3189
    if (thisChildHint & (eRestyle_Self | eRestyle_Subtree)) {
3305
    if (thisChildHint & (eRestyle_Self | eRestyle_Subtree)) {
3190
      undisplayedContext =
3306
      undisplayedContext =
3191
        styleSet->ResolveStyleFor(element,
3307
        styleSet->ResolveStyleFor(element, aParentContext, mTreeMatchContext);
3192
                                  mFrame->StyleContext(),
3193
                                  mTreeMatchContext);
3194
    } else if (thisChildHint ||
3308
    } else if (thisChildHint ||
3195
               styleSet->IsInRuleTreeReconstruct()) {
3309
               styleSet->IsInRuleTreeReconstruct()) {
3196
      // Use ResolveStyleWithReplacement either for actual
3310
      // Use ResolveStyleWithReplacement either for actual
3197
      // replacements, or as a substitute for ReparentStyleContext
3311
      // replacements, or as a substitute for ReparentStyleContext
3198
      // that rebuilds the path in the rule tree rather than reusing
3312
      // that rebuilds the path in the rule tree rather than reusing
3199
      // the rule node, as we need to do during a rule tree
3313
      // the rule node, as we need to do during a rule tree
3200
      // reconstruct.
3314
      // reconstruct.
3201
      undisplayedContext =
3315
      undisplayedContext =
3202
        styleSet->ResolveStyleWithReplacement(element,
3316
        styleSet->ResolveStyleWithReplacement(element,
3203
                                              mFrame->StyleContext(),
3317
                                              aParentContext,
3204
                                              undisplayed->mStyle,
3318
                                              undisplayed->mStyle,
3205
                                              thisChildHint);
3319
                                              thisChildHint);
3206
    } else {
3320
    } else {
3207
      undisplayedContext =
3321
      undisplayedContext =
3208
        styleSet->ReparentStyleContext(undisplayed->mStyle,
3322
        styleSet->ReparentStyleContext(undisplayed->mStyle,
3209
                                       mFrame->StyleContext(),
3323
                                       aParentContext,
3210
                                       element, element);
3324
                                       element, element);
3211
    }
3325
    }
3212
    const nsStyleDisplay* display = undisplayedContext->StyleDisplay();
3326
    const nsStyleDisplay* display = undisplayedContext->StyleDisplay();
3213
    if (display->mDisplay != aDisplay) {
3327
    if (display->mDisplay != aDisplay) {
3214
      NS_ASSERTION(element, "Must have undisplayed content");
3328
      NS_ASSERTION(element, "Must have undisplayed content");
3215
      mChangeList->AppendChange(nullptr, element,
3329
      mChangeList->AppendChange(nullptr, element,
3216
                                NS_STYLE_HINT_FRAMECHANGE);
3330
                                NS_STYLE_HINT_FRAMECHANGE);
3217
      // The node should be removed from the undisplayed map when
3331
      // The node should be removed from the undisplayed map when
3218
      // we reframe it.
3332
      // we reframe it.
3219
    } else {
3333
    } else {
3220
      // update the undisplayed node with the new context
3334
      // update the undisplayed node with the new context
3221
      undisplayed->mStyle = undisplayedContext;
3335
      undisplayed->mStyle = undisplayedContext;
3222
3336
3223
      if (aDisplay == NS_STYLE_DISPLAY_CONTENTS) {
3337
      if (aDisplay == NS_STYLE_DISPLAY_CONTENTS) {
3224
        DoRestyleUndisplayedDescendants(aChildRestyleHint, element);
3338
        DoRestyleUndisplayedDescendants(aChildRestyleHint, element,
3339
                                        undisplayed->mStyle);
3225
      }
3340
      }
3226
    }
3341
    }
3227
  }
3342
  }
3228
}
3343
}
3229
3344
3230
void
3345
void
3231
ElementRestyler::MaybeReframeForBeforePseudo()
3346
ElementRestyler::MaybeReframeForBeforePseudo()
3232
{
3347
{
3348
  MaybeReframeForBeforePseudo(mFrame, mFrame, mFrame->GetContent(),
3349
                              mFrame->StyleContext());
3350
}
3351
3352
void
3353
ElementRestyler::MaybeReframeForBeforePseudo(nsIFrame* aGenConParentFrame,
3354
                                             nsIFrame* aFrame,
3355
                                             nsIContent* aContent,
3356
                                             nsStyleContext* aStyleContext)
3357
{
3233
  // Make sure not to do this for pseudo-frames or frames that
3358
  // Make sure not to do this for pseudo-frames or frames that
3234
  // can't have generated content.
3359
  // can't have generated content.
3235
  nsContainerFrame* cif;
3360
  nsContainerFrame* cif;
3236
  if (!mFrame->StyleContext()->GetPseudo() &&
3361
  if (!aStyleContext->GetPseudo() &&
3237
      ((mFrame->GetStateBits() & NS_FRAME_MAY_HAVE_GENERATED_CONTENT) ||
3362
      ((aGenConParentFrame->GetStateBits() & NS_FRAME_MAY_HAVE_GENERATED_CONTENT) ||
3238
       // Our content insertion frame might have gotten flagged
3363
       // Our content insertion frame might have gotten flagged.
3239
       ((cif = mFrame->GetContentInsertionFrame()) &&
3364
       ((cif = aGenConParentFrame->GetContentInsertionFrame()) &&
3240
        (cif->GetStateBits() & NS_FRAME_MAY_HAVE_GENERATED_CONTENT)))) {
3365
        (cif->GetStateBits() & NS_FRAME_MAY_HAVE_GENERATED_CONTENT)))) {
3241
    // Check for a new :before pseudo and an existing :before
3366
    // Check for a ::before pseudo style and the absence of a ::before content,
3242
    // frame, but only if the frame is the first continuation.
3367
    // but only if aFrame is null or is the first continuation.
3243
    nsIFrame* prevContinuation = mFrame->GetPrevContinuation();
3368
    if (!aFrame || !aFrame->GetPrevContinuation()) {
3244
    if (!prevContinuation) {
3369
      // Checking for a ::before frame is cheaper than getting the
3245
      // Checking for a :before frame is cheaper than getting the
3370
      // ::before style context.
3246
      // :before style context.
3371
      if (!nsLayoutUtils::GetBeforeFrameForContent(aGenConParentFrame, aContent) &&
3247
      if (!nsLayoutUtils::GetBeforeFrame(mFrame) &&
3372
          nsLayoutUtils::HasPseudoStyle(aContent, aStyleContext,
3248
          nsLayoutUtils::HasPseudoStyle(mFrame->GetContent(),
3249
                                        mFrame->StyleContext(),
3250
                                        nsCSSPseudoElements::ePseudo_before,
3373
                                        nsCSSPseudoElements::ePseudo_before,
3251
                                        mPresContext)) {
3374
                                        mPresContext)) {
3252
        // Have to create the new :before frame
3375
        // Have to create the new ::before frame.
3253
        NS_UpdateHint(mHintsHandled, nsChangeHint_ReconstructFrame);
3376
        NS_UpdateHint(mHintsHandled, nsChangeHint_ReconstructFrame);
3254
        mChangeList->AppendChange(mFrame, mContent,
3377
        mChangeList->AppendChange(aFrame, aContent,
3255
                                  nsChangeHint_ReconstructFrame);
3378
                                  nsChangeHint_ReconstructFrame);
3256
      }
3379
      }
3257
    }
3380
    }
3258
  }
3381
  }
3259
}
3382
}
3260
3383
3261
/**
3384
/**
3262
 * aFrame is the last continuation or block-in-inline sibling that this
3385
 * aFrame is the last continuation or block-in-inline sibling that this
3263
 * ElementRestyler is restyling.
3386
 * ElementRestyler is restyling.
3264
 */
3387
 */
3265
void
3388
void
3266
ElementRestyler::MaybeReframeForAfterPseudo(nsIFrame* aFrame)
3389
ElementRestyler::MaybeReframeForAfterPseudo(nsIFrame* aFrame)
3267
{
3390
{
3391
  MOZ_ASSERT(aFrame);
3392
  MaybeReframeForAfterPseudo(aFrame, aFrame, aFrame->GetContent(),
3393
                             aFrame->StyleContext());
3394
}
3395
3396
void
3397
ElementRestyler::MaybeReframeForAfterPseudo(nsIFrame* aGenConParentFrame,
3398
                                            nsIFrame* aFrame,
3399
                                            nsIContent* aContent,
3400
                                            nsStyleContext* aStyleContext)
3401
{
3268
  // Make sure not to do this for pseudo-frames or frames that
3402
  // Make sure not to do this for pseudo-frames or frames that
3269
  // can't have generated content.
3403
  // can't have generated content.
3270
  nsContainerFrame* cif;
3404
  nsContainerFrame* cif;
3271
  if (!aFrame->StyleContext()->GetPseudo() &&
3405
  if (!aStyleContext->GetPseudo() &&
3272
      ((aFrame->GetStateBits() & NS_FRAME_MAY_HAVE_GENERATED_CONTENT) ||
3406
      ((aGenConParentFrame->GetStateBits() & NS_FRAME_MAY_HAVE_GENERATED_CONTENT) ||
3273
       // Our content insertion frame might have gotten flagged
3407
       // Our content insertion frame might have gotten flagged.
3274
       ((cif = aFrame->GetContentInsertionFrame()) &&
3408
       ((cif = aGenConParentFrame->GetContentInsertionFrame()) &&
3275
        (cif->GetStateBits() & NS_FRAME_MAY_HAVE_GENERATED_CONTENT)))) {
3409
        (cif->GetStateBits() & NS_FRAME_MAY_HAVE_GENERATED_CONTENT)))) {
3276
    // Check for new :after content, but only if the frame is the
3410
    // Check for an ::after pseudo style and the absence of an ::after content,
3277
    // last continuation.
3411
    // but only if aFrame is null or is the last continuation.
3278
    nsIFrame* nextContinuation = aFrame->GetNextContinuation();
3412
    if (!aFrame || !aFrame->GetNextContinuation()) {
3279
3413
      // Checking for an ::after frame is cheaper than getting the
3280
    if (!nextContinuation) {
3414
      // ::after style context.
3281
      // Getting the :after frame is more expensive than getting the pseudo
3415
      if (!nsLayoutUtils::GetAfterFrameForContent(aGenConParentFrame, aContent) &&
3282
      // context, so get the pseudo context first.
3416
          nsLayoutUtils::HasPseudoStyle(aContent, aStyleContext,
3283
      if (nsLayoutUtils::HasPseudoStyle(aFrame->GetContent(),
3284
                                        aFrame->StyleContext(),
3285
                                        nsCSSPseudoElements::ePseudo_after,
3417
                                        nsCSSPseudoElements::ePseudo_after,
3286
                                        mPresContext) &&
3418
                                        mPresContext)) {
3287
          !nsLayoutUtils::GetAfterFrame(aFrame)) {
3419
        // Have to create the new ::after frame.
3288
        // have to create the new :after frame
3289
        NS_UpdateHint(mHintsHandled, nsChangeHint_ReconstructFrame);
3420
        NS_UpdateHint(mHintsHandled, nsChangeHint_ReconstructFrame);
3290
        mChangeList->AppendChange(aFrame, mContent,
3421
        mChangeList->AppendChange(aFrame, mContent,
3291
                                  nsChangeHint_ReconstructFrame);
3422
                                  nsChangeHint_ReconstructFrame);
3292
      }
3423
      }
3293
    }
3424
    }
3294
  }
3425
  }
3295
}
3426
}
3296
3427
3297
void
3428
void
3298
ElementRestyler::InitializeAccessibilityNotifications()
3429
ElementRestyler::InitializeAccessibilityNotifications(nsStyleContext* aNewContext)
3299
{
3430
{
3300
#ifdef ACCESSIBILITY
3431
#ifdef ACCESSIBILITY
3301
  // Notify a11y for primary frame only if it's a root frame of visibility
3432
  // Notify a11y for primary frame only if it's a root frame of visibility
3302
  // changes or its parent frame was hidden while it stays visible and
3433
  // changes or its parent frame was hidden while it stays visible and
3303
  // it is not inside a {ib} split or is the first frame of {ib} split.
3434
  // it is not inside a {ib} split or is the first frame of {ib} split.
3304
  if (nsIPresShell::IsAccessibilityActive() &&
3435
  if (nsIPresShell::IsAccessibilityActive() &&
3305
      !mFrame->GetPrevContinuation() &&
3436
      (!mFrame ||
3306
      !mFrame->FrameIsNonFirstInIBSplit()) {
3437
       (!mFrame->GetPrevContinuation() &&
3438
        !mFrame->FrameIsNonFirstInIBSplit()))) {
3307
    if (mDesiredA11yNotifications == eSendAllNotifications) {
3439
    if (mDesiredA11yNotifications == eSendAllNotifications) {
3308
      bool isFrameVisible = mFrame->StyleVisibility()->IsVisible();
3440
      bool isFrameVisible = aNewContext->StyleVisibility()->IsVisible();
3309
      if (isFrameVisible != mWasFrameVisible) {
3441
      if (isFrameVisible != mWasFrameVisible) {
3310
        if (isFrameVisible) {
3442
        if (isFrameVisible) {
3311
          // Notify a11y the element (perhaps with its children) was shown.
3443
          // Notify a11y the element (perhaps with its children) was shown.
3312
          // We don't fall into this case if this element gets or stays shown
3444
          // We don't fall into this case if this element gets or stays shown
3313
          // while its parent becomes hidden.
3445
          // while its parent becomes hidden.
3314
          mKidsDesiredA11yNotifications = eSkipNotifications;
3446
          mKidsDesiredA11yNotifications = eSkipNotifications;
3315
          mOurA11yNotification = eNotifyShown;
3447
          mOurA11yNotification = eNotifyShown;
3316
        } else {
3448
        } else {
 Lines 3319-3338   ElementRestyler::InitializeAccessibility Link Here 
3319
          // visible children then we should notify a11y about that as if
3451
          // visible children then we should notify a11y about that as if
3320
          // they were inserted into tree. Notify a11y this element was
3452
          // they were inserted into tree. Notify a11y this element was
3321
          // hidden.
3453
          // hidden.
3322
          mKidsDesiredA11yNotifications = eNotifyIfShown;
3454
          mKidsDesiredA11yNotifications = eNotifyIfShown;
3323
          mOurA11yNotification = eNotifyHidden;
3455
          mOurA11yNotification = eNotifyHidden;
3324
        }
3456
        }
3325
      }
3457
      }
3326
    } else if (mDesiredA11yNotifications == eNotifyIfShown &&
3458
    } else if (mDesiredA11yNotifications == eNotifyIfShown &&
3327
               mFrame->StyleVisibility()->IsVisible()) {
3459
               aNewContext->StyleVisibility()->IsVisible()) {
3328
      // Notify a11y that element stayed visible while its parent was
3460
      // Notify a11y that element stayed visible while its parent was hidden.
3329
      // hidden.
3461
      nsIContent* c = mFrame ? mFrame->GetContent() : mContent;
3330
      mVisibleKidsOfHiddenElement.AppendElement(mFrame->GetContent());
3462
      mVisibleKidsOfHiddenElement.AppendElement(c);
3331
      mKidsDesiredA11yNotifications = eSkipNotifications;
3463
      mKidsDesiredA11yNotifications = eSkipNotifications;
3332
    }
3464
    }
3333
  }
3465
  }
3334
#endif
3466
#endif
3335
}
3467
}
3336
3468
3337
void
3469
void
3338
ElementRestyler::RestyleContentChildren(nsIFrame* aParent,
3470
ElementRestyler::RestyleContentChildren(nsIFrame* aParent,
 Lines 3408-3435   ElementRestyler::RestyleContentChildren( Link Here 
3408
void
3540
void
3409
ElementRestyler::SendAccessibilityNotifications()
3541
ElementRestyler::SendAccessibilityNotifications()
3410
{
3542
{
3411
#ifdef ACCESSIBILITY
3543
#ifdef ACCESSIBILITY
3412
  // Send notifications about visibility changes.
3544
  // Send notifications about visibility changes.
3413
  if (mOurA11yNotification == eNotifyShown) {
3545
  if (mOurA11yNotification == eNotifyShown) {
3414
    nsAccessibilityService* accService = nsIPresShell::AccService();
3546
    nsAccessibilityService* accService = nsIPresShell::AccService();
3415
    if (accService) {
3547
    if (accService) {
3416
      nsIPresShell* presShell = mFrame->PresContext()->GetPresShell();
3548
      nsIPresShell* presShell = mPresContext->GetPresShell();
3417
      nsIContent* content = mFrame->GetContent();
3549
      nsIContent* content = mFrame ? mFrame->GetContent() : mContent;
3418
3550
3419
      accService->ContentRangeInserted(presShell, content->GetParent(),
3551
      accService->ContentRangeInserted(presShell, content->GetParent(),
3420
                                       content,
3552
                                       content,
3421
                                       content->GetNextSibling());
3553
                                       content->GetNextSibling());
3422
    }
3554
    }
3423
  } else if (mOurA11yNotification == eNotifyHidden) {
3555
  } else if (mOurA11yNotification == eNotifyHidden) {
3424
    nsAccessibilityService* accService = nsIPresShell::AccService();
3556
    nsAccessibilityService* accService = nsIPresShell::AccService();
3425
    if (accService) {
3557
    if (accService) {
3426
      nsIPresShell* presShell = mFrame->PresContext()->GetPresShell();
3558
      nsIPresShell* presShell = mPresContext->GetPresShell();
3427
      nsIContent* content = mFrame->GetContent();
3559
      nsIContent* content = mFrame ? mFrame->GetContent() : mContent;
3428
      accService->ContentRemoved(presShell, content->GetParent(), content);
3560
      accService->ContentRemoved(presShell, content->GetParent(), content);
3429
3561
3430
      // Process children staying shown.
3562
      // Process children staying shown.
3431
      uint32_t visibleContentCount = mVisibleKidsOfHiddenElement.Length();
3563
      uint32_t visibleContentCount = mVisibleKidsOfHiddenElement.Length();
3432
      for (uint32_t idx = 0; idx < visibleContentCount; idx++) {
3564
      for (uint32_t idx = 0; idx < visibleContentCount; idx++) {
3433
        nsIContent* childContent = mVisibleKidsOfHiddenElement[idx];
3565
        nsIContent* childContent = mVisibleKidsOfHiddenElement[idx];
3434
        accService->ContentRangeInserted(presShell, childContent->GetParent(),
3566
        accService->ContentRangeInserted(presShell, childContent->GetParent(),
3435
                                         childContent,
3567
                                         childContent,
(-)a/layout/base/RestyleManager.h (-2 / +32 lines)
Line     Link Here 
 Lines 99-114   public: Link Here 
99
   * the new parent style context will be automatically computed based on the
99
   * the new parent style context will be automatically computed based on the
100
   * new position in the frame tree.
100
   * new position in the frame tree.
101
   *
101
   *
102
   * @param aFrame the root of the subtree to reparent.  Must not be null.
102
   * @param aFrame the root of the subtree to reparent.  Must not be null.
103
   */
103
   */
104
  nsresult ReparentStyleContext(nsIFrame* aFrame);
104
  nsresult ReparentStyleContext(nsIFrame* aFrame);
105
105
106
private:
106
private:
107
  friend class ElementRestyler;
107
  void ComputeAndProcessStyleChange(nsIFrame* aFrame,
108
  void ComputeAndProcessStyleChange(nsIFrame* aFrame,
108
                                    nsChangeHint aMinChange,
109
                                    nsChangeHint aMinChange,
109
                                    RestyleTracker& aRestyleTracker,
110
                                    RestyleTracker& aRestyleTracker,
110
                                    nsRestyleHint aRestyleHint);
111
                                    nsRestyleHint aRestyleHint);
111
112
112
  /**
113
  /**
113
   * Re-resolve the style contexts for a frame tree, building
114
   * Re-resolve the style contexts for a frame tree, building
114
   * aChangeList based on the resulting style changes, plus aMinChange
115
   * aChangeList based on the resulting style changes, plus aMinChange
 Lines 429-444   public: Link Here 
429
  // as the parent style context for their outer table frame (table
430
  // as the parent style context for their outer table frame (table
430
  // wrapper frame).  We should probably try to get rid of this
431
  // wrapper frame).  We should probably try to get rid of this
431
  // exception and have the inheritance go the other way.)
432
  // exception and have the inheritance go the other way.)
432
  enum ParentContextFromChildFrame { PARENT_CONTEXT_FROM_CHILD_FRAME };
433
  enum ParentContextFromChildFrame { PARENT_CONTEXT_FROM_CHILD_FRAME };
433
  ElementRestyler(ParentContextFromChildFrame,
434
  ElementRestyler(ParentContextFromChildFrame,
434
                  const ElementRestyler& aParentFrameRestyler,
435
                  const ElementRestyler& aParentFrameRestyler,
435
                  nsIFrame* aFrame);
436
                  nsIFrame* aFrame);
436
437
438
  // For restyling undisplayed content only (mFrame==null).
439
  ElementRestyler(nsPresContext* aPresContext,
440
                  nsIContent* aContent,
441
                  nsStyleChangeList* aChangeList,
442
                  nsChangeHint aHintsHandledByAncestors,
443
                  RestyleTracker& aRestyleTracker,
444
                  TreeMatchContext& aTreeMatchContext,
445
                  nsTArray<nsIContent*>& aVisibleKidsOfHiddenElement);
446
437
  /**
447
  /**
438
   * Restyle our frame's element and its subtree.
448
   * Restyle our frame's element and its subtree.
439
   *
449
   *
440
   * Use eRestyle_Self for the aRestyleHint argument to mean
450
   * Use eRestyle_Self for the aRestyleHint argument to mean
441
   * "reresolve our style context but not kids", use eRestyle_Subtree
451
   * "reresolve our style context but not kids", use eRestyle_Subtree
442
   * to mean "reresolve our style context and kids", and use
452
   * to mean "reresolve our style context and kids", and use
443
   * nsRestyleHint(0) to mean recompute a new style context for our
453
   * nsRestyleHint(0) to mean recompute a new style context for our
444
   * current parent and existing rulenode, and the same for kids.
454
   * current parent and existing rulenode, and the same for kids.
 Lines 449-464   public: Link Here 
449
   * mHintsHandled changes over time; it starts off as the hints that
459
   * mHintsHandled changes over time; it starts off as the hints that
450
   * have been handled by ancestors, and by the end of Restyle it
460
   * have been handled by ancestors, and by the end of Restyle it
451
   * represents the hints that have been handled for this frame.  This
461
   * represents the hints that have been handled for this frame.  This
452
   * method is intended to be called after Restyle, to find out what
462
   * method is intended to be called after Restyle, to find out what
453
   * hints have been handled for this frame.
463
   * hints have been handled for this frame.
454
   */
464
   */
455
  nsChangeHint HintsHandledForFrame() { return mHintsHandled; }
465
  nsChangeHint HintsHandledForFrame() { return mHintsHandled; }
456
466
467
  /**
468
   * Called from RestyleManager::RestyleElement to restyle children of
469
   * a display:contents element.
470
   */
471
  void RestyleChildrenOfDisplayContentsElement(nsIFrame* aParentFrame,
472
                                               nsStyleContext* aNewContext,
473
                                               nsChangeHint    aMinHint,
474
                                               RestyleTracker& aRestyleTracker,
475
                                               nsRestyleHint   aRestyleHint,
476
                                               RestyleManager* aRestyleManager);
457
private:
477
private:
458
  // Enum for the result of RestyleSelf, which indicates whether the
478
  // Enum for the result of RestyleSelf, which indicates whether the
459
  // restyle procedure should continue to the children, and how.
479
  // restyle procedure should continue to the children, and how.
460
  //
480
  //
461
  // These values must be ordered so that later values imply that all
481
  // These values must be ordered so that later values imply that all
462
  // the work of the earlier values is also done.
482
  // the work of the earlier values is also done.
463
  enum RestyleResult {
483
  enum RestyleResult {
464
484
 Lines 498-523   private: Link Here 
498
  RestyleResult ComputeRestyleResultFromNewContext(nsIFrame* aSelf,
518
  RestyleResult ComputeRestyleResultFromNewContext(nsIFrame* aSelf,
499
                                                   nsStyleContext* aNewContext);
519
                                                   nsStyleContext* aNewContext);
500
520
501
  /**
521
  /**
502
   * Helpers for RestyleChildren().
522
   * Helpers for RestyleChildren().
503
   */
523
   */
504
  void RestyleUndisplayedDescendants(nsRestyleHint aChildRestyleHint);
524
  void RestyleUndisplayedDescendants(nsRestyleHint aChildRestyleHint);
505
  void DoRestyleUndisplayedDescendants(nsRestyleHint aChildRestyleHint,
525
  void DoRestyleUndisplayedDescendants(nsRestyleHint aChildRestyleHint,
506
                                       nsIContent* aParent);
526
                                       nsIContent* aParent,
527
                                       nsStyleContext* aParentStyleContext);
507
  void RestyleUndisplayedNodes(nsRestyleHint    aChildRestyleHint,
528
  void RestyleUndisplayedNodes(nsRestyleHint    aChildRestyleHint,
508
                               UndisplayedNode* aUndisplayed,
529
                               UndisplayedNode* aUndisplayed,
509
                               nsIContent*      aUndisplayedParent,
530
                               nsIContent*      aUndisplayedParent,
531
                               nsStyleContext*  aParentStyleContext,
510
                               const uint8_t    aDisplay);
532
                               const uint8_t    aDisplay);
511
  void MaybeReframeForBeforePseudo();
533
  void MaybeReframeForBeforePseudo();
534
  void MaybeReframeForBeforePseudo(nsIFrame* aGenConParentFrame,
535
                                   nsIFrame* aFrame,
536
                                   nsIContent* aContent,
537
                                   nsStyleContext* aStyleContext);
512
  void MaybeReframeForAfterPseudo(nsIFrame* aFrame);
538
  void MaybeReframeForAfterPseudo(nsIFrame* aFrame);
539
  void MaybeReframeForAfterPseudo(nsIFrame* aGenConParentFrame,
540
                                  nsIFrame* aFrame,
541
                                  nsIContent* aContent,
542
                                  nsStyleContext* aStyleContext);
513
  void RestyleContentChildren(nsIFrame* aParent,
543
  void RestyleContentChildren(nsIFrame* aParent,
514
                              nsRestyleHint aChildRestyleHint);
544
                              nsRestyleHint aChildRestyleHint);
515
  void InitializeAccessibilityNotifications();
545
  void InitializeAccessibilityNotifications(nsStyleContext* aNewContext);
516
  void SendAccessibilityNotifications();
546
  void SendAccessibilityNotifications();
517
547
518
  enum DesiredA11yNotifications {
548
  enum DesiredA11yNotifications {
519
    eSkipNotifications,
549
    eSkipNotifications,
520
    eSendAllNotifications,
550
    eSendAllNotifications,
521
    eNotifyIfShown
551
    eNotifyIfShown
522
  };
552
  };
523
553
(-)a/layout/base/nsCSSFrameConstructor.cpp (-37 / +25 lines)
Line     Link Here 
 Lines 5760-5811   nsCSSFrameConstructor::AddFrameConstruct Link Here 
5760
      ((bits & FCDATA_DISALLOW_OUT_OF_FLOW) ||
5760
      ((bits & FCDATA_DISALLOW_OUT_OF_FLOW) ||
5761
       !aState.GetGeometricParent(display, nullptr))) {
5761
       !aState.GetGeometricParent(display, nullptr))) {
5762
    item->mIsLineParticipant = true;
5762
    item->mIsLineParticipant = true;
5763
    aItems.LineParticipantItemAdded();
5763
    aItems.LineParticipantItemAdded();
5764
  }
5764
  }
5765
}
5765
}
5766
5766
5767
static void
5767
static void
5768
DestroyContentArray(void* aPropertyValue)
5768
AddGenConPseudoToFrame(nsIFrame* aOwnerFrame, nsIContent* aContent)
5769
{
5769
{
5770
  typedef nsAutoTArray<nsIContent*, 2> T;
5770
  typedef nsAutoTArray<nsIContent*, 2> T;
5771
  T* arr = static_cast<T*>(aPropertyValue);
5771
  const FramePropertyDescriptor* prop = nsIFrame::GenConProperty();
5772
  for (T::size_type i = 0; i < arr->Length(); ++i) {
5773
    nsIContent* content = (*arr)[i];
5774
    content->UnbindFromTree();
5775
    NS_RELEASE(content);
5776
  }
5777
  delete arr;
5778
}
5779
5780
NS_DECLARE_FRAME_PROPERTY(GenConProperty, DestroyContentArray)
5781
5782
static void
5783
AddGenConPseudoToFrame(nsIFrame* aOwnerFrame, nsIContent* aContent)
5784
{
5785
  typedef nsAutoTArray<nsIContent*, 2> T;
5786
  const FramePropertyDescriptor* prop = GenConProperty();
5787
  FrameProperties props = aOwnerFrame->Properties();
5772
  FrameProperties props = aOwnerFrame->Properties();
5788
  T* value = static_cast<T*>(props.Get(prop));
5773
  T* value = static_cast<T*>(props.Get(prop));
5789
  if (!value) {
5774
  if (!value) {
5790
    value = new T;
5775
    value = new T;
5791
    props.Set(prop, value);
5776
    props.Set(prop, value);
5792
  }
5777
  }
5793
  value->AppendElement(aContent);
5778
  value->AppendElement(aContent);
5794
}
5779
}
5795
5780
5796
static nsTArray<nsIContent*>*
5797
GetGenConPseudos(nsIFrame* aOwnerFrame)
5798
{
5799
  const FramePropertyDescriptor* prop = GenConProperty();
5800
  FrameProperties props = aOwnerFrame->Properties();
5801
  return static_cast<nsTArray<nsIContent*>*>(props.Get(prop));
5802
}
5803
5804
/**
5781
/**
5805
 * Return true if the frame construction item pointed to by aIter will
5782
 * Return true if the frame construction item pointed to by aIter will
5806
 * create a frame adjacent to a line boundary in the frame tree, and that
5783
 * create a frame adjacent to a line boundary in the frame tree, and that
5807
 * line boundary is induced by a content node adjacent to the frame's
5784
 * line boundary is induced by a content node adjacent to the frame's
5808
 * content node in the content tree. The latter condition is necessary so
5785
 * content node in the content tree. The latter condition is necessary so
5809
 * that ContentAppended/ContentInserted/ContentRemoved can easily find any
5786
 * that ContentAppended/ContentInserted/ContentRemoved can easily find any
5810
 * text nodes that were suppressed here.
5787
 * text nodes that were suppressed here.
5811
 */
5788
 */
 Lines 6042-6058   AdjustAppendParentForAfterContent(nsFram Link Here 
6042
                                  nsIContent* aChild,
6019
                                  nsIContent* aChild,
6043
                                  nsIFrame** aAfterFrame)
6020
                                  nsIFrame** aAfterFrame)
6044
{
6021
{
6045
  // If the parent frame has any pseudo-elements or aContainer is a
6022
  // If the parent frame has any pseudo-elements or aContainer is a
6046
  // display:contents node then we need to walk through the child
6023
  // display:contents node then we need to walk through the child
6047
  // frames to find the first one that is either a ::after frame for an
6024
  // frames to find the first one that is either a ::after frame for an
6048
  // ancestor of aChild or a frame that is for a node later in the
6025
  // ancestor of aChild or a frame that is for a node later in the
6049
  // document than aChild and return that in aAfterFrame.
6026
  // document than aChild and return that in aAfterFrame.
6050
  if (GetGenConPseudos(aParentFrame) ||
6027
  if (aParentFrame->GetGenConPseudos() ||
6051
      nsLayoutUtils::HasPseudoStyle(aContainer, aParentFrame->StyleContext(),
6028
      nsLayoutUtils::HasPseudoStyle(aContainer, aParentFrame->StyleContext(),
6052
                                    nsCSSPseudoElements::ePseudo_after,
6029
                                    nsCSSPseudoElements::ePseudo_after,
6053
                                    aParentFrame->PresContext()) ||
6030
                                    aParentFrame->PresContext()) ||
6054
      aFrameManager->GetDisplayContentsStyleFor(aContainer)) {
6031
      aFrameManager->GetDisplayContentsStyleFor(aContainer)) {
6055
    nsIFrame* afterFrame = nullptr;
6032
    nsIFrame* afterFrame = nullptr;
6056
    nsContainerFrame* parent =
6033
    nsContainerFrame* parent =
6057
      static_cast<nsContainerFrame*>(aParentFrame->LastContinuation());
6034
      static_cast<nsContainerFrame*>(aParentFrame->LastContinuation());
6058
    bool done = false;
6035
    bool done = false;
 Lines 7918-7934   nsCSSFrameConstructor::ContentRemoved(ns Link Here 
7918
    nsIContent* ancestor = aContainer;
7895
    nsIContent* ancestor = aContainer;
7919
    for (; ancestor; ancestor = ancestor->GetParent()) {
7896
    for (; ancestor; ancestor = ancestor->GetParent()) {
7920
      ancestorFrame = ancestor->GetPrimaryFrame();
7897
      ancestorFrame = ancestor->GetPrimaryFrame();
7921
      if (ancestorFrame) {
7898
      if (ancestorFrame) {
7922
        break;
7899
        break;
7923
      }
7900
      }
7924
    }
7901
    }
7925
    if (ancestorFrame) {
7902
    if (ancestorFrame) {
7926
      nsTArray<nsIContent*>* generated = GetGenConPseudos(ancestorFrame);
7903
      nsTArray<nsIContent*>* generated = ancestorFrame->GetGenConPseudos();
7927
      if (generated) {
7904
      if (generated) {
7928
        LAYOUT_PHASE_TEMP_EXIT();
7905
        LAYOUT_PHASE_TEMP_EXIT();
7929
        // XXXmats Can we recreate frames only for the ::after/::before content?
7906
        // XXXmats Can we recreate frames only for the ::after/::before content?
7930
        // XXX Perhaps even only those that belong to the aChild sub-tree?
7907
        // XXX Perhaps even only those that belong to the aChild sub-tree?
7931
        RecreateFramesForContent(ancestor, false);
7908
        RecreateFramesForContent(ancestor, false);
7932
        LAYOUT_PHASE_TEMP_REENTER();
7909
        LAYOUT_PHASE_TEMP_REENTER();
7933
        *aDidReconstruct = true;
7910
        *aDidReconstruct = true;
7934
        return NS_OK;
7911
        return NS_OK;
 Lines 8863-8907   nsCSSFrameConstructor::CaptureStateForFr Link Here 
8863
8840
8864
static bool EqualURIs(mozilla::css::URLValue *aURI1,
8841
static bool EqualURIs(mozilla::css::URLValue *aURI1,
8865
                      mozilla::css::URLValue *aURI2)
8842
                      mozilla::css::URLValue *aURI2)
8866
{
8843
{
8867
  return aURI1 == aURI2 ||    // handle null==null, and optimize
8844
  return aURI1 == aURI2 ||    // handle null==null, and optimize
8868
         (aURI1 && aURI2 && aURI1->URIEquals(*aURI2));
8845
         (aURI1 && aURI2 && aURI1->URIEquals(*aURI2));
8869
}
8846
}
8870
8847
8871
nsresult
8848
nsStyleContext*
8872
nsCSSFrameConstructor::MaybeRecreateFramesForElement(Element* aElement)
8849
nsCSSFrameConstructor::MaybeRecreateFramesForElement(Element* aElement)
8873
{
8850
{
8874
  nsRefPtr<nsStyleContext> oldContext = GetUndisplayedContent(aElement);
8851
  nsRefPtr<nsStyleContext> oldContext = GetUndisplayedContent(aElement);
8852
  uint8_t oldDisplay = NS_STYLE_DISPLAY_NONE;
8875
  if (!oldContext) {
8853
  if (!oldContext) {
8876
    return NS_OK;
8854
    oldContext = GetDisplayContentsStyleFor(aElement);
8855
    if (!oldContext) {
8856
      return nullptr;
8857
    }
8858
    oldDisplay = NS_STYLE_DISPLAY_CONTENTS;
8877
  }
8859
  }
8878
8860
8879
  // The parent has a frame, so try resolving a new context.
8861
  // The parent has a frame, so try resolving a new context.
8880
  nsRefPtr<nsStyleContext> newContext = mPresShell->StyleSet()->
8862
  nsRefPtr<nsStyleContext> newContext = mPresShell->StyleSet()->
8881
    ResolveStyleFor(aElement, oldContext->GetParent());
8863
    ResolveStyleFor(aElement, oldContext->GetParent());
8882
8864
8883
  ChangeUndisplayedContent(aElement, newContext);
8865
  if (oldDisplay == NS_STYLE_DISPLAY_NONE) {
8866
    ChangeUndisplayedContent(aElement, newContext);
8867
  } else {
8868
    ChangeDisplayContents(aElement, newContext);
8869
  }
8870
8884
  const nsStyleDisplay* disp = newContext->StyleDisplay();
8871
  const nsStyleDisplay* disp = newContext->StyleDisplay();
8885
  if (disp->mDisplay == NS_STYLE_DISPLAY_NONE) {
8872
  if (oldDisplay == disp->mDisplay) {
8886
    // We can skip trying to recreate frames here, but only if our style
8873
    // We can skip trying to recreate frames here, but only if our style
8887
    // context does not have a binding URI that differs from our old one.
8874
    // context does not have a binding URI that differs from our old one.
8888
    // Otherwise, we should try to recreate, because we may want to apply the
8875
    // Otherwise, we should try to recreate, because we may want to apply the
8889
    // new binding
8876
    // new binding
8890
    if (!disp->mBinding) {
8877
    if (!disp->mBinding) {
8891
      return NS_OK;
8878
      return newContext;
8892
    }
8879
    }
8893
    const nsStyleDisplay* oldDisp = oldContext->PeekStyleDisplay();
8880
    const nsStyleDisplay* oldDisp = oldContext->PeekStyleDisplay();
8894
    if (oldDisp && EqualURIs(disp->mBinding, oldDisp->mBinding)) {
8881
    if (oldDisp && EqualURIs(disp->mBinding, oldDisp->mBinding)) {
8895
      return NS_OK;
8882
      return newContext;
8896
    }
8883
    }
8897
  }
8884
  }
8898
8885
8899
  return RecreateFramesForContent(aElement, false);
8886
  RecreateFramesForContent(aElement, false);
8887
  return nullptr;
8900
}
8888
}
8901
8889
8902
static nsIFrame*
8890
static nsIFrame*
8903
FindFirstNonWhitespaceChild(nsIFrame* aParentFrame)
8891
FindFirstNonWhitespaceChild(nsIFrame* aParentFrame)
8904
{
8892
{
8905
  nsIFrame* f = aParentFrame->GetFirstPrincipalChild();
8893
  nsIFrame* f = aParentFrame->GetFirstPrincipalChild();
8906
  while (f && f->GetType() == nsGkAtoms::textFrame &&
8894
  while (f && f->GetType() == nsGkAtoms::textFrame &&
8907
         f->GetContent()->TextIsOnlyWhitespace()) {
8895
         f->GetContent()->TextIsOnlyWhitespace()) {
(-)a/layout/base/nsCSSFrameConstructor.h (-1 / +8 lines)
Line     Link Here 
 Lines 1503-1519   private: Link Here 
1503
                        nsContainerFrame*        aScrolledFrame,
1503
                        nsContainerFrame*        aScrolledFrame,
1504
                        nsIContent*              aContent,
1504
                        nsIContent*              aContent,
1505
                        nsContainerFrame*        aParentFrame,
1505
                        nsContainerFrame*        aParentFrame,
1506
                        nsStyleContext*          aStyleContext,
1506
                        nsStyleContext*          aStyleContext,
1507
                        bool                     aBuildCombobox,
1507
                        bool                     aBuildCombobox,
1508
                        PendingBinding*          aPendingBinding,
1508
                        PendingBinding*          aPendingBinding,
1509
                        nsFrameItems&            aFrameItems);
1509
                        nsFrameItems&            aFrameItems);
1510
1510
1511
  nsresult MaybeRecreateFramesForElement(Element* aElement);
1511
  /**
1512
   * ReResolve style for aElement then recreate frames if required.
1513
   * Do nothing for other types of style changes, except for undisplayed nodes
1514
   * (display:none/contents) which will have their style context updated in the
1515
   * frame manager undisplayed maps.
1516
   * @return null if frames were recreated, the new style context otherwise
1517
   */
1518
  nsStyleContext* MaybeRecreateFramesForElement(Element* aElement);
1512
1519
1513
  // If aAsyncInsert is true then a restyle event will be posted to handle the
1520
  // If aAsyncInsert is true then a restyle event will be posted to handle the
1514
  // required ContentInserted call instead of doing it immediately.
1521
  // required ContentInserted call instead of doing it immediately.
1515
  nsresult RecreateFramesForContent(nsIContent* aContent, bool aAsyncInsert);
1522
  nsresult RecreateFramesForContent(nsIContent* aContent, bool aAsyncInsert);
1516
1523
1517
  // If removal of aFrame from the frame tree requires reconstruction of some
1524
  // If removal of aFrame from the frame tree requires reconstruction of some
1518
  // containing block (either of aFrame or of its parent) due to {ib} splits or
1525
  // containing block (either of aFrame or of its parent) due to {ib} splits or
1519
  // table pseudo-frames, recreate the relevant frame subtree.  The return value
1526
  // table pseudo-frames, recreate the relevant frame subtree.  The return value
(-)a/layout/base/nsLayoutUtils.cpp (-96 / +64 lines)
Line     Link Here 
 Lines 1011-1093   nsLayoutUtils::LastContinuationWithChild Link Here 
1011
  NS_PRECONDITION(aFrame, "NULL frame pointer");
1011
  NS_PRECONDITION(aFrame, "NULL frame pointer");
1012
  nsIFrame* f = aFrame->LastContinuation();
1012
  nsIFrame* f = aFrame->LastContinuation();
1013
  while (!f->GetFirstPrincipalChild() && f->GetPrevContinuation()) {
1013
  while (!f->GetFirstPrincipalChild() && f->GetPrevContinuation()) {
1014
    f = f->GetPrevContinuation();
1014
    f = f->GetPrevContinuation();
1015
  }
1015
  }
1016
  return static_cast<nsContainerFrame*>(f);
1016
  return static_cast<nsContainerFrame*>(f);
1017
}
1017
}
1018
1018
1019
/**
1020
 * GetFirstChildFrame returns the first "real" child frame of a
1021
 * given frame.  It will descend down into pseudo-frames (unless the
1022
 * pseudo-frame is the :before generated frame).
1023
 * @param aFrame the frame
1024
 * @param aFrame the frame's content node
1025
 */
1026
static nsIFrame*
1027
GetFirstChildFrame(nsIFrame*       aFrame,
1028
                   nsIContent*     aContent)
1029
{
1030
  NS_PRECONDITION(aFrame, "NULL frame pointer");
1031
1032
  // Get the first child frame
1033
  nsIFrame* childFrame = aFrame->GetFirstPrincipalChild();
1034
1035
  // If the child frame is a pseudo-frame, then return its first child.
1036
  // Note that the frame we create for the generated content is also a
1037
  // pseudo-frame and so don't drill down in that case
1038
  if (childFrame &&
1039
      childFrame->IsPseudoFrame(aContent) &&
1040
      !childFrame->IsGeneratedContentFrame()) {
1041
    return GetFirstChildFrame(childFrame, aContent);
1042
  }
1043
1044
  return childFrame;
1045
}
1046
1047
/**
1048
 * GetLastChildFrame returns the last "real" child frame of a
1049
 * given frame.  It will descend down into pseudo-frames (unless the
1050
 * pseudo-frame is the :after generated frame).
1051
 * @param aFrame the frame
1052
 * @param aFrame the frame's content node
1053
 */
1054
static nsIFrame*
1055
GetLastChildFrame(nsContainerFrame* aFrame,
1056
                  nsIContent*       aContent)
1057
{
1058
  NS_PRECONDITION(aFrame, "NULL frame pointer");
1059
1060
  // Get the last continuation frame that's a parent
1061
  nsContainerFrame* lastParentContinuation =
1062
    nsLayoutUtils::LastContinuationWithChild(aFrame);
1063
  nsIFrame* lastChildFrame =
1064
    lastParentContinuation->GetLastChild(nsIFrame::kPrincipalList);
1065
  if (lastChildFrame) {
1066
    // Get the frame's first continuation. This matters in case the frame has
1067
    // been continued across multiple lines or split by BiDi resolution.
1068
    lastChildFrame = lastChildFrame->FirstContinuation();
1069
1070
    // If the last child frame is a pseudo-frame, then return its last child.
1071
    // Note that the frame we create for the generated content is also a
1072
    // pseudo-frame and so don't drill down in that case
1073
    if (lastChildFrame &&
1074
        lastChildFrame->IsPseudoFrame(aContent) &&
1075
        !lastChildFrame->IsGeneratedContentFrame()) {
1076
      return GetLastChildFrame(static_cast<nsContainerFrame*>(lastChildFrame),
1077
                               aContent);
1078
    }
1079
1080
    return lastChildFrame;
1081
  }
1082
1083
  return nullptr;
1084
}
1085
1086
//static
1019
//static
1087
FrameChildListID
1020
FrameChildListID
1088
nsLayoutUtils::GetChildListNameFor(nsIFrame* aChildFrame)
1021
nsLayoutUtils::GetChildListNameFor(nsIFrame* aChildFrame)
1089
{
1022
{
1090
  nsIFrame::ChildListID id = nsIFrame::kPrincipalList;
1023
  nsIFrame::ChildListID id = nsIFrame::kPrincipalList;
1091
1024
1092
  if (aChildFrame->GetStateBits() & NS_FRAME_IS_OVERFLOW_CONTAINER) {
1025
  if (aChildFrame->GetStateBits() & NS_FRAME_IS_OVERFLOW_CONTAINER) {
1093
    nsIFrame* pif = aChildFrame->GetPrevInFlow();
1026
    nsIFrame* pif = aChildFrame->GetPrevInFlow();
 Lines 1176-1229   nsLayoutUtils::GetChildListNameFor(nsIFr Link Here 
1176
    // else it's positioned and should have been on the 'id' child list.
1109
    // else it's positioned and should have been on the 'id' child list.
1177
    NS_POSTCONDITION(found, "not in child list");
1110
    NS_POSTCONDITION(found, "not in child list");
1178
  }
1111
  }
1179
#endif
1112
#endif
1180
1113
1181
  return id;
1114
  return id;
1182
}
1115
}
1183
1116
1184
// static
1117
/*static*/ nsIFrame*
1185
nsIFrame*
1118
nsLayoutUtils::GetBeforeFrameForContent(nsIFrame* aFrame,
1119
                                        nsIContent* aContent)
1120
{
1121
  nsContainerFrame* genConParentFrame = aFrame->GetContentInsertionFrame();
1122
  if (!genConParentFrame) {
1123
    return nullptr;
1124
  }
1125
  nsTArray<nsIContent*>* prop = genConParentFrame->GetGenConPseudos();
1126
  if (prop) {
1127
    const nsTArray<nsIContent*>& pseudos(*prop);
1128
    for (uint32_t i = 0; i < pseudos.Length(); ++i) {
1129
      if (pseudos[i]->GetParent() == aContent &&
1130
          pseudos[i]->Tag() == nsGkAtoms::mozgeneratedcontentbefore) {
1131
        return pseudos[i]->GetPrimaryFrame();
1132
      }
1133
    }
1134
  }
1135
  // If the first child frame is a pseudo-frame, then try that.
1136
  // Note that the frame we create for the generated content is also a
1137
  // pseudo-frame and so don't drill down in that case.
1138
  nsIFrame* childFrame = genConParentFrame->GetFirstPrincipalChild();
1139
  if (childFrame &&
1140
      childFrame->IsPseudoFrame(aContent) &&
1141
      !childFrame->IsGeneratedContentFrame()) {
1142
    return GetBeforeFrameForContent(childFrame, aContent);
1143
  }
1144
  return nullptr;
1145
}
1146
1147
/*static*/ nsIFrame*
1186
nsLayoutUtils::GetBeforeFrame(nsIFrame* aFrame)
1148
nsLayoutUtils::GetBeforeFrame(nsIFrame* aFrame)
1187
{
1149
{
1188
  NS_PRECONDITION(aFrame, "NULL frame pointer");
1150
  return GetBeforeFrameForContent(aFrame, aFrame->GetContent());
1189
  NS_ASSERTION(!aFrame->GetPrevContinuation(),
1151
}
1190
               "aFrame must be first continuation");
1152
1191
1153
/*static*/ nsIFrame*
1192
  nsIFrame* cif = aFrame->GetContentInsertionFrame();
1154
nsLayoutUtils::GetAfterFrameForContent(nsIFrame* aFrame,
1193
  if (!cif) {
1155
                                       nsIContent* aContent)
1156
{
1157
  nsContainerFrame* genConParentFrame = aFrame->GetContentInsertionFrame();
1158
  if (!genConParentFrame) {
1194
    return nullptr;
1159
    return nullptr;
1195
  }
1160
  }
1196
  nsIFrame* firstFrame = GetFirstChildFrame(cif, aFrame->GetContent());
1161
  nsTArray<nsIContent*>* prop = genConParentFrame->GetGenConPseudos();
1197
  if (firstFrame && IsGeneratedContentFor(nullptr, firstFrame,
1162
  if (prop) {
1198
                                          nsCSSPseudoElements::before)) {
1163
    const nsTArray<nsIContent*>& pseudos(*prop);
1199
    return firstFrame;
1164
    for (uint32_t i = 0; i < pseudos.Length(); ++i) {
1200
  }
1165
      if (pseudos[i]->GetParent() == aContent &&
1201
1166
          pseudos[i]->Tag() == nsGkAtoms::mozgeneratedcontentafter) {
1167
        return pseudos[i]->GetPrimaryFrame();
1168
      }
1169
    }
1170
  }
1171
  // If the last child frame is a pseudo-frame, then try that.
1172
  // Note that the frame we create for the generated content is also a
1173
  // pseudo-frame and so don't drill down in that case.
1174
  nsIFrame* lastParentContinuation =
1175
    nsLayoutUtils::LastContinuationWithChild(genConParentFrame);
1176
  nsIFrame* childFrame =
1177
    lastParentContinuation->GetLastChild(nsIFrame::kPrincipalList);
1178
  if (childFrame &&
1179
      childFrame->IsPseudoFrame(aContent) &&
1180
      !childFrame->IsGeneratedContentFrame()) {
1181
    return GetAfterFrameForContent(childFrame->FirstContinuation(), aContent);
1182
  }
1202
  return nullptr;
1183
  return nullptr;
1203
}
1184
}
1204
1185
1205
// static
1186
/*static*/ nsIFrame*
1206
nsIFrame*
1207
nsLayoutUtils::GetAfterFrame(nsIFrame* aFrame)
1187
nsLayoutUtils::GetAfterFrame(nsIFrame* aFrame)
1208
{
1188
{
1209
  NS_PRECONDITION(aFrame, "NULL frame pointer");
1189
  return GetAfterFrameForContent(aFrame, aFrame->GetContent());
1210
1211
  nsContainerFrame* cif = aFrame->GetContentInsertionFrame();
1212
  if (!cif) {
1213
    return nullptr;
1214
  }
1215
  nsIFrame* lastFrame = GetLastChildFrame(cif, aFrame->GetContent());
1216
  if (lastFrame && IsGeneratedContentFor(nullptr, lastFrame,
1217
                                         nsCSSPseudoElements::after)) {
1218
    return lastFrame;
1219
  }
1220
1221
  return nullptr;
1222
}
1190
}
1223
1191
1224
// static
1192
// static
1225
nsIFrame*
1193
nsIFrame*
1226
nsLayoutUtils::GetClosestFrameOfType(nsIFrame* aFrame, nsIAtom* aFrameType)
1194
nsLayoutUtils::GetClosestFrameOfType(nsIFrame* aFrame, nsIAtom* aFrameType)
1227
{
1195
{
1228
  for (nsIFrame* frame = aFrame; frame; frame = frame->GetParent()) {
1196
  for (nsIFrame* frame = aFrame; frame; frame = frame->GetParent()) {
1229
    if (frame->GetType() == aFrameType) {
1197
    if (frame->GetType() == aFrameType) {
(-)a/layout/base/nsLayoutUtils.h (-4 / +29 lines)
Line     Link Here 
 Lines 202-233   public: Link Here 
202
202
203
  /**
203
  /**
204
   * Use heuristics to figure out the child list that
204
   * Use heuristics to figure out the child list that
205
   * aChildFrame is currently in.
205
   * aChildFrame is currently in.
206
   */
206
   */
207
  static mozilla::layout::FrameChildListID GetChildListNameFor(nsIFrame* aChildFrame);
207
  static mozilla::layout::FrameChildListID GetChildListNameFor(nsIFrame* aChildFrame);
208
208
209
  /**
209
  /**
210
   * GetBeforeFrame returns the outermost :before frame of the given frame, if
210
   * GetBeforeFrameForContent returns the ::before frame for aContent, if
211
   * one exists.  This is typically O(1).  The frame passed in must be
211
   * one exists.  This is typically O(1).  The frame passed in must be
212
   * the first-in-flow.
212
   * the first-in-flow.
213
   *
213
   *
214
   * @param aFrame the frame whose :before is wanted
214
   * @param aGenConParentFrame an ancestor of the ::before frame
215
   * @param aContent the content whose ::before is wanted
216
   * @return the ::before frame or nullptr if there isn't one
217
   */
218
  static nsIFrame* GetBeforeFrameForContent(nsIFrame* aGenConParentFrame,
219
                                            nsIContent* aContent);
220
221
  /**
222
   * GetBeforeFrame returns the outermost ::before frame of the given frame, if
223
   * one exists.  This is typically O(1).  The frame passed in must be
224
   * the first-in-flow.
225
   *
226
   * @param aFrame the frame whose ::before is wanted
215
   * @return the :before frame or nullptr if there isn't one
227
   * @return the :before frame or nullptr if there isn't one
216
   */
228
   */
217
  static nsIFrame* GetBeforeFrame(nsIFrame* aFrame);
229
  static nsIFrame* GetBeforeFrame(nsIFrame* aFrame);
218
230
219
  /**
231
  /**
220
   * GetAfterFrame returns the outermost :after frame of the given frame, if one
232
   * GetAfterFrameForContent returns the ::after frame for aContent, if one
233
   * exists.  This will walk the in-flow chain of aGenConParentFrame to the
234
   * last-in-flow if needed.  This function is typically O(N) in the number
235
   * of child frames, following in-flows, etc.
236
   *
237
   * @param aGenConParentFrame an ancestor of the ::after frame
238
   * @param aContent the content whose ::after is wanted
239
   * @return the ::after frame or nullptr if there isn't one
240
   */
241
  static nsIFrame* GetAfterFrameForContent(nsIFrame* aGenConParentFrame,
242
                                           nsIContent* aContent);
243
244
  /**
245
   * GetAfterFrame returns the outermost ::after frame of the given frame, if one
221
   * exists.  This will walk the in-flow chain to the last-in-flow if
246
   * exists.  This will walk the in-flow chain to the last-in-flow if
222
   * needed.  This function is typically O(N) in the number of child
247
   * needed.  This function is typically O(N) in the number of child
223
   * frames, following in-flows, etc.
248
   * frames, following in-flows, etc.
224
   *
249
   *
225
   * @param aFrame the frame whose :after is wanted
250
   * @param aFrame the frame whose ::after is wanted
226
   * @return the :after frame or nullptr if there isn't one
251
   * @return the :after frame or nullptr if there isn't one
227
   */
252
   */
228
  static nsIFrame* GetAfterFrame(nsIFrame* aFrame);
253
  static nsIFrame* GetAfterFrame(nsIFrame* aFrame);
229
254
230
  /**
255
  /**
231
   * Given a frame, search up the frame tree until we find an
256
   * Given a frame, search up the frame tree until we find an
232
   * ancestor that (or the frame itself) is of type aFrameType, if any.
257
   * ancestor that (or the frame itself) is of type aFrameType, if any.
233
   *
258
   *
(-)a/layout/generic/nsFrame.cpp (+13 lines)
Line     Link Here 
 Lines 8609-8624   nsIFrame::DestroyDT(void* aPropertyValue Link Here 
8609
}
8609
}
8610
8610
8611
void
8611
void
8612
nsIFrame::DestroyRegion(void* aPropertyValue)
8612
nsIFrame::DestroyRegion(void* aPropertyValue)
8613
{
8613
{
8614
  delete static_cast<nsRegion*>(aPropertyValue);
8614
  delete static_cast<nsRegion*>(aPropertyValue);
8615
}
8615
}
8616
8616
8617
/*static*/ void
8618
nsIFrame::DestroyContentArray(void* aPropertyValue)
8619
{
8620
  typedef nsTArray<nsIContent*> T;
8621
  T* arr = static_cast<T*>(aPropertyValue);
8622
  for (T::size_type i = 0; i < arr->Length(); ++i) {
8623
    nsIContent* content = (*arr)[i];
8624
    content->UnbindFromTree();
8625
    NS_RELEASE(content);
8626
  }
8627
  delete arr;
8628
}
8629
8617
bool
8630
bool
8618
nsIFrame::IsPseudoStackingContextFromStyle() {
8631
nsIFrame::IsPseudoStackingContextFromStyle() {
8619
  const nsStyleDisplay* disp = StyleDisplay();
8632
  const nsStyleDisplay* disp = StyleDisplay();
8620
  // If you change this, also change the computation of pseudoStackingContext
8633
  // If you change this, also change the computation of pseudoStackingContext
8621
  // in BuildDisplayListForChild()
8634
  // in BuildDisplayListForChild()
8622
  return disp->mOpacity != 1.0f ||
8635
  return disp->mOpacity != 1.0f ||
8623
         disp->IsPositioned(this) ||
8636
         disp->IsPositioned(this) ||
8624
         disp->IsFloating(this) ||
8637
         disp->IsFloating(this) ||
(-)a/layout/generic/nsIFrame.h (+8 lines)
Line     Link Here 
 Lines 780-795   public: Link Here 
780
780
781
  static void DestroyOverflowAreas(void* aPropertyValue)
781
  static void DestroyOverflowAreas(void* aPropertyValue)
782
  {
782
  {
783
    delete static_cast<nsOverflowAreas*>(aPropertyValue);
783
    delete static_cast<nsOverflowAreas*>(aPropertyValue);
784
  }
784
  }
785
785
786
  static void DestroySurface(void* aPropertyValue);
786
  static void DestroySurface(void* aPropertyValue);
787
  static void DestroyDT(void* aPropertyValue);
787
  static void DestroyDT(void* aPropertyValue);
788
  static void DestroyContentArray(void* aPropertyValue);
788
789
789
#ifdef _MSC_VER
790
#ifdef _MSC_VER
790
// XXX Workaround MSVC issue by making the static FramePropertyDescriptor
791
// XXX Workaround MSVC issue by making the static FramePropertyDescriptor
791
// non-const.  See bug 555727.
792
// non-const.  See bug 555727.
792
#define NS_PROPERTY_DESCRIPTOR_CONST
793
#define NS_PROPERTY_DESCRIPTOR_CONST
793
#else
794
#else
794
#define NS_PROPERTY_DESCRIPTOR_CONST const
795
#define NS_PROPERTY_DESCRIPTOR_CONST const
795
#endif
796
#endif
 Lines 839-854   public: Link Here 
839
840
840
  NS_DECLARE_FRAME_PROPERTY(CachedBackgroundImage, DestroySurface)
841
  NS_DECLARE_FRAME_PROPERTY(CachedBackgroundImage, DestroySurface)
841
  NS_DECLARE_FRAME_PROPERTY(CachedBackgroundImageDT, DestroyDT)
842
  NS_DECLARE_FRAME_PROPERTY(CachedBackgroundImageDT, DestroyDT)
842
843
843
  NS_DECLARE_FRAME_PROPERTY(InvalidationRect, DestroyRect)
844
  NS_DECLARE_FRAME_PROPERTY(InvalidationRect, DestroyRect)
844
845
845
  NS_DECLARE_FRAME_PROPERTY(RefusedAsyncAnimation, nullptr)
846
  NS_DECLARE_FRAME_PROPERTY(RefusedAsyncAnimation, nullptr)
846
847
848
  NS_DECLARE_FRAME_PROPERTY(GenConProperty, DestroyContentArray)
849
850
  nsTArray<nsIContent*>* GetGenConPseudos() {
851
    const FramePropertyDescriptor* prop = GenConProperty();
852
    return static_cast<nsTArray<nsIContent*>*>(Properties().Get(prop));
853
  }
854
847
  /**
855
  /**
848
   * Return the distance between the border edge of the frame and the
856
   * Return the distance between the border edge of the frame and the
849
   * margin edge of the frame.  Like GetRect(), returns the dimensions
857
   * margin edge of the frame.  Like GetRect(), returns the dimensions
850
   * as of the most recent reflow.
858
   * as of the most recent reflow.
851
   *
859
   *
852
   * This doesn't include any margin collapsing that may have occurred.
860
   * This doesn't include any margin collapsing that may have occurred.
853
   *
861
   *
854
   * It also treats 'auto' margins as zero, and treats any margins that
862
   * It also treats 'auto' margins as zero, and treats any margins that

Return to bug 907396