@khanacademy/math-input 2.0.0 → 4.0.0

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 (264) hide show
  1. package/CHANGELOG.md +55 -0
  2. package/dist/components/input/__tests__/test-math-wrapper.d.ts +1 -1
  3. package/dist/components/input/__tests__/test-math-wrapper.js.flow +1 -1
  4. package/dist/components/input/key-handlers/handle-arrow.d.ts +3 -0
  5. package/dist/components/input/key-handlers/handle-arrow.js.flow +12 -0
  6. package/dist/components/input/key-handlers/handle-backspace.d.ts +7 -0
  7. package/dist/components/input/key-handlers/handle-backspace.js.flow +14 -0
  8. package/dist/components/input/key-handlers/handle-exponent.d.ts +3 -0
  9. package/dist/components/input/key-handlers/handle-exponent.js.flow +12 -0
  10. package/dist/components/input/key-handlers/handle-jump-out.d.ts +7 -0
  11. package/dist/components/input/key-handlers/handle-jump-out.js.flow +14 -0
  12. package/dist/components/input/math-input.d.ts +1 -1
  13. package/dist/components/input/math-input.js.flow +1 -1
  14. package/dist/components/input/math-wrapper.d.ts +7 -78
  15. package/dist/components/input/math-wrapper.js.flow +16 -78
  16. package/dist/components/input/mathquill-helpers.d.ts +46 -0
  17. package/dist/components/input/mathquill-helpers.js.flow +56 -0
  18. package/dist/components/input/mathquill-instance.d.ts +3 -0
  19. package/dist/components/input/mathquill-instance.js.flow +9 -0
  20. package/dist/components/input/mathquill-types.d.ts +25 -0
  21. package/dist/components/input/mathquill-types.js.flow +34 -0
  22. package/dist/components/key-translator.d.ts +4 -0
  23. package/dist/components/key-translator.js.flow +10 -0
  24. package/dist/components/keypad/button-assets.d.ts +2 -2
  25. package/dist/components/keypad/button-assets.js.flow +2 -2
  26. package/dist/components/keypad/button.d.ts +1 -2
  27. package/dist/components/keypad/button.js.flow +1 -1
  28. package/dist/components/keypad/{pre-algebra-page.d.ts → geometry-page/index.d.ts} +1 -1
  29. package/dist/components/keypad/{pre-algebra-page.js.flow → geometry-page/index.js.flow} +1 -1
  30. package/dist/components/keypad/index.d.ts +5 -4
  31. package/dist/components/keypad/index.js.flow +9 -4
  32. package/dist/components/keypad/keypad-page-items.d.ts +9 -3
  33. package/dist/components/keypad/keypad-page-items.js.flow +9 -3
  34. package/dist/components/keypad/{numeric-input-page.d.ts → numbers-page/index.d.ts} +3 -2
  35. package/dist/components/keypad/numbers-page/index.js.flow +17 -0
  36. package/dist/components/keypad/numbers-page/types.d.ts +4 -0
  37. package/dist/components/keypad/numbers-page/types.js.flow +10 -0
  38. package/dist/components/keypad/operators-page/advanced-relations-buttons.d.ts +7 -0
  39. package/dist/components/keypad/{numeric-input-page.js.flow → operators-page/advanced-relations-buttons.js.flow} +3 -4
  40. package/dist/components/keypad/operators-page/basic-relations-buttons.d.ts +7 -0
  41. package/dist/components/keypad/{trigonometry-page.js.flow → operators-page/basic-relations-buttons.js.flow} +3 -6
  42. package/dist/components/keypad/operators-page/index.d.ts +9 -0
  43. package/dist/components/keypad/operators-page/index.js.flow +17 -0
  44. package/dist/components/keypad/operators-page/logarithms-buttons.d.ts +7 -0
  45. package/dist/components/keypad/operators-page/logarithms-buttons.js.flow +12 -0
  46. package/dist/components/keypad/operators-page/pre-algebra-buttons.d.ts +7 -0
  47. package/dist/components/keypad/operators-page/pre-algebra-buttons.js.flow +12 -0
  48. package/dist/components/keypad/operators-page/types.d.ts +6 -0
  49. package/dist/components/keypad/operators-page/types.js.flow +12 -0
  50. package/dist/components/{compute-layout-parameters.d.ts → keypad-legacy/compute-layout-parameters.d.ts} +1 -1
  51. package/dist/components/{compute-layout-parameters.js.flow → keypad-legacy/compute-layout-parameters.js.flow} +1 -1
  52. package/dist/components/{echo-manager.d.ts → keypad-legacy/echo-manager.d.ts} +2 -11
  53. package/dist/components/{echo-manager.js.flow → keypad-legacy/echo-manager.js.flow} +2 -11
  54. package/dist/components/{expression-keypad.d.ts → keypad-legacy/expression-keypad.d.ts} +3 -4
  55. package/dist/components/{expression-keypad.js.flow → keypad-legacy/expression-keypad.js.flow} +3 -4
  56. package/dist/components/{fraction-keypad.d.ts → keypad-legacy/fraction-keypad.d.ts} +2 -2
  57. package/dist/components/{fraction-keypad.js.flow → keypad-legacy/fraction-keypad.js.flow} +2 -2
  58. package/dist/components/{gesture-manager.d.ts → keypad-legacy/gesture-manager.d.ts} +22 -10
  59. package/dist/components/{gesture-manager.js.flow → keypad-legacy/gesture-manager.js.flow} +28 -13
  60. package/dist/components/{gesture-state-machine.d.ts → keypad-legacy/gesture-state-machine.d.ts} +9 -9
  61. package/dist/components/{gesture-state-machine.js.flow → keypad-legacy/gesture-state-machine.js.flow} +10 -10
  62. package/dist/components/{icon.d.ts → keypad-legacy/icon.d.ts} +1 -1
  63. package/dist/components/{icon.js.flow → keypad-legacy/icon.js.flow} +1 -1
  64. package/dist/components/{keypad-button.d.ts → keypad-legacy/keypad-button.d.ts} +6 -6
  65. package/dist/components/{keypad-button.js.flow → keypad-legacy/keypad-button.js.flow} +7 -7
  66. package/dist/components/{keypad-container.d.ts → keypad-legacy/keypad-container.d.ts} +2 -2
  67. package/dist/components/{keypad-container.js.flow → keypad-legacy/keypad-container.js.flow} +3 -3
  68. package/dist/components/{keypad.d.ts → keypad-legacy/keypad.d.ts} +3 -3
  69. package/dist/components/{keypad.js.flow → keypad-legacy/keypad.js.flow} +3 -3
  70. package/dist/components/{multi-symbol-grid.d.ts → keypad-legacy/multi-symbol-grid.d.ts} +1 -1
  71. package/dist/components/{multi-symbol-grid.js.flow → keypad-legacy/multi-symbol-grid.js.flow} +1 -1
  72. package/dist/components/{multi-symbol-popover.d.ts → keypad-legacy/multi-symbol-popover.d.ts} +1 -1
  73. package/dist/components/{multi-symbol-popover.js.flow → keypad-legacy/multi-symbol-popover.js.flow} +1 -1
  74. package/dist/components/{node-manager.d.ts → keypad-legacy/node-manager.d.ts} +3 -4
  75. package/dist/components/{node-manager.js.flow → keypad-legacy/node-manager.js.flow} +3 -5
  76. package/dist/components/{popover-manager.d.ts → keypad-legacy/popover-manager.d.ts} +1 -1
  77. package/dist/components/{popover-manager.js.flow → keypad-legacy/popover-manager.js.flow} +1 -1
  78. package/dist/components/{popover-state-machine.d.ts → keypad-legacy/popover-state-machine.d.ts} +1 -1
  79. package/dist/components/{popover-state-machine.js.flow → keypad-legacy/popover-state-machine.js.flow} +1 -1
  80. package/dist/components/{provided-keypad.d.ts → keypad-legacy/provided-keypad.d.ts} +1 -1
  81. package/dist/components/{provided-keypad.js.flow → keypad-legacy/provided-keypad.js.flow} +1 -1
  82. package/dist/{store → components/keypad-legacy/store}/actions.d.ts +6 -17
  83. package/dist/{store → components/keypad-legacy/store}/actions.js.flow +7 -22
  84. package/dist/{store → components/keypad-legacy/store}/index.d.ts +0 -1
  85. package/dist/{store → components/keypad-legacy/store}/index.js.flow +0 -1
  86. package/dist/components/keypad-legacy/store/shared.d.ts +7 -0
  87. package/dist/components/keypad-legacy/store/shared.js.flow +14 -0
  88. package/dist/{store → components/keypad-legacy/store}/types.d.ts +5 -15
  89. package/dist/{store → components/keypad-legacy/store}/types.js.flow +5 -15
  90. package/dist/components/keypad-legacy/touchable-keypad-button.d.ts +37 -0
  91. package/dist/components/keypad-legacy/touchable-keypad-button.js.flow +59 -0
  92. package/dist/components/{two-page-keypad.d.ts → keypad-legacy/two-page-keypad.d.ts} +0 -1
  93. package/dist/components/{two-page-keypad.js.flow → keypad-legacy/two-page-keypad.js.flow} +0 -1
  94. package/dist/data/key-configs.d.ts +4 -5
  95. package/dist/data/key-configs.js.flow +3 -6
  96. package/dist/data/keys.d.ts +2 -56
  97. package/dist/data/keys.js.flow +116 -57
  98. package/dist/enums.d.ts +2 -9
  99. package/dist/enums.js.flow +2 -11
  100. package/dist/es/index.js +6393 -5116
  101. package/dist/es/index.js.map +1 -1
  102. package/dist/index.d.ts +5 -3
  103. package/dist/index.js +6868 -5330
  104. package/dist/index.js.flow +6 -3
  105. package/dist/index.js.map +1 -1
  106. package/dist/strings.js +26 -10
  107. package/dist/types.d.ts +19 -17
  108. package/dist/types.js.flow +28 -23
  109. package/package.json +1 -1
  110. package/src/components/input/__tests__/context-tracking.test.ts +43 -44
  111. package/src/components/input/__tests__/mathquill.test.ts +133 -135
  112. package/src/components/input/key-handlers/handle-arrow.ts +70 -0
  113. package/src/components/input/key-handlers/handle-backspace.ts +275 -0
  114. package/src/components/input/key-handlers/handle-exponent.ts +52 -0
  115. package/src/components/input/key-handlers/handle-jump-out.ts +103 -0
  116. package/src/components/input/math-input.tsx +12 -13
  117. package/src/components/input/math-wrapper.ts +88 -837
  118. package/src/components/input/mathquill-helpers.ts +268 -0
  119. package/src/components/input/mathquill-instance.ts +5 -0
  120. package/src/components/input/mathquill-types.ts +55 -0
  121. package/src/components/key-translator.ts +209 -0
  122. package/src/components/keypad/button-assets.tsx +452 -116
  123. package/src/components/keypad/button.stories.tsx +61 -13
  124. package/src/components/keypad/button.tsx +1 -1
  125. package/src/components/keypad/{trigonometry-page.tsx → geometry-page/index.tsx} +4 -5
  126. package/src/components/keypad/index.tsx +19 -14
  127. package/src/components/keypad/keypad-mathquill.stories.tsx +69 -0
  128. package/src/components/keypad/keypad-page-items.tsx +36 -22
  129. package/src/components/keypad/keypad-pages.stories.tsx +5 -5
  130. package/src/components/keypad/keypad.stories.tsx +75 -17
  131. package/src/components/keypad/{numeric-input-page.tsx → numbers-page/index.tsx} +47 -11
  132. package/src/components/keypad/numbers-page/types.ts +4 -0
  133. package/src/components/keypad/operators-page/advanced-relations-buttons.tsx +32 -0
  134. package/src/components/keypad/operators-page/basic-relations-buttons.tsx +32 -0
  135. package/src/components/keypad/{pre-algebra-page.tsx → operators-page/index.tsx} +26 -30
  136. package/src/components/keypad/operators-page/logarithms-buttons.tsx +32 -0
  137. package/src/components/keypad/operators-page/pre-algebra-buttons.tsx +36 -0
  138. package/src/components/keypad/operators-page/types.ts +6 -0
  139. package/src/components/{__tests__ → keypad-legacy/__tests__}/two-page-keypad.test.tsx +0 -2
  140. package/src/components/{compute-layout-parameters.ts → keypad-legacy/compute-layout-parameters.ts} +2 -3
  141. package/src/components/{corner-decal.tsx → keypad-legacy/corner-decal.tsx} +2 -3
  142. package/src/components/{echo-manager.tsx → keypad-legacy/echo-manager.tsx} +8 -21
  143. package/src/components/{empty-keypad-button.tsx → keypad-legacy/empty-keypad-button.tsx} +8 -6
  144. package/src/components/{expression-keypad.tsx → keypad-legacy/expression-keypad.tsx} +8 -17
  145. package/src/components/{fraction-keypad.tsx → keypad-legacy/fraction-keypad.tsx} +6 -6
  146. package/src/components/{gesture-manager.ts → keypad-legacy/gesture-manager.ts} +34 -11
  147. package/src/components/{gesture-state-machine.ts → keypad-legacy/gesture-state-machine.ts} +14 -14
  148. package/src/components/{icon.tsx → keypad-legacy/icon.tsx} +3 -3
  149. package/src/components/{keypad-button.tsx → keypad-legacy/keypad-button.tsx} +26 -26
  150. package/src/components/{keypad-container.tsx → keypad-legacy/keypad-container.tsx} +6 -6
  151. package/src/components/{keypad.tsx → keypad-legacy/keypad.tsx} +5 -5
  152. package/src/components/{many-keypad-button.tsx → keypad-legacy/many-keypad-button.tsx} +13 -6
  153. package/src/components/{math-icon.tsx → keypad-legacy/math-icon.tsx} +2 -2
  154. package/src/components/{multi-symbol-grid.tsx → keypad-legacy/multi-symbol-grid.tsx} +4 -4
  155. package/src/components/{multi-symbol-popover.tsx → keypad-legacy/multi-symbol-popover.tsx} +3 -4
  156. package/src/components/{navigation-pad.tsx → keypad-legacy/navigation-pad.tsx} +5 -5
  157. package/src/components/{node-manager.ts → keypad-legacy/node-manager.ts} +2 -10
  158. package/src/components/{popover-manager.tsx → keypad-legacy/popover-manager.tsx} +2 -2
  159. package/src/components/{popover-state-machine.ts → keypad-legacy/popover-state-machine.ts} +1 -1
  160. package/src/components/{provided-keypad.tsx → keypad-legacy/provided-keypad.tsx} +4 -5
  161. package/src/{store → components/keypad-legacy/store}/actions.ts +7 -36
  162. package/src/{store → components/keypad-legacy/store}/echo-reducer.ts +3 -7
  163. package/src/{store → components/keypad-legacy/store}/index.ts +7 -20
  164. package/src/{store → components/keypad-legacy/store}/input-reducer.ts +4 -5
  165. package/src/{store → components/keypad-legacy/store}/keypad-reducer.ts +3 -4
  166. package/src/{store → components/keypad-legacy/store}/layout-reducer.ts +3 -3
  167. package/src/{store → components/keypad-legacy/store}/shared.ts +3 -3
  168. package/src/{store → components/keypad-legacy/store}/types.ts +15 -19
  169. package/src/components/{styles.ts → keypad-legacy/styles.ts} +1 -1
  170. package/src/components/{text-icon.tsx → keypad-legacy/text-icon.tsx} +2 -2
  171. package/src/components/{touchable-keypad-button.tsx → keypad-legacy/touchable-keypad-button.tsx} +35 -21
  172. package/src/components/{two-page-keypad.tsx → keypad-legacy/two-page-keypad.tsx} +5 -6
  173. package/src/components/tabbar/icons.tsx +0 -2
  174. package/src/data/key-configs.ts +751 -309
  175. package/src/data/keys.ts +118 -70
  176. package/src/enums.ts +10 -9
  177. package/src/index.ts +6 -3
  178. package/src/math-input.stories.tsx +3 -3
  179. package/src/types.ts +21 -16
  180. package/tsconfig-build.tsbuildinfo +1 -1
  181. package/dist/components/keypad/trigonometry-page.d.ts +0 -8
  182. package/dist/components/touchable-keypad-button.d.ts +0 -30
  183. package/dist/components/touchable-keypad-button.js.flow +0 -35
  184. package/dist/components/velocity-tracker.d.ts +0 -48
  185. package/dist/components/velocity-tracker.js.flow +0 -54
  186. package/dist/store/pager-reducer.d.ts +0 -4
  187. package/dist/store/pager-reducer.js.flow +0 -13
  188. package/dist/store/shared.d.ts +0 -7
  189. package/dist/store/shared.js.flow +0 -14
  190. package/src/components/velocity-tracker.ts +0 -86
  191. package/src/store/pager-reducer.ts +0 -125
  192. /package/dist/components/{corner-decal.d.ts → keypad-legacy/corner-decal.d.ts} +0 -0
  193. /package/dist/components/{corner-decal.js.flow → keypad-legacy/corner-decal.js.flow} +0 -0
  194. /package/dist/components/{empty-keypad-button.d.ts → keypad-legacy/empty-keypad-button.d.ts} +0 -0
  195. /package/dist/components/{empty-keypad-button.js.flow → keypad-legacy/empty-keypad-button.js.flow} +0 -0
  196. /package/dist/components/{many-keypad-button.d.ts → keypad-legacy/many-keypad-button.d.ts} +0 -0
  197. /package/dist/components/{many-keypad-button.js.flow → keypad-legacy/many-keypad-button.js.flow} +0 -0
  198. /package/dist/components/{math-icon.d.ts → keypad-legacy/math-icon.d.ts} +0 -0
  199. /package/dist/components/{math-icon.js.flow → keypad-legacy/math-icon.js.flow} +0 -0
  200. /package/dist/components/{navigation-pad.d.ts → keypad-legacy/navigation-pad.d.ts} +0 -0
  201. /package/dist/components/{navigation-pad.js.flow → keypad-legacy/navigation-pad.js.flow} +0 -0
  202. /package/dist/{store → components/keypad-legacy/store}/echo-reducer.d.ts +0 -0
  203. /package/dist/{store → components/keypad-legacy/store}/echo-reducer.js.flow +0 -0
  204. /package/dist/{store → components/keypad-legacy/store}/input-reducer.d.ts +0 -0
  205. /package/dist/{store → components/keypad-legacy/store}/input-reducer.js.flow +0 -0
  206. /package/dist/{store → components/keypad-legacy/store}/keypad-reducer.d.ts +0 -0
  207. /package/dist/{store → components/keypad-legacy/store}/keypad-reducer.js.flow +0 -0
  208. /package/dist/{store → components/keypad-legacy/store}/layout-reducer.d.ts +0 -0
  209. /package/dist/{store → components/keypad-legacy/store}/layout-reducer.js.flow +0 -0
  210. /package/dist/components/{styles.d.ts → keypad-legacy/styles.d.ts} +0 -0
  211. /package/dist/components/{styles.js.flow → keypad-legacy/styles.js.flow} +0 -0
  212. /package/dist/components/{svg-icon.d.ts → keypad-legacy/svg-icon.d.ts} +0 -0
  213. /package/dist/components/{svg-icon.js.flow → keypad-legacy/svg-icon.js.flow} +0 -0
  214. /package/dist/components/{text-icon.d.ts → keypad-legacy/text-icon.d.ts} +0 -0
  215. /package/dist/components/{text-icon.js.flow → keypad-legacy/text-icon.js.flow} +0 -0
  216. /package/dist/components/{z-indexes.d.ts → keypad-legacy/z-indexes.d.ts} +0 -0
  217. /package/dist/components/{z-indexes.js.flow → keypad-legacy/z-indexes.js.flow} +0 -0
  218. /package/src/components/{__tests__ → keypad-legacy/__tests__}/gesture-state-machine.test.ts +0 -0
  219. /package/src/components/{__tests__ → keypad-legacy/__tests__}/node-manager.test.ts +0 -0
  220. /package/src/components/{iconography → keypad-legacy/iconography}/arrow.js +0 -0
  221. /package/src/components/{iconography → keypad-legacy/iconography}/backspace.js +0 -0
  222. /package/src/components/{iconography → keypad-legacy/iconography}/cdot.js +0 -0
  223. /package/src/components/{iconography → keypad-legacy/iconography}/cos.js +0 -0
  224. /package/src/components/{iconography → keypad-legacy/iconography}/cube-root.js +0 -0
  225. /package/src/components/{iconography → keypad-legacy/iconography}/dismiss.js +0 -0
  226. /package/src/components/{iconography → keypad-legacy/iconography}/divide.js +0 -0
  227. /package/src/components/{iconography → keypad-legacy/iconography}/down.js +0 -0
  228. /package/src/components/{iconography → keypad-legacy/iconography}/equal.js +0 -0
  229. /package/src/components/{iconography → keypad-legacy/iconography}/exp-2.js +0 -0
  230. /package/src/components/{iconography → keypad-legacy/iconography}/exp-3.js +0 -0
  231. /package/src/components/{iconography → keypad-legacy/iconography}/exp.js +0 -0
  232. /package/src/components/{iconography → keypad-legacy/iconography}/frac.js +0 -0
  233. /package/src/components/{iconography → keypad-legacy/iconography}/geq.js +0 -0
  234. /package/src/components/{iconography → keypad-legacy/iconography}/gt.js +0 -0
  235. /package/src/components/{iconography → keypad-legacy/iconography}/index.js +0 -0
  236. /package/src/components/{iconography → keypad-legacy/iconography}/jump-into-numerator.js +0 -0
  237. /package/src/components/{iconography → keypad-legacy/iconography}/jump-out-base.js +0 -0
  238. /package/src/components/{iconography → keypad-legacy/iconography}/jump-out-denominator.js +0 -0
  239. /package/src/components/{iconography → keypad-legacy/iconography}/jump-out-exponent.js +0 -0
  240. /package/src/components/{iconography → keypad-legacy/iconography}/jump-out-numerator.js +0 -0
  241. /package/src/components/{iconography → keypad-legacy/iconography}/jump-out-parentheses.js +0 -0
  242. /package/src/components/{iconography → keypad-legacy/iconography}/left-paren.js +0 -0
  243. /package/src/components/{iconography → keypad-legacy/iconography}/left.js +0 -0
  244. /package/src/components/{iconography → keypad-legacy/iconography}/leq.js +0 -0
  245. /package/src/components/{iconography → keypad-legacy/iconography}/ln.js +0 -0
  246. /package/src/components/{iconography → keypad-legacy/iconography}/log-n.js +0 -0
  247. /package/src/components/{iconography → keypad-legacy/iconography}/log.js +0 -0
  248. /package/src/components/{iconography → keypad-legacy/iconography}/lt.js +0 -0
  249. /package/src/components/{iconography → keypad-legacy/iconography}/minus.js +0 -0
  250. /package/src/components/{iconography → keypad-legacy/iconography}/neq.js +0 -0
  251. /package/src/components/{iconography → keypad-legacy/iconography}/parens.js +0 -0
  252. /package/src/components/{iconography → keypad-legacy/iconography}/percent.js +0 -0
  253. /package/src/components/{iconography → keypad-legacy/iconography}/period.js +0 -0
  254. /package/src/components/{iconography → keypad-legacy/iconography}/plus.js +0 -0
  255. /package/src/components/{iconography → keypad-legacy/iconography}/radical.js +0 -0
  256. /package/src/components/{iconography → keypad-legacy/iconography}/right-paren.js +0 -0
  257. /package/src/components/{iconography → keypad-legacy/iconography}/right.js +0 -0
  258. /package/src/components/{iconography → keypad-legacy/iconography}/sin.js +0 -0
  259. /package/src/components/{iconography → keypad-legacy/iconography}/sqrt.js +0 -0
  260. /package/src/components/{iconography → keypad-legacy/iconography}/tan.js +0 -0
  261. /package/src/components/{iconography → keypad-legacy/iconography}/times.js +0 -0
  262. /package/src/components/{iconography → keypad-legacy/iconography}/up.js +0 -0
  263. /package/src/components/{svg-icon.tsx → keypad-legacy/svg-icon.tsx} +0 -0
  264. /package/src/components/{z-indexes.ts → keypad-legacy/z-indexes.ts} +0 -0
@@ -0,0 +1,268 @@
1
+ import {CursorContext} from "./cursor-contexts";
2
+ import MQ from "./mathquill-instance";
3
+ import {
4
+ MathFieldActionType,
5
+ MathFieldCursor,
6
+ MathFieldInterface,
7
+ } from "./mathquill-types";
8
+
9
+ const Numerals = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"];
10
+ const GreekLetters = ["\\theta", "\\pi"];
11
+ const Letters = [
12
+ "A",
13
+ "B",
14
+ "C",
15
+ "D",
16
+ "E",
17
+ "F",
18
+ "G",
19
+ "H",
20
+ "I",
21
+ "J",
22
+ "K",
23
+ "L",
24
+ "M",
25
+ "N",
26
+ "O",
27
+ "P",
28
+ "Q",
29
+ "R",
30
+ "S",
31
+ "T",
32
+ "U",
33
+ "V",
34
+ "W",
35
+ "X",
36
+ "Y",
37
+ "Z",
38
+ ];
39
+
40
+ // We only consider numerals, variables, and Greek Letters to be proper
41
+ // leaf nodes.
42
+ const ValidLeaves = [
43
+ ...Numerals,
44
+ ...GreekLetters,
45
+ ...Letters.map((letter) => letter.toLowerCase()),
46
+ ...Letters.map((letter) => letter.toUpperCase()),
47
+ ];
48
+
49
+ export function getCursor(mathField: MathFieldInterface): MathFieldCursor {
50
+ return mathField.__controller.cursor;
51
+ }
52
+
53
+ export function isFraction(node): boolean {
54
+ return node.jQ && node.jQ.hasClass("mq-fraction");
55
+ }
56
+
57
+ export function isNumerator(node): boolean {
58
+ return node.jQ && node.jQ.hasClass("mq-numerator");
59
+ }
60
+
61
+ export function isDenominator(node): boolean {
62
+ return node.jQ && node.jQ.hasClass("mq-denominator");
63
+ }
64
+
65
+ export function isSubScript(node): boolean {
66
+ // NOTE(charlie): MyScript has a structure whereby its superscripts seem
67
+ // to be represented as a parent node with 'mq-sup-only' containing a
68
+ // single child with 'mq-sup'.
69
+ return (
70
+ node.jQ &&
71
+ (node.jQ.hasClass("mq-sub-only") || node.jQ.hasClass("mq-sub"))
72
+ );
73
+ }
74
+
75
+ export function isSuperScript(node): boolean {
76
+ // NOTE(charlie): MyScript has a structure whereby its superscripts seem
77
+ // to be represented as a parent node with 'mq-sup-only' containing a
78
+ // single child with 'mq-sup'.
79
+ return (
80
+ node.jQ &&
81
+ (node.jQ.hasClass("mq-sup-only") || node.jQ.hasClass("mq-sup"))
82
+ );
83
+ }
84
+
85
+ export function isParens(node): boolean {
86
+ return node && node.ctrlSeq === "\\left(";
87
+ }
88
+
89
+ export function isLeaf(node): boolean {
90
+ return node && node.ctrlSeq && ValidLeaves.includes(node.ctrlSeq.trim());
91
+ }
92
+
93
+ export function isSquareRoot(node): boolean {
94
+ return (
95
+ node.blocks &&
96
+ node.blocks[0].jQ &&
97
+ node.blocks[0].jQ.hasClass("mq-sqrt-stem")
98
+ );
99
+ }
100
+
101
+ export function isNthRoot(node): boolean {
102
+ return (
103
+ node.blocks &&
104
+ node.blocks[0].jQ &&
105
+ node.blocks[0].jQ.hasClass("mq-nthroot")
106
+ );
107
+ }
108
+
109
+ export function isNthRootIndex(node): boolean {
110
+ return node.jQ && node.jQ.hasClass("mq-nthroot");
111
+ }
112
+
113
+ export function isInsideLogIndex(cursor: MathFieldCursor): boolean {
114
+ const grandparent = cursor.parent.parent;
115
+
116
+ if (grandparent && grandparent.jQ.hasClass("mq-supsub")) {
117
+ const command = maybeFindCommandBeforeParens(grandparent);
118
+
119
+ if (command && command.name === "\\log") {
120
+ return true;
121
+ }
122
+ }
123
+
124
+ return false;
125
+ }
126
+
127
+ export function isInsideEmptyNode(cursor: MathFieldCursor): boolean {
128
+ return (
129
+ cursor[MQ.L] === MathFieldActionType.MQ_END &&
130
+ cursor[MQ.R] === MathFieldActionType.MQ_END
131
+ );
132
+ }
133
+
134
+ export function selectNode(node, cursor) {
135
+ cursor.insLeftOf(node);
136
+ cursor.startSelection();
137
+ cursor.insRightOf(node);
138
+ cursor.select();
139
+ cursor.endSelection();
140
+ }
141
+
142
+ /**
143
+ * Return the start node, end node, and full name of the command of which
144
+ * the initial node is a part, or `null` if the node is not part of a
145
+ * command.
146
+ *
147
+ * @param {node} initialNode - the node to included as part of the command
148
+ * @returns {null|object} - `null` or an object containing the start node
149
+ * (`startNode`), end node (`endNode`), and full
150
+ * name (`name`) of the command
151
+ */
152
+ export function maybeFindCommand(initialNode) {
153
+ if (!initialNode) {
154
+ return null;
155
+ }
156
+
157
+ // MathQuill stores commands as separate characters so that
158
+ // users can delete commands one character at a time. We iterate over
159
+ // the nodes from right to left until we hit a sequence starting with a
160
+ // '\\', which signifies the start of a command; then we iterate from
161
+ // left to right until we hit a '\\left(', which signifies the end of a
162
+ // command. If we encounter any character that doesn't belong in a
163
+ // command, we return null. We match a single character at a time.
164
+ // Ex) ['\\l', 'o', 'g ', '\\left(', ...]
165
+ const commandCharRegex = /^[a-z]$/;
166
+ const commandStartRegex = /^\\[a-z]$/;
167
+ const commandEndSeq = "\\left(";
168
+
169
+ // Note: We allowlist the set of valid commands, since relying solely on
170
+ // a command being prefixed with a backslash leads to undesired
171
+ // behavior. For example, Greek symbols, left parentheses, and square
172
+ // roots all get treated as commands.
173
+ const validCommands = ["\\log", "\\ln", "\\cos", "\\sin", "\\tan"];
174
+
175
+ let name = "";
176
+ let startNode;
177
+ let endNode;
178
+
179
+ // Collect the portion of the command from the current node, leftwards
180
+ // until the start of the command.
181
+ let node = initialNode;
182
+ while (node !== 0) {
183
+ const ctrlSeq = node.ctrlSeq.trim();
184
+ if (commandCharRegex.test(ctrlSeq)) {
185
+ name = ctrlSeq + name;
186
+ } else if (commandStartRegex.test(ctrlSeq)) {
187
+ name = ctrlSeq + name;
188
+ startNode = node;
189
+ break;
190
+ } else {
191
+ break;
192
+ }
193
+
194
+ node = node[MQ.L];
195
+ }
196
+
197
+ // If we hit the start of a command, then grab the rest of it by
198
+ // iterating rightwards to compute the full name of the command, along
199
+ // with its terminal node.
200
+ if (startNode) {
201
+ // Next, iterate from the start to the right.
202
+ node = initialNode[MQ.R];
203
+ while (node !== 0) {
204
+ const ctrlSeq = node.ctrlSeq.trim();
205
+ if (commandCharRegex.test(ctrlSeq)) {
206
+ // If we have a single character, add it to the command
207
+ // name.
208
+ name = name + ctrlSeq;
209
+ } else if (ctrlSeq === commandEndSeq) {
210
+ // If we hit the command end delimiter (the left
211
+ // parentheses surrounding its arguments), stop.
212
+ endNode = node;
213
+ break;
214
+ }
215
+
216
+ node = node[MQ.R];
217
+ }
218
+ if (validCommands.includes(name)) {
219
+ return {name, startNode, endNode};
220
+ } else {
221
+ return null;
222
+ }
223
+ } else {
224
+ return null;
225
+ }
226
+ }
227
+
228
+ /**
229
+ * Return the start node, end node, and full name of the command to the left
230
+ * of `\\left(`, or `null` if there is no command.
231
+ *
232
+ * @param {node} leftParenNode - node where .ctrlSeq == `\\left(`
233
+ * @returns {null|object} - `null` or an object containing the start node
234
+ * (`startNode`), end node (`endNode`), and full
235
+ * name (`name`) of the command
236
+ */
237
+ export function maybeFindCommandBeforeParens(leftParenNode) {
238
+ return maybeFindCommand(leftParenNode[MQ.L]);
239
+ }
240
+
241
+ export function contextForCursor(cursor: MathFieldCursor): CursorContext {
242
+ // First, try to find any fraction to the right, unimpeded.
243
+ let visitor = cursor;
244
+ while (visitor[MQ.R] !== MathFieldActionType.MQ_END) {
245
+ if (isFraction(visitor[MQ.R])) {
246
+ return CursorContext.BEFORE_FRACTION;
247
+ } else if (!isLeaf(visitor[MQ.R])) {
248
+ break;
249
+ }
250
+ visitor = visitor[MQ.R];
251
+ }
252
+
253
+ // If that didn't work, check if the parent or grandparent is a special
254
+ // context, so that we can jump outwards.
255
+ if (isParens(cursor.parent && cursor.parent.parent)) {
256
+ return CursorContext.IN_PARENS;
257
+ } else if (isNumerator(cursor.parent)) {
258
+ return CursorContext.IN_NUMERATOR;
259
+ } else if (isDenominator(cursor.parent)) {
260
+ return CursorContext.IN_DENOMINATOR;
261
+ } else if (isSubScript(cursor.parent)) {
262
+ return CursorContext.IN_SUB_SCRIPT;
263
+ } else if (isSuperScript(cursor.parent)) {
264
+ return CursorContext.IN_SUPER_SCRIPT;
265
+ } else {
266
+ return CursorContext.NONE;
267
+ }
268
+ }
@@ -0,0 +1,5 @@
1
+ import MathQuill from "mathquill";
2
+
3
+ import {MathQuillInterface} from "./mathquill-types";
4
+
5
+ export default MathQuill.getInterface(2) as MathQuillInterface;
@@ -0,0 +1,55 @@
1
+ import Key from "../../data/keys";
2
+
3
+ export interface MathQuillInterface {
4
+ L: "L";
5
+ R: "R";
6
+ MathField: (mount: HTMLDivElement, options: any) => MathFieldInterface;
7
+ }
8
+
9
+ export interface MathFieldInterface {
10
+ // Write LaTeX
11
+ // https://docs.mathquill.com/en/latest/Api_Methods/#writelatex_string
12
+ write: (input: string) => void;
13
+ // Enter a LaTeX command
14
+ // https://docs.mathquill.com/en/latest/Api_Methods/#cmdlatex_string
15
+ cmd: (input: string) => void;
16
+ // Simulates keystrokes given a string like "Ctrl-Home Del"
17
+ // https://docs.mathquill.com/en/latest/Api_Methods/#keystrokekeys
18
+ keystroke: (input: string) => void;
19
+ // Simulates typing text, one character at a time
20
+ // https://docs.mathquill.com/en/latest/Api_Methods/#typedtexttext
21
+ typedText: (input: string) => void;
22
+ // () => {}: Gets the contents as LaTeX
23
+ // (string) => {}: Sets the contents as LaTeX
24
+ // https://docs.mathquill.com/en/latest/Api_Methods/#latex
25
+ latex: (input?: string) => string;
26
+ // Moves the cursor to the end of the mathfield in the direction specified
27
+ // https://docs.mathquill.com/en/latest/Api_Methods/#movetodirenddirection
28
+ moveToDirEnd: (direction: "L" | "R") => void;
29
+ // Selects the contents
30
+ // https://docs.mathquill.com/en/latest/Api_Methods/#select
31
+ select: () => void;
32
+ // Clears the selection
33
+ // https://docs.mathquill.com/en/latest/Api_Methods/#clearselection
34
+ clearSelection: () => void;
35
+ // This isn't part of the MathQuill public API
36
+ // I don't know what it is and it feels wrong using it
37
+ __controller: any;
38
+ }
39
+
40
+ export enum MathFieldActionType {
41
+ WRITE = "write",
42
+ CMD = "cmd",
43
+ KEYSTROKE = "keystroke",
44
+ MQ_END = 0,
45
+ }
46
+
47
+ // The MathQuill MathField Cursor
48
+ // it's not part of the public API for MathQuill,
49
+ // we reach into the internals to get it
50
+ export type MathFieldCursor = any;
51
+
52
+ export type MathQuillUpdaterCallback = (
53
+ mathQuill: MathFieldInterface,
54
+ key: Key,
55
+ ) => void;
@@ -0,0 +1,209 @@
1
+ import Key from "../data/keys";
2
+ import {DecimalSeparator} from "../enums";
3
+ import {decimalSeparator} from "../utils";
4
+
5
+ import MQ from "./input/mathquill-instance";
6
+ import {
7
+ MathFieldInterface,
8
+ MathQuillUpdaterCallback,
9
+ } from "./input/mathquill-types";
10
+
11
+ enum ActionType {
12
+ WRITE = "write",
13
+ CMD = "cmd",
14
+ KEYSTROKE = "keystroke",
15
+ MQ_END = 0,
16
+ }
17
+
18
+ const decimalSymbol = decimalSeparator === DecimalSeparator.COMMA ? "," : ".";
19
+
20
+ function buildGenericCallback(
21
+ str: string,
22
+ type: ActionType = ActionType.WRITE,
23
+ ): MathQuillUpdaterCallback {
24
+ return function (mathQuill: MathFieldInterface) {
25
+ switch (type) {
26
+ case ActionType.WRITE: {
27
+ mathQuill.write(str);
28
+ return;
29
+ }
30
+ case ActionType.CMD: {
31
+ mathQuill.cmd(str);
32
+ return;
33
+ }
34
+ case ActionType.KEYSTROKE: {
35
+ mathQuill.keystroke(str);
36
+ return;
37
+ }
38
+ }
39
+ };
40
+ }
41
+
42
+ const keyToMathquillMap: Record<Key, MathQuillUpdaterCallback> = {
43
+ CDOT: buildGenericCallback("\\cdot"),
44
+ COS: buildGenericCallback("cos"),
45
+ DECIMAL: buildGenericCallback(decimalSymbol),
46
+ DIVIDE: buildGenericCallback("\\div"),
47
+ EQUAL: buildGenericCallback("="),
48
+ EXP: buildGenericCallback("^"),
49
+ EXP_2: buildGenericCallback("^2"),
50
+ EXP_3: buildGenericCallback("^3"),
51
+ GEQ: buildGenericCallback("\\geq"),
52
+ GT: buildGenericCallback(">"),
53
+ LEQ: buildGenericCallback("\\leq"),
54
+ LN: buildGenericCallback("\\ln"),
55
+ LOG: buildGenericCallback("\\log"),
56
+ LT: buildGenericCallback("<"),
57
+ MINUS: buildGenericCallback("-"),
58
+ NEGATIVE: buildGenericCallback("-"),
59
+ NEQ: buildGenericCallback("\\neq"),
60
+ PERCENT: buildGenericCallback("%"),
61
+ PERIOD: buildGenericCallback("."),
62
+ PLUS: buildGenericCallback("+"),
63
+ SIN: buildGenericCallback("sin"),
64
+ TAN: buildGenericCallback("tan"),
65
+ TIMES: buildGenericCallback("\\times"),
66
+
67
+ // The `FRAC_EXCLUSIVE` variant is handled manually, since we may need to do
68
+ // some additional navigation depending on the cursor position.
69
+ FRAC_INCLUSIVE: buildGenericCallback("/", ActionType.CMD),
70
+ LEFT_PAREN: buildGenericCallback("(", ActionType.CMD),
71
+ RIGHT_PAREN: buildGenericCallback(")", ActionType.CMD),
72
+ SQRT: buildGenericCallback("sqrt", ActionType.CMD),
73
+ PHI: buildGenericCallback("\\phi", ActionType.CMD),
74
+ PI: buildGenericCallback("pi", ActionType.CMD),
75
+ THETA: buildGenericCallback("theta", ActionType.CMD),
76
+ RADICAL: buildGenericCallback("nthroot", ActionType.CMD),
77
+
78
+ UP: buildGenericCallback("Up", ActionType.KEYSTROKE),
79
+ DOWN: buildGenericCallback("Down", ActionType.KEYSTROKE),
80
+
81
+ CUBE_ROOT: (mathQuill) => {
82
+ mathQuill.write("\\sqrt[3]{}");
83
+ mathQuill.keystroke("Left"); // under the root
84
+ },
85
+
86
+ FRAC_EXCLUSIVE: (mathQuill) => {
87
+ const cursor = mathQuill.__controller.cursor;
88
+ // If there's nothing to the left of the cursor, then we want to
89
+ // leave the cursor to the left of the fraction after creating it.
90
+ const shouldNavigateLeft = cursor[MQ.L] === ActionType.MQ_END;
91
+ mathQuill.cmd("\\frac");
92
+ if (shouldNavigateLeft) {
93
+ mathQuill.keystroke("Left");
94
+ }
95
+ },
96
+
97
+ LOG_B: (mathQuill) => {
98
+ mathQuill.typedText("log_");
99
+ mathQuill.keystroke("Right");
100
+ mathQuill.typedText("(");
101
+ mathQuill.keystroke("Left");
102
+ mathQuill.keystroke("Left");
103
+ },
104
+
105
+ LOG_N: (mathQuill) => {
106
+ mathQuill.write("log_{ }\\left(\\right)");
107
+ mathQuill.keystroke("Left"); // into parentheses
108
+ mathQuill.keystroke("Left"); // out of parentheses
109
+ mathQuill.keystroke("Left"); // into index
110
+ },
111
+
112
+ NTHROOT3: (mathQuill) => {
113
+ mathQuill.typedText("nthroot3");
114
+ mathQuill.keystroke("Right");
115
+ },
116
+
117
+ POW: (mathQuill) => {
118
+ const contents = mathQuill.latex();
119
+ mathQuill.typedText("^");
120
+
121
+ // If the input hasn't changed (for example, if we're
122
+ // attempting to add an exponent on an empty input or an empty
123
+ // denominator), insert our own "a^b"
124
+ if (mathQuill.latex() === contents) {
125
+ mathQuill.typedText("a^b");
126
+ }
127
+ },
128
+
129
+ // These need to be overwritten by the consumer
130
+ // if they're going to be used
131
+ FRAC: () => {},
132
+ RIGHT: () => {},
133
+ LEFT: () => {},
134
+ BACKSPACE: () => {},
135
+ DISMISS: () => {},
136
+ JUMP_OUT_PARENTHESES: () => {},
137
+ JUMP_OUT_EXPONENT: () => {},
138
+ JUMP_OUT_BASE: () => {},
139
+ JUMP_INTO_NUMERATOR: () => {},
140
+ JUMP_OUT_NUMERATOR: () => {},
141
+ JUMP_OUT_DENOMINATOR: () => {},
142
+ NOOP: () => {},
143
+ MANY: () => {},
144
+
145
+ NUM_0: buildGenericCallback("0"),
146
+ NUM_1: buildGenericCallback("1"),
147
+ NUM_2: buildGenericCallback("2"),
148
+ NUM_3: buildGenericCallback("3"),
149
+ NUM_4: buildGenericCallback("4"),
150
+ NUM_5: buildGenericCallback("5"),
151
+ NUM_6: buildGenericCallback("6"),
152
+ NUM_7: buildGenericCallback("7"),
153
+ NUM_8: buildGenericCallback("8"),
154
+ NUM_9: buildGenericCallback("9"),
155
+ a: buildGenericCallback("a"),
156
+ b: buildGenericCallback("b"),
157
+ c: buildGenericCallback("c"),
158
+ d: buildGenericCallback("d"),
159
+ e: buildGenericCallback("e"),
160
+ f: buildGenericCallback("f"),
161
+ g: buildGenericCallback("g"),
162
+ h: buildGenericCallback("h"),
163
+ i: buildGenericCallback("i"),
164
+ j: buildGenericCallback("j"),
165
+ k: buildGenericCallback("k"),
166
+ l: buildGenericCallback("l"),
167
+ m: buildGenericCallback("m"),
168
+ n: buildGenericCallback("n"),
169
+ o: buildGenericCallback("o"),
170
+ p: buildGenericCallback("p"),
171
+ q: buildGenericCallback("q"),
172
+ r: buildGenericCallback("r"),
173
+ s: buildGenericCallback("s"),
174
+ t: buildGenericCallback("t"),
175
+ u: buildGenericCallback("u"),
176
+ v: buildGenericCallback("v"),
177
+ w: buildGenericCallback("w"),
178
+ x: buildGenericCallback("x"),
179
+ y: buildGenericCallback("y"),
180
+ z: buildGenericCallback("z"),
181
+ A: buildGenericCallback("A"),
182
+ B: buildGenericCallback("B"),
183
+ C: buildGenericCallback("C"),
184
+ D: buildGenericCallback("D"),
185
+ E: buildGenericCallback("E"),
186
+ F: buildGenericCallback("F"),
187
+ G: buildGenericCallback("G"),
188
+ H: buildGenericCallback("H"),
189
+ I: buildGenericCallback("I"),
190
+ J: buildGenericCallback("J"),
191
+ K: buildGenericCallback("K"),
192
+ L: buildGenericCallback("L"),
193
+ M: buildGenericCallback("M"),
194
+ N: buildGenericCallback("N"),
195
+ O: buildGenericCallback("O"),
196
+ P: buildGenericCallback("P"),
197
+ Q: buildGenericCallback("Q"),
198
+ R: buildGenericCallback("R"),
199
+ S: buildGenericCallback("S"),
200
+ T: buildGenericCallback("T"),
201
+ U: buildGenericCallback("U"),
202
+ V: buildGenericCallback("V"),
203
+ W: buildGenericCallback("W"),
204
+ X: buildGenericCallback("X"),
205
+ Y: buildGenericCallback("Y"),
206
+ Z: buildGenericCallback("Z"),
207
+ };
208
+
209
+ export default keyToMathquillMap;