里屋Style

新增字体设置 调节分栏比例和图片展示大小

目前为 2023-12-12 提交的版本。查看 最新版本

// ==UserScript==
// @name         里屋Style
// @namespace    https://github.com/Particaly/
// @version      1.0.2
// @description  新增字体设置 调节分栏比例和图片展示大小
// @author       J.S.Patrick
// @match        *://253874.net/*
// @match        *://www.253874.net/*
// @grant        none
// @license      MIT
// ==/UserScript==

(function () {
  'use strict';
  // ------------------ 公用
  const cn_fonts = [
    { name: 'Noto Sans SC', url: 'https://fonts.googleapis.com/css?family=Noto+Sans+SC', fontFamily: 'Noto Sans SC' },
    { name: 'Ma Shan Zheng', url: 'https://fonts.googleapis.com/css?family=Ma+Shan+Zheng', fontFamily: 'Ma Shan Zheng' }
  ]
  const extra_style = `
    html[data-darkreader-scheme=dark] body{
      background: #fff;
    }
  `
  const frame_ids = ['gb_top', 'gb_left', 'gb_right', 'gb_search']
  function sleep(time) {
    return new Promise(resolve => {
      setTimeout(resolve, time)
    })
  }
  // ------------------
  // ------------------ 记录 frame 的尺寸
  function getFrameSize() {
    return window.localStorage.getItem('frameset-size');
  }
  function updateFrameSize() {
    const outerFrameSet = document.getElementById('gb_bodys');
    const children = Array.from(outerFrameSet.children);
    const size = children.map(t => t.clientWidth).join(',');
    window.localStorage.setItem('frameset-size', size);
    return size;
  }
  function setFrameSize() {
    const outerFrameSet = document.getElementById('gb_bodys');
    const size = getFrameSize() || updateFrameSize();
    outerFrameSet.cols = size;
  }
  // ---------------------------------------

  // ------------------ 注入字体选项
  function registerFontInjectionListener() {

    const hashchange = () => {
      const right_frame = document.getElementById('gb_right');
      const right_win = right_frame.contentWindow;
      const href = right_win.location.href;
      setFont();
      if (href === 'https://www.253874.net/panel###') {
        injectFontOptions();
      }
    };

    const unload = async id => {
      const frame = document.getElementById(id);
      const doc = frame.contentDocument;
      const win = frame.contentWindow;

      sleep(300).then(() => {
        win.addEventListener('unload', () => unload(id));
        win.addEventListener('hashchange', hashchange);
        setFont()
      });
    };

    frame_ids.forEach(id => {
      const frame = document.getElementById(id);
      if (!frame) return console.warn('not found frame', id)
      const doc = frame.contentDocument;
      const win = frame.contentWindow;
      win.addEventListener('unload', () => unload(id))
    })

    setFont();
  }
  function injectFontOptions() {
    const right_frame = document.getElementById('gb_right');
    const right_doc = right_frame.contentDocument;
    const target = right_doc.querySelector('[name=font_cn]')
    cn_fonts.forEach(f => {
      if (f.url) {
        const option = document.createElement('option');
        option.value = f.fontFamily;
        option.innerText = f.name;
        target.appendChild(option)
      }
    })
    const container = right_doc.querySelector('[id=font_panel]');
    container.addEventListener('change', () => {
      updateFont();
      setFont();
    });
  }
  function getFont() {
    const str = window.localStorage.getItem('font');
    try {
      return JSON.parse(str)
    } catch(e) {
      return null
    }
  }
  function setFont() {
    const css = getFont();
    console.log('set font style', css)
    if (!css) return;

    const setTask = async (id, retryTimes=0) => {
      if (retryTimes > 10) return false;
      const frame = document.getElementById(id);
      if (!frame) {
        await sleep(50);
        retryTimes++;
        return setTask(id, retryTimes);
      }
      const doc = frame.contentDocument;
      const sheetContent = extra_style + `
        body {
          font-family: ${css['font-family']};
          font-size: ${css['font-size']};
          line-height: ${css['line-height']};
        }
      `
      const sheet = document.createElement('style');
      sheet.type = 'text/css';
      sheet.innerText = sheetContent;
      doc.head.appendChild(sheet);
      cn_fonts.forEach(font => {
        if (css['font-family'].includes(font.fontFamily)) {
          const link = document.createElement('link');
          link.rel = 'stylesheet';
          link.href = font.url;
          doc.head.appendChild(link);
        }
      })
    }

    frame_ids.forEach(id => {
      setTask(id);
    })
  }
  function updateFont(overwrite) {
    const frame = document.getElementById('gb_right');
    const dom = frame.contentDocument;
    const $ = dom.querySelector.bind(dom);
    const font = [];
    console.log($('select[name=font_en]'))
    const font_en = $('select[name=font_en]').value;
    const font_cn = $('select[name=font_cn]').value;
    const font_size = $('select[name="font_size"]').value;
    let css = {};
    if (font_en.length > 0) {
      font.push(font_en);
    }

    if (font_cn.length > 0) {
      font.push(font_cn);
    }
    if (font.length > 0) {
      css['font-family'] = "'" + font.join("', '") + "', sans-serif";
    }

    if (font_size > 0) {
      css['font-size'] = font_size + 'px';
      css['line-height'] = '22px';
    }
    window.localStorage.setItem('font', JSON.stringify(css));
  }

  window.addEventListener('load', async function () {
    // 调整 frameset 宽度
    const outerFrameSet = document.getElementById('gb_bodys');
    if (outerFrameSet) {
      outerFrameSet.addEventListener('mousemove', e => {
        const children = Array.from(outerFrameSet.children);
        const size = children.map(t => t.clientWidth).join(',');
        if (size === getFrameSize()) return;
        updateFrameSize();
      });
      setFrameSize();
    }
    await sleep(100)
    registerFontInjectionListener();

    const posts = document.querySelectorAll('.post_list');
    posts.forEach(post => {
      const images = post.querySelectorAll('img');
      images.forEach(img => {
        // 跳过gif表情包
        if (img.src.toLowerCase().endsWith('.gif')) {
          return;
        }

        // 设置图片的初始高度,保持宽高比
        img.style.height = '300px';
        img.style.width = 'auto';

        let originalHeight = img.naturalHeight;
        let originalWidth = img.naturalWidth;

        // 点击时切换图片大小
        img.addEventListener('click', () => {
          if (img.style.height === '300px') {
            img.style.height = originalHeight + 'px';
            img.style.width = originalWidth + 'px';
          } else {
            img.style.height = '300px';
            img.style.width = 'auto';
          }
        });
      });
    });
  });
})();