diff options
author | Shin'ya Ueoka <ueokande@i-beam.org> | 2017-10-15 09:02:09 +0900 |
---|---|---|
committer | Shin'ya Ueoka <ueokande@i-beam.org> | 2017-10-15 09:04:00 +0900 |
commit | 4c9d0433a6ac851e72d50d6fb0451baa9d35fd35 (patch) | |
tree | 5b831137fe327e94fd73339e2b395bfe3e98961c /src/content/components/common/input.js | |
parent | 042aa94936c9114f0a0fd05fb0a91df8f5565ecd (diff) |
make top-content component and frame-content component
Diffstat (limited to 'src/content/components/common/input.js')
-rw-r--r-- | src/content/components/common/input.js | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/src/content/components/common/input.js b/src/content/components/common/input.js new file mode 100644 index 0000000..df09894 --- /dev/null +++ b/src/content/components/common/input.js @@ -0,0 +1,72 @@ +export default class InputComponent { + constructor(target) { + this.pressed = {}; + this.onKeyListeners = []; + + target.addEventListener('keypress', this.onKeyPress.bind(this)); + target.addEventListener('keydown', this.onKeyDown.bind(this)); + target.addEventListener('keyup', this.onKeyUp.bind(this)); + } + + update() { + } + + onKey(cb) { + this.onKeyListeners.push(cb); + } + + onKeyPress(e) { + if (this.pressed[e.key] && this.pressed[e.key] !== 'keypress') { + return; + } + this.pressed[e.key] = 'keypress'; + this.capture(e); + } + + onKeyDown(e) { + if (this.pressed[e.key] && this.pressed[e.key] !== 'keydown') { + return; + } + this.pressed[e.key] = 'keydown'; + this.capture(e); + } + + onKeyUp(e) { + delete this.pressed[e.key]; + } + + capture(e) { + if (this.fromInput(e)) { + if (e.key === 'Escape' && e.target.blur) { + e.target.blur(); + } + return; + } + if (['Shift', 'Control', 'Alt', 'OS'].includes(e.key)) { + // pressing only meta key is ignored + return; + } + + let stop = false; + for (let listener of this.onKeyListeners) { + stop = stop || listener(e.key, e.ctrlKey); + if (stop) { + break; + } + } + if (stop) { + e.preventDefault(); + e.stopPropagation(); + } + } + + fromInput(e) { + return e.target instanceof HTMLInputElement || + e.target instanceof HTMLTextAreaElement || + e.target instanceof HTMLSelectElement || + e.target instanceof HTMLElement && + e.target.hasAttribute('contenteditable') && ( + e.target.getAttribute('contenteditable').toLowerCase() === 'true' || + e.target.getAttribute('contenteditable').toLowerCase() === ''); + } +} |