toggle theme

网站@media (prefers-color-scheme: dark)主题样式切换,深色模式和浅色模式的切换

目前为 2020-02-15 提交的版本。查看 最新版本

// ==UserScript==
// @name         toggle theme
// @name:zh-CN   切换主题
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  网站@media (prefers-color-scheme: dark)主题样式切换,深色模式和浅色模式的切换
// @author       taumu
// @include      *.weixin.*
// @run-at       document-idle
// @require      https://unpkg.com/style-media-toggle
// @grant        GM_registerMenuCommand
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_xmlhttpRequest
// ==/UserScript==

(function() {
  'use strict';
  const mediaName = 'prefers-color-scheme'
  const { matches } = matchMedia(`(${mediaName}: dark)`)
  const { host } = location
  const name = `${mediaName}:${host}`

  function getValue(saveName, defaultVal = matches) {
    return GM_getValue(saveName, defaultVal)
  }

  function registerMenu(title, saveName) {
    const value = getValue(saveName)
    if (value) title += '            √'
    GM_registerMenuCommand(title, () => {
      GM_setValue(saveName, !value)
      location.reload()
    })
  }

  function getUrl(src, path) {
    const sList = src.split('/')
    const pList = path.split('/')
    const host = sList.slice(0, 3).filter((v) => !!v).join('//')
    let absPath
    if (path.startsWith('/')) {
      absPath = pList.slice(1)
    } else {
      const lastIndex = pList.lastIndexOf('..')
      const index = lastIndex === -1 ? undefined : lastIndex + 1
      absPath = sList.slice(3, index && -index).concat(
        pList.slice(index).filter((v) => v !== '.')
      )
    }
    return `url(${host}/${absPath.join('/')})`
  }

  function replaceCssText(cssText, href) {
    const lastIndex = href.lastIndexOf('/')
    const src = href.slice(0, lastIndex)
    return cssText.replace(/url\(([^\)]*)\)/g, (match, p1) => {
      if (p1.includes('data:image')) {
        return match
      }
      return getUrl(src, p1)
    })
  }

  const herfSet = new Set()
  function replaceStyle(styleSheet) {
    const { href } = styleSheet
    if (herfSet.has(href)) return

    herfSet.add(href)
    GM_xmlhttpRequest({
      method: 'GET',
      url: href,
      onload: res => {
        const { responseText } = res
        const style = document.createElement('style')
        style.innerText = replaceCssText(responseText, href)
        styleSheet.disabled = true
        document.head.appendChild(style)
      }
  });
  }

  registerMenu('深色模式', name)
  const mediaToggle = getMediaToggle({
    onError(e, styleSheet) {
      replaceStyle(styleSheet)
    }
  })

  let first = false
  function toggle() {
    first = true
    const value = getValue(name)
    const mediaMap = mediaToggle.get()
    const key = [...mediaMap.keys()].find((v) => v.includes(mediaName))
    const media = key && mediaMap.get(key)
    if (media) {
        media.toggle(!value)
    }
  }

  mediaToggle.subscribe(toggle)
  if(!first) toggle()
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址