Source: control2/input/Text.js

(function() {
    /**
     * @typedef {Help4.control2.Control.Params} Help4.control2.input.Text.Params
     * @property {string} [tag = 'input'] - input <html> tag
     * @property {?string} [type = null] - input type (search, date, checkbox etc...)
     * @property {?string} [ariaAutocomplete = null] - aria-autocomplete attribute
     * @property {?string} [ariaHaspopup = null] - aria-haspopup attribute
     * @property {?string} [ariaControls = null] - aria-controls attribute
     * @property {?string} [autoComplete = null] - autocomplete attribute for search
     * @property {?string} [autoCorrect = null] - autocorrect attribute for search
     * @property {string} [value = ''] - value of the field
     * @property {string} [placeholder = ''] - placeholder text
     */

    /**
     * Creates an input field
     * @augments Help4.control2.Control
     * @property {?string} type - input type (search, date, checkbox etc...)
     * @property {?string} ariaAutocomplete - aria-autocomplete attribute
     * @property {?string} ariaHaspopup - aria-haspopup attribute
     * @property {?string} ariaControls - aria-controls attribute
     * @property {?string} autoComplete - autocomplete attribute for search
     * @property {?string} autoCorrect - autocorrect attribute for search
     * @property {string} value - value of the field
     * @property {string} placeholder - placeholder text
     */
    Help4.control2.input.Text = class extends Help4.control2.Control {
        /**
         * @override
         * @param {Help4.control2.input.Text.Params} [params]
         * @param {Help4.jscore.ControlBase.Params} [derived]
         */
        constructor(params, derived) {
            const css = params.tag === 'textarea' ? 'textarea' : 'field';
            const {TYPES: T, TEXT_TYPES: TT} = Help4.jscore.ControlBase;

            super(params, {
                params: {
                    tag:              {init: 'input'},

                    type:             {type: T.string_null},
                    autoComplete:     {type: T.string_null},
                    autoCorrect:      {type: T.string_null},
                    value:            {type: T.string},
                    placeholder:      {type: T.string},

                    ariaAutocomplete: {type: T.string_null},
                    ariaHaspopup:     {type: T.string_null},
                    ariaControls:     {type: T.string_null},
                },
                config: {
                    css: `control-input ${css}`
                },
                texts: {
                    placeholder: TT.placeholder
                },
                statics: {
                    _input: {destroy: false}
                },
                derived
            });
        }

        /**
         * @override
         * @param {HTMLElement} dom - control DOM
         */
        _onDomCreated(dom) {
            super._onDomCreated(dom);

            const {value, placeholder, type, autoComplete: autocomplete, autoCorrect: autocorrect} = this;
            Help4.Element.setAttribute(dom, {placeholder, value, type, autocomplete, autocorrect});
            this._applyTextAttribute(dom, 'placeholder', !!placeholder);

            Help4.Event.observe(dom, {
                type: 'simple',
                callback: event => _onEvent.call(this, event),
                scope: this
            });
        }

        /** @override  */
        _onBeforeDestroy() {
            Help4.Event.stopObserving(this.getDom());
        }

        /**
         * @override
         * @param {Help4.jscore.ControlBase.PropertyChangeEvent} event - the change event
         */
        _applyPropertyToDom({name, value, oldValue}) {
            switch (name) {
                case 'ariaAutocomplete':
                case 'ariaHaspopup':
                case 'ariaControls':
                    const o = {};
                    o[name] = value;
                    Help4.Element.setAttribute(this.getDom(), o);
                    break;

                case 'value':
                    this.getDom().value = value;
                    break;

                default:
                    super._applyPropertyToDom({name, value, oldValue});
                    break;
            }
        }
    }

    /**
     * @memberof Help4.control2.input.Text#
     * @param {Object} event - event triggered from input field
     * @private
     */
    function _onEvent(event) {
        if (Help4.includes(['keyup', 'paste', 'input'], event.type)) {
            // delay in order to get the correct changes from dom after paste event using mouse
            setTimeout(() => {
                if (this.isDestroyed()) return;

                const key = Help4.service.HotkeyService.getKey(event);
                if (key === 'enter') {
                    this._fireEvent({type: 'enter'});
                } else {
                    this.value = this.getDom().value;
                    this._fireEvent({type: 'change', data: event});
                }
            }, 1);
        }
    }
})();