JlatexmathResourcesJs.java

package net.sourceforge.plantuml.teavm.js;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Base64;

import org.scilab.forge.jlatexmath.TeXResourceProvider;
import org.teavm.jso.JSBody;

// ::remove file when JAVA8 or __MIT__ or __EPL__ or __BSD__ or __ASL__ or __LGPL__

/**
 * Where JLaTeXMath finds its resources (the XML files and the glyph outlines)
 * in the browser build, which has no class loader: in the global
 * {@code PLANTUML_JLATEXMATH}, a map from the path of the resource (under
 * {@code org/scilab/forge/jlatexmath/}) to its content in Base64. The map is
 * made by {@code jlatexmath.js}, generated by {@code JlatexmathJsGenerator} and
 * loaded on demand (see {@code MathResources}), or registered by the host.
 */
public final class JlatexmathResourcesJs implements TeXResourceProvider {

	/** The folder of the resources of the library, in the class path. */
	static final String PACKAGE = "org/scilab/forge/jlatexmath/";

	// Same lookup as the other generated scripts (emoji.js, themes.js), so that a
	// Web Worker can register the data too
	private static final String GLOBAL = "var g = (typeof globalThis !== 'undefined') ? globalThis"
			+ " : ((typeof self !== 'undefined') ? self : this);";

	public JlatexmathResourcesJs() {
	}

	/** Whether the data of the library is registered. */
	public static boolean isAvailable() {
		return jsHasData();
	}

	@Override
	public InputStream open(String name) throws IOException {
		if (name.startsWith(PACKAGE) == false)
			return null;

		final String base64 = jsGet(name.substring(PACKAGE.length()));
		if (base64 == null)
			return null;

		return new ByteArrayInputStream(Base64.getDecoder().decode(base64));
	}

	@JSBody(script = GLOBAL + "return !!(g && g.PLANTUML_JLATEXMATH);")
	private static native boolean jsHasData();

	@JSBody(params = "path", script = GLOBAL + "var d = g && g.PLANTUML_JLATEXMATH;"
			+ "return (d && d[path]) ? d[path] : null;")
	private static native String jsGet(String path);

}