diff --git a/.eslintrc b/.eslintrc index c85bf67c..7535811f 100644 --- a/.eslintrc +++ b/.eslintrc @@ -25,6 +25,7 @@ "keyword-spacing": 2, "linebreak-style": [2, "unix"], "max-len": [2, 84, 4, { "ignoreUrls": true, "ignorePattern": "\\brequire\\([\"']|eslint-disable" }], + "new-cap": 2, "no-alert": 2, "no-array-constructor": 2, "no-console": 2, diff --git a/dockers/screenshotter/screenshotter.js b/dockers/screenshotter/screenshotter.js index 3aa0d66f..b53d26b0 100644 --- a/dockers/screenshotter/screenshotter.js +++ b/dockers/screenshotter/screenshotter.js @@ -12,7 +12,7 @@ const selenium = require("selenium-webdriver"); const firefox = require("selenium-webdriver/firefox"); const webpack = require('webpack'); -const webpackDevServer = require("webpack-dev-server"); +const WebpackDevServer = require("webpack-dev-server"); const webpackConfig = require("../../webpack.dev")[0]; const data = require("../../test/screenshotter/ss_data"); @@ -161,7 +161,7 @@ function startServer() { } const port = Math.floor(Math.random() * (maxPort - minPort)) + minPort; const compiler = webpack(webpackConfig); - const wds = new webpackDevServer(compiler, webpackConfig.devServer); + const wds = new WebpackDevServer(compiler, webpackConfig.devServer); const server = wds.listen(port); server.once("listening", function() { devServer = wds; diff --git a/dockers/texcmp/texcmp.js b/dockers/texcmp/texcmp.js index 3e49da60..8abb6100 100644 --- a/dockers/texcmp/texcmp.js +++ b/dockers/texcmp/texcmp.js @@ -268,5 +268,6 @@ function fftImage(image) { // Create a new matrix of preconfigured dimensions, initialized to zero function createMatrix() { const array = new Float64Array(alignWidth * alignHeight); + /* eslint-disable-next-line new-cap */ return new ndarray(array, [alignWidth, alignHeight]); } diff --git a/katex.js b/katex.js index 93a80b79..cb86390d 100644 --- a/katex.js +++ b/katex.js @@ -14,7 +14,14 @@ import Settings from "./src/Settings"; import {buildTree, buildHTMLTree} from "./src/buildTree"; import parseTree from "./src/parseTree"; import buildCommon from "./src/buildCommon"; -import domTree from "./src/domTree"; +import { + Span, + Anchor, + SymbolNode, + SvgNode, + PathNode, + LineNode, +} from "./src/domTree"; import utils from "./src/utils"; import type {SettingsOptions} from "./src/Settings"; @@ -90,7 +97,7 @@ const renderError = function( throw error; } const node = buildCommon.makeSpan(["katex-error"], - [new domTree.symbolNode(expression)]); + [new SymbolNode(expression)]); node.setAttribute("title", error.toString()); node.setAttribute("style", `color:${options.errorColor}`); return node; @@ -196,5 +203,12 @@ export default { * The internal tree representation is unstable and is very likely * to change. Use at your own risk. */ - __domTree: domTree, + __domTree: { + Span, + Anchor, + SymbolNode, + SvgNode, + PathNode, + LineNode, + }, }; diff --git a/src/buildCommon.js b/src/buildCommon.js index 5ba78f4c..f21d990d 100644 --- a/src/buildCommon.js +++ b/src/buildCommon.js @@ -5,13 +5,13 @@ * different kinds of domTree nodes in a consistent manner. */ -import domTree from "./domTree"; +import {SymbolNode, Anchor, Span, PathNode, SvgNode} from "./domTree"; import {getCharacterMetrics} from "./fontMetrics"; import symbols, {ligatures} from "./symbols"; import utils from "./utils"; import {wideCharacterFont} from "./wide-character"; import {calculateSize} from "./units"; -import * as tree from "./tree"; +import {DocumentFragment} from "./tree"; import type Options from "./Options"; import type {ParseNode} from "./parseNode"; @@ -65,7 +65,7 @@ const makeSymbol = function( mode: Mode, options?: Options, classes?: string[], -): domTree.symbolNode { +): SymbolNode { const lookup = lookupSymbol(value, fontName, mode); const metrics = lookup.metrics; value = lookup.value; @@ -76,7 +76,7 @@ const makeSymbol = function( if (mode === "text") { italic = 0; } - symbolNode = new domTree.symbolNode( + symbolNode = new SymbolNode( value, metrics.height, metrics.depth, italic, metrics.skew, metrics.width, classes); } else { @@ -84,7 +84,7 @@ const makeSymbol = function( typeof console !== "undefined" && console.warn( "No character metrics for '" + value + "' in style '" + fontName + "'"); - symbolNode = new domTree.symbolNode(value, 0, 0, 0, 0, 0, classes); + symbolNode = new SymbolNode(value, 0, 0, 0, 0, 0, classes); } if (options) { @@ -112,7 +112,7 @@ const mathsym = function( mode: Mode, options?: Options, classes?: string[] = [], -): domTree.symbolNode { +): SymbolNode { // Decide what font to render the symbol in by its entry in the symbols // table. // Have a special case for when the value = \ because the \ is used as a @@ -141,7 +141,7 @@ const mathDefault = function( options: Options, classes: string[], type: NodeType, -): domTree.symbolNode { +): SymbolNode { if (type === "mathord") { const fontLookup = mathit(value, mode, options, classes); return makeSymbol(value, fontLookup.fontName, mode, options, @@ -235,7 +235,7 @@ const makeOrd = function( group: ParseNode, options: Options, type: "mathord" | "textord", -): HtmlDocumentFragment | domTree.symbolNode { +): HtmlDocumentFragment | SymbolNode { const mode = group.mode; const text = group.text; @@ -309,7 +309,7 @@ const tryCombineChars = function(chars: HtmlDomNode[]): HtmlDomNode[] { * children. */ const sizeElementFromChildren = function( - elem: DomSpan | domTree.anchor | HtmlDocumentFragment, + elem: DomSpan | Anchor | HtmlDocumentFragment, ) { let height = 0; let depth = 0; @@ -347,7 +347,7 @@ const makeSpan = function( options?: Options, style?: CssStyle, ): DomSpan { - const span = new domTree.span(classes, children, options, style); + const span = new Span(classes, children, options, style); sizeElementFromChildren(span); @@ -358,10 +358,10 @@ const makeSpan = function( // This is also a separate method for typesafety. const makeSvgSpan = ( classes?: string[], - children?: domTree.svgNode[], + children?: SvgNode[], options?: Options, style?: CssStyle, -): SvgSpan => new domTree.span(classes, children, options, style); +): SvgSpan => new Span(classes, children, options, style); const makeLineSpan = function( className: string, @@ -385,7 +385,7 @@ const makeAnchor = function( children: HtmlDomNode[], options: Options, ) { - const anchor = new domTree.anchor(href, classes, children, options); + const anchor = new Anchor(href, classes, children, options); sizeElementFromChildren(anchor); @@ -398,7 +398,7 @@ const makeAnchor = function( const makeFragment = function( children: HtmlDomNode[], ): HtmlDocumentFragment { - const fragment = new tree.documentFragment(children); + const fragment = new DocumentFragment(children); sizeElementFromChildren(fragment); @@ -594,7 +594,7 @@ const makeVList = function(params: VListParam, options: Options): DomSpan { // Safari wants the first row to have inline content; otherwise it // puts the bottom of the *second* row on the baseline. - const topStrut = makeSpan(["vlist-s"], [new domTree.symbolNode("\u200b")]); + const topStrut = makeSpan(["vlist-s"], [new SymbolNode("\u200b")]); rows = [makeSpan(["vlist-r"], [vlist, topStrut]), makeSpan(["vlist-r"], [depthStrut])]; @@ -762,8 +762,8 @@ const svgData: { const staticSvg = function(value: string, options: Options): SvgSpan { // Create a span with inline SVG for the element. const [pathName, width, height] = svgData[value]; - const path = new domTree.pathNode(pathName); - const svgNode = new domTree.svgNode([path], { + const path = new PathNode(pathName); + const svgNode = new SvgNode([path], { "width": width + "em", "height": height + "em", // Override CSS rule `.katex svg { width: 100% }` diff --git a/src/buildHTML.js b/src/buildHTML.js index 57bb5fec..6ba68e31 100644 --- a/src/buildHTML.js +++ b/src/buildHTML.js @@ -9,12 +9,12 @@ import ParseError from "./ParseError"; import Style from "./Style"; import buildCommon from "./buildCommon"; -import domTree from "./domTree"; +import {Anchor} from "./domTree"; import utils, {assert} from "./utils"; import {checkNodeType} from "./parseNode"; import {spacings, tightSpacings} from "./spacingData"; import {_htmlGroupBuilders as groupBuilders} from "./defineFunction"; -import * as tree from "./tree"; +import {DocumentFragment} from "./tree"; import type Options from "./Options"; import type {AnyParseNode} from "./parseNode"; @@ -91,7 +91,7 @@ export const buildExpression = function( const rawGroups: HtmlDomNode[] = []; for (let i = 0; i < expression.length; i++) { const output = buildGroup(expression[i], options); - if (output instanceof tree.documentFragment) { + if (output instanceof DocumentFragment) { const children: HtmlDomNode[] = output.children; rawGroups.push(...children); } else { @@ -190,8 +190,8 @@ const getOutermostNode = function( node: HtmlDomNode, side: Side, ): HtmlDomNode { - if (node instanceof tree.documentFragment || - node instanceof domTree.anchor) { + if (node instanceof DocumentFragment || + node instanceof Anchor) { const children = node.children; if (children.length) { if (side === "right") { diff --git a/src/delimiter.js b/src/delimiter.js index 8b61a109..3bad853f 100644 --- a/src/delimiter.js +++ b/src/delimiter.js @@ -24,7 +24,7 @@ import ParseError from "./ParseError"; import Style from "./Style"; -import domTree from "./domTree"; +import {PathNode, SvgNode, SymbolNode} from "./domTree"; import buildCommon from "./buildCommon"; import {getCharacterMetrics} from "./fontMetrics"; import symbols from "./symbols"; @@ -125,7 +125,7 @@ const mathrmSize = function( size: number, mode: Mode, options: Options, -): domTree.symbolNode { +): SymbolNode { return buildCommon.makeSymbol(value, "Size" + size + "-Regular", mode, options); }; @@ -391,9 +391,9 @@ const sqrtSvg = function( -294.333-240-727l-212 -643 -85 170c-4-3.333-8.333-7.667-13 -13l-13-13l77-155 77-156c66 199.333 139 419.667 219 661 l218 661zM702 ${vbPad}H400000v40H742z`; } - const pathNode = new domTree.pathNode(sqrtName, alternate); + const pathNode = new PathNode(sqrtName, alternate); - const svg = new domTree.svgNode([pathNode], { + const svg = new SvgNode([pathNode], { // Note: 1000:1 ratio of viewBox to document em width. "width": "400em", "height": height + "em", diff --git a/src/domTree.js b/src/domTree.js index d39a13f9..da4aa4db 100644 --- a/src/domTree.js +++ b/src/domTree.js @@ -15,7 +15,7 @@ import {scriptFromCodepoint} from "./unicodeScripts"; import utils from "./utils"; import svgGeometry from "./svgGeometry"; import type Options from "./Options"; -import * as tree from "./tree"; +import {DocumentFragment} from "./tree"; import type {VirtualNode} from "./tree"; @@ -139,12 +139,12 @@ export interface HtmlDomNode extends VirtualNode { } // Span wrapping other DOM nodes. -export type DomSpan = span; +export type DomSpan = Span; // Span wrapping an SVG node. -export type SvgSpan = span; +export type SvgSpan = Span; -export type SvgChildNode = pathNode | lineNode; -export type documentFragment = tree.documentFragment; +export type SvgChildNode = PathNode | LineNode; +export type documentFragment = DocumentFragment; /** @@ -156,7 +156,7 @@ export type documentFragment = tree.documentFragment; * otherwise. This typesafety is important when HTML builders access a span's * children. */ -class span implements HtmlDomNode { +export class Span implements HtmlDomNode { children: ChildType[]; attributes: {[string]: string}; classes: string[]; @@ -211,7 +211,7 @@ class span implements HtmlDomNode { * This node represents an anchor () element with a hyperlink. See `span` * for further details. */ -class anchor implements HtmlDomNode { +export class Anchor implements HtmlDomNode { children: HtmlDomNode[]; attributes: {[string]: string}; classes: string[]; @@ -265,7 +265,7 @@ const iCombinations = { * to a single text node, or a span with a single text node in it, depending on * whether it has CSS classes, styles, or needs italic correction. */ -class symbolNode implements HtmlDomNode { +export class SymbolNode implements HtmlDomNode { text: string; height: number; depth: number; @@ -319,7 +319,7 @@ class symbolNode implements HtmlDomNode { tryCombine(sibling: HtmlDomNode): boolean { if (!sibling - || !(sibling instanceof symbolNode) + || !(sibling instanceof SymbolNode) || this.italic > 0 || createClass(this.classes) !== createClass(sibling.classes) || this.skew !== sibling.skew @@ -427,7 +427,7 @@ class symbolNode implements HtmlDomNode { /** * SVG nodes are used to render stretchy wide elements. */ -class svgNode implements VirtualNode { +export class SvgNode implements VirtualNode { children: SvgChildNode[]; attributes: {[string]: string}; @@ -476,7 +476,7 @@ class svgNode implements VirtualNode { } } -class pathNode implements VirtualNode { +export class PathNode implements VirtualNode { pathName: string; alternate: ?string; @@ -507,7 +507,7 @@ class pathNode implements VirtualNode { } } -class lineNode implements VirtualNode { +export class LineNode implements VirtualNode { attributes: {[string]: string}; constructor(attributes?: {[string]: string}) { @@ -545,8 +545,8 @@ class lineNode implements VirtualNode { export function assertSymbolDomNode( group: HtmlDomNode, -): symbolNode { - if (group instanceof symbolNode) { +): SymbolNode { + if (group instanceof SymbolNode) { return group; } else { throw new Error(`Expected symbolNode but got ${String(group)}.`); @@ -555,19 +555,10 @@ export function assertSymbolDomNode( export function assertSpan( group: HtmlDomNode, -): span { - if (group instanceof span) { +): Span { + if (group instanceof Span) { return group; } else { throw new Error(`Expected span but got ${String(group)}.`); } } - -export default { - span, - anchor, - symbolNode, - svgNode, - pathNode, - lineNode, -}; diff --git a/src/functions/color.js b/src/functions/color.js index 0cfc24a9..35d1c390 100644 --- a/src/functions/color.js +++ b/src/functions/color.js @@ -18,7 +18,7 @@ const htmlBuilder = (group, options) => { // To accomplish this, we wrap the results in a fragment, so the inner // elements will be able to directly interact with their neighbors. For // example, `\color{red}{2 +} 3` has the same spacing as `2 + 3` - return new buildCommon.makeFragment(elements); + return buildCommon.makeFragment(elements); }; const mathmlBuilder = (group, options) => { diff --git a/src/functions/href.js b/src/functions/href.js index 697de3ea..4be210a3 100644 --- a/src/functions/href.js +++ b/src/functions/href.js @@ -28,7 +28,7 @@ defineFunction({ }, htmlBuilder: (group, options) => { const elements = html.buildExpression(group.body, options, false); - return new buildCommon.makeAnchor(group.href, [], elements, options); + return buildCommon.makeAnchor(group.href, [], elements, options); }, mathmlBuilder: (group, options) => { const math = mml.buildExpressionRow(group.body, options); diff --git a/src/functions/htmlmathml.js b/src/functions/htmlmathml.js index 50f4c7e3..5c08bb58 100644 --- a/src/functions/htmlmathml.js +++ b/src/functions/htmlmathml.js @@ -26,7 +26,7 @@ defineFunction({ options, false ); - return new buildCommon.makeFragment(elements); + return buildCommon.makeFragment(elements); }, mathmlBuilder: (group, options) => { return mml.buildExpressionRow(group.mathml, options); diff --git a/src/functions/mathchoice.js b/src/functions/mathchoice.js index 4664d575..a8e2f5e1 100644 --- a/src/functions/mathchoice.js +++ b/src/functions/mathchoice.js @@ -41,7 +41,7 @@ defineFunction({ options, false ); - return new buildCommon.makeFragment(elements); + return buildCommon.makeFragment(elements); }, mathmlBuilder: (group, options) => { const body = chooseMathStyle(group, options); diff --git a/src/functions/op.js b/src/functions/op.js index a89a0adc..16a14cfd 100644 --- a/src/functions/op.js +++ b/src/functions/op.js @@ -2,7 +2,7 @@ // Limits, symbols import defineFunction, {ordargument} from "../defineFunction"; import buildCommon from "../buildCommon"; -import domTree from "../domTree"; +import {SymbolNode} from "../domTree"; import * as mathMLTree from "../mathMLTree"; import utils from "../utils"; import Style from "../Style"; @@ -91,7 +91,7 @@ export const htmlBuilder: HtmlBuilderSupSub<"op"> = (grp, options) => { } else if (group.body) { // If this is a list, compose that list. const inner = html.buildExpression(group.body, options, true); - if (inner.length === 1 && inner[0] instanceof domTree.symbolNode) { + if (inner.length === 1 && inner[0] instanceof SymbolNode) { base = inner[0]; base.classes[0] = "mop"; // replace old mclass } else { @@ -112,7 +112,7 @@ export const htmlBuilder: HtmlBuilderSupSub<"op"> = (grp, options) => { // If content of op is a single symbol, shift it vertically. let baseShift = 0; let slant = 0; - if ((base instanceof domTree.symbolNode + if ((base instanceof SymbolNode || group.name === "\\oiint" || group.name === "\\oiiint") && !group.suppressBaseShift) { // We suppress the shift of the base of \overset and \underset. Otherwise, diff --git a/src/functions/operatorname.js b/src/functions/operatorname.js index 5764ed94..57b8b948 100644 --- a/src/functions/operatorname.js +++ b/src/functions/operatorname.js @@ -2,7 +2,7 @@ import defineFunction, {ordargument} from "../defineFunction"; import buildCommon from "../buildCommon"; import mathMLTree from "../mathMLTree"; -import domTree from "../domTree"; +import {SymbolNode} from "../domTree"; import * as html from "../buildHTML"; import * as mml from "../buildMathML"; @@ -46,7 +46,7 @@ defineFunction({ for (let i = 0; i < expression.length; i++) { const child = expression[i]; - if (child instanceof domTree.symbolNode) { + if (child instanceof SymbolNode) { // Per amsopn package, // change minus to hyphen and \ast to asterisk child.text = child.text.replace(/\u2212/, "-") diff --git a/src/functions/phantom.js b/src/functions/phantom.js index ad74f97b..626479a6 100644 --- a/src/functions/phantom.js +++ b/src/functions/phantom.js @@ -30,7 +30,7 @@ defineFunction({ // \phantom isn't supposed to affect the elements it contains. // See "color" for more details. - return new buildCommon.makeFragment(elements); + return buildCommon.makeFragment(elements); }, mathmlBuilder: (group, options) => { const inner = mml.buildExpression(group.body, options); diff --git a/src/functions/sqrt.js b/src/functions/sqrt.js index 6351dddf..11098dbe 100644 --- a/src/functions/sqrt.js +++ b/src/functions/sqrt.js @@ -5,7 +5,7 @@ import mathMLTree from "../mathMLTree"; import delimiter from "../delimiter"; import Style from "../Style"; -import * as tree from "../tree"; +import {DocumentFragment} from "../tree"; import * as html from "../buildHTML"; import * as mml from "../buildMathML"; @@ -39,7 +39,7 @@ defineFunction({ // Some groups can return document fragments. Handle those by wrapping // them in a span. - if (inner instanceof tree.documentFragment) { + if (inner instanceof DocumentFragment) { inner = buildCommon.makeSpan([], [inner], options); } diff --git a/src/functions/supsub.js b/src/functions/supsub.js index bb916372..2769f851 100644 --- a/src/functions/supsub.js +++ b/src/functions/supsub.js @@ -1,7 +1,7 @@ // @flow import {defineFunctionBuilders} from "../defineFunction"; import buildCommon from "../buildCommon"; -import domTree from "../domTree"; +import {SymbolNode} from "../domTree"; import mathMLTree from "../mathMLTree"; import utils from "../utils"; import Style from "../Style"; @@ -117,7 +117,7 @@ defineFunctionBuilders({ const isOiint = group.base && group.base.type === "op" && group.base.name && (group.base.name === "\\oiint" || group.base.name === "\\oiiint"); - if (base instanceof domTree.symbolNode || isOiint) { + if (base instanceof SymbolNode || isOiint) { // $FlowFixMe marginLeft = -base.italic + "em"; } diff --git a/src/mathMLTree.js b/src/mathMLTree.js index 2761db34..971d1a99 100644 --- a/src/mathMLTree.js +++ b/src/mathMLTree.js @@ -10,7 +10,7 @@ */ import utils from "./utils"; -import * as tree from "./tree"; +import {DocumentFragment} from "./tree"; import type {VirtualNode} from "./tree"; @@ -31,9 +31,9 @@ export interface MathDomNode extends VirtualNode { toText(): string; } -export type documentFragment = tree.documentFragment; +export type documentFragment = DocumentFragment; export function newDocumentFragment(children: MathDomNode[]): documentFragment { - return new tree.documentFragment(children); + return new DocumentFragment(children); } /** diff --git a/src/stretchy.js b/src/stretchy.js index 7d16122b..9769f682 100644 --- a/src/stretchy.js +++ b/src/stretchy.js @@ -5,7 +5,7 @@ * and other CSS trickery. */ -import domTree from "./domTree"; +import {LineNode, PathNode, SvgNode} from "./domTree"; import buildCommon from "./buildCommon"; import mathMLTree from "./mathMLTree"; import utils from "./utils"; @@ -220,8 +220,8 @@ const svgSpan = function( pathName = "tilde" + imgIndex; } } - const path = new domTree.pathNode(pathName); - const svgNode = new domTree.svgNode([path], { + const path = new PathNode(pathName); + const svgNode = new SvgNode([path], { "width": "100%", "height": height + "em", "viewBox": `0 0 ${viewBoxWidth} ${viewBoxHeight}`, @@ -260,9 +260,9 @@ const svgSpan = function( } for (let i = 0; i < numSvgChildren; i++) { - const path = new domTree.pathNode(paths[i]); + const path = new PathNode(paths[i]); - const svgNode = new domTree.svgNode([path], { + const svgNode = new SvgNode([path], { "width": "400em", "height": height + "em", "viewBox": `0 0 ${viewBoxWidth} ${viewBoxHeight}`, @@ -326,7 +326,7 @@ const encloseSpan = function( const lines = []; if (/^[bx]cancel$/.test(label)) { - lines.push(new domTree.lineNode({ + lines.push(new LineNode({ "x1": "0", "y1": "0", "x2": "100%", @@ -336,7 +336,7 @@ const encloseSpan = function( } if (/^x?cancel$/.test(label)) { - lines.push(new domTree.lineNode({ + lines.push(new LineNode({ "x1": "0", "y1": "100%", "x2": "100%", @@ -345,7 +345,7 @@ const encloseSpan = function( })); } - const svgNode = new domTree.svgNode(lines, { + const svgNode = new SvgNode(lines, { "width": "100%", "height": totalHeight + "em", }); diff --git a/src/tree.js b/src/tree.js index 221ed8d1..32d05cd4 100644 --- a/src/tree.js +++ b/src/tree.js @@ -18,7 +18,7 @@ export interface VirtualNode { * placed into the DOM doesn't have any representation itself. It only contains * children and doesn't have any DOM node properties. */ -export class documentFragment +export class DocumentFragment implements HtmlDomNode, MathDomNode { children: ChildType[]; // HtmlDomNode diff --git a/test/helpers.js b/test/helpers.js index 0b9ae26d..afea19c7 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -31,6 +31,7 @@ const printActualErrorMessage = error => { const {message, stack} = separateMessageFromStack(error.stack); return ( 'Instead, it threw:\n' + + /* eslint-disable-next-line new-cap */ RECEIVED_COLOR( ` ${message}` + formatStackTrace(