From 95353248f5bb2b81fe7a6236fde3a27437d10d8b Mon Sep 17 00:00:00 2001 From: morethanwords Date: Sat, 29 Aug 2020 18:10:04 +0300 Subject: [PATCH] Fix emoji --- src/emoji/index.ts | 36 ++ src/emoji/regex.ts | 4 + ...htextprocessor.js => richtextprocessor.ts} | 364 +++++++++--------- src/lib/utils.ts | 51 --- src/scripts/format_jsons.js | 2 + 5 files changed, 233 insertions(+), 224 deletions(-) create mode 100644 src/emoji/index.ts create mode 100644 src/emoji/regex.ts rename src/lib/{richtextprocessor.js => richtextprocessor.ts} (54%) diff --git a/src/emoji/index.ts b/src/emoji/index.ts new file mode 100644 index 00000000..f480ce3c --- /dev/null +++ b/src/emoji/index.ts @@ -0,0 +1,36 @@ +// https://github.com/twitter/twemoji-parser/blob/master/src/lib/regex.js + +export function encodeEmoji(emojiText: string) { + const codepoints = toCodePoints(removeVS16s(emojiText)).join('-'); + return codepoints; +} + +const vs16RegExp = /\uFE0F/g; +// avoid using a string literal like '\u200D' here because minifiers expand it inline +const zeroWidthJoiner = String.fromCharCode(0x200d); + +const removeVS16s = (rawEmoji: string) => (rawEmoji.indexOf(zeroWidthJoiner) < 0 ? rawEmoji.replace(vs16RegExp, '') : rawEmoji); + +export function toCodePoints(unicodeSurrogates: string): Array { + const points = []; + let char = 0; + let previous = 0; + let i = 0; + while(i < unicodeSurrogates.length) { + char = unicodeSurrogates.charCodeAt(i++); + if(previous) { + points.push((0x10000 + ((previous - 0xd800) << 10) + (char - 0xdc00)).toString(16)); + previous = 0; + } else if (char > 0xd800 && char <= 0xdbff) { + previous = char; + } else { + points.push(char.toString(16)); + } + } + + if(points.length && points[0].length == 2) { + points[0] = '00' + points[0]; + } + + return points; +} \ No newline at end of file diff --git a/src/emoji/regex.ts b/src/emoji/regex.ts new file mode 100644 index 00000000..b31120a8 --- /dev/null +++ b/src/emoji/regex.ts @@ -0,0 +1,4 @@ +// Copyright Twitter Inc. Licensed under MIT +// https://github.com/twitter/twemoji-parser/blob/master/LICENSE.md + +export default "(?:\ud83d\udc68\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffc-\udfff]|\ud83d\udc68\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffd-\udfff]|\ud83d\udc68\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc68\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffd\udfff]|\ud83d\udc68\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffe]|\ud83d\udc69\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffc-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffc-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffd-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb\udffd-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc69\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc69\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffd\udfff]|\ud83d\udc69\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb-\udffd\udfff]|\ud83d\udc69\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffe]|\ud83d\udc69\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb-\udffe]|\ud83e\uddd1\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\u200d\ud83e\udd1d\u200d\ud83e\uddd1|\ud83d\udc6b\ud83c[\udffb-\udfff]|\ud83d\udc6c\ud83c[\udffb-\udfff]|\ud83d\udc6d\ud83c[\udffb-\udfff]|\ud83d[\udc6b-\udc6d])|(?:\ud83d[\udc68\udc69]|\ud83e\uddd1)(?:\ud83c[\udffb-\udfff])?\u200d(?:\u2695\ufe0f|\u2696\ufe0f|\u2708\ufe0f|\ud83c[\udf3e\udf73\udf7c\udf84\udf93\udfa4\udfa8\udfeb\udfed]|\ud83d[\udcbb\udcbc\udd27\udd2c\ude80\ude92]|\ud83e[\uddaf-\uddb3\uddbc\uddbd])|(?:\ud83c[\udfcb\udfcc]|\ud83d[\udd74\udd75]|\u26f9)((?:\ud83c[\udffb-\udfff]|\ufe0f)\u200d[\u2640\u2642]\ufe0f)|(?:\ud83c[\udfc3\udfc4\udfca]|\ud83d[\udc6e\udc70\udc71\udc73\udc77\udc81\udc82\udc86\udc87\ude45-\ude47\ude4b\ude4d\ude4e\udea3\udeb4-\udeb6]|\ud83e[\udd26\udd35\udd37-\udd39\udd3d\udd3e\uddb8\uddb9\uddcd-\uddcf\uddd6-\udddd])(?:\ud83c[\udffb-\udfff])?\u200d[\u2640\u2642]\ufe0f|(?:\ud83d\udc68\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68|\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d[\udc68\udc69]|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\u2764\ufe0f\u200d\ud83d\udc68|\ud83d\udc68\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\u2764\ufe0f\u200d\ud83d[\udc68\udc69]|\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83c\udff3\ufe0f\u200d\u26a7\ufe0f|\ud83c\udff3\ufe0f\u200d\ud83c\udf08|\ud83c\udff4\u200d\u2620\ufe0f|\ud83d\udc15\u200d\ud83e\uddba|\ud83d\udc3b\u200d\u2744\ufe0f|\ud83d\udc41\u200d\ud83d\udde8|\ud83d\udc68\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83d\udc6f\u200d\u2640\ufe0f|\ud83d\udc6f\u200d\u2642\ufe0f|\ud83e\udd3c\u200d\u2640\ufe0f|\ud83e\udd3c\u200d\u2642\ufe0f|\ud83e\uddde\u200d\u2640\ufe0f|\ud83e\uddde\u200d\u2642\ufe0f|\ud83e\udddf\u200d\u2640\ufe0f|\ud83e\udddf\u200d\u2642\ufe0f|\ud83d\udc08\u200d\u2b1b)|[#*0-9]\ufe0f?\u20e3|(?:[©®\u2122\u265f]\ufe0f)|(?:\ud83c[\udc04\udd70\udd71\udd7e\udd7f\ude02\ude1a\ude2f\ude37\udf21\udf24-\udf2c\udf36\udf7d\udf96\udf97\udf99-\udf9b\udf9e\udf9f\udfcd\udfce\udfd4-\udfdf\udff3\udff5\udff7]|\ud83d[\udc3f\udc41\udcfd\udd49\udd4a\udd6f\udd70\udd73\udd76-\udd79\udd87\udd8a-\udd8d\udda5\udda8\uddb1\uddb2\uddbc\uddc2-\uddc4\uddd1-\uddd3\udddc-\uddde\udde1\udde3\udde8\uddef\uddf3\uddfa\udecb\udecd-\udecf\udee0-\udee5\udee9\udef0\udef3]|[\u203c\u2049\u2139\u2194-\u2199\u21a9\u21aa\u231a\u231b\u2328\u23cf\u23ed-\u23ef\u23f1\u23f2\u23f8-\u23fa\u24c2\u25aa\u25ab\u25b6\u25c0\u25fb-\u25fe\u2600-\u2604\u260e\u2611\u2614\u2615\u2618\u2620\u2622\u2623\u2626\u262a\u262e\u262f\u2638-\u263a\u2640\u2642\u2648-\u2653\u2660\u2663\u2665\u2666\u2668\u267b\u267f\u2692-\u2697\u2699\u269b\u269c\u26a0\u26a1\u26a7\u26aa\u26ab\u26b0\u26b1\u26bd\u26be\u26c4\u26c5\u26c8\u26cf\u26d1\u26d3\u26d4\u26e9\u26ea\u26f0-\u26f5\u26f8\u26fa\u26fd\u2702\u2708\u2709\u270f\u2712\u2714\u2716\u271d\u2721\u2733\u2734\u2744\u2747\u2757\u2763\u2764\u27a1\u2934\u2935\u2b05-\u2b07\u2b1b\u2b1c\u2b50\u2b55\u3030\u303d\u3297\u3299])(?:\ufe0f|(?!\ufe0e))|(?:(?:\ud83c[\udfcb\udfcc]|\ud83d[\udd74\udd75\udd90]|[\u261d\u26f7\u26f9\u270c\u270d])(?:\ufe0f|(?!\ufe0e))|(?:\ud83c[\udf85\udfc2-\udfc4\udfc7\udfca]|\ud83d[\udc42\udc43\udc46-\udc50\udc66-\udc69\udc6e\udc70-\udc78\udc7c\udc81-\udc83\udc85-\udc87\udcaa\udd7a\udd95\udd96\ude45-\ude47\ude4b-\ude4f\udea3\udeb4-\udeb6\udec0\udecc]|\ud83e[\udd0c\udd0f\udd18-\udd1c\udd1e\udd1f\udd26\udd30-\udd39\udd3d\udd3e\udd77\uddb5\uddb6\uddb8\uddb9\uddbb\uddcd-\uddcf\uddd1-\udddd]|[\u270a\u270b]))(?:\ud83c[\udffb-\udfff])?|(?:\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc65\udb40\udc6e\udb40\udc67\udb40\udc7f|\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc73\udb40\udc63\udb40\udc74\udb40\udc7f|\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc77\udb40\udc6c\udb40\udc73\udb40\udc7f|\ud83c\udde6\ud83c[\udde8-\uddec\uddee\uddf1\uddf2\uddf4\uddf6-\uddfa\uddfc\uddfd\uddff]|\ud83c\udde7\ud83c[\udde6\udde7\udde9-\uddef\uddf1-\uddf4\uddf6-\uddf9\uddfb\uddfc\uddfe\uddff]|\ud83c\udde8\ud83c[\udde6\udde8\udde9\uddeb-\uddee\uddf0-\uddf5\uddf7\uddfa-\uddff]|\ud83c\udde9\ud83c[\uddea\uddec\uddef\uddf0\uddf2\uddf4\uddff]|\ud83c\uddea\ud83c[\udde6\udde8\uddea\uddec\udded\uddf7-\uddfa]|\ud83c\uddeb\ud83c[\uddee-\uddf0\uddf2\uddf4\uddf7]|\ud83c\uddec\ud83c[\udde6\udde7\udde9-\uddee\uddf1-\uddf3\uddf5-\uddfa\uddfc\uddfe]|\ud83c\udded\ud83c[\uddf0\uddf2\uddf3\uddf7\uddf9\uddfa]|\ud83c\uddee\ud83c[\udde8-\uddea\uddf1-\uddf4\uddf6-\uddf9]|\ud83c\uddef\ud83c[\uddea\uddf2\uddf4\uddf5]|\ud83c\uddf0\ud83c[\uddea\uddec-\uddee\uddf2\uddf3\uddf5\uddf7\uddfc\uddfe\uddff]|\ud83c\uddf1\ud83c[\udde6-\udde8\uddee\uddf0\uddf7-\uddfb\uddfe]|\ud83c\uddf2\ud83c[\udde6\udde8-\udded\uddf0-\uddff]|\ud83c\uddf3\ud83c[\udde6\udde8\uddea-\uddec\uddee\uddf1\uddf4\uddf5\uddf7\uddfa\uddff]|\ud83c\uddf4\ud83c\uddf2|\ud83c\uddf5\ud83c[\udde6\uddea-\udded\uddf0-\uddf3\uddf7-\uddf9\uddfc\uddfe]|\ud83c\uddf6\ud83c\udde6|\ud83c\uddf7\ud83c[\uddea\uddf4\uddf8\uddfa\uddfc]|\ud83c\uddf8\ud83c[\udde6-\uddea\uddec-\uddf4\uddf7-\uddf9\uddfb\uddfd-\uddff]|\ud83c\uddf9\ud83c[\udde6\udde8\udde9\uddeb-\udded\uddef-\uddf4\uddf7\uddf9\uddfb\uddfc\uddff]|\ud83c\uddfa\ud83c[\udde6\uddec\uddf2\uddf3\uddf8\uddfe\uddff]|\ud83c\uddfb\ud83c[\udde6\udde8\uddea\uddec\uddee\uddf3\uddfa]|\ud83c\uddfc\ud83c[\uddeb\uddf8]|\ud83c\uddfd\ud83c\uddf0|\ud83c\uddfe\ud83c[\uddea\uddf9]|\ud83c\uddff\ud83c[\udde6\uddf2\uddfc]|\ud83c[\udccf\udd8e\udd91-\udd9a\udde6-\uddff\ude01\ude32-\ude36\ude38-\ude3a\ude50\ude51\udf00-\udf20\udf2d-\udf35\udf37-\udf7c\udf7e-\udf84\udf86-\udf93\udfa0-\udfc1\udfc5\udfc6\udfc8\udfc9\udfcf-\udfd3\udfe0-\udff0\udff4\udff8-\udfff]|\ud83d[\udc00-\udc3e\udc40\udc44\udc45\udc51-\udc65\udc6a\udc6f\udc79-\udc7b\udc7d-\udc80\udc84\udc88-\udca9\udcab-\udcfc\udcff-\udd3d\udd4b-\udd4e\udd50-\udd67\udda4\uddfb-\ude44\ude48-\ude4a\ude80-\udea2\udea4-\udeb3\udeb7-\udebf\udec1-\udec5\uded0-\uded2\uded5-\uded7\udeeb\udeec\udef4-\udefc\udfe0-\udfeb]|\ud83e[\udd0d\udd0e\udd10-\udd17\udd1d\udd20-\udd25\udd27-\udd2f\udd3a\udd3c\udd3f-\udd45\udd47-\udd76\udd78\udd7a-\uddb4\uddb7\uddba\uddbc-\uddcb\uddd0\uddde-\uddff\ude70-\ude74\ude78-\ude7a\ude80-\ude86\ude90-\udea8\udeb0-\udeb6\udec0-\udec2\uded0-\uded6]|[\u23e9-\u23ec\u23f0\u23f3\u267e\u26ce\u2705\u2728\u274c\u274e\u2753-\u2755\u2795-\u2797\u27b0\u27bf\ue50a])|\ufe0f"; \ No newline at end of file diff --git a/src/lib/richtextprocessor.js b/src/lib/richtextprocessor.ts similarity index 54% rename from src/lib/richtextprocessor.js rename to src/lib/richtextprocessor.ts index 641ade7b..090b220e 100644 --- a/src/lib/richtextprocessor.js +++ b/src/lib/richtextprocessor.ts @@ -1,19 +1,19 @@ -import {encodeEntities, copy, emojiUnicode} from './utils'; +import {encodeEntities, copy} from './utils'; import Config from './config'; +import emojiRegExp from '../emoji/regex'; +import { encodeEmoji } from '../emoji'; + var EmojiHelper = { - emojiMap: (code) => { return code; }, - shortcuts: [], - emojis: [] + emojiMap: (code: string) => { return code; }, + shortcuts: [] as any, + emojis: [] as any }; var emojiData = Config.Emoji; var emojiSupported = navigator.userAgent.search(/OS X|iPhone|iPad|iOS/i) != -1/* && false *//* || true */, emojiCode; -// added * to (?:[©®\\u2122\\u265f]\\ufe0f) and removed \\ufe0f from end -// there are no 2640 and 2642 (signs) -var emojiRegExp = '(?:\\ud83d\\udc68\\ud83c\\udffb\\u200d\\ud83e\\udd1d\\u200d\\ud83d\\udc68\\ud83c[\\udffc-\\udfff]|\\ud83d\\udc68\\ud83c\\udffc\\u200d\\ud83e\\udd1d\\u200d\\ud83d\\udc68\\ud83c[\\udffb\\udffd-\\udfff]|\\ud83d\\udc68\\ud83c\\udffd\\u200d\\ud83e\\udd1d\\u200d\\ud83d\\udc68\\ud83c[\\udffb\\udffc\\udffe\\udfff]|\\ud83d\\udc68\\ud83c\\udffe\\u200d\\ud83e\\udd1d\\u200d\\ud83d\\udc68\\ud83c[\\udffb-\\udffd\\udfff]|\\ud83d\\udc68\\ud83c\\udfff\\u200d\\ud83e\\udd1d\\u200d\\ud83d\\udc68\\ud83c[\\udffb-\\udffe]|\\ud83d\\udc69\\ud83c\\udffb\\u200d\\ud83e\\udd1d\\u200d\\ud83d\\udc68\\ud83c[\\udffc-\\udfff]|\\ud83d\\udc69\\ud83c\\udffb\\u200d\\ud83e\\udd1d\\u200d\\ud83d\\udc69\\ud83c[\\udffc-\\udfff]|\\ud83d\\udc69\\ud83c\\udffc\\u200d\\ud83e\\udd1d\\u200d\\ud83d\\udc68\\ud83c[\\udffb\\udffd-\\udfff]|\\ud83d\\udc69\\ud83c\\udffc\\u200d\\ud83e\\udd1d\\u200d\\ud83d\\udc69\\ud83c[\\udffb\\udffd-\\udfff]|\\ud83d\\udc69\\ud83c\\udffd\\u200d\\ud83e\\udd1d\\u200d\\ud83d\\udc68\\ud83c[\\udffb\\udffc\\udffe\\udfff]|\\ud83d\\udc69\\ud83c\\udffd\\u200d\\ud83e\\udd1d\\u200d\\ud83d\\udc69\\ud83c[\\udffb\\udffc\\udffe\\udfff]|\\ud83d\\udc69\\ud83c\\udffe\\u200d\\ud83e\\udd1d\\u200d\\ud83d\\udc68\\ud83c[\\udffb-\\udffd\\udfff]|\\ud83d\\udc69\\ud83c\\udffe\\u200d\\ud83e\\udd1d\\u200d\\ud83d\\udc69\\ud83c[\\udffb-\\udffd\\udfff]|\\ud83d\\udc69\\ud83c\\udfff\\u200d\\ud83e\\udd1d\\u200d\\ud83d\\udc68\\ud83c[\\udffb-\\udffe]|\\ud83d\\udc69\\ud83c\\udfff\\u200d\\ud83e\\udd1d\\u200d\\ud83d\\udc69\\ud83c[\\udffb-\\udffe]|\\ud83e\\uddd1\\ud83c\\udffb\\u200d\\ud83e\\udd1d\\u200d\\ud83e\\uddd1\\ud83c[\\udffb-\\udfff]|\\ud83e\\uddd1\\ud83c\\udffc\\u200d\\ud83e\\udd1d\\u200d\\ud83e\\uddd1\\ud83c[\\udffb-\\udfff]|\\ud83e\\uddd1\\ud83c\\udffd\\u200d\\ud83e\\udd1d\\u200d\\ud83e\\uddd1\\ud83c[\\udffb-\\udfff]|\\ud83e\\uddd1\\ud83c\\udffe\\u200d\\ud83e\\udd1d\\u200d\\ud83e\\uddd1\\ud83c[\\udffb-\\udfff]|\\ud83e\\uddd1\\ud83c\\udfff\\u200d\\ud83e\\udd1d\\u200d\\ud83e\\uddd1\\ud83c[\\udffb-\\udfff]|\\ud83e\\uddd1\\u200d\\ud83e\\udd1d\\u200d\\ud83e\\uddd1|\\ud83d\\udc6b\\ud83c[\\udffb-\\udfff]|\\ud83d\\udc6c\\ud83c[\\udffb-\\udfff]|\\ud83d\\udc6d\\ud83c[\\udffb-\\udfff]|\\ud83d[\\udc6b-\\udc6d])|(?:\\ud83d[\\udc68\\udc69]|\\ud83e\\uddd1)(?:\\ud83c[\\udffb-\\udfff])?\\u200d(?:\\u2695\\ufe0f|\\u2696\\ufe0f|\\u2708\\ufe0f|\\ud83c[\\udf3e\\udf73\\udf7c\\udf84\\udf93\\udfa4\\udfa8\\udfeb\\udfed]|\\ud83d[\\udcbb\\udcbc\\udd27\\udd2c\\ude80\\ude92]|\\ud83e[\\uddaf-\\uddb3\\uddbc\\uddbd])|(?:\\ud83c[\\udfcb\\udfcc]|\\ud83d[\\udd74\\udd75]|\\u26f9)((?:\\ud83c[\\udffb-\\udfff]|\\ufe0f)\\u200d[\\u2640\\u2642]\\ufe0f)|(?:\\ud83c[\\udfc3\\udfc4\\udfca]|\\ud83d[\\udc6e\\udc70\\udc71\\udc73\\udc77\\udc81\\udc82\\udc86\\udc87\\ude45-\\ude47\\ude4b\\ude4d\\ude4e\\udea3\\udeb4-\\udeb6]|\\ud83e[\\udd26\\udd35\\udd37-\\udd39\\udd3d\\udd3e\\uddb8\\uddb9\\uddcd-\\uddcf\\uddd6-\\udddd])(?:\\ud83c[\\udffb-\\udfff])?\\u200d[\\u2640\\u2642]\\ufe0f|(?:\\ud83d\\udc68\\u200d\\u2764\\ufe0f\\u200d\\ud83d\\udc8b\\u200d\\ud83d\\udc68|\\ud83d\\udc68\\u200d\\ud83d\\udc68\\u200d\\ud83d\\udc66\\u200d\\ud83d\\udc66|\\ud83d\\udc68\\u200d\\ud83d\\udc68\\u200d\\ud83d\\udc67\\u200d\\ud83d[\\udc66\\udc67]|\\ud83d\\udc68\\u200d\\ud83d\\udc69\\u200d\\ud83d\\udc66\\u200d\\ud83d\\udc66|\\ud83d\\udc68\\u200d\\ud83d\\udc69\\u200d\\ud83d\\udc67\\u200d\\ud83d[\\udc66\\udc67]|\\ud83d\\udc69\\u200d\\u2764\\ufe0f\\u200d\\ud83d\\udc8b\\u200d\\ud83d[\\udc68\\udc69]|\\ud83d\\udc69\\u200d\\ud83d\\udc69\\u200d\\ud83d\\udc66\\u200d\\ud83d\\udc66|\\ud83d\\udc69\\u200d\\ud83d\\udc69\\u200d\\ud83d\\udc67\\u200d\\ud83d[\\udc66\\udc67]|\\ud83d\\udc68\\u200d\\u2764\\ufe0f\\u200d\\ud83d\\udc68|\\ud83d\\udc68\\u200d\\ud83d\\udc66\\u200d\\ud83d\\udc66|\\ud83d\\udc68\\u200d\\ud83d\\udc67\\u200d\\ud83d[\\udc66\\udc67]|\\ud83d\\udc68\\u200d\\ud83d\\udc68\\u200d\\ud83d[\\udc66\\udc67]|\\ud83d\\udc68\\u200d\\ud83d\\udc69\\u200d\\ud83d[\\udc66\\udc67]|\\ud83d\\udc69\\u200d\\u2764\\ufe0f\\u200d\\ud83d[\\udc68\\udc69]|\\ud83d\\udc69\\u200d\\ud83d\\udc66\\u200d\\ud83d\\udc66|\\ud83d\\udc69\\u200d\\ud83d\\udc67\\u200d\\ud83d[\\udc66\\udc67]|\\ud83d\\udc69\\u200d\\ud83d\\udc69\\u200d\\ud83d[\\udc66\\udc67]|\\ud83c\\udff3\\ufe0f\\u200d\\u26a7\\ufe0f|\\ud83c\\udff3\\ufe0f\\u200d\\ud83c\\udf08|\\ud83c\\udff4\\u200d\\u2620\\ufe0f|\\ud83d\\udc15\\u200d\\ud83e\\uddba|\\ud83d\\udc3b\\u200d\\u2744\\ufe0f|\\ud83d\\udc41\\u200d\\ud83d\\udde8|\\ud83d\\udc68\\u200d\\ud83d[\\udc66\\udc67]|\\ud83d\\udc69\\u200d\\ud83d[\\udc66\\udc67]|\\ud83d\\udc6f\\u200d\\u2640\\ufe0f|\\ud83d\\udc6f\\u200d\\u2642\\ufe0f|\\ud83e\\udd3c\\u200d\\u2640\\ufe0f|\\ud83e\\udd3c\\u200d\\u2642\\ufe0f|\\ud83e\\uddde\\u200d\\u2640\\ufe0f|\\ud83e\\uddde\\u200d\\u2642\\ufe0f|\\ud83e\\udddf\\u200d\\u2640\\ufe0f|\\ud83e\\udddf\\u200d\\u2642\\ufe0f|\\ud83d\\udc08\\u200d\\u2b1b)|[#*0-9]\\ufe0f?\\u20e3|(?:[©®\\u2122\\u265f]\\ufe0f*)|(?:\\ud83c[\\udc04\\udd70\\udd71\\udd7e\\udd7f\\ude02\\ude1a\\ude2f\\ude37\\udf21\\udf24-\\udf2c\\udf36\\udf7d\\udf96\\udf97\\udf99-\\udf9b\\udf9e\\udf9f\\udfcd\\udfce\\udfd4-\\udfdf\\udff3\\udff5\\udff7]|\\ud83d[\\udc3f\\udc41\\udcfd\\udd49\\udd4a\\udd6f\\udd70\\udd73\\udd76-\\udd79\\udd87\\udd8a-\\udd8d\\udda5\\udda8\\uddb1\\uddb2\\uddbc\\uddc2-\\uddc4\\uddd1-\\uddd3\\udddc-\\uddde\\udde1\\udde3\\udde8\\uddef\\uddf3\\uddfa\\udecb\\udecd-\\udecf\\udee0-\\udee5\\udee9\\udef0\\udef3]|[\\u203c\\u2049\\u2139\\u2194-\\u2199\\u21a9\\u21aa\\u231a\\u231b\\u2328\\u23cf\\u23ed-\\u23ef\\u23f1\\u23f2\\u23f8-\\u23fa\\u24c2\\u25aa\\u25ab\\u25b6\\u25c0\\u25fb-\\u25fe\\u2600-\\u2604\\u260e\\u2611\\u2614\\u2615\\u2618\\u2620\\u2622\\u2623\\u2626\\u262a\\u262e\\u262f\\u2638-\\u263a\\u2640\\u2642\\u2648-\\u2653\\u2660\\u2663\\u2665\\u2666\\u2668\\u267b\\u267f\\u2692-\\u2697\\u2699\\u269b\\u269c\\u26a0\\u26a1\\u26a7\\u26aa\\u26ab\\u26b0\\u26b1\\u26bd\\u26be\\u26c4\\u26c5\\u26c8\\u26cf\\u26d1\\u26d3\\u26d4\\u26e9\\u26ea\\u26f0-\\u26f5\\u26f8\\u26fa\\u26fd\\u2702\\u2708\\u2709\\u270f\\u2712\\u2714\\u2716\\u271d\\u2721\\u2733\\u2734\\u2744\\u2747\\u2757\\u2763\\u2764\\u27a1\\u2934\\u2935\\u2b05-\\u2b07\\u2b1b\\u2b1c\\u2b50\\u2b55\\u3030\\u303d\\u3297\\u3299])(?:\\ufe0f|(?!\\ufe0e))|(?:(?:\\ud83c[\\udfcb\\udfcc]|\\ud83d[\\udd74\\udd75\\udd90]|[\\u261d\\u26f7\\u26f9\\u270c\\u270d])(?:\\ufe0f|(?!\\ufe0e))|(?:\\ud83c[\\udf85\\udfc2-\\udfc4\\udfc7\\udfca]|\\ud83d[\\udc42\\udc43\\udc46-\\udc50\\udc66-\\udc69\\udc6e\\udc70-\\udc78\\udc7c\\udc81-\\udc83\\udc85-\\udc87\\udcaa\\udd7a\\udd95\\udd96\\ude45-\\ude47\\ude4b-\\ude4f\\udea3\\udeb4-\\udeb6\\udec0\\udecc]|\\ud83e[\\udd0c\\udd0f\\udd18-\\udd1c\\udd1e\\udd1f\\udd26\\udd30-\\udd39\\udd3d\\udd3e\\udd77\\uddb5\\uddb6\\uddb8\\uddb9\\uddbb\\uddcd-\\uddcf\\uddd1-\\udddd]|[\\u270a\\u270b]))(?:\\ud83c[\\udffb-\\udfff])?|(?:\\ud83c\\udff4\\udb40\\udc67\\udb40\\udc62\\udb40\\udc65\\udb40\\udc6e\\udb40\\udc67\\udb40\\udc7f|\\ud83c\\udff4\\udb40\\udc67\\udb40\\udc62\\udb40\\udc73\\udb40\\udc63\\udb40\\udc74\\udb40\\udc7f|\\ud83c\\udff4\\udb40\\udc67\\udb40\\udc62\\udb40\\udc77\\udb40\\udc6c\\udb40\\udc73\\udb40\\udc7f|\\ud83c\\udde6\\ud83c[\\udde8-\\uddec\\uddee\\uddf1\\uddf2\\uddf4\\uddf6-\\uddfa\\uddfc\\uddfd\\uddff]|\\ud83c\\udde7\\ud83c[\\udde6\\udde7\\udde9-\\uddef\\uddf1-\\uddf4\\uddf6-\\uddf9\\uddfb\\uddfc\\uddfe\\uddff]|\\ud83c\\udde8\\ud83c[\\udde6\\udde8\\udde9\\uddeb-\\uddee\\uddf0-\\uddf5\\uddf7\\uddfa-\\uddff]|\\ud83c\\udde9\\ud83c[\\uddea\\uddec\\uddef\\uddf0\\uddf2\\uddf4\\uddff]|\\ud83c\\uddea\\ud83c[\\udde6\\udde8\\uddea\\uddec\\udded\\uddf7-\\uddfa]|\\ud83c\\uddeb\\ud83c[\\uddee-\\uddf0\\uddf2\\uddf4\\uddf7]|\\ud83c\\uddec\\ud83c[\\udde6\\udde7\\udde9-\\uddee\\uddf1-\\uddf3\\uddf5-\\uddfa\\uddfc\\uddfe]|\\ud83c\\udded\\ud83c[\\uddf0\\uddf2\\uddf3\\uddf7\\uddf9\\uddfa]|\\ud83c\\uddee\\ud83c[\\udde8-\\uddea\\uddf1-\\uddf4\\uddf6-\\uddf9]|\\ud83c\\uddef\\ud83c[\\uddea\\uddf2\\uddf4\\uddf5]|\\ud83c\\uddf0\\ud83c[\\uddea\\uddec-\\uddee\\uddf2\\uddf3\\uddf5\\uddf7\\uddfc\\uddfe\\uddff]|\\ud83c\\uddf1\\ud83c[\\udde6-\\udde8\\uddee\\uddf0\\uddf7-\\uddfb\\uddfe]|\\ud83c\\uddf2\\ud83c[\\udde6\\udde8-\\udded\\uddf0-\\uddff]|\\ud83c\\uddf3\\ud83c[\\udde6\\udde8\\uddea-\\uddec\\uddee\\uddf1\\uddf4\\uddf5\\uddf7\\uddfa\\uddff]|\\ud83c\\uddf4\\ud83c\\uddf2|\\ud83c\\uddf5\\ud83c[\\udde6\\uddea-\\udded\\uddf0-\\uddf3\\uddf7-\\uddf9\\uddfc\\uddfe]|\\ud83c\\uddf6\\ud83c\\udde6|\\ud83c\\uddf7\\ud83c[\\uddea\\uddf4\\uddf8\\uddfa\\uddfc]|\\ud83c\\uddf8\\ud83c[\\udde6-\\uddea\\uddec-\\uddf4\\uddf7-\\uddf9\\uddfb\\uddfd-\\uddff]|\\ud83c\\uddf9\\ud83c[\\udde6\\udde8\\udde9\\uddeb-\\udded\\uddef-\\uddf4\\uddf7\\uddf9\\uddfb\\uddfc\\uddff]|\\ud83c\\uddfa\\ud83c[\\udde6\\uddec\\uddf2\\uddf3\\uddf8\\uddfe\\uddff]|\\ud83c\\uddfb\\ud83c[\\udde6\\udde8\\uddea\\uddec\\uddee\\uddf3\\uddfa]|\\ud83c\\uddfc\\ud83c[\\uddeb\\uddf8]|\\ud83c\\uddfd\\ud83c\\uddf0|\\ud83c\\uddfe\\ud83c[\\uddea\\uddf9]|\\ud83c\\uddff\\ud83c[\\udde6\\uddf2\\uddfc]|\\ud83c[\\udccf\\udd8e\\udd91-\\udd9a\\udde6-\\uddff\\ude01\\ude32-\\ude36\\ude38-\\ude3a\\ude50\\ude51\\udf00-\\udf20\\udf2d-\\udf35\\udf37-\\udf7c\\udf7e-\\udf84\\udf86-\\udf93\\udfa0-\\udfc1\\udfc5\\udfc6\\udfc8\\udfc9\\udfcf-\\udfd3\\udfe0-\\udff0\\udff4\\udff8-\\udfff]|\\ud83d[\\udc00-\\udc3e\\udc40\\udc44\\udc45\\udc51-\\udc65\\udc6a\\udc6f\\udc79-\\udc7b\\udc7d-\\udc80\\udc84\\udc88-\\udca9\\udcab-\\udcfc\\udcff-\\udd3d\\udd4b-\\udd4e\\udd50-\\udd67\\udda4\\uddfb-\\ude44\\ude48-\\ude4a\\ude80-\\udea2\\udea4-\\udeb3\\udeb7-\\udebf\\udec1-\\udec5\\uded0-\\uded2\\uded5-\\uded7\\udeeb\\udeec\\udef4-\\udefc\\udfe0-\\udfeb]|\\ud83e[\\udd0d\\udd0e\\udd10-\\udd17\\udd1d\\udd20-\\udd25\\udd27-\\udd2f\\udd3a\\udd3c\\udd3f-\\udd45\\udd47-\\udd76\\udd78\\udd7a-\\uddb4\\uddb7\\uddba\\uddbc-\\uddcb\\uddd0\\uddde-\\uddff\\ude70-\\ude74\\ude78-\\ude7a\\ude80-\\ude86\\ude90-\\udea8\\udeb0-\\udeb6\\udec0-\\udec2\\uded0-\\uded6]|[\\u23e9-\\u23ec\\u23f0\\u23f3\\u267e\\u26ce\\u2705\\u2728\\u274c\\u274e\\u2753-\\u2755\\u2795-\\u2797\\u27b0\\u27bf\\ue50a])'; var alphaCharsRegExp = 'a-z' + '\\u00c0-\\u00d6\\u00d8-\\u00f6\\u00f8-\\u00ff' + // Latin-1 '\\u0100-\\u024f' + // Latin Extended A and B @@ -59,40 +59,36 @@ var urlRegExp = '((?:https?|ftp)://|mailto:)?' + // port number '(?::\\d{2,5})?' + // resource path - '(?:/(?:\\S{0,255}[^\\s.;,(\\[\\]{}<>"\'])?)?' -var usernameRegExp = '[a-zA-Z\\d_]{5,32}' -var botCommandRegExp = '\\/([a-zA-Z\\d_]{1,32})(?:@(' + usernameRegExp + '))?(\\b|$)' + '(?:/(?:\\S{0,255}[^\\s.;,(\\[\\]{}<>"\'])?)?'; +var usernameRegExp = '[a-zA-Z\\d_]{5,32}'; +var botCommandRegExp = '\\/([a-zA-Z\\d_]{1,32})(?:@(' + usernameRegExp + '))?(\\b|$)'; var fullRegExp = new RegExp('(^| )(@)(' + usernameRegExp + ')|(' + urlRegExp + ')|(\\n)|(' + emojiRegExp + ')|(^|[\\s\\(\\]])(#[' + alphaNumericRegExp + ']{2,64})|(^|\\s)' + botCommandRegExp, 'i') -var emailRegExp = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/ -var markdownTestRegExp = /[`_*@]/ -var markdownRegExp = /(^|\s|\n)(````?)([\s\S]+?)(````?)([\s\n\.,:?!;]|$)|(^|\s)(`|\*\*|__)([^\n]+?)\7([\s\.,:?!;]|$)|@(\d+)\s*\((.+?)\)/m -var siteHashtags = { +var emailRegExp = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; +var markdownTestRegExp = /[`_*@]/; +var markdownRegExp = /(^|\s|\n)(````?)([\s\S]+?)(````?)([\s\n\.,:?!;]|$)|(^|\s)(`|\*\*|__)([^\n]+?)\7([\s\.,:?!;]|$)|@(\d+)\s*\((.+?)\)/m; +var siteHashtags: any = { Telegram: 'tg://search_hashtag?hashtag={1}', Twitter: 'https://twitter.com/hashtag/{1}', Instagram: 'https://instagram.com/explore/tags/{1}/', 'Google Plus': 'https://plus.google.com/explore/{1}' -} -var siteMentions = { +}; + +var siteMentions: any = { Telegram: '#/im?p=%40{1}', Twitter: 'https://twitter.com/{1}', Instagram: 'https://instagram.com/{1}/', GitHub: 'https://github.com/{1}' -} +}; var markdownEntities = { '`': 'messageEntityCode', '**': 'messageEntityBold', '__': 'messageEntityItalic' -} -function getEmojiSpritesheetCoords(emojiCode) { - let emojiInfo = emojiData[emojiCode/* .replace(/\ufe0f/g, '') */]; - if(emojiInfo === undefined) { - //console.error('no emoji by code:', emojiCode, emojiCode && emojiCode.length, new TextEncoder().encode(emojiCode), emojiUnicode(emojiCode)); - return null; - } +}; - return emojiUnicode(emojiCode).replace(/(-fe0f|fe0f)/g, ''); +function getEmojiSpritesheetCoords(emojiCode: string) { + return encodeEmoji(emojiCode).replace(/(-fe0f|fe0f)/g, ''); } -function parseEntities(text, options = {}) { +function parseEntities(text: string, options = {}) { var match; var raw = text, url; var entities = [], matchIndex; @@ -117,7 +113,7 @@ function parseEntities(text, options = {}) { length: match[4].length }); } else { - var url = false; + var url: any = false; var protocol = match[5]; var tld = match[6]; var excluded = ''; @@ -187,7 +183,7 @@ function parseEntities(text, options = {}) { // } return entities } -function parseEmojis (text) { +function parseEmojis(text: string) { return text.replace(/:([a-z0-9\-\+\*_]+?):/gi, function (all, shortcut) { var emojiCode = EmojiHelper.shortcuts[shortcut] if (emojiCode !== undefined) { @@ -196,15 +192,16 @@ function parseEmojis (text) { return all }) } -function parseMarkdown (text, entities, noTrim) { -  if (!markdownTestRegExp.test(text)) { - return noTrim ? text : text.trim() +function parseMarkdown(text: string, entities: any[], noTrim?: any) { +  if(!markdownTestRegExp.test(text)) { + return noTrim ? text : text.trim(); } - var raw = text - var match - var newText = [] - var rawOffset = 0 - var matchIndex + + var raw = text; + var match; + var newText: any = []; + var rawOffset = 0; + var matchIndex; while (match = raw.match(markdownRegExp)) { matchIndex = rawOffset + match.index newText.push(raw.substr(0, match.index)) @@ -231,6 +228,7 @@ function parseMarkdown (text, entities, noTrim) { } else if (match[7]) { // code|italic|bold newText.push(match[6] + text + match[9]) entities.push({ + // @ts-ignore _: markdownEntities[match[7]], offset: matchIndex + match[6].length, length: text.length @@ -260,73 +258,80 @@ function parseMarkdown (text, entities, noTrim) { } return newText } -function mergeEntities (currentEntities, newEntities, fromApi) { - var totalEntities = newEntities.slice() - var i - var len = currentEntities.length - var j - var len2 = newEntities.length - var startJ = 0 - var curEntity - var newEntity - var start, end - var cStart, cEnd - var bad - for (i = 0; i < len; i++) { - curEntity = currentEntities[i] +function mergeEntities (currentEntities: any[], newEntities: any[], fromApi: any) { + var totalEntities = newEntities.slice(); + var i; + var len = currentEntities.length; + var j; + var len2 = newEntities.length; + var startJ = 0; + var curEntity; + var newEntity; + var start, end; + var cStart, cEnd; + var bad; + for(i = 0; i < len; i++) { + curEntity = currentEntities[i]; if (fromApi && curEntity._ != 'messageEntityLinebreak' && curEntity._ != 'messageEntityEmoji') { - continue + continue; } - // console.log('s', curEntity, newEntities) - start = curEntity.offset - end = start + curEntity.length - bad = false - for (j = startJ; j < len2; j++) { - newEntity = newEntities[j] - cStart = newEntity.offset - cEnd = cStart + newEntity.length - if (cStart <= start) { - startJ = j + // console.log('s', curEntity, newEntities); + start = curEntity.offset; + end = start + curEntity.length; + bad = false; + for(j = startJ; j < len2; j++) { + newEntity = newEntities[j]; + cStart = newEntity.offset; + cEnd = cStart + newEntity.length; + if(cStart <= start) { + startJ = j; } - if (start >= cStart && start < cEnd || + + if(start >= cStart && start < cEnd || end > cStart && end <= cEnd) { // console.log('bad', curEntity, newEntity) - if (fromApi && + if(fromApi && start >= cStart && end <= cEnd) { - if (newEntity.nested === undefined) { - newEntity.nested = [] + if(newEntity.nested === undefined) { + newEntity.nested = []; } - curEntity.offset -= cStart - newEntity.nested.push(copy(curEntity)) + + curEntity.offset -= cStart; + newEntity.nested.push(copy(curEntity)); } - bad = true - break + + bad = true; + break; } - if (cStart >= end) { - break + + if(cStart >= end) { + break; } } - if (bad) { - continue + + if(bad) { + continue; } - totalEntities.push(curEntity) + + totalEntities.push(curEntity); } - totalEntities.sort(function (a, b) { - return a.offset - b.offset - }) + + totalEntities.sort((a, b) => { + return a.offset - b.offset; + }); // console.log('merge', currentEntities, newEntities, totalEntities) - return totalEntities + return totalEntities; } -function wrapRichNestedText (text, nested, options) { +function wrapRichNestedText (text: string, nested: any, options: any) { if (nested === undefined) { return encodeEntities(text) } options.hasNested = true return wrapRichText(text, {entities: nested, nested: true}) } -function wrapRichText (text, options = {}) { +function wrapRichText (text: string, options: any = {}) { if(!text || !text.length) { return '' } @@ -554,93 +559,99 @@ function wrapRichText (text, options = {}) { } */ return text;//$sce.trustAs('html', text) } -function wrapDraftText (text, options) { - if (!text || !text.length) { - return '' +function wrapDraftText (text: string, options: any = {}) { + if(!text || !text.length) { + return ''; } - options = options || {} - var entities = options.entities - if (entities === undefined) { - entities = parseEntities(text, options) + + var entities = options.entities; + if(entities === undefined) { + entities = parseEntities(text, options); } - var i = 0 - var len = entities.length - var entity - var entityText - var skipEntity - var code = [] - var lastOffset = 0 - for (i = 0; i < len; i++) { - entity = entities[i] - if (entity.offset > lastOffset) { + var i = 0; + var len = entities.length; + var entity; + var entityText; + var skipEntity; + var code = []; + var lastOffset = 0; + for(i = 0; i < len; i++) { + entity = entities[i]; + if(entity.offset > lastOffset) { code.push( text.substr(lastOffset, entity.offset - lastOffset) - ) - } - else if (entity.offset < lastOffset) { - continue + ); + } else if(entity.offset < lastOffset) { + continue; } - skipEntity = false - entityText = text.substr(entity.offset, entity.length) - switch (entity._) { + + skipEntity = false; + entityText = text.substr(entity.offset, entity.length); + switch(entity._) { case 'messageEntityEmoji': code.push( ':', entity.title, ':' - ) - break + ); + break; + case 'messageEntityCode': code.push( '`', entityText, '`' - ) - break + ); + break; + case 'messageEntityBold': code.push( '**', entityText, '**' - ) - break + ); + break; + case 'messageEntityItalic': code.push( '__', entityText, '__' - ) - break + ); + break; + case 'messageEntityPre': code.push( '```', entityText, '```' - ) - break + ); + break; + case 'messageEntityMentionName': code.push( '@', entity.user_id, ' (', entityText, ')' - ) - break + ); + break; + default: - skipEntity = true + skipEntity = true; } - lastOffset = entity.offset + (skipEntity ? 0 : entity.length) + lastOffset = entity.offset + (skipEntity ? 0 : entity.length); } - code.push(text.substr(lastOffset)) - return code.join('') + code.push(text.substr(lastOffset)); + return code.join(''); } -function checkBrackets (url) { - var urlLength = url.length - var urlOpenBrackets = url.split('(').length - 1 - var urlCloseBrackets = url.split(')').length - 1 - while (urlCloseBrackets > urlOpenBrackets && +function checkBrackets(url: string) { + var urlLength = url.length; + var urlOpenBrackets = url.split('(').length - 1; + var urlCloseBrackets = url.split(')').length - 1; + while(urlCloseBrackets > urlOpenBrackets && url.charAt(urlLength - 1) === ')') { url = url.substr(0, urlLength - 1) - urlCloseBrackets-- - urlLength-- + urlCloseBrackets--; + urlLength--; } - if (urlOpenBrackets > urlCloseBrackets) { - url = url.replace(/\)+$/, '') + if(urlOpenBrackets > urlCloseBrackets) { + url = url.replace(/\)+$/, ''); } - return url + return url; } -function replaceUrlEncodings(urlWithEncoded) { - return urlWithEncoded.replace(/(%[A-Z\d]{2})+/g, function (str) { +function replaceUrlEncodings(urlWithEncoded: string) { + return urlWithEncoded.replace(/(%[A-Z\d]{2})+/g, (str) => { try { return decodeURIComponent(str); } catch (e) { @@ -649,7 +660,7 @@ function replaceUrlEncodings(urlWithEncoded) { }); } -function wrapPlainText(text, options = {}) { +function wrapPlainText(text: any, options: any = {}) { if(emojiSupported) { return text; } @@ -661,12 +672,14 @@ function wrapPlainText(text, options = {}) { text = text.replace(/\ufe0f/g, '', text); var match; var raw = text; - var text = [], + var text: any = [], emojiTitle; while((match = raw.match(fullRegExp))) { text.push(raw.substr(0, match.index)) if(match[8]) { + // @ts-ignore if((emojiCode = EmojiHelper.emojiMap[match[8]]) && + // @ts-ignore (emojiTitle = emojiData[emojiCode][1][0])) { text.push(':' + emojiTitle + ':'); } else { @@ -681,60 +694,62 @@ function wrapPlainText(text, options = {}) { text.push(raw); return text.join(''); } -function wrapEmojiText(text) { +function wrapEmojiText(text: string) { if(!text) return ''; let entities = parseEntities(text).filter(e => e._ == 'messageEntityEmoji'); return wrapRichText(text, {entities}); } -function wrapUrl (url, unsafe) { - if (!url.match(/^https?:\/\//i)) { - url = 'http://' + url - } - var tgMeMatch - var telescoPeMatch - if (unsafe == 2) { - url = 'tg://unsafe_url?url=' + encodeURIComponent(url) +function wrapUrl(url: string, unsafe: any): string { + if(!url.match(/^https?:\/\//i)) { + url = 'http://' + url; } - else if ((tgMeMatch = url.match(/^https?:\/\/t(?:elegram)?\.me\/(.+)/))) { - var fullPath = tgMeMatch[1] - var path = fullPath.split('/') - switch (path[0]) { + + var tgMeMatch; + var telescoPeMatch; + if(unsafe == 2) { + url = 'tg://unsafe_url?url=' + encodeURIComponent(url); + } else if((tgMeMatch = url.match(/^https?:\/\/t(?:elegram)?\.me\/(.+)/))) { + var fullPath = tgMeMatch[1]; + var path = fullPath.split('/'); + switch(path[0]) { case 'joinchat': - url = 'tg://join?invite=' + path[1] - break + url = 'tg://join?invite=' + path[1]; + break; + case 'addstickers': - url = 'tg://addstickers?set=' + path[1] - break + url = 'tg://addstickers?set=' + path[1]; + break; + default: - if (path[1] && path[1].match(/^\d+$/)) { - url = 'tg://resolve?domain=' + path[0] + '&post=' + path[1] - } - else if (path.length == 1) { - var domainQuery = path[0].split('?') - var domain = domainQuery[0] - var query = domainQuery[1] - if (domain == 'iv') { - var match = (query || '').match(/url=([^&=]+)/) - if (match) { - url = match[1] + if(path[1] && path[1].match(/^\d+$/)) { + url = 'tg://resolve?domain=' + path[0] + '&post=' + path[1]; + } else if(path.length == 1) { + var domainQuery = path[0].split('?'); + var domain = domainQuery[0]; + var query = domainQuery[1]; + if(domain == 'iv') { + var match = (query || '').match(/url=([^&=]+)/); + if(match) { + url = match[1]; try { - url = decodeURIComponent(url) + url = decodeURIComponent(url); } catch (e) {} - return wrapUrl(url, unsafe) + + return wrapUrl(url, unsafe); } } - url = 'tg://resolve?domain=' + domain + (query ? '&' + query : '') + + url = 'tg://resolve?domain=' + domain + (query ? '&' + query : ''); } } + } else if((telescoPeMatch = url.match(/^https?:\/\/telesco\.pe\/([^/?]+)\/(\d+)/))) { + url = 'tg://resolve?domain=' + telescoPeMatch[1] + '&post=' + telescoPeMatch[2]; + } else if(unsafe) { + url = 'tg://unsafe_url?url=' + encodeURIComponent(url); } - else if ((telescoPeMatch = url.match(/^https?:\/\/telesco\.pe\/([^/?]+)\/(\d+)/))) { - url = 'tg://resolve?domain=' + telescoPeMatch[1] + '&post=' + telescoPeMatch[2] - } - else if (unsafe) { - url = 'tg://unsafe_url?url=' + encodeURIComponent(url) - } - return url + + return url; } let RichTextProcessor = { @@ -751,7 +766,10 @@ let RichTextProcessor = { emojiSupported: emojiSupported }; -window.RichTextProcessor = RichTextProcessor; +// @ts-ignore +if(process.env.NODE_ENV != 'production') { + (window as any).RichTextProcessor = RichTextProcessor; +} export {RichTextProcessor}; diff --git a/src/lib/utils.ts b/src/lib/utils.ts index 704a7994..1b5d2aa5 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -482,57 +482,6 @@ export function calcImageInBox (imageW: number, imageH: number, boxW: number, bo return {w: boxedImageW, h: boxedImageH}; } -/** - * emojiUnicode - * Get the unicode code of an emoji in base 16. - * - * @name emojiUnicode - * @function - * @param {String} input The emoji character. - * @returns {String} The base 16 unicode code. - */ -export function emojiUnicode(input: string) { - let pairs = emojiUnicode.raw(input).split(' ').map(val => parseInt(val).toString(16))/* .filter(p => p != 'fe0f') */; - if(pairs.length && pairs[0].length == 2) pairs[0] = '00' + pairs[0]; - return pairs.join('-'); -} - -/** -* emojiunicode.raw -* Get the unicode code points of an emoji in base 16. -* -* @name emojiunicode.raw -* @function -* @param {String} input The emoji character. -* @returns {String} The unicode code points. -*/ -emojiUnicode.raw = function(input: string) { - if(input.length === 1) { - return input.charCodeAt(0).toString(); - } else if(input.length > 1) { - const pairs = []; - for(var i = 0; i < input.length; i++) { - // high surrogate - if(input.charCodeAt(i) >= 0xd800 && input.charCodeAt(i) <= 0xdbff) { - if(input.charCodeAt(i + 1) >= 0xdc00 && input.charCodeAt(i + 1) <= 0xdfff) { - // low surrogate - pairs.push( - (input.charCodeAt(i) - 0xd800) * 0x400 - + (input.charCodeAt(i + 1) - 0xdc00) + 0x10000 - ); - } - } else if(input.charCodeAt(i) < 0xd800 || input.charCodeAt(i) > 0xdfff) { - // modifiers and joiners - pairs.push(input.charCodeAt(i)) - } - } - - return pairs.join(' '); - } - - return ''; -}; - export function getEmojiToneIndex(input: string) { let match = input.match(/[\uDFFB-\uDFFF]/); return match ? 5 - (57343 - match[0].charCodeAt(0)) : 0; diff --git a/src/scripts/format_jsons.js b/src/scripts/format_jsons.js index 2778d713..ecf74893 100644 --- a/src/scripts/format_jsons.js +++ b/src/scripts/format_jsons.js @@ -92,6 +92,8 @@ if(false) { let emoji = unified/* .replace(/-FE0F/gi, '') */.split('-') .reduce((prev, curr) => prev + String.fromCodePoint(parseInt(curr, 16)), ''); + + //emoji = emoji.replace(/\ufe0f/g, ''); let c = categories[category] === undefined ? 9 : categories[category]; //obj[emoji] = '' + c + sort_order;