Use postMessage between page/content (#31)

This commit is contained in:
Jaco Greeff 2019-05-26 09:45:55 +02:00 committed by GitHub
parent 69cb9015d2
commit 886b36c20a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 27 additions and 41 deletions

View File

@ -1,14 +0,0 @@
// Copyright 2019 @polkadot/extension authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
const eventTarget = document;
const events = {
request: 'PolkadotJsWebRequest',
response: 'PolkadotJsWebResponse'
};
export { eventTarget };
export default events;

View File

@ -5,7 +5,6 @@
import { InjectedWindow } from '@polkadot/extension-dapp/types';
import { MessageTypes } from '../background/types';
import events, { eventTarget } from '../events';
import Injected from './Injected';
// when sending a message from the injector to the expension, we
@ -27,17 +26,15 @@ const windowInject = window as InjectedWindow;
const callbacks: Callbacks = {};
let idCounter = 0;
// a generic message sender that creates an event, returning a promise that will resolve once
// the event is resolved (by the response listener just below this)
// a generic message sender that creates an event, returning a promise that will
// resolve once the event is resolved (by the response listener just below this)
function sendMessage (message: MessageTypes, request: any = null): Promise<any> {
return new Promise((resolve, reject) => {
const id = ++idCounter;
callbacks[id] = { resolve, reject };
eventTarget.dispatchEvent(
new CustomEvent(events.request, { detail: { id, message, request } })
);
window.postMessage({ id, message, origin: 'inject', request }, '*');
});
}
@ -49,21 +46,25 @@ async function enable (origin: string): Promise<Injected> {
}
// setup a response listener (events created by the loader for extension responses)
eventTarget.addEventListener(events.response, (event) => {
const response = (event as CustomEvent).detail;
const promise = callbacks[response.id];
if (!promise) {
console.error(`Uknown response: ${JSON.stringify(response)}`);
window.addEventListener('message', ({ data, source }) => {
// only allow messages from our window, by the loader
if (source !== window || data.origin !== 'loader') {
return;
}
delete callbacks[response.id];
const promise = callbacks[data.id];
if (response.error) {
promise.reject(new Error(response.error));
if (!promise) {
console.error(`Uknown response: ${JSON.stringify(data)}`);
return;
}
delete callbacks[data.id];
if (data.error) {
promise.reject(new Error(data.error));
} else {
promise.resolve(response.response);
promise.resolve(data.response);
}
});

View File

@ -4,23 +4,22 @@
import extension from 'extensionizer';
import events, { eventTarget } from './events';
function sendResponse (detail: any): void {
// create the custom event, this will be handled on the injection script
eventTarget.dispatchEvent(new CustomEvent(events.response, { detail }));
function sendResponse (data: any): void {
window.postMessage({ ...data, origin: 'loader' }, '*');
}
// Handle all custom events, passing messages to the extension
eventTarget.addEventListener(events.request, (event) => {
// get the request as part of the the event detailt
const request = (event as CustomEvent).detail;
// Handle all messages, passing messages to the extension
window.addEventListener('message', ({ data, source }) => {
// only allow messages from our window, by the inject
if (source !== window || data.origin !== 'inject') {
return;
}
// pass the detail as-is as a message to the extension
extension.runtime.sendMessage(request, (response) => {
extension.runtime.sendMessage(data, (response) => {
if (!response) {
// no data, send diconnected/unknown error
sendResponse({ id: request.id, error: 'Unknown response' });
sendResponse({ id: data.id, error: 'Unknown response' });
} else {
// handle the response, passing as a custom event
sendResponse(response);