truncate-smart.js 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.truncateSmart = void 0;
  4. /**
  5. * Date: 2015-10-05
  6. * Author: Kasper Søfren <soefritz@gmail.com> (https://github.com/kafoso)
  7. *
  8. * A truncation feature, where the ellipsis will be placed at a section within
  9. * the URL making it still somewhat human readable.
  10. *
  11. * @param {String} url A URL.
  12. * @param {Number} truncateLen The maximum length of the truncated output URL string.
  13. * @param {String} ellipsisChars The characters to place within the url, e.g. "...".
  14. * @return {String} The truncated URL.
  15. */
  16. function truncateSmart(url, truncateLen, ellipsisChars) {
  17. var ellipsisLengthBeforeParsing;
  18. var ellipsisLength;
  19. if (ellipsisChars == null) {
  20. ellipsisChars = '&hellip;';
  21. ellipsisLength = 3;
  22. ellipsisLengthBeforeParsing = 8;
  23. }
  24. else {
  25. ellipsisLength = ellipsisChars.length;
  26. ellipsisLengthBeforeParsing = ellipsisChars.length;
  27. }
  28. var parse_url = function (url) {
  29. // Functionality inspired by PHP function of same name
  30. var urlObj = {};
  31. var urlSub = url;
  32. var match = urlSub.match(/^([a-z]+):\/\//i);
  33. if (match) {
  34. urlObj.scheme = match[1];
  35. urlSub = urlSub.substr(match[0].length);
  36. }
  37. match = urlSub.match(/^(.*?)(?=(\?|#|\/|$))/i);
  38. if (match) {
  39. urlObj.host = match[1];
  40. urlSub = urlSub.substr(match[0].length);
  41. }
  42. match = urlSub.match(/^\/(.*?)(?=(\?|#|$))/i);
  43. if (match) {
  44. urlObj.path = match[1];
  45. urlSub = urlSub.substr(match[0].length);
  46. }
  47. match = urlSub.match(/^\?(.*?)(?=(#|$))/i);
  48. if (match) {
  49. urlObj.query = match[1];
  50. urlSub = urlSub.substr(match[0].length);
  51. }
  52. match = urlSub.match(/^#(.*?)$/i);
  53. if (match) {
  54. urlObj.fragment = match[1];
  55. //urlSub = urlSub.substr(match[0].length); -- not used. Uncomment if adding another block.
  56. }
  57. return urlObj;
  58. };
  59. var buildUrl = function (urlObj) {
  60. var url = '';
  61. if (urlObj.scheme && urlObj.host) {
  62. url += urlObj.scheme + '://';
  63. }
  64. if (urlObj.host) {
  65. url += urlObj.host;
  66. }
  67. if (urlObj.path) {
  68. url += '/' + urlObj.path;
  69. }
  70. if (urlObj.query) {
  71. url += '?' + urlObj.query;
  72. }
  73. if (urlObj.fragment) {
  74. url += '#' + urlObj.fragment;
  75. }
  76. return url;
  77. };
  78. var buildSegment = function (segment, remainingAvailableLength) {
  79. var remainingAvailableLengthHalf = remainingAvailableLength / 2, startOffset = Math.ceil(remainingAvailableLengthHalf), endOffset = -1 * Math.floor(remainingAvailableLengthHalf), end = '';
  80. if (endOffset < 0) {
  81. end = segment.substr(endOffset);
  82. }
  83. return segment.substr(0, startOffset) + ellipsisChars + end;
  84. };
  85. if (url.length <= truncateLen) {
  86. return url;
  87. }
  88. var availableLength = truncateLen - ellipsisLength;
  89. var urlObj = parse_url(url);
  90. // Clean up the URL
  91. if (urlObj.query) {
  92. var matchQuery = urlObj.query.match(/^(.*?)(?=(\?|\#))(.*?)$/i);
  93. if (matchQuery) {
  94. // Malformed URL; two or more "?". Removed any content behind the 2nd.
  95. urlObj.query = urlObj.query.substr(0, matchQuery[1].length);
  96. url = buildUrl(urlObj);
  97. }
  98. }
  99. if (url.length <= truncateLen) {
  100. return url;
  101. }
  102. if (urlObj.host) {
  103. urlObj.host = urlObj.host.replace(/^www\./, '');
  104. url = buildUrl(urlObj);
  105. }
  106. if (url.length <= truncateLen) {
  107. return url;
  108. }
  109. // Process and build the URL
  110. var str = '';
  111. if (urlObj.host) {
  112. str += urlObj.host;
  113. }
  114. if (str.length >= availableLength) {
  115. if (urlObj.host.length == truncateLen) {
  116. return (urlObj.host.substr(0, truncateLen - ellipsisLength) + ellipsisChars).substr(0, availableLength + ellipsisLengthBeforeParsing);
  117. }
  118. return buildSegment(str, availableLength).substr(0, availableLength + ellipsisLengthBeforeParsing);
  119. }
  120. var pathAndQuery = '';
  121. if (urlObj.path) {
  122. pathAndQuery += '/' + urlObj.path;
  123. }
  124. if (urlObj.query) {
  125. pathAndQuery += '?' + urlObj.query;
  126. }
  127. if (pathAndQuery) {
  128. if ((str + pathAndQuery).length >= availableLength) {
  129. if ((str + pathAndQuery).length == truncateLen) {
  130. return (str + pathAndQuery).substr(0, truncateLen);
  131. }
  132. var remainingAvailableLength = availableLength - str.length;
  133. return (str + buildSegment(pathAndQuery, remainingAvailableLength)).substr(0, availableLength + ellipsisLengthBeforeParsing);
  134. }
  135. else {
  136. str += pathAndQuery;
  137. }
  138. }
  139. if (urlObj.fragment) {
  140. var fragment = '#' + urlObj.fragment;
  141. if ((str + fragment).length >= availableLength) {
  142. if ((str + fragment).length == truncateLen) {
  143. return (str + fragment).substr(0, truncateLen);
  144. }
  145. var remainingAvailableLength2 = availableLength - str.length;
  146. return (str + buildSegment(fragment, remainingAvailableLength2)).substr(0, availableLength + ellipsisLengthBeforeParsing);
  147. }
  148. else {
  149. str += fragment;
  150. }
  151. }
  152. if (urlObj.scheme && urlObj.host) {
  153. var scheme = urlObj.scheme + '://';
  154. if ((str + scheme).length < availableLength) {
  155. return (scheme + str).substr(0, truncateLen);
  156. }
  157. }
  158. if (str.length <= truncateLen) {
  159. return str;
  160. }
  161. var end = '';
  162. if (availableLength > 0) {
  163. end = str.substr(-1 * Math.floor(availableLength / 2));
  164. }
  165. return (str.substr(0, Math.ceil(availableLength / 2)) + ellipsisChars + end).substr(0, availableLength + ellipsisLengthBeforeParsing);
  166. }
  167. exports.truncateSmart = truncateSmart;
  168. //# sourceMappingURL=truncate-smart.js.map