1 | import {customAttribute} from 'aurelia-templating';
|
2 | import {bindingMode} from 'aurelia-binding';
|
3 | import {TaskQueue} from 'aurelia-task-queue';
|
4 | import {DOM} from 'aurelia-pal';
|
5 |
|
6 |
|
7 |
|
8 |
|
9 | @customAttribute('focus', bindingMode.twoWay)
|
10 | export class Focus {
|
11 | |
12 |
|
13 |
|
14 | element: any;
|
15 | |
16 |
|
17 |
|
18 | taskQueue: any;
|
19 | |
20 |
|
21 |
|
22 | isAttached: boolean;
|
23 | |
24 |
|
25 |
|
26 | needsApply: boolean;
|
27 | |
28 |
|
29 |
|
30 | value: any;
|
31 |
|
32 |
|
33 | static inject() {
|
34 | return [DOM.Element, TaskQueue];
|
35 | }
|
36 | |
37 |
|
38 |
|
39 |
|
40 |
|
41 | constructor(element, taskQueue) {
|
42 | this.element = element;
|
43 | this.taskQueue = taskQueue;
|
44 | this.isAttached = false;
|
45 | this.needsApply = false;
|
46 | }
|
47 |
|
48 | |
49 |
|
50 |
|
51 | valueChanged() {
|
52 | if (this.isAttached) {
|
53 | this._apply();
|
54 | } else {
|
55 | this.needsApply = true;
|
56 | }
|
57 | }
|
58 |
|
59 | |
60 |
|
61 |
|
62 | _apply() {
|
63 | if (this.value) {
|
64 | this.taskQueue.queueMicroTask(() => {
|
65 | if (this.value) {
|
66 | this.element.focus();
|
67 | }
|
68 | });
|
69 | } else {
|
70 | this.element.blur();
|
71 | }
|
72 | }
|
73 |
|
74 | |
75 |
|
76 |
|
77 | attached() {
|
78 | this.isAttached = true;
|
79 | if (this.needsApply) {
|
80 | this.needsApply = false;
|
81 | this._apply();
|
82 | }
|
83 | this.element.addEventListener('focus', this);
|
84 | this.element.addEventListener('blur', this);
|
85 | }
|
86 |
|
87 | |
88 |
|
89 |
|
90 | detached() {
|
91 | this.isAttached = false;
|
92 | this.element.removeEventListener('focus', this);
|
93 | this.element.removeEventListener('blur', this);
|
94 | }
|
95 |
|
96 | handleEvent(e) {
|
97 | if (e.type === 'focus') {
|
98 | this.value = true;
|
99 | } else if (DOM.activeElement !== this.element) {
|
100 | this.value = false;
|
101 | }
|
102 | }
|
103 | }
|