theme-chooser.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. function initThemeChooser(settings) {
  2. var isInitialized = false;
  3. var currentThemeSystem; // don't set this directly. use setThemeSystem
  4. var currentStylesheetEl;
  5. var loadingEl = document.getElementById('loading');
  6. var systemSelectEl = document.querySelector('#theme-system-selector select');
  7. var themeSelectWrapEls = Array.prototype.slice.call( // convert to real array
  8. document.querySelectorAll('.selector[data-theme-system]')
  9. );
  10. systemSelectEl.addEventListener('change', function() {
  11. setThemeSystem(this.value);
  12. });
  13. setThemeSystem(systemSelectEl.value);
  14. themeSelectWrapEls.forEach(function(themeSelectWrapEl) {
  15. var themeSelectEl = themeSelectWrapEl.querySelector('select');
  16. themeSelectWrapEl.addEventListener('change', function() {
  17. setTheme(
  18. currentThemeSystem,
  19. themeSelectEl.options[themeSelectEl.selectedIndex].value
  20. );
  21. });
  22. });
  23. function setThemeSystem(themeSystem) {
  24. var selectedTheme;
  25. currentThemeSystem = themeSystem;
  26. themeSelectWrapEls.forEach(function(themeSelectWrapEl) {
  27. var themeSelectEl = themeSelectWrapEl.querySelector('select');
  28. var themeSystems = (themeSelectWrapEl.getAttribute('data-theme-system') || '').split(',')
  29. if (themeSystems.includes(themeSystem)) {
  30. selectedTheme = themeSelectEl.options[themeSelectEl.selectedIndex].value;
  31. themeSelectWrapEl.style.display = 'inline-block';
  32. } else {
  33. themeSelectWrapEl.style.display = 'none';
  34. }
  35. });
  36. setTheme(themeSystem, selectedTheme);
  37. }
  38. function setTheme(themeSystem, themeName) {
  39. var stylesheetUrl = generateStylesheetUrl(themeSystem, themeName);
  40. var stylesheetEl;
  41. function done() {
  42. if (!isInitialized) {
  43. isInitialized = true;
  44. settings.init(themeSystem);
  45. }
  46. else {
  47. settings.change(themeSystem);
  48. }
  49. showCredits(themeSystem, themeName);
  50. }
  51. if (stylesheetUrl) {
  52. stylesheetEl = document.createElement('link');
  53. stylesheetEl.setAttribute('rel', 'stylesheet');
  54. stylesheetEl.setAttribute('href', stylesheetUrl);
  55. document.querySelector('head').appendChild(stylesheetEl);
  56. loadingEl.style.display = 'inline';
  57. whenStylesheetLoaded(stylesheetEl, function() {
  58. if (currentStylesheetEl) {
  59. currentStylesheetEl.parentNode.removeChild(currentStylesheetEl);
  60. }
  61. currentStylesheetEl = stylesheetEl;
  62. loadingEl.style.display = 'none';
  63. done();
  64. });
  65. } else {
  66. if (currentStylesheetEl) {
  67. currentStylesheetEl.parentNode.removeChild(currentStylesheetEl);
  68. currentStylesheetEl = null
  69. }
  70. done();
  71. }
  72. }
  73. function generateStylesheetUrl(themeSystem, themeName) {
  74. if (themeSystem === 'bootstrap') {
  75. if (themeName) {
  76. return 'https://bootswatch.com/4/' + themeName + '/bootstrap.min.css';
  77. }
  78. else { // the default bootstrap theme
  79. return 'https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css';
  80. }
  81. } else if (themeSystem === 'bootstrap5') {
  82. if (themeName) {
  83. return 'https://bootswatch.com/5/' + themeName + '/bootstrap.min.css';
  84. }
  85. else { // the default bootstrap theme
  86. return 'https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css';
  87. }
  88. }
  89. }
  90. function showCredits(themeSystem, themeName) {
  91. var creditId;
  92. if (themeSystem.match('bootstrap')) {
  93. if (themeName) {
  94. creditId = 'bootstrap-custom';
  95. }
  96. else {
  97. creditId = 'bootstrap-standard';
  98. }
  99. }
  100. Array.prototype.slice.call( // convert to real array
  101. document.querySelectorAll('.credits')
  102. ).forEach(function(creditEl) {
  103. if (creditEl.getAttribute('data-credit-id') === creditId) {
  104. creditEl.style.display = 'block';
  105. } else {
  106. creditEl.style.display = 'none';
  107. }
  108. })
  109. }
  110. function whenStylesheetLoaded(linkNode, callback) {
  111. var isReady = false;
  112. function ready() {
  113. if (!isReady) { // avoid double-call
  114. isReady = true;
  115. callback();
  116. }
  117. }
  118. linkNode.onload = ready; // does not work cross-browser
  119. setTimeout(ready, 2000); // max wait. also handles browsers that don't support onload
  120. }
  121. }