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.

Vous devrez installer une extension telle que Tampermonkey, Greasemonkey ou Violentmonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey ou Violentmonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey ou Userscripts pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey pour installer ce script.

Vous devrez installer une extension de gestionnaire de script utilisateur pour installer ce script.

(J'ai déjà un gestionnaire de scripts utilisateur, laissez-moi l'installer !)

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

(J'ai déjà un gestionnaire de style utilisateur, laissez-moi l'installer!)

// ==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)