[ 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                   * Why can't we be friends? Everyone can now shake hands in emoji, regardless of skin tone!
 119                   *
 120                   * To test for Emoji 14.0 support, try to render a new emoji: Handshake: Light Skin Tone, Dark Skin Tone.
 121                   *
 122                   * The Handshake: Light Skin Tone, Dark Skin Tone emoji is a ZWJ sequence combining 🫱 Rightwards Hand,
 123                   * 🏻 Light Skin Tone, a Zero Width Joiner, 🫲 Leftwards Hand, and 🏿 Dark Skin Tone.
 124                   *
 125                   * 0x1FAF1 == Rightwards Hand
 126                   * 0x1F3FB == Light Skin Tone
 127                   * 0x200D == Zero-Width Joiner (ZWJ) that links the code points for the new emoji or
 128                   * 0x200B == Zero-Width Space (ZWS) that is rendered for clients not supporting the new emoji.
 129                   * 0x1FAF2 == Leftwards Hand
 130                   * 0x1F3FF == Dark Skin Tone.
 131                   *
 132                   * When updating this test for future Emoji releases, ensure that individual emoji that make up the
 133                   * sequence come from older emoji standards.
 134                   */
 135                  isIdentical = emojiSetsRenderIdentically(
 136                      [0x1FAF1, 0x1F3FB, 0x200D, 0x1FAF2, 0x1F3FF],
 137                      [0x1FAF1, 0x1F3FB, 0x200B, 0x1FAF2, 0x1F3FF]
 138                  );
 139  
 140                  return ! isIdentical;
 141          }
 142  
 143          return false;
 144      }
 145  
 146      /**
 147       * Adds a script to the head of the document.
 148       *
 149       * @ignore
 150       *
 151       * @since 4.2.0
 152       *
 153       * @param {Object} src The url where the script is located.
 154       * @return {void}
 155       */
 156  	function addScript( src ) {
 157          var script = document.createElement( 'script' );
 158  
 159          script.src = src;
 160          script.defer = script.type = 'text/javascript';
 161          document.getElementsByTagName( 'head' )[0].appendChild( script );
 162      }
 163  
 164      tests = Array( 'flag', 'emoji' );
 165  
 166      settings.supports = {
 167          everything: true,
 168          everythingExceptFlag: true
 169      };
 170  
 171      /*
 172       * Tests the browser support for flag emojis and other emojis, and adjusts the
 173       * support settings accordingly.
 174       */
 175      for( ii = 0; ii < tests.length; ii++ ) {
 176          settings.supports[ tests[ ii ] ] = browserSupportsEmoji( tests[ ii ] );
 177  
 178          settings.supports.everything = settings.supports.everything && settings.supports[ tests[ ii ] ];
 179  
 180          if ( 'flag' !== tests[ ii ] ) {
 181              settings.supports.everythingExceptFlag = settings.supports.everythingExceptFlag && settings.supports[ tests[ ii ] ];
 182          }
 183      }
 184  
 185      settings.supports.everythingExceptFlag = settings.supports.everythingExceptFlag && ! settings.supports.flag;
 186  
 187      // Sets DOMReady to false and assigns a ready function to settings.
 188      settings.DOMReady = false;
 189      settings.readyCallback = function() {
 190          settings.DOMReady = true;
 191      };
 192  
 193      // When the browser can not render everything we need to load a polyfill.
 194      if ( ! settings.supports.everything ) {
 195          ready = function() {
 196              settings.readyCallback();
 197          };
 198  
 199          /*
 200           * Cross-browser version of adding a dom ready event.
 201           */
 202          if ( document.addEventListener ) {
 203              document.addEventListener( 'DOMContentLoaded', ready, false );
 204              window.addEventListener( 'load', ready, false );
 205          } else {
 206              window.attachEvent( 'onload', ready );
 207              document.attachEvent( 'onreadystatechange', function() {
 208                  if ( 'complete' === document.readyState ) {
 209                      settings.readyCallback();
 210                  }
 211              } );
 212          }
 213  
 214          src = settings.source || {};
 215  
 216          if ( src.concatemoji ) {
 217              addScript( src.concatemoji );
 218          } else if ( src.wpemoji && src.twemoji ) {
 219              addScript( src.twemoji );
 220              addScript( src.wpemoji );
 221          }
 222      }
 223  
 224  } )( window, document, window._wpemojiSettings );


Generated: Tue Apr 23 01:00:02 2024 Cross-referenced by PHPXref 0.7.1