Skip to content

Commit

Permalink
fixup! refactor(core): Remove jsaction from element after handling th…
Browse files Browse the repository at this point in the history
…e event.
  • Loading branch information
iteriani committed May 1, 2024
1 parent ebdb449 commit 3e80de8
Show file tree
Hide file tree
Showing 4 changed files with 10 additions and 65 deletions.
11 changes: 0 additions & 11 deletions goldens/public-api/core/primitives/event-dispatch/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,6 @@
```ts

// @public (undocumented)
export enum Attribute {
JSACTION = "jsaction",
JSINSTANCE = "jsinstance",
JSNAMESPACE = "jsnamespace",
JSTRACK = "jstrack",
OI = "oi",
VED = "ved",
VET = "vet"
}

// @public
export function bootstrapEventContract(field: string, container: Element, appId: string, events: string[], anyWindow?: any): EventContract;

Expand Down
1 change: 0 additions & 1 deletion packages/core/primitives/event-dispatch/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
* found in the LICENSE file at https://angular.io/license
*/

export {Attribute} from './src/attribute';
export {Dispatcher, registerDispatcher} from './src/dispatcher';
export {EventContractContainer} from './src/event_contract_container';
export {EventContract} from './src/eventcontract';
Expand Down
9 changes: 5 additions & 4 deletions packages/core/src/hydration/event_replay.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
*/

import {
Attribute,
Dispatcher,
EventContract,
EventInfoWrapper,
Expand Down Expand Up @@ -36,6 +35,8 @@ declare global {
var ngContracts: {[key: string]: EventContract};
}

const JSACTION_ATTRIBUTE = 'jsaction';

/**
* Returns a set of providers required to setup support for event replay.
* Requires hydration to be enabled separately.
Expand All @@ -50,8 +51,8 @@ export function withEventReplay(): Provider[] {
provide: ENVIRONMENT_INITIALIZER,
useValue: () => {
setDisableEventReplayImpl((el: RElement) => {
if (el.hasAttribute(Attribute.JSACTION)) {
el.removeAttribute(Attribute.JSACTION);
if (el.hasAttribute(JSACTION_ATTRIBUTE)) {
el.removeAttribute(JSACTION_ATTRIBUTE);
}
});
},
Expand Down Expand Up @@ -141,7 +142,7 @@ export function setJSActionAttribute(
const events = nativeElementToEvents.get(nativeElement) ?? [];
const parts = events.map((event) => `${event}:`);
if (parts.length > 0) {
nativeElement.setAttribute('jsaction', parts.join(';'));
nativeElement.setAttribute(JSACTION_ATTRIBUTE, parts.join(';'));
}
}
}
Expand Down
54 changes: 5 additions & 49 deletions packages/platform-server/test/event_replay_spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ describe('event replay', () => {
expect(clickSpy).toHaveBeenCalled();
});

it('should remove jsaction attributes and stop listening after hydration.', async () => {
it('should remove jsaction attributes, but continue listening to events.', async () => {
@Component({
standalone: true,
selector: 'app',
Expand All @@ -164,16 +164,10 @@ describe('event replay', () => {
const docContents = `<html><head></head><body>${EVENT_DISPATCH_SCRIPT}<app></app></body></html>`;
const html = await ssr(SimpleComponent, {doc: docContents});
const ssrContents = getAppContents(html);
const originalRemoveEventListener = doc.body.removeEventListener;
const removeEventListenerSpy = jasmine.createSpy();
doc.body.removeEventListener = function (
type: string,
listener: EventListenerOrEventListenerObject,
options: boolean | EventListenerOptions | undefined,
) {
originalRemoveEventListener.call(doc.body, type, listener, options);
removeEventListenerSpy();
};
const removeEventListenerSpy = spyOn(
document.body,
'removeEventListener',
).and.callThrough();
render(doc, ssrContents);
const el = doc.getElementById('1')!;
expect(el.hasAttribute('jsaction')).toBeTrue();
Expand All @@ -190,44 +184,6 @@ describe('event replay', () => {
expect(removeEventListenerSpy).not.toHaveBeenCalled();
});

describe('bubbling behavior', () => {
it('should remove jsaction attributes and stop listening after hydration.', async () => {
const clickSpyOne = jasmine.createSpy();
const clickSpyTwo = jasmine.createSpy();
@Component({
standalone: true,
selector: 'app',
template: `
<div (click)="onClick()" id="1">
<div (click)="onClick2()" id="2"></div>
</div>
`,
})
class SimpleComponent {
onClick = clickSpyOne;
onClick2 = clickSpyTwo;
}

const docContents = `<html><head></head><body>${EVENT_DISPATCH_SCRIPT}<app></app></body></html>`;
const html = await ssr(SimpleComponent, {doc: docContents});
const ssrContents = getAppContents(html);
render(doc, ssrContents);
const el = doc.getElementById('2')!;
const clickEvent = new CustomEvent('click', {bubbles: true});
el.dispatchEvent(clickEvent);
resetTViewsFor(SimpleComponent);
const appRef = await hydrate(doc, SimpleComponent, {
hydrationFeatures: [withEventReplay()],
});
appRef.tick();
expect(clickSpyTwo).toHaveBeenCalledTimes(1);
expect(clickSpyOne).toHaveBeenCalledTimes(0);
el.dispatchEvent(clickEvent);
expect(clickSpyTwo).toHaveBeenCalledTimes(2);
expect(clickSpyOne).toHaveBeenCalledTimes(1);
});
});

it(`should add 'nonce' attribute to event record script when 'ngCspNonce' is provided`, async () => {
@Component({
standalone: true,
Expand Down

0 comments on commit 3e80de8

Please sign in to comment.