Sankaku Tag Popularity Autocompletion

Makes the default autocompletion pick the most popular tag. Borders are added to the currently selected autocompletion. Arrow keys can also pick completions in textareas.

θα χρειαστεί να εγκαταστήσετε μια επέκταση όπως το Tampermonkey, το Greasemonkey ή το Violentmonkey για να εγκαταστήσετε αυτόν τον κώδικα.

You will need to install an extension such as Tampermonkey to install this script.

θα χρειαστεί να εγκαταστήσετε μια επέκταση όπως το Tampermonkey ή το Violentmonkey για να εγκαταστήσετε αυτόν τον κώδικα.

θα χρειαστεί να εγκαταστήσετε μια επέκταση όπως το Tampermonkey ή το Userscripts για να εγκαταστήσετε αυτόν τον κώδικα.

You will need to install an extension such as Tampermonkey to install this script.

Θα χρειαστεί να εγκαταστήσετε μια επέκταση διαχείρισης κώδικα χρήστη για να εγκαταστήσετε αυτόν τον κώδικα.

(Έχω ήδη έναν διαχειριστή κώδικα χρήστη, επιτρέψτε μου να τον εγκαταστήσω!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(Έχω ήδη έναν διαχειριστή στυλ χρήστη, επιτρέψτε μου να τον εγκαταστήσω!)

// ==UserScript==
// @name        Sankaku Tag Popularity Autocompletion
// @namespace   SankakuTagPopularityAutocompletion
// @match       https://chan.sankakucomplex.com/*
// @match       https://legacy.sankakucomplex.com/*
// @match       https://idol.sankakucomplex.com/*
// @noframes
// @grant       GM.addStyle
// @version     1.1.0
// @author      epair
// @description Makes the default autocompletion pick the most popular tag. Borders are added to the currently selected autocompletion. Arrow keys can also pick completions in textareas.
// ==/UserScript==

var selected_index = -1

function add_style(css) {
  if(GM.addStyle) {
    return Promise.resolve(GM.addStyle(css))
    //Violentmonkey returns a style element whereas Tampermonkey returns a Promise
  } else {
    const sheet = document.createElement('STYLE')
    sheet.innerText = css
    document.head.appendChild(sheet)
    return Promise.resolve(sheet)
  }
}

{
  //set style based on dark/light theme
  let theme = document.cookie
    .split('; ')
    .find((row) => row.startsWith('theme='))
    ?.split('=')[1];

  let is_dark_mode = theme !== undefined && Number(theme) !== 0

  let bg = is_dark_mode ? '#000' : '#aaa'
  let fg = is_dark_mode ? '#aaa' : '#000'

  add_style(`
  #autocomplete li {
    border: 2px dotted ${bg};
  }
  #autocomplete li.autocomplete-select {
    border: 2px solid ${fg};
  }`)
}

//parse number from human readable suffix
function num_from_suffix(n) {
  let base = 1
  if(n.charAt(n.length-1) === 'M')
    base = 1000000
  else if(n.charAt(n.length-1) === 'K')
    base = 1000
  else
    return Number.parseFloat(n)
  return Number.parseFloat(n.substring(0, n.length-1)) * base
}

//prevent tag edit textarea default events from hiding autocomplete
function key_up(e) {
  switch(e.key) {
    case 'ArrowDown':
    case 'PageDown':
    case 'PageUp':
    case 'ArrowUp':
      if(document.querySelector("#autocomplete").style.display !== 'block')
        break
      e.preventDefault()
      e.stopImmediatePropagation()
  }
}

function key_down(e) {
  switch(e.key) {
    case 'Tab':
    case 'Enter':
      let counts = document.querySelectorAll('#autocomplete span.item-count')
			if(counts.length < 1) {				document.querySelector('#autocomplete').children.item(selected_index || 0).click()

			}

      let greatest = 0
      let first = num_from_suffix(counts.item(0).innerText)
      let second = num_from_suffix(counts.item(1).innerText)

      if(first < second)
        greatest = 1

      if(selected_index > -1 || first < 1)
        greatest = selected_index
			//alert(counts.length + ' ' + first)
      //complete selected tag or greatest post count if unselected
      counts.item(greatest).parentNode.click()

      e.preventDefault()
      e.stopImmediatePropagation()
      break
    case 'ArrowDown':
    case 'PageDown':
    case 'PageUp':
    case 'ArrowUp':
      //break to allow cursor and selection movement when autocomplete is hidden
      if(document.querySelector("#autocomplete").style.display !== 'block')
        break
      let completions = document.querySelectorAll('#autocomplete li')

      selected_index += (e.key === 'ArrowUp' || e.key === 'PageUp') ? -1 : 1
      if(selected_index < 0)
        selected_index = completions.length - 1
      if(selected_index >= completions.length)
        selected_index = 0

      for(let c of completions)
        c.classList.remove('autocomplete-select')
      completions.item(selected_index).classList.add('autocomplete-select')
      e.preventDefault()
      e.stopImmediatePropagation()
      break
    default:
      selected_index = -1
      break
  }
}

function query_add_event(selector, event, func, cap=false){
  let q = document.querySelector(selector)
  if(q !== null)
    q.addEventListener(event, func, cap)
}

query_add_event("#tags", "keydown", key_down)
query_add_event("#post_tags", "keydown", key_down, true)
query_add_event("#post_tags", "keyup", key_up, true)