MCBBS Wiki欢迎您共同参与编辑!在参与编辑之前请先阅读Wiki方针

如果在编辑的过程中遇到了什么问题,可以去讨论板提问。

为了您能够无阻碍地参与编辑 未验证/绑定过邮箱的用户,请尽快绑定/验证

MCBBS Wiki GitHub群组已上线!

您可以在回声洞中发表吐槽!

服务器状态监控。点击进入

本站由MCBBS用户自行搭建,与MCBBS及东银河系漫游指南(北京)科技有限公司没有从属关系。点此了解 MCBBS Wiki 不是什么>>

MediaWiki:Gadget-VectorThemeLoader.js:修订间差异

来自MCBBS Wiki
跳到导航 跳到搜索
(新的主题切换功能)
 
(区分新旧版vector皮肤)
第177行: 第177行:
//! https://github.com/mcbbs-wiki/mcbbs-wiki-widget-repo/tree/master/widget/VectorThemeLoader
//! https://github.com/mcbbs-wiki/mcbbs-wiki-widget-repo/tree/master/widget/VectorThemeLoader
addStyle(widget_t_default);
addStyle(widget_t_default);
var isLegacy = document.body.classList.contains("skin-vector-legacy");
var themeMap = {
var themeMap = isLegacy ? {
book: {
book: {
name: "仿MCBBS书页风格",
name: "仿MCBBS书页风格",
common: "MediaWiki:Vector-Book.css",
common: "MediaWiki:Vector-Legacy-Book.css",
default: {
default: {
name: "夏季主题",
name: "夏季主题",
第189行: 第190行:
nether: { name: "下界主题", css: "MediaWiki:Vector-Book-Nether.css" },
nether: { name: "下界主题", css: "MediaWiki:Vector-Book-Nether.css" },
winter: { name: "冬季主题", css: "MediaWiki:Vector-Book-Winter.css" }
winter: { name: "冬季主题", css: "MediaWiki:Vector-Book-Winter.css" }
},
legacy: {
name: "",
common: "MediaWiki:Vector-Legacy-Book.css",
default: { name: "夏季主题", css: "MediaWiki:Vector-Book-Summer.css" },
other: {
nether: { name: "下界主题", css: "MediaWiki:Vector-Book-Nether.css" },
winter: { name: "冬季主题", css: "MediaWiki:Vector-Book-Winter.css" }
}
}
}
}
} : {
v4: {
name: "仿MCBBS v4风格",
common: "MediaWiki:Vector-V4.css",
default: { name: "默认风格", css: "MediaWiki:Vector-V4.css" },
other: {}
}
}
};
};
var defaultStyle = Object.keys(themeMap)[0];
var isLegacy = document.body.classList.contains("skin-vector-legacy");
var styleKey = "skin-vector-style";
var styleKey = isLegacy ? "mcbbs-wiki-skin-vector-legacy-style" : "mcbbs-wiki-skin-vector-style";
var themeKey = "skin-vector-theme";
var themeKey = isLegacy ? "mcbbs-wiki-skin-vector-legacy-theme" : "mcbbs-wiki-skin-vector-theme";
var loadThemeStyle = (style, theme) => {
var loadThemeStyle = (style, theme) => {
const _styleMap = themeMap[style];
const styleMap = themeMap[style] || themeMap[defaultStyle];
const styleMap = isLegacy ? _styleMap.legacy || _styleMap : _styleMap;
const currentCommonStyle = styleMap.common;
const currentCommonStyle = styleMap.common;
loadWikiStyle(currentCommonStyle, "salt-wiki-style-common");
loadWikiStyle(currentCommonStyle, "salt-wiki-style-common");
第213行: 第211行:
};
};
var initTheme = () => {
var initTheme = () => {
const current = { style: "book", theme: "default" };
const current = { style: defaultStyle, theme: "default" };
const [style] = readAndListen({
const [style] = readAndListen({
key: styleKey,
key: styleKey,
defaultValue: "book",
defaultValue: defaultStyle,
listener: (ev) => {
listener: (ev) => {
if (ev.newValue) {
if (ev.newValue) {

2022年8月14日 (日) 14:18的版本

"use strict";
(() => {
  // src/utils/resource.ts
  function addStyleUrl(url, key) {
    let style;
    if (key && document.getElementById(key) instanceof HTMLLinkElement) {
      style = document.getElementById(key);
    } else {
      style = document.createElement("link");
      style.rel = "stylesheet";
      style.type = "text/css";
      if (key)
        style.id = key;
    }
    if (style.href === url)
      return;
    style.href = url;
    document.head.appendChild(style);
  }
  function addStyle(css) {
    const style = document.createElement("style");
    style.textContent = css;
    document.head.appendChild(style);
  }
  function loadWikiStyle(page, key) {
    addStyleUrl(`https://mcbbs.wiki/index.php?title=${page}&action=raw&ctype=text/css`, key);
  }

  // src/utils/storage.ts
  function parse(str) {
    if (str) {
      try {
        return JSON.parse(str);
      } catch (e) {
      }
    }
    return null;
  }
  function write(key, value) {
    localStorage.setItem(key, JSON.stringify(value));
  }
  function unsafeRead(key) {
    const storage = localStorage.getItem(key);
    return parse(storage);
  }
  function listen(listener, options = { passive: true }) {
    window.addEventListener("storage", listener, options);
    return () => window.removeEventListener("storage", listener, options);
  }
  function readAndListen(props) {
    const {
      key,
      defaultValue,
      listener,
      callOnChange = true,
      options = { passive: true }
    } = props;
    let v = unsafeRead(key);
    if (defaultValue !== void 0 && v === null) {
      write(key, defaultValue);
      v = defaultValue;
    }
    const fn = (ev) => {
      if (ev.key !== key || ev.storageArea !== localStorage)
        return;
      const newValue = parse(ev.newValue);
      const oldValue = parse(ev.oldValue);
      if (callOnChange && newValue === oldValue)
        return;
      const encapsulatedEvent = {
        key,
        newValue,
        oldValue,
        storageArea: ev.storageArea,
        url: ev.url
      };
      listener(encapsulatedEvent);
    };
    const off = listen(fn, options);
    return [v, off];
  }

  // src/utils/utils.ts
  var i = document.createElement("textarea");
  i.setAttribute("style", "pointer-events:none;opacity:0;position:fixed;");
  function clickOutside(el, callback) {
    const cb = (ev) => {
      const { target } = ev;
      if (!(target instanceof Element))
        return;
      if (target === el)
        return;
      let obj = target.parentElement;
      while (obj && obj !== el && obj.parentElement) {
        obj = obj.parentElement;
      }
      if (obj !== el)
        callback();
    };
    window.addEventListener("click", cb, true);
    return () => window.removeEventListener("click", cb);
  }

  // widget/VectorThemeLoader/SwitchPanel.ts
  function createPanel(props, ...innerElements) {
    const {
      className,
      position: { x, y }
    } = props;
    const panel = document.createElement("div");
    panel.className = `salt-panel ${className || ""}`;
    panel.style.position = "absolute";
    for (const el of innerElements)
      panel.appendChild(el);
    document.body.appendChild(panel);
    const { offsetWidth, offsetHeight } = panel;
    panel.style.left = `${Math.max(x - offsetWidth / 2, 0)}px`;
    panel.style.top = `${y + 2}px`;
    const cancel = clickOutside(panel, () => {
      console.log("awa");
      panel.remove();
      cancel();
    });
    return panel;
  }

  // widget/VectorThemeLoader/widget.t.scss
  var widget_t_default = `
.salt-panel.style-list {
  padding: 8px 12px;
  border-radius: 4px;
  background-color: var(--lightcolor, #f9f9f9);
  box-shadow: 1px 2px 5px 0 rgba(153, 153, 153, 0.4);
  font-size: 1rem;
  z-index: 9999;
}
.salt-panel.style-list, .salt-panel.style-list * {
  box-sizing: border-box;
}
.salt-panel.style-list .style-list-item {
  display: block;
  min-width: 196px;
  margin: 4px 0;
  list-style: none;
  overflow: hidden;
}
.salt-panel.style-list .style-list-item .theme-list {
  padding: 2px 4px;
  margin: 0;
  overflow: hidden;
}
.salt-panel.style-list .style-list-item .theme-list .theme-list-item {
  padding: 4px 8px;
  list-style: none;
  overflow: hidden;
  user-select: none;
  cursor: pointer;
}
.salt-panel.style-list .style-list-item .theme-list .theme-list-item:hover {
  background-color: rgba(153, 153, 153, 0.0666666667);
}
.salt-panel.style-list .style-list-item .theme-list .theme-list-item:active {
  background-color: rgba(153, 153, 153, 0.2);
}
.salt-panel.style-list .style-list-item .theme-list .theme-list-item .theme-list-item-img {
  display: inline-block;
  width: 1rem;
  height: 1rem;
  vertical-align: middle;
  margin-right: 4px;
}
.salt-panel.style-list .style-list-item .theme-list .theme-list-item .theme-list-item-name {
  display: inline;
}`;

  // widget/VectorThemeLoader/widget.ts
  //! https://github.com/mcbbs-wiki/mcbbs-wiki-widget-repo/tree/master/widget/VectorThemeLoader
  addStyle(widget_t_default);
  var isLegacy = document.body.classList.contains("skin-vector-legacy");
  var themeMap = isLegacy ? {
    book: {
      name: "仿MCBBS书页风格",
      common: "MediaWiki:Vector-Legacy-Book.css",
      default: {
        name: "夏季主题",
        css: "MediaWiki:Vector-Book-Summer.css",
        img: "https://mcbbs.wiki/images/2/2f/艺术家与认证用户回帖图标.png"
      },
      other: {
        nether: { name: "下界主题", css: "MediaWiki:Vector-Book-Nether.css" },
        winter: { name: "冬季主题", css: "MediaWiki:Vector-Book-Winter.css" }
      }
    }
  } : {
    v4: {
      name: "仿MCBBS v4风格",
      common: "MediaWiki:Vector-V4.css",
      default: { name: "默认风格", css: "MediaWiki:Vector-V4.css" },
      other: {}
    }
  };
  var defaultStyle = Object.keys(themeMap)[0];
  var styleKey = isLegacy ? "mcbbs-wiki-skin-vector-legacy-style" : "mcbbs-wiki-skin-vector-style";
  var themeKey = isLegacy ? "mcbbs-wiki-skin-vector-legacy-theme" : "mcbbs-wiki-skin-vector-theme";
  var loadThemeStyle = (style, theme) => {
    const styleMap = themeMap[style] || themeMap[defaultStyle];
    const currentCommonStyle = styleMap.common;
    loadWikiStyle(currentCommonStyle, "salt-wiki-style-common");
    const currentTheme = theme === "default" || !styleMap.other[theme] ? styleMap.default : styleMap.other[theme];
    loadWikiStyle(currentTheme.css, "salt-wiki-style-theme");
  };
  var initTheme = () => {
    const current = { style: defaultStyle, theme: "default" };
    const [style] = readAndListen({
      key: styleKey,
      defaultValue: defaultStyle,
      listener: (ev) => {
        if (ev.newValue) {
          current.style = ev.newValue;
          loadCurrentTheme();
        }
      }
    });
    const [theme] = readAndListen({
      key: themeKey,
      defaultValue: "default",
      listener: (ev) => {
        if (ev.newValue) {
          current.theme = ev.newValue;
          loadCurrentTheme();
        }
      }
    });
    current.style = style;
    current.theme = theme;
    const loadCurrentTheme = () => {
      const { style: style2, theme: theme2 } = current;
      loadThemeStyle(style2, theme2);
    };
    loadCurrentTheme();
  };
  initTheme();
  var handleSwitchBtn = (ev) => {
    const { top, left } = $(btn).offset();
    console.log(ev);
    const innerElements = [];
    const createThemeSwitch = (style, themeCode, theme) => {
      const { name, img: imgSrc } = theme;
      const handleClick = () => {
        write(styleKey, style);
        write(themeKey, themeCode);
        loadThemeStyle(style, themeCode);
      };
      const li2 = document.createElement("li");
      li2.className = "theme-list-item";
      li2.addEventListener("click", handleClick);
      if (imgSrc) {
        const img = document.createElement("img");
        img.src = imgSrc;
        img.className = "theme-list-item-img";
        li2.appendChild(img);
      }
      const div = document.createElement("div");
      div.textContent = name;
      div.className = "theme-list-item-name";
      li2.appendChild(div);
      return li2;
    };
    for (const style in themeMap) {
      const li2 = document.createElement("li");
      li2.className = "style-list-item";
      const title = document.createElement("div");
      title.className = "style-list-item-title";
      title.textContent = themeMap[style].name;
      const ul = document.createElement("ul");
      ul.className = "theme-list";
      const themeList = [];
      const defaultTheme = themeMap[style].default;
      themeList.push(createThemeSwitch(style, "default", defaultTheme));
      for (const themeCode in themeMap[style].other) {
        themeList.push(createThemeSwitch(style, themeCode, themeMap[style].other[themeCode]));
      }
      for (const el of themeList)
        ul.appendChild(el);
      li2.appendChild(title);
      li2.appendChild(ul);
      innerElements.push(li2);
    }
    createPanel({
      className: "style-list",
      position: { x: left, y: top + btn.offsetHeight }
    }, ...innerElements);
  };
  var headLogoutBtn = document.getElementById("pt-logout");
  var btn = document.createElement("a");
  btn.textContent = "切换主题";
  btn.title = "切换主题";
  btn.onclick = handleSwitchBtn;
  var li = document.createElement("li");
  li.className = "mw-list-item";
  li.appendChild(btn);
  console.log("headLogoutBtn.parentElement", headLogoutBtn.parentElement);
  headLogoutBtn.parentElement.insertBefore(li, headLogoutBtn);
})();