Skip to content

Commit

Permalink
Merge pull request #53 from CrowdStrike/improve-navigation
Browse files Browse the repository at this point in the history
chore: if target is not <a> element, don't handle onClick event
  • Loading branch information
RuslanZavacky authored Nov 22, 2023
2 parents dae2d02 + 2000545 commit 7cfe7a1
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 7 deletions.
12 changes: 12 additions & 0 deletions .changeset/cold-swans-travel.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
'@crowdstrike/foundry-js': minor
---

Improve how we handle onClick for navigation. Now when adding event listener to click event:

```javascript
document.querySelector('[data-internal-links]')
.addEventListener('click', (event) => falcon.navigation.onClick(event, '_self', 'internal'));
```

we'll call preventDefault correctly and won't throw error in the console.
6 changes: 3 additions & 3 deletions src/lib/navigation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,12 @@ export class Navigation<DATA extends LocalData = LocalData> {
return;
}

event.preventDefault();

if (!(event.target instanceof HTMLAnchorElement)) {
throw Error(`event target is not an anchor element, ${event.target}`);
return;
}

event.preventDefault();

const path = event.target.getAttribute('href');
defaultTarget =
(event.target.getAttribute('target') as '_self' | '_blank') ??
Expand Down
47 changes: 43 additions & 4 deletions tests/lib/navigation.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,13 @@ test('onClick fails if MouseEvent not passed', async () => {
});

test('onClick fails target element was not an anchor element', async () => {
const spy = vi.spyOn(window.parent, 'postMessage');

const mouseEventClass = new MouseEvent('click');

// resetting the types to see what happens when types are ignored and wrong event is passed
await expect(async () =>
navigation.onClick(mouseEventClass),
).rejects.toThrowError(/event target is not an anchor element/);
navigation.onClick(mouseEventClass);

expect(spy).not.toHaveBeenCalledOnce();
});

test('onClick fails with anchor element missing href attribute', async () => {
Expand Down Expand Up @@ -122,3 +123,41 @@ test('onClick triggers navigateTo message', async () => {
}),
);
});

test('onClick triggers navigateTo message with query params for internal navigation', async () => {
const spy = vi.spyOn(window.parent, 'postMessage');

const anchorElement = document.createElement('a');

anchorElement.href = '/?param1=value1';

class SyntheticMouseEvent extends MouseEvent {
target = anchorElement;
}

const mouseEventClass = new SyntheticMouseEvent('click');

navigation.onClick(mouseEventClass);

expect(spy).toHaveBeenCalledOnce();

expect(spy.mock.lastCall?.[0]).toEqual(
expect.objectContaining({
message: {
type: 'navigateTo',
payload: {
path: '/?param1=value1',
target: '_self',
metaKey: false,
ctrlKey: false,
shiftKey: false,
type: 'falcon',
},
},
meta: {
version: 'current',
messageId: expect.stringMatching(uuidV4Regex),
},
}),
);
});

0 comments on commit 7cfe7a1

Please sign in to comment.