首页 > 解决方案 > 用于替换 emoji-mart 表情符号的角管

问题描述

为此目的,GitHub 上已经有一个现有的管道,但它不起作用。它似乎有点过时,但我不知道我需要改变什么。以下错误被记录到浏览器控制台中:

GET http://localhost:4200/assets/images/emojis/apple_32.png 404 (Not Found)

我希望可以复制整个管道:

import { Pipe, PipeTransform, Inject } from '@angular/core';
import { DOCUMENT } from '@angular/common';
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
import { emojis, EmojiService, CompressedEmojiData } from '@ctrl/ngx-emoji-mart/ngx-emoji';

@Pipe({
    name: 'replaceEmojis'
})
export class ReplaceEmojisPipe implements PipeTransform {
    private static cachedEmojiRegex: RegExp;
    private sheet: string;

    constructor(@Inject(DOCUMENT) private document: Document, private sanitizer: DomSanitizer, private emojiService: EmojiService) {}

    public transform(html: string, sheet = 'apple'): SafeHtml {
        this.sheet = sheet;
        return this.sanitizer.bypassSecurityTrustHtml(
            this.emojisToImages(html)
        );
    }

    /**
     * Replaces all unicode emojis available through emoji-mart with a span displaying
     * the image representation of that emoji
     * @param html The original html
     */
    public emojisToImages(html: string): string {
        // Ensure most html entities are parsed to unicode:
        const div = <Element> this.document.createElement('div');
        div.innerHTML = html;
        html = div.innerHTML;

        html = html
            // Replace zero width joins with their unicode representations:
            .replace(/&zwj;/g, '\u200d')

            // Replace every emoji with a span with a background image:
            .replace(this.emojiRegex, unicodeEmoji => {
                const hexCodeSegments = [];
                let i = 0;
                while (i < unicodeEmoji.length) {
                    const segment = unicodeEmoji.codePointAt(i).toString(16).toUpperCase();
                    hexCodeSegments.push(segment);

                    i += Math.ceil(segment.length / 4);
                }
                const hexCode = hexCodeSegments.join('-');
                const matchingData = this.findEmojiData(hexCode);
                if (matchingData) {
                    const span = document.createElement('span');
                    span.style.width = '22px';
                    span.style.height = '22px';
                    span.style.display = 'inline-block';
                    span.style.backgroundImage = `url(/assets/images/emojis/${this.sheet}_32.png)`;
                    span.style.backgroundSize = `${100 * 52}%`;
                    const multiply = 100 / 51;
                    span.style.backgroundPosition = `${multiply * matchingData.sheet[0]}% ${multiply * matchingData.sheet[1]}%`;
                    span.style.textIndent = '-10000px';
                    span.style.overflow = 'hidden';
                    span.innerText = unicodeEmoji;


                    return span.outerHTML;
                }

                return unicodeEmoji;
        });

        return html;
    }

    /**
     * Regex matching all unicode emojis contained in emoji-mart
     */
    private get emojiRegex(): RegExp {
        if (ReplaceEmojisPipe.cachedEmojiRegex) {
            return ReplaceEmojisPipe.cachedEmojiRegex;
        }

        let characterRegexStrings: string[] = [];
        for (const emoji of emojis) {
            characterRegexStrings.push(this.emojiService.unifiedToNative(emoji.unified).replace(/[.*+?^${}()|[\]\\]/g, '\\$&'));

            if (emoji.skin_variations) {
                for (const skinVariation of emoji.skin_variations) {
                    characterRegexStrings.push(this.emojiService.unifiedToNative(skinVariation.unified).replace(/[.*+?^${}()|[\]\\]/g, '\\$&'));
                }
            }
        }

        characterRegexStrings = characterRegexStrings.sort((a, b) => {
            if (a.length > b.length) {
                return -1;
            }

            if (b.length > a.length) {
                return 1;
            }

            return 0;
        });

        const strings = characterRegexStrings;
        const reString = '(' + strings.join('|') + ')';
        ReplaceEmojisPipe.cachedEmojiRegex = new RegExp(reString, 'gu');

        return ReplaceEmojisPipe.cachedEmojiRegex;
    }

    /**
     * Find raw emoji-mart data for a specific emoji hex code
     * @param hexCode String representation of the emoji hex code
     */
    private findEmojiData(hexCode: string): CompressedEmojiData {
        for (const emojiData of emojis) {
            if (emojiData.unified === hexCode) {
                return emojiData;
            }

            if (emojiData.skinVariations) {
                for (const skinVariation of emojiData.skinVariations) {
                    if (skinVariation.unified === hexCode) {
                        const skinData = Object.assign({}, emojiData);
                        skinData.sheet = skinVariation.sheet;
                        return skinData;
                    }
                }
            }
        }

        return null;
    }

}

来源是:https ://gist.github.com/lentschi/8600f9b6ea7e7f5178f40a36f3053de7

因此,过时的第一件事是您需要将变量名从 更改skin_variationsskinVariations。如果我现在想将它用作我的 HTML 文件的 innerHTML,则会发生错误。

我真的很想拥有它,因为拥有一个包含所有可能集合的表情符号选择器是没有用的,但是在 Chrome 中,所有的表情都是用浏览器主题设计的。

标签: angularpipeemoji

解决方案


这对我有用。

我从 npm 包ngx-emoji-mart链接到图像)下载了 32px 图像,并将其存储在我的应用程序下/assets/images/emojis/32.png

然后我用

span.style.backgroundImage = `url(/assets/images/emojis/32.png)`;

该管道非常适合我的 Angular 应用程序,它显示由 emojimart 创建的本机表情符号。这就是我需要的职位。


推荐阅读