discourse/app/assets/javascripts/select-kit/mixins/events.js.es6

244 lines
6.6 KiB
Plaintext
Raw Normal View History

export default Ember.Mixin.create({
init() {
this._super();
this.keys = {
TAB: 9,
ENTER: 13,
ESC: 27,
UP: 38,
DOWN: 40,
BACKSPACE: 8,
};
},
willDestroyElement() {
this._super();
$(document)
.off("mousedown.select-kit")
.off("touchstart.select-kit");
this.$header()
.off("focus.select-kit")
.off("blur.select-kit")
.off("keypress.select-kit")
.off("keydown.select-kit");
this.$filterInput()
.off("change.select-kit")
.off("keydown.select-kit")
2017-11-21 23:59:03 +08:00
.off("keypress.select-kit")
.off("focus.select-kit")
.off("focusin.select-kit");
},
didInsertElement() {
this._super();
$(document)
.on("mousedown.select-kit, touchstart.select-kit", event => {
if (Ember.isNone(this.get("element"))) return;
if (this.get("element").contains(event.target)) return;
this.didClickOutside(event);
});
this.$header()
.on("blur.select-kit", () => {
if (this.get("isExpanded") === false && this.get("isFocused") === true) {
this.close();
}
})
.on("focus.select-kit", (event) => {
this.set("isFocused", true);
this._destroyEvent(event);
})
.on("keydown.select-kit", (event) => {
const keyCode = event.keyCode || event.which;
if (document.activeElement !== this.$header()[0]) return event;
if (keyCode === this.keys.TAB) this.tabFromHeader(event);
if (keyCode === this.keys.BACKSPACE) this.backspaceFromHeader(event);
if (keyCode === this.keys.ESC) this.escapeFromHeader(event);
if (keyCode === this.keys.ENTER) this.enterFromHeader(event);
if ([this.keys.UP, this.keys.DOWN].includes(keyCode)) this.upAndDownFromHeader(event);
return event;
})
.on("keypress.select-kit", (event) => {
const keyCode = event.keyCode || event.which;
if (keyCode === this.keys.ENTER) { return true; }
this.expand(event);
if (this.get("filterable") === true || this.get("autoFilterable")) {
this.set("renderedFilterOnce", true);
}
Ember.run.schedule("afterRender", () => {
let newVal = this.$filterInput().val();
const start = this.$filterInput()[0].selectionStart;
const end = this.$filterInput()[0].selectionEnd;
if (!Ember.isNone(start) && !Ember.isNone(end)) {
newVal = newVal.substr(0, start) +
String.fromCharCode(keyCode) +
newVal.substr(end, newVal.length);
} else {
newVal = newVal + String.fromCharCode(keyCode);
}
this.$filterInput().focus().val(newVal);
});
return false;
});
this.$filterInput()
.on("change.select-kit", (event) => {
this.send("onFilter", $(event.target).val());
})
.on("focus.select-kit focusin.select-kit", (event) => {
this.set("isFocused", true);
this._destroyEvent(event);
})
2017-11-21 23:59:03 +08:00
.on("keypress.select-kit", (event) => {
event.stopPropagation();
})
.on("keydown.select-kit", (event) => {
const keyCode = event.keyCode || event.which;
if (keyCode === this.keys.TAB) this.tabFromFilter(event);
if (keyCode === this.keys.ESC) this.escapeFromFilter(event);
if (keyCode === this.keys.ENTER) this.enterFromFilter(event);
if ([this.keys.UP, this.keys.DOWN].includes(keyCode)) this.upAndDownFromFilter(event);
});
},
didPressTab(event) {
if (this.get("isExpanded") === false) {
this.unfocus(event);
} else if (this.$highlightedRow().length === 1) {
this._destroyEvent(event);
Ember.run.throttle(this, this._rowClick, this.$highlightedRow(), 150, 150, true);
this.focus(event);
} else {
this._destroyEvent(event);
this.unfocus(event);
}
return true;
},
didPressEscape(event) {
this._destroyEvent(event);
this.unfocus(event);
},
didPressUpAndDownArrows(event) {
this._destroyEvent(event);
const keyCode = event.keyCode || event.which;
const $rows = this.$rows();
if (this.get("isExpanded") === false) {
this.expand(event);
if (this.$selectedRow().length === 1) {
this._highlightRow(this.$selectedRow());
return;
}
}
if ($rows.length <= 0) { return; }
if ($rows.length === 1) {
this._rowSelection($rows, 0);
return;
}
const direction = keyCode === 38 ? -1 : 1;
Ember.run.throttle(this, this._moveHighlight, direction, $rows, 32);
},
didPressBackspace(event) {
this._destroyEvent(event);
this.expand(event);
if (this.$filterInput().is(":visible")) {
this.$filterInput().focus().trigger(event).trigger("change");
}
},
didPressEnter(event) {
this._destroyEvent(event);
if (this.get("isExpanded") === false) {
this.expand(event);
} else if (this.$highlightedRow().length === 1) {
Ember.run.throttle(this, this._rowClick, this.$highlightedRow(), 150, true);
}
},
didClickOutside(event) {
if ($(event.target).parents(".select-kit").length === 1) {
this.close(event);
return false;
}
2017-11-22 00:37:13 +08:00
this.close(event);
return;
},
// make sure we dont propagate a click outside component
// to avoid closing a modal containing the component for example
click(event) {
this._destroyEvent(event);
},
tabFromHeader(event) { this.didPressTab(event); },
tabFromFilter(event) { this.didPressTab(event); },
escapeFromHeader(event) { this.didPressEscape(event); },
escapeFromFilter(event) { this.didPressEscape(event); },
upAndDownFromHeader(event) { this.didPressUpAndDownArrows(event); },
upAndDownFromFilter(event) { this.didPressUpAndDownArrows(event); },
backspaceFromHeader(event) { this.didPressBackspace(event); },
enterFromHeader(event) { this.didPressEnter(event); },
enterFromFilter(event) { this.didPressEnter(event); },
_moveHighlight(direction, $rows) {
const currentIndex = $rows.index(this.$highlightedRow());
let nextIndex = currentIndex + direction;
if (nextIndex < 0) {
nextIndex = $rows.length - 1;
} else if (nextIndex >= $rows.length) {
nextIndex = 0;
}
this._rowSelection($rows, nextIndex);
},
_rowClick($row) { $row.click(); },
_rowSelection($rows, nextIndex) {
const highlightableValue = $rows.eq(nextIndex).attr("data-value");
const $highlightableRow = this.$findRowByValue(highlightableValue);
this._highlightRow($highlightableRow);
},
_highlightRow($row) {
Ember.run.schedule("afterRender", () => {
$row.trigger("mouseover").focus();
this.focus();
});
}
});