(0xD83D - 0xD800) * 0x400 + 0xDE00 - 0xDC00 + 0x10000 = 1f600
D83D = ((0x1f600 - 0x10000) >> 10) + 0xD800; DE00 = ((0x1f600 - 0x10000) % 0x400) + 0xDC00;
String.prototype.codePointAt // , String.fromCodePoint // .
/\u{1F466}/u
function emojiToHtml(str) { str = str.replace(/\uFE0F/g, ''); return str.replace(emojiRegex, buildImgFromEmoji); } var tpl = '<img class="emoji emoji--{code} js-smile-insert" src="{src}" srcset="{src} 1x, {src_x2} 2x" unselectable="on">'; var url = 'https://badoocdn.com/big/chat/emoji/{code}.png'; var url2 = 'https://badoocdn.com/big/chat/emoji@x2/{code}.png'; function buildImgFromEmoji(emoji) { var codePoint = extractEmojiToCodePoint(emoji); return $tpl(tpl, { code: codePoint, src: $tpl(url, { code: codePoint }), src_x2: $tpl(url2, { code: codePoint }) }); } function extractEmojiToCodePoint(emoji) { return emoji .split('') .map(function (symbol, index) { return emoji.codePointAt(index).toString(16); }) .filter(function (codePoint) { return !isSurrogatePair(codePoint); }, this) .join('-'); } function isSurrogatePair(codePoint) { codePoint = parseInt(codePoint, 16); return codePoint >= 0xD800 && codePoint <= 0xDFFF; }
var emojiRanges = [ '(?:\uD83C[\uDDE6-\uDDFF]){2}', // '[\u0023-\u0039]\u20E3', // '(?:[\uD83D\uD83C\uD83E][\uDC00-\uDFFF]|[\u270A-\u270D\u261D\u26F9])\uD83C[\uDFFB-\uDFFF]', // '\uD83D[\uDC68\uDC69][\u200D\u200C].+?\uD83D[\uDC66-\uDC69](?![\u200D\u200C])', // '[\uD83D\uD83C\uD83E][\uDC00-\uDFFF]', // '[\u3297\u3299\u303D\u2B50\u2B55\u2B1B\u27BF\u27A1\u24C2\u25B6\u25C0\u2600\u2705\u21AA\u21A9]', // '[\u203C\u2049\u2122\u2328\u2601\u260E\u261d\u2620\u2626\u262A\u2638\u2639\u263a\u267B\u267F\u2702\u2708]', '[\u2194-\u2199]', '[\u2B05-\u2B07]', '[\u2934-\u2935]', '[\u2795-\u2797]', '[\u2709-\u2764]', '[\u2622-\u2623]', '[\u262E-\u262F]', '[\u231A-\u231B]', '[\u23E9-\u23EF]', '[\u23F0-\u23F4]', '[\u23F8-\u23FA]', '[\u25AA-\u25AB]', '[\u25FB-\u25FE]', '[\u2602-\u2618]', '[\u2648-\u2653]', '[\u2660-\u2668]', '[\u26A0-\u26FA]', '[\u2692-\u269C]' ]; var emojiRegex = new RegExp(emojiRanges.join('|'), 'g');
<div id="t" contenteditable="true" data-placeholder=" "></div>
var tagRegex = /<[^>]+>/gim; var styleTagRegex = /<style\b[^>]*>([\s\S]*?)<\/style>/gim; var validTagsRegex = /<br[\s/]*>|<img\s+class="emoji\semoji[-\w\s]+"\s+((src|srcset|unselectable)="[^"]*"\s*)+>/i; function cleanUp(text) { return text .replace(styleTagRegex, '') .replace(tagRegex, function (tag) { return tag.match(validTagsRegex) ? tag : ''; }) .replace(/\n/g, ''); }
function onPaste(e) { e.preventDefault(); var clp = e.clipboardData; if (clp !== undefined || window.clipboardData !== undefined) { var text; if (clp !== undefined) { text = clp.getData('text/html') || clp.getData('text/plain') || ''; } else { text = window.clipboardData.getData('text') || ''; } if (text) { text = cleanUp(text); text = emojiToHtml(text); var el = document.createElement('span'); el.innerHTML = text; el.innerHTML = el.innerHTML.replace(/\n/g, ''); t.appendChild(el); restore(); } } }
function restore() { var range = document.createRange(); range.selectNodeContents(t); range.collapse(false); var sel = window.getSelection(); sel.removeAllRanges(); sel.addRange(range); }
var htmlToEmojiRegex = /<img.*?class="emoji\semoji--(.+?)\sjs-smile-insert".*?>/gi; function htmlToEmoji(html) { return html.replace(htmlToEmojiRegex, function (imgTag, codesStr) { var codesInt = codesStr.split('-').map(function (codePoint) { return parseInt(codePoint, 16); }); var emoji = String.fromCodePoint.apply(null, codesInt); return emoji.match(emojiRegex) ? emoji : ''; }); }
Source: https://habr.com/ru/post/282113/
All Articles