@remit/ui 0.0.135 → 0.0.136
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/package.json
CHANGED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `isWritingElsewhere` against a real focused element (#839) — mounted on jsdom
|
|
3
|
+
* rather than a stub, so the `type` fallback is the platform's own and not one
|
|
4
|
+
* the test agrees with.
|
|
5
|
+
*/
|
|
6
|
+
import "@remit/test-dom";
|
|
7
|
+
import assert from "node:assert/strict";
|
|
8
|
+
import { afterEach, describe, it } from "node:test";
|
|
9
|
+
import { isWritingElsewhere } from "./editor-focus.js";
|
|
10
|
+
|
|
11
|
+
const editor = document.createElement("div");
|
|
12
|
+
|
|
13
|
+
const focusInput = (type: string | null): void => {
|
|
14
|
+
const input = document.createElement("input");
|
|
15
|
+
if (type !== null) input.setAttribute("type", type);
|
|
16
|
+
document.body.append(input);
|
|
17
|
+
input.focus();
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
afterEach(() => {
|
|
21
|
+
document.body.replaceChildren();
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
describe("isWritingElsewhere", () => {
|
|
25
|
+
it("reads an input the platform renders as text as writing", () => {
|
|
26
|
+
for (const type of [
|
|
27
|
+
"text",
|
|
28
|
+
"search",
|
|
29
|
+
"email",
|
|
30
|
+
"url",
|
|
31
|
+
"tel",
|
|
32
|
+
"password",
|
|
33
|
+
"number",
|
|
34
|
+
"date",
|
|
35
|
+
"datetime-local",
|
|
36
|
+
"month",
|
|
37
|
+
"time",
|
|
38
|
+
"week",
|
|
39
|
+
]) {
|
|
40
|
+
document.body.replaceChildren();
|
|
41
|
+
focusInput(type);
|
|
42
|
+
assert.equal(isWritingElsewhere(editor), true, type);
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it("reads an empty type as writing", () => {
|
|
47
|
+
// HTML falls back to a text field, so the reader may be mid-sentence in it.
|
|
48
|
+
focusInput("");
|
|
49
|
+
assert.equal(isWritingElsewhere(editor), true);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it("reads an unrecognised type as writing", () => {
|
|
53
|
+
focusInput("wibble");
|
|
54
|
+
assert.equal(isWritingElsewhere(editor), true);
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it("reads a missing type as writing", () => {
|
|
58
|
+
focusInput(null);
|
|
59
|
+
assert.equal(isWritingElsewhere(editor), true);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it("leaves the controls alone", () => {
|
|
63
|
+
for (const type of [
|
|
64
|
+
"button",
|
|
65
|
+
"checkbox",
|
|
66
|
+
"color",
|
|
67
|
+
"file",
|
|
68
|
+
"image",
|
|
69
|
+
"radio",
|
|
70
|
+
"range",
|
|
71
|
+
"reset",
|
|
72
|
+
"submit",
|
|
73
|
+
]) {
|
|
74
|
+
document.body.replaceChildren();
|
|
75
|
+
focusInput(type);
|
|
76
|
+
assert.equal(isWritingElsewhere(editor), false, type);
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
it("ignores the case the type is written in", () => {
|
|
81
|
+
focusInput("CheckBox");
|
|
82
|
+
assert.equal(isWritingElsewhere(editor), false);
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it("is not writing elsewhere when nothing holds the caret", () => {
|
|
86
|
+
assert.equal(isWritingElsewhere(editor), false);
|
|
87
|
+
});
|
|
88
|
+
});
|
|
@@ -13,23 +13,26 @@
|
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
|
-
* The types an `<input>`
|
|
17
|
-
* checkbox, a radio, a button, a file or colour picker
|
|
18
|
-
*
|
|
16
|
+
* The types an `<input>` is a control rather than a writing surface in — a
|
|
17
|
+
* checkbox, a radio, a button, a file or colour picker, something the reader
|
|
18
|
+
* clicks and is never mid-word in.
|
|
19
|
+
*
|
|
20
|
+
* Named the other way round on purpose. An `<input>` with an empty or
|
|
21
|
+
* unrecognised `type` renders as a text field, so listing the ones that accept
|
|
22
|
+
* prose would read every new or misspelt type as a control and take the caret
|
|
23
|
+
* out of a field the reader is typing in.
|
|
19
24
|
*/
|
|
20
|
-
const
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
"
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
-
"
|
|
31
|
-
"time",
|
|
32
|
-
"week",
|
|
25
|
+
const NON_TEXT_INPUT_TYPES = new Set([
|
|
26
|
+
"button",
|
|
27
|
+
"checkbox",
|
|
28
|
+
"color",
|
|
29
|
+
"file",
|
|
30
|
+
"hidden",
|
|
31
|
+
"image",
|
|
32
|
+
"radio",
|
|
33
|
+
"range",
|
|
34
|
+
"reset",
|
|
35
|
+
"submit",
|
|
33
36
|
]);
|
|
34
37
|
|
|
35
38
|
/**
|
|
@@ -59,7 +62,7 @@ const takesTyping = (element: Element): boolean => {
|
|
|
59
62
|
if (tag === "SELECT") return true;
|
|
60
63
|
if (tag === "INPUT") {
|
|
61
64
|
const type = (element.getAttribute("type") ?? "text").toLowerCase();
|
|
62
|
-
return
|
|
65
|
+
return !NON_TEXT_INPUT_TYPES.has(type);
|
|
63
66
|
}
|
|
64
67
|
// The attribute as well as the property: `isContentEditable` is computed by
|
|
65
68
|
// the engine, and a document that never lays out does not answer for it.
|