tftv keyboard shortcuts

Adds keyboard shortcuts for navigating forum pages on teamfortress.tv

目前为 2015-09-01 提交的版本。查看 最新版本

// ==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.4
// @grant       none
// ==/UserScript==

/*
 * Helper function to scroll to post by id
 */
function goto_post(id) {
  document.getElementById(id).scrollIntoView();
  // Show upper border
  window.scrollBy(0,-1);
}

function frag(id, type, frag_action) {
  var btn_container = document.querySelector('.'+type+'-frag-container[data-'+type+'-id="'+id+'"]');

  var frag_status = btn_container.attributes["data-frag-status"].nodeValue;
  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 = btn_container.firstElementChild;
  var new_frag_count = parseInt(frag_count_container.textContent, 10) + diff;
  frag_count_container.textContent = new_frag_count;
  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';

  var plus_classes = btn_container.children[3].classList;
  var minus_classes = btn_container.children[2].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");
  }
  btn_container.setAttribute("data-frag-status", new_status);

  var xmlhttp = new XMLHttpRequest();
  xmlhttp.onreadystatechange = function() {
      if (xmlhttp.readyState == XMLHttpRequest.DONE ) {
         if(xmlhttp.status == 200){
             console.log(xmlhttp.responseText);
         }
         else if(xmlhttp.status == 400) {
            alert('There was an error 400')
         }
         else {
             alert('something else other than 200 was returned')
         }
      }
  }
  xmlhttp.open("POST", '/' + type + '/frag/' + id + '/' + frag_action, true);
  xmlhttp.send();
}

/*
 * Find the number of pages in the thread
 */
var pageList = document.querySelectorAll(".page-btn");
var lastPage = parseInt(pageList[pageList.length-2].textContent);

var posts = document.querySelectorAll(".post");
var cur_post = 0;

/*
 * Get and process 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 > 0) {
        cur_post--;
      }
      goto_post(posts[cur_post].id);
      break;
    case "s":
      if(cur_post < posts.length - 1) {
        cur_post++;
      }
      goto_post(posts[cur_post].id);
      break;
    case "W":
      cur_post = 0;
      goto_post(posts[cur_post].id);
      break;
    case "S":
      cur_post = posts.length - 1;
      goto_post(posts[cur_post].id);
      break;
    /*
     * Frags (+/-)
     */
    case "q":
      frag(posts[cur_post].id.slice(8), (cur_post == 0 && page == 1) ? "thread" : "post", "plus");
      break;
    case "e":
      frag(posts[cur_post].id.slice(8), "post", "minus");
      break;
  }};