diff --git a/Gruntfile.js b/Gruntfile.js index 779d4e923e..1a574d3050 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -302,6 +302,7 @@ module.exports = function(grunt) { '!wp-includes/js/hoverIntent.js', '!wp-includes/js/json2.js', '!wp-includes/js/tw-sack.js', + '!wp-includes/js/twemoji.js', '!**/*.min.js' ], // Remove once other JSHint errors are resolved diff --git a/src/wp-admin/js/inline-edit-post.js b/src/wp-admin/js/inline-edit-post.js index 958de0682c..40ee595b97 100644 --- a/src/wp-admin/js/inline-edit-post.js +++ b/src/wp-admin/js/inline-edit-post.js @@ -272,7 +272,6 @@ inlineEditPost = { if ( -1 !== r.indexOf( ']*?>/g, '' ); diff --git a/src/wp-admin/js/inline-edit-tax.js b/src/wp-admin/js/inline-edit-tax.js index 7347bc27d8..6a9ce5d06b 100644 --- a/src/wp-admin/js/inline-edit-tax.js +++ b/src/wp-admin/js/inline-edit-tax.js @@ -117,8 +117,6 @@ inlineEditTax = { // Update the value in the Parent dropdown. $( '#parent' ).find( 'option[value=' + option_value + ']' ).text( row.find( '.row-title' ).text() ); - wp.emoji.parse( row.get( 0 ) ); - row.hide().fadeIn(); } else { $('#edit-'+id+' .inline-edit-save .error').html(r).show(); diff --git a/src/wp-admin/js/post.js b/src/wp-admin/js/post.js index 36750c6e5a..32c5f9c9e3 100644 --- a/src/wp-admin/js/post.js +++ b/src/wp-admin/js/post.js @@ -741,8 +741,6 @@ jQuery(document).ready( function($) { }); } - wp.emoji.parse( box.get( 0 ) ); - b.html(revert_b); real_slug.val(new_slug); $('#view-post-btn').show(); diff --git a/src/wp-admin/js/tags.js b/src/wp-admin/js/tags.js index e5ad2ca935..333a2eb563 100644 --- a/src/wp-admin/js/tags.js +++ b/src/wp-admin/js/tags.js @@ -49,8 +49,6 @@ jQuery(document).ready(function($) { else $( '.tags' ).prepend( res.responses[0].supplemental.parents ); // As the parent is not visible, Insert the version with Parent - Child - ThisTerm - wp.emoji.parse( $( '.tags' ).get( 0 ) ); - $('.tags .no-items').remove(); if ( form.find('select#parent') ) { diff --git a/src/wp-includes/js/tinymce/plugins/wpemoji/plugin.js b/src/wp-includes/js/tinymce/plugins/wpemoji/plugin.js index 3dfd36a709..82741b676d 100755 --- a/src/wp-includes/js/tinymce/plugins/wpemoji/plugin.js +++ b/src/wp-includes/js/tinymce/plugins/wpemoji/plugin.js @@ -21,10 +21,10 @@ typing = event.type === 'keydown'; } ); - editor.on( 'input setcontent', function() { + editor.on( 'input setcontent', function( event ) { var selection, node, bookmark, imgs; - if ( typing ) { + if ( typing && event.type === 'input' ) { return; } diff --git a/src/wp-includes/js/wp-emoji.js b/src/wp-includes/js/wp-emoji.js index 734b7b0dd2..7b36505cd1 100644 --- a/src/wp-includes/js/wp-emoji.js +++ b/src/wp-includes/js/wp-emoji.js @@ -1,34 +1,13 @@ -/* global _wpemojiSettings, twemoji */ window.wp = window.wp || {}; -(function() { - var emoji; - - wp.emoji = emoji = { - /** - * The CDN URL for where emoji files are hosted. - * - * @since 4.2.0 - * - * @var string - */ - baseUrl: '//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', - +( function( window, wp, twemoji, settings ) { + var emoji = { /** * Flag to determine if we should parse all emoji characters into Twemoji images. * * @since 4.2.0 * - * @var bool + * @var Boolean */ parseAllEmoji: false, @@ -37,7 +16,7 @@ window.wp = window.wp || {}; * * @since 4.2.0 * - * @var bool + * @var Boolean */ parseEmoji: false, @@ -46,7 +25,7 @@ window.wp = window.wp || {}; * * @since 4.2.0 * - * @var bool + * @var Boolean */ parseFlags: false, @@ -56,17 +35,14 @@ window.wp = window.wp || {}; * @since 4.2.0 */ init: function() { - if ( typeof _wpemojiSettings !== 'undefined' ) { - emoji.baseUrl = _wpemojiSettings.baseUrl || emoji.baseUrl; - emoji.ext = _wpemojiSettings.ext || emoji.ext; - } - emoji.parseAllEmoji = ! emoji.browserSupportsEmoji(); emoji.parseFlags = ! emoji.browserSupportsFlagEmoji(); emoji.parseEmoji = emoji.parseAllEmoji || emoji.parseFlags; - if ( ! emoji.parseEmoji ) { - return; + if ( window.addEventListener ) { + window.addEventListener( 'load', emoji.load, false ); + } else if ( window.attachEvent ) { + window.attachEvent( 'onload', emoji.load ); } }, @@ -76,6 +52,35 @@ window.wp = window.wp || {}; * @since 4.2.0 */ load: function() { + if ( MutationObserver ) { + new MutationObserver( function( mutationRecords ) { + var i = mutationRecords.length, + ii, + node; + + while ( i-- ) { + ii = mutationRecords[ i ].addedNodes.length; + + while ( ii-- ) { + node = mutationRecords[ i ].addedNodes[ ii ]; + + if ( node.nodeType === 3 ) { + node = node.parentNode; + } + + if ( node.nodeType === 1 ) { + emoji.parse( node ); + } + } + } + } ) + + .observe( document.body, { + childList: true, + subtree: true + } ); + } + emoji.parse( document.body ); }, @@ -84,22 +89,16 @@ window.wp = window.wp || {}; * * @since 4.2.0 * - * @return {bool} True if the browser can render emoji, false if it cannot. + * @return {Boolean} True if the browser can render emoji, false if it cannot. */ browserSupportsEmoji: function() { - var context, smile; + var canvas = document.createElement( 'canvas' ), + context = canvas.getContext && canvas.getContext( '2d' ); - if ( ! document.createElement( 'canvas' ).getContext ) { - return; + if ( ! context.fillText ) { + return false; } - 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 @@ -107,7 +106,7 @@ window.wp = window.wp || {}; */ context.textBaseline = 'top'; context.font = '600 32px Arial'; - context.fillText( smile, 0, 0 ); + context.fillText( String.fromCharCode( 55357, 56835 ), 0, 0 ); return context.getImageData( 16, 16, 1, 1 ).data[0] !== 0; }, @@ -117,29 +116,20 @@ window.wp = window.wp || {}; * 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. + * + * @return {Boolean} True if the browser renders flag characters as a flag glyph, false if it does not. */ browserSupportsFlagEmoji: function() { - var context, flag, canvas; + var canvas = document.createElement( 'canvas' ), + context = canvas.getContext && canvas.getContext( '2d' ); - canvas = document.createElement( 'canvas' ); - - if ( ! canvas.getContext ) { - return; + if ( ! context.fillText ) { + return false; } - 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 ); + context.fillText( String.fromCharCode( 55356, 56812, 55356, 56807 ), 0, 0 ); /* * This works because the image will be one of three things: @@ -151,24 +141,23 @@ window.wp = window.wp || {}; * to a larger image (4-5KB data URL). */ return canvas.toDataURL().length > 3000; - }, /** - * Given a DOM node, parse any emoji characters into Twemoji images. + * Given an element or string, parse any emoji characters into Twemoji images. * * @since 4.2.0 * - * @param {Element} element The DOM node to parse. + * @param {HTMLElement|String} object The element or string to parse. */ - parse: function( element ) { + parse: function( object ) { if ( ! emoji.parseEmoji ) { - return; + return object; } - return twemoji.parse( element, { - base: emoji.baseUrl, - ext: emoji.ext, + return twemoji.parse( object, { + base: settings.baseUrl, + ext: settings.ext, callback: function( icon, options ) { // Ignore some standard characters that TinyMCE recommends in its character map. switch ( icon ) { @@ -193,11 +182,7 @@ window.wp = window.wp || {}; } }; - if ( window.addEventListener ) { - window.addEventListener( 'load', emoji.load, false ); - } else if ( window.attachEvent ) { - window.attachEvent( 'onload', emoji.load ); - } - emoji.init(); -})(); + + wp.emoji = emoji; +} )( window, window.wp, window.twemoji, window._wpemojiSettings ); diff --git a/src/wp-includes/script-loader.php b/src/wp-includes/script-loader.php index edf2e1acb3..846ebdbbfc 100644 --- a/src/wp-includes/script-loader.php +++ b/src/wp-includes/script-loader.php @@ -447,7 +447,7 @@ function wp_default_scripts( &$scripts ) { $scripts->enqueue( 'emoji' ); if ( is_admin() ) { - $scripts->add( 'admin-tags', "/wp-admin/js/tags$suffix.js", array( 'jquery', 'wp-ajax-response', 'emoji' ), false, 1 ); + $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( 'noPerm' => __('You do not have permission to do that.'), 'broken' => __('An unidentified error has occurred.') @@ -470,7 +470,7 @@ function wp_default_scripts( &$scripts ) { 'tagDelimiter' => _x( ',', 'tag delimiter' ), ) ); - $scripts->add( 'post', "/wp-admin/js/post$suffix.js", array( 'suggest', 'wp-lists', 'postbox', 'tags-box', 'emoji' ), false, 1 ); + $scripts->add( 'post', "/wp-admin/js/post$suffix.js", array( 'suggest', 'wp-lists', 'postbox', 'tags-box' ), false, 1 ); did_action( 'init' ) && $scripts->localize( 'post', 'postL10n', array( 'ok' => __('OK'), 'cancel' => __('Cancel'), @@ -522,7 +522,7 @@ function wp_default_scripts( &$scripts ) { $scripts->add( 'theme', "/wp-admin/js/theme$suffix.js", array( 'wp-backbone' ), false, 1 ); - $scripts->add( 'inline-edit-post', "/wp-admin/js/inline-edit-post$suffix.js", array( 'jquery', 'suggest', 'emoji' ), false, 1 ); + $scripts->add( 'inline-edit-post', "/wp-admin/js/inline-edit-post$suffix.js", array( 'jquery', 'suggest' ), false, 1 ); did_action( 'init' ) && $scripts->localize( 'inline-edit-post', 'inlineEditL10n', array( 'error' => __('Error while saving the changes.'), 'ntdeltitle' => __('Remove From Bulk Edit'), @@ -530,7 +530,7 @@ function wp_default_scripts( &$scripts ) { 'comma' => trim( _x( ',', 'tag delimiter' ) ), ) ); - $scripts->add( 'inline-edit-tax', "/wp-admin/js/inline-edit-tax$suffix.js", array( 'jquery', 'emoji' ), false, 1 ); + $scripts->add( 'inline-edit-tax', "/wp-admin/js/inline-edit-tax$suffix.js", array( 'jquery' ), false, 1 ); did_action( 'init' ) && $scripts->localize( 'inline-edit-tax', 'inlineEditL10n', array( 'error' => __('Error while saving the changes.') ) );