diff --git a/src/js/_enqueues/wp/emoji.js b/src/js/_enqueues/wp/emoji.js index 274868f52d859..5d6fbcfbc9853 100644 --- a/src/js/_enqueues/wp/emoji.js +++ b/src/js/_enqueues/wp/emoji.js @@ -235,9 +235,18 @@ return false; } + /* + * When only the flag test failed, replace flags and nothing else. The list covers + * every kind of flag that test checks (country, subdivision and ZWJ flags), so a + * failing flag is never left to a font that cannot draw it. + */ if ( settings.supports.everythingExceptFlag && - ! /^1f1(?:e[6-9a-f]|f[0-9a-f])-1f1(?:e[6-9a-f]|f[0-9a-f])$/.test( icon ) && // Country flags. - ! /^(1f3f3-fe0f-200d-1f308|1f3f4-200d-2620-fe0f)$/.test( icon ) // Rainbow and pirate flags. + // Country flags. + ! /^1f1(?:e[6-9a-f]|f[0-9a-f])-1f1(?:e[6-9a-f]|f[0-9a-f])$/.test( icon ) && + // Subdivision flags, such as England: a black flag, tag characters, and a cancel tag. + ! /^1f3f4(?:-e00[2-7][0-9a-f])+-e007f$/.test( icon ) && + // Rainbow, transgender and pirate flags. + ! /^(1f3f3-fe0f-200d-1f308|1f3f3-fe0f-200d-26a7-fe0f|1f3f4-200d-2620-fe0f)$/.test( icon ) ) { return false; } diff --git a/tests/qunit/wp-includes/js/emoji-flags.html b/tests/qunit/wp-includes/js/emoji-flags.html new file mode 100644 index 0000000000000..4e6691398b8ea --- /dev/null +++ b/tests/qunit/wp-includes/js/emoji-flags.html @@ -0,0 +1,34 @@ + + + + wp.emoji flag fallback QUnit Test Suite + + + + + + + +
+
+ + + + + + + diff --git a/tests/qunit/wp-includes/js/emoji-flags.js b/tests/qunit/wp-includes/js/emoji-flags.js new file mode 100644 index 0000000000000..b3cbb87bfe35a --- /dev/null +++ b/tests/qunit/wp-includes/js/emoji-flags.js @@ -0,0 +1,78 @@ +( function( QUnit ) { + /* + * wp-emoji.js is loaded with `everythingExceptFlag`: the browser renders emoji but failed the + * flag test. Every kind of flag that test checks must then be replaced by an image, and nothing + * else. See https://core.trac.wordpress.org/ticket/63451. + */ + QUnit.module( 'wp.emoji flag fallback' ); + + function imageSources( html ) { + var container = document.createElement( 'div' ); + + container.innerHTML = html; + return Array.prototype.map.call( container.querySelectorAll( 'img.emoji' ), function( img ) { + return img.getAttribute( 'src' ); + } ); + } + + QUnit.test( 'replaces a country flag', function( assert ) { + var sources = imageSources( window.wp.emoji.parse( '\uD83C\uDDF0\uD83C\uDDF7' ) ); // Flag: South Korea. + + assert.strictEqual( sources.length, 1, 'one image' ); + assert.ok( /\/1f1f0-1f1f7\.(svg|png)$/.test( sources[0] ), 'for 1f1f0-1f1f7' ); + } ); + + QUnit.test( 'replaces the England flag', function( assert ) { + var sources = imageSources( window.wp.emoji.parse( '\uD83C\uDFF4\uDB40\uDC67\uDB40\uDC62\uDB40\uDC65\uDB40\uDC6E\uDB40\uDC67\uDB40\uDC7F' ) ); // Flag: England. + + assert.strictEqual( sources.length, 1, 'one image' ); + assert.ok( /\/1f3f4-e0067-e0062-e0065-e006e-e0067-e007f\.(svg|png)$/.test( sources[0] ), 'for 1f3f4-e0067-e0062-e0065-e006e-e0067-e007f' ); + } ); + + QUnit.test( 'replaces the Scotland flag', function( assert ) { + var sources = imageSources( window.wp.emoji.parse( '\uD83C\uDFF4\uDB40\uDC67\uDB40\uDC62\uDB40\uDC73\uDB40\uDC63\uDB40\uDC74\uDB40\uDC7F' ) ); // Flag: Scotland. + + assert.strictEqual( sources.length, 1, 'one image' ); + assert.ok( /\/1f3f4-e0067-e0062-e0073-e0063-e0074-e007f\.(svg|png)$/.test( sources[0] ), 'for 1f3f4-e0067-e0062-e0073-e0063-e0074-e007f' ); + } ); + + QUnit.test( 'replaces the Wales flag', function( assert ) { + var sources = imageSources( window.wp.emoji.parse( '\uD83C\uDFF4\uDB40\uDC67\uDB40\uDC62\uDB40\uDC77\uDB40\uDC6C\uDB40\uDC73\uDB40\uDC7F' ) ); // Flag: Wales. + + assert.strictEqual( sources.length, 1, 'one image' ); + assert.ok( /\/1f3f4-e0067-e0062-e0077-e006c-e0073-e007f\.(svg|png)$/.test( sources[0] ), 'for 1f3f4-e0067-e0062-e0077-e006c-e0073-e007f' ); + } ); + + QUnit.test( 'replaces the transgender flag', function( assert ) { + var sources = imageSources( window.wp.emoji.parse( '\uD83C\uDFF3\uFE0F\u200D\u26A7\uFE0F' ) ); // Transgender flag. + + assert.strictEqual( sources.length, 1, 'one image' ); + assert.ok( /\/1f3f3-fe0f-200d-26a7-fe0f\.(svg|png)$/.test( sources[0] ), 'for 1f3f3-fe0f-200d-26a7-fe0f' ); + } ); + + QUnit.test( 'replaces the rainbow flag', function( assert ) { + var sources = imageSources( window.wp.emoji.parse( '\uD83C\uDFF3\uFE0F\u200D\uD83C\uDF08' ) ); // Rainbow flag. + + assert.strictEqual( sources.length, 1, 'one image' ); + assert.ok( /\/1f3f3-fe0f-200d-1f308\.(svg|png)$/.test( sources[0] ), 'for 1f3f3-fe0f-200d-1f308' ); + } ); + + QUnit.test( 'replaces the pirate flag', function( assert ) { + var sources = imageSources( window.wp.emoji.parse( '\uD83C\uDFF4\u200D\u2620\uFE0F' ) ); // Pirate flag. + + assert.strictEqual( sources.length, 1, 'one image' ); + assert.ok( /\/1f3f4-200d-2620-fe0f\.(svg|png)$/.test( sources[0] ), 'for 1f3f4-200d-2620-fe0f' ); + } ); + + QUnit.test( 'leaves an emoji that is not a flag as text', function( assert ) { + var text = '\uD83D\uDE00'; // Grinning face. + + assert.strictEqual( window.wp.emoji.parse( text ), text ); + } ); + + QUnit.test( 'leaves a black flag on its own as text', function( assert ) { + var text = '\uD83C\uDFF4'; // Black flag. + + assert.strictEqual( window.wp.emoji.parse( text ), text ); + } ); +} )( window.QUnit );