Handle URL token in a closer way to the CSS3 spec
This commit is contained in:
parent
2ada41b81c
commit
c42398f67c
|
@ -1067,6 +1067,7 @@ Scanner.prototype = {
|
||||||
// aToken.mIdent may be "url" at this point; clear that out
|
// aToken.mIdent may be "url" at this point; clear that out
|
||||||
aToken.mIdent.length = 0;
|
aToken.mIdent.length = 0;
|
||||||
|
|
||||||
|
let hasString = false;
|
||||||
let ch = this.Peek();
|
let ch = this.Peek();
|
||||||
// Do we have a string?
|
// Do we have a string?
|
||||||
if (ch == QUOTATION_MARK || ch == APOSTROPHE) {
|
if (ch == QUOTATION_MARK || ch == APOSTROPHE) {
|
||||||
|
@ -1075,6 +1076,7 @@ Scanner.prototype = {
|
||||||
aToken.mType = eCSSToken_Bad_URL;
|
aToken.mType = eCSSToken_Bad_URL;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
hasString = true;
|
||||||
} else {
|
} else {
|
||||||
// Otherwise, this is the start of a non-quoted url (which may be empty).
|
// Otherwise, this is the start of a non-quoted url (which may be empty).
|
||||||
aToken.mSymbol = 0;
|
aToken.mSymbol = 0;
|
||||||
|
@ -1093,6 +1095,25 @@ Scanner.prototype = {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
aToken.mType = eCSSToken_Bad_URL;
|
aToken.mType = eCSSToken_Bad_URL;
|
||||||
|
if (!hasString) {
|
||||||
|
// Consume until before the next right parenthesis, which follows
|
||||||
|
// how <bad-url-token> is consumed in CSS Syntax 3 spec.
|
||||||
|
// Note that, we only do this when "url(" is not followed by a
|
||||||
|
// string, because in the spec, "url(" followed by a string is
|
||||||
|
// handled as a url function rather than a <url-token>, so the
|
||||||
|
// rest of content before ")" should be consumed in balance,
|
||||||
|
// which will be done by the parser.
|
||||||
|
// The closing ")" is not consumed here. It is left to the parser
|
||||||
|
// so that the parser can handle both cases.
|
||||||
|
do {
|
||||||
|
if (IsVertSpace(ch)) {
|
||||||
|
this.AdvanceLine();
|
||||||
|
} else {
|
||||||
|
this.Advance();
|
||||||
|
}
|
||||||
|
ch = this.Peek();
|
||||||
|
} while (ch >= 0 && ch != RIGHT_PARENTHESIS);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -128,8 +128,7 @@ var LEX_TESTS = [
|
||||||
["url:http://example.com"]],
|
["url:http://example.com"]],
|
||||||
// In CSS Level 3, this is an ordinary URL, not a BAD_URL.
|
// In CSS Level 3, this is an ordinary URL, not a BAD_URL.
|
||||||
["url(http://example.com", ["url:http://example.com"]],
|
["url(http://example.com", ["url:http://example.com"]],
|
||||||
// See bug 1153981 to understand why this gets a SYMBOL token.
|
["url(http://example.com @", ["bad_url:http://example.com"]],
|
||||||
["url(http://example.com @", ["bad_url:http://example.com", "symbol:@"]],
|
|
||||||
["quo\\ting", ["ident:quoting"]],
|
["quo\\ting", ["ident:quoting"]],
|
||||||
["'bad string\n", ["bad_string:bad string", "whitespace"]],
|
["'bad string\n", ["bad_string:bad string", "whitespace"]],
|
||||||
["~=", ["includes"]],
|
["~=", ["includes"]],
|
||||||
|
|
|
@ -22,17 +22,16 @@
|
||||||
#two { background-color: green; }
|
#two { background-color: green; }
|
||||||
</style>
|
</style>
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
/* not a URI token; the unterminated string ends at end of line, so
|
/* not a URI token; bad-url token is consumed until the first closing ) */
|
||||||
the brace never matches */
|
|
||||||
#three { background-color: green; }
|
|
||||||
#foo { background: url(foo"bar) }
|
#foo { background: url(foo"bar) }
|
||||||
#three { background-color: red; }
|
#three { background-color: green; }
|
||||||
</style>
|
</style>
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
/* not a URI token; the unterminated string ends at end of line */
|
/* not a URI token; bad-url token is consumed until the first closing ) */
|
||||||
|
#four { background-color: green; }
|
||||||
#foo { background: url(foo"bar) }
|
#foo { background: url(foo"bar) }
|
||||||
) }
|
) }
|
||||||
#four { background-color: green; }
|
#four { background-color: red; }
|
||||||
</style>
|
</style>
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
/* not a URI token; the unterminated string ends at end of line, so
|
/* not a URI token; the unterminated string ends at end of line, so
|
||||||
|
@ -68,18 +67,19 @@
|
||||||
#eleven { background: url([) green; }
|
#eleven { background: url([) green; }
|
||||||
</style>
|
</style>
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
/* not a URI token; brace matching should work only after invalid URI token */
|
/* not a URI token; bad-url token is consumed until the first closing )
|
||||||
#twelve { background: url(}{""{)}); background-color: green; }
|
so the brace immediately after it closes the declaration block */
|
||||||
|
#twelve { background-color: green; }
|
||||||
|
#twelve { background: url(}{""{)}); background-color: red; }
|
||||||
</style>
|
</style>
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
/* invalid URI token absorbs the [ */
|
/* invalid URI token absorbs the [ */
|
||||||
#thirteen { background: url([""); background-color: green; }
|
#thirteen { background: url([""); background-color: green; }
|
||||||
</style>
|
</style>
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
/* not a URI token; the opening ( is never matched */
|
/* not a URI token; bad-url token is consumed until the first closing ) */
|
||||||
#fourteen { background-color: green; }
|
|
||||||
#foo { background: url(() }
|
#foo { background: url(() }
|
||||||
#fourteen { background-color: red; }
|
#fourteen { background-color: green; }
|
||||||
</style>
|
</style>
|
||||||
<!-- The next three tests test that invalid URI tokens absorb [ and { -->
|
<!-- The next three tests test that invalid URI tokens absorb [ and { -->
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
|
|
|
@ -1164,6 +1164,7 @@ nsCSSScanner::NextURL(nsCSSToken& aToken)
|
||||||
// aToken.mIdent may be "url" at this point; clear that out
|
// aToken.mIdent may be "url" at this point; clear that out
|
||||||
aToken.mIdent.Truncate();
|
aToken.mIdent.Truncate();
|
||||||
|
|
||||||
|
bool hasString = false;
|
||||||
int32_t ch = Peek();
|
int32_t ch = Peek();
|
||||||
// Do we have a string?
|
// Do we have a string?
|
||||||
if (ch == '"' || ch == '\'') {
|
if (ch == '"' || ch == '\'') {
|
||||||
|
@ -1173,7 +1174,7 @@ nsCSSScanner::NextURL(nsCSSToken& aToken)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
MOZ_ASSERT(aToken.mType == eCSSToken_String, "unexpected token type");
|
MOZ_ASSERT(aToken.mType == eCSSToken_String, "unexpected token type");
|
||||||
|
hasString = true;
|
||||||
} else {
|
} else {
|
||||||
// Otherwise, this is the start of a non-quoted url (which may be empty).
|
// Otherwise, this is the start of a non-quoted url (which may be empty).
|
||||||
aToken.mSymbol = char16_t(0);
|
aToken.mSymbol = char16_t(0);
|
||||||
|
@ -1193,6 +1194,25 @@ nsCSSScanner::NextURL(nsCSSToken& aToken)
|
||||||
} else {
|
} else {
|
||||||
mSeenBadToken = true;
|
mSeenBadToken = true;
|
||||||
aToken.mType = eCSSToken_Bad_URL;
|
aToken.mType = eCSSToken_Bad_URL;
|
||||||
|
if (!hasString) {
|
||||||
|
// Consume until before the next right parenthesis, which follows
|
||||||
|
// how <bad-url-token> is consumed in CSS Syntax 3 spec.
|
||||||
|
// Note that, we only do this when "url(" is not followed by a
|
||||||
|
// string, because in the spec, "url(" followed by a string is
|
||||||
|
// handled as a url function rather than a <url-token>, so the
|
||||||
|
// rest of content before ")" should be consumed in balance,
|
||||||
|
// which will be done by the parser.
|
||||||
|
// The closing ")" is not consumed here. It is left to the parser
|
||||||
|
// so that the parser can handle both cases.
|
||||||
|
do {
|
||||||
|
if (IsVertSpace(ch)) {
|
||||||
|
AdvanceLine();
|
||||||
|
} else {
|
||||||
|
Advance();
|
||||||
|
}
|
||||||
|
ch = Peek();
|
||||||
|
} while (ch >= 0 && ch != ')');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,8 +55,7 @@ var LEX_TESTS = [
|
||||||
["url:http://example.com"]],
|
["url:http://example.com"]],
|
||||||
// In CSS Level 3, this is an ordinary URL, not a BAD_URL.
|
// In CSS Level 3, this is an ordinary URL, not a BAD_URL.
|
||||||
["url(http://example.com", ["url:http://example.com"]],
|
["url(http://example.com", ["url:http://example.com"]],
|
||||||
// See bug 1153981 to understand why this gets a SYMBOL token.
|
["url(http://example.com @", ["bad_url:http://example.com"]],
|
||||||
["url(http://example.com @", ["bad_url:http://example.com", "symbol:@"]],
|
|
||||||
["quo\\ting", ["ident:quoting"]],
|
["quo\\ting", ["ident:quoting"]],
|
||||||
["'bad string\n", ["bad_string:bad string", "whitespace"]],
|
["'bad string\n", ["bad_string:bad string", "whitespace"]],
|
||||||
["~=", ["includes"]],
|
["~=", ["includes"]],
|
||||||
|
|
Loading…
Reference in New Issue