Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(15)

Side by Side Diff: utils/template/parser.dart

Issue 9728009: Template bug fixes and new features. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Undid css.status change Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « utils/template/htmltree.dart ('k') | utils/template/tokenizer.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 3
4 class TagStack { 4 class TagStack {
5 List<ASTNode> _stack; 5 List<ASTNode> _stack;
6 6
7 TagStack(var elem) : _stack = [] { 7 TagStack(var elem) : _stack = [] {
8 _stack.add(elem); 8 _stack.add(elem);
9 } 9 }
10 10
(...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after
364 '</${TokenKind.tagNameFromTokenId(tagToken.kind)}>'); 364 '</${TokenKind.tagNameFromTokenId(tagToken.kind)}>');
365 } 365 }
366 } else { 366 } else {
367 // Too many end tags. 367 // Too many end tags.
368 _error('Too many end tags at ' + 368 _error('Too many end tags at ' +
369 '</${TokenKind.tagNameFromTokenId(tagToken.kind)}>'); 369 '</${TokenKind.tagNameFromTokenId(tagToken.kind)}>');
370 } 370 }
371 } 371 }
372 } 372 }
373 } else if (_maybeEat(TokenKind.START_COMMAND)) { 373 } else if (_maybeEat(TokenKind.START_COMMAND)) {
374 if (_peekIdentifier()) { 374 Identifier commandName = processAsIdentifier();
375 var commandName = identifier(); 375 if (commandName != null) {
376 switch (commandName.name) { 376 switch (commandName.name) {
377 case "each": 377 case "each":
378 case "with": 378 case "with":
379 if (_peekIdentifier()) { 379 var listName = processAsIdentifier();
380 var listName = identifier(); 380 if (listName != null) {
381 var loopItem = processAsIdentifier();
382 // Is the optional item name specified?
383 // #each lists [item]
384 // #with expression [item]
381 385
382 _eat(TokenKind.RBRACE); 386 _eat(TokenKind.RBRACE);
383 387
384 var frag = new TemplateElement.fragment( 388 var frag = new TemplateElement.fragment(
385 _makeSpan(_peekToken.start)); 389 _makeSpan(_peekToken.start));
386 TemplateDocument docFrag = processHTML(frag); 390 TemplateDocument docFrag = processHTML(frag);
387 391
388 if (docFrag != null) { 392 if (docFrag != null) {
389 var span = _makeSpan(start); 393 var span = _makeSpan(start);
390 var cmd; 394 var cmd;
391 if (commandName.name == "each") { 395 if (commandName.name == "each") {
392 cmd = new TemplateEachCommand(listName, docFrag, span); 396 cmd = new TemplateEachCommand(listName, loopItem, docFrag,
397 span);
393 } else if (commandName.name == "with") { 398 } else if (commandName.name == "with") {
394 cmd = new TemplateWithCommand(listName, docFrag, span); 399 cmd = new TemplateWithCommand(listName, loopItem, docFrag,
400 span);
395 } 401 }
396 402
397 stack.top().add(cmd); 403 stack.top().add(cmd);
398 stack.push(cmd); 404 stack.push(cmd);
399 } 405 }
400 406
401 // Process ${/commandName} 407 // Process ${/commandName}
402 _eat(TokenKind.END_COMMAND); 408 _eat(TokenKind.END_COMMAND);
403 409
404 // Close command ${/commandName} 410 // Close command ${/commandName}
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
437 } 443 }
438 } else { 444 } else {
439 _error("Missing listname for #each command"); 445 _error("Missing listname for #each command");
440 } 446 }
441 break; 447 break;
442 case "if": 448 case "if":
443 break; 449 break;
444 case "else": 450 case "else":
445 break; 451 break;
446 default: 452 default:
447 _error("Unknown template command"); 453 // Calling another template.
448 } 454 int startPos = this._previousToken.end;
455 // Gobble up everything until we hit }
456 while (_peek() != TokenKind.RBRACE &&
457 _peek() != TokenKind.END_OF_FILE) {
458 _next(false);
459 }
460
461 if (_peek() == TokenKind.RBRACE) {
462 int endPos = this._previousToken.end;
463 TemplateCall callNode = new TemplateCall(commandName.name,
464 source.text.substring(startPos, endPos), _makeSpan(start));
465 stack.top().add(callNode);
466
467 _next(false);
468 } else {
469 _error("Unknown template command");
470 }
471 } // End of switch/case
449 } 472 }
450 } else if (_peekKind(TokenKind.END_COMMAND)) { 473 } else if (_peekKind(TokenKind.END_COMMAND)) {
451 break; 474 break;
452 } else { 475 } else {
453 // Any text or expression nodes? 476 // Any text or expression nodes?
454 var nodes = processTextNodes(); 477 var nodes = processTextNodes();
455 if (nodes.length > 0) { 478 if (nodes.length > 0) {
456 assert(stack.top() != null); 479 assert(stack.top() != null);
457 for (var node in nodes) { 480 for (var node in nodes) {
458 stack.top().add(node); 481 stack.top().add(node);
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
518 } 541 }
519 542
520 List<ASTNode> processTextNodes() { 543 List<ASTNode> processTextNodes() {
521 // May contain TemplateText and TemplateExpression. 544 // May contain TemplateText and TemplateExpression.
522 List<ASTNode> nodes = []; 545 List<ASTNode> nodes = [];
523 546
524 int start = _peekToken.start; 547 int start = _peekToken.start;
525 bool inExpression = false; 548 bool inExpression = false;
526 StringBuffer stringValue = new StringBuffer(); 549 StringBuffer stringValue = new StringBuffer();
527 550
551 // Any text chars between close of tag and text node?
552 if (_previousToken.kind == TokenKind.GREATER_THAN) {
553 // If the next token is } could be the close template token. If user
554 // needs } as token in text node use the entity &125;
555 // TODO(terry): Probably need a &RCURLY entity instead of 125.
556 if (_peek() == TokenKind.ERROR) {
557 // Backup, just past previous token, & rescan we're outside of the tag.
558 tokenizer.index = _previousToken.end;
559 _next(false);
560 } else if (_peek() != TokenKind.RBRACE) {
561 // Yes, grab the chars after the >
562 stringValue.add(_previousToken.source.text.substring(
563 this._previousToken.end, this._peekToken.start));
564 }
565 }
566
528 // Gobble up everything until we hit < 567 // Gobble up everything until we hit <
529 int runningStart = _peekToken.start;
530 while (_peek() != TokenKind.LESS_THAN && 568 while (_peek() != TokenKind.LESS_THAN &&
531 (_peek() != TokenKind.RBRACE || 569 (_peek() != TokenKind.RBRACE ||
532 (_peek() == TokenKind.RBRACE && inExpression)) && 570 (_peek() == TokenKind.RBRACE && inExpression)) &&
533 _peek() != TokenKind.END_OF_FILE) { 571 _peek() != TokenKind.END_OF_FILE) {
534 572
535 // Beginning of expression? 573 // Beginning of expression?
536 if (_peek() == TokenKind.START_EXPRESSION) { 574 if (_peek() == TokenKind.START_EXPRESSION) {
537 if (stringValue.length > 0) { 575 if (stringValue.length > 0) {
538 // We have a real text node create the text node. 576 // We have a real text node create the text node.
539 nodes.add(new TemplateText(stringValue.toString(), _makeSpan(start))); 577 nodes.add(new TemplateText(stringValue.toString(), _makeSpan(start)));
(...skipping 18 matching lines...) Expand all
558 } 596 }
559 597
560 if (stringValue.length > 0) { 598 if (stringValue.length > 0) {
561 nodes.add(new TemplateText(stringValue.toString(), _makeSpan(start))); 599 nodes.add(new TemplateText(stringValue.toString(), _makeSpan(start)));
562 } 600 }
563 601
564 return nodes; 602 return nodes;
565 } 603 }
566 604
567 } 605 }
OLDNEW
« no previous file with comments | « utils/template/htmltree.dart ('k') | utils/template/tokenizer.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698