forked from mozilla/web-ext
-
Notifications
You must be signed in to change notification settings - Fork 1
/
remote.js
152 lines (139 loc) · 4.87 KB
/
remote.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
/* @flow */
import {createLogger} from '../util/logger';
import {RemoteTempInstallNotSupported, WebExtError} from '../errors';
import defaultFirefoxConnector from 'node-firefox-connect';
const log = createLogger(__filename);
// The default port that Firefox's remote debugger will listen on and the
// client will connect to.
export const REMOTE_PORT = 6005;
export default function connect(
port: number = REMOTE_PORT,
{connectToFirefox=defaultFirefoxConnector}: Object = {}): Promise {
log.debug(`Connecting to Firefox on port ${port}`);
return connectToFirefox(port)
.then((client) => {
log.debug('Connected to the remote Firefox debugger');
return new RemoteFirefox(client);
});
}
export class RemoteFirefox {
client: Object;
checkForAddonReloading: Function;
checkedForAddonReloading: boolean;
addonRequest: Function;
getInstalledAddon: Function;
constructor(client: Object) {
this.client = client;
this.checkedForAddonReloading = false;
client.client.on('disconnect', () => {
log.debug('Received "disconnect" from Firefox client');
});
client.client.on('end', () => {
log.debug('Received "end" from Firefox client');
});
client.client.on('message', (info) => {
// These are arbitrary messages that the client library ignores.
log.debug(`Received message from client: ${JSON.stringify(info)}`);
});
}
disconnect() {
this.client.disconnect();
}
addonRequest(addon: Object, request: string): Promise {
return new Promise((resolve, reject) => {
this.client.client.makeRequest(
{to: addon.actor, type: request}, (response) => {
if (response.error) {
reject(
new WebExtError(`${request} response error: ` +
`${response.error}: ${response.message}`));
} else {
resolve(response);
}
});
});
}
installTemporaryAddon(addonPath: string): Promise {
return new Promise((resolve, reject) => {
this.client.request('listTabs', (error, response) => {
if (error) {
return reject(new WebExtError(
`Remote Firefox: listTabs() error: ${error}`));
}
if (!response.addonsActor) {
log.debug(
`listTabs returned a falsey addonsActor: ${response.addonsActor}`);
return reject(new RemoteTempInstallNotSupported(
'This is an older version of Firefox that does not provide an ' +
'add-ons actor for remote installation. Try Firefox 49 or ' +
'higher.'));
}
this.client.client.makeRequest(
{to: response.addonsActor, type: 'installTemporaryAddon', addonPath},
(response) => {
if (response.error) {
return reject(new WebExtError(
'installTemporaryAddon: Error: ' +
`${response.error}: ${response.message}`));
}
log.debug(`installTemporaryAddon: ${JSON.stringify(response)}`);
log.info(`Installed ${addonPath} as a temporary add-on`);
resolve(response);
});
});
});
}
getInstalledAddon(addonId: string): Promise {
return new Promise(
(resolve, reject) => {
this.client.request('listAddons', (error, response) => {
if (error) {
reject(new WebExtError(
`Remote Firefox: listAddons() error: ${error}`));
} else {
resolve(response.addons);
}
});
})
.then((addons) => {
for (const addon of addons) {
if (addon.id === addonId) {
return addon;
}
}
log.debug(
`Remote Firefox has these addons: ${addons.map((a) => a.id)}`);
throw new WebExtError(
'The remote Firefox does not have your extension installed');
});
}
checkForAddonReloading(addon: Object): Promise {
if (this.checkedForAddonReloading) {
// We only need to check once if reload() is supported.
return Promise.resolve(addon);
} else {
return this.addonRequest(addon, 'requestTypes')
.then((response) => {
if (response.requestTypes.indexOf('reload') === -1) {
log.debug(
`Remote Firefox only supports: ${response.requestTypes}`);
throw new WebExtError(
'This Firefox version does not support add-on reloading. ' +
'Re-run with --no-reload');
} else {
this.checkedForAddonReloading = true;
return addon;
}
});
}
}
reloadAddon(addonId: string): Promise {
return this.getInstalledAddon(addonId)
.then((addon) => this.checkForAddonReloading(addon))
.then((addon) => {
log.info(
`${(new Date()).toTimeString()}: Reloaded extension: ${addon.id}`);
return this.addonRequest(addon, 'reload');
});
}
}