зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1338921 - Handle lazy frame construction in the regular post-servo pass. r=emilio
MozReview-Commit-ID: FSXKAiyZDzt
This commit is contained in:
Родитель
c589f558a4
Коммит
fa5229bbea
|
@ -1404,13 +1404,12 @@ RestyleManager::ProcessRestyledFrames(nsStyleChangeList& aChangeList)
|
|||
{
|
||||
MOZ_ASSERT(aChangeList[i].mHint & nsChangeHint_ReconstructFrame);
|
||||
MOZ_ASSERT(!aChangeList[i].mFrame);
|
||||
MOZ_ASSERT(!aChangeList[i].mContent->GetPrimaryFrame());
|
||||
++i;
|
||||
}
|
||||
if (i != lazyRangeStart) {
|
||||
nsIContent* start = aChangeList[lazyRangeStart].mContent;
|
||||
nsIContent* end = aChangeList[i-1].mContent->GetNextSibling();
|
||||
nsIContent* container = start->GetFlattenedTreeParent();
|
||||
nsIContent* container = start->GetParent();
|
||||
MOZ_ASSERT(container);
|
||||
if (!end) {
|
||||
frameConstructor->ContentAppended(container, start, false);
|
||||
|
|
|
@ -127,23 +127,36 @@ ClearRestyleStateFromSubtree(Element* aElement)
|
|||
|
||||
Unused << Servo_TakeChangeHint(aElement);
|
||||
aElement->UnsetHasDirtyDescendantsForServo();
|
||||
aElement->UnsetFlags(NODE_DESCENDANTS_NEED_FRAMES);
|
||||
}
|
||||
|
||||
void
|
||||
ServoRestyleManager::RecreateStyleContexts(Element* aElement,
|
||||
nsStyleContext* aParentContext,
|
||||
ServoStyleSet* aStyleSet,
|
||||
nsStyleChangeList& aChangeListToProcess)
|
||||
ServoRestyleManager::ProcessPostTraversal(Element* aElement,
|
||||
nsStyleContext* aParentContext,
|
||||
ServoStyleSet* aStyleSet,
|
||||
nsStyleChangeList& aChangeList)
|
||||
{
|
||||
nsIFrame* styleFrame = nsLayoutUtils::GetStyleFrame(aElement);
|
||||
|
||||
// Grab the change hint from Servo.
|
||||
nsChangeHint changeHint = Servo_TakeChangeHint(aElement);
|
||||
|
||||
// Handle lazy frame construction by posting a reconstruct for any lazily-
|
||||
// constructed roots.
|
||||
if (aElement->HasFlag(NODE_NEEDS_FRAME)) {
|
||||
changeHint |= nsChangeHint_ReconstructFrame;
|
||||
// The only time the primary frame is non-null is when image maps do hacky
|
||||
// SetPrimaryFrame calls.
|
||||
MOZ_ASSERT_IF(styleFrame, styleFrame->GetType() == nsGkAtoms::imageFrame);
|
||||
styleFrame = nullptr;
|
||||
}
|
||||
|
||||
// Although we shouldn't generate non-ReconstructFrame hints for elements with
|
||||
// no frames, we can still get them here if they were explicitly posted by
|
||||
// PostRestyleEvent, such as a RepaintFrame hint when a :link changes to be
|
||||
// :visited. Skip processing these hints if there is no frame.
|
||||
if ((styleFrame || (changeHint & nsChangeHint_ReconstructFrame)) && changeHint) {
|
||||
aChangeListToProcess.AppendChange(styleFrame, aElement, changeHint);
|
||||
aChangeList.AppendChange(styleFrame, aElement, changeHint);
|
||||
}
|
||||
|
||||
// If our change hint is reconstruct, we delegate to the frame constructor,
|
||||
|
@ -219,8 +232,7 @@ ServoRestyleManager::RecreateStyleContexts(Element* aElement,
|
|||
}
|
||||
|
||||
if (styleFrame) {
|
||||
styleFrame->UpdateStyleOfOwnedAnonBoxes(*aStyleSet, aChangeListToProcess,
|
||||
changeHint);
|
||||
styleFrame->UpdateStyleOfOwnedAnonBoxes(*aStyleSet, aChangeList, changeHint);
|
||||
}
|
||||
|
||||
// Update pseudo-elements state if appropriate.
|
||||
|
@ -258,8 +270,10 @@ ServoRestyleManager::RecreateStyleContexts(Element* aElement,
|
|||
}
|
||||
}
|
||||
|
||||
bool traverseElementChildren = aElement->HasDirtyDescendantsForServo();
|
||||
bool traverseTextChildren = recreateContext;
|
||||
bool descendantsNeedFrames = aElement->HasFlag(NODE_DESCENDANTS_NEED_FRAMES);
|
||||
bool traverseElementChildren =
|
||||
aElement->HasDirtyDescendantsForServo() || descendantsNeedFrames;
|
||||
bool traverseTextChildren = recreateContext || descendantsNeedFrames;
|
||||
if (traverseElementChildren || traverseTextChildren) {
|
||||
nsStyleContext* upToDateContext =
|
||||
recreateContext ? newContext : oldStyleContext;
|
||||
|
@ -267,22 +281,31 @@ ServoRestyleManager::RecreateStyleContexts(Element* aElement,
|
|||
StyleChildrenIterator it(aElement);
|
||||
for (nsIContent* n = it.GetNextChild(); n; n = it.GetNextChild()) {
|
||||
if (traverseElementChildren && n->IsElement()) {
|
||||
RecreateStyleContexts(n->AsElement(), upToDateContext,
|
||||
aStyleSet, aChangeListToProcess);
|
||||
ProcessPostTraversal(n->AsElement(), upToDateContext,
|
||||
aStyleSet, aChangeList);
|
||||
} else if (traverseTextChildren && n->IsNodeOfType(nsINode::eTEXT)) {
|
||||
RecreateStyleContextsForText(n, upToDateContext, aStyleSet);
|
||||
ProcessPostTraversalForText(n, upToDateContext, aStyleSet, aChangeList);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
aElement->UnsetHasDirtyDescendantsForServo();
|
||||
aElement->UnsetFlags(NODE_DESCENDANTS_NEED_FRAMES);
|
||||
}
|
||||
|
||||
void
|
||||
ServoRestyleManager::RecreateStyleContextsForText(nsIContent* aTextNode,
|
||||
nsStyleContext* aParentContext,
|
||||
ServoStyleSet* aStyleSet)
|
||||
ServoRestyleManager::ProcessPostTraversalForText(nsIContent* aTextNode,
|
||||
nsStyleContext* aParentContext,
|
||||
ServoStyleSet* aStyleSet,
|
||||
nsStyleChangeList& aChangeList)
|
||||
{
|
||||
// Handle lazy frame construction.
|
||||
if (aTextNode->HasFlag(NODE_NEEDS_FRAME)) {
|
||||
aChangeList.AppendChange(nullptr, aTextNode, nsChangeHint_ReconstructFrame);
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle restyle.
|
||||
nsIFrame* primaryFrame = aTextNode->GetPrimaryFrame();
|
||||
if (primaryFrame) {
|
||||
RefPtr<nsStyleContext> oldStyleContext = primaryFrame->StyleContext();
|
||||
|
@ -360,24 +383,14 @@ ServoRestyleManager::ProcessPendingRestyles()
|
|||
// uninstalling XBL bindings) can trigger additional style validations.
|
||||
mInStyleRefresh = true;
|
||||
while (styleSet->StyleDocument()) {
|
||||
|
||||
PresContext()->EffectCompositor()->ClearElementsToRestyle();
|
||||
|
||||
// First do any queued-up frame creation. (see bugs 827239 and 997506).
|
||||
//
|
||||
// XXXEmilio I'm calling this to avoid random behavior changes, since we
|
||||
// delay frame construction after styling we should re-check once our
|
||||
// model is more stable whether we can skip this call.
|
||||
//
|
||||
// Note this has to be *after* restyling, because otherwise frame
|
||||
// construction will find unstyled nodes, and that's not funny.
|
||||
PresContext()->FrameConstructor()->CreateNeededFrames();
|
||||
|
||||
// Recreate style contexts and queue up change hints.
|
||||
// Recreate style contexts, and queue up change hints (which also handle
|
||||
// lazy frame construction).
|
||||
nsStyleChangeList currentChanges;
|
||||
DocumentStyleRootIterator iter(doc);
|
||||
while (Element* root = iter.GetNextStyleRoot()) {
|
||||
RecreateStyleContexts(root, nullptr, styleSet, currentChanges);
|
||||
ProcessPostTraversal(root, nullptr, styleSet, currentChanges);
|
||||
}
|
||||
|
||||
// Process the change hints.
|
||||
|
|
|
@ -100,17 +100,17 @@ protected:
|
|||
|
||||
private:
|
||||
/**
|
||||
* Traverses a tree of content that Servo has just restyled, recreating style
|
||||
* contexts for their frames with the new style data.
|
||||
* Performs post-Servo-traversal processing on this element and its descendants.
|
||||
*/
|
||||
void RecreateStyleContexts(Element* aElement,
|
||||
nsStyleContext* aParentContext,
|
||||
ServoStyleSet* aStyleSet,
|
||||
nsStyleChangeList& aChangeList);
|
||||
void ProcessPostTraversal(Element* aElement,
|
||||
nsStyleContext* aParentContext,
|
||||
ServoStyleSet* aStyleSet,
|
||||
nsStyleChangeList& aChangeList);
|
||||
|
||||
void RecreateStyleContextsForText(nsIContent* aTextNode,
|
||||
nsStyleContext* aParentContext,
|
||||
ServoStyleSet* aStyleSet);
|
||||
void ProcessPostTraversalForText(nsIContent* aTextNode,
|
||||
nsStyleContext* aParentContext,
|
||||
ServoStyleSet* aStyleSet,
|
||||
nsStyleChangeList& aChangeList);
|
||||
|
||||
inline ServoStyleSet* StyleSet() const
|
||||
{
|
||||
|
|
|
@ -29,9 +29,14 @@ nsStyleChangeList::AppendChange(nsIFrame* aFrame, nsIContent* aContent, nsChange
|
|||
// display:contents elements posts the changes for their children:
|
||||
(aFrame && aContent->GetParent() &&
|
||||
aFrame->PresContext()->FrameManager()->
|
||||
GetDisplayContentsStyleFor(aContent->GetParent())),
|
||||
GetDisplayContentsStyleFor(aContent->GetParent())) ||
|
||||
(aContent->IsNodeOfType(nsINode::eTEXT) &&
|
||||
aContent->IsStyledByServo() &&
|
||||
aContent->HasFlag(NODE_NEEDS_FRAME) &&
|
||||
aHint & nsChangeHint_ReconstructFrame),
|
||||
"Shouldn't be trying to restyle non-elements directly, "
|
||||
"except if it's a display:contents child");
|
||||
"except if it's a display:contents child or a text node "
|
||||
"doing lazy frame construction");
|
||||
MOZ_ASSERT(!(aHint & nsChangeHint_AllReflowHints) ||
|
||||
(aHint & nsChangeHint_NeedReflow),
|
||||
"Reflow hint bits set without actually asking for a reflow");
|
||||
|
|
|
@ -38,10 +38,10 @@ Any line which doesn't follow the format above would be ignored like comment.
|
|||
* test_all_shorthand.html: all shorthand servo/servo#15055 [*]
|
||||
* Animation support:
|
||||
* test_animations.html [277]
|
||||
* test_animations_async_tests.html [3]
|
||||
* test_animations_async_tests.html [2]
|
||||
* test_animations_dynamic_changes.html [1]
|
||||
* test_bug716226.html [1]
|
||||
* test_flexbox_flex_grow_and_shrink.html [16]
|
||||
* test_flexbox_flex_grow_and_shrink.html [8]
|
||||
* OMTA
|
||||
* test_animations_effect_timing_duration.html [1]
|
||||
* test_animations_effect_timing_enddelay.html [1]
|
||||
|
|
Загрузка…
Ссылка в новой задаче