eventhandlers.js 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749
  1. import { iphone, mobile } from "./environment";
  2. import window from "./global/window";
  3. import {
  4. applyInputValue,
  5. checkVal,
  6. clearOptionalTail,
  7. HandleNativePlaceholder,
  8. writeBuffer
  9. } from "./inputHandling";
  10. import { keys } from "./keycode.js";
  11. import {
  12. caret,
  13. determineNewCaretPosition,
  14. getBuffer,
  15. getBufferTemplate,
  16. getLastValidPosition,
  17. isMask,
  18. resetMaskSet,
  19. seekNext,
  20. seekPrevious,
  21. translatePosition
  22. } from "./positioning";
  23. import { handleRemove, isComplete, isSelection, isValid } from "./validation";
  24. import { getPlaceholder, getTest } from "./validation-tests";
  25. export { EventHandlers };
  26. var EventHandlers = {
  27. keyEvent: function (e, checkval, writeOut, strict, ndx) {
  28. const inputmask = this.inputmask,
  29. opts = inputmask.opts,
  30. $ = inputmask.dependencyLib,
  31. maskset = inputmask.maskset,
  32. input = this,
  33. $input = $(input),
  34. c = e.key,
  35. pos = caret.call(inputmask, input),
  36. kdResult = opts.onKeyDown.call(
  37. this,
  38. e,
  39. getBuffer.call(inputmask),
  40. pos,
  41. opts
  42. );
  43. if (kdResult !== undefined) return kdResult;
  44. // backspace, delete, and escape get special treatment
  45. if (
  46. c === keys.Backspace ||
  47. c === keys.Delete ||
  48. (iphone && c === keys.BACKSPACE_SAFARI) ||
  49. (e.ctrlKey && c === keys.x && !("oncut" in input))
  50. ) {
  51. // backspace/delete
  52. e.preventDefault(); // stop default action but allow propagation
  53. handleRemove.call(inputmask, input, c, pos);
  54. writeBuffer(
  55. input,
  56. getBuffer.call(inputmask, true),
  57. maskset.p,
  58. e,
  59. input.inputmask._valueGet() !== getBuffer.call(inputmask).join("")
  60. );
  61. } else if (c === keys.End || c === keys.PageDown) {
  62. // when END or PAGE_DOWN pressed set position at lastmatch
  63. e.preventDefault();
  64. const caretPos = seekNext.call(
  65. inputmask,
  66. getLastValidPosition.call(inputmask)
  67. );
  68. caret.call(
  69. inputmask,
  70. input,
  71. e.shiftKey ? pos.begin : caretPos,
  72. caretPos,
  73. true
  74. );
  75. } else if ((c === keys.Home && !e.shiftKey) || c === keys.PageUp) {
  76. // Home or page_up
  77. e.preventDefault();
  78. caret.call(inputmask, input, 0, e.shiftKey ? pos.begin : 0, true);
  79. } else if (
  80. ((opts.undoOnEscape && c === keys.Escape) ||
  81. (false && c === keys.z && e.ctrlKey)) &&
  82. e.altKey !== true
  83. ) {
  84. // escape && undo && #762
  85. checkVal(input, true, false, inputmask.undoValue.split(""));
  86. $input.trigger("click");
  87. } else if (
  88. c === keys.Insert &&
  89. !(e.shiftKey || e.ctrlKey) &&
  90. inputmask.userOptions.insertMode === undefined
  91. ) {
  92. // insert
  93. if (!isSelection.call(inputmask, pos)) {
  94. opts.insertMode = !opts.insertMode;
  95. caret.call(inputmask, input, pos.begin, pos.begin);
  96. } else opts.insertMode = !opts.insertMode;
  97. } else if (opts.tabThrough === true && c === keys.Tab) {
  98. if (e.shiftKey === true) {
  99. pos.end = seekPrevious.call(inputmask, pos.end, true);
  100. if (getTest.call(inputmask, pos.end - 1).match.static === true) {
  101. pos.end--;
  102. }
  103. pos.begin = seekPrevious.call(inputmask, pos.end, true);
  104. if (pos.begin >= 0 && pos.end > 0) {
  105. e.preventDefault();
  106. caret.call(inputmask, input, pos.begin, pos.end);
  107. }
  108. } else {
  109. pos.begin = seekNext.call(inputmask, pos.begin, true);
  110. pos.end = seekNext.call(inputmask, pos.begin, true);
  111. if (pos.end < maskset.maskLength) pos.end--;
  112. if (pos.begin <= maskset.maskLength) {
  113. e.preventDefault();
  114. caret.call(inputmask, input, pos.begin, pos.end);
  115. }
  116. }
  117. } else if (!e.shiftKey) {
  118. if (opts.insertModeVisual && opts.insertMode === false) {
  119. if (c === keys.ArrowRight) {
  120. setTimeout(function () {
  121. const caretPos = caret.call(inputmask, input);
  122. caret.call(inputmask, input, caretPos.begin);
  123. }, 0);
  124. } else if (c === keys.ArrowLeft) {
  125. setTimeout(function () {
  126. const caretPos = {
  127. begin: translatePosition.call(
  128. inputmask,
  129. input.inputmask.caretPos.begin
  130. ),
  131. end: translatePosition.call(
  132. inputmask,
  133. input.inputmask.caretPos.end
  134. )
  135. };
  136. if (inputmask.isRTL) {
  137. caret.call(
  138. inputmask,
  139. input,
  140. caretPos.begin + (caretPos.begin === maskset.maskLength ? 0 : 1)
  141. );
  142. } else {
  143. caret.call(
  144. inputmask,
  145. input,
  146. caretPos.begin - (caretPos.begin === 0 ? 0 : 1)
  147. );
  148. }
  149. }, 0);
  150. }
  151. } else {
  152. inputmask.keyEventHook === undefined || inputmask.keyEventHook(e);
  153. }
  154. }
  155. inputmask.isComposing = c == keys.Process || c == keys.Unidentified;
  156. inputmask.ignorable =
  157. c.length > 1 &&
  158. !(input.tagName.toLowerCase() === "textarea" && c == keys.Enter);
  159. return EventHandlers.keypressEvent.call(
  160. this,
  161. e,
  162. checkval,
  163. writeOut,
  164. strict,
  165. ndx
  166. );
  167. },
  168. keypressEvent: function (e, checkval, writeOut, strict, ndx) {
  169. const inputmask = this.inputmask || this,
  170. opts = inputmask.opts,
  171. $ = inputmask.dependencyLib,
  172. maskset = inputmask.maskset;
  173. let input = inputmask.el,
  174. $input = $(input),
  175. c = e.key;
  176. if (
  177. checkval !== true &&
  178. !(e.ctrlKey && e.altKey && !inputmask.ignorable) &&
  179. (e.ctrlKey || e.metaKey || inputmask.ignorable)
  180. ) {
  181. if (c === keys.Enter) {
  182. if (inputmask.undoValue !== inputmask._valueGet(true)) {
  183. inputmask.undoValue = inputmask._valueGet(true);
  184. // e.preventDefault();
  185. setTimeout(function () {
  186. $input.trigger("change");
  187. }, 0);
  188. }
  189. }
  190. // inputmask.skipInputEvent = true; //skip the input as otherwise the skipped char could be picked up for validation by the inputfallback
  191. } else if (c) {
  192. // special treat the decimal separator
  193. // if ((k === 44 || k === 46) && e.location === 3 && opts.radixPoint !== "") k = opts.radixPoint.charCodeAt(0);
  194. let pos = checkval
  195. ? {
  196. begin: ndx,
  197. end: ndx
  198. }
  199. : caret.call(inputmask, input),
  200. forwardPosition;
  201. // allow for character substitution
  202. if (!checkval) c = opts.substitutes[c] || c;
  203. maskset.writeOutBuffer = true;
  204. const valResult = isValid.call(
  205. inputmask,
  206. pos,
  207. c,
  208. strict,
  209. undefined,
  210. undefined,
  211. undefined,
  212. checkval
  213. );
  214. if (valResult !== false) {
  215. resetMaskSet.call(inputmask, true);
  216. forwardPosition =
  217. valResult.caret !== undefined
  218. ? valResult.caret
  219. : seekNext.call(
  220. inputmask,
  221. valResult.pos.begin ? valResult.pos.begin : valResult.pos
  222. );
  223. maskset.p = forwardPosition; // needed for checkval
  224. }
  225. forwardPosition =
  226. opts.numericInput && valResult.caret === undefined
  227. ? seekPrevious.call(inputmask, forwardPosition)
  228. : forwardPosition;
  229. if (writeOut !== false) {
  230. setTimeout(function () {
  231. opts.onKeyValidation.call(input, c, valResult);
  232. }, 0);
  233. if (maskset.writeOutBuffer && valResult !== false) {
  234. const buffer = getBuffer.call(inputmask);
  235. writeBuffer(input, buffer, forwardPosition, e, checkval !== true);
  236. }
  237. }
  238. e.preventDefault();
  239. if (checkval) {
  240. if (valResult !== false) valResult.forwardPosition = forwardPosition;
  241. return valResult;
  242. }
  243. }
  244. },
  245. pasteEvent: async function (e) {
  246. function handlePaste(
  247. inputmask,
  248. input,
  249. inputValue,
  250. pastedValue,
  251. onBeforePaste
  252. ) {
  253. let caretPos = caret.call(inputmask, input, undefined, undefined, true),
  254. valueBeforeCaret = inputValue.substr(0, caretPos.begin),
  255. valueAfterCaret = inputValue.substr(caretPos.end, inputValue.length);
  256. if (
  257. valueBeforeCaret ==
  258. (inputmask.isRTL
  259. ? getBufferTemplate.call(inputmask).slice().reverse()
  260. : getBufferTemplate.call(inputmask)
  261. )
  262. .slice(0, caretPos.begin)
  263. .join("")
  264. )
  265. valueBeforeCaret = "";
  266. if (
  267. valueAfterCaret ==
  268. (inputmask.isRTL
  269. ? getBufferTemplate.call(inputmask).slice().reverse()
  270. : getBufferTemplate.call(inputmask)
  271. )
  272. .slice(caretPos.end)
  273. .join("")
  274. )
  275. valueAfterCaret = "";
  276. pastedValue = valueBeforeCaret + pastedValue + valueAfterCaret;
  277. if (inputmask.isRTL && opts.numericInput !== true) {
  278. pastedValue = pastedValue.split("");
  279. for (const c of getBufferTemplate.call(inputmask)) {
  280. if (pastedValue[0] === c) pastedValue.shift();
  281. }
  282. pastedValue = pastedValue.reverse().join("");
  283. }
  284. let pasteValue = pastedValue;
  285. if (typeof onBeforePaste === "function") {
  286. pasteValue = onBeforePaste.call(inputmask, pasteValue, opts);
  287. if (pasteValue === false) {
  288. return false;
  289. }
  290. if (!pasteValue) {
  291. pasteValue = inputValue;
  292. }
  293. }
  294. checkVal(input, true, false, pasteValue.toString().split(""), e);
  295. }
  296. const input = this,
  297. inputmask = this.inputmask,
  298. opts = inputmask.opts;
  299. let inputValue = inputmask._valueGet(true),
  300. pastedValue;
  301. inputmask.skipInputEvent = true;
  302. if (e.clipboardData && e.clipboardData.getData) {
  303. pastedValue = e.clipboardData.getData("text/plain");
  304. } else if (window.clipboardData && window.clipboardData.getData) {
  305. // IE
  306. pastedValue = window.clipboardData.getData("Text");
  307. }
  308. handlePaste(inputmask, input, inputValue, pastedValue, opts.onBeforePaste);
  309. e.preventDefault();
  310. },
  311. inputFallBackEvent: function (e) {
  312. // fallback when keypress is not triggered
  313. const inputmask = this.inputmask,
  314. opts = inputmask.opts,
  315. $ = inputmask.dependencyLib;
  316. // console.log(e.inputType);
  317. function analyseChanges(inputValue, buffer, caretPos) {
  318. let frontPart = inputValue.substr(0, caretPos.begin).split(""),
  319. backPart = inputValue.substr(caretPos.begin).split(""),
  320. frontBufferPart = buffer.substr(0, caretPos.begin).split(""),
  321. backBufferPart = buffer.substr(caretPos.begin).split(""),
  322. fpl =
  323. frontPart.length >= frontBufferPart.length
  324. ? frontPart.length
  325. : frontBufferPart.length,
  326. bpl =
  327. backPart.length >= backBufferPart.length
  328. ? backPart.length
  329. : backBufferPart.length,
  330. bl,
  331. i,
  332. action = "",
  333. data = [],
  334. marker = "~",
  335. placeholder;
  336. // align buffers
  337. while (frontPart.length < fpl) frontPart.push(marker);
  338. while (frontBufferPart.length < fpl) frontBufferPart.push(marker);
  339. while (backPart.length < bpl) backPart.unshift(marker);
  340. while (backBufferPart.length < bpl) backBufferPart.unshift(marker);
  341. const newBuffer = frontPart.concat(backPart),
  342. oldBuffer = frontBufferPart.concat(backBufferPart);
  343. // console.log("N " + newBuffer);
  344. // console.log("O " + oldBuffer);
  345. for (i = 0, bl = newBuffer.length; i < bl; i++) {
  346. placeholder = getPlaceholder.call(
  347. inputmask,
  348. translatePosition.call(inputmask, i)
  349. );
  350. switch (action) {
  351. case "insertText":
  352. if (
  353. oldBuffer[i - 1] === newBuffer[i] &&
  354. caretPos.begin == newBuffer.length - 1
  355. ) {
  356. data.push(newBuffer[i]);
  357. }
  358. i = bl;
  359. break;
  360. case "insertReplacementText":
  361. if (newBuffer[i] === marker) {
  362. // extend selection
  363. caretPos.end++;
  364. } else {
  365. // breakout loop
  366. i = bl;
  367. }
  368. break;
  369. case "deleteContentBackward":
  370. if (newBuffer[i] === marker) {
  371. caretPos.end++;
  372. } else {
  373. // breakout loop
  374. i = bl;
  375. }
  376. break;
  377. default:
  378. if (newBuffer[i] !== oldBuffer[i]) {
  379. if (
  380. (newBuffer[i + 1] === marker ||
  381. newBuffer[i + 1] === placeholder ||
  382. newBuffer[i + 1] === undefined) &&
  383. ((oldBuffer[i] === placeholder &&
  384. oldBuffer[i + 1] === marker) ||
  385. oldBuffer[i] === marker)
  386. ) {
  387. // basic insert
  388. action = "insertText";
  389. data.push(newBuffer[i]);
  390. caretPos.begin--;
  391. caretPos.end--;
  392. } else if (
  393. oldBuffer[i + 1] === marker &&
  394. oldBuffer[i] === newBuffer[i + 1]
  395. ) {
  396. // insert between
  397. action = "insertText";
  398. data.push(newBuffer[i]);
  399. caretPos.begin--;
  400. caretPos.end--;
  401. } else if (
  402. newBuffer[i] !== placeholder &&
  403. newBuffer[i] !== marker &&
  404. (newBuffer[i + 1] === marker ||
  405. (oldBuffer[i] !== newBuffer[i] &&
  406. oldBuffer[i + 1] ===
  407. newBuffer[i + 1])) /* single char replacement */
  408. ) {
  409. // replace selection
  410. action = "insertReplacementText";
  411. data.push(newBuffer[i]);
  412. caretPos.begin--;
  413. } else if (newBuffer[i] === marker) {
  414. // delete~backspace
  415. action = "deleteContentBackward";
  416. if (
  417. isMask.call(
  418. inputmask,
  419. translatePosition.call(inputmask, i),
  420. true
  421. ) ||
  422. oldBuffer[i] === opts.radixPoint
  423. )
  424. caretPos.end++;
  425. } else {
  426. i = bl;
  427. }
  428. }
  429. break;
  430. }
  431. }
  432. return {
  433. action,
  434. data,
  435. caret: caretPos
  436. };
  437. }
  438. let input = this,
  439. inputValue = input.inputmask._valueGet(true),
  440. buffer = (
  441. inputmask.isRTL
  442. ? getBuffer.call(inputmask).slice().reverse()
  443. : getBuffer.call(inputmask)
  444. ).join(""),
  445. caretPos = caret.call(inputmask, input, undefined, undefined, true),
  446. changes;
  447. if (buffer !== inputValue) {
  448. changes = analyseChanges(inputValue, buffer, caretPos);
  449. if (
  450. (input.inputmask.shadowRoot || input.ownerDocument).activeElement !==
  451. input
  452. ) {
  453. input.focus();
  454. }
  455. writeBuffer(input, getBuffer.call(inputmask));
  456. caret.call(inputmask, input, caretPos.begin, caretPos.end, true);
  457. // Japanese IME hack #2662
  458. if (
  459. !mobile &&
  460. inputmask.skipNextInsert &&
  461. e.inputType === "insertText" &&
  462. changes.action === "insertText" &&
  463. inputmask.isComposing
  464. ) {
  465. return false;
  466. }
  467. if (
  468. e.inputType === "insertCompositionText" &&
  469. changes.action === "insertText" &&
  470. inputmask.isComposing
  471. ) {
  472. inputmask.skipNextInsert = true;
  473. } else {
  474. inputmask.skipNextInsert = false;
  475. }
  476. switch (changes.action) {
  477. case "insertText":
  478. case "insertReplacementText":
  479. changes.data.forEach(function (entry, ndx) {
  480. const keypress = new $.Event("keypress");
  481. keypress.key = entry;
  482. inputmask.ignorable = false; // make sure ignorable is ignored ;-)
  483. EventHandlers.keypressEvent.call(input, keypress);
  484. });
  485. setTimeout(function () {
  486. // #2195 trigger keyup to help some other plugins to track changes
  487. inputmask.$el.trigger("keyup");
  488. }, 0);
  489. break;
  490. case "deleteContentBackward":
  491. var keydown = new $.Event("keydown");
  492. keydown.key = keys.Backspace;
  493. EventHandlers.keyEvent.call(input, keydown);
  494. break;
  495. default:
  496. applyInputValue(input, inputValue);
  497. caret.call(inputmask, input, caretPos.begin, caretPos.end, true);
  498. break;
  499. }
  500. e.preventDefault();
  501. }
  502. },
  503. setValueEvent: function (e) {
  504. const inputmask = this.inputmask,
  505. $ = inputmask.dependencyLib;
  506. let input = this,
  507. value = e && e.detail ? e.detail[0] : arguments[1];
  508. if (value === undefined) {
  509. value = input.inputmask._valueGet(true);
  510. }
  511. applyInputValue(input, value, new $.Event("input"));
  512. if ((e.detail && e.detail[1] !== undefined) || arguments[2] !== undefined) {
  513. caret.call(inputmask, input, e.detail ? e.detail[1] : arguments[2]);
  514. }
  515. },
  516. focusEvent: function (e) {
  517. const inputmask = this.inputmask,
  518. opts = inputmask.opts,
  519. input = this,
  520. nptValue = inputmask && inputmask._valueGet();
  521. if (opts.showMaskOnFocus) {
  522. if (nptValue !== getBuffer.call(inputmask).join("")) {
  523. writeBuffer(
  524. input,
  525. getBuffer.call(inputmask),
  526. seekNext.call(inputmask, getLastValidPosition.call(inputmask))
  527. );
  528. } /* else if (mouseEnter === false) { //only executed on focus without mouseenter
  529. caret(input, seekNext(getLastValidPosition()));
  530. } */
  531. }
  532. if (
  533. opts.positionCaretOnTab === true &&
  534. inputmask.mouseEnter === false &&
  535. (!isComplete.call(inputmask, getBuffer.call(inputmask)) ||
  536. getLastValidPosition.call(inputmask) === -1)
  537. ) {
  538. EventHandlers.clickEvent.apply(input, [e, true]);
  539. }
  540. inputmask.undoValue = inputmask && inputmask._valueGet(true);
  541. },
  542. invalidEvent: function (e) {
  543. this.inputmask.validationEvent = true;
  544. },
  545. mouseleaveEvent: function () {
  546. const inputmask = this.inputmask,
  547. opts = inputmask.opts,
  548. input = this;
  549. inputmask.mouseEnter = false;
  550. if (
  551. opts.clearMaskOnLostFocus &&
  552. (input.inputmask.shadowRoot || input.ownerDocument).activeElement !==
  553. input
  554. ) {
  555. HandleNativePlaceholder(input, inputmask.originalPlaceholder);
  556. }
  557. },
  558. clickEvent: function (e, tabbed) {
  559. const inputmask = this.inputmask;
  560. inputmask.clicked++;
  561. const input = this;
  562. if (
  563. (input.inputmask.shadowRoot || input.ownerDocument).activeElement ===
  564. input
  565. ) {
  566. const newCaretPosition = determineNewCaretPosition.call(
  567. inputmask,
  568. caret.call(inputmask, input),
  569. tabbed
  570. );
  571. if (newCaretPosition !== undefined) {
  572. caret.call(inputmask, input, newCaretPosition);
  573. }
  574. }
  575. },
  576. cutEvent: function (e) {
  577. const inputmask = this.inputmask,
  578. maskset = inputmask.maskset,
  579. input = this,
  580. pos = caret.call(inputmask, input),
  581. // correct clipboardData
  582. clipData = inputmask.isRTL
  583. ? getBuffer.call(inputmask).slice(pos.end, pos.begin)
  584. : getBuffer.call(inputmask).slice(pos.begin, pos.end),
  585. clipDataText = inputmask.isRTL
  586. ? clipData.reverse().join("")
  587. : clipData.join("");
  588. if (window.navigator && window.navigator.clipboard)
  589. window.navigator.clipboard.writeText(clipDataText);
  590. else if (window.clipboardData && window.clipboardData.getData) {
  591. // IE
  592. window.clipboardData.setData("Text", clipDataText);
  593. }
  594. handleRemove.call(inputmask, input, keys.Delete, pos);
  595. writeBuffer(
  596. input,
  597. getBuffer.call(inputmask),
  598. maskset.p,
  599. e,
  600. inputmask.undoValue !== inputmask._valueGet(true)
  601. );
  602. },
  603. blurEvent: function (e) {
  604. const inputmask = this.inputmask,
  605. opts = inputmask.opts,
  606. $ = inputmask.dependencyLib;
  607. inputmask.clicked = 0;
  608. const $input = $(this),
  609. input = this;
  610. if (input.inputmask) {
  611. HandleNativePlaceholder(input, inputmask.originalPlaceholder);
  612. let nptValue = input.inputmask._valueGet(),
  613. buffer = getBuffer.call(inputmask).slice();
  614. if (nptValue !== "") {
  615. if (opts.clearMaskOnLostFocus) {
  616. if (
  617. getLastValidPosition.call(inputmask) === -1 &&
  618. nptValue === getBufferTemplate.call(inputmask).join("")
  619. ) {
  620. buffer = [];
  621. } else {
  622. // clearout optional tail of the mask
  623. clearOptionalTail.call(inputmask, buffer);
  624. }
  625. }
  626. if (isComplete.call(inputmask, buffer) === false) {
  627. setTimeout(function () {
  628. $input.trigger("incomplete");
  629. }, 0);
  630. if (opts.clearIncomplete) {
  631. resetMaskSet.call(inputmask, false);
  632. if (opts.clearMaskOnLostFocus) {
  633. buffer = [];
  634. } else {
  635. buffer = getBufferTemplate.call(inputmask).slice();
  636. }
  637. }
  638. }
  639. writeBuffer(input, buffer, undefined, e);
  640. }
  641. nptValue = inputmask._valueGet(true);
  642. if (inputmask.undoValue !== nptValue) {
  643. if (
  644. nptValue != "" ||
  645. inputmask.undoValue != getBufferTemplate.call(inputmask).join("") ||
  646. (inputmask.undoValue == getBufferTemplate.call(inputmask).join("") &&
  647. inputmask.maskset.validPositions.length > 0)
  648. ) {
  649. inputmask.undoValue = nptValue;
  650. $input.trigger("change");
  651. }
  652. }
  653. }
  654. },
  655. mouseenterEvent: function () {
  656. const inputmask = this.inputmask,
  657. { showMaskOnHover } = inputmask.opts,
  658. input = this;
  659. inputmask.mouseEnter = true;
  660. if (
  661. (input.inputmask.shadowRoot || input.ownerDocument).activeElement !==
  662. input
  663. ) {
  664. const bufferTemplate = (
  665. inputmask.isRTL
  666. ? getBufferTemplate.call(inputmask).slice().reverse()
  667. : getBufferTemplate.call(inputmask)
  668. ).join("");
  669. if (showMaskOnHover) {
  670. HandleNativePlaceholder(input, bufferTemplate);
  671. }
  672. }
  673. },
  674. submitEvent: function () {
  675. // trigger change on submit if any
  676. const inputmask = this.inputmask,
  677. opts = inputmask.opts;
  678. if (inputmask.undoValue !== inputmask._valueGet(true)) {
  679. inputmask.$el.trigger("change");
  680. }
  681. if (
  682. /* opts.clearMaskOnLostFocus && */ getLastValidPosition.call(
  683. inputmask
  684. ) === -1 &&
  685. inputmask._valueGet &&
  686. inputmask._valueGet() === getBufferTemplate.call(inputmask).join("")
  687. ) {
  688. inputmask._valueSet(""); // clear masktemplete on submit and still has focus
  689. }
  690. if (
  691. opts.clearIncomplete &&
  692. isComplete.call(inputmask, getBuffer.call(inputmask)) === false
  693. ) {
  694. inputmask._valueSet("");
  695. }
  696. if (opts.removeMaskOnSubmit) {
  697. inputmask._valueSet(inputmask.unmaskedvalue(), true);
  698. setTimeout(function () {
  699. writeBuffer(inputmask.el, getBuffer.call(inputmask));
  700. }, 0);
  701. }
  702. },
  703. resetEvent: function () {
  704. const inputmask = this.inputmask;
  705. inputmask.refreshValue = true; // indicate a forced refresh when there is a call to the value before leaving the triggering event fn
  706. setTimeout(function () {
  707. applyInputValue(inputmask.el, inputmask._valueGet(true));
  708. }, 0);
  709. }
  710. };