mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-08 19:04:45 +00:00
Merge three changesets from Zack Weinberg <zweinberg@mozilla.com>.
This commit is contained in:
commit
36fa7ce69d
File diff suppressed because it is too large
Load Diff
@ -61,14 +61,14 @@
|
||||
#undef COLLECT_WHITESPACE
|
||||
|
||||
static const PRUnichar CSS_ESCAPE = PRUnichar('\\');
|
||||
const PRUint8 nsCSSScanner::IS_DIGIT = 0x01;
|
||||
const PRUint8 nsCSSScanner::IS_HEX_DIGIT = 0x02;
|
||||
const PRUint8 nsCSSScanner::START_IDENT = 0x04;
|
||||
const PRUint8 nsCSSScanner::IS_IDENT = 0x08;
|
||||
const PRUint8 nsCSSScanner::IS_WHITESPACE = 0x10;
|
||||
static const PRUint8 IS_DIGIT = 0x01;
|
||||
static const PRUint8 IS_HEX_DIGIT = 0x02;
|
||||
static const PRUint8 START_IDENT = 0x04;
|
||||
static const PRUint8 IS_IDENT = 0x08;
|
||||
static const PRUint8 IS_WHITESPACE = 0x10;
|
||||
|
||||
static PRBool gLexTableSetup = PR_FALSE;
|
||||
PRUint8 nsCSSScanner::gLexTable[256];
|
||||
static PRUint8 gLexTable[256];
|
||||
|
||||
#ifdef CSS_REPORT_PARSE_ERRORS
|
||||
static PRBool gReportErrors = PR_TRUE;
|
||||
@ -77,9 +77,8 @@ static nsIFactory *gScriptErrorFactory;
|
||||
static nsIStringBundle *gStringBundle;
|
||||
#endif
|
||||
|
||||
/* static */
|
||||
void
|
||||
nsCSSScanner::BuildLexTable()
|
||||
static void
|
||||
BuildLexTable()
|
||||
{
|
||||
gLexTableSetup = PR_TRUE;
|
||||
|
||||
@ -109,6 +108,40 @@ nsCSSScanner::BuildLexTable()
|
||||
}
|
||||
}
|
||||
|
||||
static inline PRBool
|
||||
IsIdentStart(PRInt32 aChar)
|
||||
{
|
||||
return aChar >= 0 &&
|
||||
(aChar >= 256 || (gLexTable[aChar] & START_IDENT) != 0);
|
||||
}
|
||||
|
||||
static inline PRBool
|
||||
StartsIdent(PRInt32 aFirstChar, PRInt32 aSecondChar)
|
||||
{
|
||||
return IsIdentStart(aFirstChar) ||
|
||||
(aFirstChar == '-' && IsIdentStart(aSecondChar));
|
||||
}
|
||||
|
||||
static inline PRBool
|
||||
IsWhitespace(PRInt32 ch) {
|
||||
return PRUint32(ch) < 256 && (gLexTable[ch] & IS_WHITESPACE) != 0;
|
||||
}
|
||||
|
||||
static inline PRBool
|
||||
IsDigit(PRInt32 ch) {
|
||||
return PRUint32(ch) < 256 && (gLexTable[ch] & IS_DIGIT) != 0;
|
||||
}
|
||||
|
||||
static inline PRBool
|
||||
IsHexDigit(PRInt32 ch) {
|
||||
return PRUint32(ch) < 256 && (gLexTable[ch] & IS_HEX_DIGIT) != 0;
|
||||
}
|
||||
|
||||
static inline PRBool
|
||||
IsIdent(PRInt32 ch) {
|
||||
return ch >= 0 && (ch >= 256 || (gLexTable[ch] & IS_IDENT) != 0);
|
||||
}
|
||||
|
||||
nsCSSToken::nsCSSToken()
|
||||
{
|
||||
mType = eCSSToken_Symbol;
|
||||
@ -189,6 +222,7 @@ nsCSSToken::AppendToString(nsString& aBuffer)
|
||||
nsCSSScanner::nsCSSScanner()
|
||||
: mInputStream(nsnull)
|
||||
, mReadPointer(nsnull)
|
||||
, mLowLevelError(NS_OK)
|
||||
#ifdef MOZ_SVG
|
||||
, mSVGMode(PR_FALSE)
|
||||
#endif
|
||||
@ -217,17 +251,33 @@ nsCSSScanner::~nsCSSScanner()
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsCSSScanner::GetLowLevelError()
|
||||
{
|
||||
return mLowLevelError;
|
||||
}
|
||||
|
||||
void
|
||||
nsCSSScanner::SetLowLevelError(nsresult aErrorCode)
|
||||
{
|
||||
NS_ASSERTION(aErrorCode != NS_OK, "SetLowLevelError() used to clear error");
|
||||
NS_ASSERTION(mLowLevelError == NS_OK, "there is already a low-level error");
|
||||
mLowLevelError = aErrorCode;
|
||||
}
|
||||
|
||||
#ifdef CSS_REPORT_PARSE_ERRORS
|
||||
#define CSS_ERRORS_PREF "layout.css.report_errors"
|
||||
|
||||
PR_STATIC_CALLBACK(int) CSSErrorsPrefChanged(const char *aPref, void *aClosure)
|
||||
PR_STATIC_CALLBACK(int)
|
||||
CSSErrorsPrefChanged(const char *aPref, void *aClosure)
|
||||
{
|
||||
gReportErrors = nsContentUtils::GetBoolPref(CSS_ERRORS_PREF, PR_TRUE);
|
||||
return NS_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* static */ PRBool nsCSSScanner::InitGlobals()
|
||||
/* static */ PRBool
|
||||
nsCSSScanner::InitGlobals()
|
||||
{
|
||||
#ifdef CSS_REPORT_PARSE_ERRORS
|
||||
if (gConsoleService && gScriptErrorFactory)
|
||||
@ -247,7 +297,8 @@ PR_STATIC_CALLBACK(int) CSSErrorsPrefChanged(const char *aPref, void *aClosure)
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
/* static */ void nsCSSScanner::ReleaseGlobals()
|
||||
/* static */ void
|
||||
nsCSSScanner::ReleaseGlobals()
|
||||
{
|
||||
#ifdef CSS_REPORT_PARSE_ERRORS
|
||||
nsContentUtils::UnregisterPrefCallback(CSS_ERRORS_PREF, CSSErrorsPrefChanged, nsnull);
|
||||
@ -257,9 +308,10 @@ PR_STATIC_CALLBACK(int) CSSErrorsPrefChanged(const char *aPref, void *aClosure)
|
||||
#endif
|
||||
}
|
||||
|
||||
void nsCSSScanner::Init(nsIUnicharInputStream* aInput,
|
||||
const PRUnichar * aBuffer, PRUint32 aCount,
|
||||
nsIURI* aURI, PRUint32 aLineNumber)
|
||||
void
|
||||
nsCSSScanner::Init(nsIUnicharInputStream* aInput,
|
||||
const PRUnichar * aBuffer, PRUint32 aCount,
|
||||
nsIURI* aURI, PRUint32 aLineNumber)
|
||||
{
|
||||
NS_PRECONDITION(!mInputStream, "Should not have an existing input stream!");
|
||||
NS_PRECONDITION(!mReadPointer, "Should not have an existing input buffer!");
|
||||
@ -296,6 +348,7 @@ void nsCSSScanner::Init(nsIUnicharInputStream* aInput,
|
||||
// Reset variables that we use to keep track of our progress through the input
|
||||
mOffset = 0;
|
||||
mPushbackCount = 0;
|
||||
mLowLevelError = NS_OK;
|
||||
|
||||
#ifdef CSS_REPORT_PARSE_ERRORS
|
||||
mColNumber = 0;
|
||||
@ -308,7 +361,8 @@ void nsCSSScanner::Init(nsIUnicharInputStream* aInput,
|
||||
#define REPORT_UNEXPECTED_EOF(lf_) \
|
||||
ReportUnexpectedEOF(#lf_)
|
||||
|
||||
void nsCSSScanner::AddToError(const nsSubstring& aErrorText)
|
||||
void
|
||||
nsCSSScanner::AddToError(const nsSubstring& aErrorText)
|
||||
{
|
||||
if (mError.IsEmpty()) {
|
||||
mErrorLineNumber = mLineNumber;
|
||||
@ -319,12 +373,14 @@ void nsCSSScanner::AddToError(const nsSubstring& aErrorText)
|
||||
}
|
||||
}
|
||||
|
||||
void nsCSSScanner::ClearError()
|
||||
void
|
||||
nsCSSScanner::ClearError()
|
||||
{
|
||||
mError.Truncate();
|
||||
}
|
||||
|
||||
void nsCSSScanner::OutputError()
|
||||
void
|
||||
nsCSSScanner::OutputError()
|
||||
{
|
||||
if (mError.IsEmpty()) return;
|
||||
|
||||
@ -349,7 +405,8 @@ void nsCSSScanner::OutputError()
|
||||
ClearError();
|
||||
}
|
||||
|
||||
static PRBool InitStringBundle()
|
||||
static PRBool
|
||||
InitStringBundle()
|
||||
{
|
||||
if (gStringBundle)
|
||||
return PR_TRUE;
|
||||
@ -383,9 +440,10 @@ void nsCSSScanner::ReportUnexpected(const char* aMessage)
|
||||
AddToError(str);
|
||||
}
|
||||
|
||||
void nsCSSScanner::ReportUnexpectedParams(const char* aMessage,
|
||||
const PRUnichar **aParams,
|
||||
PRUint32 aParamsLength)
|
||||
void
|
||||
nsCSSScanner::ReportUnexpectedParams(const char* aMessage,
|
||||
const PRUnichar **aParams,
|
||||
PRUint32 aParamsLength)
|
||||
{
|
||||
NS_PRECONDITION(aParamsLength > 0, "use the non-params version");
|
||||
ENSURE_STRINGBUNDLE;
|
||||
@ -398,7 +456,8 @@ void nsCSSScanner::ReportUnexpectedParams(const char* aMessage,
|
||||
}
|
||||
|
||||
// aLookingFor is a plain string, not a format string
|
||||
void nsCSSScanner::ReportUnexpectedEOF(const char* aLookingFor)
|
||||
void
|
||||
nsCSSScanner::ReportUnexpectedEOF(const char* aLookingFor)
|
||||
{
|
||||
ENSURE_STRINGBUNDLE;
|
||||
|
||||
@ -417,7 +476,8 @@ void nsCSSScanner::ReportUnexpectedEOF(const char* aLookingFor)
|
||||
}
|
||||
|
||||
// aLookingFor is a single character
|
||||
void nsCSSScanner::ReportUnexpectedEOF(PRUnichar aLookingFor)
|
||||
void
|
||||
nsCSSScanner::ReportUnexpectedEOF(PRUnichar aLookingFor)
|
||||
{
|
||||
ENSURE_STRINGBUNDLE;
|
||||
|
||||
@ -434,8 +494,9 @@ void nsCSSScanner::ReportUnexpectedEOF(PRUnichar aLookingFor)
|
||||
|
||||
// aMessage must take 1 parameter (for the string representation of the
|
||||
// unexpected token)
|
||||
void nsCSSScanner::ReportUnexpectedToken(nsCSSToken& tok,
|
||||
const char *aMessage)
|
||||
void
|
||||
nsCSSScanner::ReportUnexpectedToken(nsCSSToken& tok,
|
||||
const char *aMessage)
|
||||
{
|
||||
ENSURE_STRINGBUNDLE;
|
||||
|
||||
@ -450,10 +511,11 @@ void nsCSSScanner::ReportUnexpectedToken(nsCSSToken& tok,
|
||||
}
|
||||
|
||||
// aParams's first entry must be null, and we'll fill in the token
|
||||
void nsCSSScanner::ReportUnexpectedTokenParams(nsCSSToken& tok,
|
||||
const char* aMessage,
|
||||
const PRUnichar **aParams,
|
||||
PRUint32 aParamsLength)
|
||||
void
|
||||
nsCSSScanner::ReportUnexpectedTokenParams(nsCSSToken& tok,
|
||||
const char* aMessage,
|
||||
const PRUnichar **aParams,
|
||||
PRUint32 aParamsLength)
|
||||
{
|
||||
NS_PRECONDITION(aParamsLength > 1, "use the non-params version");
|
||||
NS_PRECONDITION(aParams[0] == nsnull, "first param should be empty");
|
||||
@ -473,7 +535,8 @@ void nsCSSScanner::ReportUnexpectedTokenParams(nsCSSToken& tok,
|
||||
|
||||
#endif // CSS_REPORT_PARSE_ERRORS
|
||||
|
||||
void nsCSSScanner::Close()
|
||||
void
|
||||
nsCSSScanner::Close()
|
||||
{
|
||||
mInputStream = nsnull;
|
||||
mReadPointer = nsnull;
|
||||
@ -495,39 +558,43 @@ void nsCSSScanner::Close()
|
||||
#define TAB_STOP_WIDTH 8
|
||||
#endif
|
||||
|
||||
PRBool nsCSSScanner::EnsureData(nsresult& aErrorCode)
|
||||
PRBool
|
||||
nsCSSScanner::EnsureData()
|
||||
{
|
||||
if (mOffset < mCount)
|
||||
return PR_TRUE;
|
||||
|
||||
if (mInputStream) {
|
||||
mOffset = 0;
|
||||
aErrorCode = mInputStream->Read(mBuffer, CSS_BUFFER_SIZE, &mCount);
|
||||
if (NS_FAILED(aErrorCode) || mCount == 0) {
|
||||
mCount = 0;
|
||||
return PR_FALSE;
|
||||
}
|
||||
return PR_TRUE;
|
||||
if (!mInputStream)
|
||||
return PR_FALSE;
|
||||
|
||||
mOffset = 0;
|
||||
nsresult rv = mInputStream->Read(mBuffer, CSS_BUFFER_SIZE, &mCount);
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
mCount = 0;
|
||||
SetLowLevelError(rv);
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
return PR_FALSE;
|
||||
return mCount > 0;
|
||||
}
|
||||
|
||||
// Returns -1 on error or eof
|
||||
PRInt32 nsCSSScanner::Read(nsresult& aErrorCode)
|
||||
PRInt32
|
||||
nsCSSScanner::Read()
|
||||
{
|
||||
PRInt32 rv;
|
||||
if (0 < mPushbackCount) {
|
||||
rv = PRInt32(mPushback[--mPushbackCount]);
|
||||
} else {
|
||||
if (mOffset == mCount && !EnsureData(aErrorCode)) {
|
||||
if (mOffset == mCount && !EnsureData()) {
|
||||
return -1;
|
||||
}
|
||||
rv = PRInt32(mReadPointer[mOffset++]);
|
||||
// There are four types of newlines in CSS: "\r", "\n", "\r\n", and "\f".
|
||||
// To simplify dealing with newlines, they are all normalized to "\n" here
|
||||
if (rv == '\r') {
|
||||
if (EnsureData(aErrorCode) && mReadPointer[mOffset] == '\n') {
|
||||
if (EnsureData() && mReadPointer[mOffset] == '\n') {
|
||||
mOffset++;
|
||||
}
|
||||
rv = '\n';
|
||||
@ -555,10 +622,11 @@ PRInt32 nsCSSScanner::Read(nsresult& aErrorCode)
|
||||
return rv;
|
||||
}
|
||||
|
||||
PRInt32 nsCSSScanner::Peek(nsresult& aErrorCode)
|
||||
PRInt32
|
||||
nsCSSScanner::Peek()
|
||||
{
|
||||
if (0 == mPushbackCount) {
|
||||
PRInt32 ch = Read(aErrorCode);
|
||||
PRInt32 ch = Read();
|
||||
if (ch < 0) {
|
||||
return -1;
|
||||
}
|
||||
@ -569,7 +637,8 @@ PRInt32 nsCSSScanner::Peek(nsresult& aErrorCode)
|
||||
return PRInt32(mPushback[mPushbackCount - 1]);
|
||||
}
|
||||
|
||||
void nsCSSScanner::Pushback(PRUnichar aChar)
|
||||
void
|
||||
nsCSSScanner::Pushback(PRUnichar aChar)
|
||||
{
|
||||
if (mPushbackCount == mPushbackSize) { // grow buffer
|
||||
PRUnichar* newPushback = new PRUnichar[mPushbackSize + 4];
|
||||
@ -586,9 +655,10 @@ void nsCSSScanner::Pushback(PRUnichar aChar)
|
||||
mPushback[mPushbackCount++] = aChar;
|
||||
}
|
||||
|
||||
PRBool nsCSSScanner::LookAhead(nsresult& aErrorCode, PRUnichar aChar)
|
||||
PRBool
|
||||
nsCSSScanner::LookAhead(PRUnichar aChar)
|
||||
{
|
||||
PRInt32 ch = Read(aErrorCode);
|
||||
PRInt32 ch = Read();
|
||||
if (ch < 0) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
@ -599,11 +669,12 @@ PRBool nsCSSScanner::LookAhead(nsresult& aErrorCode, PRUnichar aChar)
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
PRBool nsCSSScanner::EatWhiteSpace(nsresult& aErrorCode)
|
||||
PRBool
|
||||
nsCSSScanner::EatWhiteSpace()
|
||||
{
|
||||
PRBool eaten = PR_FALSE;
|
||||
for (;;) {
|
||||
PRInt32 ch = Read(aErrorCode);
|
||||
PRInt32 ch = Read();
|
||||
if (ch < 0) {
|
||||
break;
|
||||
}
|
||||
@ -617,9 +688,10 @@ PRBool nsCSSScanner::EatWhiteSpace(nsresult& aErrorCode)
|
||||
return eaten;
|
||||
}
|
||||
|
||||
PRBool nsCSSScanner::EatNewline(nsresult& aErrorCode)
|
||||
PRBool
|
||||
nsCSSScanner::EatNewline()
|
||||
{
|
||||
PRInt32 ch = Read(aErrorCode);
|
||||
PRInt32 ch = Read();
|
||||
if (ch < 0) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
@ -632,67 +704,68 @@ PRBool nsCSSScanner::EatNewline(nsresult& aErrorCode)
|
||||
return eaten;
|
||||
}
|
||||
|
||||
PRBool nsCSSScanner::Next(nsresult& aErrorCode, nsCSSToken& aToken)
|
||||
PRBool
|
||||
nsCSSScanner::Next(nsCSSToken& aToken)
|
||||
{
|
||||
PRInt32 ch = Read(aErrorCode);
|
||||
PRInt32 ch = Read();
|
||||
if (ch < 0) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// IDENT
|
||||
if (StartsIdent(ch, Peek(aErrorCode)))
|
||||
return ParseIdent(aErrorCode, ch, aToken);
|
||||
if (StartsIdent(ch, Peek()))
|
||||
return ParseIdent(ch, aToken);
|
||||
|
||||
// AT_KEYWORD
|
||||
if (ch == '@') {
|
||||
PRInt32 nextChar = Read(aErrorCode);
|
||||
PRInt32 nextChar = Read();
|
||||
if (nextChar >= 0) {
|
||||
PRInt32 followingChar = Peek(aErrorCode);
|
||||
PRInt32 followingChar = Peek();
|
||||
Pushback(nextChar);
|
||||
if (StartsIdent(nextChar, followingChar))
|
||||
return ParseAtKeyword(aErrorCode, ch, aToken);
|
||||
return ParseAtKeyword(ch, aToken);
|
||||
}
|
||||
}
|
||||
|
||||
// NUMBER or DIM
|
||||
if ((ch == '.') || (ch == '+') || (ch == '-')) {
|
||||
PRInt32 nextChar = Peek(aErrorCode);
|
||||
PRInt32 nextChar = Peek();
|
||||
if (IsDigit(nextChar)) {
|
||||
return ParseNumber(aErrorCode, ch, aToken);
|
||||
return ParseNumber(ch, aToken);
|
||||
}
|
||||
else if (('.' == nextChar) && ('.' != ch)) {
|
||||
nextChar = Read(aErrorCode);
|
||||
PRInt32 followingChar = Peek(aErrorCode);
|
||||
nextChar = Read();
|
||||
PRInt32 followingChar = Peek();
|
||||
Pushback(nextChar);
|
||||
if (IsDigit(followingChar))
|
||||
return ParseNumber(aErrorCode, ch, aToken);
|
||||
return ParseNumber(ch, aToken);
|
||||
}
|
||||
}
|
||||
if (IsDigit(ch)) {
|
||||
return ParseNumber(aErrorCode, ch, aToken);
|
||||
return ParseNumber(ch, aToken);
|
||||
}
|
||||
|
||||
// ID
|
||||
if (ch == '#') {
|
||||
return ParseRef(aErrorCode, ch, aToken);
|
||||
return ParseRef(ch, aToken);
|
||||
}
|
||||
|
||||
// STRING
|
||||
if ((ch == '"') || (ch == '\'')) {
|
||||
return ParseString(aErrorCode, ch, aToken);
|
||||
return ParseString(ch, aToken);
|
||||
}
|
||||
|
||||
// WS
|
||||
if (IsWhitespace(ch)) {
|
||||
aToken.mType = eCSSToken_WhiteSpace;
|
||||
aToken.mIdent.Assign(PRUnichar(ch));
|
||||
(void) EatWhiteSpace(aErrorCode);
|
||||
(void) EatWhiteSpace();
|
||||
return PR_TRUE;
|
||||
}
|
||||
if (ch == '/') {
|
||||
PRInt32 nextChar = Peek(aErrorCode);
|
||||
PRInt32 nextChar = Peek();
|
||||
if (nextChar == '*') {
|
||||
(void) Read(aErrorCode);
|
||||
(void) Read();
|
||||
#if 0
|
||||
// If we change our storage data structures such that comments are
|
||||
// stored (for Editor), we should reenable this code, condition it
|
||||
@ -701,15 +774,15 @@ PRBool nsCSSScanner::Next(nsresult& aErrorCode, nsCSSToken& aToken)
|
||||
aToken.mIdent.SetCapacity(2);
|
||||
aToken.mIdent.Assign(PRUnichar(ch));
|
||||
aToken.mIdent.Append(PRUnichar(nextChar));
|
||||
return ParseCComment(aErrorCode, aToken);
|
||||
return ParseCComment(aToken);
|
||||
#endif
|
||||
return SkipCComment(aErrorCode) && Next(aErrorCode, aToken);
|
||||
return SkipCComment() && Next(aToken);
|
||||
}
|
||||
}
|
||||
if (ch == '<') { // consume HTML comment tags
|
||||
if (LookAhead(aErrorCode, '!')) {
|
||||
if (LookAhead(aErrorCode, '-')) {
|
||||
if (LookAhead(aErrorCode, '-')) {
|
||||
if (LookAhead('!')) {
|
||||
if (LookAhead('-')) {
|
||||
if (LookAhead('-')) {
|
||||
aToken.mType = eCSSToken_HTMLComment;
|
||||
aToken.mIdent.AssignLiteral("<!--");
|
||||
return PR_TRUE;
|
||||
@ -720,8 +793,8 @@ PRBool nsCSSScanner::Next(nsresult& aErrorCode, nsCSSToken& aToken)
|
||||
}
|
||||
}
|
||||
if (ch == '-') { // check for HTML comment end
|
||||
if (LookAhead(aErrorCode, '-')) {
|
||||
if (LookAhead(aErrorCode, '>')) {
|
||||
if (LookAhead('-')) {
|
||||
if (LookAhead('>')) {
|
||||
aToken.mType = eCSSToken_HTMLComment;
|
||||
aToken.mIdent.AssignLiteral("-->");
|
||||
return PR_TRUE;
|
||||
@ -733,7 +806,7 @@ PRBool nsCSSScanner::Next(nsresult& aErrorCode, nsCSSToken& aToken)
|
||||
// INCLUDES ("~=") and DASHMATCH ("|=")
|
||||
if (( ch == '|' ) || ( ch == '~' ) || ( ch == '^' ) ||
|
||||
( ch == '$' ) || ( ch == '*' )) {
|
||||
PRInt32 nextChar = Read(aErrorCode);
|
||||
PRInt32 nextChar = Read();
|
||||
if ( nextChar == '=' ) {
|
||||
if (ch == '~') {
|
||||
aToken.mType = eCSSToken_Includes;
|
||||
@ -760,29 +833,30 @@ PRBool nsCSSScanner::Next(nsresult& aErrorCode, nsCSSToken& aToken)
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
PRBool nsCSSScanner::NextURL(nsresult& aErrorCode, nsCSSToken& aToken)
|
||||
PRBool
|
||||
nsCSSScanner::NextURL(nsCSSToken& aToken)
|
||||
{
|
||||
PRInt32 ch = Read(aErrorCode);
|
||||
PRInt32 ch = Read();
|
||||
if (ch < 0) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// STRING
|
||||
if ((ch == '"') || (ch == '\'')) {
|
||||
return ParseString(aErrorCode, ch, aToken);
|
||||
return ParseString(ch, aToken);
|
||||
}
|
||||
|
||||
// WS
|
||||
if (IsWhitespace(ch)) {
|
||||
aToken.mType = eCSSToken_WhiteSpace;
|
||||
aToken.mIdent.Assign(PRUnichar(ch));
|
||||
(void) EatWhiteSpace(aErrorCode);
|
||||
(void) EatWhiteSpace();
|
||||
return PR_TRUE;
|
||||
}
|
||||
if (ch == '/') {
|
||||
PRInt32 nextChar = Peek(aErrorCode);
|
||||
PRInt32 nextChar = Peek();
|
||||
if (nextChar == '*') {
|
||||
(void) Read(aErrorCode);
|
||||
(void) Read();
|
||||
#if 0
|
||||
// If we change our storage data structures such that comments are
|
||||
// stored (for Editor), we should reenable this code, condition it
|
||||
@ -791,9 +865,9 @@ PRBool nsCSSScanner::NextURL(nsresult& aErrorCode, nsCSSToken& aToken)
|
||||
aToken.mIdent.SetCapacity(2);
|
||||
aToken.mIdent.Assign(PRUnichar(ch));
|
||||
aToken.mIdent.Append(PRUnichar(nextChar));
|
||||
return ParseCComment(aErrorCode, aToken);
|
||||
return ParseCComment(aToken);
|
||||
#endif
|
||||
return SkipCComment(aErrorCode) && Next(aErrorCode, aToken);
|
||||
return SkipCComment() && Next(aToken);
|
||||
}
|
||||
}
|
||||
|
||||
@ -819,17 +893,17 @@ PRBool nsCSSScanner::NextURL(nsresult& aErrorCode, nsCSSToken& aToken)
|
||||
Pushback(ch);
|
||||
PRBool ok = PR_TRUE;
|
||||
for (;;) {
|
||||
ch = Read(aErrorCode);
|
||||
ch = Read();
|
||||
if (ch < 0) break;
|
||||
if (ch == CSS_ESCAPE) {
|
||||
ParseAndAppendEscape(aErrorCode, ident);
|
||||
ParseAndAppendEscape(ident);
|
||||
} else if ((ch == '"') || (ch == '\'') || (ch == '(')) {
|
||||
// This is an invalid URL spec
|
||||
ok = PR_FALSE;
|
||||
} else if (IsWhitespace(ch)) {
|
||||
// Whitespace is allowed at the end of the URL
|
||||
(void) EatWhiteSpace(aErrorCode);
|
||||
if (LookAhead(aErrorCode, ')')) {
|
||||
(void) EatWhiteSpace();
|
||||
if (LookAhead(')')) {
|
||||
Pushback(')'); // leave the closing symbol
|
||||
// done!
|
||||
break;
|
||||
@ -858,9 +932,9 @@ PRBool nsCSSScanner::NextURL(nsresult& aErrorCode, nsCSSToken& aToken)
|
||||
|
||||
|
||||
void
|
||||
nsCSSScanner::ParseAndAppendEscape(nsresult& aErrorCode, nsString& aOutput)
|
||||
nsCSSScanner::ParseAndAppendEscape(nsString& aOutput)
|
||||
{
|
||||
PRInt32 ch = Peek(aErrorCode);
|
||||
PRInt32 ch = Peek();
|
||||
if (ch < 0) {
|
||||
aOutput.Append(CSS_ESCAPE);
|
||||
return;
|
||||
@ -869,7 +943,7 @@ nsCSSScanner::ParseAndAppendEscape(nsresult& aErrorCode, nsString& aOutput)
|
||||
PRInt32 rv = 0;
|
||||
int i;
|
||||
for (i = 0; i < 6; i++) { // up to six digits
|
||||
ch = Read(aErrorCode);
|
||||
ch = Read();
|
||||
if (ch < 0) {
|
||||
// Whoops: error or premature eof
|
||||
break;
|
||||
@ -893,9 +967,9 @@ nsCSSScanner::ParseAndAppendEscape(nsresult& aErrorCode, nsString& aOutput)
|
||||
}
|
||||
}
|
||||
if (6 == i) { // look for trailing whitespace and eat it
|
||||
ch = Peek(aErrorCode);
|
||||
ch = Peek();
|
||||
if (IsWhitespace(ch)) {
|
||||
ch = Read(aErrorCode);
|
||||
ch = Read();
|
||||
}
|
||||
}
|
||||
NS_ASSERTION(rv >= 0, "How did rv become negative?");
|
||||
@ -907,8 +981,8 @@ nsCSSScanner::ParseAndAppendEscape(nsresult& aErrorCode, nsString& aOutput)
|
||||
// "Any character except a hexidecimal digit can be escaped to
|
||||
// remove its special meaning by putting a backslash in front"
|
||||
// -- CSS1 spec section 7.1
|
||||
if (!EatNewline(aErrorCode)) { // skip escaped newline
|
||||
(void) Read(aErrorCode);
|
||||
if (!EatNewline()) { // skip escaped newline
|
||||
(void) Read();
|
||||
if (ch > 0) {
|
||||
aOutput.Append(ch);
|
||||
}
|
||||
@ -924,18 +998,18 @@ nsCSSScanner::ParseAndAppendEscape(nsresult& aErrorCode, nsString& aOutput)
|
||||
* until the first non-identifier character is seen. The termination
|
||||
* character is unread for the future re-reading.
|
||||
*/
|
||||
PRBool nsCSSScanner::GatherIdent(nsresult& aErrorCode, PRInt32 aChar,
|
||||
nsString& aIdent)
|
||||
PRBool
|
||||
nsCSSScanner::GatherIdent(PRInt32 aChar, nsString& aIdent)
|
||||
{
|
||||
if (aChar == CSS_ESCAPE) {
|
||||
ParseAndAppendEscape(aErrorCode, aIdent);
|
||||
ParseAndAppendEscape(aIdent);
|
||||
}
|
||||
else if (0 < aChar) {
|
||||
aIdent.Append(aChar);
|
||||
}
|
||||
for (;;) {
|
||||
// If nothing in pushback, first try to get as much as possible in one go
|
||||
if (!mPushbackCount && EnsureData(aErrorCode)) {
|
||||
if (!mPushbackCount && EnsureData()) {
|
||||
// See how much we can consume and append in one go
|
||||
PRUint32 n = mOffset;
|
||||
// Count number of Ident characters that can be processed
|
||||
@ -952,10 +1026,10 @@ PRBool nsCSSScanner::GatherIdent(nsresult& aErrorCode, PRInt32 aChar,
|
||||
}
|
||||
}
|
||||
|
||||
aChar = Read(aErrorCode);
|
||||
aChar = Read();
|
||||
if (aChar < 0) break;
|
||||
if (aChar == CSS_ESCAPE) {
|
||||
ParseAndAppendEscape(aErrorCode, aIdent);
|
||||
ParseAndAppendEscape(aIdent);
|
||||
} else if (IsIdent(aChar)) {
|
||||
aIdent.Append(PRUnichar(aChar));
|
||||
} else {
|
||||
@ -966,23 +1040,22 @@ PRBool nsCSSScanner::GatherIdent(nsresult& aErrorCode, PRInt32 aChar,
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
PRBool nsCSSScanner::ParseRef(nsresult& aErrorCode,
|
||||
PRInt32 aChar,
|
||||
nsCSSToken& aToken)
|
||||
PRBool
|
||||
nsCSSScanner::ParseRef(PRInt32 aChar, nsCSSToken& aToken)
|
||||
{
|
||||
aToken.mIdent.SetLength(0);
|
||||
aToken.mType = eCSSToken_Ref;
|
||||
PRInt32 ch = Read(aErrorCode);
|
||||
PRInt32 ch = Read();
|
||||
if (ch < 0) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
if (IsIdent(ch) || ch == CSS_ESCAPE) {
|
||||
// First char after the '#' is a valid ident char (or an escape),
|
||||
// so it makes sense to keep going
|
||||
if (StartsIdent(ch, Peek(aErrorCode))) {
|
||||
if (StartsIdent(ch, Peek())) {
|
||||
aToken.mType = eCSSToken_ID;
|
||||
}
|
||||
return GatherIdent(aErrorCode, ch, aToken.mIdent);
|
||||
return GatherIdent(ch, aToken.mIdent);
|
||||
}
|
||||
|
||||
// No ident chars after the '#'. Just unread |ch| and get out of here.
|
||||
@ -990,19 +1063,18 @@ PRBool nsCSSScanner::ParseRef(nsresult& aErrorCode,
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
PRBool nsCSSScanner::ParseIdent(nsresult& aErrorCode,
|
||||
PRInt32 aChar,
|
||||
nsCSSToken& aToken)
|
||||
PRBool
|
||||
nsCSSScanner::ParseIdent(PRInt32 aChar, nsCSSToken& aToken)
|
||||
{
|
||||
nsString& ident = aToken.mIdent;
|
||||
ident.SetLength(0);
|
||||
if (!GatherIdent(aErrorCode, aChar, ident)) {
|
||||
if (!GatherIdent(aChar, ident)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
nsCSSTokenType tokenType = eCSSToken_Ident;
|
||||
// look for functions (ie: "ident(")
|
||||
if (PRUnichar('(') == PRUnichar(Peek(aErrorCode))) { // this is a function definition
|
||||
if (PRUnichar('(') == PRUnichar(Peek())) { // this is a function definition
|
||||
tokenType = eCSSToken_Function;
|
||||
}
|
||||
|
||||
@ -1010,16 +1082,16 @@ PRBool nsCSSScanner::ParseIdent(nsresult& aErrorCode,
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
PRBool nsCSSScanner::ParseAtKeyword(nsresult& aErrorCode, PRInt32 aChar,
|
||||
nsCSSToken& aToken)
|
||||
PRBool
|
||||
nsCSSScanner::ParseAtKeyword(PRInt32 aChar, nsCSSToken& aToken)
|
||||
{
|
||||
aToken.mIdent.SetLength(0);
|
||||
aToken.mType = eCSSToken_AtKeyword;
|
||||
return GatherIdent(aErrorCode, 0, aToken.mIdent);
|
||||
return GatherIdent(0, aToken.mIdent);
|
||||
}
|
||||
|
||||
PRBool nsCSSScanner::ParseNumber(nsresult& aErrorCode, PRInt32 c,
|
||||
nsCSSToken& aToken)
|
||||
PRBool
|
||||
nsCSSScanner::ParseNumber(PRInt32 c, nsCSSToken& aToken)
|
||||
{
|
||||
nsString& ident = aToken.mIdent;
|
||||
ident.SetLength(0);
|
||||
@ -1032,21 +1104,21 @@ PRBool nsCSSScanner::ParseNumber(nsresult& aErrorCode, PRInt32 c,
|
||||
// Gather up characters that make up the number
|
||||
PRBool gotE = PR_FALSE;
|
||||
for (;;) {
|
||||
c = Read(aErrorCode);
|
||||
c = Read();
|
||||
if (c < 0) break;
|
||||
if (!gotDot && !gotE && (c == '.') &&
|
||||
IsDigit(Peek(aErrorCode))) {
|
||||
IsDigit(Peek())) {
|
||||
gotDot = PR_TRUE;
|
||||
#ifdef MOZ_SVG
|
||||
} else if (!gotE && (c == 'e' || c == 'E')) {
|
||||
if (!IsSVGMode()) {
|
||||
break;
|
||||
}
|
||||
PRInt32 nextChar = Peek(aErrorCode);
|
||||
PRInt32 nextChar = Peek();
|
||||
PRInt32 sign = 0;
|
||||
if (nextChar == '-' || nextChar == '+') {
|
||||
sign = Read(aErrorCode);
|
||||
nextChar = Peek(aErrorCode);
|
||||
sign = Read();
|
||||
nextChar = Peek();
|
||||
}
|
||||
if (IsDigit(nextChar)) {
|
||||
gotE = PR_TRUE;
|
||||
@ -1083,8 +1155,8 @@ PRBool nsCSSScanner::ParseNumber(nsresult& aErrorCode, PRInt32 c,
|
||||
|
||||
// Look at character that terminated the number
|
||||
if (c >= 0) {
|
||||
if (StartsIdent(c, Peek(aErrorCode))) {
|
||||
if (!GatherIdent(aErrorCode, c, ident)) {
|
||||
if (StartsIdent(c, Peek())) {
|
||||
if (!GatherIdent(c, ident)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
type = eCSSToken_Dimension;
|
||||
@ -1102,13 +1174,14 @@ PRBool nsCSSScanner::ParseNumber(nsresult& aErrorCode, PRInt32 c,
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
PRBool nsCSSScanner::SkipCComment(nsresult& aErrorCode)
|
||||
PRBool
|
||||
nsCSSScanner::SkipCComment()
|
||||
{
|
||||
for (;;) {
|
||||
PRInt32 ch = Read(aErrorCode);
|
||||
PRInt32 ch = Read();
|
||||
if (ch < 0) break;
|
||||
if (ch == '*') {
|
||||
if (LookAhead(aErrorCode, '/')) {
|
||||
if (LookAhead('/')) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
@ -1119,14 +1192,15 @@ PRBool nsCSSScanner::SkipCComment(nsresult& aErrorCode)
|
||||
}
|
||||
|
||||
#if 0
|
||||
PRBool nsCSSScanner::ParseCComment(nsresult& aErrorCode, nsCSSToken& aToken)
|
||||
PRBool
|
||||
nsCSSScanner::ParseCComment(nsCSSToken& aToken)
|
||||
{
|
||||
nsString& ident = aToken.mIdent;
|
||||
for (;;) {
|
||||
PRInt32 ch = Read(aErrorCode);
|
||||
PRInt32 ch = Read();
|
||||
if (ch < 0) break;
|
||||
if (ch == '*') {
|
||||
if (LookAhead(aErrorCode, '/')) {
|
||||
if (LookAhead('/')) {
|
||||
ident.Append(PRUnichar(ch));
|
||||
ident.Append(PRUnichar('/'));
|
||||
break;
|
||||
@ -1142,15 +1216,16 @@ PRBool nsCSSScanner::ParseCComment(nsresult& aErrorCode, nsCSSToken& aToken)
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
PRBool nsCSSScanner::ParseEOLComment(nsresult& aErrorCode, nsCSSToken& aToken)
|
||||
PRBool
|
||||
nsCSSScanner::ParseEOLComment(nsCSSToken& aToken)
|
||||
{
|
||||
nsString& ident = aToken.mIdent;
|
||||
ident.SetLength(0);
|
||||
for (;;) {
|
||||
if (EatNewline(aErrorCode)) {
|
||||
if (EatNewline()) {
|
||||
break;
|
||||
}
|
||||
PRInt32 ch = Read(aErrorCode);
|
||||
PRInt32 ch = Read();
|
||||
if (ch < 0) {
|
||||
break;
|
||||
}
|
||||
@ -1163,15 +1238,15 @@ PRBool nsCSSScanner::ParseEOLComment(nsresult& aErrorCode, nsCSSToken& aToken)
|
||||
}
|
||||
#endif // 0
|
||||
|
||||
PRBool nsCSSScanner::ParseString(nsresult& aErrorCode, PRInt32 aStop,
|
||||
nsCSSToken& aToken)
|
||||
PRBool
|
||||
nsCSSScanner::ParseString(PRInt32 aStop, nsCSSToken& aToken)
|
||||
{
|
||||
aToken.mIdent.SetLength(0);
|
||||
aToken.mType = eCSSToken_String;
|
||||
aToken.mSymbol = PRUnichar(aStop); // remember how it's quoted
|
||||
for (;;) {
|
||||
// If nothing in pushback, first try to get as much as possible in one go
|
||||
if (!mPushbackCount && EnsureData(aErrorCode)) {
|
||||
if (!mPushbackCount && EnsureData()) {
|
||||
// See how much we can consume and append in one go
|
||||
PRUint32 n = mOffset;
|
||||
// Count number of characters that can be processed
|
||||
@ -1196,7 +1271,7 @@ PRBool nsCSSScanner::ParseString(nsresult& aErrorCode, PRInt32 aStop,
|
||||
mOffset = n;
|
||||
}
|
||||
}
|
||||
PRInt32 ch = Read(aErrorCode);
|
||||
PRInt32 ch = Read();
|
||||
if (ch < 0 || ch == aStop) {
|
||||
break;
|
||||
}
|
||||
@ -1208,7 +1283,7 @@ PRBool nsCSSScanner::ParseString(nsresult& aErrorCode, PRInt32 aStop,
|
||||
break;
|
||||
}
|
||||
if (ch == CSS_ESCAPE) {
|
||||
ParseAndAppendEscape(aErrorCode, aToken.mIdent);
|
||||
ParseAndAppendEscape(aToken.mIdent);
|
||||
} else {
|
||||
aToken.mIdent.Append(ch);
|
||||
}
|
||||
|
@ -188,10 +188,10 @@ class nsCSSScanner {
|
||||
|
||||
// Get the next token. Return PR_FALSE on EOF. aTokenResult
|
||||
// is filled in with the data for the token.
|
||||
PRBool Next(nsresult& aErrorCode, nsCSSToken& aTokenResult);
|
||||
PRBool Next(nsCSSToken& aTokenResult);
|
||||
|
||||
// Get the next token that may be a string or unquoted URL or whitespace
|
||||
PRBool NextURL(nsresult& aErrorCode, nsCSSToken& aTokenResult);
|
||||
PRBool NextURL(nsCSSToken& aTokenResult);
|
||||
|
||||
// It's really ugly that we have to expose this, but it's the easiest
|
||||
// way to do :nth-child() parsing sanely. (In particular, in
|
||||
@ -199,58 +199,34 @@ class nsCSSScanner {
|
||||
// "-1" back so we can read it again as a number.)
|
||||
void Pushback(PRUnichar aChar);
|
||||
|
||||
static inline PRBool
|
||||
IsIdentStart(PRInt32 aChar)
|
||||
{
|
||||
return aChar >= 0 &&
|
||||
(aChar >= 256 || (gLexTable[aChar] & START_IDENT) != 0);
|
||||
}
|
||||
// Reports operating-system level errors, e.g. read failures and
|
||||
// out of memory.
|
||||
nsresult GetLowLevelError();
|
||||
|
||||
static inline PRBool
|
||||
StartsIdent(PRInt32 aFirstChar, PRInt32 aSecondChar)
|
||||
{
|
||||
return IsIdentStart(aFirstChar) ||
|
||||
(aFirstChar == '-' && IsIdentStart(aSecondChar));
|
||||
}
|
||||
|
||||
static PRBool IsWhitespace(PRInt32 ch) {
|
||||
return PRUint32(ch) < 256 && (gLexTable[ch] & IS_WHITESPACE) != 0;
|
||||
}
|
||||
|
||||
static PRBool IsDigit(PRInt32 ch) {
|
||||
return PRUint32(ch) < 256 && (gLexTable[ch] & IS_DIGIT) != 0;
|
||||
}
|
||||
|
||||
static PRBool IsHexDigit(PRInt32 ch) {
|
||||
return PRUint32(ch) < 256 && (gLexTable[ch] & IS_HEX_DIGIT) != 0;
|
||||
}
|
||||
|
||||
static PRBool IsIdent(PRInt32 ch) {
|
||||
return ch >= 0 && (ch >= 256 || (gLexTable[ch] & IS_IDENT) != 0);
|
||||
}
|
||||
// sometimes the parser wants to make note of a low-level error
|
||||
void SetLowLevelError(nsresult aErrorCode);
|
||||
|
||||
protected:
|
||||
PRBool EnsureData(nsresult& aErrorCode);
|
||||
PRInt32 Read(nsresult& aErrorCode);
|
||||
PRInt32 Peek(nsresult& aErrorCode);
|
||||
PRBool LookAhead(nsresult& aErrorCode, PRUnichar aChar);
|
||||
PRBool EatWhiteSpace(nsresult& aErrorCode);
|
||||
PRBool EatNewline(nsresult& aErrorCode);
|
||||
PRBool EnsureData();
|
||||
PRInt32 Read();
|
||||
PRInt32 Peek();
|
||||
PRBool LookAhead(PRUnichar aChar);
|
||||
PRBool EatWhiteSpace();
|
||||
PRBool EatNewline();
|
||||
|
||||
void ParseAndAppendEscape(nsresult& aErrorCode, nsString& aOutput);
|
||||
PRBool ParseIdent(nsresult& aErrorCode, PRInt32 aChar, nsCSSToken& aResult);
|
||||
PRBool ParseAtKeyword(nsresult& aErrorCode, PRInt32 aChar,
|
||||
nsCSSToken& aResult);
|
||||
PRBool ParseNumber(nsresult& aErrorCode, PRInt32 aChar, nsCSSToken& aResult);
|
||||
PRBool ParseRef(nsresult& aErrorCode, PRInt32 aChar, nsCSSToken& aResult);
|
||||
PRBool ParseString(nsresult& aErrorCode, PRInt32 aChar, nsCSSToken& aResult);
|
||||
void ParseAndAppendEscape(nsString& aOutput);
|
||||
PRBool ParseIdent(PRInt32 aChar, nsCSSToken& aResult);
|
||||
PRBool ParseAtKeyword(PRInt32 aChar, nsCSSToken& aResult);
|
||||
PRBool ParseNumber(PRInt32 aChar, nsCSSToken& aResult);
|
||||
PRBool ParseRef(PRInt32 aChar, nsCSSToken& aResult);
|
||||
PRBool ParseString(PRInt32 aChar, nsCSSToken& aResult);
|
||||
#if 0
|
||||
PRBool ParseEOLComment(nsresult& aErrorCode, nsCSSToken& aResult);
|
||||
PRBool ParseCComment(nsresult& aErrorCode, nsCSSToken& aResult);
|
||||
PRBool ParseCComment(nsCSSToken& aResult);
|
||||
PRBool ParseEOLComment(nsCSSToken& aResult);
|
||||
#endif
|
||||
PRBool SkipCComment(nsresult& aErrorCode);
|
||||
PRBool SkipCComment();
|
||||
|
||||
PRBool GatherIdent(nsresult& aErrorCode, PRInt32 aChar, nsString& aIdent);
|
||||
PRBool GatherIdent(PRInt32 aChar, nsString& aIdent);
|
||||
|
||||
// Only used when input is a stream
|
||||
nsCOMPtr<nsIUnicharInputStream> mInputStream;
|
||||
@ -263,6 +239,7 @@ protected:
|
||||
PRInt32 mPushbackCount;
|
||||
PRInt32 mPushbackSize;
|
||||
PRUnichar mLocalPushback[4];
|
||||
nsresult mLowLevelError;
|
||||
|
||||
PRUint32 mLineNumber;
|
||||
#ifdef MOZ_SVG
|
||||
@ -276,15 +253,6 @@ protected:
|
||||
nsFixedString mError;
|
||||
PRUnichar mErrorBuf[200];
|
||||
#endif
|
||||
|
||||
static const PRUint8 IS_DIGIT;
|
||||
static const PRUint8 IS_HEX_DIGIT;
|
||||
static const PRUint8 START_IDENT;
|
||||
static const PRUint8 IS_IDENT;
|
||||
static const PRUint8 IS_WHITESPACE;
|
||||
|
||||
static PRUint8 gLexTable[256];
|
||||
static void BuildLexTable();
|
||||
};
|
||||
|
||||
#endif /* nsCSSScanner_h___ */
|
||||
|
Loading…
Reference in New Issue
Block a user