diff options
-rw-r--r-- | src/wp-includes/formatting.php | 45 | ||||
-rw-r--r-- | src/wp-includes/js/wp-emoji.js | 26 | ||||
-rw-r--r-- | tests/phpunit/tests/formatting/Emoji.php | 68 |
3 files changed, 131 insertions, 8 deletions
diff --git a/src/wp-includes/formatting.php b/src/wp-includes/formatting.php index c2f08028c5..b236014c47 100644 --- a/src/wp-includes/formatting.php +++ b/src/wp-includes/formatting.php @@ -4517,12 +4517,12 @@ img.emoji { } /** + * Print the inline Emoji detection script if it is not already printed. * - * @global string $wp_version + * @since 4.2.0 * @staticvar bool $printed */ function print_emoji_detection_script() { - global $wp_version; static $printed = false; if ( $printed ) { @@ -4531,24 +4531,57 @@ function print_emoji_detection_script() { $printed = true; + _print_emoji_detection_script(); +} + +/** + * Print inline Emoji dection script + * + * @ignore + * @since 4.6.0 + * @access private + * + * @global string $wp_version + */ +function _print_emoji_detection_script() { + global $wp_version; + $settings = array( /** - * Filter the URL where emoji images are hosted. + * Filter the URL where emoji png images are hosted. * * @since 4.2.0 * - * @param string The emoji base URL. + * @param string The emoji base URL for png images. */ 'baseUrl' => apply_filters( 'emoji_url', 'https://s.w.org/images/core/emoji/72x72/' ), /** - * Filter the extension of the emoji files. + * Filter the extension of the emoji png files. * * @since 4.2.0 * - * @param string The emoji extension. Default .png. + * @param string The emoji extension for png files. Default .png. */ 'ext' => apply_filters( 'emoji_ext', '.png' ), + + /** + * Filter the URL where emoji SVG images are hosted. + * + * @since 4.2.0 + * + * @param string The emoji base URL for svg images. + */ + 'svgUrl' => apply_filters( 'emoji_svg_url', 'https://s.w.org/images/core/emoji/svg/' ), + + /** + * Filter the extension of the emoji SVG files. + * + * @since 4.2.0 + * + * @param string The emoji extension for svg files. Default .svg. + */ + 'svgExt' => apply_filters( 'emoji_svg_ext', '.svg' ), ); $version = 'ver=' . $wp_version; diff --git a/src/wp-includes/js/wp-emoji.js b/src/wp-includes/js/wp-emoji.js index dafcc36fdd..4156f01b5f 100644 --- a/src/wp-includes/js/wp-emoji.js +++ b/src/wp-includes/js/wp-emoji.js @@ -3,6 +3,9 @@ function wpEmoji() { var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver, + // Compression and maintain local scope + document = window.document, + // Private twemoji, timer, loaded = false, @@ -10,6 +13,25 @@ ie11 = window.navigator.userAgent.indexOf( 'Trident/7.0' ) > 0; /** + * Detect if the browser supports SVG. + * + * @since 4.6.0 + * + * @return {Boolean} True if the browser supports svg, false if not. + */ + function browserSupportsSvgAsImage() { + if ( !! document.implementation.hasFeature ) { + // Source: Modernizr + // https://github.com/Modernizr/Modernizr/blob/master/feature-detects/svg/asimg.js + return document.implementation.hasFeature( 'http://www.w3.org/TR/SVG11/feature#Image', '1.1' ); + } + + // document.implementation.hasFeature is deprecated. It can be presumed + // if future browsers remove it, the browser will support SVGs as images. + return true; + } + + /** * Runs when the document load event is fired, so we can do our first parse of the page. * * @since 4.2.0 @@ -141,8 +163,8 @@ args = args || {}; params = { - base: settings.baseUrl, - ext: settings.ext, + base: browserSupportsSvgAsImage() ? settings.svgUrl : settings.baseUrl, + ext: browserSupportsSvgAsImage() ? settings.svgExt : settings.ext, className: args.className || 'emoji', callback: function( icon, options ) { // Ignore some standard characters that TinyMCE recommends in its character map. diff --git a/tests/phpunit/tests/formatting/Emoji.php b/tests/phpunit/tests/formatting/Emoji.php new file mode 100644 index 0000000000..6045747ac0 --- /dev/null +++ b/tests/phpunit/tests/formatting/Emoji.php @@ -0,0 +1,68 @@ +<?php + +/** + * @group formatting + */ +class Tests_Formatting_Emoji extends WP_UnitTestCase { + /** + * @ticket 36525 + */ + public function test_unfiltered_emoji_cdns() { + $png_cdn = 'https://s.w.org/images/core/emoji/72x72/'; + $svn_cdn = 'https://s.w.org/images/core/emoji/svg/'; + + $output = get_echo( '_print_emoji_detection_script' ); + + $this->assertContains( wp_json_encode( $png_cdn ), $output ); + $this->assertContains( wp_json_encode( $svn_cdn ), $output ); + } + + public function _filtered_emoji_svn_cdn( $cdn = '' ) { + return 'https://s.wordpress.org/images/core/emoji/svg/'; + } + + /** + * @ticket 36525 + */ + public function test_filtered_emoji_svn_cdn() { + $png_cdn = 'https://s.w.org/images/core/emoji/72x72/'; + $svn_cdn = 'https://s.w.org/images/core/emoji/svg/'; + + $filtered_svn_cdn = $this->_filtered_emoji_svn_cdn(); + + add_filter( 'emoji_svg_url', array( $this, '_filtered_emoji_svn_cdn' ) ); + + $output = get_echo( '_print_emoji_detection_script' ); + + $this->assertContains( wp_json_encode( $png_cdn ), $output ); + $this->assertNotContains( wp_json_encode( $svn_cdn ), $output ); + $this->assertContains( wp_json_encode( $filtered_svn_cdn ), $output ); + + remove_filter( 'emoji_svg_url', array( $this, '_filtered_emoji_svn_cdn' ) ); + } + + public function _filtered_emoji_png_cdn( $cdn = '' ) { + return 'https://s.wordpress.org/images/core/emoji/png_cdn/'; + } + + /** + * @ticket 36525 + */ + public function test_filtered_emoji_png_cdn() { + $png_cdn = 'https://s.w.org/images/core/emoji/72x72/'; + $svn_cdn = 'https://s.w.org/images/core/emoji/svg/'; + + $filtered_png_cdn = $this->_filtered_emoji_png_cdn(); + + add_filter( 'emoji_url', array( $this, '_filtered_emoji_png_cdn' ) ); + + $output = get_echo( '_print_emoji_detection_script' ); + + $this->assertContains( wp_json_encode( $filtered_png_cdn ), $output ); + $this->assertNotContains( wp_json_encode( $png_cdn ), $output ); + $this->assertContains( wp_json_encode( $svn_cdn ), $output ); + + remove_filter( 'emoji_url', array( $this, '_filtered_emoji_png_cdn' ) ); + } + +} |