HiNativeTool

Handy Hinative tool!!

目前为 2020-04-14 提交的版本。查看 最新版本

// ==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("&nbsp;")
        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("&nbsp;")
    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()
    })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址