postmate icon indicating copy to clipboard operation
postmate copied to clipboard

Question: Attach postmate to existing iframe instead of having postmate create one

Open javaguy opened this issue 7 years ago • 8 comments

Thanks for putting together this useful component. I'm new to using postMessage for communication and appreciate that I could find something which handles some of the complexities and security of dealing with iframes.

I'd like to use this library as part of a project I'm working on, and was wondering if I have an existing iframe rendered, can I attached postmate to that iframe instead? The reason for that is that I'm using react and preference would be to have react deal with the DOM manipulations.

javaguy avatar Feb 21 '18 15:02 javaguy

Interesting. It seems that this option could be provided. I will discuss it with the team soon.

~Thanks @javaguy!

yowainwright avatar Feb 24 '18 02:02 yowainwright

@javaguy sorry about the delay.

Would you mind submitting a PR with an appropriate test for this?

yowainwright avatar Jun 20 '18 01:06 yowainwright

I would also love to see this feature.

stefanedberg avatar Apr 05 '19 08:04 stefanedberg

+1 For working in the Vue.js world.

ventralnet avatar May 15 '19 19:05 ventralnet

Hello Guys, Any updates on this? Would love to use it within reactjs? Any workaround for this?

ivalsaraj avatar Jan 18 '20 07:01 ivalsaraj

+1 for this It would be good if it was just a message bus between two windows, not messing up with DOM manipulations...

munichmule avatar Apr 22 '20 02:04 munichmule

+1...

shikelong avatar Jun 30 '21 06:06 shikelong

I've seen a few requests on this, so I thought i'd share my approach here as a guide on how to use this with React. Sorry it's been a couple of years, so not sure if this will work with the latest versions of React or PostMate. Corrections welcome.

On the container component

componentDidMount() {
    let that = this;
    let container = this.iframeContainer,
        { viewerUrl, url } = this.props;

    // Kick off the handshake with the iFrame
    const handshake = new Postmate({
        container: container, // Element to inject frame into
        url: viewerUrl + '?url=' + encodeURI(url) // Page to load, must have postmate.js. This will also be the origin used for communication.
    });

    // When parent <-> child handshake is complete, data may be requested from the child
    handshake.then(child => {
        that.childPostmate = child;

        // You can now use child.call
        child.call('setParams', this.props.params);

        // Listen to a particular event from the child
        child.on('ActionPerformed', data => {
            console.log('Parent ActionPerformed called with data - ', data);
            // take action here
        });
    });
}

componentWillUnmount() {
    this.childPostmate.destroy();
    this.childPostmate = null;
}

render() {
    let { className } = this.props;

    return (
        <div
            className={className}
            ref={el => {
                this.iframeContainer = el;
            }}
        />
    );
}

On the component in the iFrame


componentDidMount() {
    const that = this;

    // Sets up IPC
    let handshake = new Postmate.Model({
        setParams: this.setParams
    });

    handshake
        .then(parent => {
            console.log('child handshake completed');
            that.parentPostmate = parent;
        })
        .catch(err => {
            console.log('could not establish link with parent.');
        });
}

setParams() {
    // Do something
}

onAction = (params) => {

    if (this.parentPostmate) {
        this.parentPostmate.emit('ActionPerformed', params);
    }
};

javaguy avatar Jun 30 '21 11:06 javaguy