aboutsummaryrefslogtreecommitdiff
path: root/src/content/components/common/input.js
diff options
context:
space:
mode:
authorShin'ya Ueoka <ueokande@i-beam.org>2017-10-15 09:02:09 +0900
committerShin'ya Ueoka <ueokande@i-beam.org>2017-10-15 09:04:00 +0900
commit4c9d0433a6ac851e72d50d6fb0451baa9d35fd35 (patch)
tree5b831137fe327e94fd73339e2b395bfe3e98961c /src/content/components/common/input.js
parent042aa94936c9114f0a0fd05fb0a91df8f5565ecd (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.js72
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() === '');
+ }
+}