insertion-text.js 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. /*
  2. Copyright 2012-2015, Yahoo Inc.
  3. Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
  4. */
  5. function InsertionText(text, consumeBlanks) {
  6. this.text = text;
  7. this.origLength = text.length;
  8. this.offsets = [];
  9. this.consumeBlanks = consumeBlanks;
  10. this.startPos = this.findFirstNonBlank();
  11. this.endPos = this.findLastNonBlank();
  12. }
  13. var WHITE_RE = /[ \f\n\r\t\v\u00A0\u2028\u2029]/;
  14. InsertionText.prototype = {
  15. findFirstNonBlank: function () {
  16. var pos = -1,
  17. text = this.text,
  18. len = text.length,
  19. i;
  20. for (i = 0; i < len; i += 1) {
  21. if (!text.charAt(i).match(WHITE_RE)) {
  22. pos = i;
  23. break;
  24. }
  25. }
  26. return pos;
  27. },
  28. findLastNonBlank: function () {
  29. var text = this.text,
  30. len = text.length,
  31. pos = text.length + 1,
  32. i;
  33. for (i = len - 1; i >= 0; i -= 1) {
  34. if (!text.charAt(i).match(WHITE_RE)) {
  35. pos = i;
  36. break;
  37. }
  38. }
  39. return pos;
  40. },
  41. originalLength: function () {
  42. return this.origLength;
  43. },
  44. insertAt: function (col, str, insertBefore, consumeBlanks) {
  45. consumeBlanks = typeof consumeBlanks === 'undefined' ? this.consumeBlanks : consumeBlanks;
  46. col = col > this.originalLength() ? this.originalLength() : col;
  47. col = col < 0 ? 0 : col;
  48. if (consumeBlanks) {
  49. if (col <= this.startPos) {
  50. col = 0;
  51. }
  52. if (col > this.endPos) {
  53. col = this.origLength;
  54. }
  55. }
  56. var len = str.length,
  57. offset = this.findOffset(col, len, insertBefore),
  58. realPos = col + offset,
  59. text = this.text;
  60. this.text = text.substring(0, realPos) + str + text.substring(realPos);
  61. return this;
  62. },
  63. findOffset: function (pos, len, insertBefore) {
  64. var offsets = this.offsets,
  65. offsetObj,
  66. cumulativeOffset = 0,
  67. i;
  68. for (i = 0; i < offsets.length; i += 1) {
  69. offsetObj = offsets[i];
  70. if (offsetObj.pos < pos || (offsetObj.pos === pos && !insertBefore)) {
  71. cumulativeOffset += offsetObj.len;
  72. }
  73. if (offsetObj.pos >= pos) {
  74. break;
  75. }
  76. }
  77. if (offsetObj && offsetObj.pos === pos) {
  78. offsetObj.len += len;
  79. } else {
  80. offsets.splice(i, 0, { pos: pos, len: len });
  81. }
  82. return cumulativeOffset;
  83. },
  84. wrap: function (startPos, startText, endPos, endText, consumeBlanks) {
  85. this.insertAt(startPos, startText, true, consumeBlanks);
  86. this.insertAt(endPos, endText, false, consumeBlanks);
  87. return this;
  88. },
  89. wrapLine: function (startText, endText) {
  90. this.wrap(0, startText, this.originalLength(), endText);
  91. },
  92. toString: function () {
  93. return this.text;
  94. }
  95. };
  96. module.exports = InsertionText;