@@ -266,8 +266,18 @@ namespace Sass {
266
266
import_single_file (imp, lexed);
267
267
}
268
268
}
269
- else if (peek< uri_prefix >()) {
270
- imp->urls ().push_back (parse_value ());
269
+ else if (lex< uri_prefix >()) {
270
+ Arguments* args = new (ctx.mem ) Arguments (pstate);
271
+ Function_Call* result = new (ctx.mem ) Function_Call (pstate, " url" , args);
272
+ if (lex < uri_value >()) { // chunk seems to work too!
273
+ String* the_url = parse_interpolated_chunk (lexed);
274
+ *args << new (ctx.mem ) Argument (the_url->pstate (), the_url);
275
+ }
276
+ else {
277
+ error (" malformed URL" , pstate);
278
+ }
279
+ if (!lex< exactly<' )' > >()) error (" URI is missing ')'" , pstate);
280
+ imp->urls ().push_back (result);
271
281
}
272
282
else {
273
283
if (first) error (" @import directive requires a url or quoted path" , pstate);
@@ -301,16 +311,16 @@ namespace Sass {
301
311
302
312
Parameters* Parser::parse_parameters ()
303
313
{
304
- string name (lexed); // for the error message
314
+ string name (lexed);
315
+ Position position = after_token;
305
316
Parameters* params = new (ctx.mem ) Parameters (pstate);
306
- if (lex < exactly<' (' > >()) {
317
+ if (lex_css < exactly<' (' > >()) {
307
318
// if there's anything there at all
308
- if (!peek < exactly<' )' > >()) {
319
+ if (!peek_css < exactly<' )' > >()) {
309
320
do (*params) << parse_parameter ();
310
321
while (lex_css< exactly<' ,' > >());
311
322
}
312
- while (lex< alternatives < spaces, block_comment > >()) {};
313
- if (!lex< exactly<' )' > >()) error (" expected a variable name (e.g. $x) or ')' for the parameter list for " + name, pstate);
323
+ if (!lex_css< exactly<' )' > >()) error (" expected a variable name (e.g. $x) or ')' for the parameter list for " + name, position);
314
324
}
315
325
return params;
316
326
}
@@ -351,34 +361,36 @@ namespace Sass {
351
361
return the_call;
352
362
}
353
363
354
- Arguments* Parser::parse_arguments ()
364
+ Arguments* Parser::parse_arguments (bool has_url )
355
365
{
356
366
string name (lexed);
367
+ Position position = after_token;
357
368
Arguments* args = new (ctx.mem ) Arguments (pstate);
358
-
359
- if (lex< exactly<' (' > >()) {
369
+ if (lex_css< exactly<' (' > >()) {
360
370
// if there's anything there at all
361
- if (!peek < exactly<' )' > >()) {
362
- do (*args) << parse_argument ();
371
+ if (!peek_css < exactly<' )' > >()) {
372
+ do (*args) << parse_argument (has_url );
363
373
while (lex_css< exactly<' ,' > >());
364
374
}
365
- while (lex< block_comment >());
366
- if (!lex< exactly<' )' > >()) error (" expected a variable name (e.g. $x) or ')' for the parameter list for " + name, pstate);
375
+ if (!lex_css< exactly<' )' > >()) error (" expected a variable name (e.g. $x) or ')' for the parameter list for " + name, position);
367
376
}
368
-
369
377
return args;
370
378
}
371
379
372
- Argument* Parser::parse_argument ()
380
+ Argument* Parser::parse_argument (bool has_url )
373
381
{
382
+
374
383
Argument* arg;
375
- while (lex< alternatives < spaces, block_comment > >());
376
- if (peek< sequence < variable, zero_plus < alternatives < spaces, line_comment, block_comment > >, exactly<' :' > > >()) {
377
- lex< variable >();
384
+ // some urls can look like line comments (parse literally - chunk would not work)
385
+ if (has_url && lex< sequence < uri_value, lookahead < exactly<' )' > > > >(false )) {
386
+ String* the_url = parse_interpolated_chunk (lexed);
387
+ arg = new (ctx.mem ) Argument (the_url->pstate (), the_url);
388
+ }
389
+ else if (peek_css< sequence < variable, optional_css_comments, exactly<' :' > > >()) {
390
+ lex_css< variable >();
378
391
string name (Util::normalize_underscores (lexed));
379
392
ParserState p = pstate;
380
- while (lex< alternatives < spaces, block_comment > >()) {};
381
- lex< exactly<' :' > >();
393
+ lex_css< exactly<' :' > >();
382
394
Expression* val = parse_space_list ();
383
395
val->is_delayed (false );
384
396
arg = new (ctx.mem ) Argument (p, val, name);
@@ -388,7 +400,7 @@ namespace Sass {
388
400
bool is_keyword = false ;
389
401
Expression* val = parse_space_list ();
390
402
val->is_delayed (false );
391
- if (lex < exactly< ellipsis > >()) {
403
+ if (lex_css < exactly< ellipsis > >()) {
392
404
if (val->concrete_type () == Expression::MAP) is_keyword = true ;
393
405
else is_arglist = true ;
394
406
}
@@ -1118,10 +1130,10 @@ namespace Sass {
1118
1130
{
1119
1131
Expression* conj1 = parse_conjunction ();
1120
1132
// if it's a singleton, return it directly; don't wrap it
1121
- if (!peek< sequence< kwd_or, negate< identifier > > >()) return conj1;
1133
+ if (!peek_css< kwd_or >()) return conj1;
1122
1134
1123
1135
vector<Expression*> operands;
1124
- while (lex< sequence< kwd_or, negate< identifier > > >())
1136
+ while (lex_css< kwd_or >())
1125
1137
operands.push_back (parse_conjunction ());
1126
1138
1127
1139
return fold_operands (conj1, operands, Binary_Expression::OR);
@@ -1131,10 +1143,10 @@ namespace Sass {
1131
1143
{
1132
1144
Expression* rel1 = parse_relation ();
1133
1145
// if it's a singleton, return it directly; don't wrap it
1134
- if (!peek< sequence< kwd_and, negate< identifier > > >()) return rel1;
1146
+ if (!peek_css< kwd_and >()) return rel1;
1135
1147
1136
1148
vector<Expression*> operands;
1137
- while (lex< sequence< kwd_and, negate< identifier > > >())
1149
+ while (lex_css< kwd_and >())
1138
1150
operands.push_back (parse_relation ());
1139
1151
1140
1152
return fold_operands (rel1, operands, Binary_Expression::AND);
@@ -1249,7 +1261,7 @@ namespace Sass {
1249
1261
else if (peek< sequence< identifier_schema, negate< exactly<' %' > > > >()) {
1250
1262
return parse_identifier_schema ();
1251
1263
}
1252
- else if (peek< functional >() && !peek< uri_prefix >() ) {
1264
+ else if (peek< functional >()) {
1253
1265
return parse_function_call ();
1254
1266
}
1255
1267
else if (lex< sequence< exactly<' +' >, optional_css_whitespace, negate< number > > >()) {
@@ -1272,45 +1284,7 @@ namespace Sass {
1272
1284
1273
1285
Expression* Parser::parse_value ()
1274
1286
{
1275
- while (lex< block_comment >());
1276
- if (lex< uri_prefix >()) {
1277
- Arguments* args = new (ctx.mem ) Arguments (pstate);
1278
- Function_Call* result = new (ctx.mem ) Function_Call (pstate, " url" , args);
1279
- const char * here = position;
1280
- Position here_p = before_token;
1281
- // Try to parse a SassScript expression. If it succeeds and we can munch
1282
- // a matching rparen, then that's our url. If we can't munch a matching
1283
- // rparen, or if the attempt to parse an expression fails, then try to
1284
- // munch a regular CSS url.
1285
- try {
1286
- // special case -- if there's a comment, treat it as part of a URL
1287
- lex<spaces>();
1288
- if (peek<line_comment>() || peek<block_comment_prefix>()) error (" comment in URL" , pstate); // doesn't really matter what we throw
1289
- Expression* expr = parse_list ();
1290
- if (!lex< exactly<' )' > >()) error (" dangling expression in URL" , pstate); // doesn't really matter what we throw
1291
- Argument* arg = new (ctx.mem ) Argument (expr->pstate (), expr);
1292
- *args << arg;
1293
- return result;
1294
- }
1295
- catch (Sass_Error&) {
1296
- // back up so we can try again
1297
- position = here;
1298
- before_token = here_p;
1299
- }
1300
- catch (...) { throw ; }
1301
- lex< spaces >();
1302
- if (lex< url >()) {
1303
- String* the_url = parse_interpolated_chunk (lexed);
1304
- Argument* arg = new (ctx.mem ) Argument (the_url->pstate (), the_url);
1305
- *args << arg;
1306
- }
1307
- else {
1308
- error (" malformed URL" , pstate);
1309
- }
1310
- if (!lex< exactly<' )' > >()) error (" URI is missing ')'" , pstate);
1311
- return result;
1312
- }
1313
-
1287
+ lex< css_comments >();
1314
1288
if (lex< ampersand >())
1315
1289
{
1316
1290
return new (ctx.mem ) Parent_Selector (pstate, parse_selector_group ()); }
@@ -1322,13 +1296,13 @@ namespace Sass {
1322
1296
if ((stop = peek< value_schema >()))
1323
1297
{ return parse_value_schema (stop); }
1324
1298
1325
- if (lex< sequence< kwd_true, negate< identifier > > >())
1299
+ if (lex< kwd_true >())
1326
1300
{ return new (ctx.mem ) Boolean (pstate, true ); }
1327
1301
1328
- if (lex< sequence< kwd_false, negate< identifier > > >())
1302
+ if (lex< kwd_false >())
1329
1303
{ return new (ctx.mem ) Boolean (pstate, false ); }
1330
1304
1331
- if (lex< sequence< kwd_null, negate< identifier > > >())
1305
+ if (lex< kwd_null >())
1332
1306
{ return new (ctx.mem ) Null (pstate); }
1333
1307
1334
1308
if (lex< identifier >()) {
@@ -1634,10 +1608,8 @@ namespace Sass {
1634
1608
{
1635
1609
lex< identifier >();
1636
1610
string name (lexed);
1637
- ParserState source_position_of_call = pstate;
1638
-
1639
- Function_Call* the_call = new (ctx.mem ) Function_Call (source_position_of_call, name, parse_arguments ());
1640
- return the_call;
1611
+ Arguments* args = parse_arguments (name == " url" );
1612
+ return new (ctx.mem ) Function_Call (pstate, name, args);
1641
1613
}
1642
1614
1643
1615
Function_Call_Schema* Parser::parse_function_call_schema ()
0 commit comments