diff --git a/.gitignore b/.gitignore
index 60c0056..f217f53 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,4 @@
*.swp
keysocket.zip
+*.crx
+*.pem
diff --git a/extension/background.html b/extension/background.html
new file mode 100644
index 0000000..33a4932
--- /dev/null
+++ b/extension/background.html
@@ -0,0 +1,10 @@
+
+
+
+
+keysocket
+
+
+
+
+
\ No newline at end of file
diff --git a/extension/background.js b/extension/background.js
index b8bc0b1..832c287 100644
--- a/extension/background.js
+++ b/extension/background.js
@@ -12,187 +12,143 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
-var registeredTabs = [];
-var registerTab = function (tabId) {
- if (registeredTabs.indexOf(tabId) == -1) {
- registeredTabs.push(tabId);
-
- chrome.pageAction.show(tabId);
- chrome.pageAction.setIcon({
- tabId: tabId,
- path: {
- '19': 'icons/icon19.png',
- '38': 'icons/icon38.png'
- }
- });
- chrome.pageAction.setTitle({
- tabId: tabId,
- title: 'Click to disable media keys for this tab'
- });
-
- updateContextMenu(tabId);
+
+var tabsState = {};
+var controllableTabs = {};
+var playingTabs = {};
+var lastPlayingTab = -1;
+var activeTab = -1;
+
+function togglePlaying(tabId, state) {
+ if(state === undefined) {
+ state = !playingTabs[tabId];
+ }
+
+ if (playingTabs.hasOwnProperty(tabId) && !state) {
+ delete playingTabs[tabId];
+ } else if (!playingTabs.hasOwnProperty(tabId) && state) {
+ playingTabs[tabId] = true;
}
-};
-var unregisterTab = function (tabId) {
- var index = registeredTabs.indexOf(tabId);
- if (index > -1) {
- registeredTabs.splice(index, 1);
+}
- chrome.pageAction.setIcon({
- tabId: tabId,
- path: {
- '19': 'icons/icon19-inactive.png',
- '38': 'icons/icon38-inactive.png'
+function sendCommand(tabId, command) {
+
+ if (command === 'play-pause') {
+ togglePlaying(tabId);
+ }
+
+ chrome.tabs.sendMessage(tabId, {command: command});
+}
+
+function registerTab(tabId) {
+ if (!controllableTabs.hasOwnProperty(tabId)) {
+ controllableTabs[tabId] = true;
+
+ chrome.tabs.get(tabId, function(tab) {
+ if (tab.audible) {
+ togglePlaying(tabId, true);
}
});
- chrome.pageAction.setTitle({
- tabId: tabId,
- title: 'Click to enable media keys for this tab'
- });
- updateContextMenu(tabId);
+ chrome.pageAction.show(tabId);
+ //TODO: save state in local storage
+ tabsPluginState(tabId, true);
}
-};
+}
-var updateContextMenu = function(tabId){
- chrome.tabs.query({active: true}, function(tab){
- tab = tab[0];
- if(tab.id == tabId) {
- var index = registeredTabs.indexOf(tabId);
- if (index > -1) {
- chrome.contextMenus.update("keySocketMediaKeys-disableThisTab", {enabled: true});
- chrome.contextMenus.update("keySocketMediaKeys-enableThisTab", {enabled: false});
- }
- else {
- chrome.contextMenus.update("keySocketMediaKeys-disableThisTab", {enabled: false});
- chrome.contextMenus.update("keySocketMediaKeys-enableThisTab", {enabled: true});
- }
- }
- });
-};
-
-chrome.commands.onCommand.addListener(function (command) {
- console.log('Command:', command);
-
- for (var i = 0; i < registeredTabs.length; i++) {
- chrome.tabs.sendMessage(registeredTabs[i], {command: command});
+function unregisterTab(tabId) {
+ if (controllableTabs.hasOwnProperty(tabId)) {
+ delete controllableTabs[tabId];
+ delete tabsPluginState[tabId];
+ togglePlaying(tabId, false);
}
-});
-
-chrome.runtime.onMessage.addListener(
- function (request, sender, sendResponse) {
- console.log('Received tab message: ', request);
+}
- if (request.command == 'registerTab' && sender.tab) {
- registerTab(sender.tab.id);
- } else if (request.command == 'unregisterTab' && sender.tab) {
- unregisterTab(sender.tab.id);
- }
+function checkAudible(tabId, changeInfo) {
+ if (!changeInfo.hasOwnProperty('audible')) {
+ return;
}
-);
-
-chrome.tabs.onRemoved.addListener(unregisterTab);
-
-chrome.pageAction.onClicked.addListener(function (tab) {
- var index = registeredTabs.indexOf(tab.id);
- if (index < 0) {
- registerTab(tab.id);
+
+ if (!controllableTabs.hasOwnProperty(tabId)) {
+ console.log('ignore unregistered', tabId);
+ return;
+ }
+
+ if (changeInfo.audible) {
+ playingTabs[tabId] = true;
+ lastPlayingTab = tabId;
+ console.log('update playingTabs', playingTabs);
} else {
- unregisterTab(tab.id);
+ togglePlaying(tabId, false);
+ lastPlayingTab = tabId;
}
-});
-
-chrome.tabs.onActivated.addListener(function (evt) {
- updateContextMenu(evt.tabId);
-});
+}
+
+function tabsPluginState(tabId, state) {
+ tabId = tabId.id || tabId
+ tabsState[tabId] = state !== undefined && state || !tabsState[tabId]
+ postfix = ''
+
+ if (!tabsState[tabId]) {
+ postfix = '-inactive'
+ }
+
+ chrome.pageAction.setIcon({
+ tabId: tabId,
+ path: {
+ '19': 'icons/icon19' + postfix + '.png',
+ '38': 'icons/icon38' + postfix + '.png'
+ }
+ });
-chrome.contextMenus.create({id: "keySocketMediaKeys-group", title: "Key Socket Media Keys"});
+}
-chrome.contextMenus.create({
- parentId: "keySocketMediaKeys-group",
- id: "keySocketMediaKeys-disableThisTab",
- title: "Disable this tab",
- onclick: function (a, tab) {
- unregisterTab(tab.id);
+function processAction(command) {
+ console.log('Command:', command);
+ var isPlaying = false;
+
+ for (tabId in playingTabs) {
+
+ if (playingTabs.hasOwnProperty(tabId) && tabsState[tabId]) {
+ isPlaying = true;
+ sendCommand(+tabId, command);
+ console.log('control playing', tabId);
+ }
+
+ }
+
+ if (isPlaying) {
+ return;
}
-});
-chrome.contextMenus.create({
- parentId: "keySocketMediaKeys-group",
- id: "keySocketMediaKeys-enableThisTab",
- title: "Enable this tab",
- onclick: function (a, tab) {
- registerTab(tab.id);
+
+ if (controllableTabs[activeTab] && tabsState[activeTab]){
+ console.log('control active', activeTab);
+ sendCommand(activeTab, command)
+ } else if (lastPlayingTab !== -1 && tabsState[lastPlayingTab]) {
+ console.log('control lastPlayingTab', lastPlayingTab)
+ sendCommand(lastPlayingTab, command);
}
-});
+}
-chrome.contextMenus.create({
- parentId: "keySocketMediaKeys-group",
- id: "keySocketMediaKeys-separator1",
- type: "separator"
-});
+function processRegisterMessage(request, sender, sendResponse) {
+ console.log('Received tab message: ', request);
-chrome.contextMenus.create({
- parentId: "keySocketMediaKeys-group",
- id: "keySocketMediaKeys-disableAllTabs",
- title: "Disable all tabs",
- onclick: function (a, tab) {
- chrome.tabs.getAllInWindow(null, function (tabs) {
- for (var i = 0; i < tabs.length; i++) {
- unregisterTab(tabs[i].id);
- }
- });
+ if (request.command == 'registerTab' && sender.tab) {
+ registerTab(sender.tab.id);
+ } else if (request.command == 'unregisterTab' && sender.tab) {
+ unregisterTab(sender.tab.id);
}
-});
-chrome.contextMenus.create({
- parentId: "keySocketMediaKeys-group",
- id: "keySocketMediaKeys-enableAllTabs",
- title: "Enable all tabs",
- onclick: function (a, tab) {
- chrome.tabs.getAllInWindow(null, function (tabs) {
- for (var i = 0; i < tabs.length; i++) {
- registerTab(tabs[i].id);
- }
- });
- }
-});
+}
-chrome.contextMenus.create({
- parentId: "keySocketMediaKeys-group",
- id: "keySocketMediaKeys-separator2",
- type: "separator"
-});
-
-chrome.contextMenus.create({
- parentId: "keySocketMediaKeys-group",
- id: "keySocketMediaKeys-disableAllBut",
- title: "Disable all but this tab",
- onclick: function (a, tab) {
- chrome.tabs.getAllInWindow(null, function (tabs) {
- for (var i = 0; i < tabs.length; i++) {
- if (tab.id !== tabs[i].id) {
- unregisterTab(tabs[i].id);
- }
- }
- });
+function switchActiveTab(evt) {
+ activeTab = evt.tabId;
+}
- registerTab(tab.id);
- }
-});
+chrome.commands.onCommand.addListener(processAction);
+chrome.tabs.onRemoved.addListener(unregisterTab);
+chrome.tabs.onUpdated.addListener(checkAudible);
+chrome.pageAction.onClicked.addListener(tabsPluginState);
+chrome.runtime.onMessage.addListener(processRegisterMessage);
+chrome.tabs.onActivated.addListener(switchActiveTab);
-chrome.contextMenus.create({
- parentId: "keySocketMediaKeys-group",
- id: "keySocketMediaKeys-enableAllBut",
- title: "Enable all but this tab",
- onclick: function (a, tab) {
- unregisterTab(tab.id);
- chrome.tabs.getAllInWindow(null, function (tabs) {
- for (var i = 0; i < tabs.length; i++) {
- if (tab.id !== tabs[i].id) {
- registerTab(tabs[i].id);
- }
- }
- });
- }
-});
\ No newline at end of file
diff --git a/extension/manifest.json b/extension/manifest.json
index 22feba5..f62ace3 100644
--- a/extension/manifest.json
+++ b/extension/manifest.json
@@ -45,7 +45,7 @@
}
},
"background": {
- "scripts": ["background.js"],
+ "page": "background.html",
"persistent": true
},
"page_action": {
diff --git a/extension/plugin-api.js b/extension/plugin-api.js
index 14c308d..3cb02a1 100644
--- a/extension/plugin-api.js
+++ b/extension/plugin-api.js
@@ -122,14 +122,9 @@ keySocket.injectHandler = function (keysocketEventHandler)
});
};
- injectFunction(handleKeysocketMessages);
-
+ injectCode('(' + handleKeysocketMessages + ')()');
injectCode('window.keysocketOnKeyPressed = ' + keysocketEventHandler);
- function injectFunction(injectionFunction) {
- injectCode('(' + injectionFunction + ')()');
- }
-
function injectCode(injection) {
var injectedScript = document.createElement('script');
injectedScript.textContent = injection;