// ==UserScript==
// @name kk-helper
// @namespace https://gf.qytechs.cn/zh-CN/users/1167332-stephenykk
// @homepage https://gf.qytechs.cn/zh-CN/scripts/474672-kk-helper
// @version 3.0.0
// @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 toast(msg) {
const toastEle = document.createElement("div");
toastEle.style = `
position: fixed;
top: 30%;
left: 50%;
transform: translate(-50%, -50%);
background: rgba(0, 0, 0, 0.7);
color: white;
padding: 15px 30px;
border-radius: 5px;
z-index: 1000000;
font-size: 15px;
line-height: 1.5;
`;
toastEle.innerText = msg;
document.body.appendChild(toastEle);
setTimeout(() => {
document.body.removeChild(toastEle);
}, 2000);
}
const btnStyle = `
opacity: 0.7;
font-size: 15px;
border: 0;
background: brown;
color: white;
padding: 8px 16px;
border-radius: 5px;
cursor: pointer;
margin: 0 20px;
`;
function createBtn(text, listener, style = "") {
let btnsWrap = $("#myBtnsWrap");
if (!btnsWrap) {
btnsWrap = document.createElement("div");
btnsWrap.id = "myBtnsWrap";
btnsWrap.style =
"position: fixed; left: 50%; top: 10px; z-index: 10000; transform: translateX(-50%);";
document.body.appendChild(btnsWrap);
}
// if (this.mybtn) return;
const btn = document.createElement("button");
btn.textContent = text || "Submit";
btn.className = "mybtn";
btn.setAttribute("data-txt", text);
btn.style = btnStyle + style;
btnsWrap.appendChild(btn);
btn.addEventListener("click", listener);
console.log("createBtn: btn=", btn);
// this.mybtn = btn;
return btn;
}
function getCopyMethod() {
let input = document.querySelector("#myInputEle");
if (input) {
return input.copyOf;
}
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");
toast("copy ok");
log("copy done");
};
input.copyOf = doCopy;
return input.copyOf;
}
function $(selector) {
return document.querySelector(selector);
}
class OriginLinkCopyAction {
start() {
// 复制原文地址按钮
this.btn = createBtn("原文地址", () => {
const copy = getCopyMethod();
copy(`> 原文地址: [${document.title}](${location.href})`);
});
}
}
// eslint-disable-next-line
const linkCopyAction = new OriginLinkCopyAction();
linkCopyAction.start();
class BlogTitleCopyAction {
start() {
// 复制原文地址按钮
this.btn = createBtn(
"文章标题",
() => {
const copy = getCopyMethod();
copy(document.title);
},
"right: 300px"
);
}
}
const titleCopyAction = new BlogTitleCopyAction();
titleCopyAction.start();
// 表单填写
class FormFiller {
constructor(enableUrl, values, btn) {
this.url = enableUrl;
this.values = values;
this.btn = btn;
}
element(selector) {
return $(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 = btnStyle;
document.body.appendChild(btn);
// this.mybtn = btn;
return btn;
}
start() {
if (location.href.includes(this.url) === false) return;
this.mybtn = this.createBtn();
// click mybtn, fill data to input box, and trigger submit button click method
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 localCacheEntries(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 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,
pick,
copy,
getCookies,
setCookie,
delCookie,
clearCookies,
localCacheEntries,
clearStorageAndCookie,
};
})();