@khanacademy/math-input 17.0.5 → 17.0.7

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.
@@ -31,9 +31,9 @@ declare class MathWrapper {
31
31
  * should be placed
32
32
  */
33
33
  setCursorPosition(x: number, y: number, hitNode: HTMLElement): void;
34
- getCursor(): any;
34
+ getCursor(): import("mathquill").Cursor;
35
35
  contextForCursor(): import("./cursor-contexts").CursorContext;
36
- getSelection(): any;
36
+ getSelection(): import("mathquill").MQSelection | undefined;
37
37
  getContent(): string;
38
38
  setContent(latex: string): void;
39
39
  isEmpty(): boolean;
@@ -7,17 +7,60 @@ export type MathFieldConfig = MathQuill.v3.Config;
7
7
  * the ones listed here.
8
8
  * https://docs.mathquill.com/en/latest/Api_Methods/
9
9
  */
10
- export type MathFieldInterface = MathQuill.v3.EditableMathQuill;
10
+ export type MathFieldInterface = MathQuill.v3.EditableMathQuill & {
11
+ cursor: () => MathQuill.Cursor;
12
+ controller: () => MathQuill.Controller;
13
+ };
11
14
  export declare enum MathFieldActionType {
12
15
  WRITE = "write",
13
16
  CMD = "cmd",
14
17
  KEYSTROKE = "keystroke",
15
18
  MQ_END = 0
16
19
  }
20
+ export type MathFieldUpdaterCallback = (mathField: MathFieldInterface, key: Key) => void;
17
21
  /**
18
- * The MathQuill MathField Cursor
19
- * it's not part of the public API for MathQuill,
20
- * we reach into the internals to get it
22
+ * The MathQuill API (see mathuill.d.ts) does not include types
23
+ * for cursor() and controller(), and adding these types there
24
+ * in the MathQuill repo causes unexpected conflicts with other types.
25
+ *
26
+ * We don't want to use the cursor and controller default type `any`
27
+ * so we declare the types here.
21
28
  */
22
- export type MathFieldCursor = any;
23
- export type MathFieldUpdaterCallback = (mathField: MathFieldInterface, key: Key) => void;
29
+ declare module "mathquill" {
30
+ interface MQNode extends ControllerRoot {
31
+ id: number;
32
+ parent: NodeBase;
33
+ }
34
+ interface MQSelection {
35
+ id: number;
36
+ getEnd(dir: number): number;
37
+ }
38
+ interface NodeBase extends MQNode {
39
+ ctrlSeq: string | undefined;
40
+ blocks: MQNode;
41
+ latex(): string;
42
+ }
43
+ interface Cursor {
44
+ parent: MQNode;
45
+ selection: MQSelection | undefined;
46
+ select(): void;
47
+ endSelection(): void;
48
+ show(): Cursor;
49
+ hide(): Cursor;
50
+ insAtRightEnd(root: ControllerRoot): Cursor;
51
+ insRightOf(el: MQNode): Cursor;
52
+ insLeftOf(el: MQNode): Cursor;
53
+ startSelection(): void;
54
+ }
55
+ interface Controller {
56
+ parent: string;
57
+ root: ControllerRoot;
58
+ cursor: Cursor;
59
+ backspace(): Controller;
60
+ seek(targetElm: HTMLElement, clientX: number, _clientY: number): Controller;
61
+ }
62
+ interface ControllerRoot {
63
+ controller: Controller;
64
+ cursor?: Cursor;
65
+ }
66
+ }
package/dist/es/index.js CHANGED
@@ -7,7 +7,7 @@ import { StyleSheet, css } from 'aphrodite';
7
7
  import * as React from 'react';
8
8
  import { useState, useMemo, useEffect } from 'react';
9
9
  import ReactDOM from 'react-dom';
10
- import $ from 'jquery';
10
+ import { SpeechRuleEngine } from '@khanacademy/mathjax-renderer';
11
11
  import MathQuill from 'mathquill';
12
12
  import { View as View$1 } from '@khanacademy/wonder-blocks-core';
13
13
  import Clickable from '@khanacademy/wonder-blocks-clickable';
@@ -17,7 +17,7 @@ import PropTypes from 'prop-types';
17
17
 
18
18
  // This file is processed by a Rollup plugin (replace) to inject the production
19
19
  const libName = "@khanacademy/math-input";
20
- const libVersion = "17.0.5";
20
+ const libVersion = "17.0.7";
21
21
  addLibraryVersionToPerseusDebug(libName, libVersion);
22
22
 
23
23
  function _extends() {
@@ -339,6 +339,50 @@ let CursorContext = /*#__PURE__*/function (CursorContext) {
339
339
  return CursorContext;
340
340
  }({});
341
341
 
342
+ var _process;
343
+ const DecimalSeparator = {
344
+ COMMA: ",",
345
+ PERIOD: "."
346
+ };
347
+
348
+ // NOTES(kevinb):
349
+ // - In order to get the correct decimal separator for the current locale,
350
+ // the locale must bet set using `setLocale(kaLocale)` which can be
351
+ // imported from wonder-blocks-i18n.
352
+ // - Some languages/locales use different decimal separators than the ones
353
+ // listed here. Much of the Arab world uses U+066C.
354
+ const decimalSeparator = getDecimalSeparator() === "," ? DecimalSeparator.COMMA : DecimalSeparator.PERIOD;
355
+ const CDOT_ONLY = ["az", "cs", "da", "de", "hu", "hy", "kk", "ky", "lt", "lv", "nb", "sk", "sr", "sv", "uz"];
356
+ const TIMES_ONLY = ["fr", "tr", "pt-pt"];
357
+
358
+ /**
359
+ * convertDotToTimes (aka `times`) is an option the content creators have to
360
+ * use × (TIMES) rather than · (CDOT) for multiplication (for younger learners).
361
+ * Some locales _only_ use one or the other for all multiplication regardless
362
+ * of age.
363
+ *
364
+ * convertDotToTimesByLocale overrides convertDotToTimes for those locales.
365
+ *
366
+ * @param {boolean} convertDotToTimes - the setting set by content creators
367
+ * @returns {boolean} - true to convert to × (TIMES), false to use · (CDOT)
368
+ */
369
+ function convertDotToTimesByLocale(convertDotToTimes) {
370
+ const locale = getLocale();
371
+ if (CDOT_ONLY.includes(locale)) {
372
+ return false;
373
+ }
374
+ if (TIMES_ONLY.includes(locale)) {
375
+ return true;
376
+ }
377
+ return convertDotToTimes;
378
+ }
379
+
380
+ /**
381
+ * Use this to avoid running code that should not run in Jest.
382
+ **/
383
+ const inJest = typeof process !== "undefined" && !!((_process = process) != null && (_process = _process.env) != null && _process.JEST_WORKER_ID);
384
+ // Explicitly checking for undefined because Cypress throws an error
385
+
342
386
  // We only need one MathQuill instance (referred to as MQ in the docs)
343
387
  // and that contains some MQ constants and the MathField constructor
344
388
  const mathQuillInstance = MathQuill.getInterface(3);
@@ -390,6 +434,12 @@ function createMathField(container, configCallback) {
390
434
  const mathField = mathQuillInstance.MathField(container, config)
391
435
  // translated in ./math-input.tsx
392
436
  .setAriaLabel(i18n._("Math input box"));
437
+
438
+ // We should avoid running SpeechRuleEngine.setup() in Jest. It makes an
439
+ // HTTP request to fetch non-english speech rules, and cannot be easily
440
+ // mocked in consuming packages now that we do not bundle source code.
441
+ // When it eventually times out, it will cause arbitrary test failures.
442
+ !inJest && SpeechRuleEngine.setup().then(SRE => mathField.setMathspeakOverride(SRE.texToSpeech));
393
443
  return mathField;
394
444
  }
395
445
 
@@ -408,9 +458,12 @@ let MathFieldActionType = /*#__PURE__*/function (MathFieldActionType) {
408
458
  }({});
409
459
 
410
460
  /**
411
- * The MathQuill MathField Cursor
412
- * it's not part of the public API for MathQuill,
413
- * we reach into the internals to get it
461
+ * The MathQuill API (see mathuill.d.ts) does not include types
462
+ * for cursor() and controller(), and adding these types there
463
+ * in the MathQuill repo causes unexpected conflicts with other types.
464
+ *
465
+ * We don't want to use the cursor and controller default type `any`
466
+ * so we declare the types here.
414
467
  */
415
468
 
416
469
  const Numerals = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"];
@@ -825,43 +878,6 @@ function handleBackspace(mathField) {
825
878
  }
826
879
  }
827
880
 
828
- const DecimalSeparator = {
829
- COMMA: ",",
830
- PERIOD: "."
831
- };
832
-
833
- // NOTES(kevinb):
834
- // - In order to get the correct decimal separator for the current locale,
835
- // the locale must bet set using `setLocale(kaLocale)` which can be
836
- // imported from wonder-blocks-i18n.
837
- // - Some languages/locales use different decimal separators than the ones
838
- // listed here. Much of the Arab world uses U+066C.
839
- const decimalSeparator = getDecimalSeparator() === "," ? DecimalSeparator.COMMA : DecimalSeparator.PERIOD;
840
- const CDOT_ONLY = ["az", "cs", "da", "de", "hu", "hy", "kk", "ky", "lt", "lv", "nb", "sk", "sr", "sv", "uz"];
841
- const TIMES_ONLY = ["fr", "tr", "pt-pt"];
842
-
843
- /**
844
- * convertDotToTimes (aka `times`) is an option the content creators have to
845
- * use × (TIMES) rather than · (CDOT) for multiplication (for younger learners).
846
- * Some locales _only_ use one or the other for all multiplication regardless
847
- * of age.
848
- *
849
- * convertDotToTimesByLocale overrides convertDotToTimes for those locales.
850
- *
851
- * @param {boolean} convertDotToTimes - the setting set by content creators
852
- * @returns {boolean} - true to convert to × (TIMES), false to use · (CDOT)
853
- */
854
- function convertDotToTimesByLocale(convertDotToTimes) {
855
- const locale = getLocale();
856
- if (CDOT_ONLY.includes(locale)) {
857
- return false;
858
- }
859
- if (TIMES_ONLY.includes(locale)) {
860
- return true;
861
- }
862
- return convertDotToTimes;
863
- }
864
-
865
881
  function handleLeftArrow(mathField, cursor) {
866
882
  // If we're inside a function, and just after the left parentheses, we
867
883
  // need to skip the entire function name, rather than move the cursor
@@ -1323,7 +1339,7 @@ class MathWrapper {
1323
1339
  const controller = this.mathField.controller();
1324
1340
  const pageX = x - document.body.scrollLeft;
1325
1341
  const pageY = y - document.body.scrollTop;
1326
- controller.seek($(el), pageX, pageY).cursor.startSelection();
1342
+ controller.seek(el, pageX, pageY).cursor.startSelection();
1327
1343
 
1328
1344
  // Unless that would leave us mid-command, in which case, we
1329
1345
  // need to adjust and place the cursor inside the parens