Bug 1366157 - stylo: Implement getDefaultComputedStyle. r=emilio
MozReview-Commit-ID: GKr06ylK4tA
--- a/layout/style/ServoBindingList.h
+++ b/layout/style/ServoBindingList.h
@@ -449,16 +449,17 @@ SERVO_BINDING_FUNC(Servo_HasAuthorSpecif
// though caching is not possible within display:none subtrees, and the styles
// may be invalidated by already-scheduled restyles.
//
// The tree must be in a consistent state such that a normal traversal could be
// performed, and this function maintains that invariant.
SERVO_BINDING_FUNC(Servo_ResolveStyleLazily, ServoComputedValuesStrong,
RawGeckoElementBorrowed element,
mozilla::CSSPseudoElementType pseudo_type,
+ mozilla::StyleRuleInclusion rule_inclusion,
const mozilla::ServoElementSnapshotTable* snapshots,
RawServoStyleSetBorrowed set)
// Use ServoStyleSet::PrepareAndTraverseSubtree instead of calling this
// directly
SERVO_BINDING_FUNC(Servo_TraverseSubtree,
bool,
RawGeckoElementBorrowed root,
--- a/layout/style/ServoBindings.toml
+++ b/layout/style/ServoBindings.toml
@@ -245,16 +245,17 @@ whitelist-types = [
"StyleShapeSource",
"StyleTransition",
"mozilla::UniquePtr",
"mozilla::DefaultDelete",
"mozilla::Side",
"mozilla::binding_danger::AssertAndSuppressCleanupPolicy",
"mozilla::ParsingMode",
"mozilla::InheritTarget",
+ "mozilla::StyleRuleInclusion",
]
opaque-types = [
"std::pair__PCCP",
"std::namespace::atomic___base", "std::atomic__My_base",
"std::atomic",
"std::atomic___base",
"mozilla::gfx::.*",
"FallibleTArray",
@@ -421,16 +422,17 @@ structs-types = [
"nsresult",
"Loader",
"ServoStyleSheet",
"EffectCompositor_CascadeLevel",
"UpdateAnimationsTasks",
"ParsingMode",
"InheritTarget",
"URLMatchingFunction",
+ "StyleRuleInclusion",
]
array-types = [
{ cpp-type = "uintptr_t", rust-type = "usize" },
]
servo-owned-types = [
{ name = "RawServoStyleSet", opaque = true },
{ name = "StyleChildrenIterator", opaque = true },
{ name = "ServoElementSnapshot", opaque = false },
--- a/layout/style/ServoStyleSet.cpp
+++ b/layout/style/ServoStyleSet.cpp
@@ -509,33 +509,36 @@ ServoStyleSet::ResolvePseudoElementStyle
nsIAtom* pseudoTag = nsCSSPseudoElements::GetPseudoAtom(aType);
return GetContext(computedValues.forget(), aParentContext, pseudoTag, aType,
isBeforeOrAfter ? aOriginatingElement : nullptr);
}
already_AddRefed<nsStyleContext>
ServoStyleSet::ResolveTransientStyle(Element* aElement,
nsIAtom* aPseudoTag,
- CSSPseudoElementType aPseudoType)
+ CSSPseudoElementType aPseudoType,
+ StyleRuleInclusion aRuleInclusion)
{
RefPtr<ServoComputedValues> computedValues =
- ResolveTransientServoStyle(aElement, aPseudoType);
+ ResolveTransientServoStyle(aElement, aPseudoType, aRuleInclusion);
return GetContext(computedValues.forget(),
nullptr,
aPseudoTag,
aPseudoType, nullptr);
}
already_AddRefed<ServoComputedValues>
-ServoStyleSet::ResolveTransientServoStyle(Element* aElement,
- CSSPseudoElementType aPseudoType)
+ServoStyleSet::ResolveTransientServoStyle(
+ Element* aElement,
+ CSSPseudoElementType aPseudoType,
+ StyleRuleInclusion aRuleInclusion)
{
PreTraverseSync();
- return ResolveStyleLazily(aElement, aPseudoType);
+ return ResolveStyleLazily(aElement, aPseudoType, aRuleInclusion);
}
already_AddRefed<nsStyleContext>
ServoStyleSet::ResolveInheritingAnonymousBoxStyle(nsIAtom* aPseudoTag,
nsStyleContext* aParentContext)
{
MOZ_ASSERT(nsCSSAnonBoxes::IsAnonBox(aPseudoTag) &&
!nsCSSAnonBoxes::IsNonInheritingAnonBox(aPseudoTag));
@@ -1050,17 +1053,18 @@ ServoStyleSet::ClearNonInheritingStyleCo
{
for (RefPtr<nsStyleContext>& ptr : mNonInheritingStyleContexts) {
ptr = nullptr;
}
}
already_AddRefed<ServoComputedValues>
ServoStyleSet::ResolveStyleLazily(Element* aElement,
- CSSPseudoElementType aPseudoType)
+ CSSPseudoElementType aPseudoType,
+ StyleRuleInclusion aRuleInclusion)
{
mPresContext->EffectCompositor()->PreTraverse(aElement, aPseudoType);
MOZ_ASSERT(!StylistNeedsUpdate());
AutoSetInServoTraversal guard(this);
/**
* NB: This is needed because we process animations and transitions on the
@@ -1085,23 +1089,25 @@ ServoStyleSet::ResolveStyleLazily(Elemen
elementForStyleResolution = pseudo;
pseudoTypeForStyleResolution = CSSPseudoElementType::NotPseudo;
}
}
RefPtr<ServoComputedValues> computedValues =
Servo_ResolveStyleLazily(elementForStyleResolution,
pseudoTypeForStyleResolution,
+ aRuleInclusion,
&Snapshots(),
mRawSet.get()).Consume();
if (mPresContext->EffectCompositor()->PreTraverse(aElement, aPseudoType)) {
computedValues =
Servo_ResolveStyleLazily(elementForStyleResolution,
pseudoTypeForStyleResolution,
+ aRuleInclusion,
&Snapshots(),
mRawSet.get()).Consume();
}
return computedValues.forget();
}
bool
--- a/layout/style/ServoStyleSet.h
+++ b/layout/style/ServoStyleSet.h
@@ -167,23 +167,27 @@ public:
// Resolves style for a (possibly-pseudo) Element without assuming that the
// style has been resolved, and without worrying about setting the style
// context up to live in the style context tree (a null parent is used).
// |aPeudoTag| and |aPseudoType| must match.
already_AddRefed<nsStyleContext>
ResolveTransientStyle(dom::Element* aElement,
nsIAtom* aPseudoTag,
- CSSPseudoElementType aPseudoType);
+ CSSPseudoElementType aPseudoType,
+ StyleRuleInclusion aRules =
+ StyleRuleInclusion::All);
// Similar to ResolveTransientStyle() but returns ServoComputedValues.
// Unlike ResolveServoStyle() this function calls PreTraverseSync().
already_AddRefed<ServoComputedValues>
ResolveTransientServoStyle(dom::Element* aElement,
- CSSPseudoElementType aPseudoTag);
+ CSSPseudoElementType aPseudoTag,
+ StyleRuleInclusion aRules =
+ StyleRuleInclusion::All);
// Get a style context for an anonymous box. aPseudoTag is the pseudo-tag to
// use and must be non-null. It must be an anon box, and must be one that
// inherits style from the given aParentContext.
already_AddRefed<nsStyleContext>
ResolveInheritingAnonymousBoxStyle(nsIAtom* aPseudoTag,
nsStyleContext* aParentContext);
@@ -476,17 +480,20 @@ private:
void UpdateStylistIfNeeded()
{
if (StylistNeedsUpdate()) {
UpdateStylist();
}
}
already_AddRefed<ServoComputedValues>
- ResolveStyleLazily(dom::Element* aElement, CSSPseudoElementType aPseudoType);
+ ResolveStyleLazily(dom::Element* aElement,
+ CSSPseudoElementType aPseudoType,
+ StyleRuleInclusion aRules =
+ StyleRuleInclusion::All);
void RunPostTraversalTasks();
void PrependSheetOfType(SheetType aType,
ServoStyleSheet* aSheet);
void AppendSheetOfType(SheetType aType,
ServoStyleSheet* aSheet);
--- a/layout/style/ServoTypes.h
+++ b/layout/style/ServoTypes.h
@@ -68,16 +68,25 @@ enum class TraversalRestyleBehavior {
// are unneeded, since the old frames have already been destroyed.
ForReconstruct,
// Processes animation-only restyle.
ForAnimationOnly,
// Traverses as normal mode but tries to update all CSS animations.
ForCSSRuleChanges,
};
+// Indicates which rules should be included when performing selecting matching
+// on an element. DefaultOnly is used to exclude all rules except for those
+// that come from UA style sheets, and is used to implemented
+// getDefaultComputedStyle.
+enum class StyleRuleInclusion {
+ All,
+ DefaultOnly,
+};
+
// Represents which tasks are performed in a SequentialTask of UpdateAnimations.
enum class UpdateAnimationsTasks : uint8_t {
CSSAnimations = 1 << 0,
CSSTransitions = 1 << 1,
EffectProperties = 1 << 2,
CascadeResults = 1 << 3,
};
--- a/layout/style/nsComputedDOMStyle.cpp
+++ b/layout/style/nsComputedDOMStyle.cpp
@@ -657,21 +657,20 @@ nsComputedDOMStyle::DoGetStyleContextNoF
if (type >= CSSPseudoElementType::Count) {
return nullptr;
}
}
// For Servo, compute the result directly without recursively building up
// a throwaway style context chain.
if (ServoStyleSet* servoSet = styleSet->GetAsServo()) {
- if (aStyleType == eDefaultOnly) {
- NS_WARNING("stylo: ServoStyleSets cannot supply UA-only styles yet");
- return nullptr;
- }
- return servoSet->ResolveTransientStyle(aElement, aPseudo, type);
+ StyleRuleInclusion rules = aStyleType == eDefaultOnly
+ ? StyleRuleInclusion::DefaultOnly
+ : StyleRuleInclusion::All;
+ return servoSet->ResolveTransientStyle(aElement, aPseudo, type, rules);
}
RefPtr<nsStyleContext> parentContext;
nsIContent* parent = aPseudo ? aElement : aElement->GetParent();
// Don't resolve parent context for document fragments.
if (parent && parent->IsElement()) {
parentContext = GetStyleContextNoFlush(parent->AsElement(), nullptr,
aPresShell, aStyleType);