您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Adds keyboard shortcuts for navigating forum pages on teamfortress.tv
当前为
// ==UserScript== // @name tftv keyboard shortcuts // @namespace Lense // @description Adds keyboard shortcuts for navigating forum pages on teamfortress.tv // @include /^https?://(www\.)?teamfortress.tv/.*/ // @version 0.5.3 // @grant none // ==/UserScript== // Toggle highlighting of focused post. With this off, there are no visual changes. var focus_highlight = true; /* * Style post with a highlight */ function focus_post(post) { if(!focus_highlight) { return; } post.style.background = "#fff"; post.style.boxShadow = "1px 1px 8px"; post.style.zIndex = "1"; } /* * Reset style to normal */ function unfocus_post(post) { post.style.background = ""; post.style.boxShadow = ""; post.style.zIndex = ""; } /* * Helper function to scroll to post by id */ function goto_post(id) { unfocus_post(document.getElementById(prev_post_id)); prev_post_id = id; var post = document.getElementById(id); post.scrollIntoView(); // Show upper border window.scrollBy(0,-1); // Highlight the current post focus_post(post); } /* * Update styles on plus/minus frag and send the http request * id is the post id * frag_action is either plus or minus */ function frag(id, frag_action) { var btn_container = document.querySelector('.post-frag-container[data-post-id="'+id+'"]'); var type; if(btn_container.classList.contains("self")) { // This post doesn't actually have frags; it's the OP. type = "thread"; btn_container = document.querySelector('.thread-frag-container' + (type=="post" ? '[data-'+type+'-id="'+id+'"]' : '')); } else { type = "post"; } // Most of this is ripped+modified from tftv js var frag_status = btn_container.attributes["data-frag-status"].value; if(frag_status == 'neutral' && frag_action == 'plus' || frag_status == 'minused' && frag_action == 'minus') var diff = 1; if(frag_status == 'neutral' && frag_action == 'minus' || frag_status == 'plused' && frag_action == 'plus') var diff = -1; if(frag_status == 'minused' && frag_action == 'plus') var diff = 2; if(frag_status == 'plused' && frag_action == 'minus') var diff = -2; var frag_count_container = type=="post" ? btn_container.firstElementChild : btn_container.querySelector("#thread-frag-count"); var new_frag_count = parseInt(frag_count_container.textContent, 10) + diff; frag_count_container.textContent = new_frag_count; if(type == "post") { btn_container.children[0].classList.remove("positive"); btn_container.children[0].classList.remove("negative"); btn_container.children[0].classList.remove("neutral"); btn_container.children[0].classList.add(new_frag_count > 0 ? "positive" : (new_frag_count < 0 ? "negative" : "neutral")); } if(frag_status == 'plused' && frag_action == 'plus' || frag_status == 'minused' && frag_action == 'minus') new_status = 'neutral'; if(frag_action == 'plus' && frag_status !== 'plused') new_status = 'plused'; if(frag_action == 'minus' && frag_status !== 'minused') new_status = 'minused'; btn_container.setAttribute("data-frag-status", new_status); var plus_classes = btn_container.querySelector("." + type + "-frag-btn.plus").classList; var minus_classes = btn_container.querySelector("." + type + "-frag-btn.minus").classList; if(frag_action == "plus") { if(plus_classes.contains("clicked")) { plus_classes.remove("clicked"); } else { plus_classes.add("clicked"); } minus_classes.remove("clicked"); } else { if(minus_classes.contains("clicked")) { minus_classes.remove("clicked"); } else { minus_classes.add("clicked"); } plus_classes.remove("clicked"); } var xmlhttp = new XMLHttpRequest(); xmlhttp.onreadystatechange = function() { if(xmlhttp.readyState == XMLHttpRequest.DONE) { if(xmlhttp.status != 200) { alert('VOTE NOT SENT'); } } } xmlhttp.open("POST", '/' + type + '/frag/' + (type=="post" ? id : btn_container.attributes["data-thread-id"].value) + '/' + frag_action, true); xmlhttp.send(); } /* * Find the number of pages in the thread */ var pageList = document.querySelectorAll(".mod-page"); var lastPage = parseInt(pageList[pageList.length-2].textContent); if(isNaN(lastPage)) { lastPage = 1; } var posts = document.querySelectorAll(".post"); focus_post(posts[0]); var cur_post_index = 0; var prev_post_id = posts[0].id; /* * Handle keypresses */ document.onkeypress = function(e) { // Not entirely sure why this is useful, but it can't break anything that isn't already broken e = e || window.event; // Ignore keypresses in text boxes, but allow if nothing or a link is selected if(e.target.nodeName != "BODY" && e.target.nodeName != "A") { // Got keypress, but it's probably in a textbox, so ignore it return; } // Current page number var page = window.location.search == "" || parseInt(window.location.search.match("page=([0-9]*)")[1]); switch(e["key"]) { /* * Pages (left/right) */ case "d": if(page != lastPage) { page = (page+1).toString(); window.location.search = "?page=" + page; } break; case "a": if(page != 1) { page = (page-1).toString(); window.location.search = "?page=" + page; } break; case "D": if(page != lastPage) { window.location.search = "?page=" + lastPage.toString(); } break; case "A": if(page != 1) { window.location.search = "?page=1"; } break; /* * Posts (up/down) */ case "w": if(cur_post_index > 0) { cur_post_index--; } goto_post(posts[cur_post_index].id); break; case "s": if(cur_post_index < posts.length - 1) { cur_post_index++; } goto_post(posts[cur_post_index].id); break; case "W": cur_post_index = 0; goto_post(posts[cur_post_index].id); break; case "S": cur_post_index = posts.length - 1; goto_post(posts[cur_post_index].id); break; /* * Frags (+/-) */ case "q": frag(posts[cur_post_index].id.slice(8), "plus"); break; case "e": frag(posts[cur_post_index].id.slice(8), "minus"); break; }};