Bug 1321284 - Part 5: Process document level NAC when restyling. r=bholley
MozReview-Commit-ID: GigSrTHXXte
--- a/layout/base/RestyleManagerHandleInlines.h
+++ b/layout/base/RestyleManagerHandleInlines.h
@@ -4,16 +4,17 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_RestyleManagerHandleInlines_h
#define mozilla_RestyleManagerHandleInlines_h
#include "mozilla/RestyleManager.h"
#include "mozilla/ServoRestyleManager.h"
+#include "mozilla/ServoRestyleManagerInlines.h"
#define FORWARD_CONCRETE(method_, geckoargs_, servoargs_) \
if (IsGecko()) { \
return AsGecko()->method_ geckoargs_; \
} else { \
return AsServo()->method_ servoargs_; \
}
--- a/layout/base/ServoRestyleManager.cpp
+++ b/layout/base/ServoRestyleManager.cpp
@@ -1,16 +1,19 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/ServoRestyleManager.h"
+
+#include "mozilla/DocumentStyleRootIterator.h"
#include "mozilla/ServoBindings.h"
+#include "mozilla/ServoRestyleManagerInlines.h"
#include "mozilla/ServoStyleSet.h"
#include "mozilla/dom/ChildIterator.h"
#include "nsContentUtils.h"
#include "nsPrintfCString.h"
#include "nsStyleChangeList.h"
using namespace mozilla::dom;
@@ -284,37 +287,38 @@ ServoRestyleManager::ProcessPendingResty
}
if (!HasPendingRestyles()) {
return;
}
ServoStyleSet* styleSet = StyleSet();
nsIDocument* doc = PresContext()->Document();
- Element* root = doc->GetRootElement();
// XXXbholley: Should this be while() per bug 1316247?
if (HasPendingRestyles()) {
- MOZ_ASSERT(root);
mInStyleRefresh = true;
styleSet->StyleDocument();
// 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.
nsStyleChangeList currentChanges;
- RecreateStyleContexts(root, nullptr, styleSet, currentChanges);
+ DocumentStyleRootIterator iter(doc);
+ while (Element* root = iter.GetNextStyleRoot()) {
+ RecreateStyleContexts(root, nullptr, styleSet, currentChanges);
+ }
// Process the change hints.
//
// Unfortunately, the frame constructor can generate new change hints while
// processing existing ones. We redirect those into a secondary queue and
// iterate until there's nothing left.
ReentrantChangeList newChanges;
mReentrantChanges = &newChanges;
--- a/layout/base/ServoRestyleManager.h
+++ b/layout/base/ServoRestyleManager.h
@@ -2,16 +2,17 @@
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_ServoRestyleManager_h
#define mozilla_ServoRestyleManager_h
+#include "mozilla/DocumentStyleRootIterator.h"
#include "mozilla/EventStates.h"
#include "mozilla/RestyleManagerBase.h"
#include "mozilla/ServoBindings.h"
#include "mozilla/ServoElementSnapshot.h"
#include "nsChangeHint.h"
#include "nsHashKeys.h"
#include "nsINode.h"
#include "nsISupportsImpl.h"
@@ -73,21 +74,17 @@ public:
const nsAttrValue* aNewValue);
void AttributeChanged(dom::Element* aElement, int32_t aNameSpaceID,
nsIAtom* aAttribute, int32_t aModType,
const nsAttrValue* aOldValue);
nsresult ReparentStyleContext(nsIFrame* aFrame);
- bool HasPendingRestyles()
- {
- Element* root = PresContext()->Document()->GetRootElement();
- return root && root->HasDirtyDescendantsForServo();
- }
+ inline bool HasPendingRestyles();
/**
* Gets the appropriate frame given a content and a pseudo-element tag.
*
* Right now only supports a null tag, before or after. If the pseudo-element
* is not null, the content needs to be an element.
*/
new file mode 100644
--- /dev/null
+++ b/layout/base/ServoRestyleManagerInlines.h
@@ -0,0 +1,33 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef ServoRestyleManagerInlines_h
+#define ServoRestyleManagerInlines_h
+
+#include "ServoRestyleManager.h"
+
+#include "mozilla/dom/ElementInlines.h"
+
+namespace mozilla {
+
+using namespace dom;
+
+inline bool
+ServoRestyleManager::HasPendingRestyles()
+{
+ nsIDocument* doc = PresContext()->Document();
+ DocumentStyleRootIterator iter(doc);
+ while (Element* root = iter.GetNextStyleRoot()) {
+ if (root->ShouldTraverseForServo()) {
+ return true;
+ }
+ }
+ return false;
+}
+
+} // namespace mozilla
+
+#endif // ServoRestyleManagerInlines_h
--- a/layout/base/moz.build
+++ b/layout/base/moz.build
@@ -72,16 +72,17 @@ EXPORTS.mozilla += [
'GeometryUtils.h',
'OverflowChangedTracker.h',
'RestyleLogging.h',
'RestyleManager.h',
'RestyleManagerBase.h',
'RestyleManagerHandle.h',
'RestyleManagerHandleInlines.h',
'ServoRestyleManager.h',
+ 'ServoRestyleManagerInlines.h',
'StaticPresData.h',
]
UNIFIED_SOURCES += [
'AccessibleCaret.cpp',
'AccessibleCaretEventHub.cpp',
'AccessibleCaretManager.cpp',
'FramePropertyTable.cpp',
--- a/layout/base/nsPresContext.cpp
+++ b/layout/base/nsPresContext.cpp
@@ -71,16 +71,17 @@
#include "nsContentUtils.h"
#include "nsPIWindowRoot.h"
#include "mozilla/Preferences.h"
#include "gfxTextRun.h"
#include "nsFontFaceUtils.h"
#include "nsLayoutStylesheetCache.h"
#include "mozilla/StyleSheet.h"
#include "mozilla/StyleSheetInlines.h"
+#include "mozilla/ServoRestyleManagerInlines.h"
#if defined(MOZ_WIDGET_GTK)
#include "gfxPlatformGtk.h" // xxx - for UseFcFontList
#endif
// Needed for Start/Stop of Image Animation
#include "imgIContainer.h"
--- a/layout/style/ServoStyleSet.cpp
+++ b/layout/style/ServoStyleSet.cpp
@@ -1,16 +1,17 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/ServoStyleSet.h"
+#include "mozilla/DocumentStyleRootIterator.h"
#include "mozilla/ServoRestyleManager.h"
#include "mozilla/dom/ChildIterator.h"
#include "nsCSSAnonBoxes.h"
#include "nsCSSPseudoElements.h"
#include "nsIDocumentInlines.h"
#include "nsPrintfCString.h"
#include "nsStyleContext.h"
#include "nsStyleSet.h"
@@ -41,17 +42,18 @@ ServoStyleSet::BeginShutdown()
// frame tree has been destroyed, but before the script runners that delete
// native anonymous content (which also could be holding on the RuleNodes)
// have run. By clearing style here, before the frame tree is destroyed,
// the AllChildrenIterator will find the anonymous content.
//
// Note that this is pretty bad for performance; we should find a way to
// get by with the ServoNodeDatas being dropped as part of the document
// going away.
- if (Element* root = mPresContext->Document()->GetRootElement()) {
+ DocumentStyleRootIterator iter(mPresContext->Document());
+ while (Element* root = iter.GetNextStyleRoot()) {
ServoRestyleManager::ClearServoDataFromSubtree(root);
}
}
void
ServoStyleSet::Shutdown()
{
mRawSet = nullptr;
@@ -443,23 +445,24 @@ ServoStyleSet::HasStateDependentStyle(do
{
NS_WARNING("stylo: HasStateDependentStyle always returns zero!");
return nsRestyleHint(0);
}
void
ServoStyleSet::StyleDocument()
{
- // Grab the root.
- nsIDocument* doc = mPresContext->Document();
- Element* root = doc->GetRootElement();
- MOZ_ASSERT(root);
-
- // Restyle the document.
- Servo_TraverseSubtree(root, mRawSet.get(), SkipRootBehavior::DontSkip);
+ // Restyle the document from the root element and each of the document level
+ // NAC subtree roots.
+ DocumentStyleRootIterator iter(mPresContext->Document());
+ while (Element* root = iter.GetNextStyleRoot()) {
+ if (root->ShouldTraverseForServo()) {
+ Servo_TraverseSubtree(root, mRawSet.get(), SkipRootBehavior::DontSkip);
+ }
+ }
}
void
ServoStyleSet::StyleNewSubtree(nsIContent* aContent)
{
if (aContent->IsElement()) {
Servo_TraverseSubtree(aContent->AsElement(), mRawSet.get(), SkipRootBehavior::DontSkip);
}