MCPcopy Index your code
hub / github.com/angular/angular / _consumeAttr

Method _consumeAttr

packages/compiler/src/ml_parser/parser.ts:641–704  ·  view source on GitHub ↗
(attrName: AttributeNameToken)

Source from the content-addressed store, hash-verified

639 }
640
641 private _consumeAttr(attrName: AttributeNameToken): html.Attribute {
642 const fullName = mergeNsAndName(attrName.parts[0], attrName.parts[1]);
643 let attrEnd = attrName.sourceSpan.end;
644
645 // Consume any quote
646 if (this._peek.type === TokenType.ATTR_QUOTE) {
647 this._advance();
648 }
649
650 // Consume the attribute value
651 let value = '';
652 const valueTokens: InterpolatedAttributeToken[] = [];
653 let valueStartSpan: ParseSourceSpan | undefined = undefined;
654 let valueEnd: ParseLocation | undefined = undefined;
655 // NOTE: We need to use a new variable `nextTokenType` here to hide the actual type of
656 // `_peek.type` from TS. Otherwise TS will narrow the type of `_peek.type` preventing it from
657 // being able to consider `ATTR_VALUE_INTERPOLATION` as an option. This is because TS is not
658 // able to see that `_advance()` will actually mutate `_peek`.
659 const nextTokenType = this._peek.type as TokenType;
660 if (nextTokenType === TokenType.ATTR_VALUE_TEXT) {
661 valueStartSpan = this._peek.sourceSpan;
662 valueEnd = this._peek.sourceSpan.end;
663 while (
664 this._peek.type === TokenType.ATTR_VALUE_TEXT ||
665 this._peek.type === TokenType.ATTR_VALUE_INTERPOLATION ||
666 this._peek.type === TokenType.ENCODED_ENTITY
667 ) {
668 const valueToken = this._advance<InterpolatedAttributeToken>();
669 valueTokens.push(valueToken);
670 if (valueToken.type === TokenType.ATTR_VALUE_INTERPOLATION) {
671 // For backward compatibility we decode HTML entities that appear in interpolation
672 // expressions. This is arguably a bug, but it could be a considerable breaking change to
673 // fix it. It should be addressed in a larger project to refactor the entire parser/lexer
674 // chain after View Engine has been removed.
675 value += valueToken.parts.join('').replace(/&([^;]+);/g, decodeEntity);
676 } else if (valueToken.type === TokenType.ENCODED_ENTITY) {
677 value += valueToken.parts[0];
678 } else {
679 value += valueToken.parts.join('');
680 }
681 valueEnd = attrEnd = valueToken.sourceSpan.end;
682 }
683 }
684
685 // Consume any quote
686 if (this._peek.type === TokenType.ATTR_QUOTE) {
687 const quoteToken = this._advance<AttributeQuoteToken>();
688 attrEnd = quoteToken.sourceSpan.end;
689 }
690
691 const valueSpan =
692 valueStartSpan &&
693 valueEnd &&
694 new ParseSourceSpan(valueStartSpan.start, valueEnd, valueStartSpan.fullStart);
695 return new html.Attribute(
696 fullName,
697 value,
698 new ParseSourceSpan(attrName.sourceSpan.start, attrEnd, attrName.sourceSpan.fullStart),

Callers 2

_consumeDirectiveMethod · 0.95

Calls 5

_advanceMethod · 0.95
mergeNsAndNameFunction · 0.90
joinMethod · 0.65
pushMethod · 0.45
replaceMethod · 0.45

Tested by

no test coverage detected