WordPress.org

Make WordPress Core

Ticket #22229: js-plurals.diff

File js-plurals.diff, 10.1 KB (added by nbachiyski, 18 months 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 );