HTML5 notifications on Spotify Web Player

Adds silent song notifications with title, artist and cover art

当前为 2015-11-14 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name HTML5 notifications on Spotify Web Player
  3. // @description Adds silent song notifications with title, artist and cover art
  4. // @namespace https://greasyfork.org/users/4813-swyter
  5. // @match https://play.spotify.com/*
  6. // @version 2015.11.14.02
  7. // @grant none
  8. // @noframes
  9. // ==/UserScript==
  10.  
  11. /* run this just on the parent page, not in sub-frames */
  12. if (window.parent !== window)
  13. throw "stop execution";
  14.  
  15. function when_external_loaded()
  16. {
  17. /* request permission to show notifications, if needed */
  18. if (Notification.permission !== 'granted')
  19. Notification.requestPermission();
  20.  
  21. /* create a listener mechanism for title changes using mutation observers,
  22. let's be good citizens (http://stackoverflow.com/a/29540461) */
  23. document.aptEventListener = document.addEventListener;
  24. document.addEventListener = function(what, callback)
  25. {
  26. if (what !== 'title')
  27. return document.aptEventListener.apply(this, arguments);
  28.  
  29. console.log('title event listener =>', arguments);
  30.  
  31. new MutationObserver(function(mutations)
  32. {
  33. console.log('mutation observer =>', mutations[0].target); setTimeout(callback, 1500);
  34. }).observe(document.querySelector('title'), {subtree: true, childList: true, characterData: true});
  35. };
  36.  
  37. /* trigger a new notification every time the page title changes */
  38. document.addEventListener('title', function()
  39. {
  40. /* trigger it only if we are actually playing songs */
  41. if (!document.title.match('▶') || document.prevtitle === document.title)
  42. {
  43. console.log('returning without showing it up', document.title);
  44. return;
  45. }
  46.  
  47. document.prevtitle = document.title;
  48.  
  49. console.log('showing it up', document.title, document.prevtitle);
  50. /* feel free to customize the formatting and layout to your liking */
  51. var track_name = document.querySelector("iframe#app-player").contentWindow.document.querySelector("#track-name > a").textContent;
  52. var track_artist = document.querySelector("iframe#app-player").contentWindow.document.querySelector("#track-artist > a").textContent;
  53. var track_coverart = document.querySelector("iframe#app-player").contentWindow.document.querySelector(".sp-image-img").style.backgroundImage.replace(/"/g,'').split("(")[1].split(")")[0];
  54.  
  55. /* show it! */
  56. new Notification(track_name, {body: track_artist, icon: track_coverart, silent: true});
  57. });
  58. }
  59.  
  60. /* inject this cleaning function right in the page to avoid silly sandbox-related greasemonkey limitations */
  61. window.document.head.appendChild(
  62. inject_fn = document.createElement("script")
  63. );
  64.  
  65. inject_fn.innerHTML = '(' + when_external_loaded.toString() + ')()';