1 import {Injectable, EventEmitter} from '@angular/core';
3 export class HatchMessage {
5 resolver: (HatchMessage) => void; // promise resolver
6 rejector: (HatchMessage) => void; // promise rejector
8 message: string; // error message
13 // Response from Hatch.
18 constructor(hash: any) {
20 Object.keys(hash).forEach(key => this[key] = hash[key]);
26 export class HatchService {
30 messages: {[msgid:number]: HatchMessage};
33 this.isAvailable = null;
40 if (this.isAvailable !== null) {
41 return this.isAvailable;
44 // When the Hatch extension loads, it tacks an attribute onto
45 // the top-level documentElement to indicate it's available.
46 if (!window.document.documentElement.getAttribute('hatch-is-open')) {
47 console.warn('Could not connect to Hatch');
48 return this.isAvailable = false;
51 window.addEventListener('message', event => {
53 // We only accept messages from our own content script.
54 if (event.source !== window) { return; }
56 // We only care about messages from the Hatch extension.
57 if (event.data && event.data.from === 'extension') {
59 // Avoid logging full Hatch responses. they can get large.
61 `Hatch responded to message ID ${event.data.msgid}`);
63 this.handleResponse(event.data);
67 return this.isAvailable = true;
70 // Send a request from the browser to Hatch.
71 sendRequest(msg: HatchMessage): Promise<HatchMessage> {
72 if (this.isAvailable === false) {
73 return Promise.reject('Hatch is not connected');
76 msg.msgid = this.msgId++;
78 this.messages[msg.msgid] = msg;
79 window.postMessage(msg, window.location.origin);
81 return new Promise((resolve, reject) => {
82 msg.resolver = resolve;
83 msg.rejector = reject;
87 // Handle the data sent back to the browser from Hatch.
88 handleResponse(data: any) {
90 const msg = this.messages[data.msgid];
92 console.warn(`No Hatch request found with ID ${data.msgid}`);
96 delete this.messages[data.msgid];
97 msg.response = data.content;
98 msg.message = data.message;
99 msg.status = Number(data.status);
101 if (msg.status === 200) {
104 console.error(`Hatch request returned status ${msg.status}`, msg);