Fix bugs in Chrome extension, rewrite it in ES6

This commit is contained in:
Alexey Andreev 2018-12-26 18:57:30 +03:00
parent 58c19e3abc
commit 830aa2c9b1
3 changed files with 128 additions and 94 deletions

View File

@ -14,13 +14,13 @@
* limitations under the License.
*/
var connected = false;
window.addEventListener("message", function(event) {
let connected = false;
window.addEventListener("message", (event) => {
if (event.source !== window) {
return;
}
var data = event.data;
const data = event.data;
if (typeof data.teavmDebugger !== "undefined" && !connected) {
connected = true;
chrome.runtime.sendMessage({ command: "debug", port: data.teavmDebugger.port });

View File

@ -1,110 +1,144 @@
debuggerAgentMap = {};
debuggerAgentMap = Object.create(null);
class DebuggerAgent {
constructor(tab, port) {
this.pendingMessages = [];
this.connection = null;
this.attachedToDebugger = false;
this.messageBuffer = "";
this.port = 0;
this.disconnectCallbacks = null;
this.debuggee = { tabId : tab.id };
this.port = port;
debuggerAgentMap[tab.id] = this;
}
attach() {
chrome.debugger.attach(this.debuggee, "1.2", () => {
this.attachedToDebugger = true;
chrome.debugger.sendCommand(this.debuggee, "Debugger.enable", {}, () => this.connectToServer());
});
}
connectToServer() {
this.connection = new WebSocket("ws://localhost:" + this.port + "/");
this.connection.onmessage = event => {
const str = event.data;
const ctl = str.substring(0, 1);
this.messageBuffer += str.substring(1);
if (ctl === '.') {
this.receiveMessage(JSON.parse(this.messageBuffer));
this.messageBuffer = "";
}
};
this.connection.onclose = () => {
if (this.connection != null) {
this.connection = null;
this.disconnect();
}
};
this.connection.onopen = () => {
for (const pendingMessage of this.pendingMessages) {
this.sendMessage(pendingMessage);
}
this.pendingMessages = null;
};
}
receiveMessage(message) {
chrome.debugger.sendCommand(this.debuggee, message.method, message.params, response => {
if (message.id) {
const responseToServer = {
id : message.id,
result : response,
error : response ? void 0 : chrome.runtime.lastError
};
this.sendMessage(responseToServer);
}
});
}
sendMessage(message) {
let str = JSON.stringify(message);
while (str.length > DebuggerAgent.MAX_MESSAGE_SIZE) {
const part = "," + str.substring(0, DebuggerAgent.MAX_MESSAGE_SIZE);
this.connection.send(part);
str = str.substring(DebuggerAgent.MAX_MESSAGE_SIZE);
}
this.connection.send("." + str);
}
disconnect(callback) {
if (this.connection) {
const conn = this.connection;
this.connection = null;
conn.close();
}
if (this.attachedToDebugger) {
chrome.debugger.detach(this.debuggee, () => {
if (this.debuggee) {
delete debuggerAgentMap[this.debuggee.tabId];
this.debuggee = null;
}
for (const callback of this.disconnectCallbacks) {
callback();
}
this.disconnectCallbacks = null;
});
this.attachedToDebugger = false;
this.disconnectCallbacks = [];
}
if (callback) {
if (this.disconnectCallbacks != null) {
this.disconnectCallbacks.push(callback);
} else {
callback();
}
}
}
}
DebuggerAgent.MAX_MESSAGE_SIZE = 65534;
chrome.browserAction.onClicked.addListener(function(tab) {
chrome.storage.sync.get({
port: 2357,
}, function(items) {
new DebuggerAgent(tab, items.port).attach();
});
chrome.storage.sync.get({ port: 2357 }, items => attachDebugger(tab, items.port));
});
function DebuggerAgent(tab, port) {
this.pendingMessages = [];
this.connection = null;
this.tab = null;
this.debuggee = { tabId : tab.id };
this.attachedToDebugger = false;
this.messageBuffer = "";
this.port = port;
debuggerAgentMap[tab.id] = this;
}
DebuggerAgent.MAX_MESSAGE_SIZE = 65534;
DebuggerAgent.prototype.attach = function() {
chrome.debugger.attach(this.debuggee, "1.0", function(callback) {
this.attachedToDebugger = true;
chrome.debugger.sendCommand(this.debuggee, "Debugger.enable", {}, callback);
}.bind(this, this.connectToServer.bind(this)));
};
DebuggerAgent.prototype.connectToServer = function() {
this.connection = new WebSocket("ws://localhost:" + this.port + "/");
this.connection.onmessage = function(event) {
var str = event.data;
var ctl = str.substring(0, 1);
this.messageBuffer += str.substring(1);
if (ctl === '.') {
this.receiveMessage(JSON.parse(this.messageBuffer));
this.messageBuffer = "";
}
}.bind(this);
this.connection.onclose = function(event) {
if (this.connection != null) {
this.connection = null;
this.disconnect();
}
}.bind(this);
this.connection.onopen = function() {
for (var i = 0; i < this.pendingMessages.length; ++i) {
this.sendMessage(this.pendingMessages[i]);
}
this.pendingMessages = null;
}.bind(this);
};
DebuggerAgent.prototype.receiveMessage = function(message) {
chrome.debugger.sendCommand(this.debuggee, message.method, message.params, function(response) {
if (message.id) {
var responseToServer = { id : message.id, result : response,
error : response ? undefined : chrome.runtime.lastError };
this.sendMessage(responseToServer);
}
}.bind(this));
};
DebuggerAgent.prototype.sendMessage = function(message) {
var str = JSON.stringify(message);
while (str.length > DebuggerAgent.MAX_MESSAGE_SIZE) {
var part = "," + str.substring(0, DebuggerAgent.MAX_MESSAGE_SIZE);
this.connection.send(part);
str = str.substring(DebuggerAgent.MAX_MESSAGE_SIZE);
}
this.connection.send("." + str);
};
DebuggerAgent.prototype.disconnect = function() {
if (this.connection) {
var conn = this.connection;
this.connection = null;
conn.close();
}
if (this.attachedToDebugger) {
chrome.debugger.detach(this.debuggee);
this.attachedToDebugger = false;
}
if (this.debuggee) {
delete debuggerAgentMap[this.debuggee.tabId];
this.debuggee = null;
}
};
chrome.debugger.onEvent.addListener(function(source, method, params) {
var agent = debuggerAgentMap[source.tabId];
chrome.debugger.onEvent.addListener((source, method, params) => {
const agent = debuggerAgentMap[source.tabId];
if (!agent) {
return;
}
var message = { method : method, params : params };
const message = { method : method, params : params };
if (agent.pendingMessages) {
agent.pendingMessages.push(message);
} else if (agent.connection) {
agent.sendMessage(message);
}
});
chrome.debugger.onDetach.addListener(function(source) {
var agent = debuggerAgentMap[source.tabId];
chrome.debugger.onDetach.addListener((source) => {
const agent = debuggerAgentMap[source.tabId];
if (agent) {
agent.attachedToDebugger = false;
agent.disconnect();
}
});
chrome.runtime.onMessage.addListener(function(message, sender, callback) {
chrome.runtime.onMessage.addListener((message, sender) => {
if (message.command === "debug") {
new DebuggerAgent(sender.tab, message.port).attach();
attachDebugger(sender.tab, message.port);
}
});
});
function attachDebugger(tab, port) {
const existingAgent = debuggerAgentMap[tab.id];
if (!existingAgent) {
new DebuggerAgent(tab, port).attach();
} else if (existingAgent.port !== port) {
existingAgent.disconnect(() => {
new DebuggerAgent(tab, port).attach();
});
}
}

View File

@ -15,7 +15,7 @@
*/
function saveOptions() {
var port = document.getElementById("port").value;
const port = document.getElementById("port").value;
chrome.storage.sync.set({
port: port !== "" ? parseInt(port) : 2357,
});
@ -24,7 +24,7 @@ function saveOptions() {
function loadOptions() {
chrome.storage.sync.get({
port: 2357,
}, function(items) {
}, (items) => {
document.getElementById("port").value = items.port;
});
}