diff --git a/README.md b/README.md index 1184847..48203cb 100644 --- a/README.md +++ b/README.md @@ -3,8 +3,8 @@ Allows your keyboard media keys (play/pause, next, previous) to work when you're listening to music on various streaming websites. # Supported Sites + * 163 Music - * 22tracks * 8tracks * Amazon Cloud Player * Bandcamp @@ -22,53 +22,60 @@ when you're listening to music on various streaming websites. * iloveradio.de * Jamstash * Jango.com - * JB Hi-Fi Now - * Livestream.com * Mixcloud - * Music Choice + * Music Choice (untested) * Myspace * Myzuka.fm * Naxos Music Library * Netflix - * Noon Pacific + * Noon Pacific (untested) * NRK Radio * Ok.ru - * Overcast + * Overcast (untested) * Pandora * Phish Tracks * Picarto.tv - * Plex + * Plex (untested) * Pocketcasts.com * Prostopleer * Qobuz - * Rdio * Relax-Hub.com * Saavn.com * Slacker * Sirius XM Radio * SomaFM - * Songza * Soundcloud * Sowndhaus * Spotify * Spreaker * Streamsquid * Subsonic (and Madsonic) - * Superplayer.fm - * Synology Audio Station v.5 + * Superplayer.fm (untested) + * Synology Audio Station v.5 (untested) * thesixtyone - * Tidal - * Tracksflow.com + * Tidal (untested) * tunein.com * Twitch.tv * Ustream.tv * vk.com (Vkontakte) + * XFINITY (untested) * Xiami Music * YouTube * Zvooq * Яндекс.Музыка (Yandex.Music) * Яндекс.Радио (Yandex.Radio) +# Untested Sites (after latest changes) + + * Music Choice (account is needed) + * Noon Pacific (account is needed) + * Overcast (account is needed) + * Plex (can't simulate click, not working) + * Superplayer.fm (regional restrictions) + * Synology (special environment is needed) + * Tidal (regional restrictions) + * XFINITY (account is needed) + # Usage 1. Install extension from the [chrome web store][crx]. @@ -112,8 +119,49 @@ document.addEventListener("MediaNext", function () { }); ``` -# Please contribute! +# Please, contribute! + +* Looking for plugins for other music players. Create Pull Requests to contribute. Create Issues to inform us about +broken sites (but PR is preferable). + +Plugin creation is simple. If you have found a website with media content, that isn't supported by keysocket, just +write a plugin by yourself and create new Pull Request to share it with others. How to do it? + +First of all, determine the fixed part of website's URL, where a media content is shown. In `extension/manifest.json` +add an item into `content_scripts` array like this: + +``` + { + "matches": ["*://example.com/player*"], + "js": ["plugin-api.js", "keysocket-example-service-name.js"] + }, +``` + +Create new file into `extension` folder using the pattern `keysocket-example-service-name.js` (use your service name to +replace `example-service-name` part). Write plugin's code there. Check other plugins for examples. + +Typically, plugin can interact with a player using either button press simulation or public API call. The second option +implies you writing custom JS code to talk to player, while the first one requires just to mention DOM selectors to +configure keysocket. + +```javascript +keySocket.init('example-service-name', { + "play-pause": '...', + "prev": '...', + "next": '...', + "stop": '...' +}); +``` + +In the code above two arguments were passed to `keySocket.init` function. The first argument is a plugin name, it used for +logging and can be anything you want. The second argument is a map used to bind keysocket events (which is caused by +user pressing control keys) to buttons or code, that handles this event. The events are `play-pause`, `prev`, `next` +and `stop`. Any of them can be omitted in the map. + +So, passing a function as an event handler, you set the code, that will be called when event is thrown. Passing anything +else, which expected to be a string, you define DOM selector to look up for a DOM object to simulate click on it. -* Looking for adapters for other music players. +Different websites require different approaches to dial with them. So, make a research to find the best solution in +your case. Look through the other plugins (`extension/keysocket-*.js` files) for the reference. [crx]: https://chrome.google.com/webstore/detail/fphfgdknbpakeedbaenojjdcdoajihik diff --git a/extension/keysocket-163.js b/extension/keysocket-163.js index 0d69fbb..12ef189 100644 --- a/extension/keysocket-163.js +++ b/extension/keysocket-163.js @@ -1,12 +1,9 @@ -function onKeyPress(key) { - if (key === NEXT) { - var nextButton = document.querySelector('.m-playbar .nxt'); - simulateClick(nextButton); - } else if (key === PLAY) { - var playPauseButton = document.querySelector('.m-playbar .ply'); - simulateClick(playPauseButton); - } else if (key === PREV) { - var backButton = document.querySelector('.m-playbar .prv'); - simulateClick(backButton); +keySocket.init( + "163", + { + "play-pause": ".m-playbar .ply", + "prev": ".m-playbar .prv", + "next": ".m-playbar .nxt" + // stop is omitted } -} \ No newline at end of file +); \ No newline at end of file diff --git a/extension/keysocket-amazon-cloud-player.js b/extension/keysocket-amazon-cloud-player.js index 5e689a4..c5e8ab9 100644 --- a/extension/keysocket-amazon-cloud-player.js +++ b/extension/keysocket-amazon-cloud-player.js @@ -1,12 +1,9 @@ -function onKeyPress(key) { - if (key === NEXT) { - var nextButton = document.querySelector('.button.icon-fastForward'); - simulateClick(nextButton); - } else if (key === PLAY) { - var playPauseButton = document.querySelector(".button.playButton"); - simulateClick(playPauseButton); - } else if (key === PREV) { - var backButton = document.querySelector('.button.icon-fastBackward'); - simulateClick(backButton); +keySocket.init( + "amazon-cloud-player", + { + "play-pause": ".button.playButton", + "prev": ".button.icon-fastBackward", + "next": ".button.icon-fastForward" + // stop is omitted } -} +); \ No newline at end of file diff --git a/extension/keysocket-bandcamp.js b/extension/keysocket-bandcamp.js index 066387e..60462ca 100644 --- a/extension/keysocket-bandcamp.js +++ b/extension/keysocket-bandcamp.js @@ -1,13 +1,9 @@ -var playTarget = '.inline_player .playbutton'; -var nextTarget = '.inline_player .nextbutton'; -var prevTarget = '.inline_player .prevbutton'; - -function onKeyPress(key) { - if (key === PREV) { - simulateClick(document.querySelector(prevTarget)); - } else if (key === NEXT) { - simulateClick(document.querySelector(nextTarget)); - } else if (key === PLAY) { - simulateClick(document.querySelector(playTarget)); +keySocket.init( + "bandcamp", + { + "play-pause": ".inline_player .playbutton", + "prev": ".inline_player .prevbutton", + "next": ".inline_player .nextbutton" + // stop is omitted } -} +); \ No newline at end of file diff --git a/extension/keysocket-birp.js b/extension/keysocket-birp.js index 3224239..9d3b982 100644 --- a/extension/keysocket-birp.js +++ b/extension/keysocket-birp.js @@ -1,12 +1,9 @@ -function onKeyPress(key) { - if (key === NEXT) { - var nextButton = document.getElementById('fap-next'); - simulateClick(nextButton); - } else if (key === PLAY) { - var playPauseButton = document.getElementById('fap-play-pause'); - simulateClick(playPauseButton); - } else if (key === PREV) { - var backButton = document.getElementById('fap-previous'); - simulateClick(backButton); +keySocket.init( + "birp", + { + "play-pause": "#playbtn", + "prev": ".fa-fast-backward", + "next": ".fa-fast-forward" + // stop is omitted } -} +); \ No newline at end of file diff --git a/extension/keysocket-bop.js b/extension/keysocket-bop.js deleted file mode 100644 index ad63de7..0000000 --- a/extension/keysocket-bop.js +++ /dev/null @@ -1,12 +0,0 @@ -function onKeyPress(key) { - if (key === NEXT) { - var nextButton = document.getElementsByClassName('icon-next')[0]; - simulateClick(nextButton); - } else if (key === PLAY) { - var playPauseButton = document.getElementsByClassName('wrapper-icon-play-pause')[0]; - simulateClick(playPauseButton); - } else if (key === PREV) { - var backButton = document.getElementsByClassName('icon-previous')[0]; - simulateClick(backButton); - } -} diff --git a/extension/keysocket-bugs.js b/extension/keysocket-bugs.js index 8ba3200..16b7978 100644 --- a/extension/keysocket-bugs.js +++ b/extension/keysocket-bugs.js @@ -1,12 +1,9 @@ -function onKeyPress(key) { - if (key === NEXT) { - var nextButton = document.getElementsByTagName('button')[4]; - simulateClick(nextButton); - } else if (key === PLAY) { - var playPauseButton = document.getElementsByTagName('button')[3]; - simulateClick(playPauseButton); - } else if (key === PREV) { - var backButton = document.getElementsByTagName('button')[2]; - simulateClick(backButton); +keySocket.init( + "bugs", + { + "play-pause": ".btnPlay > button, .btnStop > button", + "prev": ".btnPrev > button", + "next": ".btnNext > button" + // stop is omitted } -} +); \ No newline at end of file diff --git a/extension/keysocket-builtin-player.js b/extension/keysocket-builtin-player.js index 548eecf..5adafd8 100644 --- a/extension/keysocket-builtin-player.js +++ b/extension/keysocket-builtin-player.js @@ -1,12 +1,18 @@ -function onKeyPress(key) { - var videoElement = document.getElementsByTagName("video")[0]; - - if (key === PLAY) { - if (videoElement.paused) { - videoElement.play(); - } - else { - videoElement.pause(); +keySocket.init( + "builtin-player", + { + "play-pause": function () { + var videoElement = document.getElementsByTagName("video")[0]; + + if (videoElement.paused) { + videoElement.play(); + } + else { + videoElement.pause(); + } } + // prev is skipped + // next is skipped + // stop is omitted } -} +); \ No newline at end of file diff --git a/extension/keysocket-deezer.js b/extension/keysocket-deezer.js index a7cc7c5..d7aa32b 100644 --- a/extension/keysocket-deezer.js +++ b/extension/keysocket-deezer.js @@ -1,37 +1,9 @@ -function onKeyPress(key) { - if (document.getElementById('player_control_play')) { // old deezer style - if (key === NEXT) { - var nextButton = document.getElementById('player_control_next'); - simulateClick(nextButton); - } else if (key === PLAY) { - var isPlaying = document.getElementById('player_control_play').style.display === 'none'; - var playPauseButton = null; - if (isPlaying) { - playPauseButton = document.getElementById('player_control_pause'); - } else { - playPauseButton = document.getElementById('player_control_play'); - } - simulateClick(playPauseButton); - } else if (key === PREV) { - var backButton = document.getElementById('player_control_prev'); - simulateClick(backButton); - } - } else { // new deezer style - if (key === NEXT) { - var nextButton = document.getElementsByClassName('control-next')[0]; - simulateClick(nextButton); - } else if (key === PLAY) { - var isPlaying = document.getElementsByClassName('control-play')[0] ? false : true; - var playPauseButton = null; - if (isPlaying) { - playPauseButton = document.getElementsByClassName('control-pause')[0]; - } else { - playPauseButton = document.getElementsByClassName('control-play')[0]; - } - simulateClick(playPauseButton); - } else if (key === PREV) { - var backButton = document.getElementsByClassName('control-prev')[0]; - simulateClick(backButton); - } +keySocket.init( + "deezer", + { + "play-pause": ".control-play, .control-pause", + "prev": ".control-prev", + "next": ".control-next" + // stop is omitted } -} +); \ No newline at end of file diff --git a/extension/keysocket-digitallyimported.js b/extension/keysocket-digitallyimported.js index 5dab20c..28f6f3f 100644 --- a/extension/keysocket-digitallyimported.js +++ b/extension/keysocket-digitallyimported.js @@ -1,6 +1,9 @@ -function onKeyPress(key) { - if (key === PLAY) { - var playPauseButton = document.querySelector('#webplayer-region .controls a:first-child'); - simulateClick(playPauseButton); +keySocket.init( + "digitallyimported", + { + "play-pause": "#webplayer-region .controls a:first-child" + // prev is skipped + // next is skipped + // stop is omitted } -} +); \ No newline at end of file diff --git a/extension/keysocket-eighttracks.js b/extension/keysocket-eighttracks.js index 4b27e2c..6f1eca1 100644 --- a/extension/keysocket-eighttracks.js +++ b/extension/keysocket-eighttracks.js @@ -3,14 +3,14 @@ var usCanadaVersionSelectors = { pauseButtonSelector:'#player_pause_button', skipButtonSelector: '#player_skip_button', nextMixButtonSelector: '#next_mix_button' -} +}; var youtubeVersionSelectors = { playButtonSelector: '#youtube_play_button', pauseButtonSelector: '#youtube_pause_button', skipButtonSelector: '#youtube_skip_button', nextMixButtonSelector: '#youtube_mix_button' -} +}; function isYoutubeVersionRendered(){ return document.querySelector('.international_message') @@ -26,23 +26,26 @@ function getSelectorsForTheVersion() { function pressOneButtonOrAnother(oneButtonSelector, anotherButtonSelector) { var oneButton = document.querySelector(oneButtonSelector); if(window.getComputedStyle(oneButton).display !== "none"){ - simulateClick(oneButton); + keySocket.simulateClick(oneButton); } else{ var anotherButton = document.querySelector(anotherButtonSelector); - simulateClick(anotherButton); + keySocket.simulateClick(anotherButton); } } -function onKeyPress(key) { - - var selectors = getSelectorsForTheVersion() - - if (key === NEXT) { - pressOneButtonOrAnother(selectors.skipButtonSelector, selectors.nextMixButtonSelector) - } else if (key === PLAY) { - pressOneButtonOrAnother(selectors.playButtonSelector, selectors.pauseButtonSelector) +keySocket.init( + "8tracks", + { + "play-pause": function () { + var selectors = getSelectorsForTheVersion(); + pressOneButtonOrAnother(selectors.playButtonSelector, selectors.pauseButtonSelector) + }, + // "prev": ".previous", + "next": function () { + var selectors = getSelectorsForTheVersion(); + pressOneButtonOrAnother(selectors.skipButtonSelector, selectors.nextMixButtonSelector) + } + // stop is omitted } -} - -console.log('keysocket: Loading 8tracks extension keysocket'); +); \ No newline at end of file diff --git a/extension/keysocket-gaana.js b/extension/keysocket-gaana.js index 0f0ee97..9de49ec 100644 --- a/extension/keysocket-gaana.js +++ b/extension/keysocket-gaana.js @@ -1,16 +1,9 @@ -function onKeyPress(key) { - if (key == NEXT) { - var nextbutton = document.querySelector('div.player_wrapper > a.next'); - simulateClick(nextbutton); - } else if (key == PREV) { - var prevbutton = document.querySelector('div.player_wrapper > a.prev'); - simulateClick(prevbutton); - } else if (key == PLAY) { - var playbutton = document.querySelector('div.player_wrapper > a.playPause.pause'); - var pausebutton = document.querySelector('div.player_wrapper > a.playPause.play'); - if (playbutton) - simulateClick(playbutton); - else - simulateClick(pausebutton); +keySocket.init( + "gaana", + { + "play-pause": ".playPause", + "prev": ".previous", + "next": ".next" + // stop is omitted } -} +); \ No newline at end of file diff --git a/extension/keysocket-googlemusic.js b/extension/keysocket-googlemusic.js index 95a35a7..c6f005a 100644 --- a/extension/keysocket-googlemusic.js +++ b/extension/keysocket-googlemusic.js @@ -1,17 +1,9 @@ -function onKeyPress(key) { - if (key === NEXT) { - var nextButton = document.querySelector('[data-id=forward]'); - simulateClick(nextButton); - } else if (key === PLAY) { - var playPauseButton = document.querySelector('[data-id=play-pause]'); - simulateClick(playPauseButton); - } else if (key === PREV) { - var backButton = document.querySelector('[data-id=rewind]'); - simulateClick(backButton); - } else if (key === STOP) { - var stopButton = document.querySelector('[data-id=play-pause].playing'); - simulateClick(stopButton); +keySocket.init( + "googlemusic", + { + "play-pause": "#player-bar-play-pause", + "prev": "#player-bar-rewind", + "next": "#player-bar-forward", + "stop": "#player-bar-play-pause.playing" } -} - -console.log('keysocket: Loading Gmusic extension'); +); \ No newline at end of file diff --git a/extension/keysocket-groovemusic.js b/extension/keysocket-groovemusic.js index 9689337..49d28a5 100644 --- a/extension/keysocket-groovemusic.js +++ b/extension/keysocket-groovemusic.js @@ -1,14 +1,9 @@ -function onKeyPress(key) { - if (key === NEXT) { - var nextButton = document.querySelector('.iconPlayerNext'); - simulateClick(nextButton); - } else if (key === PLAY) { - var playPauseButton = document.querySelector('.iconPlayerPause') || document.querySelector('.iconPlayerPlay'); - simulateClick(playPauseButton); - } else if (key === PREV) { - var backButton = document.querySelector('.iconPlayerPrevious'); - simulateClick(backButton); +keySocket.init( + "groovemusic", + { + "play-pause": ".iconPlayerPause, .iconPlayerPlay", + "prev": ".iconPlayerPrevious", + "next": ".iconPlayerNext" + // stop is omitted } -} - -console.log('keysocket: Loading Groove Music extension'); +); \ No newline at end of file diff --git a/extension/keysocket-hypem.js b/extension/keysocket-hypem.js index c2c6912..fb1316a 100644 --- a/extension/keysocket-hypem.js +++ b/extension/keysocket-hypem.js @@ -1,9 +1,9 @@ -function onKeyPress(key) { - if (key === NEXT) { - simulateClick(document.querySelector('#playerNext')); - } else if (key === PLAY) { - simulateClick(document.querySelector('#playerPlay')); - } else if (key === PREV) { - simulateClick(document.querySelector('#playerPrev')); +keySocket.init( + "hypem", + { + "play-pause": "#playerPlay", + "prev": "#playerPrev", + "next": "#playerNext" + // stop is omitted } -} +); \ No newline at end of file diff --git a/extension/keysocket-iloveradio.js b/extension/keysocket-iloveradio.js index f75ba00..a7b330e 100644 --- a/extension/keysocket-iloveradio.js +++ b/extension/keysocket-iloveradio.js @@ -1,6 +1,9 @@ -function onKeyPress(key) { - if (key === PLAY) { - var playPauseButton = document.querySelector('#playstop'); - simulateClick(playPauseButton); +keySocket.init( + "iloveradio", + { + "play-pause": "#playstop" + // prev is skipped + // next is skipped + // stop is omitted } -} +); \ No newline at end of file diff --git a/extension/keysocket-jamstash.js b/extension/keysocket-jamstash.js index 8935d9a..b8bdbf4 100644 --- a/extension/keysocket-jamstash.js +++ b/extension/keysocket-jamstash.js @@ -1,16 +1,16 @@ -function onKeyPress(key) { - if (key === PREV) { - var prevButton = document.getElementById('PreviousTrack'); - simulateClick(prevButton); - } else if (key === NEXT) { - var nextButton = document.getElementById('NextTrack'); - simulateClick(nextButton); - } else if (key === PLAY) { - var playPauseButton = document.getElementsByClassName('PlayTrack')[0]; - var isPlaying = playPauseButton.style.display === 'none'; - if (isPlaying) { - playPauseButton = document.getElementsByClassName('PauseTrack')[0]; - } - simulateClick(playPauseButton); +keySocket.init( + "jamstash", + { + "play-pause": function () { + var playPauseButton = document.getElementsByClassName('PlayTrack')[0]; + var isPlaying = playPauseButton.style.display === 'none'; + if (isPlaying) { + playPauseButton = document.getElementsByClassName('PauseTrack')[0]; + } + keySocket.simulateClick(playPauseButton); + }, + "prev": "PreviousTrack", + "next": "NextTrack" + // stop is omitted } -} +); \ No newline at end of file diff --git a/extension/keysocket-jango.js b/extension/keysocket-jango.js index 2cc70fa..1d76258 100644 --- a/extension/keysocket-jango.js +++ b/extension/keysocket-jango.js @@ -1,12 +1,9 @@ -function onKeyPress(key) { - if (key === NEXT) { - var nextButton = document.querySelector('#btn-ff button.pcb'); - simulateClick(nextButton); - } else if (key === PLAY) { - var playPauseButton = document.querySelector('#btn-playpause button.pcb'); - simulateClick(playPauseButton); - } else if (key === PREV) { - var playPrev = document.querySelector('#btn-rewind button.pcb'); - simulateClick(playPrev); +keySocket.init( + "myspace", + { + "play-pause": "#btn-playpause button.pcb", + "prev": "#btn-rewind button.pcb", + "next": "#btn-ff button.pcb" + // stop is omitted } -} \ No newline at end of file +); \ No newline at end of file diff --git a/extension/keysocket-livestream.js b/extension/keysocket-livestream.js deleted file mode 100644 index f749a7a..0000000 --- a/extension/keysocket-livestream.js +++ /dev/null @@ -1,32 +0,0 @@ -if(!window.__isPlaying){ - window.__isPlaying = false; -} -function onKeyPress(key) { - var player = null; - var objs = document.querySelectorAll("object"); - if(objs.length == 0){ - objs = document.querySelectorAll("button"); - for (var i = 0; i < objs.length; i++) { - if(objs[i].className === "js-vod_play play_btn") { - objs[i].click(); - window.__isPlaying = true; - break; - } - } - } - for (var i = 0; i < objs.length; i++) { - if(objs[i].id.startsWith("live_player_") || objs[i].id.startsWith("vod_player_")) { - player = objs[i]; - break; - } - } - if (player && key === PLAY) { - if (window.__isPlaying) { - player.pausePlayback(); - window.__isPlaying = false; - } else { - player.startPlayback(); - window.__isPlaying = true; - } - } -} \ No newline at end of file diff --git a/extension/keysocket-mixcloud.js b/extension/keysocket-mixcloud.js index bd05231..08320d9 100644 --- a/extension/keysocket-mixcloud.js +++ b/extension/keysocket-mixcloud.js @@ -1,6 +1,9 @@ -function onKeyPress(key) { - if (key === PLAY) { - var playPauseButton = document.querySelector('.player-control'); - simulateClick(playPauseButton); +keySocket.init( + "mixcloud", + { + "play-pause": ".player-control" + // prev is skipped + // next is skipped + // stop is omitted } -} +); \ No newline at end of file diff --git a/extension/keysocket-musicchoice.js b/extension/keysocket-musicchoice.js index cbb6578..91eb4de 100644 --- a/extension/keysocket-musicchoice.js +++ b/extension/keysocket-musicchoice.js @@ -1,7 +1,11 @@ -console.log('keysocket: Loading Music Choice extension'); +// not tested (account is needed) -function onKeyPress(key) { - if (key === PLAY) { - simulateClick(document.querySelector('#audiomute')); +keySocket.init( + "musicchoise", + { + "play-pause": "#audiomute" + // prev is skipped + // next is skipped + // stop is omitted } -} +); \ No newline at end of file diff --git a/extension/keysocket-myspace.js b/extension/keysocket-myspace.js index b881b2a..0b4b801 100644 --- a/extension/keysocket-myspace.js +++ b/extension/keysocket-myspace.js @@ -1,12 +1,9 @@ -function onKeyPress(key) { - if (key === NEXT) { - var nextButton = document.querySelector('[data-click-object-type="GlobalNavPlayerPrevious"]'); - simulateClick(nextButton); - } else if (key === PLAY) { - var playButton = document.querySelector('[data-click-object-type="GlobalNavPlayerPlay"]'); - simulateClick(playButton); - } else if (key === PREV) { - var backButton = document.querySelector('[data-click-object-type="GlobalNavPlayerNext"]'); - simulateClick(backButton); +keySocket.init( + "myspace", + { + "play-pause": "[data-click-object-type=\"GlobalNavPlayerPlay\"]", + "prev": "[data-click-object-type=\"GlobalNavPlayerPrevious\"]", + "next": "[data-click-object-type=\"GlobalNavPlayerNext\"]" + // stop is omitted } -} +); \ No newline at end of file diff --git a/extension/keysocket-myzukafm.js b/extension/keysocket-myzukafm.js index 43c5ec4..b8e8a74 100644 --- a/extension/keysocket-myzukafm.js +++ b/extension/keysocket-myzukafm.js @@ -1,21 +1,20 @@ -var playButton = '.jp-play'; -var pauseButton = '.jp-pause' -var nextButton = '.jp-next'; -var prevButton = '.jp-previous'; +keySocket.init( + "myzuka.me", + { + "play-pause": function () { + var playButton = '.jp-play'; + var pauseButton = '.jp-pause'; -function onKeyPress(key) { - if (key === NEXT) { - simulateClick(document.querySelector(nextButton)); - } else if (key === PLAY) { - var isPlaying = document.querySelector(playButton).style.display == 'none'; - var playPauseButton = null; - if (isPlaying) { - playPauseButton = document.querySelector(pauseButton); - } else { - playPauseButton = document.querySelector(playButton); - } - simulateClick(playPauseButton); - } else if (key === PREV) { - simulateClick(document.querySelector(prevButton)); + var isPlaying = document.querySelector(playButton).style.display === 'none'; + if (isPlaying) { + var playPauseButton = document.querySelector(pauseButton); + } else { + playPauseButton = document.querySelector(playButton); + } + keySocket.simulateClick(playPauseButton); + }, + prev: ".jp-previous", + next: ".jp-next" + // stop is omitted } -} \ No newline at end of file +); \ No newline at end of file diff --git a/extension/keysocket-netflix.js b/extension/keysocket-netflix.js index 53600d3..b24682f 100644 --- a/extension/keysocket-netflix.js +++ b/extension/keysocket-netflix.js @@ -1,25 +1,25 @@ -function onKeyPress(key) { - if (key === NEXT) { - var nextButtonEpisode = document.querySelector('div.player-next-episode'); - simulateClick(nextButtonEpisode); - } else if (key === PREV) { - var prevButtonEpisode = null; - var episodeList = document.querySelector('li.episode-list-item--expanded'); - if (episodeList) { - prevButtonEpisode = episodeList.previousElementSibling.querySelector('div.play-icon'); - if (prevButtonEpisode) { - episodeList.previousElementSibling.className += ' episode-list-item--expanded'; - simulateClick(prevButtonEpisode); +keySocket.init( + "nexflix", + { + "play-pause": ".player-play-pause", + "prev": function () { + var prevButtonEpisode = null; + var episodeList = document.querySelector('li.episode-list-item--expanded'); + if (episodeList) { + prevButtonEpisode = episodeList.previousElementSibling.querySelector('div.play-icon'); + if (prevButtonEpisode) { + episodeList.previousElementSibling.className += ' episode-list-item--expanded'; + keySocket.simulateClick(prevButtonEpisode); + } + } + }, + "next": "div.player-next-episode", + "stop": function () { + var isPlaying = document.querySelector('div.player-play-pause.pause'); + if (isPlaying) { + var playPauseButton = document.querySelector('.player-play-pause'); + keySocket.simulateClick(playPauseButton); } - } - } else if (key === PLAY) { - playPauseButton = document.querySelector('.player-play-pause'); - simulateClick(playPauseButton); - } else if (key === STOP) { - var isPlaying = document.querySelector('div.player-play-pause.pause'); - if (isPlaying) { - var playPauseButton = document.querySelector('.player-play-pause'); - simulateClick(playPauseButton); } } -} \ No newline at end of file +); \ No newline at end of file diff --git a/extension/keysocket-nml.js b/extension/keysocket-nml.js index 6ed2350..6ef13dc 100644 --- a/extension/keysocket-nml.js +++ b/extension/keysocket-nml.js @@ -1,18 +1,17 @@ -function onKeyPress(key) { - if (key === NEXT) { - var nextButton = document.querySelector('#ctrl-next'); - simulateClick(nextButton); - } else if (key === PLAY) { - var isPlaying = document.querySelector('#ctrl-play').style.display == 'none'; - var playPauseButton = null; - if (isPlaying) { - playPauseButton = document.querySelector('#ctrl-pause'); - } else { - playPauseButton = document.querySelector('#ctrl-play'); - } - simulateClick(playPauseButton); - } else if (key === PREV) { - var prevButton = document.querySelector('#ctrl-previous'); - simulateClick(prevButton); +keySocket.init( + "naxosmusiclibrary", + { + "play-pause": function () { + var isPlaying = document.querySelector('#ctrl-play').style.display === 'none'; + if (isPlaying) { + var playPauseButton = document.querySelector('#ctrl-pause'); + } else { + playPauseButton = document.querySelector('#ctrl-play'); + } + keySocket.simulateClick(playPauseButton); + }, + prev: "#ctrl-previous", + next: "#ctrl-next" + // stop is omitted } -} +); \ No newline at end of file diff --git a/extension/keysocket-noon-pacific.js b/extension/keysocket-noon-pacific.js index af8ffbd..74b3d33 100644 --- a/extension/keysocket-noon-pacific.js +++ b/extension/keysocket-noon-pacific.js @@ -1,26 +1,33 @@ -var playPauseButtonSelectors = [ - '.control-buttons .fa-pause', - '.control-buttons .fa-play', - '[ng-click="PlayPauseClick()"]', - '[ng-click^="playPause"]', - '[ng-click^="player.play"]:not(.ng-hide)', - '[class*="pause"]' -]; +// not tested (account is needed) -function onKeyPress(key) { - if (key === PLAY) { - for (var i = 0; i < playPauseButtonSelectors.length; i++) { - var playPauseButtonCandidate = document.querySelector(playPauseButtonSelectors[i]); - if (playPauseButtonCandidate) { - simulateClick(playPauseButtonCandidate, {cancelable: true}); - return; +keySocket.init( + "noonpacific", + { + "play-pause": function () { + var playPauseButtonSelectors = [ + '.control-buttons .fa-pause', + '.control-buttons .fa-play', + '[ng-click="PlayPauseClick()"]', + '[ng-click^="playPause"]', + '[ng-click^="player.play"]:not(.ng-hide)', + '[class*="pause"]' + ]; + for (var i = 0; i < playPauseButtonSelectors.length; i++) { + var playPauseButtonCandidate = document.querySelector(playPauseButtonSelectors[i]); + if (playPauseButtonCandidate) { + keySocket.simulateClick(playPauseButtonCandidate, {cancelable: true}); + return; + } } + }, + "prev": function () { + var prevButton = document.querySelector('[ng-click="audio.PlayPreviousSong()"], .fa-backward'); + keySocket.simulateClick(prevButton, {cancelable: true}); + }, + "next": function () { + var nextButton = document.querySelector('[ng-click="audio.PlayNextSong()"], .fa-forward'); + keySocket.simulateClick(nextButton, {cancelable: true}); } - } else if (key === NEXT) { - var nextButton = document.querySelector('[ng-click="audio.PlayNextSong()"], .fa-forward'); - simulateClick(nextButton, {cancelable: true}); - } else if (key === PREV) { - var prevButton = document.querySelector('[ng-click="audio.PlayPreviousSong()"], .fa-backward'); - simulateClick(prevButton, {cancelable: true}); + // stop is omitted } -} +); \ No newline at end of file diff --git a/extension/keysocket-now-jbhifi.js b/extension/keysocket-now-jbhifi.js deleted file mode 100644 index 8304ecf..0000000 --- a/extension/keysocket-now-jbhifi.js +++ /dev/null @@ -1,17 +0,0 @@ -function onKeyPress(key) { - if (key === NEXT) { - var nextButton = document.querySelector('li.next'); - simulateClick(nextButton); - } else if (key === PLAY) { - var playPauseButton = document.querySelector('li.play-pause'); - simulateClick(playPauseButton); - } else if (key === STOP) { - var playStopButton = document.querySelector('li.playing'); - if (playStopButton != null) simulateClick(playStopButton); - } else if (key === PREV) { - var backButton = document.querySelector('li.prev'); - simulateClick(backButton); - } -} - -console.log('keysocket: Loading JB Hi-Fi Now extension'); diff --git a/extension/keysocket-nrkradio.js b/extension/keysocket-nrkradio.js index bb5bfcd..a5c3958 100644 --- a/extension/keysocket-nrkradio.js +++ b/extension/keysocket-nrkradio.js @@ -1,6 +1,9 @@ -function onKeyPress(key) { - if (key === PLAY) { - var playPauseButton = document.querySelector('button.ludo-bar__button--playpause'); - simulateClick(playPauseButton); +keySocket.init( + "nrkradio", + { + "play-pause": "button.ludo-bar__button--playpause", + "prev": ".ludo-bar__button:nth-child(2)", + "next": ".ludo-bar__button:nth-child(3)" + // stop is omitted } -} +); \ No newline at end of file diff --git a/extension/keysocket-ok.js b/extension/keysocket-ok.js index afe47de..57a1cff 100644 --- a/extension/keysocket-ok.js +++ b/extension/keysocket-ok.js @@ -1,13 +1,9 @@ -var playTarget = '.mus_player-controls_i.__pause, .toolbar_music-play'; -var nextTarget = '.mus_player-controls_i.__forward'; -var prevTarget = '.mus_player-controls_i.__back'; - -function onKeyPress(key) { - if (key === PREV) { - simulateClick(document.querySelector(prevTarget)); - } else if (key === NEXT) { - simulateClick(document.querySelector(nextTarget)); - } else if (key === PLAY) { - simulateClick(document.querySelector(playTarget)); +keySocket.init( + "ok.ru", + { + "play-pause": ".mus_player-controls_i.__pause, .toolbar_music-play", + "prev": ".mus_player-controls_i.__back", + "next": ".mus_player-controls_i.__forward" + // stop is omitted } -} +); \ No newline at end of file diff --git a/extension/keysocket-overcast.js b/extension/keysocket-overcast.js index cc4682d..bfebf8c 100644 --- a/extension/keysocket-overcast.js +++ b/extension/keysocket-overcast.js @@ -1,10 +1,17 @@ -function onKeyPress(key) { - var player = document.getElementById('audioplayer'); - if (key === PLAY) { - if (!player.paused) { - player.pause(); - } else { - player.play(); +// not tested (account is needed) + +keySocket.init( + "overcast.fm", + { + "play-pause": function () { + if (!player.paused) { + player.pause(); + } else { + player.play(); + } } + // prev is skipped + // next is skipped + // stop is omitted } -} +); \ No newline at end of file diff --git a/extension/keysocket-pandora.js b/extension/keysocket-pandora.js index c6c960d..9e0e0ea 100644 --- a/extension/keysocket-pandora.js +++ b/extension/keysocket-pandora.js @@ -1,15 +1,9 @@ -function onKeyPress(key) { - if (key === NEXT) { - var skipButton = document.querySelector('div.Tuner__Control__Skip span button'); - simulateClick(skipButton); - } else if (key === PREV) { - var replayButton = document.querySelector('div.Tuner__Control__Replay span button'); - simulateClick(replayButton); - } else if (key === PLAY) { - var playPauseButton = document.querySelector('div.Tuner__Control__Play span button'); - simulateClick(playPauseButton); - } else if (key === STOP) { - stopButton = document.querySelector('div.Tuner__Control__ThumbDown span button'); - simulateClick(stopButton); +keySocket.init( + "pandora", + { + "play-pause": "div.Tuner__Control__Play span button", + "prev": "div.Tuner__Control__Replay span button", + "next": "div.Tuner__Control__Skip span button", + "stop": "div.Tuner__Control__ThumbDown span button" } -} +); \ No newline at end of file diff --git a/extension/keysocket-phishtracks.js b/extension/keysocket-phishtracks.js index 940abb4..9fb1237 100644 --- a/extension/keysocket-phishtracks.js +++ b/extension/keysocket-phishtracks.js @@ -1,14 +1,9 @@ -function onKeyPress(key) { - if (key === NEXT) { - var nextButton = document.querySelector('[data-control=next]'); - simulateClick(nextButton); - } else if (key === PLAY) { - var playPauseButton = document.querySelector('[data-control=togglePause]'); - simulateClick(playPauseButton); - } else if (key === PREV) { - var backButton = document.querySelector('[data-control=prev]'); - simulateClick(backButton); +keySocket.init( + "plex", + { + "play-pause": "[data-control=togglePause]", + "prev": "[data-control=prev]", + "next": "[data-control=next]" + // stop is omitted } -} - -console.log('keysocket: Loading Phishtracks extension'); +); \ No newline at end of file diff --git a/extension/keysocket-picartotv.js b/extension/keysocket-picartotv.js index 5ef4099..7559949 100644 --- a/extension/keysocket-picartotv.js +++ b/extension/keysocket-picartotv.js @@ -1,8 +1,14 @@ -function onKeyPress(key) { - if (key === PLAY) { - var playPauseButtons = document.getElementsByClassName('vjs-play-control'); - for (var i = playPauseButtons.length - 1; i >= 0; i--) { - simulateClick(playPauseButtons[i]); +keySocket.init( + "picarto.tv", + { + "play-pause": function () { + var playPauseButtons = document.getElementsByClassName('vjs-play-control'); + for (var i = playPauseButtons.length - 1; i >= 0; i--) { + keySocket.simulateClick(playPauseButtons[i]); + } } + // prev is skipped + // next is skipped + // stop is omitted } -} +); \ No newline at end of file diff --git a/extension/keysocket-plex.js b/extension/keysocket-plex.js index 39acd43..10e6bf4 100644 --- a/extension/keysocket-plex.js +++ b/extension/keysocket-plex.js @@ -1,26 +1,11 @@ -function onKeyPress(key) { - if (key === NEXT) { - var nextButton = document.querySelector('button.next-btn'); - simulateClick(nextButton); - } else if (key === PLAY) { - var playButton = document.querySelector('button.play-btn'), - pauseButton; - try { - if (playButton.classList.contains('hidden')) { - pauseButton = document.querySelector('button.pause-btn'); - simulateClick(pauseButton); - } else { - simulateClick(playButton); - } - } catch (e) { - var playAllButton = document.querySelector('a.play-btn'); - simulateClick(playAllButton); - } - } else if (key === PREV) { - var backButton = document.querySelector('button.previous-btn'); - simulateClick(backButton); - } else if (key === STOP) { - var stopButton = document.querySelector('button.stop-btn'); - simulateClick(stopButton); +// can't simulate click, not working + +keySocket.init( + "plex", + { + "play-pause": "button[aria-label=\"Play\"], button[aria-label=\"Pause\"]", + "prev": "button[aria-label=\"Previous\"]", + "next": "button[aria-label=\"Next\"]" + // stop is omitted } -} +); \ No newline at end of file diff --git a/extension/keysocket-pocketcasts.js b/extension/keysocket-pocketcasts.js index 33f4e83..3b8689c 100644 --- a/extension/keysocket-pocketcasts.js +++ b/extension/keysocket-pocketcasts.js @@ -1,12 +1,9 @@ -function onKeyPress(key) { - if (key === NEXT) { - var nextButton = document.querySelector('div.skip_forward_button'); - simulateClick(nextButton); - } else if (key === PLAY) { - var playButton = document.querySelector('div.play_pause_button'); - simulateClick(playButton); - } else if (key === PREV) { - var backButton = document.querySelector('div.skip_back_button'); - simulateClick(backButton); +keySocket.init( + "pocketcasts", + { + "play-pause": "div.play_pause_button", + "prev": "div.skip_back_button", + "next": "div.skip_forward_button" + // stop is omitted } -} +); \ No newline at end of file diff --git a/extension/keysocket-prostopleer.js b/extension/keysocket-prostopleer.js index 586e8a4..4deb5cc 100644 --- a/extension/keysocket-prostopleer.js +++ b/extension/keysocket-prostopleer.js @@ -1,9 +1,9 @@ -function onKeyPress(key) { - if (key === PREV) { - simulateClick(document.querySelector('#rw')); - } else if (key === NEXT) { - simulateClick(document.querySelector('#fw')); - } else if (key === PLAY) { - simulateClick(document.querySelector('#play')); +keySocket.init( + "pleer.net", + { + "play-pause": "#play", + "prev": "#rw", + "next": "#fw" + // stop is omitted } -} \ No newline at end of file +); \ No newline at end of file diff --git a/extension/keysocket-qobuz.js b/extension/keysocket-qobuz.js index b4dd376..8ef3d7d 100644 --- a/extension/keysocket-qobuz.js +++ b/extension/keysocket-qobuz.js @@ -1,13 +1,13 @@ -function onKeyPress(key) { - if (key === NEXT) { - var nextButton = document.querySelector('.pct-player-prev'); - simulateClick(nextButton); - } else if (key === PLAY) { - var playPauseButton = document.querySelector('.pct-player-play'); - var pausePauseButton = document.querySelector('.pct-player-pause'); - playPauseButton && simulateClick(playPauseButton) || simulateClick(pausePauseButton); - } else if (key === PREV) { - var backButton = document.querySelector('.pct-player-next'); - simulateClick(backButton); +keySocket.init( + "qobuz", + { + "play-pause": function () { + var playPauseButton = document.querySelector('.pct-player-play'); + var pausePauseButton = document.querySelector('.pct-player-pause'); + playPauseButton && keySocket.simulateClick(playPauseButton) || keySocket.simulateClick(pausePauseButton); + }, + "prev": ".pct-player-prev", + "next": ".pct-player-next" + // stop is omitted } -} +); \ No newline at end of file diff --git a/extension/keysocket-rdio.js b/extension/keysocket-rdio.js deleted file mode 100644 index f662c63..0000000 --- a/extension/keysocket-rdio.js +++ /dev/null @@ -1,12 +0,0 @@ -function onKeyPress(key) { - if (key === NEXT) { - var nextButton = document.querySelector('.left_controls .next'); - simulateClick(nextButton); - } else if (key === PLAY) { - var playPauseButton = document.querySelector('.left_controls .play_pause'); - simulateClick(playPauseButton); - } else if (key === PREV) { - var backButton = document.querySelector('.left_controls .prev'); - simulateClick(backButton); - } -} diff --git a/extension/keysocket-saavn.js b/extension/keysocket-saavn.js index 3c92c81..189a0a3 100644 --- a/extension/keysocket-saavn.js +++ b/extension/keysocket-saavn.js @@ -1,20 +1,19 @@ -function onKeyPress(key) { - if (key == NEXT) { - var nextbutton = document.querySelector('button#fwd'); - simulateClick(nextbutton); - } else if (key == PREV) { - var prevbutton = document.querySelector('button#rew'); - simulateClick(prevbutton); - } else if (key == PLAY) { - var playbutton = document.querySelector('button#play'); - var pausebutton = document.querySelector('button#pause'); - var hidebutton = document.querySelector('button.controls.hide'); - if (hidebutton != null) { - if (hidebutton.id == 'play') - simulateClick(pausebutton); - else - simulateClick(playbutton); - } +keySocket.init( + "saavn", + { + "play-pause": function () { + var playButton = document.querySelector('button#play'); + var pauseButton = document.querySelector('button#pause'); + var hideButton = document.querySelector('button.controls.hide'); + if (hideButton) { + if (hideButton.id === "play") + keySocket.simulateClick(pauseButton); + else + keySocket.simulateClick(playButton); + } + }, + "prev": "button#rew", + "next": "button#fwd" + // stop is omitted } - -} +); \ No newline at end of file diff --git a/extension/keysocket-siriusxm.js b/extension/keysocket-siriusxm.js index d4dbee8..7a82d3a 100644 --- a/extension/keysocket-siriusxm.js +++ b/extension/keysocket-siriusxm.js @@ -1,12 +1,9 @@ -function onKeyPress(key) { - if (key === NEXT) { - var nextButton = document.querySelector('.scrub-controls .next'); - simulateClick(nextButton); - } else if (key === PLAY) { - var playButtonElement = document.querySelector('.scrub-controls .play'); - simulateClick(playButtonElement); - } else if (key === PREV) { - var backButton = document.querySelector('.scrub-controls .prev'); - simulateClick(backButton); +keySocket.init( + "siriusxm", + { + "play-pause": ".scrub-controls .play", + "prev": ".scrub-controls .prev", + "next": ".scrub-controls .next" + // stop is omitted } -} +); \ No newline at end of file diff --git a/extension/keysocket-slacker.js b/extension/keysocket-slacker.js index f7fd626..0bb619f 100644 --- a/extension/keysocket-slacker.js +++ b/extension/keysocket-slacker.js @@ -1,12 +1,9 @@ -function onKeyPress(key) { - if (key === NEXT) { - var nextButton = document.querySelector('#transport > li.skip-forward > a'); - simulateClick(nextButton); - } else if (key === PLAY) { - var playPauseButton = document.querySelector('#transport > li.playpause > a.play'); - simulateClick(playPauseButton); - } else if (key === PREV) { - var backButton = document.querySelector('#transport > li.skip-back > a'); - simulateClick(backButton); +keySocket.init( + "slacker", + { + "play-pause": "#transport > li.playpause > a.play", + "prev": "#transport > li.skip-back > a", + "next": "#transport > li.skip-forward > a" + // stop is omitted } -} +); \ No newline at end of file diff --git a/extension/keysocket-somafm.js b/extension/keysocket-somafm.js index ccb186c..65d1ad4 100644 --- a/extension/keysocket-somafm.js +++ b/extension/keysocket-somafm.js @@ -1,6 +1,9 @@ -/* keysocket support for SomaFM at somafm.com */ -function onKeyPress(key) { - if (key === PLAY) { - simulateClick(document.getElementById('playBtn')); +keySocket.init( + "somafm", + { + "play-pause": "#playBtn, #stopBtn" + // prev is skipped + // next is skipped + // stop is omitted } -} +); \ No newline at end of file diff --git a/extension/keysocket-songza.js b/extension/keysocket-songza.js deleted file mode 100644 index 4610c8e..0000000 --- a/extension/keysocket-songza.js +++ /dev/null @@ -1,9 +0,0 @@ -function onKeyPress(key) { - if (key === NEXT) { - var nextButton = document.querySelector('#player .miniplayer-control-skip'); - simulateClick(nextButton); - } else if (key === PLAY) { - var playPauseButton = document.querySelector('#player .miniplayer-control-play-pause'); - simulateClick(playPauseButton); - } -} diff --git a/extension/keysocket-soundcloud.js b/extension/keysocket-soundcloud.js index dc5db63..e8250c2 100644 --- a/extension/keysocket-soundcloud.js +++ b/extension/keysocket-soundcloud.js @@ -1,15 +1,9 @@ -function onKeyPress(key) { - if (key === NEXT) { - var nextButton = document.querySelector('.skipControl__next'); - simulateClick(nextButton); - } else if (key === PLAY) { - var playPauseButton = document.querySelector('.playControl'); - simulateClick(playPauseButton); - } else if (key === PREV) { - var backButton = document.querySelector('.skipControl__previous'); - simulateClick(backButton); - } else if (key === STOP) { - var stopButton = document.querySelector('.playControl.playing'); - simulateClick(stopButton); +keySocket.init( + "soundcloud", + { + "play-pause": ".playControl", + "prev": ".skipControl__previous", + "next": ".skipControl__next", + "stop": ".playControl.playing" } -} +); \ No newline at end of file diff --git a/extension/keysocket-sowndhaus.js b/extension/keysocket-sowndhaus.js index b7c934c..4d8c2e5 100644 --- a/extension/keysocket-sowndhaus.js +++ b/extension/keysocket-sowndhaus.js @@ -1,17 +1,17 @@ -function onKeyPress(key) { - if (key === NEXT) { - var nextButton = document.querySelector('.next-button'); - simulateClick(nextButton); - } else if (key === PLAY) { - var playButton = document.querySelector('.jp-play'); - var pauseButton = document.querySelector('.jp-pause'); - if (playButton.style.display === 'none') { - simulateClick(pauseButton); - } else { - simulateClick(playButton); - } - } else if (key === PREV) { - var backButton = document.querySelector('.prev-button'); - simulateClick(backButton); +keySocket.init( + "sowndhaus", + { + "play-pause": function () { + var playButton = document.querySelector('.jp-play'); + var pauseButton = document.querySelector('.jp-pause'); + if (playButton.style.display === 'none') { + keySocket.simulateClick(pauseButton); + } else { + keySocket.simulateClick(playButton); + } + }, + "prev": ".prev-button", + "next": ".next-button" + // stop is omitted } -} +); \ No newline at end of file diff --git a/extension/keysocket-spotify.js b/extension/keysocket-spotify.js index 2918b03..81a2c6e 100644 --- a/extension/keysocket-spotify.js +++ b/extension/keysocket-spotify.js @@ -1,15 +1,9 @@ -function onKeyPress(key) { - if (key === NEXT) { - var nextButton = document.querySelector('.spoticon-skip-forward-16'); - simulateClick(nextButton); - } else if (key === PLAY) { - var playPauseButton = document.querySelector('.spoticon-pause-16, .spoticon-play-16'); - simulateClick(playPauseButton); - } else if (key === PREV) { - var backButton = document.querySelector('.spoticon-skip-back-16'); - simulateClick(backButton); - } else if (key === STOP) { - var stopButton = frame.contentDocument.querySelector('#play-pause.playing'); - simulateClick(stopButton); +keySocket.init( + "spotify", + { + "play-pause": ".spoticon-pause-16, .spoticon-play-16", + "prev": ".spoticon-skip-back-16", + "next": ".spoticon-skip-forward-16" + // stop is omitted } -} +); \ No newline at end of file diff --git a/extension/keysocket-spreaker.js b/extension/keysocket-spreaker.js index 40d1f90..74a0b52 100644 --- a/extension/keysocket-spreaker.js +++ b/extension/keysocket-spreaker.js @@ -1,12 +1,9 @@ -function onKeyPress(key){ - if(key === NEXT) { - var nextButton = document.getElementById('pl_next_button'); - simulateClick(nextButton); - } else if(key === PLAY) { - var playPauseButton = document.getElementById('pl_play_button'); - simulateClick(playPauseButton); - } else if(key === PREV) { - var backButton = document.getElementById('pl_prev_button'); - simulateClick(backButton); +keySocket.init( + "spreaker", + { + "play-pause": ".pl_btn_pause, .pl_btn_play", + "prev": ".pl_btn_prev", + "next": ".pl_btn_next" + // stop is omitted } -} +); \ No newline at end of file diff --git a/extension/keysocket-streamsquid.js b/extension/keysocket-streamsquid.js index df6e912..c6e70e0 100644 --- a/extension/keysocket-streamsquid.js +++ b/extension/keysocket-streamsquid.js @@ -1,17 +1,17 @@ -function onKeyPress(key) { - if (key === NEXT) { - var nextButton = document.querySelector('#player-next'); - simulateClick(nextButton); - } else if (key === PLAY) { - var playPauseButton = document.querySelector('#player-play'); +keySocket.init( + "streamsquid", + { + "play-pause": function () { + var playPauseButton = document.querySelector('#player-play'); - if(document.querySelector('#player-pause').style.getPropertyValue("display") == "block"){ - playPauseButton = document.querySelector('#player-pause'); - } + if(document.querySelector('#player-pause').style.getPropertyValue("display") === "block"){ + playPauseButton = document.querySelector('#player-pause'); + } - simulateClick(playPauseButton); - } else if (key === PREV) { - var backButton = document.querySelector('#player-back'); - simulateClick(backButton); + keySocket.simulateClick(playPauseButton); + }, + "prev": "#player-back", + "next": "#player-next" + // stop is omitted } -} \ No newline at end of file +); \ No newline at end of file diff --git a/extension/keysocket-subsonic.js b/extension/keysocket-subsonic.js index e194420..b5c9cea 100644 --- a/extension/keysocket-subsonic.js +++ b/extension/keysocket-subsonic.js @@ -1,9 +1,15 @@ -function onKeyPress(key) { - if (key === NEXT) { - location.href = "javascript:window.onNext(repeatEnabled)"; - } else if (key === PLAY) { - location.href = "javascript:if(localPlayer.paused)window.onStart();else window.onStop();console.log(1)"; - } else if (key === PREV) { - location.href = "javascript:window.onPrevious()"; - } -} +keySocket.init( + "subsonic", + { + "play-pause": function () { + location.href = "javascript:if(localPlayer.paused)window.onStart();else window.onStop();"; + }, + "prev": function () { + location.href = "javascript:window.onPrevious()"; + }, + "next": function () { + location.href = "javascript:window.onNext(repeatEnabled)"; + } + // stop is omitted + } +); \ No newline at end of file diff --git a/extension/keysocket-superplayer.js b/extension/keysocket-superplayer.js index 38e1814..dfafef2 100644 --- a/extension/keysocket-superplayer.js +++ b/extension/keysocket-superplayer.js @@ -1,11 +1,11 @@ -function onKeyPress(key) { - if (key === NEXT) { - var nextButton = document.querySelector('[data-function=next]'); - simulateClick(nextButton); - } else if (key === PLAY) { - var playPauseButton = document.querySelector('[data-function=play]'); - simulateClick(playPauseButton); - } -} +// not tested (regional restrictions) -console.log('keysocket: Loading Superplayer extension'); +keySocket.init( + "superplayer", + { + "play-pause": "[data-function=play]", + // prev is skipped + "next": "[data-function=next]" + // stop is omitted + } +); \ No newline at end of file diff --git a/extension/keysocket-synology.js b/extension/keysocket-synology.js index 1b3f2ee..5f6c7d7 100644 --- a/extension/keysocket-synology.js +++ b/extension/keysocket-synology.js @@ -1,14 +1,11 @@ -function onKeyPress(key) { - if (key === PREV) { - var prevButton = document.querySelector(".player-prev [type='button']"); - simulateClick(prevButton); - } else if (key === NEXT) { - var nextButton = document.querySelector(".player-next [type='button']"); - simulateClick(nextButton); - } else if (key === PLAY) { - var playPauseButton = document.querySelector(".player-play [type='button']"); - simulateClick(playPauseButton); - } -} +// not tested (special environments is needed) -console.log('keysocket: Loading Synology extension'); +keySocket.init( + "synology", + { + "play-pause": ".player-play [type='button']", + "prev": ".player-prev [type='button']", + "next": ".player-next [type='button']" + // stop is omitted + } +); \ No newline at end of file diff --git a/extension/keysocket-t61.js b/extension/keysocket-t61.js deleted file mode 100644 index 7865404..0000000 --- a/extension/keysocket-t61.js +++ /dev/null @@ -1,18 +0,0 @@ -function onKeyPress(key) { - if (key === NEXT) { - var nextButton = document.getElementById('large_next_song_button'); - simulateClick(nextButton); - } else if (key === PLAY) { - var isPlaying = document.getElementById('pause_button').style.display !== 'none'; - var playPauseButton = null; - if (isPlaying) { - playPauseButton = document.getElementById('pause_button'); - } else { - playPauseButton = document.getElementById('play_button'); - } - simulateClick(playPauseButton); - } else if (key === PREV) { - var backButton = document.getElementById('large_previous_song_button'); - simulateClick(backButton); - } -} diff --git a/extension/keysocket-tidal.js b/extension/keysocket-tidal.js index ec0a51d..42556ae 100644 --- a/extension/keysocket-tidal.js +++ b/extension/keysocket-tidal.js @@ -1,21 +1,19 @@ -function onKeyPress(key) { - if (key === NEXT) { - var nextButton = document.querySelector('button.play-controls__next'); - simulateClick(nextButton); - } else if (key === PLAY) { - var playButton = document.querySelector('button.play-controls__play'); - var pauseButton = document.querySelector('button.play-controls__pause'); - if (isVisible(playButton)) { - simulateClick(playButton); - } else { - simulateClick(pauseButton); - } - } else if (key === PREV) { - var backButton = document.querySelector('button.play-controls__previous'); - simulateClick(backButton); - } -} +// not tested (account is needed) -function isVisible(el) { - return el.offsetParent != null; -} +keySocket.init( + "tidal", + { + "play-pause": function () { + var playButton = document.querySelector('button.play-controls__play'); + var pauseButton = document.querySelector('button.play-controls__pause'); + if (playButton.offsetParent !== null) { + keySocket.simulateClick(playButton); + } else { + keySocket.simulateClick(pauseButton); + } + }, + "prev": "button.play-controls__previous", + "next": "button.play-controls__next" + // stop is omitted + } +); \ No newline at end of file diff --git a/extension/keysocket-tracksflow.js b/extension/keysocket-tracksflow.js deleted file mode 100644 index 0d6dafa..0000000 --- a/extension/keysocket-tracksflow.js +++ /dev/null @@ -1,12 +0,0 @@ -function onKeyPress(key) { - if (key === NEXT) { - var nextButton = document.getElementsByClassName('js-rewind')[0]; - simulateClick(nextButton); - } else if (key === PLAY) { - var playPauseButton = document.getElementsByClassName('js-play')[0]; - simulateClick(playPauseButton); - } else if (key === PREV) { - var backButton = document.getElementsByClassName('js-forward')[0]; - simulateClick(backButton); - } -} diff --git a/extension/keysocket-tunein.js b/extension/keysocket-tunein.js index 35e24e0..d795879 100644 --- a/extension/keysocket-tunein.js +++ b/extension/keysocket-tunein.js @@ -1,6 +1,10 @@ -function onKeyPress(key) { - if (key === PLAY) { - var playPauseButton = document.querySelector('.play-button') - simulateClick(playPauseButton); +keySocket.init( + "tunein", + { + // function example + "play-pause": "#playerActionButton" + // prev is skipped + // next is skipped + // stop is omitted } -} +); \ No newline at end of file diff --git a/extension/keysocket-twentytwotracks.js b/extension/keysocket-twentytwotracks.js deleted file mode 100644 index 75d9c7d..0000000 --- a/extension/keysocket-twentytwotracks.js +++ /dev/null @@ -1,12 +0,0 @@ -function onKeyPress(key) { - if (key === NEXT) { - var nextButton = document.querySelector("[ng-click=\"Audio.next()\"]"); - simulateClick(nextButton); - } else if (key === PLAY) { - var playPauseButton = document.querySelector("[ng-click=\"Audio.playpause()\"]"); - simulateClick(playPauseButton); - } else if (key === PREV) { - var backButton = document.querySelector("[ng-click=\"Audio.previous()\"]"); - simulateClick(backButton); - } -} \ No newline at end of file diff --git a/extension/keysocket-twitch.js b/extension/keysocket-twitch.js index 90942f2..56a217f 100644 --- a/extension/keysocket-twitch.js +++ b/extension/keysocket-twitch.js @@ -1,25 +1,28 @@ -function onKeyPress(key) { - var player = null; +keySocket.init( + "twitch", + function (key) { + var player = null; - // Handle the Flash version of the player. - var objs = document.querySelectorAll("object"); - for (var i = 0; i < objs.length; i++) { - if(objs[i].id.endsWith("-flash-player")) { - player = objs[i]; - break; + // Handle the Flash version of the player. + var objs = document.querySelectorAll("object"); + for (var i = 0; i < objs.length; i++) { + if(objs[i].id.endsWith("-flash-player")) { + player = objs[i]; + break; + } } - } - if (player && key === PLAY) { - if (player.isPaused()) { - player.playVideo(); - } else { - player.pauseVideo(); + if (player && key === keySocket.PLAY) { + if (player.isPaused()) { + player.playVideo(); + } else { + player.pauseVideo(); + } } - } - // Handle the HTML 5 version of the player. - player = document.querySelector("video"); - if (player && key === PLAY) { - player.paused ? player.play() : player.pause(); + // Handle the HTML 5 version of the player. + player = document.querySelector("video"); + if (player && key === keySocket.PLAY) { + player.paused ? player.play() : player.pause(); + } } -} +); \ No newline at end of file diff --git a/extension/keysocket-ustream.js b/extension/keysocket-ustream.js index 3c394ca..467170a 100644 --- a/extension/keysocket-ustream.js +++ b/extension/keysocket-ustream.js @@ -49,12 +49,15 @@ function ustream_pause () { window.extisplaing = false; } -function onKeyPress(key) { - if (key === PLAY) { - if (window.extisplaing) { - ustream_pause(); - } else { - ustream_play(); +keySocket.init( + "ustream", + function (key) { + if (key === keySocket.PLAY) { + if (window.extisplaing) { + ustream_pause(); + } else { + ustream_play(); + } } } -} +); diff --git a/extension/keysocket-vkontakte.js b/extension/keysocket-vkontakte.js index 045c118..d8fd1a4 100755 --- a/extension/keysocket-vkontakte.js +++ b/extension/keysocket-vkontakte.js @@ -1,12 +1,12 @@ -function onKeyPress(key) { - if (key === NEXT) { - var nextButton = document.querySelector('button.top_audio_player_next'); - simulateClick(nextButton); - } else if (key === PLAY) { - var playPauseButton = document.querySelector('button.top_audio_player_play'); - simulateClick(playPauseButton); - } else if (key === PREV) { - var backButton = document.querySelector('button.top_audio_player_prev'); - simulateClick(backButton); +keySocket.init( + "vkontakte", + { + // function example + "play-pause": function () { + keySocket.simulateClick(document.querySelector('button.top_audio_player_play')); + }, + "prev": 'button.top_audio_player_prev', // selector example + "next": 'button.top_audio_player_next' // selector example + // stop is omitted } -} \ No newline at end of file +); \ No newline at end of file diff --git a/extension/keysocket-xfinity.js b/extension/keysocket-xfinity.js index 234be5e..c6391f7 100644 --- a/extension/keysocket-xfinity.js +++ b/extension/keysocket-xfinity.js @@ -1,6 +1,11 @@ -function onKeyPress(key) { - if (key === PLAY) { - var playPauseButton = document.querySelector('.xa-icon-button.tv-player-play-toggle-button'); - simulateClick(playPauseButton); +// not tested (regional restrictions) + +keySocket.init( + "xfinity", + { + "play-pause": ".xa-icon-button.tv-player-play-toggle-button" + // prev is skipped + // next is skipped + // stop is omitted } -} +); \ No newline at end of file diff --git a/extension/keysocket-xiami.js b/extension/keysocket-xiami.js index 18363d3..c57cdb1 100644 --- a/extension/keysocket-xiami.js +++ b/extension/keysocket-xiami.js @@ -1,12 +1,9 @@ -function onKeyPress(key) { - if (key === NEXT) { - var nextButton = document.getElementById('J_nextBtn'); - simulateClick(nextButton); - } else if (key === PLAY) { - var playPauseButton = document.getElementById('J_playBtn'); - simulateClick(playPauseButton); - } else if (key === PREV) { - var backButton = document.getElementById('J_prevBtn'); - simulateClick(backButton); +keySocket.init( + "xiami", + { + "play-pause": "#J_playBtn", + "prev": "#J_prevBtn", + "next": "#J_nextBtn" + // stop is omitted } -} +); \ No newline at end of file diff --git a/extension/keysocket-yandex-music-and-radio.js b/extension/keysocket-yandex-music-and-radio.js index fb367f9..4b94eca 100644 --- a/extension/keysocket-yandex-music-and-radio.js +++ b/extension/keysocket-yandex-music-and-radio.js @@ -1,18 +1,7 @@ -// Require shared-injection.js - -/** - * Initialize shared-injection.js - * - * The argument is a function that gets `key` as argument (possible - * values are `pause-play`, `prev`, `next`) and calls needed API functions - * to manage player depending on `key` argument. - */ -injectionInit(function (key) { +keySocket.init("Yandex.Music & Yandex.Radio", keySocket.injectHandler(function (key) { switch (key) { case "play-pause": externalAPI.togglePause(); break; case "prev": externalAPI.prev(); break; case "next": externalAPI.next(); break; } -}); - -pluginLoaded('Yandex.Music'); \ No newline at end of file +})); \ No newline at end of file diff --git a/extension/keysocket-youtube.js b/extension/keysocket-youtube.js index 6af8a43..7997fd0 100644 --- a/extension/keysocket-youtube.js +++ b/extension/keysocket-youtube.js @@ -1,28 +1,32 @@ -function onKeyPress(key) { - var video = document.querySelector('#movie_player'); - if (!video.getPlayerState) { // HTML5 Player - if (key === NEXT) { - var nextButton = document.querySelector('.ytp-button-next, .ytp-next-button'); - simulateClick(nextButton); - } else if (key === PLAY) { - var playPauseButton = document.querySelector('.ytp-button-pause, .ytp-button-play, .ytp-pause-button, .ytp-play-button'); - simulateClick(playPauseButton); - } else if (key === PREV) { - var backButton = document.querySelector('.ytp-button-prev, .ytp-prev-button'); - simulateClick(backButton); - } else if (key === STOP) { - var stopButton = document.querySelector('.ytp-button-pause'); - simulateClick(stopButton); - } - } else { // Flash Player - if (key === PLAY) { - if (video.getPlayerState() === 2) { - video.playVideo(); - } else { +keySocket.init( + "youtube", + function (key) { + var video = document.querySelector('#movie_player'); + + if (!video.getPlayerState) { // HTML5 Player + if (key === keySocket.NEXT) { + var nextButton = document.querySelector('.ytp-button-next, .ytp-next-button'); + keySocket.simulateClick(nextButton); + } else if (key === keySocket.PLAY) { + var playPauseButton = document.querySelector('.ytp-button-pause, .ytp-button-play, .ytp-pause-button, .ytp-play-button'); + keySocket.simulateClick(playPauseButton); + } else if (key === keySocket.PREV) { + var backButton = document.querySelector('.ytp-button-prev, .ytp-prev-button'); + keySocket.simulateClick(backButton); + } else if (key === keySocket.STOP) { + var stopButton = document.querySelector('.ytp-button-pause'); + keySocket.simulateClick(stopButton); + } + } else { // Flash Player + if (key === keySocket.PLAY) { + if (video.getPlayerState() === 2) { + video.playVideo(); + } else { + video.pauseVideo(); + } + } else if (key === keySocket.STOP) { video.pauseVideo(); } - } else if (key === STOP) { - video.pauseVideo(); } } -} +); \ No newline at end of file diff --git a/extension/keysocket-zvooq.js b/extension/keysocket-zvooq.js index b26ee61..7e60060 100644 --- a/extension/keysocket-zvooq.js +++ b/extension/keysocket-zvooq.js @@ -1,13 +1,9 @@ -var playTarget = '.topPanelPlay, .topPanelPause'; -var nextTarget = '.topPanelForward'; -var prevTarget = '.topPanelRewind'; - -function onKeyPress(key) { - if (key === PREV) { - simulateClick(document.querySelector(prevTarget)); - } else if (key === NEXT) { - simulateClick(document.querySelector(nextTarget)); - } else if (key === PLAY) { - simulateClick(document.querySelector(playTarget)); +keySocket.init( + "zvooq", + { + "play-pause": ".topPanelPlay, .topPanelPause", + "prev": '.topPanelForward', + "next": '.topPanelRewind' + // stop is omitted } -} +); \ No newline at end of file diff --git a/extension/manifest.json b/extension/manifest.json index 2aeb454..5dd6bfd 100644 --- a/extension/manifest.json +++ b/extension/manifest.json @@ -1,6 +1,6 @@ { "name": "Key Socket Media Keys", - "version": "0.8.7", + "version": "0.9.0", "icons": { "16": "icons/icon16.png", "48": "icons/icon48.png", @@ -62,256 +62,224 @@ }, { "matches": ["*://8tracks.com/*"], - "js": ["shared.js","keysocket-eighttracks.js"] - }, - { - "matches": ["*://22tracks.com/*"], - "js": ["shared.js","keysocket-twentytwotracks.js"] + "js": ["plugin-api.js","keysocket-eighttracks.js"] }, { "matches": ["https://music.amazon.com/*", "https://music.amazon.de/*"], - "js": ["shared.js", "keysocket-amazon-cloud-player.js"] + "js": ["plugin-api.js", "keysocket-amazon-cloud-player.js"] }, { "matches": ["*://*.bandcamp.com/*"], - "js": ["shared.js", "keysocket-bandcamp.js"] + "js": ["plugin-api.js", "keysocket-bandcamp.js"] }, { "matches": ["*://*.birp.fm/*"], - "js": ["shared.js", "keysocket-birp.js"] - }, - { - "matches": ["*://bop.fm/*"], - "js": ["shared.js", "keysocket-bop.js"] + "js": ["plugin-api.js", "keysocket-birp.js"] }, { "matches": ["http://music.bugs.co.kr/newPlayer*"], - "js": ["shared.js","keysocket-bugs.js"] + "js": ["plugin-api.js","keysocket-bugs.js"] }, { - "matches": ["*://*/*.mp3", "*://*/*.mp3?*"], - "js": ["shared.js", "keysocket-builtin-player.js"] + "matches": ["*://*/*.mp3", "*://*/*.mp3?*", "file:///*.mp3"], + "js": ["plugin-api.js", "keysocket-builtin-player.js"] }, { "matches": ["*://www.deezer.com/*"], - "js": ["shared.js", "keysocket-deezer.js"] + "js": ["plugin-api.js", "keysocket-deezer.js"] }, { "matches": ["*://www.di.fm/*"], - "js": ["shared.js", "keysocket-digitallyimported.js"] + "js": ["plugin-api.js", "keysocket-digitallyimported.js"] }, { "matches": ["*://*.gaana.com/*"], - "js": ["shared.js", "keysocket-gaana.js"] + "js": ["plugin-api.js", "keysocket-gaana.js"] }, { "matches": ["https://play.google.com/music/*"], - "js": ["shared.js", "keysocket-googlemusic.js"] + "js": ["plugin-api.js", "keysocket-googlemusic.js"] }, { "matches": ["*://music.microsoft.com/*"], - "js": ["shared.js", "keysocket-groovemusic.js"] + "js": ["plugin-api.js", "keysocket-groovemusic.js"] }, { "matches": ["*://hypem.com/*"], - "js": ["shared.js", "keysocket-hypem.js"] + "js": ["plugin-api.js", "keysocket-hypem.js"] }, { "matches": ["*://*.iloveradio.de/*"], - "js": ["shared.js","keysocket-iloveradio.js"] + "js": ["plugin-api.js","keysocket-iloveradio.js"] }, { "matches": ["*://jamstash.com/*", "*://*.jamstash.com/*"], - "js": ["shared.js", "keysocket-jamstash.js"] + "js": ["plugin-api.js", "keysocket-jamstash.js"] }, { "matches": ["*://www.jango.com/*"], - "js": ["shared.js", "keysocket-jango.js"] - }, - { - "matches": ["https://now.jbhifi.com.au/*"], - "js": ["shared.js", "keysocket-now-jbhifi.js"] - }, - { - "matches": ["*://*.livestream.com/*"], - "js": ["shared.js", "keysocket-livestream.js"] + "js": ["plugin-api.js", "keysocket-jango.js"] }, { "matches": ["*://*.mixcloud.com/*"], - "js": ["shared.js", "keysocket-mixcloud.js"] + "js": ["plugin-api.js", "keysocket-mixcloud.js"] }, { "matches": ["*://*.musicchoice.com/*"], - "js": ["shared.js", "keysocket-musicchoice.js"] + "js": ["plugin-api.js", "keysocket-musicchoice.js"] }, { "matches": ["*://myspace.com/*"], - "js": ["shared.js", "keysocket-myspace.js"] + "js": ["plugin-api.js", "keysocket-myspace.js"] }, { - "matches": ["*://*.myzuka.fm/*"], - "js": ["shared.js", "keysocket-myzukafm.js"] + "matches": ["*://*.myzuka.me/*"], + "js": ["plugin-api.js", "keysocket-myzukafm.js"] }, { - "matches": ["http://*.naxosmusiclibrary.com/mediaplayer/*"], - "js": ["shared.js", "keysocket-nml.js"] + "matches": ["*://*.naxosmusiclibrary.com/mediaplayer/*"], + "js": ["plugin-api.js", "keysocket-nml.js"] }, { "matches": ["https://www.netflix.com/*"], - "js": ["shared.js", "keysocket-netflix.js"] + "js": ["plugin-api.js", "keysocket-netflix.js"] }, { "matches": ["*://noonpacific.com/*"], - "js": ["shared.js", "keysocket-noon-pacific.js"] + "js": ["plugin-api.js", "keysocket-noon-pacific.js"] }, { "matches": ["*://radio.nrk.no/*"], - "js": ["shared.js", "keysocket-nrkradio.js"] + "js": ["plugin-api.js", "keysocket-nrkradio.js"] }, { - "matches": ["*://ok.ru/*"], - "js": ["shared.js", "keysocket-ok.js"] + "matches": ["*://ok.ru/*", "*://www.ok.ru/*"], + "js": ["plugin-api.js", "keysocket-ok.js"] }, { "matches": ["https://overcast.fm/*"], - "js": ["shared.js", "keysocket-overcast.js"] + "js": ["plugin-api.js", "keysocket-overcast.js"] }, { "matches": ["*://www.pandora.com/*"], - "js": ["shared.js", "keysocket-pandora.js"] + "js": ["plugin-api.js", "keysocket-pandora.js"] }, { "matches": ["*://*.phishtracks.com/*"], - "js": ["shared.js", "keysocket-phishtracks.js"] + "js": ["plugin-api.js", "keysocket-phishtracks.js"] }, { "matches": ["*://picarto.tv/*", "*://*.picarto.tv/*"], - "js": ["shared.js", "keysocket-picartotv.js"] + "js": ["plugin-api.js", "keysocket-picartotv.js"] }, { - "matches": ["*://plex.tv/web/*", "*://app.plex.tv/web/*"], - "js": ["shared.js", "keysocket-plex.js"] + "matches": ["*://plex.tv/web/*", "*://app.plex.tv/*"], + "js": ["plugin-api.js", "keysocket-plex.js"] }, { "matches": ["*://play.pocketcasts.com/*"], - "js": ["shared.js", "keysocket-pocketcasts.js"] + "js": ["plugin-api.js", "keysocket-pocketcasts.js"] }, { "matches": ["*://pleer.net/*"], - "js": ["shared.js", "keysocket-prostopleer.js"] + "js": ["plugin-api.js", "keysocket-prostopleer.js"] }, { "matches": ["*://*.qobuz.com/*"], - "js": ["shared.js","keysocket-qobuz.js"] - }, - { - "matches": ["http://www.rdio.com/*"], - "js": ["shared.js", "keysocket-rdio.js"] + "js": ["plugin-api.js","keysocket-qobuz.js"] }, { "matches": ["*://*.saavn.com/*"], - "js": ["shared.js", "keysocket-saavn.js"] + "js": ["plugin-api.js", "keysocket-saavn.js"] }, { "matches": ["*://*.siriusxm.com/*"], - "js": ["shared.js","keysocket-siriusxm.js"] + "js": ["plugin-api.js","keysocket-siriusxm.js"] }, { "matches": ["*://www.slacker.com/*"], - "js": ["shared.js", "keysocket-slacker.js"] + "js": ["plugin-api.js", "keysocket-slacker.js"] }, { "matches": ["*://somafm.com/player/*"], - "js": ["shared.js", "keysocket-somafm.js"] - }, - { - "matches": ["*://songza.com/*"], - "js": ["shared.js", "keysocket-songza.js"] + "js": ["plugin-api.js", "keysocket-somafm.js"] }, { "matches": ["https://soundcloud.com/*"], - "js": ["shared.js", "keysocket-soundcloud.js"] + "js": ["plugin-api.js", "keysocket-soundcloud.js"] }, { "matches": ["https://sowndhaus.com/*"], - "js": ["shared.js", "keysocket-sowndhaus.js"] + "js": ["plugin-api.js", "keysocket-sowndhaus.js"] }, { "matches": ["*://*.spotify.com/*"], - "js": ["shared.js", "keysocket-spotify.js"] + "js": ["plugin-api.js", "keysocket-spotify.js"] }, { "matches": ["*://www.spreaker.com/*"], - "js": ["shared.js","keysocket-spreaker.js"] + "js": ["plugin-api.js","keysocket-spreaker.js"] }, { "matches": ["*://*.streamsquid.com/*"], - "js": ["shared.js","keysocket-streamsquid.js"] + "js": ["plugin-api.js","keysocket-streamsquid.js"] }, { "all_frames": true, "matches": ["*://*/playQueue.view", "*://*/playQueue.view?", "*://*/playQueue.view?*"], - "js": ["shared.js", "keysocket-subsonic.js"] + "js": ["plugin-api.js", "keysocket-subsonic.js"] }, { "matches": ["*://www.superplayer.fm/*"], - "js": ["shared.js", "keysocket-superplayer.js"] + "js": ["plugin-api.js", "keysocket-superplayer.js"] }, { "matches": ["*://*/webman/*", "*://*/audio/"], - "js": ["shared.js", "keysocket-synology.js"] - }, - { - "matches": ["http://www.thesixtyone.com/*"], - "js": ["shared.js", "keysocket-t61.js"] + "js": ["plugin-api.js", "keysocket-synology.js"] }, { "matches": ["*://listen.tidalhifi.com/*", "*://listen.tidal.com/*"], - "js": ["shared.js", "keysocket-tidal.js"] - }, - { - "matches": ["*://tracksflow.com/*"], - "js": ["shared.js", "keysocket-tracksflow.js"] + "js": ["plugin-api.js", "keysocket-tidal.js"] }, { "matches": ["*://*.tunein.com/*"], - "js": ["shared.js","keysocket-tunein.js"] + "js": ["plugin-api.js","keysocket-tunein.js"] }, { "matches": ["*://*.twitch.tv/*"], - "js": ["shared.js", "keysocket-twitch.js"] + "js": ["plugin-api.js", "keysocket-twitch.js"] }, { "matches": ["*://*.ustream.tv/*"], - "js": ["shared.js", "keysocket-ustream.js"] + "js": ["plugin-api.js", "keysocket-ustream.js"] }, { "matches": ["*://vk.com/*"], - "js": ["shared.js", "keysocket-vkontakte.js"] + "js": ["plugin-api.js","keysocket-vkontakte.js"] }, { "matches": ["*://tv.xfinity.com/*"], - "js": ["shared.js","keysocket-xfinity.js"] + "js": ["plugin-api.js","keysocket-xfinity.js"] }, { "matches": ["http://www.xiami.com/play*"], - "js": ["shared.js", "keysocket-xiami.js"] + "js": ["plugin-api.js", "keysocket-xiami.js"] }, { "matches": ["*://music.yandex.ru/*", "*://music.yandex.by/*", "*://music.yandex.ua/*", "*://music.yandex.kz/*", "*://music.yandex.tr/*", "*://radio.yandex.ru/*", "*://radio.yandex.by/*", "*://radio.yandex.ua/*", "*://radio.yandex.kz/*", "*://radio.yandex.tr/*"], - "js": ["shared.js", "shared-injection.js", "keysocket-yandex-music-and-radio.js"] + "js": ["plugin-api.js", "keysocket-yandex-music-and-radio.js"] }, { "matches": ["*://*.youtube.com/*"], - "js": ["shared.js", "keysocket-youtube.js"] + "js": ["plugin-api.js", "keysocket-youtube.js"] }, { "matches": ["*://zvooq.com/*"], - "js": ["shared.js", "keysocket-zvooq.js"] + "js": ["plugin-api.js", "keysocket-zvooq.js"] }, { "matches": ["*://music.163.com/*"], - "js": ["shared.js", "keysocket-163.js"] + "js": ["plugin-api.js", "keysocket-163.js"] } ] } diff --git a/extension/plugin-api.js b/extension/plugin-api.js new file mode 100644 index 0000000..14c308d --- /dev/null +++ b/extension/plugin-api.js @@ -0,0 +1,143 @@ +/* + * Copyright 2015 Feedbee. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * This file is running in tab context. It defines API for communication between extension background page script + * and web page. Use keySocket.init to initialise the tab to be controlled wia keySocket events (hot keys). + */ +keySocket = {}; + +keySocket.PREV = "prev"; +keySocket.PLAY = "play-pause"; +keySocket.NEXT = "next"; +keySocket.STOP = "stop"; + +/** + * Registers handler(s) for keysocket commands. + * + * handlers can be a function taking one argument (key) or a hash/array. If the argument is function, it's called on + * every event. It's argument provides the command (key) that user have pressed. If the argument is a hash/array, + * it will be searched for keys named as keysocket events (prev, play-pause, next, stop). If one will be found, it + * will either be called (if the key's value is a function) or used as a selector to emulate click (in other way). + * + * @param name Plugin name for logging + * @param handlers Function or hash/array + */ +keySocket.init = function (name, handlers) { + chrome.runtime.onMessage.addListener( + function (request) { + console.log('keysocket: keypress received: ', request); + + // single handler + if (typeof handlers === "function") { + handlers(request.command); + } else { // independent handlers (per command (key) -- function or selector) + switch (request.command) { + case keySocket.PLAY: handlers[keySocket.PLAY] && keySocket.call(handlers[keySocket.PLAY]); break; + case keySocket.STOP: handlers[keySocket.STOP] && keySocket.call(handlers[keySocket.STOP]); break; + case keySocket.PREV: handlers[keySocket.PREV] && keySocket.call(handlers[keySocket.PREV]); break; + case keySocket.NEXT: handlers[keySocket.NEXT] && keySocket.call(handlers[keySocket.NEXT]); break; + } + } + } + ); + + chrome.runtime.sendMessage({command: 'registerTab'}); + + window.onunload = function () { + chrome.runtime.sendMessage({command: "unregisterTab"}); + }; + + console.log("keysocket: plugin " + name + " loaded"); +}; + +keySocket.call = function (what) { + if (typeof what === "function") { + what(); + } else { + keySocket.simulateClick(document.querySelector(what)); + } +}; + + +/** + * Use keySocket.simulateClick to emulate user click on web page control (button, link or other active element). + * + * @param element + * @param options + * @returns {boolean} + */ +keySocket.simulateClick = function (element, options) { + if (!element) { + console.log('keysocket: cannot simulate click, element undefined'); + return false; + } + + var clickConfig = { + bubbles: true, + cancelable: false, + view: window + }; + if (options && options.cancelable) { + clickConfig.cancelable = options.cancelable; + } + var click = new MouseEvent('click', clickConfig); + return element.dispatchEvent(click); +}; + +/** + * keySocket.injectHandler is used for players that have an API on web page side. + * Extension can't execute web page JS functions in raw way from the extension's scope. + * keySocket.injectHandler inject JS code into the page scope and communicate with it + * through browser's messages bus (window.postMessage). + * + * Initialize injection. `keysocketEventHandler` is a function + * that will handle keysocket event on the web page side. + * + * @param keysocketEventHandler + */ +keySocket.injectHandler = function (keysocketEventHandler) +{ + var handleKeysocketMessages = function () { + window.addEventListener("message", function(event) { + if (event.source !== window) { + return; + } + + if (event.data.type && (event.data.type === "keysocket-media-event")) { + window.keysocketOnKeyPressed(event.data.command); + } + }); + }; + + injectFunction(handleKeysocketMessages); + + injectCode('window.keysocketOnKeyPressed = ' + keysocketEventHandler); + + function injectFunction(injectionFunction) { + injectCode('(' + injectionFunction + ')()'); + } + + function injectCode(injection) { + var injectedScript = document.createElement('script'); + injectedScript.textContent = injection; + (document.head || document.documentElement).appendChild(injectedScript); + injectedScript.parentNode.removeChild(injectedScript); + } + + return function (key) { + window.postMessage({ type: "keysocket-media-event", command: key }, "*"); + }; +}; \ No newline at end of file diff --git a/extension/shared-injection.js b/extension/shared-injection.js deleted file mode 100644 index 8ed2f76..0000000 --- a/extension/shared-injection.js +++ /dev/null @@ -1,55 +0,0 @@ -/** - * shared-injection used for players that have API on web page side. - * Extension can't execute web page JS functions in raw way from - * the extension's scope. shared-injection inject JS code into - * the page scope and communicate with it through messages bus - * (window.postMessage). - * - * So, instead of defining `onKeyPress(key)` function, shared-injection - * must be initialized calling injectionInit() and with the - * handler function (similar to `onKeyPress(key)`) as it's argument. - */ - -/** - * Initialize injection. `keysocketEventHandler` is a function - * that will handle keysocket event on the web page side. - * - * @param keysocketEventHandler - */ -function injectionInit(keysocketEventHandler) -{ - var handleKeysocketMessages = function () { - window.addEventListener("message", function(event) { - if (event.source !== window) { - return; - } - - if (event.data.type && (event.data.type === "keysocket-media-event")) { - window.keysocketOnKeyPressed(event.data.command); - } - }); - }; - - injectFunction(handleKeysocketMessages); - - injectCode('window.keysocketOnKeyPressed = ' + keysocketEventHandler); - - function injectFunction(injectionFunction) { - injectCode('(' + injectionFunction + ')()'); - } - - function injectCode(injection) { - var injectedScript = document.createElement('script'); - injectedScript.textContent = injection; - (document.head || document.documentElement).appendChild(injectedScript); - injectedScript.parentNode.removeChild(injectedScript); - } -} - -/** - * Standard extension-side command handler. Used in shared.js - * @param key string - */ -function onKeyPress(key) { - window.postMessage({ type: "keysocket-media-event", command: key }, "*"); -} \ No newline at end of file diff --git a/extension/shared.js b/extension/shared.js deleted file mode 100644 index 2c3e47c..0000000 --- a/extension/shared.js +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2015 Boris Smus. All Rights Reserved. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -var PREV = 'prev'; -var PLAY = 'play-pause'; -var NEXT = 'next'; -var STOP = 'stop'; - - -function simulateClick(element, options) { - if (!element) { - console.log('keysocket: Cannot simulate click, element undefined'); - return false; - } - - var clickConfig = { - bubbles: true, - cancelable: false, - view: window - }; - if (options && options.cancelable) { - clickConfig.cancelable = options.cancelable; - } - var click = new MouseEvent('click', clickConfig); - return element.dispatchEvent(click); -} - -chrome.runtime.onMessage.addListener( - function(request) { - console.log('Received keypress: ', request); - onKeyPress(request.command); - } -); - -chrome.runtime.sendMessage({command: 'registerTab'}); - -window.onunload = function() { - chrome.runtime.sendMessage({command: "unregisterTab"}); -}; \ No newline at end of file