Bug 1409672: Hook in the invalidator stuff. r=xidorn

MozReview-Commit-ID: EoSMrYPS7dl
This commit is contained in:
Emilio Cobos Álvarez 2018-01-16 15:14:39 +01:00
Родитель 141792488a
Коммит e191632bd8
6 изменённых файлов: 65 добавлений и 44 удалений

Просмотреть файл

@ -1144,20 +1144,3 @@ nsBindingManager::FindNestedSingleInsertionPoint(nsIContent* aContainer,
return parent;
}
bool
nsBindingManager::AnyBindingHasDocumentStateDependency(EventStates aStateMask)
{
MOZ_ASSERT(mDocument->IsStyledByServo());
bool result = false;
EnumerateBoundContentBindings([&](nsXBLBinding* aBinding) {
ServoStyleSet* styleSet = aBinding->PrototypeBinding()->GetServoStyleSet();
if (styleSet && styleSet->HasDocumentStateDependency(aStateMask)) {
result = true;
return false;
}
return true;
});
return result;
}

Просмотреть файл

@ -173,7 +173,11 @@ public:
nsIContent* FindNestedSingleInsertionPoint(nsIContent* aContainer, bool* aMulti);
bool AnyBindingHasDocumentStateDependency(mozilla::EventStates aStateMask);
// Enumerate each bound content's bindings (including its base bindings)
// in mBoundContentSet. Return false from the callback to stop enumeration.
using BoundContentBindingCallback = std::function<bool (nsXBLBinding*)>;
bool EnumerateBoundContentBindings(
const BoundContentBindingCallback& aCallback) const;
protected:
nsIXPConnectWrappedJS* GetWrappedJS(nsIContent* aContent);
@ -195,14 +199,7 @@ protected:
// Call PostProcessAttachedQueueEvent() on a timer.
static void PostPAQEventCallback(nsITimer* aTimer, void* aClosure);
// Enumerate each bound content's bindings (including its base bindings)
// in mBoundContentSet. Return false from the callback to stop enumeration.
using BoundContentBindingCallback = std::function<bool (nsXBLBinding*)>;
bool EnumerateBoundContentBindings(
const BoundContentBindingCallback& aCallback) const;
// MEMBER VARIABLES
protected:
// A set of nsIContent that currently have a binding installed.
nsAutoPtr<nsTHashtable<nsRefPtrHashKey<nsIContent> > > mBoundContentSet;

Просмотреть файл

@ -4352,35 +4352,30 @@ PresShell::ContentStateChanged(nsIDocument* aDocument,
}
void
PresShell::DocumentStatesChanged(nsIDocument* aDocument,
EventStates aStateMask)
PresShell::DocumentStatesChanged(nsIDocument* aDocument, EventStates aStateMask)
{
NS_PRECONDITION(!mIsDocumentGone, "Unexpected DocumentStatesChanged");
NS_PRECONDITION(aDocument == mDocument, "Unexpected aDocument");
MOZ_ASSERT(!aStateMask.IsEmpty());
if (mDidInitialize) {
Element* rootElement = aDocument->GetRootElement();
bool needRestyle = false;
if (mStyleSet->IsServo()) {
needRestyle = rootElement &&
(mStyleSet->AsServo()->HasDocumentStateDependency(aStateMask) ||
aDocument->BindingManager()->
AnyBindingHasDocumentStateDependency(aStateMask));
} else {
needRestyle = mStyleSet->AsGecko()->
HasDocumentStateDependentStyle(rootElement, aStateMask);
}
if (needRestyle) {
mPresContext->RestyleManager()->PostRestyleEvent(rootElement,
eRestyle_Subtree,
nsChangeHint(0));
VERIFY_STYLE_TREE;
mStyleSet->AsServo()->InvalidateStyleForDocumentStateChanges(aStateMask);
} else if (Element* rootElement = aDocument->GetRootElement()) {
const bool needRestyle =
mStyleSet->AsGecko()->HasDocumentStateDependentStyle(
rootElement, aStateMask);
if (needRestyle) {
mPresContext->RestyleManager()->PostRestyleEvent(rootElement,
eRestyle_Subtree,
nsChangeHint(0));
VERIFY_STYLE_TREE;
}
}
}
if (aStateMask.HasState(NS_DOCUMENT_STATE_WINDOW_INACTIVE)) {
nsIFrame* root = mFrameConstructor->GetRootFrame();
if (root) {
if (nsIFrame* root = mFrameConstructor->GetRootFrame()) {
root->SchedulePaint();
}
}

Просмотреть файл

@ -40,6 +40,11 @@ SERVO_BINDING_FUNC(Servo_Element_IsDisplayNone,
SERVO_BINDING_FUNC(Servo_Element_IsPrimaryStyleReusedViaRuleNode,
bool,
RawGeckoElementBorrowed element)
SERVO_BINDING_FUNC(Servo_InvalidateStyleForDocStateChanges,
void,
RawGeckoElementBorrowed root,
const nsTArray<RawServoStyleSetBorrowed>* sets,
uint64_t aStatesChanged)
// Styleset and Stylesheet management
SERVO_BINDING_FUNC(Servo_StyleSheet_FromUTF8Bytes,

Просмотреть файл

@ -33,6 +33,7 @@
#include "nsSMILAnimationController.h"
#include "nsStyleContext.h"
#include "nsStyleSet.h"
#include "nsXBLPrototypeBinding.h"
#include "gfxUserFontSet.h"
using namespace mozilla;
@ -223,6 +224,43 @@ ServoStyleSet::SetPresContext(nsPresContext* aPresContext)
return false;
}
void
ServoStyleSet::InvalidateStyleForDocumentStateChanges(EventStates aStatesChanged)
{
MOZ_ASSERT(IsMaster());
MOZ_ASSERT(mDocument);
MOZ_ASSERT(!aStatesChanged.IsEmpty());
nsPresContext* pc = GetPresContext();
if (!pc) {
return;
}
Element* root = mDocument->GetRootElement();
if (!root) {
return;
}
// TODO(emilio): It may be nicer to just invalidate stuff in a given subtree
// for XBL sheets / shadow DOM. Consider just enumerating bound content
// instead and run invalidation individually, passing mRawSet for the UA /
// User sheets.
AutoTArray<RawServoStyleSetBorrowed, 20> styleSets;
styleSets.AppendElement(mRawSet.get());
// FIXME(emilio): When bug 1425759 is fixed we need to enumerate ShadowRoots
// too.
mDocument->BindingManager()->EnumerateBoundContentBindings(
[&](nsXBLBinding* aBinding) {
if (ServoStyleSet* set = aBinding->PrototypeBinding()->GetServoStyleSet()) {
styleSets.AppendElement(set->RawSet());
}
return true;
});
Servo_InvalidateStyleForDocStateChanges(
root, &styleSets, aStatesChanged.ServoValue());
}
nsRestyleHint
ServoStyleSet::MediumFeaturesChanged(bool aViewportChanged)
{

Просмотреть файл

@ -146,6 +146,9 @@ public:
// the relevant AppendSheet / RemoveSheet...
void RecordStyleSheetChange(ServoStyleSheet*, StyleSheet::ChangeType) {}
// Runs style invalidation due to document state changes.
void InvalidateStyleForDocumentStateChanges(EventStates aStatesChanged);
void RecordShadowStyleChange(dom::ShadowRoot* aShadowRoot) {
// FIXME(emilio): When we properly support shadow dom we'll need to do
// better.