msgFormatter.js 6.9 KB

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