Skip to content

Commit

Permalink
- require a target window only when posting a message (not when recei…
Browse files Browse the repository at this point in the history
…ving), because that will not cause issues on the Cadenza end and can be handled by the custom app (by unsubscribing all subscribers)

- add CadenzaClient#destroy for conveniently unsubscribing all subscribers

(cherry picked from commit 9233dd5)
  • Loading branch information
jkissel committed Jun 11, 2024
1 parent 1ce6ae5 commit d94578d
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 9 deletions.
7 changes: 6 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,18 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## Unreleased
### Added
- `CadenzaClient#destroy`

### Fixed
- To avoid errors with active subscriptions when the iframe is not visible, a target window (for postMessage communication) is now required only for _sending_ a message (and not for receiving messages).

## 2.8.0 - 2024-05-28
### Added
- `invalidateCaches` option for `CadenzaClient#reload`
- Allow communication with parent Cadenza window (Previously, communication was possible only with an embedded Cadenza iframe.)
- `cadenza()` overload with a single options parameter
- `CadenzaClient#closeMe` function
- `CadenzaClient#closeMe`
- Documentation on listening when a custom application is closed (unload and visibilitychange events)

### Deprecated
Expand Down
25 changes: 18 additions & 7 deletions src/cadenza.js
Original file line number Diff line number Diff line change
Expand Up @@ -221,12 +221,11 @@ export class CadenzaClient {
}

get #targetWindow() {
if (this.#iframe) {
return /** @type {WindowProxy} */ (this.#requiredIframe.contentWindow);
}
const targetWindow = window.opener ?? window.parent;
assert(targetWindow !== window, 'Cannot find target window');
return /** @type {WindowProxy} */ targetWindow;
const targetWindow = this.#iframe
? this.iframe?.contentWindow
: // If a window does not have a parent, its parent property is a reference to itself.
window.opener ?? (window.parent !== window ? window.parent : null);
return /** @type {WindowProxy | null} */ targetWindow;
}

get #requiredIframe() {
Expand Down Expand Up @@ -730,6 +729,16 @@ export class CadenzaClient {
});
};

/**
* Remove all subscriptions.
*
* @see {@link CadenzaClient#on}
*/
destroy() {
this.#subscriptions = [];
window.removeEventListener('message', this.#onMessage);
}

/**
* Posts an event to Cadenza and returns a `Promise` for the response.
*
Expand Down Expand Up @@ -766,7 +775,9 @@ export class CadenzaClient {
#postEvent(type, detail, transfer) {
const cadenzaEvent = { type, detail };
this.#log('postMessage', cadenzaEvent);
this.#targetWindow.postMessage(cadenzaEvent, {
const targetWindow = this.#targetWindow;
assert(targetWindow != null, 'Cannot find target window');
targetWindow.postMessage(cadenzaEvent, {
targetOrigin: this.#origin,
transfer,
});
Expand Down
12 changes: 11 additions & 1 deletion src/cadenza.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ describe('Given a Cadenza JS client instance', () => {

it('Throws when attempting to show an embedding target without an iframe', () =>
expect(() => cadenza(BASE_URL).show(EMBEDDING_TARGET_ID)).toThrow(
'present',
'Required iframe',
));

it('Throws when attempting to reload the worksheet views without an iframe', () =>
Expand Down Expand Up @@ -230,6 +230,16 @@ describe('Given a Cadenza JS client instance', () => {
expect(subscriber).not.toHaveBeenCalled());
});

describe('When the event is sent again after the instance has been destroyed', () => {
beforeEach(() => {
cad.destroy();
sendEvent(EVENT.type, EVENT.detail);
});

it('Subscribers are not called anymore', () =>
expect(subscriber).not.toHaveBeenCalled());
});

describe('When the event is sent from another origin', () => {
beforeEach(() => sendEvent(EVENT.type, EVENT.detail, 'http://disy.net'));

Expand Down

0 comments on commit d94578d

Please sign in to comment.