@khanacademy/math-input 1.0.1 → 2.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.
- package/CHANGELOG.md +5 -1
- package/dist/components/compute-layout-parameters.d.ts +2 -1
- package/dist/components/compute-layout-parameters.js.flow +2 -21
- package/dist/components/echo-manager.d.ts +4 -4
- package/dist/components/echo-manager.js.flow +4 -4
- package/dist/components/expression-keypad.d.ts +1 -1
- package/dist/components/expression-keypad.js.flow +1 -1
- package/dist/components/fraction-keypad.d.ts +1 -1
- package/dist/components/fraction-keypad.js.flow +1 -1
- package/dist/components/gesture-state-machine.d.ts +7 -7
- package/dist/components/gesture-state-machine.js.flow +8 -8
- package/dist/components/icon.d.ts +2 -2
- package/dist/components/icon.js.flow +2 -2
- package/dist/components/input/cursor-contexts.d.ts +10 -9
- package/dist/components/input/cursor-contexts.js.flow +11 -16
- package/dist/components/input/math-wrapper.d.ts +3 -2
- package/dist/components/input/math-wrapper.js.flow +3 -16
- package/dist/components/keypad-button.d.ts +8 -8
- package/dist/components/keypad-button.js.flow +10 -9
- package/dist/components/keypad-container.d.ts +2 -3
- package/dist/components/keypad-container.js.flow +2 -3
- package/dist/components/keypad.d.ts +1 -1
- package/dist/components/keypad.js.flow +1 -1
- package/dist/components/multi-symbol-grid.d.ts +2 -2
- package/dist/components/multi-symbol-grid.js.flow +2 -2
- package/dist/components/styles.d.ts +1 -2
- package/dist/components/styles.js.flow +1 -3
- package/dist/components/touchable-keypad-button.d.ts +6 -6
- package/dist/components/touchable-keypad-button.js.flow +6 -6
- package/dist/data/keys.d.ts +51 -52
- package/dist/data/keys.js.flow +50 -99
- package/dist/enums.d.ts +49 -0
- package/dist/enums.js.flow +63 -0
- package/dist/es/index.js +362 -391
- package/dist/es/index.js.map +1 -1
- package/dist/fake-react-native-web/view.d.ts +1 -2
- package/dist/fake-react-native-web/view.js.flow +1 -2
- package/dist/index.d.ts +3 -6
- package/dist/index.js +379 -406
- package/dist/index.js.flow +3 -6
- package/dist/index.js.map +1 -1
- package/dist/store/actions.d.ts +3 -3
- package/dist/store/actions.js.flow +5 -4
- package/dist/store/shared.d.ts +2 -1
- package/dist/store/shared.js.flow +2 -1
- package/dist/store/types.d.ts +4 -5
- package/dist/store/types.js.flow +4 -5
- package/dist/types.d.ts +15 -16
- package/dist/types.js.flow +20 -20
- package/package.json +1 -1
- package/src/components/compute-layout-parameters.ts +6 -6
- package/src/components/echo-manager.tsx +10 -10
- package/src/components/expression-keypad.tsx +9 -10
- package/src/components/fraction-keypad.tsx +11 -12
- package/src/components/gesture-state-machine.ts +8 -8
- package/src/components/icon.tsx +6 -6
- package/src/components/input/__tests__/context-tracking.test.ts +20 -20
- package/src/components/input/cursor-contexts.ts +22 -29
- package/src/components/input/math-wrapper.ts +75 -67
- package/src/components/keypad-button.tsx +20 -21
- package/src/components/keypad-container.tsx +8 -9
- package/src/components/many-keypad-button.tsx +2 -2
- package/src/components/multi-symbol-grid.tsx +4 -5
- package/src/components/multi-symbol-popover.tsx +1 -1
- package/src/components/navigation-pad.tsx +1 -1
- package/src/components/touchable-keypad-button.tsx +7 -7
- package/src/data/key-configs.ts +58 -58
- package/src/data/keys.ts +53 -105
- package/src/enums.ts +74 -0
- package/src/index.ts +3 -9
- package/src/math-input.stories.tsx +8 -8
- package/src/store/actions.ts +4 -3
- package/src/store/echo-reducer.ts +5 -5
- package/src/store/index.ts +1 -2
- package/src/store/input-reducer.ts +4 -4
- package/src/store/layout-reducer.ts +9 -9
- package/src/store/pager-reducer.ts +3 -3
- package/src/store/shared.ts +4 -4
- package/src/store/types.ts +4 -5
- package/src/types.ts +20 -20
- package/src/utils.ts +3 -3
- package/tsconfig-build.tsbuildinfo +1 -0
- package/dist/consts.d.ts +0 -51
- package/dist/consts.js.flow +0 -66
- package/src/consts.ts +0 -91
- package/tsconfig.tsbuildinfo +0 -1
- /package/{tsconfig.json → tsconfig-build.json} +0 -0
package/dist/es/index.js
CHANGED
|
@@ -16,6 +16,29 @@ import { View as View$1 } from '@khanacademy/wonder-blocks-core';
|
|
|
16
16
|
import Clickable from '@khanacademy/wonder-blocks-clickable';
|
|
17
17
|
import now from 'performance-now';
|
|
18
18
|
|
|
19
|
+
/**
|
|
20
|
+
* Enum that defines the various contexts in which a cursor can exist. The
|
|
21
|
+
* active context is determined first by looking at the cursor's siblings (e.g.,
|
|
22
|
+
* for the `BEFORE_FRACTION` context), and then at its direct parent. Though a
|
|
23
|
+
* cursor could in theory be nested in multiple contexts, we only care about the
|
|
24
|
+
* immediate context.
|
|
25
|
+
*
|
|
26
|
+
* TODO(charlie): Add a context to represent being inside of a radical. Right
|
|
27
|
+
* now, we show the dismiss button rather than allowing the user to jump out of
|
|
28
|
+
* the radical.
|
|
29
|
+
*/
|
|
30
|
+
|
|
31
|
+
let CursorContext = /*#__PURE__*/function (CursorContext) {
|
|
32
|
+
CursorContext["NONE"] = "NONE";
|
|
33
|
+
CursorContext["IN_PARENS"] = "IN_PARENS";
|
|
34
|
+
CursorContext["IN_SUPER_SCRIPT"] = "IN_SUPER_SCRIPT";
|
|
35
|
+
CursorContext["IN_SUB_SCRIPT"] = "IN_SUB_SCRIPT";
|
|
36
|
+
CursorContext["IN_NUMERATOR"] = "IN_NUMERATOR";
|
|
37
|
+
CursorContext["IN_DENOMINATOR"] = "IN_DENOMINATOR";
|
|
38
|
+
CursorContext["BEFORE_FRACTION"] = "BEFORE_FRACTION";
|
|
39
|
+
return CursorContext;
|
|
40
|
+
}({});
|
|
41
|
+
|
|
19
42
|
function _extends() {
|
|
20
43
|
_extends = Object.assign || function (target) {
|
|
21
44
|
for (var i = 1; i < arguments.length; i++) {
|
|
@@ -38,69 +61,61 @@ function _extends() {
|
|
|
38
61
|
* This file contains constants for keypad buttons that aren't single
|
|
39
62
|
* alphanumeric characters.
|
|
40
63
|
*/
|
|
41
|
-
|
|
42
64
|
// TODO(charlie): There's duplication between this file and key-configs.js.
|
|
43
65
|
// We should clean it up by removing this file and requiring clients to use the
|
|
44
66
|
// `id` field on the key configurations.
|
|
45
|
-
|
|
46
|
-
PLUS
|
|
47
|
-
MINUS
|
|
48
|
-
NEGATIVE
|
|
49
|
-
TIMES
|
|
50
|
-
DIVIDE
|
|
51
|
-
DECIMAL
|
|
52
|
-
PERIOD
|
|
53
|
-
PERCENT
|
|
54
|
-
CDOT
|
|
55
|
-
EQUAL
|
|
56
|
-
NEQ
|
|
57
|
-
GT
|
|
58
|
-
LT
|
|
59
|
-
GEQ
|
|
60
|
-
LEQ
|
|
61
|
-
FRAC_INCLUSIVE
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
FRAC_MULTI: "FRAC_MULTI",
|
|
98
|
-
// mobile native only
|
|
99
|
-
|
|
100
|
-
// A custom key that captures an arbitrary number of symbols but has no
|
|
101
|
-
// 'default' symbol or action.
|
|
102
|
-
MANY: "MANY"
|
|
103
|
-
};
|
|
67
|
+
var Keys = /*#__PURE__*/function (Keys) {
|
|
68
|
+
Keys["PLUS"] = "PLUS";
|
|
69
|
+
Keys["MINUS"] = "MINUS";
|
|
70
|
+
Keys["NEGATIVE"] = "NEGATIVE";
|
|
71
|
+
Keys["TIMES"] = "TIMES";
|
|
72
|
+
Keys["DIVIDE"] = "DIVIDE";
|
|
73
|
+
Keys["DECIMAL"] = "DECIMAL";
|
|
74
|
+
Keys["PERIOD"] = "PERIOD";
|
|
75
|
+
Keys["PERCENT"] = "PERCENT";
|
|
76
|
+
Keys["CDOT"] = "CDOT";
|
|
77
|
+
Keys["EQUAL"] = "EQUAL";
|
|
78
|
+
Keys["NEQ"] = "NEQ";
|
|
79
|
+
Keys["GT"] = "GT";
|
|
80
|
+
Keys["LT"] = "LT";
|
|
81
|
+
Keys["GEQ"] = "GEQ";
|
|
82
|
+
Keys["LEQ"] = "LEQ";
|
|
83
|
+
Keys["FRAC_INCLUSIVE"] = "FRAC_INCLUSIVE";
|
|
84
|
+
Keys["FRAC_EXCLUSIVE"] = "FRAC_EXCLUSIVE";
|
|
85
|
+
Keys["FRAC"] = "FRAC";
|
|
86
|
+
Keys["EXP"] = "EXP";
|
|
87
|
+
Keys["EXP_2"] = "EXP_2";
|
|
88
|
+
Keys["EXP_3"] = "EXP_3";
|
|
89
|
+
Keys["SQRT"] = "SQRT";
|
|
90
|
+
Keys["CUBE_ROOT"] = "CUBE_ROOT";
|
|
91
|
+
Keys["RADICAL"] = "RADICAL";
|
|
92
|
+
Keys["LEFT_PAREN"] = "LEFT_PAREN";
|
|
93
|
+
Keys["RIGHT_PAREN"] = "RIGHT_PAREN";
|
|
94
|
+
Keys["LN"] = "LN";
|
|
95
|
+
Keys["LOG"] = "LOG";
|
|
96
|
+
Keys["LOG_N"] = "LOG_N";
|
|
97
|
+
Keys["SIN"] = "SIN";
|
|
98
|
+
Keys["COS"] = "COS";
|
|
99
|
+
Keys["TAN"] = "TAN";
|
|
100
|
+
Keys["PI"] = "PI";
|
|
101
|
+
Keys["THETA"] = "THETA";
|
|
102
|
+
Keys["UP"] = "UP";
|
|
103
|
+
Keys["RIGHT"] = "RIGHT";
|
|
104
|
+
Keys["DOWN"] = "DOWN";
|
|
105
|
+
Keys["LEFT"] = "LEFT";
|
|
106
|
+
Keys["BACKSPACE"] = "BACKSPACE";
|
|
107
|
+
Keys["DISMISS"] = "DISMISS";
|
|
108
|
+
Keys["JUMP_OUT_PARENTHESES"] = "JUMP_OUT_PARENTHESES";
|
|
109
|
+
Keys["JUMP_OUT_EXPONENT"] = "JUMP_OUT_EXPONENT";
|
|
110
|
+
Keys["JUMP_OUT_BASE"] = "JUMP_OUT_BASE";
|
|
111
|
+
Keys["JUMP_INTO_NUMERATOR"] = "JUMP_INTO_NUMERATOR";
|
|
112
|
+
Keys["JUMP_OUT_NUMERATOR"] = "JUMP_OUT_NUMERATOR";
|
|
113
|
+
Keys["JUMP_OUT_DENOMINATOR"] = "JUMP_OUT_DENOMINATOR";
|
|
114
|
+
Keys["NOOP"] = "NOOP";
|
|
115
|
+
Keys["FRAC_MULTI"] = "FRAC_MULTI";
|
|
116
|
+
Keys["MANY"] = "MANY";
|
|
117
|
+
return Keys;
|
|
118
|
+
}(Keys || {});
|
|
104
119
|
|
|
105
120
|
class Text extends React.Component {
|
|
106
121
|
render() {
|
|
@@ -390,66 +405,64 @@ class DragListener {
|
|
|
390
405
|
* Constants that are shared between multiple files.
|
|
391
406
|
*/
|
|
392
407
|
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
};
|
|
398
|
-
|
|
399
|
-
EMPTY
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
};
|
|
429
|
-
const BorderDirections = {
|
|
430
|
-
LEFT: "LEFT",
|
|
431
|
-
BOTTOM: "BOTTOM"
|
|
432
|
-
};
|
|
408
|
+
let KeypadType = /*#__PURE__*/function (KeypadType) {
|
|
409
|
+
KeypadType["FRACTION"] = "FRACTION";
|
|
410
|
+
KeypadType["EXPRESSION"] = "EXPRESSION";
|
|
411
|
+
return KeypadType;
|
|
412
|
+
}({});
|
|
413
|
+
let KeyType = /*#__PURE__*/function (KeyType) {
|
|
414
|
+
KeyType["EMPTY"] = "EMPTY";
|
|
415
|
+
KeyType["VALUE"] = "VALUE";
|
|
416
|
+
KeyType["OPERATOR"] = "OPERATOR";
|
|
417
|
+
KeyType["INPUT_NAVIGATION"] = "INPUT_NAVIGATION";
|
|
418
|
+
KeyType["KEYPAD_NAVIGATION"] = "KEYPAD_NAVIGATION";
|
|
419
|
+
KeyType["MANY"] = "MANY";
|
|
420
|
+
KeyType["ECHO"] = "ECHO";
|
|
421
|
+
return KeyType;
|
|
422
|
+
}({});
|
|
423
|
+
let DeviceOrientation = /*#__PURE__*/function (DeviceOrientation) {
|
|
424
|
+
DeviceOrientation["LANDSCAPE"] = "LANDSCAPE";
|
|
425
|
+
DeviceOrientation["PORTRAIT"] = "PORTRAIT";
|
|
426
|
+
return DeviceOrientation;
|
|
427
|
+
}({});
|
|
428
|
+
let DeviceType = /*#__PURE__*/function (DeviceType) {
|
|
429
|
+
DeviceType["PHONE"] = "PHONE";
|
|
430
|
+
DeviceType["TABLET"] = "TABLET";
|
|
431
|
+
return DeviceType;
|
|
432
|
+
}({});
|
|
433
|
+
let LayoutMode = /*#__PURE__*/function (LayoutMode) {
|
|
434
|
+
LayoutMode["FULLSCREEN"] = "FULLSCREEN";
|
|
435
|
+
LayoutMode["COMPACT"] = "COMPACT";
|
|
436
|
+
return LayoutMode;
|
|
437
|
+
}({});
|
|
438
|
+
let BorderDirection = /*#__PURE__*/function (BorderDirection) {
|
|
439
|
+
BorderDirection["LEFT"] = "LEFT";
|
|
440
|
+
BorderDirection["BOTTOM"] = "BOTTOM";
|
|
441
|
+
return BorderDirection;
|
|
442
|
+
}({});
|
|
433
443
|
const BorderStyles = {
|
|
434
|
-
LEFT: [
|
|
435
|
-
BOTTOM: [
|
|
436
|
-
ALL: [
|
|
444
|
+
LEFT: [BorderDirection.LEFT],
|
|
445
|
+
BOTTOM: [BorderDirection.BOTTOM],
|
|
446
|
+
ALL: [BorderDirection.LEFT, BorderDirection.BOTTOM],
|
|
437
447
|
NONE: []
|
|
438
448
|
};
|
|
439
|
-
|
|
440
|
-
MATH
|
|
441
|
-
SVG
|
|
442
|
-
TEXT
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
449
|
+
let IconType = /*#__PURE__*/function (IconType) {
|
|
450
|
+
IconType["MATH"] = "MATH";
|
|
451
|
+
IconType["SVG"] = "SVG";
|
|
452
|
+
IconType["TEXT"] = "TEXT";
|
|
453
|
+
return IconType;
|
|
454
|
+
}({});
|
|
455
|
+
let DecimalSeparator = /*#__PURE__*/function (DecimalSeparator) {
|
|
456
|
+
DecimalSeparator["COMMA"] = "COMMA";
|
|
457
|
+
DecimalSeparator["PERIOD"] = "PERIOD";
|
|
458
|
+
return DecimalSeparator;
|
|
459
|
+
}({});
|
|
460
|
+
let EchoAnimationType = /*#__PURE__*/function (EchoAnimationType) {
|
|
461
|
+
EchoAnimationType["SLIDE_AND_FADE"] = "SLIDE_AND_FADE";
|
|
462
|
+
EchoAnimationType["FADE_ONLY"] = "FADE_ONLY";
|
|
463
|
+
EchoAnimationType["LONG_FADE_ONLY"] = "LONG_FADE_ONLY";
|
|
464
|
+
return EchoAnimationType;
|
|
465
|
+
}({});
|
|
453
466
|
|
|
454
467
|
// NOTES(kevinb):
|
|
455
468
|
// - In order to get the correct decimal separator for the current locale,
|
|
@@ -457,50 +470,7 @@ const EchoAnimationTypes = {
|
|
|
457
470
|
// imported from wonder-blocks-i18n.
|
|
458
471
|
// - Some languages/locales use different decimal separators than the ones
|
|
459
472
|
// listed here. Much of the Arab world uses U+066C.
|
|
460
|
-
const decimalSeparator = getDecimalSeparator() === "," ?
|
|
461
|
-
|
|
462
|
-
/**
|
|
463
|
-
* Constants that define the various contexts in which a cursor can exist. The
|
|
464
|
-
* active context is determined first by looking at the cursor's siblings (e.g.,
|
|
465
|
-
* for the `BEFORE_FRACTION` context), and then at its direct parent. Though a
|
|
466
|
-
* cursor could in theory be nested in multiple contexts, we only care about the
|
|
467
|
-
* immediate context.
|
|
468
|
-
*
|
|
469
|
-
* TODO(charlie): Add a context to represent being inside of a radical. Right
|
|
470
|
-
* now, we show the dismiss button rather than allowing the user to jump out of
|
|
471
|
-
* the radical.
|
|
472
|
-
*/
|
|
473
|
-
|
|
474
|
-
// TODO: Get rid of these constants in favour of CursorContext type.
|
|
475
|
-
|
|
476
|
-
// The cursor is not in any of the other viable contexts.
|
|
477
|
-
const NONE = "NONE";
|
|
478
|
-
// The cursor is within a set of parentheses.
|
|
479
|
-
const IN_PARENS = "IN_PARENS";
|
|
480
|
-
// The cursor is within a superscript (e.g., an exponent).
|
|
481
|
-
const IN_SUPER_SCRIPT = "IN_SUPER_SCRIPT";
|
|
482
|
-
// The cursor is within a subscript (e.g., the base of a custom logarithm).
|
|
483
|
-
const IN_SUB_SCRIPT = "IN_SUB_SCRIPT";
|
|
484
|
-
// The cursor is in the numerator of a fraction.
|
|
485
|
-
const IN_NUMERATOR = "IN_NUMERATOR";
|
|
486
|
-
// The cursor is in the denominator of a fraction.
|
|
487
|
-
const IN_DENOMINATOR = "IN_DENOMINATOR";
|
|
488
|
-
// The cursor is sitting before a fraction; that is, the cursor is within
|
|
489
|
-
// what looks to be a mixed number preceding a fraction. This will only be
|
|
490
|
-
// the case when the only math between the cursor and the fraction to its
|
|
491
|
-
// write is non-leaf math (numbers and variables).
|
|
492
|
-
const BEFORE_FRACTION = "BEFORE_FRACTION";
|
|
493
|
-
|
|
494
|
-
var cursorContexts = /*#__PURE__*/Object.freeze({
|
|
495
|
-
__proto__: null,
|
|
496
|
-
NONE: NONE,
|
|
497
|
-
IN_PARENS: IN_PARENS,
|
|
498
|
-
IN_SUPER_SCRIPT: IN_SUPER_SCRIPT,
|
|
499
|
-
IN_SUB_SCRIPT: IN_SUB_SCRIPT,
|
|
500
|
-
IN_NUMERATOR: IN_NUMERATOR,
|
|
501
|
-
IN_DENOMINATOR: IN_DENOMINATOR,
|
|
502
|
-
BEFORE_FRACTION: BEFORE_FRACTION
|
|
503
|
-
});
|
|
473
|
+
const decimalSeparator = getDecimalSeparator() === "," ? DecimalSeparator.COMMA : DecimalSeparator.PERIOD;
|
|
504
474
|
|
|
505
475
|
/**
|
|
506
476
|
* This file contains a wrapper around MathQuill so that we can provide a
|
|
@@ -511,110 +481,111 @@ var cursorContexts = /*#__PURE__*/Object.freeze({
|
|
|
511
481
|
// Keeping `window` in place for test suite and GitHub Pages.
|
|
512
482
|
// If it does not exist, fall back to CommonJS require. - jsatk
|
|
513
483
|
|
|
514
|
-
const decimalSymbol = decimalSeparator ===
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
484
|
+
const decimalSymbol = decimalSeparator === DecimalSeparator.COMMA ? "," : ".";
|
|
485
|
+
var ActionType = /*#__PURE__*/function (ActionType) {
|
|
486
|
+
ActionType["WRITE"] = "write";
|
|
487
|
+
ActionType["CMD"] = "cmd";
|
|
488
|
+
ActionType["KEYSTROKE"] = "keystroke";
|
|
489
|
+
ActionType[ActionType["MQ_END"] = 0] = "MQ_END";
|
|
490
|
+
return ActionType;
|
|
491
|
+
}(ActionType || {}); // A mapping from keys that can be pressed on a keypad to the way in which
|
|
521
492
|
// MathQuill should modify its input in response to that key-press. Any keys
|
|
522
493
|
// that do not provide explicit actions (like the numeral keys) will merely
|
|
523
494
|
// write their contents to MathQuill.
|
|
524
495
|
const KeyActions = {
|
|
525
496
|
[Keys.PLUS]: {
|
|
526
497
|
str: "+",
|
|
527
|
-
fn: WRITE
|
|
498
|
+
fn: ActionType.WRITE
|
|
528
499
|
},
|
|
529
500
|
[Keys.MINUS]: {
|
|
530
501
|
str: "-",
|
|
531
|
-
fn: WRITE
|
|
502
|
+
fn: ActionType.WRITE
|
|
532
503
|
},
|
|
533
504
|
[Keys.NEGATIVE]: {
|
|
534
505
|
str: "-",
|
|
535
|
-
fn: WRITE
|
|
506
|
+
fn: ActionType.WRITE
|
|
536
507
|
},
|
|
537
508
|
[Keys.TIMES]: {
|
|
538
509
|
str: "\\times",
|
|
539
|
-
fn: WRITE
|
|
510
|
+
fn: ActionType.WRITE
|
|
540
511
|
},
|
|
541
512
|
[Keys.DIVIDE]: {
|
|
542
513
|
str: "\\div",
|
|
543
|
-
fn: WRITE
|
|
514
|
+
fn: ActionType.WRITE
|
|
544
515
|
},
|
|
545
516
|
[Keys.DECIMAL]: {
|
|
546
517
|
str: decimalSymbol,
|
|
547
|
-
fn: WRITE
|
|
518
|
+
fn: ActionType.WRITE
|
|
548
519
|
},
|
|
549
520
|
[Keys.EQUAL]: {
|
|
550
521
|
str: "=",
|
|
551
|
-
fn: WRITE
|
|
522
|
+
fn: ActionType.WRITE
|
|
552
523
|
},
|
|
553
524
|
[Keys.NEQ]: {
|
|
554
525
|
str: "\\neq",
|
|
555
|
-
fn: WRITE
|
|
526
|
+
fn: ActionType.WRITE
|
|
556
527
|
},
|
|
557
528
|
[Keys.CDOT]: {
|
|
558
529
|
str: "\\cdot",
|
|
559
|
-
fn: WRITE
|
|
530
|
+
fn: ActionType.WRITE
|
|
560
531
|
},
|
|
561
532
|
[Keys.PERCENT]: {
|
|
562
533
|
str: "%",
|
|
563
|
-
fn: WRITE
|
|
534
|
+
fn: ActionType.WRITE
|
|
564
535
|
},
|
|
565
536
|
[Keys.LEFT_PAREN]: {
|
|
566
537
|
str: "(",
|
|
567
|
-
fn: CMD
|
|
538
|
+
fn: ActionType.CMD
|
|
568
539
|
},
|
|
569
540
|
[Keys.RIGHT_PAREN]: {
|
|
570
541
|
str: ")",
|
|
571
|
-
fn: CMD
|
|
542
|
+
fn: ActionType.CMD
|
|
572
543
|
},
|
|
573
544
|
[Keys.SQRT]: {
|
|
574
545
|
str: "sqrt",
|
|
575
|
-
fn: CMD
|
|
546
|
+
fn: ActionType.CMD
|
|
576
547
|
},
|
|
577
548
|
[Keys.PI]: {
|
|
578
549
|
str: "pi",
|
|
579
|
-
fn: CMD
|
|
550
|
+
fn: ActionType.CMD
|
|
580
551
|
},
|
|
581
552
|
[Keys.THETA]: {
|
|
582
553
|
str: "theta",
|
|
583
|
-
fn: CMD
|
|
554
|
+
fn: ActionType.CMD
|
|
584
555
|
},
|
|
585
556
|
[Keys.RADICAL]: {
|
|
586
557
|
str: "nthroot",
|
|
587
|
-
fn: CMD
|
|
558
|
+
fn: ActionType.CMD
|
|
588
559
|
},
|
|
589
560
|
[Keys.LT]: {
|
|
590
561
|
str: "<",
|
|
591
|
-
fn: WRITE
|
|
562
|
+
fn: ActionType.WRITE
|
|
592
563
|
},
|
|
593
564
|
[Keys.LEQ]: {
|
|
594
565
|
str: "\\leq",
|
|
595
|
-
fn: WRITE
|
|
566
|
+
fn: ActionType.WRITE
|
|
596
567
|
},
|
|
597
568
|
[Keys.GT]: {
|
|
598
569
|
str: ">",
|
|
599
|
-
fn: WRITE
|
|
570
|
+
fn: ActionType.WRITE
|
|
600
571
|
},
|
|
601
572
|
[Keys.GEQ]: {
|
|
602
573
|
str: "\\geq",
|
|
603
|
-
fn: WRITE
|
|
574
|
+
fn: ActionType.WRITE
|
|
604
575
|
},
|
|
605
576
|
[Keys.UP]: {
|
|
606
577
|
str: "Up",
|
|
607
|
-
fn: KEYSTROKE
|
|
578
|
+
fn: ActionType.KEYSTROKE
|
|
608
579
|
},
|
|
609
580
|
[Keys.DOWN]: {
|
|
610
581
|
str: "Down",
|
|
611
|
-
fn: KEYSTROKE
|
|
582
|
+
fn: ActionType.KEYSTROKE
|
|
612
583
|
},
|
|
613
584
|
// The `FRAC_EXCLUSIVE` variant is handled manually, since we may need to do
|
|
614
585
|
// some additional navigation depending on the cursor position.
|
|
615
586
|
[Keys.FRAC_INCLUSIVE]: {
|
|
616
587
|
str: "/",
|
|
617
|
-
fn: CMD
|
|
588
|
+
fn: ActionType.CMD
|
|
618
589
|
}
|
|
619
590
|
};
|
|
620
591
|
const NormalCommands = {
|
|
@@ -634,12 +605,12 @@ const Letters = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M"
|
|
|
634
605
|
// leaf nodes.
|
|
635
606
|
const ValidLeaves = [...Numerals, ...GreekLetters, ...Letters.map(letter => letter.toLowerCase()), ...Letters.map(letter => letter.toUpperCase())];
|
|
636
607
|
const KeysForJumpContext = {
|
|
637
|
-
[IN_PARENS]: Keys.JUMP_OUT_PARENTHESES,
|
|
638
|
-
[IN_SUPER_SCRIPT]: Keys.JUMP_OUT_EXPONENT,
|
|
639
|
-
[IN_SUB_SCRIPT]: Keys.JUMP_OUT_BASE,
|
|
640
|
-
[BEFORE_FRACTION]: Keys.JUMP_INTO_NUMERATOR,
|
|
641
|
-
[IN_NUMERATOR]: Keys.JUMP_OUT_NUMERATOR,
|
|
642
|
-
[IN_DENOMINATOR]: Keys.JUMP_OUT_DENOMINATOR
|
|
608
|
+
[CursorContext.IN_PARENS]: Keys.JUMP_OUT_PARENTHESES,
|
|
609
|
+
[CursorContext.IN_SUPER_SCRIPT]: Keys.JUMP_OUT_EXPONENT,
|
|
610
|
+
[CursorContext.IN_SUB_SCRIPT]: Keys.JUMP_OUT_BASE,
|
|
611
|
+
[CursorContext.BEFORE_FRACTION]: Keys.JUMP_INTO_NUMERATOR,
|
|
612
|
+
[CursorContext.IN_NUMERATOR]: Keys.JUMP_OUT_NUMERATOR,
|
|
613
|
+
[CursorContext.IN_DENOMINATOR]: Keys.JUMP_OUT_DENOMINATOR
|
|
643
614
|
};
|
|
644
615
|
class MathWrapper {
|
|
645
616
|
// MathQuill interface
|
|
@@ -702,14 +673,14 @@ class MathWrapper {
|
|
|
702
673
|
} else if (key === Keys.FRAC_EXCLUSIVE) {
|
|
703
674
|
// If there's nothing to the left of the cursor, then we want to
|
|
704
675
|
// leave the cursor to the left of the fraction after creating it.
|
|
705
|
-
const shouldNavigateLeft = cursor[this.MQ.L] === MQ_END;
|
|
676
|
+
const shouldNavigateLeft = cursor[this.MQ.L] === ActionType.MQ_END;
|
|
706
677
|
this.mathField.cmd("\\frac");
|
|
707
678
|
if (shouldNavigateLeft) {
|
|
708
679
|
this.mathField.keystroke("Left");
|
|
709
680
|
}
|
|
710
681
|
} else if (key === Keys.FRAC) {
|
|
711
682
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
712
|
-
cursor[this.MQ.L] === MQ_END;
|
|
683
|
+
cursor[this.MQ.L] === ActionType.MQ_END;
|
|
713
684
|
this.mathField.cmd("\\frac");
|
|
714
685
|
} else if (key === Keys.LOG_N) {
|
|
715
686
|
this.mathField.write("log_{ }\\left(\\right)");
|
|
@@ -730,9 +701,9 @@ class MathWrapper {
|
|
|
730
701
|
} else if (key === Keys.RIGHT) {
|
|
731
702
|
this._handleRightArrow(cursor);
|
|
732
703
|
} else if (/^[a-zA-Z]$/.test(key)) {
|
|
733
|
-
this.mathField[WRITE](key);
|
|
704
|
+
this.mathField[ActionType.WRITE](key);
|
|
734
705
|
} else if (/^NUM_\d/.test(key)) {
|
|
735
|
-
this.mathField[WRITE](key[4]);
|
|
706
|
+
this.mathField[ActionType.WRITE](key[4]);
|
|
736
707
|
}
|
|
737
708
|
if (!cursor.selection) {
|
|
738
709
|
// don't show the cursor for selections
|
|
@@ -826,7 +797,7 @@ class MathWrapper {
|
|
|
826
797
|
// when upgrading MathQuill.
|
|
827
798
|
|
|
828
799
|
_handleBackspaceInNthRoot(cursor) {
|
|
829
|
-
const isAtLeftEnd = cursor[this.MQ.L] === MQ_END;
|
|
800
|
+
const isAtLeftEnd = cursor[this.MQ.L] === ActionType.MQ_END;
|
|
830
801
|
const isRootEmpty = this._isInsideEmptyNode(cursor.parent.parent.blocks[0].ends);
|
|
831
802
|
if (isAtLeftEnd) {
|
|
832
803
|
this._selectNode(cursor.parent.parent, cursor);
|
|
@@ -857,16 +828,16 @@ class MathWrapper {
|
|
|
857
828
|
return;
|
|
858
829
|
}
|
|
859
830
|
switch (context) {
|
|
860
|
-
case IN_PARENS:
|
|
831
|
+
case CursorContext.IN_PARENS:
|
|
861
832
|
// Insert at the end of the parentheses, and then navigate right
|
|
862
833
|
// once more to get 'beyond' the parentheses.
|
|
863
834
|
cursor.insRightOf(cursor.parent.parent);
|
|
864
835
|
break;
|
|
865
|
-
case BEFORE_FRACTION:
|
|
836
|
+
case CursorContext.BEFORE_FRACTION:
|
|
866
837
|
// Find the nearest fraction to the right of the cursor.
|
|
867
838
|
let fractionNode;
|
|
868
839
|
let visitor = cursor;
|
|
869
|
-
while (visitor[this.MQ.R] !== MQ_END) {
|
|
840
|
+
while (visitor[this.MQ.R] !== ActionType.MQ_END) {
|
|
870
841
|
if (this._isFraction(visitor[this.MQ.R])) {
|
|
871
842
|
fractionNode = visitor[this.MQ.R];
|
|
872
843
|
}
|
|
@@ -877,7 +848,7 @@ class MathWrapper {
|
|
|
877
848
|
cursor.insLeftOf(fractionNode);
|
|
878
849
|
this.mathField.keystroke("Right");
|
|
879
850
|
break;
|
|
880
|
-
case IN_NUMERATOR:
|
|
851
|
+
case CursorContext.IN_NUMERATOR:
|
|
881
852
|
// HACK(charlie): I can't find a better way to do this. The goal
|
|
882
853
|
// is to place the cursor at the start of the matching
|
|
883
854
|
// denominator. So, we identify the appropriate node, and
|
|
@@ -889,10 +860,10 @@ class MathWrapper {
|
|
|
889
860
|
this.mathField.keystroke("Right");
|
|
890
861
|
}
|
|
891
862
|
break;
|
|
892
|
-
case IN_DENOMINATOR:
|
|
863
|
+
case CursorContext.IN_DENOMINATOR:
|
|
893
864
|
cursor.insRightOf(cursor.parent.parent);
|
|
894
865
|
break;
|
|
895
|
-
case IN_SUB_SCRIPT:
|
|
866
|
+
case CursorContext.IN_SUB_SCRIPT:
|
|
896
867
|
// Insert just beyond the superscript.
|
|
897
868
|
cursor.insRightOf(cursor.parent.parent);
|
|
898
869
|
|
|
@@ -903,7 +874,7 @@ class MathWrapper {
|
|
|
903
874
|
this.mathField.keystroke("Right");
|
|
904
875
|
}
|
|
905
876
|
break;
|
|
906
|
-
case IN_SUPER_SCRIPT:
|
|
877
|
+
case CursorContext.IN_SUPER_SCRIPT:
|
|
907
878
|
// Insert just beyond the superscript.
|
|
908
879
|
cursor.insRightOf(cursor.parent.parent);
|
|
909
880
|
break;
|
|
@@ -940,7 +911,7 @@ class MathWrapper {
|
|
|
940
911
|
this._handleBackspaceInLogIndex(cursor);
|
|
941
912
|
} else if (leftNode.ctrlSeq === "\\ge " || leftNode.ctrlSeq === "\\le ") {
|
|
942
913
|
this._handleBackspaceAfterLigaturedSymbol(cursor);
|
|
943
|
-
} else if (this._isNthRoot(grandparent) && leftNode === MQ_END) {
|
|
914
|
+
} else if (this._isNthRoot(grandparent) && leftNode === ActionType.MQ_END) {
|
|
944
915
|
this._handleBackspaceInNthRoot(cursor);
|
|
945
916
|
} else {
|
|
946
917
|
this.mathField.keystroke("Backspace");
|
|
@@ -957,10 +928,10 @@ class MathWrapper {
|
|
|
957
928
|
// the entire expression, rather than between the `s` and the left
|
|
958
929
|
// parenthesis.
|
|
959
930
|
// From the cursor's perspective, this requires that our left node is
|
|
960
|
-
// the MQ_END node, that our grandparent is the left parenthesis, and
|
|
931
|
+
// the ActionType.MQ_END node, that our grandparent is the left parenthesis, and
|
|
961
932
|
// the nodes to the left of our grandparent comprise a valid function
|
|
962
933
|
// name.
|
|
963
|
-
if (cursor[this.MQ.L] === MQ_END) {
|
|
934
|
+
if (cursor[this.MQ.L] === ActionType.MQ_END) {
|
|
964
935
|
const parent = cursor.parent;
|
|
965
936
|
const grandparent = parent.parent;
|
|
966
937
|
if (grandparent.ctrlSeq === "\\left(") {
|
|
@@ -995,7 +966,7 @@ class MathWrapper {
|
|
|
995
966
|
// parentheses and apply the exponent to that.
|
|
996
967
|
const invalidPrefixes = [...ArithmeticOperators, ...EqualityOperators];
|
|
997
968
|
const precedingNode = cursor[this.MQ.L];
|
|
998
|
-
const shouldPrefixWithParens = precedingNode === MQ_END || invalidPrefixes.includes(precedingNode.ctrlSeq.trim());
|
|
969
|
+
const shouldPrefixWithParens = precedingNode === ActionType.MQ_END || invalidPrefixes.includes(precedingNode.ctrlSeq.trim());
|
|
999
970
|
if (shouldPrefixWithParens) {
|
|
1000
971
|
this.mathField.write("\\left(\\right)");
|
|
1001
972
|
}
|
|
@@ -1180,7 +1151,7 @@ class MathWrapper {
|
|
|
1180
1151
|
return false;
|
|
1181
1152
|
}
|
|
1182
1153
|
_isInsideEmptyNode(cursor) {
|
|
1183
|
-
return cursor[this.MQ.L] === MQ_END && cursor[this.MQ.R] === MQ_END;
|
|
1154
|
+
return cursor[this.MQ.L] === ActionType.MQ_END && cursor[this.MQ.R] === ActionType.MQ_END;
|
|
1184
1155
|
}
|
|
1185
1156
|
_handleBackspaceInRootIndex(cursor) {
|
|
1186
1157
|
if (this._isInsideEmptyNode(cursor)) {
|
|
@@ -1208,14 +1179,14 @@ class MathWrapper {
|
|
|
1208
1179
|
this.mathField.write(latex.replace(/^\\sqrt\[\]/, "\\sqrt"));
|
|
1209
1180
|
|
|
1210
1181
|
// Adjust the cursor to be to the left the sqrt.
|
|
1211
|
-
if (reinsertionPoint === MQ_END) {
|
|
1182
|
+
if (reinsertionPoint === ActionType.MQ_END) {
|
|
1212
1183
|
this.mathField.moveToDirEnd(this.MQ.L);
|
|
1213
1184
|
} else {
|
|
1214
1185
|
cursor.insRightOf(reinsertionPoint);
|
|
1215
1186
|
}
|
|
1216
1187
|
}
|
|
1217
1188
|
} else {
|
|
1218
|
-
if (cursor[this.MQ.L] !== MQ_END) {
|
|
1189
|
+
if (cursor[this.MQ.L] !== ActionType.MQ_END) {
|
|
1219
1190
|
// If the cursor is not at the leftmost position inside the
|
|
1220
1191
|
// root's index, delete a character.
|
|
1221
1192
|
this.mathField.keystroke("Backspace");
|
|
@@ -1228,7 +1199,7 @@ class MathWrapper {
|
|
|
1228
1199
|
const command = this._maybeFindCommandBeforeParens(grandparent);
|
|
1229
1200
|
cursor.insLeftOf(command == null ? void 0 : command.startNode);
|
|
1230
1201
|
cursor.startSelection();
|
|
1231
|
-
if (grandparent[this.MQ.R] !== MQ_END) {
|
|
1202
|
+
if (grandparent[this.MQ.R] !== ActionType.MQ_END) {
|
|
1232
1203
|
cursor.insRightOf(grandparent[this.MQ.R]);
|
|
1233
1204
|
} else {
|
|
1234
1205
|
cursor.insRightOf(grandparent);
|
|
@@ -1262,7 +1233,7 @@ class MathWrapper {
|
|
|
1262
1233
|
// the parens.
|
|
1263
1234
|
cursor.insLeftOf(command.startNode);
|
|
1264
1235
|
cursor.startSelection();
|
|
1265
|
-
if (rightNode === MQ_END) {
|
|
1236
|
+
if (rightNode === ActionType.MQ_END) {
|
|
1266
1237
|
cursor.insAtRightEnd(cursor.parent);
|
|
1267
1238
|
} else {
|
|
1268
1239
|
cursor.insLeftOf(rightNode);
|
|
@@ -1301,7 +1272,7 @@ class MathWrapper {
|
|
|
1301
1272
|
// - \log(|x+1) => |\log(x+1)|
|
|
1302
1273
|
// - \log(|) => |
|
|
1303
1274
|
|
|
1304
|
-
if (cursor[this.MQ.L] !== MQ_END) {
|
|
1275
|
+
if (cursor[this.MQ.L] !== ActionType.MQ_END) {
|
|
1305
1276
|
// This command contains math and there's some math to
|
|
1306
1277
|
// the left of the cursor that we should delete normally
|
|
1307
1278
|
// before doing anything special.
|
|
@@ -1350,9 +1321,9 @@ class MathWrapper {
|
|
|
1350
1321
|
contextForCursor(cursor) {
|
|
1351
1322
|
// First, try to find any fraction to the right, unimpeded.
|
|
1352
1323
|
let visitor = cursor;
|
|
1353
|
-
while (visitor[this.MQ.R] !== MQ_END) {
|
|
1324
|
+
while (visitor[this.MQ.R] !== ActionType.MQ_END) {
|
|
1354
1325
|
if (this._isFraction(visitor[this.MQ.R])) {
|
|
1355
|
-
return BEFORE_FRACTION;
|
|
1326
|
+
return CursorContext.BEFORE_FRACTION;
|
|
1356
1327
|
} else if (!this._isLeaf(visitor[this.MQ.R])) {
|
|
1357
1328
|
break;
|
|
1358
1329
|
}
|
|
@@ -1362,17 +1333,17 @@ class MathWrapper {
|
|
|
1362
1333
|
// If that didn't work, check if the parent or grandparent is a special
|
|
1363
1334
|
// context, so that we can jump outwards.
|
|
1364
1335
|
if (this._isParens(cursor.parent && cursor.parent.parent)) {
|
|
1365
|
-
return IN_PARENS;
|
|
1336
|
+
return CursorContext.IN_PARENS;
|
|
1366
1337
|
} else if (this._isNumerator(cursor.parent)) {
|
|
1367
|
-
return IN_NUMERATOR;
|
|
1338
|
+
return CursorContext.IN_NUMERATOR;
|
|
1368
1339
|
} else if (this._isDenominator(cursor.parent)) {
|
|
1369
|
-
return IN_DENOMINATOR;
|
|
1340
|
+
return CursorContext.IN_DENOMINATOR;
|
|
1370
1341
|
} else if (this._isSubScript(cursor.parent)) {
|
|
1371
|
-
return IN_SUB_SCRIPT;
|
|
1342
|
+
return CursorContext.IN_SUB_SCRIPT;
|
|
1372
1343
|
} else if (this._isSuperScript(cursor.parent)) {
|
|
1373
|
-
return IN_SUPER_SCRIPT;
|
|
1344
|
+
return CursorContext.IN_SUPER_SCRIPT;
|
|
1374
1345
|
} else {
|
|
1375
|
-
return NONE;
|
|
1346
|
+
return CursorContext.NONE;
|
|
1376
1347
|
}
|
|
1377
1348
|
}
|
|
1378
1349
|
_isAtTopLevel(cursor) {
|
|
@@ -3010,231 +2981,231 @@ class GestureManager {
|
|
|
3010
2981
|
const KeyConfigs = {
|
|
3011
2982
|
// Basic math keys.
|
|
3012
2983
|
[Keys.PLUS]: {
|
|
3013
|
-
type:
|
|
2984
|
+
type: KeyType.OPERATOR,
|
|
3014
2985
|
// I18N: A label for a plus sign.
|
|
3015
2986
|
ariaLabel: i18n._("Plus")
|
|
3016
2987
|
},
|
|
3017
2988
|
[Keys.MINUS]: {
|
|
3018
|
-
type:
|
|
2989
|
+
type: KeyType.OPERATOR,
|
|
3019
2990
|
// I18N: A label for a minus sign.
|
|
3020
2991
|
ariaLabel: i18n._("Minus")
|
|
3021
2992
|
},
|
|
3022
2993
|
[Keys.NEGATIVE]: {
|
|
3023
|
-
type:
|
|
2994
|
+
type: KeyType.VALUE,
|
|
3024
2995
|
// I18N: A label for a minus sign.
|
|
3025
2996
|
ariaLabel: i18n._("Negative")
|
|
3026
2997
|
},
|
|
3027
2998
|
[Keys.TIMES]: {
|
|
3028
|
-
type:
|
|
2999
|
+
type: KeyType.OPERATOR,
|
|
3029
3000
|
// I18N: A label for a multiplication sign (represented with an 'x').
|
|
3030
3001
|
ariaLabel: i18n._("Multiply")
|
|
3031
3002
|
},
|
|
3032
3003
|
[Keys.DIVIDE]: {
|
|
3033
|
-
type:
|
|
3004
|
+
type: KeyType.OPERATOR,
|
|
3034
3005
|
// I18N: A label for a division sign.
|
|
3035
3006
|
ariaLabel: i18n._("Divide")
|
|
3036
3007
|
},
|
|
3037
3008
|
[Keys.DECIMAL]: {
|
|
3038
|
-
type:
|
|
3009
|
+
type: KeyType.VALUE,
|
|
3039
3010
|
// I18N: A label for a decimal symbol.
|
|
3040
3011
|
ariaLabel: i18n._("Decimal"),
|
|
3041
|
-
icon: decimalSeparator ===
|
|
3012
|
+
icon: decimalSeparator === DecimalSeparator.COMMA ? {
|
|
3042
3013
|
// TODO(charlie): Get an SVG icon for the comma, or verify with
|
|
3043
3014
|
// design that the text-rendered version is acceptable.
|
|
3044
|
-
type:
|
|
3015
|
+
type: IconType.TEXT,
|
|
3045
3016
|
data: ","
|
|
3046
3017
|
} : {
|
|
3047
|
-
type:
|
|
3018
|
+
type: IconType.SVG,
|
|
3048
3019
|
data: Keys.PERIOD
|
|
3049
3020
|
}
|
|
3050
3021
|
},
|
|
3051
3022
|
[Keys.PERCENT]: {
|
|
3052
|
-
type:
|
|
3023
|
+
type: KeyType.OPERATOR,
|
|
3053
3024
|
// I18N: A label for a percent sign.
|
|
3054
3025
|
ariaLabel: i18n._("Percent")
|
|
3055
3026
|
},
|
|
3056
3027
|
[Keys.CDOT]: {
|
|
3057
|
-
type:
|
|
3028
|
+
type: KeyType.OPERATOR,
|
|
3058
3029
|
// I18N: A label for a multiplication sign (represented as a dot).
|
|
3059
3030
|
ariaLabel: i18n._("Multiply")
|
|
3060
3031
|
},
|
|
3061
3032
|
[Keys.EQUAL]: {
|
|
3062
|
-
type:
|
|
3033
|
+
type: KeyType.OPERATOR,
|
|
3063
3034
|
ariaLabel: i18n._("Equals sign")
|
|
3064
3035
|
},
|
|
3065
3036
|
[Keys.NEQ]: {
|
|
3066
|
-
type:
|
|
3037
|
+
type: KeyType.OPERATOR,
|
|
3067
3038
|
ariaLabel: i18n._("Not-equals sign")
|
|
3068
3039
|
},
|
|
3069
3040
|
[Keys.GT]: {
|
|
3070
|
-
type:
|
|
3041
|
+
type: KeyType.OPERATOR,
|
|
3071
3042
|
// I18N: A label for a 'greater than' sign (represented as '>').
|
|
3072
3043
|
ariaLabel: i18n._("Greater than sign")
|
|
3073
3044
|
},
|
|
3074
3045
|
[Keys.LT]: {
|
|
3075
|
-
type:
|
|
3046
|
+
type: KeyType.OPERATOR,
|
|
3076
3047
|
// I18N: A label for a 'less than' sign (represented as '<').
|
|
3077
3048
|
ariaLabel: i18n._("Less than sign")
|
|
3078
3049
|
},
|
|
3079
3050
|
[Keys.GEQ]: {
|
|
3080
|
-
type:
|
|
3051
|
+
type: KeyType.OPERATOR,
|
|
3081
3052
|
ariaLabel: i18n._("Greater than or equal to sign")
|
|
3082
3053
|
},
|
|
3083
3054
|
[Keys.LEQ]: {
|
|
3084
|
-
type:
|
|
3055
|
+
type: KeyType.OPERATOR,
|
|
3085
3056
|
ariaLabel: i18n._("Less than or equal to sign")
|
|
3086
3057
|
},
|
|
3087
3058
|
// mobile native
|
|
3088
3059
|
[Keys.FRAC_INCLUSIVE]: {
|
|
3089
|
-
type:
|
|
3060
|
+
type: KeyType.OPERATOR,
|
|
3090
3061
|
// I18N: A label for a button that creates a new fraction and puts the
|
|
3091
3062
|
// current expression in the numerator of that fraction.
|
|
3092
3063
|
ariaLabel: i18n._("Fraction, with current expression in numerator")
|
|
3093
3064
|
},
|
|
3094
3065
|
// mobile native
|
|
3095
3066
|
[Keys.FRAC_EXCLUSIVE]: {
|
|
3096
|
-
type:
|
|
3067
|
+
type: KeyType.OPERATOR,
|
|
3097
3068
|
// I18N: A label for a button that creates a new fraction next to the
|
|
3098
3069
|
// cursor.
|
|
3099
3070
|
ariaLabel: i18n._("Fraction, excluding the current expression")
|
|
3100
3071
|
},
|
|
3101
3072
|
// mobile web
|
|
3102
3073
|
[Keys.FRAC]: {
|
|
3103
|
-
type:
|
|
3074
|
+
type: KeyType.OPERATOR,
|
|
3104
3075
|
// I18N: A label for a button that creates a new fraction next to the
|
|
3105
3076
|
// cursor.
|
|
3106
3077
|
ariaLabel: i18n._("Fraction, excluding the current expression")
|
|
3107
3078
|
},
|
|
3108
3079
|
[Keys.EXP]: {
|
|
3109
|
-
type:
|
|
3080
|
+
type: KeyType.OPERATOR,
|
|
3110
3081
|
// I18N: A label for a button that will allow the user to input a custom
|
|
3111
3082
|
// exponent.
|
|
3112
3083
|
ariaLabel: i18n._("Custom exponent")
|
|
3113
3084
|
},
|
|
3114
3085
|
[Keys.EXP_2]: {
|
|
3115
|
-
type:
|
|
3086
|
+
type: KeyType.OPERATOR,
|
|
3116
3087
|
// I18N: A label for a button that will square (take to the second
|
|
3117
3088
|
// power) some math.
|
|
3118
3089
|
ariaLabel: i18n._("Square")
|
|
3119
3090
|
},
|
|
3120
3091
|
[Keys.EXP_3]: {
|
|
3121
|
-
type:
|
|
3092
|
+
type: KeyType.OPERATOR,
|
|
3122
3093
|
// I18N: A label for a button that will cube (take to the third power)
|
|
3123
3094
|
// some math.
|
|
3124
3095
|
ariaLabel: i18n._("Cube")
|
|
3125
3096
|
},
|
|
3126
3097
|
[Keys.SQRT]: {
|
|
3127
|
-
type:
|
|
3098
|
+
type: KeyType.OPERATOR,
|
|
3128
3099
|
ariaLabel: i18n._("Square root")
|
|
3129
3100
|
},
|
|
3130
3101
|
[Keys.CUBE_ROOT]: {
|
|
3131
|
-
type:
|
|
3102
|
+
type: KeyType.OPERATOR,
|
|
3132
3103
|
ariaLabel: i18n._("Cube root")
|
|
3133
3104
|
},
|
|
3134
3105
|
[Keys.RADICAL]: {
|
|
3135
|
-
type:
|
|
3106
|
+
type: KeyType.OPERATOR,
|
|
3136
3107
|
ariaLabel: i18n._("Radical with custom root")
|
|
3137
3108
|
},
|
|
3138
3109
|
[Keys.LEFT_PAREN]: {
|
|
3139
|
-
type:
|
|
3110
|
+
type: KeyType.OPERATOR,
|
|
3140
3111
|
ariaLabel: i18n._("Left parenthesis")
|
|
3141
3112
|
},
|
|
3142
3113
|
[Keys.RIGHT_PAREN]: {
|
|
3143
|
-
type:
|
|
3114
|
+
type: KeyType.OPERATOR,
|
|
3144
3115
|
ariaLabel: i18n._("Right parenthesis")
|
|
3145
3116
|
},
|
|
3146
3117
|
[Keys.LN]: {
|
|
3147
|
-
type:
|
|
3118
|
+
type: KeyType.OPERATOR,
|
|
3148
3119
|
ariaLabel: i18n._("Natural logarithm")
|
|
3149
3120
|
},
|
|
3150
3121
|
[Keys.LOG]: {
|
|
3151
|
-
type:
|
|
3122
|
+
type: KeyType.OPERATOR,
|
|
3152
3123
|
ariaLabel: i18n._("Logarithm with base 10")
|
|
3153
3124
|
},
|
|
3154
3125
|
[Keys.LOG_N]: {
|
|
3155
|
-
type:
|
|
3126
|
+
type: KeyType.OPERATOR,
|
|
3156
3127
|
ariaLabel: i18n._("Logarithm with custom base")
|
|
3157
3128
|
},
|
|
3158
3129
|
[Keys.SIN]: {
|
|
3159
|
-
type:
|
|
3130
|
+
type: KeyType.OPERATOR,
|
|
3160
3131
|
ariaLabel: i18n._("Sine")
|
|
3161
3132
|
},
|
|
3162
3133
|
[Keys.COS]: {
|
|
3163
|
-
type:
|
|
3134
|
+
type: KeyType.OPERATOR,
|
|
3164
3135
|
ariaLabel: i18n._("Cosine")
|
|
3165
3136
|
},
|
|
3166
3137
|
[Keys.TAN]: {
|
|
3167
|
-
type:
|
|
3138
|
+
type: KeyType.OPERATOR,
|
|
3168
3139
|
ariaLabel: i18n._("Tangent")
|
|
3169
3140
|
},
|
|
3170
3141
|
[Keys.PI]: {
|
|
3171
|
-
type:
|
|
3142
|
+
type: KeyType.VALUE,
|
|
3172
3143
|
ariaLabel: i18n._("Pi"),
|
|
3173
3144
|
icon: {
|
|
3174
|
-
type:
|
|
3145
|
+
type: IconType.MATH,
|
|
3175
3146
|
data: "\\pi"
|
|
3176
3147
|
}
|
|
3177
3148
|
},
|
|
3178
3149
|
[Keys.THETA]: {
|
|
3179
|
-
type:
|
|
3150
|
+
type: KeyType.VALUE,
|
|
3180
3151
|
ariaLabel: i18n._("Theta"),
|
|
3181
3152
|
icon: {
|
|
3182
|
-
type:
|
|
3153
|
+
type: IconType.MATH,
|
|
3183
3154
|
data: "\\theta"
|
|
3184
3155
|
}
|
|
3185
3156
|
},
|
|
3186
3157
|
[Keys.NOOP]: {
|
|
3187
|
-
type:
|
|
3158
|
+
type: KeyType.EMPTY
|
|
3188
3159
|
},
|
|
3189
3160
|
// Input navigation keys.
|
|
3190
3161
|
[Keys.UP]: {
|
|
3191
|
-
type:
|
|
3162
|
+
type: KeyType.INPUT_NAVIGATION,
|
|
3192
3163
|
ariaLabel: i18n._("Up arrow")
|
|
3193
3164
|
},
|
|
3194
3165
|
[Keys.RIGHT]: {
|
|
3195
|
-
type:
|
|
3166
|
+
type: KeyType.INPUT_NAVIGATION,
|
|
3196
3167
|
ariaLabel: i18n._("Right arrow")
|
|
3197
3168
|
},
|
|
3198
3169
|
[Keys.DOWN]: {
|
|
3199
|
-
type:
|
|
3170
|
+
type: KeyType.INPUT_NAVIGATION,
|
|
3200
3171
|
ariaLabel: i18n._("Down arrow")
|
|
3201
3172
|
},
|
|
3202
3173
|
[Keys.LEFT]: {
|
|
3203
|
-
type:
|
|
3174
|
+
type: KeyType.INPUT_NAVIGATION,
|
|
3204
3175
|
ariaLabel: i18n._("Left arrow")
|
|
3205
3176
|
},
|
|
3206
3177
|
[Keys.JUMP_OUT_PARENTHESES]: {
|
|
3207
|
-
type:
|
|
3178
|
+
type: KeyType.INPUT_NAVIGATION,
|
|
3208
3179
|
ariaLabel: i18n._("Navigate right out of a set of parentheses")
|
|
3209
3180
|
},
|
|
3210
3181
|
[Keys.JUMP_OUT_EXPONENT]: {
|
|
3211
|
-
type:
|
|
3182
|
+
type: KeyType.INPUT_NAVIGATION,
|
|
3212
3183
|
ariaLabel: i18n._("Navigate right out of an exponent")
|
|
3213
3184
|
},
|
|
3214
3185
|
[Keys.JUMP_OUT_BASE]: {
|
|
3215
|
-
type:
|
|
3186
|
+
type: KeyType.INPUT_NAVIGATION,
|
|
3216
3187
|
ariaLabel: i18n._("Navigate right out of a base")
|
|
3217
3188
|
},
|
|
3218
3189
|
[Keys.JUMP_INTO_NUMERATOR]: {
|
|
3219
|
-
type:
|
|
3190
|
+
type: KeyType.INPUT_NAVIGATION,
|
|
3220
3191
|
ariaLabel: i18n._("Navigate right into the numerator of a fraction")
|
|
3221
3192
|
},
|
|
3222
3193
|
[Keys.JUMP_OUT_NUMERATOR]: {
|
|
3223
|
-
type:
|
|
3194
|
+
type: KeyType.INPUT_NAVIGATION,
|
|
3224
3195
|
ariaLabel: i18n._("Navigate right out of the numerator and into the denominator")
|
|
3225
3196
|
},
|
|
3226
3197
|
[Keys.JUMP_OUT_DENOMINATOR]: {
|
|
3227
|
-
type:
|
|
3198
|
+
type: KeyType.INPUT_NAVIGATION,
|
|
3228
3199
|
ariaLabel: i18n._("Navigate right out of the denominator of a fraction")
|
|
3229
3200
|
},
|
|
3230
3201
|
[Keys.BACKSPACE]: {
|
|
3231
|
-
type:
|
|
3202
|
+
type: KeyType.INPUT_NAVIGATION,
|
|
3232
3203
|
// I18N: A label for a button that will delete some input.
|
|
3233
3204
|
ariaLabel: i18n._("Delete")
|
|
3234
3205
|
},
|
|
3235
3206
|
// Keypad navigation keys.
|
|
3236
3207
|
[Keys.DISMISS]: {
|
|
3237
|
-
type:
|
|
3208
|
+
type: KeyType.KEYPAD_NAVIGATION,
|
|
3238
3209
|
// I18N: A label for a button that will dismiss/hide a keypad.
|
|
3239
3210
|
ariaLabel: i18n._("Dismiss")
|
|
3240
3211
|
}
|
|
@@ -3252,7 +3223,7 @@ KeyConfigs[Keys.FRAC_MULTI] = {
|
|
|
3252
3223
|
|
|
3253
3224
|
// TODO(charlie): Use the numeral color for the 'Many' key.
|
|
3254
3225
|
KeyConfigs[Keys.MANY] = {
|
|
3255
|
-
type:
|
|
3226
|
+
type: KeyType.MANY
|
|
3256
3227
|
// childKeyIds will be configured by the client.
|
|
3257
3228
|
};
|
|
3258
3229
|
|
|
@@ -3264,10 +3235,10 @@ for (const num of NUMBERS) {
|
|
|
3264
3235
|
// would mean that we'd be using text beyond the variable key).
|
|
3265
3236
|
const textRepresentation = `${num}`;
|
|
3266
3237
|
KeyConfigs[`NUM_${num}`] = {
|
|
3267
|
-
type:
|
|
3238
|
+
type: KeyType.VALUE,
|
|
3268
3239
|
ariaLabel: textRepresentation,
|
|
3269
3240
|
icon: {
|
|
3270
|
-
type:
|
|
3241
|
+
type: IconType.TEXT,
|
|
3271
3242
|
data: textRepresentation
|
|
3272
3243
|
}
|
|
3273
3244
|
};
|
|
@@ -3280,10 +3251,10 @@ for (const letter of LETTERS) {
|
|
|
3280
3251
|
const upperCaseVariable = letter.toUpperCase();
|
|
3281
3252
|
for (const textRepresentation of [lowerCaseVariable, upperCaseVariable]) {
|
|
3282
3253
|
KeyConfigs[textRepresentation] = {
|
|
3283
|
-
type:
|
|
3254
|
+
type: KeyType.VALUE,
|
|
3284
3255
|
ariaLabel: textRepresentation,
|
|
3285
3256
|
icon: {
|
|
3286
|
-
type:
|
|
3257
|
+
type: IconType.MATH,
|
|
3287
3258
|
data: textRepresentation
|
|
3288
3259
|
}
|
|
3289
3260
|
};
|
|
@@ -3294,7 +3265,7 @@ for (const key of Object.keys(KeyConfigs)) {
|
|
|
3294
3265
|
id: key,
|
|
3295
3266
|
// Default to an SVG icon indexed by the key name.
|
|
3296
3267
|
icon: {
|
|
3297
|
-
type:
|
|
3268
|
+
type: IconType.SVG,
|
|
3298
3269
|
data: key
|
|
3299
3270
|
}
|
|
3300
3271
|
}, KeyConfigs[key]);
|
|
@@ -3313,11 +3284,11 @@ const echoReducer = function echoReducer(state = initialEchoState, action) {
|
|
|
3313
3284
|
|
|
3314
3285
|
// Add in the echo animation if the user performs a math
|
|
3315
3286
|
// operation.
|
|
3316
|
-
if (keyConfig.type ===
|
|
3287
|
+
if (keyConfig.type === KeyType.VALUE || keyConfig.type === KeyType.OPERATOR) {
|
|
3317
3288
|
return _extends({}, state, {
|
|
3318
3289
|
echoes: [...state.echoes, {
|
|
3319
3290
|
animationId: "" + _lastAnimationId++,
|
|
3320
|
-
animationType: action.inPopover ?
|
|
3291
|
+
animationType: action.inPopover ? EchoAnimationType.LONG_FADE_ONLY : EchoAnimationType.FADE_ONLY,
|
|
3321
3292
|
borders: action.borders,
|
|
3322
3293
|
id: keyConfig.id,
|
|
3323
3294
|
initialBounds: action.initialBounds
|
|
@@ -3340,7 +3311,7 @@ const echoReducer = function echoReducer(state = initialEchoState, action) {
|
|
|
3340
3311
|
const initialInputState = {
|
|
3341
3312
|
keyHandler: null,
|
|
3342
3313
|
cursor: {
|
|
3343
|
-
context: NONE
|
|
3314
|
+
context: CursorContext.NONE
|
|
3344
3315
|
}
|
|
3345
3316
|
};
|
|
3346
3317
|
const inputReducer = function inputReducer(state = initialInputState, action) {
|
|
@@ -3351,7 +3322,7 @@ const inputReducer = function inputReducer(state = initialInputState, action) {
|
|
|
3351
3322
|
});
|
|
3352
3323
|
case "PressKey":
|
|
3353
3324
|
const keyConfig = KeyConfigs[action.key];
|
|
3354
|
-
if (keyConfig.type !==
|
|
3325
|
+
if (keyConfig.type !== KeyType.KEYPAD_NAVIGATION) {
|
|
3355
3326
|
// This is probably an anti-pattern but it works for the
|
|
3356
3327
|
// case where we don't actually control the state but we
|
|
3357
3328
|
// still want to communicate with the other object
|
|
@@ -4722,48 +4693,48 @@ const JumpOutDenominator = () => {
|
|
|
4722
4693
|
*/
|
|
4723
4694
|
|
|
4724
4695
|
var Iconography = /*#__PURE__*/Object.freeze({
|
|
4725
|
-
|
|
4726
|
-
|
|
4727
|
-
|
|
4728
|
-
|
|
4729
|
-
|
|
4730
|
-
|
|
4731
|
-
|
|
4732
|
-
|
|
4733
|
-
|
|
4734
|
-
|
|
4735
|
-
|
|
4736
|
-
|
|
4737
|
-
|
|
4738
|
-
|
|
4739
|
-
|
|
4740
|
-
|
|
4741
|
-
|
|
4742
|
-
|
|
4743
|
-
|
|
4744
|
-
|
|
4745
|
-
|
|
4746
|
-
|
|
4747
|
-
|
|
4748
|
-
|
|
4749
|
-
|
|
4750
|
-
|
|
4751
|
-
|
|
4752
|
-
|
|
4753
|
-
|
|
4754
|
-
|
|
4755
|
-
|
|
4756
|
-
|
|
4757
|
-
|
|
4758
|
-
|
|
4759
|
-
|
|
4760
|
-
|
|
4761
|
-
|
|
4762
|
-
|
|
4763
|
-
|
|
4764
|
-
|
|
4765
|
-
|
|
4766
|
-
|
|
4696
|
+
__proto__: null,
|
|
4697
|
+
COS: Cos,
|
|
4698
|
+
LOG: Log,
|
|
4699
|
+
EQUAL: Equal,
|
|
4700
|
+
BACKSPACE: Backspace,
|
|
4701
|
+
SQRT: Sqrt,
|
|
4702
|
+
EXP: Exp,
|
|
4703
|
+
NEQ: Neq,
|
|
4704
|
+
GEQ: Geq,
|
|
4705
|
+
LN: Ln,
|
|
4706
|
+
DISMISS: Dismiss,
|
|
4707
|
+
SIN: Sin,
|
|
4708
|
+
LT: Lt,
|
|
4709
|
+
CUBE_ROOT: CubeRoot,
|
|
4710
|
+
PLUS: Plus,
|
|
4711
|
+
TAN: Tan,
|
|
4712
|
+
LEFT: Left,
|
|
4713
|
+
UP: Up,
|
|
4714
|
+
DOWN: Down,
|
|
4715
|
+
LEFT_PAREN: LeftParen,
|
|
4716
|
+
RIGHT_PAREN: RightParen,
|
|
4717
|
+
GT: Gt,
|
|
4718
|
+
DIVIDE: Divide,
|
|
4719
|
+
PERIOD: Period,
|
|
4720
|
+
PERCENT: Percent,
|
|
4721
|
+
TIMES: Times,
|
|
4722
|
+
EXP_3: Exp3,
|
|
4723
|
+
EXP_2: Exp2,
|
|
4724
|
+
RIGHT: Right,
|
|
4725
|
+
CDOT: Cdot,
|
|
4726
|
+
LOG_N: LogN,
|
|
4727
|
+
LEQ: Leq,
|
|
4728
|
+
MINUS: Minus,
|
|
4729
|
+
NEGATIVE: Minus,
|
|
4730
|
+
RADICAL: Radical,
|
|
4731
|
+
FRAC: FracInclusive,
|
|
4732
|
+
JUMP_OUT_PARENTHESES: JumpOutParentheses,
|
|
4733
|
+
JUMP_OUT_EXPONENT: JumpOutExponent,
|
|
4734
|
+
JUMP_OUT_BASE: JumpOutBase,
|
|
4735
|
+
JUMP_INTO_NUMERATOR: JumpIntoNumerator,
|
|
4736
|
+
JUMP_OUT_NUMERATOR: JumpOutNumerator,
|
|
4737
|
+
JUMP_OUT_DENOMINATOR: JumpOutDenominator
|
|
4767
4738
|
});
|
|
4768
4739
|
|
|
4769
4740
|
/**
|
|
@@ -4828,12 +4799,12 @@ class Icon extends React.PureComponent {
|
|
|
4828
4799
|
} = this.props;
|
|
4829
4800
|
const styleWithFocus = [focused ? styles$a.focused : styles$a.unfocused, ...(Array.isArray(style) ? style : [style])];
|
|
4830
4801
|
switch (icon.type) {
|
|
4831
|
-
case
|
|
4802
|
+
case IconType.MATH:
|
|
4832
4803
|
return /*#__PURE__*/React.createElement(MathIcon, {
|
|
4833
4804
|
math: icon.data,
|
|
4834
4805
|
style: styleWithFocus
|
|
4835
4806
|
});
|
|
4836
|
-
case
|
|
4807
|
+
case IconType.SVG:
|
|
4837
4808
|
// TODO(charlie): Support passing style objects to `SvgIcon`.
|
|
4838
4809
|
// This will require migrating the individual icons to use
|
|
4839
4810
|
// `currentColor` and accept a `className` prop, rather than
|
|
@@ -4842,7 +4813,7 @@ class Icon extends React.PureComponent {
|
|
|
4842
4813
|
name: icon.data,
|
|
4843
4814
|
color: focused ? focusedColor : unfocusedColor
|
|
4844
4815
|
});
|
|
4845
|
-
case
|
|
4816
|
+
case IconType.TEXT:
|
|
4846
4817
|
return /*#__PURE__*/React.createElement(TextIcon, {
|
|
4847
4818
|
character: icon.data,
|
|
4848
4819
|
style: styleWithFocus
|
|
@@ -4884,7 +4855,7 @@ class MultiSymbolGrid extends React.Component {
|
|
|
4884
4855
|
// Supporting other types of icons is possible but would require
|
|
4885
4856
|
// some styles coercion and doesn't seem worthwhile right now.
|
|
4886
4857
|
icons.forEach(icon => {
|
|
4887
|
-
if (icon.type !==
|
|
4858
|
+
if (icon.type !== IconType.MATH) {
|
|
4888
4859
|
throw new Error(`Received invalid icon: type=${icon.type}, ` + `data=${icon.data}`);
|
|
4889
4860
|
}
|
|
4890
4861
|
});
|
|
@@ -5002,7 +4973,7 @@ class KeypadButton extends React.PureComponent {
|
|
|
5002
4973
|
// object. This method must be called whenever a property that
|
|
5003
4974
|
// influences the possible outcomes of `this._getFocusStyle` and
|
|
5004
4975
|
// `this._getButtonStyle` changes (such as `this.buttonSizeStyle`).
|
|
5005
|
-
for (const type of Object.
|
|
4976
|
+
for (const type of Object.values(KeyType)) {
|
|
5006
4977
|
css(View.styles.initial, ...this._getFocusStyle(type));
|
|
5007
4978
|
for (const borders of Object.values(BorderStyles)) {
|
|
5008
4979
|
css(View.styles.initial, ...this._getButtonStyle(type, borders));
|
|
@@ -5011,7 +4982,7 @@ class KeypadButton extends React.PureComponent {
|
|
|
5011
4982
|
};
|
|
5012
4983
|
this._getFocusStyle = type => {
|
|
5013
4984
|
let focusBackgroundStyle;
|
|
5014
|
-
if (type ===
|
|
4985
|
+
if (type === KeyType.INPUT_NAVIGATION || type === KeyType.KEYPAD_NAVIGATION) {
|
|
5015
4986
|
focusBackgroundStyle = styles$8.light;
|
|
5016
4987
|
} else {
|
|
5017
4988
|
focusBackgroundStyle = styles$8.bright;
|
|
@@ -5022,34 +4993,34 @@ class KeypadButton extends React.PureComponent {
|
|
|
5022
4993
|
// Select the appropriate style for the button.
|
|
5023
4994
|
let backgroundStyle;
|
|
5024
4995
|
switch (type) {
|
|
5025
|
-
case
|
|
4996
|
+
case KeyType.EMPTY:
|
|
5026
4997
|
backgroundStyle = styles$8.empty;
|
|
5027
4998
|
break;
|
|
5028
|
-
case
|
|
5029
|
-
case
|
|
4999
|
+
case KeyType.MANY:
|
|
5000
|
+
case KeyType.VALUE:
|
|
5030
5001
|
backgroundStyle = styles$8.value;
|
|
5031
5002
|
break;
|
|
5032
|
-
case
|
|
5003
|
+
case KeyType.OPERATOR:
|
|
5033
5004
|
backgroundStyle = styles$8.operator;
|
|
5034
5005
|
break;
|
|
5035
|
-
case
|
|
5036
|
-
case
|
|
5006
|
+
case KeyType.INPUT_NAVIGATION:
|
|
5007
|
+
case KeyType.KEYPAD_NAVIGATION:
|
|
5037
5008
|
backgroundStyle = styles$8.control;
|
|
5038
5009
|
break;
|
|
5039
|
-
case
|
|
5010
|
+
case KeyType.ECHO:
|
|
5040
5011
|
backgroundStyle = null;
|
|
5041
5012
|
break;
|
|
5042
5013
|
}
|
|
5043
5014
|
const borderStyle = [];
|
|
5044
|
-
if (borders.includes(
|
|
5015
|
+
if (borders.includes(BorderDirection.LEFT)) {
|
|
5045
5016
|
// @ts-expect-error TS2345
|
|
5046
5017
|
borderStyle.push(styles$8.leftBorder);
|
|
5047
5018
|
}
|
|
5048
|
-
if (borders.includes(
|
|
5019
|
+
if (borders.includes(BorderDirection.BOTTOM)) {
|
|
5049
5020
|
// @ts-expect-error TS2345
|
|
5050
5021
|
borderStyle.push(styles$8.bottomBorder);
|
|
5051
5022
|
}
|
|
5052
|
-
return [styles$8.buttonBase, backgroundStyle, ...borderStyle, type ===
|
|
5023
|
+
return [styles$8.buttonBase, backgroundStyle, ...borderStyle, type === KeyType.ECHO && styles$8.echo, this.buttonSizeStyle,
|
|
5053
5024
|
// React Native allows you to set the 'style' props on user defined
|
|
5054
5025
|
// components.
|
|
5055
5026
|
// See: https://facebook.github.io/react-native/docs/style.html
|
|
@@ -5091,7 +5062,7 @@ class KeypadButton extends React.PureComponent {
|
|
|
5091
5062
|
|
|
5092
5063
|
// We render in the focus state if the key is focused, or if it's an
|
|
5093
5064
|
// echo.
|
|
5094
|
-
const renderFocused = !disabled && focused || popoverEnabled || type ===
|
|
5065
|
+
const renderFocused = !disabled && focused || popoverEnabled || type === KeyType.ECHO;
|
|
5095
5066
|
const buttonStyle = this._getButtonStyle(type, borders, style);
|
|
5096
5067
|
const focusStyle = this._getFocusStyle(type);
|
|
5097
5068
|
const iconWrapperStyle = [styles$8.iconWrapper, disabled ? styles$8.disabled : undefined];
|
|
@@ -5107,11 +5078,11 @@ class KeypadButton extends React.PureComponent {
|
|
|
5107
5078
|
const maybeCornerDecal = !renderFocused && !disabled && childKeys && childKeys.length > 0 && /*#__PURE__*/React.createElement(CornerDecal, {
|
|
5108
5079
|
style: styles$8.decalInset
|
|
5109
5080
|
});
|
|
5110
|
-
if (type ===
|
|
5081
|
+
if (type === KeyType.EMPTY) {
|
|
5111
5082
|
return /*#__PURE__*/React.createElement(View, _extends({
|
|
5112
5083
|
style: buttonStyle
|
|
5113
5084
|
}, eventHandlers));
|
|
5114
|
-
} else if (type ===
|
|
5085
|
+
} else if (type === KeyType.MANY) {
|
|
5115
5086
|
// TODO(charlie): Make the long-press interaction accessible. See
|
|
5116
5087
|
// the TODO in key-configs.js for more.
|
|
5117
5088
|
const manyButtonA11yMarkup = {
|
|
@@ -5350,7 +5321,7 @@ const mapStateToProps$5 = (state, ownProps) => {
|
|
|
5350
5321
|
|
|
5351
5322
|
// Override with the default child props, if the key is a multi-symbol key
|
|
5352
5323
|
// (but not a many-symbol key, which operates under different rules).
|
|
5353
|
-
const useFirstChildProps = type !==
|
|
5324
|
+
const useFirstChildProps = type !== KeyType.MANY && childKeys && childKeys.length > 0;
|
|
5354
5325
|
return _extends({}, rest, {
|
|
5355
5326
|
childKeyIds: childKeyIds,
|
|
5356
5327
|
gestureManager: gestures.gestureManager,
|
|
@@ -5395,7 +5366,7 @@ class ManyKeypadButton extends React.Component {
|
|
|
5395
5366
|
} else {
|
|
5396
5367
|
const keyConfig = {
|
|
5397
5368
|
id: Keys.MANY,
|
|
5398
|
-
type:
|
|
5369
|
+
type: KeyType.MANY,
|
|
5399
5370
|
childKeyIds: keys
|
|
5400
5371
|
};
|
|
5401
5372
|
return /*#__PURE__*/React.createElement(TouchableKeypadButton$1, _extends({
|
|
@@ -5454,7 +5425,7 @@ class Echo extends React.Component {
|
|
|
5454
5425
|
style: containerStyle
|
|
5455
5426
|
}, /*#__PURE__*/React.createElement(KeypadButton$1, {
|
|
5456
5427
|
icon: icon,
|
|
5457
|
-
type:
|
|
5428
|
+
type: KeyType.ECHO,
|
|
5458
5429
|
borders: borders
|
|
5459
5430
|
}));
|
|
5460
5431
|
}
|
|
@@ -5468,15 +5439,15 @@ class EchoManager extends React.Component {
|
|
|
5468
5439
|
let animationDurationMs;
|
|
5469
5440
|
let animationTransitionName;
|
|
5470
5441
|
switch (animationType) {
|
|
5471
|
-
case
|
|
5442
|
+
case EchoAnimationType.SLIDE_AND_FADE:
|
|
5472
5443
|
animationDurationMs = 400;
|
|
5473
5444
|
animationTransitionName = "echo-slide-and-fade";
|
|
5474
5445
|
break;
|
|
5475
|
-
case
|
|
5446
|
+
case EchoAnimationType.FADE_ONLY:
|
|
5476
5447
|
animationDurationMs = 300;
|
|
5477
5448
|
animationTransitionName = "echo-fade-only";
|
|
5478
5449
|
break;
|
|
5479
|
-
case
|
|
5450
|
+
case EchoAnimationType.LONG_FADE_ONLY:
|
|
5480
5451
|
animationDurationMs = 400;
|
|
5481
5452
|
animationTransitionName = "echo-long-fade-only";
|
|
5482
5453
|
break;
|
|
@@ -5494,7 +5465,7 @@ class EchoManager extends React.Component {
|
|
|
5494
5465
|
echoes,
|
|
5495
5466
|
onAnimationFinish
|
|
5496
5467
|
} = this.props;
|
|
5497
|
-
return /*#__PURE__*/React.createElement("span", null, Object.keys(
|
|
5468
|
+
return /*#__PURE__*/React.createElement("span", null, Object.keys(EchoAnimationType).map(animationType => {
|
|
5498
5469
|
// Collect the relevant parameters for the animation type, and
|
|
5499
5470
|
// filter for the appropriate echoes.
|
|
5500
5471
|
const {
|
|
@@ -6020,25 +5991,25 @@ class ExpressionKeypad extends React.Component {
|
|
|
6020
5991
|
let dismissOrJumpOutKey;
|
|
6021
5992
|
if (dynamicJumpOut) {
|
|
6022
5993
|
switch (cursorContext) {
|
|
6023
|
-
case IN_PARENS:
|
|
5994
|
+
case CursorContext.IN_PARENS:
|
|
6024
5995
|
dismissOrJumpOutKey = KeyConfigs.JUMP_OUT_PARENTHESES;
|
|
6025
5996
|
break;
|
|
6026
|
-
case IN_SUPER_SCRIPT:
|
|
5997
|
+
case CursorContext.IN_SUPER_SCRIPT:
|
|
6027
5998
|
dismissOrJumpOutKey = KeyConfigs.JUMP_OUT_EXPONENT;
|
|
6028
5999
|
break;
|
|
6029
|
-
case IN_SUB_SCRIPT:
|
|
6000
|
+
case CursorContext.IN_SUB_SCRIPT:
|
|
6030
6001
|
dismissOrJumpOutKey = KeyConfigs.JUMP_OUT_BASE;
|
|
6031
6002
|
break;
|
|
6032
|
-
case BEFORE_FRACTION:
|
|
6003
|
+
case CursorContext.BEFORE_FRACTION:
|
|
6033
6004
|
dismissOrJumpOutKey = KeyConfigs.JUMP_INTO_NUMERATOR;
|
|
6034
6005
|
break;
|
|
6035
|
-
case IN_NUMERATOR:
|
|
6006
|
+
case CursorContext.IN_NUMERATOR:
|
|
6036
6007
|
dismissOrJumpOutKey = KeyConfigs.JUMP_OUT_NUMERATOR;
|
|
6037
6008
|
break;
|
|
6038
|
-
case IN_DENOMINATOR:
|
|
6009
|
+
case CursorContext.IN_DENOMINATOR:
|
|
6039
6010
|
dismissOrJumpOutKey = KeyConfigs.JUMP_OUT_DENOMINATOR;
|
|
6040
6011
|
break;
|
|
6041
|
-
case NONE:
|
|
6012
|
+
case CursorContext.NONE:
|
|
6042
6013
|
default:
|
|
6043
6014
|
dismissOrJumpOutKey = KeyConfigs.DISMISS;
|
|
6044
6015
|
break;
|
|
@@ -6253,25 +6224,25 @@ class FractionKeypad extends React.Component {
|
|
|
6253
6224
|
let dismissOrJumpOutKey;
|
|
6254
6225
|
if (dynamicJumpOut) {
|
|
6255
6226
|
switch (cursorContext) {
|
|
6256
|
-
case IN_PARENS:
|
|
6227
|
+
case CursorContext.IN_PARENS:
|
|
6257
6228
|
dismissOrJumpOutKey = KeyConfigs.JUMP_OUT_PARENTHESES;
|
|
6258
6229
|
break;
|
|
6259
|
-
case IN_SUPER_SCRIPT:
|
|
6230
|
+
case CursorContext.IN_SUPER_SCRIPT:
|
|
6260
6231
|
dismissOrJumpOutKey = KeyConfigs.JUMP_OUT_EXPONENT;
|
|
6261
6232
|
break;
|
|
6262
|
-
case IN_SUB_SCRIPT:
|
|
6233
|
+
case CursorContext.IN_SUB_SCRIPT:
|
|
6263
6234
|
dismissOrJumpOutKey = KeyConfigs.JUMP_OUT_BASE;
|
|
6264
6235
|
break;
|
|
6265
|
-
case BEFORE_FRACTION:
|
|
6236
|
+
case CursorContext.BEFORE_FRACTION:
|
|
6266
6237
|
dismissOrJumpOutKey = KeyConfigs.JUMP_INTO_NUMERATOR;
|
|
6267
6238
|
break;
|
|
6268
|
-
case IN_NUMERATOR:
|
|
6239
|
+
case CursorContext.IN_NUMERATOR:
|
|
6269
6240
|
dismissOrJumpOutKey = KeyConfigs.JUMP_OUT_NUMERATOR;
|
|
6270
6241
|
break;
|
|
6271
|
-
case IN_DENOMINATOR:
|
|
6242
|
+
case CursorContext.IN_DENOMINATOR:
|
|
6272
6243
|
dismissOrJumpOutKey = KeyConfigs.JUMP_OUT_DENOMINATOR;
|
|
6273
6244
|
break;
|
|
6274
|
-
case NONE:
|
|
6245
|
+
case CursorContext.NONE:
|
|
6275
6246
|
default:
|
|
6276
6247
|
dismissOrJumpOutKey = KeyConfigs.DISMISS;
|
|
6277
6248
|
break;
|
|
@@ -6300,7 +6271,7 @@ class FractionKeypad extends React.Component {
|
|
|
6300
6271
|
// then when the cursor was inside a parenthetical
|
|
6301
6272
|
// expression in a numerator or denominator, this check
|
|
6302
6273
|
// would fail.
|
|
6303
|
-
cursorContext === IN_NUMERATOR || cursorContext === IN_DENOMINATOR,
|
|
6274
|
+
cursorContext === CursorContext.IN_NUMERATOR || cursorContext === CursorContext.IN_DENOMINATOR,
|
|
6304
6275
|
style: roundTopRight && roundedTopRight
|
|
6305
6276
|
})), /*#__PURE__*/React.createElement(View, {
|
|
6306
6277
|
style: row$2
|
|
@@ -6357,10 +6328,10 @@ var FractionKeypad$1 = connect(mapStateToProps$1, null, null, {
|
|
|
6357
6328
|
forwardRef: true
|
|
6358
6329
|
})(FractionKeypad);
|
|
6359
6330
|
|
|
6360
|
-
const defaultKeypadType =
|
|
6331
|
+
const defaultKeypadType = KeypadType.EXPRESSION;
|
|
6361
6332
|
const keypadForType = {
|
|
6362
|
-
[
|
|
6363
|
-
[
|
|
6333
|
+
[KeypadType.FRACTION]: fractionKeypadLayout,
|
|
6334
|
+
[KeypadType.EXPRESSION]: expressionKeypadLayout
|
|
6364
6335
|
};
|
|
6365
6336
|
|
|
6366
6337
|
const initialKeypadState = {
|
|
@@ -6468,8 +6439,8 @@ const computeLayoutParameters = ({
|
|
|
6468
6439
|
|
|
6469
6440
|
// Then, compute the button dimensions based on the provided parameters.
|
|
6470
6441
|
let buttonDimensions;
|
|
6471
|
-
if (deviceType ===
|
|
6472
|
-
const isLandscape = deviceOrientation ===
|
|
6442
|
+
if (deviceType === DeviceType.PHONE) {
|
|
6443
|
+
const isLandscape = deviceOrientation === DeviceOrientation.LANDSCAPE;
|
|
6473
6444
|
|
|
6474
6445
|
// In many cases, the browser chrome will already have been factored
|
|
6475
6446
|
// into `pageHeightPx`. But we have no way of knowing if that's
|
|
@@ -6512,7 +6483,7 @@ const computeLayoutParameters = ({
|
|
|
6512
6483
|
widthPx: buttonWidthPx,
|
|
6513
6484
|
heightPx: buttonHeightPx
|
|
6514
6485
|
};
|
|
6515
|
-
} else if (deviceType ===
|
|
6486
|
+
} else if (deviceType === DeviceType.TABLET) {
|
|
6516
6487
|
buttonDimensions = {
|
|
6517
6488
|
widthPx: maxButtonSize,
|
|
6518
6489
|
heightPx: maxButtonSize
|
|
@@ -6527,7 +6498,7 @@ const computeLayoutParameters = ({
|
|
|
6527
6498
|
const keypadWidth = effectiveNumColumns * buttonDimensions.widthPx + (navigationPadEnabled ? navigationPadWidthPx : 0) + numSeparators * innerBorderWidthPx;
|
|
6528
6499
|
return {
|
|
6529
6500
|
buttonDimensions,
|
|
6530
|
-
layoutMode: keypadWidth >= pageWidthPx ?
|
|
6501
|
+
layoutMode: keypadWidth >= pageWidthPx ? LayoutMode.FULLSCREEN : LayoutMode.COMPACT
|
|
6531
6502
|
};
|
|
6532
6503
|
};
|
|
6533
6504
|
|
|
@@ -6546,7 +6517,7 @@ const initialLayoutState = {
|
|
|
6546
6517
|
pageWidthPx: 0,
|
|
6547
6518
|
pageHeightPx: 0
|
|
6548
6519
|
},
|
|
6549
|
-
layoutMode:
|
|
6520
|
+
layoutMode: LayoutMode.FULLSCREEN,
|
|
6550
6521
|
paginationEnabled: false,
|
|
6551
6522
|
navigationPadEnabled: false
|
|
6552
6523
|
};
|
|
@@ -6562,13 +6533,13 @@ const layoutParametersForDimensions = (pageDimensions, gridDimensions) => {
|
|
|
6562
6533
|
} = pageDimensions;
|
|
6563
6534
|
|
|
6564
6535
|
// Determine the device type and orientation.
|
|
6565
|
-
const deviceOrientation = pageWidthPx > pageHeightPx ?
|
|
6566
|
-
const deviceType = Math.min(pageWidthPx, pageHeightPx) > tabletCutoffPx ?
|
|
6536
|
+
const deviceOrientation = pageWidthPx > pageHeightPx ? DeviceOrientation.LANDSCAPE : DeviceOrientation.PORTRAIT;
|
|
6537
|
+
const deviceType = Math.min(pageWidthPx, pageHeightPx) > tabletCutoffPx ? DeviceType.TABLET : DeviceType.PHONE;
|
|
6567
6538
|
|
|
6568
6539
|
// Using that information, make some decisions (or assumptions)
|
|
6569
6540
|
// about the resulting layout.
|
|
6570
|
-
const navigationPadEnabled = deviceType ===
|
|
6571
|
-
const paginationEnabled = deviceType ===
|
|
6541
|
+
const navigationPadEnabled = deviceType === DeviceType.TABLET;
|
|
6542
|
+
const paginationEnabled = deviceType === DeviceType.PHONE && deviceOrientation === DeviceOrientation.PORTRAIT;
|
|
6572
6543
|
const deviceInfo = {
|
|
6573
6544
|
deviceOrientation,
|
|
6574
6545
|
deviceType
|
|
@@ -6727,7 +6698,7 @@ const pagerReducer = function pagerReducer(state = initialPagerState, action) {
|
|
|
6727
6698
|
const keyConfig = KeyConfigs[action.key];
|
|
6728
6699
|
|
|
6729
6700
|
// Reset the keypad page if the user performs a math operation.
|
|
6730
|
-
if (keyConfig.type ===
|
|
6701
|
+
if (keyConfig.type === KeyType.VALUE || keyConfig.type === KeyType.OPERATOR) {
|
|
6731
6702
|
return _extends({}, state, {
|
|
6732
6703
|
animateToPosition: true,
|
|
6733
6704
|
// We start at the right-most page.
|
|
@@ -7010,8 +6981,8 @@ class KeypadContainer extends React.Component {
|
|
|
7010
6981
|
// compact keypad, we need to instruct some of our child views to
|
|
7011
6982
|
// crop themselves. At least we're colocating all the layout
|
|
7012
6983
|
// information in this component, though.
|
|
7013
|
-
roundTopLeft: layoutMode ===
|
|
7014
|
-
roundTopRight: layoutMode ===
|
|
6984
|
+
roundTopLeft: layoutMode === LayoutMode.COMPACT && !navigationPadEnabled,
|
|
6985
|
+
roundTopRight: layoutMode === LayoutMode.COMPACT
|
|
7015
6986
|
};
|
|
7016
6987
|
|
|
7017
6988
|
// Select the appropriate keyboard given the type.
|
|
@@ -7022,9 +6993,9 @@ class KeypadContainer extends React.Component {
|
|
|
7022
6993
|
// clear what that format would look like exactly. Plus, there aren't
|
|
7023
6994
|
// very many of them. So to keep us moving, we'll just hardcode.
|
|
7024
6995
|
switch (keypadType) {
|
|
7025
|
-
case
|
|
6996
|
+
case KeypadType.FRACTION:
|
|
7026
6997
|
return /*#__PURE__*/React.createElement(FractionKeypad$1, keypadProps);
|
|
7027
|
-
case
|
|
6998
|
+
case KeypadType.EXPRESSION:
|
|
7028
6999
|
return /*#__PURE__*/React.createElement(ExpressionKeypad$1, keypadProps);
|
|
7029
7000
|
default:
|
|
7030
7001
|
throw new Error("Invalid keypad type: " + keypadType);
|
|
@@ -7082,7 +7053,7 @@ class KeypadContainer extends React.Component {
|
|
|
7082
7053
|
dynamicStyle = _extends({}, dynamicStyle, inlineStyles.invisible);
|
|
7083
7054
|
}
|
|
7084
7055
|
const keypadContainerStyle = [row, centered, fullWidth, styles.keypadContainer, ...(Array.isArray(style) ? style : [style])];
|
|
7085
|
-
const keypadStyle = [row, styles.keypadBorder, layoutMode ===
|
|
7056
|
+
const keypadStyle = [row, styles.keypadBorder, layoutMode === LayoutMode.FULLSCREEN ? styles.fullscreen : styles.compact];
|
|
7086
7057
|
|
|
7087
7058
|
// TODO(charlie): When the keypad is shorter than the width of the
|
|
7088
7059
|
// screen, add a border on its left and right edges, and round out the
|
|
@@ -7100,7 +7071,7 @@ class KeypadContainer extends React.Component {
|
|
|
7100
7071
|
}
|
|
7101
7072
|
}
|
|
7102
7073
|
}, navigationPadEnabled && /*#__PURE__*/React.createElement(NavigationPad, {
|
|
7103
|
-
roundTopLeft: layoutMode ===
|
|
7074
|
+
roundTopLeft: layoutMode === LayoutMode.COMPACT,
|
|
7104
7075
|
style: styles.navigationPadContainer
|
|
7105
7076
|
}), /*#__PURE__*/React.createElement(View, {
|
|
7106
7077
|
style: styles.keypadLayout
|
|
@@ -7246,5 +7217,5 @@ class ProvidedKeypad extends React.Component {
|
|
|
7246
7217
|
}
|
|
7247
7218
|
}
|
|
7248
7219
|
|
|
7249
|
-
export {
|
|
7220
|
+
export { CursorContext, KeyConfigs, KeyType, ProvidedKeypad as Keypad, MathInput as KeypadInput, KeypadType, Keys, keypadElementPropType };
|
|
7250
7221
|
//# sourceMappingURL=index.js.map
|