Ticket #33901: 33901.3.diff
File 33901.3.diff, 31.7 KB (added by , 10 years ago) |
---|
-
src/wp-admin/includes/widgets.php
diff --git src/wp-admin/includes/widgets.php src/wp-admin/includes/widgets.php index 356970f..19fd390 100644
function wp_widget_control( $sidebar_args ) { 181 181 $multi_number = isset($sidebar_args['_multi_num']) ? $sidebar_args['_multi_num'] : ''; 182 182 $add_new = isset($sidebar_args['_add']) ? $sidebar_args['_add'] : ''; 183 183 184 $before_form = isset( $sidebar_args['before_form'] ) ? $sidebar_args['before_form'] : '<form method="post">'; 185 $after_form = isset( $sidebar_args['after_form'] ) ? $sidebar_args['after_form'] : '</form>'; 186 $before_widget_content = isset( $sidebar_args['before_widget_content'] ) ? $sidebar_args['before_widget_content'] : '<div class="widget-content">'; 187 $after_widget_content = isset( $sidebar_args['after_widget_content'] ) ? $sidebar_args['after_widget_content'] : '</div>'; 188 184 189 $query_arg = array( 'editwidget' => $widget['id'] ); 185 190 if ( $add_new ) { 186 191 $query_arg['addnew'] = 1; … … function wp_widget_control( $sidebar_args ) { 225 230 </div> 226 231 227 232 <div class="widget-inside"> 228 < form method="post">229 < div class="widget-content">230 <?php231 if ( isset( $control['callback']) )233 <?php echo $before_form; ?> 234 <?php echo $before_widget_content; ?> 235 <?php 236 if ( isset( $control['callback'] ) ) { 232 237 $has_form = call_user_func_array( $control['callback'], $control['params'] ); 233 else 234 echo "\t\t<p>" . __('There are no options for this widget.') . "</p>\n"; ?> 235 </div> 238 } else { 239 echo "\t\t<p>" . __('There are no options for this widget.') . "</p>\n"; 240 } 241 ?> 242 <?php echo $after_widget_content; ?> 236 243 <input type="hidden" name="widget-id" class="widget-id" value="<?php echo esc_attr($id_format); ?>" /> 237 244 <input type="hidden" name="id_base" class="id_base" value="<?php echo esc_attr($id_base); ?>" /> 238 245 <input type="hidden" name="widget-width" class="widget-width" value="<?php if (isset( $control['width'] )) echo esc_attr($control['width']); ?>" /> … … function wp_widget_control( $sidebar_args ) { 252 259 </div> 253 260 <br class="clear" /> 254 261 </div> 255 < /form>262 <?php echo $after_form; ?> 256 263 </div> 257 264 258 265 <div class="widget-description"> -
src/wp-admin/js/customize-widgets.js
diff --git src/wp-admin/js/customize-widgets.js src/wp-admin/js/customize-widgets.js index 6a640e0..8edc02c 100644
417 417 /** 418 418 * @since 4.1.0 419 419 */ 420 initialize: function 420 initialize: function( id, options ) { 421 421 var control = this; 422 api.Control.prototype.initialize.call( control, id, options ); 423 control.expanded = new api.Value(); 422 423 control.widgetControlEmbedded = false; 424 control.widgetContentEmbedded = false; 425 control.expanded = new api.Value( false ); 424 426 control.expandedArgumentsQueue = []; 425 control.expanded.bind( function 427 control.expanded.bind( function( expanded ) { 426 428 var args = control.expandedArgumentsQueue.shift(); 427 429 args = $.extend( {}, control.defaultExpandedArguments, args ); 428 430 control.onChangeExpanded( expanded, args ); 429 431 }); 430 control.expanded.set( false ); 432 433 api.Control.prototype.initialize.call( control, id, options ); 431 434 }, 432 435 433 436 /** 434 * Set up the control 437 * Set up the control. 438 * 439 * @since 3.9.0 435 440 */ 436 441 ready: function() { 437 this._setupModel(); 438 this._setupWideWidget(); 439 this._setupControlToggle(); 440 this._setupWidgetTitle(); 441 this._setupReorderUI(); 442 this._setupHighlightEffects(); 443 this._setupUpdateUI(); 444 this._setupRemoveUI(); 442 var control = this; 443 444 /* 445 * Embed a placeholder once the section is expanded. The full widget 446 * form content will be embedded once the control itself is expanded, 447 * and at this point the widget-added event will be triggered. 448 */ 449 if ( ! control.section() ) { 450 control.embedWidgetControl(); 451 } else { 452 api.section( control.section(), function( section ) { 453 var onExpanded = function( isExpanded ) { 454 if ( isExpanded ) { 455 control.embedWidgetControl(); 456 section.expanded.unbind( onExpanded ); 457 } 458 }; 459 if ( section.expanded() ) { 460 onExpanded( true ); 461 } else { 462 section.expanded.bind( onExpanded ); 463 } 464 } ); 465 } 466 }, 467 468 /** 469 * Embed the .widget element inside the li container. 470 * 471 * @since 4.4.0 472 */ 473 embedWidgetControl: function() { 474 var control = this, widgetControl; 475 476 if ( control.widgetControlEmbedded ) { 477 return; 478 } 479 control.widgetControlEmbedded = true; 480 481 widgetControl = $( control.params.widget_control ); 482 control.container.append( widgetControl ); 483 484 control._setupModel(); 485 control._setupWideWidget(); 486 control._setupControlToggle(); 487 488 control._setupWidgetTitle(); 489 control._setupReorderUI(); 490 control._setupHighlightEffects(); 491 control._setupUpdateUI(); 492 control._setupRemoveUI(); 493 }, 494 495 /** 496 * Embed the actual widget form inside of .widget-content and finally trigger the widget-added event. 497 * 498 * @since 4.4.0 499 */ 500 embedWidgetContent: function() { 501 var control = this, widgetContent; 502 503 control.embedWidgetControl(); 504 if ( control.widgetContentEmbedded ) { 505 return; 506 } 507 control.widgetContentEmbedded = true; 508 509 widgetContent = $( control.params.widget_content ); 510 control.container.find( '.widget-content:first' ).append( widgetContent ); 445 511 446 512 /* 447 513 * Trigger widget-added event so that plugins can attach any event 448 514 * listeners and dynamic UI elements. 449 515 */ 450 $( document ).trigger( 'widget-added', [ this.container.find( '.widget:first' ) ] ); 516 $( document ).trigger( 'widget-added', [ control.container.find( '.widget:first' ) ] ); 517 451 518 }, 452 519 453 520 /** … … 1008 1075 var self = this, instanceOverride, completeCallback, $widgetRoot, $widgetContent, 1009 1076 updateNumber, params, data, $inputs, processing, jqxhr, isChanged; 1010 1077 1078 // The updateWidget logic requires that the form fields to be fully present. 1079 self.embedWidgetContent(); 1080 1011 1081 args = $.extend( { 1012 1082 instance: null, 1013 1083 complete: null, … … 1255 1325 onChangeExpanded: function ( expanded, args ) { 1256 1326 var self = this, $widget, $inside, complete, prevComplete; 1257 1327 1328 self.embedWidgetControl(); // Make sure the outer form is embedded so that the expanded state can be set in the UI. 1329 if ( expanded ) { 1330 self.embedWidgetContent(); 1331 } 1332 1258 1333 // If the expanded state is unchanged only manipulate container expanded states 1259 1334 if ( args.unchanged ) { 1260 1335 if ( expanded ) { -
src/wp-includes/class-wp-customize-control.php
diff --git src/wp-includes/class-wp-customize-control.php src/wp-includes/class-wp-customize-control.php index f105ab1..b6ffa1a 100644
class WP_Widget_Form_Customize_Control extends WP_Customize_Control { 1487 1487 public $height; 1488 1488 public $is_wide = false; 1489 1489 1490 /** 1491 * Gather control params for exporting to JavaScript. 1492 * 1493 * @global array $wp_registered_widgets 1494 */ 1490 1495 public function to_json() { 1496 global $wp_registered_widgets; 1497 1491 1498 parent::to_json(); 1492 1499 $exported_properties = array( 'widget_id', 'widget_id_base', 'sidebar_id', 'width', 'height', 'is_wide' ); 1493 1500 foreach ( $exported_properties as $key ) { 1494 1501 $this->json[ $key ] = $this->$key; 1495 1502 } 1496 }1497 1503 1498 /** 1499 * 1500 * @global array $wp_registered_widgets 1501 */ 1502 public function render_content() { 1503 global $wp_registered_widgets; 1504 // Get the widget_control and widget_content. 1504 1505 require_once ABSPATH . '/wp-admin/includes/widgets.php'; 1505 1506 1506 1507 $widget = $wp_registered_widgets[ $this->widget_id ]; … … class WP_Widget_Form_Customize_Control extends WP_Customize_Control { 1514 1515 ); 1515 1516 1516 1517 $args = wp_list_widget_controls_dynamic_sidebar( array( 0 => $args, 1 => $widget['params'][0] ) ); 1517 echo $this->manager->widgets->get_widget_control( $args ); 1518 $widget_control_parts = $this->manager->widgets->get_widget_control_parts( $args ); 1519 1520 $this->json['widget_control'] = $widget_control_parts['control']; 1521 $this->json['widget_content'] = $widget_control_parts['content']; 1518 1522 } 1519 1523 1520 1524 /** 1525 * Override render_content to be no-op since content is exported via to_json for deferred embedding. 1526 */ 1527 public function render_content() {} 1528 1529 /** 1521 1530 * Whether the current widget is rendered on the page. 1522 1531 * 1523 1532 * @since 4.0.0 -
src/wp-includes/class-wp-customize-widgets.php
diff --git src/wp-includes/class-wp-customize-widgets.php src/wp-includes/class-wp-customize-widgets.php index 8569228..a003393 100644
final class WP_Customize_Widgets { 898 898 * @return string Widget control form HTML markup. 899 899 */ 900 900 public function get_widget_control( $args ) { 901 $args[0]['before_form'] = '<div class="form">'; 902 $args[0]['after_form'] = '</div><!-- .form -->'; 903 $args[0]['before_widget_content'] = '<div class="widget-content">'; 904 $args[0]['after_widget_content'] = '</div><!-- .widget-content -->'; 901 905 ob_start(); 902 903 906 call_user_func_array( 'wp_widget_control', $args ); 904 $replacements = array(905 '<form method="post">' => '<div class="form">',906 '</form>' => '</div><!-- .form -->',907 );908 909 907 $control_tpl = ob_get_clean(); 908 return $control_tpl; 909 } 910 910 911 $control_tpl = str_replace( array_keys( $replacements ), array_values( $replacements ), $control_tpl ); 911 /** 912 * Get the widget control markup parts. 913 * 914 * @since 4.4.0 915 * @access public 916 * 917 * @param array $args Widget control arguments. 918 * @return array { 919 * @type string $control Markup for widget control wrapping form. 920 * @type string $content The contents of the widget form itself. 921 * } 922 */ 923 public function get_widget_control_parts( $args ) { 924 $args[0]['before_widget_content'] = '<div class="widget-content">'; 925 $args[0]['after_widget_content'] = '</div><!-- .widget-content -->'; 926 $control_markup = $this->get_widget_control( $args ); 927 928 $content_start_pos = strpos( $control_markup, $args[0]['before_widget_content'] ); 929 $content_end_pos = strrpos( $control_markup, $args[0]['after_widget_content'] ); 930 931 $control = substr( $control_markup, 0, $content_start_pos + strlen( $args[0]['before_widget_content'] ) ); 932 $control .= substr( $control_markup, $content_end_pos ); 933 $content = trim( substr( 934 $control_markup, 935 $content_start_pos + strlen( $args[0]['before_widget_content'] ), 936 $content_end_pos - $content_start_pos - strlen( $args[0]['before_widget_content'] ) 937 ) ); 912 938 913 return $control_tpl;939 return compact( 'control', 'content' ); 914 940 } 915 941 916 942 /** -
tests/phpunit/tests/customize/widgets.php
diff --git tests/phpunit/tests/customize/widgets.php tests/phpunit/tests/customize/widgets.php index 9f30b94..50aab18 100644
class Tests_WP_Customize_Widgets extends WP_UnitTestCase { 195 195 $unsanitized_from_js = $this->manager->widgets->sanitize_widget_instance( $sanitized_for_js ); 196 196 $this->assertEquals( $unsanitized_from_js, $new_categories_instance ); 197 197 } 198 199 /** 200 * Get the widget control args for tests. 201 * 202 * @return array 203 */ 204 function get_test_widget_control_args() { 205 global $wp_registered_widgets; 206 require_once ABSPATH . '/wp-admin/includes/widgets.php'; 207 $widget_id = 'search-2'; 208 $widget = $wp_registered_widgets[ $widget_id ]; 209 $args = array( 210 'widget_id' => $widget['id'], 211 'widget_name' => $widget['name'], 212 ); 213 $args = wp_list_widget_controls_dynamic_sidebar( array( 0 => $args, 1 => $widget['params'][0] ) ); 214 return $args; 215 } 216 217 /** 218 * @see WP_Customize_Widgets::get_widget_control() 219 */ 220 function test_get_widget_control() { 221 $this->do_customize_boot_actions(); 222 $widget_control = $this->manager->widgets->get_widget_control( $this->get_test_widget_control_args() ); 223 224 $this->assertContains( '<div class="form">', $widget_control ); 225 $this->assertContains( '<div class="widget-content">', $widget_control ); 226 $this->assertContains( '<input type="hidden" name="id_base" class="id_base" value="search"', $widget_control ); 227 $this->assertContains( '<input class="widefat"', $widget_control ); 228 } 229 230 /** 231 * @see WP_Customize_Widgets::get_widget_control_parts() 232 */ 233 function test_get_widget_control_parts() { 234 $this->do_customize_boot_actions(); 235 $widget_control_parts = $this->manager->widgets->get_widget_control_parts( $this->get_test_widget_control_args() ); 236 $this->assertArrayHasKey( 'content', $widget_control_parts ); 237 $this->assertArrayHasKey( 'control', $widget_control_parts ); 238 239 $this->assertContains( '<div class="form">', $widget_control_parts['control'] ); 240 $this->assertContains( '<div class="widget-content">', $widget_control_parts['control'] ); 241 $this->assertContains( '<input type="hidden" name="id_base" class="id_base" value="search"', $widget_control_parts['control'] ); 242 $this->assertNotContains( '<input class="widefat"', $widget_control_parts['control'] ); 243 $this->assertContains( '<input class="widefat"', $widget_control_parts['content'] ); 244 } 245 246 /** 247 * @see WP_Widget_Form_Customize_Control::json() 248 */ 249 function test_wp_widget_form_customize_control_json() { 250 $this->do_customize_boot_actions(); 251 $control = $this->manager->get_control( 'widget_search[2]' ); 252 $params = $control->json(); 253 254 $this->assertEquals( 'widget_form', $params['type'] ); 255 $this->assertRegExp( '#^<li[^>]+>\s+</li>$#', $params['content'] ); 256 $this->assertRegExp( '#^<div[^>]*class=\'widget\'[^>]*#s', $params['widget_control'] ); 257 $this->assertContains( '<div class="widget-content"></div>', $params['widget_control'] ); 258 $this->assertNotContains( '<input class="widefat"', $params['widget_control'] ); 259 $this->assertContains( '<input class="widefat"', $params['widget_content'] ); 260 $this->assertEquals( 'search-2', $params['widget_id'] ); 261 $this->assertEquals( 'search', $params['widget_id_base'] ); 262 $this->assertArrayHasKey( 'sidebar_id', $params ); 263 $this->assertArrayHasKey( 'width', $params ); 264 $this->assertArrayHasKey( 'height', $params ); 265 $this->assertInternalType( 'bool', $params['is_wide'] ); 266 267 } 198 268 } -
tests/phpunit/tests/widgets.php
diff --git tests/phpunit/tests/widgets.php tests/phpunit/tests/widgets.php index 443d3f3..c0dfe08 100644
class Tests_Widgets extends WP_UnitTestCase { 293 293 $this->assertArrayNotHasKey( 2, $option_value ); 294 294 } 295 295 296 /** 297 * @see wp_widget_control() 298 */ 299 function test_wp_widget_control() { 300 global $wp_registered_widgets; 301 302 wp_widgets_init(); 303 require_once ABSPATH . '/wp-admin/includes/widgets.php'; 304 $widget_id = 'search-2'; 305 $widget = $wp_registered_widgets[ $widget_id ]; 306 $params = array( 307 'widget_id' => $widget['id'], 308 'widget_name' => $widget['name'], 309 ); 310 $args = wp_list_widget_controls_dynamic_sidebar( array( 0 => $params, 1 => $widget['params'][0] ) ); 311 312 ob_start(); 313 call_user_func_array( 'wp_widget_control', $args ); 314 $control = ob_get_clean(); 315 $this->assertNotEmpty( $control ); 316 317 $this->assertContains( '<div class="widget-top">', $control ); 318 $this->assertContains( '<div class="widget-title-action">', $control ); 319 $this->assertContains( '<div class="widget-title">', $control ); 320 $this->assertContains( '<form method="post">', $control ); 321 $this->assertContains( '<div class="widget-content">', $control ); 322 $this->assertContains( '<input class="widefat"', $control ); 323 $this->assertContains( '<input type="hidden" name="id_base" class="id_base" value="search"', $control ); 324 $this->assertContains( '<div class="widget-control-actions">', $control ); 325 $this->assertContains( '<div class="alignleft">', $control ); 326 $this->assertContains( 'widget-control-remove', $control ); 327 $this->assertContains( 'widget-control-close', $control ); 328 $this->assertContains( '<div class="alignright">', $control ); 329 $this->assertContains( '<input type="submit" name="savewidget"', $control ); 330 331 $param_overrides = array( 332 'before_form' => '<!-- before_form -->', 333 'after_form' => '<!-- after_form -->', 334 'before_widget_content' => '<!-- before_widget_content -->', 335 'after_widget_content' => '<!-- after_widget_content -->', 336 ); 337 $params = array_merge( $params, $param_overrides ); 338 $args = wp_list_widget_controls_dynamic_sidebar( array( 0 => $params, 1 => $widget['params'][0] ) ); 339 340 ob_start(); 341 call_user_func_array( 'wp_widget_control', $args ); 342 $control = ob_get_clean(); 343 $this->assertNotEmpty( $control ); 344 $this->assertNotContains( '<form method="post">', $control ); 345 $this->assertNotContains( '<div class="widget-content">', $control ); 346 347 foreach ( $param_overrides as $contained ) { 348 $this->assertContains( $contained, $control ); 349 } 350 } 351 296 352 } -
tests/qunit/fixtures/customize-settings.js
diff --git tests/qunit/fixtures/customize-settings.js tests/qunit/fixtures/customize-settings.js index af1a2cf..39a49f5 100644
1 1 window.wp = window.wp || {}; 2 window.wp.customize = window.wp.customize || { get: function() {}};2 window.wp.customize = window.wp.customize || { get: function() {} }; 3 3 4 4 var customizerRootElement; 5 5 customizerRootElement = jQuery( '<div id="customize-theme-controls"><ul></ul></div>' ); 6 customizerRootElement.css( { position: 'absolute', left: -10000, top: -10000 } ); // remove from view6 customizerRootElement.css( { position: 'absolute', left: -10000, top: -10000 } ); // Remove from view. 7 7 jQuery( document.body ).append( customizerRootElement ); 8 8 9 9 window._wpCustomizeSettings = { -
new file tests/qunit/fixtures/customize-widgets.js
diff --git tests/qunit/fixtures/customize-widgets.js tests/qunit/fixtures/customize-widgets.js new file mode 100644 index 0000000..d3f8bb0
- + 1 window._wpCustomizeWidgetsSettings = { 2 'nonce': '12cc9d3284', 3 'registeredSidebars': [{ 4 'name': 'Widget Area', 5 'id': 'sidebar-1', 6 'description': 'Add widgets here to appear in your sidebar.', 7 'class': '', 8 'before_widget': '<aside id="%1$s" class="widget %2$s">', 9 'after_widget': '</aside>', 10 'before_title': '<h2 class="widget-title">', 11 'after_title': '</h2>' 12 }], 13 'registeredWidgets': { 14 'search-2': { 15 'name': 'Search', 16 'id': 'search-2', 17 'params': [ 18 { 19 'number': 2 20 } 21 ], 22 'classname': 'widget_search', 23 'description': 'A search form for your site.' 24 } 25 }, 26 'availableWidgets': [ 27 { 28 'name': 'Search', 29 'id': 'search-2', 30 'params': [ 31 { 32 'number': 2 33 } 34 ], 35 'classname': 'widget_search', 36 'description': 'A search form for your site.', 37 'temp_id': 'search-__i__', 38 'is_multi': true, 39 'multi_number': 3, 40 'is_disabled': false, 41 'id_base': 'search', 42 'transport': 'refresh', 43 'width': 250, 44 'height': 200, 45 'is_wide': false 46 } 47 ], 48 'l10n': { 49 'saveBtnLabel': 'Apply', 50 'saveBtnTooltip': 'Save and preview changes before publishing them.', 51 'removeBtnLabel': 'Remove', 52 'removeBtnTooltip': 'Trash widget by moving it to the inactive widgets sidebar.', 53 'error': 'An error has occurred. Please reload the page and try again.', 54 'widgetMovedUp': 'Widget moved up', 55 'widgetMovedDown': 'Widget moved down' 56 }, 57 'tpl': { 58 'widgetReorderNav': '<div class="widget-reorder-nav"><span class="move-widget" tabindex="0">Move to another area…</span><span class="move-widget-down" tabindex="0">Move down</span><span class="move-widget-up" tabindex="0">Move up</span></div>', 59 'moveWidgetArea': '<div class="move-widget-area"> <p class="description">Select an area to move this widget into:</p> <ul class="widget-area-select"> <% _.each( sidebars, function ( sidebar ){ %> <li class="" data-id="<%- sidebar.id %>" title="<%- sidebar.description %>" tabindex="0"><%- sidebar.name %></li> <% }); %> </ul> <div class="move-widget-actions"> <button class="move-widget-btn button-secondary" type="button">Move</button> </div> </div>' 60 } 61 }; 62 63 window._wpCustomizeSettings.panels.widgets = { 64 'id': 'widgets', 65 'description': 'Widgets are independent sections of content that can be placed into widgetized areas provided by your theme (commonly called sidebars).', 66 'priority': 110, 67 'type': 'default', 68 'title': 'Widgets', 69 'content': '', 70 'active': true, 71 'instanceNumber': 1 72 }; 73 74 window._wpCustomizeSettings.sections['sidebar-widgets-sidebar-1'] = { 75 'id': 'sidebar-widgets-sidebar-1', 76 'description': 'Add widgets here to appear in your sidebar.', 77 'priority': 0, 78 'panel': 'widgets', 79 'type': 'sidebar', 80 'title': 'Widget Area', 81 'content': '', 82 'active': false, 83 'instanceNumber': 1, 84 'customizeAction': 'Customizing ▸ Widgets', 85 'sidebarId': 'sidebar-1' 86 }; 87 88 window._wpCustomizeSettings.settings['widget_search[2]'] = { 89 'value': { 90 'encoded_serialized_instance': 'YToxOntzOjU6InRpdGxlIjtzOjY6IkJ1c2NhciI7fQ==', 91 'title': 'Buscar', 92 'is_widget_customizer_js_value': true, 93 'instance_hash_key': '45f0a7f15e50bd3be86b141e2a8b3aaf' 94 }, 95 'transport': 'refresh', 96 'dirty': false 97 }; 98 window._wpCustomizeSettings.settings['sidebars_widgets[sidebar-1]'] = { 99 'value': [ 'search-2' ], 100 'transport': 'refresh', 101 'dirty': false 102 }; 103 104 window._wpCustomizeSettings.controls['widget_search[2]'] = { 105 'settings': { 106 'default': 'widget_search[2]' 107 }, 108 'type': 'widget_form', 109 'priority': 0, 110 'active': false, 111 'section': 'sidebar-widgets-sidebar-1', 112 'content': '<li id="customize-control-widget_search-2" class="customize-control customize-control-widget_form"> <\/li>', 113 'label': 'Search', 114 'description': '', 115 'instanceNumber': 2, 116 'widget_id': 'search-2', 117 'widget_id_base': 'search', 118 'sidebar_id': 'sidebar-1', 119 'width': 250, 120 'height': 200, 121 'is_wide': false, 122 'widget_control': '<div id="widget-15_search-2" class="widget"> <div class="widget-top"> <div class="widget-title-action"> <a class="widget-action hide-if-no-js" href="#available-widgets"><\/a> <a class="widget-control-edit hide-if-js" href="\/wp-admin\/customize.php?editwidget=search-2&key=-1"> <span class="edit">Edit<\/span> <span class="add">Add<\/span> <span class="screen-reader-text">Search<\/span> <\/a> <\/div> <div class="widget-title"><h4>Search<span class="in-widget-title"><\/span><\/h4><\/div> <\/div> <div class="widget-inside"> <div class="form"> <div class="widget-content"><\/div><!-- .widget-content --> <input type="hidden" name="widget-id" class="widget-id" value="search-2" \/> <input type="hidden" name="id_base" class="id_base" value="search" \/> <input type="hidden" name="widget-width" class="widget-width" value="250" \/> <input type="hidden" name="widget-height" class="widget-height" value="200" \/> <input type="hidden" name="widget_number" class="widget_number" value="2" \/> <input type="hidden" name="multi_number" class="multi_number" value="" \/> <input type="hidden" name="add_new" class="add_new" value="" \/> <div class="widget-control-actions"> <div class="alignleft"> <a class="widget-control-remove" href="#remove">Delete<\/a> | <a class="widget-control-close" href="#close">Close<\/a> <\/div> <div class="alignright"> <input type="submit" name="savewidget" id="widget-search-2-savewidget" class="button button-primary widget-control-save right" value="Save" \/> <span class="spinner"><\/span> <\/div> <br class="clear" \/> <\/div> <\/div><!-- .form --> <\/div> <div class="widget-description"> A search form for your site. <\/div> <\/div>', 123 'widget_content': '<p><label for="widget-search-2-title">Title: <input class="widefat" id="widget-search-2-title" name="widget-search[2][title]" type="text" value="Buscar" \/><\/label><\/p>' 124 }; 125 window._wpCustomizeSettings.controls['sidebars_widgets[sidebar-1]'] = { 126 'settings': { 127 'default': 'sidebars_widgets[sidebar-1]' 128 }, 129 'type': 'sidebar_widgets', 130 'priority': 99, 131 'active': true, 132 'section': 'sidebar-widgets-sidebar-1', 133 'content': '<li id="customize-control-sidebars_widgets-sidebar-1" class="customize-control customize-control-sidebar_widgets"> <span class="button-secondary add-new-widget" tabindex="0"> Add a Widget <\/span> <span class="reorder-toggle" tabindex="0"> <span class="reorder">Reorder<\/span> <span class="reorder-done">Done<\/span> <\/span> <\/li>', 134 'label': '', 135 'description': '', 136 'instanceNumber': 1, 137 'sidebar_id': 'sidebar-1' 138 }; -
tests/qunit/index.html
diff --git tests/qunit/index.html tests/qunit/index.html index 71599d4..aa454a9 100644
25 25 <script src="fixtures/customize-header.js"></script> 26 26 <script src="fixtures/customize-settings.js"></script> 27 27 <script src="fixtures/customize-menus.js"></script> 28 <script src="fixtures/customize-widgets.js"></script> 28 29 </div> 29 30 <p><a href="editor">TinyMCE tests</a></p> 30 31 … … 44 45 45 46 <script src="../../src/wp-admin/js/nav-menu.js"></script> 46 47 <script src="../../src/wp-admin/js/customize-nav-menus.js"></script> 48 <script src="../../src/wp-admin/js/customize-widgets.js"></script> 47 49 <script src="../../src/wp-admin/js/word-count.js"></script> 48 50 49 51 <!-- Unit tests --> … … 54 56 <script src="wp-admin/js/customize-controls.js"></script> 55 57 <script src="wp-admin/js/customize-controls-utils.js"></script> 56 58 <script src="wp-admin/js/customize-nav-menus.js"></script> 59 <script src="wp-admin/js/customize-widgets.js"></script> 57 60 <script src="wp-admin/js/word-count.js"></script> 58 61 59 62 <!-- Customizer templates for sections --> … … 267 270 <div class="menu-item-reorder-nav"> 268 271 <button type="button" class="menus-move-up">Move up</button><button type="button" class="menus-move-down">Move down</button><button type="button" class="menus-move-left">Move one level up</button><button type="button" class="menus-move-right">Move one level down</button> </div> 269 272 </script> 273 274 <script type="text/html" id="tmpl-customize-section-sidebar"> 275 <li id="accordion-section-{{ data.id }}" class="accordion-section control-section control-section-{{ data.type }}"> 276 <h3 class="accordion-section-title" tabindex="0"> 277 {{ data.title }} 278 <span class="screen-reader-text">Press return or enter to open</span> 279 </h3> 280 <ul class="accordion-section-content"> 281 <li class="customize-section-description-container"> 282 <div class="customize-section-title"> 283 <button class="customize-section-back" tabindex="-1"> 284 <span class="screen-reader-text">Back</span> 285 </button> 286 <h3> 287 <span class="customize-action"> 288 {{{ data.customizeAction }}} 289 </span> 290 {{ data.title }} 291 </h3> 292 </div> 293 <# if ( data.description ) { #> 294 <div class="description customize-section-description"> 295 {{{ data.description }}} 296 </div> 297 <# } #> 298 </li> 299 </ul> 300 </li> 301 </script> 302 270 303 <div hidden> 271 304 <div id="available-menu-items" class="accordion-container"> 272 305 <div class="customize-section-title"> … … 375 408 </div><!-- #available-menu-items --> 376 409 </div><!-- end nav menu templates --> 377 410 411 <div hidden> 412 <div id="widgets-left"><!-- compatibility with JS which looks for widget templates here --> 413 <div id="available-widgets"> 414 <div class="customize-section-title"> 415 <button class="customize-section-back" tabindex="-1"> 416 <span class="screen-reader-text">Back</span> 417 </button> 418 <h3> 419 <span class="customize-action">Customizing ▸ Widgets</span> 420 Add a Widget </h3> 421 </div> 422 <div id="available-widgets-filter"> 423 <label class="screen-reader-text" for="widgets-search">Search Widgets</label> 424 <input type="search" id="widgets-search" placeholder="Search widgets…" /> 425 </div> 426 <div id="available-widgets-list"> 427 <div id="widget-tpl-search-2" data-widget-id="search-2" class="widget-tpl search-2" tabindex="0"> 428 <div id='widget-11_search-__i__' class='widget'> <div class="widget-top"> 429 <div class="widget-title-action"> 430 <a class="widget-action hide-if-no-js" href="#available-widgets"></a> 431 <a class="widget-control-edit hide-if-js" href="/wp-admin/customize.php?editwidget=search-2&addnew=1&num=3&base=search"> 432 <span class="edit">Edit</span> 433 <span class="add">Add</span> 434 <span class="screen-reader-text">Search</span> 435 </a> 436 </div> 437 <div class="widget-title"><h4>Search<span class="in-widget-title"></span></h4></div> 438 </div> 378 439 440 <div class="widget-inside"> 441 <div class="form"> 442 <div class="widget-content"> 443 <p><label for="widget-search-__i__-title">Title: <input class="widefat" id="widget-search-__i__-title" name="widget-search[__i__][title]" type="text" value="" /></label></p> 444 </div> 445 <input type="hidden" name="widget-id" class="widget-id" value="search-__i__" /> 446 <input type="hidden" name="id_base" class="id_base" value="search" /> 447 <input type="hidden" name="widget-width" class="widget-width" value="250" /> 448 <input type="hidden" name="widget-height" class="widget-height" value="200" /> 449 <input type="hidden" name="widget_number" class="widget_number" value="2" /> 450 <input type="hidden" name="multi_number" class="multi_number" value="3" /> 451 <input type="hidden" name="add_new" class="add_new" value="multi" /> 452 453 <div class="widget-control-actions"> 454 <div class="alignleft"> 455 <a class="widget-control-remove" href="#remove">Delete</a> | 456 <a class="widget-control-close" href="#close">Close</a> 457 </div> 458 <div class="alignright"> 459 <input type="submit" name="savewidget" id="widget-search-__i__-savewidget" class="button button-primary widget-control-save right" value="Save" /> <span class="spinner"></span> 460 </div> 461 <br class="clear" /> 462 </div> 463 </div><!-- .form --> 464 </div> 465 466 <div class="widget-description"> 467 A search form for your site. 468 </div> 469 </div> </div> 470 </div><!-- #available-widgets-list --> 471 </div><!-- #available-widgets --> 472 </div><!-- #widgets-left --> 473 </div><!-- end widget templates --> 379 474 <script src="../../src/wp-includes/js/tinymce/tinymce.js"></script> 380 475 <script src="editor/js/utils.js"></script> 381 476 <script src="wp-includes/js/tinymce/plugins/wptextpattern/plugin.js"></script> -
new file tests/qunit/wp-admin/js/customize-widgets.js
diff --git tests/qunit/wp-admin/js/customize-widgets.js tests/qunit/wp-admin/js/customize-widgets.js new file mode 100644 index 0000000..3a8a3e3
- + 1 /* global wp */ 2 jQuery( window ).load( function() { 3 4 var api = wp.customize, $ = jQuery; 5 6 module( 'Customize Widgets' ); 7 8 test( 'fixtures should be present', function() { 9 var widgetControl; 10 ok( api.panel( 'widgets' ) ); 11 ok( api.section( 'sidebar-widgets-sidebar-1' ) ); 12 widgetControl = api.control( 'widget_search[2]' ); 13 ok( widgetControl ); 14 ok( api.control( 'sidebars_widgets[sidebar-1]' ) ); 15 ok( api( 'widget_search[2]' ) ); 16 ok( api( 'sidebars_widgets[sidebar-1]' ) ); 17 ok( widgetControl.params.content ); 18 ok( widgetControl.params.widget_control ); 19 ok( widgetControl.params.widget_content ); 20 ok( widgetControl.params.widget_id ); 21 ok( widgetControl.params.widget_id_base ); 22 }); 23 24 test( 'widget contents should embed (with widget-added event) when section and control expand', function() { 25 var control, section, widgetAddedEvent = null, widgetControlRootElement = null; 26 control = api.control( 'widget_search[2]' ); 27 section = api.section( 'sidebar-widgets-sidebar-1' ); 28 29 $( document ).on( 'widget-added', function( event, widgetElement ) { 30 widgetAddedEvent = event; 31 widgetControlRootElement = widgetElement; 32 }); 33 34 ok( ! section.expanded() ); 35 ok( 0 === control.container.find( '> .widget' ).length ); 36 37 section.expand(); 38 ok( ! widgetAddedEvent ); 39 ok( 1 === control.container.find( '> .widget' ).length ); 40 ok( 0 === control.container.find( '.widget-content' ).children().length ); 41 42 control.expand(); 43 ok( 1 === control.container.find( '.widget-content' ).children().length ); 44 ok( widgetAddedEvent ); 45 ok( widgetControlRootElement.is( control.container.find( '> .widget' ) ) ); 46 ok( 1 === control.container.find( '.widget-content #widget-search-2-title' ).length ); 47 48 $( document ).off( 'widget-added' ); 49 }); 50 });