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 #31242



git-svn-id: https://develop.svn.wordpress.org/trunk@31733 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
Gary Pendergast 2015-03-11 22:48:16 +00:00
parent 1c1e5f377f
commit ae391ec226
14 changed files with 1088 additions and 66 deletions

View File

@ -360,6 +360,7 @@ final class _WP_Editors {
'wordpress',
'wpautoresize',
'wpeditimage',
'wpemoji',
'wpgallery',
'wplink',
'wpdialogs',

View File

@ -160,15 +160,20 @@ add_filter( 'the_title_rss', 'strip_tags' );
add_filter( 'the_title_rss', 'ent2ncr', 8 );
add_filter( 'the_title_rss', 'esc_html' );
add_filter( 'the_content_rss', 'ent2ncr', 8 );
add_filter( 'the_content_feed', 'feed_emoji' );
add_filter( 'the_excerpt_rss', 'convert_chars' );
add_filter( 'the_excerpt_rss', 'ent2ncr', 8 );
add_filter( 'comment_author_rss', 'ent2ncr', 8 );
add_filter( 'comment_text_rss', 'ent2ncr', 8 );
add_filter( 'comment_text_rss', 'esc_html' );
add_filter( 'comment_text_rss', 'feed_emoji' );
add_filter( 'bloginfo_rss', 'ent2ncr', 8 );
add_filter( 'the_author', 'ent2ncr', 8 );
add_filter( 'the_guid', 'esc_url' );
// Email filters
add_filter( 'wp_mail', 'mail_emoji' );
// Misc filters
add_filter( 'option_ping_sites', 'privacy_ping_filter' );
add_filter( 'option_blog_charset', '_wp_specialchars' ); // IMPORTANT: This must not be wp_specialchars() or esc_html() or it'll cause an infinite loop
@ -218,6 +223,7 @@ add_action( 'template_redirect', 'wp_shortlink_header', 11, 0 );
add_action( 'wp_print_footer_scripts', '_wp_footer_scripts' );
add_action( 'init', 'check_theme_switched', 99 );
add_action( 'after_switch_theme', '_wp_sidebars_changed' );
add_action( 'wp_print_styles', 'print_emoji_styles' );
if ( isset( $_GET['replytocom'] ) )
add_action( 'wp_head', 'wp_no_robots' );
@ -248,6 +254,7 @@ add_action( 'sanitize_comment_cookies', 'sanitize_comment_cookies'
add_action( 'admin_print_scripts', 'print_head_scripts', 20 );
add_action( 'admin_print_footer_scripts', '_wp_footer_scripts' );
add_action( 'admin_print_styles', 'print_admin_styles', 20 );
add_action( 'admin_print_styles', 'print_emoji_styles' );
add_action( 'init', 'smilies_init', 5 );
add_action( 'plugins_loaded', 'wp_maybe_load_widgets', 0 );
add_action( 'plugins_loaded', 'wp_maybe_load_embeds', 0 );

View File

@ -649,3 +649,14 @@ function fetch_feed( $url ) {
return $feed;
}
/**
* 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 );
}

View File

@ -2038,6 +2038,15 @@ function translate_smiley( $matches ) {
$smiley = trim( reset( $matches ) );
$img = $wpsmiliestrans[ $smiley ];
$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;
}
/**
* Filter the Smiley image URL before it's used in the image element.
*
@ -4015,3 +4024,155 @@ function wp_spaces_regexp() {
return $spaces;
}
/**
* 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;
}

View File

@ -2945,51 +2945,51 @@ function smilies_init() {
if ( !isset( $wpsmiliestrans ) ) {
$wpsmiliestrans = array(
':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',
':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",
// This one transformation breaks regular text with frequency.
// '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',
// '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",
);
}

201
src/wp-includes/js/emoji.js Executable file
View File

@ -0,0 +1,201 @@
/* 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();
})();

View File

@ -0,0 +1,15 @@
.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;
}

View File

@ -0,0 +1,17 @@
/* 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;
}

View File

@ -0,0 +1,64 @@
( 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 );

519
src/wp-includes/js/twemoji.js Executable file

File diff suppressed because one or more lines are too long

View File

@ -3329,6 +3329,17 @@ function wp_insert_post( $postarr, $wp_error = false ) {
// Expected_slashed (everything!).
$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' );
$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 ] );
}
}
}
if ( 'attachment' === $post_type ) {
/**
* Filter attachment post data before it is updated in or added to the database.

View File

@ -424,6 +424,28 @@ function wp_default_scripts( &$scripts ) {
$scripts->add( 'media-audiovideo', "/wp-includes/js/media/audio-video$suffix.js", array( 'media-editor' ), false, 1 );
$scripts->add( 'mce-view', "/wp-includes/js/mce-view$suffix.js", array( 'shortcode', 'media-models', 'media-audiovideo', 'wp-playlist' ), false, 1 );
$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' );
if ( is_admin() ) {
$scripts->add( 'admin-tags', "/wp-admin/js/tags$suffix.js", array('jquery', 'wp-ajax-response'), false, 1 );
did_action( 'init' ) && $scripts->localize( 'admin-tags', 'tagsl10n', array(

View File

@ -12,6 +12,7 @@ class Tests_Dependencies_Styles extends WP_UnitTestCase {
$GLOBALS['wp_styles'] = null;
$this->old_wp_styles = $GLOBALS['wp_styles'];
remove_action( 'wp_default_styles', 'wp_default_styles' );
remove_action( 'wp_print_styles', 'print_emoji_styles' );
$GLOBALS['wp_styles'] = new WP_Styles();
$GLOBALS['wp_styles']->default_version = get_bloginfo( 'version' );
}
@ -19,6 +20,7 @@ class Tests_Dependencies_Styles extends WP_UnitTestCase {
function tearDown() {
$GLOBALS['wp_styles'] = $this->old_wp_styles;
add_action( 'wp_default_styles', 'wp_default_styles' );
add_action( 'wp_print_styles', 'print_emoji_styles' );
parent::tearDown();
}

View File

@ -16,15 +16,15 @@ class Tests_Formatting_Smilies extends WP_UnitTestCase {
return array (
array (
'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 :?:',
'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" />'
"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"
),
array (
'<strong>Welcome to the jungle!</strong> We got fun n games! :) We got everything you want 8-) <em>Honey we know the names :)</em>',
'<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>'
"<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>"
),
array (
"<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",
"<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"
"<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"
),
array (
'<strong style="here comes the sun :-D">and I say it\'s allright:D:D',
@ -147,7 +147,7 @@ class Tests_Formatting_Smilies extends WP_UnitTestCase {
$includes_path = includes_url("images/smilies/");
$in_str = 'Do we ingore smilies ;-) in ' . $element . ' tags <' . $element . '>My Content Here :?: </' . $element . '>';
$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 . '>';
$exp_str = "Do we ingore smilies \xf0\x9f\x98\x89 in $element tags <$element>My Content Here :?: </$element>";
// standard smilies, use_smilies: ON
update_option( 'use_smilies', 1 );
@ -169,27 +169,27 @@ class Tests_Formatting_Smilies extends WP_UnitTestCase {
return array (
array (
'8-O :-(',
'<img src="' . $includes_path . 'icon_eek.gif" alt="8-O" class="wp-smiley" /> <img src="' . $includes_path . 'icon_sad.gif" alt=":-(" class="wp-smiley" />'
"\xf0\x9f\x98\xaf \xf0\x9f\x98\xa6"
),
array (
'8-) 8-O',
'<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" />'
"\xf0\x9f\x98\x8e \xf0\x9f\x98\xaf"
),
array (
'8-) 8O',
'<img src="' . $includes_path . 'icon_cool.gif" alt="8-)" class="wp-smiley" /> <img src="' . $includes_path . 'icon_eek.gif" alt="8O" class="wp-smiley" />'
"\xf0\x9f\x98\x8e \xf0\x9f\x98\xaf"
),
array (
'8-) :-(',
'<img src="' . $includes_path . 'icon_cool.gif" alt="8-)" class="wp-smiley" /> <img src="' . $includes_path . 'icon_sad.gif" alt=":-(" class="wp-smiley" />'
"\xf0\x9f\x98\x8e \xf0\x9f\x98\xa6"
),
array (
'8-) :twisted:',
'<img src="' . $includes_path . 'icon_cool.gif" alt="8-)" class="wp-smiley" /> <img src="' . $includes_path . 'icon_twisted.gif" alt=":twisted:" class="wp-smiley" />'
"\xf0\x9f\x98\x8e \xf0\x9f\x98\x88"
),
array (
'8O :twisted: :( :? :(',
'<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" />'
"\xf0\x9f\x98\xaf \xf0\x9f\x98\x88 \xf0\x9f\x98\xa6 \xf0\x9f\x98\xaf \xf0\x9f\x98\xa6"
),
);
}
@ -228,11 +228,11 @@ class Tests_Formatting_Smilies extends WP_UnitTestCase {
),
array (
'8O :) additional text here :)',
'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" />'
'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" />'
),
array (
':) :) :) :)',
'<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" />'
'<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" />'
),
);
}
@ -257,7 +257,7 @@ class Tests_Formatting_Smilies extends WP_UnitTestCase {
$orig_trans = $wpsmiliestrans; // save original tranlations array
$wpsmiliestrans = array (
':)' => 'icon_smile.gif'
':)' => 'simple-smile.png'
);
smilies_init();
@ -294,21 +294,12 @@ class Tests_Formatting_Smilies extends WP_UnitTestCase {
$input[] = 'My test :) smile';
$output[] = array('test <img ', 'alt=":)"', ' /> smile');
$input[] = 'My test ;) smile';
$output[] = array('test <img ', 'alt=";)"', ' /> smile');
$input[] = 'My test &nbsp;:)&nbsp;smile';
$output[] = array('test &nbsp;<img ', 'alt=":)"', ' />&nbsp;smile');
$input[] = 'My test &nbsp;;)&nbsp;smile';
$output[] = array('test &nbsp;<img ', 'alt=";)"', ' />&nbsp;smile');
$input[] = "My test {$nbsp}:){$nbsp}smile";
$output[] = array("test {$nbsp}<img ", 'alt=":)"', " />{$nbsp}smile");
$input[] = "My test {$nbsp};){$nbsp}smile";
$output[] = array("test {$nbsp}<img ", 'alt=";)"', " />{$nbsp}smile");
foreach($input as $key => $in) {
$result = convert_smilies( $in );
foreach($output[$key] as $out) {