@khanacademy/math-input 17.0.3 → 17.0.5
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/dist/es/index.js +2 -2
- package/dist/es/index.js.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/package.json +5 -2
- package/.eslintrc.js +0 -18
- package/CHANGELOG.md +0 -654
- package/less/main.less +0 -2
- package/less/overrides.less +0 -122
- package/src/components/__tests__/integration.test.tsx +0 -300
- package/src/components/aphrodite-css-transition-group/index.tsx +0 -78
- package/src/components/aphrodite-css-transition-group/transition-child.tsx +0 -192
- package/src/components/aphrodite-css-transition-group/types.ts +0 -20
- package/src/components/aphrodite-css-transition-group/util.ts +0 -97
- package/src/components/input/__tests__/context-tracking.test.ts +0 -176
- package/src/components/input/__tests__/mathquill-helpers.test.ts +0 -105
- package/src/components/input/__tests__/mathquill.test.ts +0 -747
- package/src/components/input/__tests__/test-math-wrapper.ts +0 -29
- package/src/components/input/cursor-contexts.ts +0 -37
- package/src/components/input/cursor-handle.tsx +0 -137
- package/src/components/input/cursor-styles.ts +0 -10
- package/src/components/input/drag-listener.ts +0 -79
- package/src/components/input/math-input.tsx +0 -1036
- package/src/components/input/math-wrapper.ts +0 -189
- package/src/components/input/mathquill-helpers.ts +0 -262
- package/src/components/input/mathquill-instance.ts +0 -106
- package/src/components/input/mathquill-types.ts +0 -32
- package/src/components/input/scroll-into-view.ts +0 -65
- package/src/components/key-handlers/__tests__/handle-jump-out.test.ts +0 -94
- package/src/components/key-handlers/handle-arrow.ts +0 -70
- package/src/components/key-handlers/handle-backspace.ts +0 -277
- package/src/components/key-handlers/handle-exponent.ts +0 -53
- package/src/components/key-handlers/handle-jump-out.ts +0 -107
- package/src/components/key-handlers/key-translator.ts +0 -222
- package/src/components/keypad/__tests__/__snapshots__/keypad.test.tsx.snap +0 -1913
- package/src/components/keypad/__tests__/__snapshots__/mobile-keypad.test.tsx.snap +0 -600
- package/src/components/keypad/__tests__/keypad-button.test.tsx +0 -84
- package/src/components/keypad/__tests__/keypad-v2-mathquill.test.tsx +0 -304
- package/src/components/keypad/__tests__/keypad-v2.cypress.ts +0 -16
- package/src/components/keypad/__tests__/keypad.test.tsx +0 -321
- package/src/components/keypad/__tests__/mobile-keypad.test.tsx +0 -115
- package/src/components/keypad/__tests__/test-data-tabs.ts +0 -21
- package/src/components/keypad/button-assets.tsx +0 -1880
- package/src/components/keypad/index.tsx +0 -2
- package/src/components/keypad/keypad-button.stories.tsx +0 -81
- package/src/components/keypad/keypad-button.tsx +0 -124
- package/src/components/keypad/keypad-mathquill.stories.tsx +0 -109
- package/src/components/keypad/keypad-pages/extras-page.tsx +0 -35
- package/src/components/keypad/keypad-pages/fractions-page.tsx +0 -125
- package/src/components/keypad/keypad-pages/geometry-page.tsx +0 -34
- package/src/components/keypad/keypad-pages/keypad-pages.stories.tsx +0 -37
- package/src/components/keypad/keypad-pages/numbers-page.tsx +0 -94
- package/src/components/keypad/keypad-pages/operators-page.tsx +0 -117
- package/src/components/keypad/keypad.tsx +0 -233
- package/src/components/keypad/mobile-keypad-internals.tsx +0 -240
- package/src/components/keypad/mobile-keypad.tsx +0 -24
- package/src/components/keypad/navigation-button.tsx +0 -127
- package/src/components/keypad/navigation-pad.stories.tsx +0 -26
- package/src/components/keypad/navigation-pad.tsx +0 -67
- package/src/components/keypad/shared-keys.tsx +0 -109
- package/src/components/keypad/utils.ts +0 -34
- package/src/components/keypad-context.tsx +0 -70
- package/src/components/prop-types.ts +0 -16
- package/src/components/tabbar/__tests__/tabbar.test.tsx +0 -105
- package/src/components/tabbar/icons.tsx +0 -122
- package/src/components/tabbar/index.ts +0 -1
- package/src/components/tabbar/item.tsx +0 -146
- package/src/components/tabbar/tabbar.stories.tsx +0 -83
- package/src/components/tabbar/tabbar.tsx +0 -65
- package/src/data/key-configs.ts +0 -770
- package/src/data/keys.ts +0 -123
- package/src/enums.ts +0 -27
- package/src/fake-react-native-web/index.ts +0 -11
- package/src/fake-react-native-web/text.tsx +0 -55
- package/src/fake-react-native-web/view.tsx +0 -91
- package/src/full-keypad.stories.tsx +0 -142
- package/src/full-mobile-input.stories.tsx +0 -115
- package/src/index.ts +0 -52
- package/src/types.ts +0 -70
- package/src/utils.test.ts +0 -33
- package/src/utils.ts +0 -61
- package/src/version.ts +0 -10
- package/tsconfig-build.json +0 -11
- package/tsconfig-build.tsbuildinfo +0 -1
|
@@ -1,747 +0,0 @@
|
|
|
1
|
-
import TestMathWrapper from "./test-math-wrapper";
|
|
2
|
-
|
|
3
|
-
const MQ = {L: "-1", R: "1"};
|
|
4
|
-
const END_OF_EXPR = 0;
|
|
5
|
-
|
|
6
|
-
const isInsideEmptyParens = (cursor) => {
|
|
7
|
-
return (
|
|
8
|
-
cursor[MQ.L] === END_OF_EXPR &&
|
|
9
|
-
cursor[MQ.R] === END_OF_EXPR &&
|
|
10
|
-
cursor.parent.parent.ctrlSeq === "\\left("
|
|
11
|
-
);
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
describe("MathQuill", () => {
|
|
15
|
-
let mathField;
|
|
16
|
-
let span;
|
|
17
|
-
|
|
18
|
-
beforeEach(() => {
|
|
19
|
-
span = document.createElement("span");
|
|
20
|
-
document.body.appendChild(span);
|
|
21
|
-
|
|
22
|
-
mathField = new TestMathWrapper(span);
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
afterEach(() => {
|
|
26
|
-
document.body.removeChild(span);
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
// TODO(charlie): Add tests for "FRAC_EXCLUSIVE" (the mixed-number
|
|
30
|
-
// fraction key).
|
|
31
|
-
describe("Fraction Bar", () => {
|
|
32
|
-
it("should work with no content", () => {
|
|
33
|
-
mathField.pressKey("FRAC_INCLUSIVE");
|
|
34
|
-
expect(mathField.getContent()).toEqual("\\frac{ }{ }");
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
it("should work after an expression", () => {
|
|
38
|
-
mathField.setContent("35x^{2}");
|
|
39
|
-
mathField.pressKey("FRAC_INCLUSIVE");
|
|
40
|
-
expect(mathField.getContent()).toEqual("\\frac{35x^{2}}{ }");
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
it("should work before an expression", () => {
|
|
44
|
-
mathField.setContent("35x^{2}");
|
|
45
|
-
mathField.moveToStart();
|
|
46
|
-
mathField.pressKey("FRAC_INCLUSIVE");
|
|
47
|
-
expect(mathField.getContent()).toEqual("\\frac{ }{ }35x^{2}");
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
it("should work with a selected expression", () => {
|
|
51
|
-
mathField.setContent("35x^{2}");
|
|
52
|
-
mathField.selectAll();
|
|
53
|
-
mathField.pressKey("FRAC_INCLUSIVE");
|
|
54
|
-
expect(mathField.getContent()).toEqual("\\frac{35x^{2}}{ }");
|
|
55
|
-
});
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
describe("Parentheses", () => {
|
|
59
|
-
it("should work with no content", () => {
|
|
60
|
-
mathField.setContent("");
|
|
61
|
-
mathField.pressKey("LEFT_PAREN");
|
|
62
|
-
expect(mathField.getContent()).toEqual("\\left(\\right)");
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
it("should work after an expression", () => {
|
|
66
|
-
mathField.setContent("35x^{2}");
|
|
67
|
-
mathField.pressKey("RIGHT_PAREN");
|
|
68
|
-
expect(mathField.getContent()).toEqual("\\left(35x^{2}\\right)");
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
it("should work before an expression", () => {
|
|
72
|
-
mathField.setContent("35x^{2}");
|
|
73
|
-
mathField.moveToStart();
|
|
74
|
-
mathField.pressKey("LEFT_PAREN");
|
|
75
|
-
expect(mathField.getContent()).toEqual("\\left(35x^{2}\\right)");
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
it.skip("should work on a selected expression", () => {
|
|
79
|
-
mathField.setContent("35x + 5");
|
|
80
|
-
mathField.selectAll();
|
|
81
|
-
mathField.pressKey("LEFT_PAREN");
|
|
82
|
-
expect(mathField.getContent()).toEqual("\\left(35x^{2}\\right)");
|
|
83
|
-
});
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
describe("Squared", () => {
|
|
87
|
-
it("should prefix with empty parens after no content", () => {
|
|
88
|
-
mathField.pressKey("EXP_2");
|
|
89
|
-
expect(mathField.getContent()).toEqual("\\left(\\right)^{2}");
|
|
90
|
-
|
|
91
|
-
// Verify that the cursor is in parens.
|
|
92
|
-
expect(isInsideEmptyParens(mathField.getCursor())).toBeTruthy();
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
it("should prefix with empty parens after an operator", () => {
|
|
96
|
-
mathField.pressKey("DIVIDE");
|
|
97
|
-
mathField.pressKey("EXP_2");
|
|
98
|
-
expect(mathField.getContent()).toEqual("\\div\\left(\\right)^{2}");
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
it("should work after an expression", () => {
|
|
102
|
-
mathField.setContent("35x");
|
|
103
|
-
mathField.pressKey("EXP_2");
|
|
104
|
-
expect(mathField.getContent()).toEqual("35x^{2}");
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
it.skip("should work on a selected expression", () => {
|
|
108
|
-
mathField.setContent("35x+5");
|
|
109
|
-
mathField.selectAll();
|
|
110
|
-
mathField.pressKey("EXP_2");
|
|
111
|
-
expect(mathField.getContent()).toEqual("\\left(35x+5\\right)^{2}");
|
|
112
|
-
});
|
|
113
|
-
});
|
|
114
|
-
|
|
115
|
-
describe("Cubed", () => {
|
|
116
|
-
it("should prefix with empty parens after no content", () => {
|
|
117
|
-
mathField.pressKey("EXP_3");
|
|
118
|
-
expect(mathField.getContent()).toEqual("\\left(\\right)^{3}");
|
|
119
|
-
|
|
120
|
-
// Verify that the cursor is in parens.
|
|
121
|
-
expect(isInsideEmptyParens(mathField.getCursor())).toBeTruthy();
|
|
122
|
-
});
|
|
123
|
-
|
|
124
|
-
it("should prefix with empty parens after an operator", () => {
|
|
125
|
-
mathField.pressKey("EQUAL");
|
|
126
|
-
mathField.pressKey("EXP_3");
|
|
127
|
-
expect(mathField.getContent()).toEqual("=\\left(\\right)^{3}");
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
it("should work after an expression", () => {
|
|
131
|
-
mathField.setContent("35x");
|
|
132
|
-
mathField.pressKey("EXP_3");
|
|
133
|
-
expect(mathField.getContent()).toEqual("35x^{3}");
|
|
134
|
-
});
|
|
135
|
-
|
|
136
|
-
it.skip("should work on a selected expression", () => {
|
|
137
|
-
mathField.setContent("35x+5");
|
|
138
|
-
mathField.selectAll();
|
|
139
|
-
mathField.pressKey("EXP_3");
|
|
140
|
-
expect(mathField.getContent()).toEqual("\\left(35x+5\\right)^{3}");
|
|
141
|
-
});
|
|
142
|
-
});
|
|
143
|
-
|
|
144
|
-
describe("Exponent", () => {
|
|
145
|
-
it("should prefix with empty parens after no content", () => {
|
|
146
|
-
mathField.pressKey("EXP");
|
|
147
|
-
expect(mathField.getContent()).toEqual("\\left(\\right)^{ }");
|
|
148
|
-
|
|
149
|
-
// Verify that the cursor is in the exponent, not within the parens,
|
|
150
|
-
// writing a unique character to verify cursor position.
|
|
151
|
-
expect(isInsideEmptyParens(mathField.getCursor())).toBeFalsy();
|
|
152
|
-
mathField.pressKey("PLUS");
|
|
153
|
-
expect(mathField.getContent()).toEqual("\\left(\\right)^{+}");
|
|
154
|
-
});
|
|
155
|
-
|
|
156
|
-
it("should prefix with empty parens after an operator", () => {
|
|
157
|
-
mathField.pressKey("PLUS");
|
|
158
|
-
mathField.pressKey("EXP");
|
|
159
|
-
expect(mathField.getContent()).toEqual("+\\left(\\right)^{ }");
|
|
160
|
-
});
|
|
161
|
-
|
|
162
|
-
it("should work after an expression", () => {
|
|
163
|
-
mathField.setContent("35x");
|
|
164
|
-
mathField.pressKey("EXP");
|
|
165
|
-
expect(mathField.getContent()).toEqual("35x^{ }");
|
|
166
|
-
});
|
|
167
|
-
|
|
168
|
-
// TODO(kevinb): makes the expression an exponent when it shouldn't
|
|
169
|
-
it.skip("should work on a selected expression", () => {
|
|
170
|
-
mathField.setContent("35x+5");
|
|
171
|
-
mathField.selectAll();
|
|
172
|
-
mathField.pressKey("EXP");
|
|
173
|
-
expect(mathField.getContent()).toEqual("\\left(35x+5\\right)^{ }");
|
|
174
|
-
});
|
|
175
|
-
});
|
|
176
|
-
|
|
177
|
-
describe("Square Root", () => {
|
|
178
|
-
it("should work with no content", () => {
|
|
179
|
-
mathField.pressKey("SQRT");
|
|
180
|
-
expect(mathField.getContent()).toEqual("\\sqrt{ }");
|
|
181
|
-
});
|
|
182
|
-
|
|
183
|
-
it("should work after an expression", () => {
|
|
184
|
-
mathField.setContent("35x^{2}");
|
|
185
|
-
mathField.pressKey("SQRT");
|
|
186
|
-
expect(mathField.getContent()).toEqual("35x^{2}\\sqrt{ }");
|
|
187
|
-
});
|
|
188
|
-
|
|
189
|
-
it("should work on a selected expression", () => {
|
|
190
|
-
mathField.setContent("35x+5");
|
|
191
|
-
mathField.selectAll();
|
|
192
|
-
mathField.pressKey("SQRT");
|
|
193
|
-
expect(mathField.getContent()).toEqual("\\sqrt{35x+5}");
|
|
194
|
-
});
|
|
195
|
-
});
|
|
196
|
-
|
|
197
|
-
describe("Radical", () => {
|
|
198
|
-
it("should work with no content", () => {
|
|
199
|
-
mathField.pressKey("RADICAL");
|
|
200
|
-
expect(mathField.getContent()).toEqual("\\sqrt[]{}");
|
|
201
|
-
});
|
|
202
|
-
|
|
203
|
-
it("should work after an expression", () => {
|
|
204
|
-
mathField.setContent("35x^{2}");
|
|
205
|
-
mathField.pressKey("RADICAL");
|
|
206
|
-
expect(mathField.getContent()).toEqual("35x^{2}\\sqrt[]{}");
|
|
207
|
-
});
|
|
208
|
-
|
|
209
|
-
it.skip("should work on a selected expression", () => {
|
|
210
|
-
mathField.setContent("35x+5");
|
|
211
|
-
mathField.selectAll();
|
|
212
|
-
mathField.pressKey("RADICAL");
|
|
213
|
-
// TODO(kevinb): check cursor location
|
|
214
|
-
expect(mathField.getContent()).toEqual("\\sqrt[ ]{35x+5}");
|
|
215
|
-
});
|
|
216
|
-
});
|
|
217
|
-
|
|
218
|
-
describe("Log", () => {
|
|
219
|
-
it("should work with no content", () => {
|
|
220
|
-
mathField.pressKey("LOG");
|
|
221
|
-
expect(mathField.getContent()).toEqual("\\log\\left(\\right)");
|
|
222
|
-
});
|
|
223
|
-
|
|
224
|
-
it("should work after an expression", () => {
|
|
225
|
-
mathField.setContent("35x^{2}");
|
|
226
|
-
mathField.pressKey("LOG");
|
|
227
|
-
expect(mathField.getContent()).toEqual(
|
|
228
|
-
"35x^{2}\\log\\left(\\right)",
|
|
229
|
-
);
|
|
230
|
-
});
|
|
231
|
-
|
|
232
|
-
it.skip("should work on a selected expression", () => {
|
|
233
|
-
mathField.setContent("35x+5");
|
|
234
|
-
mathField.selectAll();
|
|
235
|
-
mathField.pressKey("LOG");
|
|
236
|
-
expect(mathField.getContent()).toEqual("\\log\\left(35x+5\\right)");
|
|
237
|
-
});
|
|
238
|
-
});
|
|
239
|
-
|
|
240
|
-
describe("Log w/ base n", () => {
|
|
241
|
-
it("should work with no content", () => {
|
|
242
|
-
mathField.pressKey("LOG_N");
|
|
243
|
-
expect(mathField.getContent()).toEqual("\\log_{ }\\left(\\right)");
|
|
244
|
-
});
|
|
245
|
-
|
|
246
|
-
it("should work after an expression", () => {
|
|
247
|
-
mathField.setContent("35x^{2}");
|
|
248
|
-
mathField.pressKey("LOG_N");
|
|
249
|
-
expect(mathField.getContent()).toEqual(
|
|
250
|
-
"35x^{2}\\log_{ }\\left(\\right)",
|
|
251
|
-
);
|
|
252
|
-
});
|
|
253
|
-
|
|
254
|
-
it.skip("should work on a selected expression", () => {
|
|
255
|
-
mathField.setContent("35x+5");
|
|
256
|
-
mathField.selectAll();
|
|
257
|
-
mathField.pressKey("LOG_N");
|
|
258
|
-
expect(mathField.getContent()).toEqual(
|
|
259
|
-
"\\log_{ }\\left(35x+5\\right)",
|
|
260
|
-
);
|
|
261
|
-
});
|
|
262
|
-
});
|
|
263
|
-
|
|
264
|
-
describe("Backspace", () => {
|
|
265
|
-
it("should delete an empty fraction from the numerator", () => {
|
|
266
|
-
mathField.setContent("\\frac{ }{ }");
|
|
267
|
-
mathField.moveToStart();
|
|
268
|
-
mathField.pressKey("RIGHT");
|
|
269
|
-
mathField.pressKey("BACKSPACE");
|
|
270
|
-
expect(mathField.getContent()).toEqual("");
|
|
271
|
-
});
|
|
272
|
-
|
|
273
|
-
it("should convert a fraction when deleting the denominator", () => {
|
|
274
|
-
mathField.setContent("\\frac{35x^{2}}{ }");
|
|
275
|
-
mathField.pressKey("LEFT");
|
|
276
|
-
mathField.pressKey("BACKSPACE");
|
|
277
|
-
expect(mathField.getContent()).toEqual("35x^{2}");
|
|
278
|
-
});
|
|
279
|
-
|
|
280
|
-
// TODO(kevinb) math isn't selected
|
|
281
|
-
it("should select a fraction when deleting from outside of it", () => {
|
|
282
|
-
const expr = "\\frac{35x+5}{x^{2}}";
|
|
283
|
-
mathField.setContent(expr);
|
|
284
|
-
mathField.pressKey("BACKSPACE");
|
|
285
|
-
expect(mathField.isSelected()).toBeTruthy();
|
|
286
|
-
expect(mathField.getContent()).toEqual(expr);
|
|
287
|
-
});
|
|
288
|
-
|
|
289
|
-
it("should delete parens when inside empty parens", () => {
|
|
290
|
-
mathField.setContent("\\left(\\right)");
|
|
291
|
-
mathField.pressKey("LEFT");
|
|
292
|
-
mathField.pressKey("BACKSPACE");
|
|
293
|
-
expect(mathField.getContent()).toEqual("");
|
|
294
|
-
});
|
|
295
|
-
|
|
296
|
-
it("deletes only the first parens when inside empty parens", () => {
|
|
297
|
-
mathField.setContent("\\left(\\right)\\left(\\right)");
|
|
298
|
-
mathField.pressKey("LEFT");
|
|
299
|
-
mathField.pressKey("BACKSPACE");
|
|
300
|
-
expect(mathField.getContent()).toEqual("\\left(\\right)");
|
|
301
|
-
});
|
|
302
|
-
|
|
303
|
-
it("should select an expression when deleting from outside (1)", () => {
|
|
304
|
-
const expr = "\\left(35x+5\\right)";
|
|
305
|
-
mathField.setContent(expr);
|
|
306
|
-
mathField.pressKey("BACKSPACE");
|
|
307
|
-
expect(mathField.isSelected()).toBeTruthy();
|
|
308
|
-
expect(mathField.getContent()).toEqual(expr);
|
|
309
|
-
});
|
|
310
|
-
|
|
311
|
-
it("should select an expression when deleting from outside (2)", () => {
|
|
312
|
-
const expr = "1+\\left(35x+5\\right)";
|
|
313
|
-
mathField.setContent(expr);
|
|
314
|
-
mathField.pressKey("BACKSPACE");
|
|
315
|
-
const selection = mathField.getSelection();
|
|
316
|
-
const left = selection.ends[MQ.L][MQ.L];
|
|
317
|
-
const right = selection.ends[MQ.R][MQ.R];
|
|
318
|
-
|
|
319
|
-
expect(left.ctrlSeq).toEqual("+");
|
|
320
|
-
expect(right).toEqual(END_OF_EXPR);
|
|
321
|
-
expect(mathField.getContent()).toEqual(expr);
|
|
322
|
-
});
|
|
323
|
-
|
|
324
|
-
it("should select an expression when deleting from outside (3)", () => {
|
|
325
|
-
const expr = "1+\\left(35x+5\\right)-1";
|
|
326
|
-
mathField.setContent(expr);
|
|
327
|
-
mathField.pressKey("LEFT");
|
|
328
|
-
mathField.pressKey("LEFT");
|
|
329
|
-
mathField.pressKey("BACKSPACE");
|
|
330
|
-
const selection = mathField.getSelection();
|
|
331
|
-
const left = selection.ends[MQ.L][MQ.L];
|
|
332
|
-
const right = selection.ends[MQ.R][MQ.R];
|
|
333
|
-
|
|
334
|
-
expect(left.ctrlSeq).toEqual("+");
|
|
335
|
-
expect(right.ctrlSeq).toEqual("-");
|
|
336
|
-
expect(mathField.getContent()).toEqual(expr);
|
|
337
|
-
});
|
|
338
|
-
|
|
339
|
-
it("should select an expression when deleting from outside (4)", () => {
|
|
340
|
-
const expr = "\\left(35x+5\\right)-1";
|
|
341
|
-
mathField.setContent(expr);
|
|
342
|
-
mathField.pressKey("LEFT");
|
|
343
|
-
mathField.pressKey("LEFT");
|
|
344
|
-
mathField.pressKey("BACKSPACE");
|
|
345
|
-
const selection = mathField.getSelection();
|
|
346
|
-
const left = selection.ends[MQ.L][MQ.L];
|
|
347
|
-
const right = selection.ends[MQ.R][MQ.R];
|
|
348
|
-
|
|
349
|
-
expect(left).toEqual(END_OF_EXPR);
|
|
350
|
-
expect(right.ctrlSeq).toEqual("-");
|
|
351
|
-
expect(mathField.getContent()).toEqual(expr);
|
|
352
|
-
});
|
|
353
|
-
|
|
354
|
-
it("should select an expression when deleting from outside", () => {
|
|
355
|
-
mathField.setContent("\\left(35x+5\\right)");
|
|
356
|
-
mathField.pressKey("BACKSPACE");
|
|
357
|
-
expect(mathField.isSelected()).toBeTruthy();
|
|
358
|
-
expect(mathField.getContent()).toEqual("\\left(35x+5\\right)");
|
|
359
|
-
});
|
|
360
|
-
|
|
361
|
-
// TODO(kevinb) fix this behavior so that we delete the exponent too
|
|
362
|
-
it.skip("should not delete squared exponents", () => {
|
|
363
|
-
mathField.setContent("35x^{2}");
|
|
364
|
-
mathField.pressKey("BACKSPACE");
|
|
365
|
-
expect(mathField.getContent()).toEqual("35x^{2}");
|
|
366
|
-
mathField.pressKey("BACKSPACE");
|
|
367
|
-
expect(mathField.getContent()).toEqual("35x^{ }");
|
|
368
|
-
});
|
|
369
|
-
|
|
370
|
-
it("should not delete non-square exponents", () => {
|
|
371
|
-
mathField.setContent("35x^5");
|
|
372
|
-
mathField.pressKey("BACKSPACE");
|
|
373
|
-
expect(mathField.getContent()).toEqual("35x^{5}");
|
|
374
|
-
mathField.pressKey("BACKSPACE");
|
|
375
|
-
expect(mathField.getContent()).toEqual("35x^{ }");
|
|
376
|
-
});
|
|
377
|
-
|
|
378
|
-
it("should delete an empty exponent", () => {
|
|
379
|
-
mathField.setContent("35x^{}");
|
|
380
|
-
mathField.pressKey("LEFT");
|
|
381
|
-
mathField.pressKey("BACKSPACE");
|
|
382
|
-
expect(mathField.getContent()).toEqual("35x");
|
|
383
|
-
});
|
|
384
|
-
|
|
385
|
-
it("should delete an empty square root", () => {
|
|
386
|
-
mathField.setContent("\\sqrt{}");
|
|
387
|
-
mathField.pressKey("LEFT");
|
|
388
|
-
mathField.pressKey("BACKSPACE");
|
|
389
|
-
expect(mathField.getContent()).toEqual("");
|
|
390
|
-
});
|
|
391
|
-
|
|
392
|
-
it("should delete an empty radical when cursor is in index", () => {
|
|
393
|
-
mathField.setContent("\\sqrt[]{}");
|
|
394
|
-
mathField.moveToStart();
|
|
395
|
-
mathField.pressKey("RIGHT");
|
|
396
|
-
mathField.pressKey("BACKSPACE");
|
|
397
|
-
expect(mathField.getContent()).toEqual("");
|
|
398
|
-
});
|
|
399
|
-
|
|
400
|
-
it("should delete an empty radical when cursor is in body", () => {
|
|
401
|
-
mathField.pressKey("RADICAL");
|
|
402
|
-
mathField.pressKey("RIGHT");
|
|
403
|
-
mathField.pressKey("BACKSPACE");
|
|
404
|
-
expect(mathField.getContent()).toEqual("");
|
|
405
|
-
});
|
|
406
|
-
|
|
407
|
-
it("should select an empty radical with non-empty root", () => {
|
|
408
|
-
mathField.pressKey("CUBE_ROOT");
|
|
409
|
-
const expr = mathField.getContent();
|
|
410
|
-
mathField.pressKey("BACKSPACE");
|
|
411
|
-
|
|
412
|
-
expect(mathField.isSelected()).toBeTruthy();
|
|
413
|
-
expect(mathField.getContent()).toEqual(expr);
|
|
414
|
-
});
|
|
415
|
-
|
|
416
|
-
it("should normally delete within a non-empty radical", () => {
|
|
417
|
-
mathField.pressKey("CUBE_ROOT");
|
|
418
|
-
const expr = mathField.getContent();
|
|
419
|
-
|
|
420
|
-
mathField.pressKey("NUM_2");
|
|
421
|
-
mathField.pressKey("BACKSPACE");
|
|
422
|
-
|
|
423
|
-
expect(mathField.getContent()).toEqual(expr);
|
|
424
|
-
});
|
|
425
|
-
|
|
426
|
-
it("deletes nthroot index normally", () => {
|
|
427
|
-
mathField.setContent("\\sqrt[3]{35x+5}");
|
|
428
|
-
mathField.moveToStart();
|
|
429
|
-
mathField.pressKey("RIGHT");
|
|
430
|
-
mathField.pressKey("RIGHT");
|
|
431
|
-
mathField.pressKey("BACKSPACE");
|
|
432
|
-
|
|
433
|
-
const cursor = mathField.getCursor();
|
|
434
|
-
|
|
435
|
-
expect(cursor[MQ.L]).toEqual(END_OF_EXPR);
|
|
436
|
-
expect(mathField.getContent()).toEqual("\\sqrt[]{35x+5}");
|
|
437
|
-
});
|
|
438
|
-
|
|
439
|
-
it("converts nthroot to sqrt when deleting from index (1)", () => {
|
|
440
|
-
mathField.setContent("\\sqrt[]{35x+5}");
|
|
441
|
-
mathField.moveToStart();
|
|
442
|
-
mathField.pressKey("RIGHT");
|
|
443
|
-
mathField.pressKey("BACKSPACE");
|
|
444
|
-
|
|
445
|
-
const cursor = mathField.getCursor();
|
|
446
|
-
|
|
447
|
-
expect(cursor[MQ.L]).toEqual(END_OF_EXPR);
|
|
448
|
-
expect(mathField.getContent()).toEqual("\\sqrt{35x+5}");
|
|
449
|
-
});
|
|
450
|
-
|
|
451
|
-
it("converts nthroot to sqrt when deleting from index (2)", () => {
|
|
452
|
-
mathField.setContent("1+\\sqrt[]{35x+5}");
|
|
453
|
-
mathField.moveToStart();
|
|
454
|
-
mathField.pressKey("RIGHT");
|
|
455
|
-
mathField.pressKey("RIGHT");
|
|
456
|
-
mathField.pressKey("RIGHT");
|
|
457
|
-
mathField.pressKey("BACKSPACE");
|
|
458
|
-
|
|
459
|
-
const cursor = mathField.getCursor();
|
|
460
|
-
|
|
461
|
-
expect(cursor[MQ.L].ctrlSeq).toEqual("+");
|
|
462
|
-
expect(mathField.getContent()).toEqual("1+\\sqrt{35x+5}");
|
|
463
|
-
});
|
|
464
|
-
|
|
465
|
-
it("should not delete if the index has contents", () => {
|
|
466
|
-
const expr = "\\sqrt[3]{35x+5}";
|
|
467
|
-
mathField.setContent(expr);
|
|
468
|
-
mathField.moveToStart();
|
|
469
|
-
mathField.pressKey("RIGHT");
|
|
470
|
-
mathField.pressKey("BACKSPACE");
|
|
471
|
-
|
|
472
|
-
expect(mathField.getContent()).toEqual(expr);
|
|
473
|
-
});
|
|
474
|
-
|
|
475
|
-
it("should select a full square root before deleting it", () => {
|
|
476
|
-
const expr = "\\sqrt{35x+5}";
|
|
477
|
-
mathField.setContent(expr);
|
|
478
|
-
mathField.pressKey("BACKSPACE");
|
|
479
|
-
|
|
480
|
-
expect(mathField.isSelected()).toBeTruthy();
|
|
481
|
-
expect(mathField.getContent()).toEqual(expr);
|
|
482
|
-
});
|
|
483
|
-
|
|
484
|
-
it("should select a full nth-root before deleting it", () => {
|
|
485
|
-
const expr = "\\sqrt[3]{35x+5}";
|
|
486
|
-
mathField.setContent(expr);
|
|
487
|
-
mathField.pressKey("BACKSPACE");
|
|
488
|
-
|
|
489
|
-
expect(mathField.isSelected()).toBeTruthy();
|
|
490
|
-
expect(mathField.getContent()).toEqual(expr);
|
|
491
|
-
});
|
|
492
|
-
|
|
493
|
-
it("should delete log when inside empty log", () => {
|
|
494
|
-
mathField.setContent("\\log\\left(\\right)");
|
|
495
|
-
mathField.pressKey("LEFT");
|
|
496
|
-
mathField.pressKey("BACKSPACE");
|
|
497
|
-
expect(mathField.getContent()).toEqual("");
|
|
498
|
-
});
|
|
499
|
-
|
|
500
|
-
it("should select log when inside full log at head", () => {
|
|
501
|
-
const expr = "\\log\\left(35x\\right)";
|
|
502
|
-
mathField.setContent(expr);
|
|
503
|
-
mathField.moveToStart();
|
|
504
|
-
mathField.pressKey("RIGHT");
|
|
505
|
-
mathField.pressKey("BACKSPACE");
|
|
506
|
-
expect(mathField.isSelected()).toBeTruthy();
|
|
507
|
-
expect(mathField.getContent()).toEqual(expr);
|
|
508
|
-
});
|
|
509
|
-
|
|
510
|
-
it("should select log when outside full log at tail (1)", () => {
|
|
511
|
-
const expr = "\\log\\left(35x\\right)";
|
|
512
|
-
mathField.setContent(expr);
|
|
513
|
-
mathField.pressKey("BACKSPACE");
|
|
514
|
-
expect(mathField.isSelected()).toBeTruthy();
|
|
515
|
-
expect(mathField.getContent()).toEqual(expr);
|
|
516
|
-
});
|
|
517
|
-
|
|
518
|
-
it("should select log when outside full log at tail (2)", () => {
|
|
519
|
-
const expr = "1+\\log\\left(35x\\right)";
|
|
520
|
-
mathField.setContent(expr);
|
|
521
|
-
mathField.pressKey("BACKSPACE");
|
|
522
|
-
const selection = mathField.getSelection();
|
|
523
|
-
const left = selection.ends[MQ.L][MQ.L];
|
|
524
|
-
const right = selection.ends[MQ.R][MQ.R];
|
|
525
|
-
|
|
526
|
-
expect(left.ctrlSeq).toEqual("+");
|
|
527
|
-
expect(right).toEqual(END_OF_EXPR);
|
|
528
|
-
expect(mathField.getContent()).toEqual(expr);
|
|
529
|
-
});
|
|
530
|
-
|
|
531
|
-
it("should select log when outside full log at tail (3)", () => {
|
|
532
|
-
const expr = "1+\\log\\left(35x\\right)-1";
|
|
533
|
-
mathField.setContent(expr);
|
|
534
|
-
mathField.pressKey("LEFT");
|
|
535
|
-
mathField.pressKey("LEFT");
|
|
536
|
-
mathField.pressKey("BACKSPACE");
|
|
537
|
-
const selection = mathField.getSelection();
|
|
538
|
-
const left = selection.ends[MQ.L][MQ.L];
|
|
539
|
-
const right = selection.ends[MQ.R][MQ.R];
|
|
540
|
-
|
|
541
|
-
expect(left.ctrlSeq).toEqual("+");
|
|
542
|
-
expect(right.ctrlSeq).toEqual("-");
|
|
543
|
-
expect(mathField.getContent()).toEqual(expr);
|
|
544
|
-
});
|
|
545
|
-
|
|
546
|
-
it("should select log when outside full log at tail (4)", () => {
|
|
547
|
-
const expr = "\\log\\left(35x\\right)-1";
|
|
548
|
-
mathField.setContent(expr);
|
|
549
|
-
mathField.pressKey("LEFT");
|
|
550
|
-
mathField.pressKey("LEFT");
|
|
551
|
-
mathField.pressKey("BACKSPACE");
|
|
552
|
-
const selection = mathField.getSelection();
|
|
553
|
-
const left = selection.ends[MQ.L][MQ.L];
|
|
554
|
-
const right = selection.ends[MQ.R][MQ.R];
|
|
555
|
-
|
|
556
|
-
expect(left).toEqual(END_OF_EXPR);
|
|
557
|
-
expect(right.ctrlSeq).toEqual("-");
|
|
558
|
-
expect(mathField.getContent()).toEqual(expr);
|
|
559
|
-
});
|
|
560
|
-
|
|
561
|
-
it("should delete empty log when at index", () => {
|
|
562
|
-
mathField.setContent("\\log_{ }\\left(\\right)");
|
|
563
|
-
mathField.moveToStart();
|
|
564
|
-
|
|
565
|
-
// Move right once to get into the parens, and then left twice to
|
|
566
|
-
// get to the empty index.
|
|
567
|
-
mathField.pressKey("RIGHT");
|
|
568
|
-
mathField.pressKey("LEFT");
|
|
569
|
-
mathField.pressKey("LEFT");
|
|
570
|
-
|
|
571
|
-
mathField.pressKey("BACKSPACE");
|
|
572
|
-
expect(mathField.getContent()).toEqual("");
|
|
573
|
-
});
|
|
574
|
-
|
|
575
|
-
it("should delete log index normally", () => {
|
|
576
|
-
mathField.setContent("\\log_5\\left(\\right)");
|
|
577
|
-
mathField.moveToStart();
|
|
578
|
-
|
|
579
|
-
// Move right once to get into the parens, and then left twice to
|
|
580
|
-
// get to the index.
|
|
581
|
-
mathField.pressKey("RIGHT");
|
|
582
|
-
mathField.pressKey("LEFT");
|
|
583
|
-
mathField.pressKey("LEFT");
|
|
584
|
-
|
|
585
|
-
mathField.pressKey("BACKSPACE");
|
|
586
|
-
expect(mathField.getContent()).toEqual("\\log_{ }\\left(\\right)");
|
|
587
|
-
});
|
|
588
|
-
|
|
589
|
-
it("should move to index from inside empty log with index", () => {
|
|
590
|
-
mathField.setContent("\\log_5\\left(\\right)");
|
|
591
|
-
mathField.pressKey("LEFT");
|
|
592
|
-
mathField.pressKey("BACKSPACE");
|
|
593
|
-
|
|
594
|
-
const cursor = mathField.getCursor();
|
|
595
|
-
|
|
596
|
-
expect(cursor[MQ.L].ctrlSeq).toEqual("5");
|
|
597
|
-
expect(mathField.getContent()).toEqual("\\log_{5}\\left(\\right)");
|
|
598
|
-
});
|
|
599
|
-
|
|
600
|
-
it("should select full log when deleting from empty index (1)", () => {
|
|
601
|
-
const expr = "\\log_{ }\\left(x\\right)";
|
|
602
|
-
mathField.setContent(expr);
|
|
603
|
-
mathField.moveToStart();
|
|
604
|
-
|
|
605
|
-
// Move right once to get into the parens, and then left twice to
|
|
606
|
-
// get to the empty index.
|
|
607
|
-
mathField.pressKey("RIGHT");
|
|
608
|
-
mathField.pressKey("LEFT");
|
|
609
|
-
mathField.pressKey("LEFT");
|
|
610
|
-
|
|
611
|
-
mathField.pressKey("BACKSPACE");
|
|
612
|
-
|
|
613
|
-
expect(mathField.isSelected()).toBeTruthy();
|
|
614
|
-
expect(mathField.getContent()).toEqual(expr);
|
|
615
|
-
});
|
|
616
|
-
|
|
617
|
-
it("should select full log when deleting from empty index (2)", () => {
|
|
618
|
-
const expr = "1+\\log_{ }\\left(x\\right)";
|
|
619
|
-
mathField.setContent(expr);
|
|
620
|
-
mathField.moveToStart();
|
|
621
|
-
|
|
622
|
-
// Move right once to get into the parens, and then left twice to
|
|
623
|
-
// get to the empty index.
|
|
624
|
-
mathField.pressKey("RIGHT");
|
|
625
|
-
mathField.pressKey("RIGHT");
|
|
626
|
-
mathField.pressKey("RIGHT");
|
|
627
|
-
mathField.pressKey("LEFT");
|
|
628
|
-
mathField.pressKey("LEFT");
|
|
629
|
-
|
|
630
|
-
mathField.pressKey("BACKSPACE");
|
|
631
|
-
|
|
632
|
-
const selection = mathField.getSelection();
|
|
633
|
-
const left = selection.ends[MQ.L][MQ.L];
|
|
634
|
-
const right = selection.ends[MQ.R][MQ.R];
|
|
635
|
-
|
|
636
|
-
expect(left.ctrlSeq).toEqual("+");
|
|
637
|
-
expect(right).toEqual(END_OF_EXPR);
|
|
638
|
-
expect(mathField.getContent()).toEqual(expr);
|
|
639
|
-
});
|
|
640
|
-
|
|
641
|
-
it("should select full log when deleting from empty index (3)", () => {
|
|
642
|
-
const expr = "1+\\log_{ }\\left(x\\right)-1";
|
|
643
|
-
mathField.setContent(expr);
|
|
644
|
-
mathField.moveToStart();
|
|
645
|
-
|
|
646
|
-
// Move right three times to get into the parens, and then left
|
|
647
|
-
// twice to get to the start of the empty index.
|
|
648
|
-
mathField.pressKey("RIGHT");
|
|
649
|
-
mathField.pressKey("RIGHT");
|
|
650
|
-
mathField.pressKey("RIGHT");
|
|
651
|
-
mathField.pressKey("LEFT");
|
|
652
|
-
mathField.pressKey("LEFT");
|
|
653
|
-
|
|
654
|
-
mathField.pressKey("BACKSPACE");
|
|
655
|
-
|
|
656
|
-
const selection = mathField.getSelection();
|
|
657
|
-
const left = selection.ends[MQ.L][MQ.L];
|
|
658
|
-
const right = selection.ends[MQ.R][MQ.R];
|
|
659
|
-
|
|
660
|
-
expect(left.ctrlSeq).toEqual("+");
|
|
661
|
-
expect(right.ctrlSeq).toEqual("-");
|
|
662
|
-
expect(mathField.getContent()).toEqual(expr);
|
|
663
|
-
});
|
|
664
|
-
|
|
665
|
-
it("should select full log when deleting from empty index (4)", () => {
|
|
666
|
-
const expr = "\\log_{ }\\left(x\\right)-1";
|
|
667
|
-
mathField.setContent(expr);
|
|
668
|
-
mathField.moveToStart();
|
|
669
|
-
|
|
670
|
-
// Move right once to get into the parens, and then left twice to
|
|
671
|
-
// get to the start of the empty index.
|
|
672
|
-
mathField.pressKey("RIGHT");
|
|
673
|
-
mathField.pressKey("LEFT");
|
|
674
|
-
mathField.pressKey("LEFT");
|
|
675
|
-
|
|
676
|
-
mathField.pressKey("BACKSPACE");
|
|
677
|
-
|
|
678
|
-
const selection = mathField.getSelection();
|
|
679
|
-
const left = selection.ends[MQ.L][MQ.L];
|
|
680
|
-
const right = selection.ends[MQ.R][MQ.R];
|
|
681
|
-
|
|
682
|
-
expect(left).toEqual(END_OF_EXPR);
|
|
683
|
-
expect(right.ctrlSeq).toEqual("-");
|
|
684
|
-
expect(mathField.getContent()).toEqual(expr);
|
|
685
|
-
});
|
|
686
|
-
});
|
|
687
|
-
|
|
688
|
-
describe("Left arrow", () => {
|
|
689
|
-
it("skips function names", () => {
|
|
690
|
-
mathField.pressKey("COS");
|
|
691
|
-
const cursor = mathField.getCursor();
|
|
692
|
-
|
|
693
|
-
// Verify that we're inside the function.
|
|
694
|
-
expect(cursor[MQ.L]).toEqual(END_OF_EXPR);
|
|
695
|
-
expect(cursor[MQ.R]).toEqual(END_OF_EXPR);
|
|
696
|
-
|
|
697
|
-
// Navigate left.
|
|
698
|
-
mathField.pressKey("LEFT");
|
|
699
|
-
|
|
700
|
-
// Verify that we moved beyond the body of the function.
|
|
701
|
-
expect(cursor[MQ.L]).toEqual(END_OF_EXPR);
|
|
702
|
-
expect(cursor[MQ.R].ctrlSeq).toEqual("\\c");
|
|
703
|
-
});
|
|
704
|
-
|
|
705
|
-
it("does not skip out of a function with valid content present", () => {
|
|
706
|
-
mathField.pressKey("COS");
|
|
707
|
-
mathField.pressKey("PLUS");
|
|
708
|
-
const cursor = mathField.getCursor();
|
|
709
|
-
|
|
710
|
-
// Verify that we're inside the function.
|
|
711
|
-
expect(cursor[MQ.L].ctrlSeq).toEqual("+");
|
|
712
|
-
expect(cursor[MQ.R]).toEqual(END_OF_EXPR);
|
|
713
|
-
|
|
714
|
-
// Navigate left.
|
|
715
|
-
mathField.pressKey("LEFT");
|
|
716
|
-
|
|
717
|
-
// Verify that we didn't move out of the function.
|
|
718
|
-
expect(cursor[MQ.L]).toEqual(END_OF_EXPR);
|
|
719
|
-
expect(cursor[MQ.R].ctrlSeq).toEqual("+");
|
|
720
|
-
});
|
|
721
|
-
});
|
|
722
|
-
|
|
723
|
-
describe("Right arrow", () => {
|
|
724
|
-
it("skips function names", () => {
|
|
725
|
-
mathField.setContent("\\cos\\left(5\\right)");
|
|
726
|
-
mathField.moveToStart();
|
|
727
|
-
const cursor = mathField.getCursor();
|
|
728
|
-
|
|
729
|
-
// Verify that we're outside the function.
|
|
730
|
-
expect(cursor[MQ.L]).toEqual(END_OF_EXPR);
|
|
731
|
-
expect(cursor[MQ.R].ctrlSeq).toEqual("\\c");
|
|
732
|
-
|
|
733
|
-
// Navigate right.
|
|
734
|
-
mathField.pressKey("RIGHT");
|
|
735
|
-
|
|
736
|
-
// Verify that we moved into the body of the function.
|
|
737
|
-
expect(cursor[MQ.L]).toEqual(END_OF_EXPR);
|
|
738
|
-
expect(cursor[MQ.R].ctrlSeq).toEqual("5");
|
|
739
|
-
});
|
|
740
|
-
});
|
|
741
|
-
|
|
742
|
-
describe.skip("Jump out", () => {
|
|
743
|
-
// TODO(charlie): Write extensive tests for the 'Jump out' behavior.
|
|
744
|
-
});
|
|
745
|
-
|
|
746
|
-
describe.skip("Equals =, !=, <, <=, >, >=", () => {});
|
|
747
|
-
});
|