_onKeyup(e) {
        if (this.compositioning) {
            return;
        }
        this.isEditing = false;
        this.keydownEventCounter = 0; // Reset the keydown events counter

        if (this.formulaMode) {
            return;
        }

        if (this.settings.isCancellable && this.eventKey === AutoNumericEnum.keyName.Esc) {
            // If the user wants to cancel its modifications, we drop the 'keyup' event for the Esc key
            e.preventDefault();

            return;
        }

        // Manage the undo/redo events
        this._updateEventKeyInfo(e); // Fixes #761, where the Ctrl key is not correctly detected during undo/redo since this.eventKey was not updated from 'Z' to 'Control'
        if (this.eventKey === AutoNumericEnum.keyName.Z || this.eventKey === AutoNumericEnum.keyName.z) {
            if (e.ctrlKey && e.shiftKey) {
                // Redo
                e.preventDefault();
                this._historyTableRedo();
                this._triggerEvent(AutoNumeric.events.native.input, e.target); //TODO instead of adding the event here, generate it from the `_historyTableRedo()` function?
                this.onGoingRedo = true;

                return;
            } else if (e.ctrlKey && !e.shiftKey) {
                if (this.onGoingRedo) {
                    // Prevent an 'undo' to be launched when releasing the shift key before the ctrl key after a 'redo' shortcut
                    this.onGoingRedo = false;
                } else {
                    e.preventDefault();
                    // Undo
                    this._historyTableUndo();
                    this._triggerEvent(AutoNumeric.events.native.input, e.target); //TODO instead of adding the event here, generate it from the `_historyTableRedo()` function?

                    return;
                }
            }
        } else if ((this.eventKey === AutoNumericEnum.keyName.Y || this.eventKey === AutoNumericEnum.keyName.y) && e.ctrlKey) {
            // Redo
            e.preventDefault();
            this._historyTableRedo();
            this._triggerEvent(AutoNumeric.events.native.input, e.target); //TODO instead of adding the event here, generate it from the `_historyTableRedo()` function?
            this.onGoingRedo = true;

            return;
        }

        if (this.onGoingRedo && (e.ctrlKey || e.shiftKey)) {
            // Special case where if the user has entered `Control+Shift+z`, then release `z`, keeping `Control` or `Shift` pressed, then `this.onGoingRedo` is never changed back to `false` when the user release `Control` or `Shift`
            this.onGoingRedo = false;
        }

        // Manage the Cut event
        if ((e.ctrlKey || e.metaKey) && (this.eventKey === AutoNumericEnum.keyName.X || this.eventKey === AutoNumericEnum.keyName.x)) {
            // Save the caret position at the start of the selection
            const caretPosition = AutoNumericHelper.getElementSelection(this.domElement).start;
            // Convert the remaining 'formatted' numbers in a Js number
            const cutNumber = this.constructor._toNumericValue(AutoNumericHelper.getElementValue(e.target), this.settings);
            // Try to set that value with `set()`
            this.set(cutNumber);
            // Set back the initial caret position
            this._setCaretPosition(caretPosition);
        }

        // Manage the reformat when hovered with the Alt key pressed
        if (this.eventKey === AutoNumericEnum.keyName.Alt && this.settings.unformatOnHover && this.hoveredWithAlt) {
            this.constructor._reformatAltHovered(this);

            return;
        }

        // Manage the Backspace and Delete keys when used in combination with the control key (fix #656)
        if ((e.ctrlKey || e.metaKey) && (this.eventKey === AutoNumericEnum.keyName.Backspace || this.eventKey === AutoNumericEnum.keyName.Delete)) {
            const targetValue = AutoNumericHelper.getElementValue(e.target);
            this._setRawValue(this._formatOrUnformatOther(false, targetValue));

            return;
        }

        this._updateInternalProperties(e);

        const skip = this._processNonPrintableKeysAndShortcuts(e);
        delete this.valuePartsBeforePaste;
        const targetValue = AutoNumericHelper.getElementValue(e.target);
        if (skip || targetValue === '' && this.initialValueOnFirstKeydown === '') { // If the user enters skippable keys, or keeps deleting/backspacing into the empty input, no 'formatted' event are sent (cf. issue #621)
            return;
        }

        // Added to properly place the caret when only the currency sign is present
        if (targetValue === this.settings.currencySymbol) {
            if (this.settings.currencySymbolPlacement === AutoNumeric.options.currencySymbolPlacement.suffix) {
                AutoNumericHelper.setElementSelection(e.target, 0);
            } else {
                AutoNumericHelper.setElementSelection(e.target, this.settings.currencySymbol.length);
            }
        } else if (this.eventKey === AutoNumericEnum.keyName.Tab) {
            AutoNumericHelper.setElementSelection(e.target, 0, targetValue.length);
        }

        if ((targetValue === this.settings.suffixText) ||
            (this.rawValue === '' && this.settings.currencySymbol !== '' && this.settings.suffixText !== '')) {
            AutoNumericHelper.setElementSelection(e.target, 0);
        }

        // Saves the extended decimal to preserve the data when navigating away from the page
        if (this.settings.decimalPlacesShownOnFocus !== null) {
            this._saveValueToPersistentStorage();
        }

        if (!this.formatted) {  //TODO Is this line needed? Considering that onKeydown and onKeypress both finish by setting it to false...
            this._formatValue(e);
        }

        this._setValidOrInvalidState(this.rawValue);

        // Force the `rawValue` update on Android Chrome
        this._saveRawValueForAndroid();

        // If the input value has changed during the key press event chain, an event is sent to alert that a formatting has been done (cf. Issue #187)
        if (targetValue !== this.initialValueOnFirstKeydown) { // Checking the value that were saved after the very first keydown event ensure that the 'formatted' event will be sent even if the user continuously press the Delete/Backspace key
            this._triggerEvent(AutoNumeric.events.formatted, e.target, {
                oldValue   : this.initialValueOnFirstKeydown,
                newValue   : targetValue,
                oldRawValue: this.initialRawValueOnFirstKeydown,
                newRawValue: this.rawValue,
                isPristine : this.isPristine(false),
                error      : null,
                aNElement  : this,
            });
        }

        // Update the selection of the current element of the history table
        if (this.historyTable.length > 1) {
            const selection = AutoNumericHelper.getElementSelection(this.domElement);
            this.selectionStart = selection.start;
            this.selectionEnd = selection.end;
            this.historyTable[this.historyTableIndex].start = this.selectionStart;
            this.historyTable[this.historyTableIndex].end = this.selectionEnd;
        }
    }
Handler for 'keyup' events.
The user just released any key, hence one event is sent.

@param {KeyboardEvent} e