[ Index ]

PHP Cross Reference of WordPress

title

Body

[close]

/wp-includes/js/ -> wp-emoji-loader.js (source)

   1  /**
   2   * @output wp-includes/js/wp-emoji-loader.js
   3   */
   4  
   5  ( function( window, document, settings ) {
   6      var src, ready, ii, tests;
   7  
   8      // Create a canvas element for testing native browser support of emoji.
   9      var canvas = document.createElement( 'canvas' );
  10      var context = canvas.getContext && canvas.getContext( '2d' );
  11  
  12      /**
  13       * Checks if two sets of Emoji characters render the same visually.
  14       *
  15       * @since 4.9.0
  16       *
  17       * @private
  18       *
  19       * @param {number[]} set1 Set of Emoji character codes.
  20       * @param {number[]} set2 Set of Emoji character codes.
  21       *
  22       * @return {boolean} True if the two sets render the same.
  23       */
  24  	function emojiSetsRenderIdentically( set1, set2 ) {
  25          var stringFromCharCode = String.fromCharCode;
  26  
  27          // Cleanup from previous test.
  28          context.clearRect( 0, 0, canvas.width, canvas.height );
  29          context.fillText( stringFromCharCode.apply( this, set1 ), 0, 0 );
  30          var rendered1 = canvas.toDataURL();
  31  
  32          // Cleanup from previous test.
  33          context.clearRect( 0, 0, canvas.width, canvas.height );
  34          context.fillText( stringFromCharCode.apply( this, set2 ), 0, 0 );
  35          var rendered2 = canvas.toDataURL();
  36  
  37          return rendered1 === rendered2;
  38      }
  39  
  40      /**
  41       * Detects if the browser supports rendering emoji or flag emoji.
  42       *
  43       * Flag emoji are a single glyph made of two characters, so some browsers
  44       * (notably, Firefox OS X) don't support them.
  45       *
  46       * @since 4.2.0
  47       *
  48       * @private
  49       *
  50       * @param {string} type Whether to test for support of "flag" or "emoji".
  51       *
  52       * @return {boolean} True if the browser can render emoji, false if it cannot.
  53       */
  54  	function browserSupportsEmoji( type ) {
  55          var isIdentical;
  56  
  57          if ( ! context || ! context.fillText ) {
  58              return false;
  59          }
  60  
  61          /*
  62           * Chrome on OS X added native emoji rendering in M41. Unfortunately,
  63           * it doesn't work when the font is bolder than 500 weight. So, we
  64           * check for bold rendering support to avoid invisible emoji in Chrome.
  65           */
  66          context.textBaseline = 'top';
  67          context.font = '600 32px Arial';
  68  
  69          switch ( type ) {
  70              case 'flag':
  71                  /*
  72                   * Test for Transgender flag compatibility. This flag is shortlisted for the Emoji 13 spec,
  73                   * but has landed in Twemoji early, so we can add support for it, too.
  74                   *
  75                   * To test for support, we try to render it, and compare the rendering to how it would look if
  76                   * the browser doesn't render it correctly (white flag emoji + transgender symbol).
  77                   */
  78                  isIdentical = emojiSetsRenderIdentically(
  79                      [ 0x1F3F3, 0xFE0F, 0x200D, 0x26A7, 0xFE0F ],
  80                      [ 0x1F3F3, 0xFE0F, 0x200B, 0x26A7, 0xFE0F ]
  81                  );
  82  
  83                  if ( isIdentical ) {
  84                      return false;
  85                  }
  86  
  87                  /*
  88                   * Test for UN flag compatibility. This is the least supported of the letter locale flags,
  89                   * so gives us an easy test for full support.
  90                   *
  91                   * To test for support, we try to render it, and compare the rendering to how it would look if
  92                   * the browser doesn't render it correctly ([U] + [N]).
  93                   */
  94                  isIdentical = emojiSetsRenderIdentically(
  95                      [ 0xD83C, 0xDDFA, 0xD83C, 0xDDF3 ],
  96                      [ 0xD83C, 0xDDFA, 0x200B, 0xD83C, 0xDDF3 ]
  97                  );
  98  
  99                  if ( isIdentical ) {
 100                      return false;
 101                  }
 102  
 103                  /*
 104                   * Test for English flag compatibility. England is a country in the United Kingdom, it
 105                   * does not have a two letter locale code but rather an five letter sub-division code.
 106                   *
 107                   * To test for support, we try to render it, and compare the rendering to how it would look if
 108                   * the browser doesn't render it correctly (black flag emoji + [G] + [B] + [E] + [N] + [G]).
 109                   */
 110                  isIdentical = emojiSetsRenderIdentically(
 111                      [ 0xD83C, 0xDFF4, 0xDB40, 0xDC67, 0xDB40, 0xDC62, 0xDB40, 0xDC65, 0xDB40, 0xDC6E, 0xDB40, 0xDC67, 0xDB40, 0xDC7F ],
 112                      [ 0xD83C, 0xDFF4, 0x200B, 0xDB40, 0xDC67, 0x200B, 0xDB40, 0xDC62, 0x200B, 0xDB40, 0xDC65, 0x200B, 0xDB40, 0xDC6E, 0x200B, 0xDB40, 0xDC67, 0x200B, 0xDB40, 0xDC7F ]
 113                  );
 114  
 115                  return ! isIdentical;
 116              case 'emoji':
 117                  /*
 118                   * So easy, even a baby could do it!
 119                   *
 120                   *  To test for Emoji 13 support, try to render a new emoji: Man Feeding Baby.
 121                   *
 122                   * The Man Feeding Baby emoji is a ZWJ sequence combining 👨 Man, a Zero Width Joiner and 🍼 Baby Bottle.
 123                   *
 124                   * 0xD83D, 0xDC68 == Man emoji.
 125                   * 0x200D == Zero-Width Joiner (ZWJ) that links the two code points for the new emoji or
 126                   * 0x200B == Zero-Width Space (ZWS) that is rendered for clients not supporting the new emoji.
 127                   * 0xD83C, 0xDF7C == Baby Bottle.
 128                   *
 129                   * When updating this test for future Emoji releases, ensure that individual emoji that make up the
 130                   * sequence come from older emoji standards.
 131                   */
 132                  isIdentical = emojiSetsRenderIdentically(
 133                      [0xD83D, 0xDC68, 0x200D, 0xD83C, 0xDF7C],
 134                      [0xD83D, 0xDC68, 0x200B, 0xD83C, 0xDF7C]
 135                  );
 136  
 137                  return ! isIdentical;
 138          }
 139  
 140          return false;
 141      }
 142  
 143      /**
 144       * Adds a script to the head of the document.
 145       *
 146       * @ignore
 147       *
 148       * @since 4.2.0
 149       *
 150       * @param {Object} src The url where the script is located.
 151       * @return {void}
 152       */
 153  	function addScript( src ) {
 154          var script = document.createElement( 'script' );
 155  
 156          script.src = src;
 157          script.defer = script.type = 'text/javascript';
 158          document.getElementsByTagName( 'head' )[0].appendChild( script );
 159      }
 160  
 161      tests = Array( 'flag', 'emoji' );
 162  
 163      settings.supports = {
 164          everything: true,
 165          everythingExceptFlag: true
 166      };
 167  
 168      /*
 169       * Tests the browser support for flag emojis and other emojis, and adjusts the
 170       * support settings accordingly.
 171       */
 172      for( ii = 0; ii < tests.length; ii++ ) {
 173          settings.supports[ tests[ ii ] ] = browserSupportsEmoji( tests[ ii ] );
 174  
 175          settings.supports.everything = settings.supports.everything && settings.supports[ tests[ ii ] ];
 176  
 177          if ( 'flag' !== tests[ ii ] ) {
 178              settings.supports.everythingExceptFlag = settings.supports.everythingExceptFlag && settings.supports[ tests[ ii ] ];
 179          }
 180      }
 181  
 182      settings.supports.everythingExceptFlag = settings.supports.everythingExceptFlag && ! settings.supports.flag;
 183  
 184      // Sets DOMReady to false and assigns a ready function to settings.
 185      settings.DOMReady = false;
 186      settings.readyCallback = function() {
 187          settings.DOMReady = true;
 188      };
 189  
 190      // When the browser can not render everything we need to load a polyfill.
 191      if ( ! settings.supports.everything ) {
 192          ready = function() {
 193              settings.readyCallback();
 194          };
 195  
 196          /*
 197           * Cross-browser version of adding a dom ready event.
 198           */
 199          if ( document.addEventListener ) {
 200              document.addEventListener( 'DOMContentLoaded', ready, false );
 201              window.addEventListener( 'load', ready, false );
 202          } else {
 203              window.attachEvent( 'onload', ready );
 204              document.attachEvent( 'onreadystatechange', function() {
 205                  if ( 'complete' === document.readyState ) {
 206                      settings.readyCallback();
 207                  }
 208              } );
 209          }
 210  
 211          src = settings.source || {};
 212  
 213          if ( src.concatemoji ) {
 214              addScript( src.concatemoji );
 215          } else if ( src.wpemoji && src.twemoji ) {
 216              addScript( src.twemoji );
 217              addScript( src.wpemoji );
 218          }
 219      }
 220  
 221  } )( window, document, window._wpemojiSettings );


Generated: Tue May 18 01:00:05 2021 Cross-referenced by PHPXref 0.7.1