コード例 #1
0
void
nsTransitionManager::UpdateAllThrottledStyles()
{
  if (PR_CLIST_IS_EMPTY(&mElementData)) {
    // no throttled transitions, leave early
    mPresContext->TickLastUpdateThrottledStyle();
    return;
  }

  if (mPresContext->ThrottledStyleIsUpToDate()) {
    // throttled transitions are up to date, leave early
    return;
  }

  mPresContext->TickLastUpdateThrottledStyle();
  TimeStamp now = mPresContext->RefreshDriver()->MostRecentRefresh();

  nsStyleChangeList changeList;

  // update each transitioning element by finding its root-most ancestor with a
  // transition, and flushing the style on that ancestor and all its descendants
  PRCList *next = PR_LIST_HEAD(&mElementData);
  while (next != &mElementData) {
    ElementTransitions* et = static_cast<ElementTransitions*>(next);
    next = PR_NEXT_LINK(next);

    if (et->mFlushGeneration == now) {
      // this element has been ticked already
      continue;
    }

    // element is initialised to the starting element (i.e., one we know has
    // a transition) and ends up with the root-most transitioning ancestor,
    // that is, the element where we begin updates.
    dom::Element* element = et->mElement;
    // make a list of ancestors
    nsTArray<dom::Element*> ancestors;
    do {
      ancestors.AppendElement(element);
    } while ((element = element->GetParentElement()));

    // walk down the ancestors until we find one with a throttled transition
    for (int32_t i = ancestors.Length() - 1; i >= 0; --i) {
      if (GetElementTransitions(ancestors[i],
                                nsCSSPseudoElements::ePseudo_NotPseudoElement,
                                false)) {
        element = ancestors[i];
        break;
      }
    }

    nsIFrame* primaryFrame;
    if (element &&
        (primaryFrame = nsLayoutUtils::GetStyleFrame(element))) {
      UpdateThrottledStylesForSubtree(element,
        primaryFrame->StyleContext()->GetParent(), changeList);
    }
  }

  RestyleManager* restyleManager = mPresContext->RestyleManager();
  restyleManager->ProcessRestyledFrames(changeList);
  restyleManager->FlushOverflowChangedTracker();
}