{"version":3,"file":"HTMLText.mjs","sources":["../../../src/scene/text-html/HTMLText.ts"],"sourcesContent":["import { TextureSource } from '../../rendering/renderers/shared/texture/sources/TextureSource';\nimport { TextureStyle, type TextureStyleOptions } from '../../rendering/renderers/shared/texture/TextureStyle';\nimport { AbstractText, ensureTextOptions } from '../text/AbstractText';\nimport { type BatchableHTMLText } from './BatchableHTMLText';\nimport { HTMLTextStyle } from './HTMLTextStyle';\nimport { measureHtmlText } from './utils/measureHtmlText';\nimport './init';\n\nimport type { View } from '../../rendering/renderers/shared/view/View';\nimport type { TextOptions, TextString } from '../text/AbstractText';\nimport type { HTMLTextStyleOptions } from './HTMLTextStyle';\n\n/**\n * Constructor options used for `HTMLText` instances. Extends the base text options\n * with HTML-specific features and texture styling capabilities.\n * @example\n * ```ts\n * // Basic HTML text\n * const basicText = new HTMLText({\n *     text: '<b>Bold</b> and <i>Italic</i> text',\n *     style: {\n *         fontSize: 24,\n *         fill: 0xff1010\n *     }\n * });\n *\n * // Rich HTML text with styling\n * const richText = new HTMLText({\n *     text: '<custom>Custom Tag</custom>',\n *     style: {\n *         fontFamily: 'Arial',\n *         fontSize: 32,\n *         fill: 0x4a4a4a,\n *         align: 'center',\n *         tagStyles: {\n *             custom: {\n *                 fontSize: 32,\n *                 fill: '#00ff00',\n *                 fontStyle: 'italic'\n *             }\n *         }\n *     }\n *     textureStyle: {\n *         scaleMode: 'linear',\n *     }\n * });\n * ```\n * @category text\n * @standard\n */\nexport interface HTMLTextOptions extends TextOptions<HTMLTextStyle, HTMLTextStyleOptions>, PixiMixins.HTMLTextOptions\n{\n    /**\n     * Optional texture style to use for the text texture. This allows fine control over\n     * how the text is rendered to a texture before being displayed.\n     *\n     * The texture style can affect:\n     * - Scale mode (nearest/linear)\n     * - Resolution\n     * - Format (rgb/rgba)\n     * - Alpha handling\n     * @example\n     * ```ts\n     * const text = new HTMLText({\n     *     text: 'Crisp Text',\n     *     textureStyle: {\n     *         scaleMode: 'nearest', // Pixel-perfect scaling\n     *     }\n     * });\n     * ```\n     * @advanced\n     */\n    textureStyle?: TextureStyle | TextureStyleOptions;\n    /**\n     * Whether to generate mipmaps for the text texture.\n     * Improves rendering quality when the text is scaled down.\n     * @default undefined - Falls back to TextureSource.defaultOptions.autoGenerateMipmaps\n     */\n    autoGenerateMipmaps?: boolean;\n}\n\n// eslint-disable-next-line requireExport/require-export-jsdoc, requireMemberAPI/require-member-api-doc\nexport interface HTMLText extends PixiMixins.HTMLText, AbstractText<\n    HTMLTextStyle,\n    HTMLTextStyleOptions,\n    HTMLTextOptions,\n    BatchableHTMLText\n> {}\n\n/**\n * A HTMLText object creates text using HTML/CSS rendering with SVG foreignObject.\n * This allows for rich text formatting using standard HTML tags and CSS styling.\n *\n * Key features:\n * - HTML tag support (&lt;strong&gt;, &lt;em&gt;, etc.)\n * - CSS styling and custom style overrides\n * - Emoji and special character support\n * - Line breaking and word wrapping\n * - SVG-based rendering\n * @example\n * ```ts\n * import { HTMLText } from 'pixi.js';\n *\n * // Basic HTML text with tags\n * const text = new HTMLText({\n *     text: '<h1>Title</h1><p>This is a <strong>bold</strong> and <em>italic</em> text.</p>',\n *     style: {\n *         fontFamily: 'Arial',\n *         fontSize: 24,\n *         fill: 0xff1010,\n *         align: 'center',\n *     }\n * });\n *\n * // Rich HTML text with custom styling\n * const richText = new HTMLText({\n *     text: `\n *         <div class=\"title\">Welcome</div>\n *         <div class=\"content\">\n *             This text supports:\n *             <ul>\n *                 <li>✨ Emojis</li>\n *                 <li>🎨 Custom CSS</li>\n *                 <li>📏 Auto-sizing</li>\n *             </ul>\n *         </div>\n *     `,\n *     style: {\n *         fontSize: 24,\n *         fill: '#334455',\n *         cssOverrides: [\n *             '.title { font-size: 32px; color: red; }',\n *             '.content { line-height: 1.5; }'\n *         ],\n *         wordWrap: true,\n *         wordWrapWidth: 300,\n *     }\n * });\n *\n * // Text with custom texture settings\n * const crispText = new HTMLText({\n *     text: '<div style=\"padding: 10px\">High Quality Text</div>',\n *     style: {\n *         fontSize: 24,\n *         fill: '#4a4a4a',\n *     },\n *     textureStyle: {\n *         scaleMode: 'nearest',\n *     }\n * });\n * ```\n *\n * Platform Considerations:\n * - Rendering may vary slightly between browsers\n * - Requires browser support for foreignObject\n * - Performance similar to Canvas text\n * - Memory usage comparable to Canvas text\n * @category text\n * @standard\n * @see {@link HTMLTextStyle} For detailed style options\n * @see {@link Text} For canvas-based text rendering\n * @see {@link BitmapText} For high-performance static text\n */\nexport class HTMLText extends AbstractText<\n    HTMLTextStyle,\n    HTMLTextStyleOptions,\n    HTMLTextOptions,\n    BatchableHTMLText\n> implements View\n{\n    /** @internal */\n    public override readonly renderPipeId: string = 'htmlText';\n\n    /**\n     * Optional texture style to use for the text.\n     * > [!NOTE] HTMLText is not updated when this property is updated,\n     * > you must update the text manually by calling `text.onViewUpdate()`\n     * @advanced\n     */\n    public textureStyle?: TextureStyle;\n\n    /**\n     * Whether to generate mipmaps for the text texture.\n     * Improves rendering quality when the text is scaled down.\n     * > [!NOTE] HTMLText is not updated when this property is updated,\n     * > you must update the text manually by calling `text.onViewUpdate()`\n     * @default undefined - Falls back to TextureSource.defaultOptions.autoGenerateMipmaps\n     */\n    public autoGenerateMipmaps?: boolean;\n\n    /**\n     * @param {HTMLTextOptions} options - The options of the html text.\n     */\n    constructor(options?: HTMLTextOptions);\n    /** @deprecated since 8.0.0 */\n    constructor(text?: TextString, options?: Partial<HTMLTextStyle>);\n    constructor(...args: [HTMLTextOptions?] | [TextString, Partial<HTMLTextStyle>])\n    {\n        const options = ensureTextOptions<HTMLTextOptions>(args, 'HtmlText');\n\n        super(options, HTMLTextStyle);\n\n        if (options.textureStyle)\n        {\n            this.textureStyle = options.textureStyle instanceof TextureStyle\n                ? options.textureStyle\n                : new TextureStyle(options.textureStyle);\n        }\n\n        this.autoGenerateMipmaps = options.autoGenerateMipmaps ?? TextureSource.defaultOptions.autoGenerateMipmaps;\n    }\n\n    /** @private */\n    protected updateBounds()\n    {\n        const bounds = this._bounds;\n        const anchor = this._anchor;\n\n        const htmlMeasurement = measureHtmlText(this.text, this._style as HTMLTextStyle);\n\n        const { width, height } = htmlMeasurement;\n\n        bounds.minX = (-anchor._x * width);\n        bounds.maxX = bounds.minX + width;\n        bounds.minY = (-anchor._y * height);\n        bounds.maxY = bounds.minY + height;\n    }\n\n    override get text(): string\n    {\n        return this._text;\n    }\n    /**\n     * The text content to display. Use '\\n' for line breaks.\n     * Accepts strings, numbers, or objects with toString() method.\n     * @example\n     * ```ts\n     * const text = new HTMLText({\n     *     text: 'Hello Pixi!',\n     * });\n     * const multilineText = new HTMLText({\n     *     text: 'Line 1\\nLine 2\\nLine 3',\n     * });\n     * const numberText = new HTMLText({\n     *     text: 12345, // Will be converted to '12345'\n     * });\n     * const objectText = new HTMLText({\n     *     text: { toString: () => 'Object Text' }, // Custom toString\n     * });\n     *\n     * // Update text dynamically\n     * text.text = 'Updated Text'; // Re-renders with new text\n     * text.text = 67890; // Updates to '67890'\n     * text.text = { toString: () => 'Dynamic Text' }; // Uses custom toString method\n     * // Clear text\n     * text.text = ''; // Clears the text\n     * ```\n     * @default ''\n     */\n    override set text(text: TextString)\n    {\n        // Sanitise the text to ensure it is valid HTML\n        const sanitisedText = this._sanitiseText(text.toString());\n\n        // Call the parent class's text setter with the sanitised text\n        super.text = sanitisedText;\n    }\n\n    /**\n     * Sanitise text - replace `<br>` with `<br/>`, `&nbsp;` with `&#160;`\n     * @param text\n     * @see https://www.sitepoint.com/community/t/xhtml-1-0-transitional-xml-parsing-error-entity-nbsp-not-defined/3392/3\n     */\n    private _sanitiseText(text: string): string\n    {\n        return this._removeInvalidHtmlTags(text\n            .replace(/<br>/gi, '<br/>')\n            .replace(/<hr>/gi, '<hr/>')\n            .replace(/&nbsp;/gi, '&#160;'));\n    }\n\n    private _removeInvalidHtmlTags(input: string): string\n    {\n        // This regex finds \"<\" followed by anything except \">\" until the next \"<\" or end-of-string\n        // i.e., it finds broken tags like \"<br\" or \"<div id='x'\" that never close\n        const brokenTagPattern = /<[^>]*?(?=<|$)/g;\n\n        return input.replace(brokenTagPattern, '');\n    }\n}\n"],"names":[],"mappings":";;;;;;;;AAmKO,MAAM,iBAAiB,YAAA,CAM9B;AAAA,EA2BI,eAAe,IAAA,EACf;AACI,IAAA,MAAM,OAAA,GAAU,iBAAA,CAAmC,IAAA,EAAM,UAAU,CAAA;AAEnE,IAAA,KAAA,CAAM,SAAS,aAAa,CAAA;AA7BhC;AAAA,IAAA,IAAA,CAAyB,YAAA,GAAuB,UAAA;AA+B5C,IAAA,IAAI,QAAQ,YAAA,EACZ;AACI,MAAA,IAAA,CAAK,YAAA,GAAe,QAAQ,YAAA,YAAwB,YAAA,GAC9C,QAAQ,YAAA,GACR,IAAI,YAAA,CAAa,OAAA,CAAQ,YAAY,CAAA;AAAA,IAC/C;AAEA,IAAA,IAAA,CAAK,mBAAA,GAAsB,OAAA,CAAQ,mBAAA,IAAuB,aAAA,CAAc,cAAA,CAAe,mBAAA;AAAA,EAC3F;AAAA;AAAA,EAGU,YAAA,GACV;AACI,IAAA,MAAM,SAAS,IAAA,CAAK,OAAA;AACpB,IAAA,MAAM,SAAS,IAAA,CAAK,OAAA;AAEpB,IAAA,MAAM,eAAA,GAAkB,eAAA,CAAgB,IAAA,CAAK,IAAA,EAAM,KAAK,MAAuB,CAAA;AAE/E,IAAA,MAAM,EAAE,KAAA,EAAO,MAAA,EAAO,GAAI,eAAA;AAE1B,IAAA,MAAA,CAAO,IAAA,GAAQ,CAAC,MAAA,CAAO,EAAA,GAAK,KAAA;AAC5B,IAAA,MAAA,CAAO,IAAA,GAAO,OAAO,IAAA,GAAO,KAAA;AAC5B,IAAA,MAAA,CAAO,IAAA,GAAQ,CAAC,MAAA,CAAO,EAAA,GAAK,MAAA;AAC5B,IAAA,MAAA,CAAO,IAAA,GAAO,OAAO,IAAA,GAAO,MAAA;AAAA,EAChC;AAAA,EAEA,IAAa,IAAA,GACb;AACI,IAAA,OAAO,IAAA,CAAK,KAAA;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA4BA,IAAa,KAAK,IAAA,EAClB;AAEI,IAAA,MAAM,aAAA,GAAgB,IAAA,CAAK,aAAA,CAAc,IAAA,CAAK,UAAU,CAAA;AAGxD,IAAA,KAAA,CAAM,IAAA,GAAO,aAAA;AAAA,EACjB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,cAAc,IAAA,EACtB;AACI,IAAA,OAAO,IAAA,CAAK,sBAAA,CAAuB,IAAA,CAC9B,OAAA,CAAQ,UAAU,OAAO,CAAA,CACzB,OAAA,CAAQ,QAAA,EAAU,OAAO,CAAA,CACzB,OAAA,CAAQ,UAAA,EAAY,QAAQ,CAAC,CAAA;AAAA,EACtC;AAAA,EAEQ,uBAAuB,KAAA,EAC/B;AAGI,IAAA,MAAM,gBAAA,GAAmB,iBAAA;AAEzB,IAAA,OAAO,KAAA,CAAM,OAAA,CAAQ,gBAAA,EAAkB,EAAE,CAAA;AAAA,EAC7C;AACJ;;;;"}