(textTokenType: TokenType)
| 703 | } |
| 704 | |
| 705 | private _consumeEntity(textTokenType: TokenType): void { |
| 706 | this._beginToken(TokenType.ENCODED_ENTITY); |
| 707 | const start = this._cursor.clone(); |
| 708 | this._cursor.advance(); |
| 709 | if (this._attemptCharCode(chars.$HASH)) { |
| 710 | const isHex = this._attemptCharCode(chars.$x) || this._attemptCharCode(chars.$X); |
| 711 | const codeStart = this._cursor.clone(); |
| 712 | this._attemptCharCodeUntilFn(isDigitEntityEnd); |
| 713 | if (this._cursor.peek() != chars.$SEMICOLON) { |
| 714 | // Advance cursor to include the peeked character in the string provided to the error |
| 715 | // message. |
| 716 | this._cursor.advance(); |
| 717 | const entityType = isHex ? CharacterReferenceType.HEX : CharacterReferenceType.DEC; |
| 718 | throw this._createError( |
| 719 | _unparsableEntityErrorMsg(entityType, this._cursor.getChars(start)), |
| 720 | this._cursor.getSpan(), |
| 721 | ); |
| 722 | } |
| 723 | const strNum = this._cursor.getChars(codeStart); |
| 724 | this._cursor.advance(); |
| 725 | try { |
| 726 | const charCode = parseInt(strNum, isHex ? 16 : 10); |
| 727 | this._endToken([String.fromCodePoint(charCode), this._cursor.getChars(start)]); |
| 728 | } catch { |
| 729 | throw this._createError( |
| 730 | _unknownEntityErrorMsg(this._cursor.getChars(start)), |
| 731 | this._cursor.getSpan(), |
| 732 | ); |
| 733 | } |
| 734 | } else { |
| 735 | const nameStart = this._cursor.clone(); |
| 736 | this._attemptCharCodeUntilFn(isNamedEntityEnd); |
| 737 | if (this._cursor.peek() != chars.$SEMICOLON) { |
| 738 | // No semicolon was found so abort the encoded entity token that was in progress, and treat |
| 739 | // this as a text token |
| 740 | this._beginToken(textTokenType, start); |
| 741 | this._cursor = nameStart; |
| 742 | this._endToken(['&']); |
| 743 | } else { |
| 744 | const name = this._cursor.getChars(nameStart); |
| 745 | this._cursor.advance(); |
| 746 | const char = Object.hasOwn(NAMED_ENTITIES, name) && NAMED_ENTITIES[name]; |
| 747 | if (!char) { |
| 748 | throw this._createError(_unknownEntityErrorMsg(name), this._cursor.getSpan(start)); |
| 749 | } |
| 750 | this._endToken([char, `&${name};`]); |
| 751 | } |
| 752 | } |
| 753 | } |
| 754 | |
| 755 | private _consumeRawText(consumeEntities: boolean, endMarkerPredicate: () => boolean): void { |
| 756 | this._beginToken(consumeEntities ? TokenType.ESCAPABLE_RAW_TEXT : TokenType.RAW_TEXT); |
no test coverage detected