// ==UserScript==
// @name 我的搜索
// @namespace http://tampermonkey.net/
// @version 3.1.0
// @description 订阅式搜索,打造属于自己的搜索引擎!
// @license MIT
// @author zhuangjie
// @match *://*/*
// @exclude http://127.0.0.1*
// @exclude http://localhost*
// @exclude http://192.168.*
// @icon data:image/png;base64,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
// @require https://cdn.bootcdn.net/ajax/libs/jquery/3.6.2/jquery.min.js
// @grant window.onurlchange
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_deleteValue
// @grant GM_registerMenuCommand
// ==/UserScript==
(function() {
'use strict';
// 模块一:快捷键触发某一事件 (属于触发策略组)
// 模块二:搜索视图(显示与隐藏)(属于搜索视图组)
// 模块三:触发策略组触发策略触发搜索视图组视图
// 模块四:根据用户提供的策略(策略属于数据生成策略组)生成搜索项的数据库
// 模块五:视图接入数据库
// 【函数库】
// 加载样式
function loadStyleString(css) {
var style = document.createElement("style");
style.type = "text/css";
try {
style.appendChild(document.createTextNode(css));
} catch(ex) {
style.styleSheet.cssText = css;
}
var head = document.getElementsByTagName('head')[0];
head.appendChild(style);
}
// 数据缓存器
let cache = {
get(key) {
return GM_getValue(key);
},
set(key,value) {
GM_setValue(key,value);
},
remove(key) {
GM_deleteValue(key);
},
cookieSet(cname,cvalue,exdays) {
var d = new Date();
d.setTime(d.getTime()+exdays);
var expires = "expires="+d.toGMTString();
document.cookie = cname + "=" + cvalue + "; " + expires;
},
cookieGet(cname) {
var name = cname + "=";
var ca = document.cookie.split(';');
for(var i=0; i<ca.length; i++)
{
var c = ca[i].trim();
if (c.indexOf(name)==0) return c.substring(name.length,c.length);
}
return "";
}
}
// 加载全局样式
loadStyleString(`
.searchItem {
background-image: url(data:image/jpeg;base64,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);
background-size: 100% 100%;
background-clip: content-box;
background-origin: content-box;
}
`)
//防抖函数模板
function debounce(fun, wait) {
let timer = null;
return function (...args) {
// 清除原来的定时器
if (timer) clearTimeout(timer)
// 开启一个新的定时器
timer = setTimeout(() => {
fun.apply(this, args)
}, wait)
}
}
// 判断是否为指定指令
function isInstructions(val,cmd) {
return val == ":"+cmd;
}
// 全局注册表
let ERROR = {
tell(info) {
console.error("ERROR " + info)
}
}
//registry.searchData.SEARCH_DATA_KEY
let registry = {
view: {
viewVisibilityController: () => { ERROR.tell("视图未初始化,但你使用了它的未初始化的注册表信息!") },
viewDocument: null,
setButtonVisibility: () => { ERROR.tell("按钮未初始化!") },
},
searchData: { //registry.searchData.getDataLength
data: [],
subscribeKey: "subscribeKey",
// 事件函数
dataChange: [],
// 持久化Key
SEARCH_DATA_KEY: "SEARCH_DATA_KEY",
// 搜索搜索出来的数据
searchData: [],
pos: 0,
getFaviconAPI: "https://ico.di8du.com/get.php?url=",
getDataLength(target = "SELECT") {
// 持久化的数据项数
let cacheData = cache.get(this.SEARCH_DATA_KEY) == null?[]:cache.get(this.SEARCH_DATA_KEY).data;
let tmpData = this.data.length === 0?cacheData:this.data;
let dataLength = (tmpData == null)?0:tmpData.length;
let inputDesc = `我的搜索( 👌 数据库记录数 ${dataLength}条)`;
if(target == "UPDATE") {
setTimeout(()=>{
$("#search_input").attr("placeholder",this.getDataLength());
},2000)
return `我的搜索( 🔁 数据库更新到 ${dataLength}条)`;
}
return inputDesc;
}
}
}
let dao = {}
function showControlButton() {
// 会显示一个按钮
// 初始化按钮
let viewDocument = registry.view.viewDocument;
if(viewDocument == null) return;
// 视图已初始化,可以显示按钮
}
function hideControlButton() {
// 隐藏掉输入框右边按钮
}
// 实现模块一:使用快捷键触发指定事件
function triggerAndEvent(goKeys = "ctrl+alt+s", fun, isKeyCode = false) {
// 监听键盘按下事件
let handle = function (event) {
let isCtrl = goKeys.indexOf("ctrl") >= 0;
let isAlt = goKeys.indexOf("alt") >= 0;
let lastKey = goKeys.replaceAll("alt", "").replaceAll("ctrl", "").replace(/\++/gm,"").trim();
// 判断 Ctrl+S
if (event.ctrlKey != isCtrl || event.altKey != isAlt) return;
if (!isKeyCode) {
// 查看 lastKey == 按下的key
if (lastKey.toUpperCase() == event.key.toUpperCase()) fun();
} else {
// 查看 lastKey == event.keyCode
if (lastKey == event.keyCode) fun();
}
}
// 如果使用 document.onkeydown 这种,只能有一个监听者
$(document).keyup(handle);
}
// 解决有些网站不加载图片
// 插入 meta 标签
/* var oMeta = document.createElement('meta');
oMeta.content = "default-src 'self' data: * 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src * ;img-src *";
oMeta['http-equiv'] = "Content-Security-Policy";
document.getElementsByTagName('head')[0].appendChild(oMeta);
*/
// 【数据初始化】
// 获取存在的订阅信息
function getSubscribe() {
// 查看是否有订阅信息
let subscribeKey = registry.searchData.subscribeKey;
let subscribeInfo = cache.get(subscribeKey);
if(subscribeInfo == null ) {
// 初始化订阅信息(初次)
subscribeInfo = `
<tis::https://raw.githubusercontent.com/18476305640/xiaozhuang/dev/%E6%88%91%E7%9A%84%E6%90%9C%E7%B4%A2%E8%AE%A2%E9%98%85%E6%96%87%E4%BB%B6.txt />
`;
cache.set(subscribeKey,subscribeInfo);
}
return subscribeInfo;
}
function editSubscribe(subscribe) {
// 判断导入的订阅是否有效
// 获取订阅信息(得到的值肯定不会为空)
let pageTextHandleChainsY = pageTextHandleChains.init(subscribe);
let tisHasFetchFun = pageTextHandleChainsY.parseSingleTab("tis","fetchFun");
let tisNotFetchFun = pageTextHandleChainsY.parseSingleTabValue("tis");
let tis = [...tisHasFetchFun, ...tisNotFetchFun];
// 生成订阅信息存储
let subscribeText = "\n";
for(let aTis of tisHasFetchFun) {
subscribeText += `<tis::${aTis.tabValue} fetchFun="${aTis.attrValue}" />\n`
}
for(let aTis of tisNotFetchFun) {
subscribeText += `<tis::${aTis.tabValue} />\n`
}
// 持久化
let newSubscribeInfo = subscribeText.replace(/\n+/gm,"\n\n");
cache.set(registry.searchData.subscribeKey,newSubscribeInfo);
return tis.length;
}
// 存储订阅信息,当指定 sLineFetchFun 时,表示将解析“直接页”的配置,如果没有指定 sLineFetchFun 时,只解析内容
// 在提取函数中 \n 要改写为 \\n
let dataSources = getSubscribe()+ `
<fetchFun name="mLineFetchFun">
function(pageText) {
let type = "sketch"; // url sketch
let lines = pageText.split("\\n");
let search_data_lines = []; // 扫描的搜索数据 {},{}
let current_build_search_item = {};
let current_build_search_item_resource = "";
let point = 0; // 指的是上面的 current_build_search_item
let default_desc = "--无描述--"
function getTitleLineData(titleLine) {
const regex = /# ([^()()]+)[((]?([^()()]*)[^))]?/;
let matchData = regex.exec(titleLine)
return {
title: matchData[1],
desc: ((matchData[2]==null || matchData[2] == "")?default_desc:matchData[2])
}
}
for (let i = 0; i < lines.length; i++) {
let line = lines[i];
if(line.indexOf("# ") == 0) {
// 当前新的开始工作
point++;
// 创建新的搜索项目容器
current_build_search_item = {...getTitleLineData(line)}
// 重置resource
current_build_search_item_resource = "";
continue;
}
// 如果是刚开始,没有标题的内容行,跳过
if(point == 0) continue;
// 向当前搜索项目容器追加当前行
current_build_search_item_resource += (line+"\\n");
// 如果是最后一行,打包
let nextLine = lines[i+1];
if(i === lines.length-1 || ( nextLine != null && nextLine.indexOf("#") == 0 )) {
// 加入resource,最后一项
current_build_search_item.resource = current_build_search_item_resource;
// 打包装箱
search_data_lines.push(current_build_search_item);
}
}
// 添加种类
for(let line of search_data_lines) {
line.type = type;
}
return search_data_lines;
}
</fetchFun>
<fetchFun name="sLineFetchFun">
function(pageText) {
let type = "url"; // url sketch
let lines = pageText.split("\\n");
let search_data_lines = []
for (let line of lines) {
let search_data_line = (function(line) {
const baseReg = /([^::\\n]+)[((](.*)[))]\\s*[::]\s*(.+)/gm;
const ifNotDescMatchReg = /([^::]+)\\s*[::]\\s*(.*)/gm;
let title = "";
let desc = "";
let resource = "";
let captureResult = null;
if( !(/[()()]/.test(line))) {
// 兼容没有描述
captureResult = ifNotDescMatchReg.exec(line);
if(captureResult == null ) return;
title = captureResult[1];
desc = "--无描述--";
resource = captureResult[2];
}else {
// 正常语法
captureResult = baseReg.exec(line);
if(captureResult == null ) return;
title = captureResult[1];
desc = captureResult[2];
resource = captureResult[3];
}
return {
title: title,
desc: desc,
resource: resource
};
})(line);
if (search_data_line == null || search_data_line.title == null) continue;
search_data_lines.push(search_data_line)
}
for(let line of search_data_lines) {
line.type = type;
}
return search_data_lines;
}
</fetchFun>
`;
// github CDN加速包装器
function cdnPack(githubResourceUrl) {
let githubUrlFlag = "raw.githubusercontent.com";
// 如何不满足github url ,不加速
if(githubResourceUrl.indexOf(githubUrlFlag) < 0) return githubResourceUrl;
return "https://proxy.zyun.vip/"+githubResourceUrl;
}
// 模块四:初始化数据源
// 使用责任链模式——对pageText进行操作的工具
const pageTextHandleChains = {
pageText: "",
setPageText(newPageText) {
this.pageText = newPageText;
},
getPageText() {
return this.pageText;
},
init(newPageText = "") {
// 深拷贝一份实例
let wo = {...this};
// 初始化
wo.setPageText(newPageText);
return wo;
},
// 解析双标签-获取指定标签下指定属性下的值
parseDoubleTab(tabName,attrName) {
// 返回指定标签下指定属性下的值
const regex = RegExp(`<\\s*${tabName}[^<>]*\\s*${attrName}="([^<>]*)"\\s*>([\\s\\S]*?)<\/\\s*${tabName}\\s*>`,"gm");
let m;
let tabNameArr = [];
let copyPageText = this.pageText;
// 注意下面的 copyPageText 不能改变
while ((m = regex.exec(copyPageText)) !== null) {
// 这对于避免零宽度匹配的无限循环是必要的
if (m.index === regex.lastIndex) {
regex.lastIndex++;
}
tabNameArr.push({
attrValue: m[1],
tabValue: m[2]
})
const newPageText =this.pageText.replace(m[0], "");
this.pageText = newPageText;
}
return tabNameArr;
},
// 解析双标签-只获取值
parseDoubleTabValue(tabName) {
// 返回指定标签下指定属性下的值
const regex = RegExp(`<\\s*${tabName}[^<>]*\\s*>([\\s\\S]*?)<\/\\s*${tabName}\\s*>`,"gm");
let m;
let tabNameArr = [];
let copyPageText = this.pageText;
while ((m = regex.exec(copyPageText)) !== null) {
// 这对于避免零宽度匹配的无限循环是必要的
if (m.index === regex.lastIndex) {
regex.lastIndex++;
}
tabNameArr.push({
tabValue: m[1]
})
const newPageText =this.pageText.replace(m[0], "");
this.pageText = newPageText;
}
return tabNameArr;
},
// 获取指定单标签指定属性与标签值(标签::值)
parseSingleTab(tabName,attrName) {
// 返回指定标签下指定属性下的值
const regex = RegExp(`<${tabName}::([^\\s<>]*)\\s*${attrName}="([^"<>]*)"\\s*\/>`,"gm");
let m;
let tabNameArr = []
let copyPageText = this.pageText;
while ((m = regex.exec(copyPageText)) !== null) {
// 这对于避免零宽度匹配的无限循环是必要的
if (m.index === regex.lastIndex) {
regex.lastIndex++;
}
tabNameArr.push({
tabValue: m[1],
attrValue: m[2]
})
const newPageText =this.pageText.replace(m[0], "");
this.pageText = newPageText;
}
return tabNameArr;
},
parseSingleTabValue(tabName) {
// 返回指定标签下指定属性下的值
const regex = RegExp(`<${tabName}::([^\\s<>]*)[^<>]*\/>`,"gm");
let m;
let tabNameArr = []
let copyPageText = this.pageText;
while ((m = regex.exec(copyPageText)) !== null) {
// 这对于避免零宽度匹配的无限循环是必要的
if (m.index === regex.lastIndex) {
regex.lastIndex++;
}
tabNameArr.push({
tabValue: m[1]
})
const newPageText =this.pageText.replace(m[0], "");
this.pageText = newPageText;
}
return tabNameArr;
},
// 清除指定单双标签
cleanTabByTabName(tabName) {
const regex = RegExp(`<\\s*${tabName}[^<>]*>([^<>]*)(<\/[^<>]*>)*`,"gm");
// 替换的内容
const subst = ``;
// 被替换的值将包含在结果变量中
const cleanedText = this.pageText.replace(regex, subst);
this.pageText = cleanedText;
}
}
// 从 订阅信息(或页) 中解析出配置(json)
function getConfigFromDataSource(pageText) {
let config = {
// {url、fetchFun属性}
tis: [],
// {name与fetchFun属性}
fetchFuns: []
}
// 从config中放在返回对象中
let pageTextHandleChainsX = pageTextHandleChains.init(pageText);
let fetchFunTabDatas = pageTextHandleChainsX.parseDoubleTab("fetchFun","name");
for(let fetchFunTabData of fetchFunTabDatas) {
config.fetchFuns.push( { name:fetchFunTabData.attrValue,fetchFun:fetchFunTabData.tabValue } )
}
// 获取tis
let tisHasFetchFun = pageTextHandleChainsX.parseSingleTab("tis","fetchFun");
let tisNotFetchFun = pageTextHandleChainsX.parseSingleTabValue("tis");
let tisArr = [...tisHasFetchFun, ...tisNotFetchFun]
for(let tis of tisArr) {
config.tis.push( { url:tis.tabValue, fetchFun:tis.attrValue } )
}
return config;
}
// 将url转为文本(url请求得到的就是文本),当下面的dataSourceUrl不是http的url时,就会直接返回,不作请求
function urlToText(dataSourceUrl) {
// dataSourceUrl 转text
return new Promise(function (resolve, reject) {
if((dataSourceUrl.trim().indexOf("http") != 0 ) ) return resolve(dataSourceUrl) ;
$.ajax({
url: cdnPack(dataSourceUrl+"?time="+new Date().getTime()),
success: function (result) {
resolve(result)
}
});
});
}
// 下面的 dataSourceHandle 函数
let globalFetchFun = [];
// tis处理队列
let waitQueue = [];
// 将解析出来的部分数据push 到 registry.searchData.data的操作队列 (push到全局不能并发,所以这里必须是单线程操作)
let searchDataController = {
// 加入到全局的等待队列
queueData: [],
// 是否空闲
isIdle: true,
// 是否第一次 pushToGlobal
isFirsPush: true,
// 给外面触发,加入到队列中
pushToGlobal:function(newItems) {
if(this.isFirsPush) {
this.isFirsPush = false;
// 清空全局数据容器的数据
registry.searchData.data = [];
}
this.queueData.push(...newItems);
// 如果当前不是空闲的,其它线程当会处理刚才push的数据到全局中
if(!this.isIdle) return;
// 设置当前为工作模式
this.isIdle = false;
// 处理队列中的数据
let newItem = null;
while((newItem = this.queueData.pop() ) != null) {
// 下一个编号索引号
let nextIndex = registry.searchData.data.length;
newItem.index = nextIndex;
registry.searchData.data[nextIndex] = newItem;
}
// 设置当前空闲
this.isIdle = true;
// 更新视图显示条数
$("#search_input").attr("placeholder",registry.searchData.getDataLength("UPDATE"));
},
}
function dataSourceHandle(resourcePageUrl,tisTabFetchFunName) {
urlToText(resourcePageUrl).then(text => {
if(tisTabFetchFunName == null) {
// --> 是配置 <--
let data = []
// 解析配置,是一个json
let config = getConfigFromDataSource(text);
console.log("解析的配置:",config)
// 将FetchFun放到全局解析器中
globalFetchFun.push(...config.fetchFuns);
// 将tis放到处理队列中
waitQueue.push(...config.tis);
let tis = null;
while((tis = waitQueue.pop()) != undefined) {
// tis有两个url,第二是fetchFun
dataSourceHandle(tis.url,tis.fetchFun);
}
// 清理内容
pageTextHandleChains.setPageText("");
}else {
// --> 是内容 <--
// 解析内容
if(tisTabFetchFunName === "") return;
let fetchFunStr = getFetchFunGetByName(tisTabFetchFunName);
let search_data_line =(new Function('text', "return ( " + fetchFunStr + " )(`"+text.replace(/[`]/gm,"<反引号>")+"`)"))();
// 将之前修改为 <wrapLine> 改为真正的换行符 \n
let replaceBefore = "<反引号>";
let replaceAfter = "`";
// 处理并push到全局数据容器中
for(let item of search_data_line) {
item.title = item.title.replaceAll(replaceAfter,replaceBefore);
item.desc = item.desc.replaceAll(replaceAfter,replaceBefore);
item.resource = item.resource.replaceAll(replaceAfter,replaceBefore);
}
// 加入到push到全局的搜索数据队列中,等待加入到全局数据容器中
searchDataController.pushToGlobal(search_data_line);
// 触发搜索数据改变事件(做缓存等操作,观察者模式)
for(let fun of registry.searchData.dataChange) {
fun(search_data_line);
}
}
})
}
// 根据fetchFun名返回字符串函数
function getFetchFunGetByName(fetchFunName) {
for(let fetchFunData of globalFetchFun) {
if(fetchFunData.name == fetchFunName) {
return fetchFunData.fetchFun;
}
}
}
// 缓存数据
function cacheSearchData(newSearchData) {
console.log("触发了缓存,当前数据",registry.searchData.data)
// 当有数据加入到全局数据容器时,会触发缓存,当前函数会执行
let SEARCH_DATA_KEY = registry.searchData.SEARCH_DATA_KEY;
cache.remove(SEARCH_DATA_KEY)
cache.set(SEARCH_DATA_KEY,{
data: registry.searchData.data,
expire: new Date().getTime() + (1000*60*60*1) // 一个小时
})
// 加载一下图片,让服务器的redis缓存图标
loadWebFavicon(newSearchData);
}
// 加载一下网站图标,让远程redis有记录,下次会很快
async function loadWebFavicon(searchItems) {
let CACHE_FLAG = "loadHistory";
let loadHistory = cache.get(CACHE_FLAG);
if(loadHistory == null) loadHistory = [];
// 创建容器
let imgBox=document.createElement("div");
imgBox.style="display:none";
document.body.appendChild(imgBox);
for(let item of searchItems) {
let resource = item.resource.trim();
if(resource.toUpperCase().indexOf("HTTP") == 0) {
// 如果历史中有,跳过此项后续操作
if(loadHistory.includes(resource)) continue;
// 记录一下,下次不会再进行此操作,给服务减压
loadHistory.push(resource);
// 装箱
var img=document.createElement("img");
img.src = registry.searchData.getFaviconAPI+resource;
imgBox.appendChild(img);
}
if(item === searchItems[searchItems.length-1] ) {
// 这是最后一个,去掉痕迹
setTimeout(function() {
// 将记录持久化
cache.set(CACHE_FLAG,loadHistory);
imgBox.remove();
},500)
}
}
}
// 检查是否已经执行初始化
function checkIsInitializedAndSetInitialized(secondTime) {
let key = "DATA_INIT";
let value = cache.cookieGet(key);
if(value != null && value != "") return true;
cache.cookieSet(key,key,1000*secondTime);
return false;
}
// 【数据初始化主函数】
let isInitialized = false;
function dataInitFun() {
// 检查是否已经执行初始化
if(isInitialized) return;
// 设置为已初始化,保障只初始化一次,如果不能保障,同时初始化时,出现重复数据
isInitialized = true;
// 从缓存中获取数据,判断是否还有效
const SEARCH_DATA_KEY = registry.searchData.SEARCH_DATA_KEY;
// cache.remove(SEARCH_DATA_KEY)
let dataBox = cache.get(registry.searchData.SEARCH_DATA_KEY);
if(dataBox != null) {
// 只要数据不为空,不管是否过期,先用着,直接将之前缓存的数据放在全局搜索数据容器中
registry.searchData.data = dataBox.data
// 缓存信息不为空,深入判断是否使用缓存的数据
let dataExpireTime = dataBox.expire;
let currentTime = new Date().getTime();
// console.log("缓存的数据:",dataBox.data)
// 数据多大时,才开启缓存
const TRIGGER_CACHE_DATA_LENGTH = 300;
// 判断是否有效,有效的话放到全局容器中
let isValid = (dataExpireTime != null && dataExpireTime > currentTime && dataBox.data != null && dataBox.data.length > 0);
// 如果网站比较特殊,忽略数据过期时间
if(!isValid && window.location.host.toUpperCase().indexOf("GITHUB.COM") >= 0) {
isValid = true;
}
// 如果数据过期,或数据量不满足缓存大小,会去请求数据
if(isValid && dataBox.data.length >= TRIGGER_CACHE_DATA_LENGTH ) {
console.log("我的搜索:本次从缓冲中获取, 数据有效期还有"+parseInt((dataExpireTime - currentTime)/1000/60)+"分钟!", dataBox.data)
return
};
}
// 内部将使用递归,解析出信息
dataSourceHandle(dataSources,null);
// 监听数据改变
registry.searchData.dataChange.push(cacheSearchData)
}
// 判断是否要直接执行初始化函数-如果没有数据,这里要直接执行
(function() {
let SEARCH_DATA_KEY = registry.searchData.SEARCH_DATA_KEY;
if(cache.get(SEARCH_DATA_KEY) == null) {
// 执行初始化函数
console.log("将执行初始化函数")
dataInitFun();
}
})();
// 模块二
registry.view.viewVisibilityController = (function () {
// 整个视图对象
let viewDocument = null;
let searchInputDocument = null;
let matchItems = null;
let searchBox = null;
let isInitializedView = false;
let viewName = "my_search_view"
let controlButton = null;
let textShow = null;
let matchResult = null;
let initView = function () {
// 初始化视图
let view = document.createElement("div")
view.innerHTML = (`
<div id="${viewName}">
<div id="searchBox">
<input placeholder="${registry.searchData.getDataLength()}" id="search_input" />
<button id="controlButton">Bug</button>
</div>
<div id="matchResult">
<ol id="matchItems">
<!-- <li><a href="#">webGL水族馆(测试电脑性能)</a></li> -->
</ol>
</div>
<div id="text_show">
</div>
</div>
`)
// 设置样式
view.style = `
position: fixed;left: 25%;right: 25%;top:50px;
border:2px solid #cecece;z-index:10000;
background: #ffffff;
overflow: hidden;
`;
// 挂载到文档中
document.body.appendChild(view)
// 整个视图对象放在组件全局中/注册表中
registry.view.viewDocument = viewDocument = view;
// 搜索框对象
searchInputDocument = $("#search_input")
matchItems = $("#matchItems");
searchBox = $("#searchBox")
controlButton = $("#controlButton")
textShow = $("#text_show")
matchResult = $("#matchResult");
searchBox.css({
"height": "45px",
"background": "#ffffff",
"padding": "0px",
"box-sizing": " border-box",
"z-index": "10001",
"position":"relative"
})
searchInputDocument.css({
"width": "100%",
"height": "100%",
"border": "none",
"outline": "none",
"font-size": "15px",
"background": "#fff",
"padding": "0px 10px",
"box-sizing": " border-box",
"color":"rgba(0,0,0,.87)",
"font-weight":"400"
})
$("#matchResult > ol").css({
"margin": "0px",
"padding": "0px 15px",
"overflow": "hidden"
})
controlButton.css({
"position": "absolute",
"font-size":"12px !important",
"right": "5px",
"margin":"10px 7px",
"padding":"3px 15px",
"border-radius":"13.5px",
"border":"none",
"display":"none", // 默认隐藏,由函数控制
})
textShow.css({
"display":"none",
"width":"100%",
"box-sizing": "border-box",
"padding": "5px 10px 7px",
"font-size": "15px",
"line-height":"25px",
"max-height":"450px",
"overflow": "auto",
"text-align":"left"
})
// 初始化搜索数据
dataInitFun();
// 在搜索的结果集中上下选择移动然后回车(相当点击)
searchInputDocument.keydown(function(event){
let e = event || window.event || arguments.callee.caller.arguments[0];
if(e && e.keyCode!=38 && e.keyCode!=40 && e.keyCode!=13) return;
if(e && e.keyCode==38){ // 上
registry.searchData.pos --;
}
if(e && e.keyCode==40){ //下
registry.searchData.pos ++;
}
// 如果是回车 && registry.searchData.pos == 0 时,设置 registry.searchData.pos = 1 (这样是为了搜索后回车相当于点击第一个)
if(e && e.keyCode==13 && registry.searchData.pos == 0){ // 回车
registry.searchData.pos = 1;
}
// 当指针位置越出时,位置重定向
if(registry.searchData.pos < 1 || registry.searchData.pos > registry.searchData.searchData.length ) {
if(registry.searchData.pos < 1) {
// 回到最后一个
registry.searchData.pos = registry.searchData.searchData.length;
}else {
// 回到第一个
registry.searchData.pos = 1;
}
}
// 设置显示样式
let activeItem = $($("#matchItems > li")[registry.searchData.pos-1]);
// if(activeItem == null) return;
// 设置活跃背景颜色
activeItem.css({
"background":"#dee2e6"
})
// 设置其它子元素背景为默认统一背景
activeItem.siblings().css({
"background":"#fff"
})
if(e && e.keyCode==13){ // 回车
// 点击当前活跃的项,点击
activeItem.find("a")[0].click();
}
// 取消冒泡
e.stopPropagation();
})
// 将输入框的控制按钮设置可见性函数公开放注册表中
registry.view.setButtonVisibility = function (buttonVisibility = false) {
// registry.view.setButtonVisibility
controlButton.css({
"display": buttonVisibility?"block":"none"
})
}
function searchUnitHandler(beforeData = [],keyword = "") {
// 如果没有搜索内容,返回空数据
if(keyword.trim() == "" || registry.searchData.data.length == 0 ) return [];
// 切割搜索内容以空格隔开,得到多个 keyword
let searchUnits = keyword.split(/\s+/);
// 弹出一个 keyword
keyword = searchUnits.pop();
// 本次搜索的总数据容器
let searchResultData = [];
let searchLevelData = [
[],[],[] // 分别是匹配标题/desc/url 的结果
]
// 数据出来的总数据
//let searchData = []
// 前置处理函数,这里使用观察者模式
// searchPreFun(keyword);
// 搜索操作
for (let dataItem of beforeData) {
keyword =keyword.toUpperCase();
// 将数据放在指定搜索层级数据上
if ((dataItem.title.toUpperCase().indexOf(keyword) >= 0 && searchLevelData[0].push(dataItem) )
|| (dataItem.desc.toUpperCase().indexOf(keyword) >= 0 && searchLevelData[1].push(dataItem) )
|| (dataItem.resource.toUpperCase().indexOf(keyword) >= 0 && searchLevelData[2].push(dataItem) ) ) {
// 向满足条件的数据对象添加在总数据中的索引
}
}
console.log("层级数据:",searchLevelData)
// 将上面层级数据放在总容器中
searchResultData.push(...searchLevelData[0])
searchResultData.push(...searchLevelData[1])
searchResultData.push(...searchLevelData[2])
if(searchUnits.length > 0) {
searchResultData = searchUnitHandler(searchResultData,searchUnits.join(" "));
}
return searchResultData;
}
// 给输入框加事件
// 执行 debounce 函数返回新函数
let handler = function (e) {
let key = e.target.value.trim();
// 过滤
// 数据出来的总数据
let searchData = []
// 递归搜索,根据空字符切换出来的多个keyword
let searchResultData = searchUnitHandler(registry.searchData.data,key)
console.log("搜索总数据:",searchResultData)
// 放到视图上
// 置空内容
matchItems.html("")
// 最多显示条数
let show_item_number = 15;
function getFlag(searchResultItem) {
let resource = searchResultItem.resource.trim();
let sketchFavicon = "data:image/png;base64,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";
let loadErrorFlagIcon = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAYAAACtWK6eAAAAAXNSR0IArs4c6QAAExhJREFUeF7tnYu1JDcRQLURgCNYE4EhgsURGEewEAFsBAsRGCJYHIHZCIAIDBEAERhHAOfOa832zHRPq6UqqSSVznnn7dnXH6lUt+uj36vgpYUEPg8hvA4h/DyE8NOlAr/cqMj67/HP/wgh/Pfu2n+HEPihxH//vUXDRnvnq9EaZKg9KP4XIQRg4Adlj79rVROQACpC87cQwo/L/9WqQ9fvcUBku+9NCAFLEH9kny73NMABlr+EELA00frIvWGQJzkgZR3ZCxBHrQQQgOHHgVlJywE5Up3Hv38VQvjV8hPjh/NPsX0HwPw5hPDt7NbFAUlTVGKH3y5Q8O+ZClYFWD5uJAeGl4MDst/FWAesxe+WAHt4ZThoIHELMQtWBWimKA7IYzcTYL8NIfx6Cg3Ia2R0wf40ulVxQD4pCGC8XzJQeWoz311YlT+GEIYFxQF5Sck6GGVwDwvKzIA4GGVQbN0dQRkm+zUjIA6GPBhbT8T1+kPvMcpMgJCV+saD7zp0LG/BopAFxKJ0WWYBhDGM368mBnbZWR1XmrTwb3ocdBwdECYIfvBxDDNo8ZHqKuM1KiC4U2SmMO9ebEmAMZR3y6CjrZpt1GZEQAjCv3N3yrzuMSqP23W/tsVUxUcDBKuBGffShwSwJl9bXp8yCiC4VFiNrVV5fajK3LXEFSY2MVdGAMRdKnNqlVUhky5X74C4S5Wli2ZvMudy9QqIu1RmdVykYgTvrEFpXnoEBDj+6mMbzXVHuwIkW5iq0rT0BggDf8Ax6lLXpspg8OVYEaxJs9ITIA5HMzVp+uKmkPQCCJskMGXELUdTXW32cvb2+rLFoGIPgLD0FTi8zC2BJpBYB8ThqAMFe2ExDhG3NeU3hTEmXFt+s4FF60Ia+Bc1LYllQBwOXXX8z7KeHB8/ZT4U7i2uLtkl9hVuVapaEquA8MUiW+VFRwKkT0vmrDE1hPt/olO9w6dWg8QiIJ6tOtSP7Av+uVgBib14sShAwmK0FgWXkImOqsUaIA6HXnez7FVjry+sPW5aC7dLPQVsCRC+SN8vRwToqcmcT9aeukHf4XYxN652UYXECiA+fURPrbThWNecfYvZzaR2xkutjVYAISD3tRyykHBQDlmnFvvo8l5Aqel2EY8Ql4gWC4AQ6LUwzaKCNPYw4OCDE8czWlSvdhBPqpoxEokExFVerQHxdK6O6qp8TTOrWjOI54MAJGKlJSAelIt1482D1PzxgurWtCalYzw3zWwJCGvI8VW9yEnAIhzr1pFmJjbRHmBkYqNI7NUKEFKCbAPqRUYCxBwon3iQKlO9m6cw1oXyakJCPPKzxCk0T5vYAhAExHiHFxkJWAjIz7YElwtIOCZbq/B8LElRqQ2Ixx1F3fVwM1NHCIJTJhvKvrn8aTUgKY5HagPiKd1yxYpPYB+p3rdW1YakOPVbExBGWf8lpx/TPqnlAKCG0IGE9KzWoGLRpMaagPhoebl6cRQzwXiPLtWz1msH7tlZrVqAkM4lreslTwIsbgIMkdRlXhXU79LUkeyViDUA8cA8T7cIwHE9mK06Mhhr6WjGqFkBew1AGBhqtagmTzXr3BUBAIL7teB1amDzLXwM3ihVjbGRU3O1tAHxMY/bngYKPhgEjqPFEVI6TTKHD4bGQOLpsRFtQDwwf1EbgmtSsqe+XlIa1+FzNOORUwG7JiBuPULAYgDGLDGEJItYWY2FV6esiCYgBJdvJSXW2bO01oB3Jobs6pLcweJquFrJVkQLkNkHBbMyJtmqNO6NWq5WshXRAmRm62F9ynlvOGm5WklWRAOQma0HW3j62npZBLWyWklWRAOQma3H6Ty7rC4N+zStAcRDKyINyMzWw4NyXT4J2KUnNB72mTQgM4+ae+yhC4jWBh9Prb40ID9MfMjNobnW1Z8pnq4xDeVpxlESEK2UXC89/5lPH1HvKg0XHtcNK7JZJAHRSsepS13oBZKyFKrSkI/RSALtWn+pTmXUE/dq5iIly5llmNJ2DSuyG6xLdapv4xOCu1gp6i1zjbQV2d0mSAoQtvFhcuLMxYP0er2vYUU2s5ASgPis3RfFsLQfbj1Vbfcm6Zh3c2RdApCZxz7W6uETFOvCopE1fRgTkQCErXwwebMX8Z3FZxdoQvuJHSSnwz+4WaWAaPiCCXIxe4nHIXW7Rtp7YeXnzYbqpYD4Wea3CsGgE7FIy4Nr6qpo27dJu1lYJLKR11IKiHS6ra245d7O7FNy674GXU6me0/6n/ArOIDn+oErBcTjj+e9wxcpCvt+XTr/z4Zwbm3KNFx6fta7ZeeZS61KAPH4o6xj13fTyVgbMmFudc7JVdqLuYlDSgDx+ONcR6ZeTX6fndt9J5Q0iUkvprqJQ0oAkSY3TRzzXIXrBSyAwlJeL9sSkA7Uecs1DikBxOOPuioLKBEaB+aT7DUWUl3jkFxAfPZuXTi23gYw/OAzzxzoawByjUNyAdGoVHuV67cGBPbAgktG585UNHTxujtNLiAeoNtVQYJMQJkFFg1ArhneXECkMwd21a3vmmFZSKaMPGipBchlfU8uINKDM32rYR+1BxTSx6PFK1qAXObV5QLiC6T6gGKrloAy0oCkljdzyWTlAiI9/6Vfdeu35qPs46XlzVzW9+QA4lNM+oXivuZYE0DpuWh9rC+ZrBxAtHy+njup57rfzF7trCGam4VcFsDlAKJZqc76Z4jq9rpUuMZeCK9yANEKiobQtg4bQWaLj15PBTg4/5IZHZrFAdGUbifP7ilYBwiOFOcjXaM4IDWkbPwdvZxpwnmXgFFzgxAHxLjyalePU3gtb/hH3QCDqU3a7tSWrL/MiUF8HYi22tZ7/s3y0nqv3X0TELxZjrFjnUdNayEGiNbAjIH+maoKPy4KyOTGloWz0Bk64MeaNcuyIA5IS3WSe/fh8WNyr3p4Epbh/bIHVQvXKbVpDkiqpAa8rlVwTjzxTaOY4mw3OiBnJTbI9S2sB5YCMACkl/IuJ0h3F6uX7t2vZ+3pJcQWHwzGGEc96RbkSEID/r12apdsFHBYjjX2utkBWSTDzM24xU5cUESHrrMrpB9HKDVHzgnEa416a/RNFiDSB5doNCzlmWz7yZgOP6m7GQJNTEWSibnP06//j+skt+ZPadPRNbVSu8gJq3GzU/pR5Qz+PQuQ3icrAgZtAAztEoFCUQhOWwNz3a1DseF8JL7rMN7YEslUgOB7AwYWsFUBEurwulEFtAGpNcu2lvg+y8li9WZBalqMlI7DqjC9nJ/aFmX3NNeUih9cQ7yG5egxGN9r2tCTFfG3UcIarlSOfuGKUD/cr7MWJWfr0Zhk0FhmO+oq02EBYREQlq71PKNUcGJwj4ty/wUmq0Y71meNpD73/joUGUDYV5lsVmpy4tn7RnOr1m3NAsTy14IvK1/l0fZ+ygVi677YfwDHR4SPSWoB5HtrR1zV0+h4altxzT/PiUFqrAVObcT6ul7XVue0tfSe9U4gzIxAduvzSADhiyUTBVBbKe3SOli/P3tXExqmtdVKjtAgHT/erUa69Pb6D0i23Lz0J49z5WWtfo4FQQT4rmcDSw3RkbrlC9dLrKEhg7PP9KMr0iSWvXEcj7cwYdHhSOvo+6s0TmTKq4ntu4r25pU+wD1HVJcG5Nw4+T0W+q6HLrjMeM51sSwMFubWvYfO0ayjBeuv2T6pZ1/0K1fJLKR6c+suJcBen2Ph42ZddtclAblKZmED69y6W+8c7foRpJNkqT3NRbtdks8vPoLNQqrXAclXCQseQH7t9e+8jqmVKFlrX/ZyRJa+rIZ9g58zud+1X8dZ3yWAtPZlPYtVzq5Dsi3D68e3BJDWZrrm0tFyVbT7BIfktm9u1uyXAMJjcXFaBXsttq6xq+ZlNXNIPsnv5jiIUkBark8nE8PmZ15kJOCQvMjxxnUvBaT1aVPXYEpGR6Z/im9Mfjc2WApI66nvWBGmBHg2S4Ztlsz2vhNJiSQe1uyXAtI6DuH9GktIS4Tc672tvQELcntYUyQBSMs4JArVISlTL5/h+yK/hy1ZJQCxIlwGLolJ3N06B8vIa8rPSOKyxPb+BglALLhZsV2sKgQSic0Izgi352s5LZYxrdnL5mm/UoBYyn5gQagPrl/O9jgzKUrrwV5Lst48L0UKkNbZrGeCXm+Xg2XhB3eMEdPZ3bHW04WsALK7470UIDTUyjr1VKFHS8NBlrOW1hNOrch9d9qSJCC9pgmJWxg93bMmBG4cXh83h+DaUYoD8tKTuzPDJQGxsIgqV3GBBHfj4/KAeBwx0y/uB85GmkXsgITwdE6fJCDoloUxkVxIYjYOV/HZccQjbVDngLxkPXd3/JcGxMqYSAkkR/dupgOPbjL699mD9M2xj3VfSQPSY7B+Vne1z9g4W5+S62cH5HBNkQYgo0+bHmma/QwWf+8Dcmg9uFEDkBmsCKlhNmDrvcwMyKH10ARkdCuC7BitJ2DveVrLrC5WkvXQBGQGKxKtR8+gcJDOwwS93s1iQv2TM5FaLhZ1nMGKxL7IOYwmoR9VL5nVvTp1FLYmIDNZkbU1IT6xPseLgdDv3Xocf4C0AZnJikRpM+jE4JPlMusU91PWQzsGiQrCNA6O85qpWJ6OMmtgjv4lZa7WiqptQXiX5anwWtBaTQPjWhGYl55lzmApbiTPoX9b7Y12pv+yBnhrAEIjZju0xeq+waULpJjYx6zt+xgLUHg2sPA7nsl+RoG1r31Yb57ywlqAzLTlvuW5WiXu1dmdLMmS8fM2RRGVr8nuk1qAzJL2ZQCKr6jVLFbu7N0s92RReuTBe1u5YUV9UhMQ5JXbQcofGLHHZ5lxsbcfP+iHjPiDzA9KXjJjoNS1O27Z/hVFu2/WBmTkgD15dLaktwvuzV3QJtGuVkdPl1i+i6hrA8I7S/zgAv1QvTV5bo9qLZ4/PHdMSiLhkPvuEnFJWL4mgIzoakl8ZUuUIeXenNWeZwPzvXrkvDulTc+uKXKt4oNbWBDePVpWS0qRSpXi2f058YcE+C3ij+ys1b0AWwFCPVoITlMBLQfouRMTSwFpMedrd4+rnM5vCcho8YjloxhyXZxSQGofp0DcwYeX6U0ipTUgNGKkuVpHe2yJdNrJh5RkkEpcxxaB+em5VkeytAAI6UcUq9VA0pGMzv4dS0JHMeZjoZRkDXPX37dI55fAvNtPFgChcrk+sgUF3KuDhZWGEpMTNzd1fiL4FscpEHfEnS9FdcIKIDSqhUkWFebOw1qCIiHTMzOTh4KD/rQEyMiQtFiSK5VBwv0lQ3dUJGA8esf930UGA5+91Bog1NXSWSNnO+zoevEg8skLS2KP+8c+c7Nwbdjcu/bhn+IZqy1ZWgRkZEiwJCib9mxfEh+sOS9dGBV1Zn1yF89+vfj8QPFsH+OjD0bu36vAYdHFWgssN3efK/Ra99WwIrXHH2rJLr6nhgwv77JqQagbXz9SpaOtZ6dNmmeM9HpOSypk1eCwDsjIkJzJDKUqDte1GH84U7/Sa6vC0QMgUaAjBu7SO5+0SLGWKnzq/cQcWEb0oGqx7GLdC2I0SCQDdokBwaqKd+Jl1QLynrJYe/KTTF2e6CO1SyXiESzHh0bZJDXBLA9uCkdPLta6I1oMSGkqQsmMWdKswCGVztVs59lnM32E9pWshT/7zofre3KxRoYkJx55vyxfLlYCgw9Qm1t1tq29AhIzNoyVMGjVezmzloSRa+Dg94hlb3O6Jm3tGRAEhmtB8P5VE+nJvvRomShtZdPpFiPXsi3dflqzTNWzxvUOSGzbCINjZLVox5bPDRQkKEaMNehDXCpiS7GVgFJEjwLIaC6XVP/28BwsJ/Brz0/LksVIgIzmcmV1aEc34VJhNYgjzZbRAImCRvDsKD/KMl6zCpRZMXY8pI+apnBT6j4qINGaAImF3cVT+mKGa7qwGuuOGBmQ2E7SoYAy2qzg3oAyHWvsCXMGQNaZLoJBd7vqooU7RXbOXIYqRQwzAeJBfIpGyF1jclzjbPNmA2TtdmFNLB4VdrYPrV0PGLi0/JhM3Z4R2KyARBmxvhpQPJA/ozXb1w4FRmzi7IA4KOVgcDYKHxnGM7q3GPficEBuJeIWJR2YCEb1VX7pVSy/0gHZliGgsBaB7MsIs4XLNeXTEz4uE0RNj4BLNdgBOZYkEwUBBWBmTREzmZCge0g36pkKOCDHgKyvABKmSIwwvf6o5bhQAAEY5qeEHDUm9+8OSJ7kmHYOLIzS8zOKG4alYJ08YFg5viGvh4TuckBkBIkbFmHhdy+uWAQCGPgZLgtV2r0OSKkEt+9fA4O1sTAgicuEq8SUDwcisd8dkERBCVwGKIDDD//G0vBbchIlg3UAAAgRBqyCu0uZHeiAZApO6bYI0frx8f9Q9PsJf1v/p1S1OR/rgMzZ797qRAk4IImC8svmlIADMme/e6sTJeCAJArKL5tTAg7InP3urU6UgAOSKCi/bE4JOCBz9ru3OlECDkiioPyyOSXggMzZ797qRAk4IImC8svmlIADMme/e6sTJeCAJArKL5tTAv8H9tmE9nVFdD4AAAAASUVORK5CYII=";
if(!resource.toUpperCase().indexOf("HTTP") == 0) return searchResultItem.type=="sketch"?`<img src="${sketchFavicon}" />`:`<img src="${sketchFavicon}" />`;
function loaded() {
alert("loaded!")
}
return `<img src="${registry.searchData.getFaviconAPI+resource}" onerror="this.src='${loadErrorFlagIcon}';" class="searchItem" />`
// return `<img src="${registry.searchData.getFaviconAPI+resource}" class="searchItem" />`
}
/* $("#matchItems").on("load","li img", function (){
alert("加载完成!")
})*/
// 标题flag颜色选择器
function titleFlagColorMatchHandler(flagValue) {
let vcObj = {
"非最佳":"rgb(244,201,13)",
"推荐":"rgb(91,184,93)",
"装机必备":"#9933E5"
}
let resultFlagColor = "#5eb95e";
Object.getOwnPropertyNames(vcObj).forEach(function(key){
console.log(key);
if(key == flagValue) {
resultFlagColor = vcObj[key];
}
});
return resultFlagColor;
}
// 标题内容处理程序
function titleHandler(title) {
if(!(/[\[]?/.test(title) && /[\]]?/.test(title))) return title;
// 格式是:[flag]title(desc):resource 这种的
const regex = /\[\s*([^\]]+)\s*\]\s*(.+)\s*/;
let m;
if ((m = regex.exec(title)) !== null) {
if(m.length != 3) return title;
// 正确提取
let style = `
background: ${titleFlagColorMatchHandler(m[1])};
color: #fff;
font-size: 10px;
padding: 2px 5px;
border-radius: 5px;
font-weight: 500;
margin-right: 2px;
box-sizing: border-box;
box-shadow:
7px 7px 12px rgba(0, 0, 0, .4),
-7px -7px 12px rgba(255, 255, 255, .9),
inset 0 0 0x rgba(255, 255, 255, .9),
inset 0 0 0 rgba(0, 0, 0, .4);
`;
return `<span style="${style}">${m[1]}</span> ${m[2]}`;
}
return title;
}
for(let searchResultItem of searchResultData ) {
// 限制条数
if(show_item_number-- <= 0) {
break;
}
// 将数据放入局部容器中
searchData.push(searchResultItem)
// 将符合的数据装载到视图
let item = `
<li>${getFlag(searchResultItem)}
<a href="${searchResultItem.resource}" target="_blank" title="${searchResultItem.desc}" index="${searchResultItem.index}" >
${titleHandler(searchResultItem.title)}
<span class="desc">(${searchResultItem.desc})</span>
</a>
</li>`
matchItems.html(matchItems.html() + item)
}
// 给刚才添加的img添加加载完成事件,去除加载背景
for(let imgObj of $("#matchItems").find('img')) {
imgObj.onload = function(e) {
$(e.target).css({
"background": "rgba(0,0,0,0)"
})
}
}
// 隐藏文本显示视图
textShow.css({
"display":"none"
})
// 让搜索结果显示
matchResult.css({
"display":"block"
})
// 将搜索的数据放入全局容器中
registry.searchData.searchData = searchData;
// 指令归位(置零)
registry.searchData.pos = 0;
// 设置li样式
$("#matchResult li").css({
"line-height": "30px",
"height": "30px",
"color": "#0088cc",
"list-style": "none", //decimal
"width":"100%",
"margin":"0px",
"display":"flex",
"justify-content":"left",
"align-items":"center",
"padding":"0px",
"margin":"0px"
})
$("#matchResult li>a").css({
"display":"inline-block",
"font-size":"15px",
"color": "#1a0dab",
"text-decoration":"none",
"text-align":"left",
"overflow":"hidden", //超出的文本隐藏
"text-overflow":"ellipsis", //溢出用省略号显示
"white-space":"nowrap", //溢出不换行
"cursor":"pointer",
"font-weight":"400"
})
$("#matchResult .desc").css({
"color":"#4d5156"
})
$("#matchResult img").css({
"display": "inline-block",
"width": "17px",
"height":"17px",
"margin":"0px 7px 0px 5px",
"box-shadow": "0 0 2px rgba(0,0,0,0.5)",
"border-radius": "30%",
"box-sizing": " border-box",
"padding":"2px",
"flex-shrink":"0" // 当容量不够时,不压缩图片的大小
})
}
// 给查询出来的结果添加事件 -- 设置事件委托
$("#matchItems").on("click","li > a",function(e) {
// 设置为阅读模式
// $("#search_input").val(":read");
// 获取当前结果在搜索数组中的索引
let dataIndex = parseInt($(e.target).attr("index"));
console.log("target==>",dataIndex)
let itemData = registry.searchData.data[dataIndex];
// 如果是简述搜索信息,那就取消a标签的默认跳转事件
if(itemData.resource.trim().indexOf("http") !== 0) {
// 取消默认事件
e.preventDefault();
matchResult.css({
"display": "none"
})
textShow.css({
"display":"block"
})
textShow.html("<span style='color:red'>标题</span>:"+itemData.title+"<br />"+ "<span style='color:red'>描述:</span>"+itemData.desc+"<br />"+"<span style='color:red'>简述内容:</span><br />"+itemData.resource.replace(/\n/gm,"<br />"))
return;
}
// 取消冒泡
window.event? window.event.cancelBubble = true : e.stopPropagation();
// 隐藏视图
registry.view.viewVisibilityController(false)
// 否则是URL跳转
})
const refresh = debounce(handler, 460)
// 第一次触发 scroll 执行一次 fn,后续只有在停止滑动 1 秒后才执行函数 fn
searchBox.on('input', refresh)
// 初始化后将isInitializedView变量设置为true
isInitializedView = true;
}
let hideView = function () {
// 隐藏视图
// 如果视图还没有初始化,直接退出
if (!isInitializedView) return;
// 让视图隐藏
viewDocument.style.display = "none";
// 将输入框内容置空
searchInputDocument.val("")
// 将之前搜索结果置空
matchItems.html("")
// 隐藏文本显示视图
textShow.css({
"display":"none"
})
// 让搜索结果显示
matchResult.css({
"display":"block"
})
}
let showView = function () {
// 让视图可见
viewDocument.style.display = "block";
//聚焦
searchInputDocument.focus()
// 当输入框失去焦点时,隐藏视图
searchInputDocument.blur(function() {
// 判断输入框的内容是不是":debug"或是否正处于阅读模式,如果是,不隐藏
if(isInstructions(searchInputDocument.val(),"debug") || isInstructions(searchInputDocument.val(),"read")) return;
// 当前视图是否在展示数据,如搜索结果,简述内容?如果在展示不隐藏
let isNotExhibition = (($("#matchResult").css("display") == "none" || $("#matchItems > li").length == 0 ) && ($("#text_show").css("display") == "none" || $("#text_show").text().trim() == "") );
if(!isNotExhibition) return;
setTimeout(()=>{registry.view.viewVisibilityController(false)},200)
});
}
// 返回给外界控制视图显示与隐藏
return function (isSetViewVisibility) {
if (isSetViewVisibility) {
// 让视图可见 >>>
// 如果还没初始化先初始化 // 初始化数据 initData();
if (!isInitializedView) {
// 初始化视图
initView();
// 初始化数据
// initData();
}
// 让视图可见
showView();
} else {
// 隐藏视图 >>>
if (isInitializedView) hideView();
}
}
})();
// 触发策略——快捷键
let useKeyTrigger = function (viewVisibilityController) {
// 将视图与触发策略绑定
triggerAndEvent("ctrl+alt+s", function () {
// 让视图可见
viewVisibilityController(true);
})
triggerAndEvent("Escape", function () {
// 让视图不可见
viewVisibilityController(false);
})
}
// 触发策略组
let trigger_group = [useKeyTrigger];
// 初始化入选的触发策略
(function () {
for (let trigger of trigger_group) {
trigger(registry.view.viewVisibilityController);
}
})();
// 打开视图进行配置
// 显示配置视图
// 是否显示进度 - 进度控制
GM_registerMenuCommand("订阅管理",function() {
showConfigView();
});
GM_registerMenuCommand("清理缓存",function() {
cache.remove(registry.searchData.SEARCH_DATA_KEY);
});
// 显示配置规则视图
function showConfigView() {
if($("#subscribe_save")[0] != null) return;
// 显示视图
var configViewContainer = document.createElement("div");
configViewContainer.style=`
width:450px; background:pink;
position: fixed;right: 0px; top: 0px;
z-index:10000;
padding: 20px;
border-radius: 14px;
`
configViewContainer.innerHTML = `
<p id="title">订阅总览:</p>
<textarea id="all_subscribe" ></textarea>
<button id="subscribe_save" >保存并应用</button>
`;
// 设置样式
document.body.appendChild(configViewContainer);
document.getElementById("title").style="margin-bottom: 10px; font-size: 16px;";
document.getElementById("all_subscribe").style="width:100%;height:150px";
document.getElementById("subscribe_save").style=" margin-top: 20px; border: none; border-radius: 3px; padding: 4px 20px; cursor: pointer;";
// 回显
document.getElementById("all_subscribe").value = getSubscribe();
// 保存
document.getElementById("subscribe_save").onclick=function() {
// 保存到对象
let allSubscribe = document.getElementById("all_subscribe").value;
let validCount = editSubscribe(allSubscribe);
// 清除视图
configViewContainer.remove();
alert("保存配置成功!有效订阅数:"+validCount);
}
}
})();