number_box.caret.js 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. /**
  2. * DevExtreme (ui/number_box/number_box.caret.js)
  3. * Version: 19.1.16
  4. * Build date: Tue Oct 18 2022
  5. *
  6. * Copyright (c) 2012 - 2022 Developer Express Inc. ALL RIGHTS RESERVED
  7. * Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/
  8. */
  9. "use strict";
  10. var fitIntoRange = require("../../core/utils/math").fitIntoRange;
  11. var escapeRegExp = require("../../core/utils/common").escapeRegExp;
  12. var number = require("../../localization/number");
  13. var getCaretBoundaries = function(text, format) {
  14. var signParts = format.split(";");
  15. var sign = number.getSign(text, format);
  16. signParts[1] = signParts[1] || "-" + signParts[0];
  17. format = signParts[sign < 0 ? 1 : 0];
  18. var mockEscapedStubs = function(str) {
  19. return str.replace(/'([^']*)'/g, function(str) {
  20. return str.split("").map(function() {
  21. return " "
  22. }).join("").substr(2)
  23. })
  24. };
  25. format = mockEscapedStubs(format);
  26. var prefixStubLength = /^[^#0.,]*/.exec(format)[0].length;
  27. var postfixStubLength = /[^#0.,]*$/.exec(format)[0].length;
  28. return {
  29. start: prefixStubLength,
  30. end: text.length - postfixStubLength
  31. }
  32. };
  33. var _getDigitCountBeforeIndex = function(index, text) {
  34. var decimalSeparator = number.getDecimalSeparator();
  35. var regExp = new RegExp("[^0-9" + escapeRegExp(decimalSeparator) + "]", "g");
  36. var textBeforePosition = text.slice(0, index);
  37. return textBeforePosition.replace(regExp, "").length
  38. };
  39. var _reverseText = function(text) {
  40. return text.split("").reverse().join("")
  41. };
  42. var _getDigitPositionByIndex = function(digitIndex, text) {
  43. if (!digitIndex) {
  44. return -1
  45. }
  46. var regExp = /[0-9]/g;
  47. var counter = 1;
  48. var index = null;
  49. var result = regExp.exec(text);
  50. while (result) {
  51. index = result.index;
  52. if (!digitIndex || counter >= digitIndex) {
  53. return index
  54. }
  55. counter++;
  56. result = regExp.exec(text)
  57. }
  58. return null === index ? text.length : index
  59. };
  60. var getCaretWithOffset = function(caret, offset) {
  61. if (void 0 === caret.start) {
  62. caret = {
  63. start: caret,
  64. end: caret
  65. }
  66. }
  67. return {
  68. start: caret.start + offset,
  69. end: caret.end + offset
  70. }
  71. };
  72. var getCaretAfterFormat = function(text, formatted, caret, format) {
  73. caret = getCaretWithOffset(caret, 0);
  74. var point = number.getDecimalSeparator();
  75. var isSeparatorBasedText = isSeparatorBasedString(text);
  76. var pointPosition = isSeparatorBasedText ? 0 : text.indexOf(point);
  77. var newPointPosition = formatted.indexOf(point);
  78. var textParts = isSeparatorBasedText ? text.split(text[pointPosition]) : text.split(point);
  79. var formattedParts = formatted.split(point);
  80. var isCaretOnFloat = pointPosition !== -1 && caret.start > pointPosition;
  81. if (isCaretOnFloat) {
  82. var relativeIndex = caret.start - pointPosition - 1;
  83. var digitsBefore = _getDigitCountBeforeIndex(relativeIndex, textParts[1]);
  84. var newPosition = formattedParts[1] ? newPointPosition + 1 + _getDigitPositionByIndex(digitsBefore, formattedParts[1]) + 1 : formatted.length;
  85. return getCaretInBoundaries(newPosition, formatted, format)
  86. } else {
  87. var positionFromEnd = textParts[0].length - caret.start;
  88. var digitsFromEnd = _getDigitCountBeforeIndex(positionFromEnd, _reverseText(textParts[0]));
  89. var newPositionFromEnd = _getDigitPositionByIndex(digitsFromEnd, _reverseText(formattedParts[0]));
  90. var newPositionFromBegin = formattedParts[0].length - (newPositionFromEnd + 1);
  91. return getCaretInBoundaries(newPositionFromBegin, formatted, format)
  92. }
  93. };
  94. var isSeparatorBasedString = function(text) {
  95. return 1 === text.length && !!text.match(/^[,.][0-9]*$/g)
  96. };
  97. var isCaretInBoundaries = function(caret, text, format) {
  98. caret = getCaretWithOffset(caret, 0);
  99. var boundaries = getCaretInBoundaries(caret, text, format);
  100. return caret.start >= boundaries.start && caret.end <= boundaries.end
  101. };
  102. var getCaretInBoundaries = function(caret, text, format) {
  103. caret = getCaretWithOffset(caret, 0);
  104. var boundaries = getCaretBoundaries(text, format);
  105. var adjustedCaret = {
  106. start: fitIntoRange(caret.start, boundaries.start, boundaries.end),
  107. end: fitIntoRange(caret.end, boundaries.start, boundaries.end)
  108. };
  109. return adjustedCaret
  110. };
  111. var getCaretOffset = function(previousText, newText, format) {
  112. var previousBoundaries = getCaretBoundaries(previousText, format);
  113. var newBoundaries = getCaretBoundaries(newText, format);
  114. return newBoundaries.start - previousBoundaries.start
  115. };
  116. exports.getCaretBoundaries = getCaretBoundaries;
  117. exports.isCaretInBoundaries = isCaretInBoundaries;
  118. exports.getCaretWithOffset = getCaretWithOffset;
  119. exports.getCaretInBoundaries = getCaretInBoundaries;
  120. exports.getCaretAfterFormat = getCaretAfterFormat;
  121. exports.getCaretOffset = getCaretOffset;