зеркало из https://github.com/mozilla/gecko-dev.git
Bug 441469. Implement parsing of @font-face rules. r+sr=dbaron
This commit is contained in:
Родитель
a32dce381d
Коммит
af751d9b0a
|
@ -42,8 +42,8 @@ PEParseRuleWSOnly=Whitespace-only string given to be parsed as rule.
|
||||||
PEDeclDropped=Declaration dropped.
|
PEDeclDropped=Declaration dropped.
|
||||||
PEDeclSkipped=Skipped to next declaration.
|
PEDeclSkipped=Skipped to next declaration.
|
||||||
PEUnknownProperty=Unknown property '%1$S'.
|
PEUnknownProperty=Unknown property '%1$S'.
|
||||||
PEPropertyParsingError=Error in parsing value for property '%1$S'.
|
PEValueParsingError=Error in parsing value for '%1$S'.
|
||||||
PEExpectEndProperty=Expected end of value for property but found '%1$S'.
|
PEExpectEndValue=Expected end of value but found '%1$S'.
|
||||||
PESkipAtRuleEOF=end of unknown at-rule
|
PESkipAtRuleEOF=end of unknown at-rule
|
||||||
PEUnknownAtRule=Unrecognized at-rule or error parsing at-rule '%1$S'.
|
PEUnknownAtRule=Unrecognized at-rule or error parsing at-rule '%1$S'.
|
||||||
PECharsetRuleEOF=charset string in @charset rule
|
PECharsetRuleEOF=charset string in @charset rule
|
||||||
|
@ -127,6 +127,8 @@ PEBadDeclOrRuleEnd2=Expected ';' or '}' to terminate declaration but found '%1$S
|
||||||
PEInaccessibleProperty2=Cannot specify value for internal property.
|
PEInaccessibleProperty2=Cannot specify value for internal property.
|
||||||
PECommentEOF=end of comment
|
PECommentEOF=end of comment
|
||||||
SEUnterminatedString=Found unclosed string '%1$S'.
|
SEUnterminatedString=Found unclosed string '%1$S'.
|
||||||
|
PEFontDescExpected=Expected font descriptor but found '%1$S'.
|
||||||
|
PEUnknownFontDesc=Unknown descriptor '%1$S' in @font-face rule.
|
||||||
PEMQExpectedExpressionStart=Expected '(' to start media query expression but found '%1$S'.
|
PEMQExpectedExpressionStart=Expected '(' to start media query expression but found '%1$S'.
|
||||||
PEMQExpressionEOF=contents of media query expression
|
PEMQExpressionEOF=contents of media query expression
|
||||||
PEMQExpectedFeatureName=Expected media feature name but found '%1$S'.
|
PEMQExpectedFeatureName=Expected media feature name but found '%1$S'.
|
||||||
|
|
|
@ -428,6 +428,10 @@ enum nsDOMClassInfoID {
|
||||||
eDOMClassInfo_Geolocation_id,
|
eDOMClassInfo_Geolocation_id,
|
||||||
eDOMClassInfo_Geolocator_id,
|
eDOMClassInfo_Geolocator_id,
|
||||||
|
|
||||||
|
// @font-face in CSS
|
||||||
|
eDOMClassInfo_CSSFontFaceRule_id,
|
||||||
|
eDOMClassInfo_CSSFontFaceStyleDecl_id,
|
||||||
|
|
||||||
// WhatWG Video Element
|
// WhatWG Video Element
|
||||||
#if defined(MOZ_MEDIA)
|
#if defined(MOZ_MEDIA)
|
||||||
eDOMClassInfo_HTMLVideoElement_id,
|
eDOMClassInfo_HTMLVideoElement_id,
|
||||||
|
|
|
@ -325,6 +325,7 @@
|
||||||
#include "nsIDOMCSSCharsetRule.h"
|
#include "nsIDOMCSSCharsetRule.h"
|
||||||
#include "nsIDOMCSSImportRule.h"
|
#include "nsIDOMCSSImportRule.h"
|
||||||
#include "nsIDOMCSSMediaRule.h"
|
#include "nsIDOMCSSMediaRule.h"
|
||||||
|
#include "nsIDOMCSSFontFaceRule.h"
|
||||||
#include "nsIDOMCSSMozDocumentRule.h"
|
#include "nsIDOMCSSMozDocumentRule.h"
|
||||||
#include "nsIDOMCSSPrimitiveValue.h"
|
#include "nsIDOMCSSPrimitiveValue.h"
|
||||||
#include "nsIDOMCSSStyleRule.h"
|
#include "nsIDOMCSSStyleRule.h"
|
||||||
|
@ -814,7 +815,7 @@ static nsDOMClassInfoData sClassInfoData[] = {
|
||||||
NS_DEFINE_CLASSINFO_DATA(CSSStyleDeclaration, nsCSSStyleDeclSH,
|
NS_DEFINE_CLASSINFO_DATA(CSSStyleDeclaration, nsCSSStyleDeclSH,
|
||||||
ARRAY_SCRIPTABLE_FLAGS)
|
ARRAY_SCRIPTABLE_FLAGS)
|
||||||
NS_DEFINE_CLASSINFO_DATA(ComputedCSSStyleDeclaration, nsCSSStyleDeclSH,
|
NS_DEFINE_CLASSINFO_DATA(ComputedCSSStyleDeclaration, nsCSSStyleDeclSH,
|
||||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
ARRAY_SCRIPTABLE_FLAGS)
|
||||||
NS_DEFINE_CLASSINFO_DATA(ROCSSPrimitiveValue, nsDOMGenericSH,
|
NS_DEFINE_CLASSINFO_DATA(ROCSSPrimitiveValue, nsDOMGenericSH,
|
||||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||||
|
|
||||||
|
@ -1253,6 +1254,11 @@ static nsDOMClassInfoData sClassInfoData[] = {
|
||||||
NS_DEFINE_CLASSINFO_DATA(Geolocator, nsDOMGenericSH,
|
NS_DEFINE_CLASSINFO_DATA(Geolocator, nsDOMGenericSH,
|
||||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||||
|
|
||||||
|
NS_DEFINE_CLASSINFO_DATA(CSSFontFaceRule, nsDOMGenericSH,
|
||||||
|
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||||
|
NS_DEFINE_CLASSINFO_DATA(CSSFontFaceStyleDecl, nsCSSStyleDeclSH,
|
||||||
|
ARRAY_SCRIPTABLE_FLAGS)
|
||||||
|
|
||||||
#if defined(MOZ_MEDIA)
|
#if defined(MOZ_MEDIA)
|
||||||
NS_DEFINE_CLASSINFO_DATA(HTMLVideoElement, nsHTMLElementSH,
|
NS_DEFINE_CLASSINFO_DATA(HTMLVideoElement, nsHTMLElementSH,
|
||||||
ELEMENT_SCRIPTABLE_FLAGS)
|
ELEMENT_SCRIPTABLE_FLAGS)
|
||||||
|
@ -3440,6 +3446,15 @@ nsDOMClassInfo::Init()
|
||||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMGeolocator)
|
DOM_CLASSINFO_MAP_ENTRY(nsIDOMGeolocator)
|
||||||
DOM_CLASSINFO_MAP_END
|
DOM_CLASSINFO_MAP_END
|
||||||
|
|
||||||
|
DOM_CLASSINFO_MAP_BEGIN(CSSFontFaceRule, nsIDOMCSSFontFaceRule)
|
||||||
|
DOM_CLASSINFO_MAP_ENTRY(nsIDOMCSSFontFaceRule)
|
||||||
|
DOM_CLASSINFO_MAP_END
|
||||||
|
|
||||||
|
DOM_CLASSINFO_MAP_BEGIN_NO_CLASS_IF(CSSFontFaceStyleDecl,
|
||||||
|
nsIDOMCSSStyleDeclaration)
|
||||||
|
DOM_CLASSINFO_MAP_ENTRY(nsIDOMCSSStyleDeclaration)
|
||||||
|
DOM_CLASSINFO_MAP_END
|
||||||
|
|
||||||
#if defined(MOZ_MEDIA)
|
#if defined(MOZ_MEDIA)
|
||||||
DOM_CLASSINFO_MAP_BEGIN(HTMLVideoElement, nsIDOMHTMLVideoElement)
|
DOM_CLASSINFO_MAP_BEGIN(HTMLVideoElement, nsIDOMHTMLVideoElement)
|
||||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMHTMLVideoElement)
|
DOM_CLASSINFO_MAP_ENTRY(nsIDOMHTMLVideoElement)
|
||||||
|
|
|
@ -150,6 +150,11 @@ public:
|
||||||
void List(FILE* out = stdout, PRInt32 aIndent = 0) const;
|
void List(FILE* out = stdout, PRInt32 aIndent = 0) const;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// return whether there was a value in |aValue| (i.e., it had a non-null unit)
|
||||||
|
static PRBool AppendCSSValueToString(nsCSSProperty aProperty,
|
||||||
|
const nsCSSValue& aValue,
|
||||||
|
nsAString& aResult);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Not implemented, and not supported.
|
// Not implemented, and not supported.
|
||||||
nsCSSDeclaration& operator=(const nsCSSDeclaration& aCopy);
|
nsCSSDeclaration& operator=(const nsCSSDeclaration& aCopy);
|
||||||
|
@ -158,13 +163,6 @@ private:
|
||||||
static void AppendImportanceToString(PRBool aIsImportant, nsAString& aString);
|
static void AppendImportanceToString(PRBool aIsImportant, nsAString& aString);
|
||||||
// return whether there was a value in |aValue| (i.e., it had a non-null unit)
|
// return whether there was a value in |aValue| (i.e., it had a non-null unit)
|
||||||
PRBool AppendValueToString(nsCSSProperty aProperty, nsAString& aResult) const;
|
PRBool AppendValueToString(nsCSSProperty aProperty, nsAString& aResult) const;
|
||||||
public:
|
|
||||||
// return whether there was a value in |aValue| (i.e., it had a non-null unit)
|
|
||||||
static PRBool AppendCSSValueToString(nsCSSProperty aProperty,
|
|
||||||
const nsCSSValue& aValue,
|
|
||||||
nsAString& aResult);
|
|
||||||
|
|
||||||
private:
|
|
||||||
// May be called only for properties whose type is eCSSType_Value.
|
// May be called only for properties whose type is eCSSType_Value.
|
||||||
nsresult GetValueOrImportantValue(nsCSSProperty aProperty, nsCSSValue& aValue) const;
|
nsresult GetValueOrImportantValue(nsCSSProperty aProperty, nsCSSValue& aValue) const;
|
||||||
|
|
||||||
|
|
|
@ -294,7 +294,12 @@ protected:
|
||||||
PRBool ProcessNameSpace(nsresult& aErrorCode, const nsString& aPrefix,
|
PRBool ProcessNameSpace(nsresult& aErrorCode, const nsString& aPrefix,
|
||||||
const nsString& aURLSpec, RuleAppendFunc aAppendFunc,
|
const nsString& aURLSpec, RuleAppendFunc aAppendFunc,
|
||||||
void* aProcessData);
|
void* aProcessData);
|
||||||
|
|
||||||
PRBool ParseFontFaceRule(nsresult& aErrorCode, RuleAppendFunc aAppendFunc, void* aProcessData);
|
PRBool ParseFontFaceRule(nsresult& aErrorCode, RuleAppendFunc aAppendFunc, void* aProcessData);
|
||||||
|
PRBool ParseFontDescriptor(nsresult& aErrorCode, nsCSSFontFaceRule* aRule);
|
||||||
|
PRBool ParseFontDescriptorValue(nsresult& aErrorCode, nsCSSFontDesc aDescID,
|
||||||
|
nsCSSValue& aValue);
|
||||||
|
|
||||||
PRBool ParsePageRule(nsresult& aErrorCode, RuleAppendFunc aAppendFunc, void* aProcessData);
|
PRBool ParsePageRule(nsresult& aErrorCode, RuleAppendFunc aAppendFunc, void* aProcessData);
|
||||||
|
|
||||||
enum nsSelectorParsingStatus {
|
enum nsSelectorParsingStatus {
|
||||||
|
@ -416,7 +421,11 @@ protected:
|
||||||
PRBool ParseCursor(nsresult& aErrorCode);
|
PRBool ParseCursor(nsresult& aErrorCode);
|
||||||
PRBool ParseFont(nsresult& aErrorCode);
|
PRBool ParseFont(nsresult& aErrorCode);
|
||||||
PRBool ParseFontWeight(nsresult& aErrorCode, nsCSSValue& aValue);
|
PRBool ParseFontWeight(nsresult& aErrorCode, nsCSSValue& aValue);
|
||||||
|
PRBool ParseOneFamily(nsresult& aErrorCode, nsAString& aValue);
|
||||||
PRBool ParseFamily(nsresult& aErrorCode, nsCSSValue& aValue);
|
PRBool ParseFamily(nsresult& aErrorCode, nsCSSValue& aValue);
|
||||||
|
PRBool ParseFontSrc(nsresult& aErrorCode, nsCSSValue& aValue);
|
||||||
|
PRBool ParseFontSrcFormat(nsresult& aErrorCode, nsTArray<nsCSSValue>& values);
|
||||||
|
PRBool ParseFontRanges(nsresult& aErrorCode, nsCSSValue& aValue);
|
||||||
PRBool ParseListStyle(nsresult& aErrorCode);
|
PRBool ParseListStyle(nsresult& aErrorCode);
|
||||||
PRBool ParseMargin(nsresult& aErrorCode);
|
PRBool ParseMargin(nsresult& aErrorCode);
|
||||||
PRBool ParseMarks(nsresult& aErrorCode, nsCSSValue& aValue);
|
PRBool ParseMarks(nsresult& aErrorCode, nsCSSValue& aValue);
|
||||||
|
@ -1076,13 +1085,13 @@ CSSParserImpl::ParseProperty(const nsCSSProperty aPropID,
|
||||||
} else {
|
} else {
|
||||||
if (parsedOK) {
|
if (parsedOK) {
|
||||||
// Junk at end of property value.
|
// Junk at end of property value.
|
||||||
REPORT_UNEXPECTED_TOKEN(PEExpectEndProperty);
|
REPORT_UNEXPECTED_TOKEN(PEExpectEndValue);
|
||||||
}
|
}
|
||||||
NS_ConvertASCIItoUTF16 propName(nsCSSProps::GetStringValue(aPropID));
|
NS_ConvertASCIItoUTF16 propName(nsCSSProps::GetStringValue(aPropID));
|
||||||
const PRUnichar *params[] = {
|
const PRUnichar *params[] = {
|
||||||
propName.get()
|
propName.get()
|
||||||
};
|
};
|
||||||
REPORT_UNEXPECTED_P(PEPropertyParsingError, params);
|
REPORT_UNEXPECTED_P(PEValueParsingError, params);
|
||||||
REPORT_UNEXPECTED(PEDeclDropped);
|
REPORT_UNEXPECTED(PEDeclDropped);
|
||||||
OUTPUT_ERROR();
|
OUTPUT_ERROR();
|
||||||
ClearTempData(aPropID);
|
ClearTempData(aPropID);
|
||||||
|
@ -1306,7 +1315,7 @@ PRBool CSSParserImpl::ExpectEndProperty(nsresult& aErrorCode)
|
||||||
UngetToken();
|
UngetToken();
|
||||||
return PR_TRUE;
|
return PR_TRUE;
|
||||||
}
|
}
|
||||||
REPORT_UNEXPECTED_TOKEN(PEExpectEndProperty);
|
REPORT_UNEXPECTED_TOKEN(PEExpectEndValue);
|
||||||
UngetToken();
|
UngetToken();
|
||||||
return PR_FALSE;
|
return PR_FALSE;
|
||||||
}
|
}
|
||||||
|
@ -1990,12 +1999,109 @@ PRBool CSSParserImpl::ProcessNameSpace(nsresult& aErrorCode, const nsString& aPr
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
PRBool CSSParserImpl::ParseFontFaceRule(nsresult& aErrorCode, RuleAppendFunc aAppendFunc, void* aData)
|
// font-face-rule: '@font-face' '{' font-description '}'
|
||||||
|
// font-description: font-descriptor+
|
||||||
|
PRBool
|
||||||
|
CSSParserImpl::ParseFontFaceRule(nsresult& aErrorCode,
|
||||||
|
RuleAppendFunc aAppendFunc, void* aData)
|
||||||
{
|
{
|
||||||
// XXX not yet implemented
|
if (!ExpectSymbol(aErrorCode, '{', PR_TRUE))
|
||||||
|
return PR_FALSE;
|
||||||
|
|
||||||
|
nsRefPtr<nsCSSFontFaceRule> rule(new nsCSSFontFaceRule());
|
||||||
|
if (!rule) {
|
||||||
|
aErrorCode = NS_ERROR_OUT_OF_MEMORY;
|
||||||
return PR_FALSE;
|
return PR_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
if (!GetToken(aErrorCode, PR_TRUE)) {
|
||||||
|
REPORT_UNEXPECTED_EOF(PEFontFaceEOF);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (mToken.IsSymbol('}')) { // done!
|
||||||
|
UngetToken();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ignore extra semicolons
|
||||||
|
if (mToken.IsSymbol(';'))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!ParseFontDescriptor(aErrorCode, rule)) {
|
||||||
|
REPORT_UNEXPECTED(PEDeclSkipped);
|
||||||
|
OUTPUT_ERROR();
|
||||||
|
if (!SkipDeclaration(aErrorCode, PR_TRUE))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!ExpectSymbol(aErrorCode, '}', PR_TRUE))
|
||||||
|
return PR_FALSE;
|
||||||
|
(*aAppendFunc)(rule, aData);
|
||||||
|
return PR_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// font-descriptor: font-family-desc
|
||||||
|
// | font-style-desc
|
||||||
|
// | font-weight-desc
|
||||||
|
// | font-stretch-desc
|
||||||
|
// | font-src-desc
|
||||||
|
// | unicode-range-desc
|
||||||
|
//
|
||||||
|
// All font-*-desc productions follow the pattern
|
||||||
|
// IDENT ':' value ';'
|
||||||
|
//
|
||||||
|
// On entry to this function, mToken is the IDENT.
|
||||||
|
|
||||||
|
PRBool
|
||||||
|
CSSParserImpl::ParseFontDescriptor(nsresult& aErrorCode,
|
||||||
|
nsCSSFontFaceRule* aRule)
|
||||||
|
{
|
||||||
|
if (eCSSToken_Ident != mToken.mType) {
|
||||||
|
REPORT_UNEXPECTED_TOKEN(PEFontDescExpected);
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsString descName = mToken.mIdent;
|
||||||
|
if (!ExpectSymbol(aErrorCode, ':', PR_TRUE)) {
|
||||||
|
REPORT_UNEXPECTED_TOKEN(PEParseDeclarationNoColon);
|
||||||
|
OUTPUT_ERROR();
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCSSFontDesc descID = nsCSSProps::LookupFontDesc(descName);
|
||||||
|
nsCSSValue value;
|
||||||
|
|
||||||
|
if (descID == eCSSFontDesc_UNKNOWN) {
|
||||||
|
if (NonMozillaVendorIdentifier(descName)) {
|
||||||
|
// silently skip other vendors' extensions
|
||||||
|
SkipDeclaration(aErrorCode, PR_TRUE);
|
||||||
|
return PR_TRUE;
|
||||||
|
} else {
|
||||||
|
const PRUnichar *params[] = {
|
||||||
|
descName.get()
|
||||||
|
};
|
||||||
|
REPORT_UNEXPECTED_P(PEUnknownFontDesc, params);
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ParseFontDescriptorValue(aErrorCode, descID, value)) {
|
||||||
|
const PRUnichar *params[] = {
|
||||||
|
descName.get()
|
||||||
|
};
|
||||||
|
REPORT_UNEXPECTED_P(PEValueParsingError, params);
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ExpectEndProperty(aErrorCode))
|
||||||
|
return PR_FALSE;
|
||||||
|
|
||||||
|
aRule->SetDesc(descID, value);
|
||||||
|
return PR_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
PRBool CSSParserImpl::ParsePageRule(nsresult& aErrorCode, RuleAppendFunc aAppendFunc, void* aData)
|
PRBool CSSParserImpl::ParsePageRule(nsresult& aErrorCode, RuleAppendFunc aAppendFunc, void* aData)
|
||||||
{
|
{
|
||||||
// XXX not yet implemented
|
// XXX not yet implemented
|
||||||
|
@ -3747,7 +3853,7 @@ CSSParserImpl::ParseDeclaration(nsresult& aErrorCode,
|
||||||
const PRUnichar *params[] = {
|
const PRUnichar *params[] = {
|
||||||
propertyName.get()
|
propertyName.get()
|
||||||
};
|
};
|
||||||
REPORT_UNEXPECTED_P(PEPropertyParsingError, params);
|
REPORT_UNEXPECTED_P(PEValueParsingError, params);
|
||||||
REPORT_UNEXPECTED(PEDeclDropped);
|
REPORT_UNEXPECTED(PEDeclDropped);
|
||||||
OUTPUT_ERROR();
|
OUTPUT_ERROR();
|
||||||
ClearTempData(propID);
|
ClearTempData(propID);
|
||||||
|
@ -4444,7 +4550,8 @@ PRBool CSSParserImpl::ParseAttr(nsresult& aErrorCode, nsCSSValue& aValue)
|
||||||
return PR_FALSE;
|
return PR_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
PRBool CSSParserImpl::ParseURL(nsresult& aErrorCode, nsCSSValue& aValue)
|
PRBool
|
||||||
|
CSSParserImpl::ParseURL(nsresult& aErrorCode, nsCSSValue& aValue)
|
||||||
{
|
{
|
||||||
if (!mSheetPrincipal) {
|
if (!mSheetPrincipal) {
|
||||||
NS_NOTREACHED("Codepaths that expect to parse URLs MUST pass in an "
|
NS_NOTREACHED("Codepaths that expect to parse URLs MUST pass in an "
|
||||||
|
@ -4452,39 +4559,40 @@ PRBool CSSParserImpl::ParseURL(nsresult& aErrorCode, nsCSSValue& aValue)
|
||||||
return PR_FALSE;
|
return PR_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ExpectSymbol(aErrorCode, '(', PR_FALSE)) {
|
if (!ExpectSymbol(aErrorCode, '(', PR_FALSE))
|
||||||
if (! GetURLToken(aErrorCode)) {
|
|
||||||
return PR_FALSE;
|
return PR_FALSE;
|
||||||
}
|
if (!GetURLToken(aErrorCode))
|
||||||
|
return PR_FALSE;
|
||||||
|
|
||||||
nsCSSToken* tk = &mToken;
|
nsCSSToken* tk = &mToken;
|
||||||
if ((eCSSToken_String == tk->mType) || (eCSSToken_URL == tk->mType)) {
|
if (eCSSToken_String != tk->mType && eCSSToken_URL != tk->mType)
|
||||||
// Translate url into an absolute url if the url is relative to
|
return PR_FALSE;
|
||||||
// the style sheet.
|
|
||||||
|
nsString url = tk->mIdent;
|
||||||
|
if (!ExpectSymbol(aErrorCode, ')', PR_TRUE))
|
||||||
|
return PR_FALSE;
|
||||||
|
|
||||||
|
// Translate url into an absolute url if the url is relative to the
|
||||||
|
// style sheet.
|
||||||
nsCOMPtr<nsIURI> uri;
|
nsCOMPtr<nsIURI> uri;
|
||||||
NS_NewURI(getter_AddRefs(uri), tk->mIdent, nsnull, mBaseURL);
|
NS_NewURI(getter_AddRefs(uri), url, nsnull, mBaseURL);
|
||||||
if (ExpectSymbol(aErrorCode, ')', PR_TRUE)) {
|
|
||||||
// Set a null value on failure. Most failure cases should be
|
nsStringBuffer* buffer = nsCSSValue::BufferFromString(url);
|
||||||
// NS_ERROR_MALFORMED_URI.
|
|
||||||
nsStringBuffer* buffer = nsCSSValue::BufferFromString(tk->mIdent);
|
|
||||||
if (NS_UNLIKELY(!buffer)) {
|
if (NS_UNLIKELY(!buffer)) {
|
||||||
aErrorCode = NS_ERROR_OUT_OF_MEMORY;
|
aErrorCode = NS_ERROR_OUT_OF_MEMORY;
|
||||||
return PR_FALSE;
|
return PR_FALSE;
|
||||||
}
|
}
|
||||||
|
nsCSSValue::URL *urlVal =
|
||||||
nsCSSValue::URL *url =
|
|
||||||
new nsCSSValue::URL(uri, buffer, mSheetURL, mSheetPrincipal);
|
new nsCSSValue::URL(uri, buffer, mSheetURL, mSheetPrincipal);
|
||||||
|
|
||||||
buffer->Release();
|
buffer->Release();
|
||||||
if (NS_UNLIKELY(!url)) {
|
if (NS_UNLIKELY(!urlVal)) {
|
||||||
aErrorCode = NS_ERROR_OUT_OF_MEMORY;
|
aErrorCode = NS_ERROR_OUT_OF_MEMORY;
|
||||||
return PR_FALSE;
|
return PR_FALSE;
|
||||||
}
|
}
|
||||||
aValue.SetURLValue(url);
|
aValue.SetURLValue(urlVal);
|
||||||
return PR_TRUE;
|
return PR_TRUE;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
return PR_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
PRInt32 CSSParserImpl::ParseChoice(nsresult& aErrorCode, nsCSSValue aValues[],
|
PRInt32 CSSParserImpl::ParseChoice(nsresult& aErrorCode, nsCSSValue aValues[],
|
||||||
const nsCSSProperty aPropIDs[], PRInt32 aNumIDs)
|
const nsCSSProperty aPropIDs[], PRInt32 aNumIDs)
|
||||||
|
@ -5385,6 +5493,95 @@ PRBool CSSParserImpl::ParseSingleValueProperty(nsresult& aErrorCode,
|
||||||
return PR_FALSE;
|
return PR_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// nsFont::EnumerateFamilies callback for ParseFontDescriptorValue
|
||||||
|
struct NS_STACK_CLASS ExtractFirstFamilyData {
|
||||||
|
nsAutoString mFamilyName;
|
||||||
|
PRBool mGood;
|
||||||
|
ExtractFirstFamilyData() : mFamilyName(), mGood(PR_FALSE) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
static PRBool
|
||||||
|
ExtractFirstFamily(const nsString& aFamily,
|
||||||
|
PRBool aGeneric,
|
||||||
|
void* aData)
|
||||||
|
{
|
||||||
|
ExtractFirstFamilyData* realData = (ExtractFirstFamilyData*) aData;
|
||||||
|
if (aGeneric || realData->mFamilyName.Length() > 0) {
|
||||||
|
realData->mGood = PR_FALSE;
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
realData->mFamilyName.Assign(aFamily);
|
||||||
|
realData->mGood = PR_TRUE;
|
||||||
|
return PR_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// font-descriptor: descriptor ':' value ';'
|
||||||
|
// caller has advanced mToken to point at the descriptor
|
||||||
|
PRBool
|
||||||
|
CSSParserImpl::ParseFontDescriptorValue(nsresult& aErrorCode,
|
||||||
|
nsCSSFontDesc aDescID,
|
||||||
|
nsCSSValue& aValue)
|
||||||
|
{
|
||||||
|
switch (aDescID) {
|
||||||
|
// These four are similar to the properties of the same name,
|
||||||
|
// possibly with more restrictions on the values they can take.
|
||||||
|
case eCSSFontDesc_Family: {
|
||||||
|
if (!ParseFamily(aErrorCode, aValue) ||
|
||||||
|
aValue.GetUnit() != eCSSUnit_String)
|
||||||
|
return PR_FALSE;
|
||||||
|
|
||||||
|
// the style parameters to the nsFont constructor are ignored,
|
||||||
|
// because it's only being used to call EnumerateFamilies
|
||||||
|
nsAutoString valueStr;
|
||||||
|
aValue.GetStringValue(valueStr);
|
||||||
|
nsFont font(valueStr, 0, 0, 0, 0, 0);
|
||||||
|
ExtractFirstFamilyData dat;
|
||||||
|
|
||||||
|
font.EnumerateFamilies(ExtractFirstFamily, (void*) &dat);
|
||||||
|
if (!dat.mGood)
|
||||||
|
return PR_FALSE;
|
||||||
|
|
||||||
|
aValue.SetStringValue(dat.mFamilyName, eCSSUnit_String);
|
||||||
|
return PR_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
case eCSSFontDesc_Style:
|
||||||
|
// property is VARIANT_HMK|VARIANT_SYSFONT
|
||||||
|
return ParseVariant(aErrorCode, aValue, VARIANT_KEYWORD | VARIANT_NORMAL,
|
||||||
|
nsCSSProps::kFontStyleKTable);
|
||||||
|
|
||||||
|
case eCSSFontDesc_Weight:
|
||||||
|
return (ParseFontWeight(aErrorCode, aValue) &&
|
||||||
|
aValue.GetUnit() != eCSSUnit_Inherit &&
|
||||||
|
aValue.GetUnit() != eCSSUnit_Initial &&
|
||||||
|
(aValue.GetUnit() != eCSSUnit_Enumerated ||
|
||||||
|
(aValue.GetIntValue() != NS_STYLE_FONT_WEIGHT_BOLDER &&
|
||||||
|
aValue.GetIntValue() != NS_STYLE_FONT_WEIGHT_LIGHTER)));
|
||||||
|
|
||||||
|
case eCSSFontDesc_Stretch:
|
||||||
|
// property is VARIANT_HMK|VARIANT_SYSFONT
|
||||||
|
return (ParseVariant(aErrorCode, aValue, VARIANT_KEYWORD | VARIANT_NORMAL,
|
||||||
|
nsCSSProps::kFontStretchKTable) &&
|
||||||
|
(aValue.GetUnit() != eCSSUnit_Enumerated ||
|
||||||
|
(aValue.GetIntValue() != NS_STYLE_FONT_STRETCH_WIDER &&
|
||||||
|
aValue.GetIntValue() != NS_STYLE_FONT_STRETCH_NARROWER)));
|
||||||
|
|
||||||
|
// These two are unique to @font-face and have their own special grammar.
|
||||||
|
case eCSSFontDesc_Src:
|
||||||
|
return ParseFontSrc(aErrorCode, aValue);
|
||||||
|
|
||||||
|
case eCSSFontDesc_UnicodeRange:
|
||||||
|
return ParseFontRanges(aErrorCode, aValue);
|
||||||
|
|
||||||
|
case eCSSFontDesc_UNKNOWN:
|
||||||
|
case eCSSFontDesc_COUNT:
|
||||||
|
NS_NOTREACHED("bad nsCSSFontDesc code");
|
||||||
|
}
|
||||||
|
// explicitly do NOT have a default case to let the compiler
|
||||||
|
// help find missing descriptors
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CSSParserImpl::InitBoxPropsAsPhysical(const nsCSSProperty *aSourceProperties)
|
CSSParserImpl::InitBoxPropsAsPhysical(const nsCSSProperty *aSourceProperties)
|
||||||
{
|
{
|
||||||
|
@ -6424,18 +6621,58 @@ PRBool CSSParserImpl::ParseFontWeight(nsresult& aErrorCode, nsCSSValue& aValue)
|
||||||
return PR_FALSE;
|
return PR_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
PRBool CSSParserImpl::ParseFamily(nsresult& aErrorCode, nsCSSValue& aValue)
|
PRBool CSSParserImpl::ParseOneFamily(nsresult& aErrorCode, nsAString& aFamily)
|
||||||
{
|
{
|
||||||
|
if (!GetToken(aErrorCode, PR_TRUE))
|
||||||
|
return PR_FALSE;
|
||||||
|
|
||||||
nsCSSToken* tk = &mToken;
|
nsCSSToken* tk = &mToken;
|
||||||
nsAutoString family;
|
|
||||||
PRBool firstOne = PR_TRUE;
|
if (eCSSToken_Ident == tk->mType) {
|
||||||
|
aFamily.Append(tk->mIdent);
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (!GetToken(aErrorCode, PR_TRUE)) {
|
if (!GetToken(aErrorCode, PR_FALSE))
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (eCSSToken_Ident == tk->mType) {
|
||||||
|
aFamily.Append(tk->mIdent);
|
||||||
|
} else if (eCSSToken_WhiteSpace == tk->mType) {
|
||||||
|
// Lookahead one token and drop whitespace if we are ending the
|
||||||
|
// font name.
|
||||||
|
if (!GetToken(aErrorCode, PR_TRUE))
|
||||||
|
break;
|
||||||
|
|
||||||
|
UngetToken();
|
||||||
|
if (eCSSToken_Ident == tk->mType)
|
||||||
|
aFamily.Append(PRUnichar(' '));
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
UngetToken();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (eCSSToken_Ident == tk->mType) {
|
}
|
||||||
if (firstOne) {
|
return PR_TRUE;
|
||||||
nsCSSKeyword keyword = nsCSSKeywords::LookupKeyword(tk->mIdent);
|
|
||||||
|
} else if (eCSSToken_String == tk->mType) {
|
||||||
|
aFamily.Append(tk->mSymbol); // replace the quotes
|
||||||
|
aFamily.Append(tk->mIdent); // XXX What if it had escaped quotes?
|
||||||
|
aFamily.Append(tk->mSymbol);
|
||||||
|
return PR_TRUE;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
UngetToken();
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PRBool CSSParserImpl::ParseFamily(nsresult& aErrorCode, nsCSSValue& aValue)
|
||||||
|
{
|
||||||
|
if (!GetToken(aErrorCode, PR_TRUE))
|
||||||
|
return PR_FALSE;
|
||||||
|
|
||||||
|
if (eCSSToken_Ident == mToken.mType) {
|
||||||
|
nsCSSKeyword keyword = nsCSSKeywords::LookupKeyword(mToken.mIdent);
|
||||||
if (keyword == eCSSKeyword_inherit) {
|
if (keyword == eCSSKeyword_inherit) {
|
||||||
aValue.SetInheritValue();
|
aValue.SetInheritValue();
|
||||||
return PR_TRUE;
|
return PR_TRUE;
|
||||||
|
@ -6450,52 +6687,20 @@ PRBool CSSParserImpl::ParseFamily(nsresult& aErrorCode, nsCSSValue& aValue)
|
||||||
return PR_TRUE;
|
return PR_TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
family.Append(PRUnichar(','));
|
UngetToken();
|
||||||
}
|
|
||||||
family.Append(tk->mIdent);
|
nsAutoString family;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (!GetToken(aErrorCode, PR_FALSE)) {
|
if (!ParseOneFamily(aErrorCode, family))
|
||||||
|
return PR_FALSE;
|
||||||
|
|
||||||
|
if (!ExpectSymbol(aErrorCode, ',', PR_TRUE))
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
if (eCSSToken_Ident == tk->mType) {
|
|
||||||
family.Append(tk->mIdent);
|
|
||||||
} else if (eCSSToken_WhiteSpace == tk->mType) {
|
|
||||||
// Lookahead one token and drop whitespace if we ending the
|
|
||||||
// font name.
|
|
||||||
if (!GetToken(aErrorCode, PR_TRUE)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (eCSSToken_Ident != tk->mType) {
|
|
||||||
UngetToken();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
UngetToken();
|
|
||||||
family.Append(PRUnichar(' '));
|
|
||||||
} else {
|
|
||||||
UngetToken();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
firstOne = PR_FALSE;
|
|
||||||
} else if (eCSSToken_String == tk->mType) {
|
|
||||||
if (!firstOne) {
|
|
||||||
family.Append(PRUnichar(','));
|
family.Append(PRUnichar(','));
|
||||||
}
|
}
|
||||||
family.Append(tk->mSymbol); // replace the quotes
|
|
||||||
family.Append(tk->mIdent); // XXX What if it had escaped quotes?
|
|
||||||
family.Append(tk->mSymbol);
|
|
||||||
firstOne = PR_FALSE;
|
|
||||||
} else if (eCSSToken_Symbol == tk->mType) {
|
|
||||||
if (',' != tk->mSymbol) {
|
|
||||||
UngetToken();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
UngetToken();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (family.IsEmpty()) {
|
if (family.IsEmpty()) {
|
||||||
return PR_FALSE;
|
return PR_FALSE;
|
||||||
}
|
}
|
||||||
|
@ -6503,6 +6708,111 @@ PRBool CSSParserImpl::ParseFamily(nsresult& aErrorCode, nsCSSValue& aValue)
|
||||||
return PR_TRUE;
|
return PR_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// src: ( uri-src | local-src ) (',' ( uri-src | local-src ) )*
|
||||||
|
// uri-src: uri [ 'format(' string ( ',' string )* ')' ]
|
||||||
|
// local-src: 'local(' ( string | ident ) ')'
|
||||||
|
|
||||||
|
PRBool
|
||||||
|
CSSParserImpl::ParseFontSrc(nsresult& aErrorCode, nsCSSValue& aValue)
|
||||||
|
{
|
||||||
|
// could we maybe turn nsCSSValue::Array into nsTArray<nsCSSValue>?
|
||||||
|
nsTArray<nsCSSValue> values;
|
||||||
|
nsCSSValue cur;
|
||||||
|
for (;;) {
|
||||||
|
if (!GetToken(aErrorCode, PR_TRUE))
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (mToken.mType == eCSSToken_Function &&
|
||||||
|
mToken.mIdent.LowerCaseEqualsLiteral("url")) {
|
||||||
|
if (!ParseURL(aErrorCode, cur))
|
||||||
|
return PR_FALSE;
|
||||||
|
values.AppendElement(cur);
|
||||||
|
if (!ParseFontSrcFormat(aErrorCode, values))
|
||||||
|
return PR_FALSE;
|
||||||
|
|
||||||
|
} else if (mToken.mType == eCSSToken_Function &&
|
||||||
|
mToken.mIdent.LowerCaseEqualsLiteral("local")) {
|
||||||
|
// css3-fonts does not specify a formal grammar for local().
|
||||||
|
// The text permits both unquoted identifiers and quoted
|
||||||
|
// strings. We resolve this ambiguity in the spec by
|
||||||
|
// assuming that the appropriate production is a single
|
||||||
|
// <family-name>, possibly surrounded by whitespace.
|
||||||
|
|
||||||
|
nsAutoString family;
|
||||||
|
if (!ExpectSymbol(aErrorCode, '(', PR_FALSE))
|
||||||
|
return PR_FALSE;
|
||||||
|
if (!ParseOneFamily(aErrorCode, family))
|
||||||
|
return PR_FALSE;
|
||||||
|
if (!ExpectSymbol(aErrorCode, ')', PR_TRUE))
|
||||||
|
return PR_FALSE;
|
||||||
|
|
||||||
|
// the style parameters to the nsFont constructor are ignored,
|
||||||
|
// because it's only being used to call EnumerateFamilies
|
||||||
|
nsFont font(family, 0, 0, 0, 0, 0);
|
||||||
|
ExtractFirstFamilyData dat;
|
||||||
|
|
||||||
|
font.EnumerateFamilies(ExtractFirstFamily, (void*) &dat);
|
||||||
|
if (!dat.mGood)
|
||||||
|
return PR_FALSE;
|
||||||
|
|
||||||
|
cur.SetStringValue(dat.mFamilyName, eCSSUnit_Local_Font);
|
||||||
|
values.AppendElement(cur);
|
||||||
|
} else {
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ExpectSymbol(aErrorCode, ',', PR_TRUE))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsRefPtr<nsCSSValue::Array> srcVals
|
||||||
|
= nsCSSValue::Array::Create(values.Length());
|
||||||
|
if (!srcVals)
|
||||||
|
return PR_FALSE;
|
||||||
|
|
||||||
|
PRUint32 i;
|
||||||
|
for (i = 0; i < values.Length(); i++)
|
||||||
|
srcVals->Item(i) = values[i];
|
||||||
|
aValue.SetArrayValue(srcVals, eCSSUnit_Array);
|
||||||
|
return PR_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
PRBool
|
||||||
|
CSSParserImpl::ParseFontSrcFormat(nsresult& aErrorCode,
|
||||||
|
nsTArray<nsCSSValue> & values)
|
||||||
|
{
|
||||||
|
if (!GetToken(aErrorCode, PR_TRUE))
|
||||||
|
return PR_TRUE; // EOF harmless here
|
||||||
|
if (mToken.mType != eCSSToken_Function ||
|
||||||
|
!mToken.mIdent.LowerCaseEqualsLiteral("format")) {
|
||||||
|
UngetToken();
|
||||||
|
return PR_TRUE;
|
||||||
|
}
|
||||||
|
if (!ExpectSymbol(aErrorCode, '(', PR_FALSE))
|
||||||
|
return PR_FALSE;
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (!GetToken(aErrorCode, PR_TRUE))
|
||||||
|
return PR_FALSE;
|
||||||
|
|
||||||
|
if (mToken.mType != eCSSToken_String)
|
||||||
|
return PR_FALSE;
|
||||||
|
|
||||||
|
nsCSSValue cur(mToken.mIdent, eCSSUnit_Font_Format);
|
||||||
|
values.AppendElement(cur);
|
||||||
|
} while (ExpectSymbol(aErrorCode, ',', PR_TRUE));
|
||||||
|
|
||||||
|
return ExpectSymbol(aErrorCode, ')', PR_TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// font-ranges: urange ( ',' urange )*
|
||||||
|
PRBool
|
||||||
|
CSSParserImpl::ParseFontRanges(nsresult& aErrorCode, nsCSSValue& aValue)
|
||||||
|
{
|
||||||
|
// not currently implemented (bug 443976)
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
PRBool CSSParserImpl::ParseListStyle(nsresult& aErrorCode)
|
PRBool CSSParserImpl::ParseListStyle(nsresult& aErrorCode)
|
||||||
{
|
{
|
||||||
const PRInt32 numProps = 3;
|
const PRInt32 numProps = 3;
|
||||||
|
|
|
@ -75,4 +75,19 @@ enum nsCSSType {
|
||||||
eCSSType_ValuePairList
|
eCSSType_ValuePairList
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// The "descriptors" that can appear in a @font-face rule.
|
||||||
|
// They have the syntax of properties but different value rules.
|
||||||
|
// Keep in sync with kCSSRawFontDescs in nsCSSProps.cpp and
|
||||||
|
// nsCSSFontFaceStyleDecl::Fields in nsCSSRules.cpp.
|
||||||
|
enum nsCSSFontDesc {
|
||||||
|
eCSSFontDesc_UNKNOWN = -1,
|
||||||
|
eCSSFontDesc_Family,
|
||||||
|
eCSSFontDesc_Style,
|
||||||
|
eCSSFontDesc_Weight,
|
||||||
|
eCSSFontDesc_Stretch,
|
||||||
|
eCSSFontDesc_Src,
|
||||||
|
eCSSFontDesc_UnicodeRange,
|
||||||
|
eCSSFontDesc_COUNT
|
||||||
|
};
|
||||||
|
|
||||||
#endif /* nsCSSProperty_h___ */
|
#endif /* nsCSSProperty_h___ */
|
||||||
|
|
|
@ -68,12 +68,25 @@ const char* const kCSSRawProperties[] = {
|
||||||
|
|
||||||
static PRInt32 gTableRefCount;
|
static PRInt32 gTableRefCount;
|
||||||
static nsStaticCaseInsensitiveNameTable* gPropertyTable;
|
static nsStaticCaseInsensitiveNameTable* gPropertyTable;
|
||||||
|
static nsStaticCaseInsensitiveNameTable* gFontDescTable;
|
||||||
|
|
||||||
|
// Keep in sync with enum nsCSSFontDesc in nsCSSProperty.h.
|
||||||
|
static const char* const kCSSRawFontDescs[] = {
|
||||||
|
"font-family",
|
||||||
|
"font-style",
|
||||||
|
"font-weight",
|
||||||
|
"font-stretch",
|
||||||
|
"src",
|
||||||
|
"unicode-range"
|
||||||
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
nsCSSProps::AddRefTable(void)
|
nsCSSProps::AddRefTable(void)
|
||||||
{
|
{
|
||||||
if (0 == gTableRefCount++) {
|
if (0 == gTableRefCount++) {
|
||||||
NS_ASSERTION(!gPropertyTable, "pre existing array!");
|
NS_ASSERTION(!gPropertyTable, "pre existing array!");
|
||||||
|
NS_ASSERTION(!gFontDescTable, "pre existing array!");
|
||||||
|
|
||||||
gPropertyTable = new nsStaticCaseInsensitiveNameTable();
|
gPropertyTable = new nsStaticCaseInsensitiveNameTable();
|
||||||
if (gPropertyTable) {
|
if (gPropertyTable) {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
@ -83,13 +96,30 @@ nsCSSProps::AddRefTable(void)
|
||||||
nsCAutoString temp1(kCSSRawProperties[index]);
|
nsCAutoString temp1(kCSSRawProperties[index]);
|
||||||
nsCAutoString temp2(kCSSRawProperties[index]);
|
nsCAutoString temp2(kCSSRawProperties[index]);
|
||||||
ToLowerCase(temp1);
|
ToLowerCase(temp1);
|
||||||
NS_ASSERTION(temp1.Equals(temp2), "upper case char in table");
|
NS_ASSERTION(temp1.Equals(temp2), "upper case char in prop table");
|
||||||
NS_ASSERTION(-1 == temp1.FindChar('_'), "underscore char in table");
|
NS_ASSERTION(-1 == temp1.FindChar('_'), "underscore char in prop table");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
gPropertyTable->Init(kCSSRawProperties, eCSSProperty_COUNT);
|
gPropertyTable->Init(kCSSRawProperties, eCSSProperty_COUNT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gFontDescTable = new nsStaticCaseInsensitiveNameTable();
|
||||||
|
if (gFontDescTable) {
|
||||||
|
#ifdef DEBUG
|
||||||
|
{
|
||||||
|
// let's verify the table...
|
||||||
|
for (PRInt32 index = 0; index < eCSSFontDesc_COUNT; ++index) {
|
||||||
|
nsCAutoString temp1(kCSSRawFontDescs[index]);
|
||||||
|
nsCAutoString temp2(kCSSRawFontDescs[index]);
|
||||||
|
ToLowerCase(temp1);
|
||||||
|
NS_ASSERTION(temp1.Equals(temp2), "upper case char in desc table");
|
||||||
|
NS_ASSERTION(-1 == temp1.FindChar('_'), "underscore char in desc table");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
gFontDescTable->Init(kCSSRawFontDescs, eCSSFontDesc_COUNT);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,6 +131,10 @@ nsCSSProps::ReleaseTable(void)
|
||||||
delete gPropertyTable;
|
delete gPropertyTable;
|
||||||
gPropertyTable = nsnull;
|
gPropertyTable = nsnull;
|
||||||
}
|
}
|
||||||
|
if (gFontDescTable) {
|
||||||
|
delete gFontDescTable;
|
||||||
|
gFontDescTable = nsnull;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,6 +194,20 @@ nsCSSProps::LookupProperty(const nsAString& aProperty)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsCSSFontDesc
|
||||||
|
nsCSSProps::LookupFontDesc(const nsACString& aFontDesc)
|
||||||
|
{
|
||||||
|
NS_ASSERTION(gFontDescTable, "no lookup table, needs addref");
|
||||||
|
return nsCSSFontDesc(gFontDescTable->Lookup(aFontDesc));
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCSSFontDesc
|
||||||
|
nsCSSProps::LookupFontDesc(const nsAString& aFontDesc)
|
||||||
|
{
|
||||||
|
NS_ASSERTION(gFontDescTable, "no lookup table, needs addref");
|
||||||
|
return nsCSSFontDesc(gFontDescTable->Lookup(aFontDesc));
|
||||||
|
}
|
||||||
|
|
||||||
const nsAFlatCString&
|
const nsAFlatCString&
|
||||||
nsCSSProps::GetStringValue(nsCSSProperty aProperty)
|
nsCSSProps::GetStringValue(nsCSSProperty aProperty)
|
||||||
{
|
{
|
||||||
|
@ -172,6 +220,18 @@ nsCSSProps::GetStringValue(nsCSSProperty aProperty)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const nsAFlatCString&
|
||||||
|
nsCSSProps::GetStringValue(nsCSSFontDesc aFontDescID)
|
||||||
|
{
|
||||||
|
NS_ASSERTION(gFontDescTable, "no lookup table, needs addref");
|
||||||
|
if (gFontDescTable) {
|
||||||
|
return gFontDescTable->GetStringValue(PRInt32(aFontDescID));
|
||||||
|
} else {
|
||||||
|
static nsDependentCString sNullStr("");
|
||||||
|
return sNullStr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
||||||
|
|
|
@ -65,8 +65,13 @@ public:
|
||||||
return (aProperty >= eCSSProperty_COUNT_no_shorthands);
|
return (aProperty >= eCSSProperty_COUNT_no_shorthands);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Same but for @font-face descriptors
|
||||||
|
static nsCSSFontDesc LookupFontDesc(const nsAString& aProperty);
|
||||||
|
static nsCSSFontDesc LookupFontDesc(const nsACString& aProperty);
|
||||||
|
|
||||||
// Given a property enum, get the string value
|
// Given a property enum, get the string value
|
||||||
static const nsAFlatCString& GetStringValue(nsCSSProperty aProperty);
|
static const nsAFlatCString& GetStringValue(nsCSSProperty aProperty);
|
||||||
|
static const nsAFlatCString& GetStringValue(nsCSSFontDesc aFontDesc);
|
||||||
|
|
||||||
// Given a CSS Property and a Property Enum Value
|
// Given a CSS Property and a Property Enum Value
|
||||||
// Return back a const nsString& representation of the
|
// Return back a const nsString& representation of the
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
/* rules in a CSS stylesheet other than style rules (e.g., @import rules) */
|
/* rules in a CSS stylesheet other than style rules (e.g., @import rules) */
|
||||||
|
|
||||||
#include "nsCSSRules.h"
|
#include "nsCSSRules.h"
|
||||||
|
#include "nsCSSValue.h"
|
||||||
#include "nsICSSImportRule.h"
|
#include "nsICSSImportRule.h"
|
||||||
#include "nsICSSNameSpaceRule.h"
|
#include "nsICSSNameSpaceRule.h"
|
||||||
|
|
||||||
|
@ -47,6 +48,7 @@
|
||||||
#include "nsIURL.h"
|
#include "nsIURL.h"
|
||||||
|
|
||||||
#include "nsCSSRule.h"
|
#include "nsCSSRule.h"
|
||||||
|
#include "nsCSSProps.h"
|
||||||
#include "nsICSSStyleSheet.h"
|
#include "nsICSSStyleSheet.h"
|
||||||
|
|
||||||
#include "nsCOMPtr.h"
|
#include "nsCOMPtr.h"
|
||||||
|
@ -56,6 +58,7 @@
|
||||||
#include "nsIDOMCSSMediaRule.h"
|
#include "nsIDOMCSSMediaRule.h"
|
||||||
#include "nsIDOMCSSMozDocumentRule.h"
|
#include "nsIDOMCSSMozDocumentRule.h"
|
||||||
#include "nsIDOMCSSCharsetRule.h"
|
#include "nsIDOMCSSCharsetRule.h"
|
||||||
|
#include "nsIDOMCSSStyleDeclaration.h"
|
||||||
#include "nsIMediaList.h"
|
#include "nsIMediaList.h"
|
||||||
#include "nsIDOMMediaList.h"
|
#include "nsIDOMMediaList.h"
|
||||||
#include "nsIDOMCSSRuleList.h"
|
#include "nsIDOMCSSRuleList.h"
|
||||||
|
@ -66,6 +69,8 @@
|
||||||
#include "nsContentUtils.h"
|
#include "nsContentUtils.h"
|
||||||
#include "nsStyleConsts.h"
|
#include "nsStyleConsts.h"
|
||||||
#include "nsDOMError.h"
|
#include "nsDOMError.h"
|
||||||
|
#include "nsStyleUtil.h"
|
||||||
|
#include "nsCSSDeclaration.h"
|
||||||
|
|
||||||
#define IMPL_STYLE_RULE_INHERIT(_class, super) \
|
#define IMPL_STYLE_RULE_INHERIT(_class, super) \
|
||||||
NS_IMETHODIMP _class::GetStyleSheet(nsIStyleSheet*& aSheet) const { return super::GetStyleSheet(aSheet); } \
|
NS_IMETHODIMP _class::GetStyleSheet(nsIStyleSheet*& aSheet) const { return super::GetStyleSheet(aSheet); } \
|
||||||
|
@ -1013,7 +1018,7 @@ nsCSSMediaRule::GetMedia(nsIDOMMediaList* *aMedia)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
return CallQueryInterface(mMedia, aMedia);
|
return CallQueryInterface(mMedia.get(), aMedia);
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
|
@ -1451,3 +1456,424 @@ CSSNameSpaceRuleImpl::GetParentRule(nsIDOMCSSRule** aParentRule)
|
||||||
*aParentRule = nsnull;
|
*aParentRule = nsnull;
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------
|
||||||
|
// nsCSSFontFaceStyleDecl and related routines
|
||||||
|
//
|
||||||
|
|
||||||
|
// A src: descriptor is represented as an array value; each entry in
|
||||||
|
// the array can be eCSSUnit_URL, eCSSUnit_Local_Font, or
|
||||||
|
// eCSSUnit_Font_Format. Blocks of eCSSUnit_Font_Format may appear
|
||||||
|
// only after one of the first two. (css3-fonts only contemplates
|
||||||
|
// annotating URLs with formats, but we handle the general case.)
|
||||||
|
static void
|
||||||
|
SerializeFontSrc(const nsCSSValue& src, nsAString & aResult NS_OUTPARAM)
|
||||||
|
{
|
||||||
|
NS_PRECONDITION(src.GetUnit() == eCSSUnit_Null ||
|
||||||
|
src.GetUnit() == eCSSUnit_Array,
|
||||||
|
"improper value unit for src:");
|
||||||
|
aResult.Truncate();
|
||||||
|
if (src.GetUnit() != eCSSUnit_Array)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const nsCSSValue::Array& sources = *src.GetArrayValue();
|
||||||
|
PRUint32 i = 0;
|
||||||
|
|
||||||
|
while (i < sources.Count()) {
|
||||||
|
nsAutoString formats;
|
||||||
|
|
||||||
|
if (sources[i].GetUnit() == eCSSUnit_URL) {
|
||||||
|
nsDependentString url(sources[i].GetOriginalURLValue());
|
||||||
|
nsAutoString escapedUrl;
|
||||||
|
nsStyleUtil::EscapeCSSString(url, escapedUrl);
|
||||||
|
aResult.AppendLiteral("url(\"");
|
||||||
|
aResult.Append(escapedUrl);
|
||||||
|
aResult.AppendLiteral("\")");
|
||||||
|
} else if (sources[i].GetUnit() == eCSSUnit_Local_Font) {
|
||||||
|
nsDependentString local(sources[i].GetStringBufferValue());
|
||||||
|
nsAutoString escapedLocal;
|
||||||
|
nsStyleUtil::EscapeCSSString(local, escapedLocal);
|
||||||
|
aResult.AppendLiteral("local(\"");
|
||||||
|
aResult.Append(escapedLocal);
|
||||||
|
aResult.AppendLiteral("\")");
|
||||||
|
} else {
|
||||||
|
NS_NOTREACHED("entry in src: descriptor with improper unit");
|
||||||
|
i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
i++;
|
||||||
|
formats.Truncate();
|
||||||
|
while (i < sources.Count() &&
|
||||||
|
sources[i].GetUnit() == eCSSUnit_Font_Format) {
|
||||||
|
formats.Append('"');
|
||||||
|
formats.Append(sources[i].GetStringBufferValue());
|
||||||
|
formats.AppendLiteral("\", ");
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
if (formats.Length() > 0) {
|
||||||
|
formats.Truncate(formats.Length() - 2); // remove the last comma
|
||||||
|
aResult.AppendLiteral(" format(");
|
||||||
|
aResult.Append(formats);
|
||||||
|
aResult.Append(')');
|
||||||
|
}
|
||||||
|
aResult.AppendLiteral(", ");
|
||||||
|
}
|
||||||
|
aResult.Truncate(aResult.Length() - 2); // remove the last comma-space
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mapping from nsCSSFontDesc codes to nsCSSFontFaceStyleDecl fields.
|
||||||
|
// Keep this in sync with enum nsCSSFontDesc in nsCSSProperty.h.
|
||||||
|
nsCSSValue nsCSSFontFaceStyleDecl::* const
|
||||||
|
nsCSSFontFaceStyleDecl::Fields[] = {
|
||||||
|
&nsCSSFontFaceStyleDecl::mFamily,
|
||||||
|
&nsCSSFontFaceStyleDecl::mStyle,
|
||||||
|
&nsCSSFontFaceStyleDecl::mWeight,
|
||||||
|
&nsCSSFontFaceStyleDecl::mStretch,
|
||||||
|
&nsCSSFontFaceStyleDecl::mSrc,
|
||||||
|
&nsCSSFontFaceStyleDecl::mUnicodeRange
|
||||||
|
};
|
||||||
|
|
||||||
|
// QueryInterface implementation for nsCSSFontFaceStyleDecl
|
||||||
|
NS_INTERFACE_MAP_BEGIN(nsCSSFontFaceStyleDecl)
|
||||||
|
NS_INTERFACE_MAP_ENTRY(nsIDOMCSSStyleDeclaration)
|
||||||
|
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||||
|
NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(CSSFontFaceStyleDecl)
|
||||||
|
NS_INTERFACE_MAP_END
|
||||||
|
|
||||||
|
NS_IMPL_ADDREF_USING_AGGREGATOR(nsCSSFontFaceStyleDecl, ContainingRule())
|
||||||
|
NS_IMPL_RELEASE_USING_AGGREGATOR(nsCSSFontFaceStyleDecl, ContainingRule())
|
||||||
|
|
||||||
|
// helper for string GetPropertyValue and RemovePropertyValue
|
||||||
|
nsresult
|
||||||
|
nsCSSFontFaceStyleDecl::GetPropertyValue(nsCSSFontDesc aFontDescID,
|
||||||
|
nsAString & aResult NS_OUTPARAM) const
|
||||||
|
{
|
||||||
|
NS_ENSURE_ARG_RANGE(aFontDescID, eCSSFontDesc_UNKNOWN,
|
||||||
|
eCSSFontDesc_COUNT - 1);
|
||||||
|
|
||||||
|
aResult.Truncate();
|
||||||
|
if (aFontDescID == eCSSFontDesc_UNKNOWN)
|
||||||
|
return NS_OK;
|
||||||
|
|
||||||
|
const nsCSSValue& val = this->*nsCSSFontFaceStyleDecl::Fields[aFontDescID];
|
||||||
|
|
||||||
|
switch (aFontDescID) {
|
||||||
|
case eCSSFontDesc_Family: {
|
||||||
|
// we don't use AppendCSSValueToString here because it doesn't
|
||||||
|
// canonicalize the way we want, and anyway it's overkill when
|
||||||
|
// we know we have eCSSUnit_String
|
||||||
|
nsDependentString family(val.GetStringBufferValue());
|
||||||
|
nsAutoString escapedFamily;
|
||||||
|
nsStyleUtil::EscapeCSSString(family, escapedFamily);
|
||||||
|
aResult.Append('"');
|
||||||
|
aResult.Append(escapedFamily);
|
||||||
|
aResult.Append('"');
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
case eCSSFontDesc_Style:
|
||||||
|
nsCSSDeclaration::AppendCSSValueToString(eCSSProperty_font_style, val,
|
||||||
|
aResult);
|
||||||
|
return NS_OK;
|
||||||
|
|
||||||
|
case eCSSFontDesc_Weight:
|
||||||
|
nsCSSDeclaration::AppendCSSValueToString(eCSSProperty_font_weight, val,
|
||||||
|
aResult);
|
||||||
|
return NS_OK;
|
||||||
|
|
||||||
|
case eCSSFontDesc_Stretch:
|
||||||
|
nsCSSDeclaration::AppendCSSValueToString(eCSSProperty_font_stretch, val,
|
||||||
|
aResult);
|
||||||
|
return NS_OK;
|
||||||
|
|
||||||
|
case eCSSFontDesc_Src:
|
||||||
|
SerializeFontSrc(val, aResult);
|
||||||
|
return NS_OK;
|
||||||
|
|
||||||
|
case eCSSFontDesc_UnicodeRange:
|
||||||
|
// these are not implemented, so always return an empty string
|
||||||
|
return NS_OK;
|
||||||
|
|
||||||
|
case eCSSFontDesc_UNKNOWN:
|
||||||
|
case eCSSFontDesc_COUNT:
|
||||||
|
;
|
||||||
|
}
|
||||||
|
NS_NOTREACHED("nsCSSFontFaceStyleDecl::GetPropertyValue: "
|
||||||
|
"out-of-range value got to the switch");
|
||||||
|
return NS_ERROR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// attribute DOMString cssText;
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsCSSFontFaceStyleDecl::GetCssText(nsAString & aCssText)
|
||||||
|
{
|
||||||
|
nsAutoString descStr;
|
||||||
|
|
||||||
|
aCssText.Truncate();
|
||||||
|
for (nsCSSFontDesc id = nsCSSFontDesc(eCSSFontDesc_UNKNOWN + 1);
|
||||||
|
id < eCSSFontDesc_COUNT;
|
||||||
|
id = nsCSSFontDesc(id + 1)) {
|
||||||
|
if ((this->*nsCSSFontFaceStyleDecl::Fields[id]).GetUnit()
|
||||||
|
!= eCSSUnit_Null &&
|
||||||
|
NS_SUCCEEDED(GetPropertyValue(id, descStr))) {
|
||||||
|
NS_ASSERTION(descStr.Length() > 0,
|
||||||
|
"GetCssText: non-null unit, empty property value");
|
||||||
|
aCssText.AppendLiteral(" ");
|
||||||
|
aCssText.AppendASCII(nsCSSProps::GetStringValue(id).get());
|
||||||
|
aCssText.AppendLiteral(": ");
|
||||||
|
aCssText.Append(descStr);
|
||||||
|
aCssText.AppendLiteral(";\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsCSSFontFaceStyleDecl::SetCssText(const nsAString & aCssText)
|
||||||
|
{
|
||||||
|
return NS_ERROR_NOT_IMPLEMENTED; // bug 443978
|
||||||
|
}
|
||||||
|
|
||||||
|
// DOMString getPropertyValue (in DOMString propertyName);
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsCSSFontFaceStyleDecl::GetPropertyValue(const nsAString & propertyName,
|
||||||
|
nsAString & aResult NS_OUTPARAM)
|
||||||
|
{
|
||||||
|
return GetPropertyValue(nsCSSProps::LookupFontDesc(propertyName), aResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
// nsIDOMCSSValue getPropertyCSSValue (in DOMString propertyName);
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsCSSFontFaceStyleDecl::GetPropertyCSSValue(const nsAString & propertyName,
|
||||||
|
nsIDOMCSSValue **aResult NS_OUTPARAM)
|
||||||
|
{
|
||||||
|
// ??? nsDOMCSSDeclaration returns null/NS_OK, but that seems wrong.
|
||||||
|
return NS_ERROR_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
// DOMString removeProperty (in DOMString propertyName) raises (DOMException);
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsCSSFontFaceStyleDecl::RemoveProperty(const nsAString & propertyName,
|
||||||
|
nsAString & aResult NS_OUTPARAM)
|
||||||
|
{
|
||||||
|
nsCSSFontDesc descID = nsCSSProps::LookupFontDesc(propertyName);
|
||||||
|
NS_ASSERTION(descID >= eCSSFontDesc_UNKNOWN &&
|
||||||
|
descID < eCSSFontDesc_COUNT,
|
||||||
|
"LookupFontDesc returned value out of range");
|
||||||
|
|
||||||
|
if (descID == eCSSFontDesc_UNKNOWN) {
|
||||||
|
aResult.Truncate();
|
||||||
|
} else {
|
||||||
|
nsresult rv = GetPropertyValue(descID, aResult);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
(this->*nsCSSFontFaceStyleDecl::Fields[descID]).Reset();
|
||||||
|
}
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// DOMString getPropertyPriority (in DOMString propertyName);
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsCSSFontFaceStyleDecl::GetPropertyPriority(const nsAString & propertyName,
|
||||||
|
nsAString & aResult NS_OUTPARAM)
|
||||||
|
{
|
||||||
|
// font descriptors do not have priorities at present
|
||||||
|
aResult.Truncate();
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// void setProperty (in DOMString propertyName, in DOMString value,
|
||||||
|
// in DOMString priority) raises (DOMException);
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsCSSFontFaceStyleDecl::SetProperty(const nsAString & propertyName,
|
||||||
|
const nsAString & value,
|
||||||
|
const nsAString & priority)
|
||||||
|
{
|
||||||
|
return NS_ERROR_NOT_IMPLEMENTED; // bug 443978
|
||||||
|
}
|
||||||
|
|
||||||
|
// readonly attribute unsigned long length;
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsCSSFontFaceStyleDecl::GetLength(PRUint32 *aLength)
|
||||||
|
{
|
||||||
|
PRUint32 len = 0;
|
||||||
|
for (nsCSSFontDesc id = nsCSSFontDesc(eCSSFontDesc_UNKNOWN + 1);
|
||||||
|
id < eCSSFontDesc_COUNT;
|
||||||
|
id = nsCSSFontDesc(id + 1))
|
||||||
|
if ((this->*nsCSSFontFaceStyleDecl::Fields[id]).GetUnit() != eCSSUnit_Null)
|
||||||
|
len++;
|
||||||
|
|
||||||
|
*aLength = len;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// DOMString item (in unsigned long index);
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsCSSFontFaceStyleDecl::Item(PRUint32 index, nsAString & aResult NS_OUTPARAM)
|
||||||
|
{
|
||||||
|
PRInt32 nset = -1;
|
||||||
|
for (nsCSSFontDesc id = nsCSSFontDesc(eCSSFontDesc_UNKNOWN + 1);
|
||||||
|
id < eCSSFontDesc_COUNT;
|
||||||
|
id = nsCSSFontDesc(id + 1)) {
|
||||||
|
if ((this->*nsCSSFontFaceStyleDecl::Fields[id]).GetUnit()
|
||||||
|
!= eCSSUnit_Null) {
|
||||||
|
nset++;
|
||||||
|
if (nset == PRInt32(index)) {
|
||||||
|
aResult.AssignASCII(nsCSSProps::GetStringValue(id).get());
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
aResult.Truncate();
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// readonly attribute nsIDOMCSSRule parentRule;
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsCSSFontFaceStyleDecl::GetParentRule(nsIDOMCSSRule** aParentRule)
|
||||||
|
{
|
||||||
|
return ContainingRule()->GetDOMRule(aParentRule);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// -------------------------------------------
|
||||||
|
// nsCSSFontFaceRule
|
||||||
|
//
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsCSSFontFaceRule::Clone(nsICSSRule*& aClone) const
|
||||||
|
{
|
||||||
|
nsCSSFontFaceRule* clone = new nsCSSFontFaceRule(*this);
|
||||||
|
if (clone) {
|
||||||
|
return CallQueryInterface(clone, &aClone);
|
||||||
|
}
|
||||||
|
aClone = nsnull;
|
||||||
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMPL_ADDREF_INHERITED(nsCSSFontFaceRule, nsCSSRule)
|
||||||
|
NS_IMPL_RELEASE_INHERITED(nsCSSFontFaceRule, nsCSSRule)
|
||||||
|
|
||||||
|
// QueryInterface implementation for nsCSSFontFaceRule
|
||||||
|
NS_INTERFACE_MAP_BEGIN(nsCSSFontFaceRule)
|
||||||
|
NS_INTERFACE_MAP_ENTRY(nsICSSRule)
|
||||||
|
NS_INTERFACE_MAP_ENTRY(nsIStyleRule)
|
||||||
|
NS_INTERFACE_MAP_ENTRY(nsIDOMCSSFontFaceRule)
|
||||||
|
NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule)
|
||||||
|
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsICSSRule)
|
||||||
|
NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(CSSFontFaceRule)
|
||||||
|
NS_INTERFACE_MAP_END
|
||||||
|
|
||||||
|
IMPL_STYLE_RULE_INHERIT(nsCSSFontFaceRule, nsCSSRule)
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsCSSFontFaceRule::List(FILE* out, PRInt32 aIndent) const
|
||||||
|
{
|
||||||
|
nsCString baseInd, descInd;
|
||||||
|
for (PRInt32 indent = aIndent; --indent >= 0; ) {
|
||||||
|
baseInd.AppendLiteral(" ");
|
||||||
|
descInd.AppendLiteral(" ");
|
||||||
|
}
|
||||||
|
descInd.AppendLiteral(" ");
|
||||||
|
|
||||||
|
nsString descStr;
|
||||||
|
|
||||||
|
fprintf(out, "%s@font-face {\n", baseInd.get());
|
||||||
|
for (nsCSSFontDesc id = nsCSSFontDesc(eCSSFontDesc_UNKNOWN + 1);
|
||||||
|
id < eCSSFontDesc_COUNT;
|
||||||
|
id = nsCSSFontDesc(id + 1))
|
||||||
|
if ((mDecl.*nsCSSFontFaceStyleDecl::Fields[id]).GetUnit()
|
||||||
|
!= eCSSUnit_Null) {
|
||||||
|
if (NS_FAILED(mDecl.GetPropertyValue(id, descStr)))
|
||||||
|
descStr.AssignLiteral("#<serialization error>");
|
||||||
|
else if (descStr.Length() == 0)
|
||||||
|
descStr.AssignLiteral("#<serialization missing>");
|
||||||
|
fprintf(out, "%s%s: %s\n",
|
||||||
|
descInd.get(), nsCSSProps::GetStringValue(id).get(),
|
||||||
|
NS_ConvertUTF16toUTF8(descStr).get());
|
||||||
|
}
|
||||||
|
fprintf(out, "%s}\n", baseInd.get());
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsCSSFontFaceRule::GetType(PRInt32& aType) const
|
||||||
|
{
|
||||||
|
aType = nsICSSRule::FONT_FACE_RULE;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsCSSFontFaceRule::GetType(PRUint16* aType)
|
||||||
|
{
|
||||||
|
*aType = nsIDOMCSSRule::FONT_FACE_RULE;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsCSSFontFaceRule::GetCssText(nsAString& aCssText)
|
||||||
|
{
|
||||||
|
nsAutoString propText;
|
||||||
|
mDecl.GetCssText(propText);
|
||||||
|
|
||||||
|
aCssText.AssignLiteral("@font-face {\n");
|
||||||
|
aCssText.Append(propText);
|
||||||
|
aCssText.Append('}');
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsCSSFontFaceRule::SetCssText(const nsAString& aCssText)
|
||||||
|
{
|
||||||
|
return NS_ERROR_NOT_IMPLEMENTED; // bug 443978
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsCSSFontFaceRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet)
|
||||||
|
{
|
||||||
|
if (mSheet) {
|
||||||
|
return CallQueryInterface(mSheet, aSheet);
|
||||||
|
}
|
||||||
|
*aSheet = nsnull;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsCSSFontFaceRule::GetParentRule(nsIDOMCSSRule** aParentRule)
|
||||||
|
{
|
||||||
|
if (mParentRule) {
|
||||||
|
return mParentRule->GetDOMRule(aParentRule);
|
||||||
|
}
|
||||||
|
*aParentRule = nsnull;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsCSSFontFaceRule::GetStyle(nsIDOMCSSStyleDeclaration** aStyle)
|
||||||
|
{
|
||||||
|
return CallQueryInterface(&mDecl, aStyle);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Arguably these should forward to nsCSSFontFaceStyleDecl methods.
|
||||||
|
void
|
||||||
|
nsCSSFontFaceRule::SetDesc(nsCSSFontDesc aDescID, nsCSSValue const & aValue)
|
||||||
|
{
|
||||||
|
NS_PRECONDITION(aDescID > eCSSFontDesc_UNKNOWN &&
|
||||||
|
aDescID < eCSSFontDesc_COUNT,
|
||||||
|
"aDescID out of range in nsCSSFontFaceRule::SetDesc");
|
||||||
|
|
||||||
|
mDecl.*nsCSSFontFaceStyleDecl::Fields[aDescID] = aValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsCSSFontFaceRule::GetDesc(nsCSSFontDesc aDescID, nsCSSValue & aValue)
|
||||||
|
{
|
||||||
|
NS_PRECONDITION(aDescID > eCSSFontDesc_UNKNOWN &&
|
||||||
|
aDescID < eCSSFontDesc_COUNT,
|
||||||
|
"aDescID out of range in nsCSSFontFaceRule::GetDesc");
|
||||||
|
|
||||||
|
aValue = mDecl.*nsCSSFontFaceStyleDecl::Fields[aDescID];
|
||||||
|
}
|
||||||
|
|
|
@ -45,12 +45,13 @@
|
||||||
|
|
||||||
#include "nsCSSRule.h"
|
#include "nsCSSRule.h"
|
||||||
#include "nsICSSGroupRule.h"
|
#include "nsICSSGroupRule.h"
|
||||||
#include "nsCOMPtr.h"
|
|
||||||
#include "nsAutoPtr.h"
|
|
||||||
#include "nsCOMArray.h"
|
|
||||||
#include "nsIDOMCSSMediaRule.h"
|
#include "nsIDOMCSSMediaRule.h"
|
||||||
#include "nsIDOMCSSMozDocumentRule.h"
|
#include "nsIDOMCSSMozDocumentRule.h"
|
||||||
#include "nsString.h"
|
#include "nsIDOMCSSFontFaceRule.h"
|
||||||
|
#include "nsIDOMCSSStyleDeclaration.h"
|
||||||
|
#include "nsAutoPtr.h"
|
||||||
|
#include "nsCSSProperty.h"
|
||||||
|
#include "nsCSSValue.h"
|
||||||
|
|
||||||
class CSSGroupRuleRuleListImpl;
|
class CSSGroupRuleRuleListImpl;
|
||||||
class nsMediaList;
|
class nsMediaList;
|
||||||
|
@ -142,7 +143,7 @@ public:
|
||||||
nsresult SetMedia(nsMediaList* aMedia);
|
nsresult SetMedia(nsMediaList* aMedia);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
nsCOMPtr<nsMediaList> mMedia;
|
nsRefPtr<nsMediaList> mMedia;
|
||||||
};
|
};
|
||||||
|
|
||||||
class nsCSSDocumentRule : public nsCSSGroupRule,
|
class nsCSSDocumentRule : public nsCSSGroupRule,
|
||||||
|
@ -201,5 +202,81 @@ protected:
|
||||||
nsAutoPtr<URL> mURLs; // linked list of |struct URL| above.
|
nsAutoPtr<URL> mURLs; // linked list of |struct URL| above.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// A nsCSSFontFaceStyleDecl is always embedded in a nsCSSFontFaceRule.
|
||||||
|
class nsCSSFontFaceRule;
|
||||||
|
class nsCSSFontFaceStyleDecl : public nsIDOMCSSStyleDeclaration
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NS_DECL_ISUPPORTS
|
||||||
|
NS_DECL_NSIDOMCSSSTYLEDECLARATION
|
||||||
|
|
||||||
|
nsresult GetPropertyValue(nsCSSFontDesc aFontDescID,
|
||||||
|
nsAString & aResult NS_OUTPARAM) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
friend class nsCSSFontFaceRule;
|
||||||
|
nsCSSValue mFamily;
|
||||||
|
nsCSSValue mStyle;
|
||||||
|
nsCSSValue mWeight;
|
||||||
|
nsCSSValue mStretch;
|
||||||
|
nsCSSValue mSrc;
|
||||||
|
nsCSSValue mUnicodeRange;
|
||||||
|
|
||||||
|
static nsCSSValue nsCSSFontFaceStyleDecl::* const Fields[];
|
||||||
|
inline nsCSSFontFaceRule* ContainingRule();
|
||||||
|
inline const nsCSSFontFaceRule* ContainingRule() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// NOT TO BE IMPLEMENTED
|
||||||
|
// This object cannot be allocated on its own, only as part of
|
||||||
|
// nsCSSFontFaceRule.
|
||||||
|
void* operator new(size_t size) CPP_THROW_NEW;
|
||||||
|
};
|
||||||
|
|
||||||
|
class nsCSSFontFaceRule : public nsCSSRule,
|
||||||
|
public nsICSSRule,
|
||||||
|
public nsIDOMCSSFontFaceRule
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NS_DECL_ISUPPORTS_INHERITED
|
||||||
|
|
||||||
|
// nsIStyleRule methods
|
||||||
|
#ifdef DEBUG
|
||||||
|
NS_IMETHOD List(FILE* out = stdout, PRInt32 aIndent = 0) const;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// nsICSSRule methods
|
||||||
|
DECL_STYLE_RULE_INHERIT
|
||||||
|
|
||||||
|
NS_IMETHOD GetType(PRInt32& aType) const;
|
||||||
|
NS_IMETHOD Clone(nsICSSRule*& aClone) const;
|
||||||
|
|
||||||
|
// nsIDOMCSSRule interface
|
||||||
|
NS_DECL_NSIDOMCSSRULE
|
||||||
|
|
||||||
|
// nsIDOMCSSFontFaceRule interface
|
||||||
|
NS_DECL_NSIDOMCSSFONTFACERULE
|
||||||
|
|
||||||
|
void SetDesc(nsCSSFontDesc aDescID, nsCSSValue const & aValue);
|
||||||
|
void GetDesc(nsCSSFontDesc aDescID, nsCSSValue & aValue);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
friend class nsCSSFontFaceStyleDecl;
|
||||||
|
nsCSSFontFaceStyleDecl mDecl;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline nsCSSFontFaceRule*
|
||||||
|
nsCSSFontFaceStyleDecl::ContainingRule()
|
||||||
|
{
|
||||||
|
return reinterpret_cast<nsCSSFontFaceRule*>
|
||||||
|
(reinterpret_cast<char*>(this) - offsetof(nsCSSFontFaceRule, mDecl));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const nsCSSFontFaceRule*
|
||||||
|
nsCSSFontFaceStyleDecl::ContainingRule() const
|
||||||
|
{
|
||||||
|
return reinterpret_cast<const nsCSSFontFaceRule*>
|
||||||
|
(reinterpret_cast<const char*>(this) - offsetof(nsCSSFontFaceRule, mDecl));
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* !defined(nsCSSRules_h_) */
|
#endif /* !defined(nsCSSRules_h_) */
|
||||||
|
|
|
@ -80,8 +80,8 @@ nsCSSValue::nsCSSValue(float aValue, nsCSSUnit aUnit)
|
||||||
nsCSSValue::nsCSSValue(const nsString& aValue, nsCSSUnit aUnit)
|
nsCSSValue::nsCSSValue(const nsString& aValue, nsCSSUnit aUnit)
|
||||||
: mUnit(aUnit)
|
: mUnit(aUnit)
|
||||||
{
|
{
|
||||||
NS_ASSERTION((eCSSUnit_String <= aUnit) && (aUnit <= eCSSUnit_Attr), "not a string value");
|
NS_ASSERTION(UnitHasStringValue(), "not a string value");
|
||||||
if ((eCSSUnit_String <= aUnit) && (aUnit <= eCSSUnit_Attr)) {
|
if (UnitHasStringValue()) {
|
||||||
mValue.mString = BufferFromString(aValue);
|
mValue.mString = BufferFromString(aValue);
|
||||||
if (NS_UNLIKELY(!mValue.mString)) {
|
if (NS_UNLIKELY(!mValue.mString)) {
|
||||||
// XXXbz not much we can do here; just make sure that our promise of a
|
// XXXbz not much we can do here; just make sure that our promise of a
|
||||||
|
@ -133,7 +133,7 @@ nsCSSValue::nsCSSValue(const nsCSSValue& aCopy)
|
||||||
else if (eCSSUnit_Percent <= mUnit) {
|
else if (eCSSUnit_Percent <= mUnit) {
|
||||||
mValue.mFloat = aCopy.mValue.mFloat;
|
mValue.mFloat = aCopy.mValue.mFloat;
|
||||||
}
|
}
|
||||||
else if (eCSSUnit_String <= mUnit && mUnit <= eCSSUnit_Attr) {
|
else if (UnitHasStringValue()) {
|
||||||
mValue.mString = aCopy.mValue.mString;
|
mValue.mString = aCopy.mValue.mString;
|
||||||
mValue.mString->AddRef();
|
mValue.mString->AddRef();
|
||||||
}
|
}
|
||||||
|
@ -175,7 +175,7 @@ PRBool nsCSSValue::operator==(const nsCSSValue& aOther) const
|
||||||
if (mUnit <= eCSSUnit_Dummy) {
|
if (mUnit <= eCSSUnit_Dummy) {
|
||||||
return PR_TRUE;
|
return PR_TRUE;
|
||||||
}
|
}
|
||||||
else if ((eCSSUnit_String <= mUnit) && (mUnit <= eCSSUnit_Attr)) {
|
else if (UnitHasStringValue()) {
|
||||||
return (NS_strcmp(GetBufferValue(mValue.mString),
|
return (NS_strcmp(GetBufferValue(mValue.mString),
|
||||||
GetBufferValue(aOther.mValue.mString)) == 0);
|
GetBufferValue(aOther.mValue.mString)) == 0);
|
||||||
}
|
}
|
||||||
|
@ -247,7 +247,7 @@ nscoord nsCSSValue::GetLengthTwips() const
|
||||||
|
|
||||||
void nsCSSValue::DoReset()
|
void nsCSSValue::DoReset()
|
||||||
{
|
{
|
||||||
if (eCSSUnit_String <= mUnit && mUnit <= eCSSUnit_Attr) {
|
if (UnitHasStringValue()) {
|
||||||
mValue.mString->Release();
|
mValue.mString->Release();
|
||||||
} else if (eCSSUnit_Array <= mUnit && mUnit <= eCSSUnit_Counters) {
|
} else if (eCSSUnit_Array <= mUnit && mUnit <= eCSSUnit_Counters) {
|
||||||
mValue.mArray->Release();
|
mValue.mArray->Release();
|
||||||
|
@ -291,17 +291,18 @@ void nsCSSValue::SetFloatValue(float aValue, nsCSSUnit aUnit)
|
||||||
void nsCSSValue::SetStringValue(const nsString& aValue,
|
void nsCSSValue::SetStringValue(const nsString& aValue,
|
||||||
nsCSSUnit aUnit)
|
nsCSSUnit aUnit)
|
||||||
{
|
{
|
||||||
NS_ASSERTION((eCSSUnit_String <= aUnit) && (aUnit <= eCSSUnit_Attr), "not a string unit");
|
|
||||||
Reset();
|
Reset();
|
||||||
if ((eCSSUnit_String <= aUnit) && (aUnit <= eCSSUnit_Attr)) {
|
|
||||||
mUnit = aUnit;
|
mUnit = aUnit;
|
||||||
|
NS_ASSERTION(UnitHasStringValue(), "not a string unit");
|
||||||
|
if (UnitHasStringValue()) {
|
||||||
mValue.mString = BufferFromString(aValue);
|
mValue.mString = BufferFromString(aValue);
|
||||||
if (NS_UNLIKELY(!mValue.mString)) {
|
if (NS_UNLIKELY(!mValue.mString)) {
|
||||||
// XXXbz not much we can do here; just make sure that our promise of a
|
// XXXbz not much we can do here; just make sure that our promise of a
|
||||||
// non-null mValue.mString holds for string units.
|
// non-null mValue.mString holds for string units.
|
||||||
mUnit = eCSSUnit_Null;
|
mUnit = eCSSUnit_Null;
|
||||||
}
|
}
|
||||||
}
|
} else
|
||||||
|
mUnit = eCSSUnit_Null;
|
||||||
}
|
}
|
||||||
|
|
||||||
void nsCSSValue::SetColorValue(nscolor aValue)
|
void nsCSSValue::SetColorValue(nscolor aValue)
|
||||||
|
|
|
@ -66,6 +66,8 @@ enum nsCSSUnit {
|
||||||
// only in temporary values
|
// only in temporary values
|
||||||
eCSSUnit_String = 10, // (PRUnichar*) a string value
|
eCSSUnit_String = 10, // (PRUnichar*) a string value
|
||||||
eCSSUnit_Attr = 11, // (PRUnichar*) a attr(string) value
|
eCSSUnit_Attr = 11, // (PRUnichar*) a attr(string) value
|
||||||
|
eCSSUnit_Local_Font = 12, // (PRUnichar*) a local font name
|
||||||
|
eCSSUnit_Font_Format = 13, // (PRUnichar*) a font format name
|
||||||
eCSSUnit_Array = 20, // (nsCSSValue::Array*) a list of values
|
eCSSUnit_Array = 20, // (nsCSSValue::Array*) a list of values
|
||||||
eCSSUnit_Counter = 21, // (nsCSSValue::Array*) a counter(string,[string]) value
|
eCSSUnit_Counter = 21, // (nsCSSValue::Array*) a counter(string,[string]) value
|
||||||
eCSSUnit_Counters = 22, // (nsCSSValue::Array*) a counters(string,string[,string]) value
|
eCSSUnit_Counters = 22, // (nsCSSValue::Array*) a counters(string,string[,string]) value
|
||||||
|
@ -161,17 +163,20 @@ public:
|
||||||
|
|
||||||
nsCSSUnit GetUnit() const { return mUnit; }
|
nsCSSUnit GetUnit() const { return mUnit; }
|
||||||
PRBool IsLengthUnit() const
|
PRBool IsLengthUnit() const
|
||||||
{ return PRBool((eCSSUnit_Inch <= mUnit) && (mUnit <= eCSSUnit_Pixel)); }
|
{ return eCSSUnit_Inch <= mUnit && mUnit <= eCSSUnit_Pixel; }
|
||||||
PRBool IsFixedLengthUnit() const
|
PRBool IsFixedLengthUnit() const
|
||||||
{ return PRBool((eCSSUnit_Inch <= mUnit) && (mUnit <= eCSSUnit_Cicero)); }
|
{ return eCSSUnit_Inch <= mUnit && mUnit <= eCSSUnit_Cicero; }
|
||||||
PRBool IsRelativeLengthUnit() const
|
PRBool IsRelativeLengthUnit() const
|
||||||
{ return PRBool((eCSSUnit_EM <= mUnit) && (mUnit <= eCSSUnit_Pixel)); }
|
{ return eCSSUnit_EM <= mUnit && mUnit <= eCSSUnit_Pixel; }
|
||||||
PRBool IsAngularUnit() const
|
PRBool IsAngularUnit() const
|
||||||
{ return PRBool((eCSSUnit_Degree <= mUnit) && (mUnit <= eCSSUnit_Radian)); }
|
{ return eCSSUnit_Degree <= mUnit && mUnit <= eCSSUnit_Radian; }
|
||||||
PRBool IsFrequencyUnit() const
|
PRBool IsFrequencyUnit() const
|
||||||
{ return PRBool((eCSSUnit_Hertz <= mUnit) && (mUnit <= eCSSUnit_Kilohertz)); }
|
{ return eCSSUnit_Hertz <= mUnit && mUnit <= eCSSUnit_Kilohertz; }
|
||||||
PRBool IsTimeUnit() const
|
PRBool IsTimeUnit() const
|
||||||
{ return PRBool((eCSSUnit_Seconds <= mUnit) && (mUnit <= eCSSUnit_Milliseconds)); }
|
{ return eCSSUnit_Seconds <= mUnit && mUnit <= eCSSUnit_Milliseconds; }
|
||||||
|
|
||||||
|
PRBool UnitHasStringValue() const
|
||||||
|
{ return eCSSUnit_String <= mUnit && mUnit <= eCSSUnit_Font_Format; }
|
||||||
|
|
||||||
PRInt32 GetIntValue() const
|
PRInt32 GetIntValue() const
|
||||||
{
|
{
|
||||||
|
@ -195,8 +200,7 @@ public:
|
||||||
|
|
||||||
nsAString& GetStringValue(nsAString& aBuffer) const
|
nsAString& GetStringValue(nsAString& aBuffer) const
|
||||||
{
|
{
|
||||||
NS_ASSERTION(eCSSUnit_String <= mUnit && mUnit <= eCSSUnit_Attr,
|
NS_ASSERTION(UnitHasStringValue(), "not a string value");
|
||||||
"not a string value");
|
|
||||||
aBuffer.Truncate();
|
aBuffer.Truncate();
|
||||||
PRUint32 len = NS_strlen(GetBufferValue(mValue.mString));
|
PRUint32 len = NS_strlen(GetBufferValue(mValue.mString));
|
||||||
mValue.mString->ToString(len, aBuffer);
|
mValue.mString->ToString(len, aBuffer);
|
||||||
|
@ -205,8 +209,7 @@ public:
|
||||||
|
|
||||||
const PRUnichar* GetStringBufferValue() const
|
const PRUnichar* GetStringBufferValue() const
|
||||||
{
|
{
|
||||||
NS_ASSERTION(eCSSUnit_String <= mUnit && mUnit <= eCSSUnit_Attr,
|
NS_ASSERTION(UnitHasStringValue(), "not a string value");
|
||||||
"not a string value");
|
|
||||||
return GetBufferValue(mValue.mString);
|
return GetBufferValue(mValue.mString);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -99,6 +99,7 @@ _TEST_FILES = test_acid3_test46.html \
|
||||||
test_compute_data_with_start_struct.html \
|
test_compute_data_with_start_struct.html \
|
||||||
test_css_eof_handling.html \
|
test_css_eof_handling.html \
|
||||||
test_dont_use_document_colors.html \
|
test_dont_use_document_colors.html \
|
||||||
|
test_font_face_parser.html \
|
||||||
test_inherit_computation.html \
|
test_inherit_computation.html \
|
||||||
test_inherit_storage.html \
|
test_inherit_storage.html \
|
||||||
test_initial_computation.html \
|
test_initial_computation.html \
|
||||||
|
|
|
@ -0,0 +1,206 @@
|
||||||
|
<!DOCTYPE HTML><html>
|
||||||
|
<!-- https://bugzilla.mozilla.org/show_bug.cgi?id=441469 -->
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="content-type" content="text/html; charset=utf-8">
|
||||||
|
<title>Test of @font-face parser</title>
|
||||||
|
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
|
||||||
|
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||||
|
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<p>@font-face parsing (<a
|
||||||
|
target="_blank"
|
||||||
|
href="https://bugzilla.mozilla.org/show_bug.cgi?id=441469"
|
||||||
|
>bug 441469</a>)</p>
|
||||||
|
<pre id="display"></pre>
|
||||||
|
<style type="text/css" id="testbox"></style>
|
||||||
|
<script class="testbody" type="text/javascript">
|
||||||
|
function _(b) { return "@font-face { " + b + " }"; };
|
||||||
|
var testset = [
|
||||||
|
// Complete nonsense - shouldn't make a font-face rule at all.
|
||||||
|
{ rule: "@font-face;" },
|
||||||
|
{ rule: "font-face { }" },
|
||||||
|
{ rule: "@fontface { }" },
|
||||||
|
{ rule: "@namespace foo url(http://example.com/foo);" },
|
||||||
|
|
||||||
|
// Empty rule.
|
||||||
|
{ rule: "@font-face { }", d: {} },
|
||||||
|
{ rule: "@font-face {", d: {} },
|
||||||
|
{ rule: "@font-face { ; }", d: {}, noncanonical: true },
|
||||||
|
|
||||||
|
// Correct font-family.
|
||||||
|
{ rule: _("font-family: \"Mouse\";"), d: {"font-family" : "\"Mouse\""} },
|
||||||
|
{ rule: _("font-family: \"Mouse\""), d: {"font-family" : "\"Mouse\""},
|
||||||
|
noncanonical: true },
|
||||||
|
{ rule: _("font-family: Mouse;"), d: {"font-family" : "\"Mouse\"" },
|
||||||
|
noncanonical: true },
|
||||||
|
{ rule: _("font-family: Mouse"), d: {"font-family" : "\"Mouse\"" },
|
||||||
|
noncanonical: true },
|
||||||
|
|
||||||
|
// Correct but unusual font-family.
|
||||||
|
{ rule: _("font-family: Hoefler Text;"),
|
||||||
|
d: {"font-family" : "\"Hoefler Text\""},
|
||||||
|
noncanonical: true },
|
||||||
|
|
||||||
|
// Incorrect font-family.
|
||||||
|
{ rule: _("font-family:"), d: {} },
|
||||||
|
{ rule: _("font-family \"Mouse\""), d: {} },
|
||||||
|
{ rule: _("font-family: *"), d: {} },
|
||||||
|
{ rule: _("font-family: Mouse, Rat"), d: {} },
|
||||||
|
{ rule: _("font-family: sans-serif"), d: {} },
|
||||||
|
|
||||||
|
// Correct font-style.
|
||||||
|
{ rule: _("font-style: normal;"), d: {"font-style" : "normal"} },
|
||||||
|
{ rule: _("font-style: italic;"), d: {"font-style" : "italic"} },
|
||||||
|
{ rule: _("font-style: oblique;"), d: {"font-style" : "oblique"} },
|
||||||
|
|
||||||
|
// Correct font-weight.
|
||||||
|
{ rule: _("font-weight: 100;"), d: {"font-weight" : "100"} },
|
||||||
|
{ rule: _("font-weight: 200;"), d: {"font-weight" : "200"} },
|
||||||
|
{ rule: _("font-weight: 300;"), d: {"font-weight" : "300"} },
|
||||||
|
{ rule: _("font-weight: 400;"), d: {"font-weight" : "400"} },
|
||||||
|
{ rule: _("font-weight: 500;"), d: {"font-weight" : "500"} },
|
||||||
|
{ rule: _("font-weight: 600;"), d: {"font-weight" : "600"} },
|
||||||
|
{ rule: _("font-weight: 700;"), d: {"font-weight" : "700"} },
|
||||||
|
{ rule: _("font-weight: 800;"), d: {"font-weight" : "800"} },
|
||||||
|
{ rule: _("font-weight: 900;"), d: {"font-weight" : "900"} },
|
||||||
|
{ rule: _("font-weight: normal;"), d: {"font-weight" : "normal"} },
|
||||||
|
{ rule: _("font-weight: bold;"), d: {"font-weight" : "bold"} },
|
||||||
|
|
||||||
|
// Incorrect font-weight.
|
||||||
|
{ rule: _("font-weight: bolder;"), d: {} },
|
||||||
|
{ rule: _("font-weight: lighter;"), d: {} },
|
||||||
|
|
||||||
|
// Correct font-stretch.
|
||||||
|
{ rule: _("font-stretch: ultra-condensed;"),
|
||||||
|
d: {"font-stretch" : "ultra-condensed"} },
|
||||||
|
{ rule: _("font-stretch: extra-condensed;"),
|
||||||
|
d: {"font-stretch" : "extra-condensed"} },
|
||||||
|
{ rule: _("font-stretch: condensed;"),
|
||||||
|
d: {"font-stretch" : "condensed"} },
|
||||||
|
{ rule: _("font-stretch: semi-condensed;"),
|
||||||
|
d: {"font-stretch" : "semi-condensed"} },
|
||||||
|
{ rule: _("font-stretch: normal;"),
|
||||||
|
d: {"font-stretch" : "normal"} },
|
||||||
|
{ rule: _("font-stretch: semi-expanded;"),
|
||||||
|
d: {"font-stretch" : "semi-expanded"} },
|
||||||
|
{ rule: _("font-stretch: expanded;"),
|
||||||
|
d: {"font-stretch" : "expanded"} },
|
||||||
|
{ rule: _("font-stretch: extra-expanded;"),
|
||||||
|
d: {"font-stretch" : "extra-expanded"} },
|
||||||
|
{ rule: _("font-stretch: ultra-expanded;"),
|
||||||
|
d: {"font-stretch" : "ultra-expanded"} },
|
||||||
|
|
||||||
|
// Incorrect font-stretch.
|
||||||
|
{ rule: _("font-stretch: wider;"), d: {} },
|
||||||
|
{ rule: _("font-stretch: narrower;"), d: {} },
|
||||||
|
|
||||||
|
// Correct src:
|
||||||
|
{ rule: _("src: url(\"/fonts/Mouse\");"),
|
||||||
|
d: { "src" : "url(\"/fonts/Mouse\")" } },
|
||||||
|
{ rule: _("src: url(/fonts/Mouse);"),
|
||||||
|
d: { "src" : "url(\"/fonts/Mouse\")" }, noncanonical: true },
|
||||||
|
|
||||||
|
{ rule: _("src: url(\"/fonts/Mouse\") format(\"truetype\");"),
|
||||||
|
d: { "src" : "url(\"/fonts/Mouse\") format(\"truetype\")" } },
|
||||||
|
{ rule: _("src: url(\"/fonts/Mouse\") format(\"truetype\", \"opentype\");"),
|
||||||
|
d: { "src" : "url(\"/fonts/Mouse\") format(\"truetype\", \"opentype\")" } },
|
||||||
|
|
||||||
|
{ rule: _("src: url(\"/fonts/Mouse\"), url(\"/fonts/Rat\");"),
|
||||||
|
d: { "src" : "url(\"/fonts/Mouse\"), url(\"/fonts/Rat\")" } },
|
||||||
|
|
||||||
|
{ rule: _("src: local(Mouse), url(\"/fonts/Mouse\");"),
|
||||||
|
d: { "src" : "local(\"Mouse\"), url(\"/fonts/Mouse\")" },
|
||||||
|
noncanonical: true },
|
||||||
|
|
||||||
|
{ rule: _("src: local(\"老鼠\"), url(\"/fonts/Mouse\");"),
|
||||||
|
d: { "src" : "local(\"老鼠\"), url(\"/fonts/Mouse\")" } },
|
||||||
|
|
||||||
|
{ rule: _("src: local(\"老鼠\"), url(\"/fonts/Mouse\") format(\"truetype\");"),
|
||||||
|
d: { "src" : "local(\"老鼠\"), url(\"/fonts/Mouse\") format(\"truetype\")" } },
|
||||||
|
|
||||||
|
// Correct but unusual src:
|
||||||
|
{ rule: _("src: local(Hoefler Text);"),
|
||||||
|
d: {"src" : "local(\"Hoefler Text\")"}, noncanonical: true },
|
||||||
|
|
||||||
|
// Incorrect src:
|
||||||
|
{ rule: _("src: \"/fonts/Mouse\";"), d: {} },
|
||||||
|
{ rule: _("src: /fonts/Mouse;"), d: {} },
|
||||||
|
{ rule: _("src: url(\"/fonts/Mouse\") format(truetype);"), d: {} },
|
||||||
|
{ rule: _("src: url(\"/fonts/Mouse\") format(\"truetype\",opentype);"), d: {} },
|
||||||
|
{ rule: _("src: local(*);"), d: {} },
|
||||||
|
{ rule: _("src: format(\"truetype\");"), d: {} },
|
||||||
|
{ rule: _("src: local(Mouse) format(\"truetype\");"), d: {} },
|
||||||
|
{ rule: _("src: local(Mouse, Rat);"), d: {} },
|
||||||
|
{ rule: _("src: local(sans-serif);"), d: {} }
|
||||||
|
|
||||||
|
// unicode-range is not implemented (bug 443976).
|
||||||
|
// tests for that omitted for now.
|
||||||
|
];
|
||||||
|
|
||||||
|
var display = document.getElementById("display");
|
||||||
|
var sheet = document.styleSheets[1];
|
||||||
|
|
||||||
|
for (var curTest = 0; curTest < testset.length; curTest++) {
|
||||||
|
try {
|
||||||
|
while(sheet.cssRules.length > 0)
|
||||||
|
sheet.deleteRule(0);
|
||||||
|
sheet.insertRule(testset[curTest].rule, 0);
|
||||||
|
} catch (e if e instanceof DOMException) {
|
||||||
|
ok(e.code == DOMException.SYNTAX_ERR
|
||||||
|
&& !('d' in testset[curTest]),
|
||||||
|
testset[curTest].rule + " syntax error thrown", e);
|
||||||
|
} catch (e) {
|
||||||
|
ok(false, testset[curTest].rule, "During prep: " + e);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (testset[curTest].d) {
|
||||||
|
is(sheet.cssRules.length, 1,
|
||||||
|
testset[curTest].rule + " rule count");
|
||||||
|
is(sheet.cssRules[0].type, 5 /*FONT_FACE_RULE*/,
|
||||||
|
testset[curTest].rule + " rule type");
|
||||||
|
|
||||||
|
var d = testset[curTest].d;
|
||||||
|
var s = sheet.cssRules[0].style;
|
||||||
|
var n = 0;
|
||||||
|
|
||||||
|
// everything is set that should be
|
||||||
|
for (var name in d) {
|
||||||
|
is(s.getPropertyValue(name), d[name],
|
||||||
|
testset[curTest].rule + " (prop " + name + ")");
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
// nothing else is set
|
||||||
|
is(s.length, n, testset[curTest].rule + "prop count");
|
||||||
|
for (var i = 0; i < s.length; i++) {
|
||||||
|
ok(s[i] in d, testset[curTest].rule,
|
||||||
|
"Unexpected item #" + i + ": " + s[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// round-tripping of cssText
|
||||||
|
// this is a strong test; it's okay if the exact serialization
|
||||||
|
// changes in the future
|
||||||
|
if (n && !testset[curTest].noncanonical) {
|
||||||
|
is(sheet.cssRules[0].cssText.replace(/[ \n]+/g, " "),
|
||||||
|
testset[curTest].rule,
|
||||||
|
testset[curTest].rule + " rule text");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (sheet.cssRules.length == 0) {
|
||||||
|
is(sheet.cssRules.length, 0,
|
||||||
|
testset[curTest].rule + " rule count (0)");
|
||||||
|
} else {
|
||||||
|
is(sheet.cssRules.length, 1,
|
||||||
|
testset[curTest].rule + " rule count (1 non-fontface)");
|
||||||
|
isnot(sheet.cssRules[0].type, 5 /*FONT_FACE_RULE*/,
|
||||||
|
testset[curTest].rule + " rule type (1 non-fontface)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
ok(false, testset[curTest].rule, "During test: " + e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
Загрузка…
Ссылка в новой задаче