-
Notifications
You must be signed in to change notification settings - Fork 24.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
refactor(core): Allow the container and the listenable element to be … #55586
Changes from 12 commits
6af29b0
ba01a42
b406441
c2bbd97
c786d8a
6596a07
a17d287
ab609cc
4f0cece
f7a4a88
6fc5cf1
83cb5f5
bd8ff2c
db26ee0
11e95a0
2726fc7
7e6d966
e8159de
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -32,7 +32,7 @@ | |
|
||
import * as a11yClickLib from './a11y_click'; | ||
import {ActionResolver} from './action_resolver'; | ||
import {EarlyJsactionData} from './earlyeventcontract'; | ||
import {EarlyJsactionData, EarlyJsactionDataContainer} from './earlyeventcontract'; | ||
import * as eventLib from './event'; | ||
import {EventContractContainerManager} from './event_contract_container'; | ||
import { | ||
|
@@ -255,10 +255,12 @@ export class EventContract implements UnrenamedEventContract { | |
* in the provided event contract. Once all the events are replayed, it cleans | ||
* up the early contract. | ||
*/ | ||
replayEarlyEvents() { | ||
replayEarlyEvents( | ||
earlyJsactionContainer: EarlyJsactionDataContainer = window as EarlyJsactionDataContainer, | ||
) { | ||
// Check if the early contract is present and prevent calling this function | ||
// more than once. | ||
const earlyJsactionData: EarlyJsactionData | undefined = window._ejsa; | ||
const earlyJsactionData: EarlyJsactionData | undefined = earlyJsactionContainer._ejsa; | ||
if (!earlyJsactionData) { | ||
return; | ||
} | ||
|
@@ -282,9 +284,14 @@ export class EventContract implements UnrenamedEventContract { | |
const earlyEventHandler: (event: Event) => void = earlyJsactionData.h; | ||
for (let idx = 0; idx < earlyEventTypes.length; idx++) { | ||
const eventType: string = earlyEventTypes[idx]; | ||
window.document.documentElement.removeEventListener(eventType, earlyEventHandler); | ||
earlyJsactionData.c.removeEventListener(eventType, earlyEventHandler); | ||
} | ||
const earlyEventTypesCapture: string[] = earlyJsactionData.etc; | ||
for (let idx = 0; idx < earlyEventTypesCapture.length; idx++) { | ||
const eventType: string = earlyEventTypes[idx]; | ||
earlyJsactionData.c.removeEventListener(eventType, earlyEventHandler, /* useCapture */ true); | ||
iteriani marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
delete window._ejsa; | ||
delete earlyJsactionContainer._ejsa; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a pre-existing code, but I wanted to mention that we generally try not to use |
||
} | ||
|
||
/** | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,34 +6,63 @@ | |
* found in the LICENSE file at https://angular.io/license | ||
*/ | ||
|
||
import {EarlyEventContract, EarlyJsactionDataContainer} from './earlyeventcontract'; | ||
import {EventContractContainer} from './event_contract_container'; | ||
import {EventContract} from './eventcontract'; | ||
|
||
type Container = {[key: string]: {[appId: string]: EarlyJsactionDataContainer}}; | ||
iteriani marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
/** | ||
* Provides a factory function for bootstrapping an event contract on a | ||
* window object. | ||
* @param field The property on the window that the event contract will be placed on. | ||
* specified object (by default, exposed on the `window`). | ||
* @param field The property on the object that the event contract will be placed on. | ||
* @param container The container that listens to events | ||
* @param appId A given identifier for an application. If there are multiple apps on the page | ||
* then this is how contracts can be initialized for each one. | ||
* @param events An array of event names that should be listened to. | ||
* @param anyWindow The global window object that should receive the event contract. | ||
* @returns The `event` contract. This is both assigned to `anyWindow` and returned for testing. | ||
* @param earlyJsactionTracker The object that should receive the event contract. | ||
*/ | ||
export function bootstrapEventContract( | ||
field: string, | ||
container: Element, | ||
appId: string, | ||
events: string[], | ||
anyWindow: any = window, | ||
earlyJsactionTracker: any = window, | ||
iteriani marked this conversation as resolved.
Show resolved
Hide resolved
|
||
) { | ||
if (!anyWindow[field]) { | ||
anyWindow[field] = {}; | ||
if (!earlyJsactionTracker[field]) { | ||
earlyJsactionTracker[field] = {}; | ||
} | ||
const eventContract = new EventContract(new EventContractContainer(container)); | ||
anyWindow[field][appId] = eventContract; | ||
earlyJsactionTracker[field][appId] = eventContract; | ||
for (const ev of events) { | ||
eventContract.addEvent(ev); | ||
} | ||
return eventContract; | ||
} | ||
|
||
/** | ||
* Provides a factory function for bootstrapping an event contract on a | ||
* specified object (by default, exposed on the `window`). | ||
* @param field The property on the object that the event contract will be placed on. | ||
* @param container The container that listens to events | ||
* @param appId A given identifier for an application. If there are multiple apps on the page | ||
* then this is how contracts can be initialized for each one. | ||
* @param eventTypes An array of event names that should be listened to. | ||
* @param captureEventTypes An array of event names that should be listened to with capture. | ||
* @param earlyJsactionTracker The object that should receive the event contract. | ||
*/ | ||
export function bootstrapEarlyEventContract( | ||
field: string, | ||
container: HTMLElement, | ||
appId: string, | ||
eventTypes: string[], | ||
captureEventTypes: string[], | ||
earlyJsactionTracker: Container = window as unknown as Container, | ||
) { | ||
if (!earlyJsactionTracker[field]) { | ||
earlyJsactionTracker[field] = {}; | ||
} | ||
earlyJsactionTracker[field][appId] = {}; | ||
Comment on lines
+63
to
+64
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we do a tree-shakable dev-mode checks in this code? If yes, it might be great to assert whether There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. there's no such thing as a dev mode binary i think... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we do have some dev-mode flags 1P/3P compatible (via copybara transform) in the signals code. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We can also do this in a followup PR (let's not block this PR on this change). |
||
const eventContract = new EarlyEventContract(earlyJsactionTracker[field][appId], container); | ||
eventContract.addEvents(eventTypes); | ||
eventContract.addEvents(captureEventTypes, true); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You'll probably need to re-generate golden files, this
any
would be replaced withTracker
type.