mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-01-26 23:23:33 +00:00
Bug 950436 - Store ImageValues that resulted from re-parsing a nsCSSValueTokenStream on that object. r=dbaron
This commit is contained in:
parent
4e5989ae37
commit
2b8efd3f5d
5
layout/reftests/bugs/950436-1-ref.html
Normal file
5
layout/reftests/bugs/950436-1-ref.html
Normal file
@ -0,0 +1,5 @@
|
||||
<!DOCTYPE html>
|
||||
<style>
|
||||
body { background-image: url(950436-1.png); }
|
||||
</style>
|
||||
<body>
|
7
layout/reftests/bugs/950436-1.html
Normal file
7
layout/reftests/bugs/950436-1.html
Normal file
@ -0,0 +1,7 @@
|
||||
<!DOCTYPE html>
|
||||
<style>
|
||||
/* It's important here to reference an image that has not previously been loaded
|
||||
during the reftest run. So don't use 950436-1.png in any other test. */
|
||||
body { var-a: url(950436-1.png); background-image: var(a); }
|
||||
</style>
|
||||
<body>
|
BIN
layout/reftests/bugs/950436-1.png
Normal file
BIN
layout/reftests/bugs/950436-1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 201 B |
@ -1793,6 +1793,7 @@ fuzzy-if(OSX==10.6,2,30) skip-if(B2G&&browserIsRemote) == 933264-1.html 933264-1
|
||||
== 953334-win32-clipping.html 953334-win32-clipping-ref.html
|
||||
== 956513-1.svg 956513-1-ref.svg
|
||||
== 944291-1.html 944291-1-ref.html
|
||||
== 950436-1.html 950436-1-ref.html
|
||||
== 957770-1.svg 957770-1-ref.svg
|
||||
== 960277-1.html 960277-1-ref.html
|
||||
pref(layout.css.overflow-clip-box.enabled,true) fuzzy(50,10) == 966992-1.html 966992-1-ref.html
|
||||
|
@ -48,19 +48,27 @@ ShouldIgnoreColors(nsRuleData *aRuleData)
|
||||
* Image sources are specified by |url()| or |-moz-image-rect()| function.
|
||||
*/
|
||||
static void
|
||||
TryToStartImageLoadOnValue(const nsCSSValue& aValue, nsIDocument* aDocument)
|
||||
TryToStartImageLoadOnValue(const nsCSSValue& aValue, nsIDocument* aDocument,
|
||||
nsCSSValueTokenStream* aTokenStream)
|
||||
{
|
||||
MOZ_ASSERT(aDocument);
|
||||
|
||||
if (aValue.GetUnit() == eCSSUnit_URL) {
|
||||
aValue.StartImageLoad(aDocument);
|
||||
if (aTokenStream) {
|
||||
aTokenStream->mImageValues.PutEntry(aValue.GetImageStructValue());
|
||||
}
|
||||
}
|
||||
else if (aValue.GetUnit() == eCSSUnit_Image) {
|
||||
// If we already have a request, see if this document needs to clone it.
|
||||
imgIRequest* request = aValue.GetImageValue(nullptr);
|
||||
|
||||
if (request) {
|
||||
aDocument->StyleImageLoader()->MaybeRegisterCSSImage(aValue.GetImageStructValue());
|
||||
mozilla::css::ImageValue* imageValue = aValue.GetImageStructValue();
|
||||
aDocument->StyleImageLoader()->MaybeRegisterCSSImage(imageValue);
|
||||
if (aTokenStream) {
|
||||
aTokenStream->mImageValues.PutEntry(imageValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (aValue.EqualsFunction(eCSSKeyword__moz_image_rect)) {
|
||||
@ -68,25 +76,27 @@ TryToStartImageLoadOnValue(const nsCSSValue& aValue, nsIDocument* aDocument)
|
||||
NS_ABORT_IF_FALSE(arguments->Count() == 6, "unexpected num of arguments");
|
||||
|
||||
const nsCSSValue& image = arguments->Item(1);
|
||||
TryToStartImageLoadOnValue(image, aDocument);
|
||||
TryToStartImageLoadOnValue(image, aDocument, aTokenStream);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
TryToStartImageLoad(const nsCSSValue& aValue, nsIDocument* aDocument,
|
||||
nsCSSProperty aProperty)
|
||||
nsCSSProperty aProperty,
|
||||
nsCSSValueTokenStream* aTokenStream)
|
||||
{
|
||||
if (aValue.GetUnit() == eCSSUnit_List) {
|
||||
for (const nsCSSValueList* l = aValue.GetListValue(); l; l = l->mNext) {
|
||||
TryToStartImageLoad(l->mValue, aDocument, aProperty);
|
||||
TryToStartImageLoad(l->mValue, aDocument, aProperty, aTokenStream);
|
||||
}
|
||||
} else if (nsCSSProps::PropHasFlags(aProperty,
|
||||
CSS_PROPERTY_IMAGE_IS_IN_ARRAY_0)) {
|
||||
if (aValue.GetUnit() == eCSSUnit_Array) {
|
||||
TryToStartImageLoadOnValue(aValue.GetArrayValue()->Item(0), aDocument);
|
||||
TryToStartImageLoadOnValue(aValue.GetArrayValue()->Item(0), aDocument,
|
||||
aTokenStream);
|
||||
}
|
||||
} else {
|
||||
TryToStartImageLoadOnValue(aValue, aDocument);
|
||||
TryToStartImageLoadOnValue(aValue, aDocument, aTokenStream);
|
||||
}
|
||||
}
|
||||
|
||||
@ -111,9 +121,28 @@ MapSinglePropertyInto(nsCSSProperty aProp,
|
||||
nsRuleData* aRuleData)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(aValue->GetUnit() != eCSSUnit_Null, "oops");
|
||||
|
||||
// Although aTarget is the nsCSSValue we are going to write into,
|
||||
// we also look at its value before writing into it. This is done
|
||||
// when aTarget is a token stream value, which is the case when we
|
||||
// have just re-parsed a property that had a variable reference (in
|
||||
// nsCSSParser::ParsePropertyWithVariableReferences). TryToStartImageLoad
|
||||
// then records any resulting ImageValue objects on the
|
||||
// nsCSSValueTokenStream object we found on aTarget. See the comment
|
||||
// above nsCSSValueTokenStream::mImageValues for why.
|
||||
NS_ABORT_IF_FALSE(aTarget->GetUnit() == eCSSUnit_TokenStream ||
|
||||
aTarget->GetUnit() == eCSSUnit_Null,
|
||||
"aTarget must only be a token stream (when re-parsing "
|
||||
"properties with variable references) or null");
|
||||
|
||||
nsCSSValueTokenStream* tokenStream =
|
||||
aTarget->GetUnit() == eCSSUnit_TokenStream ?
|
||||
aTarget->GetTokenStreamValue() :
|
||||
nullptr;
|
||||
|
||||
if (ShouldStartImageLoads(aRuleData, aProp)) {
|
||||
nsIDocument* doc = aRuleData->mPresContext->Document();
|
||||
TryToStartImageLoad(*aValue, doc, aProp);
|
||||
TryToStartImageLoad(*aValue, doc, aProp, tokenStream);
|
||||
}
|
||||
*aTarget = *aValue;
|
||||
if (nsCSSProps::PropHasFlags(aProp,
|
||||
|
@ -1355,6 +1355,18 @@ struct nsCSSValueTokenStream {
|
||||
uint32_t mLineNumber;
|
||||
uint32_t mLineOffset;
|
||||
|
||||
// This table is used to hold a reference on to any ImageValue that results
|
||||
// from re-parsing this token stream at computed value time. When properties
|
||||
// like background-image contain a normal url(), the Declaration's data block
|
||||
// will hold a reference to the ImageValue. When a token stream is used,
|
||||
// the Declaration only holds on to this nsCSSValueTokenStream object, and
|
||||
// the ImageValue would only exist for the duration of
|
||||
// nsRuleNode::WalkRuleTree, in the AutoCSSValueArray. So instead when
|
||||
// we re-parse a token stream and get an ImageValue, we record it in this
|
||||
// table so that the Declaration can be the object that keeps holding
|
||||
// a reference to it.
|
||||
nsTHashtable<nsRefPtrHashKey<mozilla::css::ImageValue> > mImageValues;
|
||||
|
||||
private:
|
||||
nsCSSValueTokenStream(const nsCSSValueTokenStream& aOther) MOZ_DELETE;
|
||||
nsCSSValueTokenStream& operator=(const nsCSSValueTokenStream& aOther) MOZ_DELETE;
|
||||
|
@ -2073,6 +2073,14 @@ nsRuleNode::ResolveVariableReferences(const nsStyleStructID aSID,
|
||||
&aContext->StyleVariables()->mVariables;
|
||||
nsCSSValueTokenStream* tokenStream = value->GetTokenStreamValue();
|
||||
|
||||
// Note that ParsePropertyWithVariableReferences relies on the fact
|
||||
// that the nsCSSValue in aRuleData for the property we are re-parsing
|
||||
// is still the token stream value. When
|
||||
// ParsePropertyWithVariableReferences calls
|
||||
// nsCSSExpandedDataBlock::MapRuleInfoInto, that function will add
|
||||
// the ImageValue that is created into the token stream object's
|
||||
// mImageValues table; see the comment above mImageValues for why.
|
||||
|
||||
// XXX Should pass in sheet here (see bug 952338).
|
||||
parser.ParsePropertyWithVariableReferences(
|
||||
tokenStream->mPropertyID, tokenStream->mShorthandPropertyID,
|
||||
|
Loading…
x
Reference in New Issue
Block a user