--- a/dom/animation/EffectCompositor.cpp
+++ b/dom/animation/EffectCompositor.cpp
@@ -1279,20 +1279,20 @@ EffectCompositor::AnimationStyleRuleProc
MallocSizeOf aMallocSizeOf) const
{
return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
}
template
void
EffectCompositor::UpdateEffectProperties(
- nsStyleContext* aStyleContext,
+ GeckoStyleContext* aStyleContext,
Element* aElement,
CSSPseudoElementType aPseudoType);
template
void
EffectCompositor::UpdateEffectProperties(
- const ServoComputedValues* aServoValues,
+ const ServoStyleContext* aStyleContext,
Element* aElement,
CSSPseudoElementType aPseudoType);
} // namespace mozilla
--- a/dom/animation/KeyframeEffectReadOnly.cpp
+++ b/dom/animation/KeyframeEffectReadOnly.cpp
@@ -181,43 +181,53 @@ KeyframeEffectReadOnly::SetKeyframes(JSC
{
nsTArray<Keyframe> keyframes =
KeyframeUtils::GetKeyframesFromObject(aContext, mDocument, aKeyframes, aRv);
if (aRv.Failed()) {
return;
}
RefPtr<nsStyleContext> styleContext = GetTargetStyleContext();
- SetKeyframes(Move(keyframes), styleContext);
+ if (styleContext) {
+ if (auto gecko = styleContext->GetAsGecko()) {
+ SetKeyframes(Move(keyframes), gecko);
+ } else {
+ SetKeyframes(Move(keyframes), styleContext->AsServo());
+ }
+ } else {
+ // SetKeyframes has the same behavior for null StyleType* for
+ // both backends, just pick one and use it.
+ SetKeyframes(Move(keyframes), (GeckoStyleContext*) nullptr);
+ }
}
void
KeyframeEffectReadOnly::SetKeyframes(nsTArray<Keyframe>&& aKeyframes,
- nsStyleContext* aStyleContext)
+ GeckoStyleContext* aStyleContext)
{
DoSetKeyframes(Move(aKeyframes), Move(aStyleContext));
}
void
KeyframeEffectReadOnly::SetKeyframes(
nsTArray<Keyframe>&& aKeyframes,
- const ServoComputedValues* aComputedValues)
+ const ServoStyleContext* aComputedValues)
{
DoSetKeyframes(Move(aKeyframes), aComputedValues);
}
template<typename StyleType>
void
KeyframeEffectReadOnly::DoSetKeyframes(nsTArray<Keyframe>&& aKeyframes,
StyleType* aStyle)
{
- static_assert(IsSame<StyleType, nsStyleContext>::value ||
- IsSame<StyleType, const ServoComputedValues>::value,
- "StyleType should be nsStyleContext* or "
- "const ServoComputedValues*");
+ static_assert(IsSame<StyleType, GeckoStyleContext>::value ||
+ IsSame<StyleType, const ServoStyleContext>::value,
+ "StyleType should be GeckoStyleContext* or "
+ "const ServoStyleContext*");
if (KeyframesEqualIgnoringComputedOffsets(aKeyframes, mKeyframes)) {
return;
}
mKeyframes = Move(aKeyframes);
KeyframeUtils::DistributeKeyframes(mKeyframes);
@@ -291,31 +301,29 @@ SpecifiedKeyframeArraysAreEqual(const ns
}
#endif
void
KeyframeEffectReadOnly::UpdateProperties(nsStyleContext* aStyleContext)
{
MOZ_ASSERT(aStyleContext);
- if (!mDocument->IsStyledByServo()) {
- DoUpdateProperties(Move(aStyleContext));
+ if (auto gecko = aStyleContext->GetAsGecko()) {
+ DoUpdateProperties(Move(gecko));
return;
}
- const ServoComputedValues* currentStyle = aStyleContext->ComputedValues();
-
- DoUpdateProperties(currentStyle);
+ UpdateProperties(aStyleContext->AsServo());
}
void
KeyframeEffectReadOnly::UpdateProperties(
- const ServoComputedValues* aComputedValues)
+ const ServoStyleContext* aStyleContext)
{
- DoUpdateProperties(aComputedValues);
+ DoUpdateProperties(aStyleContext);
}
template<typename StyleType>
void
KeyframeEffectReadOnly::DoUpdateProperties(StyleType* aStyle)
{
MOZ_ASSERT(aStyle);
@@ -435,17 +443,17 @@ KeyframeEffectReadOnly::CompositeValue(
return CompositeValue(aProperty,
aValueToComposite,
underlyingValue,
aCompositeOperation);
}
void
KeyframeEffectReadOnly::EnsureBaseStyles(
- nsStyleContext* aStyleContext,
+ GeckoStyleContext* aStyleContext,
const nsTArray<AnimationProperty>& aProperties)
{
if (!mTarget) {
return;
}
mBaseStyleValues.Clear();
@@ -463,17 +471,17 @@ KeyframeEffectReadOnly::EnsureBaseStyles
break;
}
}
}
void
KeyframeEffectReadOnly::EnsureBaseStyle(
nsCSSPropertyID aProperty,
- nsStyleContext* aStyleContext,
+ GeckoStyleContext* aStyleContext,
RefPtr<nsStyleContext>& aCachedBaseStyleContext)
{
if (mBaseStyleValues.Contains(aProperty)) {
return;
}
if (!aCachedBaseStyleContext) {
aCachedBaseStyleContext =
@@ -492,17 +500,17 @@ KeyframeEffectReadOnly::EnsureBaseStyle(
MOZ_ASSERT(success, "Should be able to extract computed animation value");
MOZ_ASSERT(!result.IsNull(), "Should have a valid StyleAnimationValue");
mBaseStyleValues.Put(aProperty, result);
}
void
KeyframeEffectReadOnly::EnsureBaseStyles(
- const ServoComputedValues* aComputedValues,
+ const ServoStyleContext* aComputedValues,
const nsTArray<AnimationProperty>& aProperties)
{
if (!mTarget) {
return;
}
mBaseStyleValuesForServo.Clear();
@@ -523,17 +531,17 @@ KeyframeEffectReadOnly::EnsureBaseStyles
}
}
void
KeyframeEffectReadOnly::EnsureBaseStyle(
const AnimationProperty& aProperty,
CSSPseudoElementType aPseudoType,
nsPresContext* aPresContext,
- const ServoComputedValues* aComputedStyle,
+ const ServoStyleContext* aComputedStyle,
RefPtr<ServoStyleContext>& aBaseStyleContext)
{
bool hasAdditiveValues = false;
for (const AnimationPropertySegment& segment : aProperty.mSegments) {
if (!segment.HasReplaceableValues()) {
hasAdditiveValues = true;
break;
@@ -904,20 +912,20 @@ KeyframeEffectReadOnly::ConstructKeyfram
effect->mProperties = aSource.mProperties;
return effect.forget();
}
template<typename StyleType>
nsTArray<AnimationProperty>
KeyframeEffectReadOnly::BuildProperties(StyleType* aStyle)
{
- static_assert(IsSame<StyleType, nsStyleContext>::value ||
- IsSame<StyleType, const ServoComputedValues>::value,
- "StyleType should be nsStyleContext* or "
- "const ServoComputedValues*");
+ static_assert(IsSame<StyleType, GeckoStyleContext>::value ||
+ IsSame<StyleType, const ServoStyleContext>::value,
+ "StyleType should be GeckoStyleContext* or "
+ "const ServoStyleContext*");
MOZ_ASSERT(aStyle);
nsTArray<AnimationProperty> result;
// If mTarget is null, return an empty property array.
if (!mTarget) {
return result;
}
--- a/dom/animation/KeyframeEffectReadOnly.h
+++ b/dom/animation/KeyframeEffectReadOnly.h
@@ -41,16 +41,17 @@ namespace mozilla {
class AnimValuesStyleRule;
enum class CSSPseudoElementType : uint8_t;
class ErrorResult;
struct AnimationRule;
struct TimingParams;
class EffectSet;
class ServoStyleContext;
+class GeckoStyleContext;
namespace dom {
class ElementOrCSSPseudoElement;
class GlobalObject;
class OwningElementOrCSSPseudoElement;
class UnrestrictedDoubleOrKeyframeAnimationOptions;
class UnrestrictedDoubleOrKeyframeEffectOptions;
enum class IterationCompositeOperation : uint8_t;
@@ -160,19 +161,19 @@ public:
IterationCompositeOperation IterationComposite() const;
CompositeOperation Composite() const;
void NotifyAnimationTimingUpdated();
void RequestRestyle(EffectCompositor::RestyleType aRestyleType);
void SetAnimation(Animation* aAnimation) override;
void SetKeyframes(JSContext* aContext, JS::Handle<JSObject*> aKeyframes,
ErrorResult& aRv);
void SetKeyframes(nsTArray<Keyframe>&& aKeyframes,
- nsStyleContext* aStyleContext);
+ GeckoStyleContext* aStyleContext);
void SetKeyframes(nsTArray<Keyframe>&& aKeyframes,
- const ServoComputedValues* aComputedValues);
+ const ServoStyleContext* aComputedValues);
// Returns true if the effect includes |aProperty| regardless of whether the
// property is overridden by !important rule.
bool HasAnimationOfProperty(nsCSSPropertyID aProperty) const;
// GetEffectiveAnimationOfProperty returns AnimationProperty corresponding
// to a given CSS property if the effect includes the property and the
// property is not overridden by !important rules.
@@ -191,17 +192,17 @@ public:
{
return mProperties;
}
// Update |mProperties| by recalculating from |mKeyframes| using
// |aStyleContext| to resolve specified values.
void UpdateProperties(nsStyleContext* aStyleContext);
// Servo version of the above function.
- void UpdateProperties(const ServoComputedValues* aComputedValues);
+ void UpdateProperties(const ServoStyleContext* aComputedValues);
// Update various bits of state related to running ComposeStyle().
// We need to update this outside ComposeStyle() because we should avoid
// mutating any state in ComposeStyle() since it might be called during
// parallel traversal.
void WillComposeStyle();
// Updates |aComposeResult| with the animation values produced by this
@@ -254,17 +255,17 @@ public:
const AnimationPerformanceWarning& aWarning);
// Record telemetry about the size of the content being animated.
void RecordFrameSizeTelemetry(uint32_t aPixelArea);
// Cumulative change hint on each segment for each property.
// This is used for deciding the animation is paint-only.
void CalculateCumulativeChangeHint(nsStyleContext* aStyleContext);
- void CalculateCumulativeChangeHint(const ServoComputedValues* aComputedValues)
+ void CalculateCumulativeChangeHint(const ServoStyleContext* aComputedValues)
{
}
// Returns true if all of animation properties' change hints
// can ignore painting if the animation is not visible.
// See nsChangeHint_Hints_CanIgnoreIfNotVisible in nsChangeHint.h
// in detail which change hint can be ignored.
bool CanIgnoreIfNotVisible() const;
@@ -362,35 +363,35 @@ protected:
CompositeOperation aCompositeOperation);
// Returns underlying style animation value for |aProperty|.
StyleAnimationValue GetUnderlyingStyle(
nsCSSPropertyID aProperty,
const RefPtr<AnimValuesStyleRule>& aAnimationRule);
// Ensure the base styles is available for any properties in |aProperties|.
- void EnsureBaseStyles(nsStyleContext* aStyleContext,
+ void EnsureBaseStyles(GeckoStyleContext* aStyleContext,
const nsTArray<AnimationProperty>& aProperties);
- void EnsureBaseStyles(const ServoComputedValues* aComputedValues,
+ void EnsureBaseStyles(const ServoStyleContext* aComputedValues,
const nsTArray<AnimationProperty>& aProperties);
// If no base style is already stored for |aProperty|, resolves the base style
// for |aProperty| using |aStyleContext| and stores it in mBaseStyleValues.
// If |aCachedBaseStyleContext| is non-null, it will be used, otherwise the
// base style context will be resolved and stored in
// |aCachedBaseStyleContext|.
void EnsureBaseStyle(nsCSSPropertyID aProperty,
- nsStyleContext* aStyleContext,
+ GeckoStyleContext* aStyleContext,
RefPtr<nsStyleContext>& aCachedBaseStyleContext);
// Stylo version of the above function that also first checks for an additive
// value in |aProperty|'s list of segments.
void EnsureBaseStyle(const AnimationProperty& aProperty,
CSSPseudoElementType aPseudoType,
nsPresContext* aPresContext,
- const ServoComputedValues* aComputedValues,
+ const ServoStyleContext* aComputedValues,
RefPtr<mozilla::ServoStyleContext>& aBaseComputedValues);
Maybe<OwningAnimationTarget> mTarget;
KeyframeEffectParams mEffectOptions;
// The specified keyframes.
nsTArray<Keyframe> mKeyframes;
--- a/dom/animation/KeyframeUtils.cpp
+++ b/dom/animation/KeyframeUtils.cpp
@@ -363,22 +363,22 @@ MarkAsComputeValuesFailureKey(PropertyVa
static bool
IsComputeValuesFailureKey(const PropertyValuePair& aPair);
#endif
static nsTArray<ComputedKeyframeValues>
GetComputedKeyframeValues(const nsTArray<Keyframe>& aKeyframes,
dom::Element* aElement,
- nsStyleContext* aStyleContext);
+ GeckoStyleContext* aStyleContext);
static nsTArray<ComputedKeyframeValues>
GetComputedKeyframeValues(const nsTArray<Keyframe>& aKeyframes,
dom::Element* aElement,
- const ServoComputedValues* aComputedValues);
+ const ServoStyleContext* aComputedValues);
static void
BuildSegmentsFromValueEntries(nsTArray<KeyframeValueEntry>& aEntries,
nsTArray<AnimationProperty>& aResult);
static void
GetKeyframeListFromPropertyIndexedKeyframe(JSContext* aCx,
nsIDocument* aDocument,
@@ -1007,17 +1007,17 @@ IsComputeValuesFailureKey(const Property
* @param aElement The context element.
* @param aStyleContext The style context to use when computing values.
* @return The set of ComputedKeyframeValues. The length will be the same as
* aFrames.
*/
static nsTArray<ComputedKeyframeValues>
GetComputedKeyframeValues(const nsTArray<Keyframe>& aKeyframes,
dom::Element* aElement,
- nsStyleContext* aStyleContext)
+ GeckoStyleContext* aStyleContext)
{
MOZ_ASSERT(aStyleContext);
MOZ_ASSERT(aElement);
const size_t len = aKeyframes.Length();
nsTArray<ComputedKeyframeValues> result(len);
for (const Keyframe& frame : aKeyframes) {
@@ -1082,26 +1082,26 @@ GetComputedKeyframeValues(const nsTArray
}
/**
* The variation of the above function. This is for Servo backend.
*/
static nsTArray<ComputedKeyframeValues>
GetComputedKeyframeValues(const nsTArray<Keyframe>& aKeyframes,
dom::Element* aElement,
- const ServoComputedValues* aComputedValues)
+ const ServoStyleContext* aStyleContext)
{
MOZ_ASSERT(aElement);
MOZ_ASSERT(aElement->IsStyledByServo());
nsPresContext* presContext = nsContentUtils::GetContextForContent(aElement);
MOZ_ASSERT(presContext);
return presContext->StyleSet()->AsServo()
- ->GetComputedKeyframeValuesFor(aKeyframes, aElement, aComputedValues);
+ ->GetComputedKeyframeValuesFor(aKeyframes, aElement, aStyleContext->ComputedValues());
}
static void
AppendInitialSegment(AnimationProperty* aAnimationProperty,
const KeyframeValueEntry& aFirstEntry)
{
AnimationPropertySegment* segment =
aAnimationProperty->mSegments.AppendElement();
--- a/dom/canvas/CanvasRenderingContext2D.cpp
+++ b/dom/canvas/CanvasRenderingContext2D.cpp
@@ -2839,17 +2839,17 @@ CreateDeclarationForServo(nsCSSPropertyI
static already_AddRefed<RawServoDeclarationBlock>
CreateFontDeclarationForServo(const nsAString& aFont,
nsIDocument* aDocument)
{
return CreateDeclarationForServo(eCSSProperty_font, aFont, aDocument);
}
-static already_AddRefed<ServoComputedValues>
+static already_AddRefed<ServoStyleContext>
GetFontStyleForServo(Element* aElement, const nsAString& aFont,
nsIPresShell* aPresShell,
nsAString& aOutUsedFont,
ErrorResult& aError)
{
MOZ_ASSERT(aPresShell->StyleSet()->IsServo());
RefPtr<RawServoDeclarationBlock> declarations =
@@ -2864,44 +2864,45 @@ GetFontStyleForServo(Element* aElement,
// at font-size-adjust, which the font shorthand resets to 'none'.
if (Servo_DeclarationBlock_HasCSSWideKeyword(declarations,
eCSSProperty_font_size_adjust)) {
return nullptr;
}
ServoStyleSet* styleSet = aPresShell->StyleSet()->AsServo();
- RefPtr<ServoComputedValues> parentStyle;
+ RefPtr<ServoStyleContext> parentStyle;
// have to get a parent style context for inherit-like relative
// values (2em, bolder, etc.)
if (aElement && aElement->IsInUncomposedDoc()) {
// Inherit from the canvas element.
aPresShell->FlushPendingNotifications(FlushType::Style);
// We need to use ResolveTransientServoStyle, which involves traversal,
// instead of ResolveServoStyle() because we need up-to-date style even if
// the canvas element is display:none.
parentStyle =
styleSet->ResolveTransientServoStyle(aElement,
- CSSPseudoElementType::NotPseudo);
+ CSSPseudoElementType::NotPseudo,
+ nullptr);
} else {
RefPtr<RawServoDeclarationBlock> declarations =
CreateFontDeclarationForServo(NS_LITERAL_STRING("10px sans-serif"),
aPresShell->GetDocument());
MOZ_ASSERT(declarations);
parentStyle = aPresShell->StyleSet()->AsServo()->
ResolveForDeclarations(nullptr, declarations);
}
MOZ_RELEASE_ASSERT(parentStyle, "Should have a valid parent style");
MOZ_ASSERT(!aPresShell->IsDestroying(),
"GetFontParentStyleContext should have returned an error if the presshell is being destroyed.");
- RefPtr<ServoComputedValues> sc =
+ RefPtr<ServoStyleContext> sc =
styleSet->ResolveForDeclarations(parentStyle, declarations);
// The font getter is required to be reserialized based on what we
// parsed (including having line-height removed). (Older drafts of
// the spec required font sizes be converted to pixels, but that no
// longer seems to be required.)
Servo_SerializeFontValueForCanvas(declarations, &aOutUsedFont);
@@ -2955,19 +2956,19 @@ ResolveFilterStyle(const nsAString& aFil
static already_AddRefed<RawServoDeclarationBlock>
CreateFilterDeclarationForServo(const nsAString& aFilter,
nsIDocument* aDocument)
{
return CreateDeclarationForServo(eCSSProperty_filter, aFilter, aDocument);
}
-static already_AddRefed<ServoComputedValues>
+static already_AddRefed<ServoStyleContext>
ResolveFilterStyleForServo(const nsAString& aFilterString,
- const ServoComputedValues* aParentStyle,
+ const ServoStyleContext* aParentStyle,
nsIPresShell* aPresShell,
ErrorResult& aError)
{
MOZ_ASSERT(aPresShell->StyleSet()->IsServo());
RefPtr<RawServoDeclarationBlock> declarations =
CreateFilterDeclarationForServo(aFilterString, aPresShell->GetDocument());
if (!declarations) {
@@ -2978,17 +2979,17 @@ ResolveFilterStyleForServo(const nsAStri
// In addition to unparseable values, the spec says we need to reject
// 'inherit' and 'initial'.
if (Servo_DeclarationBlock_HasCSSWideKeyword(declarations,
eCSSProperty_filter)) {
return nullptr;
}
ServoStyleSet* styleSet = aPresShell->StyleSet()->AsServo();
- RefPtr<ServoComputedValues> computedValues =
+ RefPtr<ServoStyleContext> computedValues =
styleSet->ResolveForDeclarations(aParentStyle, declarations);
return computedValues.forget();
}
bool
CanvasRenderingContext2D::ParseFilter(const nsAString& aString,
nsTArray<nsStyleFilter>& aFilterChain,
@@ -3023,36 +3024,36 @@ CanvasRenderingContext2D::ParseFilter(co
}
aFilterChain = sc->StyleEffects()->mFilters;
return true;
}
// For stylo
MOZ_ASSERT(presShell->StyleSet()->IsServo());
- RefPtr<ServoComputedValues> parentStyle =
+ RefPtr<ServoStyleContext> parentStyle =
GetFontStyleForServo(mCanvasElement,
GetFont(),
presShell,
usedFont,
aError);
if (!parentStyle) {
return false;
}
- RefPtr<ServoComputedValues> computedValues =
+ RefPtr<ServoStyleContext> computedValues =
ResolveFilterStyleForServo(aString,
parentStyle,
presShell,
aError);
if (!computedValues) {
return false;
}
- const nsStyleEffects* effects = Servo_GetStyleEffects(computedValues);
+ const nsStyleEffects* effects = Servo_GetStyleEffects(computedValues->ComputedValues());
// XXX: This mFilters is a one shot object, we probably could avoid copying.
aFilterChain = effects->mFilters;
return true;
}
void
CanvasRenderingContext2D::SetFilter(const nsAString& aFilter, ErrorResult& aError)
{
@@ -3950,29 +3951,29 @@ CanvasRenderingContext2D::SetFontInterna
nsCOMPtr<nsIPresShell> presShell = GetPresShell();
if (!presShell) {
aError.Throw(NS_ERROR_FAILURE);
return false;
}
RefPtr<nsStyleContext> sc;
- RefPtr<ServoComputedValues> computedValues;
+ RefPtr<ServoStyleContext> computedValues;
nsString usedFont;
const nsStyleFont* fontStyle;
if (presShell->StyleSet()->IsServo()) {
computedValues = GetFontStyleForServo(mCanvasElement,
aFont,
presShell,
usedFont,
aError);
if (!computedValues) {
return false;
}
- fontStyle = Servo_GetStyleFont(computedValues);
+ fontStyle = Servo_GetStyleFont(computedValues->ComputedValues());
} else {
sc = GetFontStyleContext(mCanvasElement,
aFont,
presShell,
usedFont,
aError);
if (!sc) {
return false;
--- a/layout/base/ServoRestyleManager.cpp
+++ b/layout/base/ServoRestyleManager.cpp
@@ -6,16 +6,17 @@
#include "mozilla/ServoRestyleManager.h"
#include "mozilla/AutoRestyleTimelineMarker.h"
#include "mozilla/AutoTimelineMarker.h"
#include "mozilla/DocumentStyleRootIterator.h"
#include "mozilla/ServoBindings.h"
#include "mozilla/ServoStyleSet.h"
+#include "mozilla/ServoStyleContext.h"
#include "mozilla/Unused.h"
#include "mozilla/ViewportFrame.h"
#include "mozilla/dom/ChildIterator.h"
#include "mozilla/dom/ElementInlines.h"
#include "nsBlockFrame.h"
#include "nsBulletFrame.h"
#include "nsPlaceholderFrame.h"
#include "nsContentUtils.h"
@@ -434,16 +435,17 @@ UpdateFramePseudoElementStyles(nsIFrame*
}
bool
ServoRestyleManager::ProcessPostTraversal(Element* aElement,
nsStyleContext* aParentContext,
ServoRestyleState& aRestyleState)
{
nsIFrame* styleFrame = nsLayoutUtils::GetStyleFrame(aElement);
+ ServoStyleContext* parent = aParentContext ? aParentContext->AsServo() : nullptr;
// NOTE(emilio): This is needed because for table frames the bit is set on the
// table wrapper (which is the primary frame), not on the table itself.
const bool isOutOfFlow =
aElement->GetPrimaryFrame() &&
aElement->GetPrimaryFrame()->HasAnyStateBits(NS_FRAME_OUT_OF_FLOW);
// Grab the change hint from Servo.
@@ -501,31 +503,31 @@ ServoRestyleManager::ProcessPostTraversa
if (!oldStyleContext) {
displayContentsNode =
PresContext()->FrameConstructor()->GetDisplayContentsNodeFor(aElement);
if (displayContentsNode) {
oldStyleContext = displayContentsNode->mStyle->AsServo();
}
}
- RefPtr<ServoComputedValues> computedValues =
+ RefPtr<ServoStyleContext> currentContext =
aRestyleState.StyleSet().ResolveServoStyle(aElement);
// Note that we rely in the fact that we don't cascade pseudo-element styles
// separately right now (that is, if a pseudo style changes, the normal style
// changes too).
//
// Otherwise we should probably encode that information somehow to avoid
// expensive checks in the common case.
//
// Also, we're going to need to check for pseudos of display: contents
// elements, though that is buggy right now even in non-stylo mode, see
// bug 1251799.
const bool recreateContext = oldStyleContext &&
- oldStyleContext->ComputedValues() != computedValues;
+ oldStyleContext->ComputedValues() != currentContext->ComputedValues();
Maybe<ServoRestyleState> thisFrameRestyleState;
if (styleFrame) {
auto type = isOutOfFlow
? ServoRestyleState::Type::OutOfFlow
: ServoRestyleState::Type::InFlow;
thisFrameRestyleState.emplace(*styleFrame, aRestyleState, changeHint, type);
@@ -539,18 +541,22 @@ ServoRestyleManager::ProcessPostTraversa
RefPtr<ServoStyleContext> newContext = nullptr;
if (recreateContext) {
MOZ_ASSERT(styleFrame || displayContentsNode);
auto pseudo = aElement->GetPseudoElementType();
nsIAtom* pseudoTag = pseudo == CSSPseudoElementType::NotPseudo
? nullptr : nsCSSPseudoElements::GetPseudoAtom(pseudo);
- newContext = aRestyleState.StyleSet().GetContext(
- computedValues.forget(), aParentContext, pseudoTag, pseudo, aElement);
+ // XXXManishearth we should just reuse the old one here
+ RefPtr<ServoStyleContext> tempContext =
+ Servo_StyleContext_NewContext(currentContext->ComputedValues(), parent,
+ PresContext(), pseudo, pseudoTag).Consume();
+ newContext = aRestyleState.StyleSet().GetContext(tempContext.forget(), aParentContext,
+ pseudoTag, pseudo, aElement);
newContext->ResolveSameStructsAs(PresContext(), oldStyleContext);
// We want to walk all the continuations here, even the ones with different
// styles. In practice, the only reason we get continuations with different
// styles here is ::first-line (::first-letter never affects element
// styles). But in that case, newContext is the right context for the
// _later_ continuations anyway (the ones not affected by ::first-line), not
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -1920,21 +1920,21 @@ nsCSSFrameConstructor::CreateGeneratedCo
return;
}
// Servo has already eagerly computed the style for the container, so we can
// just stick the style on the element and avoid an additional traversal.
//
// We don't do this for pseudos that may trigger animations or transitions,
// since those need to be kicked off by the traversal machinery.
- bool isServo = pseudoStyleContext->IsServo();
bool hasServoAnimations = false;
- if (isServo) {
- ServoComputedValues* servoStyle = pseudoStyleContext->ComputedValues();
- hasServoAnimations = Servo_ComputedValues_SpecifiesAnimationsOrTransitions(servoStyle);
+ ServoStyleContext* servoStyle = pseudoStyleContext->GetAsServo();
+ if (servoStyle) {
+ hasServoAnimations =
+ Servo_ComputedValues_SpecifiesAnimationsOrTransitions(servoStyle->ComputedValues());
if (!hasServoAnimations) {
Servo_SetExplicitStyle(container, servoStyle);
}
}
// stylo: ServoRestyleManager does not handle transitions yet, and when it
// does it probably won't need to track reframed style contexts to start
// transitions correctly.
@@ -1966,17 +1966,17 @@ nsCSSFrameConstructor::CreateGeneratedCo
container->AppendChildTo(content, false);
if (content->IsElement()) {
createdChildElement = true;
}
}
}
// We may need to do a synchronous servo traversal in various uncommon cases.
- if (isServo) {
+ if (servoStyle) {
if (hasServoAnimations) {
// If animations are involved, we avoid the SetExplicitStyle optimization
// above.
mPresShell->StyleSet()->AsServo()->StyleNewSubtree(container);
} else if (createdChildElement) {
// If we created any children elements, Servo needs to traverse them, but
// the root is already set up.
mPresShell->StyleSet()->AsServo()->StyleNewChildren(container);
@@ -5881,18 +5881,20 @@ nsCSSFrameConstructor::AddFrameConstruct
// XXX: We should have a better way to restyle ourselves.
ServoRestyleManager::ClearServoDataFromSubtree(element);
styleSet->StyleNewSubtree(element);
// Servo's should_traverse_children() in traversal.rs skips
// styling descendants of elements with a -moz-binding the
// first time. Thus call StyleNewChildren() again.
styleSet->StyleNewChildren(element);
+
styleContext =
- styleSet->ResolveStyleFor(element, nullptr, LazyComputeBehavior::Assert);
+ styleSet->ResolveStyleFor(element, styleContext->GetParentAllowServo()->AsServo(),
+ LazyComputeBehavior::Assert);
} else {
styleContext =
ResolveStyleContext(styleContext->GetParent(), aContent, &aState);
}
display = styleContext->StyleDisplay();
aStyleContext = styleContext;
}
--- a/layout/style/GeckoStyleContext.h
+++ b/layout/style/GeckoStyleContext.h
@@ -105,16 +105,40 @@ public:
bool HasNoChildren() const;
nsRuleNode* RuleNode() const {
MOZ_ASSERT(mRuleNode);
return mRuleNode;
}
+ void AddRef() {
+ if (mRefCnt == UINT32_MAX) {
+ NS_WARNING("refcount overflow, leaking object");
+ return;
+ }
+ ++mRefCnt;
+ NS_LOG_ADDREF(this, mRefCnt, "nsStyleContext", sizeof(nsStyleContext));
+ return;
+ }
+
+ void Release() {
+ if (mRefCnt == UINT32_MAX) {
+ NS_WARNING("refcount overflow, leaking object");
+ return;
+ }
+ --mRefCnt;
+ NS_LOG_RELEASE(this, mRefCnt, "nsStyleContext");
+ if (mRefCnt == 0) {
+ Destroy();
+ return;
+ }
+ return;
+ }
+
~GeckoStyleContext() {
Destructor();
}
/**
* Swaps owned style struct pointers between this and aNewContext, on
* the assumption that aNewContext is the new style context for a frame
* and this is the old one. aStructs indicates which structs to consider
--- a/layout/style/ServoBindingList.h
+++ b/layout/style/ServoBindingList.h
@@ -75,19 +75,19 @@ SERVO_BINDING_FUNC(Servo_StyleSet_GetKey
nsTimingFunctionBorrowed timing_function,
RawGeckoKeyframeListBorrowedMut keyframe_list)
SERVO_BINDING_FUNC(Servo_StyleSet_GetFontFaceRules, void,
RawServoStyleSetBorrowed set,
RawGeckoFontFaceRuleListBorrowedMut list)
SERVO_BINDING_FUNC(Servo_StyleSet_GetCounterStyleRule, nsCSSCounterStyleRule*,
RawServoStyleSetBorrowed set, nsIAtom* name)
SERVO_BINDING_FUNC(Servo_StyleSet_ResolveForDeclarations,
- ServoComputedValuesStrong,
+ ServoStyleContextStrong,
RawServoStyleSetBorrowed set,
- ServoComputedValuesBorrowedOrNull parent_style,
+ ServoStyleContextBorrowedOrNull parent_style,
RawServoDeclarationBlockBorrowed declarations)
SERVO_BINDING_FUNC(Servo_StyleSet_MightHaveAttributeDependency, bool,
RawServoStyleSetBorrowed set,
RawGeckoElementBorrowed element,
nsIAtom* local_name)
SERVO_BINDING_FUNC(Servo_StyleSet_HasStateDependency, bool,
RawServoStyleSetBorrowed set,
RawGeckoElementBorrowed element,
@@ -454,77 +454,93 @@ SERVO_BINDING_FUNC(Servo_MediaList_Delet
// CSS supports()
SERVO_BINDING_FUNC(Servo_CSSSupports2, bool,
const nsACString* name, const nsACString* value)
SERVO_BINDING_FUNC(Servo_CSSSupports, bool,
const nsACString* cond)
// Computed style data
SERVO_BINDING_FUNC(Servo_ComputedValues_GetForAnonymousBox,
- ServoComputedValuesStrong,
- ServoComputedValuesBorrowedOrNull parent_style_or_null,
+ ServoStyleContextStrong,
+ ServoStyleContextBorrowedOrNull parent_style_or_null,
+ mozilla::CSSPseudoElementType pseudo_type,
nsIAtom* pseudo_tag,
RawServoStyleSetBorrowed set)
-SERVO_BINDING_FUNC(Servo_ComputedValues_Inherit, ServoComputedValuesStrong,
+SERVO_BINDING_FUNC(Servo_ComputedValues_Inherit, ServoStyleContextStrong,
RawServoStyleSetBorrowed set,
- ServoComputedValuesBorrowedOrNull parent_style,
+ mozilla::CSSPseudoElementType pseudo_type,
+ nsIAtom* pseudo_tag,
+ ServoStyleContextBorrowedOrNull parent_style,
mozilla::InheritTarget target)
SERVO_BINDING_FUNC(Servo_ComputedValues_GetVisitedStyle,
- ServoComputedValuesStrong,
+ ServoStyleContextStrong,
ServoComputedValuesBorrowed values)
SERVO_BINDING_FUNC(Servo_ComputedValues_GetStyleBits, uint64_t,
ServoComputedValuesBorrowed values)
SERVO_BINDING_FUNC(Servo_ComputedValues_EqualCustomProperties, bool,
ServoComputedValuesBorrowed first,
ServoComputedValuesBorrowed second)
// Gets the source style rules for the computed values. This returns
// the result via rules, which would include a list of unowned pointers
// to RawServoStyleRule.
SERVO_BINDING_FUNC(Servo_ComputedValues_GetStyleRuleList, void,
ServoComputedValuesBorrowed values,
RawGeckoServoStyleRuleListBorrowedMut rules)
+SERVO_BINDING_FUNC(Servo_StyleContext_NewContext,
+ ServoStyleContextStrong,
+ ServoComputedValuesBorrowed values,
+ ServoStyleContextBorrowedOrNull parent,
+ RawGeckoPresContextBorrowed pres_context,
+ mozilla::CSSPseudoElementType pseudo_type,
+ nsIAtom* pseudo_tag)
+
+
// Initialize Servo components. Should be called exactly once at startup.
SERVO_BINDING_FUNC(Servo_Initialize, void,
RawGeckoURLExtraData* dummy_url_data)
// Shut down Servo components. Should be called exactly once at shutdown.
SERVO_BINDING_FUNC(Servo_Shutdown, void)
// Restyle and change hints.
SERVO_BINDING_FUNC(Servo_NoteExplicitHints, void, RawGeckoElementBorrowed element,
nsRestyleHint restyle_hint, nsChangeHint change_hint)
SERVO_BINDING_FUNC(Servo_TakeChangeHint, nsChangeHint, RawGeckoElementBorrowed element)
-SERVO_BINDING_FUNC(Servo_ResolveStyle, ServoComputedValuesStrong,
+SERVO_BINDING_FUNC(Servo_ResolveStyle, ServoStyleContextStrong,
RawGeckoElementBorrowed element,
RawServoStyleSetBorrowed set)
-SERVO_BINDING_FUNC(Servo_ResolvePseudoStyle, ServoComputedValuesStrong,
+SERVO_BINDING_FUNC(Servo_ResolvePseudoStyle, ServoStyleContextStrong,
RawGeckoElementBorrowed element,
mozilla::CSSPseudoElementType pseudo_type,
+ nsIAtom* pseudo_tag,
bool is_probe,
ServoComputedValuesBorrowedOrNull inherited_style,
+ ServoStyleContextBorrowedOrNull parent_style_context,
RawServoStyleSetBorrowed set)
SERVO_BINDING_FUNC(Servo_SetExplicitStyle, void,
RawGeckoElementBorrowed element,
- ServoComputedValuesBorrowed primary_style)
+ ServoStyleContextBorrowed primary_style)
SERVO_BINDING_FUNC(Servo_HasAuthorSpecifiedRules, bool,
RawGeckoElementBorrowed element,
uint32_t rule_type_mask,
bool author_colors_allowed)
// Resolves style for an element or pseudo-element without processing pending
// restyles first. The Element and its ancestors may be unstyled, have pending
// restyles, or be in a display:none subtree. Styles are cached when possible,
// 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,
+SERVO_BINDING_FUNC(Servo_ResolveStyleLazily, ServoStyleContextStrong,
RawGeckoElementBorrowed element,
mozilla::CSSPseudoElementType pseudo_type,
+ nsIAtom* pseudo_tag,
+ ServoStyleContextBorrowedOrNull parent_style_context,
mozilla::StyleRuleInclusion rule_inclusion,
const mozilla::ServoElementSnapshotTable* snapshots,
RawServoStyleSetBorrowed set)
// Use ServoStyleSet::PrepareAndTraverseSubtree instead of calling this
// directly
SERVO_BINDING_FUNC(Servo_TraverseSubtree,
bool,
@@ -538,20 +554,20 @@ SERVO_BINDING_FUNC(Servo_TraverseSubtree
SERVO_BINDING_FUNC(Servo_AssertTreeIsClean, void, RawGeckoElementBorrowed root)
// Checks whether the rule tree has crossed its threshold for unused rule nodes,
// and if so, frees them.
SERVO_BINDING_FUNC(Servo_MaybeGCRuleTree, void, RawServoStyleSetBorrowed set)
// Returns computed values for the given element without any animations rules.
SERVO_BINDING_FUNC(Servo_StyleSet_GetBaseComputedValuesForElement,
- ServoComputedValuesStrong,
+ ServoStyleContextStrong,
RawServoStyleSetBorrowed set,
RawGeckoElementBorrowed element,
- ServoComputedValuesBorrowed existing_style,
+ ServoStyleContextBorrowed existing_style,
const mozilla::ServoElementSnapshotTable* snapshots,
mozilla::CSSPseudoElementType pseudo_type)
// For canvas font.
SERVO_BINDING_FUNC(Servo_SerializeFontValueForCanvas, void,
RawServoDeclarationBlockBorrowed declarations,
nsAString* buffer)
@@ -565,17 +581,17 @@ SERVO_BINDING_FUNC(Servo_GetCustomProper
SERVO_BINDING_FUNC(Servo_GetCustomPropertyNameAt, bool,
ServoComputedValuesBorrowed, uint32_t index,
nsAString* name)
// Style-struct management.
#define STYLE_STRUCT(name, checkdata_cb) \
struct nsStyle##name; \
- SERVO_BINDING_FUNC(Servo_GetStyle##name, const nsStyle##name*, \
+ SERVO_BINDING_FUNC(Servo_GetStyle##name, const nsStyle##name*, \
ServoComputedValuesBorrowedOrNull computed_values)
#include "nsStyleStructList.h"
#undef STYLE_STRUCT
// AddRef / Release functions
#define SERVO_ARC_TYPE(name_, type_) \
SERVO_BINDING_FUNC(Servo_##name_##_AddRef, void, type_##Borrowed) \
SERVO_BINDING_FUNC(Servo_##name_##_Release, void, type_##Borrowed)
--- a/layout/style/ServoBindingTypes.h
+++ b/layout/style/ServoBindingTypes.h
@@ -19,16 +19,17 @@ struct RawServoStyleSet;
struct RawServoAnimationValueMap;
#define SERVO_ARC_TYPE(name_, type_) struct type_;
#include "mozilla/ServoArcTypeList.h"
#undef SERVO_ARC_TYPE
namespace mozilla {
class ServoElementSnapshot;
+class ServoStyleContext;
struct StyleAnimation;
struct URLExtraData;
namespace dom {
class Element;
class StyleChildrenIterator;
} // namespace dom
struct AnimationPropertySegment;
struct ComputedTiming;
@@ -97,16 +98,24 @@ typedef mozilla::dom::StyleChildrenItera
struct MOZ_MUST_USE_TYPE type_##Strong \
{ \
type_* mPtr; \
already_AddRefed<type_> Consume(); \
};
#include "mozilla/ServoArcTypeList.h"
#undef SERVO_ARC_TYPE
+typedef mozilla::ServoStyleContext const* ServoStyleContextBorrowed;
+typedef mozilla::ServoStyleContext const* ServoStyleContextBorrowedOrNull;
+struct MOZ_MUST_USE_TYPE ServoStyleContextStrong
+{
+ mozilla::ServoStyleContext* mPtr;
+ already_AddRefed<mozilla::ServoStyleContext> Consume();
+};
+
#define DECL_OWNED_REF_TYPE_FOR(type_) \
typedef type_* type_##Owned; \
DECL_BORROWED_REF_TYPE_FOR(type_) \
DECL_BORROWED_MUT_REF_TYPE_FOR(type_)
#define DECL_NULLABLE_OWNED_REF_TYPE_FOR(type_) \
typedef type_* type_##OwnedOrNull; \
DECL_NULLABLE_BORROWED_REF_TYPE_FOR(type_) \
--- a/layout/style/ServoBindings.cpp
+++ b/layout/style/ServoBindings.cpp
@@ -78,19 +78,19 @@ using namespace mozilla::dom;
#define SERVO_ARC_TYPE(name_, type_) \
already_AddRefed<type_> \
type_##Strong::Consume() { \
RefPtr<type_> result; \
result.swap(mPtr); \
return result.forget(); \
}
#include "mozilla/ServoArcTypeList.h"
+SERVO_ARC_TYPE(StyleContext, ServoStyleContext)
#undef SERVO_ARC_TYPE
-
static Mutex* sServoFontMetricsLock = nullptr;
static RWLock* sServoLangFontPrefsLock = nullptr;
static bool sFramesTimingFunctionEnabled;
static
const nsFont*
ThreadSafeGetDefaultFontHelper(const nsPresContext* aPresContext,
@@ -204,16 +204,36 @@ Gecko_GetAnonymousContentForElement(RawG
void
Gecko_DestroyAnonymousContentList(nsTArray<nsIContent*>* aAnonContent)
{
MOZ_ASSERT(aAnonContent);
delete aAnonContent;
}
void
+Gecko_ServoStyleContext_Init(ServoStyleContext* aContext,
+ const ServoStyleContext* aParentContext,
+ RawGeckoPresContextBorrowed aPresContext, ServoComputedValuesStrong aValues,
+ mozilla::CSSPseudoElementType aPseudoType, nsIAtom* aPseudoTag)
+{
+ // because it is within an Arc it is unsafe for the Rust side to ever
+ // carry around a mutable non opaque reference to the context, so we
+ // cast it here.
+ ServoStyleContext* parent = const_cast<ServoStyleContext*>(aParentContext);
+ nsPresContext* pres = const_cast<nsPresContext*>(aPresContext);
+ new (KnownNotNull, aContext) ServoStyleContext(parent, pres, aPseudoTag, aPseudoType, aValues.Consume());
+}
+
+void
+Gecko_ServoStyleContext_Destroy(ServoStyleContext* aContext)
+{
+ aContext->~ServoStyleContext();
+}
+
+void
Gecko_ConstructStyleChildrenIterator(
RawGeckoElementBorrowed aElement,
RawGeckoStyleChildrenIteratorBorrowedMut aIterator)
{
MOZ_ASSERT(aElement);
MOZ_ASSERT(aIterator);
new (aIterator) StyleChildrenIterator(aElement);
}
@@ -600,18 +620,18 @@ bool
Gecko_StyleAnimationsEquals(RawGeckoStyleAnimationListBorrowed aA,
RawGeckoStyleAnimationListBorrowed aB)
{
return *aA == *aB;
}
void
Gecko_UpdateAnimations(RawGeckoElementBorrowed aElement,
- ServoComputedValuesBorrowedOrNull aOldComputedValues,
- ServoComputedValuesBorrowedOrNull aComputedValues,
+ ServoStyleContextBorrowedOrNull aOldComputedValues,
+ ServoStyleContextBorrowedOrNull aComputedValues,
UpdateAnimationsTasks aTasks)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aElement);
if (!aElement->IsInComposedDoc()) {
return;
}
@@ -639,17 +659,18 @@ Gecko_UpdateAnimations(RawGeckoElementBo
if (!aComputedValues) {
return;
}
if (aTasks & UpdateAnimationsTasks::CSSTransitions) {
MOZ_ASSERT(aOldComputedValues);
presContext->TransitionManager()->
UpdateTransitions(const_cast<dom::Element*>(aElement), pseudoType,
- aOldComputedValues, aComputedValues);
+ aOldComputedValues,
+ aComputedValues);
}
if (aTasks & UpdateAnimationsTasks::EffectProperties) {
presContext->EffectCompositor()->UpdateEffectProperties(
aComputedValues, const_cast<dom::Element*>(aElement), pseudoType);
}
if (aTasks & UpdateAnimationsTasks::CascadeResults) {
--- a/layout/style/ServoBindings.h
+++ b/layout/style/ServoBindings.h
@@ -45,16 +45,17 @@ namespace mozilla {
struct ImageValue;
class LoaderReusableStyleSheets;
};
namespace dom {
enum class IterationCompositeOperation : uint8_t;
};
enum class UpdateAnimationsTasks : uint8_t;
struct LangGroupFontPrefs;
+ class ServoStyleContext;
class ServoStyleSheet;
class ServoElementSnapshotTable;
}
using mozilla::FontFamilyList;
using mozilla::FontFamilyType;
using mozilla::ServoElementSnapshot;
class nsCSSCounterStyleRule;
class nsCSSFontFaceRule;
@@ -135,16 +136,22 @@ bool Gecko_IsSignificantChild(RawGeckoNo
bool text_is_significant,
bool whitespace_is_significant);
RawGeckoNodeBorrowedOrNull Gecko_GetLastChild(RawGeckoNodeBorrowed node);
RawGeckoNodeBorrowedOrNull Gecko_GetFlattenedTreeParentNode(RawGeckoNodeBorrowed node);
RawGeckoElementBorrowedOrNull Gecko_GetBeforeOrAfterPseudo(RawGeckoElementBorrowed element, bool is_before);
nsTArray<nsIContent*>* Gecko_GetAnonymousContentForElement(RawGeckoElementBorrowed element);
void Gecko_DestroyAnonymousContentList(nsTArray<nsIContent*>* anon_content);
+void Gecko_ServoStyleContext_Init(mozilla::ServoStyleContext* context,
+ ServoStyleContextBorrowedOrNull parent_context,
+ RawGeckoPresContextBorrowed pres_context, ServoComputedValuesStrong values,
+ mozilla::CSSPseudoElementType pseudo_type, nsIAtom* pseudo_tag);
+void Gecko_ServoStyleContext_Destroy(mozilla::ServoStyleContext* context);
+
// By default, Servo walks the DOM by traversing the siblings of the DOM-view
// first child. This generally works, but misses anonymous children, which we
// want to traverse during styling. To support these cases, we create an
// optional stack-allocated iterator in aIterator for nodes that need it.
void Gecko_ConstructStyleChildrenIterator(RawGeckoElementBorrowed aElement,
RawGeckoStyleChildrenIteratorBorrowedMut aIterator);
void Gecko_DestroyStyleChildrenIterator(RawGeckoStyleChildrenIteratorBorrowedMut aIterator);
RawGeckoNodeBorrowedOrNull Gecko_GetNextStyleChild(RawGeckoStyleChildrenIteratorBorrowedMut it);
@@ -220,18 +227,18 @@ bool
Gecko_GetAnimationRule(RawGeckoElementBorrowed aElementOrPseudo,
mozilla::EffectCompositor::CascadeLevel aCascadeLevel,
RawServoAnimationValueMapBorrowedMut aAnimationValues);
RawServoDeclarationBlockStrongBorrowedOrNull
Gecko_GetSMILOverrideDeclarationBlock(RawGeckoElementBorrowed element);
bool Gecko_StyleAnimationsEquals(RawGeckoStyleAnimationListBorrowed,
RawGeckoStyleAnimationListBorrowed);
void Gecko_UpdateAnimations(RawGeckoElementBorrowed aElementOrPseudo,
- ServoComputedValuesBorrowedOrNull aOldComputedValues,
- ServoComputedValuesBorrowedOrNull aComputedValues,
+ ServoStyleContextBorrowedOrNull aOldComputedValues,
+ ServoStyleContextBorrowedOrNull aComputedValues,
mozilla::UpdateAnimationsTasks aTasks);
bool Gecko_ElementHasAnimations(RawGeckoElementBorrowed aElementOrPseudo);
bool Gecko_ElementHasCSSAnimations(RawGeckoElementBorrowed aElementOrPseudo);
bool Gecko_ElementHasCSSTransitions(RawGeckoElementBorrowed aElementOrPseudo);
size_t Gecko_ElementTransitions_Length(RawGeckoElementBorrowed aElementOrPseudo);
nsCSSPropertyID Gecko_ElementTransitions_PropertyAt(
RawGeckoElementBorrowed aElementOrPseudo,
size_t aIndex);
--- a/layout/style/ServoBindings.toml
+++ b/layout/style/ServoBindings.toml
@@ -58,16 +58,17 @@ headers = [
"mozilla/ServoElementSnapshotTable.h",
"mozilla/css/ErrorReporter.h",
"mozilla/dom/Element.h",
"mozilla/dom/ChildIterator.h",
"mozilla/dom/NameSpaceConstants.h",
"mozilla/LookAndFeel.h",
"mozilla/ServoBindings.h",
"mozilla/ServoMediaList.h",
+ "mozilla/ServoStyleContext.h",
"nsCSSCounterStyleRule.h",
"nsCSSFontFaceRule.h",
"nsMediaFeatures.h",
"nsMediaList.h",
"nsXBLBinding.h",
]
raw-lines = [
# FIXME(emilio): Incrementally remove these "pub use"s. Probably
@@ -115,18 +116,18 @@ whitelist-vars = [
"kPresContext_.*",
]
whitelist-types = [
"RawGecko.*",
"mozilla::AnimationPropertySegment",
"mozilla::ComputedTiming",
"mozilla::ComputedTimingFunction",
"mozilla::ComputedTimingFunction::BeforeFlag",
- "mozilla::ServoComputedValues2",
"mozilla::ServoElementSnapshot.*",
+ "mozilla::ServoStyleContext",
"mozilla::ServoStyleSheetInner",
"mozilla::CSSPseudoClassType",
"mozilla::css::ErrorReporter",
"mozilla::css::SheetParsingMode",
"mozilla::css::URLMatchingFunction",
"mozilla::dom::IterationCompositeOperation",
"mozilla::dom::StyleChildrenIterator",
"mozilla::HalfCorner",
@@ -241,17 +242,21 @@ whitelist-types = [
"nsStyleXUL",
"nsTArray",
"nsTArrayHeader",
"Position",
"PropertyValuePair",
"Runnable",
"ServoAttrSnapshot",
"ServoBundledURI",
+ "ServoComputedValues",
"ServoElementSnapshot",
+ "ServoStyleContextStrong",
+ "ServoStyleContextBorrowed",
+ "ServoStyleContextBorrowedOrNull",
"SheetParsingMode",
"StaticRefPtr",
"StyleAnimation",
"StyleBasicShape",
"StyleBasicShapeType",
"StyleGeometryBox",
"StyleShapeSource",
"StyleTransition",
@@ -313,33 +318,38 @@ mapped-generic-types = [
{ generic = false, gecko = "ServoNodeData", servo = "AtomicRefCell<ElementData>" },
{ generic = false, gecko = "mozilla::ServoWritingMode", servo = "::logical_geometry::WritingMode" },
{ generic = false, gecko = "mozilla::ServoFontComputationData", servo = "::properties::FontComputationData" },
{ generic = false, gecko = "mozilla::ServoCustomPropertiesMap", servo = "Option<::stylearc::Arc<::custom_properties::CustomPropertiesMap>>" },
{ generic = false, gecko = "mozilla::ServoRuleNode", servo = "Option<::rule_tree::StrongRuleNode>" },
{ generic = false, gecko = "mozilla::ServoVisitedStyle", servo = "Option<::stylearc::Arc<::properties::ComputedValues>>" },
{ generic = false, gecko = "mozilla::ServoComputedValueFlags", servo = "::properties::computed_value_flags::ComputedValueFlags" },
{ generic = true, gecko = "mozilla::ServoRawOffsetArc", servo = "::stylearc::RawOffsetArc" },
+ { generic = false, gecko = "ServoStyleContextStrong", servo = "::gecko_bindings::sugar::ownership::Strong<ServoStyleContext>" },
]
fixups = [
{ pat = "root::nsString", rep = "::nsstring::nsStringRepr" },
]
[bindings]
headers = ["mozilla/ServoBindings.h"]
hide-types = [
"nsACString_internal",
"nsAString_internal",
+ "ServoStyleContextBorrowed",
+ "ServoStyleContextBorrowedOrNull",
]
raw-lines = [
"pub use nsstring::{nsACString, nsAString, nsString, nsStringRepr};",
"use gecko_bindings::structs::nsStyleTransformMatrix;",
"use gecko_bindings::structs::nsTArray;",
"type nsACString_internal = nsACString;",
"type nsAString_internal = nsAString;",
+ "pub type ServoStyleContextBorrowed<'a> = &'a ServoStyleContext;",
+ "pub type ServoStyleContextBorrowedOrNull<'a> = Option<&'a ::properties::ComputedValues>;",
]
whitelist-functions = ["Servo_.*", "Gecko_.*"]
structs-types = [
"mozilla::css::GridTemplateAreasValue",
"mozilla::css::ErrorReporter",
"mozilla::css::ImageValue",
"mozilla::css::URLValue",
"mozilla::css::URLValueData",
@@ -455,16 +465,19 @@ structs-types = [
"nsStyleXUL",
"nsTimingFunction",
"nscolor",
"nscoord",
"nsresult",
"Loader",
"LoaderReusableStyleSheets",
"ServoStyleSheet",
+ "ServoComputedValues",
+ "ServoStyleContext",
+ "ServoStyleContextStrong",
"EffectCompositor_CascadeLevel",
"UpdateAnimationsTasks",
"ParsingMode",
"InheritTarget",
"URLMatchingFunction",
"StyleRuleInclusion",
"nsStyleTransformMatrix::MatrixTransformOperator",
"RawGeckoGfxMatrix4x4",
--- a/layout/style/ServoStyleContext.h
+++ b/layout/style/ServoStyleContext.h
@@ -8,62 +8,59 @@
#define mozilla_ServoStyleContext_h
#include "nsStyleContext.h"
namespace mozilla {
class ServoStyleContext final : public nsStyleContext {
public:
-
- static already_AddRefed<ServoStyleContext>
- Create(nsStyleContext* aParentContext,
- nsPresContext* aPresContext,
- nsIAtom* aPseudoTag,
- mozilla::CSSPseudoElementType aPseudoType,
- already_AddRefed<ServoComputedValues> aComputedValues);
-
ServoStyleContext(nsStyleContext* aParent,
nsPresContext* aPresContext,
nsIAtom* aPseudoTag,
CSSPseudoElementType aPseudoType,
already_AddRefed<ServoComputedValues> aComputedValues);
nsPresContext* PresContext() const {
return mPresContext;
}
ServoComputedValues* ComputedValues() const {
return mSource;
}
+
+ void AddRef() {
+ Servo_StyleContext_AddRef(this);
+ }
+
+ void Release() {
+ Servo_StyleContext_Release(this);
+ }
+
~ServoStyleContext() {
Destructor();
}
/**
* Makes this context match |aOther| in terms of which style structs have
* been resolved.
*/
- void ResolveSameStructsAs(nsPresContext* aPresContext, ServoStyleContext* aOther) {
- // NB: This function is only called on newly-minted style contexts, but
- // those may already have resolved style structs given the SetStyleBits call
- // in FinishConstruction. So we carefully xor out the bits that are new so
- // that we don't call FinishStyle twice.
+ void ResolveSameStructsAs(nsPresContext* aPresContext, const ServoStyleContext* aOther) {
+ // Only resolve structs that are not already resolved in this struct.
uint64_t ourBits = mBits & NS_STYLE_INHERIT_MASK;
uint64_t otherBits = aOther->mBits & NS_STYLE_INHERIT_MASK;
- MOZ_ASSERT((otherBits | ourBits) == otherBits, "otherBits should be a superset");
- uint64_t newBits = (ourBits ^ otherBits) & NS_STYLE_INHERIT_MASK;
+ uint64_t newBits = otherBits & ~ourBits & NS_STYLE_INHERIT_MASK;
-#define STYLE_STRUCT(name_, checkdata_cb) \
+ #define STYLE_STRUCT(name_, checkdata_cb) \
if (nsStyle##name_::kHasFinishStyle && newBits & NS_STYLE_INHERIT_BIT(name_)) { \
const nsStyle##name_* data = Servo_GetStyle##name_(ComputedValues()); \
const_cast<nsStyle##name_*>(data)->FinishStyle(aPresContext); \
}
-#include "nsStyleStructList.h"
-#undef STYLE_STRUCT
+ #include "nsStyleStructList.h"
+ #undef STYLE_STRUCT
mBits |= newBits;
}
private:
nsPresContext* mPresContext;
RefPtr<ServoComputedValues> mSource;
};
--- a/layout/style/ServoStyleSet.cpp
+++ b/layout/style/ServoStyleSet.cpp
@@ -184,80 +184,85 @@ ServoStyleSet::GetContext(nsIContent* aC
nsStyleContext* aParentContext,
nsIAtom* aPseudoTag,
CSSPseudoElementType aPseudoType,
LazyComputeBehavior aMayCompute)
{
MOZ_ASSERT(aContent->IsElement());
Element* element = aContent->AsElement();
- RefPtr<ServoComputedValues> computedValues;
+ RefPtr<ServoStyleContext> computedValues;
+ ServoStyleContext* parent = aParentContext ? aParentContext->AsServo() : nullptr;
if (aMayCompute == LazyComputeBehavior::Allow) {
PreTraverseSync();
- computedValues =
- ResolveStyleLazily(element, CSSPseudoElementType::NotPseudo);
+ RefPtr<ServoStyleContext> tmp =
+ ResolveStyleLazily(element, CSSPseudoElementType::NotPseudo, aPseudoTag, parent);
+ computedValues = GetContext(tmp.forget(), parent, aPseudoTag, aPseudoType,
+ element);
} else {
computedValues = ResolveServoStyle(element);
}
MOZ_ASSERT(computedValues);
- return GetContext(computedValues.forget(), aParentContext, aPseudoTag, aPseudoType,
- element);
+ return computedValues.forget();
}
already_AddRefed<ServoStyleContext>
-ServoStyleSet::GetContext(already_AddRefed<ServoComputedValues> aComputedValues,
+ServoStyleSet::GetContext(already_AddRefed<ServoStyleContext> aComputedValues,
nsStyleContext* aParentContext,
nsIAtom* aPseudoTag,
CSSPseudoElementType aPseudoType,
Element* aElementForAnimation)
{
bool isLink = false;
bool isVisitedLink = false;
// If we need visited styles for callers where `aElementForAnimation` is null,
// we can precompute these and pass them as flags, similar to nsStyleSet.cpp.
if (aElementForAnimation) {
isLink = nsCSSRuleProcessor::IsLink(aElementForAnimation);
isVisitedLink = nsCSSRuleProcessor::GetContentState(aElementForAnimation)
.HasState(NS_EVENT_STATE_VISITED);
}
- RefPtr<ServoComputedValues> computedValues = Move(aComputedValues);
- RefPtr<ServoComputedValues> visitedComputedValues =
+ RefPtr<ServoStyleContext> result = Move(aComputedValues);
+ RefPtr<ServoComputedValues> computedValues = result->ComputedValues();
+
+ MOZ_ASSERT(result->GetPseudoType() == aPseudoType);
+ MOZ_ASSERT(result->GetPseudo() == aPseudoTag);
+
+ RefPtr<ServoStyleContext> resultIfVisited =
Servo_ComputedValues_GetVisitedStyle(computedValues).Consume();
- // If `visitedComputedValues` is non-null, then there was a relevant link and
+ // If `resultIfVisited` is non-null, then there was a relevant link and
// visited styles were computed. This corresponds to the cases where Gecko's
// style system produces `aVisitedRuleNode`.
// Set up `parentIfVisited` depending on whether our parent context has a
// a visited style. If it doesn't but we do have visited styles, use the
// regular parent context for visited.
nsStyleContext *parentIfVisited =
aParentContext ? aParentContext->GetStyleIfVisited() : nullptr;
if (!parentIfVisited) {
- if (visitedComputedValues) {
+ if (resultIfVisited) {
parentIfVisited = aParentContext;
}
}
+ ServoStyleContext* parentIfVisitedServo = parentIfVisited ? parentIfVisited->AsServo() : nullptr;
+
// The true visited state of the relevant link is used to decided whether
// visited styles should be consulted for all visited dependent properties.
bool relevantLinkVisited = isLink ? isVisitedLink :
(aParentContext && aParentContext->RelevantLinkVisited());
- RefPtr<ServoStyleContext> result =
- ServoStyleContext::Create(aParentContext, mPresContext, aPseudoTag, aPseudoType,
- computedValues.forget());
-
- if (visitedComputedValues) {
- RefPtr<ServoStyleContext> resultIfVisited =
- ServoStyleContext::Create(parentIfVisited, mPresContext, aPseudoTag, aPseudoType,
- visitedComputedValues.forget());
- resultIfVisited->SetIsStyleIfVisited();
- result->SetStyleIfVisited(resultIfVisited.forget());
+ if (resultIfVisited) {
+ RefPtr<ServoStyleContext> visitedContext =
+ Servo_StyleContext_NewContext(resultIfVisited->ComputedValues(), parentIfVisitedServo,
+ mPresContext, aPseudoType, aPseudoTag).Consume();
+ visitedContext->SetIsStyleIfVisited();
+ result->SetStyleIfVisited(visitedContext.forget());
if (relevantLinkVisited) {
result->AddStyleBit(NS_STYLE_RELEVANT_LINK_VISITED);
}
}
// Set the body color on the pres context. See nsStyleSet::GetContext
if (aElementForAnimation &&
@@ -439,36 +444,36 @@ ServoStyleSet::ResolveStyleForText(nsICo
MOZ_ASSERT(aTextNode && aTextNode->IsNodeOfType(nsINode::eTEXT));
MOZ_ASSERT(aTextNode->GetParent());
MOZ_ASSERT(aParentContext);
// Gecko expects text node style contexts to be like elements that match no
// rules: inherit the inherit structs, reset the reset structs. This is cheap
// enough to do on the main thread, which means that the parallel style system
// can avoid worrying about text nodes.
- const ServoComputedValues* parentComputedValues =
- aParentContext->ComputedValues();
- RefPtr<ServoComputedValues> computedValues =
+ RefPtr<ServoStyleContext> computedValues =
Servo_ComputedValues_Inherit(mRawSet.get(),
- parentComputedValues,
+ CSSPseudoElementType::InheritingAnonBox,
+ nsCSSAnonBoxes::mozText,
+ aParentContext->AsServo(),
InheritTarget::Text).Consume();
-
return GetContext(computedValues.forget(), aParentContext,
nsCSSAnonBoxes::mozText,
CSSPseudoElementType::InheritingAnonBox,
nullptr);
}
already_AddRefed<nsStyleContext>
ServoStyleSet::ResolveStyleForFirstLetterContinuation(nsStyleContext* aParentContext)
{
- const ServoComputedValues* parent =
- aParentContext->ComputedValues();
- RefPtr<ServoComputedValues> computedValues =
+ ServoStyleContext* parent = aParentContext ? aParentContext->AsServo() : nullptr;
+ RefPtr<ServoStyleContext> computedValues =
Servo_ComputedValues_Inherit(mRawSet.get(),
+ CSSPseudoElementType::InheritingAnonBox,
+ nsCSSAnonBoxes::firstLetterContinuation,
parent,
InheritTarget::FirstLetterContinuation)
.Consume();
MOZ_ASSERT(computedValues);
return GetContext(computedValues.forget(), aParentContext,
nsCSSAnonBoxes::firstLetterContinuation,
CSSPseudoElementType::InheritingAnonBox,
@@ -480,18 +485,20 @@ ServoStyleSet::ResolveStyleForPlaceholde
{
RefPtr<nsStyleContext>& cache =
mNonInheritingStyleContexts[nsCSSAnonBoxes::NonInheriting::oofPlaceholder];
if (cache) {
RefPtr<nsStyleContext> retval = cache;
return retval.forget();
}
- RefPtr<ServoComputedValues> computedValues =
+ RefPtr<ServoStyleContext> computedValues =
Servo_ComputedValues_Inherit(mRawSet.get(),
+ CSSPseudoElementType::NonInheritingAnonBox,
+ nsCSSAnonBoxes::oofPlaceholder,
nullptr,
InheritTarget::PlaceholderFrame)
.Consume();
MOZ_ASSERT(computedValues);
RefPtr<nsStyleContext> retval =
GetContext(computedValues.forget(), nullptr,
nsCSSAnonBoxes::oofPlaceholder,
@@ -506,81 +513,84 @@ ServoStyleSet::ResolvePseudoElementStyle
CSSPseudoElementType aType,
nsStyleContext* aParentContext,
Element* aPseudoElement)
{
UpdateStylistIfNeeded();
MOZ_ASSERT(aType < CSSPseudoElementType::Count);
- RefPtr<ServoComputedValues> computedValues;
+ RefPtr<ServoStyleContext> computedValues;
+
+ nsIAtom* pseudoTag = nsCSSPseudoElements::GetPseudoAtom(aType);
if (aPseudoElement) {
MOZ_ASSERT(aType == aPseudoElement->GetPseudoElementType());
computedValues = Servo_ResolveStyle(aPseudoElement,
mRawSet.get()).Consume();
} else {
const ServoComputedValues* parentStyle =
aParentContext ? aParentContext->ComputedValues() : nullptr;
+ ServoStyleContext* parent = aParentContext ? aParentContext->AsServo() : nullptr;
computedValues =
Servo_ResolvePseudoStyle(aOriginatingElement,
aType,
+ pseudoTag,
/* is_probe = */ false,
parentStyle,
+ parent,
mRawSet.get()).Consume();
}
MOZ_ASSERT(computedValues);
bool isBeforeOrAfter = aType == CSSPseudoElementType::before ||
aType == CSSPseudoElementType::after;
- nsIAtom* pseudoTag = nsCSSPseudoElements::GetPseudoAtom(aType);
return GetContext(computedValues.forget(), aParentContext, pseudoTag, aType,
isBeforeOrAfter ? aOriginatingElement : nullptr);
}
already_AddRefed<nsStyleContext>
ServoStyleSet::ResolveTransientStyle(Element* aElement,
+ CSSPseudoElementType aPseudoType,
nsIAtom* aPseudoTag,
- CSSPseudoElementType aPseudoType,
StyleRuleInclusion aRuleInclusion)
{
- RefPtr<ServoComputedValues> computedValues =
- ResolveTransientServoStyle(aElement, aPseudoType, aRuleInclusion);
-
- return GetContext(computedValues.forget(),
+ RefPtr<ServoStyleContext> result =
+ ResolveTransientServoStyle(aElement, aPseudoType, aPseudoTag, aRuleInclusion);
+ return GetContext(result.forget(),
nullptr,
aPseudoTag,
aPseudoType, nullptr);
}
-already_AddRefed<ServoComputedValues>
+already_AddRefed<ServoStyleContext>
ServoStyleSet::ResolveTransientServoStyle(
Element* aElement,
CSSPseudoElementType aPseudoType,
+ nsIAtom* aPseudoTag,
StyleRuleInclusion aRuleInclusion)
{
PreTraverseSync();
- return ResolveStyleLazily(aElement, aPseudoType, aRuleInclusion);
+ return ResolveStyleLazily(aElement, aPseudoType, aPseudoTag, nullptr, aRuleInclusion);
}
already_AddRefed<ServoStyleContext>
ServoStyleSet::ResolveInheritingAnonymousBoxStyle(nsIAtom* aPseudoTag,
nsStyleContext* aParentContext)
{
MOZ_ASSERT(nsCSSAnonBoxes::IsAnonBox(aPseudoTag) &&
!nsCSSAnonBoxes::IsNonInheritingAnonBox(aPseudoTag));
UpdateStylistIfNeeded();
- const ServoComputedValues* parentStyle =
- aParentContext ? aParentContext->ComputedValues()
- : nullptr;
- RefPtr<ServoComputedValues> computedValues =
- Servo_ComputedValues_GetForAnonymousBox(parentStyle, aPseudoTag,
+ ServoStyleContext* parent = aParentContext ? aParentContext->AsServo() : nullptr;
+ RefPtr<ServoStyleContext> computedValues =
+ Servo_ComputedValues_GetForAnonymousBox(parent, CSSPseudoElementType::InheritingAnonBox,
+ aPseudoTag,
mRawSet.get()).Consume();
#ifdef DEBUG
if (!computedValues) {
nsString pseudo;
aPseudoTag->ToString(pseudo);
NS_ERROR(nsPrintfCString("stylo: could not get anon-box: %s",
NS_ConvertUTF16toUTF8(pseudo).get()).get());
MOZ_CRASH();
@@ -613,18 +623,19 @@ ServoStyleSet::ResolveNonInheritingAnony
UpdateStylistIfNeeded();
// We always want to skip parent-based display fixup here. It never makes
// sense for non-inheriting anonymous boxes. (Static assertions in
// nsCSSAnonBoxes.cpp ensure that all non-inheriting non-anonymous boxes
// are indeed annotated as skipping this fixup.)
MOZ_ASSERT(!nsCSSAnonBoxes::IsNonInheritingAnonBox(nsCSSAnonBoxes::viewport),
"viewport needs fixup to handle blockifying it");
- RefPtr<ServoComputedValues> computedValues =
- Servo_ComputedValues_GetForAnonymousBox(nullptr, aPseudoTag,
+ RefPtr<ServoStyleContext> computedValues =
+ Servo_ComputedValues_GetForAnonymousBox(nullptr, CSSPseudoElementType::NonInheritingAnonBox,
+ aPseudoTag,
mRawSet.get()).Consume();
#ifdef DEBUG
if (!computedValues) {
nsString pseudo;
aPseudoTag->ToString(pseudo);
NS_ERROR(nsPrintfCString("stylo: could not get anon-box: %s",
NS_ConvertUTF16toUTF8(pseudo).get()).get());
MOZ_CRASH();
@@ -843,41 +854,43 @@ ServoStyleSet::ProbePseudoElementStyle(E
UpdateStylistIfNeeded();
// NB: We ignore aParentContext, because in some cases
// (first-line/first-letter on anonymous box blocks) Gecko passes something
// nonsensical there. In all other cases we want to inherit directly from
// aOriginatingElement's styles anyway.
MOZ_ASSERT(aType < CSSPseudoElementType::Count);
- RefPtr<ServoComputedValues> computedValues =
- Servo_ResolvePseudoStyle(aOriginatingElement, aType,
+ nsIAtom* pseudoTag = nsCSSPseudoElements::GetPseudoAtom(aType);
+ ServoStyleContext* parent = aParentContext ? aParentContext->AsServo() : nullptr;
+ RefPtr<ServoStyleContext> computedValues =
+ Servo_ResolvePseudoStyle(aOriginatingElement, aType, pseudoTag,
/* is_probe = */ true,
nullptr,
+ parent,
mRawSet.get()).Consume();
if (!computedValues) {
return nullptr;
}
// For :before and :after pseudo-elements, having display: none or no
// 'content' property is equivalent to not having the pseudo-element
// at all.
bool isBeforeOrAfter = aType == CSSPseudoElementType::before ||
aType == CSSPseudoElementType::after;
if (isBeforeOrAfter) {
- const nsStyleDisplay* display = Servo_GetStyleDisplay(computedValues);
- const nsStyleContent* content = Servo_GetStyleContent(computedValues);
+ const nsStyleDisplay* display = Servo_GetStyleDisplay(computedValues->ComputedValues());
+ const nsStyleContent* content = Servo_GetStyleContent(computedValues->ComputedValues());
// XXXldb What is contentCount for |content: ""|?
if (display->mDisplay == StyleDisplay::None ||
content->ContentCount() == 0) {
return nullptr;
}
}
- nsIAtom* pseudoTag = nsCSSPseudoElements::GetPseudoAtom(aType);
return GetContext(computedValues.forget(), aParentContext, pseudoTag, aType,
isBeforeOrAfter ? aOriginatingElement : nullptr);
}
nsRestyleHint
ServoStyleSet::HasStateDependentStyle(dom::Element* aElement,
EventStates aStateMask)
{
@@ -1091,25 +1104,23 @@ ServoStyleSet::GetAnimationValues(
already_AddRefed<ServoStyleContext>
ServoStyleSet::GetBaseContextForElement(
Element* aElement,
nsStyleContext* aParentContext,
nsPresContext* aPresContext,
nsIAtom* aPseudoTag,
CSSPseudoElementType aPseudoType,
- ServoComputedValuesBorrowed aStyle)
+ const ServoStyleContext* aStyle)
{
- RefPtr<ServoComputedValues> cv = Servo_StyleSet_GetBaseComputedValuesForElement(mRawSet.get(),
+ return Servo_StyleSet_GetBaseComputedValuesForElement(mRawSet.get(),
aElement,
aStyle,
&Snapshots(),
aPseudoType).Consume();
- return ServoStyleContext::Create(nullptr, aPresContext, aPseudoTag,
- aPseudoType, cv.forget());
}
already_AddRefed<RawServoAnimationValue>
ServoStyleSet::ComputeAnimationValue(
Element* aElement,
RawServoDeclarationBlock* aDeclarations,
ServoComputedValuesBorrowed aComputedValues)
{
@@ -1166,34 +1177,36 @@ ServoStyleSet::ClearDataAndMarkDeviceDir
}
void
ServoStyleSet::CompatibilityModeChanged()
{
Servo_StyleSet_CompatModeChanged(mRawSet.get());
}
-already_AddRefed<ServoComputedValues>
+already_AddRefed<ServoStyleContext>
ServoStyleSet::ResolveServoStyle(Element* aElement)
{
UpdateStylistIfNeeded();
return Servo_ResolveStyle(aElement, mRawSet.get()).Consume();
}
void
ServoStyleSet::ClearNonInheritingStyleContexts()
{
for (RefPtr<nsStyleContext>& ptr : mNonInheritingStyleContexts) {
ptr = nullptr;
}
}
-already_AddRefed<ServoComputedValues>
+already_AddRefed<ServoStyleContext>
ServoStyleSet::ResolveStyleLazily(Element* aElement,
CSSPseudoElementType aPseudoType,
+ nsIAtom* aPseudoTag,
+ const ServoStyleContext* aParentContext,
StyleRuleInclusion aRuleInclusion)
{
mPresContext->EffectCompositor()->PreTraverse(aElement, aPseudoType);
MOZ_ASSERT(!StylistNeedsUpdate());
AutoSetInServoTraversal guard(this);
/**
@@ -1216,27 +1229,31 @@ ServoStyleSet::ResolveStyleLazily(Elemen
}
} else if (aPseudoType == CSSPseudoElementType::after) {
if (Element* pseudo = nsLayoutUtils::GetAfterPseudo(aElement)) {
elementForStyleResolution = pseudo;
pseudoTypeForStyleResolution = CSSPseudoElementType::NotPseudo;
}
}
- RefPtr<ServoComputedValues> computedValues =
+ RefPtr<ServoStyleContext> computedValues =
Servo_ResolveStyleLazily(elementForStyleResolution,
pseudoTypeForStyleResolution,
+ aPseudoTag,
+ aParentContext,
aRuleInclusion,
&Snapshots(),
mRawSet.get()).Consume();
if (mPresContext->EffectCompositor()->PreTraverse(aElement, aPseudoType)) {
computedValues =
Servo_ResolveStyleLazily(elementForStyleResolution,
pseudoTypeForStyleResolution,
+ aPseudoTag,
+ aParentContext,
aRuleInclusion,
&Snapshots(),
mRawSet.get()).Consume();
}
return computedValues.forget();
}
@@ -1249,19 +1266,19 @@ ServoStyleSet::AppendFontFaceRules(nsTAr
}
nsCSSCounterStyleRule*
ServoStyleSet::CounterStyleRuleForName(nsIAtom* aName)
{
return Servo_StyleSet_GetCounterStyleRule(mRawSet.get(), aName);
}
-already_AddRefed<ServoComputedValues>
+already_AddRefed<ServoStyleContext>
ServoStyleSet::ResolveForDeclarations(
- ServoComputedValuesBorrowedOrNull aParentOrNull,
+ const ServoStyleContext* aParentOrNull,
RawServoDeclarationBlockBorrowed aDeclarations)
{
UpdateStylistIfNeeded();
return Servo_StyleSet_ResolveForDeclarations(mRawSet.get(),
aParentOrNull,
aDeclarations).Consume();
}
--- a/layout/style/ServoStyleSet.h
+++ b/layout/style/ServoStyleSet.h
@@ -183,26 +183,27 @@ public:
dom::Element* aPseudoElement);
// 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,
+ CSSPseudoElementType aPseudoType,
nsIAtom* aPseudoTag,
- CSSPseudoElementType aPseudoType,
StyleRuleInclusion aRules =
StyleRuleInclusion::All);
// Similar to ResolveTransientStyle() but returns ServoComputedValues.
// Unlike ResolveServoStyle() this function calls PreTraverseSync().
- already_AddRefed<ServoComputedValues>
+ already_AddRefed<ServoStyleContext>
ResolveTransientServoStyle(dom::Element* aElement,
- CSSPseudoElementType aPseudoTag,
+ CSSPseudoElementType aPseudoType,
+ nsIAtom* 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<ServoStyleContext>
ResolveInheritingAnonymousBoxStyle(nsIAtom* aPseudoTag,
@@ -356,17 +357,17 @@ public:
* Notifies the Servo stylesheet that the document's compatibility mode has changed.
*/
void CompatibilityModeChanged();
/**
* Resolve style for the given element, and return it as a
* ServoComputedValues, not an nsStyleContext.
*/
- already_AddRefed<ServoComputedValues> ResolveServoStyle(dom::Element* aElement);
+ already_AddRefed<ServoStyleContext> ResolveServoStyle(dom::Element* aElement);
bool GetKeyframesForName(const nsString& aName,
const nsTimingFunction& aTimingFunction,
nsTArray<Keyframe>& aKeyframes);
nsTArray<ComputedKeyframeValues>
GetComputedKeyframeValuesFor(const nsTArray<Keyframe>& aKeyframes,
dom::Element* aElement,
@@ -383,25 +384,25 @@ public:
nsCSSCounterStyleRule* CounterStyleRuleForName(nsIAtom* aName);
already_AddRefed<ServoStyleContext>
GetBaseContextForElement(dom::Element* aElement,
nsStyleContext* aParentContext,
nsPresContext* aPresContext,
nsIAtom* aPseudoTag,
CSSPseudoElementType aPseudoType,
- ServoComputedValuesBorrowed aStyle);
+ const ServoStyleContext* aStyle);
/**
* Resolve style for a given declaration block with/without the parent style.
* If the parent style is not specified, the document default computed values
* is used.
*/
- already_AddRefed<ServoComputedValues>
- ResolveForDeclarations(ServoComputedValuesBorrowedOrNull aParentOrNull,
+ already_AddRefed<ServoStyleContext>
+ ResolveForDeclarations(const ServoStyleContext* aParentOrNull,
RawServoDeclarationBlockBorrowed aDeclarations);
already_AddRefed<RawServoAnimationValue>
ComputeAnimationValue(dom::Element* aElement,
RawServoDeclarationBlock* aDeclaration,
ServoComputedValuesBorrowed aComputedValues);
void AppendTask(PostTraversalTask aTask)
@@ -472,17 +473,17 @@ private:
sInServoTraversal = nullptr;
mSet->RunPostTraversalTasks();
}
private:
ServoStyleSet* mSet;
};
- already_AddRefed<ServoStyleContext> GetContext(already_AddRefed<ServoComputedValues>,
+ already_AddRefed<ServoStyleContext> GetContext(already_AddRefed<ServoStyleContext>,
nsStyleContext* aParentContext,
nsIAtom* aPseudoTag,
CSSPseudoElementType aPseudoType,
dom::Element* aElementForAnimation);
already_AddRefed<ServoStyleContext> GetContext(nsIContent* aContent,
nsStyleContext* aParentContext,
nsIAtom* aPseudoTag,
@@ -554,19 +555,21 @@ private:
/**
* Update the stylist as needed to ensure style data is up-to-date.
*
* This should only be called if StylistNeedsUpdate returns true.
*/
void UpdateStylist();
- already_AddRefed<ServoComputedValues>
+ already_AddRefed<ServoStyleContext>
ResolveStyleLazily(dom::Element* aElement,
CSSPseudoElementType aPseudoType,
+ nsIAtom* aPseudoTag,
+ const ServoStyleContext* aParentContext,
StyleRuleInclusion aRules =
StyleRuleInclusion::All);
void RunPostTraversalTasks();
void PrependSheetOfType(SheetType aType,
ServoStyleSheet* aSheet);
--- a/layout/style/ServoTypes.h
+++ b/layout/style/ServoTypes.h
@@ -160,43 +160,43 @@ struct ServoComputedValueFlags {
};
#define STYLE_STRUCT(name_, checkdata_cb_) struct Gecko##name_;
#define STYLE_STRUCT_LIST_IGNORE_VARIABLES
#include "nsStyleStructList.h"
#undef STYLE_STRUCT
#undef STYLE_STRUCT_LIST_IGNORE_VARIABLES
+} // namespace mozilla
+
/**
* We want C++ to be abe to read the style struct fields of ComputedValues
* so we define this type on the C++ side and use the bindgenned version
* on the Rust side.
*
* C++ just sees pointers and opaque types here, so bindgen will attempt to generate a Copy
* impl. This will fail because the bindgenned version contains owned types. Opt out.
*
* <div rustbindgen nocopy></div>
*/
-struct ServoComputedValues2 {
-#define STYLE_STRUCT(name_, checkdata_cb_) ServoRawOffsetArc<Gecko##name_> name_;
+struct ServoComputedValues {
+#define STYLE_STRUCT(name_, checkdata_cb_) mozilla::ServoRawOffsetArc<mozilla::Gecko##name_> name_;
#define STYLE_STRUCT_LIST_IGNORE_VARIABLES
#include "nsStyleStructList.h"
#undef STYLE_STRUCT
#undef STYLE_STRUCT_LIST_IGNORE_VARIABLES
- ServoCustomPropertiesMap custom_properties;
- ServoWritingMode writing_mode;
- ServoFontComputationData font_computation_data;
+ mozilla::ServoCustomPropertiesMap custom_properties;
+ mozilla::ServoWritingMode writing_mode;
+ mozilla::ServoFontComputationData font_computation_data;
/// The rule node representing the ordered list of rules matched for this
/// node. Can be None for default values and text nodes. This is
/// essentially an optimization to avoid referencing the root rule node.
- ServoRuleNode rules;
+ mozilla::ServoRuleNode rules;
/// The element's computed values if visited, only computed if there's a
/// relevant link for this element. A element's "relevant link" is the
/// element being matched if it is a link or the nearest ancestor link.
- ServoVisitedStyle visited_style;
- ServoComputedValueFlags flags;
- ~ServoComputedValues2() {} // do nothing, but prevent Copy from being impl'd by bindgen
+ mozilla::ServoVisitedStyle visited_style;
+ mozilla::ServoComputedValueFlags flags;
+ ~ServoComputedValues() {} // do nothing, but prevent Copy from being impl'd by bindgen
};
-} // namespace mozilla
-
#endif // mozilla_ServoTypes_h
--- a/layout/style/nsAnimationManager.cpp
+++ b/layout/style/nsAnimationManager.cpp
@@ -399,41 +399,41 @@ ResolvedStyleCache::Get(nsPresContext *a
mCache.Put(aKeyframeDeclaration, resultStrong);
result = resultStrong;
}
return result;
}
class MOZ_STACK_CLASS ServoCSSAnimationBuilder final {
public:
- explicit ServoCSSAnimationBuilder(const ServoComputedValues* aComputedValues)
- : mComputedValues(aComputedValues)
+ explicit ServoCSSAnimationBuilder(const ServoStyleContext* aStyleContext)
+ : mStyleContext(aStyleContext)
{
- MOZ_ASSERT(aComputedValues);
+ MOZ_ASSERT(aStyleContext);
}
bool BuildKeyframes(nsPresContext* aPresContext,
const StyleAnimation& aSrc,
nsTArray<Keyframe>& aKeyframes)
{
ServoStyleSet* styleSet = aPresContext->StyleSet()->AsServo();
MOZ_ASSERT(styleSet);
const nsTimingFunction& timingFunction = aSrc.GetTimingFunction();
return styleSet->GetKeyframesForName(aSrc.GetName(),
timingFunction,
aKeyframes);
}
void SetKeyframes(KeyframeEffectReadOnly& aEffect,
nsTArray<Keyframe>&& aKeyframes)
{
- aEffect.SetKeyframes(Move(aKeyframes), mComputedValues);
+ aEffect.SetKeyframes(Move(aKeyframes), mStyleContext);
}
private:
- const ServoComputedValues* mComputedValues;
+ const ServoStyleContext* mStyleContext;
};
class MOZ_STACK_CLASS GeckoCSSAnimationBuilder final {
public:
GeckoCSSAnimationBuilder(nsStyleContext* aStyleContext,
const NonOwningAnimationTarget& aTarget)
: mStyleContext(aStyleContext)
, mTarget(aTarget)
@@ -443,17 +443,17 @@ public:
}
bool BuildKeyframes(nsPresContext* aPresContext,
const StyleAnimation& aSrc,
nsTArray<Keyframe>& aKeyframs);
void SetKeyframes(KeyframeEffectReadOnly& aEffect,
nsTArray<Keyframe>&& aKeyframes)
{
- aEffect.SetKeyframes(Move(aKeyframes), mStyleContext);
+ aEffect.SetKeyframes(Move(aKeyframes), mStyleContext->AsGecko());
}
private:
nsTArray<Keyframe> BuildAnimationFrames(nsPresContext* aPresContext,
const StyleAnimation& aSrc,
const nsCSSKeyframesRule* aRule);
Maybe<ComputedTimingFunction> GetKeyframeTimingFunction(
nsPresContext* aPresContext,
@@ -985,17 +985,17 @@ BuildAnimations(nsPresContext* aPresCont
dest->SetAnimationIndex(static_cast<uint64_t>(animIdx));
result.AppendElement(dest);
}
return result;
}
void
-nsAnimationManager::UpdateAnimations(nsStyleContext* aStyleContext,
+nsAnimationManager::UpdateAnimations(GeckoStyleContext* aStyleContext,
mozilla::dom::Element* aElement)
{
MOZ_ASSERT(mPresContext->IsDynamic(),
"Should not update animations for print or print preview");
MOZ_ASSERT(aElement->IsInComposedDoc(),
"Should not update animations that are not attached to the "
"document tree");
@@ -1010,37 +1010,37 @@ nsAnimationManager::UpdateAnimations(nsS
const nsStyleDisplay* disp = aStyleContext->StyleDisplay();
DoUpdateAnimations(target, *disp, builder);
}
void
nsAnimationManager::UpdateAnimations(
dom::Element* aElement,
CSSPseudoElementType aPseudoType,
- const ServoComputedValues* aComputedValues)
+ const ServoStyleContext* aStyleContext)
{
MOZ_ASSERT(mPresContext->IsDynamic(),
"Should not update animations for print or print preview");
MOZ_ASSERT(aElement->IsInComposedDoc(),
"Should not update animations that are not attached to the "
"document tree");
- if (!aComputedValues) {
+ if (!aStyleContext) {
// If we are in a display:none subtree we will have no computed values.
// Since CSS animations should not run in display:none subtrees we should
// stop (actually, destroy) any animations on this element here.
StopAnimationsForElement(aElement, aPseudoType);
return;
}
NonOwningAnimationTarget target(aElement, aPseudoType);
- ServoCSSAnimationBuilder builder(aComputedValues);
+ ServoCSSAnimationBuilder builder(aStyleContext);
const nsStyleDisplay *disp =
- Servo_GetStyleDisplay(aComputedValues);
+ Servo_GetStyleDisplay(aStyleContext->ComputedValues());
DoUpdateAnimations(target, *disp, builder);
}
template<class BuilderType>
void
nsAnimationManager::DoUpdateAnimations(
const NonOwningAnimationTarget& aTarget,
const nsStyleDisplay& aStyleDisplay,
--- a/layout/style/nsAnimationManager.h
+++ b/layout/style/nsAnimationManager.h
@@ -27,16 +27,19 @@ class Declaration;
namespace dom {
class KeyframeEffectReadOnly;
class Promise;
} /* namespace dom */
enum class CSSPseudoElementType : uint8_t;
struct NonOwningAnimationTarget;
+class GeckoStyleContext;
+class ServoStyleContext;
+
struct AnimationEventInfo {
RefPtr<dom::Element> mElement;
RefPtr<dom::Animation> mAnimation;
InternalAnimationEvent mEvent;
TimeStamp mTimeStamp;
AnimationEventInfo(dom::Element* aElement,
CSSPseudoElementType aPseudoType,
@@ -318,27 +321,27 @@ public:
/**
* Update the set of animations on |aElement| based on |aStyleContext|.
* If necessary, this will notify the corresponding EffectCompositor so
* that it can update its animation rule.
*
* aStyleContext may be a style context for aElement or for its
* :before or :after pseudo-element.
*/
- void UpdateAnimations(nsStyleContext* aStyleContext,
+ void UpdateAnimations(mozilla::GeckoStyleContext* aStyleContext,
mozilla::dom::Element* aElement);
/**
* This function does the same thing as the above UpdateAnimations()
* but with servo's computed values.
*/
void UpdateAnimations(
mozilla::dom::Element* aElement,
mozilla::CSSPseudoElementType aPseudoType,
- const ServoComputedValues* aComputedValues);
+ const mozilla::ServoStyleContext* aComputedValues);
/**
* Add a pending event.
*/
void QueueEvent(mozilla::AnimationEventInfo&& aEventInfo)
{
mEventDispatcher.QueueEvent(
mozilla::Forward<mozilla::AnimationEventInfo>(aEventInfo));
--- a/layout/style/nsComputedDOMStyle.cpp
+++ b/layout/style/nsComputedDOMStyle.cpp
@@ -637,17 +637,17 @@ nsComputedDOMStyle::DoGetStyleContextNoF
MOZ_ASSERT(presContext, "Should have a prescontext if we have a frame");
if (presContext && presContext->StyleSet()->IsGecko()) {
nsStyleSet* styleSet = presContext->StyleSet()->AsGecko();
return styleSet->ResolveStyleByRemovingAnimation(
aElement, result, eRestyle_AllHintsWithAnimations);
} else {
return presContext->StyleSet()->AsServo()->
GetBaseContextForElement(aElement, nullptr, presContext,
- aPseudo, pseudoType, result->ComputedValues());
+ aPseudo, pseudoType, result->AsServo());
}
}
// this function returns an addrefed style context
RefPtr<nsStyleContext> ret = result;
return ret.forget();
}
}
@@ -664,23 +664,23 @@ nsComputedDOMStyle::DoGetStyleContextNoF
// For Servo, compute the result directly without recursively building up
// a throwaway style context chain.
if (ServoStyleSet* servoSet = styleSet->GetAsServo()) {
StyleRuleInclusion rules = aStyleType == eDefaultOnly
? StyleRuleInclusion::DefaultOnly
: StyleRuleInclusion::All;
RefPtr<nsStyleContext> result =
- servoSet->ResolveTransientStyle(aElement, aPseudo, pseudoType, rules);
+ servoSet->ResolveTransientStyle(aElement, pseudoType, aPseudo, rules);
if (aAnimationFlag == eWithAnimation) {
return result.forget();
}
return servoSet->GetBaseContextForElement(aElement, nullptr, presContext,
- aPseudo, pseudoType, result->ComputedValues());
+ aPseudo, pseudoType, result->AsServo());
}
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);
--- a/layout/style/nsStyleContext.cpp
+++ b/layout/style/nsStyleContext.cpp
@@ -160,23 +160,22 @@ nsStyleContext::Destructor()
"destroying style context from old rule tree too late");
if (mParent) {
mParent->RemoveChild(this);
} else {
presContext->StyleSet()->RootStyleContextRemoved();
}
- // Free up our data structs.
+ // Free up our caches.
if (gecko) {
gecko->DestroyCachedStructs(presContext);
+ // Servo doesn't store things here, and it's not threadsafe
+ CSSVariableImageTable::RemoveAll(this);
}
-
- // Free any ImageValues we were holding on to for CSS variable values.
- CSSVariableImageTable::RemoveAll(this);
}
void nsStyleContext::AddChild(nsStyleContext* aChild)
{
if (GeckoStyleContext* gecko = GetAsGecko()) {
gecko->AddChild(aChild->AsGecko());
}
}
@@ -487,16 +486,54 @@ nsStyleContext::CalcStyleDifference(nsSt
uint32_t* aEqualStructs,
uint32_t* aSamePointerStructs)
{
return CalcStyleDifferenceInternal(aNewContext,
aEqualStructs,
aSamePointerStructs);
}
+void
+nsStyleContext::SetStyleIfVisited(already_AddRefed<nsStyleContext> aStyleIfVisited)
+{
+ MOZ_ASSERT(!IsStyleIfVisited(), "this context is not visited data");
+ // XXXManishearth
+ // Servo currently mints fresh visited contexts on calls to GetContext()
+ // in line with the previous behavior.
+ // This is suboptimal and should be phased out when we phase out GetContext()
+ NS_ASSERTION(IsServo() || !mStyleIfVisited, "should only be set once");
+
+ mStyleIfVisited = aStyleIfVisited;
+
+ MOZ_ASSERT(mStyleIfVisited->IsStyleIfVisited(),
+ "other context is visited data");
+ MOZ_ASSERT(!mStyleIfVisited->GetStyleIfVisited(),
+ "other context does not have visited data");
+ NS_ASSERTION(GetStyleIfVisited()->GetPseudo() == GetPseudo(),
+ "pseudo tag mismatch");
+ // XXXManishearth In Servo mode this can be called during ResolveTransientServoStyle
+ // in which case we may already have a visited style context but the
+ // expected parent is gone. Will be fixed when the aforementioned suboptimal
+ // behavior is removed
+ if (IsGecko()) {
+ if (GetParent() && GetParent()->GetStyleIfVisited()) {
+ MOZ_ASSERT(GetStyleIfVisited()->GetParent() ==
+ GetParent()->GetStyleIfVisited() ||
+ GetStyleIfVisited()->GetParent() ==
+ GetParent(),
+ "parent mismatch");
+ } else {
+ MOZ_ASSERT(GetStyleIfVisited()->GetParent() ==
+ GetParent(),
+ "parent mismatch");
+ }
+ }
+}
+
+
class MOZ_STACK_CLASS FakeStyleContext
{
public:
explicit FakeStyleContext(const ServoComputedValues* aComputedValues)
: mComputedValues(aComputedValues) {}
nsStyleContext* GetStyleIfVisited() {
// Bug 1364484: Figure out what to do here for Stylo visited values. We can
@@ -632,33 +669,16 @@ NS_NewStyleContext(nsStyleContext* aPare
RefPtr<nsRuleNode> node = aRuleNode;
RefPtr<GeckoStyleContext> context =
new (aRuleNode->PresContext())
GeckoStyleContext(aParentContext, aPseudoTag, aPseudoType, node.forget(),
aSkipParentDisplayBasedStyleFixup);
return context.forget();
}
-namespace mozilla {
-
-already_AddRefed<ServoStyleContext>
-ServoStyleContext::Create(nsStyleContext* aParentContext,
- nsPresContext* aPresContext,
- nsIAtom* aPseudoTag,
- CSSPseudoElementType aPseudoType,
- already_AddRefed<ServoComputedValues> aComputedValues)
-{
- RefPtr<ServoStyleContext> context =
- new ServoStyleContext(aParentContext, aPresContext, aPseudoTag, aPseudoType,
- Move(aComputedValues));
- return context.forget();
-}
-
-} // namespace mozilla
-
nsIPresShell*
nsStyleContext::Arena()
{
return PresContext()->PresShell();
}
template<typename Func>
static nscolor
--- a/layout/style/nsStyleContext.h
+++ b/layout/style/nsStyleContext.h
@@ -21,16 +21,18 @@ class nsPresContext;
namespace mozilla {
enum class CSSPseudoElementType : uint8_t;
class GeckoStyleContext;
class ServoStyleContext;
} // namespace mozilla
extern "C" {
+ void Servo_StyleContext_AddRef(mozilla::ServoStyleContext* aContext);
+ void Servo_StyleContext_Release(mozilla::ServoStyleContext* aContext);
#define STYLE_STRUCT(name_, checkdata_cb_) \
struct nsStyle##name_; \
const nsStyle##name_* Servo_GetStyle##name_( \
ServoComputedValuesBorrowedOrNull computed_values);
#include "nsStyleStructList.h"
#undef STYLE_STRUCT
}
@@ -77,39 +79,18 @@ public:
#ifdef DEBUG
/**
* Initializes a cached pref, which is only used in DEBUG code.
*/
static void Initialize();
#endif
- nsrefcnt AddRef() {
- if (mRefCnt == UINT32_MAX) {
- NS_WARNING("refcount overflow, leaking object");
- return mRefCnt;
- }
- ++mRefCnt;
- NS_LOG_ADDREF(this, mRefCnt, "nsStyleContext", sizeof(nsStyleContext));
- return mRefCnt;
- }
-
- nsrefcnt Release() {
- if (mRefCnt == UINT32_MAX) {
- NS_WARNING("refcount overflow, leaking object");
- return mRefCnt;
- }
- --mRefCnt;
- NS_LOG_RELEASE(this, mRefCnt, "nsStyleContext");
- if (mRefCnt == 0) {
- Destroy();
- return 0;
- }
- return mRefCnt;
- }
+ inline void AddRef();
+ inline void Release();
#ifdef DEBUG
void FrameAddRef() {
++mFrameRefCnt;
}
void FrameRelease() {
--mFrameRefCnt;
@@ -217,41 +198,17 @@ public:
// Structs on this context should never be examined without also
// examining the corresponding struct on |this|. Doing so will likely
// both (1) lead to a privacy leak and (2) lead to dynamic change bugs
// related to the Peek code in nsStyleContext::CalcStyleDifference.
nsStyleContext* GetStyleIfVisited() const
{ return mStyleIfVisited; }
// To be called only from nsStyleSet / ServoStyleSet.
- void SetStyleIfVisited(already_AddRefed<nsStyleContext> aStyleIfVisited)
- {
- MOZ_ASSERT(!IsStyleIfVisited(), "this context is not visited data");
- NS_ASSERTION(!mStyleIfVisited, "should only be set once");
-
- mStyleIfVisited = aStyleIfVisited;
-
- MOZ_ASSERT(mStyleIfVisited->IsStyleIfVisited(),
- "other context is visited data");
- MOZ_ASSERT(!mStyleIfVisited->GetStyleIfVisited(),
- "other context does not have visited data");
- NS_ASSERTION(GetStyleIfVisited()->GetPseudo() == GetPseudo(),
- "pseudo tag mismatch");
- if (GetParentAllowServo() && GetParentAllowServo()->GetStyleIfVisited()) {
- NS_ASSERTION(GetStyleIfVisited()->GetParentAllowServo() ==
- GetParentAllowServo()->GetStyleIfVisited() ||
- GetStyleIfVisited()->GetParentAllowServo() ==
- GetParentAllowServo(),
- "parent mismatch");
- } else {
- NS_ASSERTION(GetStyleIfVisited()->GetParentAllowServo() ==
- GetParentAllowServo(),
- "parent mismatch");
- }
- }
+ void SetStyleIfVisited(already_AddRefed<nsStyleContext> aStyleIfVisited);
// Does any descendant of this style context have any style values
// that were computed based on this style context's ancestors?
bool HasChildThatUsesGrandancestorStyle() const
{ return !!(mBits & NS_STYLE_CHILD_USES_GRANDANCESTOR_STYLE); }
// Is this style context shared with a sibling or cousin?
// (See nsStyleSet::GetContext.)
--- a/layout/style/nsStyleContextInlines.h
+++ b/layout/style/nsStyleContextInlines.h
@@ -32,16 +32,28 @@ nsStyleContext::RuleNode()
ServoComputedValues*
nsStyleContext::ComputedValues()
{
MOZ_RELEASE_ASSERT(IsServo());
return AsServo()->ComputedValues();
}
+void
+nsStyleContext::AddRef()
+{
+ MOZ_STYLO_FORWARD(AddRef, ())
+}
+
+void
+nsStyleContext::Release()
+{
+ MOZ_STYLO_FORWARD(Release, ())
+}
+
#define STYLE_STRUCT(name_, checkdata_cb_) \
const nsStyle##name_ * \
nsStyleContext::Style##name_() { \
return DoGetStyle##name_<true>(); \
} \
const nsStyle##name_ * \
nsStyleContext::ThreadsafeStyle##name_() { \
if (mozilla::ServoStyleSet::IsInServoTraversal()) { \
@@ -191,9 +203,10 @@ nsStyleContext::IsLinkContext() const
void
nsStyleContext::StartBackgroundImageLoads()
{
// Just get our background struct; that should do the trick
StyleBackground();
}
+
#endif // nsStyleContextInlines_h
--- a/layout/style/nsStyleSet.cpp
+++ b/layout/style/nsStyleSet.cpp
@@ -957,20 +957,20 @@ nsStyleSet::GetContext(nsStyleContext* a
nsIStyleRule *oldAnimRule = GetAnimationRule(aRuleNode);
nsIStyleRule *animRule = nullptr;
// Ignore animations for print or print preview, and for elements
// that are not attached to the document tree.
if (PresContext()->IsDynamic() &&
aElementForAnimation->IsInComposedDoc()) {
// Update CSS animations in case the animation-name has just changed.
- PresContext()->AnimationManager()->UpdateAnimations(result,
+ PresContext()->AnimationManager()->UpdateAnimations(result->AsGecko(),
aElementForAnimation);
PresContext()->EffectCompositor()->UpdateEffectProperties(
- result.get(), aElementForAnimation, result->GetPseudoType());
+ result->AsGecko(), aElementForAnimation, result->GetPseudoType());
animRule = PresContext()->EffectCompositor()->
GetAnimationRule(aElementForAnimation,
result->GetPseudoType(),
EffectCompositor::CascadeLevel::Animations,
result);
}
--- a/layout/style/nsTransitionManager.cpp
+++ b/layout/style/nsTransitionManager.cpp
@@ -440,26 +440,26 @@ ExtractNonDiscreteComputedValue(nsCSSPro
return (nsCSSProps::kAnimTypeTable[aProperty] != eStyleAnimType_Discrete ||
aProperty == eCSSProperty_visibility) &&
StyleAnimationValue::ExtractComputedValue(aProperty, aStyleContext,
aAnimationValue.mGecko);
}
static inline bool
ExtractNonDiscreteComputedValue(nsCSSPropertyID aProperty,
- const ServoComputedValues* aComputedStyle,
+ const ServoStyleContext* aComputedStyle,
AnimationValue& aAnimationValue)
{
if (Servo_Property_IsDiscreteAnimatable(aProperty) &&
aProperty != eCSSProperty_visibility) {
return false;
}
aAnimationValue.mServo =
- Servo_ComputedValues_ExtractAnimationValue(aComputedStyle,
+ Servo_ComputedValues_ExtractAnimationValue(aComputedStyle->ComputedValues(),
aProperty).Consume();
return !!aAnimationValue.mServo;
}
void
nsTransitionManager::StyleContextChanged(dom::Element *aElement,
nsStyleContext *aOldStyleContext,
RefPtr<nsStyleContext>* aNewStyleContext /* inout */)
@@ -584,18 +584,18 @@ nsTransitionManager::StyleContextChanged
DebugOnly<bool> startedAny = false;
// We don't have to update transitions if display:none, although we will
// cancel them after restyling.
if (!afterChangeStyle->IsInDisplayNoneSubtree()) {
startedAny = DoUpdateTransitions(disp,
aElement,
afterChangeStyle->GetPseudoType(),
collection,
- aOldStyleContext,
- afterChangeStyle.get());
+ aOldStyleContext->AsGecko(),
+ afterChangeStyle->AsGecko());
}
MOZ_ASSERT(!startedAny || collection,
"must have element transitions if we started any transitions");
EffectCompositor::CascadeLevel cascadeLevel =
EffectCompositor::CascadeLevel::Transitions;
@@ -619,27 +619,27 @@ nsTransitionManager::StyleContextChanged
cascadeLevel);
}
}
bool
nsTransitionManager::UpdateTransitions(
dom::Element *aElement,
CSSPseudoElementType aPseudoType,
- const ServoComputedValues* aOldStyle,
- const ServoComputedValues* aNewStyle)
+ const ServoStyleContext* aOldStyle,
+ const ServoStyleContext* aNewStyle)
{
if (!mPresContext->IsDynamic()) {
// For print or print preview, ignore transitions.
return false;
}
CSSTransitionCollection* collection =
CSSTransitionCollection::GetAnimationCollection(aElement, aPseudoType);
- const nsStyleDisplay *disp = Servo_GetStyleDisplay(aNewStyle);
+ const nsStyleDisplay *disp = Servo_GetStyleDisplay(aNewStyle->ComputedValues());
return DoUpdateTransitions(disp,
aElement, aPseudoType,
collection,
aOldStyle, aNewStyle);
}
template<typename StyleType>
bool
--- a/layout/style/nsTransitionManager.h
+++ b/layout/style/nsTransitionManager.h
@@ -21,16 +21,17 @@ class nsIGlobalObject;
class nsStyleContext;
class nsPresContext;
class nsCSSPropertyIDSet;
namespace mozilla {
enum class CSSPseudoElementType : uint8_t;
struct Keyframe;
struct StyleTransition;
+class ServoStyleContext;
} // namespace mozilla
/*****************************************************************************
* Per-Element data *
*****************************************************************************/
namespace mozilla {
@@ -372,18 +373,18 @@ public:
RefPtr<nsStyleContext>* aNewStyleContext /* inout */);
/**
* Update transitions for stylo.
*/
bool UpdateTransitions(
mozilla::dom::Element *aElement,
mozilla::CSSPseudoElementType aPseudoType,
- const ServoComputedValues* aOldStyle,
- const ServoComputedValues* aNewStyle);
+ const mozilla::ServoStyleContext* aOldStyle,
+ const mozilla::ServoStyleContext* aNewStyle);
/**
* When we're resolving style for an element that previously didn't have
* style, we might have some old finished transitions for it, if,
* say, it was display:none for a while, but previously displayed.
*
* This method removes any finished transitions that don't match the
* new style.
--- a/servo/components/layout/flow.rs
+++ b/servo/components/layout/flow.rs
@@ -1114,17 +1114,17 @@ impl BaseFlow {
scroll_root_id: None,
}
}
/// Update the 'flags' field when computed styles have changed.
///
/// These flags are initially set during flow construction. They only need to be updated here
/// if they are based on properties that can change without triggering `RECONSTRUCT_FLOW`.
- pub fn update_flags_if_needed(&mut self, style: &ServoComputedValues) {
+ pub fn update_flags_if_needed(&mut self, style: &ComputedValues) {
// For absolutely-positioned flows, changes to top/bottom/left/right can cause these flags
// to get out of date:
if self.restyle_damage.contains(REFLOW_OUT_OF_FLOW) {
// Note: We don't need to check whether IS_ABSOLUTELY_POSITIONED has changed, because
// changes to the 'position' property trigger flow reconstruction.
if self.flags.contains(IS_ABSOLUTELY_POSITIONED) {
let logical_position = style.logical_position();
self.flags.set(INLINE_POSITION_IS_STATIC,
--- a/servo/components/script/dom/cssrulelist.rs
+++ b/servo/components/script/dom/cssrulelist.rs
@@ -85,23 +85,25 @@ impl CSSRuleList {
panic!("Called insert_rule on non-CssRule-backed CSSRuleList");
};
let global = self.global();
let window = global.as_window();
let index = idx as usize;
let parent_stylesheet = self.parent_stylesheet.style_stylesheet();
- let new_rule =
- css_rules.insert_rule(&parent_stylesheet.shared_lock,
- rule,
- &parent_stylesheet.contents,
- index,
- nested,
- None)?;
+ let new_rule = css_rules.with_raw_offset_arc(|arc| {
+ arc.insert_rule(&parent_stylesheet.shared_lock,
+ rule,
+ &parent_stylesheet.contents,
+ index,
+ nested,
+ None)
+ })?;
+
let parent_stylesheet = &*self.parent_stylesheet;
let dom_rule = CSSRule::new_specific(&window, parent_stylesheet, new_rule);
self.dom_rules.borrow_mut().insert(index, MutNullableJS::new(Some(&*dom_rule)));
Ok((idx))
}
// In case of a keyframe rule, index must be valid.
--- a/servo/components/script/layout_wrapper.rs
+++ b/servo/components/script/layout_wrapper.rs
@@ -72,17 +72,17 @@ use style::dom::{DescendantsBit, DirtyDe
use style::dom::{PresentationalHintsSynthesizer, TElement, TNode, UnsafeNode};
use style::element_state::*;
use style::font_metrics::ServoMetricsProvider;
use style::properties::{ComputedValues, PropertyDeclarationBlock};
use style::selector_parser::{AttrValue as SelectorAttrValue, NonTSPseudoClass, PseudoClassStringArg};
use style::selector_parser::{PseudoElement, SelectorImpl, extended_filtering};
use style::shared_lock::{SharedRwLock as StyleSharedRwLock, Locked as StyleLocked};
use style::str::is_whitespace;
-use style::stylearc::Arc;
+use style::stylearc::{Arc, ArcBorrow};
#[derive(Copy, Clone)]
pub struct ServoLayoutNode<'a> {
/// The wrapped node.
node: LayoutJS<Node>,
/// Being chained to a PhantomData prevents `LayoutNode`s from escaping.
chain: PhantomData<&'a ()>,
@@ -389,19 +389,19 @@ impl<'le> TElement for ServoLayoutElemen
type ConcreteNode = ServoLayoutNode<'le>;
type FontMetricsProvider = ServoMetricsProvider;
fn as_node(&self) -> ServoLayoutNode<'le> {
ServoLayoutNode::from_layout_js(self.element.upcast())
}
- fn style_attribute(&self) -> Option<&Arc<StyleLocked<PropertyDeclarationBlock>>> {
+ fn style_attribute(&self) -> Option<ArcBorrow<StyleLocked<PropertyDeclarationBlock>>> {
unsafe {
- (*self.element.style_attribute()).as_ref()
+ (*self.element.style_attribute()).as_ref().map(|x| x.borrow_arc())
}
}
fn get_state(&self) -> ElementState {
self.element.get_state_for_layout()
}
#[inline]
--- a/servo/components/script_layout_interface/wrapper_traits.rs
+++ b/servo/components/script_layout_interface/wrapper_traits.rs
@@ -410,29 +410,29 @@ pub trait ThreadSafeLayoutElement: Clone
.unwrap().clone()
},
PseudoElementCascadeType::Precomputed => {
context.stylist.precomputed_values_for_pseudo(
&context.guards,
&style_pseudo,
Some(data.styles.primary()),
CascadeFlags::empty(),
- &ServoMetricsProvider)
+ &ServoMetricsProvider, (), ())
.clone()
}
PseudoElementCascadeType::Lazy => {
context.stylist
.lazily_compute_pseudo_element_style(
&context.guards,
unsafe { &self.unsafe_get() },
&style_pseudo,
RuleInclusion::All,
data.styles.primary(),
/* is_probe = */ false,
- &ServoMetricsProvider)
+ &ServoMetricsProvider, (), ())
.unwrap()
.clone()
}
}
}
}
}
--- a/servo/components/style/gecko/arc_types.rs
+++ b/servo/components/style/gecko/arc_types.rs
@@ -5,24 +5,25 @@
//! This file lists all arc FFI types and defines corresponding addref
//! and release functions. This list corresponds to ServoArcTypeList.h
//! file in Gecko.
#![allow(non_snake_case, missing_docs)]
use gecko_bindings::bindings::{RawServoImportRule, RawServoSupportsRule};
use gecko_bindings::bindings::{RawServoKeyframe, RawServoKeyframesRule};
+use gecko_bindings::bindings::RawServoMediaRule;
use gecko_bindings::bindings::{RawServoNamespaceRule, RawServoPageRule};
-use gecko_bindings::bindings::{RawServoRuleNode, RawServoRuleNodeStrong, RawServoDocumentRule, RawServoMediaRule};
-use gecko_bindings::bindings::{ServoComputedValues, ServoCssRules};
+use gecko_bindings::bindings::{RawServoRuleNode, RawServoRuleNodeStrong, RawServoDocumentRule};
+use gecko_bindings::bindings::ServoCssRules;
use gecko_bindings::structs::{RawServoAnimationValue, RawServoDeclarationBlock, RawServoStyleRule, RawServoMediaList};
-use gecko_bindings::structs::RawServoStyleSheetContents;
+use gecko_bindings::structs::{RawServoStyleSheetContents, ServoComputedValues, ServoStyleContext};
use gecko_bindings::sugar::ownership::{HasArcFFI, HasFFI};
use media_queries::MediaList;
-use properties::{ComputedValues, PropertyDeclarationBlock};
+use properties::{ComputedValues, ComputedValuesInner, PropertyDeclarationBlock};
use properties::animated_properties::AnimationValue;
use rule_tree::StrongRuleNode;
use shared_lock::Locked;
use std::{mem, ptr};
use stylesheets::{CssRules, StylesheetContents, StyleRule, ImportRule, KeyframesRule, MediaRule};
use stylesheets::{NamespaceRule, PageRule, SupportsRule, DocumentRule};
use stylesheets::keyframes_rule::Keyframe;
@@ -46,19 +47,22 @@ macro_rules! impl_arc_ffi {
}
impl_arc_ffi!(Locked<CssRules> => ServoCssRules
[Servo_CssRules_AddRef, Servo_CssRules_Release]);
impl_arc_ffi!(StylesheetContents => RawServoStyleSheetContents
[Servo_StyleSheetContents_AddRef, Servo_StyleSheetContents_Release]);
-impl_arc_ffi!(ComputedValues => ServoComputedValues
+impl_arc_ffi!(ComputedValuesInner => ServoComputedValues
[Servo_ComputedValues_AddRef, Servo_ComputedValues_Release]);
+impl_arc_ffi!(ComputedValues => ServoStyleContext
+ [Servo_StyleContext_AddRef, Servo_StyleContext_Release]);
+
impl_arc_ffi!(Locked<PropertyDeclarationBlock> => RawServoDeclarationBlock
[Servo_DeclarationBlock_AddRef, Servo_DeclarationBlock_Release]);
impl_arc_ffi!(Locked<StyleRule> => RawServoStyleRule
[Servo_StyleRule_AddRef, Servo_StyleRule_Release]);
impl_arc_ffi!(Locked<ImportRule> => RawServoImportRule
[Servo_ImportRule_AddRef, Servo_ImportRule_Release]);
--- a/servo/components/style/gecko/pseudo_element_definition.mako.rs
+++ b/servo/components/style/gecko/pseudo_element_definition.mako.rs
@@ -102,16 +102,35 @@ impl PseudoElement {
Some(${pseudo_element_variant(pseudo)})
},
% endif
% endfor
_ => None,
}
}
+
+ /// Construct a `CSSPseudoElementType` from a pseudo-element
+ #[inline]
+ pub fn pseudo_type(&self) -> CSSPseudoElementType {
+ match *self {
+ % for pseudo in PSEUDOS:
+ % if not pseudo.is_anon_box():
+ PseudoElement::${pseudo.capitalized()} => CSSPseudoElementType::${pseudo.original_ident},
+ % endif
+ % endfor
+ _ => CSSPseudoElementType::NotPseudo
+ }
+ }
+
+ /// Get a PseudoInfo for a pseudo
+ pub fn pseudo_info(&self) -> (*mut structs::nsIAtom, CSSPseudoElementType) {
+ (self.atom().as_ptr(), self.pseudo_type())
+ }
+
/// Construct a pseudo-element from an anonymous box `Atom`.
#[inline]
pub fn from_anon_box_atom(atom: &Atom) -> Option<Self> {
% for pseudo in PSEUDOS:
% if pseudo.is_tree_pseudo_element():
// We cannot generate ${pseudo_element_variant(pseudo)} from just an atom.
% elif pseudo.is_anon_box():
if atom == &atom!("${pseudo.value}") {
--- a/servo/components/style/gecko/restyle_damage.rs
+++ b/servo/components/style/gecko/restyle_damage.rs
@@ -2,17 +2,16 @@
* 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/. */
//! Gecko's restyle damage computation (aka change hints, aka `nsChangeHint`).
use gecko_bindings::bindings;
use gecko_bindings::structs;
use gecko_bindings::structs::{nsChangeHint, nsStyleContext};
-use gecko_bindings::sugar::ownership::FFIArcHelpers;
use matching::{StyleChange, StyleDifference};
use properties::ComputedValues;
use std::ops::{BitAnd, BitOr, BitOrAssign, Not};
use stylearc::Arc;
/// The representation of Gecko's restyle damage is just a wrapper over
/// `nsChangeHint`.
#[derive(Clone, Copy, Debug, PartialEq)]
@@ -51,17 +50,17 @@ impl GeckoRestyleDamage {
source: &nsStyleContext,
new_style: &Arc<ComputedValues>
) -> StyleDifference {
// TODO(emilio): Const-ify this?
let context = source as *const nsStyleContext as *mut nsStyleContext;
let mut any_style_changed: bool = false;
let hint = unsafe {
bindings::Gecko_CalcStyleDifference(context,
- new_style.as_borrowed(),
+ &new_style,
&mut any_style_changed)
};
let change = if any_style_changed { StyleChange::Changed } else { StyleChange::Unchanged };
StyleDifference::new(GeckoRestyleDamage(hint), change)
}
/// Returns true if this restyle damage contains all the damage of |other|.
pub fn contains(self, other: Self) -> bool {
--- a/servo/components/style/gecko/wrapper.rs
+++ b/servo/components/style/gecko/wrapper.rs
@@ -59,17 +59,17 @@ use gecko_bindings::structs::{nsIAtom, n
use gecko_bindings::structs::ELEMENT_HANDLED_SNAPSHOT;
use gecko_bindings::structs::ELEMENT_HAS_ANIMATION_ONLY_DIRTY_DESCENDANTS_FOR_SERVO;
use gecko_bindings::structs::ELEMENT_HAS_DIRTY_DESCENDANTS_FOR_SERVO;
use gecko_bindings::structs::ELEMENT_HAS_SNAPSHOT;
use gecko_bindings::structs::EffectCompositor_CascadeLevel as CascadeLevel;
use gecko_bindings::structs::NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE;
use gecko_bindings::structs::NODE_IS_NATIVE_ANONYMOUS;
use gecko_bindings::structs::nsIDocument_DocumentTheme as DocumentTheme;
-use gecko_bindings::sugar::ownership::{FFIArcHelpers, HasArcFFI, HasSimpleFFI};
+use gecko_bindings::sugar::ownership::{HasArcFFI, HasSimpleFFI};
use logical_geometry::WritingMode;
use media_queries::Device;
use properties::{ComputedValues, parse_style_attribute};
use properties::{Importance, PropertyDeclaration, PropertyDeclarationBlock};
use properties::animated_properties::{AnimatableLonghand, AnimationValue, AnimationValueMap};
use properties::animated_properties::TransitionProperty;
use properties::style_structs::Font;
use rule_tree::CascadeLevel as ServoCascadeLevel;
@@ -1099,20 +1099,19 @@ impl<'le> TElement for GeckoElement<'le>
before_change_style: Option<Arc<ComputedValues>>,
tasks: UpdateAnimationsTasks) {
// We have to update animations even if the element has no computed
// style since it means the element is in a display:none subtree, we
// should destroy all CSS animations in display:none subtree.
let computed_data = self.borrow_data();
let computed_values =
computed_data.as_ref().map(|d| d.styles.primary());
- let computed_values_opt =
- computed_values.map(|v| v.as_borrowed());
let before_change_values =
- before_change_style.as_ref().map(|v| v.as_borrowed());
+ before_change_style.as_ref().map(|x| &**x);
+ let computed_values_opt = computed_values.as_ref().map(|x| &***x);
unsafe {
Gecko_UpdateAnimations(self.0,
before_change_values,
computed_values_opt,
tasks.bits());
}
}
--- a/servo/components/style/properties/gecko.mako.rs
+++ b/servo/components/style/properties/gecko.mako.rs
@@ -41,49 +41,64 @@ use gecko_bindings::bindings::Gecko_SetL
use gecko_bindings::bindings::Gecko_SetNullImageValue;
use gecko_bindings::bindings::ServoComputedValuesBorrowedOrNull;
use gecko_bindings::bindings::{Gecko_ResetFilters, Gecko_CopyFiltersFrom};
use gecko_bindings::bindings::RawGeckoPresContextBorrowed;
use gecko_bindings::structs;
use gecko_bindings::structs::nsCSSPropertyID;
use gecko_bindings::structs::nsStyleVariables;
use gecko_bindings::sugar::ns_style_coord::{CoordDataValue, CoordData, CoordDataMut};
-use gecko_bindings::sugar::ownership::HasArcFFI;
use gecko::values::convert_nscolor_to_rgba;
use gecko::values::convert_rgba_to_nscolor;
use gecko::values::GeckoStyleCoordConvertible;
use gecko::values::round_border_to_device_pixels;
use logical_geometry::WritingMode;
use media_queries::Device;
use properties::animated_properties::TransitionProperty;
use properties::computed_value_flags::ComputedValueFlags;
use properties::{longhands, FontComputationData, Importance, LonghandId};
use properties::{PropertyDeclaration, PropertyDeclarationBlock, PropertyDeclarationId};
use rule_tree::StrongRuleNode;
-use std::mem::{forget, transmute, zeroed};
+use std::mem::{forget, uninitialized, transmute, zeroed};
use std::{cmp, ops, ptr};
use stylearc::{Arc, RawOffsetArc};
use values::{Auto, CustomIdent, Either, KeyframesName};
use values::computed::ToComputedValue;
use values::computed::effects::{BoxShadow, Filter, SimpleShadow};
use values::specified::length::Percentage;
use computed_values::border_style;
pub mod style_structs {
% for style_struct in data.style_structs:
pub use super::${style_struct.gecko_struct_name} as ${style_struct.name};
% endfor
}
-pub use ::gecko_bindings::structs::mozilla::ServoComputedValues2 as ComputedValuesInner;
-
-#[derive(Clone, Debug)]
-pub struct ComputedValues {
- pub inner: ComputedValuesInner
+pub type ComputedValuesInner = ::gecko_bindings::structs::ServoComputedValues;
+
+#[derive(Debug)]
+#[repr(C)]
+pub struct ComputedValues(::gecko_bindings::structs::mozilla::ServoStyleContext);
+
+impl Drop for ComputedValues {
+ fn drop(&mut self) {
+ unsafe {
+ bindings::Gecko_ServoStyleContext_Destroy(&mut self.0);
+ }
+ }
+}
+
+unsafe impl Sync for ComputedValues {}
+unsafe impl Send for ComputedValues {}
+
+impl Clone for ComputedValues {
+ fn clone(&self) -> Self {
+ unreachable!()
+ }
}
impl Clone for ComputedValuesInner {
fn clone(&self) -> Self {
ComputedValuesInner {
% for style_struct in data.style_structs:
${style_struct.gecko_name}: self.${style_struct.gecko_name}.clone(),
% endfor
@@ -92,16 +107,19 @@ impl Clone for ComputedValuesInner {
font_computation_data: self.font_computation_data.clone(),
flags: self.flags.clone(),
rules: self.rules.clone(),
visited_style: self.visited_style.clone(),
}
}
}
+pub type PseudoInfo = (*mut structs::nsIAtom, structs::CSSPseudoElementType);
+pub type ParentStyleContextInfo<'a> = Option< &'a ComputedValues>;
+
impl ComputedValuesInner {
pub fn new(custom_properties: Option<Arc<CustomPropertiesMap>>,
writing_mode: WritingMode,
font_size_keyword: Option<(longhands::font_size::KeywordSize, f32)>,
flags: ComputedValueFlags,
rules: Option<StrongRuleNode>,
visited_style: Option<Arc<ComputedValues>>,
% for style_struct in data.style_structs:
@@ -129,31 +147,52 @@ impl ComputedValuesInner {
rules: None,
visited_style: None,
flags: ComputedValueFlags::empty(),
% for style_struct in data.style_structs:
${style_struct.gecko_name}: Arc::into_raw_offset(style_structs::${style_struct.name}::default(pres_context)),
% endfor
}
}
- pub fn to_outer(self) -> Arc<ComputedValues> {
- Arc::new(ComputedValues {inner: self})
+ pub fn to_outer(self, device: &Device, parent: ParentStyleContextInfo,
+ info: Option<PseudoInfo>) -> Arc<ComputedValues> {
+ let (tag, ty) = if let Some(info) = info {
+ info
+ } else {
+ (ptr::null_mut(), structs::CSSPseudoElementType::NotPseudo)
+ };
+
+ unsafe { Self::to_outer_from_arc(Arc::new(self), device.pres_context(), parent, ty, tag) }
+ }
+
+ pub unsafe fn to_outer_from_arc(s: Arc<Self>, pres_context: bindings::RawGeckoPresContextBorrowed,
+ parent: ParentStyleContextInfo,
+ pseudo_ty: structs::CSSPseudoElementType,
+ pseudo_tag: *mut structs::nsIAtom) -> Arc<ComputedValues> {
+ use gecko_bindings::sugar::ownership::FFIArcHelpers;
+ let arc = unsafe {
+ let arc: Arc<ComputedValues> = Arc::new(uninitialized());
+ bindings::Gecko_ServoStyleContext_Init(&arc.0 as *const _ as *mut _, parent, pres_context,
+ s.into_strong(), pseudo_ty, pseudo_tag);
+ arc
+ };
+ arc
}
}
impl ops::Deref for ComputedValues {
type Target = ComputedValuesInner;
fn deref(&self) -> &ComputedValuesInner {
- &self.inner
+ unsafe { &*self.0.mSource.mRawPtr }
}
}
impl ops::DerefMut for ComputedValues {
fn deref_mut(&mut self) -> &mut ComputedValuesInner {
- &mut self.inner
+ unsafe { &mut *self.0.mSource.mRawPtr }
}
}
impl ComputedValuesInner {
#[inline]
pub fn is_display_contents(&self) -> bool {
self.get_box().clone_display() == longhands::display::computed_value::T::contents
}
@@ -192,22 +231,22 @@ impl ComputedValuesInner {
}
/// Whether there is a visited style.
pub fn has_visited_style(&self) -> bool {
self.visited_style.is_some()
}
/// Gets a reference to the visited style, if any.
- pub fn get_visited_style(&self) -> Option< & ComputedValuesInner> {
- self.visited_style.as_ref().map(|x| &***x)
+ pub fn get_visited_style(&self) -> Option< & ComputedValues> {
+ self.visited_style.as_ref().map(|x| &**x)
}
/// Gets a reference to the visited style. Panic if no visited style exists.
- pub fn visited_style(&self) -> &ComputedValuesInner {
+ pub fn visited_style(&self) -> &ComputedValues {
self.get_visited_style().unwrap()
}
/// Clone the visited style. Used for inheriting parent styles in
/// StyleBuilder::for_inheritance.
pub fn clone_visited_style(&self) -> Option<Arc<ComputedValues>> {
self.visited_style.clone()
}
@@ -4796,17 +4835,17 @@ clip-path
}
</%self:impl_trait>
<%def name="define_ffi_struct_accessor(style_struct)">
#[no_mangle]
#[allow(non_snake_case, unused_variables)]
pub unsafe extern "C" fn Servo_GetStyle${style_struct.gecko_name}(computed_values:
ServoComputedValuesBorrowedOrNull) -> *const ${style_struct.gecko_ffi_name} {
- ComputedValues::arc_from_borrowed(&computed_values).unwrap().get_${style_struct.name_lower}().get_gecko()
+ computed_values.unwrap().get_${style_struct.name_lower}().get_gecko()
as *const ${style_struct.gecko_ffi_name}
}
</%def>
% for style_struct in data.style_structs:
${declare_style_struct(style_struct)}
${impl_style_struct(style_struct)}
% if not style_struct.name in data.manual_style_structs:
--- a/servo/components/style/properties/properties.mako.rs
+++ b/servo/components/style/properties/properties.mako.rs
@@ -1866,19 +1866,24 @@ pub mod style_structs {
}
}
% endif
% endfor
% endfor
#[cfg(feature = "gecko")]
-pub use gecko_properties::ComputedValues;
-#[cfg(feature = "gecko")]
-pub use gecko_properties::ComputedValuesInner;
+pub use gecko_properties::{ComputedValues, ComputedValuesInner, ParentStyleContextInfo, PseudoInfo};
+
+#[cfg(feature = "servo")]
+/// Servo doesn't have style contexts so this is extraneous info
+pub type PseudoInfo = ();
+#[cfg(feature = "servo")]
+/// Servo doesn't have style contexts so this is extraneous info
+pub type ParentStyleContextInfo = ();
#[cfg(feature = "servo")]
#[cfg_attr(feature = "servo", derive(Clone, Debug))]
/// Actual data of ComputedValues, to match up with Gecko
pub struct ComputedValuesInner {
% for style_struct in data.active_style_structs():
${style_struct.ident}: Arc<style_structs::${style_struct.name}>,
@@ -1930,17 +1935,16 @@ impl ComputedValuesInner {
font_size_keyword: Option<(longhands::font_size::KeywordSize, f32)>,
flags: ComputedValueFlags,
rules: Option<StrongRuleNode>,
visited_style: Option<Arc<ComputedValues>>,
% for style_struct in data.active_style_structs():
${style_struct.ident}: Arc<style_structs::${style_struct.name}>,
% endfor
) -> Self {
- let font_computation_data = FontComputationData::new(font_size_keyword);
ComputedValuesInner {
custom_properties: custom_properties,
writing_mode: writing_mode,
font_computation_data: FontComputationData::new(font_size_keyword),
rules: rules,
visited_style: visited_style,
flags: flags,
% for style_struct in data.active_style_structs():
@@ -1966,17 +1970,18 @@ impl ops::DerefMut for ComputedValues {
fn deref_mut(&mut self) -> &mut ComputedValuesInner {
&mut self.inner
}
}
#[cfg(feature = "servo")]
impl ComputedValuesInner {
/// Convert to an Arc<ComputedValues>
- pub fn to_outer(self) -> Arc<ComputedValues> {
+ pub fn to_outer(self, _: &Device, _: ParentStyleContextInfo,
+ _: Option<PseudoInfo>) -> Arc<ComputedValues> {
Arc::new(ComputedValues {inner: self})
}
% for style_struct in data.active_style_structs():
/// Clone the ${style_struct.name} struct.
#[inline]
pub fn clone_${style_struct.name_lower}(&self) -> Arc<style_structs::${style_struct.name}> {
self.${style_struct.ident}.clone()
@@ -2007,23 +2012,23 @@ impl ComputedValuesInner {
}
/// Whether there is a visited style.
pub fn has_visited_style(&self) -> bool {
self.visited_style.is_some()
}
/// Gets a reference to the visited style, if any.
- pub fn get_visited_style(&self) -> Option< & ComputedValuesInner> {
- self.visited_style.as_ref().map(|x| &**x)
+ pub fn get_visited_style(&self) -> Option< & ComputedValues> {
+ self.visited_style.as_ref().map(|x| &*x)
}
/// Gets a reference to the visited style. Panic if no visited style exists.
- pub fn visited_style(&self) -> &ComputedValuesInner {
- self.get_visited_style().as_ref().map(|x| &**x).unwrap()
+ pub fn visited_style(&self) -> &ComputedValues {
+ self.get_visited_style().unwrap()
}
/// Clone the visited style. Used for inheriting parent styles in
/// StyleBuilder::for_inheritance.
pub fn clone_visited_style(&self) -> Option<Arc<ComputedValues>> {
self.visited_style.clone()
}
--- a/servo/components/style/servo/selector_parser.rs
+++ b/servo/components/style/servo/selector_parser.rs
@@ -161,16 +161,19 @@ impl PseudoElement {
}
}
/// Covert non-canonical pseudo-element to canonical one, and keep a
/// canonical one as it is.
pub fn canonical(&self) -> PseudoElement {
self.clone()
}
+
+ /// Stub, only Gecko needs this
+ pub fn pseudo_info(&self) -> () { () }
}
/// The type used for storing pseudo-class string arguments.
pub type PseudoClassStringArg = Box<str>;
/// A non tree-structural pseudo-class.
/// See https://drafts.csswg.org/selectors-4/#structural-pseudos
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
--- a/servo/components/style/style_resolver.rs
+++ b/servo/components/style/style_resolver.rs
@@ -42,17 +42,17 @@ struct MatchingResults {
pub struct PrimaryStyle {
/// The style per se.
pub style: Arc<ComputedValues>,
}
fn with_default_parent_styles<E, F, R>(element: E, f: F) -> R
where
E: TElement,
- F: FnOnce(Option<&ComputedValuesInner>, Option<&ComputedValuesInner>) -> R,
+ F: FnOnce(Option<&ComputedValues>, Option<&ComputedValuesInner>) -> R,
{
let parent_el = element.inheritance_parent();
let parent_data = parent_el.as_ref().and_then(|e| e.borrow_data());
let parent_style = parent_data.as_ref().map(|d| {
// Sometimes Gecko eagerly styles things without processing
// pending restyles first. In general we'd like to avoid this,
// but there can be good reasons (for example, needing to
// construct a frame for some small piece of newly-added
@@ -67,17 +67,17 @@ where
let layout_parent_data;
let mut layout_parent_style = parent_style;
if parent_style.map_or(false, |s| s.is_display_contents()) {
layout_parent_el = Some(layout_parent_el.unwrap().layout_parent());
layout_parent_data = layout_parent_el.as_ref().unwrap().borrow_data().unwrap();
layout_parent_style = Some(layout_parent_data.styles.primary());
}
- f(parent_style.map(|s| &***s), layout_parent_style.map(|s| &***s))
+ f(parent_style.map(|x| &**x), layout_parent_style.map(|s| &***s))
}
impl<'a, 'ctx, 'le, E> StyleResolverForElement<'a, 'ctx, 'le, E>
where
'ctx: 'a,
'le: 'ctx,
E: TElement + MatchMethods + 'le,
{
@@ -93,17 +93,17 @@ where
rule_inclusion,
_marker: ::std::marker::PhantomData,
}
}
/// Resolve just the style of a given element.
pub fn resolve_primary_style(
&mut self,
- parent_style: Option<&ComputedValuesInner>,
+ parent_style: Option<&ComputedValues>,
layout_parent_style: Option<&ComputedValuesInner>,
) -> PrimaryStyle {
let primary_results =
self.match_primary(VisitedHandlingMode::AllLinksUnvisited);
let relevant_link_found = primary_results.relevant_link_found;
let visited_rules = if relevant_link_found {
@@ -114,44 +114,44 @@ where
None
};
let mut visited_style = None;
let should_compute_visited_style =
relevant_link_found ||
parent_style.and_then(|s| s.get_visited_style()).is_some();
+ let pseudo = self.element.implemented_pseudo_element();
if should_compute_visited_style {
visited_style = Some(self.cascade_style(
visited_rules.as_ref(),
/* style_if_visited = */ None,
parent_style,
layout_parent_style,
CascadeVisitedMode::Visited,
- /* pseudo = */ None,
+ /* pseudo = */ pseudo.as_ref(),
));
}
-
let style = self.cascade_style(
Some(&primary_results.rule_node),
visited_style,
parent_style,
layout_parent_style,
CascadeVisitedMode::Unvisited,
- /* pseudo = */ None,
+ /* pseudo = */ pseudo.as_ref(),
);
PrimaryStyle { style, }
}
/// Resolve the style of a given element, and all its eager pseudo-elements.
pub fn resolve_style(
&mut self,
- parent_style: Option<&ComputedValuesInner>,
+ parent_style: Option<&ComputedValues>,
layout_parent_style: Option<&ComputedValuesInner>,
) -> ElementStyles {
use properties::longhands::display::computed_value::T as display;
let primary_style =
self.resolve_primary_style(parent_style, layout_parent_style);
let mut pseudo_styles = EagerPseudoStyles::default();
@@ -210,17 +210,17 @@ where
/* pseudo = */ None
)
})
}
fn cascade_style_and_visited(
&mut self,
inputs: CascadeInputs,
- parent_style: Option<&ComputedValuesInner>,
+ parent_style: Option<&ComputedValues>,
layout_parent_style: Option<&ComputedValuesInner>,
pseudo: Option<&PseudoElement>,
) -> Arc<ComputedValues> {
let mut style_if_visited = None;
if parent_style.map_or(false, |s| s.get_visited_style().is_some()) ||
inputs.visited_rules.is_some() {
style_if_visited = Some(self.cascade_style(
inputs.visited_rules.as_ref(),
@@ -457,17 +457,17 @@ where
Some(rule_node)
}
fn cascade_style(
&mut self,
rules: Option<&StrongRuleNode>,
style_if_visited: Option<Arc<ComputedValues>>,
- mut parent_style: Option<&ComputedValuesInner>,
+ mut parent_style: Option<&ComputedValues>,
layout_parent_style: Option<&ComputedValuesInner>,
cascade_visited: CascadeVisitedMode,
pseudo: Option<&PseudoElement>,
) -> Arc<ComputedValues> {
let mut cascade_info = CascadeInfo::new();
let mut cascade_flags = CascadeFlags::empty();
if self.element.skip_root_and_item_based_display_fixup() {
@@ -480,26 +480,43 @@ where
cascade_flags.insert(VISITED_DEPENDENT_ONLY);
}
if self.element.is_native_anonymous() || pseudo.is_some() {
cascade_flags.insert(PROHIBIT_DISPLAY_CONTENTS);
} else if self.element.is_root() {
cascade_flags.insert(IS_ROOT_ELEMENT);
}
+ #[cfg(feature = "gecko")]
+ let parent_style_context = parent_style;
+ #[cfg(feature = "servo")]
+ let parent_style_context = ();
+
let values =
cascade(
self.context.shared.stylist.device(),
rules.unwrap_or(self.context.shared.stylist.rule_tree().root()),
&self.context.shared.guards,
- parent_style,
+ parent_style.map(|x| &**x),
layout_parent_style,
style_if_visited,
Some(&mut cascade_info),
&self.context.thread_local.font_metrics_provider,
cascade_flags,
self.context.shared.quirks_mode
);
cascade_info.finish(&self.element.as_node());
- values.to_outer()
+
+ // In case of NAC like ::placeholder we style it via
+ // cascade_primary without a PseudoElement, but
+ // the element itself is a pseudo, so try to use that
+ // when `pseudo` is unset
+ let pseudo_info = if let Some(pseudo) = pseudo {
+ Some(pseudo.pseudo_info())
+ } else {
+ self.element.implemented_pseudo_element().map(|x| x.pseudo_info())
+ };
+ values.to_outer(self.context.shared.stylist.device(),
+ parent_style_context,
+ pseudo_info)
}
}
--- a/servo/components/style/stylist.rs
+++ b/servo/components/style/stylist.rs
@@ -12,17 +12,17 @@ use dom::TElement;
use element_state::ElementState;
use font_metrics::FontMetricsProvider;
#[cfg(feature = "gecko")]
use gecko_bindings::structs::{nsIAtom, StyleRuleInclusion};
use invalidation::element::invalidation_map::InvalidationMap;
use invalidation::media_queries::{EffectiveMediaQueryResults, ToMediaListKey};
use media_queries::Device;
use properties::{self, CascadeFlags, ComputedValues, ComputedValuesInner};
-use properties::{AnimationRules, PropertyDeclarationBlock};
+use properties::{AnimationRules, PropertyDeclarationBlock, PseudoInfo, ParentStyleContextInfo};
#[cfg(feature = "servo")]
use properties::INHERIT_ALL;
use rule_tree::{CascadeLevel, RuleTree, StyleSource};
use selector_map::{SelectorMap, SelectorMapEntry};
use selector_parser::{SelectorImpl, PseudoElement};
use selectors::attr::NamespaceConstraint;
use selectors::bloom::BloomFilter;
use selectors::matching::{ElementSelectorFlags, matches_selector, MatchingContext, MatchingMode};
@@ -596,17 +596,19 @@ impl Stylist {
/// parent; otherwise, non-inherited properties are reset to their initial
/// values. The flow constructor uses this flag when constructing anonymous
/// flows.
pub fn precomputed_values_for_pseudo(&self,
guards: &StylesheetGuards,
pseudo: &PseudoElement,
parent: Option<&ComputedValuesInner>,
cascade_flags: CascadeFlags,
- font_metrics: &FontMetricsProvider)
+ font_metrics: &FontMetricsProvider,
+ pseudo_info: PseudoInfo,
+ parent_style_context: ParentStyleContextInfo)
-> Arc<ComputedValues> {
debug_assert!(pseudo.is_precomputed());
let rule_node = match self.precomputed_pseudo_element_decls.get(pseudo) {
Some(declarations) => {
self.rule_tree.insert_ordered_rules_with_important(
declarations.into_iter().map(|a| (a.source.clone(), a.level())),
guards
@@ -633,17 +635,18 @@ impl Stylist {
&rule_node,
guards,
parent,
parent,
None,
None,
font_metrics,
cascade_flags,
- self.quirks_mode).to_outer()
+ self.quirks_mode).to_outer(self.device(), parent_style_context,
+ Some(pseudo_info))
}
/// Returns the style for an anonymous box of the given type.
#[cfg(feature = "servo")]
pub fn style_for_anonymous(&self,
guards: &StylesheetGuards,
pseudo: &PseudoElement,
parent_style: &ComputedValuesInner)
@@ -670,54 +673,60 @@ impl Stylist {
unreachable!("That pseudo doesn't represent an anonymous box!")
}
};
let mut cascade_flags = CascadeFlags::empty();
if inherit_all {
cascade_flags.insert(INHERIT_ALL);
}
self.precomputed_values_for_pseudo(guards, &pseudo, Some(parent_style), cascade_flags,
- &ServoMetricsProvider)
+ &ServoMetricsProvider, (), ())
}
/// Computes a pseudo-element style lazily during layout.
///
/// This can only be done for a certain set of pseudo-elements, like
/// :selection.
///
/// Check the documentation on lazy pseudo-elements in
/// docs/components/style.md
pub fn lazily_compute_pseudo_element_style<E>(&self,
guards: &StylesheetGuards,
element: &E,
pseudo: &PseudoElement,
rule_inclusion: RuleInclusion,
parent_style: &ComputedValuesInner,
is_probe: bool,
- font_metrics: &FontMetricsProvider)
+ font_metrics: &FontMetricsProvider,
+ pseudo_info: PseudoInfo,
+ parent_style_context: ParentStyleContextInfo)
-> Option<Arc<ComputedValues>>
where E: TElement,
{
let cascade_inputs =
self.lazy_pseudo_rules(guards, element, pseudo, is_probe, rule_inclusion);
self.compute_pseudo_element_style_with_inputs(&cascade_inputs,
guards,
parent_style,
- font_metrics)
+ font_metrics,
+ pseudo_info,
+ parent_style_context)
}
/// Computes a pseudo-element style lazily using the given CascadeInputs.
/// This can be used for truly lazy pseudo-elements or to avoid redoing
/// selector matching for eager pseudo-elements when we need to recompute
/// their style with a new parent style.
pub fn compute_pseudo_element_style_with_inputs(&self,
inputs: &CascadeInputs,
guards: &StylesheetGuards,
parent_style: &ComputedValuesInner,
- font_metrics: &FontMetricsProvider)
+ font_metrics: &FontMetricsProvider,
+ pseudo_info: PseudoInfo,
+ parent_style_context: ParentStyleContextInfo)
-> Option<Arc<ComputedValues>>
{
// We may have only visited rules in cases when we are actually
// resolving, not probing, pseudo-element style.
if inputs.rules.is_none() && inputs.visited_rules.is_none() {
return None
}
@@ -729,34 +738,35 @@ impl Stylist {
// maybe it just has visited rules, so can't unwrap_or.
let rule_node = match inputs.visited_rules.as_ref() {
Some(rules) => rules,
None => inputs.rules.as_ref().unwrap(),
};
// We want to use the visited bits (if any) from our parent style as
// our parent.
let inherited_style =
- parent_style.get_visited_style().unwrap_or(parent_style);
+ parent_style.get_visited_style().map(|x| &**x).unwrap_or(parent_style);
// FIXME(emilio): The lack of layout_parent_style here could be
// worrying, but we're probably dropping the display fixup for
// pseudos other than before and after, so it's probably ok.
//
// (Though the flags don't indicate so!)
let computed =
properties::cascade(&self.device,
rule_node,
guards,
Some(inherited_style),
Some(inherited_style),
None,
None,
font_metrics,
CascadeFlags::empty(),
- self.quirks_mode).to_outer();
+ self.quirks_mode).to_outer(self.device(), parent_style_context,
+ Some(pseudo_info.clone()));
Some(computed)
} else {
None
};
// We may not have non-visited rules, if we only had visited ones. In
// that case we want to use the root rulenode for our non-visited rules.
@@ -770,17 +780,19 @@ impl Stylist {
rules,
guards,
Some(parent_style),
Some(parent_style),
visited_values,
None,
font_metrics,
CascadeFlags::empty(),
- self.quirks_mode).to_outer())
+ self.quirks_mode).to_outer(self.device(),
+ parent_style_context,
+ Some(pseudo_info)))
}
/// Computes the cascade inputs for a lazily-cascaded pseudo-element.
///
/// See the documentation on lazy pseudo-elements in
/// docs/components/style.md
pub fn lazy_pseudo_rules<E>(&self,
guards: &StylesheetGuards,
@@ -1308,17 +1320,18 @@ impl Stylist {
results
}
/// Computes styles for a given declaration with parent_style.
pub fn compute_for_declarations(&self,
guards: &StylesheetGuards,
parent_style: &ComputedValuesInner,
- declarations: Arc<Locked<PropertyDeclarationBlock>>)
+ declarations: Arc<Locked<PropertyDeclarationBlock>>,
+ parent_style_context: ParentStyleContextInfo)
-> Arc<ComputedValues> {
use font_metrics::get_metrics_provider_for_product;
let v = vec![
ApplicableDeclarationBlock::from_declarations(declarations.clone(),
CascadeLevel::StyleAttributeNormal)
];
let rule_node =
@@ -1332,17 +1345,17 @@ impl Stylist {
&rule_node,
guards,
Some(parent_style),
Some(parent_style),
None,
None,
&metrics,
CascadeFlags::empty(),
- self.quirks_mode).to_outer()
+ self.quirks_mode).to_outer(self.device(), parent_style_context, None)
}
/// Accessor for a shared reference to the device.
pub fn device(&self) -> &Device {
&self.device
}
/// Accessor for a mutable reference to the device.
--- a/servo/components/style/traversal.rs
+++ b/servo/components/style/traversal.rs
@@ -571,34 +571,34 @@ where
}
for ancestor in ancestors_requiring_style_resolution.iter().rev() {
context.thread_local.bloom_filter.assert_complete(*ancestor);
let primary_style =
StyleResolverForElement::new(*ancestor, context, rule_inclusion)
.resolve_primary_style(
- style.as_ref().map(|s| &***s),
+ style.as_ref().map(|s| &**s),
layout_parent_style.as_ref().map(|s| &***s)
);
let is_display_contents = primary_style.style.is_display_contents();
style = Some(primary_style.style);
if !is_display_contents {
layout_parent_style = style.clone();
}
context.thread_local.bloom_filter.push(*ancestor);
}
context.thread_local.bloom_filter.assert_complete(element);
StyleResolverForElement::new(element, context, rule_inclusion)
.resolve_style(
- style.as_ref().map(|s| &***s),
+ style.as_ref().map(|s| &**s),
layout_parent_style.as_ref().map(|s| &***s)
)
}
/// Calculates the style for a single node.
#[inline]
#[allow(unsafe_code)]
pub fn recalc_style_at<E, D>(
--- a/servo/ports/geckolib/glue.rs
+++ b/servo/ports/geckolib/glue.rs
@@ -34,17 +34,17 @@ use style::gecko_bindings::bindings::{Ra
use style::gecko_bindings::bindings::{RawServoKeyframe, RawServoKeyframeBorrowed, RawServoKeyframeStrong};
use style::gecko_bindings::bindings::{RawServoKeyframesRule, RawServoKeyframesRuleBorrowed};
use style::gecko_bindings::bindings::{RawServoMediaListBorrowed, RawServoMediaListStrong};
use style::gecko_bindings::bindings::{RawServoMediaRule, RawServoMediaRuleBorrowed};
use style::gecko_bindings::bindings::{RawServoNamespaceRule, RawServoNamespaceRuleBorrowed};
use style::gecko_bindings::bindings::{RawServoPageRule, RawServoPageRuleBorrowed};
use style::gecko_bindings::bindings::{RawServoStyleSetBorrowed, RawServoStyleSetOwned};
use style::gecko_bindings::bindings::{RawServoStyleSheetContentsBorrowed, ServoComputedValuesBorrowed};
-use style::gecko_bindings::bindings::{RawServoStyleSheetContentsStrong, ServoComputedValuesStrong};
+use style::gecko_bindings::bindings::{RawServoStyleSheetContentsStrong, ServoStyleContextBorrowed};
use style::gecko_bindings::bindings::{RawServoSupportsRule, RawServoSupportsRuleBorrowed};
use style::gecko_bindings::bindings::{ServoCssRulesBorrowed, ServoCssRulesStrong};
use style::gecko_bindings::bindings::{nsACString, nsAString, nsCSSPropertyIDSetBorrowedMut};
use style::gecko_bindings::bindings::Gecko_AddPropertyToSet;
use style::gecko_bindings::bindings::Gecko_GetOrCreateFinalKeyframe;
use style::gecko_bindings::bindings::Gecko_GetOrCreateInitialKeyframe;
use style::gecko_bindings::bindings::Gecko_GetOrCreateKeyframeAtStart;
use style::gecko_bindings::bindings::Gecko_NewNoneTransform;
@@ -56,23 +56,24 @@ use style::gecko_bindings::bindings::Raw
use style::gecko_bindings::bindings::RawGeckoServoAnimationValueListBorrowed;
use style::gecko_bindings::bindings::RawGeckoServoAnimationValueListBorrowedMut;
use style::gecko_bindings::bindings::RawGeckoServoStyleRuleListBorrowedMut;
use style::gecko_bindings::bindings::RawServoAnimationValueBorrowed;
use style::gecko_bindings::bindings::RawServoAnimationValueMapBorrowedMut;
use style::gecko_bindings::bindings::RawServoAnimationValueStrong;
use style::gecko_bindings::bindings::RawServoStyleRuleBorrowed;
use style::gecko_bindings::bindings::ServoComputedValuesBorrowedOrNull;
+use style::gecko_bindings::bindings::ServoStyleContextBorrowedOrNull;
use style::gecko_bindings::bindings::nsTArrayBorrowed_uintptr_t;
use style::gecko_bindings::bindings::nsTimingFunctionBorrowed;
use style::gecko_bindings::bindings::nsTimingFunctionBorrowedMut;
use style::gecko_bindings::structs;
use style::gecko_bindings::structs::{CSSPseudoElementType, CompositeOperation, Loader};
-use style::gecko_bindings::structs::{RawServoStyleRule, ServoStyleSheet};
-use style::gecko_bindings::structs::{SheetParsingMode, nsIAtom, nsCSSPropertyID};
+use style::gecko_bindings::structs::{RawServoStyleRule, ServoStyleContextStrong};
+use style::gecko_bindings::structs::{ServoStyleSheet, SheetParsingMode, nsIAtom, nsCSSPropertyID};
use style::gecko_bindings::structs::{nsCSSFontFaceRule, nsCSSCounterStyleRule};
use style::gecko_bindings::structs::{nsRestyleHint, nsChangeHint, PropertyValuePair};
use style::gecko_bindings::structs::IterationCompositeOperation;
use style::gecko_bindings::structs::MallocSizeOf;
use style::gecko_bindings::structs::RawGeckoGfxMatrix4x4;
use style::gecko_bindings::structs::RawGeckoPresContextOwned;
use style::gecko_bindings::structs::ServoElementSnapshotTable;
use style::gecko_bindings::structs::StyleRuleInclusion;
@@ -87,17 +88,17 @@ use style::gecko_bindings::sugar::owners
use style::gecko_bindings::sugar::refptr::RefPtr;
use style::gecko_properties::{self, style_structs};
use style::invalidation::element::restyle_hints::{self, RestyleHint};
use style::media_queries::{MediaList, parse_media_query_list};
use style::parallel;
use style::parser::ParserContext;
use style::properties::{ComputedValues, ComputedValuesInner, Importance, SourcePropertyDeclaration};
use style::properties::{LonghandIdSet, PropertyDeclaration, PropertyDeclarationBlock, PropertyId, StyleBuilder};
-use style::properties::SKIP_ROOT_AND_ITEM_BASED_DISPLAY_FIXUP;
+use style::properties::{SKIP_ROOT_AND_ITEM_BASED_DISPLAY_FIXUP, PseudoInfo, ParentStyleContextInfo};
use style::properties::animated_properties::{Animatable, AnimatableLonghand, AnimationValue};
use style::properties::parse_one_declaration_into;
use style::rule_tree::StyleSource;
use style::selector_parser::PseudoElementCascadeType;
use style::sequential;
use style::shared_lock::{SharedRwLockReadGuard, StylesheetGuards, ToCssWithGuard, Locked};
use style::string_cache::Atom;
use style::style_adjuster::StyleAdjuster;
@@ -649,20 +650,20 @@ pub extern "C" fn Servo_AnimationValue_U
let global_style_data = &*GLOBAL_STYLE_DATA;
Arc::new(global_style_data.shared_lock.wrap(
PropertyDeclarationBlock::with_one(value.uncompute(), Importance::Normal))).into_strong()
}
#[no_mangle]
pub extern "C" fn Servo_StyleSet_GetBaseComputedValuesForElement(raw_data: RawServoStyleSetBorrowed,
element: RawGeckoElementBorrowed,
- computed_values: ServoComputedValuesBorrowed,
+ computed_values: ServoStyleContextBorrowed,
snapshots: *const ServoElementSnapshotTable,
pseudo_type: CSSPseudoElementType)
- -> ServoComputedValuesStrong
+ -> ServoStyleContextStrong
{
use style::style_resolver::StyleResolverForElement;
debug_assert!(!snapshots.is_null());
let computed_values = ComputedValues::as_arc(&computed_values);
let rules = match computed_values.rules {
None => return computed_values.clone().into_strong(),
@@ -725,17 +726,16 @@ pub extern "C" fn Servo_ComputedValues_E
property_id: nsCSSPropertyID)
-> RawServoAnimationValueStrong
{
let property = match AnimatableLonghand::from_nscsspropertyid(property_id) {
Some(longhand) => longhand,
None => { return Strong::null(); }
};
- let computed_values = ComputedValues::as_arc(&computed_values);
Arc::new(AnimationValue::from_computed_values(&property, computed_values)).into_strong()
}
#[no_mangle]
pub extern "C" fn Servo_Property_IsAnimatable(property: nsCSSPropertyID) -> bool {
use style::properties::animated_properties;
animated_properties::nscsspropertyid_is_animatable(property)
}
@@ -1495,91 +1495,97 @@ pub extern "C" fn Servo_SupportsRule_Get
pub extern "C" fn Servo_DocumentRule_GetConditionText(rule: RawServoDocumentRuleBorrowed,
result: *mut nsAString) {
read_locked_arc(rule, |rule: &DocumentRule| {
rule.condition.to_css(unsafe { result.as_mut().unwrap() }).unwrap();
})
}
#[no_mangle]
-pub extern "C" fn Servo_ComputedValues_GetForAnonymousBox(parent_style_or_null: ServoComputedValuesBorrowedOrNull,
+pub extern "C" fn Servo_ComputedValues_GetForAnonymousBox(parent_style_or_null: ServoStyleContextBorrowedOrNull,
+ pseudo_type: CSSPseudoElementType,
pseudo_tag: *mut nsIAtom,
raw_data: RawServoStyleSetBorrowed)
- -> ServoComputedValuesStrong {
+ -> ServoStyleContextStrong {
let global_style_data = &*GLOBAL_STYLE_DATA;
let guard = global_style_data.shared_lock.read();
let guards = StylesheetGuards::same(&guard);
let data = PerDocumentStyleData::from_ffi(raw_data).borrow_mut();
let atom = Atom::from(pseudo_tag);
let pseudo = PseudoElement::from_anon_box_atom(&atom)
.expect("Not an anon box pseudo?");
-
- let maybe_parent = ComputedValues::arc_from_borrowed(&parent_style_or_null)
- .map(|p| &p.inner);
let cascade_flags = SKIP_ROOT_AND_ITEM_BASED_DISPLAY_FIXUP;
let metrics = get_metrics_provider_for_product();
- data.stylist.precomputed_values_for_pseudo(&guards, &pseudo, maybe_parent,
- cascade_flags, &metrics)
+ data.stylist.precomputed_values_for_pseudo(&guards, &pseudo, parent_style_or_null.map(|x| &**x),
+ cascade_flags, &metrics,
+ (pseudo_tag, pseudo_type),
+ parent_style_or_null)
.into_strong()
}
#[no_mangle]
pub extern "C" fn Servo_ResolvePseudoStyle(element: RawGeckoElementBorrowed,
pseudo_type: CSSPseudoElementType,
+ pseudo_tag: *mut nsIAtom,
is_probe: bool,
inherited_style: ServoComputedValuesBorrowedOrNull,
+ parent_style_context: ServoStyleContextBorrowedOrNull,
raw_data: RawServoStyleSetBorrowed)
- -> ServoComputedValuesStrong
+ -> ServoStyleContextStrong
{
let element = GeckoElement(element);
let data = unsafe { element.ensure_data() }.borrow_mut();
let doc_data = PerDocumentStyleData::from_ffi(raw_data).borrow();
debug!("Servo_ResolvePseudoStyle: {:?} {:?}, is_probe: {}",
element, PseudoElement::from_pseudo_type(pseudo_type), is_probe);
// FIXME(bholley): Assert against this.
if !data.has_styles() {
warn!("Calling Servo_ResolvePseudoStyle on unstyled element");
return if is_probe {
Strong::null()
} else {
- doc_data.default_computed_values().clone().to_outer().into_strong()
+ doc_data.default_computed_values()
+ .clone().to_outer(doc_data.stylist.device(), parent_style_context,
+ Some((pseudo_tag, pseudo_type))).into_strong()
};
}
let pseudo = PseudoElement::from_pseudo_type(pseudo_type)
.expect("ResolvePseudoStyle with a non-pseudo?");
let global_style_data = &*GLOBAL_STYLE_DATA;
let guard = global_style_data.shared_lock.read();
let style = get_pseudo_style(
&guard,
element,
&pseudo,
RuleInclusion::All,
&data.styles,
- ComputedValues::arc_from_borrowed(&inherited_style).map(|x| &***x),
+ inherited_style,
&*doc_data,
- is_probe
+ is_probe,
+ (pseudo_tag, pseudo_type),
+ parent_style_context
);
match style {
Some(s) => s.into_strong(),
None => {
debug_assert!(is_probe);
Strong::null()
}
}
}
#[no_mangle]
pub extern "C" fn Servo_SetExplicitStyle(element: RawGeckoElementBorrowed,
- style: ServoComputedValuesBorrowed)
+ style: ServoStyleContextBorrowed)
{
let element = GeckoElement(element);
let style = ComputedValues::as_arc(&style);
debug!("Servo_SetExplicitStyle: {:?}", element);
// We only support this API for initial styling. There's no reason it couldn't
// work for other things, we just haven't had a reason to do so.
debug_assert!(element.get_data().is_none());
let mut data = unsafe { element.ensure_data() }.borrow_mut();
@@ -1610,16 +1616,18 @@ fn get_pseudo_style(
guard: &SharedRwLockReadGuard,
element: GeckoElement,
pseudo: &PseudoElement,
rule_inclusion: RuleInclusion,
styles: &ElementStyles,
inherited_styles: Option<&ComputedValuesInner>,
doc_data: &PerDocumentStyleDataImpl,
is_probe: bool,
+ pseudo_info: PseudoInfo,
+ parent_style_context: ParentStyleContextInfo,
) -> Option<Arc<ComputedValues>> {
let style = match pseudo.cascade_type() {
PseudoElementCascadeType::Eager => {
match *pseudo {
PseudoElement::FirstLetter => {
styles.pseudos.get(&pseudo).and_then(|pseudo_styles| {
// inherited_styles can be None when doing lazy resolution
// (e.g. for computed style) or when probing. In that case
@@ -1631,17 +1639,19 @@ fn get_pseudo_style(
let guards = StylesheetGuards::same(guard);
let metrics = get_metrics_provider_for_product();
let inputs = CascadeInputs::new_from_style(pseudo_styles);
doc_data.stylist
.compute_pseudo_element_style_with_inputs(
&inputs,
&guards,
inherited_styles,
- &metrics)
+ &metrics,
+ pseudo_info.clone(),
+ parent_style_context)
})
},
_ => {
debug_assert!(inherited_styles.is_none() ||
ptr::eq(&*inherited_styles.unwrap(),
&***styles.primary()));
styles.pseudos.get(&pseudo).cloned()
},
@@ -1662,105 +1672,125 @@ fn get_pseudo_style(
doc_data.stylist
.lazily_compute_pseudo_element_style(
&guards,
&element,
&pseudo,
rule_inclusion,
base,
is_probe,
- &metrics)
+ &metrics,
+ pseudo_info.clone(),
+ parent_style_context)
},
};
if is_probe {
return style;
}
Some(style.unwrap_or_else(|| {
StyleBuilder::for_inheritance(
styles.primary(),
doc_data.default_computed_values(),
- ).build().to_outer()
+ ).build().to_outer(doc_data.stylist.device(), parent_style_context,
+ Some(pseudo_info))
}))
}
#[no_mangle]
pub extern "C" fn Servo_ComputedValues_Inherit(
raw_data: RawServoStyleSetBorrowed,
- parent_style: ServoComputedValuesBorrowedOrNull,
+ pseudo_type: CSSPseudoElementType,
+ pseudo_tag: *mut nsIAtom,
+ parent_style_context: ServoStyleContextBorrowedOrNull,
target: structs::InheritTarget
-) -> ServoComputedValuesStrong {
+) -> ServoStyleContextStrong {
let data = PerDocumentStyleData::from_ffi(raw_data).borrow();
- let maybe_arc = ComputedValues::arc_from_borrowed(&parent_style);
let for_text = target == structs::InheritTarget::Text;
- let style = if let Some(reference) = maybe_arc.as_ref() {
+ let style = if let Some(reference) = parent_style_context {
let mut style =
StyleBuilder::for_inheritance(reference,
&data.default_computed_values());
if for_text {
StyleAdjuster::new(&mut style)
.adjust_for_text();
}
style.build()
} else {
debug_assert!(!for_text);
data.default_computed_values().clone()
};
- style.to_outer().into_strong()
+ let pseudo_info = if pseudo_tag.is_null() {
+ None
+ } else {
+ Some((pseudo_tag, pseudo_type))
+ };
+
+ style.to_outer(data.stylist.device(), parent_style_context, pseudo_info).into_strong()
}
#[no_mangle]
pub extern "C" fn Servo_ComputedValues_GetVisitedStyle(values: ServoComputedValuesBorrowed)
- -> ServoComputedValuesStrong {
- match ComputedValues::as_arc(&values).clone_visited_style() {
+ -> ServoStyleContextStrong {
+ match ComputedValuesInner::as_arc(&values).clone_visited_style() {
Some(v) => v.into_strong(),
None => Strong::null(),
}
}
#[no_mangle]
+pub extern "C" fn Servo_StyleContext_NewContext(values: ServoComputedValuesBorrowed,
+ parent: ServoStyleContextBorrowedOrNull,
+ pres_context: bindings::RawGeckoPresContextBorrowed,
+ pseudo_type: CSSPseudoElementType,
+ pseudo_tag: *mut nsIAtom)
+ -> ServoStyleContextStrong {
+ let arc = ComputedValuesInner::as_arc(&values);
+ unsafe {
+ ComputedValuesInner::to_outer_from_arc(arc.clone_arc(), pres_context, parent,
+ pseudo_type, pseudo_tag).into_strong()
+ }
+}
+
+#[no_mangle]
pub extern "C" fn Servo_ComputedValues_GetStyleBits(values: ServoComputedValuesBorrowed) -> u64 {
use style::properties::computed_value_flags::*;
- let flags = ComputedValues::as_arc(&values).flags;
+ let flags = values.flags;
let mut result = 0;
if flags.contains(HAS_TEXT_DECORATION_LINES) {
result |= structs::NS_STYLE_HAS_TEXT_DECORATION_LINES as u64;
}
if flags.contains(SHOULD_SUPPRESS_LINEBREAK) {
result |= structs::NS_STYLE_SUPPRESS_LINEBREAK as u64;
}
result
}
#[no_mangle]
pub extern "C" fn Servo_ComputedValues_SpecifiesAnimationsOrTransitions(values: ServoComputedValuesBorrowed)
-> bool {
- let values = ComputedValues::as_arc(&values);
let b = values.get_box();
b.specifies_animations() || b.specifies_transitions()
}
#[no_mangle]
pub extern "C" fn Servo_ComputedValues_EqualCustomProperties(
first: ServoComputedValuesBorrowed,
second: ServoComputedValuesBorrowed
) -> bool {
- let first = ComputedValues::as_arc(&first);
- let second = ComputedValues::as_arc(&second);
first.get_custom_properties() == second.get_custom_properties()
}
#[no_mangle]
pub extern "C" fn Servo_ComputedValues_GetStyleRuleList(values: ServoComputedValuesBorrowed,
rules: RawGeckoServoStyleRuleListBorrowedMut) {
- let values = ComputedValues::as_arc(&values);
if let Some(ref rule_node) = values.rules {
let mut result = vec![];
for node in rule_node.self_and_ancestors() {
if let &StyleSource::Style(ref rule) = node.style_source() {
result.push(rule);
}
}
unsafe { rules.set_len(result.len() as u32) };
@@ -2748,39 +2778,43 @@ pub extern "C" fn Servo_TakeChangeHint(e
debug!("Servo_TakeChangeHint: {:?}, damage={:?}", element, damage);
damage.as_change_hint()
}
#[no_mangle]
pub extern "C" fn Servo_ResolveStyle(element: RawGeckoElementBorrowed,
raw_data: RawServoStyleSetBorrowed)
- -> ServoComputedValuesStrong
+ -> ServoStyleContextStrong
{
let element = GeckoElement(element);
debug!("Servo_ResolveStyle: {:?}", element);
let data = unsafe { element.ensure_data() }.borrow();
if !element.has_current_styles(&*data) {
debug_assert!(false, "Resolving style on element without current styles with lazy \
computation forbidden.");
let per_doc_data = PerDocumentStyleData::from_ffi(raw_data).borrow();
- return per_doc_data.default_computed_values().clone().to_outer().into_strong();
+ return per_doc_data.default_computed_values().clone()
+ .to_outer(per_doc_data.stylist.device(), None, None)
+ .into_strong();
}
data.styles.primary().clone().into_strong()
}
#[no_mangle]
pub extern "C" fn Servo_ResolveStyleLazily(element: RawGeckoElementBorrowed,
pseudo_type: CSSPseudoElementType,
+ pseudo_tag: *mut nsIAtom,
+ parent_style_context: ServoStyleContextBorrowedOrNull,
rule_inclusion: StyleRuleInclusion,
snapshots: *const ServoElementSnapshotTable,
raw_data: RawServoStyleSetBorrowed)
- -> ServoComputedValuesStrong
+ -> ServoStyleContextStrong
{
debug_assert!(!snapshots.is_null());
let global_style_data = &*GLOBAL_STYLE_DATA;
let guard = global_style_data.shared_lock.read();
let element = GeckoElement(element);
let doc_data = PerDocumentStyleData::from_ffi(raw_data);
let data = doc_data.borrow();
let rule_inclusion = RuleInclusion::from(rule_inclusion);
@@ -2791,16 +2825,18 @@ pub extern "C" fn Servo_ResolveStyleLazi
&guard,
element,
pseudo,
rule_inclusion,
styles,
/* inherited_styles = */ None,
&*data,
/* is_probe = */ false,
+ (pseudo_tag, pseudo_type),
+ parent_style_context
).expect("We're not probing, so we should always get a style \
back")
}
None => styles.primary().clone(),
}
};
// In the common case we already have the style. Check that before setting
@@ -2844,21 +2880,21 @@ fn simulate_compute_values_failure(prope
#[cfg(not(feature = "gecko_debug"))]
fn simulate_compute_values_failure(_: &PropertyValuePair) -> bool {
false
}
fn create_context<'a>(per_doc_data: &'a PerDocumentStyleDataImpl,
font_metrics_provider: &'a FontMetricsProvider,
- style: &'a ComputedValues,
- parent_style: &'a Option<&Arc<ComputedValues>>)
+ style: &'a ComputedValuesInner,
+ parent_style: &'a Option<&ComputedValuesInner>)
-> Context<'a> {
let default_values = per_doc_data.default_computed_values();
- let inherited_style = parent_style.map(|x| &x.inner).unwrap_or(default_values);
+ let inherited_style = parent_style.unwrap_or(default_values);
Context {
is_root_element: false,
device: per_doc_data.stylist.device(),
inherited_style: inherited_style,
layout_parent_style: inherited_style,
style: StyleBuilder::for_derived_style(&style),
font_metrics_provider: font_metrics_provider,
@@ -2875,22 +2911,21 @@ pub extern "C" fn Servo_GetComputedKeyfr
raw_data: RawServoStyleSetBorrowed,
computed_keyframes: RawGeckoComputedKeyframeValuesListBorrowedMut)
{
use std::mem;
use style::properties::LonghandIdSet;
let data = PerDocumentStyleData::from_ffi(raw_data).borrow();
let metrics = get_metrics_provider_for_product();
- let style = ComputedValues::as_arc(&style);
let element = GeckoElement(element);
let parent_element = element.inheritance_parent();
let parent_data = parent_element.as_ref().and_then(|e| e.borrow_data());
- let parent_style = parent_data.as_ref().map(|d| d.styles.primary());
+ let parent_style = parent_data.as_ref().map(|d| d.styles.primary()).map(|x| &***x);
let mut context = create_context(&data, &metrics, style, &parent_style);
let global_style_data = &*GLOBAL_STYLE_DATA;
let guard = global_style_data.shared_lock.read();
let default_values = data.default_computed_values();
for (index, keyframe) in keyframes.iter().enumerate() {
@@ -2955,23 +2990,22 @@ pub extern "C" fn Servo_GetComputedKeyfr
#[no_mangle]
pub extern "C" fn Servo_GetAnimationValues(declarations: RawServoDeclarationBlockBorrowed,
element: RawGeckoElementBorrowed,
style: ServoComputedValuesBorrowed,
raw_data: RawServoStyleSetBorrowed,
animation_values: RawGeckoServoAnimationValueListBorrowedMut) {
let data = PerDocumentStyleData::from_ffi(raw_data).borrow();
- let style = ComputedValues::as_arc(&style);
let metrics = get_metrics_provider_for_product();
let element = GeckoElement(element);
let parent_element = element.inheritance_parent();
let parent_data = parent_element.as_ref().and_then(|e| e.borrow_data());
- let parent_style = parent_data.as_ref().map(|d| d.styles.primary());
+ let parent_style = parent_data.as_ref().map(|d| d.styles.primary()).map(|x| &***x);
let mut context = create_context(&data, &metrics, style, &parent_style);
let default_values = data.default_computed_values();
let global_style_data = &*GLOBAL_STYLE_DATA;
let guard = global_style_data.shared_lock.read();
let declarations = Locked::<PropertyDeclarationBlock>::as_arc(&declarations);
@@ -2984,23 +3018,22 @@ pub extern "C" fn Servo_GetAnimationValu
#[no_mangle]
pub extern "C" fn Servo_AnimationValue_Compute(element: RawGeckoElementBorrowed,
declarations: RawServoDeclarationBlockBorrowed,
style: ServoComputedValuesBorrowed,
raw_data: RawServoStyleSetBorrowed)
-> RawServoAnimationValueStrong {
let data = PerDocumentStyleData::from_ffi(raw_data).borrow();
- let style = ComputedValues::as_arc(&style);
let metrics = get_metrics_provider_for_product();
let element = GeckoElement(element);
let parent_element = element.inheritance_parent();
let parent_data = parent_element.as_ref().and_then(|e| e.borrow_data());
- let parent_style = parent_data.as_ref().map(|d| d.styles.primary());
+ let parent_style = parent_data.as_ref().map(|d| d.styles.primary()).map(|x| &***x);
let mut context = create_context(&data, &metrics, style, &parent_style);
let default_values = data.default_computed_values();
let global_style_data = &*GLOBAL_STYLE_DATA;
let guard = global_style_data.shared_lock.read();
let declarations = Locked::<PropertyDeclarationBlock>::as_arc(&declarations);
// We only compute the first element in declarations.
@@ -3234,34 +3267,35 @@ pub extern "C" fn Servo_StyleSet_GetCoun
let guard = global_style_data.shared_lock.read();
rule.read_with(&guard).get()
}).unwrap_or(ptr::null_mut())
}
#[no_mangle]
pub extern "C" fn Servo_StyleSet_ResolveForDeclarations(
raw_data: RawServoStyleSetBorrowed,
- parent_style_or_null: ServoComputedValuesBorrowedOrNull,
- declarations: RawServoDeclarationBlockBorrowed
-) -> ServoComputedValuesStrong {
+ parent_style_context: ServoStyleContextBorrowedOrNull,
+ declarations: RawServoDeclarationBlockBorrowed,
+) -> ServoStyleContextStrong {
let doc_data = PerDocumentStyleData::from_ffi(raw_data).borrow();
let global_style_data = &*GLOBAL_STYLE_DATA;
let guard = global_style_data.shared_lock.read();
let guards = StylesheetGuards::same(&guard);
- let parent_style = match ComputedValues::arc_from_borrowed(&parent_style_or_null) {
- Some(parent) => &parent.inner,
+ let parent_style = match parent_style_context {
+ Some(parent) => &**parent,
None => doc_data.default_computed_values(),
};
let declarations = Locked::<PropertyDeclarationBlock>::as_arc(&declarations);
doc_data.stylist.compute_for_declarations(&guards,
parent_style,
- declarations.clone_arc()).into_strong()
+ declarations.clone_arc(),
+ parent_style_context).into_strong()
}
#[no_mangle]
pub extern "C" fn Servo_StyleSet_MightHaveAttributeDependency(
raw_data: RawServoStyleSetBorrowed,
element: RawGeckoElementBorrowed,
local_name: *mut nsIAtom,
) -> bool {
@@ -3311,44 +3345,45 @@ pub extern "C" fn Servo_StyleSet_HasStat
has_dep
}
#[no_mangle]
pub extern "C" fn Servo_GetCustomPropertyValue(computed_values: ServoComputedValuesBorrowed,
name: *const nsAString,
value: *mut nsAString) -> bool {
- let custom_properties = match ComputedValues::as_arc(&computed_values).custom_properties() {
+
+ let custom_properties = match computed_values.custom_properties() {
Some(p) => p,
None => return false,
};
let name = unsafe { Atom::from((&*name)) };
let computed_value = match custom_properties.get_computed_value(&name) {
Some(v) => v,
None => return false,
};
computed_value.to_css(unsafe { value.as_mut().unwrap() }).unwrap();
true
}
#[no_mangle]
pub extern "C" fn Servo_GetCustomPropertiesCount(computed_values: ServoComputedValuesBorrowed) -> u32 {
- match ComputedValues::as_arc(&computed_values).custom_properties() {
+ match ComputedValuesInner::as_arc(&computed_values).custom_properties() {
Some(p) => p.len() as u32,
None => 0,
}
}
#[no_mangle]
pub extern "C" fn Servo_GetCustomPropertyNameAt(computed_values: ServoComputedValuesBorrowed,
index: u32,
name: *mut nsAString) -> bool {
- let custom_properties = match ComputedValues::as_arc(&computed_values).custom_properties() {
+ let custom_properties = match ComputedValuesInner::as_arc(&computed_values).custom_properties() {
Some(p) => p,
None => return false,
};
let property_name = match custom_properties.get_name_at(index) {
Some(n) => n,
None => return false,
};