WordPress.org

Make WordPress Core

Ticket #22229: js-plurals.diff

File js-plurals.diff, 10.1 KB (added by nbachiyski, 8 years ago)
  • wp-includes/class.wp-dependencies.php

     
    149149        }
    150150
    151151        /**
     152         * Adds dependencies
     153         *
     154         * @param string $handle Script name
     155         * @param array|string $deps Either an array of handles to become dependancies, or a single string dependancy
     156         * @rerurn bool success
     157         */
     158        function add_deps( $handle, $deps ) {
     159                if ( !isset( $this->registered[$handle] ) )
     160                        return false;
     161
     162                return $this->registered[$handle]->add_deps( $deps );
     163        }
     164
     165        /**
    152166         * Get extra data
    153167         *
    154168         * Gets data associated with a certain handle.
     
    258272                $this->extra[$name] = $data;
    259273                return true;
    260274        }
     275
     276        function add_deps( $deps ) {
     277                if ( is_string( $deps ) ) {
     278                        $deps = array( $deps );
     279                }
     280                if ( !is_array( $deps ) ) {
     281                        return false;
     282                }
     283                $this->deps = array_merge( $this->deps, $deps );
     284                return true;
     285        }
    261286}
  • wp-includes/class.wp-scripts.php

     
    1717 * @since r16
    1818 */
    1919class WP_Scripts extends WP_Dependencies {
     20
    2021        var $base_url; // Full URL with trailing slash
    2122        var $content_url;
    2223        var $default_version;
     
    9798                $src = $this->registered[$handle]->src;
    9899
    99100                if ( $this->do_concat ) {
     101                        if ( 'inline' == $src ) {
     102                                $this->print_code .= $this->print_extra_script( $handle, false );
     103                                return true;
     104                        }
    100105                        $srce = apply_filters( 'script_loader_src', $src, $handle );
    101106                        if ( $this->in_default_dir($srce) ) {
    102107                                $this->print_code .= $this->print_extra_script( $handle, false );
     
    110115                }
    111116
    112117                $this->print_extra_script( $handle );
     118
     119                if ( 'inline' == $src ) {
     120                        return true;
     121                }
     122
    113123                if ( !preg_match('|^(https?:)?//|', $src) && ! ( $this->content_url && 0 === strpos($src, $this->content_url) ) ) {
    114124                        $src = $this->base_url . $src;
    115125                }
     
    144154
    145155                        $l10n[$key] = html_entity_decode( (string) $value, ENT_QUOTES, 'UTF-8');
    146156                }
     157                $literals = WP_JS_Literal::find( $l10n );
    147158
    148                 $script = "var $object_name = " . json_encode($l10n) . ';';
     159                $this->add_deps_from_literals( $handle, $literals );
    149160
     161                $script = "var $object_name = " . WP_JS_Literal::json_encode( $l10n, $literals ) . ';';
     162
    150163                if ( !empty($after) )
    151164                        $script .= "\n$after;";
    152165
     
    155168                if ( !empty( $data ) )
    156169                        $script = "$data\n$script";
    157170
     171                $this->add_data( $handle, 'data', 'dudu' );
     172
    158173                return $this->add_data( $handle, 'data', $script );
    159174        }
    160175
     176        private function add_deps_from_literals( $handle, $literals ) {
     177                foreach( $literals as $literal ) {
     178                        $this->add_deps( $handle, $literal->get_deps() );
     179                }
     180        }
     181
    161182        function set_group( $handle, $recursion, $group = false ) {
    162183
    163184                if ( $this->registered[$handle]->args === 1 )
     
    212233                $this->ext_handles = '';
    213234        }
    214235}
     236
     237/**
     238 * Represents a literal JS text, which should not be JSON-encoded
     239 *
     240 * Used when localizing a script to tell the script loader not to encode
     241 * this specific values and to load any additional dependancies this piece
     242 * of code might have.
     243 */
     244class WP_JS_Literal {
     245        private $text;
     246        private $deps;
     247
     248        public function __construct( $js_text, $deps = array() ) {
     249                $this->text = $js_text;
     250                if ( is_string( $deps ) ) {
     251                        $this->deps = array( $deps );
     252                } elseif ( is_array( $deps ) ) {
     253                        $this->deps = $deps;
     254                } else {
     255                        $deps = array();
     256                }
     257        }
     258
     259        public function get_text() {
     260                return $this->text;
     261        }
     262
     263        public function get_deps() {
     264                return $this->deps;
     265        }
     266
     267        static public function json_encode( $value, $literals = null ) {
     268                if ( !$literals ) {
     269                        $literals = self::find( $value );
     270                }
     271                $encoded = json_encode( $value );
     272                return self::replace_literals_with_their_texts( $literals, $encoded );
     273        }
     274
     275        private static function replace_literals_with_their_texts( $literals, $json_encoded ) {
     276                $replaces_from = array();
     277                $replaces_to = array();
     278                foreach( $literals as $literal ) {
     279                        $replaces_from[] = json_encode( $literal );
     280                        $replaces_to[] = $literal->get_text();
     281                }
     282                return str_replace( $replaces_from, $replaces_to, $json_encoded );
     283        }
     284
     285        public static function find( $value ) {
     286                if ( !is_array( $value ) && !is_object( $value ) ) {
     287                        return array();
     288                }
     289                if ( is_a( $value, 'WP_JS_Literal' ) ) {
     290                        return array( $value );
     291                }
     292                $literals = array();
     293                foreach( $value as &$item ) {
     294                        $literals += self::find( $item );
     295                }
     296                return $literals;
     297        }
     298}
  • wp-includes/functions.wp-scripts.php

     
    183183
    184184        return (bool) $wp_scripts->query( $handle, $list );
    185185}
     186
     187function wp_js_make_literal( $js_text, $deps = array() ) {
     188        $literal = new WP_JS_Literal( $js_text, $deps );
     189        return $literal;
     190}
  • wp-includes/l10n.php

     
    288288        return array( 0 => $singular, 1 => $plural, 2 => $context, 'singular' => $singular, 'plural' => $plural, 'context' => $context, 'domain' => $domain );
    289289}
    290290
     291function _n_js( $singular, $plural, $domain = 'default' ) {
     292        return translate_plural_for_js( $singular, $plural, null, $domain );
     293}
     294
     295function _nx_js( $singular, $plural, $context, $domain = 'default' ) {
     296        return translate_plural_for_js( $singular, $plural, $context, $domain );
     297}
     298
     299function translate_plural_for_js( $singular, $plural, $context, $domain ) {
     300        $translations = get_translations_for_domain( $domain );
     301        $entry = new Translation_Entry( array( 'singular' => $singular, 'plural' => $plural, 'context' => $context ) );
     302        if ( $translated = $translations->translate_entry( $entry ) ) {
     303                $js_translations = json_encode( $translated->translations );
     304                $js_domain = esc_js( $domain );
     305                return wp_js_make_literal( "wp.i18n.make_plural($js_translations, '$js_domain')", 'i18n-make-plural' );
     306        } else {
     307                $js_originals = json_encode( array( $singular, $plural ) );
     308                return wp_js_make_literal( "wp.i18n.make_plural($js_originals)", 'i18n-make-plural' );
     309        }
     310}
     311
     312function wp_i18n_js_make_plural_defintion() {
     313        $json_encoded_plural_info = wp_i18n_get_json_encoded_domains_plural_info();
     314        return <<<JS
     315window.wp = window.wp || {};
     316window.wp.i18n = window.wp.i18n || {};
     317wp.i18n.domains_plural_info = $json_encoded_plural_info;
     318wp.i18n.english_plural_info = {nplurals: 2, choose: function(n) { return n != 1;}};
     319wp.i18n.make_plural = function(translations, domain) {
     320        var domain_plural_info = wp.i18n.domains_plural_info[domain] || wp.i18n.english_plural_info;
     321        return function(n) {
     322                var i = domain_plural_info['choose'](n);
     323                if (typeof i === 'boolean') i = i ? 1 : 0;
     324                return i >=0 && i < domain_plural_info['nplurals']? translations[i] : null;
     325        }
     326}
     327JS;
     328}
     329
     330function wp_i18n_get_json_encoded_domains_plural_info() {
     331        global $l10n;
     332        $domains_plural_info = array();
     333        foreach( $l10n as $domain => $translations ) {
     334                list( $nplurals, $expression ) = $translations->nplurals_and_expression();
     335                $domains_plural_info[$domain] = array(
     336                        'nplurals' => $nplurals,
     337                        'choose' => wp_js_make_literal( "function(n) { return $expression; }" ),
     338                );
     339        }
     340        return WP_JS_Literal::json_encode( $domains_plural_info );
     341}
     342
    291343/**
    292344 * Translate the result of _n_noop() or _nx_noop()
    293345 *
     
    550602        }
    551603
    552604        return $languages;
    553 }
    554  No newline at end of file
     605}
  • wp-includes/pomo/translations.php

     
    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                }
     
    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
     
    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
  • wp-includes/script-loader.php

     
    6161
    6262        $scripts->add( 'utils', "/wp-admin/js/utils$suffix.js" );
    6363
     64        $scripts->add( 'i18n-make-plural', 'inline' );
     65        $scripts->add_data( 'i18n-make-plural', 'data', wp_i18n_js_make_plural_defintion() );
     66
    6467        $scripts->add( 'common', "/wp-admin/js/common$suffix.js", array('jquery', 'hoverIntent', 'utils'), false, 1 );
    6568        did_action( 'init' ) && $scripts->localize( 'common', 'commonL10n', array(
    66                 'warnDelete' => __("You are about to permanently delete the selected items.\n  'Cancel' to stop, 'OK' to delete.")
     69                'warnDelete' => __("You are about to permanently delete the selected items.\n  'Cancel' to stop, 'OK' to delete."),
     70                'baba' => _n_js( 'baba', 'babas' ),
     71                'dudu' => _nx_js( 'dudu', 'dudus', 'cataxta' ),
    6772        ) );
    6873
    6974        $scripts->add( 'sack', "/wp-includes/js/tw-sack$suffix.js", array(), '1.6.1', 1 );