aurelia-templating-resources
Version:
A standard set of behaviors, converters and other resources for use with the Aurelia templating library.
104 lines (96 loc) • 2.19 kB
text/typescript
import {customAttribute} from 'aurelia-templating';
import {bindingMode} from 'aurelia-binding';
import {TaskQueue} from 'aurelia-task-queue';
import {DOM} from 'aurelia-pal';
/**
* CustomAttribute that binds provided DOM element's focus attribute with a property on the viewmodel.
*/
export class Focus {
/**
*@internal
*/
element: any;
/**
*@internal
*/
taskQueue: any;
/**
*@internal
*/
isAttached: boolean;
/**
*@internal
*/
needsApply: boolean;
/**
*@internal
*/
value: any;
/**@internal */
static inject() {
return [DOM.Element, TaskQueue];
}
/**
* Creates an instance of Focus.
* @paramelement Target element on where attribute is placed on.
* @param taskQueue The TaskQueue instance.
*/
constructor(element, taskQueue) {
this.element = element;
this.taskQueue = taskQueue;
this.isAttached = false;
this.needsApply = false;
}
/**
* Invoked everytime the bound value changes.
*/
valueChanged() {
if (this.isAttached) {
this._apply();
} else {
this.needsApply = true;
}
}
/**
* @internal
*/
_apply() {
if (this.value) {
this.taskQueue.queueMicroTask(() => {
if (this.value) {
this.element.focus();
}
});
} else {
this.element.blur();
}
}
/**
* Invoked when the attribute is attached to the DOM.
*/
attached() {
this.isAttached = true;
if (this.needsApply) {
this.needsApply = false;
this._apply();
}
this.element.addEventListener('focus', this);
this.element.addEventListener('blur', this);
}
/**
* Invoked when the attribute is detached from the DOM.
*/
detached() {
this.isAttached = false;
this.element.removeEventListener('focus', this);
this.element.removeEventListener('blur', this);
}
handleEvent(e) {
if (e.type === 'focus') {
this.value = true;
} else if (DOM.activeElement !== this.element) {
this.value = false;
}
}
}