@angular/core 18.0.0-rc.1 → 18.0.0-rc.2

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.
Files changed (59) hide show
  1. package/esm2022/primitives/event-dispatch/contract_binary.mjs +3 -3
  2. package/esm2022/primitives/event-dispatch/index.mjs +2 -2
  3. package/esm2022/primitives/event-dispatch/src/action_resolver.mjs +5 -18
  4. package/esm2022/primitives/event-dispatch/src/attribute.mjs +63 -65
  5. package/esm2022/primitives/event-dispatch/src/cache.mjs +10 -10
  6. package/esm2022/primitives/event-dispatch/src/dispatcher.mjs +50 -181
  7. package/esm2022/primitives/event-dispatch/src/earlyeventcontract.mjs +4 -4
  8. package/esm2022/primitives/event-dispatch/src/event_contract_defines.mjs +1 -6
  9. package/esm2022/primitives/event-dispatch/src/eventcontract.mjs +13 -30
  10. package/esm2022/primitives/event-dispatch/src/key_code.mjs +11 -13
  11. package/esm2022/primitives/event-dispatch/src/legacy_dispatcher.mjs +252 -2
  12. package/esm2022/primitives/event-dispatch/src/property.mjs +30 -27
  13. package/esm2022/primitives/event-dispatch/src/register_events.mjs +5 -25
  14. package/esm2022/primitives/event-dispatch/src/restriction.mjs +2 -2
  15. package/esm2022/src/application/create_application.mjs +11 -4
  16. package/esm2022/src/change_detection/scheduling/ng_zone_scheduling.mjs +4 -16
  17. package/esm2022/src/change_detection/scheduling/zoneless_scheduling.mjs +3 -1
  18. package/esm2022/src/change_detection/scheduling/zoneless_scheduling_impl.mjs +5 -2
  19. package/esm2022/src/core_reactivity_export_internal.mjs +1 -3
  20. package/esm2022/src/core_render3_private_export.mjs +1 -3
  21. package/esm2022/src/hydration/event_replay.mjs +51 -83
  22. package/esm2022/src/hydration/utils.mjs +1 -2
  23. package/esm2022/src/metadata/directives.mjs +1 -1
  24. package/esm2022/src/platform/platform_ref.mjs +9 -10
  25. package/esm2022/src/render3/component_ref.mjs +1 -1
  26. package/esm2022/src/render3/index.mjs +1 -3
  27. package/esm2022/src/render3/instructions/listener.mjs +3 -3
  28. package/esm2022/src/render3/interfaces/public_definitions.mjs +1 -1
  29. package/esm2022/src/version.mjs +1 -1
  30. package/esm2022/testing/src/component_fixture.mjs +2 -2
  31. package/esm2022/testing/src/logger.mjs +3 -3
  32. package/esm2022/testing/src/test_bed.mjs +1 -3
  33. package/esm2022/testing/src/test_bed_compiler.mjs +1 -3
  34. package/event-dispatch-contract.min.js +1 -1
  35. package/fesm2022/core.mjs +79 -117
  36. package/fesm2022/core.mjs.map +1 -1
  37. package/fesm2022/primitives/event-dispatch.mjs +246 -515
  38. package/fesm2022/primitives/event-dispatch.mjs.map +1 -1
  39. package/fesm2022/primitives/signals.mjs +1 -1
  40. package/fesm2022/rxjs-interop.mjs +1 -1
  41. package/fesm2022/testing.mjs +2 -4
  42. package/fesm2022/testing.mjs.map +1 -1
  43. package/index.d.ts +3 -1
  44. package/package.json +1 -1
  45. package/primitives/event-dispatch/index.d.ts +83 -131
  46. package/primitives/signals/index.d.ts +1 -1
  47. package/rxjs-interop/index.d.ts +1 -1
  48. package/schematics/migrations/http-providers/bundle.js +46 -29
  49. package/schematics/migrations/http-providers/bundle.js.map +3 -3
  50. package/schematics/migrations/invalid-two-way-bindings/bundle.js +159 -159
  51. package/schematics/migrations/invalid-two-way-bindings/bundle.js.map +2 -2
  52. package/schematics/ng-generate/control-flow-migration/bundle.js +167 -167
  53. package/schematics/ng-generate/control-flow-migration/bundle.js.map +2 -2
  54. package/schematics/ng-generate/standalone-migration/bundle.js +443 -443
  55. package/schematics/ng-generate/standalone-migration/bundle.js.map +2 -2
  56. package/testing/index.d.ts +1 -1
  57. package/esm2022/primitives/event-dispatch/src/base_dispatcher.mjs +0 -94
  58. package/esm2022/primitives/event-dispatch/src/custom_events.mjs +0 -102
  59. package/esm2022/primitives/event-dispatch/src/replay.mjs +0 -389
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Angular v18.0.0-rc.1
2
+ * @license Angular v18.0.0-rc.2
3
3
  * (c) 2010-2024 Google LLC. https://angular.io/
4
4
  * License: MIT
5
5
  */
@@ -196,168 +196,6 @@ class EventInfoWrapper {
196
196
  }
197
197
  }
198
198
 
199
- /**
200
- * @fileoverview An enum to control who can call certain jsaction APIs.
201
- */
202
- var Restriction;
203
- (function (Restriction) {
204
- Restriction[Restriction["I_AM_THE_JSACTION_FRAMEWORK"] = 1] = "I_AM_THE_JSACTION_FRAMEWORK";
205
- })(Restriction || (Restriction = {}));
206
-
207
- /**
208
- * Receives a DOM event, determines the jsaction associated with the source
209
- * element of the DOM event, and invokes the handler associated with the
210
- * jsaction.
211
- */
212
- class BaseDispatcher {
213
- /**
214
- * Options are:
215
- * 1. `eventReplayer`: When the event contract dispatches replay events
216
- * to the Dispatcher, the Dispatcher collects them and in the next tick
217
- * dispatches them to the `eventReplayer`.
218
- * @param dispatchDelegate A function that should handle dispatching an `EventInfoWrapper` to handlers.
219
- */
220
- constructor(dispatchDelegate, { eventReplayer = undefined } = {}) {
221
- this.dispatchDelegate = dispatchDelegate;
222
- /** The queue of events. */
223
- this.queuedEventInfoWrappers = [];
224
- /** Whether the event replay is scheduled. */
225
- this.eventReplayScheduled = false;
226
- this.eventReplayer = eventReplayer;
227
- }
228
- /**
229
- * Receives an event or the event queue from the EventContract. The event
230
- * queue is copied and it attempts to replay.
231
- * If event info is passed in it looks for an action handler that can handle
232
- * the given event. If there is no handler registered queues the event and
233
- * checks if a loader is registered for the given namespace. If so, calls it.
234
- *
235
- * Alternatively, if in global dispatch mode, calls all registered global
236
- * handlers for the appropriate event type.
237
- *
238
- * The three functionalities of this call are deliberately not split into
239
- * three methods (and then declared as an abstract interface), because the
240
- * interface is used by EventContract, which lives in a different jsbinary.
241
- * Therefore the interface between the three is defined entirely in terms that
242
- * are invariant under jscompiler processing (Function and Array, as opposed
243
- * to a custom type with method names).
244
- *
245
- * @param eventInfo The info for the event that triggered this call or the
246
- * queue of events from EventContract.
247
- */
248
- dispatch(eventInfo) {
249
- const eventInfoWrapper = new EventInfoWrapper(eventInfo);
250
- if (eventInfoWrapper.getIsReplay()) {
251
- if (!this.eventReplayer) {
252
- return;
253
- }
254
- this.queueEventInfoWrapper(eventInfoWrapper);
255
- this.scheduleEventReplay();
256
- return;
257
- }
258
- this.dispatchDelegate(eventInfoWrapper);
259
- }
260
- /** Queue an `EventInfoWrapper` for replay. */
261
- queueEventInfoWrapper(eventInfoWrapper) {
262
- this.queuedEventInfoWrappers.push(eventInfoWrapper);
263
- }
264
- /**
265
- * Replays queued events, if any. The replaying will happen in its own
266
- * stack once the current flow cedes control. This is done to mimic
267
- * browser event handling.
268
- */
269
- scheduleEventReplay() {
270
- if (this.eventReplayScheduled ||
271
- !this.eventReplayer ||
272
- this.queuedEventInfoWrappers.length === 0) {
273
- return;
274
- }
275
- this.eventReplayScheduled = true;
276
- Promise.resolve().then(() => {
277
- this.eventReplayScheduled = false;
278
- this.eventReplayer(this.queuedEventInfoWrappers);
279
- });
280
- }
281
- }
282
- /**
283
- * Registers deferred functionality for an EventContract and a Jsaction
284
- * Dispatcher.
285
- */
286
- function registerDispatcher$1(eventContract, dispatcher) {
287
- eventContract.ecrd((eventInfo) => {
288
- dispatcher.dispatch(eventInfo);
289
- }, Restriction.I_AM_THE_JSACTION_FRAMEWORK);
290
- }
291
-
292
- const Char = {
293
- /**
294
- * The separator between the namespace and the action name in the
295
- * jsaction attribute value.
296
- */
297
- NAMESPACE_ACTION_SEPARATOR: '.',
298
- /**
299
- * The separator between the event name and action in the jsaction
300
- * attribute value.
301
- */
302
- EVENT_ACTION_SEPARATOR: ':',
303
- /**
304
- * The separator between the logged oi attribute values in the &oi=
305
- * URL parameter value.
306
- */
307
- OI_SEPARATOR: '.',
308
- /**
309
- * The separator between the key and the value pairs in the &cad=
310
- * URL parameter value.
311
- */
312
- CAD_KEY_VALUE_SEPARATOR: ':',
313
- /**
314
- * The separator between the key-value pairs in the &cad= URL
315
- * parameter value.
316
- */
317
- CAD_SEPARATOR: ',',
318
- };
319
-
320
- /**
321
- * Determines if one node is contained within another. Adapted from
322
- * {@see goog.dom.contains}.
323
- * @param node Node that should contain otherNode.
324
- * @param otherNode Node being contained.
325
- * @return True if otherNode is contained within node.
326
- */
327
- function contains(node, otherNode) {
328
- if (otherNode === null) {
329
- return false;
330
- }
331
- // We use browser specific methods for this if available since it is faster
332
- // that way.
333
- // IE DOM
334
- if ('contains' in node && otherNode.nodeType === 1) {
335
- return node.contains(otherNode);
336
- }
337
- // W3C DOM Level 3
338
- if ('compareDocumentPosition' in node) {
339
- return node === otherNode || Boolean(node.compareDocumentPosition(otherNode) & 16);
340
- }
341
- // W3C DOM Level 1
342
- while (otherNode && node !== otherNode) {
343
- otherNode = otherNode.parentNode;
344
- }
345
- return otherNode === node;
346
- }
347
- /**
348
- * Helper method for broadcastCustomEvent. Returns true if any member of
349
- * the set is an ancestor of element.
350
- */
351
- function hasAncestorInNodeList(element, nodeList) {
352
- for (let idx = 0; idx < nodeList.length; ++idx) {
353
- const member = nodeList[idx];
354
- if (member !== element && contains(member, element)) {
355
- return true;
356
- }
357
- }
358
- return false;
359
- }
360
-
361
199
  /*
362
200
  * Names of events that are special to jsaction. These are not all
363
201
  * event types that are legal to use in either HTML or the addEvent()
@@ -595,19 +433,66 @@ const EventType = {
595
433
  CUSTOM: '_custom',
596
434
  };
597
435
 
436
+ /**
437
+ * @fileoverview An enum to control who can call certain jsaction APIs.
438
+ */
439
+ var Restriction;
440
+ (function (Restriction) {
441
+ Restriction[Restriction["I_AM_THE_JSACTION_FRAMEWORK"] = 0] = "I_AM_THE_JSACTION_FRAMEWORK";
442
+ })(Restriction || (Restriction = {}));
443
+
444
+ /**
445
+ * Determines if one node is contained within another. Adapted from
446
+ * {@see goog.dom.contains}.
447
+ * @param node Node that should contain otherNode.
448
+ * @param otherNode Node being contained.
449
+ * @return True if otherNode is contained within node.
450
+ */
451
+ function contains(node, otherNode) {
452
+ if (otherNode === null) {
453
+ return false;
454
+ }
455
+ // We use browser specific methods for this if available since it is faster
456
+ // that way.
457
+ // IE DOM
458
+ if ('contains' in node && otherNode.nodeType === 1) {
459
+ return node.contains(otherNode);
460
+ }
461
+ // W3C DOM Level 3
462
+ if ('compareDocumentPosition' in node) {
463
+ return node === otherNode || Boolean(node.compareDocumentPosition(otherNode) & 16);
464
+ }
465
+ // W3C DOM Level 1
466
+ while (otherNode && node !== otherNode) {
467
+ otherNode = otherNode.parentNode;
468
+ }
469
+ return otherNode === node;
470
+ }
471
+ /**
472
+ * Helper method for broadcastCustomEvent. Returns true if any member of
473
+ * the set is an ancestor of element.
474
+ */
475
+ function hasAncestorInNodeList(element, nodeList) {
476
+ for (let idx = 0; idx < nodeList.length; ++idx) {
477
+ const member = nodeList[idx];
478
+ if (member !== element && contains(member, element)) {
479
+ return true;
480
+ }
481
+ }
482
+ return false;
483
+ }
484
+
485
+ /**
486
+ * If on a Macintosh with an extended keyboard, the Enter key located in the
487
+ * numeric pad has a different ASCII code.
488
+ */
489
+ const MAC_ENTER = 3;
490
+ /** The Enter key. */
491
+ const ENTER = 13;
492
+ /** The Space key. */
493
+ const SPACE = 32;
598
494
  /** Special keycodes used by jsaction for the generic click action. */
599
- var KeyCode;
600
- (function (KeyCode) {
601
- /**
602
- * If on a Macintosh with an extended keyboard, the Enter key located in the
603
- * numeric pad has a different ASCII code.
604
- */
605
- KeyCode[KeyCode["MAC_ENTER"] = 3] = "MAC_ENTER";
606
- /** The Enter key. */
607
- KeyCode[KeyCode["ENTER"] = 13] = "ENTER";
608
- /** The Space key. */
609
- KeyCode[KeyCode["SPACE"] = 32] = "SPACE";
610
- })(KeyCode || (KeyCode = {}));
495
+ const KeyCode = { MAC_ENTER, ENTER, SPACE };
611
496
 
612
497
  /**
613
498
  * Gets a browser event type, if it would differ from the JSAction event type.
@@ -1244,32 +1129,20 @@ const testing = {
1244
1129
  */
1245
1130
  class Dispatcher {
1246
1131
  /**
1247
- * Receives a DOM event, determines the jsaction associated with the source
1248
- * element of the DOM event, and invokes the handler associated with the
1249
- * jsaction.
1250
- *
1251
- * @param getHandler A function that knows how to get the handler for a
1252
- * given event info.
1132
+ * Options are:
1133
+ * 1. `eventReplayer`: When the event contract dispatches replay events
1134
+ * to the Dispatcher, the Dispatcher collects them and in the next tick
1135
+ * dispatches them to the `eventReplayer`.
1136
+ * @param dispatchDelegate A function that should handle dispatching an `EventInfoWrapper` to handlers.
1253
1137
  */
1254
- constructor(getHandler, { stopPropagation = false, eventReplayer = undefined, } = {}) {
1255
- this.getHandler = getHandler;
1256
- /**
1257
- * The actions that are registered for this Dispatcher instance.
1258
- * This should be the primary one used once migration off of registerHandlers
1259
- * is done.
1260
- */
1261
- this.actions = {};
1262
- /** A map of global event handlers, where each key is an event type. */
1263
- this.globalHandlers = new Map();
1138
+ constructor(dispatchDelegate, { actionResolver = undefined, eventReplayer = undefined, } = {}) {
1139
+ this.dispatchDelegate = dispatchDelegate;
1140
+ /** Whether the event replay is scheduled. */
1141
+ this.eventReplayScheduled = false;
1142
+ /** The queue of events. */
1143
+ this.replayEventInfoWrappers = [];
1144
+ this.actionResolver = actionResolver;
1264
1145
  this.eventReplayer = eventReplayer;
1265
- this.baseDispatcher = new BaseDispatcher((eventInfoWrapper) => {
1266
- this.dispatchToHandler(eventInfoWrapper);
1267
- }, {
1268
- eventReplayer: (eventInfoWrappers) => {
1269
- this.eventReplayer?.(eventInfoWrappers, this);
1270
- },
1271
- });
1272
- this.stopPropagation = stopPropagation;
1273
1146
  }
1274
1147
  /**
1275
1148
  * Receives an event or the event queue from the EventContract. The event
@@ -1291,167 +1164,37 @@ class Dispatcher {
1291
1164
  * @param eventInfo The info for the event that triggered this call or the
1292
1165
  * queue of events from EventContract.
1293
1166
  */
1294
- dispatch(eventInfo, isGlobalDispatch) {
1295
- this.baseDispatcher.dispatch(eventInfo);
1296
- }
1297
- /**
1298
- * Dispatches an `EventInfoWrapper`.
1299
- */
1300
- dispatchToHandler(eventInfoWrapper) {
1301
- if (this.globalHandlers.size) {
1302
- const globalEventInfoWrapper = eventInfoWrapper.clone();
1303
- // In some cases, `populateAction` will rewrite `click` events to
1304
- // `clickonly`. Revert back to a regular click, otherwise we won't be able
1305
- // to execute global event handlers registered on click events.
1306
- if (globalEventInfoWrapper.getEventType() === EventType.CLICKONLY) {
1307
- globalEventInfoWrapper.setEventType(EventType.CLICK);
1308
- }
1309
- // Skip everything related to jsaction handlers, and execute the global
1310
- // handlers.
1311
- const event = globalEventInfoWrapper.getEvent();
1312
- const eventTypeHandlers = this.globalHandlers.get(globalEventInfoWrapper.getEventType());
1313
- let shouldPreventDefault = false;
1314
- if (eventTypeHandlers) {
1315
- for (const handler of eventTypeHandlers) {
1316
- if (handler(event) === false) {
1317
- shouldPreventDefault = true;
1318
- }
1319
- }
1320
- }
1321
- if (shouldPreventDefault) {
1322
- preventDefault(event);
1323
- }
1324
- }
1167
+ dispatch(eventInfo) {
1168
+ const eventInfoWrapper = new EventInfoWrapper(eventInfo);
1169
+ this.actionResolver?.resolve(eventInfo);
1325
1170
  const action = eventInfoWrapper.getAction();
1326
- if (!action) {
1327
- return;
1328
- }
1329
- if (this.stopPropagation) {
1330
- stopPropagation(eventInfoWrapper);
1331
- }
1332
- let handler = undefined;
1333
- if (this.getHandler) {
1334
- handler = this.getHandler(eventInfoWrapper);
1335
- }
1336
- if (!handler) {
1337
- handler = this.actions[action.name];
1171
+ if (action && shouldPreventDefaultBeforeDispatching(action.element, eventInfoWrapper)) {
1172
+ preventDefault(eventInfoWrapper.getEvent());
1338
1173
  }
1339
- if (handler) {
1340
- handler(eventInfoWrapper);
1341
- return;
1342
- }
1343
- // No handler was found.
1344
- this.baseDispatcher.queueEventInfoWrapper(eventInfoWrapper);
1345
- }
1346
- /**
1347
- * Registers multiple methods all bound to the same object
1348
- * instance. This is a common case: an application module binds
1349
- * multiple of its methods under public names to the event contract of
1350
- * the application. So we provide a shortcut for it.
1351
- * Attempts to replay the queued events after registering the handlers.
1352
- *
1353
- * @param namespace The namespace of the jsaction name.
1354
- *
1355
- * @param instance The object to bind the methods to. If this is null, then
1356
- * the functions are not bound, but directly added under the public names.
1357
- *
1358
- * @param methods A map from public name to functions that will be bound to
1359
- * instance and registered as action under the public name. I.e. the
1360
- * property names are the public names. The property values are the
1361
- * methods of instance.
1362
- */
1363
- registerEventInfoHandlers(namespace, instance, methods) {
1364
- for (const [name, method] of Object.entries(methods)) {
1365
- const handler = instance ? method.bind(instance) : method;
1366
- if (namespace) {
1367
- // Include a '.' separator between namespace name and action name.
1368
- // In the case that no namespace name is provided, the jsaction name
1369
- // consists of the action name only (no period).
1370
- const fullName = namespace + Char.NAMESPACE_ACTION_SEPARATOR + name;
1371
- this.actions[fullName] = handler;
1372
- }
1373
- else {
1374
- this.actions[name] = handler;
1174
+ if (eventInfoWrapper.getIsReplay()) {
1175
+ if (!this.eventReplayer) {
1176
+ return;
1375
1177
  }
1178
+ this.scheduleEventInfoWrapperReplay(eventInfoWrapper);
1179
+ return;
1376
1180
  }
1377
- this.baseDispatcher.scheduleEventReplay();
1378
- }
1379
- /**
1380
- * Unregisters an action. Provided as an easy way to reverse the effects of
1381
- * registerHandlers.
1382
- * @param namespace The namespace of the jsaction name.
1383
- * @param name The action name to unbind.
1384
- */
1385
- unregisterHandler(namespace, name) {
1386
- const fullName = namespace ? namespace + Char.NAMESPACE_ACTION_SEPARATOR + name : name;
1387
- delete this.actions[fullName];
1388
- }
1389
- /** Registers a global event handler. */
1390
- registerGlobalHandler(eventType, handler) {
1391
- if (!this.globalHandlers.has(eventType)) {
1392
- this.globalHandlers.set(eventType, new Set([handler]));
1393
- }
1394
- else {
1395
- this.globalHandlers.get(eventType).add(handler);
1396
- }
1397
- }
1398
- /** Unregisters a global event handler. */
1399
- unregisterGlobalHandler(eventType, handler) {
1400
- if (this.globalHandlers.has(eventType)) {
1401
- this.globalHandlers.get(eventType).delete(handler);
1402
- }
1403
- }
1404
- /**
1405
- * Checks whether there is an action registered under the given
1406
- * name. This returns true if there is a namespace handler, even
1407
- * if it can not yet handle the event.
1408
- *
1409
- * @param name Action name.
1410
- * @return Whether the name is registered.
1411
- * @see #canDispatch
1412
- */
1413
- hasAction(name) {
1414
- return this.actions.hasOwnProperty(name);
1181
+ this.dispatchDelegate(eventInfoWrapper);
1415
1182
  }
1416
1183
  /**
1417
- * Whether this dispatcher can dispatch the event. This can be used by
1418
- * event replayer to check whether the dispatcher can replay an event.
1184
+ * Schedules an `EventInfoWrapper` for replay. The replaying will happen in its own
1185
+ * stack once the current flow cedes control. This is done to mimic
1186
+ * browser event handling.
1419
1187
  */
1420
- canDispatch(eventInfoWrapper) {
1421
- const action = eventInfoWrapper.getAction();
1422
- if (!action) {
1423
- return false;
1188
+ scheduleEventInfoWrapperReplay(eventInfoWrapper) {
1189
+ this.replayEventInfoWrappers.push(eventInfoWrapper);
1190
+ if (this.eventReplayScheduled || !this.eventReplayer) {
1191
+ return;
1424
1192
  }
1425
- return this.hasAction(action.name);
1426
- }
1427
- /**
1428
- * Sets the event replayer, enabling queued events to be replayed when actions
1429
- * are bound. To replay events, you must register the dispatcher to the
1430
- * contract after setting the `EventReplayer`. The event replayer takes as
1431
- * parameters the queue of events and the dispatcher (used to check whether
1432
- * actions have handlers registered and can be replayed). The event replayer
1433
- * is also responsible for dequeuing events.
1434
- *
1435
- * Example: An event replayer that replays only the last event.
1436
- *
1437
- * const dispatcher = new Dispatcher();
1438
- * // ...
1439
- * dispatcher.setEventReplayer((queue, dispatcher) => {
1440
- * const lastEventInfoWrapper = queue[queue.length -1];
1441
- * if (dispatcher.canDispatch(lastEventInfoWrapper.getAction())) {
1442
- * jsaction.replay.replayEvent(
1443
- * lastEventInfoWrapper.getEvent(),
1444
- * lastEventInfoWrapper.getTargetElement(),
1445
- * lastEventInfoWrapper.getEventType(),
1446
- * );
1447
- * queue.length = 0;
1448
- * }
1449
- * });
1450
- *
1451
- * @param eventReplayer It allows elements to be replayed and dequeuing.
1452
- */
1453
- setEventReplayer(eventReplayer) {
1454
- this.eventReplayer = eventReplayer;
1193
+ this.eventReplayScheduled = true;
1194
+ Promise.resolve().then(() => {
1195
+ this.eventReplayScheduled = false;
1196
+ this.eventReplayer(this.replayEventInfoWrappers);
1197
+ });
1455
1198
  }
1456
1199
  }
1457
1200
  /** Stop propagation for an `EventInfo`. */
@@ -1475,6 +1218,18 @@ function stopPropagation(eventInfoWrapper) {
1475
1218
  }
1476
1219
  event.stopPropagation();
1477
1220
  }
1221
+ /**
1222
+ * Returns true if the default action of this event should be prevented before
1223
+ * this event is dispatched.
1224
+ */
1225
+ function shouldPreventDefaultBeforeDispatching(actionElement, eventInfoWrapper) {
1226
+ // Prevent browser from following <a> node links if a jsaction is present
1227
+ // and we are dispatching the action now. Note that the targetElement may be
1228
+ // a child of an anchor that has a jsaction attached. For that reason, we
1229
+ // need to check the actionElement rather than the targetElement.
1230
+ return ((actionElement.tagName === 'A' && eventInfoWrapper.getEventType() === EventType.CLICK) ||
1231
+ eventInfoWrapper.getEventType() === EventType.CLICKMOD);
1232
+ }
1478
1233
  /**
1479
1234
  * Registers deferred functionality for an EventContract and a Jsaction
1480
1235
  * Dispatcher.
@@ -1584,98 +1339,127 @@ function populateClickOnlyAction(actionElement, eventInfo, actionMap) {
1584
1339
  setAction(eventInfo, actionMap[EventType.CLICKONLY], actionElement);
1585
1340
  }
1586
1341
 
1587
- var Attribute;
1588
- (function (Attribute) {
1589
- /**
1590
- * The jsaction attribute defines a mapping of a DOM event to a
1591
- * generic event (aka jsaction), to which the actual event handlers
1592
- * that implement the behavior of the application are bound. The
1593
- * value is a semicolon separated list of colon separated pairs of
1594
- * an optional DOM event name and a jsaction name. If the optional
1595
- * DOM event name is omitted, 'click' is assumed. The jsaction names
1596
- * are dot separated pairs of a namespace and a simple jsaction
1597
- * name. If the namespace is absent, it is taken from the closest
1598
- * ancestor element with a jsnamespace attribute, if there is
1599
- * any. If there is no ancestor with a jsnamespace attribute, the
1600
- * simple name is assumed to be the jsaction name.
1601
- *
1602
- * Used by EventContract.
1603
- */
1604
- Attribute["JSACTION"] = "jsaction";
1605
- /**
1606
- * The jsnamespace attribute provides the namespace part of the
1607
- * jaction names occurring in the jsaction attribute where it's
1608
- * missing.
1609
- *
1610
- * Used by EventContract.
1611
- */
1612
- Attribute["JSNAMESPACE"] = "jsnamespace";
1342
+ /**
1343
+ * The jsaction attribute defines a mapping of a DOM event to a
1344
+ * generic event (aka jsaction), to which the actual event handlers
1345
+ * that implement the behavior of the application are bound. The
1346
+ * value is a semicolon separated list of colon separated pairs of
1347
+ * an optional DOM event name and a jsaction name. If the optional
1348
+ * DOM event name is omitted, 'click' is assumed. The jsaction names
1349
+ * are dot separated pairs of a namespace and a simple jsaction
1350
+ * name. If the namespace is absent, it is taken from the closest
1351
+ * ancestor element with a jsnamespace attribute, if there is
1352
+ * any. If there is no ancestor with a jsnamespace attribute, the
1353
+ * simple name is assumed to be the jsaction name.
1354
+ *
1355
+ * Used by EventContract.
1356
+ */
1357
+ const JSACTION$1 = 'jsaction';
1358
+ /**
1359
+ * The jsnamespace attribute provides the namespace part of the
1360
+ * jaction names occurring in the jsaction attribute where it's
1361
+ * missing.
1362
+ *
1363
+ * Used by EventContract.
1364
+ */
1365
+ const JSNAMESPACE$1 = 'jsnamespace';
1366
+ /**
1367
+ * The oi attribute is a log impression tag for impression logging
1368
+ * and action tracking. For an element that carries a jsaction
1369
+ * attribute, the element is identified for the purpose of
1370
+ * impression logging and click tracking by the dot separated path
1371
+ * of all oi attributes in the chain of ancestors of the element.
1372
+ *
1373
+ * Used by ActionFlow.
1374
+ */
1375
+ const OI$1 = 'oi';
1376
+ /**
1377
+ * The ved attribute is an encoded ClickTrackingCGI proto to track
1378
+ * visual elements.
1379
+ *
1380
+ * Used by ActionFlow.
1381
+ */
1382
+ const VED = 'ved';
1383
+ /**
1384
+ * The vet attribute is the visual element type used to identify tracked
1385
+ * visual elements.
1386
+ */
1387
+ const VET = 'vet';
1388
+ /**
1389
+ * Support for iteration on reprocessing.
1390
+ *
1391
+ * Used by ActionFlow.
1392
+ */
1393
+ const JSINSTANCE = 'jsinstance';
1394
+ /**
1395
+ * All click jsactions that happen on the element that carries this
1396
+ * attribute or its descendants are automatically logged.
1397
+ * Impressions of jsactions on these elements are tracked too, if
1398
+ * requested by the impression() method of ActionFlow.
1399
+ *
1400
+ * Used by ActionFlow.
1401
+ */
1402
+ const JSTRACK = 'jstrack';
1403
+ const Attribute = { JSACTION: JSACTION$1, JSNAMESPACE: JSNAMESPACE$1, OI: OI$1, VED, VET, JSINSTANCE, JSTRACK };
1404
+
1405
+ const Char = {
1613
1406
  /**
1614
- * The oi attribute is a log impression tag for impression logging
1615
- * and action tracking. For an element that carries a jsaction
1616
- * attribute, the element is identified for the purpose of
1617
- * impression logging and click tracking by the dot separated path
1618
- * of all oi attributes in the chain of ancestors of the element.
1619
- *
1620
- * Used by ActionFlow.
1407
+ * The separator between the namespace and the action name in the
1408
+ * jsaction attribute value.
1621
1409
  */
1622
- Attribute["OI"] = "oi";
1410
+ NAMESPACE_ACTION_SEPARATOR: '.',
1623
1411
  /**
1624
- * The ved attribute is an encoded ClickTrackingCGI proto to track
1625
- * visual elements.
1626
- *
1627
- * Used by ActionFlow.
1412
+ * The separator between the event name and action in the jsaction
1413
+ * attribute value.
1628
1414
  */
1629
- Attribute["VED"] = "ved";
1415
+ EVENT_ACTION_SEPARATOR: ':',
1630
1416
  /**
1631
- * The vet attribute is the visual element type used to identify tracked
1632
- * visual elements.
1417
+ * The separator between the logged oi attribute values in the &oi=
1418
+ * URL parameter value.
1633
1419
  */
1634
- Attribute["VET"] = "vet";
1420
+ OI_SEPARATOR: '.',
1635
1421
  /**
1636
- * Support for iteration on reprocessing.
1637
- *
1638
- * Used by ActionFlow.
1422
+ * The separator between the key and the value pairs in the &cad=
1423
+ * URL parameter value.
1639
1424
  */
1640
- Attribute["JSINSTANCE"] = "jsinstance";
1425
+ CAD_KEY_VALUE_SEPARATOR: ':',
1641
1426
  /**
1642
- * All click jsactions that happen on the element that carries this
1643
- * attribute or its descendants are automatically logged.
1644
- * Impressions of jsactions on these elements are tracked too, if
1645
- * requested by the impression() method of ActionFlow.
1646
- *
1647
- * Used by ActionFlow.
1427
+ * The separator between the key-value pairs in the &cad= URL
1428
+ * parameter value.
1648
1429
  */
1649
- Attribute["JSTRACK"] = "jstrack";
1650
- })(Attribute || (Attribute = {}));
1430
+ CAD_SEPARATOR: ',',
1431
+ };
1651
1432
 
1433
+ /**
1434
+ * The parsed value of the jsaction attribute is stored in this
1435
+ * property on the DOM node. The parsed value is an Object. The
1436
+ * property names of the object are the events; the values are the
1437
+ * names of the actions. This property is attached even on nodes
1438
+ * that don't have a jsaction attribute as an optimization, because
1439
+ * property lookup is faster than attribute access.
1440
+ */
1441
+ const JSACTION = '__jsaction';
1442
+ /**
1443
+ * The parsed value of the jsnamespace attribute is stored in this
1444
+ * property on the DOM node.
1445
+ */
1446
+ const JSNAMESPACE = '__jsnamespace';
1447
+ /** The value of the oi attribute as a property, for faster access. */
1448
+ const OI = '__oi';
1449
+ /**
1450
+ * The owner property references an a logical owner for a DOM node. JSAction
1451
+ * will follow this reference instead of parentNode when traversing the DOM
1452
+ * to find jsaction attributes. This allows overlaying a logical structure
1453
+ * over a document where the DOM structure can't reflect that structure.
1454
+ */
1455
+ const OWNER = '__owner';
1652
1456
  /** All properties that are used by jsaction. */
1653
- var Property;
1654
- (function (Property) {
1655
- /**
1656
- * The parsed value of the jsaction attribute is stored in this
1657
- * property on the DOM node. The parsed value is an Object. The
1658
- * property names of the object are the events; the values are the
1659
- * names of the actions. This property is attached even on nodes
1660
- * that don't have a jsaction attribute as an optimization, because
1661
- * property lookup is faster than attribute access.
1662
- */
1663
- Property["JSACTION"] = "__jsaction";
1664
- /**
1665
- * The parsed value of the jsnamespace attribute is stored in this
1666
- * property on the DOM node.
1667
- */
1668
- Property["JSNAMESPACE"] = "__jsnamespace";
1669
- /** The value of the oi attribute as a property, for faster access. */
1670
- Property["OI"] = "__oi";
1671
- /**
1672
- * The owner property references an a logical owner for a DOM node. JSAction
1673
- * will follow this reference instead of parentNode when traversing the DOM
1674
- * to find jsaction attributes. This allows overlaying a logical structure
1675
- * over a document where the DOM structure can't reflect that structure.
1676
- */
1677
- Property["OWNER"] = "__owner";
1678
- })(Property || (Property = {}));
1457
+ const Property = {
1458
+ JSACTION,
1459
+ JSNAMESPACE,
1460
+ OI,
1461
+ OWNER,
1462
+ };
1679
1463
 
1680
1464
  /**
1681
1465
  * Map from jsaction annotation to a parsed map from event name to action name.
@@ -1689,7 +1473,7 @@ const parseCache = {};
1689
1473
  */
1690
1474
  function get(element) {
1691
1475
  // @ts-ignore
1692
- return element[Property.JSACTION];
1476
+ return element[JSACTION];
1693
1477
  }
1694
1478
  /**
1695
1479
  * Writes the jsaction parser cache to the given DOM Element.
@@ -1700,7 +1484,7 @@ function get(element) {
1700
1484
  */
1701
1485
  function set(element, actionMap) {
1702
1486
  // @ts-ignore
1703
- element[Property.JSACTION] = actionMap;
1487
+ element[JSACTION] = actionMap;
1704
1488
  }
1705
1489
  /**
1706
1490
  * Looks up the parsed action map from the source jsaction attribute value.
@@ -1726,8 +1510,8 @@ function setParsed(text, parsed) {
1726
1510
  * @param element .
1727
1511
  */
1728
1512
  function clear(element) {
1729
- if (Property.JSACTION in element) {
1730
- delete element[Property.JSACTION];
1513
+ if (JSACTION in element) {
1514
+ delete element[JSACTION];
1731
1515
  }
1732
1516
  }
1733
1517
  /**
@@ -1740,7 +1524,7 @@ function clear(element) {
1740
1524
  */
1741
1525
  function getNamespace(element) {
1742
1526
  // @ts-ignore
1743
- return element[Property.JSNAMESPACE];
1527
+ return element[JSNAMESPACE];
1744
1528
  }
1745
1529
  /**
1746
1530
  * Writes the cached jsaction namespace to the given DOM Element. Null
@@ -1751,7 +1535,7 @@ function getNamespace(element) {
1751
1535
  */
1752
1536
  function setNamespace(element, jsnamespace) {
1753
1537
  // @ts-ignore
1754
- element[Property.JSNAMESPACE] = jsnamespace;
1538
+ element[JSNAMESPACE] = jsnamespace;
1755
1539
  }
1756
1540
  /**
1757
1541
  * Clears the cached jsaction namespace from the given DOM Element.
@@ -1759,8 +1543,8 @@ function setNamespace(element, jsnamespace) {
1759
1543
  * @param element .
1760
1544
  */
1761
1545
  function clearNamespace(element) {
1762
- if (Property.JSNAMESPACE in element) {
1763
- delete element[Property.JSNAMESPACE];
1546
+ if (JSNAMESPACE in element) {
1547
+ delete element[JSNAMESPACE];
1764
1548
  }
1765
1549
  }
1766
1550
 
@@ -1777,27 +1561,14 @@ const REGEXP_SEMICOLON = /\s*;\s*/;
1777
1561
  const DEFAULT_EVENT_TYPE = EventType.CLICK;
1778
1562
  /** Resolves actions for Events. */
1779
1563
  class ActionResolver {
1780
- constructor({ customEventSupport = false, syntheticMouseEventSupport = false, } = {}) {
1564
+ constructor({ syntheticMouseEventSupport = false, } = {}) {
1781
1565
  this.a11yClickSupport = false;
1782
1566
  this.updateEventInfoForA11yClick = undefined;
1783
1567
  this.preventDefaultForA11yClick = undefined;
1784
1568
  this.populateClickOnlyAction = undefined;
1785
- this.customEventSupport = customEventSupport;
1786
1569
  this.syntheticMouseEventSupport = syntheticMouseEventSupport;
1787
1570
  }
1788
1571
  resolve(eventInfo) {
1789
- if (this.customEventSupport) {
1790
- if (getEventType(eventInfo) === EventType.CUSTOM) {
1791
- const detail = getEvent(eventInfo).detail;
1792
- // For custom events, use a secondary dispatch based on the internal
1793
- // custom type of the event.
1794
- if (!detail || !detail['_type']) {
1795
- // This should never happen.
1796
- return;
1797
- }
1798
- setEventType(eventInfo, detail['_type']);
1799
- }
1800
- }
1801
1572
  this.populateAction(eventInfo);
1802
1573
  }
1803
1574
  /**
@@ -1867,8 +1638,8 @@ class ActionResolver {
1867
1638
  // ancestor chain of the event target node.
1868
1639
  break;
1869
1640
  }
1870
- if (actionElement[Property.OWNER]) {
1871
- actionElement = actionElement[Property.OWNER];
1641
+ if (actionElement[OWNER]) {
1642
+ actionElement = actionElement[OWNER];
1872
1643
  continue;
1873
1644
  }
1874
1645
  if (actionElement.parentNode?.nodeName !== '#document-fragment') {
@@ -1994,11 +1765,6 @@ const A11Y_CLICK_SUPPORT = false;
1994
1765
  * flag can be overridden in a build rule.
1995
1766
  */
1996
1767
  const MOUSE_SPECIAL_SUPPORT = false;
1997
- /**
1998
- * @define Support for custom events, which are type EventType.CUSTOM. These are
1999
- * native DOM events with an additional type field and an optional payload.
2000
- */
2001
- const CUSTOM_EVENT_SUPPORT = false;
2002
1768
 
2003
1769
  /**
2004
1770
  * @fileoverview Implements the local event handling contract. This
@@ -2038,14 +1804,10 @@ const CUSTOM_EVENT_SUPPORT = false;
2038
1804
  * be delay loaded in a generic way.
2039
1805
  */
2040
1806
  class EventContract {
2041
- static { this.CUSTOM_EVENT_SUPPORT = CUSTOM_EVENT_SUPPORT; }
2042
1807
  static { this.A11Y_CLICK_SUPPORT = A11Y_CLICK_SUPPORT; }
2043
1808
  static { this.MOUSE_SPECIAL_SUPPORT = MOUSE_SPECIAL_SUPPORT; }
2044
- constructor(containerManager) {
2045
- this.actionResolver = new ActionResolver({
2046
- customEventSupport: EventContract.CUSTOM_EVENT_SUPPORT,
2047
- syntheticMouseEventSupport: EventContract.MOUSE_SPECIAL_SUPPORT,
2048
- });
1809
+ constructor(containerManager, useActionResolver = true) {
1810
+ this.useActionResolver = useActionResolver;
2049
1811
  /**
2050
1812
  * The DOM events which this contract covers. Used to prevent double
2051
1813
  * registration of event types. The value of the map is the
@@ -2071,8 +1833,10 @@ class EventContract {
2071
1833
  /** Whether to add an a11y click listener. */
2072
1834
  this.addA11yClickListener = false;
2073
1835
  this.containerManager = containerManager;
2074
- if (EventContract.CUSTOM_EVENT_SUPPORT) {
2075
- this.addEvent(EventType.CUSTOM);
1836
+ if (this.useActionResolver) {
1837
+ this.actionResolver = new ActionResolver({
1838
+ syntheticMouseEventSupport: EventContract.MOUSE_SPECIAL_SUPPORT,
1839
+ });
2076
1840
  }
2077
1841
  if (EventContract.A11Y_CLICK_SUPPORT) {
2078
1842
  // Add a11y click support to the `EventContract`.
@@ -2098,12 +1862,8 @@ class EventContract {
2098
1862
  this.queuedEventInfos?.push(eventInfo);
2099
1863
  return;
2100
1864
  }
2101
- this.actionResolver.resolve(eventInfo);
2102
- const action = getAction(eventInfo);
2103
- if (action) {
2104
- if (shouldPreventDefaultBeforeDispatching(getActionElement(action), eventInfo)) {
2105
- preventDefault(getEvent(eventInfo));
2106
- }
1865
+ if (this.useActionResolver) {
1866
+ this.actionResolver.resolve(eventInfo);
2107
1867
  }
2108
1868
  this.dispatcher(eventInfo);
2109
1869
  }
@@ -2263,7 +2023,9 @@ class EventContract {
2263
2023
  */
2264
2024
  addA11yClickSupportImpl(updateEventInfoForA11yClick, preventDefaultForA11yClick, populateClickOnlyAction) {
2265
2025
  this.addA11yClickListener = true;
2266
- this.actionResolver.addA11yClickSupport(updateEventInfoForA11yClick, preventDefaultForA11yClick, populateClickOnlyAction);
2026
+ if (this.useActionResolver) {
2027
+ this.actionResolver.addA11yClickSupport(updateEventInfoForA11yClick, preventDefaultForA11yClick, populateClickOnlyAction);
2028
+ }
2267
2029
  }
2268
2030
  }
2269
2031
  function removeEventListeners(container, eventTypes, earlyEventHandler, capture) {
@@ -2280,19 +2042,6 @@ function removeEventListeners(container, eventTypes, earlyEventHandler, capture)
2280
2042
  function addDeferredA11yClickSupport(eventContract) {
2281
2043
  eventContract.ecaacs?.(updateEventInfoForA11yClick, preventDefaultForA11yClick, populateClickOnlyAction);
2282
2044
  }
2283
- /**
2284
- * Returns true if the default action of this event should be prevented before
2285
- * this event is dispatched.
2286
- */
2287
- function shouldPreventDefaultBeforeDispatching(actionElement, eventInfo) {
2288
- // Prevent browser from following <a> node links if a jsaction is present
2289
- // and we are dispatching the action now. Note that the targetElement may be
2290
- // a child of an anchor that has a jsaction attached. For that reason, we
2291
- // need to check the actionElement rather than the targetElement.
2292
- return (actionElement.tagName === 'A' &&
2293
- (getEventType(eventInfo) === EventType.CLICK ||
2294
- getEventType(eventInfo) === EventType.CLICKMOD));
2295
- }
2296
2045
 
2297
2046
  /**
2298
2047
  * EarlyEventContract intercepts events in the bubbling phase at the
@@ -2303,14 +2052,14 @@ class EarlyEventContract {
2303
2052
  constructor(replaySink = window, container = window.document.documentElement) {
2304
2053
  this.replaySink = replaySink;
2305
2054
  this.container = container;
2306
- this.replaySink._ejsa = {
2055
+ replaySink._ejsa = {
2307
2056
  c: container,
2308
2057
  q: [],
2309
2058
  et: [],
2310
2059
  etc: [],
2311
2060
  h: (event) => {
2312
- const eventInfo = createEventInfoFromParameters(event.type, event, event.target, window.document.documentElement, Date.now());
2313
- this.replaySink._ejsa.q.push(eventInfo);
2061
+ const eventInfo = createEventInfoFromParameters(event.type, event, event.target, container, Date.now());
2062
+ replaySink._ejsa.q.push(eventInfo);
2314
2063
  },
2315
2064
  };
2316
2065
  }
@@ -2328,26 +2077,6 @@ class EarlyEventContract {
2328
2077
  }
2329
2078
  }
2330
2079
 
2331
- /**
2332
- * Provides a factory function for bootstrapping an event contract on a
2333
- * specified object (by default, exposed on the `window`).
2334
- * @param field The property on the object that the event contract will be placed on.
2335
- * @param container The container that listens to events
2336
- * @param appId A given identifier for an application. If there are multiple apps on the page
2337
- * then this is how contracts can be initialized for each one.
2338
- * @param events An array of event names that should be listened to.
2339
- * @param earlyJsactionTracker The object that should receive the event contract.
2340
- */
2341
- function bootstrapEventContract(field, container, appId, events, earlyJsactionTracker = window) {
2342
- if (!earlyJsactionTracker[field]) {
2343
- earlyJsactionTracker[field] = {};
2344
- }
2345
- const eventContract = new EventContract(new EventContractContainer(container));
2346
- earlyJsactionTracker[field][appId] = eventContract;
2347
- for (const ev of events) {
2348
- eventContract.addEvent(ev);
2349
- }
2350
- }
2351
2080
  /**
2352
2081
  * Provides a factory function for bootstrapping an event contract on a
2353
2082
  * specified object (by default, exposed on the `window`).
@@ -2365,9 +2094,11 @@ function bootstrapEarlyEventContract(field, container, appId, eventTypes, captur
2365
2094
  }
2366
2095
  earlyJsactionTracker[field][appId] = {};
2367
2096
  const eventContract = new EarlyEventContract(earlyJsactionTracker[field][appId], container);
2368
- eventContract.addEvents(eventTypes);
2369
- eventContract.addEvents(captureEventTypes, true);
2097
+ if (eventTypes)
2098
+ eventContract.addEvents(eventTypes);
2099
+ if (captureEventTypes)
2100
+ eventContract.addEvents(captureEventTypes, true);
2370
2101
  }
2371
2102
 
2372
- export { Dispatcher, EventContract, EventContractContainer, EventInfoWrapper, bootstrapEarlyEventContract, bootstrapEventContract, registerDispatcher };
2103
+ export { Dispatcher, EventContract, EventContractContainer, EventInfoWrapper, bootstrapEarlyEventContract, registerDispatcher };
2373
2104
  //# sourceMappingURL=event-dispatch.mjs.map