// ==UserScript== // @name 健康浏览网页 // @version 1.0.0 // @license GPL-3 // @namespace https://github.com/AliubYiero/TamperMonkeyScripts // @run-at document-start // @author Yiero // @homepage https://github.com/AliubYiero/TamperMonkeyScripts // @description 限制网页访问时间 // @match https://*/* // @grant GM_getValue // @grant GM_setValue // @icon https://tampermonkey.net/favicon.ico // ==/UserScript== /* ==UserConfig== 配置项: limitTime: title: 设置屏蔽网站和限制时间 description: 设置限时访问的网站和限制时间 type: textarea default: ", , , \nhttps://www.example.com/, 18, 20, open // --> 从 18:00-20:00 开放访问 https://www.example.com/ (普通匹配)\nhttps://www.example.com/, 18:30, 20:30, limit // --> 从 18:30-20:30 限制访问 https://www.example.com/ (普通匹配), 其余时间开放访问\n/https?://www.example.com/.* /, 18, 20 // --> 从 18:00-20:00 限制访问 https://www.example.com/.* (正则匹配), 其余时间开放访问" ==/UserConfig== */ const UserConfigs = { "\u914d\u7f6e\u9879": { limitTime: { title: "\u8bbe\u7f6e\u5c4f\u853d\u7f51\u7ad9\u548c\u9650\u5236\u65f6\u95f4", description: "\u8bbe\u7f6e\u9650\u65f6\u8bbf\u95ee\u7684\u7f51\u7ad9\u548c\u9650\u5236\u65f6\u95f4", type: "textarea", default: ", , , \nhttps://www.example.com/, 18, 20, open // --\x3e \u4ece 18:00-20:00 \u5f00\u653e\u8bbf\u95ee https://www.example.com/ (\u666e\u901a\u5339\u914d)\nhttps://www.example.com/, 18:30, 20:30, limit // --\x3e \u4ece 18:30-20:30 \u9650\u5236\u8bbf\u95ee https://www.example.com/ (\u666e\u901a\u5339\u914d), \u5176\u4f59\u65f6\u95f4\u5f00\u653e\u8bbf\u95ee\n/https?://www.example.com/.* /, 18, 20 // --\x3e \u4ece 18:00-20:00 \u9650\u5236\u8bbf\u95ee https://www.example.com/.* (\u6b63\u5219\u5339\u914d), \u5176\u4f59\u65f6\u95f4\u5f00\u653e\u8bbf\u95ee" } } }; class GMStorageExtra extends Storage { constructor() { super(); } static get length() { return this.keys().length; } static getItem(key, defaultValue, group) { return this.createKey(key, group), GM_getValue(this.createKey(key, group), defaultValue); } static hasItem(key, group) { return Boolean(this.getItem(key, group)); } static setItem(key, value, group) { GM_setValue(this.createKey(key, group), value); } static removeItem(key, group) { GM_deleteValue(this.createKey(key, group)); } static clear() { const keyList = GM_listValues(); for (const key of keyList) GM_deleteValue(key); } static key(index) { return this.keys()[index]; } static keys() { return GM_listValues(); } static groups() { return this.keys().map((key => { const splitKeyList = key.split("."); return 2 === splitKeyList.length ? splitKeyList[0] : ""; })).filter((item => item)); } static createKey(key, group) { if (group) return `${group}.${key}`; for (let groupName in UserConfigs) { const configGroup = UserConfigs[groupName]; for (let configKey in configGroup) if (configKey === key) return `${groupName}.${key}`; } return key; } } function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } const parseTime = timeString => { let [hour, min = "00", sec = "00"] = timeString.split(/[:\uff1a\u2236]/); return `1970-1-1 ${hour}:${min}:${sec}`; }, parseLimitTimeString = limitTimeString => limitTimeString.split("\n").map((item => { let [urlString, startTimeString, endTimeString, limitWayKey = "limit"] = item.split(/[,\uff0c] ?/); return { url: (url => { if (url.startsWith("/") && url.match(/\/[gmyuisd]*$/)) { const [, matchRegexString, flag] = url.match(/^\/(.*)\/([gmyuisd]*)$/); return new RegExp(matchRegexString, flag); } return url.startsWith("http") ? new RegExp(`^${escapeRegExp(url)}$`) : new RegExp(`^https?://${escapeRegExp(url)}$`); })(urlString), startTime: Date.parse(parseTime(startTimeString)), endTime: Date.parse(parseTime(endTimeString)), limitWay: LimitWay[limitWayKey] }; })); var LimitWay = (LimitWay2 => (LimitWay2[LimitWay2.limit = 0] = "limit", LimitWay2[LimitWay2.open = 1] = "open", LimitWay2))(LimitWay || {}); (function(...funcs) { return (...args) => funcs.slice(1).reduce(((acc, fn) => fn(acc)), funcs[0](...args)); })((url => { const limitTimeString = GMStorageExtra.getItem("limitTime", ""); return parseLimitTimeString(limitTimeString).find((limitTime => url.match(limitTime.url))); }), (aimWeb => { if (!aimWeb) return !1; const todayDate = new Date, currentTime = Date.parse(`1970-1-1 ${todayDate.getHours()}:${todayDate.getMinutes()}:${todayDate.getMinutes()}`); if (aimWeb.limitWay === LimitWay.limit) { return currentTime >= aimWeb.startTime && currentTime <= aimWeb.endTime; } return !(currentTime >= aimWeb.startTime && currentTime <= aimWeb.endTime); }), (isCloseWeb => { isCloseWeb && window.close(); }))(document.URL);