188 lines
5.1 KiB
JavaScript
188 lines
5.1 KiB
JavaScript
function init() {
|
|
// receive messages from webpage
|
|
chrome.runtime.onMessageExternal.addListener(receiveMessage);
|
|
}
|
|
function receiveMessage(msg, sender, sendResponse) {
|
|
if (msg.cmd == "injection_result") {
|
|
var obj = Injections.get(msg.id);
|
|
if (obj) obj.addResponse(sender.tab.id, msg.data);
|
|
}
|
|
}
|
|
function extend(dest, source) {
|
|
for (var i in source) {
|
|
dest[i] = source[i];
|
|
}
|
|
}
|
|
function getWebSocket() {
|
|
return window.WebSocket || window.MozWebSocket;
|
|
}
|
|
function print() {
|
|
var msgs = [], i, tmp;
|
|
for (i = 0; i < arguments.length; i++) {
|
|
if (arguments[i] instanceof Error) tmp = [arguments[i], arguments[i].stack];
|
|
else tmp = arguments[i];
|
|
msgs.push(tmp);
|
|
}
|
|
|
|
try {
|
|
console.log.apply(console, msgs);
|
|
} catch(e) {}
|
|
}
|
|
function getExtensionId() {
|
|
return chrome.i18n.getMessage("@@extension_id");
|
|
}
|
|
function getVKTabs(callback) {
|
|
var vkTabs = [];
|
|
chrome.tabs.query({}, function(tabs) {
|
|
for (var i = 0; i < tabs.length; i++) {
|
|
var tab = tabs[i];
|
|
if (tab.url.match(new RegExp('https?://vk.com/.*', 'gi'))) {
|
|
vkTabs.push(tab);
|
|
}
|
|
}
|
|
callback(vkTabs);
|
|
});
|
|
}
|
|
function executeCommand(cmd) {
|
|
var injId = Injections.getNextId();
|
|
var code_inj = "var el = document.createElement('script'); el.src = chrome.extension.getURL('inject_and_return.js'); document.body.appendChild(el); var el1 = document.createElement('script'); el1.textContent = 'window.__vkpc_extid=\""+getExtensionId()+"\"; window.__vkpc_injid="+injId+"'; document.body.appendChild(el1)";
|
|
var code_exec = "var el = document.createElement('script'); el.src = chrome.extension.getURL('inject_exec.js'); document.body.appendChild(el); var el1 = document.createElement('script'); el1.textContent = 'window.__vkpc_cmd=\""+cmd+"\"'; document.body.appendChild(el1)";
|
|
|
|
getVKTabs(function(tabs) {
|
|
if (!tabs.length) return;
|
|
|
|
var injResponses, activeTabId = null;
|
|
var onDone = function() {
|
|
var ok = {nowPlaying: null, lsSource: null, recentlyPlayed: null, active: activeTabId, last: null};
|
|
var results = injResponses.results, lsSource = injResponses.lsSource;
|
|
|
|
for (var i = 0; i < results.length; i++) {
|
|
var data = results[i].data, id = results[i].tab;
|
|
ok.last = id;
|
|
|
|
if (data.havePlayer && (data.isPlaying || typeof data.trackId == 'string')) {
|
|
ok.recentlyPlayed = id;
|
|
}
|
|
if (data.isPlaying) {
|
|
ok.nowPlaying = id;
|
|
}
|
|
if (lsSource && lsSource == data.instanceId) {
|
|
ok.lsSource = id;
|
|
}
|
|
}
|
|
injResponses.unregister();
|
|
|
|
var rightId = ok.nowPlaying || ok.lsSource || ok.recentlyPlayed || ok.active || ok.last;
|
|
if (rightId) {
|
|
chrome.tabs.executeScript(rightId, {code: code_exec});
|
|
}
|
|
};
|
|
injResponses = new InjectionResponses(injId, tabs.length, onDone);
|
|
|
|
for (var i = 0; i < tabs.length; i++) {
|
|
if (tabs[i].active) activeTabId = tabs[i].id;
|
|
chrome.tabs.executeScript(tabs[i].id, {
|
|
code: code_inj
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
var Injections = {
|
|
id: 0,
|
|
objs: {},
|
|
getNextId: function() {
|
|
return ++this.id;
|
|
},
|
|
get: function(id) {
|
|
return this.objs[id] || false;
|
|
},
|
|
register: function(id, obj) {
|
|
this.objs[id] = obj;
|
|
},
|
|
unregister: function(id) {
|
|
if (this.objs[id] !== undefined) delete this.objs[id];
|
|
}
|
|
};
|
|
|
|
var WSClient = new function() {
|
|
var STATUS_NONE = 0, STATUS_OK = 1, STATUS_ERR = 2;
|
|
var _ws = getWebSocket(), ws;
|
|
var _status = STATUS_NONE;
|
|
var ping_timer, reconnect_timer;
|
|
|
|
if (!_ws) return;
|
|
|
|
function setTimers() {
|
|
ping_timer = setInterval(function() {
|
|
if (ws) ws.send("PING");
|
|
}, 30000);
|
|
}
|
|
function unsetTimers() {
|
|
clearInterval(ping_timer);
|
|
}
|
|
|
|
function connect() {
|
|
_status = STATUS_NONE;
|
|
|
|
print("[connect]");
|
|
ws = new _ws("ws://localhost:52178", "signaling-protocol");
|
|
ws.onopen = function() {
|
|
_status = STATUS_OK;
|
|
setTimers();
|
|
};
|
|
ws.onerror = function() {
|
|
unsetTimers();
|
|
if (_status != STATUS_ERR) {
|
|
_status = STATUS_ERR;
|
|
tryToReconnect();
|
|
}
|
|
}
|
|
ws.onclose = function() {
|
|
unsetTimers();
|
|
if (_status != STATUS_ERR) {
|
|
_status = STATUS_ERR;
|
|
tryToReconnect();
|
|
}
|
|
};
|
|
ws.onmessage = function(e) {
|
|
onCommand(e.data);
|
|
};
|
|
}
|
|
function tryToReconnect() {
|
|
print("[tryToReconnect]");
|
|
|
|
clearTimeout(reconnect_timer);
|
|
reconnect_timer = setTimeout(connect, 5000);
|
|
}
|
|
function onCommand(msg) {
|
|
executeCommand(msg);
|
|
}
|
|
|
|
connect();
|
|
};
|
|
|
|
function InjectionResponses(id, count, callback) {
|
|
this.id = id;
|
|
this.results = [];
|
|
this.lsSource = null;
|
|
this.maxCount = count;
|
|
this.callback = callback || function() {};
|
|
|
|
Injections.register(this.id, this);
|
|
}
|
|
extend(InjectionResponses.prototype, {
|
|
addResponse: function(id, response) {
|
|
this.results.push({tab: id, data: response});
|
|
if (!this.lsSource && response && response.lastInstanceId) this.lsSource = response.lastInstanceId;
|
|
if (this.results.length == this.maxCount) {
|
|
this.callback();
|
|
}
|
|
},
|
|
unregister: function() {
|
|
Injections.unregister(this.id);
|
|
}
|
|
});
|
|
|
|
init();
|