Skip to content

Commit

Permalink
Merge branch 'master' of github.com:cerner/xfc
Browse files Browse the repository at this point in the history
  • Loading branch information
kafkahw committed Oct 27, 2017
2 parents abf270e + c497919 commit a8391f8
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 8 deletions.
9 changes: 8 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,19 @@ If the embedded app does not know which domain to trust, it may require secret a
var frame = XFC.Consumer.mount(document.body, 'http://localprovider.com:8080/example/provider_b.html', {secret: 'abc123'})
```

To remove and clean up a mounted app, simple call `unmount` method.
To remove and clean up a mounted app, simply call `unmount` method.

```js
frame.unmount()
```

To load a new page within the existing frame, simply call `load` method with the new URL.

```js
frame.load(newURL)
```


#### Iframe Resizing Config
By default, the height of iframe will automatically resize based on the height of the embedded content. This behavior can be changed by passing an extra option (`resizeConfig`) into `mount` method.

Expand Down
41 changes: 34 additions & 7 deletions src/consumer/frame.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,17 @@ import URI from '../lib/uri';
*/
class Frame extends EventEmitter {

constructor(props) {
super(props);

// Binds 'this' for methods called internally
this.handleProviderMessage = this.handleProviderMessage.bind(this);
this.initIframeResizer = this.initIframeResizer.bind(this);
this.send = this.send.bind(this);
this.cleanup = this.cleanup.bind(this);
this.load = this.load.bind(this);
}

/**
* @param {object} container - The DOM node to append the application frame to.
* @param {string} source - The url source of the application
Expand All @@ -23,12 +34,10 @@ class Frame extends EventEmitter {
this.origin = new URI(this.source).origin;
this.secret = secret;
this.resizeConfig = resizeConfig;
this.handleProviderMessage = this.handleProviderMessage.bind(this);
this.initIframeResizer = this.initIframeResizer.bind(this);

const self = this;
this.JSONRPC = new JSONRPC(
self.send.bind(self),
self.send,
{
launch() {
self.wrapper.setAttribute('data-status', 'launched');
Expand Down Expand Up @@ -73,10 +82,7 @@ class Frame extends EventEmitter {
},

loadPage(url) {
self.origin = new URI(url).origin;
self.source = url;
self.wrapper.setAttribute('data-status', 'mounted');
self.iframe.src = url; // Triggers the loading of new page
self.load(url);
return Promise.resolve();
},
}
Expand Down Expand Up @@ -141,9 +147,30 @@ class Frame extends EventEmitter {
if (this.wrapper.parentNode === this.container) {
this.container.removeChild(this.wrapper);
this.emit('xfc.unmounted');
this.cleanup();
}
}

/**
* Cleans up references of detached nodes by setting them to null
* to avoid potential memory leak
*/
cleanup() {
this.iframe = null;
this.wrapper = null;
}

/**
* Loads a new page within existing frame.
* @param {string} url - the URL of new page to load.
*/
load(url) {
this.origin = new URI(url).origin;
this.source = url;
this.wrapper.setAttribute('data-status', 'mounted');
this.iframe.src = url; // Triggers the loading of new page
}

/**
* Handles an incoming message event by processing the JSONRPC request
* @param {object} event - The emitted message event.
Expand Down
22 changes: 22 additions & 0 deletions test/frame.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import JSONRPC from 'jsonrpc-dispatch';
import sinon from 'sinon';

import Frame from '../src/consumer/frame';
import URI from '../src/lib/uri';


describe('Frame', () => {
Expand Down Expand Up @@ -53,17 +54,38 @@ describe('Frame', () => {

describe('#unmount()', () => {
const emit = sinon.stub();
frame.cleanup = sinon.stub();
frame.on('xfc.unmounted', () => emit());
frame.unmount();

it("removes the wrapper from container's child nodes", () => {
expect(frame.wrapper.parentNode).to.not.equal(frame.container);
});
it("calls method 'cleanup'", () => {
sinon.assert.called(frame.cleanup);
});
it("emits 'xfc.unmounted' event", () => {
sinon.assert.called(emit);
});
});

describe('#load()', () => {
const newURL = 'http://localhost:8080/test';

it("sets the frame's origin to the origin of newURL", () => {
frame.load(newURL);
expect(frame.origin).to.equal(new URI(newURL).origin);
});
it("sets the frame's source to newURL", () => {
frame.load(newURL);
expect(frame.source).to.equal(newURL);
});
it("sets the iframe's src to newURL", () => {
frame.load(newURL);
expect(frame.iframe.src).to.equal(newURL);
});
});

describe('#send(message)', () => {
it("calls postMessage with given message on iframe.contentWindow", sinon.test(function() {
const postMessage = this.stub(frame.iframe.contentWindow, "postMessage");
Expand Down

0 comments on commit a8391f8

Please sign in to comment.