', {
class: 'hover:bg-sd-accent flex h-7 w-7 items-center justify-center rounded opacity-0',
type: 'button',
'aria-haspopup': 'dialog',
'aria-expanded': 'false',
'aria-controls': 'xxx',
'data-state': 'closed'
}).append(
$('
', {
class:
'relative text-[14px] leading-[normal] p-[1px] before:block before:h-3.5 before:w-3.5 text-sd-muted-foreground',
html: ''
})
);
$div1.append($inner1, $inner2, $inner3, $inner4);
$wrapper.append($div1);
$a.append($wrapper);
// 插入到第一个父元素的最前面
if (parentNodeList && parentNodeList.childNodes.length > 0) {
const firstChild = parentNodeList.childNodes[0];
if (firstChild) {
parentNodeList.insertBefore($a[0], firstChild);
} else {
parentNodeList.appendChild($a[0]);
}
}
}
let lcCnt = 0;
let pbSetCnt = 0;
function getData() {
let switchpbRepo = GM_getValue('switchpbRepo');
let switchTea = GM_getValue('switchTea');
let switchrealoj = GM_getValue('switchrealoj');
let switchlevel = GM_getValue('switchlevel');
let arr = document.querySelector('[class*="pb-[80px]"]');
let everydatpbidx = 0;
// pb页面加载时直接返回
if (arr == null) {
return;
}
observeIfNeeded(arr);
isSelfChanging = true;
try {
if (pbSetCnt && pbSetCnt == arr.childNodes.length) {
console.log('第' + lcCnt + '次刷新插件...');
// 到达次数之后删除定时防止卡顿
if (lcCnt == shortCnt) {
console.log('到达当前功能指定刷新次数, 检测暂时无更新, 暂停刷新...');
clearId('all');
}
lcCnt += 1;
return;
}
t2rate = JSON.parse(GM_getValue('t2ratedb', '{}').toString());
// 灵茶题目渲染
if (switchTea) {
let first = arr.firstChild;
if (!first.textContent.includes('灵茶题集')) {
createProblemCard({
title: '灵茶题集' + '-' + getCurrentDate(3),
pburl: teaSheetUrl,
difficulty: '暂无',
rate: '暂无',
parentNodeList: arr
});
}
// 经过灵茶之后,无论如何数量都会变成1
everydatpbidx = 1;
}
if (switchpbRepo) {
let childs = arr.childNodes;
let idx = switchTea ? 1 : 0;
let childLength = childs.length;
for (; idx < childLength; idx++) {
let v = childs[idx];
// 如果元素第一个就不存在或undifined就直接返回
if (!v) return;
let t = v.textContent;
let data = t.split('.');
let id = data[0].trim();
let $item = $(v);
let difficulty = $item.find('.text-sd-medium, .text-sd-easy, .text-sd-hard').first();
let passRate = difficulty.siblings('div.text-sd-muted-foreground').first();
// 如果没有难度和通过率属性,则跳过步骤
if (difficulty.length <= 0 || passRate.length <= 0) continue;
if (switchrealoj) {
// 难度修改为隐藏
if (difficulty.length > 0) {
difficulty.text('隐藏');
difficulty.removeClass('text-sd-easy text-sd-medium text-sd-hard');
}
// 通过率修改为隐藏
if (passRate.length > 0) {
passRate.text('隐藏');
}
continue;
}
// 因为lc请求是有缓存的,所以多次刷新的时候同一个位置会是不同的题目,这时候需要还原
if (t2rate[id] != null) {
let ndScore = t2rate[id]['Rating'];
difficulty.text(ndScore);
// 修改尺寸使得数字分数和文字比如(困难)保持在同一行
passRate.removeClass('w-[70px]');
passRate.addClass('w-[55px]');
} else {
let nd2ch = {
'mx-0 text-[14px] text-sd-easy lc-xl:mx-4': '简单',
'mx-0 text-[14px] text-sd-medium lc-xl:mx-4': '中等',
'mx-0 text-[14px] text-sd-hard lc-xl:mx-4': '困难'
};
difficulty.text(nd2ch[difficulty.attr('class')]);
// 恢复原有大小尺寸
passRate.removeClass('w-[55px]');
passRate.addClass('w-[70px]');
}
// 增加算术评级插入操作
if (switchlevel) {
let level = levelData[id];
let levelText = level ? '算术评级: ' + level['Level'] : '';
let $existingLevel = passRate.siblings('.arithmetic-level');
// 如果已经操作过
if ($existingLevel.length > 0) {
// 如果含有算术评级则更新文本,如果没有则删除原来插入的数据
if (level) {
$existingLevel.text(levelText);
} else {
$existingLevel.remove();
}
} else if (level) {
// 如果没有操作过
// 如果含有算术评级则插入,如果没有算术评级,则不做任何操作
// 构造新的算术等级元素(保持结构一致)
const $level = $('
')
.addClass(passRate.attr('class')) // 复用样式
.addClass('arithmetic-level') // 自定义类作为标记
.text(levelText);
// 去除灰色颜色和尺寸限制
$level
.removeClass('w-[70px] w-[55px] text-sd-muted-foreground')
.addClass('min-w-[100px]');
// 如果插入的为每日一题位置,需要修改尺寸,左移8px
if (idx == everydatpbidx) {
$level.css('transform', 'translateX(-8px)');
}
// 插入到通过率前面
passRate.before($level);
}
}
}
console.log('has refreshed problemlist...');
}
pbSetCnt = arr.childNodes.length;
} finally {
isSelfChanging = false;
}
}
// pblist插件刷新次数
let pbListCnt = 0;
// pblist当前刷新之后列表所含题目数量
let pbListpbCnt = 0;
function getPblistData() {
if (!GM_getValue('switchpblist')) return;
let switchrealoj = GM_getValue('switchrealoj');
let switchlevel = GM_getValue('switchlevel');
let switchpblistRateDisplay = GM_getValue('switchpblistRateDisplay');
let pre = document.querySelector('.w-full .pb-20');
let arr = pre?.childNodes[0]?.lastChild?.childNodes[0];
if (!arr) return;
// 设置监听官方渲染,并标记当前自己修改不被监听
observeIfNeeded(arr);
isSelfChanging = true;
try {
// console.log(arr)
// console.log(pbListpbCnt)
// console.log(arr.childNodes.length)
if (pbListpbCnt && pbListpbCnt == arr.childNodes.length) {
console.log('第' + pbListCnt + '次刷新插件...');
// 到达次数之后删除定时防止卡顿
if (pbListCnt == shortCnt) {
console.log('到达当前功能指定刷新次数, 检测暂时无更新, 暂停刷新...');
console.log('清理标记');
clearId('pblist');
}
pbListCnt += 1;
return;
}
t2rate = JSON.parse(GM_getValue('t2ratedb', '{}').toString());
let childs = arr.childNodes;
let childLength = childs.length;
for (let idx = 0; idx < childLength; idx++) {
let v = childs[idx];
if (!v) return;
let t = v.textContent;
let data = t.split('.');
let id = data[0].trim();
// console.log(id)
// 如果不是a标签,说明是自定义题单,需要多进一层
let $item = $(v);
let difficulty = $item.find('.text-sd-medium, .text-sd-easy, .text-sd-hard').first();
let passRate = difficulty.siblings('div.text-sd-muted-foreground').first();
if (switchpblistRateDisplay) passRate.removeClass('opacity-0').addClass('opacity-100');
// 如果没有难度属性,则跳过步骤
if (difficulty.length <= 0 || passRate.length <= 0) continue;
if (switchrealoj) {
// 难度修改为隐藏
if (difficulty.length > 0) {
difficulty.text('隐藏');
difficulty.removeClass('text-sd-easy text-sd-medium text-sd-hard');
}
// 通过率修改为隐藏
if (passRate.length > 0) {
passRate.text('隐藏');
}
continue;
}
// 插入竞赛分数
if (t2rate[id] != null) {
let ndScore = t2rate[id]['Rating'];
difficulty.text(ndScore);
// 修改尺寸使得数字分数和文字比如(困难)保持在同一行
passRate.removeClass('w-[70px]');
passRate.addClass('w-[55px]');
} else {
let nd2ch = {
'mx-0 text-[14px] text-sd-easy lc-xl:mx-4': '简单',
'mx-0 text-[14px] text-sd-medium lc-xl:mx-4': '中等',
'mx-0 text-[14px] text-sd-hard lc-xl:mx-4': '困难'
};
difficulty.text(nd2ch[difficulty.attr('class')]);
// 恢复原有大小尺寸
passRate.removeClass('w-[55px]');
passRate.addClass('w-[70px]');
}
// 增加算术评级插入操作
if (switchlevel) {
let level = levelData[id];
let levelText = level ? '算术评级: ' + level['Level'] : '';
let $existingLevel = passRate.siblings('.arithmetic-level');
// 如果已经操作过
if ($existingLevel.length > 0) {
// 如果含有算术评级则更新文本,如果没有则删除原来插入的数据
if (level) {
$existingLevel.text(levelText);
} else {
$existingLevel.remove();
}
} else if (level) {
// 如果没有操作过
// 如果含有算术评级则插入,如果没有算术评级,则不做任何操作
// 构造新的算术等级元素(保持结构一致)
const $level = $('
')
.addClass(passRate.attr('class')) // 复用样式
.addClass('arithmetic-level') // 自定义类作为标记
.text(levelText);
// 去除灰色颜色和尺寸限制
$level
.removeClass('opacity-0 w-[70px] w-[55px] text-sd-muted-foreground')
.addClass('min-w-[100px] opacity-100');
// 插入到通过率前面
passRate.before($level);
}
}
}
console.log('has refreshed...');
pbListpbCnt = arr.childNodes.length;
} finally {
isSelfChanging = false;
}
}
function getSearch() {
if (!GM_getValue('switchsearch')) return;
let arr = $("div[role='table']");
if (arr.length == 0) return;
arr = arr[0].childNodes[1];
let head = document.querySelector("div[role='row']");
if (!head) rerurn;
// 确认难度序列
let rateRefresh = false;
let headndidx;
for (let i = 0; i < head.childNodes.length; i++) {
let headEle = head.childNodes[i];
if (headEle.textContent.includes('难度')) {
headndidx = i;
}
if (headEle.textContent.includes('题目评分')) {
rateRefresh = true;
}
}
if (!arr) return;
let childs = arr.childNodes;
for (const element of childs) {
let v = element;
if (!v.childNodes[1]) return;
let t = v.childNodes[1].textContent;
let data = t.split('.');
let id = data[0].trim();
let nd = v.childNodes[headndidx].childNodes[0].innerHTML;
if (t2rate[id] != null && !rateRefresh) {
nd = t2rate[id]['Rating'];
v.childNodes[headndidx].childNodes[0].innerHTML = nd;
} else {
let nd2ch = { 'text-green-s': '简单', 'text-yellow': '中等', 'text-red-s': '困难' };
let clr = v.childNodes[headndidx].childNodes[0].getAttribute('class');
v.childNodes[headndidx].childNodes[0].innerHTML = nd2ch[clr];
}
}
}
/**
* 渲染 rating
* @param {HTMLElement} nd 要操作的节点
* @param {string | undefined} ndRate rating
* @param {Record
} lightn2c 亮模式难度列表
* @param {Record} darkn2c 暗模式难度列表
* @returns {boolean} 是否命中
*/
function renderRating(nd, ndRate, lightn2c, darkn2c) {
if (ndRate) {
nd.textContent = ndRate;
return true;
}
let clr = nd.classList;
if (clr.length === 0) return false;
for (const [className, text] of Object.entries({ ...lightn2c, ...darkn2c })) {
if (clr.contains(className)) {
nd.innerText = text;
return true;
}
}
return false;
}
/**
* 渲染 level
* @param {HTMLElement} nd 要操作的节点
* @param {string | undefined} level 评级
* @param {DOMTokenList} cls class 列表
* @param {boolean} hit 是否命中
* @param {number} padding 单位: px, 默认80
*/
function renderLevel(nd, level, cls, hit, padding = 80) {
if (level && GM_getValue('switchlevel')) {
let text = document.createElement('span');
text.classList.add(...cls);
text.innerHTML = '算术评级: ' + level;
text.style = nd.getAttribute('style');
text.style.paddingRight = `${hit ? padding - 5 : padding}px`; // 命中之后宽度不一样
nd.parentNode.insertBefore(text, nd);
}
}
/**
* 修正侧边栏高亮题目的样式
* @param {HTMLElement} listNode 侧边栏列表节点
* @param {string} cssSelector 子节点选择器
*/
function fixSiderbarProblemHighlight(listNode, cssSelector) {
// console.log("修正侧边栏高亮题目样式");
const pbList = listNode.querySelectorAll(cssSelector);
pbList.forEach(div => {
const levelSpan = div.querySelector(':scope > span');
const pbDiv = div.querySelector(':scope > div > div');
if (!levelSpan) return;
if (pbDiv.className !== levelSpan.className) {
// 如果className不一致,说明是高亮状态不一致
levelSpan.className = pbDiv.className;
}
});
}
// 确认之后不再刷新
let studyf;
let studyCnt = 0;
function getStudyData(css_selector) {
if (!GM_getValue('switchstudy')) return;
levelData = JSON.parse(GM_getValue('levelData', '{}').toString());
let totArr = null;
// 如果传入的是已经找到的node元素, 就不再搜索
if (css_selector instanceof Element) {
totArr = css_selector;
} else {
totArr = document.querySelector(css_selector);
}
if (totArr == null) return;
let first = totArr.firstChild?.childNodes[1]?.textContent;
if (studyf && first && studyf == first) {
// 到达次数之后删除定时防止卡顿
if (studyCnt == shortCnt) {
clearId('study');
}
studyCnt += 1;
return;
}
let childs = totArr.childNodes;
for (const arr of childs) {
for (let pbidx = 1; pbidx < arr.childNodes.length; pbidx++) {
let pb = arr.childNodes[pbidx];
let pbNameLabel = pb.querySelector('.truncate');
if (pbNameLabel == null) continue;
let pbName = pbNameLabel.textContent;
let nd = pb.childNodes[0].childNodes[1].childNodes[1];
let pbhtml = pb?.childNodes[0]?.childNodes[1]?.childNodes[0]?.childNodes[0];
pbName = pbName.trim();
// 保证 nd 存在
if (nd == null || nd.classList.length === 0) {
// console.log(nd)
continue;
}
let levelId = getLevelId(pbName);
let id = getPbNameId(pbName);
// console.log(pbName, level)
let darkn2c = {
'text-lc-green-60': '简单',
'text-lc-yellow-60': '中等',
'text-lc-red-60': '困难'
};
let lightn2c = {
'text-lc-green-60': '简单',
'text-lc-yellow-60': '中等',
'text-lc-red-60': '困难'
};
// render rating
let hit = renderRating(nd, t2rate?.[id]?.Rating, lightn2c, darkn2c);
// render level
renderLevel(nd, levelData[levelId]?.Level?.toString(), pbhtml.classList, hit, 130);
}
}
if (totArr.firstChild?.childNodes[1]) studyf = totArr.firstChild?.childNodes[1]?.textContent;
console.log('has refreshed...');
}
let pbsidef;
let pbsidee;
function getpbside(css_selector) {
let totArr = null;
// 如果传入的是已经找到的node元素, 就不再搜索
if (css_selector instanceof Element) {
totArr = css_selector;
} else {
totArr = document.querySelector(css_selector);
}
if (totArr == null) return;
if (totArr.firstChild == null) return;
let first = totArr.firstChild?.childNodes[0]?.textContent;
let last = totArr.lastChild?.childNodes[0]?.textContent;
if (first && pbsidef && pbsidef == first && last && pbsidee && pbsidee == last) {
if (pbsideCnt == normalCnt) clearId('pbside');
// TODO: 没想到什么好的办法来确切的监听源站前端对题目列表的更新,只能大概等一个延时
if (pbsideCnt === 1) {
// 在此处检查高亮状态是否改变,并修正
fixSiderbarProblemHighlight(totArr, ':scope > div > div[id] > div > :nth-child(2)');
}
pbsideCnt += 1;
return;
}
let childs = totArr.childNodes;
for (const arr of childs) {
// 特殊判定, 如果大于30则是每日一题列表
let pbidx = 1;
if (arr.childNodes.length >= 30) pbidx = 0;
for (; pbidx < arr.childNodes.length; pbidx++) {
let pb = arr.childNodes[pbidx];
let pbName = pb.childNodes[0].childNodes[1].childNodes[0].textContent;
let nd = pb.childNodes[0].childNodes[1].childNodes[1];
let pbhtml = pb?.childNodes[0]?.childNodes[1]?.childNodes[0]?.childNodes[0];
// 保证 nd 存在
if (nd == null || nd.classList.length === 0) {
// console.log(nd)
continue;
}
// console.log(pbName)
let data = pbName.split('.');
let id = data[0];
let darkn2c = {
'text-lc-green-60': '简单',
'text-lc-yellow-60': '中等',
'text-lc-red-60': '困难'
};
let lightn2c = {
'text-lc-green-60': '简单',
'text-lc-yellow-60': '中等',
'text-lc-red-60': '困难'
};
// render rating
let hit = renderRating(nd, t2rate?.[id]?.Rating, lightn2c, darkn2c);
// render level
renderLevel(nd, levelData[id]?.Level?.toString(), pbhtml.classList, hit);
}
}
if (totArr.firstChild?.childNodes[0]) pbsidef = totArr.firstChild.childNodes[0].textContent;
if (totArr.lastChild?.childNodes[0]) pbsidee = totArr.lastChild.childNodes[0].textContent;
// console.log(pbsidef, pbsidee)
console.log('已经刷新侧边栏envType分数...');
}
let pbsideCnt = 0;
function getpbsideData() {
// 左侧栏分数显示
let searchParams = location.search;
levelData = JSON.parse(GM_getValue('levelData', '{}').toString());
// ?envType=study-plan-v2&envId=leetcode-75
// 类似学习计划的展开栏
if (
searchParams.includes('envType') &&
!searchParams.includes('daily-question') &&
!searchParams.includes('problem-list')
) {
let overflow = document.querySelector('.overflow-auto.p-5');
if (overflow == null) return;
let studyplan = overflow.childNodes[0].childNodes[1];
if (!studyplan) studyf = null;
if (GM_getValue('switchstudy') && studyplan) {
getpbside(studyplan);
}
} else {
// 普通展开栏
let overflow = document.querySelector('.overflow-auto.p-4');
if (overflow == null) return;
let pbarr = overflow?.childNodes[0]?.childNodes[1];
if (pbarr == null) return;
if (pbarr.firstChild == null) return;
if (pbarr.lastChild == null) return;
if (pbsidef == pbarr.firstChild?.textContent && pbsidee == pbarr.lastChild?.textContent) {
if (pbsideCnt == normalCnt) clearId('pbside');
// TODO: 没想到什么好的办法来确切的监听源站前端对题目列表的更新,只能大概等一个延时
// 根据列表的大小不同,更新耗时可能不同,故直接对快慢两种情况运行两次修正
if (pbsideCnt === 4 || pbsideCnt === 1) {
// 在此处检查高亮状态是否改变,并修正
fixSiderbarProblemHighlight(pbarr, ':scope > .group > :first-child > :nth-child(2)');
}
pbsideCnt += 1;
return;
}
if (pbarr != null) {
for (const onepb of pbarr.childNodes) {
let tp = onepb.childNodes[0]?.childNodes[1];
if (!tp) {
// console.log(tp)
continue;
}
let pbName = tp.childNodes[0]?.textContent;
if (pbName == null) {
continue;
// pbName = tp.childNodes[0]?.textContent
// console.log(pbName)
}
let nd = tp.childNodes[1];
let pbhtml = tp.childNodes[0]?.childNodes[0];
// 保证 nd 存在
if (nd == null || nd.classList.length === 0) {
// console.log(nd)
continue;
}
// 如果为算术,说明当前已被替换过
if (nd.textContent.includes('算术')) continue;
// console.log(pbName)
let data = pbName.split('.');
let id = data[0];
let darkn2c = {
'text-sd-easy': '简单',
'text-sd-medium': '中等',
'text-sd-hard': '困难'
};
let lightn2c = {
'text-sd-easy': '简单',
'text-sd-medium': '中等',
'text-sd-hard': '困难'
};
// render rating
let hit = renderRating(nd, t2rate?.[id]?.Rating, lightn2c, darkn2c);
// render level
renderLevel(nd, levelData[id]?.Level?.toString(), pbhtml.classList, hit);
}
pbsidef = pbarr.firstChild.textContent;
pbsidee = pbarr.lastChild.textContent;
// console.log(pbsidef, pbsidee)
console.log('已经刷新侧边栏题库分数...');
}
}
}
function createSearchBtn() {
if (!GM_getValue('switchpbsearch')) return;
if (document.querySelector('#id-dropdown') == null) {
// 做个搜索框
let div = document.createElement('div');
div.setAttribute('class', 'layui-inline');
// 适配黑色主题
div.classList.add('leetcodeRating-search');
div.innerHTML += ``;
let center = document.querySelector('.flex.justify-between');
center = center?.childNodes[0]?.childNodes[0]?.childNodes[0];
if (center == null) return;
if (center.childNodes.length > 0) center.insertBefore(div, center.childNodes[1]);
else center.appendChild(div);
layui.use(function () {
let dropdown = layui.dropdown;
let $ = layui.$;
let inst = dropdown.render({
elem: '#id-dropdown',
data: [],
click: function (obj) {
this.elem.val(obj.title);
this.elem.attr('data-id', obj.id);
}
});
let elemInput = $(inst.config.elem);
let lastQueryTime = '';
let timer;
elemInput.on('input propertychange', function (event) {
clearTimeout(timer);
timer = setTimeout(function () {
let currentTime = Date.now();
if (currentTime - lastQueryTime >= 800) {
let elem = $(inst.config.elem);
let value = elem.val().trim();
elem.removeAttr('data-id');
let dataNew = findData(value);
dropdown.reloadData(inst.config.id, {
data: dataNew
});
lastQueryTime = currentTime;
}
}, 800);
});
$(inst.config.elem).on('blur', function () {
let elem = $(this);
let dataId = elem.attr('data-id');
if (!dataId) {
elem.val('');
}
});
function findData(value) {
return getsearch(value);
}
function getsearch(search) {
let queryT = `
query problemsetQuestions($in: ProblemsetQuestionsInput!) {
problemsetQuestions(in: $in) {
hasMore
questions {
titleCn
titleSlug
title
frontendId
acRate
solutionNum
difficulty
userQuestionStatus
}
}
}
`;
let list = {
query: queryT,
operationName: 'problemsetQuestions',
variables: { in: { query: search, limit: 10, offset: 0 } }
};
let resLst = [];
$.ajax({
type: 'POST',
url: lcnojgo,
data: JSON.stringify(list),
success: function (res) {
let data = res.data.problemsetQuestions.questions;
for (let idx = 0; idx < data.length; idx++) {
let resp = data[idx];
let item = {};
item.id = idx;
item.title = resp.frontendId + '.' + resp.titleCn;
item.href = 'https://leetcode.cn/problems/' + resp.titleSlug;
item.target = '_self';
resLst.push(item);
}
},
async: false,
xhrFields: { withCredentials: true },
contentType: 'application/json;charset=UTF-8'
});
return resLst;
}
});
}
}
// 因为字符显示问题,暂时去除
// 0%
let pbstatusContent = `
希望有大佬可以美化这丑丑的界面~ =v=
`;
let levelContent = `
1 无算法要求
2 知道常用数据结构和算法并简单使用
3 理解常用数据结构和算法
4 掌握常用数据结构和算法
5 熟练掌握常用数据结构和算法,初步了解高级数据结构
6 深入理解并灵活应用数据结构和算法,理解高级数据结构
7 结合多方面的数据结构和算法,处理较复杂问题
8 掌握不同的数据结构与算法之间的关联性,处理复杂问题,掌握高级数据结构
9 处理复杂问题,对时间复杂度的要求更严格
10 非常复杂的问题,非常高深的数据结构和算法(例如线段树、树状数组)
11 竞赛内容,知识点超出面试范围
`;
async function layuiload() {
// 使用layui的渲染
layui.use(function () {
let element = layui.element;
let util = layui.util;
let pbstatus = JSON.parse(GM_getValue('pbstatus', '{}').toString());
// 普通事件
util.on('lay-on', {
// loading
loading: function (othis) {
let DISABLED = 'layui-btn-disabled';
if (othis.hasClass(DISABLED)) return;
othis.addClass(DISABLED);
let cnt = Math.trunc((getpbCnt() + 99) / 100);
let headers = {
'Content-Type': 'application/json'
};
let skip = 0;
let timer = setInterval(
async function () {
ajaxReq('POST', lcgraphql, headers, allPbPostData(skip, 100), res => {
let questions = res.data.problemsetQuestionList.questions;
for (let pb of questions) {
pbstatus[pb.titleSlug] = {
titleSlug: pb.titleSlug,
id: pb.frontendQuestionId,
status: pb.status,
title: pb.title,
titleCn: pb.titleCn,
difficulty: pb.difficulty,
paidOnly: pb.paidOnly
};
}
});
skip += 100;
// skip / 100 是当前已经进行的次数
let showval = Math.trunc((skip / 100 / cnt) * 100);
if (skip / 100 >= cnt) {
showval = 100;
clearInterval(timer);
}
element.progress('demo-filter-progress', showval + '%');
if (showval == 100) {
pbstatus[pbstatusVersion] = {};
GM_setValue('pbstatus', JSON.stringify(pbstatus));
console.log('同步所有题目状态完成...');
await sleep(1000);
layer.msg('同步所有题目状态完成!');
await sleep(1000);
layer.closeAll();
}
},
300 + Math.random() * 1000
);
}
});
});
}
let t1; // pb
let pbCnt = 0;
let pbCnt2 = 0;
function getpb() {
let switchrealoj = GM_getValue('switchrealoj');
// 搜索功能
if (GM_getValue('switchpbsearch')) createSearchBtn();
// 题目页面
let curUrl = location.href;
// 只有描述页才进行加载
let isDescript =
!curUrl.match(regDiss) && !curUrl.match(regSovle) && !curUrl.match(regPbSubmission);
// 如果持续10次都不在描述页面, 则关闭pb定时
if (!isDescript) {
// 非des清除定时
if (pbCnt == shortCnt) clearId('pb');
pbCnt += 1;
return;
}
// 流动布局逻辑
if (isDynamic) {
// pb其他页面时刷新多次后也直接关闭
let t = document.querySelector('.text-title-large');
if (t == null) {
t1 = 'unknown';
pbCnt = 0;
if (pbCnt2 == shortCnt) clearId('pb');
pbCnt2 += 1;
return;
}
// console.log(t1, t.textContent)
if (t1 != null && t1 == t.textContent) {
// des清除定时
if (pbCnt == shortCnt) clearId('pb');
pbCnt += 1;
return;
}
let data = t.textContent.split('.');
let id = data[0].trim();
let colorA = ['.text-difficulty-hard', '.text-difficulty-easy', '.text-difficulty-medium'];
let colorSpan;
for (const color of colorA) {
colorSpan = document.querySelector(color);
if (colorSpan) break;
}
if (!colorSpan) {
if (switchrealoj) return;
console.log('color ele not found');
return;
}
// 统计难度分数并且修改
let nd = colorSpan.getAttribute('class');
let nd2ch = {
'text-difficulty-easy': '简单',
'text-difficulty-medium': '中等',
'text-difficulty-hard': '困难'
};
if (switchrealoj || (t2rate[id] != null && GM_getValue('switchpbscore'))) {
if (switchrealoj) colorSpan.remove();
else if (t2rate[id] != null) colorSpan.innerHTML = t2rate[id]['Rating'];
} else {
for (let item in nd2ch) {
if (nd.toString().includes(item)) {
colorSpan.innerHTML = nd2ch[item];
break;
}
}
}
// 逻辑,准备做周赛链接,如果已经不存在组件就执行操作
let url = chContestUrl;
let zhUrl = zhContestUrl;
let tips = colorSpan?.parentNode;
if (tips == null) return;
let tipsPa = tips?.parentNode;
// tips 一栏的父亲节点第一子元素的位置, 插入后变成竞赛信息位置
let tipsChildone = tipsPa.childNodes[1];
// 题目内容, 插入后变成原tips栏目
let pbDescription = tipsPa.childNodes[2];
if (pbDescription?.childNodes[0]?.getAttribute('data-track-load') != null) {
let divTips = document.createElement('div');
divTips.setAttribute('class', 'flex gap-1');
let abody = document.createElement('a');
abody.setAttribute('data-small-spacing', 'true');
abody.setAttribute('class', 'css-nabodd-Button e167268t1 hover:text-blue-s');
let abody2 = document.createElement('a');
abody2.setAttribute('data-small-spacing', 'true');
abody2.setAttribute('class', 'css-nabodd-Button e167268t1 hover:text-blue-s');
let abody3 = document.createElement('a');
abody3.setAttribute('data-small-spacing', 'true');
abody3.setAttribute('class', 'css-nabodd-Button e167268t1 hover:text-blue-s');
let abody4 = document.createElement('p');
abody4.setAttribute('data-small-spacing', 'true');
abody4.setAttribute('class', 'css-nabodd-Button e167268t1 hover:text-blue-s');
let span = document.createElement('span');
let span2 = document.createElement('span');
let span3 = document.createElement('span');
let span4 = document.createElement('span');
// 判断同步按钮
if (GM_getValue('switchpbstatusBtn')) {
// console.log(levelData[id])
span4.innerHTML = ` 同步题目状态`;
span4.onclick = function (e) {
layer.open({
type: 1,
content: `${pbstatusContent}`,
title: '同步所有题目状态',
area: ['550px', '250px'],
shade: 0.6
});
};
span4.setAttribute('style', 'cursor:pointer;');
// 使用layui的渲染
layuiload();
abody4.removeAttribute('hidden');
} else {
span4.innerText = '未知按钮';
abody4.setAttribute('hidden', 'true');
}
abody4.setAttribute('style', 'padding-left: 10px;');
levelData = JSON.parse(GM_getValue('levelData', '{}').toString());
if (levelData[id] != null) {
// console.log(levelData[id])
let des = '算术评级: ' + levelData[id]['Level'].toString();
span3.innerText = des;
span3.onclick = function (e) {
e.preventDefault();
layer.open({
type: 1, // Page 层类型
area: ['700px', '450px'],
title: '算术评级说明',
shade: 0.6, // 遮罩透明度
maxmin: true, // 允许全屏最小化
anim: 5, // 0-6的动画形式,-1不开启
content: `${levelContent}
`
});
};
abody3.removeAttribute('hidden');
} else {
span3.innerText = '未知评级';
abody3.setAttribute('hidden', 'true');
}
abody3.setAttribute('href', '/xxx');
abody3.setAttribute('style', 'padding-right: 10px;');
abody3.setAttribute('target', '_blank');
if (t2rate[id] != null) {
let contestUrl;
let num = getcontestNumber(t2rate[id]['ContestSlug']);
if (num < 83) {
contestUrl = zhUrl;
} else {
contestUrl = url;
}
span.innerText = t2rate[id]['ContestID_zh'];
span2.innerText = t2rate[id]['ProblemIndex'];
abody.setAttribute('href', contestUrl + t2rate[id]['ContestSlug']);
abody.setAttribute('target', '_blank');
abody.removeAttribute('hidden');
abody2.setAttribute(
'href',
contestUrl + t2rate[id]['ContestSlug'] + '/problems/' + t2rate[id]['TitleSlug']
);
abody2.setAttribute('target', '_blank');
if (switchrealoj) abody2.setAttribute('hidden', true);
else abody2.removeAttribute('hidden');
} else {
span.innerText = '对应周赛未知';
abody.setAttribute('href', '/xxx');
abody.setAttribute('target', '_self');
abody.setAttribute('hidden', 'true');
span2.innerText = '未知';
abody2.setAttribute('href', '/xxx');
abody2.setAttribute('target', '_self');
abody2.setAttribute('hidden', 'true');
}
abody.setAttribute('style', 'padding-right: 10px;');
// abody2.setAttribute("style", "padding-top: 1.5px;")
abody.appendChild(span);
abody2.appendChild(span2);
abody3.appendChild(span3);
abody4.appendChild(span4);
divTips.appendChild(abody3);
divTips.appendChild(abody);
divTips.appendChild(abody2);
divTips.appendChild(abody4);
tipsPa.insertBefore(divTips, tips);
} else if (
tipsChildone.childNodes != null &&
tipsChildone.childNodes.length >= 2 &&
(tipsChildone.childNodes[2].textContent.includes('Q') ||
tipsChildone.childNodes[2].textContent.includes('未知'))
) {
let pa = tipsChildone;
let le = pa.childNodes.length;
// 判断同步按钮
if (GM_getValue('switchpbstatusBtn')) {
// 使用layui的渲染, 前面已经添加渲染按钮,所以这里不用重新添加
pa.childNodes[le - 1].removeAttribute('hidden');
} else {
pa.childNodes[le - 1].childNodes[0].innerText = '未知按钮';
pa.childNodes[le - 1].setAttribute('hidden', 'true');
}
// 存在就直接替换
let levelData = JSON.parse(GM_getValue('levelData', '{}').toString());
if (levelData[id] != null) {
let des = '算术评级: ' + levelData[id]['Level'].toString();
pa.childNodes[le - 4].childNodes[0].innerText = des;
pa.childNodes[le - 4].childNodes[0].onclick = function (e) {
e.preventDefault();
layer.open({
type: 1, // Page 层类型
area: ['700px', '450px'],
title: '算术评级说明',
shade: 0.6, // 遮罩透明度
maxmin: true, // 允许全屏最小化
anim: 5, // 0-6的动画形式,-1不开启
content: `${levelContent}
`
});
};
pa.childNodes[le - 4].removeAttribute('hidden');
} else {
pa.childNodes[le - 4].childNodes[0].innerText = '未知评级';
pa.childNodes[le - 4].setAttribute('hidden', 'true');
pa.childNodes[le - 4].setAttribute('href', '/xxx');
}
// ContestID_zh ContestSlug
if (t2rate[id] != null) {
let contestUrl;
let num = getcontestNumber(t2rate[id]['ContestSlug']);
if (num < 83) {
contestUrl = zhUrl;
} else {
contestUrl = url;
}
pa.childNodes[le - 3].childNodes[0].innerText = t2rate[id]['ContestID_zh'];
pa.childNodes[le - 3].setAttribute('href', contestUrl + t2rate[id]['ContestSlug']);
pa.childNodes[le - 3].setAttribute('target', '_blank');
pa.childNodes[le - 3].removeAttribute('hidden');
pa.childNodes[le - 2].childNodes[0].innerText = t2rate[id]['ProblemIndex'];
pa.childNodes[le - 2].setAttribute(
'href',
contestUrl + t2rate[id]['ContestSlug'] + '/problems/' + t2rate[id]['TitleSlug']
);
pa.childNodes[le - 2].setAttribute('target', '_blank');
if (switchrealoj) pa.childNodes[le - 2].setAttribute('hidden', 'true');
else pa.childNodes[le - 2].removeAttribute('hidden');
} else {
pa.childNodes[le - 3].childNodes[0].innerText = '对应周赛未知';
// 不填写的话默认为当前url
pa.childNodes[le - 3].setAttribute('href', '/xxx');
pa.childNodes[le - 3].setAttribute('target', '_self');
pa.childNodes[le - 3].setAttribute('hidden', 'true');
pa.childNodes[le - 2].childNodes[0].innerText = '未知';
pa.childNodes[le - 2].setAttribute('href', '/xxx');
pa.childNodes[le - 2].setAttribute('target', '_self');
pa.childNodes[le - 2].setAttribute('hidden', 'true');
}
}
t1 = t.textContent;
}
}
function clearId(name) {
// 'all', 'tag', 'pb', 'company', 'pblist', 'search', 'study'
let tmp = GM_getValue(name, -1);
clearInterval(tmp);
console.log('clear ' + name + ' ' + id + ' success');
}
let shortCnt = 3;
let normalCnt = 5;
function initCnt() {
// 卡顿问题页面修复
// 搜索页面为自下拉,所以需要无限刷新,无法更改,这一点不会造成卡顿,所以剔除计划
// 题库页 ✅
lcCnt = 0;
pbSetCnt = 0;
// 题目页
pbCnt = 0; // ✅
pbCnt2 = 0; // ✅
// 题单页 ✅
pbsideCnt = 0;
pbListpbCnt = 0;
pbListCnt = 0; // ✅
studyCnt = 0; // ✅
}
// 初始化一些lc切换网页但是没有reload,需要执行的方法
function initfunction() {
// 添加题目页面复制按钮
console.log('当前页面url: ' + location.href);
if (GM_getValue('switchcopyright') && location.href.match(pbUrl)) {
console.log('当前处于题目页,已开始添加复制按钮....');
copyNoRight();
}
// 创建题目状态icon,题目页和讨论区刷新
waitOprpbStatus();
if (GM_getValue('switchpbstatus') && location.href.match(pbUrl)) {
console.log('当前处于题目页,已开启题目提交监听....');
pbsubmitListen();
}
}
function clearAndStart(url, timeout, isAddEvent) {
initCnt();
initfunction();
let start = '';
let targetIdx = -1;
let pageLst = ['all', 'pb', 'pblist', 'search', 'study'];
let urlLst = [allUrl, pbUrl, pblistUrl, searchUrl, studyUrl];
let funcLst = [getData, getpb, getPblistData, getSearch, getStudyData];
for (let index = 0; index < urlLst.length; index++) {
const element = urlLst[index];
if (url.match(element)) {
targetIdx = index;
} else if (!url.match(element)) {
// 清理其他的
let tmp = GM_getValue(pageLst[index], -1);
clearInterval(tmp);
}
}
if (targetIdx != -1) start = pageLst[targetIdx];
if (start != '') {
// 清理重复运行
let preId = GM_getValue(start);
if (preId != null) {
clearInterval(preId);
}
let css_selector = 'div.relative.flex.w-full.flex-col > .flex.w-full.flex-col.gap-4';
if (start == 'study') {
id = setInterval(getStudyData, timeout, css_selector);
} else if (start == 'pb') {
id = setInterval(getpb, timeout);
if (GM_getValue('switchpbside')) {
let pbsideId = setInterval(getpbsideData, timeout);
GM_setValue('pbside', pbsideId);
}
} else {
id = setInterval(funcLst[targetIdx], timeout);
}
GM_setValue(start, id);
}
if (isAddEvent) {
// 只需要定位urlchange变更
window.addEventListener('urlchange', () => {
console.log('urlchange/event/happened');
let newUrl = location.href;
clearAndStart(newUrl, 1000, false);
});
}
}
// 获取界面所需数据, 需要在菜单页面刷新前进行更新
function getNeedData() {
// 更新分数数据
async function getScore() {
let now = getCurrentDate(1);
preDate = GM_getValue('preDate', '');
if (t2rate['tagVersion9'] == null || preDate == '' || preDate != now) {
// 每天重置为空
GM_setValue('pbSubmissionInfo', '{}');
let res = await new Promise((resolve, reject) => {
GM_xmlhttpRequest({
method: 'get',
url: rakingUrl + '?timeStamp=' + new Date().getTime(),
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
onload: function (res) {
resolve(res);
},
onerror: function (err) {
console.log('error');
console.log(err);
}
});
});
if (res.status === 200) {
// 保留唯一标识
t2rate = {};
pbName2Id = {};
pbNamee2Id = {};
let dataStr = res.response;
let json = eval(dataStr);
for (const element of json) {
t2rate[element.ID] = element;
t2rate[element.ID]['Rating'] = Number.parseInt(
Number.parseFloat(element['Rating']) + 0.5
);
pbName2Id[element.TitleZH] = element.ID;
pbNamee2Id[element.Title] = element.ID;
}
t2rate['tagVersion9'] = {};
console.log('everyday getdata once...');
preDate = now;
GM_setValue('preDate', preDate);
GM_setValue('t2ratedb', JSON.stringify(t2rate));
GM_setValue('pbName2Id', JSON.stringify(pbName2Id));
GM_setValue('pbNamee2Id', JSON.stringify(pbNamee2Id));
}
}
}
getScore();
// 更新level数据
async function getPromiseLevel() {
let week = new Date().getDay();
if (levelData['tagVersion24'] == null || week == 1) {
let res = await new Promise((resolve, reject) => {
GM_xmlhttpRequest({
method: 'get',
url: levelUrl + '?timeStamp=' + new Date().getTime(),
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
onload: function (res) {
resolve(res);
},
onerror: function (err) {
console.log('error');
console.log(err);
}
});
});
if (res.status === 200) {
levelData = {};
levelTc2Id = {};
levelTe2Id = {};
let dataStr = res.response;
let json = eval(dataStr);
for (const element of json) {
if (typeof element.TitleCn == 'string') {
let titlec = element.TitleCn;
let title = element.Title;
levelData[element.ID] = element;
levelTc2Id[titlec] = element.ID;
levelTe2Id[title] = element.ID;
}
}
levelData['tagVersion24'] = {};
console.log('every Monday get level once...');
GM_setValue('levelData', JSON.stringify(levelData));
GM_setValue('levelTc2Id', JSON.stringify(levelTc2Id));
GM_setValue('levelTe2Id', JSON.stringify(levelTe2Id));
}
}
}
getPromiseLevel();
// 版本更新机制
let now = getCurrentDate(1);
preDate1 = GM_getValue('preDate1', '');
let checkVersionLayer = GM_getValue('switchupdate')
? preDate1 == '' || preDate1 != now
: true;
GM_xmlhttpRequest({
method: 'get',
url: versionUrl + '?timeStamp=' + new Date().getTime(),
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
onload: function (res) {
if (res.status === 200) {
console.log('check version success...');
let dataStr = res.response;
let json = JSON.parse(dataStr);
let v = json['version'];
let upcontent = json['content'];
// 更新纸片人地址
papermanpic = json['papermanpic'];
// 通过更新 CSS 变量来更新纸片人
document.documentElement.style.setProperty('--mumu-img', `url(${papermanpic})`);
console.log(papermanpic);
if (v != version) {
if (checkVersionLayer) {
console.log('弹窗更新栏一次..');
layer.open({
area: ['500px', '300px'],
content:
'更新通知:
leetcodeRating有新的版本' +
v +
'啦,请前往更新~
' +
'更新内容:
' +
upcontent +
'
',
yes: function (index, layer0) {
let c = window.open(sciptUrl + '?timeStamp=' + new Date().getTime());
// c.close()
layer.close(index);
preDate1 = now;
GM_setValue('preDate1', preDate1);
console.log('update preDate1 success');
}
});
} else {
console.log('有新的版本,但是已经弹窗过且开启了最多只更新一次功能,等待明天弹窗..');
}
} else {
console.log('leetcodeRating难度分插件当前已经是最新版本~');
}
}
},
onerror: function (err) {
console.log('error');
console.log(err);
}
});
}
// 获取必须获取的数据
getNeedData();
// 如果pbstatus数据开关已打开且需要更新
if (GM_getValue('switchpbstatus')) {
(function () {
let pbstatus = JSON.parse(GM_getValue('pbstatus', '{}').toString());
if (pbstatus[pbstatusVersion]) {
console.log('已经同步过初始题目状态数据...');
return;
}
let syncLayer = layer.confirm(
'检测本地没有题目数据状态,即将开始初始化进行所有题目状态,是否开始同步?
tips:(该检测和开启讨论区展示题目状态功能有关)
',
{ icon: 3 },
function () {
layer.close(syncLayer);
layer.open({
type: 1,
content: `${pbstatusContent}`,
title: '同步所有题目状态',
area: ['550px', '250px'],
shade: 0.6
});
layuiload();
},
function () {
// do nothong
}
);
})();
}
// 定时启动函数程序
clearAndStart(location.href, 1000, true);
GM_addStyle(`
.versioncontent {
white-space: pre-wrap;
word-wrap: break-word;
display: block;
}
`);
// TODO 分割
// spig js 纸片人相关
if (GM_getValue('switchperson')) {
const isindex = true;
const visitor = '主人';
let msgs = [];
// 求等级用的数据
let userTag = null;
let level = 0;
let score = 0;
const queryProcess =
'\n query userQuestionProgress($userSlug: String!) {\n userProfileUserQuestionProgress(userSlug: $userSlug) {\n numAcceptedQuestions {\n difficulty\n count\n }\n numFailedQuestions {\n difficulty\n count\n }\n numUntouchedQuestions {\n difficulty\n count\n }\n }\n}\n ';
const queryUser =
'\n query globalData {\n userStatus {\n isSignedIn\n isPremium\n username\n realName\n avatar\n userSlug\n isAdmin\n checkedInToday\n useTranslation\n premiumExpiredAt\n isTranslator\n isSuperuser\n isPhoneVerified\n isVerified\n }\n jobsMyCompany {\n nameSlug\n }\n commonNojPermissionTypes\n}\n ';
GM_addStyle(`
:root {
--mumu-img: url(${papermanpic});
}
.spig {
display:block;
width:154px;
height:190px;
position:absolute;
top: -150px;
left: 160px;
z-index:9999;
}
#message {
line-height:170%;
color :#191919;
border: 1px solid #c4c4c4;
background:#ddd;
-moz-border-radius:5px;
-webkit-border-radius:5px;
border-radius:5px;
min-height:1em;
padding:5px;
top:-30px;
position:absolute;
text-align:center;
width:auto !important;
z-index:10000;
-moz-box-shadow:0 0 15px #eeeeee;
-webkit-box-shadow:0 0 15px #eeeeee;
border-color:#eeeeee;
box-shadow:0 0 15px #eeeeee;
outline:none;
opacity: 0.75 !important;
}
.mumu {
width:154px;
height:190px;
cursor: move;
background:var(--mumu-img) no-repeat;
}
#level {
text-align:center;
z-index:9999;
color :#191919;
}
`);
const spig = ``;
const hitokoto = `Loading...`;
$('body').append(spig, hitokoto);
// 消息函数
let showMessage = (a, b) => {
if (b == null) b = 10000;
$('#mumu').css({ opacity: '0.5 !important' });
$('#message').hide().stop();
$('#message').html(a);
$('#message').fadeIn();
$('#message').fadeTo('1', 1);
$('#message').fadeOut(b);
$('#mumu').css({ opacity: '1 !important' });
};
// 右键菜单
jQuery(document).ready(function ($) {
$('#spig').mousedown(function (e) {
if (e.which == 3) {
showMessage(`秘密通道:
题库`, 10000);
}
});
$('#spig').bind('contextmenu', function (e) {
return false;
});
});
function getscore(userTag) {
let list = { query: queryProcess, variables: { userSlug: userTag } };
$.ajax({
type: 'POST',
url: lcgraphql,
data: JSON.stringify(list),
success: function (res) {
let levelData = res.data.userProfileUserQuestionProgress.numAcceptedQuestions;
levelData.forEach(e => {
if (e.difficulty == 'EASY') score += e.count * 10;
else if (e.difficulty == 'MEDIUM') score += e.count * 20;
else if (e.difficulty == 'HARD') score += e.count * 100;
});
level = score / 1000;
$('#level').text('level: ' + Math.trunc(level).toString());
console.log('目前纸片人的等级是: ' + Math.trunc(level).toString());
},
async: false,
xhrFields: { withCredentials: true },
contentType: 'application/json;charset=UTF-8'
});
}
$.ajax({
type: 'POST',
url: lcgraphql,
data: JSON.stringify({ query: queryUser, variables: {} }),
success: function (res) {
userTag = res.data.userStatus.userSlug;
// console.log(userTag)
},
async: false,
xhrFields: { withCredentials: true },
contentType: 'application/json;charset=UTF-8'
});
if (userTag != null) {
getscore(userTag);
} else {
// console.log(userTag)
$('#level').text('请登录后再尝试获取level');
}
// 监听分数提交
let addListener2 = () => {
let checkUrl = 'https://leetcode.cn/submissions/detail/[0-9]*/check/.*';
XMLHttpRequest.prototype.send = function (str) {
const _onreadystatechange = this.onreadystatechange;
this.onreadystatechange = (...args) => {
if (this.readyState == this.DONE && this.responseURL.match(checkUrl)) {
let resp = JSON.parse(this.response);
// console.log(resp)
if (resp && resp.status_msg && resp.status_msg.includes('Accepted')) {
showMessage(
'恭喜主人成功提交, 当前分数为: ' +
score +
', 当前等级为: ' +
Math.trunc(level).toString()
);
console.log(
'恭喜主人成功提交, 当前分数为: ' +
score +
', 当前等级为: ' +
Math.trunc(level).toString()
);
} else if (resp && resp.status_msg && !resp.status_msg.includes('Accepted')) {
showMessage(
'很遗憾,主人提交失败,不过也不要气馁呀,加油!
当前分数为: ' +
score +
', 当前等级为: ' +
Math.trunc(level).toString()
);
console.log(
'很遗憾,主人提交失败,不过也不要气馁呀,加油! 当前分数为: ' +
score +
', 当前等级为: ' +
Math.trunc(level).toString()
);
}
}
if (_onreadystatechange) {
_onreadystatechange.apply(this, args);
}
};
return dummySend.call(this, str);
};
};
addListener2();
// 鼠标在消息上时
jQuery(document).ready(function ($) {
$('#message').hover(function () {
$('#message').fadeTo('100', 1);
});
});
// 鼠标在上方时
jQuery(document).ready(function ($) {
$('.mumu').mouseover(function () {
$('.mumu').fadeTo('300', 0.3);
msgs = [
'我隐身了,你看不到我',
'我会隐身哦!嘿嘿!',
'别动手动脚的,把手拿开!',
'把手拿开我才出来!'
];
let i = Math.floor(Math.random() * msgs.length);
showMessage(msgs[i]);
});
$('.mumu').mouseout(function () {
$('.mumu').fadeTo('300', 1);
});
});
function msgPageWelcome(url, isAddEvent) {
let urlLst = [allUrl, pbUrl, pblistUrl, searchUrl];
let msgShow = [
'欢迎来到题库页, 美好的一天从做每日一题开始~',
'欢迎来到做题页面,让我看看是谁光看不做?🐰',
'欢迎来到题单页面~',
'欢迎来到搜索页,在这里你能搜到一切你想做的题!'
];
for (let index = 0; index < urlLst.length; index++) {
const element = urlLst[index];
if (url.match(element)) {
// console.log(msgShow[index])
showMessage(msgShow[index]);
}
}
if (isAddEvent) {
window.addEventListener('urlchange', () => {
let newUrl = location.href;
msgPageWelcome(newUrl, false);
});
}
}
// 开始
jQuery(document).ready(function ($) {
if (isindex) {
// 如果是主页
let now = new Date().getHours();
if (now > 0 && now <= 6) {
showMessage(visitor + ' 你是夜猫子呀?还不睡觉,明天起的来么你?', 6000);
} else if (now > 6 && now <= 11) {
showMessage(
visitor + ' 早上好,早起的鸟儿有虫吃噢!早起的虫儿被鸟吃,你是鸟儿还是虫儿?嘻嘻!',
6000
);
} else if (now > 11 && now <= 14) {
showMessage(visitor + ' 中午了,吃饭了么?不要饿着了,饿死了谁来挺我呀!', 6000);
} else if (now > 14 && now <= 18) {
showMessage(visitor + ' 中午的时光真难熬!还好有你在!', 6000);
} else {
showMessage(visitor + ' 快来逗我玩吧!', 6000);
}
msgPageWelcome(location.href, true);
} else {
showMessage('力扣欢迎你~', 6000);
}
let top = $('#spig').offset().top + 150;
let left = document.body.offsetWidth - 160;
if (location.href.match(pbUrl)) {
top = $('#spig').offset().top + 200;
}
$('#spig').attr('hidden', false);
$('#spig').css({ top: top, left: left });
});
// 随滚动条移动
jQuery(document).ready(function ($) {
let f = $('.spig').offset().top;
$(window).scroll(function () {
$('.spig').animate(
{
top: $(window).scrollTop() + f + 150
},
{
queue: false,
duration: 1000
}
);
});
});
// 鼠标点击时
jQuery(document).ready(function ($) {
let stat_click = 0;
let i = 0;
$('.mumu').click(function () {
if (!ismove) {
stat_click++;
if (stat_click > 4) {
msgs = [
'你有完没完呀?',
'你已经摸我' + stat_click + '次了',
'非礼呀!救命!OH,My ladygaga'
];
i = Math.floor(Math.random() * msgs.length);
showMessage(msgs[i]);
} else {
msgs = [
'筋斗云!~我飞!',
'我跑呀跑呀跑!~~',
'别摸我,有什么好摸的!',
'惹不起你,我还躲不起你么?',
'不要摸我了,我会告诉你老婆来打你的!',
'干嘛动我呀!小心我咬你!'
];
i = Math.floor(Math.random() * msgs.length);
showMessage(msgs[i]);
}
let s = [
0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.75, -0.1, -0.2, -0.3, -0.4, -0.5, -0.6, -0.7,
-0.75
];
let i1 = Math.floor(Math.random() * s.length);
let i2 = Math.floor(Math.random() * s.length);
$('.spig').animate(
{
left: (document.body.offsetWidth / 2) * (1 + s[i1]),
top: (document.body.offsetHeight / 2) * (1 + s[i2])
},
{
duration: 500,
complete: showMessage(msgs[i])
}
);
} else {
ismove = false;
}
});
});
// 拖动
let _move = false;
let ismove = false; // 移动标记
let _x, _y; // 鼠标离控件左上角的相对位置
jQuery(document).ready(function ($) {
$('#spig').mousedown(function (e) {
_move = true;
_x = e.pageX - parseInt($('#spig').css('left'));
_y = e.pageY - parseInt($('#spig').css('top'));
});
$(document)
.mousemove(function (e) {
if (_move) {
let x = e.pageX - _x;
let y = e.pageY - _y;
let wx = $(window).width() - $('#spig').width();
let dy = $(document).height() - $('#spig').height();
if (x >= 0 && x <= wx && y > 0 && y <= dy) {
$('#spig').css({
top: y,
left: x
}); //控件新位置
ismove = true;
}
}
})
.mouseup(function () {
_move = false;
});
});
// 纸片人一言api
// $("#spig").attr("hidden", false)
let hitokotohtml = function () {
let msgShow = [$('#hitokoto').text()];
showMessage(msgShow[0]);
setTimeout(hitokotohtml, 15000);
};
setTimeout(hitokotohtml, 6000);
function getkoto() {
$.get('https://v1.hitokoto.cn/?c=j&encode=json')
.then(res => {
echokoto(res);
})
.catch(xhr => xhr);
setTimeout(getkoto, 6000);
}
function echokoto(result) {
let hc = eval(result);
document.getElementById('hitokoto').textContent = hc.hitokoto;
// console.log(hc.content)
}
setTimeout(getkoto, 5000);
}
}
userScript();
})();