Skip to content

Commit d9e8a79

Browse files
committed
package.json: patch jsdom to get SubmitEvent
Backport [1] to jsdom 20. [1]: jsdom/jsdom#3481
1 parent 68d7932 commit d9e8a79

File tree

3 files changed

+298
-2
lines changed

3 files changed

+298
-2
lines changed
Lines changed: 255 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,255 @@
1+
diff --git a/lib/jsdom/living/events/SubmitEvent-impl.js b/lib/jsdom/living/events/SubmitEvent-impl.js
2+
new file mode 100644
3+
index 0000000000000000000000000000000000000000..2a9886e1369c7f6ee55abe697cb3b870034bee06
4+
--- /dev/null
5+
+++ b/lib/jsdom/living/events/SubmitEvent-impl.js
6+
@@ -0,0 +1,13 @@
7+
+"use strict";
8+
+
9+
+const EventImpl = require("./Event-impl").implementation;
10+
+
11+
+const SubmitEventInit = require("../generated/SubmitEventInit");
12+
+
13+
+// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#the-submitevent-interface
14+
+class SubmitEventImpl extends EventImpl {}
15+
+SubmitEventImpl.defaultInit = SubmitEventInit.convert(undefined, undefined);
16+
+
17+
+module.exports = {
18+
+ implementation: SubmitEventImpl
19+
+};
20+
diff --git a/lib/jsdom/living/generated/SubmitEvent.js b/lib/jsdom/living/generated/SubmitEvent.js
21+
new file mode 100644
22+
index 0000000000000000000000000000000000000000..c35c4083d4ca58a3bedffd5621cc602ff97043e7
23+
--- /dev/null
24+
+++ b/lib/jsdom/living/generated/SubmitEvent.js
25+
@@ -0,0 +1,144 @@
26+
+"use strict";
27+
+
28+
+const conversions = require("webidl-conversions");
29+
+const utils = require("./utils.js");
30+
+
31+
+const SubmitEventInit = require("./SubmitEventInit.js");
32+
+const implSymbol = utils.implSymbol;
33+
+const ctorRegistrySymbol = utils.ctorRegistrySymbol;
34+
+const Event = require("./Event.js");
35+
+
36+
+const interfaceName = "SubmitEvent";
37+
+
38+
+exports.is = value => {
39+
+ return utils.isObject(value) && utils.hasOwn(value, implSymbol) && value[implSymbol] instanceof Impl.implementation;
40+
+};
41+
+exports.isImpl = value => {
42+
+ return utils.isObject(value) && value instanceof Impl.implementation;
43+
+};
44+
+exports.convert = (globalObject, value, { context = "The provided value" } = {}) => {
45+
+ if (exports.is(value)) {
46+
+ return utils.implForWrapper(value);
47+
+ }
48+
+ throw new globalObject.TypeError(`${context} is not of type 'SubmitEvent'.`);
49+
+};
50+
+
51+
+function makeWrapper(globalObject, newTarget) {
52+
+ let proto;
53+
+ if (newTarget !== undefined) {
54+
+ proto = newTarget.prototype;
55+
+ }
56+
+
57+
+ if (!utils.isObject(proto)) {
58+
+ proto = globalObject[ctorRegistrySymbol]["SubmitEvent"].prototype;
59+
+ }
60+
+
61+
+ return Object.create(proto);
62+
+}
63+
+
64+
+exports.create = (globalObject, constructorArgs, privateData) => {
65+
+ const wrapper = makeWrapper(globalObject);
66+
+ return exports.setup(wrapper, globalObject, constructorArgs, privateData);
67+
+};
68+
+
69+
+exports.createImpl = (globalObject, constructorArgs, privateData) => {
70+
+ const wrapper = exports.create(globalObject, constructorArgs, privateData);
71+
+ return utils.implForWrapper(wrapper);
72+
+};
73+
+
74+
+exports._internalSetup = (wrapper, globalObject) => {
75+
+ Event._internalSetup(wrapper, globalObject);
76+
+};
77+
+
78+
+exports.setup = (wrapper, globalObject, constructorArgs = [], privateData = {}) => {
79+
+ privateData.wrapper = wrapper;
80+
+
81+
+ exports._internalSetup(wrapper, globalObject);
82+
+ Object.defineProperty(wrapper, implSymbol, {
83+
+ value: new Impl.implementation(globalObject, constructorArgs, privateData),
84+
+ configurable: true
85+
+ });
86+
+
87+
+ wrapper[implSymbol][utils.wrapperSymbol] = wrapper;
88+
+ if (Impl.init) {
89+
+ Impl.init(wrapper[implSymbol]);
90+
+ }
91+
+ return wrapper;
92+
+};
93+
+
94+
+exports.new = (globalObject, newTarget) => {
95+
+ const wrapper = makeWrapper(globalObject, newTarget);
96+
+
97+
+ exports._internalSetup(wrapper, globalObject);
98+
+ Object.defineProperty(wrapper, implSymbol, {
99+
+ value: Object.create(Impl.implementation.prototype),
100+
+ configurable: true
101+
+ });
102+
+
103+
+ wrapper[implSymbol][utils.wrapperSymbol] = wrapper;
104+
+ if (Impl.init) {
105+
+ Impl.init(wrapper[implSymbol]);
106+
+ }
107+
+ return wrapper[implSymbol];
108+
+};
109+
+
110+
+const exposed = new Set(["Window"]);
111+
+
112+
+exports.install = (globalObject, globalNames) => {
113+
+ if (!globalNames.some(globalName => exposed.has(globalName))) {
114+
+ return;
115+
+ }
116+
+
117+
+ const ctorRegistry = utils.initCtorRegistry(globalObject);
118+
+ class SubmitEvent extends globalObject.Event {
119+
+ constructor(type) {
120+
+ if (arguments.length < 1) {
121+
+ throw new globalObject.TypeError(
122+
+ `Failed to construct 'SubmitEvent': 1 argument required, but only ${arguments.length} present.`
123+
+ );
124+
+ }
125+
+ const args = [];
126+
+ {
127+
+ let curArg = arguments[0];
128+
+ curArg = conversions["DOMString"](curArg, {
129+
+ context: "Failed to construct 'SubmitEvent': parameter 1",
130+
+ globals: globalObject
131+
+ });
132+
+ args.push(curArg);
133+
+ }
134+
+ {
135+
+ let curArg = arguments[1];
136+
+ curArg = SubmitEventInit.convert(globalObject, curArg, {
137+
+ context: "Failed to construct 'SubmitEvent': parameter 2"
138+
+ });
139+
+ args.push(curArg);
140+
+ }
141+
+ return exports.setup(Object.create(new.target.prototype), globalObject, args);
142+
+ }
143+
+
144+
+ get submitter() {
145+
+ const esValue = this !== null && this !== undefined ? this : globalObject;
146+
+
147+
+ if (!exports.is(esValue)) {
148+
+ throw new globalObject.TypeError(
149+
+ "'get submitter' called on an object that is not a valid instance of SubmitEvent."
150+
+ );
151+
+ }
152+
+
153+
+ return utils.tryWrapperForImpl(esValue[implSymbol]["submitter"]);
154+
+ }
155+
+ }
156+
+ Object.defineProperties(SubmitEvent.prototype, {
157+
+ submitter: { enumerable: true },
158+
+ [Symbol.toStringTag]: { value: "SubmitEvent", configurable: true }
159+
+ });
160+
+ ctorRegistry[interfaceName] = SubmitEvent;
161+
+
162+
+ Object.defineProperty(globalObject, interfaceName, {
163+
+ configurable: true,
164+
+ writable: true,
165+
+ value: SubmitEvent
166+
+ });
167+
+};
168+
+
169+
+const Impl = require("../events/SubmitEvent-impl.js");
170+
diff --git a/lib/jsdom/living/generated/SubmitEventInit.js b/lib/jsdom/living/generated/SubmitEventInit.js
171+
new file mode 100644
172+
index 0000000000000000000000000000000000000000..a911318c72571a1e4c8e866cb74e997c7744d461
173+
--- /dev/null
174+
+++ b/lib/jsdom/living/generated/SubmitEventInit.js
175+
@@ -0,0 +1,36 @@
176+
+"use strict";
177+
+
178+
+const conversions = require("webidl-conversions");
179+
+const utils = require("./utils.js");
180+
+
181+
+const HTMLElement = require("./HTMLElement.js");
182+
+const EventInit = require("./EventInit.js");
183+
+
184+
+exports._convertInherit = (globalObject, obj, ret, { context = "The provided value" } = {}) => {
185+
+ EventInit._convertInherit(globalObject, obj, ret, { context });
186+
+
187+
+ {
188+
+ const key = "submitter";
189+
+ let value = obj === undefined || obj === null ? undefined : obj[key];
190+
+ if (value !== undefined) {
191+
+ if (value === null || value === undefined) {
192+
+ value = null;
193+
+ } else {
194+
+ value = HTMLElement.convert(globalObject, value, { context: context + " has member 'submitter' that" });
195+
+ }
196+
+ ret[key] = value;
197+
+ } else {
198+
+ ret[key] = null;
199+
+ }
200+
+ }
201+
+};
202+
+
203+
+exports.convert = (globalObject, obj, { context = "The provided value" } = {}) => {
204+
+ if (obj !== undefined && typeof obj !== "object" && typeof obj !== "function") {
205+
+ throw new globalObject.TypeError(`${context} is not an object.`);
206+
+ }
207+
+
208+
+ const ret = Object.create(null);
209+
+ exports._convertInherit(globalObject, obj, ret, { context });
210+
+ return ret;
211+
+};
212+
diff --git a/lib/jsdom/living/interfaces.js b/lib/jsdom/living/interfaces.js
213+
index d64eafb729fbe99e75ccc7697ecdd818d5a20f00..9c766b0dd08b13a322e8efe57ab137e84504b723 100644
214+
--- a/lib/jsdom/living/interfaces.js
215+
+++ b/lib/jsdom/living/interfaces.js
216+
@@ -130,6 +130,7 @@ const generatedInterfaces = {
217+
StorageEvent: require("./generated/StorageEvent"),
218+
ProgressEvent: require("./generated/ProgressEvent"),
219+
PageTransitionEvent: require("./generated/PageTransitionEvent"),
220+
+ SubmitEvent: require("./generated/SubmitEvent"),
221+
222+
UIEvent: require("./generated/UIEvent"),
223+
FocusEvent: require("./generated/FocusEvent"),
224+
diff --git a/lib/jsdom/living/nodes/HTMLFormElement-impl.js b/lib/jsdom/living/nodes/HTMLFormElement-impl.js
225+
index 1ab508a6f27445171b8143374ff1fae24f3bbfa6..d611fa3243e3c452d8625ba2c79c29a2b82e5e82 100644
226+
--- a/lib/jsdom/living/nodes/HTMLFormElement-impl.js
227+
+++ b/lib/jsdom/living/nodes/HTMLFormElement-impl.js
228+
@@ -9,6 +9,7 @@ const { formOwner, isListed, isSubmittable, isSubmitButton } = require("../helpe
229+
const HTMLFormControlsCollection = require("../generated/HTMLFormControlsCollection");
230+
const notImplemented = require("../../browser/not-implemented");
231+
const { parseURLToResultingURLRecord } = require("../helpers/document-base-url");
232+
+const SubmitEvent = require("../generated/SubmitEvent");
233+
234+
const encTypes = new Set([
235+
"application/x-www-form-urlencoded",
236+
@@ -87,8 +88,8 @@ class HTMLFormElementImpl extends HTMLElementImpl {
237+
notImplemented("HTMLFormElement.prototype.submit", this._ownerDocument._defaultView);
238+
}
239+
240+
- requestSubmit(submitter = undefined) {
241+
- if (submitter !== undefined) {
242+
+ requestSubmit(submitter = null) {
243+
+ if (submitter !== null) {
244+
if (!isSubmitButton(submitter)) {
245+
throw new TypeError("The specified element is not a submit button");
246+
}
247+
@@ -106,7 +107,7 @@ class HTMLFormElementImpl extends HTMLElementImpl {
248+
return;
249+
}
250+
251+
- if (!fireAnEvent("submit", this, undefined, { bubbles: true, cancelable: true })) {
252+
+ if (!fireAnEvent("submit", this, SubmitEvent, { bubbles: true, cancelable: true, submitter })) {
253+
return;
254+
}
255+

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,8 @@
170170
"resolutions": {
171171
"[email protected]": "patch:mq-polyfill@npm:1.1.8#.yarn/patches/mq-polyfill-npm-1.1.8-62fe162439.patch",
172172
"react-error-overlay": "6.0.9",
173-
"react-dev-utils@^12.0.1": "patch:react-dev-utils@npm:12.0.1#.yarn/patches/react-dev-utils-npm-12.0.1-83ba06e3ee.patch"
173+
"react-dev-utils@^12.0.1": "patch:react-dev-utils@npm:12.0.1#.yarn/patches/react-dev-utils-npm-12.0.1-83ba06e3ee.patch",
174+
"jsdom@^20.0.0": "patch:jsdom@npm%3A20.0.0#./.yarn/patches/jsdom-npm-20.0.0-9c1ad43ab8.patch"
174175
},
175176
"jest": {
176177
"roots": [

yarn.lock

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10923,7 +10923,7 @@ __metadata:
1092310923
languageName: node
1092410924
linkType: hard
1092510925

10926-
"jsdom@npm:^20.0.0":
10926+
"jsdom@npm:20.0.0":
1092710927
version: 20.0.0
1092810928
resolution: "jsdom@npm:20.0.0"
1092910929
dependencies:
@@ -10963,6 +10963,46 @@ __metadata:
1096310963
languageName: node
1096410964
linkType: hard
1096510965

10966+
"jsdom@patch:jsdom@npm%3A20.0.0#./.yarn/patches/jsdom-npm-20.0.0-9c1ad43ab8.patch::locator=%40pybricks%2Fpybricks-code%40workspace%3A.":
10967+
version: 20.0.0
10968+
resolution: "jsdom@patch:jsdom@npm%3A20.0.0#./.yarn/patches/jsdom-npm-20.0.0-9c1ad43ab8.patch::version=20.0.0&hash=37efc2&locator=%40pybricks%2Fpybricks-code%40workspace%3A."
10969+
dependencies:
10970+
abab: ^2.0.6
10971+
acorn: ^8.7.1
10972+
acorn-globals: ^6.0.0
10973+
cssom: ^0.5.0
10974+
cssstyle: ^2.3.0
10975+
data-urls: ^3.0.2
10976+
decimal.js: ^10.3.1
10977+
domexception: ^4.0.0
10978+
escodegen: ^2.0.0
10979+
form-data: ^4.0.0
10980+
html-encoding-sniffer: ^3.0.0
10981+
http-proxy-agent: ^5.0.0
10982+
https-proxy-agent: ^5.0.1
10983+
is-potential-custom-element-name: ^1.0.1
10984+
nwsapi: ^2.2.0
10985+
parse5: ^7.0.0
10986+
saxes: ^6.0.0
10987+
symbol-tree: ^3.2.4
10988+
tough-cookie: ^4.0.0
10989+
w3c-hr-time: ^1.0.2
10990+
w3c-xmlserializer: ^3.0.0
10991+
webidl-conversions: ^7.0.0
10992+
whatwg-encoding: ^2.0.0
10993+
whatwg-mimetype: ^3.0.0
10994+
whatwg-url: ^11.0.0
10995+
ws: ^8.8.0
10996+
xml-name-validator: ^4.0.0
10997+
peerDependencies:
10998+
canvas: ^2.5.0
10999+
peerDependenciesMeta:
11000+
canvas:
11001+
optional: true
11002+
checksum: 642f7fee80de51473cde95ce683d9c10ff7e97971dcb9b0cf1743d9ec49755c8fbaa3fecf23a6d54b2da1646234970aa0d30011620d381eb8b6fa465013d1966
11003+
languageName: node
11004+
linkType: hard
11005+
1096611006
"jsesc@npm:^2.5.1":
1096711007
version: 2.5.2
1096811008
resolution: "jsesc@npm:2.5.2"

0 commit comments

Comments
 (0)