keeweb/app/scripts/views/auto-type/auto-type-hint-view.js

85 lines
2.7 KiB
JavaScript
Raw Normal View History

2019-09-16 20:42:33 +02:00
import { View } from 'framework/views/view';
2019-09-15 14:16:32 +02:00
import { Links } from 'const/links';
import { Timeouts } from 'const/timeouts';
import { Features } from 'util/features';
2019-09-15 20:17:08 +02:00
import template from 'templates/auto-type-hint.hbs';
2016-04-26 21:40:18 +02:00
2019-09-15 20:17:08 +02:00
class AutoTypeHintView extends View {
parent = 'body';
2016-04-26 21:40:18 +02:00
2019-09-15 20:17:08 +02:00
template = template;
2016-04-26 21:40:18 +02:00
2019-09-15 20:17:08 +02:00
events = {};
constructor(model) {
super(model);
this.input = model.input;
2016-04-26 21:40:18 +02:00
this.bodyClick = this.bodyClick.bind(this);
this.inputBlur = this.inputBlur.bind(this);
$('body').on('click', this.bodyClick);
this.input.addEventListener('blur', this.inputBlur);
2019-09-16 20:54:14 +02:00
this.once('remove', () => {
$('body').off('click', this.bodyClick);
this.input.removeEventListener('blur', this.inputBlur);
});
2019-09-15 20:17:08 +02:00
}
2016-04-26 21:40:18 +02:00
2019-08-18 10:17:09 +02:00
render() {
2019-09-15 20:17:08 +02:00
super.render({
2019-09-15 08:11:11 +02:00
cmd: Features.isMac ? 'command' : 'ctrl',
hasCtrl: Features.isMac,
2016-04-26 21:40:18 +02:00
link: Links.AutoType
});
2017-01-31 07:50:28 +01:00
const rect = this.input.getBoundingClientRect();
2016-04-26 21:40:18 +02:00
this.$el.appendTo(document.body).css({
2019-08-16 23:05:39 +02:00
left: rect.left,
top: rect.bottom + 1,
width: rect.width
2016-04-26 21:40:18 +02:00
});
2017-01-31 07:50:28 +01:00
const selfRect = this.$el[0].getBoundingClientRect();
const bodyRect = document.body.getBoundingClientRect();
2016-04-26 21:40:18 +02:00
if (selfRect.bottom > bodyRect.bottom) {
this.$el.css('height', selfRect.height + bodyRect.bottom - selfRect.bottom - 1);
}
2019-09-15 20:17:08 +02:00
}
2016-04-26 21:40:18 +02:00
2019-08-18 10:17:09 +02:00
bodyClick(e) {
2016-04-26 21:40:18 +02:00
if (this.removeTimer) {
clearTimeout(this.removeTimer);
this.removeTimer = null;
}
if (e.target === this.input) {
e.stopPropagation();
return;
}
if ($.contains(this.$el[0], e.target) || e.target === this.$el[0]) {
e.stopPropagation();
if (e.target.tagName.toLowerCase() === 'a' && !e.target.href) {
2017-01-31 07:50:28 +01:00
let text = $(e.target).text();
2016-04-26 21:40:18 +02:00
if (text[0] !== '{') {
text = text.split(' ')[0];
}
this.insertText(text);
}
this.input.focus();
} else {
this.remove();
}
2019-09-15 20:17:08 +02:00
}
2016-04-26 21:40:18 +02:00
2019-08-18 10:17:09 +02:00
inputBlur() {
2016-04-26 21:40:18 +02:00
if (!this.removeTimer) {
2019-01-06 15:38:03 +01:00
this.removeTimer = setTimeout(this.remove.bind(this), Timeouts.DropDownClickWait);
2016-04-26 21:40:18 +02:00
}
2019-09-15 20:17:08 +02:00
}
2016-04-26 21:40:18 +02:00
2019-08-18 10:17:09 +02:00
insertText(text) {
2017-01-31 07:50:28 +01:00
const pos = this.input.selectionEnd || this.input.value.length;
2016-04-26 21:40:18 +02:00
this.input.value = this.input.value.substr(0, pos) + text + this.input.value.substr(pos);
this.input.selectionStart = this.input.selectionEnd = pos + text.length;
this.input.dispatchEvent(new Event('input', { bubbles: true }));
2016-04-26 21:40:18 +02:00
}
2019-09-15 20:17:08 +02:00
}
2016-04-26 21:40:18 +02:00
2019-09-15 14:16:32 +02:00
export { AutoTypeHintView };