WordPress.org

Make WordPress Core

Ticket #22229: 22229.4.diff

File 22229.4.diff, 11.2 KB (added by ericlewis, 6 years ago)
  • src/wp-includes/class.wp-dependencies.php

    diff --git src/wp-includes/class.wp-dependencies.php src/wp-includes/class.wp-dependencies.php
    index c1bac65..e6b6288 100644
    class WP_Dependencies { 
    201201        }
    202202
    203203        /**
     204         * Adds dependencies
     205         * @param string $handle Script name
     206         * @param array|string $deps Either an array of handles to become dependancies, or a single string dependancy
     207         * @rerurn bool success
     208         */
     209        function add_deps( $handle, $deps ) {
     210                if ( !isset( $this->registered[$handle] ) ) {
     211                        return false;
     212                }
     213                return $this->registered[$handle]->add_deps( $deps );
     214        }
     215
     216        /**
    204217         * Register an item.
    205218         *
    206219         * Registers the item if no item of that name already exists.
    class _WP_Dependency { 
    506519                return true;
    507520        }
    508521
     522        function add_deps( $deps ) {
     523                if ( is_string( $deps ) ) {
     524                        $deps = array( $deps );
     525                }
     526                if ( !is_array( $deps ) ) {
     527                        return false;
     528                }
     529                $this->deps = array_merge( $this->deps, $deps );
     530                return true;
     531        }
    509532} // _WP_Dependencies
  • src/wp-includes/class.wp-scripts.php

    diff --git src/wp-includes/class.wp-scripts.php src/wp-includes/class.wp-scripts.php
    index 89a9ec9..2083e58 100644
    class WP_Scripts extends WP_Dependencies { 
    104104                $src = $this->registered[$handle]->src;
    105105
    106106                if ( $this->do_concat ) {
     107                        if ( 'inline' == $src ) {
     108                                $this->print_code .= $this->print_extra_script( $handle, false );
     109                                return true;
     110                        }
    107111                        /**
    108112                         * Filter the script loader source.
    109113                         *
    class WP_Scripts extends WP_Dependencies { 
    125129                }
    126130
    127131                $this->print_extra_script( $handle );
     132
     133                if ( 'inline' == $src ) {
     134                        return true;
     135                }
     136
    128137                if ( !preg_match('|^(https?:)?//|', $src) && ! ( $this->content_url && 0 === strpos($src, $this->content_url) ) ) {
    129138                        $src = $this->base_url . $src;
    130139                }
    class WP_Scripts extends WP_Dependencies { 
    166175
    167176                        $l10n[$key] = html_entity_decode( (string) $value, ENT_QUOTES, 'UTF-8');
    168177                }
     178                $literals = WP_JS_Literal::find( $l10n );
    169179
    170                 $script = "var $object_name = " . json_encode($l10n) . ';';
     180                $this->add_deps_from_literals( $handle, $literals );
     181
     182                $script = "var $object_name = " . WP_JS_Literal::json_encode( $l10n, $literals ) . ';';
    171183
    172184                if ( !empty($after) )
    173185                        $script .= "\n$after;";
    class WP_Scripts extends WP_Dependencies { 
    180192                return $this->add_data( $handle, 'data', $script );
    181193        }
    182194
     195        private function add_deps_from_literals( $handle, $literals ) {
     196                foreach( $literals as $literal ) {
     197                        $this->add_deps( $handle, $literal->get_deps() );
     198                }
     199        }
     200
    183201        public function set_group( $handle, $recursion, $group = false ) {
    184202
    185203                if ( $this->registered[$handle]->args === 1 )
    class WP_Scripts extends WP_Dependencies { 
    245263                $this->ext_handles = '';
    246264        }
    247265}
     266
     267/**
     268 * Represents a literal JS text, which should not be JSON-encoded
     269 *
     270 * Used when localizing a script to tell the script loader not to encode
     271 * this specific values and to load any additional dependancies this piece
     272 * of code might have.
     273 */
     274class WP_JS_Literal {
     275        private $text;
     276        private $deps;
     277
     278        public function __construct( $js_text, $deps = array() ) {
     279                $this->text = $js_text;
     280                if ( is_string( $deps ) ) {
     281                        $this->deps = array( $deps );
     282                } elseif ( is_array( $deps ) ) {
     283                        $this->deps = $deps;
     284                } else {
     285                        $deps = array();
     286                }
     287        }
     288
     289        public function get_text() {
     290                return $this->text;
     291        }
     292
     293        public function get_deps() {
     294                return $this->deps;
     295        }
     296
     297        static public function json_encode( $value, $literals = null ) {
     298                if ( !$literals ) {
     299                        $literals = self::find( $value );
     300                }
     301                $encoded = json_encode( $value );
     302                return self::replace_literals_with_their_texts( $literals, $encoded );
     303        }
     304
     305        private static function replace_literals_with_their_texts( $literals, $json_encoded ) {
     306                $replaces_from = array();
     307                $replaces_to = array();
     308                foreach( $literals as $literal ) {
     309                        $replaces_from[] = json_encode( $literal );
     310                        $replaces_to[] = $literal->get_text();
     311                }
     312                return str_replace( $replaces_from, $replaces_to, $json_encoded );
     313        }
     314
     315        public static function find( $value ) {
     316                if ( !is_array( $value ) && !is_object( $value ) ) {
     317                        return array();
     318                }
     319                if ( is_a( $value, 'WP_JS_Literal' ) ) {
     320                        return array( $value );
     321                }
     322                $literals = array();
     323                foreach( $value as &$item ) {
     324                        $literals += self::find( $item );
     325                }
     326                return $literals;
     327        }
     328}
  • src/wp-includes/functions.wp-scripts.php

    diff --git src/wp-includes/functions.wp-scripts.php src/wp-includes/functions.wp-scripts.php
    index 4e3bda7..d194991 100644
    function wp_script_is( $handle, $list = 'enqueued' ) { 
    256256
    257257        return (bool) $wp_scripts->query( $handle, $list );
    258258}
     259
     260function wp_js_make_literal( $js_text, $deps = array() ) {
     261        $literal = new WP_JS_Literal( $js_text, $deps );
     262        return $literal;
     263}
  • src/wp-includes/l10n.php

    diff --git src/wp-includes/l10n.php src/wp-includes/l10n.php
    index ed5b224..92adbc9 100644
    function esc_html_x( $text, $context, $domain = 'default' ) { 
    289289        return esc_html( translate_with_gettext_context( $text, $context, $domain ) );
    290290}
    291291
     292function _n_js( $singular, $plural, $domain = 'default' ) {
     293        return translate_plural_for_js( $singular, $plural, null, $domain );
     294}
     295
     296function _nx_js( $singular, $plural, $context, $domain = 'default' ) {
     297        return translate_plural_for_js( $singular, $plural, $context, $domain );
     298}
     299
     300function translate_plural_for_js( $singular, $plural, $context, $domain ) {
     301        $translations = get_translations_for_domain( $domain );
     302        $entry = new Translation_Entry( array( 'singular' => $singular, 'plural' => $plural, 'context' => $context ) );
     303        if ( $translated = $translations->translate_entry( $entry ) ) {
     304                $js_translations = json_encode( $translated->translations );
     305                $js_domain = esc_js( $domain );
     306                return wp_js_make_literal( "wp.i18n.make_plural($js_translations, '$js_domain')", 'i18n-make-plural' );
     307        } else {
     308                $js_originals = json_encode( array( $singular, $plural ) );
     309                return wp_js_make_literal( "wp.i18n.make_plural($js_originals)", 'i18n-make-plural' );
     310        }
     311}
     312
     313function wp_i18n_js_make_plural_defintion() {
     314        $json_encoded_plural_info = wp_i18n_get_json_encoded_domains_plural_info();
     315        return <<<JS
     316window.wp = window.wp || {};
     317window.wp.i18n = window.wp.i18n || {};
     318wp.i18n.domains_plural_info = $json_encoded_plural_info;
     319wp.i18n.english_plural_info = {nplurals: 2, choose: function(n) { return n != 1;}};
     320wp.i18n.make_plural = function(translations, domain) {
     321        var domain_plural_info = wp.i18n.domains_plural_info[domain] || wp.i18n.english_plural_info;
     322        return function(n) {
     323                var i = domain_plural_info['choose'](n);
     324                if (typeof i === 'boolean') i = i ? 1 : 0;
     325                return i >=0 && i < domain_plural_info['nplurals']? translations[i] : null;
     326        }
     327}
     328JS;
     329}
     330
     331function wp_i18n_get_json_encoded_domains_plural_info() {
     332        global $l10n;
     333        $domains_plural_info = array();
     334        foreach( $l10n as $domain => $translations ) {
     335                list( $nplurals, $expression ) = $translations->nplurals_and_expression();
     336                $domains_plural_info[$domain] = array(
     337                        'nplurals' => $nplurals,
     338                        'choose' => wp_js_make_literal( "function(n) { return $expression; }" ),
     339                );
     340        }
     341        return WP_JS_Literal::json_encode( $domains_plural_info );
     342}
     343
    292344/**
    293345 * Retrieve the plural or single form based on the supplied amount.
    294346 *
  • src/wp-includes/pomo/translations.php

    diff --git src/wp-includes/pomo/translations.php src/wp-includes/pomo/translations.php
    index 5ad316c..16edc7f 100644
    class Gettext_Translations extends Translations { 
    142142         */
    143143        function gettext_select_plural_form($count) {
    144144                if (!isset($this->_gettext_select_plural_form) || is_null($this->_gettext_select_plural_form)) {
    145                         list( $nplurals, $expression ) = $this->nplurals_and_expression_from_header($this->get_header('Plural-Forms'));
     145                        list( $nplurals, $expression ) = $this->nplurals_and_expression();
    146146                        $this->_nplurals = $nplurals;
    147147                        $this->_gettext_select_plural_form = $this->make_plural_form_function($nplurals, $expression);
    148148                }
    class Gettext_Translations extends Translations { 
    159159                }
    160160        }
    161161
     162        function nplurals_and_expression() {
     163                $header = $this->get_header( 'Plural-Forms' );
     164                return $this->nplurals_and_expression_from_header( $header );
     165        }
     166
    162167        /**
    163168         * Makes a function, which will return the right translation index, according to the
    164169         * plural forms header
    endif; 
    229234
    230235if ( !class_exists( 'NOOP_Translations' ) ):
    231236/**
    232  * Provides the same interface as Translations, but doesn't do anything
     237 * Provides the same interface as Gettext_Translations, but doesn't do anything
     238 *
     239 * Used for domains without any translations to make sure we neither have special cases,
     240 * nor look for translations on every translate call.
    233241 */
    234 class NOOP_Translations {
     242class NOOP_Translations extends Gettext_Translations {
    235243        var $entries = array();
    236244        var $headers = array();
    237245
  • src/wp-includes/script-loader.php

    diff --git src/wp-includes/script-loader.php src/wp-includes/script-loader.php
    index 154393f..54d6782 100644
    function wp_default_scripts( &$scripts ) { 
    7777                'secure' => (string) ( 'https' === parse_url( site_url(), PHP_URL_SCHEME ) ),
    7878        ) );
    7979
     80        $scripts->add( 'i18n-make-plural', 'inline' );
     81        $scripts->add_data( 'i18n-make-plural', 'data', wp_i18n_js_make_plural_defintion() );
     82
    8083        $scripts->add( 'common', "/wp-admin/js/common$suffix.js", array('jquery', 'hoverIntent', 'utils'), false, 1 );
    8184        did_action( 'init' ) && $scripts->localize( 'common', 'commonL10n', array(
    82                 'warnDelete' => __("You are about to permanently delete the selected items.\n  'Cancel' to stop, 'OK' to delete.")
     85                'warnDelete' => __("You are about to permanently delete the selected items.\n  'Cancel' to stop, 'OK' to delete."),
    8386        ) );
    8487
    8588        $scripts->add( 'sack', "/wp-includes/js/tw-sack$suffix.js", array(), '1.6.1', 1 );
  • tests/phpunit/tests/dependencies.php

    diff --git tests/phpunit/tests/dependencies.php tests/phpunit/tests/dependencies.php
    index 5f9f579..d231805 100644
    class Tests_Dependencies extends WP_UnitTestCase { 
    136136                $this->assertFalse( $dep->query( 'one' ) );
    137137
    138138        }
     139
     140        function test_add_deps_should_add_one_string_dep() {
     141                $dep = new WP_Dependencies;
     142                $dep->add( 'baba', '', array( 'dep0' ) );
     143                $dep->add_deps( 'baba', 'new-dep' );
     144                $this->assertEquals( array( 'dep0', 'new-dep' ), $dep->query( 'baba' )->deps );
     145        }
     146
     147        function test_add_deps_should_merge_deps() {
     148                $dep = new WP_Dependencies;
     149                $dep->add( 'baba', '', array( 'dep0' ) );
     150                $dep->add_deps( 'baba', array( 'new-dep', 'another-dep' ) );
     151                $this->assertEquals( array( 'dep0', 'new-dep', 'another-dep' ), $dep->query( 'baba' )->deps );
     152        }
     153
     154        function test_add_deps_should_return_false_on_non_string_non_array_deps() {
     155                $dep = new WP_Dependencies;
     156                $dep->add( 'baba', '', array( 'dep0' ) );
     157                $this->assertFalse( $dep->add_deps( 'baba', 5 ) );
     158        }
     159
     160        function test_add_deps_should_return_false_on_non_registered_handle() {
     161                $dep = new WP_Dependencies;
     162                $this->assertFalse( $dep->add_deps( 'baba', 'dep0' ) );
     163        }
    139164}