UNPKG

@wiris/mathtype-viewer

Version:

The MathType viewer renders all MathML and LaTeX-like formulas in a webpage using the MathType rendering engine.

332 lines (286 loc) 10.6 kB
import { configurationJson, StatusError } from "./services"; import Util from "@wiris/mathtype-html-integration-devkit/src/util"; // Helper types for Config below type Viewer = "none" | "image" | "mathml" | "latex"; type StringifiedBoolean = "true" | "false"; /** * Type representing all the configuration for the viewer. */ export interface Config { editorServicesRoot: string; editorServicesExtension: string; backendConfig: { wirispluginperformance: StringifiedBoolean; wiriseditormathmlattribute: string; wiriscustomheaders: object; wiriseditorparselatex: StringifiedBoolean; }; dpi: number; element: string; lang: string; viewer: Viewer; zoom: number; ignored_containers: string | null; } /** * Fallback values for the configurations that are not set. */ const defaultValues: Config = { editorServicesRoot: "https://www.wiris.net/demo/plugins/app/", editorServicesExtension: "", backendConfig: { wirispluginperformance: "true", wiriseditormathmlattribute: "data-mathml", wiriscustomheaders: {}, wiriseditorparselatex: "true", }, dpi: 96, element: "body", lang: "en", viewer: "none", zoom: 1, ignored_containers: null, }; /** * This class will handle the parameters defined by the user. */ export class Properties { private static instance: Properties | null = null; render: () => Promise<void> = async () => {}; // Get URL properties (retrocompatibility). config: Config = defaultValues; /** * Private constructor to avoid multiple instances of the class. * To instantiate the class, use the static method {@link Properties.getInstance}. */ private constructor() {} static async getInstance(): Promise<Properties> { if (!Properties.instance) { Properties.instance = new Properties(); await Properties.instance.initialize(); } return Properties.instance; } /** * Creates and sets up a new instance of class Properties */ private async initialize(): Promise<void> { if (!Properties.instance) { console.error("Properties.instance is not set"); return; } // Get URL parameters from <script> const pluginName = "WIRISplugins.js"; const script: HTMLScriptElement | null = document.querySelector(`script[src*="${pluginName}"]`); // If the absence of the script is an error maybe this should throw if (script) { this.setProperties(script, pluginName, Properties.instance); } await Properties.instance.checkServices(); // Get backend parameters calling the configurationjson service try { Properties.instance.config.backendConfig = await configurationJson( ["wirispluginperformance", "wiriseditormathmlattribute", "wiriscustomheaders", "wiriseditorparselatex"], Properties.instance.editorServicesRoot, Properties.instance.editorServicesExtension, false, ); // We'll always get a string from the wiriscustomheaders backend parameter. It needs to be converted to an object. Properties.instance.config.backendConfig.wiriscustomheaders = Util.convertStringToObject( Properties.instance.config.backendConfig.wiriscustomheaders, ); } catch (e) { if (e instanceof StatusError) { // Do nothing; leave default values. console.error(e); } else { throw e; } } } /** * Initialize properties from <script> * @param script * @param pluginName * @param instance */ private setProperties(script: HTMLScriptElement, pluginName: string, instance: Properties) { const pluginNamePosition: number = script.src.lastIndexOf(pluginName); const params: string = script.src.substring(pluginNamePosition + pluginName.length); const urlParams = new URLSearchParams(params); const dpi = urlParams.get("dpi"); if (dpi !== null && dpi !== undefined) { instance.config.dpi = +dpi; } const element = urlParams.get("element"); if (element !== null && element !== undefined) { instance.config.element = element; } const lang = urlParams.get("lang"); if (lang !== null && lang !== undefined) { instance.config.lang = lang; } const viewer = urlParams.get("viewer"); if (viewer !== null && viewer !== undefined) { instance.config.viewer = viewer as Viewer; } const zoom = urlParams.get("zoom"); if (zoom !== null && zoom !== undefined) { instance.config.zoom = +zoom; } const ignored_containers = urlParams.get("ignored_containers"); if (ignored_containers !== null && ignored_containers !== undefined) { instance.config.ignored_containers = ignored_containers; } } /** * Check if is inside Integrations Services * @deprecated This will be removed once the viewer uncouple from the integration services. */ private async checkServices() { const path = (document.currentScript as HTMLScriptElement).src; if (path.includes("integration/WIRISplugins") || path.includes("render/WIRISplugins")) { // If the path includes 'integration/WIRISplugins' use PHP Integrations Services or Moodle. this.config.editorServicesRoot = path.replace("render/WIRISplugins", "integration/WIRISplugins"); this.config.editorServicesExtension = ".php"; } else { try { // We want to know if we are using the integrations java services. // So we call the configurationjson service assuming that the path is the one for the Java services. // If we get an answer, we know we are using the Java services, // otherwise, and since PHP has already been discarded, we'll set the services to wiris.net await configurationJson(["wirispluginperformance"], path, "", true); this.config.editorServicesRoot = path; this.config.editorServicesExtension = ""; } catch (e) { // We do noting. // Getting here means that we are not using php nor Java services so we'll stick to the wiris.net default. } } } get editorServicesRoot(): string { return this.config.editorServicesRoot || defaultValues.editorServicesRoot; } set editorServicesRoot(editorServicesRoot: string) { this.config.editorServicesRoot = editorServicesRoot; this.render(); } get editorServicesExtension(): string { return this.config.editorServicesExtension || defaultValues.editorServicesExtension; } set editorServicesExtension(editorServicesExtension: string) { this.config.editorServicesExtension = editorServicesExtension; this.render(); } /** * Return the language. * In order of priority, the first of the following that is set is returned: * - The lang parameter set in the <script> (WIRISplugin.js?lang=...) * - The HTML document language (<html lang=...>). * - The language of the browser. * - English, by default. * @returns {string} Encoded language string. */ get lang(): string { const configLang = this.config.lang === "inherit" ? null : this.config.lang; return configLang || document.getElementsByTagName("html")[0].lang || navigator.language || defaultValues.lang; } set lang(lang: string) { this.config.lang = lang; this.render(); } /** * Return the viewer mode for the MathML. * In order of priority, the first of the following that is set is returned: * - The viewer parameter set in the <script> (WIRISplugin.js?viewer=...) * - none, by default. */ get viewer(): Viewer { return this.config.viewer || defaultValues.viewer; } set viewer(viewer: Viewer) { this.config.viewer = viewer; this.render(); } /** * Return the dpi of the images. * In order of priority, the first of the following that is set is returned: * - The dpi parameter set in the <script> (WIRISplugin.js?dpi=...) * - 96, by default. */ get dpi(): number { return this.config.dpi || defaultValues.dpi; } set dpi(dpi: number) { this.config.dpi = dpi; this.render(); } /** * Return the zoom of the images. * In order of priority, the first of the following that is set is returned: * - The zoom parameter set in the <script> (WIRISplugin.js?zoom=...) * - 1, by default. */ get zoom(): number { return this.config.zoom || defaultValues.zoom; } set zoom(zoom: number) { this.config.zoom = zoom; this.render(); } /** * Return the element in which to render formulas. * In order of priority, the first of the following that is set is returned: * - The zoom parameter set in the <script> (WIRISplugin.js?element=...) * - 'body', by default. */ get element(): string { return this.config.element || defaultValues.element; } set element(element: string) { this.config.element = element; this.render(); } /** * Return the Wiris plugin performance. * In order of priority, the first of the following that is set is returned: * - The backend configuration of the parameter. * - true, by default. */ get wirispluginperformance(): StringifiedBoolean { return this.config.backendConfig.wirispluginperformance || defaultValues.backendConfig.wirispluginperformance; } set wirispluginperformance(wirispluginperformance: StringifiedBoolean) { this.config.backendConfig.wirispluginperformance = wirispluginperformance; this.render(); } /** * Return the Wiris MathML attribute. * In order of priority, the first of the following that is set is returned: * - The backend configuration of the parameter. * - data-mathml, by default. */ get wiriseditormathmlattribute(): string { return ( this.config.backendConfig.wiriseditormathmlattribute || defaultValues.backendConfig.wiriseditormathmlattribute ); } set wiriseditormathmlattribute(wiriseditormathmlattribute: string) { this.config.backendConfig.wiriseditormathmlattribute = wiriseditormathmlattribute; this.render(); } get wiriseditorparselatex(): StringifiedBoolean { return this.config.backendConfig.wiriseditorparselatex || defaultValues.backendConfig.wiriseditorparselatex; } set wiriseditorparselatex(wiriseditorparselatex: StringifiedBoolean) { this.config.backendConfig.wiriseditorparselatex = wiriseditorparselatex; this.render(); } get ignored_containers(): string | null { return this.config.ignored_containers ?? defaultValues.ignored_containers; } set ignored_containers(ignored_containers: string) { this.config.ignored_containers = ignored_containers; this.render(); } }