Greasy Fork is available in English.

kk-helper

个人开发常用帮助脚本

// ==UserScript==
// @name         kk-helper
// @namespace    https://greasyfork.org/zh-CN/users/1167332-stephenykk
// @homepage    https://greasyfork.org/zh-CN/scripts/474672-kk-helper
// @version      2.0.3
// @description  个人开发常用帮助脚本
// @author       #stephenykk
// @match        https://juejin.cn/post/*
// @match        https://blog.csdn.net/*/article/details/*
// @match        https://www.jianshu.com/p/*
// @match        https://segmentfault.com/a/*
// @match        https://mp.weixin.qq.com/s*
// @match        https://zhuanlan.zhihu.com/p/*
// @match        https://sspai.com/post/*
// @match        *://www.news.cn/*/**/*.htm*
// @match        *://*.people.com.cn/*/**/*.htm*
// @icon         https://res.wx.qq.com/a/fed_upload/9300e7ac-cec5-4454-b75c-f92260dd5b47/logo-mp.ico
// @grant        none
// @license MIT
// ==/UserScript==

(function () {
  "use strict";
  function log(...args) {
    console.log("[KKCopy]", ...args);
  }

  const autoClick = (ele, callback, seconds = 2) => {
    console.log('try auto click ele:', ele);
    ele.click()
    callback && setTimeout(callback, seconds * 1000)
  }


  function createBtn(text, listener, style='') {
    //   if (this.mybtn) return;
    const btn = document.createElement("button");
    btn.textContent = text || "Submit";
    btn.className = "mybtn";
    btn.setAttribute('data-txt', text);
    btn.style =
      "position: fixed; right: 520px; font-size: 30px; z-index: 100000; top: 0; border: 0; background: aliceblue; color: coral; padding: 0 20px; border-radius: 5px; cursor: pointer;" + style;
    document.body.appendChild(btn);
    btn.addEventListener('click', listener)
     console.log('createBtn: btn=', btn);
    //   this.mybtn = btn;
    return btn;
  }

  // 复制文章链接 [title](link)
  function getCopyHandler() {

    let input = document.querySelector("#myInputEle");
    if (input) {
        return input.copyHandler
    }

    const inpEle = document.createElement("input");
    inpEle.type = "text";
    document.body.insertBefore(inpEle, null);
    inpEle.style = "position: fixed; top: -100px; right: 0; z-index: 10000;";
    inpEle.setAttribute("id", "myInputEle");
    input = inpEle;

    const doCopy = function (text) {
      input.value = text
      input.select();
      input.setSelectionRange(0, input.value.length);
      document.execCommand("copy");
      alert('copy done');
      log("copy done");
    };

    input.copyHandler = doCopy

    return input.copyHandler
  }


  function $(selector) {
    return document.querySelector(selector);
  }

  class TitleCopyAction {
    start() {
      this.btn = createBtn('原文地址', () => {
        const copyHandler = getCopyHandler()
        copyHandler(`> 原文地址[${document.title}](${location.href})`)
      })
    }

  }

  // eslint-disable-next-line
  const copyAction = new TitleCopyAction()
  copyAction.start()


  // 表单填充
  class FormFiller {
    constructor(enableUrl, values, btn) {
      this.url = enableUrl;
      this.values = values;
      this.btn = btn;
    }

    element(selector) {
      return document.querySelector(selector);
    }

    fill() {
      const inputSelectors = Object.keys(this.values);
      const inputValues = Object.values(this.values);
      inputSelectors.forEach((inpSelctor, i) => {
        const input = this.element(inpSelctor);
        if (input) {
          input.value = inputValues[i];
        } else {
          console.log("not found element for", inpSelctor);
        }
      });
    }

    submit() {
      if (this.btn.selector) {
        const submitBtn = this.element(this.btn.selector);
        submitBtn?.click();
        return;
      }

      console.log("not found submitBtn cancel", this.btn); // debug only
    }

    createBtn() {
      //   if (this.mybtn) return;
      const btn = document.createElement("button");
      btn.textContent = this.btn.text || "Submit";
      btn.className = "mybtn";
      btn.style =
        "position: fixed; right: 250px; font-size: 30px; z-index: 100; top: 0; border: 0; background: aliceblue; color: coral; padding: 0 20px; border-radius: 5px; cursor: pointer;";
      document.body.appendChild(btn);
      //   this.mybtn = btn;
      return btn;
    }

    start() {
      if (location.href.includes(this.url) === false) return;

      this.mybtn = this.createBtn();
      this.mybtn.addEventListener("click", () => {
        this.fill();
        this.submit();
      });
    }
  }

})();


(function () {
  function clearStorageAndCookie(isrefresh = true) {
    [sessionStorage, localStorage].forEach((storage) => storage.clear());
    clearCookies();
    console.log(document.cookie, "done!!");
    isrefresh && setTimeout(location.reload.bind(location), 1000);
  }

  function pick(data, keys) {
    return keys.reduce((ret, key) => {
      ret[key] = data[key];
      return ret;
    }, {});
  }

  function setLocalStorage(data) {
    Object.keys(data).forEach((key) => {
      localStorage[key] = data[key];
    });

    console.log("done", localStorage);
  }

  function getCookies() {
    return document.cookie.match(/[\w-]+(?=\=[^;]+)/g) || [];
  }

  function clearCookies() {
    getCookies().forEach((cname) => {
      delCookie(cname);
    });
  }

  function setCookie(cname, cvalue, exdays) {
    const d = new Date();
    d.setTime(d.getTime() + exdays * 24 * 60 * 60 * 1000);
    const expires = "; Expires=" + d.toUTCString();
    // document.cookie = cname + "=" + cvalue + expires + "; Path=/";
    document.cookie = cname + "=" + cvalue + expires;
  }

  function delCookie(cname) {
    console.log("del cookie:", cname);
    setCookie(cname, "", -1);
  }

  function copy(str) {
    const el = document.createElement("textarea");
    el.value = str;
    el.setAttribute("readonly", "");
    el.style.position = "absolute";
    el.style.left = "-9999px";
    document.body.appendChild(el);
    el.select();
    document.execCommand("copy");
    document.body.removeChild(el);
  }

  function setDebugSwitch(key, val = 1) {
    // localStorage.debug = localStorage.debug + 'schema;domain;zxhbEdit=1'
    const debugval = localStorage.debug || ''
    const pairs = debugval.split(';').map(pair => pair.includes('=') ? pair.split('=') : (pair + '=true').split('='))
    const conf = Object.fromEntries(pairs)
    conf[key] = val
    console.log('new conf:', conf)
    const entriesVal = Object.entries(conf).map(pair => pair.join('=')).join(';')
    localStorage.debug = entriesVal
  }
  
  function debugDomainSchema() {
    setDebugSwitch('domain')
    setDebugSwitch('schema')
  }


  function toUnicode(str) {
    const ls = str.split("");
    const result = ls
      .map((c) => {
        if (/\w/.test(c)) return c;

        return "\\u" + c.charCodeAt(0).toString(16).toUpperCase();
      })
      .join("");

    copy(result);
    console.log("copy done");
    return result;
  }

  function isPlainObject(val) {
    return Object.prototype.toString.call(val).slice(8, -1) === "Object";
  }

  function getTableTypeDefines(vm) {
    const { tableData, schema } = vm.props ?? {};
    if (!tableData) {
      console.warn("not tableData found:", vm.props);
      return;
    }

    return getTypeDefines(tableData[0], schema);
  }

  function getTypeDefines(obj = {}, schema = false, level = 10) {
    // if (Array.isArray(obj)) {
    //   if (obj.length === 0) {
    //     return 'Array<any>'
    //   }
    //   return `Array<${getTypeDefines(obj[0], schema, level - 1)}>`
    // }
    if (Array.isArray(obj)) {
      obj = obj[0];
    }

    const getPrimativeType = (key, val) => {
      let type = typeof val;
      let text = "";

      if (!schema) {
        return { type, text };
      }

      const props = schema.properties ?? {};
      if (props[key]) {
        type = props[key].type;
        text = props[key].title;
      }

      return { type, text };
    };
    let ret = "{\n";
    Object.keys(obj).forEach((key) => {
      if (key.startsWith("_")) return;
      const val = obj[key];
      const isPrimative = !isPlainObject(val) && !Array.isArray(val);
      let title = "";
      let valType;
      if (isPrimative) {
        const { type, text } = getPrimativeType(key, val);
        valType = type;
        title = text;
      } else {
        valType = getTypeDefines(val, schema);
      }

      const keyDefine = `${key}: ${valType};${title ? " // " + title : ""}\n`;
      ret += keyDefine;
    });
    ret += "\n}";

    copy(ret);
    console.log("copy done!");
    return ret;
  }

  window.my = {
    getTableTypeDefines,
    toUnicode,
    setLocalStorage,
    pick,
    clearStorageAndCookie,
    setDebugSwitch,
    debugDomainSchema,
  }
})();