vscode-helpers
Version:
Helper functions and classes for own VS Code (extensions)
245 lines • 9.49 kB
JavaScript
;
/**
* This file is part of the vscode-helpers distribution.
* Copyright (c) Marcel Joachim Kloubert.
*
* vscode-helpers is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, version 3.
*
* vscode-helpers is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
Object.defineProperty(exports, "__esModule", { value: true });
const _ = require("lodash");
const vscode_helpers = require("../index");
const vscode_helpers_disposable = require("../disposable/index");
const vscode_helpers_events = require("../events/index");
const vscode_helpers_http = require("../http/index");
const WebSocket = require("ws");
/**
* A DevTools client.
*/
class DevToolsClient extends vscode_helpers_disposable.DisposableBase {
/**
* Initializes a new instance of that class.
*
* @param {DevToolsClientOptions} [opts] Custom options.
*/
constructor(opts) {
super();
this.options = opts || {};
}
async getBrowserItems() {
const RESP = await vscode_helpers_http.GET(`http://${this.host}:${this.port}/json`);
if (200 !== RESP.code) {
throw new Error(`Unexpected response ${RESP.code}: '${RESP.status}'`);
}
return vscode_helpers.asArray(JSON.parse((await RESP.readBody()).toString('utf8'))).filter(i => {
return !vscode_helpers.isEmptyString(i['webSocketDebuggerUrl']);
});
}
/**
* Returns a list of all IFrames.
*
* @return {Promise<BrowserFrame[]>} The promise with the frames.
*/
async getFrames() {
const IFRAMES = [];
const IFRAME_ITEMS = (await this.getBrowserItems()).filter(i => {
return 'iframe' === vscode_helpers.normalizeString(i['type']);
});
for (const FI of IFRAME_ITEMS) {
const NEW_FRAME = new BrowserFrameImpl(this);
NEW_FRAME.id = vscode_helpers.toStringSafe(FI['id']);
NEW_FRAME.parentId = vscode_helpers.toStringSafe(FI['parentId']);
NEW_FRAME.favIcon = vscode_helpers.toStringSafe(FI['faviconUrl']);
NEW_FRAME.title = vscode_helpers.toStringSafe(FI['title']);
NEW_FRAME.description = vscode_helpers.toStringSafe(FI['description']);
NEW_FRAME.socketUri = vscode_helpers.toStringSafe(FI['webSocketDebuggerUrl']);
IFRAMES.push(NEW_FRAME);
}
return IFRAMES;
}
/**
* Returns a list of all pages.
*
* @return {Promise<BrowserPage[]>} The promise with the pages.
*/
async getPages() {
const PAGES = [];
const PAGE_ITEMS = (await this.getBrowserItems()).filter(i => {
return 'page' === vscode_helpers.normalizeString(i['type']);
});
for (const PI of PAGE_ITEMS) {
const NEW_PAGE = new BrowserPageImpl(this);
NEW_PAGE.id = vscode_helpers.toStringSafe(PI['id']);
NEW_PAGE.favIcon = vscode_helpers.toStringSafe(PI['faviconUrl']);
NEW_PAGE.title = vscode_helpers.toStringSafe(PI['title']);
NEW_PAGE.description = vscode_helpers.toStringSafe(PI['description']);
NEW_PAGE.socketUri = vscode_helpers.toStringSafe(PI['webSocketDebuggerUrl']);
PAGES.push(NEW_PAGE);
}
return PAGES;
}
/**
* Gets the host address.
*/
get host() {
let hostAddr = vscode_helpers.toStringSafe(this.options.host);
if ('' === hostAddr) {
hostAddr = '127.0.0.1';
}
return hostAddr;
}
/**
* Gets the TCP port.
*/
get port() {
let tcpPort = parseInt(vscode_helpers.toStringSafe(this.options.port).trim());
if (isNaN(tcpPort)) {
tcpPort = 9222;
}
return tcpPort;
}
}
exports.DevToolsClient = DevToolsClient;
class BrowserItemBase extends vscode_helpers_disposable.DisposableBase {
constructor(client) {
super();
this.client = client;
this._nextId = 0;
}
close() {
return new Promise((resolve, reject) => {
const COMPLETED = vscode_helpers.createCompletedAction(resolve, reject);
const CUR_SOCKET = this._socket;
if (_.isNil(CUR_SOCKET)) {
COMPLETED(null, false);
return;
}
try {
CUR_SOCKET.close();
vscode_helpers_events.tryRemoveAllListeners(CUR_SOCKET);
this._socket = null;
COMPLETED(null);
}
catch (e) {
COMPLETED(e);
}
});
}
connect() {
return new Promise((resolve, reject) => {
const COMPLETED = vscode_helpers.createCompletedAction(resolve, reject);
if (this.isInFinalizeState) {
COMPLETED(new Error('Object is or is going to be disposed'));
return;
}
if (!_.isNil(this._socket)) {
COMPLETED(null, false);
return;
}
try {
const NEW_SOCKET = new WebSocket(this.socketUri);
NEW_SOCKET.once('error', (err) => {
if (err) {
COMPLETED(err);
}
});
NEW_SOCKET.once('close', () => {
this._socket = null;
this.emit('close', NEW_SOCKET);
});
NEW_SOCKET.once('open', () => {
this._sendCallbacks = {};
this._socket = NEW_SOCKET;
COMPLETED(null, true);
});
NEW_SOCKET.on('message', (data) => {
const ALL_CALLBACKS = this._sendCallbacks;
if (!_.isNil(ALL_CALLBACKS)) {
try {
let msg;
if (!_.isNil(data)) {
msg = JSON.parse(vscode_helpers.toStringSafe(data));
}
if (_.isPlainObject(msg)) {
const MSG_ID = parseInt(vscode_helpers.toStringSafe(msg.id).trim());
if (!isNaN(MSG_ID)) {
const DELETE_CALLBACK = (err) => {
delete ALL_CALLBACKS[MSG_ID];
};
try {
const CALLBACK = ALL_CALLBACKS[MSG_ID];
if (!_.isNil(CALLBACK)) {
Promise.resolve(CALLBACK(msg)).then(() => {
DELETE_CALLBACK();
}, (err) => {
DELETE_CALLBACK(err);
});
}
}
finally {
DELETE_CALLBACK();
}
}
}
}
catch (_a) { }
}
this.emit('message', NEW_SOCKET, data);
});
}
catch (e) {
COMPLETED(e);
}
});
}
get isConnected() {
return !_.isNil(this._socket);
}
onDispose() {
const CUR_SOCKET = this._socket;
if (!_.isNil(CUR_SOCKET)) {
CUR_SOCKET.close();
vscode_helpers_events.tryRemoveAllListeners(CUR_SOCKET);
this._socket = null;
}
this._sendCallbacks = null;
}
send(method, params, callback) {
method = vscode_helpers.toStringSafe(method).trim();
return new Promise((resolve, reject) => {
const COMPLETED = vscode_helpers.createCompletedAction(resolve, reject);
let id = 0;
try {
id = ++this._nextId;
if (!_.isNil(callback)) {
this._sendCallbacks[id] = callback;
}
this._socket.send(JSON.stringify({
id: id,
method: method,
params: params,
}), (err) => {
COMPLETED(err);
});
}
catch (e) {
delete this._sendCallbacks[id];
COMPLETED(e);
}
});
}
}
class BrowserPageImpl extends BrowserItemBase {
}
class BrowserFrameImpl extends BrowserPageImpl {
}
//# sourceMappingURL=index.js.map