Make WordPress Core

Ticket #31242: 31242.2.diff

File 31242.2.diff, 62.1 KB (added by pento, 10 years ago)
  • src/wp-includes/class-wp-editor.php

     
    360360                                                'wordpress',
    361361                                                'wpautoresize',
    362362                                                'wpeditimage',
     363                                                'wpemoji',
    363364                                                'wpgallery',
    364365                                                'wplink',
    365366                                                'wpdialogs',
  • src/wp-includes/default-filters.php

     
    160160add_filter( 'the_title_rss',      'ent2ncr',      8 );
    161161add_filter( 'the_title_rss',      'esc_html'        );
    162162add_filter( 'the_content_rss',    'ent2ncr',      8 );
     163add_filter( 'the_content_feed',   'feed_emoji'      );
    163164add_filter( 'the_excerpt_rss',    'convert_chars'   );
    164165add_filter( 'the_excerpt_rss',    'ent2ncr',      8 );
    165166add_filter( 'comment_author_rss', 'ent2ncr',      8 );
    166167add_filter( 'comment_text_rss',   'ent2ncr',      8 );
    167168add_filter( 'comment_text_rss',   'esc_html'        );
     169add_filter( 'comment_text_rss',   'feed_emoji'      );
    168170add_filter( 'bloginfo_rss',       'ent2ncr',      8 );
    169171add_filter( 'the_author',         'ent2ncr',      8 );
    170172
     173// Email filters
     174add_filter( 'wp_mail', 'mail_emoji' );
     175
    171176// Misc filters
    172177add_filter( 'option_ping_sites',        'privacy_ping_filter'                 );
    173178add_filter( 'option_blog_charset',      '_wp_specialchars'                    ); // IMPORTANT: This must not be wp_specialchars() or esc_html() or it'll cause an infinite loop
     
    217222add_action( 'wp_print_footer_scripts', '_wp_footer_scripts'                 );
    218223add_action( 'init',                'check_theme_switched',            99    );
    219224add_action( 'after_switch_theme',  '_wp_sidebars_changed'                   );
     225add_action( 'wp_print_styles',     'print_emoji_styles'                     );
    220226
    221227if ( isset( $_GET['replytocom'] ) )
    222228    add_action( 'wp_head', 'wp_no_robots' );
     
    247253add_action( 'admin_print_scripts',        'print_head_scripts',                      20    );
    248254add_action( 'admin_print_footer_scripts', '_wp_footer_scripts'                             );
    249255add_action( 'admin_print_styles',         'print_admin_styles',                      20    );
     256add_action( 'admin_print_styles',         'print_emoji_styles'                             );
    250257add_action( 'init',                       'smilies_init',                             5    );
    251258add_action( 'plugins_loaded',             'wp_maybe_load_widgets',                    0    );
    252259add_action( 'plugins_loaded',             'wp_maybe_load_embeds',                     0    );
  • src/wp-includes/feed.php

     
    649649
    650650        return $feed;
    651651}
     652
     653/**
     654 * Convert emoji characters in a feed into static images.
     655 *
     656 * @param string $content The content to convert.
     657 *
     658 * @return The converted content.
     659 */
     660function feed_emoji( $content ) {
     661        return wp_staticize_emoji( $content, true );
     662}
  • src/wp-includes/formatting.php

     
    20382038        $smiley = trim( reset( $matches ) );
    20392039        $img = $wpsmiliestrans[ $smiley ];
    20402040
     2041        $matches = array();
     2042        $ext = preg_match( '/\.([^.]+)$/', $img, $matches ) ? strtolower( $matches[1] ) : false;
     2043        $image_exts = array( 'jpg', 'jpeg', 'jpe', 'gif', 'png' );
     2044
     2045        // Don't convert smilies that aren't images - they're probably emoji.
     2046        if ( ! in_array( $ext, $image_exts ) ) {
     2047                return $img;
     2048        }
     2049
    20412050        /**
    20422051         * Filter the Smiley image URL before it's used in the image element.
    20432052         *
     
    40154024
    40164025        return $spaces;
    40174026}
     4027
     4028/**
     4029 * Print the important emoji-related styles.
     4030 *
     4031 * @since 4.2.0
     4032 */
     4033function print_emoji_styles() {
     4034?>
     4035<style type="text/css">
     4036img.wp-smiley,
     4037img.emoji {
     4038        border: none !important;
     4039        box-shadow: none !important;
     4040        height: 1em !important;
     4041        width: 1em !important;
     4042        margin: 0 .05em 0 .1em !important;
     4043        vertical-align: -0.1em !important;
     4044        background: none !important;
     4045        padding: 0 !important;
     4046}
     4047</style>
     4048<?php
     4049}
     4050
     4051/**
     4052 * Convert any 4 byte emoji in a string to their equivalent HTML entity.
     4053 * Currently, only Unicode 7 emoji are supported. Unicode 8 emoji will be added
     4054 * when the spec in finalised, along with the new skin-tone modifiers.
     4055 *
     4056 * This allows us to store emoji in a DB using the utf8 character set.
     4057 *
     4058 * @since 4.2.0
     4059 *
     4060 * @param string $content The content to encode.
     4061 * @return string The encoded content.
     4062 */
     4063function wp_encode_emoji( $content ) {
     4064        if ( function_exists( 'mb_convert_encoding' ) ) {
     4065                $regex = '/(
     4066                     \x23\xE2\x83\xA3               # Digits
     4067                     [\x30-\x39]\xE2\x83\xA3
     4068                   | \xF0\x9F[\x85-\x88][\xA6-\xBF] # Enclosed characters
     4069                   | \xF0\x9F[\x8C-\x97][\x80-\xBF] # Misc
     4070                   | \xF0\x9F\x98[\x80-\xBF]        # Smilies
     4071                   | \xF0\x9F\x99[\x80-\x8F]
     4072                   | \xF0\x9F\x9A[\x80-\xBF]        # Transport and map symbols
     4073                   | \xF0\x9F\x99[\x80-\x85]
     4074                )/x';
     4075
     4076                $matches = array();
     4077                if ( preg_match_all( $regex, $content, $matches ) ) {
     4078                        if ( ! empty( $matches[1] ) ) {
     4079                                foreach( $matches[1] as $emoji ) {
     4080                                        /*
     4081                                         * UTF-32's hex encoding is the same as HTML's hex encoding.
     4082                                         * So, by converting the emoji from UTF-8 to UTF-32, we magically
     4083                                         * get the correct hex encoding.
     4084                                         */
     4085                                        $unpacked = unpack( 'H*', mb_convert_encoding( $emoji, 'UTF-32', 'UTF-8' ) );
     4086                                        if ( isset( $unpacked[1] ) ) {
     4087                                                $entity = '&#x' . trim( $unpacked[1], '0' ) . ';';
     4088                                                $content = str_replace( $emoji, $entity, $content );
     4089                                        }
     4090                                }
     4091                        }
     4092                }
     4093        }
     4094
     4095        return $content;
     4096}
     4097
     4098/**
     4099 * Convert emoji to a static <img> link.
     4100 *
     4101 * @since 4.2.0
     4102 *
     4103 * @param string $content The content to encode.
     4104 * @return string The encoded content.
     4105 */
     4106function wp_staticize_emoji( $content ) {
     4107        $content = wp_encode_emoji( $content );
     4108
     4109        if ( ! class_exists( 'DOMDocument' ) ) {
     4110                return $content;
     4111        }
     4112
     4113        /** This filter is documented in wp-includes/script-loader.php */
     4114        $cdn_url = apply_filters( 'emoji_url', '//s0.wp.com/wp-content/mu-plugins/emoji/twemoji/72x72/' );
     4115        /** This filter is documented in wp-includes/script-loader.php */
     4116        $ext = apply_filters( 'emoji_ext', '.png' );
     4117
     4118        $html = '<!DOCTYPE html><html><head></head><body>' . $content . '</body></html>';
     4119
     4120        $document = new DOMDocument;
     4121        if ( ! $document->loadHTML( $html ) ) {
     4122                return $content;
     4123        }
     4124
     4125        $xpath = new DOMXPath( $document );
     4126        $textnodes = $xpath->query( '//text()' );
     4127
     4128        foreach( $textnodes as $node ) {
     4129                $originalText = $text = wp_encode_emoji( $node->nodeValue );
     4130
     4131                $matches = array();
     4132                if ( preg_match_all( '/(&#x1f1(e[6-9a-f]|f[0-9a-f]);){2}/', $text, $matches ) ) {
     4133                        if ( ! empty( $matches[0] ) ) {
     4134                                foreach ( $matches[0] as $flag ) {
     4135                                        $chars = str_replace( array( '&#x', ';'), '', $flag );
     4136
     4137                                        list( $char1, $char2 ) = str_split( $chars, 5 );
     4138                                        $entity = '<img src="https:' . $cdn_url . $char1 . '-' . $char2 . $ext . '" class="wp-smiley" style="height: 1em;" />';
     4139
     4140                                        $text = str_replace( $flag, $entity, $text );
     4141                                }
     4142                        }
     4143                }
     4144
     4145                // Loosely match the Emoji Unicode range.
     4146                $regex = '/(&#x[2-3][0-9a-f]{3};|&#x1f[1-6][0-9a-f]{2};)/';
     4147
     4148                $matches = array();
     4149                if ( preg_match_all( $regex, $text, $matches ) ) {
     4150                        if ( ! empty( $matches[1] ) ) {
     4151                                foreach ( $matches[1] as $emoji ) {
     4152                                        $char = str_replace( array( '&#x', ';'), '', $emoji );
     4153                                        $entity = '<img src="https:' . $cdn_url . $char . $ext . '" class="wp-smiley" style="height: 1em;" />';
     4154
     4155                                        $text = str_replace( $emoji, $entity, $text );
     4156                                }
     4157                        }
     4158                }
     4159
     4160                if ( $originalText !== $text ) {
     4161                        $content = str_replace( $originalText, $text, $content );
     4162                }
     4163        }
     4164
     4165        return $content;
     4166}
     4167
     4168/**
     4169 * Convert emoji in emails into static images.
     4170 *
     4171 * @param array $mail The email data array.
     4172 *
     4173 * @return array The email data array, with emoji in the message staticized.
     4174 */
     4175function mail_emoji( $mail ) {
     4176        $mail['message'] = wp_staticize_emoji( $mail['message'], true );
     4177        return $mail;
     4178}
  • src/wp-includes/functions.php

     
    29452945
    29462946        if ( !isset( $wpsmiliestrans ) ) {
    29472947                $wpsmiliestrans = array(
    2948                 ':mrgreen:' => 'icon_mrgreen.gif',
    2949                 ':neutral:' => 'icon_neutral.gif',
    2950                 ':twisted:' => 'icon_twisted.gif',
    2951                   ':arrow:' => 'icon_arrow.gif',
    2952                   ':shock:' => 'icon_eek.gif',
    2953                   ':smile:' => 'icon_smile.gif',
    2954                     ':???:' => 'icon_confused.gif',
    2955                    ':cool:' => 'icon_cool.gif',
    2956                    ':evil:' => 'icon_evil.gif',
    2957                    ':grin:' => 'icon_biggrin.gif',
    2958                    ':idea:' => 'icon_idea.gif',
    2959                    ':oops:' => 'icon_redface.gif',
    2960                    ':razz:' => 'icon_razz.gif',
    2961                    ':roll:' => 'icon_rolleyes.gif',
    2962                    ':wink:' => 'icon_wink.gif',
    2963                     ':cry:' => 'icon_cry.gif',
    2964                     ':eek:' => 'icon_surprised.gif',
    2965                     ':lol:' => 'icon_lol.gif',
    2966                     ':mad:' => 'icon_mad.gif',
    2967                     ':sad:' => 'icon_sad.gif',
    2968                       '8-)' => 'icon_cool.gif',
    2969                       '8-O' => 'icon_eek.gif',
    2970                       ':-(' => 'icon_sad.gif',
    2971                       ':-)' => 'icon_smile.gif',
    2972                       ':-?' => 'icon_confused.gif',
    2973                       ':-D' => 'icon_biggrin.gif',
    2974                       ':-P' => 'icon_razz.gif',
    2975                       ':-o' => 'icon_surprised.gif',
    2976                       ':-x' => 'icon_mad.gif',
    2977                       ':-|' => 'icon_neutral.gif',
    2978                       ';-)' => 'icon_wink.gif',
     2948                ':mrgreen:' => 'mrgreen.png',
     2949                ':neutral:' => "\xf0\x9f\x98\x90",
     2950                ':twisted:' => "\xf0\x9f\x98\x88",
     2951                  ':arrow:' => "\xe2\x9e\xa1",
     2952                  ':shock:' => "\xf0\x9f\x98\xaf",
     2953                  ':smile:' => 'simple-smile.png',
     2954                    ':???:' => "\xf0\x9f\x98\xaf",
     2955                   ':cool:' => "\xf0\x9f\x98\x8e",
     2956                   ':evil:' => "\xf0\x9f\x91\xbf",
     2957                   ':grin:' => "\xf0\x9f\x98\x84",
     2958                   ':idea:' => "\xf0\x9f\x92\xa1",
     2959                   ':oops:' => "\xf0\x9f\x98\xb3",
     2960                   ':razz:' => "\xf0\x9f\x98\x9b",
     2961                   ':roll:' => 'rolleyes.png',
     2962                   ':wink:' => "\xf0\x9f\x98\x89",
     2963                    ':cry:' => "\xf0\x9f\x98\xa5",
     2964                    ':eek:' => "\xf0\x9f\x98\xaf",
     2965                    ':lol:' => "\xf0\x9f\x98\x84",
     2966                    ':mad:' => "\xf0\x9f\x98\xa1",
     2967                    ':sad:' => "\xf0\x9f\x98\xa6",
     2968                      '8-)' => "\xf0\x9f\x98\x8e",
     2969                      '8-O' => "\xf0\x9f\x98\xaf",
     2970                      ':-(' => "\xf0\x9f\x98\xa6",
     2971                      ':-)' => 'simple-smile.png',
     2972                      ':-?' => "\xf0\x9f\x98\xaf",
     2973                      ':-D' => "\xf0\x9f\x98\x84",
     2974                      ':-P' => "\xf0\x9f\x98\x9b",
     2975                      ':-o' => "\xf0\x9f\x98\xaf",
     2976                      ':-x' => "\xf0\x9f\x98\xa1",
     2977                      ':-|' => "\xf0\x9f\x98\x90",
     2978                      ';-)' => "\xf0\x9f\x98\x89",
    29792979                // This one transformation breaks regular text with frequency.
    2980                 //     '8)' => 'icon_cool.gif',
    2981                        '8O' => 'icon_eek.gif',
    2982                        ':(' => 'icon_sad.gif',
    2983                        ':)' => 'icon_smile.gif',
    2984                        ':?' => 'icon_confused.gif',
    2985                        ':D' => 'icon_biggrin.gif',
    2986                        ':P' => 'icon_razz.gif',
    2987                        ':o' => 'icon_surprised.gif',
    2988                        ':x' => 'icon_mad.gif',
    2989                        ':|' => 'icon_neutral.gif',
    2990                        ';)' => 'icon_wink.gif',
    2991                       ':!:' => 'icon_exclaim.gif',
    2992                       ':?:' => 'icon_question.gif',
     2980                //     '8)' => "\xf0\x9f\x98\x8e",
     2981                       '8O' => "\xf0\x9f\x98\xaf",
     2982                       ':(' => "\xf0\x9f\x98\xa6",
     2983                       ':)' => 'simple-smile.png',
     2984                       ':?' => "\xf0\x9f\x98\xaf",
     2985                       ':D' => "\xf0\x9f\x98\x84",
     2986                       ':P' => "\xf0\x9f\x98\x9b",
     2987                       ':o' => "\xf0\x9f\x98\xaf",
     2988                       ':x' => "\xf0\x9f\x98\xa1",
     2989                       ':|' => "\xf0\x9f\x98\x90",
     2990                       ';)' => "\xf0\x9f\x98\x89",
     2991                      ':!:' => "\xe2\x9d\x97",
     2992                      ':?:' => "\xe2\x9d\x93",
    29932993                );
    29942994        }
    29952995
  • src/wp-includes/js/emoji.js

     
     1/* global EmojiSettings, twemoji */
     2var WPEmoji;
     3
     4(function() {
     5        WPEmoji = {
     6                /**
     7                 * The CDN URL for where emoji files are hosted.
     8                 *
     9                 * @since 4.2.0
     10                 *
     11                 * @var string
     12                 */
     13                base_url: '//s0.wp.com/wp-content/mu-plugins/emoji/twemoji/72x72',
     14
     15                /**
     16                 * The extension of the hosted emoji files.
     17                 *
     18                 * @since 4.2.0
     19                 *
     20                 * @var string
     21                 */
     22                ext: '.png',
     23
     24                /**
     25                 * Flag to determine if we should parse all emoji characters into Twemoji images.
     26                 *
     27                 * @since 4.2.0
     28                 *
     29                 * @var bool
     30                 */
     31                parseAllEmoji: false,
     32
     33                /**
     34                 * Flag to determine if we should consider parsing emoji characters into Twemoji images.
     35                 *
     36                 * @since 4.2.0
     37                 *
     38                 * @var bool
     39                 */
     40                parseEmoji: false,
     41
     42                /**
     43                 * Flag to determine if we should parse flag characters into Twemoji images.
     44                 *
     45                 * @since 4.2.0
     46                 *
     47                 * @var bool
     48                 */
     49                parseFlags: false,
     50
     51                /**
     52                 * Initialize our emoji support, and set up listeners.
     53                 *
     54                 * @since 4.2.0
     55                 */
     56                init: function() {
     57                        if ( typeof EmojiSettings !== 'undefined' ) {
     58                                this.base_url = EmojiSettings.base_url || this.base_url;
     59                                this.ext = EmojiSettings.ext || this.ext;
     60                        }
     61
     62                        WPEmoji.parseAllEmoji = ! WPEmoji.browserSupportsEmoji();
     63                        WPEmoji.parseFlags = ! WPEmoji.browserSupportsFlagEmoji();
     64                        WPEmoji.parseEmoji = WPEmoji.parseAllEmoji || WPEmoji.parseFlags;
     65
     66                        if ( ! WPEmoji.parseEmoji ) {
     67                                return;
     68                        }
     69                },
     70
     71                /**
     72                 * Runs when the document load event is fired, so we can do our first parse of the page.
     73                 *
     74                 * @since 4.2.0
     75                 */
     76                load: function() {
     77                        WPEmoji.parse( document.body );
     78                },
     79
     80                /**
     81                 * Detect if the browser supports rendering emoji.
     82                 *
     83                 * @since 4.2.0
     84                 *
     85                 * @return {bool} True if the browser can render emoji, false if it cannot.
     86                 */
     87                browserSupportsEmoji: function() {
     88                        var context, smile;
     89
     90                        if ( ! document.createElement( 'canvas' ).getContext ) {
     91                                return;
     92                        }
     93
     94                        context = document.createElement( 'canvas' ).getContext( '2d' );
     95                        if ( typeof context.fillText != 'function' ) {
     96                                return;
     97                        }
     98
     99                        smile = String.fromCharCode( 55357 ) + String.fromCharCode( 56835 );
     100
     101                        /*
     102                         * Chrome OS X added native emoji rendering in M41. Unfortunately,
     103                         * it doesn't work when the font is bolder than 500 weight. So, we
     104                         * check for bold rendering support to avoid invisible emoji in Chrome.
     105                         */
     106                        context.textBaseline = 'top';
     107                        context.font = '600 32px Arial';
     108                        context.fillText( smile, 0, 0 );
     109
     110                        return context.getImageData( 16, 16, 1, 1 ).data[0] !== 0;
     111                },
     112
     113                /**
     114                 * Detect if the browser supports rendering flag emoji. Flag emoji are a single glyph
     115                 * made of two characters, so some browsers (notably, Firefox OS X) don't support them.
     116                 *
     117                 * @since 4.2.0
     118                 * @return {bool} True if the browser renders flag characters as a flag glyph, false if it does not.
     119                 */
     120                browserSupportsFlagEmoji: function() {
     121                        var context, flag, canvas;
     122
     123                        canvas = document.createElement( 'canvas' );
     124
     125                        if ( ! canvas.getContext ) {
     126                                return;
     127                        }
     128
     129                        context = canvas.getContext( '2d' );
     130
     131                        if ( typeof context.fillText != 'function' ) {
     132                                return;
     133                        }
     134
     135                        flag =  String.fromCharCode(55356) + String.fromCharCode(56812); // [G]
     136                        flag += String.fromCharCode(55356) + String.fromCharCode(56807); // [B]
     137
     138                        context.textBaseline = 'top';
     139                        context.font = '32px Arial';
     140                        context.fillText( flag, 0, 0 );
     141
     142                        /*
     143                         * This works because the image will be one of three things:
     144                         * - Two empty squares, if the browser doen't render emoji
     145                         * - Two squares with 'G' and 'B' in them, if the browser doen't render flag emoji
     146                         * - The British flag
     147                         *
     148                         * The first two will encode to small images (1-2KB data URLs), the third will encode
     149                         * to a larger image (4-5KB data URL).
     150                         */
     151                        return canvas.toDataURL().length > 3000;
     152
     153                },
     154
     155                /**
     156                 * Given a DOM node, parse any emoji characters into Twemoji images.
     157                 *
     158                 * @since 4.2.0
     159                 *
     160                 * @param {Element} element The DOM node to parse.
     161                 */
     162                parse: function( element ) {
     163                        if ( ! WPEmoji.parseEmoji ) {
     164                                return;
     165                        }
     166
     167                        return twemoji.parse( element, {
     168                                base: this.base_url,
     169                                ext: this.ext,
     170                                callback: function( icon, options ) {
     171                                        // Ignore some standard characters that TinyMCE recommends in its character map.
     172                                        switch ( icon ) {
     173                                                case 'a9':
     174                                                case 'ae':
     175                                                case '2122':
     176                                                case '2194':
     177                                                case '2660':
     178                                                case '2663':
     179                                                case '2665':
     180                                                case '2666':
     181                                                        return false;
     182                                        }
     183
     184                                        if ( WPEmoji.parseFlags && ! WPEmoji.parseAllEmoji && ! icon.match( /^1f1(e[6-9a-f]|f[1-9a-f])-1f1(e[6-9a-f]|f[1-9a-f])$/ ) ) {
     185                                                return false;
     186                                        }
     187
     188                                        return ''.concat( options.base, '/', icon, options.ext );
     189                                }
     190                        } );
     191                }
     192        };
     193
     194        if ( window.addEventListener ) {
     195                window.addEventListener( 'load', WPEmoji.load, false );
     196        } else if ( window.attachEvent ) {
     197                window.attachEvent( 'onload', WPEmoji.load );
     198        }
     199
     200        WPEmoji.init();
     201})();
  • src/wp-includes/js/tinymce/plugins/wpemoji/css/editor.css

    Property changes on: src/wp-includes/js/emoji.js
    ___________________________________________________________________
    Added: svn:executable
    ## -0,0 +1 ##
    +*
    \ No newline at end of property
     
     1.emoji-wrapper,
     2.emoji-spacer {
     3        -moz-user-select: none;
     4        -webkit-user-select: none;
     5        -ms-user-select: none;
     6        user-select: none;
     7}
     8img.emoji {
     9        height: 1em;
     10        width: 1em;
     11        margin: 0 .05em 0 .1em;
     12        vertical-align: -0.1em;
     13        border: none;
     14        padding: 0;
     15}
  • src/wp-includes/js/tinymce/plugins/wpemoji/css/rtl/editor-rtl.css

    Property changes on: src/wp-includes/js/tinymce/plugins/wpemoji/css/editor.css
    ___________________________________________________________________
    Added: svn:executable
    ## -0,0 +1 ##
    +*
    \ No newline at end of property
     
     1/* This file was automatically generated on Nov 19 2014 05:08:11 */
     2
     3.emoji-wrapper,
     4.emoji-spacer {
     5        -moz-user-select: none;
     6        -webkit-user-select: none;
     7        -ms-user-select: none;
     8        user-select: none;
     9}
     10img.emoji {
     11        height: 1em;
     12        width: 1em;
     13        margin: 0 .1em 0 .05em;
     14        vertical-align: -0.1em;
     15        border: none;
     16        padding: 0;
     17}
  • src/wp-includes/js/tinymce/plugins/wpemoji/plugin.js

    Property changes on: src/wp-includes/js/tinymce/plugins/wpemoji/css/rtl/editor-rtl.css
    ___________________________________________________________________
    Added: svn:executable
    ## -0,0 +1 ##
    +*
    \ No newline at end of property
     
     1( function( tinymce, WPEmoji ) {
     2        tinymce.PluginManager.add( 'wpemoji', function( editor, url ) {
     3                var typing;
     4
     5                if ( ! WPEmoji.parseEmoji ) {
     6                        return;
     7                }
     8
     9                // Loads stylesheet for custom styles within the editor
     10                editor.on( 'init', function() {
     11                        var cssId = editor.dom.uniqueId();
     12                        var linkElm = editor.dom.create( 'link', {
     13                                id:   cssId,
     14                                rel:  'stylesheet',
     15                                href: url + '/css/editor.css'
     16                        });
     17                        editor.getDoc().getElementsByTagName( 'head' )[0].appendChild( linkElm );
     18                } );
     19
     20                editor.on( 'keydown keyup', function( event ) {
     21                        typing = event.type === 'keydown';
     22                } );
     23
     24                editor.on( 'input setcontent', function() {
     25                        var selection, node, bookmark, imgs;
     26
     27                        if ( typing ) {
     28                                return;
     29                        }
     30
     31                        selection = editor.selection;
     32                        node = selection.getNode();
     33                        bookmark = selection.getBookmark();
     34
     35                        WPEmoji.parse( node );
     36
     37                        imgs = editor.dom.select( 'img.emoji', node );
     38
     39                        tinymce.each( imgs, function( elem ) {
     40                                if ( ! elem.getAttribute( 'data-wp-emoji' ) ) {
     41                                        elem.setAttribute( 'data-mce-resize', 'false' );
     42                                        elem.setAttribute( 'data-mce-placeholder', '1' );
     43                                        elem.setAttribute( 'data-wp-emoji', elem.alt );
     44                                }
     45                        } );
     46
     47                        selection.moveToBookmark( bookmark );
     48                } );
     49
     50                editor.on( 'postprocess', function( event ) {
     51                        if ( event.content ) {
     52                                event.content = event.content.replace( /<img[^>]+data-wp-emoji="([^"]+)"[^>]*>/g, function( match, emoji ) {
     53                                        return emoji;
     54                                } );
     55                        }
     56                } );
     57
     58                editor.on( 'resolvename', function( event ) {
     59                        if ( event.target.nodeName === 'IMG' && editor.dom.getAttrib( event.target, 'data-wp-emoji' ) ) {
     60                                event.preventDefault();
     61                        }
     62                } );
     63        } );
     64} )( window.tinymce, window.WPEmoji );
  • src/wp-includes/js/twemoji.js

    Property changes on: src/wp-includes/js/tinymce/plugins/wpemoji/plugin.js
    ___________________________________________________________________
    Added: svn:executable
    ## -0,0 +1 ##
    +*
    \ No newline at end of property
     
     1/*jslint indent: 2, browser: true, bitwise: true, plusplus: true */
     2var twemoji;
     3twemoji = (function (
     4  /*! Copyright Twitter Inc. and other contributors. Licensed under MIT *//*
     5    https://github.com/twitter/twemoji/blob/gh-pages/LICENSE
     6  */
     7
     8  // WARNING:   this file is generated automatically via
     9  //            `node twemoji-generator.js`
     10  //            please update its `createTwemoji` function
     11  //            at the bottom of the same file instead.
     12
     13) {
     14  'use strict';
     15
     16  /*jshint maxparams:4 */
     17
     18  var
     19    // the exported module object
     20    twemoji = {
     21
     22
     23    /////////////////////////
     24    //      properties     //
     25    /////////////////////////
     26
     27      // default assets url, by default will be Twitter Inc. CDN
     28      base: (location.protocol === 'https:' ? 'https:' : 'http:') +
     29            '//twemoji.maxcdn.com/',
     30
     31      // default assets file extensions, by default '.png'
     32      ext: '.png',
     33
     34      // default assets/folder size, by default "36x36"
     35      // available via Twitter CDN: 16, 36, 72
     36      size: '36x36',
     37
     38      // default class name, by default 'emoji'
     39      className: 'emoji',
     40
     41      // basic utilities / helpers to convert code points
     42      // to JavaScript surrogates and vice versa
     43      convert: {
     44
     45        /**
     46         * Given an HEX codepoint, returns UTF16 surrogate pairs.
     47         *
     48         * @param   string  generic codepoint, i.e. '1F4A9'
     49         * @return  string  codepoint transformed into utf16 surrogates pair,
     50         *          i.e. \uD83D\uDCA9
     51         *
     52         * @example
     53         *  twemoji.convert.fromCodePoint('1f1e8');
     54         *  // "\ud83c\udde8"
     55         *
     56         *  '1f1e8-1f1f3'.split('-').map(twemoji.convert.fromCodePoint).join('')
     57         *  // "\ud83c\udde8\ud83c\uddf3"
     58         */
     59        fromCodePoint: fromCodePoint,
     60
     61        /**
     62         * Given UTF16 surrogate pairs, returns the equivalent HEX codepoint.
     63         *
     64         * @param   string  generic utf16 surrogates pair, i.e. \uD83D\uDCA9
     65         * @param   string  optional separator for double code points, default='-'
     66         * @return  string  utf16 transformed into codepoint, i.e. '1F4A9'
     67         *
     68         * @example
     69         *  twemoji.convert.toCodePoint('\ud83c\udde8\ud83c\uddf3');
     70         *  // "1f1e8-1f1f3"
     71         *
     72         *  twemoji.convert.toCodePoint('\ud83c\udde8\ud83c\uddf3', '~');
     73         *  // "1f1e8~1f1f3"
     74         */
     75        toCodePoint: toCodePoint
     76      },
     77
     78
     79    /////////////////////////
     80    //       methods       //
     81    /////////////////////////
     82
     83      /**
     84       * User first: used to remove missing images
     85       * preserving the original text intent when
     86       * a fallback for network problems is desired.
     87       * Automatically added to Image nodes via DOM
     88       * It could be recycled for string operations via:
     89       *  $('img.emoji').on('error', twemoji.onerror)
     90       */
     91      onerror: function onerror() {
     92        if (this.parentNode) {
     93          this.parentNode.replaceChild(createText(this.alt), this);
     94        }
     95      },
     96
     97      /**
     98       * Main method/logic to generate either <img> tags or HTMLImage nodes.
     99       *  "emojify" a generic text or DOM Element.
     100       *
     101       * @overloads
     102       *
     103       * String replacement for `innerHTML` or server side operations
     104       *  twemoji.parse(string);
     105       *  twemoji.parse(string, Function);
     106       *  twemoji.parse(string, Object);
     107       *
     108       * HTMLElement tree parsing for safer operations over existing DOM
     109       *  twemoji.parse(HTMLElement);
     110       *  twemoji.parse(HTMLElement, Function);
     111       *  twemoji.parse(HTMLElement, Object);
     112       *
     113       * @param   string|HTMLElement  the source to parse and enrich with emoji.
     114       *
     115       *          string              replace emoji matches with <img> tags.
     116       *                              Mainly used to inject emoji via `innerHTML`
     117       *                              It does **not** parse the string or validate it,
     118       *                              it simply replaces found emoji with a tag.
     119       *                              NOTE: be sure this won't affect security.
     120       *
     121       *          HTMLElement         walk through the DOM tree and find emoji
     122       *                              that are inside **text node only** (nodeType === 3)
     123       *                              Mainly used to put emoji in already generated DOM
     124       *                              without compromising surrounding nodes and
     125       *                              **avoiding** the usage of `innerHTML`.
     126       *                              NOTE: Using DOM elements instead of strings should
     127       *                              improve security without compromising too much
     128       *                              performance compared with a less safe `innerHTML`.
     129       *
     130       * @param   Function|Object  [optional]
     131       *                              either the callback that will be invoked or an object
     132       *                              with all properties to use per each found emoji.
     133       *
     134       *          Function            if specified, this will be invoked per each emoji
     135       *                              that has been found through the RegExp except
     136       *                              those follwed by the invariant \uFE0E ("as text").
     137       *                              Once invoked, parameters will be:
     138       *
     139       *                                codePoint:string  the lower case HEX code point
     140       *                                                  i.e. "1f4a9"
     141       *
     142       *                                options:Object    all info for this parsing operation
     143       *
     144       *                                variant:char      the optional \uFE0F ("as image")
     145       *                                                  variant, in case this info
     146       *                                                  is anyhow meaningful.
     147       *                                                  By default this is ignored.
     148       *
     149       *                              If such callback will return a falsy value instead
     150       *                              of a valid `src` to use for the image, nothing will
     151       *                              actually change for that specific emoji.
     152       *
     153       *
     154       *          Object              if specified, an object containing the following properties
     155       *
     156       *            callback   Function  the callback to invoke per each found emoji.
     157       *            base       string    the base url, by default twemoji.base
     158       *            ext        string    the image extension, by default twemoji.ext
     159       *            size       string    the assets size, by default twemoji.size
     160       *
     161       * @example
     162       *
     163       *  twemoji.parse("I \u2764\uFE0F emoji!");
     164       *  // I <img class="emoji" draggable="false" alt="❤️" src="/assets/2764.gif"> emoji!
     165       *
     166       *
     167       *  twemoji.parse("I \u2764\uFE0F emoji!", function(icon, options, variant) {
     168       *    return '/assets/' + icon + '.gif';
     169       *  });
     170       *  // I <img class="emoji" draggable="false" alt="❤️" src="/assets/2764.gif"> emoji!
     171       *
     172       *
     173       * twemoji.parse("I \u2764\uFE0F emoji!", {
     174       *   size: 72,
     175       *   callback: function(icon, options, variant) {
     176       *     return '/assets/' + options.size + '/' + icon + options.ext;
     177       *   }
     178       * });
     179       *  // I <img class="emoji" draggable="false" alt="❤️" src="/assets/72x72/2764.png"> emoji!
     180       *
     181       */
     182      parse: parse,
     183
     184      /**
     185       * Given a string, invokes the callback argument
     186       *  per each emoji found in such string.
     187       * This is the most raw version used by
     188       *  the .parse(string) method itself.
     189       *
     190       * @param   string    generic string to parse
     191       * @param   Function  a generic callback that will be
     192       *                    invoked to replace the content.
     193       *                    This calback wil receive standard
     194       *                    String.prototype.replace(str, callback)
     195       *                    arguments such:
     196       *  callback(
     197       *    match,  // the emoji match
     198       *    icon,   // the emoji text (same as text)
     199       *    variant // either '\uFE0E' or '\uFE0F', if present
     200       *  );
     201       *
     202       *                    and others commonly received via replace.
     203       *
     204       *  NOTE: When the variant \uFE0E is found, remember this is an explicit intent
     205       *  from the user: the emoji should **not** be replaced with an image.
     206       *  In \uFE0F case one, it's the opposite, it should be graphic.
     207       *  This utility convetion is that only \uFE0E are not translated into images.
     208       */
     209      replace: replace,
     210
     211      /**
     212       * Simplify string tests against emoji.
     213       *
     214       * @param   string  some text that might contain emoji
     215       * @return  boolean true if any emoji was found, false otherwise.
     216       *
     217       * @example
     218       *
     219       *  if (twemoji.test(someContent)) {
     220       *    console.log("emoji All The Things!");
     221       *  }
     222       */
     223      test: test
     224    },
     225
     226    // RegExp based on emoji's official Unicode standards
     227    // http://www.unicode.org/Public/UNIDATA/EmojiSources.txt
     228    re = /((?:\ud83c\udde8\ud83c\uddf3|\ud83c\uddfa\ud83c\uddf8|\ud83c\uddf7\ud83c\uddfa|\ud83c\uddf0\ud83c\uddf7|\ud83c\uddef\ud83c\uddf5|\ud83c\uddee\ud83c\uddf9|\ud83c\uddec\ud83c\udde7|\ud83c\uddeb\ud83c\uddf7|\ud83c\uddea\ud83c\uddf8|\ud83c\udde9\ud83c\uddea|\u0039\ufe0f?\u20e3|\u0038\ufe0f?\u20e3|\u0037\ufe0f?\u20e3|\u0036\ufe0f?\u20e3|\u0035\ufe0f?\u20e3|\u0034\ufe0f?\u20e3|\u0033\ufe0f?\u20e3|\u0032\ufe0f?\u20e3|\u0031\ufe0f?\u20e3|\u0030\ufe0f?\u20e3|\u0023\ufe0f?\u20e3|\ud83d\udeb3|\ud83d\udeb1|\ud83d\udeb0|\ud83d\udeaf|\ud83d\udeae|\ud83d\udea6|\ud83d\udea3|\ud83d\udea1|\ud83d\udea0|\ud83d\ude9f|\ud83d\ude9e|\ud83d\ude9d|\ud83d\ude9c|\ud83d\ude9b|\ud83d\ude98|\ud83d\ude96|\ud83d\ude94|\ud83d\ude90|\ud83d\ude8e|\ud83d\ude8d|\ud83d\ude8b|\ud83d\ude8a|\ud83d\ude88|\ud83d\ude86|\ud83d\ude82|\ud83d\ude81|\ud83d\ude36|\ud83d\ude34|\ud83d\ude2f|\ud83d\ude2e|\ud83d\ude2c|\ud83d\ude27|\ud83d\ude26|\ud83d\ude1f|\ud83d\ude1b|\ud83d\ude19|\ud83d\ude17|\ud83d\ude15|\ud83d\ude11|\ud83d\ude10|\ud83d\ude0e|\ud83d\ude08|\ud83d\ude07|\ud83d\ude00|\ud83d\udd67|\ud83d\udd66|\ud83d\udd65|\ud83d\udd64|\ud83d\udd63|\ud83d\udd62|\ud83d\udd61|\ud83d\udd60|\ud83d\udd5f|\ud83d\udd5e|\ud83d\udd5d|\ud83d\udd5c|\ud83d\udd2d|\ud83d\udd2c|\ud83d\udd15|\ud83d\udd09|\ud83d\udd08|\ud83d\udd07|\ud83d\udd06|\ud83d\udd05|\ud83d\udd04|\ud83d\udd02|\ud83d\udd01|\ud83d\udd00|\ud83d\udcf5|\ud83d\udcef|\ud83d\udced|\ud83d\udcec|\ud83d\udcb7|\ud83d\udcb6|\ud83d\udcad|\ud83d\udc6d|\ud83d\udc6c|\ud83d\udc65|\ud83d\udc2a|\ud83d\udc16|\ud83d\udc15|\ud83d\udc13|\ud83d\udc10|\ud83d\udc0f|\ud83d\udc0b|\ud83d\udc0a|\ud83d\udc09|\ud83d\udc08|\ud83d\udc07|\ud83d\udc06|\ud83d\udc05|\ud83d\udc04|\ud83d\udc03|\ud83d\udc02|\ud83d\udc01|\ud83d\udc00|\ud83c\udfe4|\ud83c\udfc9|\ud83c\udfc7|\ud83c\udf7c|\ud83c\udf50|\ud83c\udf4b|\ud83c\udf33|\ud83c\udf32|\ud83c\udf1e|\ud83c\udf1d|\ud83c\udf1c|\ud83c\udf1a|\ud83c\udf18|\ud83c\udccf|\ud83c\udd70|\ud83c\udd71|\ud83c\udd7e|\ud83c\udd8e|\ud83c\udd91|\ud83c\udd92|\ud83c\udd93|\ud83c\udd94|\ud83c\udd95|\ud83c\udd96|\ud83c\udd97|\ud83c\udd98|\ud83c\udd99|\ud83c\udd9a|\ud83d\udc77|\ud83d\udec5|\ud83d\udec4|\ud83d\udec3|\ud83d\udec2|\ud83d\udec1|\ud83d\udebf|\ud83d\udeb8|\ud83d\udeb7|\ud83d\udeb5|\ud83c\ude01|\ud83c\ude02|\ud83c\ude32|\ud83c\ude33|\ud83c\ude34|\ud83c\ude35|\ud83c\ude36|\ud83c\ude37|\ud83c\ude38|\ud83c\ude39|\ud83c\ude3a|\ud83c\ude50|\ud83c\ude51|\ud83c\udf00|\ud83c\udf01|\ud83c\udf02|\ud83c\udf03|\ud83c\udf04|\ud83c\udf05|\ud83c\udf06|\ud83c\udf07|\ud83c\udf08|\ud83c\udf09|\ud83c\udf0a|\ud83c\udf0b|\ud83c\udf0c|\ud83c\udf0f|\ud83c\udf11|\ud83c\udf13|\ud83c\udf14|\ud83c\udf15|\ud83c\udf19|\ud83c\udf1b|\ud83c\udf1f|\ud83c\udf20|\ud83c\udf30|\ud83c\udf31|\ud83c\udf34|\ud83c\udf35|\ud83c\udf37|\ud83c\udf38|\ud83c\udf39|\ud83c\udf3a|\ud83c\udf3b|\ud83c\udf3c|\ud83c\udf3d|\ud83c\udf3e|\ud83c\udf3f|\ud83c\udf40|\ud83c\udf41|\ud83c\udf42|\ud83c\udf43|\ud83c\udf44|\ud83c\udf45|\ud83c\udf46|\ud83c\udf47|\ud83c\udf48|\ud83c\udf49|\ud83c\udf4a|\ud83c\udf4c|\ud83c\udf4d|\ud83c\udf4e|\ud83c\udf4f|\ud83c\udf51|\ud83c\udf52|\ud83c\udf53|\ud83c\udf54|\ud83c\udf55|\ud83c\udf56|\ud83c\udf57|\ud83c\udf58|\ud83c\udf59|\ud83c\udf5a|\ud83c\udf5b|\ud83c\udf5c|\ud83c\udf5d|\ud83c\udf5e|\ud83c\udf5f|\ud83c\udf60|\ud83c\udf61|\ud83c\udf62|\ud83c\udf63|\ud83c\udf64|\ud83c\udf65|\ud83c\udf66|\ud83c\udf67|\ud83c\udf68|\ud83c\udf69|\ud83c\udf6a|\ud83c\udf6b|\ud83c\udf6c|\ud83c\udf6d|\ud83c\udf6e|\ud83c\udf6f|\ud83c\udf70|\ud83c\udf71|\ud83c\udf72|\ud83c\udf73|\ud83c\udf74|\ud83c\udf75|\ud83c\udf76|\ud83c\udf77|\ud83c\udf78|\ud83c\udf79|\ud83c\udf7a|\ud83c\udf7b|\ud83c\udf80|\ud83c\udf81|\ud83c\udf82|\ud83c\udf83|\ud83c\udf84|\ud83c\udf85|\ud83c\udf86|\ud83c\udf87|\ud83c\udf88|\ud83c\udf89|\ud83c\udf8a|\ud83c\udf8b|\ud83c\udf8c|\ud83c\udf8d|\ud83c\udf8e|\ud83c\udf8f|\ud83c\udf90|\ud83c\udf91|\ud83c\udf92|\ud83c\udf93|\ud83c\udfa0|\ud83c\udfa1|\ud83c\udfa2|\ud83c\udfa3|\ud83c\udfa4|\ud83c\udfa5|\ud83c\udfa6|\ud83c\udfa7|\ud83c\udfa8|\ud83c\udfa9|\ud83c\udfaa|\ud83c\udfab|\ud83c\udfac|\ud83c\udfad|\ud83c\udfae|\ud83c\udfaf|\ud83c\udfb0|\ud83c\udfb1|\ud83c\udfb2|\ud83c\udfb3|\ud83c\udfb4|\ud83c\udfb5|\ud83c\udfb6|\ud83c\udfb7|\ud83c\udfb8|\ud83c\udfb9|\ud83c\udfba|\ud83c\udfbb|\ud83c\udfbc|\ud83c\udfbd|\ud83c\udfbe|\ud83c\udfbf|\ud83c\udfc0|\ud83c\udfc1|\ud83c\udfc2|\ud83c\udfc3|\ud83c\udfc4|\ud83c\udfc6|\ud83c\udfc8|\ud83c\udfca|\ud83c\udfe0|\ud83c\udfe1|\ud83c\udfe2|\ud83c\udfe3|\ud83c\udfe5|\ud83c\udfe6|\ud83c\udfe7|\ud83c\udfe8|\ud83c\udfe9|\ud83c\udfea|\ud83c\udfeb|\ud83c\udfec|\ud83c\udfed|\ud83c\udfee|\ud83c\udfef|\ud83c\udff0|\ud83d\udc0c|\ud83d\udc0d|\ud83d\udc0e|\ud83d\udc11|\ud83d\udc12|\ud83d\udc14|\ud83d\udc17|\ud83d\udc18|\ud83d\udc19|\ud83d\udc1a|\ud83d\udc1b|\ud83d\udc1c|\ud83d\udc1d|\ud83d\udc1e|\ud83d\udc1f|\ud83d\udc20|\ud83d\udc21|\ud83d\udc22|\ud83d\udc23|\ud83d\udc24|\ud83d\udc25|\ud83d\udc26|\ud83d\udc27|\ud83d\udc28|\ud83d\udc29|\ud83d\udc2b|\ud83d\udc2c|\ud83d\udc2d|\ud83d\udc2e|\ud83d\udc2f|\ud83d\udc30|\ud83d\udc31|\ud83d\udc32|\ud83d\udc33|\ud83d\udc34|\ud83d\udc35|\ud83d\udc36|\ud83d\udc37|\ud83d\udc38|\ud83d\udc39|\ud83d\udc3a|\ud83d\udc3b|\ud83d\udc3c|\ud83d\udc3d|\ud83d\udc3e|\ud83d\udc40|\ud83d\udc42|\ud83d\udc43|\ud83d\udc44|\ud83d\udc45|\ud83d\udc46|\ud83d\udc47|\ud83d\udc48|\ud83d\udc49|\ud83d\udc4a|\ud83d\udc4b|\ud83d\udc4c|\ud83d\udc4d|\ud83d\udc4e|\ud83d\udc4f|\ud83d\udc50|\ud83d\udc51|\ud83d\udc52|\ud83d\udc53|\ud83d\udc54|\ud83d\udc55|\ud83d\udc56|\ud83d\udc57|\ud83d\udc58|\ud83d\udc59|\ud83d\udc5a|\ud83d\udc5b|\ud83d\udc5c|\ud83d\udc5d|\ud83d\udc5e|\ud83d\udc5f|\ud83d\udc60|\ud83d\udc61|\ud83d\udc62|\ud83d\udc63|\ud83d\udc64|\ud83d\udc66|\ud83d\udc67|\ud83d\udc68|\ud83d\udc69|\ud83d\udc6a|\ud83d\udc6b|\ud83d\udc6e|\ud83d\udc6f|\ud83d\udc70|\ud83d\udc71|\ud83d\udc72|\ud83d\udc73|\ud83d\udc74|\ud83d\udc75|\ud83d\udc76|\ud83d\udeb4|\ud83d\udc78|\ud83d\udc79|\ud83d\udc7a|\ud83d\udc7b|\ud83d\udc7c|\ud83d\udc7d|\ud83d\udc7e|\ud83d\udc7f|\ud83d\udc80|\ud83d\udc81|\ud83d\udc82|\ud83d\udc83|\ud83d\udc84|\ud83d\udc85|\ud83d\udc86|\ud83d\udc87|\ud83d\udc88|\ud83d\udc89|\ud83d\udc8a|\ud83d\udc8b|\ud83d\udc8c|\ud83d\udc8d|\ud83d\udc8e|\ud83d\udc8f|\ud83d\udc90|\ud83d\udc91|\ud83d\udc92|\ud83d\udc93|\ud83d\udc94|\ud83d\udc95|\ud83d\udc96|\ud83d\udc97|\ud83d\udc98|\ud83d\udc99|\ud83d\udc9a|\ud83d\udc9b|\ud83d\udc9c|\ud83d\udc9d|\ud83d\udc9e|\ud83d\udc9f|\ud83d\udca0|\ud83d\udca1|\ud83d\udca2|\ud83d\udca3|\ud83d\udca4|\ud83d\udca5|\ud83d\udca6|\ud83d\udca7|\ud83d\udca8|\ud83d\udca9|\ud83d\udcaa|\ud83d\udcab|\ud83d\udcac|\ud83d\udcae|\ud83d\udcaf|\ud83d\udcb0|\ud83d\udcb1|\ud83d\udcb2|\ud83d\udcb3|\ud83d\udcb4|\ud83d\udcb5|\ud83d\udcb8|\ud83d\udcb9|\ud83d\udcba|\ud83d\udcbb|\ud83d\udcbc|\ud83d\udcbd|\ud83d\udcbe|\ud83d\udcbf|\ud83d\udcc0|\ud83d\udcc1|\ud83d\udcc2|\ud83d\udcc3|\ud83d\udcc4|\ud83d\udcc5|\ud83d\udcc6|\ud83d\udcc7|\ud83d\udcc8|\ud83d\udcc9|\ud83d\udcca|\ud83d\udccb|\ud83d\udccc|\ud83d\udccd|\ud83d\udcce|\ud83d\udccf|\ud83d\udcd0|\ud83d\udcd1|\ud83d\udcd2|\ud83d\udcd3|\ud83d\udcd4|\ud83d\udcd5|\ud83d\udcd6|\ud83d\udcd7|\ud83d\udcd8|\ud83d\udcd9|\ud83d\udcda|\ud83d\udcdb|\ud83d\udcdc|\ud83d\udcdd|\ud83d\udcde|\ud83d\udcdf|\ud83d\udce0|\ud83d\udce1|\ud83d\udce2|\ud83d\udce3|\ud83d\udce4|\ud83d\udce5|\ud83d\udce6|\ud83d\udce7|\ud83d\udce8|\ud83d\udce9|\ud83d\udcea|\ud83d\udceb|\ud83d\udcee|\ud83d\udcf0|\ud83d\udcf1|\ud83d\udcf2|\ud83d\udcf3|\ud83d\udcf4|\ud83d\udcf6|\ud83d\udcf7|\ud83d\udcf9|\ud83d\udcfa|\ud83d\udcfb|\ud83d\udcfc|\ud83d\udd03|\ud83d\udd0a|\ud83d\udd0b|\ud83d\udd0c|\ud83d\udd0d|\ud83d\udd0e|\ud83d\udd0f|\ud83d\udd10|\ud83d\udd11|\ud83d\udd12|\ud83d\udd13|\ud83d\udd14|\ud83d\udd16|\ud83d\udd17|\ud83d\udd18|\ud83d\udd19|\ud83d\udd1a|\ud83d\udd1b|\ud83d\udd1c|\ud83d\udd1d|\ud83d\udd1e|\ud83d\udd1f|\ud83d\udd20|\ud83d\udd21|\ud83d\udd22|\ud83d\udd23|\ud83d\udd24|\ud83d\udd25|\ud83d\udd26|\ud83d\udd27|\ud83d\udd28|\ud83d\udd29|\ud83d\udd2a|\ud83d\udd2b|\ud83d\udd2e|\ud83d\udd2f|\ud83d\udd30|\ud83d\udd31|\ud83d\udd32|\ud83d\udd33|\ud83d\udd34|\ud83d\udd35|\ud83d\udd36|\ud83d\udd37|\ud83d\udd38|\ud83d\udd39|\ud83d\udd3a|\ud83d\udd3b|\ud83d\udd3c|\ud83d\udd3d|\ud83d\udd50|\ud83d\udd51|\ud83d\udd52|\ud83d\udd53|\ud83d\udd54|\ud83d\udd55|\ud83d\udd56|\ud83d\udd57|\ud83d\udd58|\ud83d\udd59|\ud83d\udd5a|\ud83d\udd5b|\ud83d\uddfb|\ud83d\uddfc|\ud83d\uddfd|\ud83d\uddfe|\ud83d\uddff|\ud83d\ude01|\ud83d\ude02|\ud83d\ude03|\ud83d\ude04|\ud83d\ude05|\ud83d\ude06|\ud83d\ude09|\ud83d\ude0a|\ud83d\ude0b|\ud83d\ude0c|\ud83d\ude0d|\ud83d\ude0f|\ud83d\ude12|\ud83d\ude13|\ud83d\ude14|\ud83d\ude16|\ud83d\ude18|\ud83d\ude1a|\ud83d\ude1c|\ud83d\ude1d|\ud83d\ude1e|\ud83d\ude20|\ud83d\ude21|\ud83d\ude22|\ud83d\ude23|\ud83d\ude24|\ud83d\ude25|\ud83d\ude28|\ud83d\ude29|\ud83d\ude2a|\ud83d\ude2b|\ud83d\ude2d|\ud83d\ude30|\ud83d\ude31|\ud83d\ude32|\ud83d\ude33|\ud83d\ude35|\ud83d\ude37|\ud83d\ude38|\ud83d\ude39|\ud83d\ude3a|\ud83d\ude3b|\ud83d\ude3c|\ud83d\ude3d|\ud83d\ude3e|\ud83d\ude3f|\ud83d\ude40|\ud83d\ude45|\ud83d\ude46|\ud83d\ude47|\ud83d\ude48|\ud83d\ude49|\ud83d\ude4a|\ud83d\ude4b|\ud83d\ude4c|\ud83d\ude4d|\ud83d\ude4e|\ud83d\ude4f|\ud83d\ude80|\ud83d\ude83|\ud83d\ude84|\ud83d\ude85|\ud83d\ude87|\ud83d\ude89|\ud83d\ude8c|\ud83d\ude8f|\ud83d\ude91|\ud83d\ude92|\ud83d\ude93|\ud83d\ude95|\ud83d\ude97|\ud83d\ude99|\ud83d\ude9a|\ud83d\udea2|\ud83d\udea4|\ud83d\udea5|\ud83d\udea7|\ud83d\udea8|\ud83d\udea9|\ud83d\udeaa|\ud83d\udeab|\ud83d\udeac|\ud83d\udead|\ud83d\udeb2|\ud83d\udeb6|\ud83d\udeb9|\ud83d\udeba|\ud83d\udebb|\ud83d\udebc|\ud83d\udebd|\ud83d\udebe|\ud83d\udec0|\ud83c\udde6|\ud83c\udde7|\ud83c\udde8|\ud83c\udde9|\ud83c\uddea|\ud83c\uddeb|\ud83c\uddec|\ud83c\udded|\ud83c\uddee|\ud83c\uddef|\ud83c\uddf0|\ud83c\uddf1|\ud83c\uddf2|\ud83c\uddf3|\ud83c\uddf4|\ud83c\uddf5|\ud83c\uddf6|\ud83c\uddf7|\ud83c\uddf8|\ud83c\uddf9|\ud83c\uddfa|\ud83c\uddfb|\ud83c\uddfc|\ud83c\uddfd|\ud83c\uddfe|\ud83c\uddff|\ud83c\udf0d|\ud83c\udf0e|\ud83c\udf10|\ud83c\udf12|\ud83c\udf16|\ud83c\udf17|\ue50a|\u3030|\u27b0|\u2797|\u2796|\u2795|\u2755|\u2754|\u2753|\u274e|\u274c|\u2728|\u270b|\u270a|\u2705|\u26ce|\u23f3|\u23f0|\u23ec|\u23eb|\u23ea|\u23e9|\u2122|\u27bf|\u00a9|\u00ae)|(?:(?:\ud83c\udc04|\ud83c\udd7f|\ud83c\ude1a|\ud83c\ude2f|\u3299|\u303d|\u2b55|\u2b50|\u2b1c|\u2b1b|\u2b07|\u2b06|\u2b05|\u2935|\u2934|\u27a1|\u2764|\u2757|\u2747|\u2744|\u2734|\u2733|\u2716|\u2714|\u2712|\u270f|\u270c|\u2709|\u2708|\u2702|\u26fd|\u26fa|\u26f5|\u26f3|\u26f2|\u26ea|\u26d4|\u26c5|\u26c4|\u26be|\u26bd|\u26ab|\u26aa|\u26a1|\u26a0|\u2693|\u267f|\u267b|\u3297|\u2666|\u2665|\u2663|\u2660|\u2653|\u2652|\u2651|\u2650|\u264f|\u264e|\u264d|\u264c|\u264b|\u264a|\u2649|\u2648|\u263a|\u261d|\u2615|\u2614|\u2611|\u260e|\u2601|\u2600|\u25fe|\u25fd|\u25fc|\u25fb|\u25c0|\u25b6|\u25ab|\u25aa|\u24c2|\u231b|\u231a|\u21aa|\u21a9|\u2199|\u2198|\u2197|\u2196|\u2195|\u2194|\u2139|\u2049|\u203c|\u2668)([\uFE0E\uFE0F]?)))/g,
     229
     230    // nodes with type 1 which should **not** be parsed
     231    shouldntBeParsed = /IFRAME|NOFRAMES|NOSCRIPT|SCRIPT|STYLE|TEXTAREA|SELECT/,
     232
     233    // just a private shortcut
     234    fromCharCode = String.fromCharCode;
     235
     236  return twemoji;
     237
     238
     239  /////////////////////////
     240  //  private functions  //
     241  //     declaration     //
     242  /////////////////////////
     243
     244  /**
     245   * Shortcut to create text nodes
     246   * @param   string  text used to create DOM text node
     247   * @return  Node  a DOM node with that text
     248   */
     249  function createText(text) {
     250    return document.createTextNode(text);
     251  }
     252
     253  /**
     254   * Default callback used to generate emoji src
     255   *  based on Twitter CDN
     256   * @param   string    the emoji codepoint string
     257   * @param   string    the default size to use, i.e. "36x36"
     258   * @param   string    optional "\uFE0F" variant char, ignored by default
     259   * @return  string    the image source to use
     260   */
     261  function defaultImageSrcGenerator(icon, options) {
     262    return ''.concat(options.base, options.size, '/', icon, options.ext);
     263  }
     264
     265  /**
     266   * Given a generic DOM nodeType 1, walk through all children
     267   * and store every nodeType 3 (#text) found in the tree.
     268   * @param   Element a DOM Element with probably some text in it
     269   * @param   Array the list of previously discovered text nodes
     270   * @return  Array same list with new discovered nodes, if any
     271   */
     272  function grabAllTextNodes(node, allText) {
     273    var
     274      childNodes = node.childNodes,
     275      length = childNodes.length,
     276      subnode,
     277      nodeType;
     278    while (length--) {
     279      subnode = childNodes[length];
     280      nodeType = subnode.nodeType;
     281      // parse emoji only in text nodes
     282      if (nodeType === 3) {
     283        // collect them to process emoji later
     284        allText.push(subnode);
     285      }
     286      // ignore all nodes that are not type 1 or that
     287      // should not be parsed as script, style, and others
     288      else if (nodeType === 1 && !shouldntBeParsed.test(subnode.nodeName)) {
     289        grabAllTextNodes(subnode, allText);
     290      }
     291    }
     292    return allText;
     293  }
     294
     295  /**
     296   * Used to both remove the possible variant
     297   *  and to convert utf16 into code points
     298   * @param   string    the emoji surrogate pair
     299   * @param   string    the optional variant char, if any
     300   */
     301  function grabTheRightIcon(icon, variant) {
     302    // if variant is present as \uFE0F
     303    return toCodePoint(
     304      variant === '\uFE0F' ?
     305        // the icon should not contain it
     306        icon.slice(0, -1) :
     307        // fix non standard OSX behavior
     308        (icon.length === 3 && icon.charAt(1) === '\uFE0F' ?
     309          icon.charAt(0) + icon.charAt(2) : icon)
     310    );
     311  }
     312
     313  /**
     314   * DOM version of the same logic / parser:
     315   *  emojify all found sub-text nodes placing images node instead.
     316   * @param   Element   generic DOM node with some text in some child node
     317   * @param   Object    options  containing info about how to parse
     318    *
     319    *            .callback   Function  the callback to invoke per each found emoji.
     320    *            .base       string    the base url, by default twemoji.base
     321    *            .ext        string    the image extension, by default twemoji.ext
     322    *            .size       string    the assets size, by default twemoji.size
     323    *
     324   * @return  Element same generic node with emoji in place, if any.
     325   */
     326  function parseNode(node, options) {
     327    var
     328      allText = grabAllTextNodes(node, []),
     329      length = allText.length,
     330      fragment,
     331      subnode,
     332      text,
     333      match,
     334      i,
     335      index,
     336      img,
     337      alt,
     338      icon,
     339      variant,
     340      src;
     341    while (length--) {
     342      fragment = document.createDocumentFragment();
     343      subnode = allText[length];
     344      text = subnode.nodeValue;
     345      i = 0;
     346      while ((match = re.exec(text))) {
     347        index = match.index;
     348        if (index !== i) {
     349          fragment.appendChild(
     350            createText(text.slice(i, index))
     351          );
     352        }
     353        alt = match[0];
     354        icon = match[1];
     355        variant = match[2];
     356        i = index + alt.length;
     357        if (variant !== '\uFE0E') {
     358          src = options.callback(
     359            grabTheRightIcon(icon, variant),
     360            options,
     361            variant
     362          );
     363          if (src) {
     364            img = new Image();
     365            img.onerror = twemoji.onerror;
     366            img.className = options.className;
     367            img.setAttribute('draggable', 'false');
     368            img.alt = alt;
     369            img.src = src;
     370          }
     371        }
     372        fragment.appendChild(img || createText(alt));
     373        img = null;
     374      }
     375      // is there actually anything to replace in here ?
     376      if (0 < i) {
     377        // any text left to be added ?
     378        if (i < text.length) {
     379          fragment.appendChild(
     380            createText(text.slice(i))
     381          );
     382        }
     383        // replace the text node only, leave intact
     384        // anything else surrounding such text
     385        subnode.parentNode.replaceChild(fragment, subnode);
     386      }
     387    }
     388    return node;
     389  }
     390
     391  /**
     392   * String/HTML version of the same logic / parser:
     393   *  emojify a generic text placing images tags instead of surrogates pair.
     394   * @param   string    generic string with possibly some emoji in it
     395   * @param   Object    options  containing info about how to parse
     396   *
     397   *            .callback   Function  the callback to invoke per each found emoji.
     398   *            .base       string    the base url, by default twemoji.base
     399   *            .ext        string    the image extension, by default twemoji.ext
     400   *            .size       string    the assets size, by default twemoji.size
     401   *
     402   * @return  the string with <img tags> replacing all found and parsed emoji
     403   */
     404  function parseString(str, options) {
     405    return replace(str, function (match, icon, variant) {
     406      var src;
     407      // verify the variant is not the FE0E one
     408      // this variant means "emoji as text" and should not
     409      // require any action/replacement
     410      // http://unicode.org/Public/UNIDATA/StandardizedVariants.html
     411      if (variant !== '\uFE0E') {
     412        src = options.callback(
     413          grabTheRightIcon(icon, variant),
     414          options,
     415          variant
     416        );
     417        if (src) {
     418          // recycle the match string replacing the emoji
     419          // with its image counter part
     420          match = '<img '.concat(
     421            'class="', options.className, '" ',
     422            'draggable="false" ',
     423            // needs to preserve user original intent
     424            // when variants should be copied and pasted too
     425            'alt="',
     426            match,
     427            '" ',
     428            'src="',
     429            src,
     430            '"',
     431            '>'
     432          );
     433        }
     434      }
     435      return match;
     436    });
     437  }
     438
     439  /**
     440   * Given a generic value, creates its squared counterpart if it's a number.
     441   *  As example, number 36 will return '36x36'.
     442   * @param   any     a generic value.
     443   * @return  any     a string representing asset size, i.e. "36x36"
     444   *                  only in case the value was a number.
     445   *                  Returns initial value otherwise.
     446   */
     447  function toSizeSquaredAsset(value) {
     448    return typeof value === 'number' ?
     449      value + 'x' + value :
     450      value;
     451  }
     452
     453
     454  /////////////////////////
     455  //  exported functions //
     456  //     declaration     //
     457  /////////////////////////
     458
     459  function fromCodePoint(codepoint) {
     460    var code = typeof codepoint === 'string' ?
     461          parseInt(codepoint, 16) : codepoint;
     462    if (code < 0x10000) {
     463      return fromCharCode(code);
     464    }
     465    code -= 0x10000;
     466    return fromCharCode(
     467      0xD800 + (code >> 10),
     468      0xDC00 + (code & 0x3FF)
     469    );
     470  }
     471
     472  function parse(what, how) {
     473    if (!how || typeof how === 'function') {
     474      how = {callback: how};
     475    }
     476    // if first argument is string, inject html <img> tags
     477    // otherwise use the DOM tree and parse text nodes only
     478    return (typeof what === 'string' ? parseString : parseNode)(what, {
     479      callback: how.callback || defaultImageSrcGenerator,
     480      base:     typeof how.base === 'string' ? how.base : twemoji.base,
     481      ext:      how.ext || twemoji.ext,
     482      size:     how.folder || toSizeSquaredAsset(how.size || twemoji.size),
     483      className:how.className || twemoji.className
     484    });
     485  }
     486
     487  function replace(text, callback) {
     488    return String(text).replace(re, callback);
     489  }
     490
     491  function test(text) {
     492    // IE6 needs a reset before too
     493    re.lastIndex = 0;
     494    var result = re.test(text);
     495    re.lastIndex = 0;
     496    return result;
     497  }
     498
     499  function toCodePoint(unicodeSurrogates, sep) {
     500    var
     501      r = [],
     502      c = 0,
     503      p = 0,
     504      i = 0;
     505    while (i < unicodeSurrogates.length) {
     506      c = unicodeSurrogates.charCodeAt(i++);
     507      if (p) {
     508        r.push((0x10000 + ((p - 0xD800) << 10) + (c - 0xDC00)).toString(16));
     509        p = 0;
     510      } else if (0xD800 <= c && c <= 0xDBFF) {
     511        p = c;
     512      } else {
     513        r.push(c.toString(16));
     514      }
     515    }
     516    return r.join(sep || '-');
     517  }
     518
     519}());
     520 No newline at end of file
  • src/wp-includes/post.php

    Property changes on: src/wp-includes/js/twemoji.js
    ___________________________________________________________________
    Added: svn:executable
    ## -0,0 +1 ##
    +*
    \ No newline at end of property
     
    33293329        // Expected_slashed (everything!).
    33303330        $data = compact( 'post_author', 'post_date', 'post_date_gmt', 'post_content', 'post_content_filtered', 'post_title', 'post_excerpt', 'post_status', 'post_type', 'comment_status', 'ping_status', 'post_password', 'post_name', 'to_ping', 'pinged', 'post_modified', 'post_modified_gmt', 'post_parent', 'menu_order', 'post_mime_type', 'guid' );
    33313331
     3332        $emoji_fields = array( 'post_title', 'post_content', 'post_excerpt' );
     3333
     3334        foreach( $emoji_fields as $emoji_field ) {
     3335                if ( isset( $data[ $emoji_field ] ) ) {
     3336                        $charset = $wpdb->get_col_charset( $wpdb->posts, $emoji_field );
     3337                        if ( 'utf8' === $charset ) {
     3338                                $data[ $emoji_field ] = wp_encode_emoji( $data[ $emoji_field ] );
     3339                        }
     3340                }
     3341        }
     3342
    33323343        if ( 'attachment' === $post_type ) {
    33333344                /**
    33343345                 * Filter attachment post data before it is updated in or added to the database.
  • src/wp-includes/script-loader.php

     
    424424        $scripts->add( 'media-audiovideo', "/wp-includes/js/media/audio-video$suffix.js", array( 'media-editor' ), false, 1 );
    425425        $scripts->add( 'mce-view', "/wp-includes/js/mce-view$suffix.js", array( 'shortcode', 'media-models', 'media-audiovideo', 'wp-playlist' ), false, 1 );
    426426
     427        $scripts->add( 'twemoji', "/wp-includes/js/twemoji$suffix.js", array(), false, 1 );
     428        $scripts->add( 'emoji', "/wp-includes/js/emoji$suffix.js", array( 'twemoji' ), false, 1 );
     429        did_action( 'init' ) && $scripts->localize( 'emoji', 'EmojiSettings', array(
     430                /**
     431                 * Filter the URL where emoji images are hosted.
     432                 *
     433                 * @since 4.2.0
     434                 *
     435                 * @param string The emoji base URL.
     436                 */
     437                'base_url' => apply_filters( 'emoji_url', '//s0.wp.com/wp-content/mu-plugins/emoji/twemoji/72x72/' ),
     438                /**
     439                 * Filter the extension of the emoji files.
     440                 *
     441                 * @since 4.2.0
     442                 *
     443                 * @param string The emoji extension.
     444                 */
     445                'ext'      => apply_filters( 'emoji_ext', '.png' ),
     446        ) );
     447        $scripts->enqueue( 'emoji' );
     448
    427449        if ( is_admin() ) {
    428450                $scripts->add( 'admin-tags', "/wp-admin/js/tags$suffix.js", array('jquery', 'wp-ajax-response'), false, 1 );
    429451                did_action( 'init' ) && $scripts->localize( 'admin-tags', 'tagsl10n', array(
  • tests/phpunit/tests/dependencies/styles.php

     
    1212                        $GLOBALS['wp_styles'] = null;
    1313                $this->old_wp_styles = $GLOBALS['wp_styles'];
    1414                remove_action( 'wp_default_styles', 'wp_default_styles' );
     15                remove_action( 'wp_print_styles', 'print_emoji_styles' );
    1516                $GLOBALS['wp_styles'] = new WP_Styles();
    1617                $GLOBALS['wp_styles']->default_version = get_bloginfo( 'version' );
    1718        }
     
    1920        function tearDown() {
    2021                $GLOBALS['wp_styles'] = $this->old_wp_styles;
    2122                add_action( 'wp_default_styles', 'wp_default_styles' );
     23                add_action( 'wp_print_styles', 'print_emoji_styles' );
    2224                parent::tearDown();
    2325        }
    2426
  • tests/phpunit/tests/formatting/Smilies.php

     
    1616                return array (
    1717                        array (
    1818                                'Lorem ipsum dolor sit amet mauris ;-) Praesent gravida sodales. :lol: Vivamus nec diam in faucibus eu, bibendum varius nec, imperdiet purus est, at augue at lacus malesuada elit dapibus a, :eek: mauris. Cras mauris viverra elit. Nam laoreet viverra. Pellentesque tortor. Nam libero ante, porta urna ut turpis. Nullam wisi magna, :mrgreen: tincidunt nec, sagittis non, fringilla enim. Nam consectetuer nec, ullamcorper pede eu dui odio consequat vel, vehicula tortor quis pede turpis cursus quis, egestas ipsum ultricies ut, eleifend velit. Mauris vestibulum iaculis. Sed in nunc. Vivamus elit porttitor egestas. Mauris purus :?:',
    19                                 'Lorem ipsum dolor sit amet mauris <img src="' . $includes_path . 'icon_wink.gif" alt=";-)" class="wp-smiley" /> Praesent gravida sodales. <img src="' . $includes_path . 'icon_lol.gif" alt=":lol:" class="wp-smiley" /> Vivamus nec diam in faucibus eu, bibendum varius nec, imperdiet purus est, at augue at lacus malesuada elit dapibus a, <img src="' . $includes_path . 'icon_surprised.gif" alt=":eek:" class="wp-smiley" /> mauris. Cras mauris viverra elit. Nam laoreet viverra. Pellentesque tortor. Nam libero ante, porta urna ut turpis. Nullam wisi magna, <img src="' . $includes_path . 'icon_mrgreen.gif" alt=":mrgreen:" class="wp-smiley" /> tincidunt nec, sagittis non, fringilla enim. Nam consectetuer nec, ullamcorper pede eu dui odio consequat vel, vehicula tortor quis pede turpis cursus quis, egestas ipsum ultricies ut, eleifend velit. Mauris vestibulum iaculis. Sed in nunc. Vivamus elit porttitor egestas. Mauris purus <img src="' . $includes_path . 'icon_question.gif" alt=":?:" class="wp-smiley" />'
     19                                "Lorem ipsum dolor sit amet mauris \xf0\x9f\x98\x89 Praesent gravida sodales. \xf0\x9f\x98\x84 Vivamus nec diam in faucibus eu, bibendum varius nec, imperdiet purus est, at augue at lacus malesuada elit dapibus a, \xf0\x9f\x98\xaf mauris. Cras mauris viverra elit. Nam laoreet viverra. Pellentesque tortor. Nam libero ante, porta urna ut turpis. Nullam wisi magna, <img src=\"${includes_path}mrgreen.png\" alt=\":mrgreen:\" class=\"wp-smiley\" /> tincidunt nec, sagittis non, fringilla enim. Nam consectetuer nec, ullamcorper pede eu dui odio consequat vel, vehicula tortor quis pede turpis cursus quis, egestas ipsum ultricies ut, eleifend velit. Mauris vestibulum iaculis. Sed in nunc. Vivamus elit porttitor egestas. Mauris purus \xe2\x9d\x93"
    2020                        ),
    2121                        array (
    2222                                '<strong>Welcome to the jungle!</strong> We got fun n games! :) We got everything you want 8-) <em>Honey we know the names :)</em>',
    23                                 '<strong>Welcome to the jungle!</strong> We got fun n games! <img src="' . $includes_path . 'icon_smile.gif" alt=":)" class="wp-smiley" /> We got everything you want <img src="' . $includes_path . 'icon_cool.gif" alt="8-)" class="wp-smiley" /> <em>Honey we know the names <img src="' . $includes_path . 'icon_smile.gif" alt=":)" class="wp-smiley" /></em>'
     23                                "<strong>Welcome to the jungle!</strong> We got fun n games! <img src=\"${includes_path}simple-smile.png\" alt=\":)\" class=\"wp-smiley\" /> We got everything you want \xf0\x9f\x98\x8e <em>Honey we know the names <img src=\"${includes_path}simple-smile.png\" alt=\":)\" class=\"wp-smiley\" /></em>"
    2424                        ),
    2525                        array (
    2626                                "<strong;)>a little bit of this\na little bit:other: of that :D\n:D a little bit of good\nyeah with a little bit of bad8O",
    27                                 "<strong;)>a little bit of this\na little bit:other: of that <img src=\"{$includes_path}icon_biggrin.gif\" alt=\":D\" class=\"wp-smiley\" />\n<img src=\"{$includes_path}icon_biggrin.gif\" alt=\":D\" class=\"wp-smiley\" /> a little bit of good\nyeah with a little bit of bad8O"
     27                                "<strong;)>a little bit of this\na little bit:other: of that \xf0\x9f\x98\x84\n\xf0\x9f\x98\x84 a little bit of good\nyeah with a little bit of bad8O"
    2828                        ),
    2929                        array (
    3030                                '<strong style="here comes the sun :-D">and I say it\'s allright:D:D',
     
    147147                $includes_path = includes_url("images/smilies/");
    148148
    149149                $in_str = 'Do we ingore smilies ;-) in ' . $element . ' tags <' . $element . '>My Content Here :?: </' . $element . '>';
    150                 $exp_str = 'Do we ingore smilies <img src="' . $includes_path . 'icon_wink.gif" alt=";-)" class="wp-smiley" /> in ' . $element . ' tags <' . $element . '>My Content Here :?: </' . $element . '>';
     150                $exp_str = "Do we ingore smilies \xf0\x9f\x98\x89 in $element tags <$element>My Content Here :?: </$element>";
    151151
    152152                // standard smilies, use_smilies: ON
    153153                update_option( 'use_smilies', 1 );
     
    169169                return array (
    170170                        array (
    171171                                '8-O :-(',
    172                                 '<img src="' . $includes_path . 'icon_eek.gif" alt="8-O" class="wp-smiley" /> <img src="' . $includes_path . 'icon_sad.gif" alt=":-(" class="wp-smiley" />'
     172                                "\xf0\x9f\x98\xaf \xf0\x9f\x98\xa6"
    173173                        ),
    174174                        array (
    175175                                '8-) 8-O',
    176                                 '<img src="' . $includes_path . 'icon_cool.gif" alt="8-)" class="wp-smiley" /> <img src="' . $includes_path . 'icon_eek.gif" alt="8-O" class="wp-smiley" />'
     176                                "\xf0\x9f\x98\x8e \xf0\x9f\x98\xaf"
    177177                        ),
    178178                        array (
    179179                                '8-) 8O',
    180                                 '<img src="' . $includes_path . 'icon_cool.gif" alt="8-)" class="wp-smiley" /> <img src="' . $includes_path . 'icon_eek.gif" alt="8O" class="wp-smiley" />'
     180                                "\xf0\x9f\x98\x8e \xf0\x9f\x98\xaf"
    181181                        ),
    182182                        array (
    183183                                '8-) :-(',
    184                                 '<img src="' . $includes_path . 'icon_cool.gif" alt="8-)" class="wp-smiley" /> <img src="' . $includes_path . 'icon_sad.gif" alt=":-(" class="wp-smiley" />'
     184                                "\xf0\x9f\x98\x8e \xf0\x9f\x98\xa6"
    185185                        ),
    186186                        array (
    187187                                '8-) :twisted:',
    188                                 '<img src="' . $includes_path . 'icon_cool.gif" alt="8-)" class="wp-smiley" /> <img src="' . $includes_path . 'icon_twisted.gif" alt=":twisted:" class="wp-smiley" />'
     188                                "\xf0\x9f\x98\x8e \xf0\x9f\x98\x88"
    189189                        ),
    190190                        array (
    191191                                '8O :twisted: :( :? :(',
    192                                 '<img src="' . $includes_path . 'icon_eek.gif" alt="8O" class="wp-smiley" /> <img src="' . $includes_path . 'icon_twisted.gif" alt=":twisted:" class="wp-smiley" /> <img src="' . $includes_path . 'icon_sad.gif" alt=":(" class="wp-smiley" /> <img src="' . $includes_path . 'icon_confused.gif" alt=":?" class="wp-smiley" /> <img src="' . $includes_path . 'icon_sad.gif" alt=":(" class="wp-smiley" />'
     192                                "\xf0\x9f\x98\xaf \xf0\x9f\x98\x88 \xf0\x9f\x98\xa6 \xf0\x9f\x98\xaf \xf0\x9f\x98\xa6"
    193193                        ),
    194194                );
    195195        }
     
    228228                        ),
    229229                        array (
    230230                                '8O :) additional text here :)',
    231                                 '8O <img src="' . $includes_path . 'icon_smile.gif" alt=":)" class="wp-smiley" /> additional text here <img src="' . $includes_path . 'icon_smile.gif" alt=":)" class="wp-smiley" />'
     231                                '8O <img src="' . $includes_path . 'simple-smile.png" alt=":)" class="wp-smiley" /> additional text here <img src="' . $includes_path . 'simple-smile.png" alt=":)" class="wp-smiley" />'
    232232                        ),
    233233                        array (
    234234                                ':) :) :) :)',
    235                                 '<img src="' . $includes_path . 'icon_smile.gif" alt=":)" class="wp-smiley" /> <img src="' . $includes_path . 'icon_smile.gif" alt=":)" class="wp-smiley" /> <img src="' . $includes_path . 'icon_smile.gif" alt=":)" class="wp-smiley" /> <img src="' . $includes_path . 'icon_smile.gif" alt=":)" class="wp-smiley" />'
     235                                '<img src="' . $includes_path . 'simple-smile.png" alt=":)" class="wp-smiley" /> <img src="' . $includes_path . 'simple-smile.png" alt=":)" class="wp-smiley" /> <img src="' . $includes_path . 'simple-smile.png" alt=":)" class="wp-smiley" /> <img src="' . $includes_path . 'simple-smile.png" alt=":)" class="wp-smiley" />'
    236236                        ),
    237237                );
    238238        }
     
    257257                $orig_trans = $wpsmiliestrans; // save original tranlations array
    258258
    259259                $wpsmiliestrans = array (
    260                   ':)' => 'icon_smile.gif'
     260                  ':)' => 'simple-smile.png'
    261261                );
    262262
    263263                smilies_init();
     
    294294                $input[]  = 'My test :) smile';
    295295                $output[] = array('test <img ', 'alt=":)"', ' /> smile');
    296296
    297                 $input[]  = 'My test ;) smile';
    298                 $output[] = array('test <img ', 'alt=";)"', ' /> smile');
    299 
    300297                $input[]  = 'My test &nbsp;:)&nbsp;smile';
    301298                $output[] = array('test &nbsp;<img ', 'alt=":)"', ' />&nbsp;smile');
    302299
    303                 $input[]  = 'My test &nbsp;;)&nbsp;smile';
    304                 $output[] = array('test &nbsp;<img ', 'alt=";)"', ' />&nbsp;smile');
    305 
    306300                $input[]  = "My test {$nbsp}:){$nbsp}smile";
    307301                $output[] = array("test {$nbsp}<img ", 'alt=":)"', " />{$nbsp}smile");
    308302
    309                 $input[]  = "My test {$nbsp};){$nbsp}smile";
    310                 $output[] = array("test {$nbsp}<img ", 'alt=";)"', " />{$nbsp}smile");
    311 
    312303                foreach($input as $key => $in) {
    313304                        $result = convert_smilies( $in );
    314305                        foreach($output[$key] as $out) {