/************************************************************* * * Copyright (c) 2018-2025 The MathJax Consortium * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * @file Implements the SvgMsubsup wrapper for the MmlMsubsup object * and the special cases SvgMsub and SvgMsup * * @author dpvc@mathjax.org (Davide Cervone) */ import { SVG } from '../../svg.js'; import { SvgWrapper, SvgWrapperClass } from '../Wrapper.js'; import { SvgWrapperFactory } from '../WrapperFactory.js'; import { SvgCharOptions, SvgVariantData, SvgDelimiterData, SvgFontData, SvgFontDataClass, } from '../FontData.js'; import { CommonMsub, CommonMsubClass, CommonMsubMixin, CommonMsup, CommonMsupClass, CommonMsupMixin, CommonMsubsup, CommonMsubsupClass, CommonMsubsupMixin, } from '../../common/Wrappers/msubsup.js'; import { MmlNode } from '../../../core/MmlTree/MmlNode.js'; import { SvgScriptbase, SvgScriptbaseNTD, SvgScriptbaseClass, } from './scriptbase.js'; import { MmlMsubsup, MmlMsub, MmlMsup, } from '../../../core/MmlTree/MmlNodes/msubsup.js'; /*****************************************************************/ /** * The SvgMsub interface for the SVG Msub wrapper * * @template N The HTMLElement node class * @template T The Text node class * @template D The Document class */ export interface SvgMsubNTD extends SvgScriptbaseNTD, CommonMsub< N, T, D, SVG, SvgWrapper, SvgWrapperFactory, SvgWrapperClass, SvgCharOptions, SvgVariantData, SvgDelimiterData, SvgFontData, SvgFontDataClass > {} /** * The SvgMsubClass interface for the SVG Msub wrapper * * @template N The HTMLElement node class * @template T The Text node class * @template D The Document class */ export interface SvgMsubClass extends SvgScriptbaseClass, CommonMsubClass< N, T, D, SVG, SvgWrapper, SvgWrapperFactory, SvgWrapperClass, SvgCharOptions, SvgVariantData, SvgDelimiterData, SvgFontData, SvgFontDataClass > { new ( factory: SvgWrapperFactory, node: MmlNode, parent?: SvgWrapper ): SvgMsubNTD; } /*****************************************************************/ /** * The SvgMsub wrapper class for the MmlMsub class */ export const SvgMsub = (function (): SvgMsubClass { const Base = CommonMsubMixin< N, T, D, SVG, SvgWrapper, SvgWrapperFactory, SvgWrapperClass, SvgCharOptions, SvgVariantData, SvgDelimiterData, SvgFontData, SvgFontDataClass, SvgMsubClass >(SvgScriptbase); // @ts-expect-error Avoid message about base constructors not having the same // type (they should both be SvgWrapper, but are thought of as // different by typescript) return class SvgMsub extends Base implements SvgMsubNTD { /** * @override */ public static kind = MmlMsub.prototype.kind; }; })(); /*****************************************************************/ /** * The SvgMsup interface for the SVG Msup wrapper * * @template N The HTMLElement node class * @template T The Text node class * @template D The Document class */ export interface SvgMsupNTD extends SvgScriptbaseNTD, CommonMsup< N, T, D, SVG, SvgWrapper, SvgWrapperFactory, SvgWrapperClass, SvgCharOptions, SvgVariantData, SvgDelimiterData, SvgFontData, SvgFontDataClass > {} /** * The SvgMsupClass interface for the SVG Msup wrapper * * @template N The HTMLElement node class * @template T The Text node class * @template D The Document class */ export interface SvgMsupClass extends SvgScriptbaseClass, CommonMsupClass< N, T, D, SVG, SvgWrapper, SvgWrapperFactory, SvgWrapperClass, SvgCharOptions, SvgVariantData, SvgDelimiterData, SvgFontData, SvgFontDataClass > { new ( factory: SvgWrapperFactory, node: MmlNode, parent?: SvgWrapper ): SvgMsupNTD; } /*****************************************************************/ /** * The SvgMsup wrapper class for the MmlMsup class */ export const SvgMsup = (function (): SvgMsupClass { const Base = CommonMsupMixin< N, T, D, SVG, SvgWrapper, SvgWrapperFactory, SvgWrapperClass, SvgCharOptions, SvgVariantData, SvgDelimiterData, SvgFontData, SvgFontDataClass, SvgMsupClass >(SvgScriptbase); // @ts-expect-error Avoid message about base constructors not having the same // type (they should both be SvgWrapper, but are thought of as // different by typescript) return class SvgMsup extends Base implements SvgMsupNTD { /** * @override */ public static kind = MmlMsup.prototype.kind; }; })(); /*****************************************************************/ /** * The SvgMglyph interface for the SVG Msubsup wrapper * * @template N The HTMLElement node class * @template T The Text node class * @template D The Document class */ export interface SvgMsubsupNTD extends SvgScriptbaseNTD, CommonMsubsup< N, T, D, SVG, SvgWrapper, SvgWrapperFactory, SvgWrapperClass, SvgCharOptions, SvgVariantData, SvgDelimiterData, SvgFontData, SvgFontDataClass > {} /** * The SvgMsubsupClass interface for the SVG Msubsup wrapper * * @template N The HTMLElement node class * @template T The Text node class * @template D The Document class */ export interface SvgMsubsupClass extends SvgScriptbaseClass, CommonMsubsupClass< N, T, D, SVG, SvgWrapper, SvgWrapperFactory, SvgWrapperClass, SvgCharOptions, SvgVariantData, SvgDelimiterData, SvgFontData, SvgFontDataClass > { new ( factory: SvgWrapperFactory, node: MmlNode, parent?: SvgWrapper ): SvgMsubsupNTD; } /*****************************************************************/ /** * The SvgMsubsup wrapper class for the MmlMsubsup class */ export const SvgMsubsup = (function (): SvgMsubsupClass { const Base = CommonMsubsupMixin< N, T, D, SVG, SvgWrapper, SvgWrapperFactory, SvgWrapperClass, SvgCharOptions, SvgVariantData, SvgDelimiterData, SvgFontData, SvgFontDataClass, SvgMsubsupClass >(SvgScriptbase); // @ts-expect-error Avoid message about base constructors not having the same // type (they should both be SvgWrapper, but are thought of as // different by typescript) return class SvgMsubsup extends Base implements SvgMsubsupNTD { /** * @override */ public static kind = MmlMsubsup.prototype.kind; /** * @override */ public toSVG(parents: N[]) { if (this.toEmbellishedSVG(parents)) return; const svg = this.standardSvgNodes(parents); const [base, sup, sub] = [this.baseChild, this.supChild, this.subChild]; const w = this.getBaseWidth(); const x = this.getAdjustedIc(); const [u, v] = this.getUVQ(); base.toSVG(svg); const tail = [svg[svg.length - 1]]; sup.toSVG(tail); sub.toSVG(tail); base.place(0, 0); sub.place(w + (this.baseIsChar ? 0 : x), v); sup.place(w + x, u); } }; })();