77 */
88
99import { ApplicationRef } from '../application/application_ref' ;
10+ import { APP_ID } from '../application/application_tokens' ;
1011import { isDetachedByI18n } from '../i18n/utils' ;
1112import { ViewEncapsulation } from '../metadata' ;
1213import { Renderer2 } from '../render' ;
@@ -21,12 +22,15 @@ import {unwrapLView, unwrapRNode} from '../render3/util/view_utils';
2122import { TransferState } from '../transfer_state' ;
2223
2324import { unsupportedProjectionOfDomNodes } from './error_handling' ;
25+ import { collectDomEventsInfo , EVENT_REPLAY_ENABLED_DEFAULT , setJSActionAttribute } from './event_replay' ;
2426import { getOrComputeI18nChildren , isI18nHydrationEnabled , isI18nHydrationSupportEnabled , trySerializeI18nBlock } from './i18n' ;
2527import { CONTAINERS , DISCONNECTED_NODES , ELEMENT_CONTAINERS , I18N_DATA , MULTIPLIER , NODES , NUM_ROOT_NODES , SerializedContainerView , SerializedView , TEMPLATE_ID , TEMPLATES } from './interfaces' ;
2628import { calcPathForNode , isDisconnectedNode } from './node_lookup_utils' ;
2729import { isInSkipHydrationBlock , SKIP_HYDRATION_ATTR_NAME } from './skip_hydration' ;
30+ import { IS_EVENT_REPLAY_ENABLED } from './tokens' ;
2831import { getLNodeForHydration , NGH_ATTR_NAME , NGH_DATA_KEY , processTextNodeBeforeSerialization , TextNodeMarker } from './utils' ;
2932
33+
3034/**
3135 * A collection that tracks all serialized views (`ngh` DOM annotations)
3236 * to avoid duplication. An attempt to add a duplicate view results in the
@@ -84,6 +88,8 @@ export interface HydrationContext {
8488 corruptedTextNodes : Map < HTMLElement , TextNodeMarker > ;
8589 isI18nHydrationEnabled : boolean ;
8690 i18nChildren : Map < TView , Set < number > | null > ;
91+ eventTypesToReplay : Set < string > ;
92+ shouldReplayEvents : boolean ;
8793}
8894
8995/**
@@ -160,14 +166,16 @@ function annotateLContainerForHydration(lContainer: LContainer, context: Hydrati
160166 *
161167 * @param appRef An instance of an ApplicationRef.
162168 * @param doc A reference to the current Document instance.
169+ * @return event types that need to be replayed
163170 */
164171export function annotateForHydration ( appRef : ApplicationRef , doc : Document ) {
165172 const injector = appRef . injector ;
166173 const isI18nHydrationEnabledVal = isI18nHydrationEnabled ( injector ) ;
167-
168174 const serializedViewCollection = new SerializedViewCollection ( ) ;
169175 const corruptedTextNodes = new Map < HTMLElement , TextNodeMarker > ( ) ;
170176 const viewRefs = appRef . _views ;
177+ const shouldReplayEvents = injector . get ( IS_EVENT_REPLAY_ENABLED , EVENT_REPLAY_ENABLED_DEFAULT ) ;
178+ const eventTypesToReplay = new Set < string > ( ) ;
171179 for ( const viewRef of viewRefs ) {
172180 const lNode = getLNodeForHydration ( viewRef ) ;
173181
@@ -179,6 +187,8 @@ export function annotateForHydration(appRef: ApplicationRef, doc: Document) {
179187 corruptedTextNodes,
180188 isI18nHydrationEnabled : isI18nHydrationEnabledVal ,
181189 i18nChildren : new Map ( ) ,
190+ eventTypesToReplay,
191+ shouldReplayEvents,
182192 } ;
183193 if ( isLContainer ( lNode ) ) {
184194 annotateLContainerForHydration ( lNode , context ) ;
@@ -197,6 +207,7 @@ export function annotateForHydration(appRef: ApplicationRef, doc: Document) {
197207 const serializedViews = serializedViewCollection . getAll ( ) ;
198208 const transferState = injector . get ( TransferState ) ;
199209 transferState . set ( NGH_DATA_KEY , serializedViews ) ;
210+ return eventTypesToReplay . size > 0 ? eventTypesToReplay : undefined ;
200211}
201212
202213/**
@@ -322,10 +333,16 @@ function serializeLView(lView: LView, context: HydrationContext): SerializedView
322333 const ngh : SerializedView = { } ;
323334 const tView = lView [ TVIEW ] ;
324335 const i18nChildren = getOrComputeI18nChildren ( tView , context ) ;
336+ const nativeElementsToEventTypes = context . shouldReplayEvents ?
337+ collectDomEventsInfo ( tView , lView , context . eventTypesToReplay ) :
338+ null ;
325339 // Iterate over DOM element references in an LView.
326340 for ( let i = HEADER_OFFSET ; i < tView . bindingStartIndex ; i ++ ) {
327341 const tNode = tView . data [ i ] as TNode ;
328342 const noOffsetIndex = i - HEADER_OFFSET ;
343+ if ( nativeElementsToEventTypes ) {
344+ setJSActionAttribute ( tNode , lView [ i ] , nativeElementsToEventTypes ) ;
345+ }
329346
330347 // Attempt to serialize any i18n data for the given slot. We do this first, as i18n
331348 // has its own process for serialization.
0 commit comments