// ==UserScript==
// @name 简书搜索强化
// @name:zh 简书搜索强化
// @name:en jianshu-search-pro
// @namespace https://github.com/WumaCoder/mini-tools.git
// @homepageURL https://github.com/WumaCoder/mini-tools.git
// @version 1.0.1
// @description 对简书的搜索功能进行增强,增强搜索收藏的文章,增强搜索喜欢的文章。
// @description:en Enhance the search function of the short book, enhance the search of favorite articles, enhance the search of favorite articles.
// @author WumaCoder
// @match *://www.jianshu.com/*
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_registerMenuCommand
// @grant GM_unregisterMenuCommand
// @grant GM_openInTab
// @license GPL-3.0-only
// ==/UserScript==
(function () {
/*!
* @name menuCommand.js
* @version 0.0.1
* @author Blaze
* @date 2019/9/21 14:22
* 来自 HTML5视频播放器增强脚本
*/
const monkeyMenu = {
on (title, fn, accessKey) {
return window.GM_registerMenuCommand && window.GM_registerMenuCommand(title, fn, accessKey)
},
off (id) {
return window.GM_unregisterMenuCommand && window.GM_unregisterMenuCommand(id)
},
/* 切换类型的菜单功能 */
switch (title, fn, defVal) {
const t = this;
t.on(title, fn);
}
};
/**
* 将字符串转化为doument
*/
function toDocument (str = "") {
str = str.replace(/\r\n\f/igm, '');
const dom = document.createElement('DOM');
dom.innerHTML = str;
return dom;
}
/**
* 初始化自定义样式
*/
function initStyle () {
const style = document.createElement("style");
style.innerText = `
.tip-li-icon{
float: left;
margin-right: 10px;
font-size: 18px;
color: #ea6f5a;
}
nav form .search-input:focus+.search-btn{
background-color:#ea6f5a;
}
`;
document.body.appendChild(style);
}
/**
* 初始化事件
*/
function initEvent () {
const q = document.getElementById('q');
const call = debounce(() => {
const store = window._store;
const reg = new RegExp(`[${q.value.split('').join(']+.*[')}]+`, 'igm');
createSearchTipView(
store.likedList.filter(item => item.title.match(reg)),
store.bookmarksList.filter(item => item.title.match(reg))
);
}, 500);
q.addEventListener('input', call);
}
/**
* 初始化菜单
*/
function initMenu () {
monkeyMenu.on('清空缓存', function () {
restore();
alert("请刷新网页");
});
monkeyMenu.on('更新脚本', function () {
window.GM_openInTab('https://greasyfork.org/zh-CN/scripts/400102-%E7%AE%80%E4%B9%A6%E6%90%9C%E7%B4%A2%E5%BC%BA%E5%8C%96', {
active: true,
insert: true,
setParent: true
});
});
monkeyMenu.on('关于', function () {
window.GM_openInTab('https://github.com/WumaCoder/mini-tools', {
active: true,
insert: true,
setParent: true
});
});
monkeyMenu.on('反馈', function () {
window.GM_openInTab('https://github.com/WumaCoder/mini-tools/issues', {
active: true,
insert: true,
setParent: true
});
});
}
/**
* 初始化数据
*/
function initData () {
window._store = { userInfo: null, likedList: [], likedInfo: null, bookmarksList: [], bookmarksInfo: null };
window._store.likedList = GM_getValue('likedList', []);
window._store.bookmarksList = GM_getValue('bookmarksList', []);
}
/**
* 节流函数
* @param {Function} func 回调
* @param {Number} wait 时间
*/
function throttle (func, wait) {
let previous = 0;
return function () {
let now = Date.now();
let context = this;
let args = arguments;
if (now - previous > wait) {
func.apply(context, args);
previous = now;
}
}
}
// 防抖
function debounce (fn, wait) {
let timeout = null;
return function () {
if (timeout !== null) clearTimeout(timeout);
timeout = setTimeout(fn, wait);
}
}
async function getLikedInfo () {
const url = `https://www.jianshu.com/users/${window._store.userInfo.current_user.slug}/liked_notes`;
const res = await $.get(url);
const dom = toDocument(res);
const aTag = dom.querySelector("li.active > a");
const count = aTag.innerText.replace('喜欢的文章 ', '') * 1;
window._store.likedInfo = {
count,
url
};
}
async function getUserInfo () {
const res = await $.get('https://www.jianshu.com/settings/basic');
const dom = toDocument(res);
const infoEl = dom.querySelector("script[data-name=page-data]");
window._store.userInfo = JSON.parse(infoEl.text);
}
async function getBookmarksInfo () {
const res = await $.get('https://www.jianshu.com/bookmarks');
const dom = toDocument(res);
const infoEl = dom.querySelector("script[data-name=bookmark_page_data]");
window._store.bookmarksInfo = JSON.parse(infoEl.text);
const pageInfo = window._store.bookmarksInfo;
const res1 = await $.get('https://www.jianshu.com/bookmarks', { page: pageInfo.totalPages });
const dom1 = toDocument(res1);
const aList = dom1.querySelectorAll("ul.note-list > li > div > a");
pageInfo.count = aList.length + (pageInfo.totalPages - 1) * 20;
}
/**
* 获取收藏的文章列表
* @param {number } page 页码
* @returns 是否有重复项目
*/
async function getBookmarksList (page) {
const res = await $.get(`https://www.jianshu.com/bookmarks`, { page });
const dom = toDocument(res);
const aList = dom.querySelectorAll("ul.note-list > li > div > a");
let flag = 0;
for (let i = 0; i < aList.length; i++) {
const element = aList[i];
const temp = { href: element.href, title: element.innerText };
if (window._store.bookmarksList.filter(item => temp.href == item.href).length >= 1) {
flag = 1;
break;
}
window._store.bookmarksList.push(temp);
}
GM_setValue('bookmarksList', window._store.bookmarksList);
return flag;
}
/**
* 获取喜欢的文章列表
* @param {number } page 页码
* @returns 是否有重复项目
*/
async function getLikedList (page) {
const res = await $.get(`https://www.jianshu.com/users/${window._store.userInfo.current_user.slug}/liked_notes?page=${page}`);
const dom = toDocument(res);
const aList = dom.querySelectorAll("ul.note-list > li > div > a");
let flag = 0;
for (let i = 0; i < aList.length; i++) {
const element = aList[i];
const temp = { href: element.href, title: element.innerText };
if (window._store.likedList.filter(item => temp.href == item.href).length >= 1) {
flag = 1;
break;
}
window._store.likedList.push(temp);
}
GM_setValue('likedList', window._store.likedList);
return flag;
}
/**
* 恢复
*/
function restore () {
GM_setValue('likedList', [])
}
function createLine () {
const line = document.createElement('LI');
line.style.borderBottom = "1px solid #f0f0f0";
return line.cloneNode(true);
}
function createLi (url, title, type) {
const li = document.createElement('LI');
li.innerHTML = `<a href="${url}" target="_blank">
<i class="iconfont ${type} tip-li-icon"></i>
<span>${title}</span>
</a>`;
return li.cloneNode(true)
}
function clearChildNode (el) {
for (let i = el.childNodes.length - 1; i >= 0; i--) {
const element = el.childNodes[i];
el.removeChild(element);
}
}
function cloneChildNode (el, el2) {
for (let i = 0; i < el.childNodes.length; i++) {
const element = el.childNodes[i];
el2.appendChild(element.cloneNode(true));
}
}
function createSearchTipView (likedList, bookmarksList) {
const tipElement = document.querySelector(".search-recent-item-wrap");
clearChildNode(tipElement);
if (likedList) {
likedList.length = likedList.length > 10 ? 10 : likedList.length;
likedList.forEach(item => {
tipElement.appendChild(createLi(item.href, item.title, 'ic-like'));
});
if (likedList.length === 0) {
tipElement.appendChild(createLi('#', '暂无匹配的喜欢文章', 'ic-like'));
}
}
if (bookmarksList) {
bookmarksList.length = bookmarksList.length > 10 ? 10 : bookmarksList.length;
tipElement.appendChild(createLine());
bookmarksList.forEach(item => {
tipElement.appendChild(createLi(item.href, item.title, 'ic-mark'));
});
if (bookmarksList.length === 0) {
tipElement.appendChild(createLi('#', '暂无匹配的收藏文章', 'ic-mark'));
}
}
}
/**
* 入口
*/
async function main () {
// restore();
initMenu();
initEvent();
initStyle();
initData();
await getUserInfo();
console.log('***********初始化简书搜索强化*************');
await getLikedInfo();
for (let i = 1; i <= Math.ceil(window._store.likedInfo.count / 9); i++) {
if (await getLikedList(i)) break;
console.log(`加载喜欢的文章中...(${window._store.likedInfo.count}/${window._store.likedList.length})`);
}
await getBookmarksInfo();
for (let i = 1; i <= Math.ceil(window._store.bookmarksInfo.count / 20); i++) {
if (await getBookmarksList(i)) break;
console.log(`加载收藏的文章中...(${window._store.bookmarksInfo.count}/${window._store.bookmarksList.length})`);
}
console.log('***********加载成功*************');
console.log('***********简书搜索强化1.0.1*************');
console.log('***********欢迎来Star~~*************');
}
main();
//---------------------
// Your code here...
})();