Skip to content

Commit 98a3d1e

Browse files
acivitilloAlessio Civitillormorshea
authored
Form serialize (#699)
* first try to serialize form * fix up form serialization * fix test * add form element serialization * delete temp file Co-authored-by: Alessio Civitillo <@acivitillo@dyvenia.com> Co-authored-by: rmorshea <[email protected]>
1 parent 4fd5cde commit 98a3d1e

File tree

3 files changed

+84
-30
lines changed

3 files changed

+84
-30
lines changed

docs/source/about/changelog.rst

+3-2
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,15 @@ Unreleased
2525

2626
**Removed**
2727

28-
- :pull:`840` - remove ``IDOM_FEATURE_INDEX_AS_DEFAULT_KEY`` option
28+
- :pull:`840` - Remove ``IDOM_FEATURE_INDEX_AS_DEFAULT_KEY`` option
2929
- :pull:`835` - ``serve_static_files`` option from backend configuration
3030

3131
**Added**
3232

33-
- :pull:`835` - ability to customize the ``<head>`` element of IDOM's built-in client.
33+
- :pull:`835` - Ability to customize the ``<head>`` element of IDOM's built-in client.
3434
- :pull:`835` - ``vdom_to_html`` utility function.
3535
- :pull:`843` - Ability to subscribe to changes that are made to mutable options.
36+
- :pull:`699` - Support for form element serialization
3637

3738
**Fixed**
3839

src/client/packages/idom-client-react/src/event-to-object.js

+30
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,20 @@ const elementTransformCategories = {
4949
return {};
5050
}
5151
},
52+
hasElements: (element) => {
53+
const { elements } = element;
54+
const indices = [...Array(elements.length).keys()];
55+
return {
56+
elements: indices.map((index) => serializeDomElement(elements[index])),
57+
};
58+
},
59+
hasName: (element) => {
60+
const { name } = element;
61+
// In some edge cases, "name" may not be a string. For example, in the case of
62+
// `<form><input name="name"></form>`, the "name" attribute of the `<form>` will
63+
// be the `<input>` element.
64+
return typeof name === "string" ? { name } : {};
65+
},
5266
};
5367

5468
function defaultElementTransform(element) {
@@ -69,6 +83,22 @@ const elementTagCategories = {
6983
],
7084
hasCurrentTime: ["AUDIO", "VIDEO"],
7185
hasFiles: ["INPUT"],
86+
hasElements: ["FORM"],
87+
hasName: [
88+
"BUTTON",
89+
"FORM",
90+
"FIELDSET",
91+
"IFRAME",
92+
"INPUT",
93+
"KEYGEN",
94+
"OBJECT",
95+
"OUTPUT",
96+
"SELECT",
97+
"TEXTAREA",
98+
"MAP",
99+
"META",
100+
"PARAM",
101+
],
72102
};
73103

74104
const elementTransforms = {};

src/client/packages/idom-client-react/tests/event-to-object.test.js

+51-28
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,40 @@ import * as assert from "uvu/assert";
44
import { serializeEvent } from "../src/event-to-object.js";
55
import "./tooling/setup.js";
66

7-
function assertEqualSerializedEventData(eventData, expectedSerializedData) {
8-
const mockBoundingRect = {
9-
left: 0,
10-
top: 0,
11-
right: 0,
12-
bottom: 0,
13-
x: 0,
14-
y: 0,
15-
width: 0,
16-
};
7+
const mockBoundingRect = {
8+
left: 0,
9+
top: 0,
10+
right: 0,
11+
bottom: 0,
12+
x: 0,
13+
y: 0,
14+
width: 0,
15+
};
1716

18-
const mockElement = {
19-
tagName: null,
20-
getBoundingClientRect: () => mockBoundingRect,
21-
};
17+
const mockElement = {
18+
tagName: null,
19+
getBoundingClientRect: () => mockBoundingRect,
20+
};
2221

22+
const allTargetData = {
23+
files: [
24+
{
25+
lastModified: 0,
26+
name: "something",
27+
type: "some-type",
28+
size: 0,
29+
},
30+
],
31+
value: "something",
32+
currentTime: 35,
33+
tagName: null, // overwritten in tests
34+
elements: [
35+
{ ...mockElement, tagName: "INPUT", value: "first" },
36+
{ ...mockElement, tagName: "INPUT", value: "second" },
37+
],
38+
};
39+
40+
function assertEqualSerializedEventData(eventData, expectedSerializedData) {
2341
const commonEventData = {
2442
target: mockElement,
2543
currentTarget: mockElement,
@@ -38,20 +56,6 @@ function assertEqualSerializedEventData(eventData, expectedSerializedData) {
3856
);
3957
}
4058

41-
const allTargetData = {
42-
files: [
43-
{
44-
lastModified: 0,
45-
name: "something",
46-
type: "some-type",
47-
size: 0,
48-
},
49-
],
50-
value: "something",
51-
currentTime: 35,
52-
tagName: null, // overwritten in tests
53-
};
54-
5559
[
5660
{
5761
case: "adds 'files' and 'value' attributes for INPUT if type=file",
@@ -76,6 +80,24 @@ const allTargetData = {
7680
tagName,
7781
output: { target: { currentTime: allTargetData.currentTime } },
7882
})),
83+
...["FORM"].map((tagName) => ({
84+
case: `adds 'elements' attribute for ${tagName} element`,
85+
tagName,
86+
output: {
87+
target: {
88+
elements: [
89+
{
90+
value: "first",
91+
boundingClientRect: mockBoundingRect,
92+
},
93+
{
94+
value: "second",
95+
boundingClientRect: mockBoundingRect,
96+
},
97+
],
98+
},
99+
},
100+
})),
79101
].forEach((expectation) => {
80102
test(`serializeEvent() ${expectation.case}`, () => {
81103
const eventData = {
@@ -113,6 +135,7 @@ const allEventData = {
113135
clientX: "clientX",
114136
clientY: "clientY",
115137
ctrlKey: "ctrlKey",
138+
form: "form",
116139
metaKey: "metaKey",
117140
pageX: "pageX",
118141
pageY: "pageY",

0 commit comments

Comments
 (0)