Darktheme.php 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. <?php
  2. namespace addons\darktheme;
  3. use app\common\library\Menu;
  4. use think\Addons;
  5. use think\Config;
  6. use think\Hook;
  7. use think\Request;
  8. /**
  9. * 深色模式插件
  10. */
  11. class Darktheme extends Addons
  12. {
  13. /**
  14. * 插件安装方法
  15. * @return bool
  16. */
  17. public function install()
  18. {
  19. return true;
  20. }
  21. /**
  22. * 插件卸载方法
  23. * @return bool
  24. */
  25. public function uninstall()
  26. {
  27. return true;
  28. }
  29. /**
  30. * 插件启用方法
  31. * @return bool
  32. */
  33. public function enable()
  34. {
  35. return true;
  36. }
  37. /**
  38. * 插件禁用方法
  39. * @return bool
  40. */
  41. public function disable()
  42. {
  43. return true;
  44. }
  45. /**
  46. * HTML替换
  47. */
  48. public function viewFilter(&$content)
  49. {
  50. $config = $this->getConfig();
  51. $info = get_addon_info('darktheme');
  52. $request = Request::instance();
  53. $module = strtolower($request->module());
  54. $controller = strtolower($request->controller());
  55. $action = strtolower($request->action());
  56. if ($module != 'admin') {
  57. return;
  58. }
  59. //判断忽略的URL
  60. $url = $request->url();
  61. $url = preg_replace("/\/(\w+)\.php\//i", '/', $url);
  62. $ignoreUrlArr = array_filter(explode("\n", str_replace(["\r\n"], "\n", $config['ignoreurllist'])));
  63. foreach ($ignoreUrlArr as $index => $item) {
  64. if (stripos($url, $item) === 0) {
  65. return;
  66. }
  67. }
  68. //判断用户是否有手动设定样式
  69. $mode = $config['mode'];
  70. $thememode = cookie("thememode");
  71. if ($thememode && in_array($thememode, ['dark', 'light'])) {
  72. $mode = $thememode;
  73. $config['mode'] = $thememode;
  74. }
  75. $mode = $mode === 'force' ? 'dark' : $mode;
  76. //计算资源路径
  77. $cdnurl = Config::get('view_replace_str.__CDN__');
  78. if ($mode === 'dark' || $mode === 'force') {
  79. $content = preg_replace("/<body(.*?)class=\"(.*?)\"/i", "<body\$1class=\"\$2 darktheme\"", $content);
  80. $content = preg_replace("/<body>/i", "<body class='darktheme'>", $content);
  81. } elseif (!$thememode) {
  82. $content = preg_replace("/<body(.*?)>/i", "<body\$1><script>window.matchMedia('(prefers-color-scheme: dark)').matches&&document.body.classList.add(\"darktheme\");</script>", $content);
  83. }
  84. //模式判断
  85. $media = $config['mode'] == 'auto' ? 'media="(prefers-color-scheme: dark)"' : '';
  86. $media = '';
  87. $cssfile = '<link href="' . $cdnurl . '/assets/addons/darktheme/css/darktheme.css?v=' . ($info['version'] ?? '1.0.0') . '" rel="stylesheet" ' . $media . ' data-mode="' . $mode . '" class="darktheme-link">';
  88. $customcss = $config['customcss'] ?? '';
  89. //替换页面中的自定深色CSS文件
  90. $content = preg_replace_callback("/<link(.*?)data\-render=\"darktheme\"(.*?)>/i", function ($match) use ($media) {
  91. $match[0] = str_replace('<link', '<link ' . $media, $match[0]);
  92. return $match[0];
  93. }, $content);
  94. //替换页面中的自定义深色样式
  95. $content = preg_replace_callback("/<style\sdata\-render=\"darktheme\">([\s\S]*?)<\/style>/i", function ($match) use (&$customcss) {
  96. $customcss = $customcss . "\n" . $match[1];
  97. return '';
  98. }, $content);
  99. //添加自定义CSSHook,便于其它插件适配
  100. $results = Hook::listen("darktheme_customcss", $content);
  101. foreach ($results as $index => $result) {
  102. if (!$result) {
  103. continue;
  104. }
  105. $result = str_replace('__CDN__', $cdnurl, $result);
  106. if (stripos($result, 'body.darktheme') !== false || stripos($result, '{') !== false) {
  107. $customcss = $customcss . "\n" . $result;
  108. } else {
  109. $cssfile = $cssfile . "\n" . '<link href="' . $result . '" rel="stylesheet" ' . $media . ' class="darktheme-link">';
  110. }
  111. }
  112. $cssfile = $cssfile . '<link href="/assets/addons/darktheme/css/switch.css?v=' . ($info['version'] ?? '1.0.0') . '" rel="stylesheet" >';
  113. //自定义CSS
  114. if ($customcss) {
  115. $cssmediabegin = $config['mode'] == 'auto' ? "@media (prefers-color-scheme: dark) {\n" : "";
  116. $cssmediaend = $config['mode'] == 'auto' ? "\n}" : "";
  117. $cssmediabegin = $cssmediaend = "";
  118. $cssfile .= "\n<style>\n{$cssmediabegin}{$customcss}{$cssmediaend}\n</style>";
  119. }
  120. //在head前写入CSS
  121. $content = preg_replace("/<\/head>/i", $cssfile . "\n\$0", $content);
  122. }
  123. /**
  124. * @param $params
  125. */
  126. public function configInit(&$params)
  127. {
  128. $config = $this->getConfig();
  129. $mode = $config['mode'];
  130. $thememode = cookie("thememode");
  131. if ($thememode && in_array($thememode, ['dark', 'light'])) {
  132. $mode = $thememode;
  133. }
  134. $mode = $mode === 'force' ? 'dark' : $mode;
  135. $params['darktheme'] = [
  136. 'switchbtn' => !!$config['switchbtn'],
  137. 'mode' => $mode
  138. ];
  139. }
  140. }