Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1084)

Side by Side Diff: headless/lib/browser/devtools_api/devtools_connection.js

Issue 2902583002: Add some closureised JS bindings for DevTools for use by headless embedder (Closed)
Patch Set: Make the JS better Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 /**
6 * @fileoverview Contains a class which marshals DevTools protocol messages over
7 * a provided low level message transport. This transport might be a headless
8 * TabSocket, or a WebSocket or a mock for testing.
9 */
10
11 'use strict';
12
13 goog.provide('chromium.DevTools.Connection');
14
15 /**
16 * @typedef {function(Object): undefined|function(string): undefined}
17 *
18 */
19 chromium.DevTools.CallbackFunction;
20
21 /**
22 * @class Handles sending and receiving DevTools JSON protocol messages over the
23 * provided low level message transport.
24 * @param {!Object} transport The API providing transport for devtools commands.
25 * @constructor
26 */
27 chromium.DevTools.Connection = function(transport) {
28 /** @private {!Object} */
29 this.transport_ = transport;
30
31 /** @private {number} */
32 this.commandId_ = 1;
33
34 /**
35 * An object containing pending DevTools protocol commands keyed by id.
36 *
37 * @private {!Map<number, !chromium.DevTools.CallbackFunction>}
38 */
39 this.pendingCommands_ = new Map();
40
41 /** @private {number} */
42 this.nextListenerId_ = 1;
43
44 /**
45 * An object containing DevTools protocol events we are listening for keyed by
46 * name.
47 *
48 * @private {!Map<string, !Map<number, !chromium.DevTools.CallbackFunction>>}
49 */
50 this.eventListeners_ = new Map();
51
52 /**
53 * Used for removing event listeners by id.
54 *
55 * @private {!Map<number, string>}
56 */
57 this.eventListenerIdToEventName_ = new Map();
58
59 this.transport_.onmessage = this.onMessage_.bind(this);
60 };
61
62
63 /**
64 * Listens for DevTools protocol events of the specified name and issues the
65 * callback upon reception.
66 *
67 * @param {string} eventName Name of the DevTools protocol event to listen for.
68 * @param {!chromium.DevTools.CallbackFunction} listener The callback issued
69 * when we receive a DevTools protocol event corresponding to the given name.
70 * @return {number} The id of this event listener.
71 */
72 chromium.DevTools.Connection.prototype.addEventListener = function(
73 eventName, listener) {
74 if (!this.eventListeners_.has(eventName)) {
75 this.eventListeners_.set(eventName, new Map());
76 }
77 let id = this.nextListenerId_++;
78 this.eventListeners_.get(eventName).set(id, listener);
79 this.eventListenerIdToEventName_.set(id, eventName);
80 return id;
81 };
82
83
84 /**
85 * Removes an event listener previously added by <code>addEventListener</code>.
86 *
87 * @param {number} id The id of the event listener to remove.
88 * @returbn {boolean} Returns true if the event listener was actually removed.
dpapad 2017/06/07 17:49:23 s/returnbn/return s/Returns true if/Whether
alex clarke (OOO till 29th) 2017/06/08 10:33:15 Done.
89 */
90 chromium.DevTools.Connection.prototype.removeEventListener = function(id) {
91 if (!this.eventListenerIdToEventName_.has(id)) return false;
92 let eventName = this.eventListenerIdToEventName_.get(id);
dpapad 2017/06/07 17:49:23 Nit (optional): You are using ES6 (aka ES2015) 'le
alex clarke (OOO till 29th) 2017/06/08 10:33:15 It sounds like you're OK with ES6 stuff :) ES6sty
93 this.eventListenerIdToEventName_.delete(id);
94 // This shouldn't happen, but lets check anyway.
95 if (!this.eventListeners_.has(eventName)) return false;
96 return this.eventListeners_.get(eventName).delete(id);
97 };
98
99
100 /**
101 * Issues a DevTools protocol command and returns a promise for the results.
102 *
103 * @param {string} method The name of the DevTools protocol command method.
104 * @param {!Object=} opt_params An object containing the command parameters if
105 * any.
106 * @return {!Promise<!Object>} A promise for the results object.
107 */
108 chromium.DevTools.Connection.prototype.sendDevToolsMessage = function(
109 method, opt_params) {
dpapad 2017/06/07 17:49:22 If you were to use ES6 for declaring optional para
alex clarke (OOO till 29th) 2017/06/08 10:33:15 Done.
110 if (opt_params === undefined) {
111 opt_params = {};
112 }
113 let id = this.commandId_;
114 // We increment by two because these bindings are intended to be used in
115 // conjunction with HeadlessDevToolsClient::RawProtocolListener and using odd
116 // numbers for js generated IDs lets the implementation of OnProtocolMessage
117 // easily distinguish between C++ and JS generated commands and route the
118 // response accordingly.
119 this.commandId_ += 2;
120 // Note the names are in quites to prevent closure compiler name mangling.
dpapad 2017/06/07 17:49:22 s/quites/quotes
alex clarke (OOO till 29th) 2017/06/08 10:33:15 Done.
121 this.transport_.send(
122 JSON.stringify({'method': method, 'id': id, 'params': opt_params}));
123 return new Promise((resolve, reject) => {
124 this.pendingCommands_.set(id, resolve);
dpapad 2017/06/07 17:49:22 I am assuming that the returned promise can never
alex clarke (OOO till 29th) 2017/06/08 10:33:15 Interesting. I guess right now that's not super e
125 });
126 };
127
128
129 /**
130 * @param {string} jsonMessage An object containing a DevTools protocol message.
131 * @private
132 */
133 chromium.DevTools.Connection.prototype.onMessage_ = function(jsonMessage) {
134 const message = JSON.parse(jsonMessage);
135 if (message.hasOwnProperty('id')) {
136 if (!this.pendingCommands_.has(message.id))
137 throw new Error('Unrecognized id:' + json_message);
138 if (message.hasOwnProperty('error'))
139 throw new Error('DevTools protocol error: ' + message.error);
140 this.pendingCommands_.get(message.id)(message.result);
141 this.pendingCommands_.delete(message.id);
142 } else {
143 if (!message.hasOwnProperty('method') ||
144 !message.hasOwnProperty('params')) {
145 throw new Error('Bad message:' + json_message);
146 }
147 const method = message['method'];
148 const params = message['params'];
149 if (this.eventListeners_.has(method)) {
150 this.eventListeners_.get(method).forEach(function(listener) {
151 listener(params);
152 });
153 }
154 }
155 };
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698