<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[36816] trunk/src/wp-includes/js: Emoji: Clean up the emoji browser support tests.</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta" style="font-size: 105%">
<dt style="float: left; width: 6em; font-weight: bold">Revision</dt> <dd><a style="font-weight: bold" href="https://core.trac.wordpress.org/changeset/36816">36816</a><script type="application/ld+json">{"@context":"http://schema.org","@type":"EmailMessage","description":"Review this Commit","action":{"@type":"ViewAction","url":"https://core.trac.wordpress.org/changeset/36816","name":"Review Commit"}}</script></dd>
<dt style="float: left; width: 6em; font-weight: bold">Author</dt> <dd>pento</dd>
<dt style="float: left; width: 6em; font-weight: bold">Date</dt> <dd>2016-03-03 05:16:53 +0000 (Thu, 03 Mar 2016)</dd>
</dl>

<pre style='padding-left: 1em; margin: 2em 0; border-left: 2px solid #ccc; line-height: 1.25; font-size: 105%; font-family: sans-serif'>Emoji: Clean up the emoji browser support tests.

As new sets of emoji are added to Unicode, and browsers add support for them at random intervals, we'll inevitably need to add new tests to the emoji loader. This change makes it much easier to add new tests as they're needed.

Fixes <a href="https://core.trac.wordpress.org/ticket/35300">#35300</a>.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunksrcwpincludesjswpemojiloaderjs">trunk/src/wp-includes/js/wp-emoji-loader.js</a></li>
<li><a href="#trunksrcwpincludesjswpemojijs">trunk/src/wp-includes/js/wp-emoji.js</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunksrcwpincludesjswpemojiloaderjs"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/js/wp-emoji-loader.js</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/js/wp-emoji-loader.js       2016-03-03 04:58:45 UTC (rev 36815)
+++ trunk/src/wp-includes/js/wp-emoji-loader.js 2016-03-03 05:16:53 UTC (rev 36816)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1,5 +1,5 @@
</span><span class="cx" style="display: block; padding: 0 10px"> ( function( window, document, settings ) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        var src, ready;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ var src, ready, ii, tests;
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        /**
</span><span class="cx" style="display: block; padding: 0 10px">         * Detect if the browser supports rendering emoji or flag emoji. Flag emoji are a single glyph
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -7,7 +7,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">         *
</span><span class="cx" style="display: block; padding: 0 10px">         * @since 4.2.0
</span><span class="cx" style="display: block; padding: 0 10px">         *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-         * @param type {String} Whether to test for support of "simple" or "flag" emoji.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+  * @param type {String} Whether to test for support of "simple", "flag", "diversity" or "unicode8" emoji.
</ins><span class="cx" style="display: block; padding: 0 10px">          * @return {Boolean} True if the browser can render emoji, false if it cannot.
</span><span class="cx" style="display: block; padding: 0 10px">         */
</span><span class="cx" style="display: block; padding: 0 10px">        function browserSupportsEmoji( type ) {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -28,46 +28,48 @@
</span><span class="cx" style="display: block; padding: 0 10px">                context.textBaseline = 'top';
</span><span class="cx" style="display: block; padding: 0 10px">                context.font = '600 32px Arial';
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                if ( 'flag' === type ) {
-                       /*
-                        * This works because the image will be one of three things:
-                        * - Two empty squares, if the browser doesn't render emoji
-                        * - Two squares with 'A' and 'U' in them, if the browser doesn't render flag emoji
-                        * - The Australian 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).
-                        */
-                       context.fillText( stringFromCharCode( 55356, 56806, 55356, 56826 ), 0, 0 );
-                       return canvas.toDataURL().length > 3000;
-               } else if ( 'diversity' === type ) {
-                       /*
-                        * This tests if the browser supports the Emoji Diversity specification, by rendering an
-                        * emoji with no skin tone specified (in this case, Santa). It then adds a skin tone, and
-                        * compares if the emoji rendering has changed.
-                        */
-                       context.fillText( stringFromCharCode( 55356, 57221 ), 0, 0 );
-                       tone = context.getImageData( 16, 16, 1, 1 ).data.toString();
-                       context.fillText( stringFromCharCode( 55356, 57221, 55356, 57343 ), 0, 0 );
-                       // Chrome has issues comparing arrays, so we compare it as a  string, instead.
-                       return tone !== context.getImageData( 16, 16, 1, 1 ).data.toString();
-               } else {
-                       if ( 'simple' === type ) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         switch ( type ) {
+                       case 'flag':
</ins><span class="cx" style="display: block; padding: 0 10px">                                 /*
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                 * This works because the image will be one of three things:
+                                * - Two empty squares, if the browser doesn't render emoji
+                                * - Two squares with 'A' and 'U' in them, if the browser doesn't render flag emoji
+                                * - The Australian 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).
+                                */
+                               context.fillText( stringFromCharCode( 55356, 56806, 55356, 56826 ), 0, 0 );
+                               return canvas.toDataURL().length > 3000;
+                       case 'diversity':
+                               /*
+                                * This tests if the browser supports the Emoji Diversity specification, by rendering an
+                                * emoji with no skin tone specified (in this case, Santa). It then adds a skin tone, and
+                                * compares if the emoji rendering has changed.
+                                */
+                               context.fillText( stringFromCharCode( 55356, 57221 ), 0, 0 );
+                               tone = context.getImageData( 16, 16, 1, 1 ).data.toString();
+                               context.fillText( stringFromCharCode( 55356, 57221, 55356, 57343 ), 0, 0 );
+                               // Chrome has issues comparing arrays, so we compare it as a  string, instead.
+                               return tone !== context.getImageData( 16, 16, 1, 1 ).data.toString();
+                       case 'simple':
+                               /*
</ins><span class="cx" style="display: block; padding: 0 10px">                                  * This creates a smiling emoji, and checks to see if there is any image data in the
</span><span class="cx" style="display: block; padding: 0 10px">                                 * center pixel. In browsers that don't support emoji, the character will be rendered
</span><span class="cx" style="display: block; padding: 0 10px">                                 * as an empty square, so the center pixel will be blank.
</span><span class="cx" style="display: block; padding: 0 10px">                                 */
</span><span class="cx" style="display: block; padding: 0 10px">                                context.fillText( stringFromCharCode( 55357, 56835 ), 0, 0 );
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        } else {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         return context.getImageData( 16, 16, 1, 1 ).data[0] !== 0;
+                       case 'unicode8':
</ins><span class="cx" style="display: block; padding: 0 10px">                                 /*
</span><span class="cx" style="display: block; padding: 0 10px">                                 * To check for Unicode 8 support, let's try rendering the most important advancement
</span><span class="cx" style="display: block; padding: 0 10px">                                 * that the Unicode Consortium have made in years: the burrito.
</span><span class="cx" style="display: block; padding: 0 10px">                                 */
</span><span class="cx" style="display: block; padding: 0 10px">                                context.fillText( stringFromCharCode( 55356, 57135 ), 0, 0 );
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        }
-                       return context.getImageData( 16, 16, 1, 1 ).data[0] !== 0;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         return context.getImageData( 16, 16, 1, 1 ).data[0] !== 0;
</ins><span class="cx" style="display: block; padding: 0 10px">                 }
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
+               return false;
</ins><span class="cx" style="display: block; padding: 0 10px">         }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        function addScript( src ) {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -78,19 +80,30 @@
</span><span class="cx" style="display: block; padding: 0 10px">                document.getElementsByTagName( 'head' )[0].appendChild( script );
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+        tests = Array( 'simple', 'flag', 'unicode8', 'diversity' );
+
</ins><span class="cx" style="display: block; padding: 0 10px">         settings.supports = {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                simple:    browserSupportsEmoji( 'simple' ),
-               flag:      browserSupportsEmoji( 'flag' ),
-               unicode8:  browserSupportsEmoji( 'unicode8' ),
-               diversity: browserSupportsEmoji( 'diversity' )
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         everything: true
</ins><span class="cx" style="display: block; padding: 0 10px">         };
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+        for( ii = 0; ii < tests.length; ii++ ) {
+               settings.supports[ tests[ ii ] ] = browserSupportsEmoji( tests[ ii ] );
+
+               settings.supports.everything = settings.supports.everything && settings.supports[ tests[ ii ] ];
+
+               if ( 'flag' !== tests[ ii ] ) {
+                       settings.supports.everythingExceptFlag = settings.supports.everythingExceptFlag && settings.supports[ tests[ ii ] ];
+               }
+       }
+
+       settings.supports.everythingExceptFlag = settings.supports.everythingExceptFlag && ! settings.supports.flag;
+
</ins><span class="cx" style="display: block; padding: 0 10px">         settings.DOMReady = false;
</span><span class="cx" style="display: block; padding: 0 10px">        settings.readyCallback = function() {
</span><span class="cx" style="display: block; padding: 0 10px">                settings.DOMReady = true;
</span><span class="cx" style="display: block; padding: 0 10px">        };
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        if ( ! settings.supports.simple || ! settings.supports.flag || ! settings.supports.unicode8 || ! settings.supports.diversity ) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if ( ! settings.supports.everything ) {
</ins><span class="cx" style="display: block; padding: 0 10px">                 ready = function() {
</span><span class="cx" style="display: block; padding: 0 10px">                        settings.readyCallback();
</span><span class="cx" style="display: block; padding: 0 10px">                };
</span></span></pre></div>
<a id="trunksrcwpincludesjswpemojijs"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/js/wp-emoji.js</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/js/wp-emoji.js      2016-03-03 04:58:45 UTC (rev 36815)
+++ trunk/src/wp-includes/js/wp-emoji.js        2016-03-03 05:16:53 UTC (rev 36816)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -124,7 +124,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                function parse( object, args ) {
</span><span class="cx" style="display: block; padding: 0 10px">                        var params;
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        if ( ! replaceEmoji || ! twemoji || ! object ||
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 if ( settings.supports.everything || ! twemoji || ! object ||
</ins><span class="cx" style="display: block; padding: 0 10px">                                 ( 'string' !== typeof object && ( ! object.childNodes || ! object.childNodes.length ) ) ) {
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                                return object;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -136,6 +136,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                                ext: settings.ext,
</span><span class="cx" style="display: block; padding: 0 10px">                                className: args.className || 'emoji',
</span><span class="cx" style="display: block; padding: 0 10px">                                callback: function( icon, options ) {
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                        var keys, ii;
</ins><span class="cx" style="display: block; padding: 0 10px">                                         // Ignore some standard characters that TinyMCE recommends in its character map.
</span><span class="cx" style="display: block; padding: 0 10px">                                        switch ( icon ) {
</span><span class="cx" style="display: block; padding: 0 10px">                                                case 'a9':
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -149,8 +150,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                                                        return false;
</span><span class="cx" style="display: block; padding: 0 10px">                                        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                        if ( ! settings.supports.flag && settings.supports.simple && settings.supports.unicode8 && settings.supports.diversity &&
-                                               ! /^1f1(?:e[6-9a-f]|f[0-9a-f])-1f1(?:e[6-9a-f]|f[0-9a-f])$/.test( icon ) ) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                 if ( settings.supports.everythingExceptFlag && ! /^1f1(?:e[6-9a-f]|f[0-9a-f])-1f1(?:e[6-9a-f]|f[0-9a-f])$/.test( icon ) ) {
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                                                return false;
</span><span class="cx" style="display: block; padding: 0 10px">                                        }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -178,8 +178,6 @@
</span><span class="cx" style="display: block; padding: 0 10px">                 * Initialize our emoji support, and set up listeners.
</span><span class="cx" style="display: block; padding: 0 10px">                 */
</span><span class="cx" style="display: block; padding: 0 10px">                if ( settings ) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        replaceEmoji = ! settings.supports.simple || ! settings.supports.flag || ! settings.supports.unicode8 || ! settings.supports.diversity;
-
</del><span class="cx" style="display: block; padding: 0 10px">                         if ( settings.DOMReady ) {
</span><span class="cx" style="display: block; padding: 0 10px">                                load();
</span><span class="cx" style="display: block; padding: 0 10px">                        } else {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -188,7 +186,6 @@
</span><span class="cx" style="display: block; padding: 0 10px">                }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                return {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        replaceEmoji: replaceEmoji,
</del><span class="cx" style="display: block; padding: 0 10px">                         parse: parse,
</span><span class="cx" style="display: block; padding: 0 10px">                        test: test
</span><span class="cx" style="display: block; padding: 0 10px">                };
</span></span></pre>
</div>
</div>

</body>
</html>