// ==UserScript==
// @name HiNativeTool
// @namespace http://tampermonkey.net/
// @version 1.2.73
// @description Handy Hinative tool!!
// @author Collen Zhou
// @match *://hinative.com/*
// @grant unsafeWindow
// @grant GM_getValue
// @grant GM_setValue
// @grant GM_listValues
// @require http://code.jquery.com/jquery-3.4.1.min.js
// ==/UserScript==
//The file is auto created with script, changes might get lost!
(function() {
'use strict';
console.log("Hinative tool is running!")
window. gm_get = GM_getValue
window. gm_set = GM_setValue
function toggle_setting(){
let visible=$('#popup').is(':visible')
var pop_up=$(window.popuphtml)
if(visible)
pop_up.hide()
else{
pop_up.show()
}
$('#popup').replaceWith(pop_up)
setup_popup()
}
let s=$("<span></span>")
let ts=$("<span id='setting' title='sript settings' style='font-size: 22px;cursor: pointer;' >⚙️</span>")
ts.click(toggle_setting)
s.append(ts)
$(".nav_activity").after(s)
window. TMStorage = function () {
}
//添加TM支持
TMStorage.prototype = {
get: function (keys, callback) {
let count = 0;
let sum = keys.length
let obj = {}
for (let key of keys) {
let key1 = key
window. result = gm_get(key1)
if (result == "undefined")
{
continue
}
else
{
obj[key1] = gm_get(key1)
}
}
callback(obj)
},
set: function (obj1, callback) {
let count = 0;
let sum = Object.keys(obj1).length
let obj = obj1
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
const value = obj[key];
gm_set(key, value)
}
}
if (typeof callback === "undefined")
return
else {
callback(obj)
}
}
}
TMStorage.prototype.constructor = TMStorage
window. Mode = function () {
}
Mode.prototype = {
Mode: null,
Storage: null,
OnInstalled: function (callback) { },
OnPageUpdate: function (callback) { },
ExecuteScript: function (script, callback) { }
}
Mode.prototype.constructor = Mode
//添加TM支持
window. TMMode = function () {
Mode.call(this)
this.Mode = "TM"
this.Storage = new TMStorage()
this.OnPageUpdated = function (callback) {
callback.call(this)
}
this.ExecuteScript = function (obj, callback) {
eval(obj.code)
callback.call(this)
}
}
TMMode.prototype = new Mode()
TMMode.prototype.constructor = new TMMode()
window. ExtensionMode = function () {
Mode.call(this)
this.Mode = "extension"
this.Storage = chrome.storage.local
this.OnPageUpdated = function (callback) {
chrome.tabs.onUpdated.addListener(callback)
}
this.OnInstalled = function (callback) {
chrome.runtime.onInstalled.addListener(callback)
}
this.ExecuteScript = function (script, callback) {
chrome.tabs.executeScript(script, callback)
}
}
ExtensionMode.prototype = new Mode()
ExtensionMode.prototype.constructor = ExtensionMode
window. mode = new TMMode()
window. storage = mode.Storage
function log(obj) {
if (show_log)
console.log(obj)
}
//执行一个字典里所有的脚本,并在所有脚本都执行完后调用resolve
function preload(dict) {
let len = Object.keys(dict).length
let count = 0;
return new Promise(resolve=>{
for (let key in dict) {
if (dict.hasOwnProperty(key)) {
let val = dict[key];
let key1 = key
add_script_value(key1, val).then(function () {
if (++count == len) {
resolve()
}
})
}
}
})
}
//添加一个页面变量值,如果不存在则创建并设置默认值
function add_script_value(key1, dflt1) {
let key = key1
let dflt = dflt1
return new Promise(resolve => {
storage.get([key], function (result) {
if (typeof result[key] === "undefined") {
let obj = {}
obj[key] = dflt
result[key] = dflt
log("undefined key:"+key)
storage.set(obj)
}
set_variable(key,result[key]).then(function () {
resolve()
});
});
})
}
function set_variable(key,value)
{
let code = "window."+key + ' = ' +JSON.stringify(value)
return execute_script(code);
}
//执行一个脚本返回resolve
function execute_script(script) {
let script1=script
return new Promise(resolve=>{
mode.ExecuteScript({
code: script1
},()=>{
let e=chrome.runtime.lastError
resolve()
})
})
}
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
'use strict';
mode.OnInstalled(function () {
//添加popup
chrome.declarativeContent.onPageChanged.removeRules(undefined, function () {
chrome.declarativeContent.onPageChanged.addRules([{
conditions: [new chrome.declarativeContent.PageStateMatcher({
pageUrl: { hostEquals: 'hinative.com' },
})
],
actions: [new chrome.declarativeContent.ShowPageAction()]
}]);
});
})
// execute_script("window.need_featured_answer=true")
mode.OnPageUpdated(function (tabId, changeInfo, tab) {
execute_script("window.data_loaded=false")
//在这里初始化变量
let obj={
"show_log": false,
"extension_enabled": true,
"auto_block": false,
"need_featured_answer": true,
"cache_new_users": false,
"block_rate_below": 0.3,
"validity_duration": 7,
"blocked_users": [],
"result_buffer": {},
"white_list": [],
"self_name":(()=>{})(),
"blocked_quesions":{},
"request_interval":500,
"fap_count":3
}
//数据加载完后添加全局变量data_loaded
preload(obj).then(function(){
// alert("preloaded")
execute_script("window.data_loaded=true")
})
})
$(document).ready(function () {
// https://hinative.com/en-US 只监听qeustions路径
if (!window.location.pathname.match(/^\/[^\/]*$/))
return
//缓存的结果,减少xhr次数
// result_buffer
//数据是否加载完
// data_loaded = false
//用来填充的个数
//被屏蔽的用户列表
// blocked_users = []
window.last_blocks_count = 0
//现在是否正在blocking过程中
window.blocking = false
//新用户最大提问数
window.new_user_qustion_count = 3
//自动屏蔽的用户数组
window.auto_blocked_users = []
//已经被屏蔽的问题块
window.blocked_blocks = new Set()
//已经用于填充的问题块数
window.filling_blocks_count = 0
//存放请求的队列
window.request_queue = []
//请求最小间隔,以免给hinative服务器造成负担
// request_interval
//开启请求循环
start_request_interval()
//监听blocks变化
setInterval(() => {
if ((!(typeof data_loaded === "undefined")) && data_loaded && extension_enabled) {
process_blocking()
process_scroll()
}
}, 200);
$("main").append("<div style='text-align:center'>如果需要新的提问,请下滑刷新~~ <br/>scroll down to refresh</div>")
})
//自动下拉以刷新提问
function process_scroll() {
let visible_count = 0
let qts = get_questions()
qts.each(function () {
if (this.style.visibility != "hidden" && this.style.display != "none" && $(this).is(":visible")) {
visible_count++
}
})
if ($("html").get(0).getClientRects()[0].height <= window.innerHeight) {
log("auto scroll! visible count:" + visible_count)
let tmp = $("html").get(0).scrollTop
var div = $("<div style='display:block;height:" + window.innerHeight + "px;width:20px'>神奇的伸缩棒</div>")
$("body").append(div)
$("html").get(0).scrollTop = 0
$("html").get(0).scrollTop = $("html").get(0).scrollHeight;
$("html").get(0).scrollTop = tmp
div.remove()
}
}
//获得所有问题块
function get_questions() {
return $(".d_block")
}
//主要的执行过程
function process_blocking() {
if (get_questions().length == last_blocks_count) {
//每两百毫秒执行一次,判断是否需要新的查询
return
}
if (blocking) {
log("blokcing")
return
}
//阻塞标示,以免两个interval同时运行,造成多次paint
blocking = true
last_blocks_count = get_questions().length
try {
//得到自身信息
(function get_self_username() {
if (typeof self_name === "undefined") {
let p_url = $(".spec_nav_profile>a").get(0).href
let req = request_get(p_url, null, false)
let name = to_jq(req.responseText).find(".owner_name>span").text().trim()
storage.set({ "self_name": name })
storage.set({ "self_url": p_url })
log("get self name:" + name + " self url:" + p_url)
}
})()
//遍历每个回答
get_questions().each(function () {
let href = $(this).attr("href")
let b_block = $(this).get(0)
let usr = jq_must_find(this, ".username").text()
let wrapper = jq_must_find(this, ".username_wrapper")
//如果该问题已经被屏蔽,就不用画
if (blocked_quesions[href]) {
add_block(b_block, false)
return
}
//如果是屏蔽用户则不用画
if (!check_block(b_block)) {
//log("return:" + usr)
return
}
//如果已经画过了也不用画
if (b_block.painted == true) {
return
}
let block = b_block
//判断是不是选择型问题
if ($(block).find("*:contains('does this sound natural')").length > 0) {
let c_url = href + "/choice_result"
let c_req = request_get(c_url, null, false);
//如果已经投过票了,则跳过这个问题
if (c_req.responseText.indexOf(self_name) > -1) {
log("usr:" + usr + " skip quesion because I have selected")
add_block(block)
return
}
}
//如果该用户没加载过,或者用户数据过期了就继续加载数据,否则重画
if (typeof result_buffer[usr] === "undefined") {
//没有加载过就继续
log("usr not in buffer:" + usr)
}
else if (!(typeof validity_duration === "undefined")) {
let duration = (new Date().getTime() - result_buffer[usr].time) / (86400 * 1000)
//判断数据是否过期,单位为天
if (duration >= validity_duration) {
log("validity_duration:" + validity_duration + "duration:" + duration)
log(usr + " data expired!")
} else {
//已经加载过了
//如果是新的方块则重新画一遍
do_painting(b_block, result_buffer[usr].txt)
return
}
}
let loading=null
//添加loading图片
if($(b_block).find(".script_loading").length==0)
{
loading =String.raw`<div class="script_loading" style="width: 16px;height: 16px;display: inline-block;background: url(//cdn.hinative.com/packs/media/loadings/default-091d6e81.gif) no-repeat;background-size: 16px 16px;"> </div>`
loading=$(loading)
wrapper.append(loading)
}
//发送请求
request_get(href, function (evt) {
let q_url = href
//得到用户页面
let txt = evt.srcElement.response
let page = to_jq(txt)
let wrp = $(page.find(".chat_content_wrapper").get(0))
//https://hinative.com/en-US/questions/15939889/choice_result
//获得用户profileurl
let p_url = wrp.find("a").get(0).href
let usr1 = usr
get_user_info(p_url, usr1).then(function (buffer) {
let b_block1 = b_block
let buffer1 = buffer
if (b_block1.painted == true) {
return
}
//保存了基本信息和用户地址
result_buffer[buffer.usr] = buffer1
if (!need_featured_answer)
success()
do_painting(b_block1)
if (need_featured_answer == true) {
get_user_feartured_answer(p_url, buffer1).then(function (buffer) {
log("featrued loaded:" + buffer.usr)
result_buffer[buffer.usr] = buffer
//将所有同名的block都加上rate
get_questions().each(function () {
if (this.featrued_painted != true) {
let a_usr = jq_must_find(this, ".username")
if (a_usr.text() == buffer.usr) {
do_featrued_painting(this)
}
}
})
success()
})
}
})
})
function success() {
//更新数据到本地
update_result_buffer()
loading.remove()
}
})
} finally {
blocking = false
}
}
//更新缓存到本地
function update_result_buffer() {
let clone = result_buffer
//如果选择不缓冲新人,则不将新人数据上传
if (!cache_new_users) {
clone = Object.assign({}, result_buffer)
let not_recording = []
for (const usr in clone) {
if (result_buffer[usr].info.q_n.replace("K", "000").replace(".", "") <= new_user_qustion_count) {
//如果是新人则不缓存数据
not_recording.push(usr)
}
}
for (const usr of not_recording) {
delete clone[usr]
}
}
storage.set({ "result_buffer": clone })
}
function block_user(user_name, auto_blocked = true) {
if (auto_blocked)
auto_blocked_users.push(user_name)
blocked_users.push(user_name)
blocked_users = Array.from(new Set(blocked_users))
let clone = Array.from(blocked_users)
//自动生成的block将不被储存到本地
for (const usr of auto_blocked_users) {
if (clone.indexOf(usr) > -1)
clone.splice(clone.indexOf(usr), 1)
}
storage.set({ "blocked_users": clone })
}
//将block屏蔽掉
//update代表是否更新本次操作到本地
function add_block(ele, update = true) {
let usr = jq_must_find(ele, ".username")
//如果用户被屏蔽,则隐藏这个提问
blocked_blocks.add(ele)
if (update) {
let href = $(this).attr("href")
blocked_quesions[href] = true
storage.set({ "blocked_quesions": blocked_quesions })
}
if ($("#blocked_blocks").length == 0)
$(".country_selector").append("<span id='blocked_blocks'> blocked quesions count:" + blocked_blocks.length + "</span>")
else {
$("#blocked_blocks").text("blocked quesions count:" + blocked_blocks.size)
}
log("已隐藏用户问题:" + usr.text())
ele.style.display = "none"
}
//添加用户到白名单
function add_white_list(user_name) {
white_list.push(user_name)
storage.set({ "white_list": Array.from(new Set(white_list)) })
}
//获得绘制基本信息
function get_paint_info(txt) {
//获得反应率以及其他信息
let matches = txt.match(/level_\d/)
let info = {}
let color = "white"
if (matches != null) {
//获得用户profile rate
info.rate = matches[0]
}
//获得questions number
let numbers = txt.match(/(?<=font_numbers_large['"]>)[^<]+/g)
// log(txt)
info.q_n = numbers[0]
info.a_n = numbers[1]
return info
}
//对需要框框上色
function do_painting(ele) {
//设置一个painted属性
ele.painted = true
let usr = jq_must_find(ele, ".username")
let wrp = jq_must_find(ele, ".username_wrapper")
let buffer = result_buffer[usr.text()]
let info = buffer.info
//确认是否需要自动隐藏
let is_auto_blocked = false
let color = "white"
//获得用户profile rate
let rate = info.rate
switch (rate) {
case "level_1":
color = "red"
is_auto_blocked = true
break;
case "level_2":
color = "orange"
is_auto_blocked = true
break;
case "level_3":
color = "#ffff80"
break;
case "level_4":
color = "green"
break;
}
//添加色彩显示
wrp.append("<span class='rate_badge' style=\"display:inline-block;width:16px;height:16px;border: darkblue;border-style: dotted;border-width: 1px;border-radius:8px;background-color:" + color + "\"></span>")
let q_n = info.q_n
let a_n = info.a_n
usr.get(0).style.fontWeight = "bold"
usr.get(0).style.color = "black"
usr.get(0).style.fontSize = "25"
wrp.append($("<span>" + " Q:" + q_n + " A:" + a_n + "</span>"))
//如果没有划过feture answer则画一次
if (ele.featrued_painted != true && typeof result_buffer[usr.text()].featured_answers != "undefined") {
do_featrued_painting(ele)
}
//自动屏蔽
if (is_auto_blocked && auto_block)
block_user(usr.text())
let in_white_list = white_list.indexOf(usr.text()) != -1
//添加屏蔽选项
let a = null
//如果不存在于白名单则添加屏蔽选项
if (!in_white_list) {
a = $("<a class='block' title='block this user'>❌</a>")
a.before(" ")
a.click(function (e) {
e.preventDefault()
block_user(usr.text(), false)
each_user_blocks(usr.text(), function () {
do_painting(this)
})
})
wrp.append(a)
}
//添加白名单选项
a = $("<a class='white' title='add this user to white list'>" + (in_white_list ? "💗" : "💚") + "</a>")
a.before(" ")
a.click(function (e) {
e.preventDefault()
add_white_list(usr.text())
//将用户的问题去除白名单和黑名单选项
each_user_blocks(usr.text(), function () {
$(this).find(".block").remove()
$(this).find(".white").text("💗")
})
})
wrp.append(a)
check_block(ele)
}
//添加采纳率
function do_featrued_painting(ele) {
ele.featrued_painted = true
let usr = jq_must_find(ele, ".username")
let wrp = jq_must_find(ele, ".username_wrapper")
// log("result_buffer[" + usr.text() + "]:")
// log(result_buffer[usr.text()])
let a = result_buffer[usr.text()].answers
let f = result_buffer[usr.text()].featured_answers
let rate = (f / a).toFixed(2)
wrp.append("<span class='rate_badage'> rate:" + ((a != 0) ? rate : "NO ANSWERS") + "</span>")
if (rate <= block_rate_below) {
//如果采纳率为0,则标红
jq_must_find(ele, ".rate_badge", false).css("background-color", "red")
if (auto_block) {
block_user(usr.text())
check_block(ele)
}
return false
}
//采纳率大于0.6则标绿
if (rate > 0.6) {
jq_must_find(ele, ".rate_badge", false).css("background-color", "green")
}
return true
}
//判断是否块块是否好好的,需要被屏蔽
function check_block(ele, why) {
//如果已经屏蔽,则不用画了
if (blocked_blocks.has(ele))
return false
let usr = jq_must_find(ele, ".username")
//如果在白名单里则不必屏蔽
if (white_list.indexOf(usr.text()) >= 0) {
return true
}
if (blocked_users.indexOf(usr.text()) > -1) {
add_block(ele)
return false
}
return true
}
//便遍历某个username的所有blocks
function each_user_blocks(username, handler) {
get_questions().each(function () {
if (jq_must_find(this, ".username").text() == username) {
handler.call(this)
}
})
}
//获得用户提问,回应率,回答数
function get_user_info(p_url, usr) {
let p_url1 = p_url
let usr1 = usr
return new Promise(resolve => {
request_get(p_url, function (evt1) {
let txt = evt1.srcElement.response
let buffer = { info: get_paint_info(txt), profile_url: p_url1, usr: usr1, time: new Date().getTime() }
resolve(buffer)
return
})
})
}
// 获得用户采纳情况信息
function get_user_feartured_answer(p_url, buffer) {
let buffer1 = buffer
let p_url1 = p_url
let page_count = fap_count
return new Promise(resolve => {
let buffer = buffer1
//第一回答页面
//在这里获得采纳的回答数
let q_url = p_url1 + "/questions"
let blocks_count = 0
if (typeof buffer.featured_answers === "undefined") {
buffer.featured_answers = 0
}
if (typeof buffer.answers === "undefined") {
buffer.answers = 0
}
let current_page = 0
for (let current_page = 0; current_page < page_count; current_page++) {
request_page(current_page)
}
function request_page(index) {
let q_url1 = q_url
if (index > 0) {
q_url1 = q_url + '?page=' + (index + 1)
}
log("usr:" + buffer.usr + " page:" + q_url1)
//请求该用户的提问页,用于得到问题的采纳率
request_get(q_url1, function (evt) {
let qtxt = evt.srcElement.response
let page = to_jq(qtxt)
//获得第一页回答的问题
let blocks = page.find(".d_block")
//最后一页了,则取消继续查询
if (blocks.length == 0) {
page_count = 0
}
//初始化总的有回复的提问数
blocks.each(function () {
let badge = $(jq_must_find(this, ".badge_item").get(0)).text().trim()
log("usr-question:" + buffer.usr + " badge:" + badge)
//如果无人回答则不计入
if (badge == "0") {
// log("skipped quesition")
return
}
blocks_count++;
let fq_url = this.href
//请求某一个问题的页面
request_get(fq_url, function (evt) {
let qtxt1 = evt.srcElement.response
//该问题已被采纳
if (qtxt1.indexOf("featured_answer_label") > -1) {
buffer.featured_answers++
}
else {
//未被采纳
}
buffer.answers++
// log("usr:" + buffer.usr + " index:" + index + " blocks_count:" + blocks_count + " buffer.answers:" + buffer.answers + " buffer.featured_answers:" + buffer.featured_answers)
//当所有的问题都加载完,统计结果,并添加到缓存中
if (blocks_count == buffer.answers && index >= (page_count - 1)) {
//更新时间
buffer.time = new Date().getTime()
log("usr:" + buffer.usr + " blocks_count:" + blocks_count + " buffer.answers:" + buffer.answers + " buffer.featured_answers:" + buffer.featured_answers)
resolve(buffer)
return
}
})
})
})
}
})
}
// 将文本转化为jqnodes
function to_jq(html_text) {
let qtxt = html_text
let html = $.parseHTML(qtxt)
let page = $("<div>").append(html)
return page
}
//在一个元素中查找关键selector,如果不存在则报错
function jq_must_find(ele, selector, force = true) {
let find = $(ele).find(selector)
if (force && find.length == 0) {
alert("未能找到关键样式:" + selector + " 请联系作者解决!,程序将被暂停运行~~")
extension_enabled = false
}
return find
}
//发送一次get请求
function request_get(url, callback, async = true) {
let req = new XMLHttpRequest()
if (callback)
req.addEventListener("load", callback)
req.open("GET", url, async)
// req.setRequestHeader('User-Agent','Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36')
if (async)
request_queue.push(req)
else {
req.send()
}
return req
}
function start_request_interval() {
//每秒一次请求
setInterval(function () {
if (request_queue.length > 0) {
var req = request_queue.shift()
req.send()
}
}, request_interval)
}
//更新缓存
function update_cache() {
log("current result_buffer:")
log(result_buffer)
new Promise(resolve => {
storage.get(["result_buffer"], function (rslt) {
const result_buffer = typeof rslt.result_buffer === "undefined" ? {} : rslt.result_buffer
let resolved = 0
const count = Object.keys(result_buffer).length
log("count:" + count)
log("result_buffer:")
log(result_buffer)
for (const usr in result_buffer) {
let p_url = result_buffer[usr].profile_url
let usr1 = usr
get_user_info(p_url, usr1).then(function (buffer1) {
let buffer2 = buffer1
//保存了基本信息和用户地址
result_buffer[buffer2.usr] = buffer2
if (need_featured_answer == true) {
get_user_feartured_answer(p_url, buffer2).then(function (buffer3) {
result_buffer[buffer3.usr] = buffer3
if (++resolved == count)
resolve(result_buffer)
log(buffer3.usr + "data updated:" + resolved + " left:" + (count - resolved))
})
} else {
result_buffer[buffer1.usr] = buffer1
if (++resolved == count)
resolve(result_buffer)
log("resolved:" + resolved + " left:" + (count - resolved))
}
})
}
})
}).then(rb => {
log("resovled buffer:")
log(rb)
update_result_buffer();
alert("用户信息更新完成!")
})
}
window.popuphtml=String.raw`<div id='popup' style='padding:10px;display: inline-block;position: absolute;z-index: 100;background: white;transform: translate(0, 100%);border-style: double;bottom: 0;left: 0;'><!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
.popup {
width: 400px;
height: 500px;
}
.popup,td {
position: relative;
}
.option_table {
text-align: right;
}
.range {
width: 120px;
margin: auto;
display: block;
top: 50%;
position: absolute;
transform: translate(0, -50%);
}
.numer_input {
text-align: right;
width: 120px;
}
.button {
border-style: outset;
padding: 0%;
}
.list_table_container {
text-align: left;
border-style: double;
}
.list_table {
display: inline-block;
height: 300px;
overflow: scroll;
}
</style>
</head>
<body class="popup">
<table class="option_table">
<thead>
<tr>Info</tr>
</thead>
<tbody>
<tr>
<td>username:</td>
<td><input id="username" type="text" title="user name" disabled /></td>
</tr>
</tbody>
</table>
<table class="option_table">
<thead>
<tr>Options</tr>
</thead>
<tbody>
<tr>
<td>Turn on:</td>
<td><input id="switch" type="checkbox" title="Check to allow this extension to function" /><br /></td>
</tr>
<tr>
<td>Auto-block:</td>
<td><input id="auto" type="checkbox" title="Allow this script to block users automatically" /><br /></td>
</tr>
<tr>
<td>Featured answers:</td>
<td><input id="featured" type="checkbox" title="Check to buffer and show user answer-featuring rate" /><br />
</td>
</tr>
<tr>
<td>Qustions page count:</td>
<td><input id="fap_count" type="number" class="numer_input" min="1" step="1" max="10" pattern="\d*"
title="set question pages count the script need to search, might cause low performance if set too high"
/><br /></td>
</tr>
<tr>
<td>Cache new users:</td>
<td><input id="cache_new_users" type="checkbox"
title="Check to cache new user's data,this option can be reverted." /><br /></td>
</tr>
<tr>
<td>Show log:</td>
<td><input id="show_log" type="checkbox" title="Show developer log" /><br /></td>
</tr>
<tr>
<td>Block rate below:</td>
<td><input id="block_rate_below" type="range" class="range" title="Block rate below" min="0" max="1"
step="0.1" /><br /></td>
</tr>
<tr>
<td>Data validity duration(d):</td>
<td><input id="validity_duration" type="number" class="numer_input" min="0" step="1" pattern="\d*"
title="interval of auto updateing data which has expired:" /><br /></td>
</tr>
<tr>
<td>Request interval(ms):</td>
<td><input id="request_interval" type="number" class="numer_input" min="0" step="100" pattern="\d*"
title="min allowed interval of sending xhr requests:<br/> you might get banned if the value is set too low" /><br />
</td>
</tr>
<tr>
<td> Clear cached data:</td>
<td><input id="cached" type="button" value="🚮"
title="Clear buffered responses,you might need to re-reqeust those data!" class='button'></input><br /></td>
</tr>
<tr>
<td> Update chached data:</td>
<td><input id="update" type="button" value="🆕" title="Update Cached Data,might take some time."
class='button'></input><br /></td>
</tr>
<tr>
<td class="list_table_container">
<table>
<thead>
<tr>Blocked Users</tr>
</thead>
<tbody id="blocked_users" class="list_table">
</tbody>
</table>
</td>
<td class="list_table_container">
<table>
<thead>
<tr>White List</tr>
</thead>
<tbody id="white_list" class="list_table">
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
<script src="/js/jquery-3.4.1.min.js"></script>
<script src="/js/common.js"></script>
<script src="/js/popup.js"></script>
</body>
</html></div>`
s.append(window.popuphtml)
function setup_popup(){
//清空缓存的用户数据
$("#cached").click(function () {
clear_cache()
})
//更新缓存的用户数据
$("#update").click(function () {
popup_update_cache()
})
//设置title为value
$("#block_rate_below").change(function () {
this.title = $(this).val()
})
$("#featured").click(function (e) {
if ($(this).is(":checked")) {
if (confirm("Warning:Cache will be cleared,continue?")) {
clear_cache()
}
else {
e.preventDefault()
}
}
})
set_binding("extension_enabled", $("#switch").get(0))
set_binding("auto_block", $("#auto").get(0))
set_binding("need_featured_answer", $("#featured").get(0))
set_binding("cache_new_users", $("#cache_new_users").get(0))
set_binding("block_rate_below", $("#block_rate_below").get(0))
set_binding("show_log", $("#show_log").get(0))
set_binding("validity_duration", $("#validity_duration").get(0))
set_binding("self_name", $("#username").get(0))
set_binding("request_interval", $("#request_interval").get(0))
set_binding("fap_count", $("#fap_count").get(0))
binding_list("blocked_users", $("#blocked_users").get(0))
binding_list("white_list", $("#white_list").get(0))
}
function binding_list(key, tbody) {
((key, tbody) => {
let list = []
storage.get([key], function (rslt) {
list = typeof rslt[key] === "undefined" ? [] : rslt[key]
show_list()
function remove_block(username) {
while (list.indexOf(username) > -1) {
list.splice(list.indexOf(username), 1)
}
window. obj={ }
obj[key]=list
storage.set(obj)
}
function show_list() {
$(tbody).empty()
for (const u of list) {
let tr = $("<tr>")
tr.append($("<td>" + u + "</td>"))
let a = $("<a href='#'' style='text-decoration: none' title='Remove this user from the list'>❌</a>")
a.click(function () {
$(this).closest("tr").hide()
remove_block(u)
})
let db = $("<td></td>")
db.append(a)
tr.append(db)
$(tbody).append(tr)
}
}
})
})(key, tbody)
}
function set_binding(key1, check1) {
let key = key1
let check = check1
storage.get([key], function (result) {
switch (check.type) {
case "checkbox":
$(check).attr("checked", result[key])
break
default:
$(check).val(result[key])
}
$(check).change(function () {
set_status()
})
})
function set_status() {
let value = (function () {
switch (check.type) {
case "checkbox":
return $(check).is(":checked")
default:
return $(check).val()
}
})()
set_variable(key,value)
let obj = {}
obj[key] = value
storage.set(obj)
}
}
function clear_cache() {
storage.set({ "result_buffer": {} }, function () {
log("cache cleared!")
})
}
function popup_update_cache() {
mode.ExecuteScript({
code: "update_cache()"
}, () => chrome.runtime.lastError);
}
$('#popup').hide()
})();