From cb56eeec048bcb3288b949d601d1b9770bbb5b32 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 28 Mar 2026 22:14:48 +0000 Subject: [PATCH 1/4] Initial plan From 3664ce94e8e29f14a6a5a6317b2c3baad7bfd5bf Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 28 Mar 2026 22:42:59 +0000 Subject: [PATCH 2/4] Fix auto-complete select error when input is empty Agent-Logs-Url: https://github.com/RobinHerbots/Inputmask/sessions/067db837-52f8-443c-9ef1-1c0a979dfe97 Co-authored-by: RobinHerbots <318447+RobinHerbots@users.noreply.github.com> --- Changelog.md | 1 + dist/colormask.js | 17 +++++++++++++---- dist/colormask.min.js | 17 +++++++++++++---- dist/inputmask.js | 17 +++++++++++++---- dist/inputmask.min.js | 17 +++++++++++++---- dist/jquery.inputmask.js | 17 +++++++++++++---- dist/jquery.inputmask.min.js | 17 +++++++++++++---- inputmask-pages/src/assets/Changelog.md | 1 + lib/eventhandlers.js | 15 ++++++++++++--- 9 files changed, 92 insertions(+), 27 deletions(-) diff --git a/Changelog.md b/Changelog.md index 74607198b..4a1ca75e7 100644 --- a/Changelog.md +++ b/Changelog.md @@ -21,6 +21,7 @@ ### Fixed +- Auto-complete select error when input is empty (TypeError: Cannot read properties of undefined (reading 'length')) - Minus is being deleted with the first digit #2860 - Problems with deleting static chars in alternator mask #2648 - Backspace on controlled input adds "backspace" text to the value #2865 diff --git a/dist/colormask.js b/dist/colormask.js index 3824cc997..66d856b96 100644 --- a/dist/colormask.js +++ b/dist/colormask.js @@ -14,7 +14,7 @@ var a = factory(); for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i]; } -})(typeof self !== 'undefined' ? self : this, function() { +})(Object(typeof self !== 'undefined' ? self : this), function() { return /******/ (function() { // webpackBootstrap /******/ "use strict"; /******/ var __webpack_modules__ = ([ @@ -2002,9 +2002,18 @@ var EventHandlers = exports.EventHandlers = { }, 0); break; case "deleteContentBackward": - var keydown = new $.Event("keydown"); - keydown.key = _keycode.keys.Backspace; - EventHandlers.keyEvent.call(input, keydown); + if (e.inputType && e.inputType.startsWith("insert")) { + // e.inputType indicates an insert operation (e.g. browser autocomplete + // with insertReplacementText) but analyseChanges incorrectly detected + // a deletion due to caret position / buffer length mismatch. + // Apply the value directly instead of dispatching a backspace event. + (0, _inputHandling.applyInputValue)(input, inputValue); + _positioning.caret.call(inputmask, input, caretPos.begin, caretPos.end, true); + } else { + var keydown = new $.Event("keydown"); + keydown.key = _keycode.keys.Backspace; + EventHandlers.keyEvent.call(input, keydown); + } break; default: (0, _inputHandling.applyInputValue)(input, inputValue); diff --git a/dist/colormask.min.js b/dist/colormask.min.js index 735a0d4fb..3f6a292ed 100644 --- a/dist/colormask.min.js +++ b/dist/colormask.min.js @@ -14,7 +14,7 @@ var a = factory(); for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i]; } -})(typeof self !== 'undefined' ? self : this, function() { +})(Object(typeof self !== 'undefined' ? self : this), function() { return /******/ (function() { // webpackBootstrap /******/ "use strict"; /******/ var __webpack_modules__ = ([ @@ -2002,9 +2002,18 @@ var EventHandlers = exports.EventHandlers = { }, 0); break; case "deleteContentBackward": - var keydown = new $.Event("keydown"); - keydown.key = _keycode.keys.Backspace; - EventHandlers.keyEvent.call(input, keydown); + if (e.inputType && e.inputType.startsWith("insert")) { + // e.inputType indicates an insert operation (e.g. browser autocomplete + // with insertReplacementText) but analyseChanges incorrectly detected + // a deletion due to caret position / buffer length mismatch. + // Apply the value directly instead of dispatching a backspace event. + (0, _inputHandling.applyInputValue)(input, inputValue); + _positioning.caret.call(inputmask, input, caretPos.begin, caretPos.end, true); + } else { + var keydown = new $.Event("keydown"); + keydown.key = _keycode.keys.Backspace; + EventHandlers.keyEvent.call(input, keydown); + } break; default: (0, _inputHandling.applyInputValue)(input, inputValue); diff --git a/dist/inputmask.js b/dist/inputmask.js index 412cafd93..ef0f9d82f 100644 --- a/dist/inputmask.js +++ b/dist/inputmask.js @@ -14,7 +14,7 @@ var a = factory(); for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i]; } -})(typeof self !== 'undefined' ? self : this, function() { +})(Object(typeof self !== 'undefined' ? self : this), function() { return /******/ (function() { // webpackBootstrap /******/ "use strict"; /******/ var __webpack_modules__ = ([ @@ -1979,9 +1979,18 @@ var EventHandlers = exports.EventHandlers = { }, 0); break; case "deleteContentBackward": - var keydown = new $.Event("keydown"); - keydown.key = _keycode.keys.Backspace; - EventHandlers.keyEvent.call(input, keydown); + if (e.inputType && e.inputType.startsWith("insert")) { + // e.inputType indicates an insert operation (e.g. browser autocomplete + // with insertReplacementText) but analyseChanges incorrectly detected + // a deletion due to caret position / buffer length mismatch. + // Apply the value directly instead of dispatching a backspace event. + (0, _inputHandling.applyInputValue)(input, inputValue); + _positioning.caret.call(inputmask, input, caretPos.begin, caretPos.end, true); + } else { + var keydown = new $.Event("keydown"); + keydown.key = _keycode.keys.Backspace; + EventHandlers.keyEvent.call(input, keydown); + } break; default: (0, _inputHandling.applyInputValue)(input, inputValue); diff --git a/dist/inputmask.min.js b/dist/inputmask.min.js index dd25b685d..685aad08c 100644 --- a/dist/inputmask.min.js +++ b/dist/inputmask.min.js @@ -14,7 +14,7 @@ var a = factory(); for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i]; } -})(typeof self !== 'undefined' ? self : this, function() { +})(Object(typeof self !== 'undefined' ? self : this), function() { return /******/ (function() { // webpackBootstrap /******/ "use strict"; /******/ var __webpack_modules__ = ([ @@ -1979,9 +1979,18 @@ var EventHandlers = exports.EventHandlers = { }, 0); break; case "deleteContentBackward": - var keydown = new $.Event("keydown"); - keydown.key = _keycode.keys.Backspace; - EventHandlers.keyEvent.call(input, keydown); + if (e.inputType && e.inputType.startsWith("insert")) { + // e.inputType indicates an insert operation (e.g. browser autocomplete + // with insertReplacementText) but analyseChanges incorrectly detected + // a deletion due to caret position / buffer length mismatch. + // Apply the value directly instead of dispatching a backspace event. + (0, _inputHandling.applyInputValue)(input, inputValue); + _positioning.caret.call(inputmask, input, caretPos.begin, caretPos.end, true); + } else { + var keydown = new $.Event("keydown"); + keydown.key = _keycode.keys.Backspace; + EventHandlers.keyEvent.call(input, keydown); + } break; default: (0, _inputHandling.applyInputValue)(input, inputValue); diff --git a/dist/jquery.inputmask.js b/dist/jquery.inputmask.js index d7e7e78c4..8f579d3f0 100644 --- a/dist/jquery.inputmask.js +++ b/dist/jquery.inputmask.js @@ -14,7 +14,7 @@ var a = typeof exports === 'object' ? factory(require("jquery")) : factory(root["jQuery"]); for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i]; } -})(typeof self !== 'undefined' ? self : this, function(__WEBPACK_EXTERNAL_MODULE__12__) { +})(Object(typeof self !== 'undefined' ? self : this), function(__WEBPACK_EXTERNAL_MODULE__12__) { return /******/ (function() { // webpackBootstrap /******/ "use strict"; /******/ var __webpack_modules__ = ([ @@ -1666,9 +1666,18 @@ var EventHandlers = exports.EventHandlers = { }, 0); break; case "deleteContentBackward": - var keydown = new $.Event("keydown"); - keydown.key = _keycode.keys.Backspace; - EventHandlers.keyEvent.call(input, keydown); + if (e.inputType && e.inputType.startsWith("insert")) { + // e.inputType indicates an insert operation (e.g. browser autocomplete + // with insertReplacementText) but analyseChanges incorrectly detected + // a deletion due to caret position / buffer length mismatch. + // Apply the value directly instead of dispatching a backspace event. + (0, _inputHandling.applyInputValue)(input, inputValue); + _positioning.caret.call(inputmask, input, caretPos.begin, caretPos.end, true); + } else { + var keydown = new $.Event("keydown"); + keydown.key = _keycode.keys.Backspace; + EventHandlers.keyEvent.call(input, keydown); + } break; default: (0, _inputHandling.applyInputValue)(input, inputValue); diff --git a/dist/jquery.inputmask.min.js b/dist/jquery.inputmask.min.js index 54c992548..dbfc30855 100644 --- a/dist/jquery.inputmask.min.js +++ b/dist/jquery.inputmask.min.js @@ -14,7 +14,7 @@ var a = typeof exports === 'object' ? factory(require("jquery")) : factory(root["jQuery"]); for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i]; } -})(typeof self !== 'undefined' ? self : this, function(__WEBPACK_EXTERNAL_MODULE__12__) { +})(Object(typeof self !== 'undefined' ? self : this), function(__WEBPACK_EXTERNAL_MODULE__12__) { return /******/ (function() { // webpackBootstrap /******/ "use strict"; /******/ var __webpack_modules__ = ([ @@ -1666,9 +1666,18 @@ var EventHandlers = exports.EventHandlers = { }, 0); break; case "deleteContentBackward": - var keydown = new $.Event("keydown"); - keydown.key = _keycode.keys.Backspace; - EventHandlers.keyEvent.call(input, keydown); + if (e.inputType && e.inputType.startsWith("insert")) { + // e.inputType indicates an insert operation (e.g. browser autocomplete + // with insertReplacementText) but analyseChanges incorrectly detected + // a deletion due to caret position / buffer length mismatch. + // Apply the value directly instead of dispatching a backspace event. + (0, _inputHandling.applyInputValue)(input, inputValue); + _positioning.caret.call(inputmask, input, caretPos.begin, caretPos.end, true); + } else { + var keydown = new $.Event("keydown"); + keydown.key = _keycode.keys.Backspace; + EventHandlers.keyEvent.call(input, keydown); + } break; default: (0, _inputHandling.applyInputValue)(input, inputValue); diff --git a/inputmask-pages/src/assets/Changelog.md b/inputmask-pages/src/assets/Changelog.md index 50c49bd6a..74607198b 100644 --- a/inputmask-pages/src/assets/Changelog.md +++ b/inputmask-pages/src/assets/Changelog.md @@ -21,6 +21,7 @@ ### Fixed +- Minus is being deleted with the first digit #2860 - Problems with deleting static chars in alternator mask #2648 - Backspace on controlled input adds "backspace" text to the value #2865 - Cannot read properties of null (reading 'inputmask') FormData patch #2841 diff --git a/lib/eventhandlers.js b/lib/eventhandlers.js index 66d0415d4..b1ecccb6f 100644 --- a/lib/eventhandlers.js +++ b/lib/eventhandlers.js @@ -508,9 +508,18 @@ const EventHandlers = { }, 0); break; case "deleteContentBackward": - var keydown = new $.Event("keydown"); - keydown.key = keys.Backspace; - EventHandlers.keyEvent.call(input, keydown); + if (e.inputType && e.inputType.startsWith("insert")) { + // e.inputType indicates an insert operation (e.g. browser autocomplete + // with insertReplacementText) but analyseChanges incorrectly detected + // a deletion due to caret position / buffer length mismatch. + // Apply the value directly instead of dispatching a backspace event. + applyInputValue(input, inputValue); + caret.call(inputmask, input, caretPos.begin, caretPos.end, true); + } else { + var keydown = new $.Event("keydown"); + keydown.key = keys.Backspace; + EventHandlers.keyEvent.call(input, keydown); + } break; default: applyInputValue(input, inputValue); From 30f5dbf19893f4b1462518d7958f8c82030242b3 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 31 Mar 2026 09:16:38 +0000 Subject: [PATCH 3/4] Remove dist and inputmask-pages changelog changes per review feedback Agent-Logs-Url: https://github.com/RobinHerbots/Inputmask/sessions/e240923d-85a5-4a06-88c2-5dacc20a1ae1 Co-authored-by: RobinHerbots <318447+RobinHerbots@users.noreply.github.com> --- dist/colormask.js | 17 ++++------------- dist/colormask.min.js | 17 ++++------------- dist/inputmask.js | 17 ++++------------- dist/inputmask.min.js | 17 ++++------------- dist/jquery.inputmask.js | 17 ++++------------- dist/jquery.inputmask.min.js | 17 ++++------------- inputmask-pages/src/assets/Changelog.md | 1 - 7 files changed, 24 insertions(+), 79 deletions(-) diff --git a/dist/colormask.js b/dist/colormask.js index 66d856b96..3824cc997 100644 --- a/dist/colormask.js +++ b/dist/colormask.js @@ -14,7 +14,7 @@ var a = factory(); for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i]; } -})(Object(typeof self !== 'undefined' ? self : this), function() { +})(typeof self !== 'undefined' ? self : this, function() { return /******/ (function() { // webpackBootstrap /******/ "use strict"; /******/ var __webpack_modules__ = ([ @@ -2002,18 +2002,9 @@ var EventHandlers = exports.EventHandlers = { }, 0); break; case "deleteContentBackward": - if (e.inputType && e.inputType.startsWith("insert")) { - // e.inputType indicates an insert operation (e.g. browser autocomplete - // with insertReplacementText) but analyseChanges incorrectly detected - // a deletion due to caret position / buffer length mismatch. - // Apply the value directly instead of dispatching a backspace event. - (0, _inputHandling.applyInputValue)(input, inputValue); - _positioning.caret.call(inputmask, input, caretPos.begin, caretPos.end, true); - } else { - var keydown = new $.Event("keydown"); - keydown.key = _keycode.keys.Backspace; - EventHandlers.keyEvent.call(input, keydown); - } + var keydown = new $.Event("keydown"); + keydown.key = _keycode.keys.Backspace; + EventHandlers.keyEvent.call(input, keydown); break; default: (0, _inputHandling.applyInputValue)(input, inputValue); diff --git a/dist/colormask.min.js b/dist/colormask.min.js index 3f6a292ed..735a0d4fb 100644 --- a/dist/colormask.min.js +++ b/dist/colormask.min.js @@ -14,7 +14,7 @@ var a = factory(); for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i]; } -})(Object(typeof self !== 'undefined' ? self : this), function() { +})(typeof self !== 'undefined' ? self : this, function() { return /******/ (function() { // webpackBootstrap /******/ "use strict"; /******/ var __webpack_modules__ = ([ @@ -2002,18 +2002,9 @@ var EventHandlers = exports.EventHandlers = { }, 0); break; case "deleteContentBackward": - if (e.inputType && e.inputType.startsWith("insert")) { - // e.inputType indicates an insert operation (e.g. browser autocomplete - // with insertReplacementText) but analyseChanges incorrectly detected - // a deletion due to caret position / buffer length mismatch. - // Apply the value directly instead of dispatching a backspace event. - (0, _inputHandling.applyInputValue)(input, inputValue); - _positioning.caret.call(inputmask, input, caretPos.begin, caretPos.end, true); - } else { - var keydown = new $.Event("keydown"); - keydown.key = _keycode.keys.Backspace; - EventHandlers.keyEvent.call(input, keydown); - } + var keydown = new $.Event("keydown"); + keydown.key = _keycode.keys.Backspace; + EventHandlers.keyEvent.call(input, keydown); break; default: (0, _inputHandling.applyInputValue)(input, inputValue); diff --git a/dist/inputmask.js b/dist/inputmask.js index ef0f9d82f..412cafd93 100644 --- a/dist/inputmask.js +++ b/dist/inputmask.js @@ -14,7 +14,7 @@ var a = factory(); for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i]; } -})(Object(typeof self !== 'undefined' ? self : this), function() { +})(typeof self !== 'undefined' ? self : this, function() { return /******/ (function() { // webpackBootstrap /******/ "use strict"; /******/ var __webpack_modules__ = ([ @@ -1979,18 +1979,9 @@ var EventHandlers = exports.EventHandlers = { }, 0); break; case "deleteContentBackward": - if (e.inputType && e.inputType.startsWith("insert")) { - // e.inputType indicates an insert operation (e.g. browser autocomplete - // with insertReplacementText) but analyseChanges incorrectly detected - // a deletion due to caret position / buffer length mismatch. - // Apply the value directly instead of dispatching a backspace event. - (0, _inputHandling.applyInputValue)(input, inputValue); - _positioning.caret.call(inputmask, input, caretPos.begin, caretPos.end, true); - } else { - var keydown = new $.Event("keydown"); - keydown.key = _keycode.keys.Backspace; - EventHandlers.keyEvent.call(input, keydown); - } + var keydown = new $.Event("keydown"); + keydown.key = _keycode.keys.Backspace; + EventHandlers.keyEvent.call(input, keydown); break; default: (0, _inputHandling.applyInputValue)(input, inputValue); diff --git a/dist/inputmask.min.js b/dist/inputmask.min.js index 685aad08c..dd25b685d 100644 --- a/dist/inputmask.min.js +++ b/dist/inputmask.min.js @@ -14,7 +14,7 @@ var a = factory(); for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i]; } -})(Object(typeof self !== 'undefined' ? self : this), function() { +})(typeof self !== 'undefined' ? self : this, function() { return /******/ (function() { // webpackBootstrap /******/ "use strict"; /******/ var __webpack_modules__ = ([ @@ -1979,18 +1979,9 @@ var EventHandlers = exports.EventHandlers = { }, 0); break; case "deleteContentBackward": - if (e.inputType && e.inputType.startsWith("insert")) { - // e.inputType indicates an insert operation (e.g. browser autocomplete - // with insertReplacementText) but analyseChanges incorrectly detected - // a deletion due to caret position / buffer length mismatch. - // Apply the value directly instead of dispatching a backspace event. - (0, _inputHandling.applyInputValue)(input, inputValue); - _positioning.caret.call(inputmask, input, caretPos.begin, caretPos.end, true); - } else { - var keydown = new $.Event("keydown"); - keydown.key = _keycode.keys.Backspace; - EventHandlers.keyEvent.call(input, keydown); - } + var keydown = new $.Event("keydown"); + keydown.key = _keycode.keys.Backspace; + EventHandlers.keyEvent.call(input, keydown); break; default: (0, _inputHandling.applyInputValue)(input, inputValue); diff --git a/dist/jquery.inputmask.js b/dist/jquery.inputmask.js index 8f579d3f0..d7e7e78c4 100644 --- a/dist/jquery.inputmask.js +++ b/dist/jquery.inputmask.js @@ -14,7 +14,7 @@ var a = typeof exports === 'object' ? factory(require("jquery")) : factory(root["jQuery"]); for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i]; } -})(Object(typeof self !== 'undefined' ? self : this), function(__WEBPACK_EXTERNAL_MODULE__12__) { +})(typeof self !== 'undefined' ? self : this, function(__WEBPACK_EXTERNAL_MODULE__12__) { return /******/ (function() { // webpackBootstrap /******/ "use strict"; /******/ var __webpack_modules__ = ([ @@ -1666,18 +1666,9 @@ var EventHandlers = exports.EventHandlers = { }, 0); break; case "deleteContentBackward": - if (e.inputType && e.inputType.startsWith("insert")) { - // e.inputType indicates an insert operation (e.g. browser autocomplete - // with insertReplacementText) but analyseChanges incorrectly detected - // a deletion due to caret position / buffer length mismatch. - // Apply the value directly instead of dispatching a backspace event. - (0, _inputHandling.applyInputValue)(input, inputValue); - _positioning.caret.call(inputmask, input, caretPos.begin, caretPos.end, true); - } else { - var keydown = new $.Event("keydown"); - keydown.key = _keycode.keys.Backspace; - EventHandlers.keyEvent.call(input, keydown); - } + var keydown = new $.Event("keydown"); + keydown.key = _keycode.keys.Backspace; + EventHandlers.keyEvent.call(input, keydown); break; default: (0, _inputHandling.applyInputValue)(input, inputValue); diff --git a/dist/jquery.inputmask.min.js b/dist/jquery.inputmask.min.js index dbfc30855..54c992548 100644 --- a/dist/jquery.inputmask.min.js +++ b/dist/jquery.inputmask.min.js @@ -14,7 +14,7 @@ var a = typeof exports === 'object' ? factory(require("jquery")) : factory(root["jQuery"]); for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i]; } -})(Object(typeof self !== 'undefined' ? self : this), function(__WEBPACK_EXTERNAL_MODULE__12__) { +})(typeof self !== 'undefined' ? self : this, function(__WEBPACK_EXTERNAL_MODULE__12__) { return /******/ (function() { // webpackBootstrap /******/ "use strict"; /******/ var __webpack_modules__ = ([ @@ -1666,18 +1666,9 @@ var EventHandlers = exports.EventHandlers = { }, 0); break; case "deleteContentBackward": - if (e.inputType && e.inputType.startsWith("insert")) { - // e.inputType indicates an insert operation (e.g. browser autocomplete - // with insertReplacementText) but analyseChanges incorrectly detected - // a deletion due to caret position / buffer length mismatch. - // Apply the value directly instead of dispatching a backspace event. - (0, _inputHandling.applyInputValue)(input, inputValue); - _positioning.caret.call(inputmask, input, caretPos.begin, caretPos.end, true); - } else { - var keydown = new $.Event("keydown"); - keydown.key = _keycode.keys.Backspace; - EventHandlers.keyEvent.call(input, keydown); - } + var keydown = new $.Event("keydown"); + keydown.key = _keycode.keys.Backspace; + EventHandlers.keyEvent.call(input, keydown); break; default: (0, _inputHandling.applyInputValue)(input, inputValue); diff --git a/inputmask-pages/src/assets/Changelog.md b/inputmask-pages/src/assets/Changelog.md index 74607198b..50c49bd6a 100644 --- a/inputmask-pages/src/assets/Changelog.md +++ b/inputmask-pages/src/assets/Changelog.md @@ -21,7 +21,6 @@ ### Fixed -- Minus is being deleted with the first digit #2860 - Problems with deleting static chars in alternator mask #2648 - Backspace on controlled input adds "backspace" text to the value #2865 - Cannot read properties of null (reading 'inputmask') FormData patch #2841 From c781c07e76af0793016cafc48da6a50cef613a5f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 31 Mar 2026 09:25:50 +0000 Subject: [PATCH 4/4] Add autocomplete simulation helper and regression test for empty masked input Agent-Logs-Url: https://github.com/RobinHerbots/Inputmask/sessions/17a08e56-7030-4315-86bd-458db7c45fcd Co-authored-by: RobinHerbots <318447+RobinHerbots@users.noreply.github.com> --- qunit/simulator.js | 14 +++++++++++++ qunit/tests_inputeventonly.js | 38 +++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/qunit/simulator.js b/qunit/simulator.js index d4875a6b4..9b9f2b321 100644 --- a/qunit/simulator.js +++ b/qunit/simulator.js @@ -249,4 +249,18 @@ export default function ($, Inputmask) { } $(input).trigger("input"); }; + + // Simulate a browser autocomplete selection on a masked input. + // Sets the native value and fires an input event with inputType "insertReplacementText", + // matching the browser behavior when the user selects a suggestion from the autocomplete list. + $.fn.autocomplete = function (value, caretBegin, caretEnd) { + const input = this.nodeName ? this : this[0]; + input.inputmask.__valueSet.call(input, value); + if (caretBegin !== undefined) { + $.caret(input, caretBegin, caretEnd !== undefined ? caretEnd : caretBegin); + } + const evt = $.Event("input"); + evt.inputType = "insertReplacementText"; + $(input).trigger(evt); + }; } diff --git a/qunit/tests_inputeventonly.js b/qunit/tests_inputeventonly.js index a1f3ddb17..0ad809664 100644 --- a/qunit/tests_inputeventonly.js +++ b/qunit/tests_inputeventonly.js @@ -204,4 +204,42 @@ export default function (qunit, Inputmask) { done(); }, 0); }); + + // Regression test: selecting a browser autocomplete suggestion on an empty masked input + // must not throw TypeError. analyseChanges can misdetect the insertion as a deletion + // (deleteContentBackward) when caret is at 0 and the autocomplete value is shorter than + // the mask template. The fix guards against this contradiction by checking e.inputType. + qunit.test( + "(999) 999-9999 - autocomplete on empty input (insertReplacementText)", + function (assert) { + const done = assert.async(), + $fixture = $("#qunit-fixture"); + $fixture.append(''); + const testmask = document.getElementById("testmask"); + Inputmask("(999) 999-9999", { inputEventOnly: true }).mask(testmask); + + testmask.focus(); + setTimeout(function () { + // Simulate browser autocomplete: native value set to "1231231234", caret at 0, + // input event fires with inputType "insertReplacementText". + assert.ok( + (function () { + try { + $(testmask).autocomplete("1231231234", 0, 0); + return true; + } catch (e) { + return false; + } + })(), + "No error thrown on autocomplete" + ); + assert.equal( + testmask.value, + "(123) 123-1234", + "Result " + testmask.value + ); + done(); + }, 0); + } + ); }