import { Key } from "stb-key"; import { Focus } from "stb-shadow"; import { diffNode } from "../util"; export function focus(target) { // Saves a reference to the primitive constructor var original = target; const _subscribeToEvents = original.prototype.subscribeToEvents || function () { }; const _autoFocus = original.prototype.autoFocus || function () { }; const _componentFocusDidUpdate = original.prototype.componentFocusDidUpdate || function () { }; const _render = original.prototype.render || function () { }; // Utility method used to generate an instance of a class function construct(constructor, args) { var c: any = function () { return constructor.apply(this, args); } c.prototype = constructor.prototype; return new c(); } // New constructor behavior var f: any = function (...args) { // console.log('new:' + original.name); original.prototype.render = function (...args) { let vnode = _render.apply(this, args); vnode = diffNode.apply(this, [vnode]); return vnode; } original.prototype.subscribeToEvents = function (subs) { let r = _subscribeToEvents.apply(this, [subs]); if (false !== r && undefined !== this.identCode) { subs.onkeydown((e) => { if (Key.Left === e.keyCode || Key.Up === e.keyCode || Key.Right === e.keyCode || Key.Down === e.keyCode) { this.autoFocus(e.keyCode); } else if (Key.Enter === e.keyCode) { if (this.onEnter) this.onEnter(e.data || {}); } else if (Key.Backspace === e.keyCode) { if (this.onBackspace) this.onBackspace(); } }); } } original.prototype.autoFocus = function (keyCode) { let r = _autoFocus.apply(this, [keyCode]); if (r !== false) { let f = Focus.center(this.tags.getAll(), this.index, keyCode); if (f) { this.setFocus(f.index); if (this.onChange) this.onChange(true, keyCode); } else { if (this.onChange) this.onChange(false, keyCode); } } } original.prototype.componentFocusDidUpdate = function ({ from }) { let r = _componentFocusDidUpdate.apply(this, [{ from }]); if (r !== false) { if (!this.tags || !this.tags.length || this.tags.length <= this.index) { return; } this.tags.removeClass("active").removeClass("focus"); if (this.identCode !== this.event.getTargetIdentCode() || 'blur' === from) { this.tags.eq(this.index).addClass("active"); } else if ('blur' !== from) { this.tags.eq(this.index).addClass("focus"); } } } return construct(original, args); } // Duplicate the prototype so that the instanceof operation works f.prototype = original.prototype; // Returns the new constructor return f; }