<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[31733] trunk: Add emoji support, with Twemoji fallback.</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta" style="font-size: 105%">
<dt style="float: left; width: 6em; font-weight: bold">Revision</dt> <dd><a style="font-weight: bold" href="https://core.trac.wordpress.org/changeset/31733">31733</a><script type="application/ld+json">{"@context":"http://schema.org","@type":"EmailMessage","description":"Review this Commit","action":{"@type":"ViewAction","url":"https://core.trac.wordpress.org/changeset/31733","name":"Review Commit"}}</script></dd>
<dt style="float: left; width: 6em; font-weight: bold">Author</dt> <dd>pento</dd>
<dt style="float: left; width: 6em; font-weight: bold">Date</dt> <dd>2015-03-11 22:48:16 +0000 (Wed, 11 Mar 2015)</dd>
</dl>

<pre style='padding-left: 1em; margin: 2em 0; border-left: 2px solid #ccc; line-height: 1.25; font-size: 105%; font-family: sans-serif'>Add emoji support, with Twemoji fallback.

Replace exisiting smilies with equivalent emoji, or with shiny new smiley images where no emoji existed.

Props batmoo, joen and mkaz for the original plugin upon which this is based.

Props pento, iseulde, kraftbj and peterwilsoncc for making the internet's dreams come true.

See <a href="https://core.trac.wordpress.org/ticket/31242">#31242</a></pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunksrcwpincludesclasswpeditorphp">trunk/src/wp-includes/class-wp-editor.php</a></li>
<li><a href="#trunksrcwpincludesdefaultfiltersphp">trunk/src/wp-includes/default-filters.php</a></li>
<li><a href="#trunksrcwpincludesfeedphp">trunk/src/wp-includes/feed.php</a></li>
<li><a href="#trunksrcwpincludesformattingphp">trunk/src/wp-includes/formatting.php</a></li>
<li><a href="#trunksrcwpincludesfunctionsphp">trunk/src/wp-includes/functions.php</a></li>
<li><a href="#trunksrcwpincludespostphp">trunk/src/wp-includes/post.php</a></li>
<li><a href="#trunksrcwpincludesscriptloaderphp">trunk/src/wp-includes/script-loader.php</a></li>
<li><a href="#trunktestsphpunittestsdependenciesstylesphp">trunk/tests/phpunit/tests/dependencies/styles.php</a></li>
<li><a href="#trunktestsphpunittestsformattingSmiliesphp">trunk/tests/phpunit/tests/formatting/Smilies.php</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunksrcwpincludesjsemojijs">trunk/src/wp-includes/js/emoji.js</a></li>
<li>trunk/src/wp-includes/js/tinymce/plugins/wpemoji/</li>
<li>trunk/src/wp-includes/js/tinymce/plugins/wpemoji/css/</li>
<li><a href="#trunksrcwpincludesjstinymcepluginswpemojicsseditorcss">trunk/src/wp-includes/js/tinymce/plugins/wpemoji/css/editor.css</a></li>
<li>trunk/src/wp-includes/js/tinymce/plugins/wpemoji/css/rtl/</li>
<li><a href="#trunksrcwpincludesjstinymcepluginswpemojicssrtleditorrtlcss">trunk/src/wp-includes/js/tinymce/plugins/wpemoji/css/rtl/editor-rtl.css</a></li>
<li><a href="#trunksrcwpincludesjstinymcepluginswpemojipluginjs">trunk/src/wp-includes/js/tinymce/plugins/wpemoji/plugin.js</a></li>
<li><a href="#trunksrcwpincludesjstwemojijs">trunk/src/wp-includes/js/twemoji.js</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunksrcwpincludesclasswpeditorphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/class-wp-editor.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/class-wp-editor.php 2015-03-11 22:40:56 UTC (rev 31732)
+++ trunk/src/wp-includes/class-wp-editor.php   2015-03-11 22:48:16 UTC (rev 31733)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -360,6 +360,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                                                'wordpress',
</span><span class="cx" style="display: block; padding: 0 10px">                                                'wpautoresize',
</span><span class="cx" style="display: block; padding: 0 10px">                                                'wpeditimage',
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                                'wpemoji',
</ins><span class="cx" style="display: block; padding: 0 10px">                                                 'wpgallery',
</span><span class="cx" style="display: block; padding: 0 10px">                                                'wplink',
</span><span class="cx" style="display: block; padding: 0 10px">                                                'wpdialogs',
</span></span></pre></div>
<a id="trunksrcwpincludesdefaultfiltersphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/default-filters.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/default-filters.php 2015-03-11 22:40:56 UTC (rev 31732)
+++ trunk/src/wp-includes/default-filters.php   2015-03-11 22:48:16 UTC (rev 31733)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -160,15 +160,20 @@
</span><span class="cx" style="display: block; padding: 0 10px"> add_filter( 'the_title_rss',      'ent2ncr',      8 );
</span><span class="cx" style="display: block; padding: 0 10px"> add_filter( 'the_title_rss',      'esc_html'        );
</span><span class="cx" style="display: block; padding: 0 10px"> add_filter( 'the_content_rss',    'ent2ncr',      8 );
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+add_filter( 'the_content_feed',   'feed_emoji'      );
</ins><span class="cx" style="display: block; padding: 0 10px"> add_filter( 'the_excerpt_rss',    'convert_chars'   );
</span><span class="cx" style="display: block; padding: 0 10px"> add_filter( 'the_excerpt_rss',    'ent2ncr',      8 );
</span><span class="cx" style="display: block; padding: 0 10px"> add_filter( 'comment_author_rss', 'ent2ncr',      8 );
</span><span class="cx" style="display: block; padding: 0 10px"> add_filter( 'comment_text_rss',   'ent2ncr',      8 );
</span><span class="cx" style="display: block; padding: 0 10px"> add_filter( 'comment_text_rss',   'esc_html'        );
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+add_filter( 'comment_text_rss',   'feed_emoji'      );
</ins><span class="cx" style="display: block; padding: 0 10px"> add_filter( 'bloginfo_rss',       'ent2ncr',      8 );
</span><span class="cx" style="display: block; padding: 0 10px"> add_filter( 'the_author',         'ent2ncr',      8 );
</span><span class="cx" style="display: block; padding: 0 10px"> add_filter( 'the_guid',           'esc_url'         );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+// Email filters
+add_filter( 'wp_mail', 'mail_emoji' );
+
</ins><span class="cx" style="display: block; padding: 0 10px"> // Misc filters
</span><span class="cx" style="display: block; padding: 0 10px"> add_filter( 'option_ping_sites',        'privacy_ping_filter'                 );
</span><span class="cx" style="display: block; padding: 0 10px"> add_filter( 'option_blog_charset',      '_wp_specialchars'                    ); // IMPORTANT: This must not be wp_specialchars() or esc_html() or it'll cause an infinite loop
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -218,6 +223,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> add_action( 'wp_print_footer_scripts', '_wp_footer_scripts'                 );
</span><span class="cx" style="display: block; padding: 0 10px"> add_action( 'init',                'check_theme_switched',            99    );
</span><span class="cx" style="display: block; padding: 0 10px"> add_action( 'after_switch_theme',  '_wp_sidebars_changed'                   );
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+add_action( 'wp_print_styles',     'print_emoji_styles'                     );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px"> if ( isset( $_GET['replytocom'] ) )
</span><span class="cx" style="display: block; padding: 0 10px">     add_action( 'wp_head', 'wp_no_robots' );
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -248,6 +254,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> add_action( 'admin_print_scripts',        'print_head_scripts',                      20    );
</span><span class="cx" style="display: block; padding: 0 10px"> add_action( 'admin_print_footer_scripts', '_wp_footer_scripts'                             );
</span><span class="cx" style="display: block; padding: 0 10px"> add_action( 'admin_print_styles',         'print_admin_styles',                      20    );
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+add_action( 'admin_print_styles',         'print_emoji_styles'                             );
</ins><span class="cx" style="display: block; padding: 0 10px"> add_action( 'init',                       'smilies_init',                             5    );
</span><span class="cx" style="display: block; padding: 0 10px"> add_action( 'plugins_loaded',             'wp_maybe_load_widgets',                    0    );
</span><span class="cx" style="display: block; padding: 0 10px"> add_action( 'plugins_loaded',             'wp_maybe_load_embeds',                     0    );
</span></span></pre></div>
<a id="trunksrcwpincludesfeedphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/feed.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/feed.php    2015-03-11 22:40:56 UTC (rev 31732)
+++ trunk/src/wp-includes/feed.php      2015-03-11 22:48:16 UTC (rev 31733)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -649,3 +649,14 @@
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        return $feed;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
+/**
+ * Convert emoji characters in a feed into static images.
+ *
+ * @param string $content The content to convert.
+ *
+ * @return The converted content.
+ */
+function feed_emoji( $content ) {
+       return wp_staticize_emoji( $content, true );
+}
</ins></span></pre></div>
<a id="trunksrcwpincludesformattingphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/formatting.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/formatting.php      2015-03-11 22:40:56 UTC (rev 31732)
+++ trunk/src/wp-includes/formatting.php        2015-03-11 22:48:16 UTC (rev 31733)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2038,6 +2038,15 @@
</span><span class="cx" style="display: block; padding: 0 10px">        $smiley = trim( reset( $matches ) );
</span><span class="cx" style="display: block; padding: 0 10px">        $img = $wpsmiliestrans[ $smiley ];
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+        $matches = array();
+       $ext = preg_match( '/\.([^.]+)$/', $img, $matches ) ? strtolower( $matches[1] ) : false;
+       $image_exts = array( 'jpg', 'jpeg', 'jpe', 'gif', 'png' );
+
+       // Don't convert smilies that aren't images - they're probably emoji.
+       if ( ! in_array( $ext, $image_exts ) ) {
+               return $img;
+       }
+
</ins><span class="cx" style="display: block; padding: 0 10px">         /**
</span><span class="cx" style="display: block; padding: 0 10px">         * Filter the Smiley image URL before it's used in the image element.
</span><span class="cx" style="display: block; padding: 0 10px">         *
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -4015,3 +4024,155 @@
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        return $spaces;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
+/**
+ * Print the important emoji-related styles.
+ *
+ * @since 4.2.0
+ */
+function print_emoji_styles() {
+?>
+<style type="text/css">
+img.wp-smiley,
+img.emoji {
+       border: none !important;
+       box-shadow: none !important;
+       height: 1em !important;
+       width: 1em !important;
+       margin: 0 .05em 0 .1em !important;
+       vertical-align: -0.1em !important;
+       background: none !important;
+       padding: 0 !important;
+}
+</style>
+<?php
+}
+
+/**
+ * Convert any 4 byte emoji in a string to their equivalent HTML entity.
+ * Currently, only Unicode 7 emoji are supported. Unicode 8 emoji will be added
+ * when the spec in finalised, along with the new skin-tone modifiers.
+ *
+ * This allows us to store emoji in a DB using the utf8 character set.
+ *
+ * @since 4.2.0
+ *
+ * @param string $content The content to encode.
+ * @return string The encoded content.
+ */
+function wp_encode_emoji( $content ) {
+       if ( function_exists( 'mb_convert_encoding' ) ) {
+               $regex = '/(
+                    \x23\xE2\x83\xA3               # Digits
+                    [\x30-\x39]\xE2\x83\xA3
+                  | \xF0\x9F[\x85-\x88][\xA6-\xBF] # Enclosed characters
+                  | \xF0\x9F[\x8C-\x97][\x80-\xBF] # Misc
+                  | \xF0\x9F\x98[\x80-\xBF]        # Smilies
+                  | \xF0\x9F\x99[\x80-\x8F]
+                  | \xF0\x9F\x9A[\x80-\xBF]        # Transport and map symbols
+                  | \xF0\x9F\x99[\x80-\x85]
+               )/x';
+
+               $matches = array();
+               if ( preg_match_all( $regex, $content, $matches ) ) {
+                       if ( ! empty( $matches[1] ) ) {
+                               foreach( $matches[1] as $emoji ) {
+                                       /*
+                                        * UTF-32's hex encoding is the same as HTML's hex encoding.
+                                        * So, by converting the emoji from UTF-8 to UTF-32, we magically
+                                        * get the correct hex encoding.
+                                        */
+                                       $unpacked = unpack( 'H*', mb_convert_encoding( $emoji, 'UTF-32', 'UTF-8' ) );
+                                       if ( isset( $unpacked[1] ) ) {
+                                               $entity = '&#x' . trim( $unpacked[1], '0' ) . ';';
+                                               $content = str_replace( $emoji, $entity, $content );
+                                       }
+                               }
+                       }
+               }
+       }
+
+       return $content;
+}
+
+/**
+ * Convert emoji to a static <img> link.
+ *
+ * @since 4.2.0
+ *
+ * @param string $content The content to encode.
+ * @return string The encoded content.
+ */
+function wp_staticize_emoji( $content ) {
+       $content = wp_encode_emoji( $content );
+
+       if ( ! class_exists( 'DOMDocument' ) ) {
+               return $content;
+       }
+
+       /** This filter is documented in wp-includes/script-loader.php */
+       $cdn_url = apply_filters( 'emoji_url', '//s0.wp.com/wp-content/mu-plugins/emoji/twemoji/72x72/' );
+       /** This filter is documented in wp-includes/script-loader.php */
+       $ext = apply_filters( 'emoji_ext', '.png' );
+
+       $html = '<!DOCTYPE html><html><head></head><body>' . $content . '</body></html>';
+
+       $document = new DOMDocument;
+       if ( ! $document->loadHTML( $html ) ) {
+               return $content;
+       }
+
+       $xpath = new DOMXPath( $document );
+       $textnodes = $xpath->query( '//text()' );
+
+       foreach( $textnodes as $node ) {
+               $originalText = $text = wp_encode_emoji( $node->nodeValue );
+
+               $matches = array();
+               if ( preg_match_all( '/(&#x1f1(e[6-9a-f]|f[0-9a-f]);){2}/', $text, $matches ) ) {
+                       if ( ! empty( $matches[0] ) ) {
+                               foreach ( $matches[0] as $flag ) {
+                                       $chars = str_replace( array( '&#x', ';'), '', $flag );
+
+                                       list( $char1, $char2 ) = str_split( $chars, 5 );
+                                       $entity = '<img src="https:' . $cdn_url . $char1 . '-' . $char2 . $ext . '" class="wp-smiley" style="height: 1em;" />';
+
+                                       $text = str_replace( $flag, $entity, $text );
+                               }
+                       }
+               }
+
+               // Loosely match the Emoji Unicode range.
+               $regex = '/(&#x[2-3][0-9a-f]{3};|&#x1f[1-6][0-9a-f]{2};)/';
+
+               $matches = array();
+               if ( preg_match_all( $regex, $text, $matches ) ) {
+                       if ( ! empty( $matches[1] ) ) {
+                               foreach ( $matches[1] as $emoji ) {
+                                       $char = str_replace( array( '&#x', ';'), '', $emoji );
+                                       $entity = '<img src="https:' . $cdn_url . $char . $ext . '" class="wp-smiley" style="height: 1em;" />';
+
+                                       $text = str_replace( $emoji, $entity, $text );
+                               }
+                       }
+               }
+
+               if ( $originalText !== $text ) {
+                       $content = str_replace( $originalText, $text, $content );
+               }
+       }
+
+       return $content;
+}
+
+/**
+ * Convert emoji in emails into static images.
+ *
+ * @param array $mail The email data array.
+ *
+ * @return array The email data array, with emoji in the message staticized.
+ */
+function mail_emoji( $mail ) {
+       $mail['message'] = wp_staticize_emoji( $mail['message'], true );
+       return $mail;
+}
</ins></span></pre></div>
<a id="trunksrcwpincludesfunctionsphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/functions.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/functions.php       2015-03-11 22:40:56 UTC (rev 31732)
+++ trunk/src/wp-includes/functions.php 2015-03-11 22:48:16 UTC (rev 31733)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2945,51 +2945,51 @@
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        if ( !isset( $wpsmiliestrans ) ) {
</span><span class="cx" style="display: block; padding: 0 10px">                $wpsmiliestrans = array(
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                ':mrgreen:' => 'icon_mrgreen.gif',
-               ':neutral:' => 'icon_neutral.gif',
-               ':twisted:' => 'icon_twisted.gif',
-                 ':arrow:' => 'icon_arrow.gif',
-                 ':shock:' => 'icon_eek.gif',
-                 ':smile:' => 'icon_smile.gif',
-                   ':???:' => 'icon_confused.gif',
-                  ':cool:' => 'icon_cool.gif',
-                  ':evil:' => 'icon_evil.gif',
-                  ':grin:' => 'icon_biggrin.gif',
-                  ':idea:' => 'icon_idea.gif',
-                  ':oops:' => 'icon_redface.gif',
-                  ':razz:' => 'icon_razz.gif',
-                  ':roll:' => 'icon_rolleyes.gif',
-                  ':wink:' => 'icon_wink.gif',
-                   ':cry:' => 'icon_cry.gif',
-                   ':eek:' => 'icon_surprised.gif',
-                   ':lol:' => 'icon_lol.gif',
-                   ':mad:' => 'icon_mad.gif',
-                   ':sad:' => 'icon_sad.gif',
-                     '8-)' => 'icon_cool.gif',
-                     '8-O' => 'icon_eek.gif',
-                     ':-(' => 'icon_sad.gif',
-                     ':-)' => 'icon_smile.gif',
-                     ':-?' => 'icon_confused.gif',
-                     ':-D' => 'icon_biggrin.gif',
-                     ':-P' => 'icon_razz.gif',
-                     ':-o' => 'icon_surprised.gif',
-                     ':-x' => 'icon_mad.gif',
-                     ':-|' => 'icon_neutral.gif',
-                     ';-)' => 'icon_wink.gif',
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         ':mrgreen:' => 'mrgreen.png',
+               ':neutral:' => "\xf0\x9f\x98\x90",
+               ':twisted:' => "\xf0\x9f\x98\x88",
+                 ':arrow:' => "\xe2\x9e\xa1",
+                 ':shock:' => "\xf0\x9f\x98\xaf",
+                 ':smile:' => 'simple-smile.png',
+                   ':???:' => "\xf0\x9f\x98\xaf",
+                  ':cool:' => "\xf0\x9f\x98\x8e",
+                  ':evil:' => "\xf0\x9f\x91\xbf",
+                  ':grin:' => "\xf0\x9f\x98\x84",
+                  ':idea:' => "\xf0\x9f\x92\xa1",
+                  ':oops:' => "\xf0\x9f\x98\xb3",
+                  ':razz:' => "\xf0\x9f\x98\x9b",
+                  ':roll:' => 'rolleyes.png',
+                  ':wink:' => "\xf0\x9f\x98\x89",
+                   ':cry:' => "\xf0\x9f\x98\xa5",
+                   ':eek:' => "\xf0\x9f\x98\xaf",
+                   ':lol:' => "\xf0\x9f\x98\x84",
+                   ':mad:' => "\xf0\x9f\x98\xa1",
+                   ':sad:' => "\xf0\x9f\x98\xa6",
+                     '8-)' => "\xf0\x9f\x98\x8e",
+                     '8-O' => "\xf0\x9f\x98\xaf",
+                     ':-(' => "\xf0\x9f\x98\xa6",
+                     ':-)' => 'simple-smile.png',
+                     ':-?' => "\xf0\x9f\x98\xaf",
+                     ':-D' => "\xf0\x9f\x98\x84",
+                     ':-P' => "\xf0\x9f\x98\x9b",
+                     ':-o' => "\xf0\x9f\x98\xaf",
+                     ':-x' => "\xf0\x9f\x98\xa1",
+                     ':-|' => "\xf0\x9f\x98\x90",
+                     ';-)' => "\xf0\x9f\x98\x89",
</ins><span class="cx" style="display: block; padding: 0 10px">                 // This one transformation breaks regular text with frequency.
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                //     '8)' => 'icon_cool.gif',
-                      '8O' => 'icon_eek.gif',
-                      ':(' => 'icon_sad.gif',
-                      ':)' => 'icon_smile.gif',
-                      ':?' => 'icon_confused.gif',
-                      ':D' => 'icon_biggrin.gif',
-                      ':P' => 'icon_razz.gif',
-                      ':o' => 'icon_surprised.gif',
-                      ':x' => 'icon_mad.gif',
-                      ':|' => 'icon_neutral.gif',
-                      ';)' => 'icon_wink.gif',
-                     ':!:' => 'icon_exclaim.gif',
-                     ':?:' => 'icon_question.gif',
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         //     '8)' => "\xf0\x9f\x98\x8e",
+                      '8O' => "\xf0\x9f\x98\xaf",
+                      ':(' => "\xf0\x9f\x98\xa6",
+                      ':)' => 'simple-smile.png',
+                      ':?' => "\xf0\x9f\x98\xaf",
+                      ':D' => "\xf0\x9f\x98\x84",
+                      ':P' => "\xf0\x9f\x98\x9b",
+                      ':o' => "\xf0\x9f\x98\xaf",
+                      ':x' => "\xf0\x9f\x98\xa1",
+                      ':|' => "\xf0\x9f\x98\x90",
+                      ';)' => "\xf0\x9f\x98\x89",
+                     ':!:' => "\xe2\x9d\x97",
+                     ':?:' => "\xe2\x9d\x93",
</ins><span class="cx" style="display: block; padding: 0 10px">                 );
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span></span></pre></div>
<a id="trunksrcwpincludesjsemojijs"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: trunk/src/wp-includes/js/emoji.js</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/js/emoji.js                         (rev 0)
+++ trunk/src/wp-includes/js/emoji.js   2015-03-11 22:48:16 UTC (rev 31733)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,201 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+/* global EmojiSettings, twemoji */
+var WPEmoji;
+
+(function() {
+       WPEmoji = {
+               /**
+                * The CDN URL for where emoji files are hosted.
+                *
+                * @since 4.2.0
+                *
+                * @var string
+                */
+               base_url: '//s0.wp.com/wp-content/mu-plugins/emoji/twemoji/72x72',
+
+               /**
+                * The extension of the hosted emoji files.
+                *
+                * @since 4.2.0
+                *
+                * @var string
+                */
+               ext: '.png',
+
+               /**
+                * Flag to determine if we should parse all emoji characters into Twemoji images.
+                *
+                * @since 4.2.0
+                *
+                * @var bool
+                */
+               parseAllEmoji: false,
+
+               /**
+                * Flag to determine if we should consider parsing emoji characters into Twemoji images.
+                *
+                * @since 4.2.0
+                *
+                * @var bool
+                */
+               parseEmoji: false,
+
+               /**
+                * Flag to determine if we should parse flag characters into Twemoji images.
+                *
+                * @since 4.2.0
+                *
+                * @var bool
+                */
+               parseFlags: false,
+
+               /**
+                * Initialize our emoji support, and set up listeners.
+                *
+                * @since 4.2.0
+                */
+               init: function() {
+                       if ( typeof EmojiSettings !== 'undefined' ) {
+                               this.base_url = EmojiSettings.base_url || this.base_url;
+                               this.ext = EmojiSettings.ext || this.ext;
+                       }
+
+                       WPEmoji.parseAllEmoji = ! WPEmoji.browserSupportsEmoji();
+                       WPEmoji.parseFlags = ! WPEmoji.browserSupportsFlagEmoji();
+                       WPEmoji.parseEmoji = WPEmoji.parseAllEmoji || WPEmoji.parseFlags;
+
+                       if ( ! WPEmoji.parseEmoji ) {
+                               return;
+                       }
+               },
+
+               /**
+                * Runs when the document load event is fired, so we can do our first parse of the page.
+                *
+                * @since 4.2.0
+                */
+               load: function() {
+                       WPEmoji.parse( document.body );
+               },
+
+               /**
+                * Detect if the browser supports rendering emoji.
+                *
+                * @since 4.2.0
+                *
+                * @return {bool} True if the browser can render emoji, false if it cannot.
+                */
+               browserSupportsEmoji: function() {
+                       var context, smile;
+
+                       if ( ! document.createElement( 'canvas' ).getContext ) {
+                               return;
+                       }
+
+                       context = document.createElement( 'canvas' ).getContext( '2d' );
+                       if ( typeof context.fillText != 'function' ) {
+                               return;
+                       }
+
+                       smile = String.fromCharCode( 55357 ) + String.fromCharCode( 56835 );
+
+                       /*
+                        * Chrome OS X added native emoji rendering in M41. Unfortunately,
+                        * it doesn't work when the font is bolder than 500 weight. So, we
+                        * check for bold rendering support to avoid invisible emoji in Chrome.
+                        */
+                       context.textBaseline = 'top';
+                       context.font = '600 32px Arial';
+                       context.fillText( smile, 0, 0 );
+
+                       return context.getImageData( 16, 16, 1, 1 ).data[0] !== 0;
+               },
+
+               /**
+                * Detect if the browser supports rendering flag emoji. Flag emoji are a single glyph
+                * made of two characters, so some browsers (notably, Firefox OS X) don't support them.
+                *
+                * @since 4.2.0
+                * @return {bool} True if the browser renders flag characters as a flag glyph, false if it does not.
+                */
+               browserSupportsFlagEmoji: function() {
+                       var context, flag, canvas;
+
+                       canvas = document.createElement( 'canvas' );
+
+                       if ( ! canvas.getContext ) {
+                               return;
+                       }
+
+                       context = canvas.getContext( '2d' );
+
+                       if ( typeof context.fillText != 'function' ) {
+                               return;
+                       }
+
+                       flag =  String.fromCharCode(55356) + String.fromCharCode(56812); // [G]
+                       flag += String.fromCharCode(55356) + String.fromCharCode(56807); // [B]
+
+                       context.textBaseline = 'top';
+                       context.font = '32px Arial';
+                       context.fillText( flag, 0, 0 );
+
+                       /*
+                        * This works because the image will be one of three things:
+                        * - Two empty squares, if the browser doen't render emoji
+                        * - Two squares with 'G' and 'B' in them, if the browser doen't render flag emoji
+                        * - The British flag
+                        *
+                        * The first two will encode to small images (1-2KB data URLs), the third will encode
+                        * to a larger image (4-5KB data URL).
+                        */
+                       return canvas.toDataURL().length > 3000;
+
+               },
+
+               /**
+                * Given a DOM node, parse any emoji characters into Twemoji images.
+                *
+                * @since 4.2.0
+                *
+                * @param {Element} element The DOM node to parse.
+                */
+               parse: function( element ) {
+                       if ( ! WPEmoji.parseEmoji ) {
+                               return;
+                       }
+
+                       return twemoji.parse( element, {
+                               base: this.base_url,
+                               ext: this.ext,
+                               callback: function( icon, options ) {
+                                       // Ignore some standard characters that TinyMCE recommends in its character map.
+                                       switch ( icon ) {
+                                               case 'a9':
+                                               case 'ae':
+                                               case '2122':
+                                               case '2194':
+                                               case '2660':
+                                               case '2663':
+                                               case '2665':
+                                               case '2666':
+                                                       return false;
+                                       }
+
+                                       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])$/ ) ) {
+                                               return false;
+                                       }
+
+                                       return ''.concat( options.base, '/', icon, options.ext );
+                               }
+                       } );
+               }
+       };
+
+       if ( window.addEventListener ) {
+               window.addEventListener( 'load', WPEmoji.load, false );
+       } else if ( window.attachEvent ) {
+               window.attachEvent( 'onload', WPEmoji.load );
+       }
+
+       WPEmoji.init();
+})();
</ins><span class="cx" style="display: block; padding: 0 10px">Property changes on: trunk/src/wp-includes/js/emoji.js
</span><span class="cx" style="display: block; padding: 0 10px">___________________________________________________________________
</span></span></pre></div>
<a id="svnexecutable"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: svn:executable</h4></div>
<ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+*
</ins><span class="cx" style="display: block; padding: 0 10px">\ No newline at end of property
</span><a id="trunksrcwpincludesjstinymcepluginswpemojicsseditorcss"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: trunk/src/wp-includes/js/tinymce/plugins/wpemoji/css/editor.css</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/js/tinymce/plugins/wpemoji/css/editor.css                           (rev 0)
+++ trunk/src/wp-includes/js/tinymce/plugins/wpemoji/css/editor.css     2015-03-11 22:48:16 UTC (rev 31733)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,15 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+.emoji-wrapper,
+.emoji-spacer {
+       -moz-user-select: none;
+       -webkit-user-select: none;
+       -ms-user-select: none;
+       user-select: none;
+}
+img.emoji {
+       height: 1em;
+       width: 1em;
+       margin: 0 .05em 0 .1em;
+       vertical-align: -0.1em;
+       border: none;
+       padding: 0;
+}
</ins><span class="cx" style="display: block; padding: 0 10px">Property changes on: trunk/src/wp-includes/js/tinymce/plugins/wpemoji/css/editor.css
</span><span class="cx" style="display: block; padding: 0 10px">___________________________________________________________________
</span></span></pre></div>
<a id="svnexecutable"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: svn:executable</h4></div>
<ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+*
</ins><span class="cx" style="display: block; padding: 0 10px">\ No newline at end of property
</span><a id="trunksrcwpincludesjstinymcepluginswpemojicssrtleditorrtlcss"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: trunk/src/wp-includes/js/tinymce/plugins/wpemoji/css/rtl/editor-rtl.css</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/js/tinymce/plugins/wpemoji/css/rtl/editor-rtl.css                           (rev 0)
+++ trunk/src/wp-includes/js/tinymce/plugins/wpemoji/css/rtl/editor-rtl.css     2015-03-11 22:48:16 UTC (rev 31733)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,17 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+/* This file was automatically generated on Nov 19 2014 05:08:11 */
+
+.emoji-wrapper,
+.emoji-spacer {
+       -moz-user-select: none;
+       -webkit-user-select: none;
+       -ms-user-select: none;
+       user-select: none;
+}
+img.emoji {
+       height: 1em;
+       width: 1em;
+       margin: 0 .1em 0 .05em;
+       vertical-align: -0.1em;
+       border: none;
+       padding: 0;
+}
</ins><span class="cx" style="display: block; padding: 0 10px">Property changes on: trunk/src/wp-includes/js/tinymce/plugins/wpemoji/css/rtl/editor-rtl.css
</span><span class="cx" style="display: block; padding: 0 10px">___________________________________________________________________
</span></span></pre></div>
<a id="svnexecutable"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: svn:executable</h4></div>
<ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+*
</ins><span class="cx" style="display: block; padding: 0 10px">\ No newline at end of property
</span><a id="trunksrcwpincludesjstinymcepluginswpemojipluginjs"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: trunk/src/wp-includes/js/tinymce/plugins/wpemoji/plugin.js</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/js/tinymce/plugins/wpemoji/plugin.js                                (rev 0)
+++ trunk/src/wp-includes/js/tinymce/plugins/wpemoji/plugin.js  2015-03-11 22:48:16 UTC (rev 31733)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,64 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+( function( tinymce, WPEmoji ) {
+       tinymce.PluginManager.add( 'wpemoji', function( editor, url ) {
+               var typing;
+
+               if ( ! WPEmoji.parseEmoji ) {
+                       return;
+               }
+
+               // Loads stylesheet for custom styles within the editor
+               editor.on( 'init', function() {
+                       var cssId = editor.dom.uniqueId();
+                       var linkElm = editor.dom.create( 'link', {
+                               id:   cssId,
+                               rel:  'stylesheet',
+                               href: url + '/css/editor.css'
+                       });
+                       editor.getDoc().getElementsByTagName( 'head' )[0].appendChild( linkElm );
+               } );
+
+               editor.on( 'keydown keyup', function( event ) {
+                       typing = event.type === 'keydown';
+               } );
+
+               editor.on( 'input setcontent', function() {
+                       var selection, node, bookmark, imgs;
+
+                       if ( typing ) {
+                               return;
+                       }
+
+                       selection = editor.selection;
+                       node = selection.getNode();
+                       bookmark = selection.getBookmark();
+
+                       WPEmoji.parse( node );
+
+                       imgs = editor.dom.select( 'img.emoji', node );
+
+                       tinymce.each( imgs, function( elem ) {
+                               if ( ! elem.getAttribute( 'data-wp-emoji' ) ) {
+                                       elem.setAttribute( 'data-mce-resize', 'false' );
+                                       elem.setAttribute( 'data-mce-placeholder', '1' );
+                                       elem.setAttribute( 'data-wp-emoji', elem.alt );
+                               }
+                       } );
+
+                       selection.moveToBookmark( bookmark );
+               } );
+
+               editor.on( 'postprocess', function( event ) {
+                       if ( event.content ) {
+                               event.content = event.content.replace( /<img[^>]+data-wp-emoji="([^"]+)"[^>]*>/g, function( match, emoji ) {
+                                       return emoji;
+                               } );
+                       }
+               } );
+
+               editor.on( 'resolvename', function( event ) {
+                       if ( event.target.nodeName === 'IMG' && editor.dom.getAttrib( event.target, 'data-wp-emoji' ) ) {
+                               event.preventDefault();
+                       }
+               } );
+       } );
+} )( window.tinymce, window.WPEmoji );
</ins><span class="cx" style="display: block; padding: 0 10px">Property changes on: trunk/src/wp-includes/js/tinymce/plugins/wpemoji/plugin.js
</span><span class="cx" style="display: block; padding: 0 10px">___________________________________________________________________
</span></span></pre></div>
<a id="svnexecutable"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: svn:executable</h4></div>
<ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+*
</ins><span class="cx" style="display: block; padding: 0 10px">\ No newline at end of property
</span><a id="trunksrcwpincludesjstwemojijs"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: trunk/src/wp-includes/js/twemoji.js</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/js/twemoji.js                               (rev 0)
+++ trunk/src/wp-includes/js/twemoji.js 2015-03-11 22:48:16 UTC (rev 31733)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,519 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+/*jslint indent: 2, browser: true, bitwise: true, plusplus: true */
+var twemoji;
+twemoji = (function (
+  /*! Copyright Twitter Inc. and other contributors. Licensed under MIT *//*
+    https://github.com/twitter/twemoji/blob/gh-pages/LICENSE
+  */
+
+  // WARNING:   this file is generated automatically via
+  //            `node twemoji-generator.js`
+  //            please update its `createTwemoji` function
+  //            at the bottom of the same file instead.
+
+) {
+  'use strict';
+
+  /*jshint maxparams:4 */
+
+  var
+    // the exported module object
+    twemoji = {
+
+
+    /////////////////////////
+    //      properties     //
+    /////////////////////////
+
+      // default assets url, by default will be Twitter Inc. CDN
+      base: (location.protocol === 'https:' ? 'https:' : 'http:') +
+            '//twemoji.maxcdn.com/',
+
+      // default assets file extensions, by default '.png'
+      ext: '.png',
+
+      // default assets/folder size, by default "36x36"
+      // available via Twitter CDN: 16, 36, 72
+      size: '36x36',
+
+      // default class name, by default 'emoji'
+      className: 'emoji',
+
+      // basic utilities / helpers to convert code points
+      // to JavaScript surrogates and vice versa
+      convert: {
+
+        /**
+         * Given an HEX codepoint, returns UTF16 surrogate pairs.
+         *
+         * @param   string  generic codepoint, i.e. '1F4A9'
+         * @return  string  codepoint transformed into utf16 surrogates pair,
+         *          i.e. \uD83D\uDCA9
+         *
+         * @example
+         *  twemoji.convert.fromCodePoint('1f1e8');
+         *  // "\ud83c\udde8"
+         *
+         *  '1f1e8-1f1f3'.split('-').map(twemoji.convert.fromCodePoint).join('')
+         *  // "\ud83c\udde8\ud83c\uddf3"
+         */
+        fromCodePoint: fromCodePoint,
+
+        /**
+         * Given UTF16 surrogate pairs, returns the equivalent HEX codepoint.
+         *
+         * @param   string  generic utf16 surrogates pair, i.e. \uD83D\uDCA9
+         * @param   string  optional separator for double code points, default='-'
+         * @return  string  utf16 transformed into codepoint, i.e. '1F4A9'
+         *
+         * @example
+         *  twemoji.convert.toCodePoint('\ud83c\udde8\ud83c\uddf3');
+         *  // "1f1e8-1f1f3"
+         *
+         *  twemoji.convert.toCodePoint('\ud83c\udde8\ud83c\uddf3', '~');
+         *  // "1f1e8~1f1f3"
+         */
+        toCodePoint: toCodePoint
+      },
+
+
+    /////////////////////////
+    //       methods       //
+    /////////////////////////
+
+      /**
+       * User first: used to remove missing images
+       * preserving the original text intent when
+       * a fallback for network problems is desired.
+       * Automatically added to Image nodes via DOM
+       * It could be recycled for string operations via:
+       *  $('img.emoji').on('error', twemoji.onerror)
+       */
+      onerror: function onerror() {
+        if (this.parentNode) {
+          this.parentNode.replaceChild(createText(this.alt), this);
+        }
+      },
+
+      /**
+       * Main method/logic to generate either <img> tags or HTMLImage nodes.
+       *  "emojify" a generic text or DOM Element.
+       *
+       * @overloads
+       *
+       * String replacement for `innerHTML` or server side operations
+       *  twemoji.parse(string);
+       *  twemoji.parse(string, Function);
+       *  twemoji.parse(string, Object);
+       *
+       * HTMLElement tree parsing for safer operations over existing DOM
+       *  twemoji.parse(HTMLElement);
+       *  twemoji.parse(HTMLElement, Function);
+       *  twemoji.parse(HTMLElement, Object);
+       *
+       * @param   string|HTMLElement  the source to parse and enrich with emoji.
+       *
+       *          string              replace emoji matches with <img> tags.
+       *                              Mainly used to inject emoji via `innerHTML`
+       *                              It does **not** parse the string or validate it,
+       *                              it simply replaces found emoji with a tag.
+       *                              NOTE: be sure this won't affect security.
+       *
+       *          HTMLElement         walk through the DOM tree and find emoji
+       *                              that are inside **text node only** (nodeType === 3)
+       *                              Mainly used to put emoji in already generated DOM
+       *                              without compromising surrounding nodes and
+       *                              **avoiding** the usage of `innerHTML`.
+       *                              NOTE: Using DOM elements instead of strings should
+       *                              improve security without compromising too much
+       *                              performance compared with a less safe `innerHTML`.
+       *
+       * @param   Function|Object  [optional]
+       *                              either the callback that will be invoked or an object
+       *                              with all properties to use per each found emoji.
+       *
+       *          Function            if specified, this will be invoked per each emoji
+       *                              that has been found through the RegExp except
+       *                              those follwed by the invariant \uFE0E ("as text").
+       *                              Once invoked, parameters will be:
+       *
+       *                                codePoint:string  the lower case HEX code point
+       *                                                  i.e. "1f4a9"
+       *
+       *                                options:Object    all info for this parsing operation
+       *
+       *                                variant:char      the optional \uFE0F ("as image")
+       *                                                  variant, in case this info
+       *                                                  is anyhow meaningful.
+       *                                                  By default this is ignored.
+       *
+       *                              If such callback will return a falsy value instead
+       *                              of a valid `src` to use for the image, nothing will
+       *                              actually change for that specific emoji.
+       *
+       *
+       *          Object              if specified, an object containing the following properties
+       *
+       *            callback   Function  the callback to invoke per each found emoji.
+       *            base       string    the base url, by default twemoji.base
+       *            ext        string    the image extension, by default twemoji.ext
+       *            size       string    the assets size, by default twemoji.size
+       *
+       * @example
+       *
+       *  twemoji.parse("I \u2764\uFE0F emoji!");
+       *  // I <img class="emoji" draggable="false" alt="❤️" src="/assets/2764.gif"> emoji!
+       *
+       *
+       *  twemoji.parse("I \u2764\uFE0F emoji!", function(icon, options, variant) {
+       *    return '/assets/' + icon + '.gif';
+       *  });
+       *  // I <img class="emoji" draggable="false" alt="❤️" src="/assets/2764.gif"> emoji!
+       *
+       *
+       * twemoji.parse("I \u2764\uFE0F emoji!", {
+       *   size: 72,
+       *   callback: function(icon, options, variant) {
+       *     return '/assets/' + options.size + '/' + icon + options.ext;
+       *   }
+       * });
+       *  // I <img class="emoji" draggable="false" alt="❤️" src="/assets/72x72/2764.png"> emoji!
+       *
+       */
+      parse: parse,
+
+      /**
+       * Given a string, invokes the callback argument
+       *  per each emoji found in such string.
+       * This is the most raw version used by
+       *  the .parse(string) method itself.
+       *
+       * @param   string    generic string to parse
+       * @param   Function  a generic callback that will be
+       *                    invoked to replace the content.
+       *                    This calback wil receive standard
+       *                    String.prototype.replace(str, callback)
+       *                    arguments such:
+       *  callback(
+       *    match,  // the emoji match
+       *    icon,   // the emoji text (same as text)
+       *    variant // either '\uFE0E' or '\uFE0F', if present
+       *  );
+       *
+       *                    and others commonly received via replace.
+       *
+       *  NOTE: When the variant \uFE0E is found, remember this is an explicit intent
+       *  from the user: the emoji should **not** be replaced with an image.
+       *  In \uFE0F case one, it's the opposite, it should be graphic.
+       *  This utility convetion is that only \uFE0E are not translated into images.
+       */
+      replace: replace,
+
+      /**
+       * Simplify string tests against emoji.
+       *
+       * @param   string  some text that might contain emoji
+       * @return  boolean true if any emoji was found, false otherwise.
+       *
+       * @example
+       *
+       *  if (twemoji.test(someContent)) {
+       *    console.log("emoji All The Things!");
+       *  }
+       */
+      test: test
+    },
+
+    // RegExp based on emoji's official Unicode standards
+    // http://www.unicode.org/Public/UNIDATA/EmojiSources.txt
+    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|\u
 d83c\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\udf4
 a|\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|\ud
 83d\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\u
 dcd1|\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|\ud8
 3d\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|\u
 3030|\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,
+
+    // nodes with type 1 which should **not** be parsed
+    shouldntBeParsed = /IFRAME|NOFRAMES|NOSCRIPT|SCRIPT|STYLE|TEXTAREA|SELECT/,
+
+    // just a private shortcut
+    fromCharCode = String.fromCharCode;
+
+  return twemoji;
+
+
+  /////////////////////////
+  //  private functions  //
+  //     declaration     //
+  /////////////////////////
+
+  /**
+   * Shortcut to create text nodes
+   * @param   string  text used to create DOM text node
+   * @return  Node  a DOM node with that text
+   */
+  function createText(text) {
+    return document.createTextNode(text);
+  }
+
+  /**
+   * Default callback used to generate emoji src
+   *  based on Twitter CDN
+   * @param   string    the emoji codepoint string
+   * @param   string    the default size to use, i.e. "36x36"
+   * @param   string    optional "\uFE0F" variant char, ignored by default
+   * @return  string    the image source to use
+   */
+  function defaultImageSrcGenerator(icon, options) {
+    return ''.concat(options.base, options.size, '/', icon, options.ext);
+  }
+
+  /**
+   * Given a generic DOM nodeType 1, walk through all children
+   * and store every nodeType 3 (#text) found in the tree.
+   * @param   Element a DOM Element with probably some text in it
+   * @param   Array the list of previously discovered text nodes
+   * @return  Array same list with new discovered nodes, if any
+   */
+  function grabAllTextNodes(node, allText) {
+    var
+      childNodes = node.childNodes,
+      length = childNodes.length,
+      subnode,
+      nodeType;
+    while (length--) {
+      subnode = childNodes[length];
+      nodeType = subnode.nodeType;
+      // parse emoji only in text nodes
+      if (nodeType === 3) {
+        // collect them to process emoji later
+        allText.push(subnode);
+      }
+      // ignore all nodes that are not type 1 or that
+      // should not be parsed as script, style, and others
+      else if (nodeType === 1 && !shouldntBeParsed.test(subnode.nodeName)) {
+        grabAllTextNodes(subnode, allText);
+      }
+    }
+    return allText;
+  }
+
+  /**
+   * Used to both remove the possible variant
+   *  and to convert utf16 into code points
+   * @param   string    the emoji surrogate pair
+   * @param   string    the optional variant char, if any
+   */
+  function grabTheRightIcon(icon, variant) {
+    // if variant is present as \uFE0F
+    return toCodePoint(
+      variant === '\uFE0F' ?
+        // the icon should not contain it
+        icon.slice(0, -1) :
+        // fix non standard OSX behavior
+        (icon.length === 3 && icon.charAt(1) === '\uFE0F' ?
+          icon.charAt(0) + icon.charAt(2) : icon)
+    );
+  }
+
+  /**
+   * DOM version of the same logic / parser:
+   *  emojify all found sub-text nodes placing images node instead.
+   * @param   Element   generic DOM node with some text in some child node
+   * @param   Object    options  containing info about how to parse
+    *
+    *            .callback   Function  the callback to invoke per each found emoji.
+    *            .base       string    the base url, by default twemoji.base
+    *            .ext        string    the image extension, by default twemoji.ext
+    *            .size       string    the assets size, by default twemoji.size
+    *
+   * @return  Element same generic node with emoji in place, if any.
+   */
+  function parseNode(node, options) {
+    var
+      allText = grabAllTextNodes(node, []),
+      length = allText.length,
+      fragment,
+      subnode,
+      text,
+      match,
+      i,
+      index,
+      img,
+      alt,
+      icon,
+      variant,
+      src;
+    while (length--) {
+      fragment = document.createDocumentFragment();
+      subnode = allText[length];
+      text = subnode.nodeValue;
+      i = 0;
+      while ((match = re.exec(text))) {
+        index = match.index;
+        if (index !== i) {
+          fragment.appendChild(
+            createText(text.slice(i, index))
+          );
+        }
+        alt = match[0];
+        icon = match[1];
+        variant = match[2];
+        i = index + alt.length;
+        if (variant !== '\uFE0E') {
+          src = options.callback(
+            grabTheRightIcon(icon, variant),
+            options,
+            variant
+          );
+          if (src) {
+            img = new Image();
+            img.onerror = twemoji.onerror;
+            img.className = options.className;
+            img.setAttribute('draggable', 'false');
+            img.alt = alt;
+            img.src = src;
+          }
+        }
+        fragment.appendChild(img || createText(alt));
+        img = null;
+      }
+      // is there actually anything to replace in here ?
+      if (0 < i) {
+        // any text left to be added ?
+        if (i < text.length) {
+          fragment.appendChild(
+            createText(text.slice(i))
+          );
+        }
+        // replace the text node only, leave intact
+        // anything else surrounding such text
+        subnode.parentNode.replaceChild(fragment, subnode);
+      }
+    }
+    return node;
+  }
+
+  /**
+   * String/HTML version of the same logic / parser:
+   *  emojify a generic text placing images tags instead of surrogates pair.
+   * @param   string    generic string with possibly some emoji in it
+   * @param   Object    options  containing info about how to parse
+   *
+   *            .callback   Function  the callback to invoke per each found emoji.
+   *            .base       string    the base url, by default twemoji.base
+   *            .ext        string    the image extension, by default twemoji.ext
+   *            .size       string    the assets size, by default twemoji.size
+   *
+   * @return  the string with <img tags> replacing all found and parsed emoji
+   */
+  function parseString(str, options) {
+    return replace(str, function (match, icon, variant) {
+      var src;
+      // verify the variant is not the FE0E one
+      // this variant means "emoji as text" and should not
+      // require any action/replacement
+      // http://unicode.org/Public/UNIDATA/StandardizedVariants.html
+      if (variant !== '\uFE0E') {
+        src = options.callback(
+          grabTheRightIcon(icon, variant),
+          options,
+          variant
+        );
+        if (src) {
+          // recycle the match string replacing the emoji
+          // with its image counter part
+          match = '<img '.concat(
+            'class="', options.className, '" ',
+            'draggable="false" ',
+            // needs to preserve user original intent
+            // when variants should be copied and pasted too
+            'alt="',
+            match,
+            '" ',
+            'src="',
+            src,
+            '"',
+            '>'
+          );
+        }
+      }
+      return match;
+    });
+  }
+
+  /**
+   * Given a generic value, creates its squared counterpart if it's a number.
+   *  As example, number 36 will return '36x36'.
+   * @param   any     a generic value.
+   * @return  any     a string representing asset size, i.e. "36x36"
+   *                  only in case the value was a number.
+   *                  Returns initial value otherwise.
+   */
+  function toSizeSquaredAsset(value) {
+    return typeof value === 'number' ?
+      value + 'x' + value :
+      value;
+  }
+
+
+  /////////////////////////
+  //  exported functions //
+  //     declaration     //
+  /////////////////////////
+
+  function fromCodePoint(codepoint) {
+    var code = typeof codepoint === 'string' ?
+          parseInt(codepoint, 16) : codepoint;
+    if (code < 0x10000) {
+      return fromCharCode(code);
+    }
+    code -= 0x10000;
+    return fromCharCode(
+      0xD800 + (code >> 10),
+      0xDC00 + (code & 0x3FF)
+    );
+  }
+
+  function parse(what, how) {
+    if (!how || typeof how === 'function') {
+      how = {callback: how};
+    }
+    // if first argument is string, inject html <img> tags
+    // otherwise use the DOM tree and parse text nodes only
+    return (typeof what === 'string' ? parseString : parseNode)(what, {
+      callback: how.callback || defaultImageSrcGenerator,
+      base:     typeof how.base === 'string' ? how.base : twemoji.base,
+      ext:      how.ext || twemoji.ext,
+      size:     how.folder || toSizeSquaredAsset(how.size || twemoji.size),
+      className:how.className || twemoji.className
+    });
+  }
+
+  function replace(text, callback) {
+    return String(text).replace(re, callback);
+  }
+
+  function test(text) {
+    // IE6 needs a reset before too
+    re.lastIndex = 0;
+    var result = re.test(text);
+    re.lastIndex = 0;
+    return result;
+  }
+
+  function toCodePoint(unicodeSurrogates, sep) {
+    var
+      r = [],
+      c = 0,
+      p = 0,
+      i = 0;
+    while (i < unicodeSurrogates.length) {
+      c = unicodeSurrogates.charCodeAt(i++);
+      if (p) {
+        r.push((0x10000 + ((p - 0xD800) << 10) + (c - 0xDC00)).toString(16));
+        p = 0;
+      } else if (0xD800 <= c && c <= 0xDBFF) {
+        p = c;
+      } else {
+        r.push(c.toString(16));
+      }
+    }
+    return r.join(sep || '-');
+  }
+
+}());
</ins><span class="cx" style="display: block; padding: 0 10px">\ No newline at end of file
</span><span class="cx" style="display: block; padding: 0 10px">Property changes on: trunk/src/wp-includes/js/twemoji.js
</span><span class="cx" style="display: block; padding: 0 10px">___________________________________________________________________
</span></span></pre></div>
<a id="svnexecutable"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: svn:executable</h4></div>
<ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+*
</ins><span class="cx" style="display: block; padding: 0 10px">\ No newline at end of property
</span><a id="trunksrcwpincludespostphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/post.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/post.php    2015-03-11 22:40:56 UTC (rev 31732)
+++ trunk/src/wp-includes/post.php      2015-03-11 22:48:16 UTC (rev 31733)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -3329,6 +3329,17 @@
</span><span class="cx" style="display: block; padding: 0 10px">        // Expected_slashed (everything!).
</span><span class="cx" style="display: block; padding: 0 10px">        $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' );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+        $emoji_fields = array( 'post_title', 'post_content', 'post_excerpt' );
+
+       foreach( $emoji_fields as $emoji_field ) {
+               if ( isset( $data[ $emoji_field ] ) ) {
+                       $charset = $wpdb->get_col_charset( $wpdb->posts, $emoji_field );
+                       if ( 'utf8' === $charset ) {
+                               $data[ $emoji_field ] = wp_encode_emoji( $data[ $emoji_field ] );
+                       }
+               }
+       }
+
</ins><span class="cx" style="display: block; padding: 0 10px">         if ( 'attachment' === $post_type ) {
</span><span class="cx" style="display: block; padding: 0 10px">                /**
</span><span class="cx" style="display: block; padding: 0 10px">                 * Filter attachment post data before it is updated in or added to the database.
</span></span></pre></div>
<a id="trunksrcwpincludesscriptloaderphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/script-loader.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/script-loader.php   2015-03-11 22:40:56 UTC (rev 31732)
+++ trunk/src/wp-includes/script-loader.php     2015-03-11 22:48:16 UTC (rev 31733)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -424,6 +424,28 @@
</span><span class="cx" style="display: block; padding: 0 10px">        $scripts->add( 'media-audiovideo', "/wp-includes/js/media/audio-video$suffix.js", array( 'media-editor' ), false, 1 );
</span><span class="cx" style="display: block; padding: 0 10px">        $scripts->add( 'mce-view', "/wp-includes/js/mce-view$suffix.js", array( 'shortcode', 'media-models', 'media-audiovideo', 'wp-playlist' ), false, 1 );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+        $scripts->add( 'twemoji', "/wp-includes/js/twemoji$suffix.js", array(), false, 1 );
+       $scripts->add( 'emoji', "/wp-includes/js/emoji$suffix.js", array( 'twemoji' ), false, 1 );
+       did_action( 'init' ) && $scripts->localize( 'emoji', 'EmojiSettings', array(
+               /**
+                * Filter the URL where emoji images are hosted.
+                *
+                * @since 4.2.0
+                *
+                * @param string The emoji base URL.
+                */
+               'base_url' => apply_filters( 'emoji_url', '//s0.wp.com/wp-content/mu-plugins/emoji/twemoji/72x72/' ),
+               /**
+                * Filter the extension of the emoji files.
+                *
+                * @since 4.2.0
+                *
+                * @param string The emoji extension.
+                */
+               'ext'      => apply_filters( 'emoji_ext', '.png' ),
+       ) );
+       $scripts->enqueue( 'emoji' );
+
</ins><span class="cx" style="display: block; padding: 0 10px">         if ( is_admin() ) {
</span><span class="cx" style="display: block; padding: 0 10px">                $scripts->add( 'admin-tags', "/wp-admin/js/tags$suffix.js", array('jquery', 'wp-ajax-response'), false, 1 );
</span><span class="cx" style="display: block; padding: 0 10px">                did_action( 'init' ) && $scripts->localize( 'admin-tags', 'tagsl10n', array(
</span></span></pre></div>
<a id="trunktestsphpunittestsdependenciesstylesphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/tests/phpunit/tests/dependencies/styles.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/tests/phpunit/tests/dependencies/styles.php 2015-03-11 22:40:56 UTC (rev 31732)
+++ trunk/tests/phpunit/tests/dependencies/styles.php   2015-03-11 22:48:16 UTC (rev 31733)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -12,6 +12,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                        $GLOBALS['wp_styles'] = null;
</span><span class="cx" style="display: block; padding: 0 10px">                $this->old_wp_styles = $GLOBALS['wp_styles'];
</span><span class="cx" style="display: block; padding: 0 10px">                remove_action( 'wp_default_styles', 'wp_default_styles' );
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                remove_action( 'wp_print_styles', 'print_emoji_styles' );
</ins><span class="cx" style="display: block; padding: 0 10px">                 $GLOBALS['wp_styles'] = new WP_Styles();
</span><span class="cx" style="display: block; padding: 0 10px">                $GLOBALS['wp_styles']->default_version = get_bloginfo( 'version' );
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -19,6 +20,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">        function tearDown() {
</span><span class="cx" style="display: block; padding: 0 10px">                $GLOBALS['wp_styles'] = $this->old_wp_styles;
</span><span class="cx" style="display: block; padding: 0 10px">                add_action( 'wp_default_styles', 'wp_default_styles' );
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                add_action( 'wp_print_styles', 'print_emoji_styles' );
</ins><span class="cx" style="display: block; padding: 0 10px">                 parent::tearDown();
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span></span></pre></div>
<a id="trunktestsphpunittestsformattingSmiliesphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/tests/phpunit/tests/formatting/Smilies.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/tests/phpunit/tests/formatting/Smilies.php  2015-03-11 22:40:56 UTC (rev 31732)
+++ trunk/tests/phpunit/tests/formatting/Smilies.php    2015-03-11 22:48:16 UTC (rev 31733)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -16,15 +16,15 @@
</span><span class="cx" style="display: block; padding: 0 10px">                return array (
</span><span class="cx" style="display: block; padding: 0 10px">                        array (
</span><span class="cx" style="display: block; padding: 0 10px">                                '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 :?:',
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                '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" />'
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         "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"
</ins><span class="cx" style="display: block; padding: 0 10px">                         ),
</span><span class="cx" style="display: block; padding: 0 10px">                        array (
</span><span class="cx" style="display: block; padding: 0 10px">                                '<strong>Welcome to the jungle!</strong> We got fun n games! :) We got everything you want 8-) <em>Honey we know the names :)</em>',
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                '<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>'
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         "<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>"
</ins><span class="cx" style="display: block; padding: 0 10px">                         ),
</span><span class="cx" style="display: block; padding: 0 10px">                        array (
</span><span class="cx" style="display: block; padding: 0 10px">                                "<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",
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                "<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"
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         "<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"
</ins><span class="cx" style="display: block; padding: 0 10px">                         ),
</span><span class="cx" style="display: block; padding: 0 10px">                        array (
</span><span class="cx" style="display: block; padding: 0 10px">                                '<strong style="here comes the sun :-D">and I say it\'s allright:D:D',
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -147,7 +147,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                $includes_path = includes_url("images/smilies/");
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                $in_str = 'Do we ingore smilies ;-) in ' . $element . ' tags <' . $element . '>My Content Here :?: </' . $element . '>';
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $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 . '>';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $exp_str = "Do we ingore smilies \xf0\x9f\x98\x89 in $element tags <$element>My Content Here :?: </$element>";
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                // standard smilies, use_smilies: ON
</span><span class="cx" style="display: block; padding: 0 10px">                update_option( 'use_smilies', 1 );
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -169,27 +169,27 @@
</span><span class="cx" style="display: block; padding: 0 10px">                return array (
</span><span class="cx" style="display: block; padding: 0 10px">                        array (
</span><span class="cx" style="display: block; padding: 0 10px">                                '8-O :-(',
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                '<img src="' . $includes_path . 'icon_eek.gif" alt="8-O" class="wp-smiley" /> <img src="' . $includes_path . 'icon_sad.gif" alt=":-(" class="wp-smiley" />'
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         "\xf0\x9f\x98\xaf \xf0\x9f\x98\xa6"
</ins><span class="cx" style="display: block; padding: 0 10px">                         ),
</span><span class="cx" style="display: block; padding: 0 10px">                        array (
</span><span class="cx" style="display: block; padding: 0 10px">                                '8-) 8-O',
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                '<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" />'
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         "\xf0\x9f\x98\x8e \xf0\x9f\x98\xaf"
</ins><span class="cx" style="display: block; padding: 0 10px">                         ),
</span><span class="cx" style="display: block; padding: 0 10px">                        array (
</span><span class="cx" style="display: block; padding: 0 10px">                                '8-) 8O',
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                '<img src="' . $includes_path . 'icon_cool.gif" alt="8-)" class="wp-smiley" /> <img src="' . $includes_path . 'icon_eek.gif" alt="8O" class="wp-smiley" />'
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         "\xf0\x9f\x98\x8e \xf0\x9f\x98\xaf"
</ins><span class="cx" style="display: block; padding: 0 10px">                         ),
</span><span class="cx" style="display: block; padding: 0 10px">                        array (
</span><span class="cx" style="display: block; padding: 0 10px">                                '8-) :-(',
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                '<img src="' . $includes_path . 'icon_cool.gif" alt="8-)" class="wp-smiley" /> <img src="' . $includes_path . 'icon_sad.gif" alt=":-(" class="wp-smiley" />'
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         "\xf0\x9f\x98\x8e \xf0\x9f\x98\xa6"
</ins><span class="cx" style="display: block; padding: 0 10px">                         ),
</span><span class="cx" style="display: block; padding: 0 10px">                        array (
</span><span class="cx" style="display: block; padding: 0 10px">                                '8-) :twisted:',
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                '<img src="' . $includes_path . 'icon_cool.gif" alt="8-)" class="wp-smiley" /> <img src="' . $includes_path . 'icon_twisted.gif" alt=":twisted:" class="wp-smiley" />'
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         "\xf0\x9f\x98\x8e \xf0\x9f\x98\x88"
</ins><span class="cx" style="display: block; padding: 0 10px">                         ),
</span><span class="cx" style="display: block; padding: 0 10px">                        array (
</span><span class="cx" style="display: block; padding: 0 10px">                                '8O :twisted: :( :? :(',
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                '<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" />'
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         "\xf0\x9f\x98\xaf \xf0\x9f\x98\x88 \xf0\x9f\x98\xa6 \xf0\x9f\x98\xaf \xf0\x9f\x98\xa6"
</ins><span class="cx" style="display: block; padding: 0 10px">                         ),
</span><span class="cx" style="display: block; padding: 0 10px">                );
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -228,11 +228,11 @@
</span><span class="cx" style="display: block; padding: 0 10px">                        ),
</span><span class="cx" style="display: block; padding: 0 10px">                        array (
</span><span class="cx" style="display: block; padding: 0 10px">                                '8O :) additional text here :)',
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                '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" />'
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         '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" />'
</ins><span class="cx" style="display: block; padding: 0 10px">                         ),
</span><span class="cx" style="display: block; padding: 0 10px">                        array (
</span><span class="cx" style="display: block; padding: 0 10px">                                ':) :) :) :)',
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                '<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" />'
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         '<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" />'
</ins><span class="cx" style="display: block; padding: 0 10px">                         ),
</span><span class="cx" style="display: block; padding: 0 10px">                );
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -257,7 +257,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                $orig_trans = $wpsmiliestrans; // save original tranlations array
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                $wpsmiliestrans = array (
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                  ':)' => 'icon_smile.gif'
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+           ':)' => 'simple-smile.png'
</ins><span class="cx" style="display: block; padding: 0 10px">                 );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                smilies_init();
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -294,21 +294,12 @@
</span><span class="cx" style="display: block; padding: 0 10px">                $input[]  = 'My test :) smile';
</span><span class="cx" style="display: block; padding: 0 10px">                $output[] = array('test <img ', 'alt=":)"', ' /> smile');
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $input[]  = 'My test ;) smile';
-               $output[] = array('test <img ', 'alt=";)"', ' /> smile');
-
</del><span class="cx" style="display: block; padding: 0 10px">                 $input[]  = 'My test &nbsp;:)&nbsp;smile';
</span><span class="cx" style="display: block; padding: 0 10px">                $output[] = array('test &nbsp;<img ', 'alt=":)"', ' />&nbsp;smile');
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $input[]  = 'My test &nbsp;;)&nbsp;smile';
-               $output[] = array('test &nbsp;<img ', 'alt=";)"', ' />&nbsp;smile');
-
</del><span class="cx" style="display: block; padding: 0 10px">                 $input[]  = "My test {$nbsp}:){$nbsp}smile";
</span><span class="cx" style="display: block; padding: 0 10px">                $output[] = array("test {$nbsp}<img ", 'alt=":)"', " />{$nbsp}smile");
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $input[]  = "My test {$nbsp};){$nbsp}smile";
-               $output[] = array("test {$nbsp}<img ", 'alt=";)"', " />{$nbsp}smile");
-
</del><span class="cx" style="display: block; padding: 0 10px">                 foreach($input as $key => $in) {
</span><span class="cx" style="display: block; padding: 0 10px">                        $result = convert_smilies( $in );
</span><span class="cx" style="display: block; padding: 0 10px">                        foreach($output[$key] as $out) {
</span></span></pre>
</div>
</div>

</body>
</html>