diff --git a/packages/compiler-core/src/options.ts b/packages/compiler-core/src/options.ts index 491d1eafa..a85842754 100644 --- a/packages/compiler-core/src/options.ts +++ b/packages/compiler-core/src/options.ts @@ -50,7 +50,8 @@ export interface ParserOptions */ whitespace?: 'preserve' | 'condense' /** - * Only needed for DOM compilers + * Only used for DOM compilers that runs in the browser. + * In non-browser builds, this option is ignored. */ decodeEntities?: (rawText: string, asAttr: boolean) => string /** diff --git a/packages/compiler-core/src/parser/Tokenizer.ts b/packages/compiler-core/src/parser/Tokenizer.ts index 536de3a61..2c128a670 100644 --- a/packages/compiler-core/src/parser/Tokenizer.ts +++ b/packages/compiler-core/src/parser/Tokenizer.ts @@ -22,12 +22,20 @@ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +import { ElementNode, Position } from '../ast' + +/** + * Note: entities is a non-browser-build-only dependency. + * In the browser, we use an HTML element to do the decoding. + * Make sure all imports from entities are only used in non-browser branches + * so that it can be properly treeshaken. + */ import { EntityDecoder, DecodingMode, - htmlDecodeTree + htmlDecodeTree, + fromCodePoint } from 'entities/lib/decode.js' -import { ElementNode, Position } from '../ast' export const enum ParseMode { BASE, @@ -170,7 +178,7 @@ export enum QuoteType { export interface Callbacks { ontext(start: number, endIndex: number): void - ontextentity(codepoint: number, endIndex: number): void + ontextentity(char: string, endIndex: number): void oninterpolation(start: number, endIndex: number): void @@ -180,7 +188,7 @@ export interface Callbacks { onclosetag(start: number, endIndex: number): void onattribdata(start: number, endIndex: number): void - onattribentity(codepoint: number): void + onattribentity(char: string): void onattribend(quote: QuoteType, endIndex: number): void onattribname(start: number, endIndex: number): void onattribnameend(endIndex: number): void @@ -233,15 +241,17 @@ export default class Tokenizer { /** Reocrd newline positions for fast line / column calculation */ private newlines: number[] = [] - private readonly entityDecoder: EntityDecoder + private readonly entityDecoder?: EntityDecoder constructor( private readonly stack: ElementNode[], private readonly cbs: Callbacks ) { - this.entityDecoder = new EntityDecoder(htmlDecodeTree, (cp, consumed) => - this.emitCodePoint(cp, consumed) - ) + if (!__BROWSER__) { + this.entityDecoder = new EntityDecoder(htmlDecodeTree, (cp, consumed) => + this.emitCodePoint(cp, consumed) + ) + } } public mode = ParseMode.BASE @@ -290,7 +300,7 @@ export default class Tokenizer { } this.state = State.BeforeTagName this.sectionStart = this.index - } else if (c === CharCodes.Amp) { + } else if (!__BROWSER__ && c === CharCodes.Amp) { this.startEntity() } else if (c === this.delimiterOpen[0]) { this.state = State.InterpolationOpen @@ -398,7 +408,7 @@ export default class Tokenizer { !(this.mode === ParseMode.SFC && this.stack.length === 0)) ) { // We have to parse entities in