WordPress.org

Make WordPress Core

Changeset 31875


Ignore:
Timestamp:
03/24/2015 11:32:23 PM (6 years ago)
Author:
pento
Message:

Emoji: Instead of loading the emoji JS files automatically, we now include a small JS shim in the header, to test if the user's browser needs Twemoji. It then loads the emoji JS files only if they're needed.

Props pento, azaozz.

Fixes #31701.

Location:
trunk
Files:
1 added
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/Gruntfile.js

    r31796 r31875  
    465465                ],
    466466                dest: BUILD_DIR + 'wp-includes/js/tinymce/wp-tinymce.js'
     467            },
     468            emoji: {
     469                options: {
     470                    separator: '\n',
     471                    process: function( src, filepath ) {
     472                        return '// Source: ' + filepath.replace( BUILD_DIR, '' ) + '\n' + src;
     473                    }
     474                },
     475                src: [
     476                    BUILD_DIR + 'wp-includes/js/twemoji.min.js',
     477                    BUILD_DIR + 'wp-includes/js/wp-emoji.min.js'
     478                ],
     479                dest: BUILD_DIR + 'wp-includes/js/wp-emoji-release.min.js'
    467480            }
    468481        },
     
    501514                ],
    502515                dest: SOURCE_DIR
     516            }
     517        },
     518        includes: {
     519            emoji: {
     520                src: BUILD_DIR + 'wp-includes/formatting.php',
     521                dest: '.'
    503522            }
    504523        },
     
    616635        'compress:tinymce',
    617636        'clean:tinymce',
     637        'concat:emoji',
     638        'includes:emoji',
    618639        'jsvalidate:build'
    619640    ] );
  • trunk/package.json

    r31802 r31875  
    2323    "grunt-contrib-uglify": "~0.8.0",
    2424    "grunt-contrib-watch": "~0.6.1",
     25    "grunt-includes": "~0.4.5",
    2526    "grunt-jsvalidate": "~0.2.2",
    2627    "grunt-legacy-util": "^0.2.0",
  • trunk/src/wp-includes/default-filters.php

    r31791 r31875  
    214214add_action( 'publish_future_post', 'check_and_publish_future_post',   10, 1 );
    215215add_action( 'wp_head',             'noindex',                          1    );
     216add_action( 'wp_head',             'print_emoji_detection_script',     7    );
    216217add_action( 'wp_head',             'wp_print_styles',                  8    );
    217218add_action( 'wp_head',             'wp_print_head_scripts',            9    );
  • trunk/src/wp-includes/formatting.php

    r31864 r31875  
    40834083 */
    40844084function print_emoji_styles() {
     4085    static $printed = false;
     4086
     4087    if ( $printed ) {
     4088        return;
     4089    }
     4090
     4091    $printed = true;
    40854092?>
    40864093<style type="text/css">
     
    40994106</style>
    41004107<?php
     4108}
     4109
     4110function print_emoji_detection_script() {
     4111    global $wp_version;
     4112    static $printed = false;
     4113
     4114    if ( $printed ) {
     4115        return;
     4116    }
     4117
     4118    $printed = true;
     4119
     4120    $settings = array(
     4121        /**
     4122         * Filter the URL where emoji images are hosted.
     4123         *
     4124         * @since 4.2.0
     4125         *
     4126         * @param string The emoji base URL.
     4127         */
     4128        'baseUrl' => apply_filters( 'emoji_url', set_url_scheme( '//s0.wp.com/wp-content/mu-plugins/emoji/twemoji/72x72' ) ),
     4129
     4130        /**
     4131         * Filter the extension of the emoji files.
     4132         *
     4133         * @since 4.2.0
     4134         *
     4135         * @param string The emoji extension. Default .png.
     4136         */
     4137        'ext'     => apply_filters( 'emoji_ext', '.png' ),
     4138    );
     4139
     4140    $version = 'ver=' . $wp_version;
     4141
     4142    if ( SCRIPT_DEBUG ) {
     4143        $settings['source'] = array(
     4144            'wpemoji' => includes_url( "js/wp-emoji.js?$version" ),
     4145            'twemoji' => includes_url( "js/twemoji.js?$version" ),
     4146        );
     4147
     4148        ?>
     4149        <script type="text/javascript">
     4150            window._wpemojiSettings = <?php echo wp_json_encode( $settings ); ?>;
     4151            <?php readfile( ABSPATH . WPINC . "/js/wp-emoji-loader.js" ); ?>
     4152        </script>
     4153        <?php
     4154    } else {
     4155        $settings['source'] = array(
     4156            'concatemoji' => includes_url( "js/wp-emoji-release.min.js?$version" ),
     4157        );
     4158
     4159        ?>
     4160        <script type="text/javascript">
     4161            window._wpemojiSettings = <?php echo wp_json_encode( $settings ); ?>;
     4162            include "js/wp-emoji-loader.min.js"
     4163        </script>
     4164        <?php
     4165    }
    41014166}
    41024167
     
    41644229    }
    41654230
    4166     /** This filter is documented in wp-includes/script-loader.php */
     4231    /** This filter is documented in wp-includes/formatting.php */
    41674232    $cdn_url = apply_filters( 'emoji_url', set_url_scheme( '//s0.wp.com/wp-content/mu-plugins/emoji/twemoji/72x72/' ) );
    41684233
    4169     /** This filter is documented in wp-includes/script-loader.php */
     4234    /** This filter is documented in wp-includes/formatting.php */
    41704235    $ext = apply_filters( 'emoji_ext', '.png' );
    41714236
  • trunk/src/wp-includes/js/wp-emoji.js

    r31869 r31875  
    11
    2 ( function( window, twemoji, settings ) {
     2( function( window, settings ) {
    33    function wpEmoji() {
    44        var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver,
     
    2929         * @var Boolean
    3030         */
    31         replaceEmoji = false;
     31        replaceEmoji = false,
     32
     33        // Private
     34        twemoji, timer,
     35        count = 0;
    3236
    3337        /**
     
    3741         */
    3842        function load() {
     43            if ( typeof window.twemoji === 'undefined' ) {
     44                // Break if waiting for longer than 30 sec.
     45                if ( count > 600 ) {
     46                    return;
     47                }
     48
     49                // Still waiting.
     50                window.clearTimeout( timer );
     51                timer = window.setTimeout( load, 50 );
     52                count++;
     53
     54                return;
     55            }
     56
     57            twemoji = window.twemoji;
     58
    3959            if ( MutationObserver ) {
    4060                new MutationObserver( function( mutationRecords ) {
     
    6484
    6585            parse( document.body );
    66         }
    67 
    68         /**
    69          * Detect if the browser supports rendering emoji or flag emoji. Flag emoji are a single glyph
    70          * made of two characters, so some browsers (notably, Firefox OS X) don't support them.
    71          *
    72          * @since 4.2.0
    73          *
    74          * @param type {String} Whether to test for support of "simple" or "flag" emoji.
    75          * @return {Boolean} True if the browser can render emoji, false if it cannot.
    76          */
    77         function browserSupportsEmoji( type ) {
    78             var canvas = document.createElement( 'canvas' ),
    79                 context = canvas.getContext && canvas.getContext( '2d' );
    80 
    81             if ( ! context || ! context.fillText ) {
    82                 return false;
    83             }
    84 
    85             /*
    86              * Chrome on OS X added native emoji rendering in M41. Unfortunately,
    87              * it doesn't work when the font is bolder than 500 weight. So, we
    88              * check for bold rendering support to avoid invisible emoji in Chrome.
    89              */
    90             context.textBaseline = 'top';
    91             context.font = '600 32px Arial';
    92 
    93             if ( type === 'flag' ) {
    94                 /*
    95                  * This works because the image will be one of three things:
    96                  * - Two empty squares, if the browser doesn't render emoji
    97                  * - Two squares with 'G' and 'B' in them, if the browser doesn't render flag emoji
    98                  * - The British flag
    99                  *
    100                  * The first two will encode to small images (1-2KB data URLs), the third will encode
    101                  * to a larger image (4-5KB data URL).
    102                  */
    103                 context.fillText( String.fromCharCode( 55356, 56812, 55356, 56807 ), 0, 0 );
    104                 return canvas.toDataURL().length > 3000;
    105             } else {
    106                 /*
    107                  * This creates a smiling emoji, and checks to see if there is any image data in the
    108                  * center pixel. In browsers that don't support emoji, the character will be rendered
    109                  * as an empty square, so the center pixel will be blank.
    110                  */
    111                 context.fillText( String.fromCharCode( 55357, 56835 ), 0, 0 );
    112                 return context.getImageData( 16, 16, 1, 1 ).data[0] !== 0;
    113             }
    11486        }
    11587
     
    158130        }
    159131
     132        // Load when the readyState changes to 'interactive', not 'complete'.
     133        function onLoad() {
     134            if ( 'interactive' === document.readyState ) {
     135                load();
     136            }
     137        }
     138
    160139        /**
    161140         * Initialize our emoji support, and set up listeners.
    162141         */
    163         if ( twemoji && settings ) {
    164             supportsEmoji = browserSupportsEmoji();
    165             supportsFlagEmoji = browserSupportsEmoji( 'flag' );
     142        if ( settings ) {
     143            supportsEmoji = window._wpemojiSettings.supports.simple;
     144            supportsFlagEmoji = window._wpemojiSettings.supports.flag;
    166145            replaceEmoji = ! supportsEmoji || ! supportsFlagEmoji;
    167146
    168             if ( window.addEventListener ) {
    169                 window.addEventListener( 'load', load, false );
    170             } else if ( window.attachEvent ) {
    171                 window.attachEvent( 'onload', load );
     147            if ( 'loading' == document.readyState ) {
     148                if ( document.addEventListener ) {
     149                    document.addEventListener( 'readystatechange', onLoad, false );
     150                } else if ( document.attachEvent ) {
     151                    document.attachEvent( 'onreadystatechange', onLoad );
     152                }
     153            } else {
     154                load();
    172155            }
    173156        }
    174157
    175158        return {
    176             browserSupportsEmoji: browserSupportsEmoji,
    177159            replaceEmoji: replaceEmoji,
    178160            parse: parse
     
    183165    window.wp.emoji = new wpEmoji();
    184166
    185 } )( window, window.twemoji, window._wpemojiSettings );
     167} )( window, window._wpemojiSettings );
  • trunk/src/wp-includes/script-loader.php

    r31797 r31875  
    425425    $scripts->add( 'mce-view', "/wp-includes/js/mce-view$suffix.js", array( 'shortcode', 'media-models', 'media-audiovideo', 'wp-playlist' ), false, 1 );
    426426
    427     $scripts->add( 'twemoji', "/wp-includes/js/twemoji$suffix.js", array(), '1.3.2', 1 );
    428     $scripts->add( 'emoji', "/wp-includes/js/wp-emoji$suffix.js", array( 'twemoji' ), false, 1 );
    429     did_action( 'init' ) && $scripts->localize( 'emoji', '_wpemojiSettings', array(
    430         /**
    431          * Filter the URL where emoji images are hosted.
    432          *
    433          * @since 4.2.0
    434          *
    435          * @param string The emoji base URL.
    436          */
    437         'baseUrl' => apply_filters( 'emoji_url', '//s0.wp.com/wp-content/mu-plugins/emoji/twemoji/72x72' ),
    438 
    439         /**
    440          * Filter the extension of the emoji files.
    441          *
    442          * @since 4.2.0
    443          *
    444          * @param string The emoji extension. Default .png.
    445          */
    446         'ext'      => apply_filters( 'emoji_ext', '.png' ),
    447     ) );
    448     $scripts->enqueue( 'emoji' );
    449 
    450427    if ( is_admin() ) {
    451428        $scripts->add( 'admin-tags', "/wp-admin/js/tags$suffix.js", array( 'jquery', 'wp-ajax-response' ), false, 1 );
Note: See TracChangeset for help on using the changeset viewer.