Bug 1452987: Simplify ImageValue. r=heycam

MozReview-Commit-ID: 5LRaaEPSSdY

--HG--
extra : rebase_source : 2654a870e2a985bf7a609ee436ba1800bf6033a3
This commit is contained in:
Emilio Cobos Álvarez 2018-04-10 16:54:57 +02:00
parent 532399b51c
commit 9ab1873cd3
9 changed files with 51 additions and 295 deletions

View File

@ -65,6 +65,9 @@ class nsDOMStringMap;
namespace mozilla {
class DeclarationBlock;
class TextEditor;
namespace css {
struct URLValue;
} // namespace css
namespace dom {
struct AnimationFilter;
struct ScrollIntoViewOptions;

View File

@ -30,11 +30,6 @@
#include "nsIDocument.h"
#include <algorithm>
#ifdef LoadImage
// Undefine LoadImage to prevent naming conflict with Windows.
#undef LoadImage
#endif
using namespace mozilla;
#define MISC_STR_PTR(_cont) \
@ -305,11 +300,6 @@ nsAttrValue::SetTo(const nsAttrValue& aOther)
NS_ADDREF(cont->mValue.mURL = otherCont->mValue.mURL);
break;
}
case eImage:
{
NS_ADDREF(cont->mValue.mImage = otherCont->mValue.mImage);
break;
}
case eAtomArray:
{
if (!EnsureEmptyAtomArray() ||
@ -416,7 +406,7 @@ nsAttrValue::SetTo(already_AddRefed<DeclarationBlock> aValue,
}
void
nsAttrValue::SetTo(css::URLValue* aValue, const nsAString* aSerialized)
nsAttrValue::SetTo(nsIURI* aValue, const nsAString* aSerialized)
{
MiscContainer* cont = EnsureEmptyMiscContainer();
NS_ADDREF(cont->mValue.mURL = aValue);
@ -878,10 +868,7 @@ nsAttrValue::HashValue() const
{
return NS_PTR_TO_INT32(cont->mValue.mCSSDeclaration);
}
// Intentionally identical, so that loading the image does not change the
// hash code.
case eURL:
case eImage:
{
nsString str;
ToString(str);
@ -992,10 +979,6 @@ nsAttrValue::Equals(const nsAttrValue& aOther) const
{
return thisCont->mValue.mURL == otherCont->mValue.mURL;
}
case eImage:
{
return thisCont->mValue.mImage == otherCont->mValue.mImage;
}
case eAtomArray:
{
// For classlists we could be insensitive to order, however
@ -1681,28 +1664,6 @@ nsAttrValue::ParseIntMarginValue(const nsAString& aString)
return true;
}
void
nsAttrValue::LoadImage(nsIDocument* aDocument)
{
NS_ASSERTION(Type() == eURL, "wrong type");
MiscContainer* cont = GetMiscContainer();
mozilla::css::URLValue* url = cont->mValue.mURL;
NS_ASSERTION(!url->IsStringEmpty(),
"How did we end up with an empty string for eURL");
mozilla::css::ImageValue* image =
mozilla::css::ImageValue::CreateFromURLValue(url,
aDocument,
mozilla::CORSMode::CORS_NONE);
NS_ADDREF(image);
cont->mValue.mImage = image;
NS_RELEASE(url);
cont->mType = eImage;
}
bool
nsAttrValue::ParseStyleAttribute(const nsAString& aString,
nsIPrincipal* aMaybeScriptedPrincipal,
@ -1869,11 +1830,6 @@ nsAttrValue::ClearMiscContainer()
NS_RELEASE(cont->mValue.mURL);
break;
}
case eImage:
{
NS_RELEASE(cont->mValue.mImage);
break;
}
case eAtomArray:
{
delete cont->mValue.mAtomArray;

View File

@ -30,19 +30,13 @@
#include "mozilla/dom/BindingDeclarations.h"
#include "mozilla/EnumTypeTraits.h"
// Undefine LoadImage to prevent naming conflict with Windows.
#undef LoadImage
class nsIDocument;
class nsIURI;
class nsStyledElement;
struct MiscContainer;
namespace mozilla {
class DeclarationBlock;
namespace css {
struct URLValue;
struct ImageValue;
} // namespace css
} // namespace mozilla
#define NS_ATTRVALUE_MAX_STRINGLENGTH_ATOM 12
@ -150,7 +144,7 @@ public:
void SetTo(double aValue, const nsAString* aSerialized);
void SetTo(already_AddRefed<mozilla::DeclarationBlock> aValue,
const nsAString* aSerialized);
void SetTo(mozilla::css::URLValue* aValue, const nsAString* aSerialized);
void SetTo(nsIURI* aValue, const nsAString* aSerialized);
void SetTo(const nsIntMargin& aValue);
void SetTo(const nsSVGAngle& aValue, const nsAString* aSerialized);
void SetTo(const nsSVGIntegerPair& aValue, const nsAString* aSerialized);
@ -201,8 +195,7 @@ public:
inline float GetPercentValue() const;
inline mozilla::AtomArray* GetAtomArrayValue() const;
inline mozilla::DeclarationBlock* GetCSSDeclarationValue() const;
inline mozilla::css::URLValue* GetURLValue() const;
inline mozilla::css::ImageValue* GetImageValue() const;
inline nsIURI* GetURLValue() const;
inline double GetDoubleValue() const;
bool GetIntMarginValue(nsIntMargin& aMargin) const;
@ -421,13 +414,6 @@ public:
*/
bool ParseIntMarginValue(const nsAString& aString);
/**
* Convert a URL nsAttrValue to an Image nsAttrValue.
*
* @param aDocument the document this nsAttrValue belongs to.
*/
void LoadImage(nsIDocument* aDocument);
/**
* Parse a string into a CSS style rule.
*

View File

@ -42,8 +42,7 @@ struct MiscContainer final
uint32_t mEnumValue;
int32_t mPercent;
mozilla::DeclarationBlock* mCSSDeclaration;
mozilla::css::URLValue* mURL;
mozilla::css::ImageValue* mImage;
nsIURI* mURL;
mozilla::AtomArray* mAtomArray;
nsIntMargin* mIntMargin;
const nsSVGAngle* mSVGAngle;
@ -172,20 +171,13 @@ nsAttrValue::GetCSSDeclarationValue() const
return GetMiscContainer()->mValue.mCSSDeclaration;
}
inline mozilla::css::URLValue*
inline nsIURI*
nsAttrValue::GetURLValue() const
{
NS_PRECONDITION(Type() == eURL, "wrong type");
return GetMiscContainer()->mValue.mURL;
}
inline mozilla::css::ImageValue*
nsAttrValue::GetImageValue() const
{
NS_PRECONDITION(Type() == eImage, "wrong type");
return GetMiscContainer()->mValue.mImage;
}
inline double
nsAttrValue::GetDoubleValue() const
{

View File

@ -921,11 +921,7 @@ nsGenericHTMLElement::ParseBackgroundAttribute(int32_t aNamespaceID,
if (NS_FAILED(rv)) {
return false;
}
mozilla::css::URLValue *url =
new mozilla::css::URLValue(uri, aValue, baseURI, doc->GetDocumentURI(),
NodePrincipal());
aResult.SetTo(url, &aValue);
aResult.SetTo(uri, &aValue);
return true;
}

View File

@ -111,8 +111,7 @@ ServoSpecifiedValues::SetTextDecorationColorOverride()
void
ServoSpecifiedValues::SetBackgroundImage(nsAttrValue& aValue)
{
if (aValue.Type() != nsAttrValue::eURL &&
aValue.Type() != nsAttrValue::eImage) {
if (aValue.Type() != nsAttrValue::eURL) {
return;
}
nsAutoString str;

View File

@ -698,19 +698,6 @@ nsCSSValue::GetCalcValue() const
return result;
}
void nsCSSValue::StartImageLoad(nsIDocument* aDocument,
mozilla::CORSMode aCORSMode) const
{
MOZ_ASSERT(eCSSUnit_URL == mUnit, "Not a URL value!");
mozilla::css::ImageValue* image =
mozilla::css::ImageValue::CreateFromURLValue(mValue.mURL,
aDocument,
aCORSMode);
nsCSSValue* writable = const_cast<nsCSSValue*>(this);
writable->SetImageValue(image);
}
nsCSSValue::Array*
nsCSSValue::InitFunction(nsCSSKeyword aFunctionId, uint32_t aNumArgs)
{
@ -1152,38 +1139,13 @@ nsCSSValue::Array::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) cons
return n;
}
css::URLValueData::URLValueData(already_AddRefed<nsIURI> aURI,
const nsAString& aString,
already_AddRefed<URLExtraData> aExtraData)
: mURI(Move(aURI))
, mExtraData(Move(aExtraData))
, mURIResolved(true)
, mStrings(aString)
, mUsingRustString(false)
{
MOZ_ASSERT(mExtraData);
MOZ_ASSERT(mExtraData->GetPrincipal());
}
css::URLValueData::URLValueData(already_AddRefed<nsIURI> aURI,
ServoRawOffsetArc<RustString> aString,
already_AddRefed<URLExtraData> aExtraData)
: mURI(Move(aURI))
, mExtraData(Move(aExtraData))
, mURIResolved(true)
, mStrings(aString)
, mUsingRustString(true)
{
MOZ_ASSERT(mExtraData);
MOZ_ASSERT(mExtraData->GetPrincipal());
}
css::URLValueData::URLValueData(const nsAString& aString,
already_AddRefed<URLExtraData> aExtraData)
: mExtraData(Move(aExtraData))
, mURIResolved(false)
, mStrings(aString)
, mUsingRustString(false)
, mString(aString)
{
MOZ_ASSERT(mExtraData);
MOZ_ASSERT(mExtraData->GetPrincipal());
@ -1193,8 +1155,7 @@ css::URLValueData::URLValueData(ServoRawOffsetArc<RustString> aString,
already_AddRefed<URLExtraData> aExtraData)
: mExtraData(Move(aExtraData))
, mURIResolved(false)
, mStrings(aString)
, mUsingRustString(true)
, mString(aString)
{
MOZ_ASSERT(mExtraData);
MOZ_ASSERT(mExtraData->GetPrincipal());
@ -1202,11 +1163,7 @@ css::URLValueData::URLValueData(ServoRawOffsetArc<RustString> aString,
css::URLValueData::~URLValueData()
{
if (mUsingRustString) {
Servo_ReleaseArcStringData(&mStrings.mRustString);
} else {
mStrings.mString.~nsString();
}
Servo_ReleaseArcStringData(&mString);
}
bool
@ -1217,13 +1174,7 @@ css::URLValueData::Equals(const URLValueData& aOther) const
bool eq;
const URLExtraData* self = mExtraData;
const URLExtraData* other = aOther.mExtraData;
bool stringsEqual;
if (mUsingRustString && aOther.mUsingRustString) {
stringsEqual = GetRustString() == aOther.GetRustString();
} else {
stringsEqual = GetUTF16String() == aOther.GetUTF16String();
}
return stringsEqual &&
return GetString() == aOther.GetString() &&
(GetURI() == aOther.GetURI() || // handles null == null
(mURI && aOther.mURI &&
NS_SUCCEEDED(mURI->Equals(aOther.mURI, &eq)) &&
@ -1242,10 +1193,7 @@ css::URLValueData::DefinitelyEqualURIs(const URLValueData& aOther) const
if (mExtraData->BaseURI() != aOther.mExtraData->BaseURI()) {
return false;
}
if (mUsingRustString && aOther.mUsingRustString) {
return GetRustString() == aOther.GetRustString();
}
return GetUTF16StringForAnyThread() == aOther.GetUTF16StringForAnyThread();
return GetString() == aOther.GetString();
}
bool
@ -1257,48 +1205,14 @@ css::URLValueData::DefinitelyEqualURIsAndPrincipal(
}
nsDependentCSubstring
css::URLValueData::GetRustString() const
css::URLValueData::GetString() const
{
const uint8_t* chars;
uint32_t len;
Servo_GetArcStringData(mStrings.mRustString.mPtr, &chars, &len);
Servo_GetArcStringData(mString.mPtr, &chars, &len);
return nsDependentCSubstring(reinterpret_cast<const char*>(chars), len);
}
bool
css::URLValueData::IsStringEmpty() const
{
if (mUsingRustString) {
return GetRustString().IsEmpty();
}
return mStrings.mString.IsEmpty();
}
const nsString&
css::URLValueData::GetUTF16String() const
{
MOZ_ASSERT(NS_IsMainThread());
if (mUsingRustString) {
nsDependentCSubstring rust = GetRustString();
nsString converted = NS_ConvertUTF8toUTF16(rust);
Servo_ReleaseArcStringData(&mStrings.mRustString);
new (&mStrings) RustOrGeckoString(converted);
mUsingRustString = false;
}
return mStrings.mString;
}
nsString
css::URLValueData::GetUTF16StringForAnyThread() const
{
if (!mUsingRustString) {
return mStrings.mString;
}
nsDependentCSubstring rust = GetRustString();
return NS_ConvertUTF8toUTF16(rust);
}
nsIURI*
css::URLValueData::GetURI() const
{
@ -1307,15 +1221,9 @@ css::URLValueData::GetURI() const
if (!mURIResolved) {
MOZ_ASSERT(!mURI);
nsCOMPtr<nsIURI> newURI;
if (!mUsingRustString) {
NS_NewURI(getter_AddRefs(newURI),
NS_ConvertUTF16toUTF8(mStrings.mString),
nullptr, mExtraData->BaseURI());
} else {
NS_NewURI(getter_AddRefs(newURI),
GetRustString(),
nullptr, mExtraData->BaseURI());
}
NS_NewURI(getter_AddRefs(newURI),
GetString(),
nullptr, mExtraData->BaseURI());
mURI = newURI.forget();
mURIResolved = true;
}
@ -1328,13 +1236,8 @@ css::URLValueData::IsLocalRef() const
{
if (mIsLocalRef.isNothing()) {
// IsLocalRefURL is O(N), use it only when IsLocalRef is called.
if (mUsingRustString) {
mIsLocalRef.emplace(nsContentUtils::IsLocalRefURL(GetRustString()));
} else {
mIsLocalRef.emplace(nsContentUtils::IsLocalRefURL(mStrings.mString));
}
mIsLocalRef.emplace(nsContentUtils::IsLocalRefURL(GetString()));
}
return mIsLocalRef.value();
}
@ -1364,9 +1267,7 @@ bool
css::URLValueData::MightHaveRef() const
{
if (mMightHaveRef.isNothing()) {
bool result = mUsingRustString ?
::MightHaveRef(GetRustString()) :
::MightHaveRef(mStrings.mString);
bool result = ::MightHaveRef(GetString());
if (!ServoStyleSet::IsInServoTraversal()) {
// Can only cache the result if we're not on a style worker thread.
mMightHaveRef.emplace(result);
@ -1448,34 +1349,12 @@ css::URLValueData::EqualsExceptRef(nsIURI* aURI) const
size_t
css::URLValueData::SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
{
size_t n = 0;
if (!mUsingRustString) {
n += mStrings.mString.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
}
// Measurement of the following members may be added later if DMD finds it
// is worthwhile:
// - mURI
// - mString
// - mExtraData
return n;
}
URLValue::URLValue(const nsAString& aString, nsIURI* aBaseURI, nsIURI* aReferrer,
nsIPrincipal* aOriginPrincipal)
: URLValueData(aString, do_AddRef(new URLExtraData(aBaseURI, aReferrer,
aOriginPrincipal)))
{
MOZ_ASSERT(NS_IsMainThread());
}
URLValue::URLValue(nsIURI* aURI, const nsAString& aString, nsIURI* aBaseURI,
nsIURI* aReferrer, nsIPrincipal* aOriginPrincipal)
: URLValueData(do_AddRef(aURI),
aString,
do_AddRef(new URLExtraData(aBaseURI, aReferrer,
aOriginPrincipal)))
{
MOZ_ASSERT(NS_IsMainThread());
return 0;
}
size_t
@ -1490,7 +1369,8 @@ css::URLValue::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
return n;
}
css::ImageValue::ImageValue(nsIURI* aURI, const nsAString& aString,
css::ImageValue::ImageValue(nsIURI* aURI,
ServoRawOffsetArc<RustString> aString,
already_AddRefed<URLExtraData> aExtraData,
nsIDocument* aDocument,
CORSMode aCORSMode)
@ -1500,24 +1380,6 @@ css::ImageValue::ImageValue(nsIURI* aURI, const nsAString& aString,
Initialize(aDocument);
}
css::ImageValue::ImageValue(nsIURI* aURI, ServoRawOffsetArc<RustString> aString,
already_AddRefed<URLExtraData> aExtraData,
nsIDocument* aDocument,
CORSMode aCORSMode)
: URLValueData(do_AddRef(aURI), aString, Move(aExtraData))
{
mCORSMode = aCORSMode;
Initialize(aDocument);
}
css::ImageValue::ImageValue(const nsAString& aString,
already_AddRefed<URLExtraData> aExtraData,
CORSMode aCORSMode)
: URLValueData(aString, Move(aExtraData))
{
mCORSMode = aCORSMode;
}
css::ImageValue::ImageValue(ServoRawOffsetArc<RustString> aString,
already_AddRefed<URLExtraData> aExtraData,
CORSMode aCORSMode)
@ -1526,23 +1388,17 @@ css::ImageValue::ImageValue(ServoRawOffsetArc<RustString> aString,
mCORSMode = aCORSMode;
}
/*static*/ css::ImageValue*
/*static*/ already_AddRefed<css::ImageValue>
css::ImageValue::CreateFromURLValue(URLValue* aUrl,
nsIDocument* aDocument,
CORSMode aCORSMode)
{
if (aUrl->mUsingRustString) {
return new css::ImageValue(aUrl->GetURI(),
Servo_CloneArcStringData(&aUrl->mStrings.mRustString),
do_AddRef(aUrl->mExtraData),
aDocument,
aCORSMode);
}
return new css::ImageValue(aUrl->GetURI(),
aUrl->mStrings.mString,
do_AddRef(aUrl->mExtraData),
aDocument,
aCORSMode);
return do_AddRef(
new css::ImageValue(aUrl->GetURI(),
Servo_CloneArcStringData(&aUrl->mString),
do_AddRef(aUrl->mExtraData),
aDocument,
aCORSMode));
}
void

View File

@ -100,18 +100,13 @@ protected:
// caps, which leads to REQUIRES hell, since this header is included all
// over.
// For both constructors aString must not be null.
// For both constructors principal of aExtraData must not be null.
// aString must not be null.
// principal of aExtraData must not be null.
// Construct with a base URI; this will create the actual URI lazily from
// aString and aExtraData.
URLValueData(const nsAString& aString,
already_AddRefed<URLExtraData> aExtraData);
URLValueData(ServoRawOffsetArc<RustString> aString,
already_AddRefed<URLExtraData> aExtraData);
// Construct with the actual URI.
URLValueData(already_AddRefed<nsIURI> aURI,
const nsAString& aString,
already_AddRefed<URLExtraData> aExtraData);
URLValueData(already_AddRefed<nsIURI> aURI,
ServoRawOffsetArc<RustString> aString,
already_AddRefed<URLExtraData> aExtraData);
@ -163,40 +158,29 @@ public:
bool EqualsExceptRef(nsIURI* aURI) const;
// Can only be called from the main thread. Returns this URL's UTF-16 representation,
// converting and caching its value if necessary.
const nsString& GetUTF16String() const;
// Returns this URL's UTF-16 representation, converting if necessary.
nsString GetUTF16StringForAnyThread() const;
bool IsStringEmpty() const
{
return GetString().IsEmpty();
}
bool IsStringEmpty() const;
nsDependentCSubstring GetString() const;
private:
// mURI stores the lazily resolved URI. This may be null if the URI is
// invalid, even once resolved.
mutable nsCOMPtr<nsIURI> mURI;
public:
RefPtr<URLExtraData> mExtraData;
private:
// Returns a substring based on mStrings.mRustString which should not be exposed
// to external consumers.
nsDependentCSubstring GetRustString() const;
private:
mutable bool mURIResolved;
// mIsLocalRef is set when url starts with a U+0023 number sign(#) character.
mutable Maybe<bool> mIsLocalRef;
mutable Maybe<bool> mMightHaveRef;
mutable union RustOrGeckoString {
explicit RustOrGeckoString(const nsAString& aString)
: mString(aString) {}
explicit RustOrGeckoString(ServoRawOffsetArc<RustString> aString)
: mRustString(aString) {}
~RustOrGeckoString() {}
nsString mString;
mozilla::ServoRawOffsetArc<RustString> mRustString;
} mStrings;
mutable bool mUsingRustString;
mozilla::ServoRawOffsetArc<RustString> mString;
protected:
// Only used by ImageValue. Declared up here because otherwise bindgen gets
@ -223,16 +207,10 @@ private:
struct URLValue final : public URLValueData
{
// These two constructors are safe to call only on the main thread.
URLValue(const nsAString& aString, nsIURI* aBaseURI, nsIURI* aReferrer,
nsIPrincipal* aOriginPrincipal);
URLValue(nsIURI* aURI, const nsAString& aString, nsIURI* aBaseURI,
nsIURI* aReferrer, nsIPrincipal* aOriginPrincipal);
// This constructor is safe to call from any thread.
URLValue(ServoRawOffsetArc<RustString> aString,
already_AddRefed<URLExtraData> aExtraData)
: URLValueData(aString, Move(aExtraData)) {}
: URLValueData(aString, Move(aExtraData))
{ }
URLValue(const URLValue&) = delete;
URLValue& operator=(const URLValue&) = delete;
@ -242,9 +220,8 @@ struct URLValue final : public URLValueData
struct ImageValue final : public URLValueData
{
static ImageValue* CreateFromURLValue(URLValue* url,
nsIDocument* aDocument,
CORSMode aCORSMode);
static already_AddRefed<ImageValue>
CreateFromURLValue(URLValue*, nsIDocument*, CORSMode);
// Not making the constructor and destructor inline because that would
// force us to include imgIRequest.h, which leads to REQUIRES hell, since
@ -685,15 +662,6 @@ public:
return mValue.mGridTemplateAreas;
}
const char16_t* GetOriginalURLValue() const
{
MOZ_ASSERT(mUnit == eCSSUnit_URL || mUnit == eCSSUnit_Image,
"not a URL value");
return mUnit == eCSSUnit_URL ?
mValue.mURL->GetUTF16String().get() :
mValue.mImage->GetUTF16String().get();
}
// Not making this inline because that would force us to include
// imgIRequest.h, which leads to REQUIRES hell, since this header is included
// all over.

View File

@ -623,8 +623,8 @@ nsStyleUtil::AppendSerializedFontSrc(const nsCSSValue& aValue,
if (sources[i].GetUnit() == eCSSUnit_URL) {
aResult.AppendLiteral("url(");
nsDependentString url(sources[i].GetOriginalURLValue());
nsStyleUtil::AppendEscapedCSSString(url, aResult);
nsDependentCSubstring url(sources[i].GetURLStructValue()->GetString());
nsStyleUtil::AppendEscapedCSSString(NS_ConvertUTF8toUTF16(url), aResult);
aResult.Append(')');
} else if (sources[i].GetUnit() == eCSSUnit_Local_Font) {
aResult.AppendLiteral("local(");