Advertisement
Guest User

Untitled

a guest
Mar 17th, 2019
93
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.22 KB | None | 0 0
  1. function createHintSequences(n) {
  2. let hints = 'asdfghjklzxcvbnmqwertyuiop'.split('')
  3. while (hints.length < n)
  4. hints = hints.slice(1).concat(hints.map(h => hints[0] + h))
  5. return hints
  6. }
  7.  
  8. function createHintElement(rect, innerHTML) {
  9. const hintElement = document.createElement('span')
  10. Object.assign(hintElement.style, {
  11. position: 'absolute',
  12. left: `${window.scrollX + rect.left}px`,
  13. top: `${window.scrollY + rect.top}px`,
  14. zIndex: 10000,
  15. color: '#302505',
  16. backgroundColor: '#ffd76e',
  17. boxShadow: '2px 2px 1px rgba(0,0,0,0.25)',
  18. padding: '2px',
  19. fontSize: '8pt',
  20. fontWeight: '500',
  21. textTransform: 'uppercase',
  22. border: '1px solid #ad810c',
  23. borderRadius: '2px',
  24. textAlign: 'center',
  25. })
  26. hintElement.innerHTML = innerHTML
  27. document.body.appendChild(hintElement)
  28. return hintElement
  29. }
  30.  
  31. function getTargetElements() {
  32. return Array.from(document.body.querySelectorAll([
  33. 'a',
  34. 'button',
  35. 'textarea',
  36. 'select',
  37. 'input:not([type=hidden])',
  38. '[contenteditable=true]',
  39. '[role=link]',
  40. '[role=button]',
  41. '[role=checkbox]',
  42. '[role=textbox]',
  43. ].join(','))).filter(element => {
  44. const rect = element.getBoundingClientRect()
  45. return rect.height && rect.width &&
  46. window.scrollY + rect.bottom >= window.scrollY &&
  47. window.scrollY + rect.top <= window.scrollY + window.innerHeight
  48. })
  49. }
  50.  
  51. function startHintMode(isNewTab) {
  52. const targetElements = getTargetElements()
  53. const hintSequences = createHintSequences(targetElements.length)
  54. const hintElements = targetElements.map((targetElement, i) =>
  55. createHintElement(targetElement.getBoundingClientRect(), hintSequences[i]))
  56. const input = document.createElement('input')
  57. input.placeholder = 'Type a sequence'
  58. Object.assign(input.style, {position: 'fixed', left: 0, bottom: 0})
  59. input.addEventListener('blur', () => {
  60. document.body.removeChild(input)
  61. for (const hintElement of hintElements)
  62. document.body.removeChild(hintElement)
  63. })
  64. input.addEventListener('input', () => {
  65. for (let i = 0; i < hintElements.length; i++) {
  66. if (hintSequences[i] === input.value) {
  67. input.blur()
  68. if (isNewTab && targetElements[i].href) {
  69. window.open(targetElements[i].href)
  70. } else {
  71. targetElements[i].focus()
  72. targetElements[i].click()
  73. }
  74. } else if (hintSequences[i].startsWith(input.value)) {
  75. hintElements[i].style.display = 'block'
  76. hintElements[i].innerHTML = hintSequences[i].slice(input.value.length)
  77. } else {
  78. hintElements[i].style.display = 'none'
  79. }
  80. }
  81. })
  82. document.body.appendChild(input)
  83. input.focus()
  84. }
  85.  
  86. window.addEventListener('keydown', e => {
  87. if (window.getSelection().type === 'None') {
  88. if (!e.ctrlKey && e.key.toLowerCase() === 'f') {
  89. e.preventDefault()
  90. startHintMode(e.shiftKey)
  91. }
  92. } else if (e.key === 'Escape') {
  93. e.target.blur()
  94. }
  95. })
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement