diff options
Diffstat (limited to 'src/content/follow.js')
-rw-r--r-- | src/content/follow.js | 149 |
1 files changed, 0 insertions, 149 deletions
diff --git a/src/content/follow.js b/src/content/follow.js deleted file mode 100644 index b1d2f5c..0000000 --- a/src/content/follow.js +++ /dev/null @@ -1,149 +0,0 @@ -import Hint from './hint'; -import HintKeyProducer from './hint-key-producer'; - -const DEFAULT_HINT_CHARSET = 'abcdefghijklmnopqrstuvwxyz'; - -export default class Follow { - constructor(doc) { - this.doc = doc; - this.hintElements = {}; - this.keys = []; - this.onActivatedCallbacks = []; - - let links = Follow.getTargetElements(doc); - - this.addHints(links); - - this.boundKeydown = this.handleKeydown.bind(this); - doc.addEventListener('keydown', this.boundKeydown); - } - - addHints(elements) { - let producer = new HintKeyProducer(DEFAULT_HINT_CHARSET); - Array.prototype.forEach.call(elements, (ele) => { - let keys = producer.produce(); - let hint = new Hint(ele, keys); - - this.hintElements[keys] = hint; - }); - } - - handleKeydown(e) { - let { keyCode } = e; - if (keyCode === KeyboardEvent.DOM_VK_ESCAPE) { - this.remove(); - return; - } else if (keyCode === KeyboardEvent.DOM_VK_ENTER || - keyCode === KeyboardEvent.DOM_VK_RETURN) { - let chars = Follow.codeChars(this.keys); - this.activate(this.hintElements[chars].target); - return; - } else if (Follow.availableKey(keyCode)) { - this.keys.push(keyCode); - } else if (keyCode === KeyboardEvent.DOM_VK_BACK_SPACE || - keyCode === KeyboardEvent.DOM_VK_DELETE) { - this.keys.pop(); - } - - e.stopPropagation(); - e.preventDefault(); - - this.refreshKeys(); - } - - refreshKeys() { - let chars = Follow.codeChars(this.keys); - let shown = Object.keys(this.hintElements).filter((key) => { - return key.startsWith(chars); - }); - let hidden = Object.keys(this.hintElements).filter((key) => { - return !key.startsWith(chars); - }); - if (shown.length === 0) { - this.remove(); - return; - } else if (shown.length === 1) { - this.remove(); - this.activate(this.hintElements[chars].target); - } - - shown.forEach((key) => { - this.hintElements[key].show(); - }); - hidden.forEach((key) => { - this.hintElements[key].hide(); - }); - } - - remove() { - this.doc.removeEventListener('keydown', this.boundKeydown); - Object.keys(this.hintElements).forEach((key) => { - this.hintElements[key].remove(); - }); - } - - activate(element) { - this.onActivatedCallbacks.forEach(f => f(element)); - } - - onActivated(f) { - this.onActivatedCallbacks.push(f); - } - - static availableKey(keyCode) { - return ( - KeyboardEvent.DOM_VK_0 <= keyCode && keyCode <= KeyboardEvent.DOM_VK_9 || - KeyboardEvent.DOM_VK_A <= keyCode && keyCode <= KeyboardEvent.DOM_VK_Z - ); - } - - static isNumericKey(code) { - return KeyboardEvent.DOM_VK_0 <= code && code <= KeyboardEvent.DOM_VK_9; - } - - static isAlphabeticKey(code) { - return KeyboardEvent.DOM_VK_A <= code && code <= KeyboardEvent.DOM_VK_Z; - } - - static codeChars(codes) { - const CHARCODE_ZERO = '0'.charCodeAt(0); - const CHARCODE_A = 'a'.charCodeAt(0); - - let chars = ''; - - for (let code of codes) { - if (Follow.isNumericKey(code)) { - chars += String.fromCharCode( - code - KeyboardEvent.DOM_VK_0 + CHARCODE_ZERO); - } else if (Follow.isAlphabeticKey(code)) { - chars += String.fromCharCode( - code - KeyboardEvent.DOM_VK_A + CHARCODE_A); - } - } - return chars; - } - - static inWindow(window, element) { - let { - top, left, bottom, right - } = element.getBoundingClientRect(); - return ( - top >= 0 && left >= 0 && - bottom <= (window.innerHeight || document.documentElement.clientHeight) && - right <= (window.innerWidth || document.documentElement.clientWidth) - ); - } - - static getTargetElements(doc) { - let all = doc.querySelectorAll('a,button,input,textarea'); - let filtered = Array.prototype.filter.call(all, (element) => { - let style = window.getComputedStyle(element); - return style.display !== 'none' && - style.visibility !== 'hidden' && - element.type !== 'hidden' && - element.offsetHeight > 0 && - Follow.inWindow(window, element); - }); - return filtered; - } -} |