Changeset 60953
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/interactivity-api/class-wp-interactivity-api.php
r60741 r60953 60 60 61 61 /** 62 * Keeps track of all derived state closures accessed during server-side rendering. 63 * 64 * This data is serialized and sent to the client as part of the interactivity 65 * data, and is handled later in the client to support derived state props that 66 * are lazily hydrated. 67 * 68 * @since 6.9.0 69 * @var array 70 */ 71 private $derived_state_closures = array(); 72 73 /** 62 74 * Flag that indicates whether the `data-wp-router-region` directive has 63 75 * been found in the HTML and processed. … … 237 249 * 238 250 * @since 6.7.0 251 * @since 6.9.0 Serializes derived state props accessed during directive processing. 239 252 * 240 253 * @param array $data Data to filter. … … 242 255 */ 243 256 public function filter_script_module_interactivity_data( array $data ): array { 244 if ( empty( $this->state_data ) && empty( $this->config_data ) ) { 257 if ( 258 empty( $this->state_data ) && 259 empty( $this->config_data ) && 260 empty( $this->derived_state_closures ) 261 ) { 245 262 return $data; 246 263 } … … 264 281 if ( ! empty( $state ) ) { 265 282 $data['state'] = $state; 283 } 284 285 $derived_props = array(); 286 foreach ( $this->derived_state_closures as $key => $value ) { 287 if ( ! empty( $value ) ) { 288 $derived_props[ $key ] = $value; 289 } 290 } 291 if ( ! empty( $derived_props ) ) { 292 $data['derivedStateClosures'] = $derived_props; 266 293 } 267 294 … … 599 626 $path_segments = explode( '.', $path ); 600 627 $current = $store; 601 foreach ( $path_segments as $ path_segment ) {628 foreach ( $path_segments as $index => $path_segment ) { 602 629 /* 603 630 * Special case for numeric arrays and strings. Add length … … 648 675 try { 649 676 $current = $current(); 677 678 /* 679 * Tracks derived state properties that are accessed during 680 * rendering. 681 * 682 * @since 6.9.0 683 */ 684 $this->derived_state_closures[ $ns ] = $this->derived_state_closures[ $ns ] ?? array(); 685 686 // Builds path for the current property and add it to tracking if not already present. 687 $current_path = implode( '.', array_slice( $path_segments, 0, $index + 1 ) ); 688 if ( ! in_array( $current_path, $this->derived_state_closures[ $ns ], true ) ) { 689 $this->derived_state_closures[ $ns ][] = $current_path; 690 } 650 691 } catch ( Throwable $e ) { 651 692 _doing_it_wrong( … … 1161 1202 * 1162 1203 * @since 6.5.0 1204 * @since 6.9.0 Include the list path in the rendered `data-wp-each-child` directives. 1163 1205 * 1164 1206 * @param WP_Interactivity_API_Directives_Processor $p The directives processor instance. … … 1206 1248 1207 1249 // Extracts the namespace from the directive attribute value. 1208 $namespace_value = end( $this->namespace_stack );1209 list( $namespace_value ) = is_string( $attribute_value ) && ! empty( $attribute_value )1250 $namespace_value = end( $this->namespace_stack ); 1251 list( $namespace_value, $path ) = is_string( $attribute_value ) && ! empty( $attribute_value ) 1210 1252 ? $this->extract_directive_value( $attribute_value, $namespace_value ) 1211 1253 : array( $namespace_value, null ); … … 1229 1271 } 1230 1272 1231 // Adds the `data-wp-each-child` to each top-level tag. 1273 /* 1274 * Adds the `data-wp-each-child` directive to each top-level tag 1275 * rendered by this `data-wp-each` directive. The value is the 1276 * `data-wp-each` directive's namespace and path. 1277 * 1278 * Nested `data-wp-each` directives could render 1279 * `data-wp-each-child` elements at the top level as well, and 1280 * they should be overwritten. 1281 * 1282 * @since 6.9.0 1283 */ 1232 1284 $i = new WP_Interactivity_API_Directives_Processor( $processed_item ); 1233 1285 while ( $i->next_tag() ) { 1234 $i->set_attribute( 'data-wp-each-child', true);1286 $i->set_attribute( 'data-wp-each-child', $namespace_value . '::' . $path ); 1235 1287 $i->next_balanced_tag_closer_tag(); 1236 1288 } -
trunk/tests/phpunit/tests/interactivity-api/wpInteractivityAPI-wp-each.php
r58594 r60953 89 89 '<span data-wp-text="myPlugin::context.item"></span>' . 90 90 '</template>' . 91 '<span data-wp-each-child data-wp-text="myPlugin::context.item">1</span>' .92 '<span data-wp-each-child data-wp-text="myPlugin::context.item">2</span>' .91 '<span data-wp-each-child="myPlugin::state.list" data-wp-text="myPlugin::context.item">1</span>' . 92 '<span data-wp-each-child="myPlugin::state.list" data-wp-text="myPlugin::context.item">2</span>' . 93 93 '<div id="after-wp-each" data-wp-bind--id="myPlugin::state.after">Text</div>'; 94 94 $new = $this->interactivity->process_directives( $original ); … … 141 141 '<span data-wp-bind--id="myPlugin::context.id" data-wp-text="myPlugin::context.item"></span>' . 142 142 '</template>' . 143 '<span data-wp-each-child id="some-id" data-wp-bind--id="myPlugin::context.id" data-wp-text="myPlugin::context.item">1</span>' .144 '<span data-wp-each-child id="some-id" data-wp-bind--id="myPlugin::context.id" data-wp-text="myPlugin::context.item">2</span>' .143 '<span data-wp-each-child="myPlugin::state.list" id="some-id" data-wp-bind--id="myPlugin::context.id" data-wp-text="myPlugin::context.item">1</span>' . 144 '<span data-wp-each-child="myPlugin::state.list" id="some-id" data-wp-bind--id="myPlugin::context.id" data-wp-text="myPlugin::context.item">2</span>' . 145 145 '<div id="after-wp-each" data-wp-bind--id="myPlugin::context.after" data-wp-text="myPlugin::context.item">New text</div>' . 146 146 '</div>'; … … 169 169 '<span data-wp-text="myPlugin::context.item"></span>' . 170 170 '</template>' . 171 '<span data-wp-each-child data-wp-text="myPlugin::context.item">1</span>' .172 '<span data-wp-each-child data-wp-text="myPlugin::context.item">2</span>' .171 '<span data-wp-each-child="myPlugin::context.list" data-wp-text="myPlugin::context.item">1</span>' . 172 '<span data-wp-each-child="myPlugin::context.list" data-wp-text="myPlugin::context.item">2</span>' . 173 173 '<div id="after-wp-each" data-wp-bind--id="myPlugin::state.after">Text</div>' . 174 174 '</div>'; … … 197 197 '<span data-wp-text="context.item"></span>' . 198 198 '</template>' . 199 '<span data-wp-each-child data-wp-text="context.item">1</span>' .200 '<span data-wp-each-child data-wp-text="context.item">2</span>' .199 '<span data-wp-each-child="myPlugin::state.list" data-wp-text="context.item">1</span>' . 200 '<span data-wp-each-child="myPlugin::state.list" data-wp-text="context.item">2</span>' . 201 201 '<div id="after-wp-each" data-wp-bind--id="state.after">Text</div>' . 202 202 '</div>'; … … 224 224 '<span data-wp-text="myPlugin::context.item"></span>' . 225 225 '</template>' . 226 '<span data-wp-each-child data-wp-text="myPlugin::context.item">1</span>' .227 '<span data-wp-each-child data-wp-text="myPlugin::context.item">1</span>' .228 '<span data-wp-each-child data-wp-text="myPlugin::context.item">2</span>' .229 '<span data-wp-each-child data-wp-text="myPlugin::context.item">2</span>' .226 '<span data-wp-each-child="myPlugin::state.list" data-wp-text="myPlugin::context.item">1</span>' . 227 '<span data-wp-each-child="myPlugin::state.list" data-wp-text="myPlugin::context.item">1</span>' . 228 '<span data-wp-each-child="myPlugin::state.list" data-wp-text="myPlugin::context.item">2</span>' . 229 '<span data-wp-each-child="myPlugin::state.list" data-wp-text="myPlugin::context.item">2</span>' . 230 230 '<div id="after-wp-each" data-wp-bind--id="myPlugin::state.after">Text</div>'; 231 231 $new = $this->interactivity->process_directives( $original ); … … 252 252 '<img data-wp-bind--id="myPlugin::context.item">' . 253 253 '</template>' . 254 '<img data-wp-each-child id="1" data-wp-bind--id="myPlugin::context.item">' .255 '<img data-wp-each-child id="1" data-wp-bind--id="myPlugin::context.item">' .256 '<img data-wp-each-child id="2" data-wp-bind--id="myPlugin::context.item">' .257 '<img data-wp-each-child id="2" data-wp-bind--id="myPlugin::context.item">' .254 '<img data-wp-each-child="myPlugin::state.list" id="1" data-wp-bind--id="myPlugin::context.item">' . 255 '<img data-wp-each-child="myPlugin::state.list" id="1" data-wp-bind--id="myPlugin::context.item">' . 256 '<img data-wp-each-child="myPlugin::state.list" id="2" data-wp-bind--id="myPlugin::context.item">' . 257 '<img data-wp-each-child="myPlugin::state.list" id="2" data-wp-bind--id="myPlugin::context.item">' . 258 258 '<div id="after-wp-each" data-wp-bind--id="myPlugin::state.after">Text</div>'; 259 259 $new = $this->interactivity->process_directives( $original ); … … 281 281 '<span data-wp-text="myPlugin::context.item"></span>' . 282 282 '</template>' . 283 '<img data-wp-each-child id="1" data-wp-bind--id="myPlugin::context.item">' .284 '<span data-wp-each-child data-wp-text="myPlugin::context.item">1</span>' .285 '<img data-wp-each-child id="2" data-wp-bind--id="myPlugin::context.item">' .286 '<span data-wp-each-child data-wp-text="myPlugin::context.item">2</span>' .283 '<img data-wp-each-child="myPlugin::state.list" id="1" data-wp-bind--id="myPlugin::context.item">' . 284 '<span data-wp-each-child="myPlugin::state.list" data-wp-text="myPlugin::context.item">1</span>' . 285 '<img data-wp-each-child="myPlugin::state.list" id="2" data-wp-bind--id="myPlugin::context.item">' . 286 '<span data-wp-each-child="myPlugin::state.list" data-wp-text="myPlugin::context.item">2</span>' . 287 287 '<div id="after-wp-each" data-wp-bind--id="myPlugin::state.after">Text</div>'; 288 288 $new = $this->interactivity->process_directives( $original ); … … 311 311 '</div>' . 312 312 '</template>' . 313 '<div data-wp-each-child id="1" data-wp-bind--id="myPlugin::context.item">' .313 '<div data-wp-each-child="myPlugin::state.list" id="1" data-wp-bind--id="myPlugin::context.item">' . 314 314 'id: <span data-wp-text="myPlugin::context.item">1</span>' . 315 315 '</div>' . 316 '<div data-wp-each-child id="2" data-wp-bind--id="myPlugin::context.item">' .316 '<div data-wp-each-child="myPlugin::state.list" id="2" data-wp-bind--id="myPlugin::context.item">' . 317 317 'id: <span data-wp-text="myPlugin::context.item">2</span>' . 318 318 '</div>' . … … 356 356 '<span data-wp-text="myPlugin::context.item.name"></span>' . 357 357 '</template>' . 358 '<span data-wp-each-child data-wp-text="myPlugin::context.item.id">1</span>' .359 '<span data-wp-each-child data-wp-text="myPlugin::context.item.name">one</span>' .360 '<span data-wp-each-child data-wp-text="myPlugin::context.item.id">2</span>' .361 '<span data-wp-each-child data-wp-text="myPlugin::context.item.name">two</span>' .358 '<span data-wp-each-child="myPlugin::state.list" data-wp-text="myPlugin::context.item.id">1</span>' . 359 '<span data-wp-each-child="myPlugin::state.list" data-wp-text="myPlugin::context.item.name">one</span>' . 360 '<span data-wp-each-child="myPlugin::state.list" data-wp-text="myPlugin::context.item.id">2</span>' . 361 '<span data-wp-each-child="myPlugin::state.list" data-wp-text="myPlugin::context.item.name">two</span>' . 362 362 '<div id="after-wp-each" data-wp-bind--id="myPlugin::state.after">Text</div>'; 363 363 $new = $this->interactivity->process_directives( $original ); … … 382 382 '<span data-wp-text="myPlugin::context.myitem"></span>' . 383 383 '</template>' . 384 '<span data-wp-each-child data-wp-text="myPlugin::context.myitem">1</span>' .385 '<span data-wp-each-child data-wp-text="myPlugin::context.myitem">2</span>' .384 '<span data-wp-each-child="myPlugin::state.list" data-wp-text="myPlugin::context.myitem">1</span>' . 385 '<span data-wp-each-child="myPlugin::state.list" data-wp-text="myPlugin::context.myitem">2</span>' . 386 386 '<div id="after-wp-each" data-wp-bind--id="myPlugin::state.after">Text</div>'; 387 387 $new = $this->interactivity->process_directives( $original ); … … 407 407 '<span data-wp-text="myPlugin::context.myItem"></span>' . 408 408 '</template>' . 409 '<span data-wp-each-child data-wp-text="myPlugin::context.myItem">1</span>' .410 '<span data-wp-each-child data-wp-text="myPlugin::context.myItem">2</span>' .409 '<span data-wp-each-child="myPlugin::state.list" data-wp-text="myPlugin::context.myItem">1</span>' . 410 '<span data-wp-each-child="myPlugin::state.list" data-wp-text="myPlugin::context.myItem">2</span>' . 411 411 '<div id="after-wp-each" data-wp-bind--id="myPlugin::state.after">Text</div>'; 412 412 $new = $this->interactivity->process_directives( $original ); … … 474 474 '</template>' . 475 475 '</template>' . 476 '<span data-wp-each-child data-wp-text="myPlugin::context.item1">1</span>' .477 '<template data-wp-each-child data-wp-each--item2="myPlugin::state.list2">' .476 '<span data-wp-each-child="myPlugin::state.list" data-wp-text="myPlugin::context.item1">1</span>' . 477 '<template data-wp-each-child="myPlugin::state.list" data-wp-each--item2="myPlugin::state.list2">' . 478 478 '<span data-wp-text="myPlugin::context.item2"></span>' . 479 479 '</template>' . 480 '<span data-wp-each-child data-wp-text="myPlugin::context.item2">3</span>' .481 '<span data-wp-each-child data-wp-text="myPlugin::context.item2">4</span>' .482 '<span data-wp-each-child data-wp-text="myPlugin::context.item1">2</span>' .483 '<template data-wp-each-child data-wp-each--item2="myPlugin::state.list2">' .480 '<span data-wp-each-child="myPlugin::state.list" data-wp-text="myPlugin::context.item2">3</span>' . 481 '<span data-wp-each-child="myPlugin::state.list" data-wp-text="myPlugin::context.item2">4</span>' . 482 '<span data-wp-each-child="myPlugin::state.list" data-wp-text="myPlugin::context.item1">2</span>' . 483 '<template data-wp-each-child="myPlugin::state.list" data-wp-each--item2="myPlugin::state.list2">' . 484 484 '<span data-wp-text="myPlugin::context.item2"></span>' . 485 485 '</template>' . 486 '<span data-wp-each-child data-wp-text="myPlugin::context.item2">3</span>' .487 '<span data-wp-each-child data-wp-text="myPlugin::context.item2">4</span>' .486 '<span data-wp-each-child="myPlugin::state.list" data-wp-text="myPlugin::context.item2">3</span>' . 487 '<span data-wp-each-child="myPlugin::state.list" data-wp-text="myPlugin::context.item2">4</span>' . 488 488 '<div id="after-wp-each" data-wp-bind--id="myPlugin::state.after">Text</div>'; 489 489 $new = $this->interactivity->process_directives( $original ); … … 516 516 '</template>' . 517 517 '</template>' . 518 '<template data-wp-each-child data-wp-each--item2="myPlugin::state.list2">' .518 '<template data-wp-each-child="myPlugin::state.list" data-wp-each--item2="myPlugin::state.list2">' . 519 519 '<span data-wp-text="myPlugin::context.item1"></span>' . 520 520 '<span data-wp-text="myPlugin::context.item2"></span>' . 521 521 '</template>' . 522 '<span data-wp-each-child data-wp-text="myPlugin::context.item1">1</span>' .523 '<span data-wp-each-child data-wp-text="myPlugin::context.item2">3</span>' .524 '<span data-wp-each-child data-wp-text="myPlugin::context.item1">1</span>' .525 '<span data-wp-each-child data-wp-text="myPlugin::context.item2">4</span>' .526 '<template data-wp-each-child data-wp-each--item2="myPlugin::state.list2">' .522 '<span data-wp-each-child="myPlugin::state.list" data-wp-text="myPlugin::context.item1">1</span>' . 523 '<span data-wp-each-child="myPlugin::state.list" data-wp-text="myPlugin::context.item2">3</span>' . 524 '<span data-wp-each-child="myPlugin::state.list" data-wp-text="myPlugin::context.item1">1</span>' . 525 '<span data-wp-each-child="myPlugin::state.list" data-wp-text="myPlugin::context.item2">4</span>' . 526 '<template data-wp-each-child="myPlugin::state.list" data-wp-each--item2="myPlugin::state.list2">' . 527 527 '<span data-wp-text="myPlugin::context.item1"></span>' . 528 528 '<span data-wp-text="myPlugin::context.item2"></span>' . 529 529 '</template>' . 530 '<span data-wp-each-child data-wp-text="myPlugin::context.item1">2</span>' .531 '<span data-wp-each-child data-wp-text="myPlugin::context.item2">3</span>' .532 '<span data-wp-each-child data-wp-text="myPlugin::context.item1">2</span>' .533 '<span data-wp-each-child data-wp-text="myPlugin::context.item2">4</span>' .530 '<span data-wp-each-child="myPlugin::state.list" data-wp-text="myPlugin::context.item1">2</span>' . 531 '<span data-wp-each-child="myPlugin::state.list" data-wp-text="myPlugin::context.item2">3</span>' . 532 '<span data-wp-each-child="myPlugin::state.list" data-wp-text="myPlugin::context.item1">2</span>' . 533 '<span data-wp-each-child="myPlugin::state.list" data-wp-text="myPlugin::context.item2">4</span>' . 534 534 '<div id="after-wp-each" data-wp-bind--id="myPlugin::state.after">Text</div>'; 535 535 $new = $this->interactivity->process_directives( $original ); … … 560 560 '</template>' . 561 561 '</template>' . 562 '<template data-wp-each-child data-wp-each--number="myPlugin::context.list">' .562 '<template data-wp-each-child="myPlugin::state.list2" data-wp-each--number="myPlugin::context.list">' . 563 563 '<span data-wp-text="myPlugin::context.number"></span>' . 564 564 '</template>' . 565 '<span data-wp-each-child data-wp-text="myPlugin::context.number">1</span>' .566 '<span data-wp-each-child data-wp-text="myPlugin::context.number">2</span>' .567 '<template data-wp-each-child data-wp-each--number="myPlugin::context.list">' .565 '<span data-wp-each-child="myPlugin::state.list2" data-wp-text="myPlugin::context.number">1</span>' . 566 '<span data-wp-each-child="myPlugin::state.list2" data-wp-text="myPlugin::context.number">2</span>' . 567 '<template data-wp-each-child="myPlugin::state.list2" data-wp-each--number="myPlugin::context.list">' . 568 568 '<span data-wp-text="myPlugin::context.number"></span>' . 569 569 '</template>' . 570 '<span data-wp-each-child data-wp-text="myPlugin::context.number">3</span>' .571 '<span data-wp-each-child data-wp-text="myPlugin::context.number">4</span>' .570 '<span data-wp-each-child="myPlugin::state.list2" data-wp-text="myPlugin::context.number">3</span>' . 571 '<span data-wp-each-child="myPlugin::state.list2" data-wp-text="myPlugin::context.number">4</span>' . 572 572 '<div id="after-wp-each" data-wp-bind--id="myPlugin::state.after">Text</div>'; 573 573 $new = $this->interactivity->process_directives( $original ); … … 672 672 '<span data-wp-text="myPlugin::context.item"></span>' . 673 673 '</template>' . 674 '<span data-wp-each-child data-wp-text="myPlugin::context.item">1</span>' .675 '<span data-wp-each-child data-wp-text="myPlugin::context.item">2</span>' .676 '<div data-wp-bind--id="myPlugin::state.after">Text</div>'; 677 $expected = '' . 678 '<template data-wp-each="myPlugin::state.list">' . 679 '<span data-wp-text="myPlugin::context.item"></span>' . 680 '</template>' . 681 '<span data-wp-each-child data-wp-text="myPlugin::context.item">1</span>' .682 '<span data-wp-each-child data-wp-text="myPlugin::context.item">2</span>' .674 '<span data-wp-each-child="myPlugin::state.list" data-wp-text="myPlugin::context.item">1</span>' . 675 '<span data-wp-each-child="myPlugin::state.list" data-wp-text="myPlugin::context.item">2</span>' . 676 '<div data-wp-bind--id="myPlugin::state.after">Text</div>'; 677 $expected = '' . 678 '<template data-wp-each="myPlugin::state.list">' . 679 '<span data-wp-text="myPlugin::context.item"></span>' . 680 '</template>' . 681 '<span data-wp-each-child="myPlugin::state.list" data-wp-text="myPlugin::context.item">1</span>' . 682 '<span data-wp-each-child="myPlugin::state.list" data-wp-text="myPlugin::context.item">2</span>' . 683 683 '<div id="after-wp-each" data-wp-bind--id="myPlugin::state.after">Text</div>'; 684 684 $new = $this->interactivity->process_directives( $original ); -
trunk/tests/phpunit/tests/interactivity-api/wpInteractivityAPI.php
r60729 r60953 26 26 parent::set_up(); 27 27 $this->interactivity = new WP_Interactivity_API(); 28 wp_default_script_modules(); 28 29 } 29 30 … … 315 316 316 317 $this->assertSame( array( 'state' => array( 'myPlugin' => array( 'emptyArray' => array() ) ) ), $filter->get_args()[0][0] ); 318 } 319 /** 320 * Tests that derived state props invoked during directive evaluation are 321 * serialized correctly. 322 * 323 * @ticket 63898 324 */ 325 public function test_invoked_derived_state_props_are_serialized() { 326 $returns_whatever = function () { 327 return 'whatever'; 328 }; 329 330 $returns_array = function () { 331 return array( 'prop' => 'whatever' ); 332 }; 333 334 $filter = $this->get_script_data_filter_result( 335 function () use ( $returns_whatever, $returns_array ) { 336 $this->interactivity->state( 337 'pluginWithInvokedDerivedState', 338 array( 339 'derivedProp' => $returns_whatever, 340 'nested' => array( 341 'derivedProp' => $returns_whatever, 342 'derivedPropReturnsArray' => $returns_array, 343 ), 344 ) 345 ); 346 347 $this->interactivity->state( 348 'pluginWithInvokedDerivedStateReturningArray', 349 array( 350 'derivedProp' => $returns_whatever, 351 'nested' => array( 352 'derivedProp' => $returns_whatever, 353 'derivedPropReturnsArray' => $returns_array, 354 ), 355 ) 356 ); 357 358 $this->interactivity->state( 359 'pluginWithoutInvokedDerivedState', 360 array( 361 'derivedProp' => $returns_whatever, 362 'nested' => array( 363 'derivedProp' => $returns_whatever, 364 ), 365 ) 366 ); 367 368 $this->set_internal_context_stack( array() ); 369 370 // Multiple evaluations should be serialized only once. 371 $this->set_internal_namespace_stack( 'pluginWithInvokedDerivedState' ); 372 $this->evaluate( 'state.derivedProp' ); 373 $this->evaluate( 'state.derivedProp' ); 374 $this->evaluate( 'state.nested.derivedProp' ); 375 $this->evaluate( 'state.nested.derivedProp' ); 376 377 // Only the path part that points to a derived state prop should be serialized. 378 $this->set_internal_namespace_stack( 'pluginWithInvokedDerivedStateReturningArray' ); 379 $this->evaluate( 'state.nested.derivedProp.prop' ); 380 } 381 ); 382 383 $this->assertSame( 384 array( 385 'state' => array( 386 'pluginWithInvokedDerivedState' => array( 387 'derivedProp' => $returns_whatever, 388 'nested' => array( 389 'derivedProp' => $returns_whatever, 390 'derivedPropReturnsArray' => $returns_array, 391 ), 392 ), 393 'pluginWithInvokedDerivedStateReturningArray' => array( 394 'derivedProp' => $returns_whatever, 395 'nested' => array( 396 'derivedProp' => $returns_whatever, 397 'derivedPropReturnsArray' => $returns_array, 398 ), 399 ), 400 'pluginWithoutInvokedDerivedState' => array( 401 'derivedProp' => $returns_whatever, 402 'nested' => array( 403 'derivedProp' => $returns_whatever, 404 ), 405 ), 406 ), 407 'derivedStateClosures' => array( 408 'pluginWithInvokedDerivedState' => array( 409 'state.derivedProp', 410 'state.nested.derivedProp', 411 ), 412 'pluginWithInvokedDerivedStateReturningArray' => array( 413 'state.nested.derivedProp', 414 ), 415 ), 416 ), 417 $filter->get_args()[0][0] 418 ); 317 419 } 318 420
Note: See TracChangeset for help on using the changeset viewer.