@pie-lib/math-input-mathlive 1.0.9 → 1.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/lib/__tests__/keypad-label.test.js +75 -1
- package/lib/__tests__/keypad-label.test.js.map +1 -1
- package/lib/__tests__/latex-bridge.test.js +29 -0
- package/lib/__tests__/latex-bridge.test.js.map +1 -1
- package/lib/__tests__/mathlive-instance.test.js +42 -0
- package/lib/__tests__/mathlive-instance.test.js.map +1 -1
- package/lib/__tests__/mount-race.test.js +1 -0
- package/lib/__tests__/mount-race.test.js.map +1 -1
- package/lib/keypad/index.js +11 -13
- package/lib/keypad/index.js.map +1 -1
- package/lib/keys/geometry.js +7 -4
- package/lib/keys/geometry.js.map +1 -1
- package/lib/latex-bridge.js +18 -3
- package/lib/latex-bridge.js.map +1 -1
- package/lib/mathlive-instance.js +56 -1
- package/lib/mathlive-instance.js.map +1 -1
- package/lib/mf/common-styles.js +33 -4
- package/lib/mf/common-styles.js.map +1 -1
- package/lib/mf/input.js +4 -0
- package/lib/mf/input.js.map +1 -1
- package/lib/mf/static.js +4 -0
- package/lib/mf/static.js.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/keypad-label.test.jsx +76 -1
- package/src/__tests__/latex-bridge.test.js +21 -0
- package/src/__tests__/mathlive-instance.test.js +47 -0
- package/src/__tests__/mount-race.test.jsx +1 -0
- package/src/keypad/index.jsx +11 -13
- package/src/keys/geometry.js +7 -2
- package/src/latex-bridge.js +18 -3
- package/src/mathlive-instance.js +61 -0
- package/src/mf/common-styles.js +33 -4
- package/src/mf/input.jsx +5 -1
- package/src/mf/static.jsx +5 -1
package/README.md
CHANGED
|
@@ -75,7 +75,7 @@ widget do not port and need a redesign (`mf.getElementInfo()` exposes per-elemen
|
|
|
75
75
|
- **Stylesheets: import both, once, in the host app.**
|
|
76
76
|
|
|
77
77
|
```js
|
|
78
|
-
import 'mathlive/fonts.css';
|
|
78
|
+
import 'mathlive/fonts.css'; // KaTeX @font-face rules
|
|
79
79
|
import 'mathlive/static.css'; // REQUIRED for convertLatexToMarkup output
|
|
80
80
|
```
|
|
81
81
|
|
|
@@ -128,7 +128,7 @@ widget do not port and need a redesign (`mf.getElementInfo()` exposes per-elemen
|
|
|
128
128
|
|
|
129
129
|
If you neither import the stylesheet nor call `configureFonts`, the package
|
|
130
130
|
falls back to a **version-pinned CDN** - `https://unpkg.com/mathlive@<engine
|
|
131
|
-
|
|
131
|
+
version>/fonts` - so those glyph-dependent symbols still render. Serve the
|
|
132
132
|
fonts yourself to avoid the third-party request.
|
|
133
133
|
|
|
134
134
|
- **Custom macros.** `PIE_MACROS` covers the pie-specific commands the MathQuill
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
|
|
3
5
|
var _latexBridge = require("../latex-bridge");
|
|
4
6
|
/**
|
|
5
7
|
* Keys use empty groups to show a command's shape (`\frac{}{}`, `x^{}`).
|
|
@@ -10,7 +12,9 @@ describe('keypad label display normalisation', function () {
|
|
|
10
12
|
it('gives empty groups a visible glyph', function () {
|
|
11
13
|
var out = (0, _latexBridge.withVisibleEmptySlots)('\\frac{}{}');
|
|
12
14
|
expect(out).not.toEqual('\\frac{}{}');
|
|
13
|
-
|
|
15
|
+
// a \rule, not a glyph: font metrics for a substituted glyph do not match
|
|
16
|
+
// MathLive's, which left stretchy accents narrower than the box
|
|
17
|
+
expect(out).toContain('\\rule');
|
|
14
18
|
expect(out).toContain('pie-empty');
|
|
15
19
|
});
|
|
16
20
|
it('handles every empty-group key shape', function () {
|
|
@@ -22,6 +26,76 @@ describe('keypad label display normalisation', function () {
|
|
|
22
26
|
// e.g. \frac{x}{ }
|
|
23
27
|
expect((0, _latexBridge.withVisibleEmptySlots)('\\frac{x}{ }')).toContain('pie-empty');
|
|
24
28
|
});
|
|
29
|
+
|
|
30
|
+
// MathQuill needed a nested \overline{} to draw the empty box. MathLive
|
|
31
|
+
// renders that as a real line, so those labels showed a spurious bar (a line
|
|
32
|
+
// under the arrows, and a straight line instead of the arc).
|
|
33
|
+
it('accent keys do not carry the nested-overline box hack', function () {
|
|
34
|
+
// eslint-disable-next-line global-require
|
|
35
|
+
var geometry = require('../keys/geometry');
|
|
36
|
+
Object.values(geometry).forEach(function (key) {
|
|
37
|
+
if (key && typeof key.latex === 'string') {
|
|
38
|
+
expect(key.latex).not.toContain('\\overline{}}');
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
it('an accent over an empty slot still gets a visible box', function () {
|
|
43
|
+
['\\overleftrightarrow{}', '\\overarc{}'].forEach(function (latex) {
|
|
44
|
+
var out = (0, _latexBridge.withVisibleEmptySlots)(latex);
|
|
45
|
+
expect(out).toContain('pie-empty');
|
|
46
|
+
expect(out).not.toContain('\\overline');
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
// A glyph's width comes from font metrics; U+25AB is not in the KaTeX fonts,
|
|
51
|
+
// so the browser substituted a wider one and stretchy accents came out
|
|
52
|
+
// narrower than the box. A rule has an explicit width.
|
|
53
|
+
it('the empty slot has an explicit width, not font-dependent metrics', function () {
|
|
54
|
+
var out = (0, _latexBridge.withVisibleEmptySlots)('\\overarc{}');
|
|
55
|
+
expect(out).toContain('\\rule');
|
|
56
|
+
expect(out).toMatch(/rule\{[\d.]+em\}\{[\d.]+em\}/);
|
|
57
|
+
expect(out).not.toContain('unicode');
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
// Measured in the browser: the accent's immediate wrapper computes to 0px
|
|
61
|
+
// (its .ML__stretchy child is absolutely positioned), so the svg width has to
|
|
62
|
+
// resolve against .ML__base - whose width equals the content. Without pinning
|
|
63
|
+
// that, the arc collapsed to a spike and sat right of the box.
|
|
64
|
+
it('pins the accent containing block and drops the centering shift', function () {
|
|
65
|
+
// eslint-disable-next-line global-require
|
|
66
|
+
var _require = require('../mf/common-styles'),
|
|
67
|
+
placeholderStyles = _require.placeholderStyles;
|
|
68
|
+
expect(placeholderStyles['& .ML__base'].position).toEqual('relative');
|
|
69
|
+
expect(placeholderStyles['& .ML__stretchy']).toEqual({
|
|
70
|
+
position: 'absolute',
|
|
71
|
+
left: 0,
|
|
72
|
+
width: '100%'
|
|
73
|
+
});
|
|
74
|
+
// must be !important: MathLive writes margin-left as an inline style, and a
|
|
75
|
+
// class cannot override that. Leaving it un-important also halved the arc's
|
|
76
|
+
// width, because .ML__center is the stretchy's containing block.
|
|
77
|
+
expect(placeholderStyles['& .ML__center:has(.ML__stretchy)'].marginLeft).toEqual('0 !important');
|
|
78
|
+
});
|
|
79
|
+
it('applies those rules wherever static math renders', function () {
|
|
80
|
+
// eslint-disable-next-line global-require
|
|
81
|
+
var cs = require('../mf/common-styles');
|
|
82
|
+
['commonKeyboardStyles', 'commonMathLiveStyles'].forEach(function (name) {
|
|
83
|
+
expect(cs[name]['& .ML__stretchy']).toBeDefined();
|
|
84
|
+
expect(cs[name]['& .ML__base']).toBeDefined();
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
// A bare `& svg` rule re-parents every svg in the subtree; MathLive's own rule
|
|
89
|
+
// is descendant-scoped to .ML__latex .ML__stretchy svg.
|
|
90
|
+
it('does not use a blanket svg rule', function () {
|
|
91
|
+
// eslint-disable-next-line global-require
|
|
92
|
+
var cs = require('../mf/common-styles');
|
|
93
|
+
Object.values(cs).forEach(function (style) {
|
|
94
|
+
if (style && (0, _typeof2["default"])(style) === 'object') {
|
|
95
|
+
expect(Object.keys(style)).not.toContain('& svg');
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
});
|
|
25
99
|
it('leaves latex without empty groups alone', function () {
|
|
26
100
|
['\\pi', '\\sin', 'x^2', '\\overline{AB}'].forEach(function (latex) {
|
|
27
101
|
expect((0, _latexBridge.withVisibleEmptySlots)(latex)).toEqual(latex);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"keypad-label.test.js","names":["_latexBridge","require","describe","it","out","latexForDisplay","expect","not","toEqual","toContain","forEach","latex","
|
|
1
|
+
{"version":3,"file":"keypad-label.test.js","names":["_latexBridge","require","describe","it","out","latexForDisplay","expect","not","toEqual","toContain","forEach","latex","geometry","Object","values","key","toMatch","_require","placeholderStyles","position","left","width","marginLeft","cs","name","toBeDefined","style","_typeof2","keys","undefined","keyToAction","value"],"sources":["../../src/__tests__/keypad-label.test.jsx"],"sourcesContent":["import { withVisibleEmptySlots as latexForDisplay } from '../latex-bridge';\nimport { keyToAction } from '../latex-bridge';\n\n/**\n * Keys use empty groups to show a command's shape (`\\frac{}{}`, `x^{}`).\n * MathLive renders `{}` as nothing, so labels need a visible stand-in - but the\n * value that gets *inserted* must stay untouched.\n */\ndescribe('keypad label display normalisation', () => {\n it('gives empty groups a visible glyph', () => {\n const out = latexForDisplay('\\\\frac{}{}');\n\n expect(out).not.toEqual('\\\\frac{}{}');\n // a \\rule, not a glyph: font metrics for a substituted glyph do not match\n // MathLive's, which left stretchy accents narrower than the box\n expect(out).toContain('\\\\rule');\n expect(out).toContain('pie-empty');\n });\n\n it('handles every empty-group key shape', () => {\n ['\\\\frac{}{}', '\\\\overline{}', 'x^{}', 'x_{}', '\\\\sqrt{}', '\\\\sqrt[{}]{}', '\\\\abs{}', '\\\\log_{}', '\\\\longdiv{}'].forEach(\n (latex) => {\n expect(latexForDisplay(latex)).not.toContain('{}');\n },\n );\n });\n\n it('treats a whitespace-only group as empty', () => {\n // e.g. \\frac{x}{ }\n expect(latexForDisplay('\\\\frac{x}{ }')).toContain('pie-empty');\n });\n\n // MathQuill needed a nested \\overline{} to draw the empty box. MathLive\n // renders that as a real line, so those labels showed a spurious bar (a line\n // under the arrows, and a straight line instead of the arc).\n it('accent keys do not carry the nested-overline box hack', () => {\n // eslint-disable-next-line global-require\n const geometry = require('../keys/geometry');\n\n Object.values(geometry).forEach((key) => {\n if (key && typeof key.latex === 'string') {\n expect(key.latex).not.toContain('\\\\overline{}}');\n }\n });\n });\n\n it('an accent over an empty slot still gets a visible box', () => {\n ['\\\\overleftrightarrow{}', '\\\\overarc{}'].forEach((latex) => {\n const out = latexForDisplay(latex);\n\n expect(out).toContain('pie-empty');\n expect(out).not.toContain('\\\\overline');\n });\n });\n\n // A glyph's width comes from font metrics; U+25AB is not in the KaTeX fonts,\n // so the browser substituted a wider one and stretchy accents came out\n // narrower than the box. A rule has an explicit width.\n it('the empty slot has an explicit width, not font-dependent metrics', () => {\n const out = latexForDisplay('\\\\overarc{}');\n\n expect(out).toContain('\\\\rule');\n expect(out).toMatch(/rule\\{[\\d.]+em\\}\\{[\\d.]+em\\}/);\n expect(out).not.toContain('unicode');\n });\n\n // Measured in the browser: the accent's immediate wrapper computes to 0px\n // (its .ML__stretchy child is absolutely positioned), so the svg width has to\n // resolve against .ML__base - whose width equals the content. Without pinning\n // that, the arc collapsed to a spike and sat right of the box.\n it('pins the accent containing block and drops the centering shift', () => {\n // eslint-disable-next-line global-require\n const { placeholderStyles } = require('../mf/common-styles');\n\n expect(placeholderStyles['& .ML__base'].position).toEqual('relative');\n expect(placeholderStyles['& .ML__stretchy']).toEqual({ position: 'absolute', left: 0, width: '100%' });\n // must be !important: MathLive writes margin-left as an inline style, and a\n // class cannot override that. Leaving it un-important also halved the arc's\n // width, because .ML__center is the stretchy's containing block.\n expect(placeholderStyles['& .ML__center:has(.ML__stretchy)'].marginLeft).toEqual('0 !important');\n });\n\n it('applies those rules wherever static math renders', () => {\n // eslint-disable-next-line global-require\n const cs = require('../mf/common-styles');\n\n ['commonKeyboardStyles', 'commonMathLiveStyles'].forEach((name) => {\n expect(cs[name]['& .ML__stretchy']).toBeDefined();\n expect(cs[name]['& .ML__base']).toBeDefined();\n });\n });\n\n // A bare `& svg` rule re-parents every svg in the subtree; MathLive's own rule\n // is descendant-scoped to .ML__latex .ML__stretchy svg.\n it('does not use a blanket svg rule', () => {\n // eslint-disable-next-line global-require\n const cs = require('../mf/common-styles');\n\n Object.values(cs).forEach((style) => {\n if (style && typeof style === 'object') {\n expect(Object.keys(style)).not.toContain('& svg');\n }\n });\n });\n\n it('leaves latex without empty groups alone', () => {\n ['\\\\pi', '\\\\sin', 'x^2', '\\\\overline{AB}'].forEach((latex) => {\n expect(latexForDisplay(latex)).toEqual(latex);\n });\n });\n\n it('handles nullish input', () => {\n expect(latexForDisplay(undefined)).toEqual('');\n expect(latexForDisplay('')).toEqual('');\n });\n\n it('does NOT affect what gets inserted into the field', () => {\n // the action must use the key's own latex, never the display form\n const key = { name: 'frac', latex: '\\\\frac{}{}' };\n\n expect(keyToAction(key).value).toEqual('\\\\frac{}{}');\n expect(keyToAction(key).value).not.toContain('pie-empty');\n });\n});\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -172,6 +172,35 @@ describe('latex-bridge', function () {
|
|
|
172
172
|
value: '^{#?}'
|
|
173
173
|
});
|
|
174
174
|
});
|
|
175
|
+
|
|
176
|
+
// MathQuill's `/` turned the preceding expression into the numerator: type
|
|
177
|
+
// 5, press the key, get 5/_ with the caret in the denominator. `#@` is
|
|
178
|
+
// MathLive's "selection, or the item before the cursor" token, and is what
|
|
179
|
+
// MathLive binds to `/` itself.
|
|
180
|
+
it('division takes the preceding item as the numerator', function () {
|
|
181
|
+
expect((0, _latexBridge.keyToAction)({
|
|
182
|
+
command: '/'
|
|
183
|
+
})).toEqual({
|
|
184
|
+
type: 'insert',
|
|
185
|
+
value: '\\frac{#@}{#?}'
|
|
186
|
+
});
|
|
187
|
+
});
|
|
188
|
+
it('an explicit blank-over-blank fraction stays empty', function () {
|
|
189
|
+
// distinct from `/`: this key is meant to insert two empty slots
|
|
190
|
+
expect((0, _latexBridge.keyToAction)({
|
|
191
|
+
command: '\\frac'
|
|
192
|
+
})).toEqual({
|
|
193
|
+
type: 'insert',
|
|
194
|
+
value: '\\frac{#?}{#?}'
|
|
195
|
+
});
|
|
196
|
+
});
|
|
197
|
+
it('the x-over-blank key routes through division', function () {
|
|
198
|
+
// eslint-disable-next-line global-require
|
|
199
|
+
var _require = require('../keys/fractions'),
|
|
200
|
+
xOverBlank = _require.xOverBlank;
|
|
201
|
+
expect(xOverBlank.command).toEqual('/');
|
|
202
|
+
expect((0, _latexBridge.keyToAction)(xOverBlank).value).toEqual('\\frac{#@}{#?}');
|
|
203
|
+
});
|
|
175
204
|
it('passes argument-less commands through', function () {
|
|
176
205
|
expect((0, _latexBridge.keyToAction)({
|
|
177
206
|
command: '\\pi'
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"latex-bridge.test.js","names":["_latexBridge","require","describe","it","expect","toMathLive","toEqual","undefined","concat","NEWLINE_EMBED","DEFAULT_FIELD_ID","fromMathLive","stored","forEach","l","not","toContain","toNativeCommands","out","toMatch","fieldIds","latex","keyToAction","write","type","value","command","k","_typeof2","toBe","keystroke","toBeUndefined"],"sources":["../../src/__tests__/latex-bridge.test.js"],"sourcesContent":["import {\n toMathLive,\n fromMathLive,\n fieldIds,\n keyToAction,\n toNativeCommands,\n NEWLINE_EMBED,\n DEFAULT_FIELD_ID,\n} from '../latex-bridge';\n\ndescribe('latex-bridge', () => {\n describe('toMathLive', () => {\n it('passes plain latex through', () => {\n expect(toMathLive('\\\\frac{1}{2}')).toEqual('\\\\frac{1}{2}');\n });\n\n it('handles empty/nullish', () => {\n expect(toMathLive('')).toEqual('');\n expect(toMathLive(undefined)).toEqual('');\n expect(toMathLive(null)).toEqual('');\n });\n\n it('converts a newLine embed to a multiline environment', () => {\n expect(toMathLive(`a${NEWLINE_EMBED}b`)).toEqual('\\\\displaylines{a \\\\\\\\ b}');\n });\n\n it('converts multiple newLine embeds', () => {\n expect(toMathLive(`a${NEWLINE_EMBED}b${NEWLINE_EMBED}c`)).toEqual('\\\\displaylines{a \\\\\\\\ b \\\\\\\\ c}');\n });\n\n it('converts MathQuill answer blocks to placeholders', () => {\n expect(toMathLive('x=\\\\MathQuillMathField[r1]{}')).toEqual('x=\\\\placeholder[r1]{}');\n });\n\n it('preserves answer block content', () => {\n expect(toMathLive('\\\\MathQuillMathField[r2]{7}')).toEqual('\\\\placeholder[r2]{7}');\n });\n\n it('defaults an unnamed answer block id', () => {\n expect(toMathLive('\\\\MathQuillMathField[]{}')).toEqual(`\\\\placeholder[${DEFAULT_FIELD_ID}]{}`);\n });\n\n it('handles answer blocks and newlines together', () => {\n expect(toMathLive(`\\\\MathQuillMathField[r1]{}${NEWLINE_EMBED}x`)).toEqual(\n '\\\\displaylines{\\\\placeholder[r1]{} \\\\\\\\ x}',\n );\n });\n });\n\n describe('fromMathLive', () => {\n it('passes plain latex through', () => {\n expect(fromMathLive('\\\\frac{1}{2}')).toEqual('\\\\frac{1}{2}');\n });\n\n it('unwraps displaylines back to newLine embeds', () => {\n expect(fromMathLive('\\\\displaylines{a \\\\\\\\ b}')).toEqual(`a${NEWLINE_EMBED}b`);\n });\n\n it('converts placeholders back to MathQuill answer blocks', () => {\n expect(fromMathLive('x=\\\\placeholder[r1]{}')).toEqual('x=\\\\MathQuillMathField[r1]{}');\n });\n\n it('round-trips a newline document', () => {\n const stored = `a${NEWLINE_EMBED}b${NEWLINE_EMBED}c`;\n\n expect(fromMathLive(toMathLive(stored))).toEqual(stored);\n });\n\n it('round-trips an answer-block document', () => {\n const stored = 'x=\\\\MathQuillMathField[r1]{}+\\\\MathQuillMathField[r2]{3}';\n\n expect(fromMathLive(toMathLive(stored))).toEqual(stored);\n });\n\n // MathLive serialises empty slots as \\placeholder{}, which MathJax (used by\n // @pie-lib/math-rendering for prompts/previews) renders as red error text.\n it('strips unnamed placeholders that MathLive adds', () => {\n expect(fromMathLive('\\\\longdiv{\\\\placeholder{}}')).toEqual('\\\\longdiv{}');\n expect(fromMathLive('\\\\frac{\\\\placeholder{}}{\\\\placeholder{}}')).toEqual('\\\\frac{}{}');\n });\n\n it('keeps content inside an unnamed placeholder', () => {\n expect(fromMathLive('\\\\sqrt{\\\\placeholder{7}}')).toEqual('\\\\sqrt{7}');\n });\n\n it('handles a bare \\\\placeholder with no argument', () => {\n expect(fromMathLive('\\\\longdiv{\\\\placeholder}')).toEqual('\\\\longdiv{}');\n });\n\n it('never leaks the token \\\\placeholder', () => {\n ['\\\\longdiv{\\\\placeholder{}}', '\\\\frac{\\\\placeholder{}}{x}', '\\\\placeholder{}'].forEach((l) => {\n expect(fromMathLive(l)).not.toContain('\\\\placeholder');\n });\n });\n\n it('still maps NAMED placeholders to answer blocks', () => {\n // named ones are answer blocks and must survive\n expect(fromMathLive('\\\\placeholder[r1]{}')).toEqual('\\\\MathQuillMathField[r1]{}');\n });\n\n it('round-trips answer blocks combined with newlines', () => {\n const stored = `\\\\MathQuillMathField[r1]{}${NEWLINE_EMBED}y`;\n\n expect(fromMathLive(toMathLive(stored))).toEqual(stored);\n });\n });\n\n // A MathLive macro serialises from the arguments it was created with, so text\n // typed inside its expansion never comes back out of getValue('latex').\n // Argument-taking pie commands must therefore become native constructs before\n // they reach a mathfield.\n describe('toNativeCommands', () => {\n it('expands \\\\longdiv to native \\\\enclose', () => {\n expect(toNativeCommands('\\\\longdiv{1234}')).toEqual('\\\\enclose{longdiv}{1234}');\n expect(toNativeCommands('\\\\longdiv{}')).toEqual('\\\\enclose{longdiv}{}');\n });\n\n it('expands \\\\overarc to native \\\\overparen', () => {\n expect(toNativeCommands('\\\\overarc{AB}')).toEqual('\\\\overparen{AB}');\n });\n\n it('expands \\\\abs to native \\\\left|..\\\\right|', () => {\n expect(toNativeCommands('\\\\abs{x}')).toEqual('\\\\left|x\\\\right|');\n expect(toNativeCommands('\\\\abs{}')).toEqual('\\\\left|\\\\right|');\n });\n\n it('handles nested braces inside \\\\abs', () => {\n expect(toNativeCommands('\\\\abs{\\\\frac{1}{2}}')).toEqual('\\\\left|\\\\frac{1}{2}\\\\right|');\n });\n\n it('handles several occurrences', () => {\n expect(toNativeCommands('\\\\abs{a}+\\\\abs{b}')).toEqual('\\\\left|a\\\\right|+\\\\left|b\\\\right|');\n expect(toNativeCommands('\\\\longdiv{1}\\\\longdiv{2}')).toEqual('\\\\enclose{longdiv}{1}\\\\enclose{longdiv}{2}');\n });\n\n it('leaves other latex untouched', () => {\n ['\\\\frac{1}{2}', '\\\\pi', '\\\\sqrt{x}', '\\\\overline{AB}'].forEach((l) => {\n expect(toNativeCommands(l)).toEqual(l);\n });\n });\n\n it('handles nullish input', () => {\n expect(toNativeCommands(undefined)).toEqual('');\n expect(toNativeCommands('')).toEqual('');\n });\n\n it('is applied by toMathLive', () => {\n expect(toMathLive('\\\\longdiv{5}')).toEqual('\\\\enclose{longdiv}{5}');\n });\n\n it('does not leave a pie macro in what reaches the field', () => {\n ['\\\\longdiv{7}', '\\\\abs{7}', '\\\\overarc{7}'].forEach((l) => {\n const out = toMathLive(l);\n\n expect(out).not.toMatch(/\\\\longdiv|\\\\abs|\\\\overarc/);\n });\n });\n });\n\n describe('fieldIds', () => {\n it('returns ids in document order', () => {\n expect(fieldIds('\\\\MathQuillMathField[r1]{}+\\\\MathQuillMathField[r2]{}')).toEqual(['r1', 'r2']);\n });\n\n it('returns [] when there are none', () => {\n expect(fieldIds('x+y')).toEqual([]);\n expect(fieldIds(undefined)).toEqual([]);\n });\n\n it('is repeatable (regex lastIndex is reset)', () => {\n const latex = '\\\\MathQuillMathField[r1]{}';\n\n expect(fieldIds(latex)).toEqual(['r1']);\n expect(fieldIds(latex)).toEqual(['r1']);\n });\n });\n\n describe('keyToAction', () => {\n it('prefers latex when there is no command', () => {\n expect(keyToAction({ latex: '\\\\pi', write: 'p' })).toEqual({ type: 'insert', value: '\\\\pi' });\n });\n\n it('uses write', () => {\n expect(keyToAction({ write: 'x' })).toEqual({ type: 'insert', value: 'x' });\n });\n\n it('expands commands that take arguments into placeholders', () => {\n expect(keyToAction({ command: '\\\\frac' })).toEqual({ type: 'insert', value: '\\\\frac{#?}{#?}' });\n expect(keyToAction({ command: '\\\\sqrt' })).toEqual({ type: 'insert', value: '\\\\sqrt{#?}' });\n expect(keyToAction({ command: '^' })).toEqual({ type: 'insert', value: '^{#?}' });\n });\n\n it('passes argument-less commands through', () => {\n expect(keyToAction({ command: '\\\\pi' })).toEqual({ type: 'insert', value: '\\\\pi' });\n });\n\n it('concatenates array commands (MathQuill cmd() applied them in sequence)', () => {\n // Measured Angle\n expect(keyToAction({ command: ['m', '\\\\angle'] })).toEqual({ type: 'insert', value: 'm\\\\angle' });\n // log base n - the `_` part must still expand to a placeholder\n expect(keyToAction({ command: ['\\\\log', '_'] })).toEqual({ type: 'insert', value: '\\\\log_{#?}' });\n });\n\n it('always returns a string value for insert actions', () => {\n [{ command: ['m', '\\\\angle'] }, { command: '\\\\frac' }, { write: 'x' }, { latex: '\\\\pi' }].forEach((k) => {\n expect(typeof keyToAction(k).value).toBe('string');\n });\n });\n\n it('maps keystrokes to MathLive selectors', () => {\n expect(keyToAction({ keystroke: 'Left' })).toEqual({ type: 'command', value: 'moveToPreviousChar' });\n expect(keyToAction({ keystroke: 'Right' })).toEqual({ type: 'command', value: 'moveToNextChar' });\n expect(keyToAction({ keystroke: 'Backspace' })).toEqual({ type: 'command', value: 'deleteBackward' });\n });\n\n it('returns undefined for unknown/empty input', () => {\n expect(keyToAction(undefined)).toBeUndefined();\n expect(keyToAction({})).toBeUndefined();\n expect(keyToAction({ keystroke: 'Nope' })).toBeUndefined();\n });\n\n it('latex wins over command only when command is absent', () => {\n // a key with both should use the command path (matches MathInput.keypadPress)\n expect(keyToAction({ latex: '\\\\frac{}{}', command: '\\\\frac' })).toEqual({\n type: 'insert',\n value: '\\\\frac{#?}{#?}',\n });\n });\n });\n});\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"latex-bridge.test.js","names":["_latexBridge","require","describe","it","expect","toMathLive","toEqual","undefined","concat","NEWLINE_EMBED","DEFAULT_FIELD_ID","fromMathLive","stored","forEach","l","not","toContain","toNativeCommands","out","toMatch","fieldIds","latex","keyToAction","write","type","value","command","_require","xOverBlank","k","_typeof2","toBe","keystroke","toBeUndefined"],"sources":["../../src/__tests__/latex-bridge.test.js"],"sourcesContent":["import {\n toMathLive,\n fromMathLive,\n fieldIds,\n keyToAction,\n toNativeCommands,\n NEWLINE_EMBED,\n DEFAULT_FIELD_ID,\n} from '../latex-bridge';\n\ndescribe('latex-bridge', () => {\n describe('toMathLive', () => {\n it('passes plain latex through', () => {\n expect(toMathLive('\\\\frac{1}{2}')).toEqual('\\\\frac{1}{2}');\n });\n\n it('handles empty/nullish', () => {\n expect(toMathLive('')).toEqual('');\n expect(toMathLive(undefined)).toEqual('');\n expect(toMathLive(null)).toEqual('');\n });\n\n it('converts a newLine embed to a multiline environment', () => {\n expect(toMathLive(`a${NEWLINE_EMBED}b`)).toEqual('\\\\displaylines{a \\\\\\\\ b}');\n });\n\n it('converts multiple newLine embeds', () => {\n expect(toMathLive(`a${NEWLINE_EMBED}b${NEWLINE_EMBED}c`)).toEqual('\\\\displaylines{a \\\\\\\\ b \\\\\\\\ c}');\n });\n\n it('converts MathQuill answer blocks to placeholders', () => {\n expect(toMathLive('x=\\\\MathQuillMathField[r1]{}')).toEqual('x=\\\\placeholder[r1]{}');\n });\n\n it('preserves answer block content', () => {\n expect(toMathLive('\\\\MathQuillMathField[r2]{7}')).toEqual('\\\\placeholder[r2]{7}');\n });\n\n it('defaults an unnamed answer block id', () => {\n expect(toMathLive('\\\\MathQuillMathField[]{}')).toEqual(`\\\\placeholder[${DEFAULT_FIELD_ID}]{}`);\n });\n\n it('handles answer blocks and newlines together', () => {\n expect(toMathLive(`\\\\MathQuillMathField[r1]{}${NEWLINE_EMBED}x`)).toEqual(\n '\\\\displaylines{\\\\placeholder[r1]{} \\\\\\\\ x}',\n );\n });\n });\n\n describe('fromMathLive', () => {\n it('passes plain latex through', () => {\n expect(fromMathLive('\\\\frac{1}{2}')).toEqual('\\\\frac{1}{2}');\n });\n\n it('unwraps displaylines back to newLine embeds', () => {\n expect(fromMathLive('\\\\displaylines{a \\\\\\\\ b}')).toEqual(`a${NEWLINE_EMBED}b`);\n });\n\n it('converts placeholders back to MathQuill answer blocks', () => {\n expect(fromMathLive('x=\\\\placeholder[r1]{}')).toEqual('x=\\\\MathQuillMathField[r1]{}');\n });\n\n it('round-trips a newline document', () => {\n const stored = `a${NEWLINE_EMBED}b${NEWLINE_EMBED}c`;\n\n expect(fromMathLive(toMathLive(stored))).toEqual(stored);\n });\n\n it('round-trips an answer-block document', () => {\n const stored = 'x=\\\\MathQuillMathField[r1]{}+\\\\MathQuillMathField[r2]{3}';\n\n expect(fromMathLive(toMathLive(stored))).toEqual(stored);\n });\n\n // MathLive serialises empty slots as \\placeholder{}, which MathJax (used by\n // @pie-lib/math-rendering for prompts/previews) renders as red error text.\n it('strips unnamed placeholders that MathLive adds', () => {\n expect(fromMathLive('\\\\longdiv{\\\\placeholder{}}')).toEqual('\\\\longdiv{}');\n expect(fromMathLive('\\\\frac{\\\\placeholder{}}{\\\\placeholder{}}')).toEqual('\\\\frac{}{}');\n });\n\n it('keeps content inside an unnamed placeholder', () => {\n expect(fromMathLive('\\\\sqrt{\\\\placeholder{7}}')).toEqual('\\\\sqrt{7}');\n });\n\n it('handles a bare \\\\placeholder with no argument', () => {\n expect(fromMathLive('\\\\longdiv{\\\\placeholder}')).toEqual('\\\\longdiv{}');\n });\n\n it('never leaks the token \\\\placeholder', () => {\n ['\\\\longdiv{\\\\placeholder{}}', '\\\\frac{\\\\placeholder{}}{x}', '\\\\placeholder{}'].forEach((l) => {\n expect(fromMathLive(l)).not.toContain('\\\\placeholder');\n });\n });\n\n it('still maps NAMED placeholders to answer blocks', () => {\n // named ones are answer blocks and must survive\n expect(fromMathLive('\\\\placeholder[r1]{}')).toEqual('\\\\MathQuillMathField[r1]{}');\n });\n\n it('round-trips answer blocks combined with newlines', () => {\n const stored = `\\\\MathQuillMathField[r1]{}${NEWLINE_EMBED}y`;\n\n expect(fromMathLive(toMathLive(stored))).toEqual(stored);\n });\n });\n\n // A MathLive macro serialises from the arguments it was created with, so text\n // typed inside its expansion never comes back out of getValue('latex').\n // Argument-taking pie commands must therefore become native constructs before\n // they reach a mathfield.\n describe('toNativeCommands', () => {\n it('expands \\\\longdiv to native \\\\enclose', () => {\n expect(toNativeCommands('\\\\longdiv{1234}')).toEqual('\\\\enclose{longdiv}{1234}');\n expect(toNativeCommands('\\\\longdiv{}')).toEqual('\\\\enclose{longdiv}{}');\n });\n\n it('expands \\\\overarc to native \\\\overparen', () => {\n expect(toNativeCommands('\\\\overarc{AB}')).toEqual('\\\\overparen{AB}');\n });\n\n it('expands \\\\abs to native \\\\left|..\\\\right|', () => {\n expect(toNativeCommands('\\\\abs{x}')).toEqual('\\\\left|x\\\\right|');\n expect(toNativeCommands('\\\\abs{}')).toEqual('\\\\left|\\\\right|');\n });\n\n it('handles nested braces inside \\\\abs', () => {\n expect(toNativeCommands('\\\\abs{\\\\frac{1}{2}}')).toEqual('\\\\left|\\\\frac{1}{2}\\\\right|');\n });\n\n it('handles several occurrences', () => {\n expect(toNativeCommands('\\\\abs{a}+\\\\abs{b}')).toEqual('\\\\left|a\\\\right|+\\\\left|b\\\\right|');\n expect(toNativeCommands('\\\\longdiv{1}\\\\longdiv{2}')).toEqual('\\\\enclose{longdiv}{1}\\\\enclose{longdiv}{2}');\n });\n\n it('leaves other latex untouched', () => {\n ['\\\\frac{1}{2}', '\\\\pi', '\\\\sqrt{x}', '\\\\overline{AB}'].forEach((l) => {\n expect(toNativeCommands(l)).toEqual(l);\n });\n });\n\n it('handles nullish input', () => {\n expect(toNativeCommands(undefined)).toEqual('');\n expect(toNativeCommands('')).toEqual('');\n });\n\n it('is applied by toMathLive', () => {\n expect(toMathLive('\\\\longdiv{5}')).toEqual('\\\\enclose{longdiv}{5}');\n });\n\n it('does not leave a pie macro in what reaches the field', () => {\n ['\\\\longdiv{7}', '\\\\abs{7}', '\\\\overarc{7}'].forEach((l) => {\n const out = toMathLive(l);\n\n expect(out).not.toMatch(/\\\\longdiv|\\\\abs|\\\\overarc/);\n });\n });\n });\n\n describe('fieldIds', () => {\n it('returns ids in document order', () => {\n expect(fieldIds('\\\\MathQuillMathField[r1]{}+\\\\MathQuillMathField[r2]{}')).toEqual(['r1', 'r2']);\n });\n\n it('returns [] when there are none', () => {\n expect(fieldIds('x+y')).toEqual([]);\n expect(fieldIds(undefined)).toEqual([]);\n });\n\n it('is repeatable (regex lastIndex is reset)', () => {\n const latex = '\\\\MathQuillMathField[r1]{}';\n\n expect(fieldIds(latex)).toEqual(['r1']);\n expect(fieldIds(latex)).toEqual(['r1']);\n });\n });\n\n describe('keyToAction', () => {\n it('prefers latex when there is no command', () => {\n expect(keyToAction({ latex: '\\\\pi', write: 'p' })).toEqual({ type: 'insert', value: '\\\\pi' });\n });\n\n it('uses write', () => {\n expect(keyToAction({ write: 'x' })).toEqual({ type: 'insert', value: 'x' });\n });\n\n it('expands commands that take arguments into placeholders', () => {\n expect(keyToAction({ command: '\\\\frac' })).toEqual({ type: 'insert', value: '\\\\frac{#?}{#?}' });\n expect(keyToAction({ command: '\\\\sqrt' })).toEqual({ type: 'insert', value: '\\\\sqrt{#?}' });\n expect(keyToAction({ command: '^' })).toEqual({ type: 'insert', value: '^{#?}' });\n });\n\n // MathQuill's `/` turned the preceding expression into the numerator: type\n // 5, press the key, get 5/_ with the caret in the denominator. `#@` is\n // MathLive's \"selection, or the item before the cursor\" token, and is what\n // MathLive binds to `/` itself.\n it('division takes the preceding item as the numerator', () => {\n expect(keyToAction({ command: '/' })).toEqual({ type: 'insert', value: '\\\\frac{#@}{#?}' });\n });\n\n it('an explicit blank-over-blank fraction stays empty', () => {\n // distinct from `/`: this key is meant to insert two empty slots\n expect(keyToAction({ command: '\\\\frac' })).toEqual({ type: 'insert', value: '\\\\frac{#?}{#?}' });\n });\n\n it('the x-over-blank key routes through division', () => {\n // eslint-disable-next-line global-require\n const { xOverBlank } = require('../keys/fractions');\n\n expect(xOverBlank.command).toEqual('/');\n expect(keyToAction(xOverBlank).value).toEqual('\\\\frac{#@}{#?}');\n });\n\n it('passes argument-less commands through', () => {\n expect(keyToAction({ command: '\\\\pi' })).toEqual({ type: 'insert', value: '\\\\pi' });\n });\n\n it('concatenates array commands (MathQuill cmd() applied them in sequence)', () => {\n // Measured Angle\n expect(keyToAction({ command: ['m', '\\\\angle'] })).toEqual({ type: 'insert', value: 'm\\\\angle' });\n // log base n - the `_` part must still expand to a placeholder\n expect(keyToAction({ command: ['\\\\log', '_'] })).toEqual({ type: 'insert', value: '\\\\log_{#?}' });\n });\n\n it('always returns a string value for insert actions', () => {\n [{ command: ['m', '\\\\angle'] }, { command: '\\\\frac' }, { write: 'x' }, { latex: '\\\\pi' }].forEach((k) => {\n expect(typeof keyToAction(k).value).toBe('string');\n });\n });\n\n it('maps keystrokes to MathLive selectors', () => {\n expect(keyToAction({ keystroke: 'Left' })).toEqual({ type: 'command', value: 'moveToPreviousChar' });\n expect(keyToAction({ keystroke: 'Right' })).toEqual({ type: 'command', value: 'moveToNextChar' });\n expect(keyToAction({ keystroke: 'Backspace' })).toEqual({ type: 'command', value: 'deleteBackward' });\n });\n\n it('returns undefined for unknown/empty input', () => {\n expect(keyToAction(undefined)).toBeUndefined();\n expect(keyToAction({})).toBeUndefined();\n expect(keyToAction({ keystroke: 'Nope' })).toBeUndefined();\n });\n\n it('latex wins over command only when command is absent', () => {\n // a key with both should use the command path (matches MathInput.keypadPress)\n expect(keyToAction({ latex: '\\\\frac{}{}', command: '\\\\frac' })).toEqual({\n type: 'insert',\n value: '\\\\frac{#?}{#?}',\n });\n });\n });\n});\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -225,6 +225,48 @@ describe('mathlive-instance', function () {
|
|
|
225
225
|
expect(MathfieldElement.fontsDirectory).toBeNull();
|
|
226
226
|
});
|
|
227
227
|
});
|
|
228
|
+
|
|
229
|
+
// A live <math-field> renders in shadow DOM, so nothing in the page's
|
|
230
|
+
// stylesheets reaches it - the stretchy-accent fix has to be injected there.
|
|
231
|
+
describe('applyShadowStyles', function () {
|
|
232
|
+
var host = function host() {
|
|
233
|
+
var el = document.createElement('div');
|
|
234
|
+
el.attachShadow({
|
|
235
|
+
mode: 'open'
|
|
236
|
+
});
|
|
237
|
+
return el;
|
|
238
|
+
};
|
|
239
|
+
it('is a no-op without a shadow root', function () {
|
|
240
|
+
expect(function () {
|
|
241
|
+
return instance.applyShadowStyles(undefined);
|
|
242
|
+
}).not.toThrow();
|
|
243
|
+
expect(function () {
|
|
244
|
+
return instance.applyShadowStyles(document.createElement('div'));
|
|
245
|
+
}).not.toThrow();
|
|
246
|
+
});
|
|
247
|
+
it('injects the accent fix into the shadow root', function () {
|
|
248
|
+
var el = host();
|
|
249
|
+
instance.applyShadowStyles(el);
|
|
250
|
+
var viaSheet = el.shadowRoot.__pieAccentSheet;
|
|
251
|
+
var viaStyle = el.shadowRoot.querySelector('style[data-pie-accent]');
|
|
252
|
+
var css = viaSheet ? 'adopted' : viaStyle && viaStyle.textContent || '';
|
|
253
|
+
expect(viaSheet || viaStyle).toBeTruthy();
|
|
254
|
+
if (viaStyle) {
|
|
255
|
+
expect(css).toContain('margin-left:0 !important');
|
|
256
|
+
// scoped so single-glyph accents keep their centring offset
|
|
257
|
+
expect(css).toContain(':has(.ML__stretchy)');
|
|
258
|
+
}
|
|
259
|
+
});
|
|
260
|
+
it('does not inject twice', function () {
|
|
261
|
+
var el = host();
|
|
262
|
+
instance.applyShadowStyles(el);
|
|
263
|
+
instance.applyShadowStyles(el);
|
|
264
|
+
var styles = el.shadowRoot.querySelectorAll('style[data-pie-accent]');
|
|
265
|
+
|
|
266
|
+
// either one adopted sheet, or exactly one style node
|
|
267
|
+
expect(el.shadowRoot.__pieAccentSheet ? 1 : styles.length).toBe(1);
|
|
268
|
+
});
|
|
269
|
+
});
|
|
228
270
|
describe('latexToMarkup', function () {
|
|
229
271
|
it('returns empty string when MathLive is not loaded', function () {
|
|
230
272
|
expect(instance.latexToMarkup('\\pi')).toEqual('');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mathlive-instance.test.js","names":["describe","instance","beforeEach","jest","resetModules","require","__resetEmbeds","it","registerEmbed","htmlString","latex","expect","registeredEmbeds","toEqual","getMacros","answerBlock","newLine","somethingCustom","mathliveLatex","custom","Error","not","toThrow","undefined","macros","parallelogram","toBeDefined","longdiv","napprox","forEach","name","_typeof2","PIE_MACROS","toBe","toContain","applyStaticMath","toBeUndefined","el","document","createElement","__setMathLiveForTest","convertLatexToMarkup","l","concat","innerHTML","textContent","configureFonts","MathfieldElement","fontsDirectory","baseURI","replace","startsWith","version","mathlive","toBeNull","latexToMarkup"],"sources":["../../src/__tests__/mathlive-instance.test.js"],"sourcesContent":["describe('mathlive-instance', () => {\n let instance;\n\n beforeEach(() => {\n jest.resetModules();\n // eslint-disable-next-line global-require\n instance = require('../mathlive-instance');\n instance.__resetEmbeds();\n });\n\n describe('registerEmbed', () => {\n it('registers a known embed and exposes it as a macro', () => {\n instance.registerEmbed('answerBlock', () => ({\n htmlString: '<div class=\"answerBlock\"></div>',\n latex: () => '\\\\embed{answerBlock}[]',\n }));\n\n expect(instance.registeredEmbeds()).toEqual(['answerBlock']);\n // The macro tags output with data-embed so CSS can target it, replacing\n // MathQuill's htmlString hook.\n expect(instance.getMacros().answerBlock).toEqual('\\\\htmlData{embed=answerBlock}{\\\\placeholder{}}');\n });\n\n it('registers newLine as a harmless macro (it is handled by latex-bridge)', () => {\n instance.registerEmbed('newLine', () => ({ latex: () => '\\\\embed{newLine}[]' }));\n\n expect(instance.getMacros().newLine).toEqual('\\\\htmlData{embed=newLine}{}');\n });\n\n it('falls back to a placeholder for an unknown embed', () => {\n instance.registerEmbed('somethingCustom', () => ({ htmlString: '<b>x</b>' }));\n\n expect(instance.getMacros().somethingCustom).toEqual('\\\\htmlData{embed=somethingCustom}{\\\\placeholder{}}');\n });\n\n it('honours an explicit mathliveLatex from the factory', () => {\n instance.registerEmbed('custom', () => ({ mathliveLatex: '\\\\alpha' }));\n\n expect(instance.getMacros().custom).toEqual('\\\\htmlData{embed=custom}{\\\\alpha}');\n });\n\n it('does not throw when the factory throws', () => {\n expect(() =>\n instance.registerEmbed('bad', () => {\n throw new Error('boom');\n }),\n ).not.toThrow();\n\n expect(instance.registeredEmbeds()).toEqual(['bad']);\n });\n\n it('ignores bad arguments', () => {\n instance.registerEmbed(undefined, () => ({}));\n instance.registerEmbed('noFactory', undefined);\n\n expect(instance.registeredEmbeds()).toEqual([]);\n });\n\n it('always includes the pie macro set', () => {\n const macros = instance.getMacros();\n\n expect(macros.parallelogram).toBeDefined();\n expect(macros.longdiv).toBeDefined();\n expect(macros.napprox).toEqual('\\\\not\\\\approx');\n });\n\n // Argument-taking macros exist only so previously authored latex parses.\n // Editing never goes through them: MathLive serialises a macro from its\n // original arguments, so typed content never comes back out.\n it('argument-taking macros are plain parse-only definitions', () => {\n ['longdiv', 'overarc', 'abs'].forEach((name) => {\n expect(typeof instance.PIE_MACROS[name]).toBe('string');\n expect(instance.PIE_MACROS[name]).toContain('#1');\n });\n });\n\n it('argument-less symbols stay atomic', () => {\n ['perpendicular', 'square', 'degree', 'napprox', 'parallelogram'].forEach((name) => {\n expect(typeof instance.PIE_MACROS[name]).toBe('string');\n });\n });\n\n it('longdiv matches the MathJax macro used by math-rendering', () => {\n expect(instance.PIE_MACROS.longdiv).toEqual('\\\\enclose{longdiv}{#1}');\n });\n });\n\n describe('applyStaticMath', () => {\n it('returns undefined without an element', () => {\n expect(instance.applyStaticMath(null, 'x')).toBeUndefined();\n });\n\n it('defers (returns undefined) when MathLive has not loaded', () => {\n const el = document.createElement('div');\n\n expect(instance.applyStaticMath(el, 'x')).toBeUndefined();\n });\n\n it('renders synchronously once MathLive is available', () => {\n const el = document.createElement('div');\n\n instance.__setMathLiveForTest({ convertLatexToMarkup: (l) => `<span>${l}</span>` });\n\n expect(instance.applyStaticMath(el, '\\\\pi')).toBe(el);\n expect(el.innerHTML).toEqual('<span>\\\\pi</span>');\n });\n\n it('falls back to the element textContent when no latex is passed', () => {\n const el = document.createElement('div');\n\n el.textContent = '\\\\theta';\n instance.__setMathLiveForTest({ convertLatexToMarkup: (l) => `<i>${l}</i>` });\n instance.applyStaticMath(el);\n\n expect(el.innerHTML).toEqual('<i>\\\\theta</i>');\n });\n\n it('bridges stored latex (newLine embed) before rendering', () => {\n const el = document.createElement('div');\n\n instance.__setMathLiveForTest({ convertLatexToMarkup: (l) => l });\n instance.applyStaticMath(el, 'a\\\\embed{newLine}[]b');\n\n // \\embed{newLine}[] must become a multiline environment\n expect(el.innerHTML).toContain('displaylines');\n });\n });\n\n describe('configureFonts', () => {\n // MathLive's default fontsDirectory is the relative './fonts/', which it\n // resolves against its own (empty, when bundled) script url and throws\n // \"Invalid base URL\" from loadFonts. Paths must become absolute.\n it('is exported and callable before MathLive loads', () => {\n expect(typeof instance.configureFonts).toBe('function');\n expect(() => instance.configureFonts('/mathlive-fonts')).not.toThrow();\n });\n\n it('accepts null to disable font loading', () => {\n expect(() => instance.configureFonts(null)).not.toThrow();\n });\n\n it('applies an absolute url to an already-loaded MathfieldElement', () => {\n const MathfieldElement = {};\n\n // simulate a loaded instance\n instance.__setMathLiveForTest({ MathfieldElement });\n instance.configureFonts('/mathlive-fonts');\n\n expect(MathfieldElement.fontsDirectory).toEqual(`${document.baseURI.replace(/\\/$/, '')}/mathlive-fonts`);\n expect(MathfieldElement.fontsDirectory.startsWith('http')).toBe(true);\n });\n\n // \\neq, \\nsim and \\ncong are built from Private Use Area glyphs that only\n // the KaTeX fonts contain, so \"no fonts\" renders garbage rather than\n // degrading gracefully - hence a CDN fallback by default.\n it('falls back to a version-pinned CDN when nothing is configured', () => {\n const MathfieldElement = {};\n\n instance.__setMathLiveForTest({ MathfieldElement, version: { mathlive: '9.9.9' } });\n instance.configureFonts(undefined);\n\n expect(MathfieldElement.fontsDirectory).toEqual('https://unpkg.com/mathlive@9.9.9/fonts');\n });\n\n it('uses /fonts, not /dist/fonts (the latter 404s on unpkg)', () => {\n const MathfieldElement = {};\n\n instance.__setMathLiveForTest({ MathfieldElement, version: { mathlive: '0.110.0' } });\n instance.configureFonts(undefined);\n\n expect(MathfieldElement.fontsDirectory).toEqual('https://unpkg.com/mathlive@0.110.0/fonts');\n expect(MathfieldElement.fontsDirectory).not.toContain('/dist/');\n });\n\n it('a configured path wins over the CDN', () => {\n const MathfieldElement = {};\n\n instance.__setMathLiveForTest({ MathfieldElement, version: { mathlive: '0.110.0' } });\n instance.configureFonts('/mathlive-fonts');\n\n expect(MathfieldElement.fontsDirectory).not.toContain('unpkg.com');\n });\n\n it('null still opts out entirely', () => {\n const MathfieldElement = {};\n\n instance.__setMathLiveForTest({ MathfieldElement, version: { mathlive: '0.110.0' } });\n instance.configureFonts(null);\n\n expect(MathfieldElement.fontsDirectory).toBeNull();\n });\n\n it('leaves a fully-qualified url untouched', () => {\n const MathfieldElement = {};\n\n instance.__setMathLiveForTest({ MathfieldElement });\n instance.configureFonts('https://cdn.example.com/fonts');\n\n expect(MathfieldElement.fontsDirectory).toEqual('https://cdn.example.com/fonts');\n });\n\n it('passes null through rather than resolving it', () => {\n const MathfieldElement = {};\n\n instance.__setMathLiveForTest({ MathfieldElement });\n instance.configureFonts(null);\n\n expect(MathfieldElement.fontsDirectory).toBeNull();\n });\n });\n\n describe('latexToMarkup', () => {\n it('returns empty string when MathLive is not loaded', () => {\n expect(instance.latexToMarkup('\\\\pi')).toEqual('');\n });\n\n it('returns empty string for empty latex', () => {\n expect(instance.latexToMarkup('')).toEqual('');\n });\n });\n});\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"mathlive-instance.test.js","names":["describe","instance","beforeEach","jest","resetModules","require","__resetEmbeds","it","registerEmbed","htmlString","latex","expect","registeredEmbeds","toEqual","getMacros","answerBlock","newLine","somethingCustom","mathliveLatex","custom","Error","not","toThrow","undefined","macros","parallelogram","toBeDefined","longdiv","napprox","forEach","name","_typeof2","PIE_MACROS","toBe","toContain","applyStaticMath","toBeUndefined","el","document","createElement","__setMathLiveForTest","convertLatexToMarkup","l","concat","innerHTML","textContent","configureFonts","MathfieldElement","fontsDirectory","baseURI","replace","startsWith","version","mathlive","toBeNull","host","attachShadow","mode","applyShadowStyles","viaSheet","shadowRoot","__pieAccentSheet","viaStyle","querySelector","css","toBeTruthy","styles","querySelectorAll","length","latexToMarkup"],"sources":["../../src/__tests__/mathlive-instance.test.js"],"sourcesContent":["describe('mathlive-instance', () => {\n let instance;\n\n beforeEach(() => {\n jest.resetModules();\n // eslint-disable-next-line global-require\n instance = require('../mathlive-instance');\n instance.__resetEmbeds();\n });\n\n describe('registerEmbed', () => {\n it('registers a known embed and exposes it as a macro', () => {\n instance.registerEmbed('answerBlock', () => ({\n htmlString: '<div class=\"answerBlock\"></div>',\n latex: () => '\\\\embed{answerBlock}[]',\n }));\n\n expect(instance.registeredEmbeds()).toEqual(['answerBlock']);\n // The macro tags output with data-embed so CSS can target it, replacing\n // MathQuill's htmlString hook.\n expect(instance.getMacros().answerBlock).toEqual('\\\\htmlData{embed=answerBlock}{\\\\placeholder{}}');\n });\n\n it('registers newLine as a harmless macro (it is handled by latex-bridge)', () => {\n instance.registerEmbed('newLine', () => ({ latex: () => '\\\\embed{newLine}[]' }));\n\n expect(instance.getMacros().newLine).toEqual('\\\\htmlData{embed=newLine}{}');\n });\n\n it('falls back to a placeholder for an unknown embed', () => {\n instance.registerEmbed('somethingCustom', () => ({ htmlString: '<b>x</b>' }));\n\n expect(instance.getMacros().somethingCustom).toEqual('\\\\htmlData{embed=somethingCustom}{\\\\placeholder{}}');\n });\n\n it('honours an explicit mathliveLatex from the factory', () => {\n instance.registerEmbed('custom', () => ({ mathliveLatex: '\\\\alpha' }));\n\n expect(instance.getMacros().custom).toEqual('\\\\htmlData{embed=custom}{\\\\alpha}');\n });\n\n it('does not throw when the factory throws', () => {\n expect(() =>\n instance.registerEmbed('bad', () => {\n throw new Error('boom');\n }),\n ).not.toThrow();\n\n expect(instance.registeredEmbeds()).toEqual(['bad']);\n });\n\n it('ignores bad arguments', () => {\n instance.registerEmbed(undefined, () => ({}));\n instance.registerEmbed('noFactory', undefined);\n\n expect(instance.registeredEmbeds()).toEqual([]);\n });\n\n it('always includes the pie macro set', () => {\n const macros = instance.getMacros();\n\n expect(macros.parallelogram).toBeDefined();\n expect(macros.longdiv).toBeDefined();\n expect(macros.napprox).toEqual('\\\\not\\\\approx');\n });\n\n // Argument-taking macros exist only so previously authored latex parses.\n // Editing never goes through them: MathLive serialises a macro from its\n // original arguments, so typed content never comes back out.\n it('argument-taking macros are plain parse-only definitions', () => {\n ['longdiv', 'overarc', 'abs'].forEach((name) => {\n expect(typeof instance.PIE_MACROS[name]).toBe('string');\n expect(instance.PIE_MACROS[name]).toContain('#1');\n });\n });\n\n it('argument-less symbols stay atomic', () => {\n ['perpendicular', 'square', 'degree', 'napprox', 'parallelogram'].forEach((name) => {\n expect(typeof instance.PIE_MACROS[name]).toBe('string');\n });\n });\n\n it('longdiv matches the MathJax macro used by math-rendering', () => {\n expect(instance.PIE_MACROS.longdiv).toEqual('\\\\enclose{longdiv}{#1}');\n });\n });\n\n describe('applyStaticMath', () => {\n it('returns undefined without an element', () => {\n expect(instance.applyStaticMath(null, 'x')).toBeUndefined();\n });\n\n it('defers (returns undefined) when MathLive has not loaded', () => {\n const el = document.createElement('div');\n\n expect(instance.applyStaticMath(el, 'x')).toBeUndefined();\n });\n\n it('renders synchronously once MathLive is available', () => {\n const el = document.createElement('div');\n\n instance.__setMathLiveForTest({ convertLatexToMarkup: (l) => `<span>${l}</span>` });\n\n expect(instance.applyStaticMath(el, '\\\\pi')).toBe(el);\n expect(el.innerHTML).toEqual('<span>\\\\pi</span>');\n });\n\n it('falls back to the element textContent when no latex is passed', () => {\n const el = document.createElement('div');\n\n el.textContent = '\\\\theta';\n instance.__setMathLiveForTest({ convertLatexToMarkup: (l) => `<i>${l}</i>` });\n instance.applyStaticMath(el);\n\n expect(el.innerHTML).toEqual('<i>\\\\theta</i>');\n });\n\n it('bridges stored latex (newLine embed) before rendering', () => {\n const el = document.createElement('div');\n\n instance.__setMathLiveForTest({ convertLatexToMarkup: (l) => l });\n instance.applyStaticMath(el, 'a\\\\embed{newLine}[]b');\n\n // \\embed{newLine}[] must become a multiline environment\n expect(el.innerHTML).toContain('displaylines');\n });\n });\n\n describe('configureFonts', () => {\n // MathLive's default fontsDirectory is the relative './fonts/', which it\n // resolves against its own (empty, when bundled) script url and throws\n // \"Invalid base URL\" from loadFonts. Paths must become absolute.\n it('is exported and callable before MathLive loads', () => {\n expect(typeof instance.configureFonts).toBe('function');\n expect(() => instance.configureFonts('/mathlive-fonts')).not.toThrow();\n });\n\n it('accepts null to disable font loading', () => {\n expect(() => instance.configureFonts(null)).not.toThrow();\n });\n\n it('applies an absolute url to an already-loaded MathfieldElement', () => {\n const MathfieldElement = {};\n\n // simulate a loaded instance\n instance.__setMathLiveForTest({ MathfieldElement });\n instance.configureFonts('/mathlive-fonts');\n\n expect(MathfieldElement.fontsDirectory).toEqual(`${document.baseURI.replace(/\\/$/, '')}/mathlive-fonts`);\n expect(MathfieldElement.fontsDirectory.startsWith('http')).toBe(true);\n });\n\n // \\neq, \\nsim and \\ncong are built from Private Use Area glyphs that only\n // the KaTeX fonts contain, so \"no fonts\" renders garbage rather than\n // degrading gracefully - hence a CDN fallback by default.\n it('falls back to a version-pinned CDN when nothing is configured', () => {\n const MathfieldElement = {};\n\n instance.__setMathLiveForTest({ MathfieldElement, version: { mathlive: '9.9.9' } });\n instance.configureFonts(undefined);\n\n expect(MathfieldElement.fontsDirectory).toEqual('https://unpkg.com/mathlive@9.9.9/fonts');\n });\n\n it('uses /fonts, not /dist/fonts (the latter 404s on unpkg)', () => {\n const MathfieldElement = {};\n\n instance.__setMathLiveForTest({ MathfieldElement, version: { mathlive: '0.110.0' } });\n instance.configureFonts(undefined);\n\n expect(MathfieldElement.fontsDirectory).toEqual('https://unpkg.com/mathlive@0.110.0/fonts');\n expect(MathfieldElement.fontsDirectory).not.toContain('/dist/');\n });\n\n it('a configured path wins over the CDN', () => {\n const MathfieldElement = {};\n\n instance.__setMathLiveForTest({ MathfieldElement, version: { mathlive: '0.110.0' } });\n instance.configureFonts('/mathlive-fonts');\n\n expect(MathfieldElement.fontsDirectory).not.toContain('unpkg.com');\n });\n\n it('null still opts out entirely', () => {\n const MathfieldElement = {};\n\n instance.__setMathLiveForTest({ MathfieldElement, version: { mathlive: '0.110.0' } });\n instance.configureFonts(null);\n\n expect(MathfieldElement.fontsDirectory).toBeNull();\n });\n\n it('leaves a fully-qualified url untouched', () => {\n const MathfieldElement = {};\n\n instance.__setMathLiveForTest({ MathfieldElement });\n instance.configureFonts('https://cdn.example.com/fonts');\n\n expect(MathfieldElement.fontsDirectory).toEqual('https://cdn.example.com/fonts');\n });\n\n it('passes null through rather than resolving it', () => {\n const MathfieldElement = {};\n\n instance.__setMathLiveForTest({ MathfieldElement });\n instance.configureFonts(null);\n\n expect(MathfieldElement.fontsDirectory).toBeNull();\n });\n });\n\n // A live <math-field> renders in shadow DOM, so nothing in the page's\n // stylesheets reaches it - the stretchy-accent fix has to be injected there.\n describe('applyShadowStyles', () => {\n const host = () => {\n const el = document.createElement('div');\n\n el.attachShadow({ mode: 'open' });\n\n return el;\n };\n\n it('is a no-op without a shadow root', () => {\n expect(() => instance.applyShadowStyles(undefined)).not.toThrow();\n expect(() => instance.applyShadowStyles(document.createElement('div'))).not.toThrow();\n });\n\n it('injects the accent fix into the shadow root', () => {\n const el = host();\n\n instance.applyShadowStyles(el);\n\n const viaSheet = el.shadowRoot.__pieAccentSheet;\n const viaStyle = el.shadowRoot.querySelector('style[data-pie-accent]');\n const css = viaSheet ? 'adopted' : (viaStyle && viaStyle.textContent) || '';\n\n expect(viaSheet || viaStyle).toBeTruthy();\n\n if (viaStyle) {\n expect(css).toContain('margin-left:0 !important');\n // scoped so single-glyph accents keep their centring offset\n expect(css).toContain(':has(.ML__stretchy)');\n }\n });\n\n it('does not inject twice', () => {\n const el = host();\n\n instance.applyShadowStyles(el);\n instance.applyShadowStyles(el);\n\n const styles = el.shadowRoot.querySelectorAll('style[data-pie-accent]');\n\n // either one adopted sheet, or exactly one style node\n expect(el.shadowRoot.__pieAccentSheet ? 1 : styles.length).toBe(1);\n });\n });\n\n describe('latexToMarkup', () => {\n it('returns empty string when MathLive is not loaded', () => {\n expect(instance.latexToMarkup('\\\\pi')).toEqual('');\n });\n\n it('returns empty string for empty latex', () => {\n expect(instance.latexToMarkup('')).toEqual('');\n });\n });\n});\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -45,6 +45,7 @@ jest.mock('../mathlive-instance', function () {
|
|
|
45
45
|
},
|
|
46
46
|
// must mirror the real export, otherwise the component sets `undefined`
|
|
47
47
|
MATH_MODE_SPACE: '\\ ',
|
|
48
|
+
applyShadowStyles: function applyShadowStyles() {},
|
|
48
49
|
latexToMarkup: function latexToMarkup(l) {
|
|
49
50
|
return "<span>".concat(l, "</span>");
|
|
50
51
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mount-race.test.js","names":["_input","_interopRequireDefault","require","jest","mock","FakeMathfieldElement","_createClass2","_classCallCheck2","el","global","document","createElement","value","getValue","loadMathLive","Promise","resolve","MathfieldElement","getMacros","MATH_MODE_SPACE","latexToMarkup","l","concat","holderFor","cmp","holderRef","current","fieldCount","Array","from","childNodes","filter","n","tagName","length","describe","it","_asyncToGenerator2","_regenerator","mark","_callee","input","first","second","wrap","_context","prev","next","Input","componentDidMount","componentWillUnmount","all","expect","toBe","mathField","toBeDefined","stop","_callee2","pending","_context2","toBeUndefined","_callee3","_context3","_callee4","_context4","_callee5","_context5","mathModeSpace","toEqual","not","_callee6","innerRef","_context6","fn","toHaveBeenCalledWith","toHaveBeenLastCalledWith"],"sources":["../../src/__tests__/mount-race.test.jsx"],"sourcesContent":["/**\n * MathLive loads asynchronously, so `componentDidMount` resumes after an await\n * before appending a <math-field>. Two orderings must both hold:\n *\n * - StrictMode dev double-mount (mount -> unmount -> mount on the SAME\n * instance) must end up with exactly ONE field. A boolean \"unmounted\" flag\n * latches here and blocks the remount entirely - which is why this uses a\n * generation counter.\n * - A genuine unmount while the load is in flight must append nothing.\n *\n * MathLive cannot load under jsdom, so it is mocked with a minimal stub in\n * order to actually count appended fields.\n */\njest.mock('../mathlive-instance', () => {\n // Must be a real DOM node: the component uses replaceChildren(), which\n // rejects anything that is not a Node. Returning an element from the\n // constructor replaces `this`, so callers get a genuine <math-field>.\n class FakeMathfieldElement {\n constructor() {\n // `global` rather than `document`: jest forbids out-of-scope variables in\n // a mock factory, and `global` is on its allow-list.\n const el = global.document.createElement('math-field');\n\n el.value = '';\n el.getValue = () => el.value;\n\n return el;\n }\n }\n\n return {\n loadMathLive: () => Promise.resolve({ MathfieldElement: FakeMathfieldElement }),\n getMacros: () => ({}),\n // must mirror the real export, otherwise the component sets `undefined`\n MATH_MODE_SPACE: '\\\\ ',\n latexToMarkup: (l) => `<span>${l}</span>`,\n };\n});\n\n// eslint-disable-next-line import/first\nimport Input from '../mf/input';\n\nconst holderFor = (cmp) => {\n const el = document.createElement('span');\n\n cmp.holderRef = { current: el };\n\n return el;\n};\n\nconst fieldCount = (el) => Array.from(el.childNodes).filter((n) => n.tagName === 'MATH-FIELD').length;\n\ndescribe('async mount race', () => {\n it('StrictMode mount -> unmount -> mount yields exactly one field', async () => {\n const input = new Input({});\n const el = holderFor(input);\n\n const first = input.componentDidMount();\n\n input.componentWillUnmount();\n\n const second = input.componentDidMount();\n\n await Promise.all([first, second]);\n\n expect(fieldCount(el)).toBe(1);\n expect(input.mathField).toBeDefined();\n });\n\n it('appends nothing when unmounted while the load is in flight', async () => {\n const input = new Input({});\n const el = holderFor(input);\n\n const pending = input.componentDidMount();\n\n input.componentWillUnmount();\n\n await pending;\n\n expect(fieldCount(el)).toBe(0);\n expect(input.mathField).toBeUndefined();\n });\n\n it('a normal single mount creates the field', async () => {\n const input = new Input({});\n const el = holderFor(input);\n\n await input.componentDidMount();\n\n expect(fieldCount(el)).toBe(1);\n });\n\n it('repeated mounts never accumulate fields', async () => {\n const input = new Input({});\n const el = holderFor(input);\n\n await input.componentDidMount();\n await input.componentDidMount();\n await input.componentDidMount();\n\n expect(fieldCount(el)).toBe(1);\n });\n\n // MathLive's mathModeSpace defaults to '', which makes the spacebar a no-op.\n it('configures the spacebar so a space can be typed', async () => {\n const input = new Input({});\n\n holderFor(input);\n await input.componentDidMount();\n\n // a LaTeX control space - what MathQuill produced, and MathJax understands\n expect(input.mathField.mathModeSpace).toEqual('\\\\ ');\n expect(input.mathField.mathModeSpace).not.toEqual('');\n });\n\n it('reports itself through innerRef on mount and clears it on unmount', async () => {\n const innerRef = jest.fn();\n const input = new Input({ innerRef });\n\n holderFor(input);\n await input.componentDidMount();\n\n expect(innerRef).toHaveBeenCalledWith(input);\n\n input.componentWillUnmount();\n\n expect(innerRef).toHaveBeenLastCalledWith(null);\n });\n});\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"mount-race.test.js","names":["_input","_interopRequireDefault","require","jest","mock","FakeMathfieldElement","_createClass2","_classCallCheck2","el","global","document","createElement","value","getValue","loadMathLive","Promise","resolve","MathfieldElement","getMacros","MATH_MODE_SPACE","applyShadowStyles","latexToMarkup","l","concat","holderFor","cmp","holderRef","current","fieldCount","Array","from","childNodes","filter","n","tagName","length","describe","it","_asyncToGenerator2","_regenerator","mark","_callee","input","first","second","wrap","_context","prev","next","Input","componentDidMount","componentWillUnmount","all","expect","toBe","mathField","toBeDefined","stop","_callee2","pending","_context2","toBeUndefined","_callee3","_context3","_callee4","_context4","_callee5","_context5","mathModeSpace","toEqual","not","_callee6","innerRef","_context6","fn","toHaveBeenCalledWith","toHaveBeenLastCalledWith"],"sources":["../../src/__tests__/mount-race.test.jsx"],"sourcesContent":["/**\n * MathLive loads asynchronously, so `componentDidMount` resumes after an await\n * before appending a <math-field>. Two orderings must both hold:\n *\n * - StrictMode dev double-mount (mount -> unmount -> mount on the SAME\n * instance) must end up with exactly ONE field. A boolean \"unmounted\" flag\n * latches here and blocks the remount entirely - which is why this uses a\n * generation counter.\n * - A genuine unmount while the load is in flight must append nothing.\n *\n * MathLive cannot load under jsdom, so it is mocked with a minimal stub in\n * order to actually count appended fields.\n */\njest.mock('../mathlive-instance', () => {\n // Must be a real DOM node: the component uses replaceChildren(), which\n // rejects anything that is not a Node. Returning an element from the\n // constructor replaces `this`, so callers get a genuine <math-field>.\n class FakeMathfieldElement {\n constructor() {\n // `global` rather than `document`: jest forbids out-of-scope variables in\n // a mock factory, and `global` is on its allow-list.\n const el = global.document.createElement('math-field');\n\n el.value = '';\n el.getValue = () => el.value;\n\n return el;\n }\n }\n\n return {\n loadMathLive: () => Promise.resolve({ MathfieldElement: FakeMathfieldElement }),\n getMacros: () => ({}),\n // must mirror the real export, otherwise the component sets `undefined`\n MATH_MODE_SPACE: '\\\\ ',\n applyShadowStyles: () => {},\n latexToMarkup: (l) => `<span>${l}</span>`,\n };\n});\n\n// eslint-disable-next-line import/first\nimport Input from '../mf/input';\n\nconst holderFor = (cmp) => {\n const el = document.createElement('span');\n\n cmp.holderRef = { current: el };\n\n return el;\n};\n\nconst fieldCount = (el) => Array.from(el.childNodes).filter((n) => n.tagName === 'MATH-FIELD').length;\n\ndescribe('async mount race', () => {\n it('StrictMode mount -> unmount -> mount yields exactly one field', async () => {\n const input = new Input({});\n const el = holderFor(input);\n\n const first = input.componentDidMount();\n\n input.componentWillUnmount();\n\n const second = input.componentDidMount();\n\n await Promise.all([first, second]);\n\n expect(fieldCount(el)).toBe(1);\n expect(input.mathField).toBeDefined();\n });\n\n it('appends nothing when unmounted while the load is in flight', async () => {\n const input = new Input({});\n const el = holderFor(input);\n\n const pending = input.componentDidMount();\n\n input.componentWillUnmount();\n\n await pending;\n\n expect(fieldCount(el)).toBe(0);\n expect(input.mathField).toBeUndefined();\n });\n\n it('a normal single mount creates the field', async () => {\n const input = new Input({});\n const el = holderFor(input);\n\n await input.componentDidMount();\n\n expect(fieldCount(el)).toBe(1);\n });\n\n it('repeated mounts never accumulate fields', async () => {\n const input = new Input({});\n const el = holderFor(input);\n\n await input.componentDidMount();\n await input.componentDidMount();\n await input.componentDidMount();\n\n expect(fieldCount(el)).toBe(1);\n });\n\n // MathLive's mathModeSpace defaults to '', which makes the spacebar a no-op.\n it('configures the spacebar so a space can be typed', async () => {\n const input = new Input({});\n\n holderFor(input);\n await input.componentDidMount();\n\n // a LaTeX control space - what MathQuill produced, and MathJax understands\n expect(input.mathField.mathModeSpace).toEqual('\\\\ ');\n expect(input.mathField.mathModeSpace).not.toEqual('');\n });\n\n it('reports itself through innerRef on mount and clears it on unmount', async () => {\n const innerRef = jest.fn();\n const input = new Input({ innerRef });\n\n holderFor(input);\n await input.componentDidMount();\n\n expect(innerRef).toHaveBeenCalledWith(input);\n\n input.componentWillUnmount();\n\n expect(innerRef).toHaveBeenLastCalledWith(null);\n });\n});\n"],"mappings":"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","ignoreList":[]}
|
package/lib/keypad/index.js
CHANGED
|
@@ -49,22 +49,20 @@ var LabelHolder = (0, _styles.styled)('span')(function () {
|
|
|
49
49
|
pointerEvents: 'none',
|
|
50
50
|
textTransform: 'none',
|
|
51
51
|
color: _renderUi.color.text(),
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
52
|
+
// Deliberately inline-block, NOT inline-flex: MathLive's markup relies on
|
|
53
|
+
// normal inline flow. Making its spans flex items collapses their width, and
|
|
54
|
+
// stretchy accents render an <svg width="100%" preserveAspectRatio="none">
|
|
55
|
+
// that then squeezes into a spike instead of spanning the content.
|
|
56
|
+
display: 'inline-block',
|
|
57
|
+
textAlign: 'center',
|
|
55
58
|
lineHeight: 1,
|
|
56
|
-
//
|
|
57
|
-
//
|
|
58
|
-
//
|
|
59
|
-
//
|
|
60
|
-
// the
|
|
61
|
-
// label's min-content contribution, so the grid can't blow out either way.
|
|
59
|
+
// Keep a label from sizing its grid column. `overflow: hidden` also collapses
|
|
60
|
+
// the label's min-content contribution, so a wide accent cannot drag the
|
|
61
|
+
// column across the screen. The svg's own positioning is left to
|
|
62
|
+
// mathlive-static.css (injected by the package) - duplicating it here broke
|
|
63
|
+
// the accent's containing block.
|
|
62
64
|
maxWidth: '100%',
|
|
63
65
|
overflow: 'hidden',
|
|
64
|
-
'& svg': {
|
|
65
|
-
position: 'absolute',
|
|
66
|
-
width: '100%'
|
|
67
|
-
},
|
|
68
66
|
// Answer-block / empty-slot boxes inside a label.
|
|
69
67
|
'& .ML__placeholder': {
|
|
70
68
|
backgroundColor: _renderUi.color.keypadEmptyPlaceholder ? _renderUi.color.keypadEmptyPlaceholder() : undefined
|