Skip to content

Commit

Permalink
refactor(focus): use handleEvent
Browse files Browse the repository at this point in the history
  • Loading branch information
bigopon authored and jdanyow committed Sep 23, 2017
1 parent 68838e1 commit d0310d2
Showing 1 changed file with 78 additions and 79 deletions.
157 changes: 78 additions & 79 deletions src/focus.js
Original file line number Diff line number Diff line change
@@ -1,79 +1,78 @@
import {customAttribute} from 'aurelia-templating';
import {bindingMode} from 'aurelia-binding';
import {inject} from 'aurelia-dependency-injection';
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.
*/
@customAttribute('focus', bindingMode.twoWay)
@inject(DOM.Element, TaskQueue)
export class Focus {
/**
* 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;

this.focusListener = e => {
this.value = true;
};
this.blurListener = e => {
if (DOM.activeElement !== this.element) {
this.value = false;
}
};
}

/**
* Invoked everytime the bound value changes.
* @param newValue The new value.
*/
valueChanged(newValue) {
if (this.isAttached) {
this._apply();
} else {
this.needsApply = true;
}
}

_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.focusListener);
this.element.addEventListener('blur', this.blurListener);
}

/**
* Invoked when the attribute is detached from the DOM.
*/
detached() {
this.isAttached = false;
this.element.removeEventListener('focus', this.focusListener);
this.element.removeEventListener('blur', this.blurListener);
}
}
import {customAttribute} from 'aurelia-templating';
import {bindingMode} from 'aurelia-binding';
import {inject} from 'aurelia-dependency-injection';
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.
*/
@customAttribute('focus', bindingMode.twoWay)
@inject(DOM.Element, TaskQueue)
export class Focus {
/**
* 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.
* @param newValue The new value.
*/
valueChanged(newValue) {
if (this.isAttached) {
this._apply();
} else {
this.needsApply = true;
}
}

_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;
}
}
}

0 comments on commit d0310d2

Please sign in to comment.