Event.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430
  1. "use strict";
  2. const conversions = require("webidl-conversions");
  3. const utils = require("./utils.js");
  4. const EventInit = require("./EventInit.js");
  5. const implSymbol = utils.implSymbol;
  6. const ctorRegistrySymbol = utils.ctorRegistrySymbol;
  7. const interfaceName = "Event";
  8. exports.is = value => {
  9. return utils.isObject(value) && Object.hasOwn(value, implSymbol) && value[implSymbol] instanceof Impl.implementation;
  10. };
  11. exports.isImpl = value => {
  12. return utils.isObject(value) && value instanceof Impl.implementation;
  13. };
  14. exports.convert = (globalObject, value, { context = "The provided value" } = {}) => {
  15. if (exports.is(value)) {
  16. return utils.implForWrapper(value);
  17. }
  18. throw new globalObject.TypeError(`${context} is not of type 'Event'.`);
  19. };
  20. function makeWrapper(globalObject, newTarget) {
  21. let proto;
  22. if (newTarget !== undefined) {
  23. proto = newTarget.prototype;
  24. }
  25. if (!utils.isObject(proto)) {
  26. proto = globalObject[ctorRegistrySymbol]["Event"].prototype;
  27. }
  28. return Object.create(proto);
  29. }
  30. exports.create = (globalObject, constructorArgs, privateData) => {
  31. const wrapper = makeWrapper(globalObject);
  32. return exports.setup(wrapper, globalObject, constructorArgs, privateData);
  33. };
  34. exports.createImpl = (globalObject, constructorArgs, privateData) => {
  35. const wrapper = exports.create(globalObject, constructorArgs, privateData);
  36. return utils.implForWrapper(wrapper);
  37. };
  38. function getUnforgeables(globalObject) {
  39. let unforgeables = unforgeablesMap.get(globalObject);
  40. if (unforgeables === undefined) {
  41. unforgeables = Object.create(null);
  42. utils.define(unforgeables, {
  43. get isTrusted() {
  44. const esValue = this !== null && this !== undefined ? this : globalObject;
  45. if (!exports.is(esValue)) {
  46. throw new globalObject.TypeError(
  47. "'get isTrusted' called on an object that is not a valid instance of Event."
  48. );
  49. }
  50. return esValue[implSymbol]["isTrusted"];
  51. }
  52. });
  53. Object.defineProperties(unforgeables, {
  54. isTrusted: { configurable: false }
  55. });
  56. unforgeablesMap.set(globalObject, unforgeables);
  57. }
  58. return unforgeables;
  59. }
  60. exports._internalSetup = (wrapper, globalObject) => {
  61. utils.define(wrapper, getUnforgeables(globalObject));
  62. };
  63. exports.setup = (wrapper, globalObject, constructorArgs = [], privateData = {}) => {
  64. privateData.wrapper = wrapper;
  65. exports._internalSetup(wrapper, globalObject);
  66. Object.defineProperty(wrapper, implSymbol, {
  67. value: new Impl.implementation(globalObject, constructorArgs, privateData),
  68. configurable: true
  69. });
  70. wrapper[implSymbol][utils.wrapperSymbol] = wrapper;
  71. if (Impl.init) {
  72. Impl.init(wrapper[implSymbol]);
  73. }
  74. return wrapper;
  75. };
  76. exports.new = (globalObject, newTarget) => {
  77. const wrapper = makeWrapper(globalObject, newTarget);
  78. exports._internalSetup(wrapper, globalObject);
  79. Object.defineProperty(wrapper, implSymbol, {
  80. value: Object.create(Impl.implementation.prototype),
  81. configurable: true
  82. });
  83. wrapper[implSymbol][utils.wrapperSymbol] = wrapper;
  84. if (Impl.init) {
  85. Impl.init(wrapper[implSymbol]);
  86. }
  87. return wrapper[implSymbol];
  88. };
  89. const unforgeablesMap = new WeakMap();
  90. const exposed = new Set(["Window", "Worker", "AudioWorklet"]);
  91. exports.install = (globalObject, globalNames) => {
  92. if (!globalNames.some(globalName => exposed.has(globalName))) {
  93. return;
  94. }
  95. const ctorRegistry = utils.initCtorRegistry(globalObject);
  96. class Event {
  97. constructor(type) {
  98. if (arguments.length < 1) {
  99. throw new globalObject.TypeError(
  100. `Failed to construct 'Event': 1 argument required, but only ${arguments.length} present.`
  101. );
  102. }
  103. const args = [];
  104. {
  105. let curArg = arguments[0];
  106. curArg = conversions["DOMString"](curArg, {
  107. context: "Failed to construct 'Event': parameter 1",
  108. globals: globalObject
  109. });
  110. args.push(curArg);
  111. }
  112. {
  113. let curArg = arguments[1];
  114. curArg = EventInit.convert(globalObject, curArg, { context: "Failed to construct 'Event': parameter 2" });
  115. args.push(curArg);
  116. }
  117. return exports.setup(Object.create(new.target.prototype), globalObject, args);
  118. }
  119. composedPath() {
  120. const esValue = this !== null && this !== undefined ? this : globalObject;
  121. if (!exports.is(esValue)) {
  122. throw new globalObject.TypeError("'composedPath' called on an object that is not a valid instance of Event.");
  123. }
  124. return utils.tryWrapperForImpl(esValue[implSymbol].composedPath());
  125. }
  126. stopPropagation() {
  127. const esValue = this !== null && this !== undefined ? this : globalObject;
  128. if (!exports.is(esValue)) {
  129. throw new globalObject.TypeError(
  130. "'stopPropagation' called on an object that is not a valid instance of Event."
  131. );
  132. }
  133. return esValue[implSymbol].stopPropagation();
  134. }
  135. stopImmediatePropagation() {
  136. const esValue = this !== null && this !== undefined ? this : globalObject;
  137. if (!exports.is(esValue)) {
  138. throw new globalObject.TypeError(
  139. "'stopImmediatePropagation' called on an object that is not a valid instance of Event."
  140. );
  141. }
  142. return esValue[implSymbol].stopImmediatePropagation();
  143. }
  144. preventDefault() {
  145. const esValue = this !== null && this !== undefined ? this : globalObject;
  146. if (!exports.is(esValue)) {
  147. throw new globalObject.TypeError("'preventDefault' called on an object that is not a valid instance of Event.");
  148. }
  149. return esValue[implSymbol].preventDefault();
  150. }
  151. initEvent(type) {
  152. const esValue = this !== null && this !== undefined ? this : globalObject;
  153. if (!exports.is(esValue)) {
  154. throw new globalObject.TypeError("'initEvent' called on an object that is not a valid instance of Event.");
  155. }
  156. if (arguments.length < 1) {
  157. throw new globalObject.TypeError(
  158. `Failed to execute 'initEvent' on 'Event': 1 argument required, but only ${arguments.length} present.`
  159. );
  160. }
  161. const args = [];
  162. {
  163. let curArg = arguments[0];
  164. curArg = conversions["DOMString"](curArg, {
  165. context: "Failed to execute 'initEvent' on 'Event': parameter 1",
  166. globals: globalObject
  167. });
  168. args.push(curArg);
  169. }
  170. {
  171. let curArg = arguments[1];
  172. if (curArg !== undefined) {
  173. curArg = conversions["boolean"](curArg, {
  174. context: "Failed to execute 'initEvent' on 'Event': parameter 2",
  175. globals: globalObject
  176. });
  177. } else {
  178. curArg = false;
  179. }
  180. args.push(curArg);
  181. }
  182. {
  183. let curArg = arguments[2];
  184. if (curArg !== undefined) {
  185. curArg = conversions["boolean"](curArg, {
  186. context: "Failed to execute 'initEvent' on 'Event': parameter 3",
  187. globals: globalObject
  188. });
  189. } else {
  190. curArg = false;
  191. }
  192. args.push(curArg);
  193. }
  194. return esValue[implSymbol].initEvent(...args);
  195. }
  196. get type() {
  197. const esValue = this !== null && this !== undefined ? this : globalObject;
  198. if (!exports.is(esValue)) {
  199. throw new globalObject.TypeError("'get type' called on an object that is not a valid instance of Event.");
  200. }
  201. return esValue[implSymbol]["type"];
  202. }
  203. get target() {
  204. const esValue = this !== null && this !== undefined ? this : globalObject;
  205. if (!exports.is(esValue)) {
  206. throw new globalObject.TypeError("'get target' called on an object that is not a valid instance of Event.");
  207. }
  208. return utils.tryWrapperForImpl(esValue[implSymbol]["target"]);
  209. }
  210. get srcElement() {
  211. const esValue = this !== null && this !== undefined ? this : globalObject;
  212. if (!exports.is(esValue)) {
  213. throw new globalObject.TypeError("'get srcElement' called on an object that is not a valid instance of Event.");
  214. }
  215. return utils.tryWrapperForImpl(esValue[implSymbol]["srcElement"]);
  216. }
  217. get currentTarget() {
  218. const esValue = this !== null && this !== undefined ? this : globalObject;
  219. if (!exports.is(esValue)) {
  220. throw new globalObject.TypeError(
  221. "'get currentTarget' called on an object that is not a valid instance of Event."
  222. );
  223. }
  224. return utils.tryWrapperForImpl(esValue[implSymbol]["currentTarget"]);
  225. }
  226. get eventPhase() {
  227. const esValue = this !== null && this !== undefined ? this : globalObject;
  228. if (!exports.is(esValue)) {
  229. throw new globalObject.TypeError("'get eventPhase' called on an object that is not a valid instance of Event.");
  230. }
  231. return esValue[implSymbol]["eventPhase"];
  232. }
  233. get cancelBubble() {
  234. const esValue = this !== null && this !== undefined ? this : globalObject;
  235. if (!exports.is(esValue)) {
  236. throw new globalObject.TypeError(
  237. "'get cancelBubble' called on an object that is not a valid instance of Event."
  238. );
  239. }
  240. return esValue[implSymbol]["cancelBubble"];
  241. }
  242. set cancelBubble(V) {
  243. const esValue = this !== null && this !== undefined ? this : globalObject;
  244. if (!exports.is(esValue)) {
  245. throw new globalObject.TypeError(
  246. "'set cancelBubble' called on an object that is not a valid instance of Event."
  247. );
  248. }
  249. V = conversions["boolean"](V, {
  250. context: "Failed to set the 'cancelBubble' property on 'Event': The provided value",
  251. globals: globalObject
  252. });
  253. esValue[implSymbol]["cancelBubble"] = V;
  254. }
  255. get bubbles() {
  256. const esValue = this !== null && this !== undefined ? this : globalObject;
  257. if (!exports.is(esValue)) {
  258. throw new globalObject.TypeError("'get bubbles' called on an object that is not a valid instance of Event.");
  259. }
  260. return esValue[implSymbol]["bubbles"];
  261. }
  262. get cancelable() {
  263. const esValue = this !== null && this !== undefined ? this : globalObject;
  264. if (!exports.is(esValue)) {
  265. throw new globalObject.TypeError("'get cancelable' called on an object that is not a valid instance of Event.");
  266. }
  267. return esValue[implSymbol]["cancelable"];
  268. }
  269. get returnValue() {
  270. const esValue = this !== null && this !== undefined ? this : globalObject;
  271. if (!exports.is(esValue)) {
  272. throw new globalObject.TypeError(
  273. "'get returnValue' called on an object that is not a valid instance of Event."
  274. );
  275. }
  276. return esValue[implSymbol]["returnValue"];
  277. }
  278. set returnValue(V) {
  279. const esValue = this !== null && this !== undefined ? this : globalObject;
  280. if (!exports.is(esValue)) {
  281. throw new globalObject.TypeError(
  282. "'set returnValue' called on an object that is not a valid instance of Event."
  283. );
  284. }
  285. V = conversions["boolean"](V, {
  286. context: "Failed to set the 'returnValue' property on 'Event': The provided value",
  287. globals: globalObject
  288. });
  289. esValue[implSymbol]["returnValue"] = V;
  290. }
  291. get defaultPrevented() {
  292. const esValue = this !== null && this !== undefined ? this : globalObject;
  293. if (!exports.is(esValue)) {
  294. throw new globalObject.TypeError(
  295. "'get defaultPrevented' called on an object that is not a valid instance of Event."
  296. );
  297. }
  298. return esValue[implSymbol]["defaultPrevented"];
  299. }
  300. get composed() {
  301. const esValue = this !== null && this !== undefined ? this : globalObject;
  302. if (!exports.is(esValue)) {
  303. throw new globalObject.TypeError("'get composed' called on an object that is not a valid instance of Event.");
  304. }
  305. return esValue[implSymbol]["composed"];
  306. }
  307. get timeStamp() {
  308. const esValue = this !== null && this !== undefined ? this : globalObject;
  309. if (!exports.is(esValue)) {
  310. throw new globalObject.TypeError("'get timeStamp' called on an object that is not a valid instance of Event.");
  311. }
  312. return esValue[implSymbol]["timeStamp"];
  313. }
  314. }
  315. Object.defineProperties(Event.prototype, {
  316. composedPath: { enumerable: true },
  317. stopPropagation: { enumerable: true },
  318. stopImmediatePropagation: { enumerable: true },
  319. preventDefault: { enumerable: true },
  320. initEvent: { enumerable: true },
  321. type: { enumerable: true },
  322. target: { enumerable: true },
  323. srcElement: { enumerable: true },
  324. currentTarget: { enumerable: true },
  325. eventPhase: { enumerable: true },
  326. cancelBubble: { enumerable: true },
  327. bubbles: { enumerable: true },
  328. cancelable: { enumerable: true },
  329. returnValue: { enumerable: true },
  330. defaultPrevented: { enumerable: true },
  331. composed: { enumerable: true },
  332. timeStamp: { enumerable: true },
  333. [Symbol.toStringTag]: { value: "Event", configurable: true },
  334. NONE: { value: 0, enumerable: true },
  335. CAPTURING_PHASE: { value: 1, enumerable: true },
  336. AT_TARGET: { value: 2, enumerable: true },
  337. BUBBLING_PHASE: { value: 3, enumerable: true }
  338. });
  339. Object.defineProperties(Event, {
  340. NONE: { value: 0, enumerable: true },
  341. CAPTURING_PHASE: { value: 1, enumerable: true },
  342. AT_TARGET: { value: 2, enumerable: true },
  343. BUBBLING_PHASE: { value: 3, enumerable: true }
  344. });
  345. ctorRegistry[interfaceName] = Event;
  346. Object.defineProperty(globalObject, interfaceName, {
  347. configurable: true,
  348. writable: true,
  349. value: Event
  350. });
  351. };
  352. const Impl = require("../../jsdom/living/events/Event-impl.js");