From 9c56cf2cf70093a0c5a75c95440c7c4c2351f775 Mon Sep 17 00:00:00 2001 From: Felix Arntz Date: Mon, 6 Feb 2023 21:38:15 +0000 Subject: [PATCH] Emoji: Fix emoji feature detection. The emoji feature detection that occurs on every page load by default has been broken at least since [45769], causing the feature detection to fail for browsers that in fact support emoji correctly. This has led to the `wp-emoji-release.min.js` file being loaded unnecessarily even in modern browsers, which accounts for roughly 4.7 KB of extra JavaScript on every page load. This changeset fixes the feature detection, by using the correct sequences of char codes. Props sergiomdgomes, dmsnell, peterwilsoncc. Fixes #57301. Built from https://develop.svn.wordpress.org/trunk@55241 git-svn-id: http://core.svn.wordpress.org/trunk@54774 1a063a9b-81f0-0310-95a4-ce76da25c4cd --- wp-includes/js/wp-emoji-loader.js | 38 ++++++++++++--------------- wp-includes/js/wp-emoji-loader.min.js | 2 +- wp-includes/version.php | 2 +- 3 files changed, 19 insertions(+), 23 deletions(-) diff --git a/wp-includes/js/wp-emoji-loader.js b/wp-includes/js/wp-emoji-loader.js index 0b5f3c7749..536b839f0e 100644 --- a/wp-includes/js/wp-emoji-loader.js +++ b/wp-includes/js/wp-emoji-loader.js @@ -16,32 +16,27 @@ * * @private * - * @param {number[]} set1 Set of Emoji character codes. - * @param {number[]} set2 Set of Emoji character codes. + * @param {string} set1 Set of Emoji to test. + * @param {string} set2 Set of Emoji to test. * * @return {boolean} True if the two sets render the same. */ function emojiSetsRenderIdentically( set1, set2 ) { - var stringFromCharCode = String.fromCharCode; - // Cleanup from previous test. context.clearRect( 0, 0, canvas.width, canvas.height ); - context.fillText( stringFromCharCode.apply( this, set1 ), 0, 0 ); + context.fillText( set1, 0, 0 ); var rendered1 = canvas.toDataURL(); // Cleanup from previous test. context.clearRect( 0, 0, canvas.width, canvas.height ); - context.fillText( stringFromCharCode.apply( this, set2 ), 0, 0 ); + context.fillText( set2, 0, 0 ); var rendered2 = canvas.toDataURL(); return rendered1 === rendered2; } /** - * Detects if the browser supports rendering emoji or flag emoji. - * - * Flag emoji are a single glyph made of two characters, so some browsers - * (notably, Firefox OS X) don't support them. + * Determines if the browser properly renders Emoji that Twemoji can supplement. * * @since 4.2.0 * @@ -69,15 +64,14 @@ switch ( type ) { case 'flag': /* - * Test for Transgender flag compatibility. This flag is shortlisted for the Emoji 13 spec, - * but has landed in Twemoji early, so we can add support for it, too. + * Test for Transgender flag compatibility. Added in Unicode 13. * * To test for support, we try to render it, and compare the rendering to how it would look if * the browser doesn't render it correctly (white flag emoji + transgender symbol). */ isIdentical = emojiSetsRenderIdentically( - [ 0x1F3F3, 0xFE0F, 0x200D, 0x26A7, 0xFE0F ], - [ 0x1F3F3, 0xFE0F, 0x200B, 0x26A7, 0xFE0F ] + '\uD83C\uDFF3\uFE0F\u200D\u26A7\uFE0F', // as a zero-width joiner sequence + '\uD83C\uDFF3\uFE0F\u200B\u26A7\uFE0F' // separated by a zero-width space ); if ( isIdentical ) { @@ -92,8 +86,8 @@ * the browser doesn't render it correctly ([U] + [N]). */ isIdentical = emojiSetsRenderIdentically( - [ 0xD83C, 0xDDFA, 0xD83C, 0xDDF3 ], - [ 0xD83C, 0xDDFA, 0x200B, 0xD83C, 0xDDF3 ] + '\uD83C\uDDFA\uD83C\uDDF3', // as the sequence of two code points + '\uD83C\uDDFA\u200B\uD83C\uDDF3' // as the two code points separated by a zero-width space ); if ( isIdentical ) { @@ -102,14 +96,16 @@ /* * Test for English flag compatibility. England is a country in the United Kingdom, it - * does not have a two letter locale code but rather an five letter sub-division code. + * does not have a two letter locale code but rather a five letter sub-division code. * * To test for support, we try to render it, and compare the rendering to how it would look if * the browser doesn't render it correctly (black flag emoji + [G] + [B] + [E] + [N] + [G]). */ isIdentical = emojiSetsRenderIdentically( - [ 0xD83C, 0xDFF4, 0xDB40, 0xDC67, 0xDB40, 0xDC62, 0xDB40, 0xDC65, 0xDB40, 0xDC6E, 0xDB40, 0xDC67, 0xDB40, 0xDC7F ], - [ 0xD83C, 0xDFF4, 0x200B, 0xDB40, 0xDC67, 0x200B, 0xDB40, 0xDC62, 0x200B, 0xDB40, 0xDC65, 0x200B, 0xDB40, 0xDC6E, 0x200B, 0xDB40, 0xDC67, 0x200B, 0xDB40, 0xDC7F ] + // as the flag sequence + '\uD83C\uDFF4\uDB40\uDC67\uDB40\uDC62\uDB40\uDC65\uDB40\uDC6E\uDB40\uDC67\uDB40\uDC7F', + // with each code point separated by a zero-width space + '\uD83C\uDFF4\u200B\uDB40\uDC67\u200B\uDB40\uDC62\u200B\uDB40\uDC65\u200B\uDB40\uDC6E\u200B\uDB40\uDC67\u200B\uDB40\uDC7F' ); return ! isIdentical; @@ -133,8 +129,8 @@ * sequence come from older emoji standards. */ isIdentical = emojiSetsRenderIdentically( - [0x1FAF1, 0x1F3FB, 0x200D, 0x1FAF2, 0x1F3FF], - [0x1FAF1, 0x1F3FB, 0x200B, 0x1FAF2, 0x1F3FF] + '\uD83E\uDEF1\uD83C\uDFFB\u200D\uD83E\uDEF2\uD83C\uDFFF', // as the zero-width joiner sequence + '\uD83E\uDEF1\uD83C\uDFFB\u200B\uD83E\uDEF2\uD83C\uDFFF' // separated by a zero-width space ); return ! isIdentical; diff --git a/wp-includes/js/wp-emoji-loader.min.js b/wp-includes/js/wp-emoji-loader.min.js index 3b57fef6f8..3669dc910d 100644 --- a/wp-includes/js/wp-emoji-loader.min.js +++ b/wp-includes/js/wp-emoji-loader.min.js @@ -1,2 +1,2 @@ /*! This file is auto-generated */ -!function(e,a,t){var n,r,o,i=a.createElement("canvas"),p=i.getContext&&i.getContext("2d");function s(e,t){var a=String.fromCharCode,e=(p.clearRect(0,0,i.width,i.height),p.fillText(a.apply(this,e),0,0),i.toDataURL());return p.clearRect(0,0,i.width,i.height),p.fillText(a.apply(this,t),0,0),e===i.toDataURL()}function c(e){var t=a.createElement("script");t.src=e,t.defer=t.type="text/javascript",a.getElementsByTagName("head")[0].appendChild(t)}for(o=Array("flag","emoji"),t.supports={everything:!0,everythingExceptFlag:!0},r=0;r