msgFormatter.js 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. /**
  2. * replace all :emoji: codes with corresponding image
  3. * @param {string} inputString
  4. * @return {string}
  5. **/
  6. function formatEmojis(inputString) {
  7. return inputString.replace(/:([^ \t:]+):/g, function(returnFailed, emoji) {
  8. var emojiDom = makeEmojiDom(emoji);
  9. if (emojiDom) {
  10. var domParent = document.createElement("span");
  11. domParent.className = returnFailed === inputString ? R.klass.emoji.medium : R.klass.emoji.small;
  12. domParent.appendChild(emojiDom);
  13. return domParent.outerHTML;
  14. }
  15. return returnFailed;
  16. });
  17. }
  18. /**
  19. * @param {string} fullText
  20. * @return {string}
  21. **/
  22. var formatText = (function() {
  23. return function (fullText) {
  24. if (!fullText || fullText == "")
  25. return "";
  26. var msgContents = fullText.split(/\r?\n/g);
  27. for (var msgContentIndex=0, nbMsgContents = msgContents.length; msgContentIndex < nbMsgContents; msgContentIndex++) {
  28. var msgContent = msgContents[msgContentIndex].trim()
  29. ,_msgContent = ""
  30. ,currentMods = {}
  31. ,quote = false
  32. ,i =0
  33. msgContent = msgContent.replace(new RegExp('<([@#]?)([^>]*)>', 'g'),
  34. function(matched, type, entity) {
  35. var sub = entity.split('|');
  36. if (type === '@') {
  37. if (!sub[1]) {
  38. var user = SLACK.context.users[sub[0]];
  39. sub[1] = user ? ('@' +user.name) : locale.unknownMember;
  40. } else if ('@' !== sub[1][0]) {
  41. sub[1] = '@' +sub[1];
  42. }
  43. sub[0] = '#' +sub[0];
  44. sub[2] = R.klass.msg.link +' ' +R.klass.msg.linkuser;
  45. } else if (type === '#') {
  46. if (!sub[1]) {
  47. var chan = SLACK.context.channels[sub[0]];
  48. sub[1] = chan ? ('#' +chan.name) : locale.unknownChannel;
  49. } else if ('#' !== sub[1][0]) {
  50. sub[1] = '#' +sub[1];
  51. }
  52. sub[0] = '#' +sub[0];
  53. sub[2] = R.klass.msg.link +' ' +R.klass.msg.linkchan;
  54. } else if (sub[0].indexOf("://") !== -1) {
  55. if (!sub[1])
  56. sub[1] = sub[0];
  57. sub[2] = R.klass.msg.link;
  58. } else {
  59. return matched;
  60. }
  61. return '<a href="' +sub[0] +'" class="' +sub[2] +'"' +(!type ? ' target="_blank"' : '') +'>' +sub[1] +'</a>';
  62. });
  63. msgContent = formatEmojis(msgContent);
  64. var msgLength = msgContent.length;
  65. var isAlphadec = function(c) {
  66. return ((c >= 'A' && c <= 'Z') ||
  67. (c >= 'a' && c <= 'z') ||
  68. (c >= '0' && c <= '9') ||
  69. "àèìòùÀÈÌÒÙáéíóúýÁÉÍÓÚÝâêîôûÂÊÎÔÛãñõÃÑÕäëïöüÿÄËÏÖÜŸçÇߨøÅ寿œ".indexOf(c) !== -1);
  70. }
  71. ,checkEnd = function(str, pos, c) {
  72. while (str[pos]) {
  73. if (isAlphadec(str[pos]) && str[pos] != c && str[pos +1] == c) {
  74. return true;
  75. }
  76. pos++;
  77. }
  78. return false;
  79. } ,appendMod = function(mods) {
  80. if (!Object.keys(currentMods).length)
  81. return "";
  82. return '<span class="' +Object.keys(mods).join(' ') +'">';
  83. };
  84. // Skip trailing
  85. while (i < msgLength && (msgContent[i] === ' ' || msgContent[i] === '\t'))
  86. i++;
  87. if (msgContent.substr(i, 4) === '&gt;') {
  88. quote = true;
  89. i += 4;
  90. }
  91. for (; i < msgLength; i++) {
  92. var c = msgContent[i];
  93. if (c === '<') {
  94. do {
  95. _msgContent += msgContent[i++];
  96. } while (msgContent[i -1] !== '>' && msgContent[i]);
  97. i--;
  98. continue;
  99. }
  100. if (!(currentMods[R.klass.msg.style.bold]) && c === '*' && msgContent[i +1] && checkEnd(msgContent, i, c)) {
  101. if (Object.keys(currentMods).length)
  102. _msgContent += '</span>';
  103. currentMods[R.klass.msg.style.bold] = true;
  104. _msgContent += appendMod(currentMods);
  105. } else if (!(currentMods[R.klass.msg.style.strike]) && c === '~' && msgContent[i +1] && checkEnd(msgContent, i, c)) {
  106. if (Object.keys(currentMods).length)
  107. _msgContent += '</span>';
  108. currentMods[R.klass.msg.style.strike] = true;
  109. _msgContent += appendMod(currentMods);
  110. } else if (!(currentMods[R.klass.msg.style.code]) && c === '`' && msgContent[i +1] && checkEnd(msgContent, i, c)) {
  111. if (Object.keys(currentMods).length)
  112. _msgContent += '</span>';
  113. currentMods[R.klass.msg.style.code] = true;
  114. _msgContent += appendMod(currentMods);
  115. } else if (!(currentMods[R.klass.msg.style.italic]) && c === '_' && msgContent[i +1] && checkEnd(msgContent, i, c)) {
  116. if (Object.keys(currentMods).length)
  117. _msgContent += '</span>';
  118. currentMods[R.klass.msg.style.italic] = true;
  119. _msgContent += appendMod(currentMods);
  120. } else {
  121. var finalFound = false;
  122. _msgContent += c;
  123. do {
  124. if ((currentMods[R.klass.msg.style.bold]) && c !== '*' && msgContent[i +1] === '*') {
  125. delete currentMods[R.klass.msg.style.bold];
  126. finalFound = true;
  127. } else if ((currentMods[R.klass.msg.style.strike]) && c !== '~' && msgContent[i +1] === '~') {
  128. delete currentMods[R.klass.msg.style.strike];
  129. finalFound = true;
  130. } else if ((currentMods[R.klass.msg.style.code]) && c !== '`' && msgContent[i +1] === '`') {
  131. delete currentMods[R.klass.msg.style.code];
  132. finalFound = true;
  133. } else if ((currentMods[R.klass.msg.style.italic]) && c !== '_' && msgContent[i +1] === '_') {
  134. delete currentMods[R.klass.msg.style.italic];
  135. finalFound = true;
  136. } else {
  137. break;
  138. }
  139. c = msgContent[++i];
  140. } while (i < msgLength);
  141. if (finalFound)
  142. _msgContent += '</span>' +appendMod(currentMods);
  143. }
  144. }
  145. if (!isObjectEmpty(currentMods)) {
  146. // Should not append
  147. console.warn("formatter warning");
  148. _msgContent += '</span>';
  149. }
  150. if (quote)
  151. msgContents[msgContentIndex] = '<span class="' +R.klass.msg.style.quote +'">' +_msgContent +'</span>';
  152. else
  153. msgContents[msgContentIndex] = _msgContent;
  154. }
  155. return msgContents.length === 0 ? "" : msgContents.join('<br/>');
  156. }
  157. })();