Ticket #22229: 22229.5.diff
File 22229.5.diff, 13.6 KB (added by , 10 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 { 201 201 } 202 202 203 203 /** 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 /** 204 217 * Register an item. 205 218 * 206 219 * Registers the item if no item of that name already exists. … … class _WP_Dependency { 506 519 return true; 507 520 } 508 521 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 } 509 532 } // _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..af553a5 100644
class WP_Scripts extends WP_Dependencies { 104 104 $src = $this->registered[$handle]->src; 105 105 106 106 if ( $this->do_concat ) { 107 if ( 'inline' == $src ) { 108 $this->print_code .= $this->print_extra_script( $handle, false ); 109 return true; 110 } 107 111 /** 108 112 * Filter the script loader source. 109 113 * … … class WP_Scripts extends WP_Dependencies { 125 129 } 126 130 127 131 $this->print_extra_script( $handle ); 132 133 if ( 'inline' == $src ) { 134 return true; 135 } 136 128 137 if ( !preg_match('|^(https?:)?//|', $src) && ! ( $this->content_url && 0 === strpos($src, $this->content_url) ) ) { 129 138 $src = $this->base_url . $src; 130 139 } … … class WP_Scripts extends WP_Dependencies { 166 175 167 176 $l10n[$key] = html_entity_decode( (string) $value, ENT_QUOTES, 'UTF-8'); 168 177 } 178 $literals = WP_JS_Literal::find( $l10n ); 179 180 $this->add_deps_from_literals( $handle, $literals ); 169 181 170 $script = "var $object_name = " . json_encode($l10n) . ';';182 $script = "var $object_name = " . WP_JS_Literal::json_encode( $l10n, $literals ) . ';'; 171 183 172 184 if ( !empty($after) ) 173 185 $script .= "\n$after;"; … … class WP_Scripts extends WP_Dependencies { 180 192 return $this->add_data( $handle, 'data', $script ); 181 193 } 182 194 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 183 201 public function set_group( $handle, $recursion, $group = false ) { 184 202 185 203 if ( $this->registered[$handle]->args === 1 ) … … class WP_Scripts extends WP_Dependencies { 245 263 $this->ext_handles = ''; 246 264 } 247 265 } 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 */ 274 class 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 /** 294 * Get the dependencies for the literal. 295 * 296 * @return array 297 */ 298 public function get_deps() { 299 return $this->deps; 300 } 301 302 /** 303 * JSON-encode a variable, while replacing any JS-literal object representations 304 * with the literal string. 305 * 306 * @param mixed $value Variable to be JSON encoded. 307 * @param array|null $literals 308 * @return string JSON encoded string. 309 */ 310 static public function json_encode( $value, $literals = null ) { 311 if ( !$literals ) { 312 $literals = self::find( $value ); 313 } 314 $encoded = json_encode( $value ); 315 return self::replace_literals_with_their_texts( $literals, $encoded ); 316 } 317 318 /** 319 * Replace the auto-encoded representations of WP_JS_Literal instances in a 320 * JSON blob with their literal representations. 321 * 322 * @param array $literals An array of WP_JS_Literal instances. 323 * @param string $json_encoded The JSON encoded string. 324 * @return string The fixed JSON encoded string. 325 */ 326 private static function replace_literals_with_their_texts( $literals, $json_encoded ) { 327 $replaces_from = array(); 328 $replaces_to = array(); 329 foreach( $literals as $literal ) { 330 $replaces_from[] = json_encode( $literal ); 331 $replaces_to[] = $literal->get_text(); 332 } 333 return str_replace( $replaces_from, $replaces_to, $json_encoded ); 334 } 335 336 /** 337 * Given a variable, find any WP_JS_Literal instances inside it. 338 * 339 * @param mixed $value 340 * @return array WP_JS_Literal instances. 341 */ 342 public static function find( $value ) { 343 if ( !is_array( $value ) && !is_object( $value ) ) { 344 return array(); 345 } 346 if ( is_a( $value, 'WP_JS_Literal' ) ) { 347 return array( $value ); 348 } 349 $literals = array(); 350 foreach( $value as &$item ) { 351 $literals += self::find( $item ); 352 } 353 return $literals; 354 } 355 } -
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..e7b3664 100644
function wp_script_is( $handle, $list = 'enqueued' ) { 256 256 257 257 return (bool) $wp_scripts->query( $handle, $list ); 258 258 } 259 260 /** 261 * Create a WP_JS_Literal object. 262 * 263 * @param string $js_text The javascript literal. 264 * @param string|array $deps Name of the dependent scripts. 265 * @return WP_JS_Literal An instance of WP_JS_Literal. 266 */ 267 function wp_js_make_literal( $js_text, $deps = array() ) { 268 $literal = new WP_JS_Literal( $js_text, $deps ); 269 return $literal; 270 } -
src/wp-includes/l10n.php
diff --git src/wp-includes/l10n.php src/wp-includes/l10n.php index 0719201..f665c8e 100644
function esc_html_x( $text, $context, $domain = 'default' ) { 290 290 } 291 291 292 292 /** 293 * Translate a string for use in Javascript. 294 * 295 * @param string $text Singular form. 296 * @param string $plural Plural form to be i18ned. 297 * @param string $domain Optional. Text domain. Unique identifier for retrieving translated strings. 298 * @return WP_JS_Literal An instance of a WP_JS_Literal. 299 */ 300 function _n_js( $singular, $plural, $domain = 'default' ) { 301 return translate_plural_for_js( $singular, $plural, null, $domain ); 302 } 303 304 /** 305 * Translate a string for use in Javascript with gettext context. 306 * 307 * @param string $text Singular form. 308 * @param string $plural Plural form to be i18ned. 309 * @param string $context Context information for the translators. 310 * @param string $domain Optional. Text domain. Unique identifier for retrieving translated strings. 311 * @return WP_JS_Literal An instance of a WP_JS_Literal. 312 */ 313 function _nx_js( $singular, $plural, $context, $domain = 'default' ) { 314 return translate_plural_for_js( $singular, $plural, $context, $domain ); 315 } 316 317 /** 318 * Translate a string for use in Javascript with gettext context. 319 * 320 * @param string $text Singular form. 321 * @param string $plural Plural form to be i18ned. 322 * @param string $context Context information for the translators. 323 * @param string $domain Optional. Text domain. Unique identifier for retrieving translated strings. 324 * @return WP_JS_Literal An instance of WP_JS_Literal. 325 */ 326 function translate_plural_for_js( $singular, $plural, $context, $domain ) { 327 $translations = get_translations_for_domain( $domain ); 328 $entry = new Translation_Entry( array( 'singular' => $singular, 'plural' => $plural, 'context' => $context ) ); 329 if ( $translated = $translations->translate_entry( $entry ) ) { 330 $js_translations = json_encode( $translated->translations ); 331 $js_domain = esc_js( $domain ); 332 return wp_js_make_literal( "wp.i18n.make_plural($js_translations, '$js_domain')", 'i18n-make-plural' ); 333 } else { 334 $js_originals = json_encode( array( $singular, $plural ) ); 335 return wp_js_make_literal( "wp.i18n.make_plural($js_originals)", 'i18n-make-plural' ); 336 } 337 } 338 339 /** 340 * Create Javascript for the Javascript make_plural function. 341 * 342 * @return string Javascript string. 343 */ 344 function wp_i18n_js_make_plural_definition() { 345 $json_encoded_plural_info = wp_i18n_get_json_encoded_domains_plural_info(); 346 return <<<JS 347 window.wp = window.wp || {}; 348 window.wp.i18n = window.wp.i18n || {}; 349 wp.i18n.domains_plural_info = $json_encoded_plural_info; 350 wp.i18n.english_plural_info = {nplurals: 2, choose: function(n) { return n != 1;}}; 351 /** 352 * A factory function which takes the translated strings and returns a pluralizing 353 * function. 354 */ 355 wp.i18n.make_plural = function(translations, domain) { 356 var domain_plural_info = wp.i18n.domains_plural_info[domain] || wp.i18n.english_plural_info; 357 return function(n) { 358 var i = domain_plural_info['choose'](n); 359 if (typeof i === 'boolean') i = i ? 1 : 0; 360 return i >=0 && i < domain_plural_info['nplurals']? translations[i] : null; 361 } 362 } 363 JS; 364 } 365 366 /** 367 * Get a JSON encoded string of 368 * 369 * @return string JSON encoded string. 370 */ 371 function wp_i18n_get_json_encoded_domains_plural_info() { 372 global $l10n; 373 $domains_plural_info = array(); 374 foreach( $l10n as $domain => $translations ) { 375 list( $nplurals, $expression ) = $translations->nplurals_and_expression(); 376 $domains_plural_info[$domain] = array( 377 'nplurals' => $nplurals, 378 'choose' => wp_js_make_literal( "function(n) { return $expression; }" ), 379 ); 380 } 381 return WP_JS_Literal::json_encode( $domains_plural_info ); 382 } 383 384 /** 293 385 * Retrieve the plural or single form based on the supplied amount. 294 386 * 295 387 * If the text domain is not set in the $l10n list, then a comparison will be made -
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 { 142 142 */ 143 143 function gettext_select_plural_form($count) { 144 144 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(); 146 146 $this->_nplurals = $nplurals; 147 147 $this->_gettext_select_plural_form = $this->make_plural_form_function($nplurals, $expression); 148 148 } … … class Gettext_Translations extends Translations { 159 159 } 160 160 } 161 161 162 function nplurals_and_expression() { 163 $header = $this->get_header( 'Plural-Forms' ); 164 return $this->nplurals_and_expression_from_header( $header ); 165 } 166 162 167 /** 163 168 * Makes a function, which will return the right translation index, according to the 164 169 * plural forms header … … endif; 229 234 230 235 if ( !class_exists( 'NOOP_Translations' ) ): 231 236 /** 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. 233 241 */ 234 class NOOP_Translations {242 class NOOP_Translations extends Gettext_Translations { 235 243 var $entries = array(); 236 244 var $headers = array(); 237 245 -
src/wp-includes/script-loader.php
diff --git src/wp-includes/script-loader.php src/wp-includes/script-loader.php index df09c83..f97bb9b 100644
function wp_default_scripts( &$scripts ) { 77 77 'secure' => (string) ( 'https' === parse_url( site_url(), PHP_URL_SCHEME ) ), 78 78 ) ); 79 79 80 $scripts->add( 'i18n-make-plural', 'inline' ); 81 $scripts->add_data( 'i18n-make-plural', 'data', wp_i18n_js_make_plural_definition() ); 82 80 83 $scripts->add( 'common', "/wp-admin/js/common$suffix.js", array('jquery', 'hoverIntent', 'utils'), false, 1 ); 81 84 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."), 83 86 ) ); 84 87 85 88 $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 { 136 136 $this->assertFalse( $dep->query( 'one' ) ); 137 137 138 138 } 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 } 139 164 }