@pie-lib/math-input-mathlive 1.1.5-beta.8 → 2.0.1-next.20261107131445

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.
Files changed (202) hide show
  1. package/README.md +84 -109
  2. package/dist/_virtual/_rolldown/runtime.js +11 -0
  3. package/dist/horizontal-keypad.d.ts +22 -0
  4. package/dist/horizontal-keypad.js +54 -0
  5. package/dist/index.d.ts +20 -0
  6. package/dist/index.js +12 -0
  7. package/dist/keypad/index.d.ts +40 -0
  8. package/dist/keypad/index.js +245 -0
  9. package/dist/keypad/keys-layout.d.ts +7 -0
  10. package/dist/keypad/keys-layout.js +5 -0
  11. package/dist/keys/basic-operators.d.ts +5 -0
  12. package/dist/keys/basic-operators.js +30 -0
  13. package/dist/keys/chars.d.ts +5 -0
  14. package/dist/keys/comparison.d.ts +4 -0
  15. package/dist/keys/comparison.js +32 -0
  16. package/dist/keys/constants.d.ts +4 -0
  17. package/dist/keys/constants.js +35 -0
  18. package/dist/keys/digits.d.ts +15 -0
  19. package/dist/keys/digits.js +34 -0
  20. package/dist/keys/edit.d.ts +6 -0
  21. package/dist/keys/edit.js +9 -0
  22. package/dist/keys/exponent.d.ts +4 -0
  23. package/dist/keys/exponent.js +28 -0
  24. package/dist/keys/fractions.d.ts +3 -0
  25. package/dist/keys/fractions.js +27 -0
  26. package/dist/keys/geometry.d.ts +23 -0
  27. package/dist/keys/geometry.js +127 -0
  28. package/dist/keys/grades.d.ts +9 -0
  29. package/dist/keys/grades.js +414 -0
  30. package/dist/keys/index.d.ts +6 -0
  31. package/dist/keys/index.js +50 -0
  32. package/dist/keys/log.d.ts +3 -0
  33. package/dist/keys/log.js +25 -0
  34. package/dist/keys/logic.d.ts +2 -0
  35. package/dist/keys/logic.js +13 -0
  36. package/dist/keys/matrices.d.ts +2 -0
  37. package/dist/keys/matrices.js +17 -0
  38. package/dist/keys/misc.d.ts +10 -0
  39. package/dist/keys/misc.js +60 -0
  40. package/dist/keys/navigation.d.ts +2 -0
  41. package/dist/keys/navigation.js +13 -0
  42. package/dist/keys/operators.d.ts +1 -0
  43. package/dist/keys/operators.js +11 -0
  44. package/dist/keys/statistics.d.ts +5 -0
  45. package/dist/keys/statistics.js +38 -0
  46. package/dist/keys/sub-sup.d.ts +2 -0
  47. package/dist/keys/sub-sup.js +17 -0
  48. package/dist/keys/trigonometry.d.ts +6 -0
  49. package/dist/keys/trigonometry.js +43 -0
  50. package/dist/keys/utils.d.ts +5 -0
  51. package/dist/keys/utils.js +24 -0
  52. package/dist/keys/vars.d.ts +3 -0
  53. package/dist/keys/vars.js +22 -0
  54. package/dist/latex-bridge.d.ts +197 -0
  55. package/dist/latex-bridge.js +210 -0
  56. package/dist/longdiv.d.ts +24 -0
  57. package/dist/longdiv.js +43 -0
  58. package/dist/math-input.d.ts +26 -0
  59. package/dist/math-input.js +74 -0
  60. package/dist/mathlive-instance.d.ts +221 -0
  61. package/dist/mathlive-instance.js +159 -0
  62. package/dist/mf/common-styles.d.ts +594 -0
  63. package/dist/mf/common-styles.js +80 -0
  64. package/dist/mf/field-label.d.ts +16 -0
  65. package/dist/mf/field-label.js +13 -0
  66. package/dist/mf/index.d.ts +4 -0
  67. package/dist/mf/index.js +21 -0
  68. package/dist/mf/input.d.ts +94 -0
  69. package/dist/mf/input.js +127 -0
  70. package/dist/mf/static.d.ts +143 -0
  71. package/dist/mf/static.js +230 -0
  72. package/dist/selection.d.ts +43 -0
  73. package/dist/selection.js +39 -0
  74. package/package.json +32 -18
  75. package/lib/__tests__/composites.test.js +0 -255
  76. package/lib/__tests__/drop-in-compat.test.js +0 -133
  77. package/lib/__tests__/embedded-fonts.test.js +0 -121
  78. package/lib/__tests__/index.test.js +0 -118
  79. package/lib/__tests__/input-imperative.test.js +0 -155
  80. package/lib/__tests__/input-selection.test.js +0 -103
  81. package/lib/__tests__/keypad-label.test.js +0 -231
  82. package/lib/__tests__/keypad-render.test.js +0 -206
  83. package/lib/__tests__/latex-bridge.test.js +0 -386
  84. package/lib/__tests__/mathlive-instance.test.js +0 -419
  85. package/lib/__tests__/mount-race.test.js +0 -218
  86. package/lib/__tests__/selection.test.js +0 -195
  87. package/lib/__tests__/static-prompts.test.js +0 -405
  88. package/lib/__tests__/tmp-markup.test.js +0 -26
  89. package/lib/horizontal-keypad.js +0 -101
  90. package/lib/horizontal-keypad.js.map +0 -1
  91. package/lib/index.js +0 -143
  92. package/lib/index.js.map +0 -1
  93. package/lib/keypad/index.js +0 -431
  94. package/lib/keypad/index.js.map +0 -1
  95. package/lib/keypad/keys-layout.js +0 -22
  96. package/lib/keypad/keys-layout.js.map +0 -1
  97. package/lib/keys/basic-operators.js +0 -33
  98. package/lib/keys/basic-operators.js.map +0 -1
  99. package/lib/keys/chars.js +0 -12
  100. package/lib/keys/chars.js.map +0 -1
  101. package/lib/keys/comparison.js +0 -39
  102. package/lib/keys/comparison.js.map +0 -1
  103. package/lib/keys/constants.js +0 -37
  104. package/lib/keys/constants.js.map +0 -1
  105. package/lib/keys/digits.js +0 -46
  106. package/lib/keys/digits.js.map +0 -1
  107. package/lib/keys/edit.js +0 -14
  108. package/lib/keys/edit.js.map +0 -1
  109. package/lib/keys/exponent.js +0 -30
  110. package/lib/keys/exponent.js.map +0 -1
  111. package/lib/keys/fractions.js +0 -29
  112. package/lib/keys/fractions.js.map +0 -1
  113. package/lib/keys/geometry.js +0 -143
  114. package/lib/keys/geometry.js.map +0 -1
  115. package/lib/keys/grades.js +0 -259
  116. package/lib/keys/grades.js.map +0 -1
  117. package/lib/keys/index.js +0 -35
  118. package/lib/keys/index.js.map +0 -1
  119. package/lib/keys/log.js +0 -27
  120. package/lib/keys/log.js.map +0 -1
  121. package/lib/keys/logic.js +0 -19
  122. package/lib/keys/logic.js.map +0 -1
  123. package/lib/keys/matrices.js +0 -19
  124. package/lib/keys/matrices.js.map +0 -1
  125. package/lib/keys/misc.js +0 -69
  126. package/lib/keys/misc.js.map +0 -1
  127. package/lib/keys/navigation.js +0 -20
  128. package/lib/keys/navigation.js.map +0 -1
  129. package/lib/keys/operators.js +0 -15
  130. package/lib/keys/operators.js.map +0 -1
  131. package/lib/keys/statistics.js +0 -40
  132. package/lib/keys/statistics.js.map +0 -1
  133. package/lib/keys/sub-sup.js +0 -19
  134. package/lib/keys/sub-sup.js.map +0 -1
  135. package/lib/keys/trigonometry.js +0 -45
  136. package/lib/keys/trigonometry.js.map +0 -1
  137. package/lib/keys/utils.js +0 -87
  138. package/lib/keys/utils.js.map +0 -1
  139. package/lib/keys/vars.js +0 -24
  140. package/lib/keys/vars.js.map +0 -1
  141. package/lib/latex-bridge.js +0 -445
  142. package/lib/latex-bridge.js.map +0 -1
  143. package/lib/math-input.js +0 -143
  144. package/lib/math-input.js.map +0 -1
  145. package/lib/mathlive-instance.js +0 -585
  146. package/lib/mathlive-instance.js.map +0 -1
  147. package/lib/mf/common-styles.js +0 -203
  148. package/lib/mf/common-styles.js.map +0 -1
  149. package/lib/mf/index.js +0 -84
  150. package/lib/mf/index.js.map +0 -1
  151. package/lib/mf/input.js +0 -372
  152. package/lib/mf/input.js.map +0 -1
  153. package/lib/mf/static.js +0 -500
  154. package/lib/mf/static.js.map +0 -1
  155. package/lib/selection.js +0 -148
  156. package/lib/selection.js.map +0 -1
  157. package/src/__tests__/composites.test.jsx +0 -220
  158. package/src/__tests__/drop-in-compat.test.jsx +0 -112
  159. package/src/__tests__/index.test.jsx +0 -109
  160. package/src/__tests__/input-imperative.test.jsx +0 -144
  161. package/src/__tests__/input-selection.test.jsx +0 -64
  162. package/src/__tests__/keypad-label.test.jsx +0 -283
  163. package/src/__tests__/keypad-render.test.jsx +0 -123
  164. package/src/__tests__/latex-bridge.test.js +0 -359
  165. package/src/__tests__/mathlive-instance.test.js +0 -418
  166. package/src/__tests__/mount-race.test.jsx +0 -142
  167. package/src/__tests__/selection.test.js +0 -212
  168. package/src/__tests__/static-prompts.test.jsx +0 -364
  169. package/src/horizontal-keypad.jsx +0 -73
  170. package/src/index.jsx +0 -63
  171. package/src/keypad/index.jsx +0 -386
  172. package/src/keypad/keys-layout.js +0 -16
  173. package/src/keys/basic-operators.js +0 -32
  174. package/src/keys/chars.js +0 -5
  175. package/src/keys/comparison.js +0 -28
  176. package/src/keys/constants.js +0 -35
  177. package/src/keys/digits.js +0 -40
  178. package/src/keys/edit.js +0 -3
  179. package/src/keys/exponent.js +0 -28
  180. package/src/keys/fractions.js +0 -26
  181. package/src/keys/geometry.js +0 -149
  182. package/src/keys/grades.js +0 -367
  183. package/src/keys/index.js +0 -20
  184. package/src/keys/log.js +0 -22
  185. package/src/keys/logic.js +0 -15
  186. package/src/keys/matrices.js +0 -15
  187. package/src/keys/misc.js +0 -71
  188. package/src/keys/navigation.js +0 -8
  189. package/src/keys/operators.js +0 -10
  190. package/src/keys/statistics.js +0 -38
  191. package/src/keys/sub-sup.js +0 -15
  192. package/src/keys/trigonometry.js +0 -15
  193. package/src/keys/utils.js +0 -66
  194. package/src/keys/vars.js +0 -19
  195. package/src/latex-bridge.js +0 -449
  196. package/src/math-input.jsx +0 -115
  197. package/src/mathlive-instance.js +0 -582
  198. package/src/mf/common-styles.js +0 -210
  199. package/src/mf/index.js +0 -30
  200. package/src/mf/input.jsx +0 -328
  201. package/src/mf/static.jsx +0 -479
  202. package/src/selection.js +0 -146
package/lib/selection.js DELETED
@@ -1,148 +0,0 @@
1
- "use strict";
2
-
3
- var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
- Object.defineProperty(exports, "__esModule", {
5
- value: true
6
- });
7
- exports.trackWholeAtomSelection = exports.expandRange = void 0;
8
- var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
9
- var _debug = _interopRequireDefault(require("debug"));
10
- var log = (0, _debug["default"])('pie-lib:math-input-mathlive:selection');
11
-
12
- /**
13
- * Widen a selection so it covers whole atoms of a single parent.
14
- *
15
- * MathLive extends a selection over *flat offsets*, so Shift+Arrow walks into
16
- * a fraction instead of over it: from before `2x` in `5x^2+2x+\frac{\pi}{2}-4`,
17
- * five presses select `2x+` plus the `\pi` of the numerator, and copying gives
18
- * `2x+\pi`. MathQuill treated a fraction (root, superscript...) as one unit,
19
- * which is what authors expect.
20
- *
21
- * The tree is recovered from MathLive's public `getElementInfo(offset)`, where
22
- * offset `i` describes the atom ending at caret position `i`:
23
- *
24
- * - a composite atom (fraction, root, script) owns the offset right *after*
25
- * its children; the children are one level deeper;
26
- * - each branch (numerator, denominator, radicand) opens with an empty-latex
27
- * "start" atom.
28
- *
29
- * The rule: find the shallowest depth the selection touches, counting the caret
30
- * it starts from. If the range crosses into a sibling branch at that depth, the
31
- * real common parent is one level up. Then push both ends out of anything
32
- * deeper. A script atom (`^2`) is kept with its base, since MathLive stores
33
- * `x^2` as `x` followed by a separate `^2` atom.
34
- *
35
- * Pure, so it can be tested without a browser.
36
- *
37
- * @param {number} start
38
- * @param {number} end
39
- * @param {function(number): {depth?: number, latex?: string}} info
40
- * @param {number} lastOffset
41
- * @returns {[number, number]} the widened range, start <= end
42
- */
43
- var expandRange = exports.expandRange = function expandRange(start, end, info, lastOffset) {
44
- var at = function at(i) {
45
- return info(i) || {};
46
- };
47
- var depth = function depth(i) {
48
- return at(i).depth || 0;
49
- };
50
- var isBranchStart = function isBranchStart(i) {
51
- return depth(i) > 0 && at(i).latex === '';
52
- };
53
- if (end < start) {
54
- var _ref = [end, start];
55
- start = _ref[0];
56
- end = _ref[1];
57
- }
58
- if (end - start < 1) {
59
- return [start, end];
60
- }
61
- var target = Infinity;
62
- for (var i = start; i <= end; i++) {
63
- target = Math.min(target, depth(i));
64
- }
65
- for (var _i = start + 1; _i <= end; _i++) {
66
- if (depth(_i) === target && isBranchStart(_i)) {
67
- target -= 1;
68
- break;
69
- }
70
- }
71
- target = Math.max(target, 0);
72
- while (start > 0 && depth(start) > target) {
73
- start -= 1;
74
- }
75
- while (end < lastOffset && depth(end) > target) {
76
- end += 1;
77
- }
78
-
79
- // Keep a superscript / subscript with its base.
80
- var first = start + 1;
81
- while (first <= end && depth(first) > target) {
82
- first += 1;
83
- }
84
- if (start > 0 && first <= end && /^[\^_]/.test(at(first).latex || '') && depth(start) === target) {
85
- start -= 1;
86
- }
87
- return [start, end];
88
- };
89
-
90
- /**
91
- * Keep a mathfield's selection snapped to whole atoms (see {@link expandRange}).
92
- *
93
- * This fixes both what the user sees highlighted and what copy/cut put on the
94
- * clipboard, since both come from the selection. The selection direction is
95
- * preserved, so further Shift+Arrow presses keep extending the same end.
96
- *
97
- * @param {HTMLElement} mathField a MathLive `<math-field>`
98
- * @returns {function|undefined} teardown, to call on unmount
99
- */
100
- var trackWholeAtomSelection = exports.trackWholeAtomSelection = function trackWholeAtomSelection(mathField) {
101
- if (!mathField || typeof mathField.addEventListener !== 'function') {
102
- return undefined;
103
- }
104
- var applying = false;
105
- var update = function update() {
106
- if (applying) {
107
- return;
108
- }
109
- try {
110
- if (mathField.selectionIsCollapsed || typeof mathField.getElementInfo !== 'function') {
111
- return;
112
- }
113
- var selection = mathField.selection;
114
- var range = selection && selection.ranges && selection.ranges[0];
115
- if (!range) {
116
- return;
117
- }
118
- var _range = (0, _slicedToArray2["default"])(range, 2),
119
- start = _range[0],
120
- end = _range[1];
121
- var lo = Math.min(start, end);
122
- var hi = Math.max(start, end);
123
- var _expandRange = expandRange(lo, hi, function (i) {
124
- return mathField.getElementInfo(i);
125
- }, mathField.lastOffset),
126
- _expandRange2 = (0, _slicedToArray2["default"])(_expandRange, 2),
127
- nextStart = _expandRange2[0],
128
- nextEnd = _expandRange2[1];
129
- if (nextStart === lo && nextEnd === hi) {
130
- return;
131
- }
132
- applying = true;
133
- mathField.selection = {
134
- ranges: [[nextStart, nextEnd]],
135
- direction: selection.direction
136
- };
137
- } catch (e) {
138
- log('could not normalise the selection: %s', e && e.message);
139
- } finally {
140
- applying = false;
141
- }
142
- };
143
- mathField.addEventListener('selection-change', update);
144
- return function () {
145
- return mathField.removeEventListener('selection-change', update);
146
- };
147
- };
148
- //# sourceMappingURL=selection.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"selection.js","names":["_debug","_interopRequireDefault","require","log","debug","expandRange","exports","start","end","info","lastOffset","at","i","depth","isBranchStart","latex","_ref","target","Infinity","Math","min","max","first","test","trackWholeAtomSelection","mathField","addEventListener","undefined","applying","update","selectionIsCollapsed","getElementInfo","selection","range","ranges","_range","_slicedToArray2","lo","hi","_expandRange","_expandRange2","nextStart","nextEnd","direction","e","message","removeEventListener"],"sources":["../src/selection.js"],"sourcesContent":["import debug from 'debug';\n\nconst log = debug('pie-lib:math-input-mathlive:selection');\n\n/**\n * Widen a selection so it covers whole atoms of a single parent.\n *\n * MathLive extends a selection over *flat offsets*, so Shift+Arrow walks into\n * a fraction instead of over it: from before `2x` in `5x^2+2x+\\frac{\\pi}{2}-4`,\n * five presses select `2x+` plus the `\\pi` of the numerator, and copying gives\n * `2x+\\pi`. MathQuill treated a fraction (root, superscript...) as one unit,\n * which is what authors expect.\n *\n * The tree is recovered from MathLive's public `getElementInfo(offset)`, where\n * offset `i` describes the atom ending at caret position `i`:\n *\n * - a composite atom (fraction, root, script) owns the offset right *after*\n * its children; the children are one level deeper;\n * - each branch (numerator, denominator, radicand) opens with an empty-latex\n * \"start\" atom.\n *\n * The rule: find the shallowest depth the selection touches, counting the caret\n * it starts from. If the range crosses into a sibling branch at that depth, the\n * real common parent is one level up. Then push both ends out of anything\n * deeper. A script atom (`^2`) is kept with its base, since MathLive stores\n * `x^2` as `x` followed by a separate `^2` atom.\n *\n * Pure, so it can be tested without a browser.\n *\n * @param {number} start\n * @param {number} end\n * @param {function(number): {depth?: number, latex?: string}} info\n * @param {number} lastOffset\n * @returns {[number, number]} the widened range, start <= end\n */\nexport const expandRange = (start, end, info, lastOffset) => {\n const at = (i) => info(i) || {};\n const depth = (i) => at(i).depth || 0;\n const isBranchStart = (i) => depth(i) > 0 && at(i).latex === '';\n\n if (end < start) {\n [start, end] = [end, start];\n }\n\n if (end - start < 1) {\n return [start, end];\n }\n\n let target = Infinity;\n\n for (let i = start; i <= end; i++) {\n target = Math.min(target, depth(i));\n }\n\n for (let i = start + 1; i <= end; i++) {\n if (depth(i) === target && isBranchStart(i)) {\n target -= 1;\n break;\n }\n }\n\n target = Math.max(target, 0);\n\n while (start > 0 && depth(start) > target) {\n start -= 1;\n }\n\n while (end < lastOffset && depth(end) > target) {\n end += 1;\n }\n\n // Keep a superscript / subscript with its base.\n let first = start + 1;\n\n while (first <= end && depth(first) > target) {\n first += 1;\n }\n\n if (start > 0 && first <= end && /^[\\^_]/.test(at(first).latex || '') && depth(start) === target) {\n start -= 1;\n }\n\n return [start, end];\n};\n\n/**\n * Keep a mathfield's selection snapped to whole atoms (see {@link expandRange}).\n *\n * This fixes both what the user sees highlighted and what copy/cut put on the\n * clipboard, since both come from the selection. The selection direction is\n * preserved, so further Shift+Arrow presses keep extending the same end.\n *\n * @param {HTMLElement} mathField a MathLive `<math-field>`\n * @returns {function|undefined} teardown, to call on unmount\n */\nexport const trackWholeAtomSelection = (mathField) => {\n if (!mathField || typeof mathField.addEventListener !== 'function') {\n return undefined;\n }\n\n let applying = false;\n\n const update = () => {\n if (applying) {\n return;\n }\n\n try {\n if (mathField.selectionIsCollapsed || typeof mathField.getElementInfo !== 'function') {\n return;\n }\n\n const selection = mathField.selection;\n const range = selection && selection.ranges && selection.ranges[0];\n\n if (!range) {\n return;\n }\n\n const [start, end] = range;\n const lo = Math.min(start, end);\n const hi = Math.max(start, end);\n const [nextStart, nextEnd] = expandRange(\n lo,\n hi,\n (i) => mathField.getElementInfo(i),\n mathField.lastOffset,\n );\n\n if (nextStart === lo && nextEnd === hi) {\n return;\n }\n\n applying = true;\n mathField.selection = { ranges: [[nextStart, nextEnd]], direction: selection.direction };\n } catch (e) {\n log('could not normalise the selection: %s', e && e.message);\n } finally {\n applying = false;\n }\n };\n\n mathField.addEventListener('selection-change', update);\n\n return () => mathField.removeEventListener('selection-change', update);\n};\n"],"mappings":"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","ignoreList":[]}
@@ -1,220 +0,0 @@
1
- import React from 'react';
2
- import { render } from '@testing-library/react';
3
-
4
- import MathInput from '../math-input';
5
- import HorizontalKeypad from '../horizontal-keypad';
6
- import Input from '../mf/input';
7
-
8
- /**
9
- * The pieces that sit between the keypad and the field: how a pressed key is
10
- * routed into the field, and the legacy `{value,type}` shape math-toolbar
11
- * consumes.
12
- */
13
- describe('MathInput.keypadPress routing', () => {
14
- const withInput = () => {
15
- const mi = new MathInput({});
16
- const calls = { write: [], keystroke: [] };
17
-
18
- mi.input = {
19
- write: (v) => calls.write.push(v),
20
- keystroke: (v) => calls.keystroke.push(v),
21
- };
22
-
23
- return { mi, calls };
24
- };
25
-
26
- it('routes an insert action to write()', () => {
27
- const { mi, calls } = withInput();
28
-
29
- mi.keypadPress({ latex: '\\pi' });
30
-
31
- expect(calls.write).toEqual(['\\pi']);
32
- expect(calls.keystroke).toEqual([]);
33
- });
34
-
35
- it('expands an argument-taking command before writing', () => {
36
- const { mi, calls } = withInput();
37
-
38
- mi.keypadPress({ command: '\\frac' });
39
-
40
- expect(calls.write).toEqual(['\\frac{#?}{#?}']);
41
- });
42
-
43
- it('routes a cursor keystroke to keystroke()', () => {
44
- const { mi, calls } = withInput();
45
-
46
- mi.keypadPress({ keystroke: 'Left' });
47
-
48
- expect(calls.keystroke).toEqual(['moveToPreviousChar']);
49
- expect(calls.write).toEqual([]);
50
- });
51
-
52
- it('ignores keys with no action', () => {
53
- const { mi, calls } = withInput();
54
-
55
- mi.keypadPress({});
56
- mi.keypadPress({ keystroke: 'Nonsense' });
57
-
58
- expect(calls.write).toEqual([]);
59
- expect(calls.keystroke).toEqual([]);
60
- });
61
-
62
- it('is a no-op before the field ref exists', () => {
63
- const mi = new MathInput({});
64
-
65
- expect(() => mi.keypadPress({ latex: '\\pi' })).not.toThrow();
66
- });
67
-
68
- it('changeLatex only fires onChange when the value differs', () => {
69
- const onChange = jest.fn();
70
- const mi = new MathInput({ latex: 'x', onChange });
71
-
72
- mi.changeLatex('x');
73
- expect(onChange).not.toHaveBeenCalled();
74
-
75
- mi.changeLatex('y');
76
- expect(onChange).toHaveBeenCalledWith('y');
77
- });
78
-
79
- it('tracks focus state', () => {
80
- const mi = new MathInput({});
81
-
82
- mi.setState = (s) => Object.assign(mi.state, s);
83
- mi.inputFocus();
84
- expect(mi.state.focused).toBe(true);
85
-
86
- mi.inputBlur();
87
- expect(mi.state.focused).toBe(false);
88
- });
89
- });
90
-
91
- describe('HorizontalKeypad legacy {value,type} model', () => {
92
- const pressed = (key) => {
93
- const onClick = jest.fn();
94
- const hk = new HorizontalKeypad({ onClick });
95
-
96
- hk.keypadPress(key);
97
-
98
- return onClick.mock.calls[0][0];
99
- };
100
-
101
- it('maps a command to {value, type: command}', () => {
102
- expect(pressed({ command: '\\frac' })).toEqual({ value: '\\frac', type: 'command' });
103
- });
104
-
105
- it('maps a write to {value}', () => {
106
- expect(pressed({ write: 'x' })).toEqual({ value: 'x' });
107
- });
108
-
109
- it('maps a keystroke to {type: cursor}', () => {
110
- expect(pressed({ keystroke: 'Left' })).toEqual({ type: 'cursor', value: 'Left' });
111
- });
112
-
113
- it('renders without throwing', () => {
114
- expect(() => render(<HorizontalKeypad onClick={() => {}} />)).not.toThrow();
115
- });
116
- });
117
-
118
- describe('Input: controlled-value sync and events', () => {
119
- const withField = () => {
120
- const input = new Input({});
121
-
122
- input.mathField = {
123
- value: '',
124
- getValue: () => input.mathField.value,
125
- insert(v) {
126
- input.mathField.value += v;
127
- },
128
- executeCommand() {},
129
- focus() {},
130
- blur() {},
131
- addEventListener() {},
132
- removeEventListener() {},
133
- remove() {},
134
- };
135
-
136
- return input;
137
- };
138
-
139
- it('emits stored-form latex on edit', () => {
140
- const onChange = jest.fn();
141
- const input = withField();
142
-
143
- input.props = { onChange };
144
- input.mathField.value = '\\longdiv{\\placeholder{}}';
145
- input.onInputEdit();
146
-
147
- // \placeholder is MathLive-internal and must not reach the model
148
- expect(onChange).toHaveBeenCalledWith('\\longdiv{}');
149
- expect(input.lastEmitted).toEqual('\\longdiv{}');
150
- });
151
-
152
- it('does not push a prop echo back into the field', () => {
153
- const input = withField();
154
-
155
- input.mathField.value = 'x';
156
- input.lastEmitted = 'x';
157
- input.props = { latex: 'x' };
158
-
159
- input.componentDidUpdate({ latex: '' });
160
-
161
- expect(input.mathField.value).toEqual('x');
162
- });
163
-
164
- it('pushes a genuinely new latex prop into the field', () => {
165
- const input = withField();
166
-
167
- input.mathField.value = 'x';
168
- input.lastEmitted = 'x';
169
- input.props = { latex: 'y' };
170
-
171
- input.componentDidUpdate({ latex: 'x' });
172
-
173
- expect(input.mathField.value).toEqual('y');
174
- });
175
-
176
- it('bridges stored latex on the way in', () => {
177
- const input = withField();
178
-
179
- input.props = { latex: '\\longdiv{5}' };
180
- input.componentDidUpdate({ latex: '' });
181
-
182
- // must become native \enclose so the content stays editable
183
- expect(input.mathField.value).toEqual('\\enclose{longdiv}{5}');
184
- });
185
-
186
- it('toggles readOnly', () => {
187
- const input = withField();
188
-
189
- input.props = { readOnly: true };
190
- input.componentDidUpdate({ readOnly: false });
191
-
192
- expect(input.mathField.readOnly).toBe(true);
193
- });
194
-
195
- it('clear() empties the field', () => {
196
- const input = withField();
197
-
198
- input.mathField.value = 'abc';
199
- expect(input.clear()).toEqual('');
200
- expect(input.mathField.value).toEqual('');
201
- });
202
-
203
- it('suppresses Enter so it cannot insert a line break', () => {
204
- const input = withField();
205
- const preventDefault = jest.fn();
206
-
207
- input.onKeyDown({ key: 'Enter', preventDefault });
208
- expect(preventDefault).toHaveBeenCalled();
209
-
210
- preventDefault.mockClear();
211
- input.onKeyDown({ key: 'a', preventDefault });
212
- expect(preventDefault).not.toHaveBeenCalled();
213
- });
214
-
215
- it('componentDidUpdate is safe before the field exists', () => {
216
- const input = new Input({ latex: 'x' });
217
-
218
- expect(() => input.componentDidUpdate({ latex: '' })).not.toThrow();
219
- });
220
- });
@@ -1,112 +0,0 @@
1
- import React from 'react';
2
- import { render } from '@testing-library/react';
3
- import { styled } from '@mui/material/styles';
4
-
5
- import { mq } from '../index';
6
-
7
- /**
8
- * Exercises the exact call patterns real consumers use against
9
- * @pie-lib/math-input, to catch drop-in incompatibilities.
10
- *
11
- * Sources:
12
- * - packages/math-toolbar/src/editor-and-pad.jsx:16,185
13
- * - packages/math-toolbar/src/math-preview.jsx:8,156
14
- * - packages/editable-html/src/plugins/respArea/math-templated/index.jsx:92
15
- * - packages/editable-html-tip-tap/src/components/respArea/MathTemplated.jsx:111
16
- */
17
- describe('drop-in compatibility with @pie-lib/math-input consumers', () => {
18
- describe('mq.CommonMqStyles destructuring', () => {
19
- it('math-preview.jsx: { commonMqFontStyles, longdivStyles, supsubStyles }', () => {
20
- const { commonMqFontStyles, longdivStyles, supsubStyles } = mq.CommonMqStyles;
21
-
22
- expect(commonMqFontStyles).toBeDefined();
23
- expect(longdivStyles).toBeDefined();
24
- expect(supsubStyles).toBeDefined();
25
- });
26
-
27
- it('editor-and-pad.jsx: also { commonMqKeyboardStyles }', () => {
28
- const { commonMqFontStyles, commonMqKeyboardStyles, longdivStyles, supsubStyles } = mq.CommonMqStyles;
29
-
30
- expect(commonMqKeyboardStyles).toBeDefined();
31
- // All four must be spreadable into an emotion style object.
32
- expect(() => ({
33
- ...commonMqFontStyles,
34
- ...commonMqKeyboardStyles,
35
- ...longdivStyles,
36
- ...supsubStyles,
37
- })).not.toThrow();
38
- });
39
-
40
- it('the destructured groups survive being spread into a styled component', () => {
41
- const { commonMqFontStyles, longdivStyles, supsubStyles } = mq.CommonMqStyles;
42
- const Styled = styled('div')({ ...commonMqFontStyles, ...longdivStyles, ...supsubStyles });
43
-
44
- expect(() => render(<Styled />)).not.toThrow();
45
- });
46
- });
47
-
48
- describe('mq.Input', () => {
49
- it('editor-and-pad.jsx: styled(mq.Input) renders', () => {
50
- const MathEditor = styled(mq.Input)(() => ({ width: '100%' }));
51
-
52
- expect(() => render(<MathEditor latex="\\frac{1}{2}" onChange={() => {}} />)).not.toThrow();
53
- });
54
-
55
- it('accepts the className that styled() injects', () => {
56
- const Styled = styled(mq.Input)({ padding: 4 });
57
- const { container } = render(<Styled latex="x" onChange={() => {}} />);
58
-
59
- expect(container.firstChild).toBeTruthy();
60
- expect(container.firstChild.className).toBeTruthy();
61
- });
62
- });
63
-
64
- describe('mq.Static', () => {
65
- it('math-preview.jsx: <mq.Static latex onFocus onBlur />', () => {
66
- expect(() => render(<mq.Static latex={'\\frac{1}{2}'} onFocus={() => {}} onBlur={() => {}} />)).not.toThrow();
67
- });
68
-
69
- it('math-templated respArea: <mq.Static latex={value} />', () => {
70
- expect(() => render(<mq.Static latex={'x=1'} />)).not.toThrow();
71
- });
72
-
73
- it('renders answer-block latex (the templated-math case) without throwing', () => {
74
- expect(() =>
75
- render(<mq.Static latex={'x=\\MathQuillMathField[r1]{}'} onSubFieldChange={() => {}} />),
76
- ).not.toThrow();
77
- });
78
-
79
- it('is styleable, as keypad labels were in math-input', () => {
80
- const Styled = styled(mq.Static)({ pointerEvents: 'none' });
81
-
82
- expect(() => render(<Styled latex={'\\pi'} />)).not.toThrow();
83
- });
84
- });
85
-
86
- describe('surface parity', () => {
87
- it('exposes exactly the names math-input exported', () => {
88
- // eslint-disable-next-line global-require
89
- const pkg = require('../index');
90
-
91
- [
92
- 'keysForGrade',
93
- 'addBrackets',
94
- 'removeBrackets',
95
- 'keys',
96
- 'HorizontalKeypad',
97
- 'mq',
98
- 'updateSpans',
99
- 'registerEmbed',
100
- 'applyStaticMath',
101
- ].forEach((name) => {
102
- expect(pkg[name]).toBeDefined();
103
- });
104
- });
105
-
106
- it('mq exposes Input, Static and CommonMqStyles', () => {
107
- ['Input', 'Static', 'CommonMqStyles'].forEach((name) => {
108
- expect(mq[name]).toBeDefined();
109
- });
110
- });
111
- });
112
- });
@@ -1,109 +0,0 @@
1
- import React from 'react';
2
- import { render } from '@testing-library/react';
3
-
4
- import {
5
- keys,
6
- keysForGrade,
7
- addBrackets,
8
- removeBrackets,
9
- registerEmbed,
10
- applyStaticMath,
11
- updateSpans,
12
- mf,
13
- mq,
14
- MathInput,
15
- HorizontalKeypad,
16
- KeyPad,
17
- } from '../index';
18
-
19
- describe('math-input-mathlive public API', () => {
20
- it('mirrors the @pie-lib/math-input export surface', () => {
21
- expect(typeof keysForGrade).toBe('function');
22
- expect(typeof addBrackets).toBe('function');
23
- expect(typeof removeBrackets).toBe('function');
24
- expect(typeof registerEmbed).toBe('function');
25
- expect(typeof applyStaticMath).toBe('function');
26
- expect(typeof updateSpans).toBe('function');
27
- expect(keys).toBeDefined();
28
- expect(keys.baseSet).toBeDefined();
29
- });
30
-
31
- it('exports the field wrappers under both mf and mq', () => {
32
- expect(mf.Input).toBeDefined();
33
- expect(mf.Static).toBeDefined();
34
- // `mq` alias lets a consumer swap packages by changing only the import.
35
- expect(mq).toBe(mf);
36
- });
37
-
38
- it('updateSpans is a safe no-op', () => {
39
- expect(() => updateSpans()).not.toThrow();
40
- });
41
-
42
- it('CommonMqStyles keeps the shape consumers destructure', () => {
43
- // math-toolbar does:
44
- // const { commonMqFontStyles, commonMqKeyboardStyles, longdivStyles, supsubStyles }
45
- // = mq.CommonMqStyles;
46
- const { commonMqFontStyles, commonMqKeyboardStyles, longdivStyles, supsubStyles } = mf.CommonMqStyles;
47
-
48
- [commonMqFontStyles, commonMqKeyboardStyles, longdivStyles, supsubStyles].forEach((s) => {
49
- expect(s).toBeDefined();
50
- expect(typeof s).toBe('object');
51
- });
52
- });
53
-
54
- it('bracket helpers round-trip', () => {
55
- expect(addBrackets('x')).toEqual('\\(x\\)');
56
- expect(removeBrackets('\\(x\\)')).toEqual('x');
57
- expect(removeBrackets(addBrackets('\\frac{1}{2}'))).toEqual('\\frac{1}{2}');
58
- });
59
-
60
- it('keysForGrade returns a 5-row keyset', () => {
61
- const set = keysForGrade('geometry');
62
-
63
- expect(Array.isArray(set)).toBe(true);
64
- expect(set.length).toBe(5);
65
- });
66
- });
67
-
68
- describe('rendering', () => {
69
- // MathLive is a browser-only custom element; loadMathLive() resolves async and
70
- // is a no-op-ish under jsdom. These assert the components mount without
71
- // throwing, which is what regressed most often in the MathQuill version.
72
- it('KeyPad renders without a live MathLive instance', () => {
73
- const { container } = render(<KeyPad onPress={() => {}} />);
74
-
75
- expect(container.querySelectorAll('button').length).toBeGreaterThan(0);
76
- });
77
-
78
- it('KeyPad falls back to raw latex for labels before MathLive loads', () => {
79
- const { container } = render(
80
- <KeyPad onPress={() => {}} baseSet={[[{ name: 'pi', latex: '\\pi', category: 'constants' }]]} />,
81
- );
82
-
83
- expect(container.textContent).toContain('\\pi');
84
- });
85
-
86
- it('KeyPad fires onPress with the key definition', () => {
87
- const onPress = jest.fn();
88
- const key = { name: 'x', label: 'x', write: 'x', category: 'vars' };
89
- const { container } = render(<KeyPad onPress={onPress} baseSet={[[key]]} />);
90
-
91
- container.querySelector('button').click();
92
-
93
- expect(onPress).toHaveBeenCalledWith(key);
94
- });
95
-
96
- it('MathInput mounts', () => {
97
- expect(() => render(<MathInput latex="\\frac{1}{2}" onChange={() => {}} />)).not.toThrow();
98
- });
99
-
100
- it('HorizontalKeypad mounts and reports the legacy {value,type} model', () => {
101
- const onClick = jest.fn();
102
-
103
- expect(() => render(<HorizontalKeypad onClick={onClick} />)).not.toThrow();
104
- });
105
-
106
- it('Static renders display-mode latex without a mathfield', () => {
107
- expect(() => render(<mf.Static latex="\\frac{1}{2}" />)).not.toThrow();
108
- });
109
- });