diff options
Diffstat (limited to 'extensions/chrome/common.js')
-rw-r--r-- | extensions/chrome/common.js | 187 |
1 files changed, 187 insertions, 0 deletions
diff --git a/extensions/chrome/common.js b/extensions/chrome/common.js new file mode 100644 index 0000000..30dc55a --- /dev/null +++ b/extensions/chrome/common.js @@ -0,0 +1,187 @@ +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(); |