Bug 1428339: Make attribute mapping work without a pres context. r=heycam

MozReview-Commit-ID: FisYWoArX0N

--HG--
extra : rebase_source : b47cd6960b9bb44fc4573b295068fec01339322a
This commit is contained in:
Emilio Cobos Álvarez 2018-01-05 13:47:04 +01:00
parent 1d956ff4c6
commit 63b7c47b72
19 changed files with 100 additions and 101 deletions

View File

@ -360,14 +360,14 @@ nsMappedAttributes::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
}
void
nsMappedAttributes::LazilyResolveServoDeclaration(nsPresContext* aContext)
nsMappedAttributes::LazilyResolveServoDeclaration(nsIDocument* aDoc)
{
MOZ_ASSERT(!mServoStyle,
"LazilyResolveServoDeclaration should not be called if mServoStyle is already set");
if (mRuleMapper) {
mServoStyle = Servo_DeclarationBlock_CreateEmpty().Consume();
ServoSpecifiedValues servo = ServoSpecifiedValues(aContext, mServoStyle.get());
ServoSpecifiedValues servo = ServoSpecifiedValues(aDoc, mServoStyle.get());
(*mRuleMapper)(this, &servo);
}
}

View File

@ -75,7 +75,7 @@ public:
// Apply the contained mapper to the contained set of servo rules,
// unless the servo rules have already been initialized.
void LazilyResolveServoDeclaration(nsPresContext* aPresContext);
void LazilyResolveServoDeclaration(nsIDocument* aDocument);
// Obtain the contained servo declaration block
// May return null if called before the inner block

View File

@ -167,7 +167,7 @@ HTMLBodyElement::MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
// if marginwidth or marginheight is set in the <frame> and not set in the <body>
// reflect them as margin in the <body>
if (bodyMarginWidth == -1 || bodyMarginHeight == -1) {
nsCOMPtr<nsIDocShell> docShell(aData->mPresContext->GetDocShell());
nsCOMPtr<nsIDocShell> docShell(aData->Document()->GetDocShell());
if (docShell) {
nscoord frameMarginWidth=-1; // default value
nscoord frameMarginHeight=-1; // default value
@ -197,41 +197,35 @@ HTMLBodyElement::MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
if (aData->ShouldComputeStyleStruct(NS_STYLE_INHERIT_BIT(Display))) {
// When display if first asked for, go ahead and get our colors set up.
nsIPresShell *presShell = aData->PresContext()->GetPresShell();
if (presShell) {
nsIDocument *doc = presShell->GetDocument();
if (doc) {
nsHTMLStyleSheet* styleSheet = doc->GetAttributeStyleSheet();
if (styleSheet) {
const nsAttrValue* value;
nscolor color;
value = aAttributes->GetAttr(nsGkAtoms::link);
if (value && value->GetColorValue(color)) {
styleSheet->SetLinkColor(color);
}
if (nsHTMLStyleSheet* styleSheet = aData->Document()->GetAttributeStyleSheet()) {
const nsAttrValue* value;
nscolor color;
value = aAttributes->GetAttr(nsGkAtoms::link);
if (value && value->GetColorValue(color)) {
styleSheet->SetLinkColor(color);
}
value = aAttributes->GetAttr(nsGkAtoms::alink);
if (value && value->GetColorValue(color)) {
styleSheet->SetActiveLinkColor(color);
}
value = aAttributes->GetAttr(nsGkAtoms::alink);
if (value && value->GetColorValue(color)) {
styleSheet->SetActiveLinkColor(color);
}
value = aAttributes->GetAttr(nsGkAtoms::vlink);
if (value && value->GetColorValue(color)) {
styleSheet->SetVisitedLinkColor(color);
}
}
value = aAttributes->GetAttr(nsGkAtoms::vlink);
if (value && value->GetColorValue(color)) {
styleSheet->SetVisitedLinkColor(color);
}
}
}
if (aData->ShouldComputeStyleStruct(NS_STYLE_INHERIT_BIT(Color))) {
if (!aData->PropertyIsSet(eCSSProperty_color) &&
aData->PresContext()->UseDocumentColors()) {
!aData->ShouldIgnoreColors()) {
// color: color
nscolor color;
const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::text);
if (value && value->GetColorValue(color))
if (value && value->GetColorValue(color)) {
aData->SetColorValue(eCSSProperty_color, color);
}
}
}

View File

@ -76,7 +76,7 @@ HTMLFontElement::MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
}
if (aData->ShouldComputeStyleStruct(NS_STYLE_INHERIT_BIT(Color))) {
if (!aData->PropertyIsSet(eCSSProperty_color) &&
aData->PresContext()->UseDocumentColors()) {
!aData->ShouldIgnoreColors()) {
// color: color
const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::color);
nscolor color;
@ -86,7 +86,7 @@ HTMLFontElement::MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
}
}
if (aData->ShouldComputeStyleStruct(NS_STYLE_INHERIT_BIT(TextReset)) &&
aData->PresContext()->CompatibilityMode() == eCompatibility_NavQuirks) {
aData->Document()->GetCompatibilityMode() == eCompatibility_NavQuirks) {
// Make <a><font color="red">text</font></a> give the text a red underline
// in quirks mode. The NS_STYLE_TEXT_DECORATION_LINE_OVERRIDE_ALL flag only
// affects quirks mode rendering.

View File

@ -169,8 +169,7 @@ HTMLHRElement::MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
if (aData->ShouldComputeStyleStruct(NS_STYLE_INHERIT_BIT(Color))) {
// color: a color
// (we got the color attribute earlier)
if (colorIsSet &&
aData->PresContext()->UseDocumentColors()) {
if (colorIsSet && !aData->ShouldIgnoreColors()) {
aData->SetColorValueIfUnset(eCSSProperty_color, color);
}
}

View File

@ -237,7 +237,7 @@ HTMLTableCellElement::MapAttributesIntoRule(const nsMappedAttributes* aAttribute
if (aAttributes->GetAttr(nsGkAtoms::nowrap)) {
// See if our width is not a nonzero integer width.
const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::width);
nsCompatibility mode = aData->PresContext()->CompatibilityMode();
nsCompatibility mode = aData->Document()->GetCompatibilityMode();
if (!value || value->Type() != nsAttrValue::eInteger ||
value->GetIntegerValue() == 0 ||
eCompatibility_NavQuirks != mode) {

View File

@ -952,8 +952,7 @@ HTMLTableElement::MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
// which *element* it's matching (style rules should not stop matching
// when the display type is changed).
nsPresContext* presContext = aData->PresContext();
nsCompatibility mode = presContext->CompatibilityMode();
nsCompatibility mode = aData->Document()->GetCompatibilityMode();
if (aData->ShouldComputeStyleStruct(NS_STYLE_INHERIT_BIT(TableBorder))) {
// cellspacing
@ -999,8 +998,7 @@ HTMLTableElement::MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
// bordercolor
const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::bordercolor);
nscolor color;
if (value && presContext->UseDocumentColors() &&
value->GetColorValue(color)) {
if (value && !aData->ShouldIgnoreColors() && value->GetColorValue(color)) {
aData->SetColorValueIfUnset(eCSSProperty_border_top_color, color);
aData->SetColorValueIfUnset(eCSSProperty_border_left_color, color);
aData->SetColorValueIfUnset(eCSSProperty_border_bottom_color, color);

View File

@ -1544,7 +1544,7 @@ nsGenericHTMLElement::MapBackgroundInto(const nsMappedAttributes* aAttributes,
return;
if (!aData->PropertyIsSet(eCSSProperty_background_image) &&
aData->PresContext()->UseDocumentColors()) {
!aData->ShouldIgnoreColors()) {
// background
nsAttrValue* value =
const_cast<nsAttrValue*>(aAttributes->GetAttr(nsGkAtoms::background));
@ -1562,7 +1562,7 @@ nsGenericHTMLElement::MapBGColorInto(const nsMappedAttributes* aAttributes,
return;
if (!aData->PropertyIsSet(eCSSProperty_background_color) &&
aData->PresContext()->UseDocumentColors()) {
!aData->ShouldIgnoreColors()) {
const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::bgcolor);
nscolor color;
if (value && value->GetColorValue(color)) {

View File

@ -528,7 +528,7 @@ nsMathMLElement::MapMathMLAttributesInto(const nsMappedAttributes* aAttributes,
} else {
ReportParseErrorNoTag(str,
nsGkAtoms::scriptsizemultiplier_,
aData->mPresContext->Document());
aData->Document());
}
}
}
@ -550,7 +550,7 @@ nsMathMLElement::MapMathMLAttributesInto(const nsMappedAttributes* aAttributes,
nsCSSValue scriptMinSize;
ParseNumericValue(value->GetStringValue(), scriptMinSize,
PARSE_ALLOW_UNITLESS | CONVERT_UNITLESS_TO_PERCENT,
aData->mPresContext->Document());
aData->Document());
if (scriptMinSize.GetUnit() == eCSSUnit_Percent) {
scriptMinSize.SetFloatValue(8.0 * scriptMinSize.GetPercentValue(),
@ -594,7 +594,7 @@ nsMathMLElement::MapMathMLAttributesInto(const nsMappedAttributes* aAttributes,
} else {
ReportParseErrorNoTag(str,
nsGkAtoms::scriptlevel_,
aData->mPresContext->Document());
aData->Document());
}
}
}
@ -628,7 +628,7 @@ nsMathMLElement::MapMathMLAttributesInto(const nsMappedAttributes* aAttributes,
if (value) {
WarnDeprecated(nsGkAtoms::fontsize_->GetUTF16String(),
nsGkAtoms::mathsize_->GetUTF16String(),
aData->mPresContext->Document());
aData->Document());
}
}
if (value && value->Type() == nsAttrValue::eString &&
@ -671,7 +671,7 @@ nsMathMLElement::MapMathMLAttributesInto(const nsMappedAttributes* aAttributes,
if (value) {
WarnDeprecated(nsGkAtoms::fontfamily_->GetUTF16String(),
nsGkAtoms::mathvariant_->GetUTF16String(),
aData->mPresContext->Document());
aData->Document());
}
if (value && value->Type() == nsAttrValue::eString &&
!aData->PropertyIsSet(eCSSProperty_font_family)) {
@ -692,7 +692,7 @@ nsMathMLElement::MapMathMLAttributesInto(const nsMappedAttributes* aAttributes,
if (value) {
WarnDeprecated(nsGkAtoms::fontstyle_->GetUTF16String(),
nsGkAtoms::mathvariant_->GetUTF16String(),
aData->mPresContext->Document());
aData->Document());
if (value->Type() == nsAttrValue::eString &&
!aData->PropertyIsSet(eCSSProperty_font_style)) {
nsAutoString str(value->GetStringValue());
@ -721,7 +721,7 @@ nsMathMLElement::MapMathMLAttributesInto(const nsMappedAttributes* aAttributes,
if (value) {
WarnDeprecated(nsGkAtoms::fontweight_->GetUTF16String(),
nsGkAtoms::mathvariant_->GetUTF16String(),
aData->mPresContext->Document());
aData->Document());
if (value->Type() == nsAttrValue::eString &&
!aData->PropertyIsSet(eCSSProperty_font_weight)) {
nsAutoString str(value->GetStringValue());
@ -806,7 +806,7 @@ nsMathMLElement::MapMathMLAttributesInto(const nsMappedAttributes* aAttributes,
if (value) {
WarnDeprecated(nsGkAtoms::background->GetUTF16String(),
nsGkAtoms::mathbackground_->GetUTF16String(),
aData->mPresContext->Document());
aData->Document());
}
}
if (value) {
@ -841,7 +841,7 @@ nsMathMLElement::MapMathMLAttributesInto(const nsMappedAttributes* aAttributes,
if (value) {
WarnDeprecated(nsGkAtoms::color->GetUTF16String(),
nsGkAtoms::mathcolor_->GetUTF16String(),
aData->mPresContext->Document());
aData->Document());
}
}
nscolor color;
@ -868,8 +868,7 @@ nsMathMLElement::MapMathMLAttributesInto(const nsMappedAttributes* aAttributes,
nsCSSValue width;
// This does not handle auto and unitless values
if (value && value->Type() == nsAttrValue::eString) {
ParseNumericValue(value->GetStringValue(), width, 0,
aData->mPresContext->Document());
ParseNumericValue(value->GetStringValue(), width, 0, aData->Document());
if (width.GetUnit() == eCSSUnit_Percent) {
aData->SetPercentValue(eCSSProperty_width,
width.GetPercentValue());

View File

@ -16,33 +16,42 @@
#include "mozilla/ServoUtils.h"
#include "nsCSSProps.h"
#include "nsCSSValue.h"
#include "nsPresContext.h"
#include "StyleBackendType.h"
class nsAttrValue;
struct nsRuleData;
namespace mozilla {
class ServoSpecifiedValues;
// This provides a common interface for attribute mappers (MapAttributesIntoRule)
// to use regardless of the style backend. If the style backend is Gecko,
// this will contain an nsRuleData. If it is Servo, it will be a PropertyDeclarationBlock.
// This provides a common interface for attribute mappers
// (MapAttributesIntoRule) to use regardless of the style backend. If the style
// backend is Gecko, this will contain an nsRuleData. If it is Servo, it will be
// a PropertyDeclarationBlock.
class GenericSpecifiedValues
{
protected:
explicit GenericSpecifiedValues(StyleBackendType aType,
nsPresContext* aPresContext,
uint32_t aSIDs)
explicit GenericSpecifiedValues(StyleBackendType aType, nsIDocument* aDoc, uint32_t aSIDs)
: mType(aType)
, mPresContext(aPresContext)
, mDocument(aDoc)
, mSIDs(aSIDs)
{}
public:
MOZ_DECL_STYLO_METHODS(nsRuleData, ServoSpecifiedValues)
nsIDocument* Document()
{
return mDocument;
}
// Whether we should ignore document colors.
inline bool ShouldIgnoreColors() const;
// Check if we already contain a certain longhand
inline bool PropertyIsSet(nsCSSPropertyID aId);
// Check if we are able to hold longhands from a given
// style struct. Pass the result of NS_STYLE_INHERIT_BIT to this
// function. Can accept multiple inherit bits or'd together.
@ -51,8 +60,6 @@ public:
return aInheritBits & mSIDs;
}
inline nsPresContext* PresContext() { return mPresContext; }
// Set a property to an identifier (string)
inline void SetIdentStringValue(nsCSSPropertyID aId, const nsString& aValue);
inline void SetIdentStringValueIfUnset(nsCSSPropertyID aId,
@ -116,7 +123,7 @@ public:
inline void SetBackgroundImage(nsAttrValue& value);
const mozilla::StyleBackendType mType;
nsPresContext* const mPresContext;
nsIDocument* const mDocument;
const uint32_t mSIDs;
};

View File

@ -24,6 +24,19 @@ MOZ_DEFINE_STYLO_METHODS(GenericSpecifiedValues,
nsRuleData,
ServoSpecifiedValues)
bool
GenericSpecifiedValues::ShouldIgnoreColors() const
{
if (IsServo()) {
// Servo handles this during cascading.
//
// FIXME(emilio): We should eventually move it to the document though.
return false;
}
return !AsGecko()->mPresContext->UseDocumentColors();
}
bool
GenericSpecifiedValues::PropertyIsSet(nsCSSPropertyID aId)
{

View File

@ -7,25 +7,8 @@
#include "mozilla/ServoBindings.h"
#include "mozilla/ServoSpecifiedValues.h"
namespace {
#define STYLE_STRUCT(name, checkdata_cb) | NS_STYLE_INHERIT_BIT(name)
const uint64_t ALL_SIDS = 0
#include "nsStyleStructList.h"
;
#undef STYLE_STRUCT
} // anonymous namespace
using namespace mozilla;
ServoSpecifiedValues::ServoSpecifiedValues(nsPresContext* aContext,
RawServoDeclarationBlock* aDecl)
: GenericSpecifiedValues(StyleBackendType::Servo, aContext, ALL_SIDS)
, mDecl(aDecl)
{}
bool
ServoSpecifiedValues::PropertyIsSet(nsCSSPropertyID aId)
{
@ -45,9 +28,17 @@ ServoSpecifiedValues::SetIdentAtomValue(nsCSSPropertyID aId, nsAtom* aValue)
{
Servo_DeclarationBlock_SetIdentStringValue(mDecl, aId, aValue);
if (aId == eCSSProperty__x_lang) {
// This forces the lang prefs result to be cached
// so that we can access them off main thread during traversal
mPresContext->ForceCacheLang(aValue);
// This forces the lang prefs result to be cached so that we can access them
// off main thread during traversal.
//
// FIXME(emilio): Can we move mapped attribute declarations across
// documents? Isn't this wrong in that case? This is pretty out of place
// anyway.
if (nsIPresShell* shell = mDocument->GetShell()) {
if (nsPresContext* pc = shell->GetPresContext()) {
pc->ForceCacheLang(aValue);
}
}
}
}
@ -129,5 +120,5 @@ ServoSpecifiedValues::SetBackgroundImage(nsAttrValue& aValue)
nsAutoString str;
aValue.ToString(str);
Servo_DeclarationBlock_SetBackgroundImage(
mDecl, str, mPresContext->Document()->DefaultStyleAttrURLData());
mDecl, str, mDocument->DefaultStyleAttrURLData());
}

View File

@ -20,8 +20,10 @@ namespace mozilla {
class ServoSpecifiedValues final : public GenericSpecifiedValues
{
public:
ServoSpecifiedValues(nsPresContext* aContext,
RawServoDeclarationBlock* aDecl);
ServoSpecifiedValues(nsIDocument* aDocument, RawServoDeclarationBlock* aDecl)
: GenericSpecifiedValues(StyleBackendType::Servo, aDocument, NS_STYLE_INHERIT_MASK)
, mDecl(aDecl)
{}
// GenericSpecifiedValues overrides
bool PropertyIsSet(nsCSSPropertyID aId);

View File

@ -353,7 +353,7 @@ void
ServoStyleSet::ResolveMappedAttrDeclarationBlocks()
{
if (nsHTMLStyleSheet* sheet = mPresContext->Document()->GetAttributeStyleSheet()) {
sheet->CalculateMappedServoDeclarations(mPresContext);
sheet->CalculateMappedServoDeclarations();
}
mPresContext->Document()->ResolveScheduledSVGPresAttrs();

View File

@ -567,18 +567,15 @@ nsHTMLStyleSheet::DropMappedAttributes(nsMappedAttributes* aMapped)
}
void
nsHTMLStyleSheet::CalculateMappedServoDeclarations(nsPresContext* aPresContext)
nsHTMLStyleSheet::CalculateMappedServoDeclarations()
{
MOZ_ASSERT(!mDocument->GetShell() ||
mDocument->GetShell()->GetPresContext() == aPresContext);
for (auto iter = mMappedAttrTable.Iter(); !iter.Done(); iter.Next()) {
MappedAttrTableEntry* attr = static_cast<MappedAttrTableEntry*>(iter.Get());
if (attr->mAttributes->GetServoStyle()) {
// Only handle cases which haven't been filled in already
continue;
}
attr->mAttributes->LazilyResolveServoDeclaration(aPresContext);
attr->mAttributes->LazilyResolveServoDeclaration(mDocument);
}
}

View File

@ -77,7 +77,7 @@ public:
// For each mapped presentation attribute in the cache, resolve
// the attached ServoDeclarationBlock by running the mapping
// and converting the ruledata to Servo specified values.
void CalculateMappedServoDeclarations(nsPresContext* aPresContext);
void CalculateMappedServoDeclarations();
nsIStyleRule* LangRuleFor(const nsAtom* aLanguage);

View File

@ -8,6 +8,8 @@
#include "nsAttrValueInlines.h"
#include "nsCSSParser.h"
#include "nsPresContext.h"
#include "mozilla/GeckoStyleContext.h"
#include "mozilla/Poison.h"
#include <stdint.h>
@ -31,10 +33,10 @@ nsRuleData::GetPoisonOffset()
nsRuleData::nsRuleData(uint32_t aSIDs,
nsCSSValue* aValueStorage,
nsPresContext* aContext,
GeckoStyleContext* aStyleContext)
: GenericSpecifiedValues(StyleBackendType::Gecko, aContext, aSIDs)
: GenericSpecifiedValues(StyleBackendType::Gecko, aStyleContext->PresContext()->Document(), aSIDs)
, mStyleContext(aStyleContext)
, mPresContext(aStyleContext->PresContext())
, mValueStorage(aValueStorage)
{
#ifndef MOZ_VALGRIND
@ -71,7 +73,7 @@ nsRuleData::SetBackgroundImage(nsAttrValue& aValue)
// If the value is an image, or it is a URL and we attempted a load,
// put it in the style tree.
if (aValue.Type() == nsAttrValue::eURL) {
aValue.LoadImage(mPresContext->Document());
aValue.LoadImage(mDocument);
}
if (aValue.Type() == nsAttrValue::eImage) {
nsCSSValueList* list = backImage->SetListValue();

View File

@ -36,6 +36,7 @@ struct nsRuleData final : mozilla::GenericSpecifiedValues
bool mIsImportantRule;
mozilla::SheetType mLevel;
mozilla::GeckoStyleContext* const mStyleContext;
nsPresContext* const mPresContext;
// We store nsCSSValues needed to compute the data for one or more
// style structs (specified by the bitfield mSIDs). These are stored
@ -55,7 +56,6 @@ struct nsRuleData final : mozilla::GenericSpecifiedValues
nsRuleData(uint32_t aSIDs,
nsCSSValue* aValueStorage,
nsPresContext* aContext,
mozilla::GeckoStyleContext* aStyleContext);
#ifdef DEBUG

View File

@ -2474,7 +2474,7 @@ nsRuleNode::WalkRuleTree(const nsStyleStructID aSID,
AutoCSSValueArray dataArray(dataStorage, nprops);
nsRuleData ruleData(nsCachedStyleData::GetBitForSID(aSID),
dataArray.get(), mPresContext, aContext);
dataArray.get(), aContext);
ruleData.mValueOffsets[aSID] = 0;
// We start at the most specific rule in the tree.
@ -4084,8 +4084,7 @@ nsRuleNode::SetGenericFont(nsPresContext* aPresContext,
GeckoStyleContext* context = contextPath[i];
AutoCSSValueArray dataArray(dataStorage, nprops);
nsRuleData ruleData(NS_STYLE_INHERIT_BIT(Font), dataArray.get(),
aPresContext, context);
nsRuleData ruleData(NS_STYLE_INHERIT_BIT(Font), dataArray.get(), context);
ruleData.mValueOffsets[eStyleStruct_Font] = 0;
// Trimmed down version of ::WalkRuleTree() to re-apply the style rules
@ -10193,8 +10192,7 @@ nsRuleNode::HasAuthorSpecifiedRules(GeckoStyleContext* aStyleContext,
AutoCSSValueArray dataArray(dataStorage, nprops);
/* We're relying on the use of |styleContext| not mutating it! */
nsRuleData ruleData(inheritBits, dataArray.get(),
styleContext->PresContext(), styleContext);
nsRuleData ruleData(inheritBits, dataArray.get(), styleContext);
if (ruleTypeMask & NS_AUTHOR_SPECIFIED_BACKGROUND) {
ruleData.mValueOffsets[eStyleStruct_Background] = backgroundOffset;
@ -10387,8 +10385,7 @@ nsRuleNode::ComputePropertiesOverridingAnimation(
AutoCSSValueArray dataArray(dataStorage, nprops);
// We're relying on the use of |aStyleContext| not mutating it!
nsRuleData ruleData(structBits, dataArray.get(),
aStyleContext->PresContext(), aStyleContext);
nsRuleData ruleData(structBits, dataArray.get(), aStyleContext);
for (nsStyleStructID sid = nsStyleStructID(0);
sid < nsStyleStructID_Length; sid = nsStyleStructID(sid + 1)) {
if (structBits & nsCachedStyleData::GetBitForSID(sid)) {