@pie-lib/math-input-mathlive 1.0.1 → 1.0.3
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/lib/__tests__/input-imperative.test.js +155 -0
- package/lib/__tests__/input-imperative.test.js.map +1 -0
- package/lib/__tests__/mathlive-instance.test.js +34 -1
- package/lib/__tests__/mathlive-instance.test.js.map +1 -1
- package/lib/mathlive-instance.js +17 -3
- package/lib/mathlive-instance.js.map +1 -1
- package/lib/mf/input.js +78 -9
- package/lib/mf/input.js.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/input-imperative.test.jsx +144 -0
- package/src/__tests__/mathlive-instance.test.js +30 -1
- package/src/mathlive-instance.js +18 -4
- package/src/mf/input.jsx +66 -7
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
var _latexBridge = require("../latex-bridge");
|
|
5
|
+
var _input = _interopRequireDefault(require("../mf/input"));
|
|
6
|
+
/**
|
|
7
|
+
* The imperative surface that @pie-lib/math-toolbar drives
|
|
8
|
+
* (editor-and-pad.jsx: clear/command/keystroke/write/latex).
|
|
9
|
+
*
|
|
10
|
+
* These call the methods against a stub mathfield, because a real
|
|
11
|
+
* <math-field> needs a browser. What matters here is the *translation*:
|
|
12
|
+
* MathQuill-era arguments must become valid MathLive operations.
|
|
13
|
+
*/
|
|
14
|
+
var stubField = function stubField() {
|
|
15
|
+
var calls = {
|
|
16
|
+
insert: [],
|
|
17
|
+
executeCommand: [],
|
|
18
|
+
focus: 0
|
|
19
|
+
};
|
|
20
|
+
return {
|
|
21
|
+
calls: calls,
|
|
22
|
+
value: '',
|
|
23
|
+
getValue: function getValue() {
|
|
24
|
+
return '';
|
|
25
|
+
},
|
|
26
|
+
insert: function insert(v) {
|
|
27
|
+
calls.insert.push(v);
|
|
28
|
+
},
|
|
29
|
+
executeCommand: function executeCommand(v) {
|
|
30
|
+
calls.executeCommand.push(v);
|
|
31
|
+
},
|
|
32
|
+
focus: function focus() {
|
|
33
|
+
calls.focus++;
|
|
34
|
+
},
|
|
35
|
+
blur: function blur() {}
|
|
36
|
+
};
|
|
37
|
+
};
|
|
38
|
+
var withField = function withField() {
|
|
39
|
+
var input = new _input["default"]({});
|
|
40
|
+
var f = stubField();
|
|
41
|
+
input.mathField = f;
|
|
42
|
+
return {
|
|
43
|
+
input: input,
|
|
44
|
+
f: f
|
|
45
|
+
};
|
|
46
|
+
};
|
|
47
|
+
describe('Input imperative API (drives math-toolbar)', function () {
|
|
48
|
+
describe('keystroke', function () {
|
|
49
|
+
it('maps MathQuill keystroke names to MathLive selectors', function () {
|
|
50
|
+
var _withField = withField(),
|
|
51
|
+
input = _withField.input,
|
|
52
|
+
f = _withField.f;
|
|
53
|
+
input.keystroke('Left');
|
|
54
|
+
input.keystroke('Right');
|
|
55
|
+
input.keystroke('Backspace');
|
|
56
|
+
expect(f.calls.executeCommand).toEqual(['moveToPreviousChar', 'moveToNextChar', 'deleteBackward']);
|
|
57
|
+
});
|
|
58
|
+
it('passes an unknown value through as a selector', function () {
|
|
59
|
+
var _withField2 = withField(),
|
|
60
|
+
input = _withField2.input,
|
|
61
|
+
f = _withField2.f;
|
|
62
|
+
input.keystroke('deleteForward');
|
|
63
|
+
expect(f.calls.executeCommand).toEqual(['deleteForward']);
|
|
64
|
+
});
|
|
65
|
+
it('does not throw when the engine rejects the selector', function () {
|
|
66
|
+
var _withField3 = withField(),
|
|
67
|
+
input = _withField3.input;
|
|
68
|
+
input.mathField.executeCommand = function () {
|
|
69
|
+
throw new Error('unknown command');
|
|
70
|
+
};
|
|
71
|
+
expect(function () {
|
|
72
|
+
return input.keystroke('Nonsense');
|
|
73
|
+
}).not.toThrow();
|
|
74
|
+
});
|
|
75
|
+
it('covers every keystroke the keypad emits', function () {
|
|
76
|
+
// navigation.js / edit.js only produce these three
|
|
77
|
+
['Left', 'Right', 'Backspace'].forEach(function (k) {
|
|
78
|
+
return expect(_latexBridge.KEYSTROKES[k]).toBeDefined();
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
describe('command', function () {
|
|
83
|
+
it('expands argument-taking commands into placeholders', function () {
|
|
84
|
+
var _withField4 = withField(),
|
|
85
|
+
input = _withField4.input,
|
|
86
|
+
f = _withField4.f;
|
|
87
|
+
input.command('\\frac');
|
|
88
|
+
|
|
89
|
+
// a bare \frac would give no editable slots
|
|
90
|
+
expect(f.calls.insert).toEqual(['\\frac{#?}{#?}']);
|
|
91
|
+
});
|
|
92
|
+
it('handles array commands', function () {
|
|
93
|
+
var _withField5 = withField(),
|
|
94
|
+
input = _withField5.input,
|
|
95
|
+
f = _withField5.f;
|
|
96
|
+
input.command(['\\log', '_']);
|
|
97
|
+
expect(f.calls.insert).toEqual(['\\log_{#?}']);
|
|
98
|
+
});
|
|
99
|
+
it('passes argument-less commands through', function () {
|
|
100
|
+
var _withField6 = withField(),
|
|
101
|
+
input = _withField6.input,
|
|
102
|
+
f = _withField6.f;
|
|
103
|
+
input.command('\\pi');
|
|
104
|
+
expect(f.calls.insert).toEqual(['\\pi']);
|
|
105
|
+
});
|
|
106
|
+
it('agrees with keyToAction', function () {
|
|
107
|
+
expect((0, _latexBridge.keyToAction)({
|
|
108
|
+
command: '\\sqrt'
|
|
109
|
+
}).value).toEqual('\\sqrt{#?}');
|
|
110
|
+
});
|
|
111
|
+
});
|
|
112
|
+
describe('safety before MathLive loads', function () {
|
|
113
|
+
it('every method is a no-op rather than a crash', function () {
|
|
114
|
+
var input = new _input["default"]({});
|
|
115
|
+
|
|
116
|
+
// mathField is undefined until loadMathLive() resolves
|
|
117
|
+
expect(input.latex()).toEqual('');
|
|
118
|
+
expect(input.clear()).toEqual('');
|
|
119
|
+
expect(input.command('\\frac')).toEqual('');
|
|
120
|
+
expect(input.keystroke('Left')).toEqual('');
|
|
121
|
+
expect(input.write('x')).toEqual('');
|
|
122
|
+
expect(function () {
|
|
123
|
+
return input.focus();
|
|
124
|
+
}).not.toThrow();
|
|
125
|
+
expect(function () {
|
|
126
|
+
return input.blur();
|
|
127
|
+
}).not.toThrow();
|
|
128
|
+
expect(function () {
|
|
129
|
+
return input.setLatex('x');
|
|
130
|
+
}).not.toThrow();
|
|
131
|
+
expect(input.element).toBeUndefined();
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
describe('mqCompat facade', function () {
|
|
135
|
+
// math-toolbar used to call this.input.mathField.latex(); external
|
|
136
|
+
// consumers may still do the same.
|
|
137
|
+
it('exposes latex() as a getter', function () {
|
|
138
|
+
var _withField7 = withField(),
|
|
139
|
+
input = _withField7.input;
|
|
140
|
+
input.mathField.getValue = function () {
|
|
141
|
+
return '\\frac{1}{2}';
|
|
142
|
+
};
|
|
143
|
+
expect(input.mqCompat.latex()).toEqual('\\frac{1}{2}');
|
|
144
|
+
});
|
|
145
|
+
it('exposes latex(v) as a setter and el()', function () {
|
|
146
|
+
var _withField8 = withField(),
|
|
147
|
+
input = _withField8.input,
|
|
148
|
+
f = _withField8.f;
|
|
149
|
+
input.mqCompat.latex('x+1');
|
|
150
|
+
expect(f.value).toEqual('x+1');
|
|
151
|
+
expect(input.mqCompat.el()).toBe(f);
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
});
|
|
155
|
+
//# sourceMappingURL=input-imperative.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"input-imperative.test.js","names":["_latexBridge","require","_input","_interopRequireDefault","stubField","calls","insert","executeCommand","focus","value","getValue","v","push","blur","withField","input","Input","f","mathField","describe","it","_withField","keystroke","expect","toEqual","_withField2","_withField3","Error","not","toThrow","forEach","k","KEYSTROKES","toBeDefined","_withField4","command","_withField5","_withField6","keyToAction","latex","clear","write","setLatex","element","toBeUndefined","_withField7","mqCompat","_withField8","el","toBe"],"sources":["../../src/__tests__/input-imperative.test.jsx"],"sourcesContent":["import { KEYSTROKES, keyToAction } from '../latex-bridge';\nimport Input from '../mf/input';\n\n/**\n * The imperative surface that @pie-lib/math-toolbar drives\n * (editor-and-pad.jsx: clear/command/keystroke/write/latex).\n *\n * These call the methods against a stub mathfield, because a real\n * <math-field> needs a browser. What matters here is the *translation*:\n * MathQuill-era arguments must become valid MathLive operations.\n */\nconst stubField = () => {\n const calls = { insert: [], executeCommand: [], focus: 0 };\n\n return {\n calls,\n value: '',\n getValue: () => '',\n insert(v) {\n calls.insert.push(v);\n },\n executeCommand(v) {\n calls.executeCommand.push(v);\n },\n focus() {\n calls.focus++;\n },\n blur() {},\n };\n};\n\nconst withField = () => {\n const input = new Input({});\n const f = stubField();\n\n input.mathField = f;\n\n return { input, f };\n};\n\ndescribe('Input imperative API (drives math-toolbar)', () => {\n describe('keystroke', () => {\n it('maps MathQuill keystroke names to MathLive selectors', () => {\n const { input, f } = withField();\n\n input.keystroke('Left');\n input.keystroke('Right');\n input.keystroke('Backspace');\n\n expect(f.calls.executeCommand).toEqual(['moveToPreviousChar', 'moveToNextChar', 'deleteBackward']);\n });\n\n it('passes an unknown value through as a selector', () => {\n const { input, f } = withField();\n\n input.keystroke('deleteForward');\n\n expect(f.calls.executeCommand).toEqual(['deleteForward']);\n });\n\n it('does not throw when the engine rejects the selector', () => {\n const { input } = withField();\n\n input.mathField.executeCommand = () => {\n throw new Error('unknown command');\n };\n\n expect(() => input.keystroke('Nonsense')).not.toThrow();\n });\n\n it('covers every keystroke the keypad emits', () => {\n // navigation.js / edit.js only produce these three\n ['Left', 'Right', 'Backspace'].forEach((k) => expect(KEYSTROKES[k]).toBeDefined());\n });\n });\n\n describe('command', () => {\n it('expands argument-taking commands into placeholders', () => {\n const { input, f } = withField();\n\n input.command('\\\\frac');\n\n // a bare \\frac would give no editable slots\n expect(f.calls.insert).toEqual(['\\\\frac{#?}{#?}']);\n });\n\n it('handles array commands', () => {\n const { input, f } = withField();\n\n input.command(['\\\\log', '_']);\n\n expect(f.calls.insert).toEqual(['\\\\log_{#?}']);\n });\n\n it('passes argument-less commands through', () => {\n const { input, f } = withField();\n\n input.command('\\\\pi');\n\n expect(f.calls.insert).toEqual(['\\\\pi']);\n });\n\n it('agrees with keyToAction', () => {\n expect(keyToAction({ command: '\\\\sqrt' }).value).toEqual('\\\\sqrt{#?}');\n });\n });\n\n describe('safety before MathLive loads', () => {\n it('every method is a no-op rather than a crash', () => {\n const input = new Input({});\n\n // mathField is undefined until loadMathLive() resolves\n expect(input.latex()).toEqual('');\n expect(input.clear()).toEqual('');\n expect(input.command('\\\\frac')).toEqual('');\n expect(input.keystroke('Left')).toEqual('');\n expect(input.write('x')).toEqual('');\n expect(() => input.focus()).not.toThrow();\n expect(() => input.blur()).not.toThrow();\n expect(() => input.setLatex('x')).not.toThrow();\n expect(input.element).toBeUndefined();\n });\n });\n\n describe('mqCompat facade', () => {\n // math-toolbar used to call this.input.mathField.latex(); external\n // consumers may still do the same.\n it('exposes latex() as a getter', () => {\n const { input } = withField();\n\n input.mathField.getValue = () => '\\\\frac{1}{2}';\n\n expect(input.mqCompat.latex()).toEqual('\\\\frac{1}{2}');\n });\n\n it('exposes latex(v) as a setter and el()', () => {\n const { input, f } = withField();\n\n input.mqCompat.latex('x+1');\n expect(f.value).toEqual('x+1');\n expect(input.mqCompat.el()).toBe(f);\n });\n });\n});\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -77,10 +77,43 @@ describe('mathlive-instance', function () {
|
|
|
77
77
|
it('returns undefined without an element', function () {
|
|
78
78
|
expect(instance.applyStaticMath(null, 'x')).toBeUndefined();
|
|
79
79
|
});
|
|
80
|
-
it('returns undefined when MathLive has not loaded', function () {
|
|
80
|
+
it('defers (returns undefined) when MathLive has not loaded', function () {
|
|
81
81
|
var el = document.createElement('div');
|
|
82
82
|
expect(instance.applyStaticMath(el, 'x')).toBeUndefined();
|
|
83
83
|
});
|
|
84
|
+
it('renders synchronously once MathLive is available', function () {
|
|
85
|
+
var el = document.createElement('div');
|
|
86
|
+
instance.__setMathLiveForTest({
|
|
87
|
+
convertLatexToMarkup: function convertLatexToMarkup(l) {
|
|
88
|
+
return "<span>".concat(l, "</span>");
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
expect(instance.applyStaticMath(el, '\\pi')).toBe(el);
|
|
92
|
+
expect(el.innerHTML).toEqual('<span>\\pi</span>');
|
|
93
|
+
});
|
|
94
|
+
it('falls back to the element textContent when no latex is passed', function () {
|
|
95
|
+
var el = document.createElement('div');
|
|
96
|
+
el.textContent = '\\theta';
|
|
97
|
+
instance.__setMathLiveForTest({
|
|
98
|
+
convertLatexToMarkup: function convertLatexToMarkup(l) {
|
|
99
|
+
return "<i>".concat(l, "</i>");
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
instance.applyStaticMath(el);
|
|
103
|
+
expect(el.innerHTML).toEqual('<i>\\theta</i>');
|
|
104
|
+
});
|
|
105
|
+
it('bridges stored latex (newLine embed) before rendering', function () {
|
|
106
|
+
var el = document.createElement('div');
|
|
107
|
+
instance.__setMathLiveForTest({
|
|
108
|
+
convertLatexToMarkup: function convertLatexToMarkup(l) {
|
|
109
|
+
return l;
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
instance.applyStaticMath(el, 'a\\embed{newLine}[]b');
|
|
113
|
+
|
|
114
|
+
// \embed{newLine}[] must become a multiline environment
|
|
115
|
+
expect(el.innerHTML).toContain('displaylines');
|
|
116
|
+
});
|
|
84
117
|
});
|
|
85
118
|
describe('configureFonts', function () {
|
|
86
119
|
// MathLive's default fontsDirectory is the relative './fonts/', which it
|
|
@@ -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","applyStaticMath","toBeUndefined","el","document","createElement","_typeof2","configureFonts","toBe","MathfieldElement","__setMathLiveForTest","fontsDirectory","concat","baseURI","replace","startsWith","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\n describe('applyStaticMath', () => {\n it('returns undefined without an element', () => {\n expect(instance.applyStaticMath(null, 'x')).toBeUndefined();\n });\n\n it('returns undefined when MathLive has not loaded', () => {\n const el = document.createElement('div');\n\n expect(instance.applyStaticMath(el, 'x')).toBeUndefined();\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 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","applyStaticMath","toBeUndefined","el","document","createElement","__setMathLiveForTest","convertLatexToMarkup","l","concat","toBe","innerHTML","textContent","toContain","_typeof2","configureFonts","MathfieldElement","fontsDirectory","baseURI","replace","startsWith","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\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 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":[]}
|
package/lib/mathlive-instance.js
CHANGED
|
@@ -271,22 +271,36 @@ var __setMathLiveForTest = exports.__setMathLiveForTest = function __setMathLive
|
|
|
271
271
|
* Render static math into an element. API-compatible with
|
|
272
272
|
* @pie-lib/math-input's `applyStaticMath`.
|
|
273
273
|
*
|
|
274
|
+
* Callers written against MathQuill invoke this synchronously from lifecycle
|
|
275
|
+
* methods, where MathLive (a dynamic import) may not have loaded yet. Rather
|
|
276
|
+
* than silently rendering nothing, this kicks off the load and re-applies once
|
|
277
|
+
* the engine is ready, so the element fills in on the next tick.
|
|
278
|
+
*
|
|
274
279
|
* @param {HTMLElement} element
|
|
275
280
|
* @param {string} [latex] assigned to the element before rendering
|
|
276
281
|
* @param {object} [options] `{ macros }` overrides
|
|
277
|
-
* @returns {HTMLElement|undefined} the element,
|
|
282
|
+
* @returns {HTMLElement|undefined} the element, or undefined if deferred
|
|
278
283
|
*/
|
|
279
284
|
function applyStaticMath(element, latex) {
|
|
280
285
|
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
281
286
|
if (!element || typeof window === 'undefined') {
|
|
282
287
|
return undefined;
|
|
283
288
|
}
|
|
289
|
+
|
|
290
|
+
// Capture the source now: if we defer, the element's textContent may have
|
|
291
|
+
// been overwritten by the time MathLive is ready.
|
|
292
|
+
var source = latex === undefined || latex === null ? element.textContent : latex;
|
|
284
293
|
var ml = getMathLive();
|
|
285
294
|
if (!ml) {
|
|
286
|
-
log('applyStaticMath called before MathLive loaded -
|
|
295
|
+
log('applyStaticMath called before MathLive loaded - deferring until it is ready');
|
|
296
|
+
loadMathLive().then(function (loaded) {
|
|
297
|
+
// The element may have been unmounted while loading.
|
|
298
|
+
if (loaded && element.isConnected !== false) {
|
|
299
|
+
applyStaticMath(element, source, options);
|
|
300
|
+
}
|
|
301
|
+
});
|
|
287
302
|
return undefined;
|
|
288
303
|
}
|
|
289
|
-
var source = latex === undefined || latex === null ? element.textContent : latex;
|
|
290
304
|
element.innerHTML = ml.convertLatexToMarkup((0, _latexBridge.toMathLive)(source), {
|
|
291
305
|
macros: _objectSpread(_objectSpread({}, getMacros()), options.macros || {})
|
|
292
306
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mathlive-instance.js","names":["_debug","_interopRequireDefault","require","_latexBridge","ownKeys","e","r","t","Object","keys","getOwnPropertySymbols","o","filter","getOwnPropertyDescriptor","enumerable","push","apply","_objectSpread","arguments","length","forEach","_defineProperty2","getOwnPropertyDescriptors","defineProperties","defineProperty","_interopRequireWildcard","WeakMap","n","__esModule","i","f","__proto__","_typeof","has","get","set","_t2","hasOwnProperty","call","log","debug","mathlive","fontsDirectory","absoluteFontsDirectory","dir","test","URL","document","baseURI","href","message","configureFonts","exports","MathfieldElement","PIE_MACROS","parallelogram","overarc","napprox","nsim","ncong","nparallel","perpendicular","divide","degree","square","longdiv","abs","embeds","Map","KNOWN_EMBED_LATEX","newLine","answerBlock","loadMathLive","_ref","_asyncToGenerator2","_regenerator","mark","_callee","_t","wrap","_context","prev","next","window","abrupt","undefined","Promise","resolve","then","sent","stop","getMathLive","getMacros","out","_ref2","name","latex","concat","registerEmbed","factory","definition","prototype","mathliveLatex","registeredEmbeds","Array","from","__resetEmbeds","clear","__setMathLiveForTest","stub","applyStaticMath","element","options","ml","source","textContent","innerHTML","convertLatexToMarkup","toMathLive","macros","latexToMarkup"],"sources":["../src/mathlive-instance.js"],"sourcesContent":["import debug from 'debug';\nimport { NEWLINE_EMBED, toMathLive } from './latex-bridge';\n\nconst log = debug('pie-lib:math-input-mathlive:instance');\n\n/**\n * MathLive bootstrap + compatibility shims for @pie-lib/math-input's public API.\n *\n * MathLive is loaded lazily and only in the browser: the editor bundle is\n * ~227KB gzip and registers custom elements, so it must never run during SSR.\n */\n\nlet mathlive;\n\n/**\n * Where the KaTeX woff2 fonts are served from, as configured by the host app.\n * `undefined` means \"not configured\"; `null` means \"explicitly disabled\".\n */\nlet fontsDirectory;\n\n/**\n * Turn a fonts path into a fully-qualified URL.\n *\n * MathLive's default `fontsDirectory` is the relative `'./fonts/'`, which it\n * resolves against its own script URL. Under a bundler (webpack/Next) that\n * script URL is empty, so `new URL('./fonts/', '')` throws\n * \"Failed to construct 'URL': Invalid base URL\" from `loadFonts`.\n * Resolving against `document.baseURI` avoids that entirely and honours any\n * <base href> / asset prefix the host app uses.\n */\nconst absoluteFontsDirectory = (dir) => {\n if (!dir) {\n return dir;\n }\n\n // Already absolute (http://, https://, //cdn...) - MathLive handles these.\n if (/^(?:[a-z+]+:)?\\/\\//i.test(dir)) {\n return dir;\n }\n\n try {\n return new URL(dir, document.baseURI).href;\n } catch (e) {\n log('could not resolve fontsDirectory \"%s\": %s', dir, e && e.message);\n return null;\n }\n};\n\n/**\n * Tell the package where the MathLive fonts are served from.\n *\n * Call before `loadMathLive()`. Accepts an absolute URL, a root-relative path\n * (`/mathlive-fonts`) or a relative one; pass `null` to skip font loading and\n * fall back to system fonts.\n *\n * The fonts ship inside the `mathlive` package (`node_modules/mathlive/fonts`)\n * and must be copied into whatever the host app serves statically.\n *\n * @param {string|null} dir\n */\nexport const configureFonts = (dir) => {\n fontsDirectory = dir;\n\n if (mathlive) {\n mathlive.MathfieldElement.fontsDirectory = absoluteFontsDirectory(dir);\n }\n};\n\n/**\n * Custom macros for the pie-specific commands that the MathQuill fork\n * understood but stock LaTeX does not.\n *\n * Kept deliberately in sync with the MathJax macros in\n * @pie-lib/math-rendering (`render-math.js`) so the same latex renders the same\n * way in the editor and in the static renderer.\n */\nexport const PIE_MACROS = {\n parallelogram: '\\\\htmlData{pie-macro=parallelogram}{\\\\unicode{\"25B1}}',\n overarc: '\\\\overparen{#1}',\n napprox: '\\\\not\\\\approx',\n nsim: '\\\\not\\\\sim',\n ncong: '\\\\not\\\\cong',\n nparallel: '\\\\not\\\\parallel',\n perpendicular: '\\\\perp',\n divide: '\\\\div',\n degree: '^{\\\\circ}',\n square: '\\\\unicode{\"25A1}',\n longdiv: '\\\\htmlData{pie-macro=longdiv}{#1}',\n abs: '\\\\left|#1\\\\right|',\n};\n\n/**\n * Registry for `registerEmbed`.\n *\n * MathLive has no embed plugin system, so an embed is expressed as a macro that\n * expands to real LaTeX. `\\htmlData{embed=<name>}` tags the rendered output so\n * consumers can target it with CSS exactly as they targeted the old\n * `htmlString` markup.\n *\n * Known embeds map to native constructs:\n * - `newLine` -> structural, handled by latex-bridge (`\\displaylines` + `\\\\`)\n * - `answerBlock`-> `\\placeholder{}` (interactive, read via the prompts API)\n *\n * @type {Map<string, {factory: Function, latex: string}>}\n */\nconst embeds = new Map();\n\nconst KNOWN_EMBED_LATEX = {\n // newLine is structural: it is translated by latex-bridge before it ever\n // reaches MathLive, so the macro only needs to be harmless.\n newLine: '',\n answerBlock: '\\\\placeholder{}',\n};\n\n/**\n * Load MathLive. Resolves to undefined during SSR.\n * @returns {Promise<object|undefined>}\n */\nexport const loadMathLive = async () => {\n if (typeof window === 'undefined') {\n return undefined;\n }\n\n if (!mathlive) {\n try {\n mathlive = await import('mathlive');\n } catch (e) {\n // MathLive is browser-only and ships an ESM-conditional exports map, so\n // the import can fail in test/SSR-ish runtimes. Fail soft: callers all\n // handle a missing instance (static rendering falls back to raw latex).\n log('MathLive could not be loaded: %s', e && e.message);\n return undefined;\n }\n\n // Always replace MathLive's relative `'./fonts/'` default: it throws\n // \"Invalid base URL\" when bundled. Either point at the host app's copy or\n // disable font loading, both of which are safe.\n if (fontsDirectory === undefined) {\n log(\n 'no fontsDirectory configured - MathLive will use fallback fonts. ' +\n 'Call configureFonts(\"/path/to/fonts\") with a copy of node_modules/mathlive/fonts to enable them.',\n );\n }\n\n mathlive.MathfieldElement.fontsDirectory =\n fontsDirectory === undefined ? null : absoluteFontsDirectory(fontsDirectory);\n }\n\n return mathlive;\n};\n\n/**\n * Synchronous accessor for an already-loaded MathLive.\n * @returns {object|undefined}\n */\nexport const getMathLive = () => mathlive;\n\n/**\n * The macro dictionary to hand to a mathfield: pie macros plus anything\n * registered through `registerEmbed`.\n *\n * @returns {object}\n */\nexport const getMacros = () => {\n const out = { ...PIE_MACROS };\n\n embeds.forEach(({ latex }, name) => {\n out[name] = `\\\\htmlData{embed=${name}}{${latex}}`;\n });\n\n return out;\n};\n\n/**\n * Register an embed. API-compatible with @pie-lib/math-input's `registerEmbed`\n * so existing callers do not change.\n *\n * MathQuill's factory returns `{ htmlString, text, latex }`. Only the\n * declarative parts survive: `latex` round-trips through a macro and the\n * styling hook becomes a `data-embed` attribute. Arbitrary DOM injection via\n * `htmlString` has no MathLive equivalent and is ignored.\n *\n * @param {string} name\n * @param {Function} factory\n */\nexport function registerEmbed(name, factory) {\n if (!name || typeof factory !== 'function') {\n return;\n }\n\n let definition = {};\n\n try {\n definition = factory() || {};\n } catch (e) {\n log('embed factory threw for \"%s\": %s', name, e.message);\n }\n\n const latex = Object.prototype.hasOwnProperty.call(KNOWN_EMBED_LATEX, name)\n ? KNOWN_EMBED_LATEX[name]\n : definition.mathliveLatex || '\\\\placeholder{}';\n\n if (!Object.prototype.hasOwnProperty.call(KNOWN_EMBED_LATEX, name) && !definition.mathliveLatex) {\n // Unknown third-party embed: degrade instead of throwing. `htmlString`\n // cannot be reproduced, so it renders as an editable slot.\n log(\n 'embed \"%s\" is not natively supported by MathLive; rendering as a placeholder. ' +\n 'Provide `mathliveLatex` in the factory result to control this.',\n name,\n );\n }\n\n embeds.set(name, { factory, latex });\n}\n\n/**\n * Embeds registered so far. Exposed for tests/diagnostics.\n * @returns {string[]}\n */\nexport const registeredEmbeds = () => Array.from(embeds.keys());\n\n/** Reset the embed registry. Test helper. */\nexport const __resetEmbeds = () => embeds.clear();\n\n/** Inject a stub MathLive instance. Test helper. */\nexport const __setMathLiveForTest = (stub) => {\n mathlive = stub;\n};\n\n/**\n * Render static math into an element. API-compatible with\n * @pie-lib/math-input's `applyStaticMath`.\n *\n * @param {HTMLElement} element\n * @param {string} [latex] assigned to the element before rendering\n * @param {object} [options] `{ macros }` overrides\n * @returns {HTMLElement|undefined} the element, for parity with the old return\n */\nexport function applyStaticMath(element, latex, options = {}) {\n if (!element || typeof window === 'undefined') {\n return undefined;\n }\n\n const ml = getMathLive();\n\n if (!ml) {\n log('applyStaticMath called before MathLive loaded - call loadMathLive() first');\n return undefined;\n }\n\n const source = latex === undefined || latex === null ? element.textContent : latex;\n\n element.innerHTML = ml.convertLatexToMarkup(toMathLive(source), {\n macros: { ...getMacros(), ...(options.macros || {}) },\n });\n\n return element;\n}\n\n/**\n * Convert latex to markup using the pie macro set. Used for keypad labels and\n * any read-only rendering that does not need a live mathfield.\n *\n * @param {string} latex\n * @param {object} [options]\n * @returns {string} HTML markup, or '' if MathLive is not loaded\n */\nexport function latexToMarkup(latex, options = {}) {\n const ml = getMathLive();\n\n if (!ml || !latex) {\n return '';\n }\n\n try {\n return ml.convertLatexToMarkup(toMathLive(latex), {\n macros: { ...getMacros(), ...(options.macros || {}) },\n ...options,\n });\n } catch (e) {\n log('convertLatexToMarkup failed for \"%s\": %s', latex, e.message);\n return '';\n }\n}\n\nexport { NEWLINE_EMBED };\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"mathlive-instance.js","names":["_debug","_interopRequireDefault","require","_latexBridge","ownKeys","e","r","t","Object","keys","getOwnPropertySymbols","o","filter","getOwnPropertyDescriptor","enumerable","push","apply","_objectSpread","arguments","length","forEach","_defineProperty2","getOwnPropertyDescriptors","defineProperties","defineProperty","_interopRequireWildcard","WeakMap","n","__esModule","i","f","__proto__","_typeof","has","get","set","_t2","hasOwnProperty","call","log","debug","mathlive","fontsDirectory","absoluteFontsDirectory","dir","test","URL","document","baseURI","href","message","configureFonts","exports","MathfieldElement","PIE_MACROS","parallelogram","overarc","napprox","nsim","ncong","nparallel","perpendicular","divide","degree","square","longdiv","abs","embeds","Map","KNOWN_EMBED_LATEX","newLine","answerBlock","loadMathLive","_ref","_asyncToGenerator2","_regenerator","mark","_callee","_t","wrap","_context","prev","next","window","abrupt","undefined","Promise","resolve","then","sent","stop","getMathLive","getMacros","out","_ref2","name","latex","concat","registerEmbed","factory","definition","prototype","mathliveLatex","registeredEmbeds","Array","from","__resetEmbeds","clear","__setMathLiveForTest","stub","applyStaticMath","element","options","source","textContent","ml","loaded","isConnected","innerHTML","convertLatexToMarkup","toMathLive","macros","latexToMarkup"],"sources":["../src/mathlive-instance.js"],"sourcesContent":["import debug from 'debug';\nimport { NEWLINE_EMBED, toMathLive } from './latex-bridge';\n\nconst log = debug('pie-lib:math-input-mathlive:instance');\n\n/**\n * MathLive bootstrap + compatibility shims for @pie-lib/math-input's public API.\n *\n * MathLive is loaded lazily and only in the browser: the editor bundle is\n * ~227KB gzip and registers custom elements, so it must never run during SSR.\n */\n\nlet mathlive;\n\n/**\n * Where the KaTeX woff2 fonts are served from, as configured by the host app.\n * `undefined` means \"not configured\"; `null` means \"explicitly disabled\".\n */\nlet fontsDirectory;\n\n/**\n * Turn a fonts path into a fully-qualified URL.\n *\n * MathLive's default `fontsDirectory` is the relative `'./fonts/'`, which it\n * resolves against its own script URL. Under a bundler (webpack/Next) that\n * script URL is empty, so `new URL('./fonts/', '')` throws\n * \"Failed to construct 'URL': Invalid base URL\" from `loadFonts`.\n * Resolving against `document.baseURI` avoids that entirely and honours any\n * <base href> / asset prefix the host app uses.\n */\nconst absoluteFontsDirectory = (dir) => {\n if (!dir) {\n return dir;\n }\n\n // Already absolute (http://, https://, //cdn...) - MathLive handles these.\n if (/^(?:[a-z+]+:)?\\/\\//i.test(dir)) {\n return dir;\n }\n\n try {\n return new URL(dir, document.baseURI).href;\n } catch (e) {\n log('could not resolve fontsDirectory \"%s\": %s', dir, e && e.message);\n return null;\n }\n};\n\n/**\n * Tell the package where the MathLive fonts are served from.\n *\n * Call before `loadMathLive()`. Accepts an absolute URL, a root-relative path\n * (`/mathlive-fonts`) or a relative one; pass `null` to skip font loading and\n * fall back to system fonts.\n *\n * The fonts ship inside the `mathlive` package (`node_modules/mathlive/fonts`)\n * and must be copied into whatever the host app serves statically.\n *\n * @param {string|null} dir\n */\nexport const configureFonts = (dir) => {\n fontsDirectory = dir;\n\n if (mathlive) {\n mathlive.MathfieldElement.fontsDirectory = absoluteFontsDirectory(dir);\n }\n};\n\n/**\n * Custom macros for the pie-specific commands that the MathQuill fork\n * understood but stock LaTeX does not.\n *\n * Kept deliberately in sync with the MathJax macros in\n * @pie-lib/math-rendering (`render-math.js`) so the same latex renders the same\n * way in the editor and in the static renderer.\n */\nexport const PIE_MACROS = {\n parallelogram: '\\\\htmlData{pie-macro=parallelogram}{\\\\unicode{\"25B1}}',\n overarc: '\\\\overparen{#1}',\n napprox: '\\\\not\\\\approx',\n nsim: '\\\\not\\\\sim',\n ncong: '\\\\not\\\\cong',\n nparallel: '\\\\not\\\\parallel',\n perpendicular: '\\\\perp',\n divide: '\\\\div',\n degree: '^{\\\\circ}',\n square: '\\\\unicode{\"25A1}',\n longdiv: '\\\\htmlData{pie-macro=longdiv}{#1}',\n abs: '\\\\left|#1\\\\right|',\n};\n\n/**\n * Registry for `registerEmbed`.\n *\n * MathLive has no embed plugin system, so an embed is expressed as a macro that\n * expands to real LaTeX. `\\htmlData{embed=<name>}` tags the rendered output so\n * consumers can target it with CSS exactly as they targeted the old\n * `htmlString` markup.\n *\n * Known embeds map to native constructs:\n * - `newLine` -> structural, handled by latex-bridge (`\\displaylines` + `\\\\`)\n * - `answerBlock`-> `\\placeholder{}` (interactive, read via the prompts API)\n *\n * @type {Map<string, {factory: Function, latex: string}>}\n */\nconst embeds = new Map();\n\nconst KNOWN_EMBED_LATEX = {\n // newLine is structural: it is translated by latex-bridge before it ever\n // reaches MathLive, so the macro only needs to be harmless.\n newLine: '',\n answerBlock: '\\\\placeholder{}',\n};\n\n/**\n * Load MathLive. Resolves to undefined during SSR.\n * @returns {Promise<object|undefined>}\n */\nexport const loadMathLive = async () => {\n if (typeof window === 'undefined') {\n return undefined;\n }\n\n if (!mathlive) {\n try {\n mathlive = await import('mathlive');\n } catch (e) {\n // MathLive is browser-only and ships an ESM-conditional exports map, so\n // the import can fail in test/SSR-ish runtimes. Fail soft: callers all\n // handle a missing instance (static rendering falls back to raw latex).\n log('MathLive could not be loaded: %s', e && e.message);\n return undefined;\n }\n\n // Always replace MathLive's relative `'./fonts/'` default: it throws\n // \"Invalid base URL\" when bundled. Either point at the host app's copy or\n // disable font loading, both of which are safe.\n if (fontsDirectory === undefined) {\n log(\n 'no fontsDirectory configured - MathLive will use fallback fonts. ' +\n 'Call configureFonts(\"/path/to/fonts\") with a copy of node_modules/mathlive/fonts to enable them.',\n );\n }\n\n mathlive.MathfieldElement.fontsDirectory =\n fontsDirectory === undefined ? null : absoluteFontsDirectory(fontsDirectory);\n }\n\n return mathlive;\n};\n\n/**\n * Synchronous accessor for an already-loaded MathLive.\n * @returns {object|undefined}\n */\nexport const getMathLive = () => mathlive;\n\n/**\n * The macro dictionary to hand to a mathfield: pie macros plus anything\n * registered through `registerEmbed`.\n *\n * @returns {object}\n */\nexport const getMacros = () => {\n const out = { ...PIE_MACROS };\n\n embeds.forEach(({ latex }, name) => {\n out[name] = `\\\\htmlData{embed=${name}}{${latex}}`;\n });\n\n return out;\n};\n\n/**\n * Register an embed. API-compatible with @pie-lib/math-input's `registerEmbed`\n * so existing callers do not change.\n *\n * MathQuill's factory returns `{ htmlString, text, latex }`. Only the\n * declarative parts survive: `latex` round-trips through a macro and the\n * styling hook becomes a `data-embed` attribute. Arbitrary DOM injection via\n * `htmlString` has no MathLive equivalent and is ignored.\n *\n * @param {string} name\n * @param {Function} factory\n */\nexport function registerEmbed(name, factory) {\n if (!name || typeof factory !== 'function') {\n return;\n }\n\n let definition = {};\n\n try {\n definition = factory() || {};\n } catch (e) {\n log('embed factory threw for \"%s\": %s', name, e.message);\n }\n\n const latex = Object.prototype.hasOwnProperty.call(KNOWN_EMBED_LATEX, name)\n ? KNOWN_EMBED_LATEX[name]\n : definition.mathliveLatex || '\\\\placeholder{}';\n\n if (!Object.prototype.hasOwnProperty.call(KNOWN_EMBED_LATEX, name) && !definition.mathliveLatex) {\n // Unknown third-party embed: degrade instead of throwing. `htmlString`\n // cannot be reproduced, so it renders as an editable slot.\n log(\n 'embed \"%s\" is not natively supported by MathLive; rendering as a placeholder. ' +\n 'Provide `mathliveLatex` in the factory result to control this.',\n name,\n );\n }\n\n embeds.set(name, { factory, latex });\n}\n\n/**\n * Embeds registered so far. Exposed for tests/diagnostics.\n * @returns {string[]}\n */\nexport const registeredEmbeds = () => Array.from(embeds.keys());\n\n/** Reset the embed registry. Test helper. */\nexport const __resetEmbeds = () => embeds.clear();\n\n/** Inject a stub MathLive instance. Test helper. */\nexport const __setMathLiveForTest = (stub) => {\n mathlive = stub;\n};\n\n/**\n * Render static math into an element. API-compatible with\n * @pie-lib/math-input's `applyStaticMath`.\n *\n * Callers written against MathQuill invoke this synchronously from lifecycle\n * methods, where MathLive (a dynamic import) may not have loaded yet. Rather\n * than silently rendering nothing, this kicks off the load and re-applies once\n * the engine is ready, so the element fills in on the next tick.\n *\n * @param {HTMLElement} element\n * @param {string} [latex] assigned to the element before rendering\n * @param {object} [options] `{ macros }` overrides\n * @returns {HTMLElement|undefined} the element, or undefined if deferred\n */\nexport function applyStaticMath(element, latex, options = {}) {\n if (!element || typeof window === 'undefined') {\n return undefined;\n }\n\n // Capture the source now: if we defer, the element's textContent may have\n // been overwritten by the time MathLive is ready.\n const source = latex === undefined || latex === null ? element.textContent : latex;\n const ml = getMathLive();\n\n if (!ml) {\n log('applyStaticMath called before MathLive loaded - deferring until it is ready');\n\n loadMathLive().then((loaded) => {\n // The element may have been unmounted while loading.\n if (loaded && element.isConnected !== false) {\n applyStaticMath(element, source, options);\n }\n });\n\n return undefined;\n }\n\n element.innerHTML = ml.convertLatexToMarkup(toMathLive(source), {\n macros: { ...getMacros(), ...(options.macros || {}) },\n });\n\n return element;\n}\n\n/**\n * Convert latex to markup using the pie macro set. Used for keypad labels and\n * any read-only rendering that does not need a live mathfield.\n *\n * @param {string} latex\n * @param {object} [options]\n * @returns {string} HTML markup, or '' if MathLive is not loaded\n */\nexport function latexToMarkup(latex, options = {}) {\n const ml = getMathLive();\n\n if (!ml || !latex) {\n return '';\n }\n\n try {\n return ml.convertLatexToMarkup(toMathLive(latex), {\n macros: { ...getMacros(), ...(options.macros || {}) },\n ...options,\n });\n } catch (e) {\n log('convertLatexToMarkup failed for \"%s\": %s', latex, e.message);\n return '';\n }\n}\n\nexport { NEWLINE_EMBED };\n"],"mappings":"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","ignoreList":[]}
|
package/lib/mf/input.js
CHANGED
|
@@ -163,6 +163,56 @@ var Input = exports.Input = /*#__PURE__*/function (_React$Component) {
|
|
|
163
163
|
function latex() {
|
|
164
164
|
return this.mathField ? (0, _latexBridge.fromMathLive)(this.mathField.getValue('latex')) : '';
|
|
165
165
|
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* The underlying `<math-field>` element, or undefined until MathLive has
|
|
169
|
+
* finished loading. Exposed for callers that need the real element.
|
|
170
|
+
*
|
|
171
|
+
* NOTE: this is NOT a MathQuill field. Code written against
|
|
172
|
+
* `@pie-lib/math-input` often did `input.mathField.latex()`; that shape is
|
|
173
|
+
* provided by `mqCompat` below, and `latex()` on this component is the
|
|
174
|
+
* supported replacement.
|
|
175
|
+
*/
|
|
176
|
+
}, {
|
|
177
|
+
key: "element",
|
|
178
|
+
get: function get() {
|
|
179
|
+
return this.mathField;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* MathQuill-shaped facade, so existing `input.mathField.latex()` /
|
|
184
|
+
* `.el()` call sites keep working instead of throwing. Only the members that
|
|
185
|
+
* consumers actually used are provided; MathQuill internals such as
|
|
186
|
+
* `__controller` have no MathLive equivalent and are deliberately absent.
|
|
187
|
+
*/
|
|
188
|
+
}, {
|
|
189
|
+
key: "mqCompat",
|
|
190
|
+
get: function get() {
|
|
191
|
+
var _this2 = this;
|
|
192
|
+
return {
|
|
193
|
+
latex: function latex(v) {
|
|
194
|
+
return v === undefined ? _this2.latex() : (_this2.setLatex(v), v);
|
|
195
|
+
},
|
|
196
|
+
el: function el() {
|
|
197
|
+
return _this2.mathField;
|
|
198
|
+
},
|
|
199
|
+
focus: function focus() {
|
|
200
|
+
return _this2.focus();
|
|
201
|
+
},
|
|
202
|
+
blur: function blur() {
|
|
203
|
+
return _this2.blur();
|
|
204
|
+
}
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/** Programmatically replace the content. */
|
|
209
|
+
}, {
|
|
210
|
+
key: "setLatex",
|
|
211
|
+
value: function setLatex(v) {
|
|
212
|
+
if (this.mathField) {
|
|
213
|
+
this.mathField.value = (0, _latexBridge.toMathLive)(v || '');
|
|
214
|
+
}
|
|
215
|
+
}
|
|
166
216
|
}, {
|
|
167
217
|
key: "clear",
|
|
168
218
|
value: function clear() {
|
|
@@ -184,33 +234,52 @@ var Input = exports.Input = /*#__PURE__*/function (_React$Component) {
|
|
|
184
234
|
this.mathField && this.mathField.focus();
|
|
185
235
|
}
|
|
186
236
|
|
|
187
|
-
/**
|
|
237
|
+
/**
|
|
238
|
+
* MathQuill `cmd()` equivalent.
|
|
239
|
+
*
|
|
240
|
+
* Callers pass MathQuill command names (`'\\frac'`, `'\\sqrt'`, `'^'`, or an
|
|
241
|
+
* array of them). Those must be expanded into latex with `#?` placeholders,
|
|
242
|
+
* otherwise inserting a bare `\frac` produces no editable slots.
|
|
243
|
+
*/
|
|
188
244
|
}, {
|
|
189
245
|
key: "command",
|
|
190
246
|
value: function command(v) {
|
|
191
|
-
var _this2 = this;
|
|
192
247
|
log('command: ', v);
|
|
193
248
|
if (!this.mathField) {
|
|
194
249
|
return '';
|
|
195
250
|
}
|
|
196
|
-
var
|
|
197
|
-
|
|
198
|
-
|
|
251
|
+
var action = (0, _latexBridge.keyToAction)({
|
|
252
|
+
command: v
|
|
253
|
+
});
|
|
254
|
+
if (action) {
|
|
255
|
+
this.mathField.insert(action.value, {
|
|
199
256
|
focus: true
|
|
200
257
|
});
|
|
201
|
-
}
|
|
258
|
+
}
|
|
202
259
|
this.mathField.focus();
|
|
203
260
|
return this.latex();
|
|
204
261
|
}
|
|
205
262
|
|
|
206
|
-
/**
|
|
263
|
+
/**
|
|
264
|
+
* MathQuill `keystroke()` equivalent.
|
|
265
|
+
*
|
|
266
|
+
* Accepts MathQuill keystroke names (`'Left'`, `'Right'`, `'Backspace'`) as
|
|
267
|
+
* the keypad emits them, and passes anything else through as a MathLive
|
|
268
|
+
* selector.
|
|
269
|
+
*/
|
|
207
270
|
}, {
|
|
208
271
|
key: "keystroke",
|
|
209
|
-
value: function keystroke(
|
|
272
|
+
value: function keystroke(v) {
|
|
273
|
+
log('keystroke: ', v);
|
|
210
274
|
if (!this.mathField) {
|
|
211
275
|
return '';
|
|
212
276
|
}
|
|
213
|
-
|
|
277
|
+
var selector = _latexBridge.KEYSTROKES[v] || v;
|
|
278
|
+
try {
|
|
279
|
+
this.mathField.executeCommand(selector);
|
|
280
|
+
} catch (e) {
|
|
281
|
+
log('unknown keystroke/selector "%s": %s', v, e && e.message);
|
|
282
|
+
}
|
|
214
283
|
this.mathField.focus();
|
|
215
284
|
return this.latex();
|
|
216
285
|
}
|
package/lib/mf/input.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"input.js","names":["_react","_interopRequireDefault","require","_propTypes","_styles","_debug","_mathliveInstance","_latexBridge","_callSuper","t","o","e","_getPrototypeOf2","_possibleConstructorReturn2","_isNativeReflectConstruct","Reflect","construct","constructor","apply","Boolean","prototype","valueOf","call","log","debug","Holder","styled","display","width","Input","exports","_React$Component","props","_this","_classCallCheck2","_defineProperty2","onChange","mathField","latex","fromMathLive","getValue","lastEmitted","event","key","preventDefault","holderRef","React","createRef","undefined","_inherits2","_createClass2","value","_componentDidMount","_asyncToGenerator2","_regenerator","mark","_callee","_this$setState","ml","wrap","_context","prev","next","loadMathLive","sent","current","abrupt","MathfieldElement","macros","getMacros","toMathLive","readOnly","mathVirtualKeyboardPolicy","addEventListener","onInputEdit","appendChild","innerRef","setState","stop","componentDidMount","arguments","componentDidUpdate","prevProps","_this$props","componentWillUnmount","removeEventListener","remove","clear","blur","focus","command","v","_this2","values","Array","isArray","forEach","vv","insert","keystroke","selector","executeCommand","write","_this3","render","_this$props2","className","onFocus","onBlur","onClick","createElement","onKeyDown","ref","Component","PropTypes","string","func","bool","_default"],"sources":["../../src/mf/input.jsx"],"sourcesContent":["import React from 'react';\nimport PropTypes from 'prop-types';\nimport { styled } from '@mui/material/styles';\nimport debug from 'debug';\nimport { loadMathLive, getMacros } from '../mathlive-instance';\nimport { toMathLive, fromMathLive } from '../latex-bridge';\n\nconst log = debug('pie-lib:math-input-mathlive:input');\n\nconst Holder = styled('span')({\n display: 'inline-block',\n '& math-field': {\n display: 'block',\n width: '100%',\n },\n // MathLive ships its own virtual keyboard toggle; pie supplies its own keypad.\n '& math-field::part(virtual-keyboard-toggle)': {\n display: 'none',\n },\n '& math-field::part(menu-toggle)': {\n display: 'none',\n },\n});\n\n/**\n * Editable math field. Drop-in replacement for @pie-lib/math-input's `mq.Input`.\n *\n * Keeps the same imperative surface used by MathInput's keypad\n * (`write`, `command`, `keystroke`, `clear`, `focus`, `blur`) so callers do not\n * change, and the same `latex` / `onChange` props.\n */\nexport class Input extends React.Component {\n static propTypes = {\n className: PropTypes.string,\n latex: PropTypes.string,\n onChange: PropTypes.func,\n onClick: PropTypes.func,\n onFocus: PropTypes.func,\n onBlur: PropTypes.func,\n readOnly: PropTypes.bool,\n innerRef: PropTypes.func,\n };\n\n constructor(props) {\n super(props);\n this.holderRef = React.createRef();\n // Tracks the last latex we emitted, so prop echoes don't reset the cursor.\n this.lastEmitted = undefined;\n }\n\n async componentDidMount() {\n const ml = await loadMathLive();\n\n if (!ml || !this.holderRef.current) {\n return;\n }\n\n this.mathField = new ml.MathfieldElement({ macros: getMacros() });\n this.mathField.value = toMathLive(this.props.latex || '');\n\n if (this.props.readOnly) {\n this.mathField.readOnly = true;\n }\n\n // pie drives input through its own keypad, so suppress MathLive's.\n this.mathField.mathVirtualKeyboardPolicy = 'manual';\n\n this.mathField.addEventListener('input', this.onInputEdit);\n this.holderRef.current.appendChild(this.mathField);\n\n if (this.props.innerRef) {\n this.props.innerRef(this);\n }\n\n this.setState?.({});\n }\n\n componentDidUpdate(prevProps) {\n if (!this.mathField) {\n return;\n }\n\n const { latex, readOnly } = this.props;\n\n if (readOnly !== prevProps.readOnly) {\n this.mathField.readOnly = !!readOnly;\n }\n\n // Only push the prop back into the field when it genuinely differs from\n // what the field already holds. This is the analogue of the old\n // shouldComponentUpdate latex-equality guard and prevents cursor thrash.\n if (latex !== undefined && latex !== null && latex !== this.lastEmitted) {\n const next = toMathLive(latex);\n\n if (next !== this.mathField.value) {\n this.mathField.value = next;\n }\n }\n }\n\n componentWillUnmount() {\n if (this.mathField) {\n this.mathField.removeEventListener('input', this.onInputEdit);\n this.mathField.remove();\n this.mathField = undefined;\n }\n\n if (this.props.innerRef) {\n this.props.innerRef(null);\n }\n }\n\n onInputEdit = () => {\n const { onChange } = this.props;\n\n if (!this.mathField) {\n return;\n }\n\n const latex = fromMathLive(this.mathField.getValue('latex'));\n\n this.lastEmitted = latex;\n\n if (onChange) {\n onChange(latex);\n }\n };\n\n /** Current latex, in stored (MathQuill-compatible) form. */\n latex() {\n return this.mathField ? fromMathLive(this.mathField.getValue('latex')) : '';\n }\n\n clear() {\n if (this.mathField) {\n this.mathField.value = '';\n }\n\n return '';\n }\n\n blur() {\n log('blur mathfield');\n this.mathField && this.mathField.blur();\n }\n\n focus() {\n log('focus mathfield...');\n this.mathField && this.mathField.focus();\n }\n\n /** MathQuill `cmd()` equivalent. */\n command(v) {\n log('command: ', v);\n\n if (!this.mathField) {\n return '';\n }\n\n const values = Array.isArray(v) ? v : [v];\n\n values.forEach((vv) => this.mathField.insert(vv, { focus: true }));\n this.mathField.focus();\n\n return this.latex();\n }\n\n /** MathQuill `keystroke()` equivalent - takes a MathLive selector. */\n keystroke(selector) {\n if (!this.mathField) {\n return '';\n }\n\n this.mathField.executeCommand(selector);\n this.mathField.focus();\n\n return this.latex();\n }\n\n /** MathQuill `write()` equivalent. Accepts an array, as `cmd()` did. */\n write(v) {\n log('write: ', v);\n\n if (!this.mathField) {\n return '';\n }\n\n const values = Array.isArray(v) ? v : [v];\n\n values.forEach((vv) => this.mathField.insert(vv, { focus: true }));\n this.mathField.focus();\n\n return this.latex();\n }\n\n /**\n * Enter must not insert a line break: math input is single-expression, and\n * the MathQuill version swallowed charCode 13 for the same reason. Newlines\n * are authored explicitly through the newLine embed, not the Enter key.\n */\n onKeyDown = (event) => {\n if (event.key === 'Enter') {\n event.preventDefault();\n }\n };\n\n render() {\n const { className, onFocus, onBlur, onClick } = this.props;\n\n return (\n <Holder\n className={className}\n onFocus={onFocus}\n onBlur={onBlur}\n onClick={onClick}\n onKeyDown={this.onKeyDown}\n ref={this.holderRef}\n />\n );\n }\n}\n\nexport default Input;\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"input.js","names":["_react","_interopRequireDefault","require","_propTypes","_styles","_debug","_mathliveInstance","_latexBridge","_callSuper","t","o","e","_getPrototypeOf2","_possibleConstructorReturn2","_isNativeReflectConstruct","Reflect","construct","constructor","apply","Boolean","prototype","valueOf","call","log","debug","Holder","styled","display","width","Input","exports","_React$Component","props","_this","_classCallCheck2","_defineProperty2","onChange","mathField","latex","fromMathLive","getValue","lastEmitted","event","key","preventDefault","holderRef","React","createRef","undefined","_inherits2","_createClass2","value","_componentDidMount","_asyncToGenerator2","_regenerator","mark","_callee","_this$setState","ml","wrap","_context","prev","next","loadMathLive","sent","current","abrupt","MathfieldElement","macros","getMacros","toMathLive","readOnly","mathVirtualKeyboardPolicy","addEventListener","onInputEdit","appendChild","innerRef","setState","stop","componentDidMount","arguments","componentDidUpdate","prevProps","_this$props","componentWillUnmount","removeEventListener","remove","get","_this2","v","setLatex","el","focus","blur","clear","command","action","keyToAction","insert","keystroke","selector","KEYSTROKES","executeCommand","message","write","_this3","values","Array","isArray","forEach","vv","render","_this$props2","className","onFocus","onBlur","onClick","createElement","onKeyDown","ref","Component","PropTypes","string","func","bool","_default"],"sources":["../../src/mf/input.jsx"],"sourcesContent":["import React from 'react';\nimport PropTypes from 'prop-types';\nimport { styled } from '@mui/material/styles';\nimport debug from 'debug';\nimport { loadMathLive, getMacros } from '../mathlive-instance';\nimport { toMathLive, fromMathLive, keyToAction, KEYSTROKES } from '../latex-bridge';\n\nconst log = debug('pie-lib:math-input-mathlive:input');\n\nconst Holder = styled('span')({\n display: 'inline-block',\n '& math-field': {\n display: 'block',\n width: '100%',\n },\n // MathLive ships its own virtual keyboard toggle; pie supplies its own keypad.\n '& math-field::part(virtual-keyboard-toggle)': {\n display: 'none',\n },\n '& math-field::part(menu-toggle)': {\n display: 'none',\n },\n});\n\n/**\n * Editable math field. Drop-in replacement for @pie-lib/math-input's `mq.Input`.\n *\n * Keeps the same imperative surface used by MathInput's keypad\n * (`write`, `command`, `keystroke`, `clear`, `focus`, `blur`) so callers do not\n * change, and the same `latex` / `onChange` props.\n */\nexport class Input extends React.Component {\n static propTypes = {\n className: PropTypes.string,\n latex: PropTypes.string,\n onChange: PropTypes.func,\n onClick: PropTypes.func,\n onFocus: PropTypes.func,\n onBlur: PropTypes.func,\n readOnly: PropTypes.bool,\n innerRef: PropTypes.func,\n };\n\n constructor(props) {\n super(props);\n this.holderRef = React.createRef();\n // Tracks the last latex we emitted, so prop echoes don't reset the cursor.\n this.lastEmitted = undefined;\n }\n\n async componentDidMount() {\n const ml = await loadMathLive();\n\n if (!ml || !this.holderRef.current) {\n return;\n }\n\n this.mathField = new ml.MathfieldElement({ macros: getMacros() });\n this.mathField.value = toMathLive(this.props.latex || '');\n\n if (this.props.readOnly) {\n this.mathField.readOnly = true;\n }\n\n // pie drives input through its own keypad, so suppress MathLive's.\n this.mathField.mathVirtualKeyboardPolicy = 'manual';\n\n this.mathField.addEventListener('input', this.onInputEdit);\n this.holderRef.current.appendChild(this.mathField);\n\n if (this.props.innerRef) {\n this.props.innerRef(this);\n }\n\n this.setState?.({});\n }\n\n componentDidUpdate(prevProps) {\n if (!this.mathField) {\n return;\n }\n\n const { latex, readOnly } = this.props;\n\n if (readOnly !== prevProps.readOnly) {\n this.mathField.readOnly = !!readOnly;\n }\n\n // Only push the prop back into the field when it genuinely differs from\n // what the field already holds. This is the analogue of the old\n // shouldComponentUpdate latex-equality guard and prevents cursor thrash.\n if (latex !== undefined && latex !== null && latex !== this.lastEmitted) {\n const next = toMathLive(latex);\n\n if (next !== this.mathField.value) {\n this.mathField.value = next;\n }\n }\n }\n\n componentWillUnmount() {\n if (this.mathField) {\n this.mathField.removeEventListener('input', this.onInputEdit);\n this.mathField.remove();\n this.mathField = undefined;\n }\n\n if (this.props.innerRef) {\n this.props.innerRef(null);\n }\n }\n\n onInputEdit = () => {\n const { onChange } = this.props;\n\n if (!this.mathField) {\n return;\n }\n\n const latex = fromMathLive(this.mathField.getValue('latex'));\n\n this.lastEmitted = latex;\n\n if (onChange) {\n onChange(latex);\n }\n };\n\n /** Current latex, in stored (MathQuill-compatible) form. */\n latex() {\n return this.mathField ? fromMathLive(this.mathField.getValue('latex')) : '';\n }\n\n /**\n * The underlying `<math-field>` element, or undefined until MathLive has\n * finished loading. Exposed for callers that need the real element.\n *\n * NOTE: this is NOT a MathQuill field. Code written against\n * `@pie-lib/math-input` often did `input.mathField.latex()`; that shape is\n * provided by `mqCompat` below, and `latex()` on this component is the\n * supported replacement.\n */\n get element() {\n return this.mathField;\n }\n\n /**\n * MathQuill-shaped facade, so existing `input.mathField.latex()` /\n * `.el()` call sites keep working instead of throwing. Only the members that\n * consumers actually used are provided; MathQuill internals such as\n * `__controller` have no MathLive equivalent and are deliberately absent.\n */\n get mqCompat() {\n return {\n latex: (v) => (v === undefined ? this.latex() : (this.setLatex(v), v)),\n el: () => this.mathField,\n focus: () => this.focus(),\n blur: () => this.blur(),\n };\n }\n\n /** Programmatically replace the content. */\n setLatex(v) {\n if (this.mathField) {\n this.mathField.value = toMathLive(v || '');\n }\n }\n\n clear() {\n if (this.mathField) {\n this.mathField.value = '';\n }\n\n return '';\n }\n\n blur() {\n log('blur mathfield');\n this.mathField && this.mathField.blur();\n }\n\n focus() {\n log('focus mathfield...');\n this.mathField && this.mathField.focus();\n }\n\n /**\n * MathQuill `cmd()` equivalent.\n *\n * Callers pass MathQuill command names (`'\\\\frac'`, `'\\\\sqrt'`, `'^'`, or an\n * array of them). Those must be expanded into latex with `#?` placeholders,\n * otherwise inserting a bare `\\frac` produces no editable slots.\n */\n command(v) {\n log('command: ', v);\n\n if (!this.mathField) {\n return '';\n }\n\n const action = keyToAction({ command: v });\n\n if (action) {\n this.mathField.insert(action.value, { focus: true });\n }\n\n this.mathField.focus();\n\n return this.latex();\n }\n\n /**\n * MathQuill `keystroke()` equivalent.\n *\n * Accepts MathQuill keystroke names (`'Left'`, `'Right'`, `'Backspace'`) as\n * the keypad emits them, and passes anything else through as a MathLive\n * selector.\n */\n keystroke(v) {\n log('keystroke: ', v);\n\n if (!this.mathField) {\n return '';\n }\n\n const selector = KEYSTROKES[v] || v;\n\n try {\n this.mathField.executeCommand(selector);\n } catch (e) {\n log('unknown keystroke/selector \"%s\": %s', v, e && e.message);\n }\n\n this.mathField.focus();\n\n return this.latex();\n }\n\n /** MathQuill `write()` equivalent. Accepts an array, as `cmd()` did. */\n write(v) {\n log('write: ', v);\n\n if (!this.mathField) {\n return '';\n }\n\n const values = Array.isArray(v) ? v : [v];\n\n values.forEach((vv) => this.mathField.insert(vv, { focus: true }));\n this.mathField.focus();\n\n return this.latex();\n }\n\n /**\n * Enter must not insert a line break: math input is single-expression, and\n * the MathQuill version swallowed charCode 13 for the same reason. Newlines\n * are authored explicitly through the newLine embed, not the Enter key.\n */\n onKeyDown = (event) => {\n if (event.key === 'Enter') {\n event.preventDefault();\n }\n };\n\n render() {\n const { className, onFocus, onBlur, onClick } = this.props;\n\n return (\n <Holder\n className={className}\n onFocus={onFocus}\n onBlur={onBlur}\n onClick={onClick}\n onKeyDown={this.onKeyDown}\n ref={this.holderRef}\n />\n );\n }\n}\n\nexport default Input;\n"],"mappings":"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","ignoreList":[]}
|
package/package.json
CHANGED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { KEYSTROKES, keyToAction } from '../latex-bridge';
|
|
2
|
+
import Input from '../mf/input';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* The imperative surface that @pie-lib/math-toolbar drives
|
|
6
|
+
* (editor-and-pad.jsx: clear/command/keystroke/write/latex).
|
|
7
|
+
*
|
|
8
|
+
* These call the methods against a stub mathfield, because a real
|
|
9
|
+
* <math-field> needs a browser. What matters here is the *translation*:
|
|
10
|
+
* MathQuill-era arguments must become valid MathLive operations.
|
|
11
|
+
*/
|
|
12
|
+
const stubField = () => {
|
|
13
|
+
const calls = { insert: [], executeCommand: [], focus: 0 };
|
|
14
|
+
|
|
15
|
+
return {
|
|
16
|
+
calls,
|
|
17
|
+
value: '',
|
|
18
|
+
getValue: () => '',
|
|
19
|
+
insert(v) {
|
|
20
|
+
calls.insert.push(v);
|
|
21
|
+
},
|
|
22
|
+
executeCommand(v) {
|
|
23
|
+
calls.executeCommand.push(v);
|
|
24
|
+
},
|
|
25
|
+
focus() {
|
|
26
|
+
calls.focus++;
|
|
27
|
+
},
|
|
28
|
+
blur() {},
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const withField = () => {
|
|
33
|
+
const input = new Input({});
|
|
34
|
+
const f = stubField();
|
|
35
|
+
|
|
36
|
+
input.mathField = f;
|
|
37
|
+
|
|
38
|
+
return { input, f };
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
describe('Input imperative API (drives math-toolbar)', () => {
|
|
42
|
+
describe('keystroke', () => {
|
|
43
|
+
it('maps MathQuill keystroke names to MathLive selectors', () => {
|
|
44
|
+
const { input, f } = withField();
|
|
45
|
+
|
|
46
|
+
input.keystroke('Left');
|
|
47
|
+
input.keystroke('Right');
|
|
48
|
+
input.keystroke('Backspace');
|
|
49
|
+
|
|
50
|
+
expect(f.calls.executeCommand).toEqual(['moveToPreviousChar', 'moveToNextChar', 'deleteBackward']);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
it('passes an unknown value through as a selector', () => {
|
|
54
|
+
const { input, f } = withField();
|
|
55
|
+
|
|
56
|
+
input.keystroke('deleteForward');
|
|
57
|
+
|
|
58
|
+
expect(f.calls.executeCommand).toEqual(['deleteForward']);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it('does not throw when the engine rejects the selector', () => {
|
|
62
|
+
const { input } = withField();
|
|
63
|
+
|
|
64
|
+
input.mathField.executeCommand = () => {
|
|
65
|
+
throw new Error('unknown command');
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
expect(() => input.keystroke('Nonsense')).not.toThrow();
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it('covers every keystroke the keypad emits', () => {
|
|
72
|
+
// navigation.js / edit.js only produce these three
|
|
73
|
+
['Left', 'Right', 'Backspace'].forEach((k) => expect(KEYSTROKES[k]).toBeDefined());
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
describe('command', () => {
|
|
78
|
+
it('expands argument-taking commands into placeholders', () => {
|
|
79
|
+
const { input, f } = withField();
|
|
80
|
+
|
|
81
|
+
input.command('\\frac');
|
|
82
|
+
|
|
83
|
+
// a bare \frac would give no editable slots
|
|
84
|
+
expect(f.calls.insert).toEqual(['\\frac{#?}{#?}']);
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it('handles array commands', () => {
|
|
88
|
+
const { input, f } = withField();
|
|
89
|
+
|
|
90
|
+
input.command(['\\log', '_']);
|
|
91
|
+
|
|
92
|
+
expect(f.calls.insert).toEqual(['\\log_{#?}']);
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
it('passes argument-less commands through', () => {
|
|
96
|
+
const { input, f } = withField();
|
|
97
|
+
|
|
98
|
+
input.command('\\pi');
|
|
99
|
+
|
|
100
|
+
expect(f.calls.insert).toEqual(['\\pi']);
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
it('agrees with keyToAction', () => {
|
|
104
|
+
expect(keyToAction({ command: '\\sqrt' }).value).toEqual('\\sqrt{#?}');
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
describe('safety before MathLive loads', () => {
|
|
109
|
+
it('every method is a no-op rather than a crash', () => {
|
|
110
|
+
const input = new Input({});
|
|
111
|
+
|
|
112
|
+
// mathField is undefined until loadMathLive() resolves
|
|
113
|
+
expect(input.latex()).toEqual('');
|
|
114
|
+
expect(input.clear()).toEqual('');
|
|
115
|
+
expect(input.command('\\frac')).toEqual('');
|
|
116
|
+
expect(input.keystroke('Left')).toEqual('');
|
|
117
|
+
expect(input.write('x')).toEqual('');
|
|
118
|
+
expect(() => input.focus()).not.toThrow();
|
|
119
|
+
expect(() => input.blur()).not.toThrow();
|
|
120
|
+
expect(() => input.setLatex('x')).not.toThrow();
|
|
121
|
+
expect(input.element).toBeUndefined();
|
|
122
|
+
});
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
describe('mqCompat facade', () => {
|
|
126
|
+
// math-toolbar used to call this.input.mathField.latex(); external
|
|
127
|
+
// consumers may still do the same.
|
|
128
|
+
it('exposes latex() as a getter', () => {
|
|
129
|
+
const { input } = withField();
|
|
130
|
+
|
|
131
|
+
input.mathField.getValue = () => '\\frac{1}{2}';
|
|
132
|
+
|
|
133
|
+
expect(input.mqCompat.latex()).toEqual('\\frac{1}{2}');
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
it('exposes latex(v) as a setter and el()', () => {
|
|
137
|
+
const { input, f } = withField();
|
|
138
|
+
|
|
139
|
+
input.mqCompat.latex('x+1');
|
|
140
|
+
expect(f.value).toEqual('x+1');
|
|
141
|
+
expect(input.mqCompat.el()).toBe(f);
|
|
142
|
+
});
|
|
143
|
+
});
|
|
144
|
+
});
|
|
@@ -70,11 +70,40 @@ describe('mathlive-instance', () => {
|
|
|
70
70
|
expect(instance.applyStaticMath(null, 'x')).toBeUndefined();
|
|
71
71
|
});
|
|
72
72
|
|
|
73
|
-
it('returns undefined when MathLive has not loaded', () => {
|
|
73
|
+
it('defers (returns undefined) when MathLive has not loaded', () => {
|
|
74
74
|
const el = document.createElement('div');
|
|
75
75
|
|
|
76
76
|
expect(instance.applyStaticMath(el, 'x')).toBeUndefined();
|
|
77
77
|
});
|
|
78
|
+
|
|
79
|
+
it('renders synchronously once MathLive is available', () => {
|
|
80
|
+
const el = document.createElement('div');
|
|
81
|
+
|
|
82
|
+
instance.__setMathLiveForTest({ convertLatexToMarkup: (l) => `<span>${l}</span>` });
|
|
83
|
+
|
|
84
|
+
expect(instance.applyStaticMath(el, '\\pi')).toBe(el);
|
|
85
|
+
expect(el.innerHTML).toEqual('<span>\\pi</span>');
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
it('falls back to the element textContent when no latex is passed', () => {
|
|
89
|
+
const el = document.createElement('div');
|
|
90
|
+
|
|
91
|
+
el.textContent = '\\theta';
|
|
92
|
+
instance.__setMathLiveForTest({ convertLatexToMarkup: (l) => `<i>${l}</i>` });
|
|
93
|
+
instance.applyStaticMath(el);
|
|
94
|
+
|
|
95
|
+
expect(el.innerHTML).toEqual('<i>\\theta</i>');
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
it('bridges stored latex (newLine embed) before rendering', () => {
|
|
99
|
+
const el = document.createElement('div');
|
|
100
|
+
|
|
101
|
+
instance.__setMathLiveForTest({ convertLatexToMarkup: (l) => l });
|
|
102
|
+
instance.applyStaticMath(el, 'a\\embed{newLine}[]b');
|
|
103
|
+
|
|
104
|
+
// \embed{newLine}[] must become a multiline environment
|
|
105
|
+
expect(el.innerHTML).toContain('displaylines');
|
|
106
|
+
});
|
|
78
107
|
});
|
|
79
108
|
|
|
80
109
|
describe('configureFonts', () => {
|
package/src/mathlive-instance.js
CHANGED
|
@@ -231,25 +231,39 @@ export const __setMathLiveForTest = (stub) => {
|
|
|
231
231
|
* Render static math into an element. API-compatible with
|
|
232
232
|
* @pie-lib/math-input's `applyStaticMath`.
|
|
233
233
|
*
|
|
234
|
+
* Callers written against MathQuill invoke this synchronously from lifecycle
|
|
235
|
+
* methods, where MathLive (a dynamic import) may not have loaded yet. Rather
|
|
236
|
+
* than silently rendering nothing, this kicks off the load and re-applies once
|
|
237
|
+
* the engine is ready, so the element fills in on the next tick.
|
|
238
|
+
*
|
|
234
239
|
* @param {HTMLElement} element
|
|
235
240
|
* @param {string} [latex] assigned to the element before rendering
|
|
236
241
|
* @param {object} [options] `{ macros }` overrides
|
|
237
|
-
* @returns {HTMLElement|undefined} the element,
|
|
242
|
+
* @returns {HTMLElement|undefined} the element, or undefined if deferred
|
|
238
243
|
*/
|
|
239
244
|
export function applyStaticMath(element, latex, options = {}) {
|
|
240
245
|
if (!element || typeof window === 'undefined') {
|
|
241
246
|
return undefined;
|
|
242
247
|
}
|
|
243
248
|
|
|
249
|
+
// Capture the source now: if we defer, the element's textContent may have
|
|
250
|
+
// been overwritten by the time MathLive is ready.
|
|
251
|
+
const source = latex === undefined || latex === null ? element.textContent : latex;
|
|
244
252
|
const ml = getMathLive();
|
|
245
253
|
|
|
246
254
|
if (!ml) {
|
|
247
|
-
log('applyStaticMath called before MathLive loaded -
|
|
255
|
+
log('applyStaticMath called before MathLive loaded - deferring until it is ready');
|
|
256
|
+
|
|
257
|
+
loadMathLive().then((loaded) => {
|
|
258
|
+
// The element may have been unmounted while loading.
|
|
259
|
+
if (loaded && element.isConnected !== false) {
|
|
260
|
+
applyStaticMath(element, source, options);
|
|
261
|
+
}
|
|
262
|
+
});
|
|
263
|
+
|
|
248
264
|
return undefined;
|
|
249
265
|
}
|
|
250
266
|
|
|
251
|
-
const source = latex === undefined || latex === null ? element.textContent : latex;
|
|
252
|
-
|
|
253
267
|
element.innerHTML = ml.convertLatexToMarkup(toMathLive(source), {
|
|
254
268
|
macros: { ...getMacros(), ...(options.macros || {}) },
|
|
255
269
|
});
|
package/src/mf/input.jsx
CHANGED
|
@@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
|
|
|
3
3
|
import { styled } from '@mui/material/styles';
|
|
4
4
|
import debug from 'debug';
|
|
5
5
|
import { loadMathLive, getMacros } from '../mathlive-instance';
|
|
6
|
-
import { toMathLive, fromMathLive } from '../latex-bridge';
|
|
6
|
+
import { toMathLive, fromMathLive, keyToAction, KEYSTROKES } from '../latex-bridge';
|
|
7
7
|
|
|
8
8
|
const log = debug('pie-lib:math-input-mathlive:input');
|
|
9
9
|
|
|
@@ -131,6 +131,41 @@ export class Input extends React.Component {
|
|
|
131
131
|
return this.mathField ? fromMathLive(this.mathField.getValue('latex')) : '';
|
|
132
132
|
}
|
|
133
133
|
|
|
134
|
+
/**
|
|
135
|
+
* The underlying `<math-field>` element, or undefined until MathLive has
|
|
136
|
+
* finished loading. Exposed for callers that need the real element.
|
|
137
|
+
*
|
|
138
|
+
* NOTE: this is NOT a MathQuill field. Code written against
|
|
139
|
+
* `@pie-lib/math-input` often did `input.mathField.latex()`; that shape is
|
|
140
|
+
* provided by `mqCompat` below, and `latex()` on this component is the
|
|
141
|
+
* supported replacement.
|
|
142
|
+
*/
|
|
143
|
+
get element() {
|
|
144
|
+
return this.mathField;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* MathQuill-shaped facade, so existing `input.mathField.latex()` /
|
|
149
|
+
* `.el()` call sites keep working instead of throwing. Only the members that
|
|
150
|
+
* consumers actually used are provided; MathQuill internals such as
|
|
151
|
+
* `__controller` have no MathLive equivalent and are deliberately absent.
|
|
152
|
+
*/
|
|
153
|
+
get mqCompat() {
|
|
154
|
+
return {
|
|
155
|
+
latex: (v) => (v === undefined ? this.latex() : (this.setLatex(v), v)),
|
|
156
|
+
el: () => this.mathField,
|
|
157
|
+
focus: () => this.focus(),
|
|
158
|
+
blur: () => this.blur(),
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/** Programmatically replace the content. */
|
|
163
|
+
setLatex(v) {
|
|
164
|
+
if (this.mathField) {
|
|
165
|
+
this.mathField.value = toMathLive(v || '');
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
134
169
|
clear() {
|
|
135
170
|
if (this.mathField) {
|
|
136
171
|
this.mathField.value = '';
|
|
@@ -149,7 +184,13 @@ export class Input extends React.Component {
|
|
|
149
184
|
this.mathField && this.mathField.focus();
|
|
150
185
|
}
|
|
151
186
|
|
|
152
|
-
/**
|
|
187
|
+
/**
|
|
188
|
+
* MathQuill `cmd()` equivalent.
|
|
189
|
+
*
|
|
190
|
+
* Callers pass MathQuill command names (`'\\frac'`, `'\\sqrt'`, `'^'`, or an
|
|
191
|
+
* array of them). Those must be expanded into latex with `#?` placeholders,
|
|
192
|
+
* otherwise inserting a bare `\frac` produces no editable slots.
|
|
193
|
+
*/
|
|
153
194
|
command(v) {
|
|
154
195
|
log('command: ', v);
|
|
155
196
|
|
|
@@ -157,21 +198,39 @@ export class Input extends React.Component {
|
|
|
157
198
|
return '';
|
|
158
199
|
}
|
|
159
200
|
|
|
160
|
-
const
|
|
201
|
+
const action = keyToAction({ command: v });
|
|
202
|
+
|
|
203
|
+
if (action) {
|
|
204
|
+
this.mathField.insert(action.value, { focus: true });
|
|
205
|
+
}
|
|
161
206
|
|
|
162
|
-
values.forEach((vv) => this.mathField.insert(vv, { focus: true }));
|
|
163
207
|
this.mathField.focus();
|
|
164
208
|
|
|
165
209
|
return this.latex();
|
|
166
210
|
}
|
|
167
211
|
|
|
168
|
-
/**
|
|
169
|
-
|
|
212
|
+
/**
|
|
213
|
+
* MathQuill `keystroke()` equivalent.
|
|
214
|
+
*
|
|
215
|
+
* Accepts MathQuill keystroke names (`'Left'`, `'Right'`, `'Backspace'`) as
|
|
216
|
+
* the keypad emits them, and passes anything else through as a MathLive
|
|
217
|
+
* selector.
|
|
218
|
+
*/
|
|
219
|
+
keystroke(v) {
|
|
220
|
+
log('keystroke: ', v);
|
|
221
|
+
|
|
170
222
|
if (!this.mathField) {
|
|
171
223
|
return '';
|
|
172
224
|
}
|
|
173
225
|
|
|
174
|
-
|
|
226
|
+
const selector = KEYSTROKES[v] || v;
|
|
227
|
+
|
|
228
|
+
try {
|
|
229
|
+
this.mathField.executeCommand(selector);
|
|
230
|
+
} catch (e) {
|
|
231
|
+
log('unknown keystroke/selector "%s": %s', v, e && e.message);
|
|
232
|
+
}
|
|
233
|
+
|
|
175
234
|
this.mathField.focus();
|
|
176
235
|
|
|
177
236
|
return this.latex();
|