@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.
@@ -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":";;;AAAA,IAAAA,YAAA,GAAAC,OAAA;AACA,IAAAC,MAAA,GAAAC,sBAAA,CAAAF,OAAA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAMG,SAAS,GAAG,SAAZA,SAASA,CAAA,EAAS;EACtB,IAAMC,KAAK,GAAG;IAAEC,MAAM,EAAE,EAAE;IAAEC,cAAc,EAAE,EAAE;IAAEC,KAAK,EAAE;EAAE,CAAC;EAE1D,OAAO;IACLH,KAAK,EAALA,KAAK;IACLI,KAAK,EAAE,EAAE;IACTC,QAAQ,EAAE,SAAVA,QAAQA,CAAA;MAAA,OAAQ,EAAE;IAAA;IAClBJ,MAAM,WAANA,MAAMA,CAACK,CAAC,EAAE;MACRN,KAAK,CAACC,MAAM,CAACM,IAAI,CAACD,CAAC,CAAC;IACtB,CAAC;IACDJ,cAAc,WAAdA,cAAcA,CAACI,CAAC,EAAE;MAChBN,KAAK,CAACE,cAAc,CAACK,IAAI,CAACD,CAAC,CAAC;IAC9B,CAAC;IACDH,KAAK,WAALA,KAAKA,CAAA,EAAG;MACNH,KAAK,CAACG,KAAK,EAAE;IACf,CAAC;IACDK,IAAI,WAAJA,IAAIA,CAAA,EAAG,CAAC;EACV,CAAC;AACH,CAAC;AAED,IAAMC,SAAS,GAAG,SAAZA,SAASA,CAAA,EAAS;EACtB,IAAMC,KAAK,GAAG,IAAIC,iBAAK,CAAC,CAAC,CAAC,CAAC;EAC3B,IAAMC,CAAC,GAAGb,SAAS,CAAC,CAAC;EAErBW,KAAK,CAACG,SAAS,GAAGD,CAAC;EAEnB,OAAO;IAAEF,KAAK,EAALA,KAAK;IAAEE,CAAC,EAADA;EAAE,CAAC;AACrB,CAAC;AAEDE,QAAQ,CAAC,4CAA4C,EAAE,YAAM;EAC3DA,QAAQ,CAAC,WAAW,EAAE,YAAM;IAC1BC,EAAE,CAAC,sDAAsD,EAAE,YAAM;MAC/D,IAAAC,UAAA,GAAqBP,SAAS,CAAC,CAAC;QAAxBC,KAAK,GAAAM,UAAA,CAALN,KAAK;QAAEE,CAAC,GAAAI,UAAA,CAADJ,CAAC;MAEhBF,KAAK,CAACO,SAAS,CAAC,MAAM,CAAC;MACvBP,KAAK,CAACO,SAAS,CAAC,OAAO,CAAC;MACxBP,KAAK,CAACO,SAAS,CAAC,WAAW,CAAC;MAE5BC,MAAM,CAACN,CAAC,CAACZ,KAAK,CAACE,cAAc,CAAC,CAACiB,OAAO,CAAC,CAAC,oBAAoB,EAAE,gBAAgB,EAAE,gBAAgB,CAAC,CAAC;IACpG,CAAC,CAAC;IAEFJ,EAAE,CAAC,+CAA+C,EAAE,YAAM;MACxD,IAAAK,WAAA,GAAqBX,SAAS,CAAC,CAAC;QAAxBC,KAAK,GAAAU,WAAA,CAALV,KAAK;QAAEE,CAAC,GAAAQ,WAAA,CAADR,CAAC;MAEhBF,KAAK,CAACO,SAAS,CAAC,eAAe,CAAC;MAEhCC,MAAM,CAACN,CAAC,CAACZ,KAAK,CAACE,cAAc,CAAC,CAACiB,OAAO,CAAC,CAAC,eAAe,CAAC,CAAC;IAC3D,CAAC,CAAC;IAEFJ,EAAE,CAAC,qDAAqD,EAAE,YAAM;MAC9D,IAAAM,WAAA,GAAkBZ,SAAS,CAAC,CAAC;QAArBC,KAAK,GAAAW,WAAA,CAALX,KAAK;MAEbA,KAAK,CAACG,SAAS,CAACX,cAAc,GAAG,YAAM;QACrC,MAAM,IAAIoB,KAAK,CAAC,iBAAiB,CAAC;MACpC,CAAC;MAEDJ,MAAM,CAAC;QAAA,OAAMR,KAAK,CAACO,SAAS,CAAC,UAAU,CAAC;MAAA,EAAC,CAACM,GAAG,CAACC,OAAO,CAAC,CAAC;IACzD,CAAC,CAAC;IAEFT,EAAE,CAAC,yCAAyC,EAAE,YAAM;MAClD;MACA,CAAC,MAAM,EAAE,OAAO,EAAE,WAAW,CAAC,CAACU,OAAO,CAAC,UAACC,CAAC;QAAA,OAAKR,MAAM,CAACS,uBAAU,CAACD,CAAC,CAAC,CAAC,CAACE,WAAW,CAAC,CAAC;MAAA,EAAC;IACpF,CAAC,CAAC;EACJ,CAAC,CAAC;EAEFd,QAAQ,CAAC,SAAS,EAAE,YAAM;IACxBC,EAAE,CAAC,oDAAoD,EAAE,YAAM;MAC7D,IAAAc,WAAA,GAAqBpB,SAAS,CAAC,CAAC;QAAxBC,KAAK,GAAAmB,WAAA,CAALnB,KAAK;QAAEE,CAAC,GAAAiB,WAAA,CAADjB,CAAC;MAEhBF,KAAK,CAACoB,OAAO,CAAC,QAAQ,CAAC;;MAEvB;MACAZ,MAAM,CAACN,CAAC,CAACZ,KAAK,CAACC,MAAM,CAAC,CAACkB,OAAO,CAAC,CAAC,gBAAgB,CAAC,CAAC;IACpD,CAAC,CAAC;IAEFJ,EAAE,CAAC,wBAAwB,EAAE,YAAM;MACjC,IAAAgB,WAAA,GAAqBtB,SAAS,CAAC,CAAC;QAAxBC,KAAK,GAAAqB,WAAA,CAALrB,KAAK;QAAEE,CAAC,GAAAmB,WAAA,CAADnB,CAAC;MAEhBF,KAAK,CAACoB,OAAO,CAAC,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;MAE7BZ,MAAM,CAACN,CAAC,CAACZ,KAAK,CAACC,MAAM,CAAC,CAACkB,OAAO,CAAC,CAAC,YAAY,CAAC,CAAC;IAChD,CAAC,CAAC;IAEFJ,EAAE,CAAC,uCAAuC,EAAE,YAAM;MAChD,IAAAiB,WAAA,GAAqBvB,SAAS,CAAC,CAAC;QAAxBC,KAAK,GAAAsB,WAAA,CAALtB,KAAK;QAAEE,CAAC,GAAAoB,WAAA,CAADpB,CAAC;MAEhBF,KAAK,CAACoB,OAAO,CAAC,MAAM,CAAC;MAErBZ,MAAM,CAACN,CAAC,CAACZ,KAAK,CAACC,MAAM,CAAC,CAACkB,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC;IAC1C,CAAC,CAAC;IAEFJ,EAAE,CAAC,yBAAyB,EAAE,YAAM;MAClCG,MAAM,CAAC,IAAAe,wBAAW,EAAC;QAAEH,OAAO,EAAE;MAAS,CAAC,CAAC,CAAC1B,KAAK,CAAC,CAACe,OAAO,CAAC,YAAY,CAAC;IACxE,CAAC,CAAC;EACJ,CAAC,CAAC;EAEFL,QAAQ,CAAC,8BAA8B,EAAE,YAAM;IAC7CC,EAAE,CAAC,6CAA6C,EAAE,YAAM;MACtD,IAAML,KAAK,GAAG,IAAIC,iBAAK,CAAC,CAAC,CAAC,CAAC;;MAE3B;MACAO,MAAM,CAACR,KAAK,CAACwB,KAAK,CAAC,CAAC,CAAC,CAACf,OAAO,CAAC,EAAE,CAAC;MACjCD,MAAM,CAACR,KAAK,CAACyB,KAAK,CAAC,CAAC,CAAC,CAAChB,OAAO,CAAC,EAAE,CAAC;MACjCD,MAAM,CAACR,KAAK,CAACoB,OAAO,CAAC,QAAQ,CAAC,CAAC,CAACX,OAAO,CAAC,EAAE,CAAC;MAC3CD,MAAM,CAACR,KAAK,CAACO,SAAS,CAAC,MAAM,CAAC,CAAC,CAACE,OAAO,CAAC,EAAE,CAAC;MAC3CD,MAAM,CAACR,KAAK,CAAC0B,KAAK,CAAC,GAAG,CAAC,CAAC,CAACjB,OAAO,CAAC,EAAE,CAAC;MACpCD,MAAM,CAAC;QAAA,OAAMR,KAAK,CAACP,KAAK,CAAC,CAAC;MAAA,EAAC,CAACoB,GAAG,CAACC,OAAO,CAAC,CAAC;MACzCN,MAAM,CAAC;QAAA,OAAMR,KAAK,CAACF,IAAI,CAAC,CAAC;MAAA,EAAC,CAACe,GAAG,CAACC,OAAO,CAAC,CAAC;MACxCN,MAAM,CAAC;QAAA,OAAMR,KAAK,CAAC2B,QAAQ,CAAC,GAAG,CAAC;MAAA,EAAC,CAACd,GAAG,CAACC,OAAO,CAAC,CAAC;MAC/CN,MAAM,CAACR,KAAK,CAAC4B,OAAO,CAAC,CAACC,aAAa,CAAC,CAAC;IACvC,CAAC,CAAC;EACJ,CAAC,CAAC;EAEFzB,QAAQ,CAAC,iBAAiB,EAAE,YAAM;IAChC;IACA;IACAC,EAAE,CAAC,6BAA6B,EAAE,YAAM;MACtC,IAAAyB,WAAA,GAAkB/B,SAAS,CAAC,CAAC;QAArBC,KAAK,GAAA8B,WAAA,CAAL9B,KAAK;MAEbA,KAAK,CAACG,SAAS,CAACR,QAAQ,GAAG;QAAA,OAAM,cAAc;MAAA;MAE/Ca,MAAM,CAACR,KAAK,CAAC+B,QAAQ,CAACP,KAAK,CAAC,CAAC,CAAC,CAACf,OAAO,CAAC,cAAc,CAAC;IACxD,CAAC,CAAC;IAEFJ,EAAE,CAAC,uCAAuC,EAAE,YAAM;MAChD,IAAA2B,WAAA,GAAqBjC,SAAS,CAAC,CAAC;QAAxBC,KAAK,GAAAgC,WAAA,CAALhC,KAAK;QAAEE,CAAC,GAAA8B,WAAA,CAAD9B,CAAC;MAEhBF,KAAK,CAAC+B,QAAQ,CAACP,KAAK,CAAC,KAAK,CAAC;MAC3BhB,MAAM,CAACN,CAAC,CAACR,KAAK,CAAC,CAACe,OAAO,CAAC,KAAK,CAAC;MAC9BD,MAAM,CAACR,KAAK,CAAC+B,QAAQ,CAACE,EAAE,CAAC,CAAC,CAAC,CAACC,IAAI,CAAChC,CAAC,CAAC;IACrC,CAAC,CAAC;EACJ,CAAC,CAAC;AACJ,CAAC,CAAC","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":[]}
@@ -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, for parity with the old return
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 - call loadMathLive() first');
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
- /** MathQuill `cmd()` equivalent. */
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 values = Array.isArray(v) ? v : [v];
197
- values.forEach(function (vv) {
198
- return _this2.mathField.insert(vv, {
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
- /** MathQuill `keystroke()` equivalent - takes a MathLive selector. */
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(selector) {
272
+ value: function keystroke(v) {
273
+ log('keystroke: ', v);
210
274
  if (!this.mathField) {
211
275
  return '';
212
276
  }
213
- this.mathField.executeCommand(selector);
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
  }
@@ -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":";;;;;;;;;;;;;;;AAAA,IAAAA,MAAA,GAAAC,sBAAA,CAAAC,OAAA;AACA,IAAAC,UAAA,GAAAF,sBAAA,CAAAC,OAAA;AACA,IAAAE,OAAA,GAAAF,OAAA;AACA,IAAAG,MAAA,GAAAJ,sBAAA,CAAAC,OAAA;AACA,IAAAI,iBAAA,GAAAJ,OAAA;AACA,IAAAK,YAAA,GAAAL,OAAA;AAA2D,SAAAM,WAAAC,CAAA,EAAAC,CAAA,EAAAC,CAAA,WAAAD,CAAA,OAAAE,gBAAA,aAAAF,CAAA,OAAAG,2BAAA,aAAAJ,CAAA,EAAAK,yBAAA,KAAAC,OAAA,CAAAC,SAAA,CAAAN,CAAA,EAAAC,CAAA,YAAAC,gBAAA,aAAAH,CAAA,EAAAQ,WAAA,IAAAP,CAAA,CAAAQ,KAAA,CAAAT,CAAA,EAAAE,CAAA;AAAA,SAAAG,0BAAA,cAAAL,CAAA,IAAAU,OAAA,CAAAC,SAAA,CAAAC,OAAA,CAAAC,IAAA,CAAAP,OAAA,CAAAC,SAAA,CAAAG,OAAA,iCAAAV,CAAA,aAAAK,yBAAA,YAAAA,0BAAA,aAAAL,CAAA;AAE3D,IAAMc,GAAG,GAAG,IAAAC,iBAAK,EAAC,mCAAmC,CAAC;AAEtD,IAAMC,MAAM,GAAG,IAAAC,cAAM,EAAC,MAAM,CAAC,CAAC;EAC5BC,OAAO,EAAE,cAAc;EACvB,cAAc,EAAE;IACdA,OAAO,EAAE,OAAO;IAChBC,KAAK,EAAE;EACT,CAAC;EACD;EACA,6CAA6C,EAAE;IAC7CD,OAAO,EAAE;EACX,CAAC;EACD,iCAAiC,EAAE;IACjCA,OAAO,EAAE;EACX;AACF,CAAC,CAAC;;AAEF;AACA;AACA;AACA;AACA;AACA;AACA;AANA,IAOaE,KAAK,GAAAC,OAAA,CAAAD,KAAA,0BAAAE,gBAAA;EAYhB,SAAAF,MAAYG,KAAK,EAAE;IAAA,IAAAC,KAAA;IAAA,IAAAC,gBAAA,mBAAAL,KAAA;IACjBI,KAAA,GAAAzB,UAAA,OAAAqB,KAAA,GAAMG,KAAK;IAAE,IAAAG,gBAAA,aAAAF,KAAA,iBAoED,YAAM;MAClB,IAAQG,QAAQ,GAAKH,KAAA,CAAKD,KAAK,CAAvBI,QAAQ;MAEhB,IAAI,CAACH,KAAA,CAAKI,SAAS,EAAE;QACnB;MACF;MAEA,IAAMC,KAAK,GAAG,IAAAC,yBAAY,EAACN,KAAA,CAAKI,SAAS,CAACG,QAAQ,CAAC,OAAO,CAAC,CAAC;MAE5DP,KAAA,CAAKQ,WAAW,GAAGH,KAAK;MAExB,IAAIF,QAAQ,EAAE;QACZA,QAAQ,CAACE,KAAK,CAAC;MACjB;IACF,CAAC;IAqED;AACF;AACA;AACA;AACA;IAJE,IAAAH,gBAAA,aAAAF,KAAA,eAKY,UAACS,KAAK,EAAK;MACrB,IAAIA,KAAK,CAACC,GAAG,KAAK,OAAO,EAAE;QACzBD,KAAK,CAACE,cAAc,CAAC,CAAC;MACxB;IACF,CAAC;IA/JCX,KAAA,CAAKY,SAAS,gBAAGC,iBAAK,CAACC,SAAS,CAAC,CAAC;IAClC;IACAd,KAAA,CAAKQ,WAAW,GAAGO,SAAS;IAAC,OAAAf,KAAA;EAC/B;EAAC,IAAAgB,UAAA,aAAApB,KAAA,EAAAE,gBAAA;EAAA,WAAAmB,aAAA,aAAArB,KAAA;IAAAc,GAAA;IAAAQ,KAAA;MAAA,IAAAC,kBAAA,OAAAC,kBAAA,0BAAAC,YAAA,YAAAC,IAAA,CAED,SAAAC,QAAA;QAAA,IAAAC,cAAA;QAAA,IAAAC,EAAA;QAAA,OAAAJ,YAAA,YAAAK,IAAA,WAAAC,QAAA;UAAA,kBAAAA,QAAA,CAAAC,IAAA,GAAAD,QAAA,CAAAE,IAAA;YAAA;cAAAF,QAAA,CAAAE,IAAA;cAAA,OACmB,IAAAC,8BAAY,EAAC,CAAC;YAAA;cAAzBL,EAAE,GAAAE,QAAA,CAAAI,IAAA;cAAA,MAEJ,CAACN,EAAE,IAAI,CAAC,IAAI,CAACb,SAAS,CAACoB,OAAO;gBAAAL,QAAA,CAAAE,IAAA;gBAAA;cAAA;cAAA,OAAAF,QAAA,CAAAM,MAAA;YAAA;cAIlC,IAAI,CAAC7B,SAAS,GAAG,IAAIqB,EAAE,CAACS,gBAAgB,CAAC;gBAAEC,MAAM,EAAE,IAAAC,2BAAS,EAAC;cAAE,CAAC,CAAC;cACjE,IAAI,CAAChC,SAAS,CAACc,KAAK,GAAG,IAAAmB,uBAAU,EAAC,IAAI,CAACtC,KAAK,CAACM,KAAK,IAAI,EAAE,CAAC;cAEzD,IAAI,IAAI,CAACN,KAAK,CAACuC,QAAQ,EAAE;gBACvB,IAAI,CAAClC,SAAS,CAACkC,QAAQ,GAAG,IAAI;cAChC;;cAEA;cACA,IAAI,CAAClC,SAAS,CAACmC,yBAAyB,GAAG,QAAQ;cAEnD,IAAI,CAACnC,SAAS,CAACoC,gBAAgB,CAAC,OAAO,EAAE,IAAI,CAACC,WAAW,CAAC;cAC1D,IAAI,CAAC7B,SAAS,CAACoB,OAAO,CAACU,WAAW,CAAC,IAAI,CAACtC,SAAS,CAAC;cAElD,IAAI,IAAI,CAACL,KAAK,CAAC4C,QAAQ,EAAE;gBACvB,IAAI,CAAC5C,KAAK,CAAC4C,QAAQ,CAAC,IAAI,CAAC;cAC3B;cAEA,CAAAnB,cAAA,OAAI,CAACoB,QAAQ,cAAApB,cAAA,eAAbA,cAAA,CAAAnC,IAAA,KAAI,EAAY,CAAC,CAAC,CAAC;YAAC;YAAA;cAAA,OAAAsC,QAAA,CAAAkB,IAAA;UAAA;QAAA,GAAAtB,OAAA;MAAA,CACrB;MAAA,SAzBKuB,iBAAiBA,CAAA;QAAA,OAAA3B,kBAAA,CAAAlC,KAAA,OAAA8D,SAAA;MAAA;MAAA,OAAjBD,iBAAiB;IAAA;EAAA;IAAApC,GAAA;IAAAQ,KAAA,EA2BvB,SAAA8B,kBAAkBA,CAACC,SAAS,EAAE;MAC5B,IAAI,CAAC,IAAI,CAAC7C,SAAS,EAAE;QACnB;MACF;MAEA,IAAA8C,WAAA,GAA4B,IAAI,CAACnD,KAAK;QAA9BM,KAAK,GAAA6C,WAAA,CAAL7C,KAAK;QAAEiC,QAAQ,GAAAY,WAAA,CAARZ,QAAQ;MAEvB,IAAIA,QAAQ,KAAKW,SAAS,CAACX,QAAQ,EAAE;QACnC,IAAI,CAAClC,SAAS,CAACkC,QAAQ,GAAG,CAAC,CAACA,QAAQ;MACtC;;MAEA;MACA;MACA;MACA,IAAIjC,KAAK,KAAKU,SAAS,IAAIV,KAAK,KAAK,IAAI,IAAIA,KAAK,KAAK,IAAI,CAACG,WAAW,EAAE;QACvE,IAAMqB,IAAI,GAAG,IAAAQ,uBAAU,EAAChC,KAAK,CAAC;QAE9B,IAAIwB,IAAI,KAAK,IAAI,CAACzB,SAAS,CAACc,KAAK,EAAE;UACjC,IAAI,CAACd,SAAS,CAACc,KAAK,GAAGW,IAAI;QAC7B;MACF;IACF;EAAC;IAAAnB,GAAA;IAAAQ,KAAA,EAED,SAAAiC,oBAAoBA,CAAA,EAAG;MACrB,IAAI,IAAI,CAAC/C,SAAS,EAAE;QAClB,IAAI,CAACA,SAAS,CAACgD,mBAAmB,CAAC,OAAO,EAAE,IAAI,CAACX,WAAW,CAAC;QAC7D,IAAI,CAACrC,SAAS,CAACiD,MAAM,CAAC,CAAC;QACvB,IAAI,CAACjD,SAAS,GAAGW,SAAS;MAC5B;MAEA,IAAI,IAAI,CAAChB,KAAK,CAAC4C,QAAQ,EAAE;QACvB,IAAI,CAAC5C,KAAK,CAAC4C,QAAQ,CAAC,IAAI,CAAC;MAC3B;IACF;EAAC;IAAAjC,GAAA;IAAAQ,KAAA,EAkBD;IACA,SAAAb,KAAKA,CAAA,EAAG;MACN,OAAO,IAAI,CAACD,SAAS,GAAG,IAAAE,yBAAY,EAAC,IAAI,CAACF,SAAS,CAACG,QAAQ,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE;IAC7E;EAAC;IAAAG,GAAA;IAAAQ,KAAA,EAED,SAAAoC,KAAKA,CAAA,EAAG;MACN,IAAI,IAAI,CAAClD,SAAS,EAAE;QAClB,IAAI,CAACA,SAAS,CAACc,KAAK,GAAG,EAAE;MAC3B;MAEA,OAAO,EAAE;IACX;EAAC;IAAAR,GAAA;IAAAQ,KAAA,EAED,SAAAqC,IAAIA,CAAA,EAAG;MACLjE,GAAG,CAAC,gBAAgB,CAAC;MACrB,IAAI,CAACc,SAAS,IAAI,IAAI,CAACA,SAAS,CAACmD,IAAI,CAAC,CAAC;IACzC;EAAC;IAAA7C,GAAA;IAAAQ,KAAA,EAED,SAAAsC,KAAKA,CAAA,EAAG;MACNlE,GAAG,CAAC,oBAAoB,CAAC;MACzB,IAAI,CAACc,SAAS,IAAI,IAAI,CAACA,SAAS,CAACoD,KAAK,CAAC,CAAC;IAC1C;;IAEA;EAAA;IAAA9C,GAAA;IAAAQ,KAAA,EACA,SAAAuC,OAAOA,CAACC,CAAC,EAAE;MAAA,IAAAC,MAAA;MACTrE,GAAG,CAAC,WAAW,EAAEoE,CAAC,CAAC;MAEnB,IAAI,CAAC,IAAI,CAACtD,SAAS,EAAE;QACnB,OAAO,EAAE;MACX;MAEA,IAAMwD,MAAM,GAAGC,KAAK,CAACC,OAAO,CAACJ,CAAC,CAAC,GAAGA,CAAC,GAAG,CAACA,CAAC,CAAC;MAEzCE,MAAM,CAACG,OAAO,CAAC,UAACC,EAAE;QAAA,OAAKL,MAAI,CAACvD,SAAS,CAAC6D,MAAM,CAACD,EAAE,EAAE;UAAER,KAAK,EAAE;QAAK,CAAC,CAAC;MAAA,EAAC;MAClE,IAAI,CAACpD,SAAS,CAACoD,KAAK,CAAC,CAAC;MAEtB,OAAO,IAAI,CAACnD,KAAK,CAAC,CAAC;IACrB;;IAEA;EAAA;IAAAK,GAAA;IAAAQ,KAAA,EACA,SAAAgD,SAASA,CAACC,QAAQ,EAAE;MAClB,IAAI,CAAC,IAAI,CAAC/D,SAAS,EAAE;QACnB,OAAO,EAAE;MACX;MAEA,IAAI,CAACA,SAAS,CAACgE,cAAc,CAACD,QAAQ,CAAC;MACvC,IAAI,CAAC/D,SAAS,CAACoD,KAAK,CAAC,CAAC;MAEtB,OAAO,IAAI,CAACnD,KAAK,CAAC,CAAC;IACrB;;IAEA;EAAA;IAAAK,GAAA;IAAAQ,KAAA,EACA,SAAAmD,KAAKA,CAACX,CAAC,EAAE;MAAA,IAAAY,MAAA;MACPhF,GAAG,CAAC,SAAS,EAAEoE,CAAC,CAAC;MAEjB,IAAI,CAAC,IAAI,CAACtD,SAAS,EAAE;QACnB,OAAO,EAAE;MACX;MAEA,IAAMwD,MAAM,GAAGC,KAAK,CAACC,OAAO,CAACJ,CAAC,CAAC,GAAGA,CAAC,GAAG,CAACA,CAAC,CAAC;MAEzCE,MAAM,CAACG,OAAO,CAAC,UAACC,EAAE;QAAA,OAAKM,MAAI,CAAClE,SAAS,CAAC6D,MAAM,CAACD,EAAE,EAAE;UAAER,KAAK,EAAE;QAAK,CAAC,CAAC;MAAA,EAAC;MAClE,IAAI,CAACpD,SAAS,CAACoD,KAAK,CAAC,CAAC;MAEtB,OAAO,IAAI,CAACnD,KAAK,CAAC,CAAC;IACrB;EAAC;IAAAK,GAAA;IAAAQ,KAAA,EAaD,SAAAqD,MAAMA,CAAA,EAAG;MACP,IAAAC,YAAA,GAAgD,IAAI,CAACzE,KAAK;QAAlD0E,SAAS,GAAAD,YAAA,CAATC,SAAS;QAAEC,OAAO,GAAAF,YAAA,CAAPE,OAAO;QAAEC,MAAM,GAAAH,YAAA,CAANG,MAAM;QAAEC,OAAO,GAAAJ,YAAA,CAAPI,OAAO;MAE3C,oBACE7G,MAAA,YAAA8G,aAAA,CAACrF,MAAM;QACLiF,SAAS,EAAEA,SAAU;QACrBC,OAAO,EAAEA,OAAQ;QACjBC,MAAM,EAAEA,MAAO;QACfC,OAAO,EAAEA,OAAQ;QACjBE,SAAS,EAAE,IAAI,CAACA,SAAU;QAC1BC,GAAG,EAAE,IAAI,CAACnE;MAAU,CACrB,CAAC;IAEN;EAAC;AAAA,EA5LwBC,iBAAK,CAACmE,SAAS;AAAA,IAAA9E,gBAAA,aAA7BN,KAAK,eACG;EACjB6E,SAAS,EAAEQ,qBAAS,CAACC,MAAM;EAC3B7E,KAAK,EAAE4E,qBAAS,CAACC,MAAM;EACvB/E,QAAQ,EAAE8E,qBAAS,CAACE,IAAI;EACxBP,OAAO,EAAEK,qBAAS,CAACE,IAAI;EACvBT,OAAO,EAAEO,qBAAS,CAACE,IAAI;EACvBR,MAAM,EAAEM,qBAAS,CAACE,IAAI;EACtB7C,QAAQ,EAAE2C,qBAAS,CAACG,IAAI;EACxBzC,QAAQ,EAAEsC,qBAAS,CAACE;AACtB,CAAC;AAAA,IAAAE,QAAA,GAAAxF,OAAA,cAqLYD,KAAK","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
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "1.0.1",
6
+ "version": "1.0.3",
7
7
  "description": "MathLive-based math input (drop-in alternative to @pie-lib/math-input)",
8
8
  "main": "lib/index.js",
9
9
  "module": "src/index.jsx",
@@ -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', () => {
@@ -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, for parity with the old return
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 - call loadMathLive() first');
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
- /** MathQuill `cmd()` equivalent. */
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 values = Array.isArray(v) ? v : [v];
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
- /** MathQuill `keystroke()` equivalent - takes a MathLive selector. */
169
- keystroke(selector) {
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
- this.mathField.executeCommand(selector);
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();