зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1382078
Part 3 - Support media changes for XBL stylesheets. r=emilio
MozReview-Commit-ID: EJp8EMyanBT --HG-- extra : rebase_source : 0ea61ea1f649548158fa600e5e11190631ce447f
This commit is contained in:
Родитель
a61a1227e9
Коммит
b6d71d0740
|
@ -50,6 +50,7 @@
|
|||
#include "nsThreadUtils.h"
|
||||
#include "mozilla/dom/NodeListBinding.h"
|
||||
#include "mozilla/dom/ScriptSettings.h"
|
||||
#include "mozilla/ServoStyleSet.h"
|
||||
#include "mozilla/Unused.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
@ -745,19 +746,59 @@ nsBindingManager::MediumFeaturesChanged(nsPresContext* aPresContext)
|
|||
{
|
||||
bool rulesChanged = false;
|
||||
RefPtr<nsPresContext> presContext = aPresContext;
|
||||
bool isStyledByServo = mDocument->IsStyledByServo();
|
||||
|
||||
EnumerateBoundContentBindings([=, &rulesChanged](nsXBLBinding* aBinding) {
|
||||
nsIStyleRuleProcessor* ruleProcessor =
|
||||
aBinding->PrototypeBinding()->GetRuleProcessor();
|
||||
if (ruleProcessor) {
|
||||
bool thisChanged = ruleProcessor->MediumFeaturesChanged(presContext);
|
||||
rulesChanged = rulesChanged || thisChanged;
|
||||
if (isStyledByServo) {
|
||||
ServoStyleSet* styleSet = aBinding->PrototypeBinding()->GetServoStyleSet();
|
||||
if (styleSet) {
|
||||
bool styleSetChanged = false;
|
||||
|
||||
if (styleSet->IsPresContextChanged(presContext)) {
|
||||
styleSetChanged = true;
|
||||
} else {
|
||||
// PresContext is not changed. This means aPresContext is still
|
||||
// alive since the last time it initialized this XBL styleset.
|
||||
// It's safe to check whether medium features changed.
|
||||
bool viewportUnitsUsed = false;
|
||||
styleSetChanged =
|
||||
styleSet->MediumFeaturesChangedRules(&viewportUnitsUsed);
|
||||
MOZ_ASSERT(!viewportUnitsUsed,
|
||||
"Non-master stylesets shouldn't get flagged as using "
|
||||
"viewport units!");
|
||||
}
|
||||
rulesChanged = rulesChanged || styleSetChanged;
|
||||
}
|
||||
} else {
|
||||
nsIStyleRuleProcessor* ruleProcessor =
|
||||
aBinding->PrototypeBinding()->GetRuleProcessor();
|
||||
if (ruleProcessor) {
|
||||
bool thisChanged = ruleProcessor->MediumFeaturesChanged(presContext);
|
||||
rulesChanged = rulesChanged || thisChanged;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return rulesChanged;
|
||||
}
|
||||
|
||||
void
|
||||
nsBindingManager::UpdateBoundContentBindingsForServo(nsPresContext* aPresContext)
|
||||
{
|
||||
MOZ_ASSERT(mDocument->IsStyledByServo(),
|
||||
"This should be called only by servo-backend!");
|
||||
|
||||
RefPtr<nsPresContext> presContext = aPresContext;
|
||||
|
||||
EnumerateBoundContentBindings([=](nsXBLBinding* aBinding) {
|
||||
nsXBLPrototypeBinding* protoBinding = aBinding->PrototypeBinding();
|
||||
ServoStyleSet* styleSet = protoBinding->GetServoStyleSet();
|
||||
if (styleSet && styleSet->StyleSheetsHaveChanged()) {
|
||||
protoBinding->ComputeServoStyleSet(presContext);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void
|
||||
nsBindingManager::AppendAllSheets(nsTArray<StyleSheet*>& aArray)
|
||||
{
|
||||
|
|
|
@ -130,13 +130,17 @@ public:
|
|||
|
||||
void WalkAllRules(nsIStyleRuleProcessor::EnumFunc aFunc,
|
||||
ElementDependentRuleProcessorData* aData);
|
||||
/**
|
||||
* Do any processing that needs to happen as a result of a change in
|
||||
* the characteristics of the medium, and return whether this rule
|
||||
* processor's rules have changed (e.g., because of media queries).
|
||||
*/
|
||||
|
||||
// Do any processing that needs to happen as a result of a change in the
|
||||
// characteristics of the medium, and return whether this rule processor's
|
||||
// rules or the servo style set have changed (e.g., because of media
|
||||
// queries).
|
||||
bool MediumFeaturesChanged(nsPresContext* aPresContext);
|
||||
|
||||
// Update the content bindings in mBoundContentSet due to medium features
|
||||
// changed.
|
||||
void UpdateBoundContentBindingsForServo(nsPresContext* aPresContext);
|
||||
|
||||
void AppendAllSheets(nsTArray<mozilla::StyleSheet*>& aArray);
|
||||
|
||||
void Traverse(nsIContent *aContent,
|
||||
|
|
|
@ -569,6 +569,14 @@ nsXBLPrototypeBinding::GetRuleProcessor()
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
nsXBLPrototypeBinding::ComputeServoStyleSet(nsPresContext* aPresContext)
|
||||
{
|
||||
if (mResources) {
|
||||
mResources->ComputeServoStyleSet(aPresContext);
|
||||
}
|
||||
}
|
||||
|
||||
ServoStyleSet*
|
||||
nsXBLPrototypeBinding::GetServoStyleSet() const
|
||||
{
|
||||
|
|
|
@ -131,6 +131,7 @@ public:
|
|||
void AppendStyleSheetsTo(nsTArray<mozilla::StyleSheet*>& aResult) const;
|
||||
|
||||
nsIStyleRuleProcessor* GetRuleProcessor();
|
||||
void ComputeServoStyleSet(nsPresContext* aPresContext);
|
||||
mozilla::ServoStyleSet* GetServoStyleSet() const;
|
||||
|
||||
nsresult FlushSkinSheets();
|
||||
|
|
|
@ -109,6 +109,8 @@ void
|
|||
ServoStyleSet::Init(nsPresContext* aPresContext, nsBindingManager* aBindingManager)
|
||||
{
|
||||
mPresContext = aPresContext;
|
||||
mPresContextInitXBLStyleSet = aPresContext;
|
||||
|
||||
mRawSet.reset(Servo_StyleSet_Init(aPresContext));
|
||||
mBindingManager = aBindingManager;
|
||||
|
||||
|
@ -168,11 +170,15 @@ nsRestyleHint
|
|||
ServoStyleSet::MediumFeaturesChanged(bool aViewportChanged)
|
||||
{
|
||||
bool viewportUnitsUsed = false;
|
||||
const OriginFlags rulesChanged = static_cast<OriginFlags>(
|
||||
Servo_StyleSet_MediumFeaturesChanged(mRawSet.get(), &viewportUnitsUsed));
|
||||
bool rulesChanged = MediumFeaturesChangedRules(&viewportUnitsUsed);
|
||||
|
||||
if (rulesChanged != OriginFlags(0)) {
|
||||
MarkOriginsDirty(rulesChanged);
|
||||
if (mBindingManager &&
|
||||
mBindingManager->MediumFeaturesChanged(mPresContext)) {
|
||||
SetStylistXBLStyleSheetsDirty();
|
||||
rulesChanged = true;
|
||||
}
|
||||
|
||||
if (rulesChanged) {
|
||||
return eRestyle_Subtree;
|
||||
}
|
||||
|
||||
|
@ -183,6 +189,22 @@ ServoStyleSet::MediumFeaturesChanged(bool aViewportChanged)
|
|||
return nsRestyleHint(0);
|
||||
}
|
||||
|
||||
bool
|
||||
ServoStyleSet::MediumFeaturesChangedRules(bool* aViewportUnitsUsed)
|
||||
{
|
||||
MOZ_ASSERT(aViewportUnitsUsed);
|
||||
|
||||
const OriginFlags rulesChanged = static_cast<OriginFlags>(
|
||||
Servo_StyleSet_MediumFeaturesChanged(mRawSet.get(), aViewportUnitsUsed));
|
||||
|
||||
if (rulesChanged != OriginFlags(0)) {
|
||||
MarkOriginsDirty(rulesChanged);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
MOZ_DEFINE_MALLOC_SIZE_OF(ServoStyleSetMallocSizeOf)
|
||||
|
||||
void
|
||||
|
@ -1372,13 +1394,21 @@ ServoStyleSet::UpdateStylist()
|
|||
{
|
||||
MOZ_ASSERT(StylistNeedsUpdate());
|
||||
|
||||
// There's no need to compute invalidations and such for an XBL styleset,
|
||||
// since they are loaded and unloaded synchronously, and they don't have to
|
||||
// deal with dynamic content changes.
|
||||
Element* root =
|
||||
IsMaster() ? mPresContext->Document()->GetDocumentElement() : nullptr;
|
||||
if (mStylistState & StylistState::StyleSheetsDirty) {
|
||||
// There's no need to compute invalidations and such for an XBL styleset,
|
||||
// since they are loaded and unloaded synchronously, and they don't have to
|
||||
// deal with dynamic content changes.
|
||||
Element* root =
|
||||
IsMaster() ? mPresContext->Document()->GetDocumentElement() : nullptr;
|
||||
|
||||
Servo_StyleSet_FlushStyleSheets(mRawSet.get(), root);
|
||||
}
|
||||
|
||||
if (MOZ_UNLIKELY(mStylistState & StylistState::XBLStyleSheetsDirty)) {
|
||||
MOZ_ASSERT(IsMaster(), "Only master styleset can mark XBL stylesets dirty!");
|
||||
mBindingManager->UpdateBoundContentBindingsForServo(mPresContext);
|
||||
}
|
||||
|
||||
Servo_StyleSet_FlushStyleSheets(mRawSet.get(), root);
|
||||
mStylistState = StylistState::NotDirty;
|
||||
}
|
||||
|
||||
|
|
|
@ -46,18 +46,22 @@ struct TreeMatchContext;
|
|||
|
||||
namespace mozilla {
|
||||
|
||||
/**
|
||||
* A few flags used to track which kind of stylist state we may need to
|
||||
* update.
|
||||
*/
|
||||
// A few flags used to track which kind of stylist state we may need to
|
||||
// update.
|
||||
enum class StylistState : uint8_t {
|
||||
/** The stylist is not dirty, we should do nothing */
|
||||
// The stylist is not dirty, we should do nothing.
|
||||
NotDirty = 0,
|
||||
|
||||
/** The style sheets have changed, so we need to update the style data. */
|
||||
StyleSheetsDirty,
|
||||
// The style sheets have changed, so we need to update the style data.
|
||||
StyleSheetsDirty = 1 << 0,
|
||||
|
||||
// Some of the style sheets of the bound elements in binding manager have
|
||||
// changed, so we need to tell the binding manager to update style data.
|
||||
XBLStyleSheetsDirty = 1 << 1,
|
||||
};
|
||||
|
||||
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(StylistState)
|
||||
|
||||
// Bitfield type to represent Servo stylesheet origins.
|
||||
enum class OriginFlags : uint8_t {
|
||||
UserAgent = 0x01,
|
||||
|
@ -133,6 +137,9 @@ public:
|
|||
|
||||
nsRestyleHint MediumFeaturesChanged(bool aViewportChanged);
|
||||
|
||||
// aViewportChanged outputs whether any viewport units is used.
|
||||
bool MediumFeaturesChangedRules(bool* aViewportUnitsUsed);
|
||||
|
||||
void InvalidateStyleForCSSRuleChanges();
|
||||
|
||||
void AddSizeOfIncludingThis(nsWindowSizes& aSizes) const;
|
||||
|
@ -433,6 +440,11 @@ public:
|
|||
mPresContext = nullptr;
|
||||
}
|
||||
|
||||
// Return whether this is the PresContext that initialized us.
|
||||
bool IsPresContextChanged(nsPresContext* aPresContext) const {
|
||||
return aPresContext != mPresContextInitXBLStyleSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if a modification to an an attribute with the specified
|
||||
* local name might require us to restyle the element.
|
||||
|
@ -525,7 +537,12 @@ private:
|
|||
*/
|
||||
void SetStylistStyleSheetsDirty()
|
||||
{
|
||||
mStylistState = StylistState::StyleSheetsDirty;
|
||||
mStylistState |= StylistState::StyleSheetsDirty;
|
||||
}
|
||||
|
||||
void SetStylistXBLStyleSheetsDirty()
|
||||
{
|
||||
mStylistState |= StylistState::XBLStyleSheetsDirty;
|
||||
}
|
||||
|
||||
bool StylistNeedsUpdate() const
|
||||
|
@ -565,7 +582,15 @@ private:
|
|||
ServoStyleSheet* aSheet);
|
||||
|
||||
const Kind mKind;
|
||||
nsPresContext* mPresContext;
|
||||
|
||||
// Nullptr if this is an XBL style set.
|
||||
nsPresContext* MOZ_NON_OWNING_REF mPresContext = nullptr;
|
||||
|
||||
// Because XBL style set could be used by multiple PresContext, we need to
|
||||
// store the PresContext pointer which initializes this style set for
|
||||
// computing medium rule changes.
|
||||
void* MOZ_NON_OWNING_REF mPresContextInitXBLStyleSet = nullptr;
|
||||
|
||||
UniquePtr<RawServoStyleSet> mRawSet;
|
||||
EnumeratedArray<SheetType, SheetType::Count,
|
||||
nsTArray<RefPtr<ServoStyleSheet>>> mSheets;
|
||||
|
|
|
@ -242,7 +242,6 @@ skip-if = !stylo
|
|||
skip-if = android_version == '18' #debug-only failure; timed out #Android 4.3 aws only; bug 1030419
|
||||
[test_media_queries_dynamic.html]
|
||||
[test_media_queries_dynamic_xbl.html]
|
||||
fail-if = stylo # bug 1382078
|
||||
[test_media_query_list.html]
|
||||
[test_media_query_serialization.html]
|
||||
[test_moz_device_pixel_ratio.html]
|
||||
|
|
Загрузка…
Ссылка в новой задаче