Bug 1132748 part 1: Add CSSUnprefixingService API for handling prefixed gradient expressions, with stub JS implementation. r=dbaron

This commit is contained in:
Daniel Holbert 2015-05-07 09:04:42 -07:00
Родитель 7788a8ede7
Коммит 07645d8b7d
3 изменённых файлов: 127 добавлений и 2 удалений

Просмотреть файл

@ -151,6 +151,20 @@ CSSUnprefixingService.prototype = {
// No known mapping for property aPropName.
return false;
},
// See documentation in nsICSSUnprefixingService.idl
generateUnprefixedGradientValue: function(aPrefixedFuncName,
aPrefixedFuncBody,
aUnprefixedFuncName, /*[out]*/
aUnprefixedFuncBody /*[out]*/) {
// XXX Implement me!
// Sample working output:
// aUnprefixedFuncName.value = "radial-gradient";
// aUnprefixedFuncBody.value = "lime, green";
// return true;
return false;
},
};
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([CSSUnprefixingService]);

Просмотреть файл

@ -736,6 +736,11 @@ protected:
bool aMustCallValueAppended,
bool* aChanged,
nsCSSContextType aContext);
// When we detect a webkit-prefixed gradient expression, this function can
// be used to parse its body into outparam |aValue|. Only call if
// ShouldUseUnprefixingService() returns true.
bool ParseWebkitPrefixedGradient(nsAString& aPrefixedFuncName,
nsCSSValue& aValue);
bool ParseProperty(nsCSSProperty aPropID);
bool ParsePropertyByFunction(nsCSSProperty aPropID);
@ -6685,6 +6690,72 @@ CSSParserImpl::ParsePropertyWithUnprefixingService(
return success;
}
bool
CSSParserImpl::ParseWebkitPrefixedGradient(nsAString& aPrefixedFuncName,
nsCSSValue& aValue)
{
MOZ_ASSERT(ShouldUseUnprefixingService(),
"Should only call if we're allowed to use unprefixing service");
// Record the body of the "-webkit-*gradient" function into a string.
// Note: we're already just after the opening "(".
nsAutoString prefixedFuncBody;
mScanner->StartRecording();
bool gotCloseParen = SkipUntil(')');
mScanner->StopRecording(prefixedFuncBody);
if (gotCloseParen) {
// Strip off trailing close-paren, so that the value we pass to the
// unprefixing service is *just* the function-body (no parens).
prefixedFuncBody.Truncate(prefixedFuncBody.Length() - 1);
}
// NOTE: Even if we fail, we'll be leaving the parser's cursor just after
// the close of the "-webkit-*gradient(...)" expression. This is the same
// behavior that the other Parse*Gradient functions have in their failure
// cases -- they call "SkipUntil(')') before returning false. So this is
// probably what we want.
nsCOMPtr<nsICSSUnprefixingService> unprefixingSvc =
do_GetService(NS_CSSUNPREFIXINGSERVICE_CONTRACTID);
NS_ENSURE_TRUE(unprefixingSvc, false);
bool success;
nsAutoString unprefixedFuncName;
nsAutoString unprefixedFuncBody;
nsresult rv =
unprefixingSvc->GenerateUnprefixedGradientValue(aPrefixedFuncName,
prefixedFuncBody,
unprefixedFuncName,
unprefixedFuncBody,
&success);
if (NS_FAILED(rv) || !success) {
return false;
}
// JS service thinks it successfully converted the gradient! Now let's try
// to parse the resulting string.
// First, add a close-paren if we originally recorded one (so that what we're
// about to put into the CSS parser is a faithful representation of what it
// would've seen if it were just parsing the original input stream):
if (gotCloseParen) {
unprefixedFuncBody.Append(char16_t(')'));
}
nsAutoScannerChanger scannerChanger(this, unprefixedFuncBody);
if (unprefixedFuncName.EqualsLiteral("linear-gradient")) {
return ParseLinearGradient(aValue, false, false);
}
if (unprefixedFuncName.EqualsLiteral("radial-gradient")) {
return ParseRadialGradient(aValue, false, false);
}
NS_ERROR("CSSUnprefixingService returned an unrecognized type of "
"gradient function");
return false;
}
//----------------------------------------------------------------------
bool
@ -7308,6 +7379,14 @@ CSSParserImpl::ParseVariant(nsCSSValue& aValue,
if (tmp.LowerCaseEqualsLiteral("radial-gradient")) {
return ParseRadialGradient(aValue, isRepeating, isLegacy);
}
if (ShouldUseUnprefixingService() &&
!isRepeating && !isLegacy &&
StringBeginsWith(tmp, NS_LITERAL_STRING("-webkit-"))) {
// Copy 'tmp' into a string on the stack, since as soon as we
// start parsing, its backing store (in "tk") will be overwritten
nsAutoString prefixedFuncName(tmp);
return ParseWebkitPrefixedGradient(prefixedFuncName, aValue);
}
}
if ((aVariantMask & VARIANT_IMAGE_RECT) != 0 &&
eCSSToken_Function == tk->mType &&
@ -10551,7 +10630,11 @@ CSSParserImpl::ParseBackgroundItem(CSSParserImpl::BackgroundParseState& aState)
mToken.mIdent.LowerCaseEqualsLiteral("-moz-repeating-linear-gradient") ||
mToken.mIdent.LowerCaseEqualsLiteral("-moz-repeating-radial-gradient") ||
mToken.mIdent.LowerCaseEqualsLiteral("-moz-image-rect") ||
mToken.mIdent.LowerCaseEqualsLiteral("-moz-element")))) {
mToken.mIdent.LowerCaseEqualsLiteral("-moz-element") ||
(ShouldUseUnprefixingService() &&
(mToken.mIdent.LowerCaseEqualsLiteral("-webkit-gradient") ||
mToken.mIdent.LowerCaseEqualsLiteral("-webkit-linear-gradient") ||
mToken.mIdent.LowerCaseEqualsLiteral("-webkit-radial-gradient")))))) {
if (haveImage)
return false;
haveImage = true;

Просмотреть файл

@ -8,7 +8,7 @@
#include "nsISupports.idl"
[scriptable, uuid(927a5c60-0378-4bcb-a50d-99e6d1fe6063)]
[scriptable, uuid(a5d6e2f4-d3ec-11e4-b002-782bcbaebb28)]
interface nsICSSUnprefixingService : nsISupports
{
/**
@ -40,6 +40,34 @@ interface nsICSSUnprefixingService : nsISupports
boolean generateUnprefixedDeclaration(in AString aPropName,
in AString aRightHalfOfDecl,
out AString aUnprefixedDecl);
/**
* @param aPrefixedFuncName
* The webkit-prefixed gradient function: either
* "-webkit-gradient", "-webkit-linear-gradient", or
* "-webkit-radial-gradient".
*
* @param aPrefixedFuncBody
* The body of the gradient function, inside (& not including) the
* parenthesis.
*
* @param aUnprefixedFuncName[out]
* The resulting unprefixed gradient function name:
* either "linear-gradient" or "radial-gradient".
*
* @param aUnprefixedFuncBody[out]
* The resulting unprefixed gradient function body, suitable for
* including in a "linear-gradient(...)" or "radial-gradient(...)"
* expression.
*
* @returns true if we were able to successfully parse aWebkitGradientStr
* and populate the outparams accordingly; false otherwise.
*
*/
boolean generateUnprefixedGradientValue(in AString aPrefixedFuncName,
in AString aPrefixedFuncBody,
out AString aUnprefixedFuncName,
out AString aUnprefixedFuncBody);
};
%{C++