Front end of the Slack clone application.

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. 'use strict';
  2. const isFullwidthCodePoint = require('is-fullwidth-code-point');
  3. const ESCAPES = [
  4. '\u001B',
  5. '\u009B'
  6. ];
  7. const END_CODE = 39;
  8. const ASTRAL_REGEX = /[\uD800-\uDBFF][\uDC00-\uDFFF]/;
  9. const ESCAPE_CODES = new Map([
  10. [0, 0],
  11. [1, 22],
  12. [2, 22],
  13. [3, 23],
  14. [4, 24],
  15. [7, 27],
  16. [8, 28],
  17. [9, 29],
  18. [30, 39],
  19. [31, 39],
  20. [32, 39],
  21. [33, 39],
  22. [34, 39],
  23. [35, 39],
  24. [36, 39],
  25. [37, 39],
  26. [90, 39],
  27. [40, 49],
  28. [41, 49],
  29. [42, 49],
  30. [43, 49],
  31. [44, 49],
  32. [45, 49],
  33. [46, 49],
  34. [47, 49]
  35. ]);
  36. const wrapAnsi = code => `${ESCAPES[0]}[${code}m`;
  37. module.exports = (str, begin, end) => {
  38. const arr = Array.from(str.normalize());
  39. end = typeof end === 'number' ? end : arr.length;
  40. let insideEscape = false;
  41. let escapeCode;
  42. let visible = 0;
  43. let output = '';
  44. for (const item of arr.entries()) {
  45. const i = item[0];
  46. const x = item[1];
  47. let leftEscape = false;
  48. if (ESCAPES.indexOf(x) !== -1) {
  49. insideEscape = true;
  50. const code = /\d[^m]*/.exec(str.slice(i, i + 4));
  51. escapeCode = code === END_CODE ? null : code;
  52. } else if (insideEscape && x === 'm') {
  53. insideEscape = false;
  54. leftEscape = true;
  55. }
  56. if (!insideEscape && !leftEscape) {
  57. ++visible;
  58. }
  59. if (!ASTRAL_REGEX.test(x) && isFullwidthCodePoint(x.codePointAt())) {
  60. ++visible;
  61. }
  62. if (visible > begin && visible <= end) {
  63. output += x;
  64. } else if (visible === begin && !insideEscape && escapeCode !== undefined && escapeCode !== END_CODE) {
  65. output += wrapAnsi(escapeCode);
  66. } else if (visible >= end) {
  67. if (escapeCode !== undefined) {
  68. output += wrapAnsi(ESCAPE_CODES.get(parseInt(escapeCode, 10)) || END_CODE);
  69. }
  70. break;
  71. }
  72. }
  73. return output;
  74. };