color-scheme.js 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. /* global prefs */
  2. /* exported colorScheme */
  3. 'use strict';
  4. const colorScheme = (() => {
  5. let systemPreferDark = false;
  6. let timePreferDark = false;
  7. const changeListeners = new Set();
  8. const checkTime = ['schemeSwitcher.nightStart', 'schemeSwitcher.nightEnd'];
  9. prefs.subscribe(checkTime, (key, value) => {
  10. updateTimePreferDark();
  11. createAlarm(key, value);
  12. });
  13. checkTime.forEach(key => createAlarm(key, prefs.get(key)));
  14. prefs.subscribe(['schemeSwitcher.enabled'], emitChange);
  15. chrome.alarms.onAlarm.addListener(info => {
  16. if (checkTime.includes(info.name)) {
  17. updateTimePreferDark();
  18. }
  19. });
  20. updateSystemPreferDark();
  21. updateTimePreferDark();
  22. return {shouldIncludeStyle, onChange, updateSystemPreferDark};
  23. function createAlarm(key, value) {
  24. const date = new Date();
  25. applyDate(date, value);
  26. if (date.getTime() < Date.now()) {
  27. date.setDate(date.getDate() + 1);
  28. }
  29. chrome.alarms.create(key, {
  30. when: date.getTime(),
  31. periodInMinutes: 24 * 60,
  32. });
  33. }
  34. function shouldIncludeStyle(style) {
  35. const isDark = style.preferScheme === 'dark';
  36. const isLight = style.preferScheme === 'light';
  37. if (!isDark && !isLight) {
  38. return true;
  39. }
  40. const switcherState = prefs.get('schemeSwitcher.enabled');
  41. if (switcherState === 'never') {
  42. return true;
  43. }
  44. if (switcherState === 'system') {
  45. return systemPreferDark && isDark ||
  46. !systemPreferDark && isLight;
  47. }
  48. return timePreferDark && isDark ||
  49. !timePreferDark && isLight;
  50. }
  51. function updateSystemPreferDark() {
  52. const oldValue = systemPreferDark;
  53. systemPreferDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
  54. if (systemPreferDark !== oldValue) {
  55. emitChange();
  56. }
  57. return true;
  58. }
  59. function updateTimePreferDark() {
  60. const oldValue = timePreferDark;
  61. const date = new Date();
  62. const now = date.getTime();
  63. applyDate(date, prefs.get('schemeSwitcher.nightStart'));
  64. const start = date.getTime();
  65. applyDate(date, prefs.get('schemeSwitcher.nightEnd'));
  66. const end = date.getTime();
  67. timePreferDark = start > end ?
  68. now >= start || now < end :
  69. now >= start && now < end;
  70. if (timePreferDark !== oldValue) {
  71. emitChange();
  72. }
  73. }
  74. function applyDate(date, time) {
  75. const [h, m] = time.split(':').map(Number);
  76. date.setHours(h, m, 0, 0);
  77. }
  78. function onChange(listener) {
  79. changeListeners.add(listener);
  80. }
  81. function emitChange() {
  82. for (const listener of changeListeners) {
  83. listener();
  84. }
  85. }
  86. })();