Ticket #31336: 30737-and-31336.diff
File 30737-and-31336.diff, 74.1 KB (added by , 9 years ago) |
---|
-
src/wp-admin/css/customize-controls.css
diff --git src/wp-admin/css/customize-controls.css src/wp-admin/css/customize-controls.css index b256106..016ac20 100644
body { 20 20 } 21 21 22 22 #customize-controls .description { 23 color: # 666666;23 color: #555; 24 24 } 25 25 26 26 #customize-header-actions .button-primary { … … body { 50 50 overflow-x: hidden; 51 51 } 52 52 53 #customize- info {53 #customize-controls .customize-info { 54 54 border: none; 55 55 border-top: 1px solid #ddd; 56 border-bottom: 1px solid #ddd; 57 margin-bottom: 15px; 56 58 } 57 59 58 #customize- info .accordion-section-title {59 background -color: #fff;60 color: # 666666;60 #customize-controls .customize-info .accordion-section-title { 61 background: #fff; 62 color: #555; 61 63 border-left: none; 62 64 border-right: none; 63 border-bottom: 1px solid #eeeeee; 65 border-bottom: none; 66 cursor: default; 64 67 } 65 68 66 #customize- info.open .accordion-section-title:after,67 #customize- info .accordion-section-title:hover:after,68 #customize- info .accordion-section-title:focus:after {69 color: # 555555;69 #customize-controls .customize-info.open .accordion-section-title:after, 70 #customize-controls .customize-info .accordion-section-title:hover:after, 71 #customize-controls .customize-info .accordion-section-title:focus:after { 72 color: #333; 70 73 } 71 74 72 #customize-info .preview-notice { 75 #customize-controls .customize-info .accordion-section-title:after { 76 display: none; 77 } 78 79 #customize-controls .customize-info .preview-notice { 73 80 font-size: 13px; 74 81 line-height: 24px; 75 82 } 76 83 77 #customize-info .theme-name { 84 #customize-controls .control-section .customize-section-title h3, 85 #customize-controls .control-section h3.customize-section-title, 86 #customize-controls .customize-info .panel-title { 78 87 font-size: 20px; 79 88 font-weight: 200; 80 89 line-height: 24px; 81 90 display: block; 91 overflow: hidden; 92 white-space: nowrap; 93 text-overflow: ellipsis; 82 94 } 83 95 84 #customize-info .theme-screenshot { 85 width: 258px; 96 #customize-controls .customize-section-title span.customize-action { 97 overflow: hidden; 98 white-space: nowrap; 99 text-overflow: ellipsis; 86 100 } 87 101 88 #customize-info .theme-description { 89 margin-top: 1em; 90 color: #666666; 91 line-height: 20px; 102 #customize-controls .customize-info .customize-help-toggle { 103 position: absolute; 104 top: 4px; 105 right: 1px; 106 padding: 20px 20px 10px 10px; 107 width: 20px; 108 height: 20px; 109 cursor: pointer; 110 box-shadow: none; 111 -webkit-appearance: none; 112 background: transparent; 113 color: #555; 114 border: none; 115 } 116 117 #customize-controls .customize-info .customize-help-toggle:before { 118 position: absolute; 119 top: 5px; 120 left: 5px; 121 } 122 123 #customize-controls .customize-info.open .customize-help-toggle, 124 #customize-controls .customize-info .customize-help-toggle:focus, 125 #customize-controls .customize-info .customize-help-toggle:hover { 126 color: #0073aa; 127 } 128 129 #customize-controls .customize-info .customize-panel-description { 130 color: #555; 131 display: none; 132 background: #fff; 133 padding: 12px 15px; 134 border-top: 1px solid #ddd; 135 } 136 137 #customize-controls .customize-info .customize-panel-description p:first-child { 138 margin-top: 0; 139 } 140 141 #customize-controls .customize-info .customize-panel-description p:last-child { 142 margin-bottom: 0; 143 } 144 145 #customize-controls .current-panel .control-section > h3.accordion-section-title { 146 padding-right: 30px; 92 147 } 93 148 94 149 #customize-theme-controls .control-section { … … body { 96 151 } 97 152 98 153 #customize-theme-controls .accordion-section-title { 99 color: #555 555;154 color: #555; 100 155 background-color: #fff; 101 border-bottom: 1px solid #eeeeee; 156 border-bottom: 1px solid #eee; 157 } 158 159 #customize-theme-controls .accordion-section-title:after { 160 content: "\f345"; 161 } 162 163 .rtl #customize-theme-controls .accordion-section-title:after { 164 content: "\f341"; 102 165 } 103 166 104 167 #customize-theme-controls .accordion-section-content { 105 color: #555 555;106 background: #fff;168 color: #555; 169 background: transparent; 107 170 } 108 171 109 #customize-info.open .accordion-section-title, 110 #customize-info .accordion-section-title:hover, 111 #customize-info .accordion-section-title:focus, 112 #customize-theme-controls .control-section:hover > .accordion-section-title, 113 #customize-theme-controls .control-section .accordion-section-title:hover, 114 #customize-theme-controls .control-section.open .accordion-section-title, 115 #customize-theme-controls .control-section .accordion-section-title:focus { 116 color: #23282d; 117 background: #f5f5f5; 172 #customize-controls .control-section:hover > .accordion-section-title, 173 #customize-controls .control-section .accordion-section-title:hover, 174 #customize-controls .control-section.open .accordion-section-title, 175 #customize-controls .control-section .accordion-section-title:focus { 176 color: #fff; 177 background: #0073aa; 118 178 } 119 179 120 180 .js .control-section:hover .accordion-section-title, … … body { 128 188 #customize-theme-controls .control-section .accordion-section-title:hover:after, 129 189 #customize-theme-controls .control-section.open .accordion-section-title:after, 130 190 #customize-theme-controls .control-section .accordion-section-title:focus:after { 131 color: # 555;191 color: #fff; 132 192 } 133 193 134 #customize-info.open,135 194 #customize-theme-controls .control-section.open { 136 border-bottom: 1px solid #eee eee;195 border-bottom: 1px solid #eee; 137 196 } 138 197 139 198 #customize-theme-controls .control-section.open .accordion-section-title { 140 border-bottom-color: #eee eee!important;199 border-bottom-color: #eee !important; 141 200 } 142 201 143 202 #customize-theme-controls .control-section:last-of-type.open, … … body { 145 204 border-bottom-color: #ddd; 146 205 } 147 206 148 #customize-theme-controls > ul, 207 #customize-theme-controls > ul { 208 margin: 0; 209 } 210 149 211 #customize-theme-controls .accordion-section-content { 150 212 margin: 0; 213 position: absolute; 214 left: 100%; 215 top: 0; 216 width: -webkit-calc(100% - 24px); 217 width: calc(100% - 24px); 218 padding: 12px; 151 219 } 152 220 153 .c ontrol-section.control-panel > .accordion-section-title{154 padding-right: 54px;221 .customize-section-description-container { 222 margin-bottom: 15px; 155 223 } 156 224 157 .control-section.control-panel > .accordion-section-title:after { 158 content: "\f345"; 159 background: #f5f5f5; 225 .customize-section-title { 226 margin: -12px; 227 border-bottom: 1px solid #ddd; 228 background: #fff; 229 } 230 231 #customize-theme-controls .customize-themes-panel h3.customize-section-title:first-child { 232 border-bottom: 1px solid #ddd; 233 padding: 12px 12px 12px 12px; 234 } 235 236 .ios #customize-theme-controls .customize-themes-panel h3.customize-section-title:first-child { 237 padding: 12px 12px 13px 12px; 238 } 239 240 .customize-section-title h3, 241 h3.customize-section-title { 242 padding: 10px 10px 12px 14px; 243 margin: 0; 244 line-height: 21px; 160 245 color: #555; 161 width: 38px;162 height: 100%;163 margin: -11px -10px -11px 0; /* compensate for positioning */164 line-height: 45px;165 padding-left: 5px;166 border-left: 1px solid #eee;167 z-index: 0;168 246 } 169 247 170 #customize-theme-controls .control-section.control-panel > h3.accordion-section-title:focus:after, 171 #customize-theme-controls .control-section.control-panel > h3.accordion-section-title:hover:after { 172 background: #ddd; 173 color: #000; 174 border: 1px solid #d9d9d9; 175 border-right: none; 176 margin-top: -12px; 177 line-height: 44px; 178 z-index: 1; 248 #customize-theme-controls .control-section .accordion-section-content > li.customize-control:nth-child(2) { 249 margin-top: 12px; 250 } 251 252 #customize-theme-controls { 253 position: relative; 254 left: 0; 255 transition: .18s left ease-in-out; 256 } 257 258 .section-open #customize-info, 259 .section-open #customize-theme-controls { 260 left: -100%; 261 } 262 263 .section-open .control-panel-back { 264 display: none; 179 265 } 180 266 181 267 .accordion-sub-container.control-panel-content { … … body { 184 270 left: 300px; 185 271 top: 0; 186 272 width: 300px; 187 border-top: 1px solid #ddd;188 273 -webkit-transition: left ease-in-out .18s; 189 274 transition: left ease-in-out .18s; 190 275 } 191 276 277 .ios .accordion-sub-container.control-panel-content { 278 -webkit-transition: left 0s; 279 transition: left 0s; 280 } 281 192 282 .accordion-sub-container.control-panel-content.animating { 193 283 display: block; 194 284 } … … body { 242 332 transition: left .18s ease-in-out, color .1s ease-in-out, background .1s ease-in-out; 243 333 } 244 334 245 .ios .control-panel-back { 335 .customize-panel-back, 336 .customize-section-back { 337 display: block; 338 float: left; 339 width: 48px; 340 height: 69px; 341 padding: 0 24px 0 0; 342 margin: 0; 343 background: #fff; 344 border: none; 345 border-right: 1px solid #ddd; 346 box-shadow: none; 347 cursor: pointer; 348 -webkit-transition: left .18s ease-in-out, color .1s ease-in-out, background .1s ease-in-out; 349 transition: left .18s ease-in-out, color .1s ease-in-out, background .1s ease-in-out; 350 } 351 352 .customize-section-back { 353 height: 70px; 354 } 355 356 .ios .control-panel-back, 357 .ios .customize-panel-back, 358 .ios .customize-section-back { 246 359 -webkit-transition: left 0s; 247 360 transition: left 0s; 248 361 } 249 362 250 .collapsed .control-panel-back { 363 .collapsed .control-panel-back, 364 .ios .customize-panel-back { 251 365 display: none; 252 366 } 253 367 368 .ios .expanded.in-sub-panel .customize-panel-back { 369 display: block; 370 } 371 372 .panel-meta.customize-info .accordion-section-title { 373 margin-left: 48px; 374 } 375 376 #customize-controls .panel-meta.customize-info .accordion-section-title:hover { 377 background: #fff; 378 color: #555; 379 } 380 254 381 .customize-overlay-close:focus, 255 382 .customize-overlay-close:hover, 256 383 .customize-controls-close:focus, … … body { 267 394 box-shadow: none; 268 395 } 269 396 397 .customize-panel-back:hover, 398 .customize-panel-back:focus, 399 .customize-section-back:hover, 400 .customize-section-back:focus { 401 background: #0073aa; 402 border-color: #ccc; 403 color: #fff; 404 outline: none; 405 -webkit-box-shadow: none; 406 box-shadow: none; 407 } 408 270 409 .customize-overlay-close:before, 271 410 .customize-controls-close:before { 272 411 font: normal 22px/45px dashicons; … … body { 276 415 left: 13px; 277 416 } 278 417 418 .customize-panel-back:before, 419 .customize-section-back:before { 420 font: normal 20px/69px dashicons; 421 content: "\f341"; 422 position: relative; 423 left: 13px; 424 } 425 279 426 .control-panel-back:before { 280 427 font: normal 20px/45px dashicons; 281 428 content: "\f341"; … … body { 284 431 left: 13px; 285 432 } 286 433 287 .in-sub-panel .control-panel-back {288 left: 0;289 }290 291 .current-panel > .accordion-section-title {292 height: 22px;293 }294 295 434 .wp-full-overlay-sidebar .wp-full-overlay-header { 296 435 -webkit-transition: padding ease-in-out .18s; 297 436 transition: padding ease-in-out .18s; … … body { 345 484 transition: left 0s; 346 485 } 347 486 348 .control-section.control-panel .accordion-section-title .panel-title {349 font-size: 20px;350 font-weight: 200;351 line-height: 24px;352 display: block;353 border: none;354 }355 356 .control-section.control-panel .preview-notice {357 font-size: 13px;358 line-height: 24px;359 }360 361 487 p.customize-section-description { 362 488 font-style: normal; 489 margin-top: 22px; 490 margin-bottom: 0; 363 491 } 364 492 365 493 .customize-control { 366 494 width: 100%; 367 495 float: left; 368 496 clear: both; 369 margin-bottom: 8px;497 margin-bottom: 12px; 370 498 } 371 499 372 500 .customize-control select, … … p.customize-section-description { 498 626 } 499 627 500 628 .wp-full-overlay-sidebar { 501 background: #eee eee;629 background: #eee; 502 630 border-right: 1px solid #ddd; 503 631 } 504 632 … … p.customize-section-description { 542 670 line-height: 16px; 543 671 margin-right: 16px; 544 672 padding: 4px 5px; 545 border: 2px solid #eee eee;673 border: 2px solid #eee; 546 674 -webkit-user-select: none; 547 675 -moz-user-select: none; 548 676 -ms-user-select: none; … … p.customize-section-description { 555 683 bottom: 0; 556 684 right: 0; 557 685 width: 20px; 558 background: #eee eee;686 background: #eee; 559 687 } 560 688 561 689 .customize-control .dropdown-arrow:after { … … p.customize-section-description { 575 703 576 704 .customize-control .dropdown-status { 577 705 color: #32373c; 578 background: #eee eee;706 background: #eee; 579 707 display: none; 580 708 max-width: 112px; 581 709 } … … p.customize-section-description { 595 723 } 596 724 597 725 .customize-control-color .dropdown .dropdown-content { 598 background-color: #555 555;726 background-color: #555; 599 727 border: 1px solid rgba(0, 0, 0, 0.15); 600 728 } 601 729 … … p.customize-section-description { 897 1025 898 1026 #customize-theme-controls .control-section-themes .accordion-section-title:hover, 899 1027 #customize-theme-controls .control-section-themes .accordion-section-title:focus { 900 color: #555 555;1028 color: #555; 901 1029 background-color: #fff; 902 1030 } 903 1031 … … p.customize-section-description { 913 1041 padding-right: 100px; /* Space for the button */ 914 1042 } 915 1043 916 .control-section-themes .accordion-section-title span { 917 font-size: small; 1044 .control-section-themes .accordion-section-title span.customize-action, 1045 #customize-controls .customize-section-title span.customize-action { 1046 font-size: 13px; 918 1047 display: block; 919 1048 font-weight: 400; 920 1049 } … … p.customize-section-description { 928 1057 font-weight: normal; 929 1058 } 930 1059 1060 .control-section-themes .accordion-section-title:before { 1061 display: none; 1062 } 1063 931 1064 .customize-themes-panel { 932 1065 display: none; 933 1066 padding: 0 8px; … … p.customize-section-description { 938 1071 box-sizing: border-box; 939 1072 } 940 1073 1074 .customize-themes-panel .accordion-section-title:first-child { 1075 margin-top: 0; 1076 } 1077 1078 #customize-controls .customize-themes-panel .accordion-section-title:nth-child(2) { 1079 font-size: 14px; 1080 font-weight: 600; 1081 } 941 1082 942 1083 .customize-themes-panel > h2 { 943 1084 padding: 15px 8px 0 8px; … … p.customize-section-description { 956 1097 margin-bottom: 8px; 957 1098 } 958 1099 1100 #customize-theme-controls .themes.accordion-section-content { 1101 position: relative; 1102 left: 0; 1103 padding: 0; 1104 width: 100%; 1105 } 1106 959 1107 .wp-customizer .theme-browser .themes { 960 1108 padding-bottom: 8px; 961 1109 } … … body.cheatin p { 1170 1318 margin-bottom: 4px; 1171 1319 } 1172 1320 1173 .adding-widget #customize-header-actions .primary-actions {1174 display: none;1175 }1176 1177 .adding-widget #customize-header-actions .secondary-actions {1178 display: block;1179 }1180 1181 1321 #customize-header-actions .button-primary { 1182 1322 margin-top: 6px; 1183 1323 } -
src/wp-admin/css/customize-widgets.css
diff --git src/wp-admin/css/customize-widgets.css src/wp-admin/css/customize-widgets.css index ba95022..3601cae 100644
14 14 display: none; 15 15 } 16 16 17 .control-section.control-section-sidebar .accordion-section-content.ui-sortable { 18 overflow: visible; 19 } 20 17 21 .customize-control-widget_form .widget-top { 18 22 -webkit-transition: opacity 0.5s; 19 23 transition: opacity 0.5s; … … body.adding-widget .add-new-widget:before { 348 352 width: 300px; 349 353 margin: 0; 350 354 z-index: 1; 351 background: # fff!important;355 background: #eee !important; 352 356 -webkit-transition: all 0.2s; 353 357 transition: all 0.2s; 354 border-right: 1px solid #ddd ddd;358 border-right: 1px solid #ddd; 355 359 } 356 360 357 361 #available-widgets-list { … … body.adding-widget .add-new-widget:before { 384 388 #available-widgets .widget-tpl { 385 389 position: relative; 386 390 padding: 20px 15px 20px 60px; 391 background: #fff; 387 392 border-bottom: 1px solid #e4e4e4; 388 393 cursor: pointer; 389 394 display: none; … … body.adding-widget .add-new-widget:before { 391 396 392 397 #available-widgets .widget-tpl:hover, 393 398 #available-widgets .widget-tpl.selected { 394 background: #fafafa; 399 background: #eee; 400 border-bottom-color: #ccc; 395 401 } 396 402 397 403 #available-widgets .widget-top, … … body.adding-widget #customize-preview { 583 589 #available-widgets [class*="tweet"] .widget-title:before, 584 590 #available-widgets [class*="twitter"] .widget-title:before { content: "\f301"; } 585 591 592 #available-widgets .customize-section-title { 593 display: none; 594 } 586 595 587 596 @media screen and (max-height: 700px) and (min-width: 981px) { 588 .customize-control {597 .customize-control-widget { 589 598 margin-bottom: 0; 590 599 } 591 600 .widget-top { … … body.adding-widget #customize-preview { 628 637 width: 100%; 629 638 } 630 639 640 #available-widgets .customize-section-title { 641 display: block; 642 margin: 0; 643 } 644 645 #available-widgets .customize-section-back { 646 height: 69px; 647 } 648 649 #available-widgets .customize-section-title h3 { 650 font-size: 20px; 651 font-weight: 200; 652 padding: 9px 10px 12px 14px; 653 margin: 0; 654 line-height: 24px; 655 color: #555; 656 display: block; 657 overflow: hidden; 658 white-space: nowrap; 659 text-overflow: ellipsis; 660 } 661 662 #available-widgets .customize-section-title .customize-action { 663 font-size: 13px; 664 display: block; 665 font-weight: 400; 666 overflow: hidden; 667 white-space: nowrap; 668 text-overflow: ellipsis; 669 } 670 631 671 #available-widgets-filter { 632 position: static;672 position: relative; 633 673 width: 100%; 674 background: #fff; 634 675 height: auto; 676 padding: 10px 15px; 677 } 678 679 #available-widgets-list { 680 top: 140px; 635 681 } 636 682 } -
src/wp-admin/customize.php
diff --git src/wp-admin/customize.php src/wp-admin/customize.php index 65caa29..e3ea406 100644
do_action( 'customize_controls_print_scripts' ); 147 147 148 148 <div id="widgets-right"><!-- For Widget Customizer, many widgets try to look for instances under div#widgets-right, so we have to add that ID to a container div in the Customizer for compat --> 149 149 <div class="wp-full-overlay-sidebar-content" tabindex="-1"> 150 <div id="customize-info" class="accordion-section ">151 <div class="accordion-section-title" aria-label="<?php esc_attr_e( 'Customizer Options' ); ?>" tabindex="0">150 <div id="customize-info" class="accordion-section customize-info"> 151 <div class="accordion-section-title" aria-label="<?php esc_attr_e( 'Customizer Options' ); ?>"> 152 152 <span class="preview-notice"><?php 153 echo sprintf( __( 'You are customizing %s' ), '<strong class=" theme-name site-title">' . get_bloginfo( 'name' ) . '</strong>' );153 echo sprintf( __( 'You are customizing %s' ), '<strong class="panel-title site-title">' . get_bloginfo( 'name' ) . '</strong>' ); 154 154 ?></span> 155 <button class="customize-help-toggle dashicons dashicons-editor-help" aria-expanded="false"><span class="screen-reader-text"><?php _e( 'Help' ); ?></span></button> 155 156 </div> 156 <div class=" accordion-section-content"><?php157 <div class="customize-panel-description"><?php 157 158 _e( 'The Customizer allows you to preview changes to your site before publishing them. You can also navigate to different pages on your site to preview them.' ); 158 159 ?></div> 159 160 </div> … … do_action( 'customize_controls_print_scripts' ); 174 175 <div id="customize-preview" class="wp-full-overlay-main"></div> 175 176 <?php 176 177 177 // Render control templates. 178 // Render Panel, Section, and Control templates. 179 $wp_customize->render_panel_templates(); 180 $wp_customize->render_section_templates(); 178 181 $wp_customize->render_control_templates(); 179 182 180 183 /** … … do_action( 'customize_controls_print_scripts' ); 258 261 259 262 // Prepare Customize Setting objects to pass to JavaScript. 260 263 foreach ( $wp_customize->settings() as $id => $setting ) { 261 $settings['settings'][ $id ] = array( 262 'value' => $setting->js_value(), 263 'transport' => $setting->transport, 264 'dirty' => $setting->dirty, 265 ); 264 if ( $setting->check_capabilities() ) { 265 $settings['settings'][ $id ] = array( 266 'value' => $setting->js_value(), 267 'transport' => $setting->transport, 268 'dirty' => $setting->dirty, 269 ); 270 } 266 271 } 267 272 268 273 // Prepare Customize Control objects to pass to JavaScript. 269 274 foreach ( $wp_customize->controls() as $id => $control ) { 270 $settings['controls'][ $id ] = $control->json(); 275 if ( $control->check_capabilities() ) { 276 $settings['controls'][ $id ] = $control->json(); 277 } 271 278 } 272 279 273 280 // Prepare Customize Section objects to pass to JavaScript. 274 281 foreach ( $wp_customize->sections() as $id => $section ) { 275 $settings['sections'][ $id ] = $section->json(); 282 if ( $section->check_capabilities() ) { 283 $settings['sections'][ $id ] = $section->json(); 284 } 276 285 } 277 286 278 287 // Prepare Customize Panel objects to pass to JavaScript. 279 foreach ( $wp_customize->panels() as $id => $panel ) { 280 $settings['panels'][ $id ] = $panel->json(); 281 foreach ( $panel->sections as $section_id => $section ) { 282 $settings['sections'][ $section_id ] = $section->json(); 288 foreach ( $wp_customize->panels() as $panel_id => $panel ) { 289 if ( $panel->check_capabilities() ) { 290 $settings['panels'][ $panel_id ] = $panel->json(); 291 foreach ( $panel->sections as $section_id => $section ) { 292 if ( $section->check_capabilities() ) { 293 $settings['sections'][ $section_id ] = $section->json(); 294 } 295 } 283 296 } 284 297 } 285 298 -
src/wp-admin/js/customize-controls.js
diff --git src/wp-admin/js/customize-controls.js src/wp-admin/js/customize-controls.js index e211a41..0c46d72 100644
156 156 Container = api.Class.extend({ 157 157 defaultActiveArguments: { duration: 'fast', completeCallback: $.noop }, 158 158 defaultExpandedArguments: { duration: 'fast', completeCallback: $.noop }, 159 containerType: 'container', 159 160 160 161 /** 161 162 * @since 4.1.0 … … 168 169 container.id = id; 169 170 container.params = {}; 170 171 $.extend( container, options || {} ); 172 container.templateSelector = 'customize-' + container.containerType + '-' + container.params.type; 171 173 container.container = $( container.params.content ); 174 if ( 0 === container.container.length ) { 175 container.container = $( container.getContainer() ); 176 } 172 177 173 178 container.deferred = { 174 179 embedded: new $.Deferred() … … 191 196 container.onChangeExpanded( expanded, args ); 192 197 }); 193 198 194 container.attachEvents(); 199 container.deferred.embedded.done( function () { 200 container.attachEvents(); 201 }); 195 202 196 203 api.utils.bubbleChildValueChanges( container, [ 'priority', 'active' ] ); 197 204 … … 366 373 * Bring the container into view and then expand this and bring it into view 367 374 * @param {Object} [params] 368 375 */ 369 focus: focus 376 focus: focus, 377 378 /** 379 * Return the container html, generated from its JS template, if it exists. 380 * 381 * @since 4.3.0 382 */ 383 getContainer: function () { 384 var template, 385 container = this; 386 387 if ( 0 !== $( '#tmpl-' + container.templateSelector ).length ) { 388 template = wp.template( container.templateSelector ); 389 if ( template && container.container ) { 390 return $.trim( template( container.params ) ); 391 } 392 } 393 394 return '<li></li>'; 395 } 370 396 }); 371 397 372 398 /** … … 376 402 * @augments wp.customize.Class 377 403 */ 378 404 api.Section = Container.extend({ 405 containerType: 'section', 379 406 380 407 /** 381 408 * @since 4.1.0 … … 443 470 * @since 4.1.0 444 471 */ 445 472 attachEvents: function () { 446 var section = this; 473 var section = this, 474 backBtn = section.container.find( '.customize-section-back' ), 475 sectionTitle = section.container.find( '.accordion-section-title' ).first(); 447 476 448 477 // Expand/Collapse accordion sections on click. 449 section.container.find( '.accordion-section-title ' ).on( 'click keydown', function( event ) {478 section.container.find( '.accordion-section-title, .customize-section-back' ).on( 'click keydown', function( event ) { 450 479 if ( api.utils.isKeydownButNotEnterEvent( event ) ) { 451 480 return; 452 481 } … … 454 483 455 484 if ( section.expanded() ) { 456 485 section.collapse(); 486 backBtn.attr( 'tabindex', '-1' ); 487 sectionTitle.attr( 'tabindex', '0' ); 488 sectionTitle.focus(); 457 489 } else { 458 490 section.expand(); 491 sectionTitle.attr( 'tabindex', '-1' ); 492 backBtn.attr( 'tabindex', '0' ); 493 backBtn.focus(); 459 494 } 460 495 }); 461 496 }, … … 499 534 * @param {Object} args 500 535 */ 501 536 onChangeExpanded: function ( expanded, args ) { 502 var section = this, 537 var position, scroll, section = this, 538 container = section.container.closest( '.wp-full-overlay-sidebar-content' ), 503 539 content = section.container.find( '.accordion-section-content' ), 540 overlay = section.container.closest( '.wp-full-overlay' ), 504 541 expand; 505 542 506 if ( expanded ) {543 if ( expanded && ! section.container.hasClass( 'open' ) ) { 507 544 508 545 if ( args.unchanged ) { 509 546 expand = args.completeCallback; 510 547 } else { 548 container.scrollTop( 0 ); 511 549 expand = function () { 512 content.stop().slideDown( args.duration, args.completeCallback );513 550 section.container.addClass( 'open' ); 551 overlay.addClass( 'section-open' ); 552 position = content.offset().top; 553 scroll = container.scrollTop(); 554 content.css( 'margin-top', ( 45 - position - scroll ) ); 514 555 }; 515 556 } 516 557 … … 531 572 expand(); 532 573 } 533 574 534 } else {575 } else if ( section.container.hasClass( 'open' ) ) { 535 576 section.container.removeClass( 'open' ); 536 content.slideUp( args.duration, args.completeCallback ); 577 overlay.removeClass( 'section-open' ); 578 content.css( 'margin-top', 'inherit' ); 579 container.scrollTop( 0 ); 580 section.container.find( '.accordion-section-title' ).focus(); 537 581 } 538 582 } 539 583 }); … … 718 762 overlay = section.closest( '.wp-full-overlay' ), 719 763 container = section.closest( '.wp-full-overlay-sidebar-content' ), 720 764 siblings = container.find( '.open' ), 721 topPanel = overlay.find( '#customize-theme-controls > ul > .accordion-section > .accordion-section-title' ) .add( '#customize-info > .accordion-section-title' ),765 topPanel = overlay.find( '#customize-theme-controls > ul > .accordion-section > .accordion-section-title' ), 722 766 customizeBtn = section.find( '.customize-theme' ), 723 767 changeBtn = section.find( '.change-theme' ), 724 768 content = section.find( '.control-panel-content' ); … … 748 792 args.completeCallback(); 749 793 } 750 794 } ); 751 topPanel.attr( 'tabindex', '-1' );752 changeBtn.attr( 'tabindex', '-1' );753 795 customizeBtn.focus(); 754 796 } else { 755 797 siblings.removeClass( 'open' ); … … 762 804 args.completeCallback(); 763 805 } 764 806 } ); 765 topPanel.attr( 'tabindex', '0' );766 807 customizeBtn.attr( 'tabindex', '0' ); 767 808 changeBtn.focus(); 768 809 container.scrollTop( 0 ); … … 964 1005 * @augments wp.customize.Class 965 1006 */ 966 1007 api.Panel = Container.extend({ 1008 containerType: 'panel', 1009 967 1010 /** 968 1011 * @since 4.1.0 969 1012 * … … 990 1033 991 1034 if ( ! panel.container.parent().is( parentContainer ) ) { 992 1035 parentContainer.append( panel.container ); 1036 panel.renderContent(); 993 1037 } 994 1038 panel.deferred.embedded.resolve(); 995 1039 }, … … 1012 1056 } 1013 1057 }); 1014 1058 1059 // Close panel. 1060 panel.container.find( '.customize-panel-back' ).on( 'click keydown', function( event ) { 1061 if ( api.utils.isKeydownButNotEnterEvent( event ) ) { 1062 return; 1063 } 1064 event.preventDefault(); // Keep this AFTER the key filter above 1065 1066 if ( panel.expanded() ) { 1067 panel.collapse(); 1068 } 1069 }); 1070 1015 1071 meta = panel.container.find( '.panel-meta:first' ); 1016 1072 1017 meta.find( '> .accordion-section-title ' ).on( 'click keydown', function( event ) {1073 meta.find( '> .accordion-section-title .customize-help-toggle' ).on( 'click keydown', function( event ) { 1018 1074 if ( api.utils.isKeydownButNotEnterEvent( event ) ) { 1019 1075 return; 1020 1076 } 1021 1077 event.preventDefault(); // Keep this AFTER the key filter above 1022 1078 1079 meta = panel.container.find( '.panel-meta' ); 1023 1080 if ( meta.hasClass( 'cannot-expand' ) ) { 1024 1081 return; 1025 1082 } 1026 1083 1027 var content = meta.find( '. accordion-section-content:first' );1084 var content = meta.find( '.customize-panel-description:first' ); 1028 1085 if ( meta.hasClass( 'open' ) ) { 1029 1086 meta.toggleClass( 'open' ); 1030 1087 content.slideUp( panel.defaultExpandedArguments.duration ); 1088 $( this ).attr( 'aria-expanded', false ); 1031 1089 } else { 1032 1090 content.slideDown( panel.defaultExpandedArguments.duration ); 1033 1091 meta.toggleClass( 'open' ); 1092 $( this ).attr( 'aria-expanded', true ); 1034 1093 } 1035 1094 }); 1036 1095 … … 1089 1148 // Note: there is a second argument 'args' passed 1090 1149 var position, scroll, 1091 1150 panel = this, 1092 section = panel.container.closest( '.accordion-section' ), 1151 section = panel.container.closest( '.accordion-section' ), // This is actually the panel. 1093 1152 overlay = section.closest( '.wp-full-overlay' ), 1094 1153 container = section.closest( '.wp-full-overlay-sidebar-content' ), 1095 1154 siblings = container.find( '.open' ), 1096 topPanel = overlay.find( '#customize-theme-controls > ul > .accordion-section > .accordion-section-title' ) .add( '#customize-info > .accordion-section-title' ),1097 backBtn = overlay.find( '.control-panel-back' ),1155 topPanel = overlay.find( '#customize-theme-controls > ul > .accordion-section > .accordion-section-title' ), 1156 backBtn = section.find( '.customize-panel-back' ), 1098 1157 panelTitle = section.find( '.accordion-section-title' ).first(), 1099 1158 content = section.find( '.control-panel-content' ); 1100 1159 … … 1142 1201 panelTitle.focus(); 1143 1202 container.scrollTop( 0 ); 1144 1203 } 1204 }, 1205 1206 /** 1207 * Render the panel from its JS template, if it exists. 1208 * 1209 * The panel's container must already exist in the DOM. 1210 * 1211 * @since 4.3.0 1212 */ 1213 renderContent: function () { 1214 var template, 1215 panel = this; 1216 1217 // Add the content to the container. 1218 if ( 0 !== $( '#tmpl-' + panel.templateSelector + '-content' ).length ) { 1219 template = wp.template( panel.templateSelector + '-content' ); 1220 if ( template && panel.container ) { 1221 panel.container.find( '.accordion-sub-container' ).html( template( panel.params ) ); 1222 } 1223 } 1145 1224 } 1146 1225 }); 1147 1226 … … 2573 2652 var parent, topFocus, 2574 2653 body = $( document.body ), 2575 2654 overlay = body.children( '.wp-full-overlay' ), 2576 title = $( '#customize-info . theme-name.site-title' ),2655 title = $( '#customize-info .panel-title.site-title' ), 2577 2656 closeBtn = $( '.customize-controls-close' ), 2578 2657 saveBtn = $( '#save' ); 2579 2658 … … 2588 2667 }); 2589 2668 2590 2669 // Expand/Collapse the main customizer customize info. 2591 $( ' #customize-info' ).find( '> .accordion-section-title' ).on( 'click keydown', function( event ) {2670 $( '.customize-info' ).find( '> .accordion-section-title .customize-help-toggle' ).on( 'click keydown', function( event ) { 2592 2671 if ( api.utils.isKeydownButNotEnterEvent( event ) ) { 2593 2672 return; 2594 2673 } 2595 2674 event.preventDefault(); // Keep this AFTER the key filter above 2596 2675 2597 var section = $( this ). parent(),2598 content = section.find( '. accordion-section-content:first' );2676 var section = $( this ).closest( '.accordion-section' ), 2677 content = section.find( '.customize-panel-description:first' ); 2599 2678 2600 2679 if ( section.hasClass( 'cannot-expand' ) ) { 2601 2680 return; … … 2604 2683 if ( section.hasClass( 'open' ) ) { 2605 2684 section.toggleClass( 'open' ); 2606 2685 content.slideUp( api.Panel.prototype.defaultExpandedArguments.duration ); 2686 $( this ).attr( 'aria-expanded', false ); 2607 2687 } else { 2608 2688 content.slideDown( api.Panel.prototype.defaultExpandedArguments.duration ); 2609 2689 section.toggleClass( 'open' ); 2690 $( this ).attr( 'aria-expanded', true ); 2610 2691 } 2611 2692 }); 2612 2693 -
src/wp-admin/js/customize-widgets.js
diff --git src/wp-admin/js/customize-widgets.js src/wp-admin/js/customize-widgets.js index 729e6a8..eb245ea 100644
176 176 177 177 // If the available widgets panel is open and the customize controls are 178 178 // interacted with (i.e. available widgets panel is blurred) then close the 179 // available widgets panel. 180 $( '#customize-controls, .customize-overlay-close ' ).on( 'click keydown', function( e ) {179 // available widgets panel. Also close on back button click. 180 $( '#customize-controls, .customize-overlay-close, #available-widgets .customize-section-title' ).on( 'click keydown', function( e ) { 181 181 var isAddNewBtn = $( e.target ).is( '.add-new-widget, .add-new-widget *' ); 182 182 if ( $( 'body' ).hasClass( 'adding-widget' ) && ! isAddNewBtn ) { 183 183 self.close(); … … 366 366 this.close( { returnFocus: true } ); 367 367 } 368 368 369 if ( isTab && ( isShift && isSearchFocused || ! isShift && isLastWidgetFocused ) ) {369 if ( this.currentSidebarControl && isTab && ( isShift && isSearchFocused || ! isShift && isLastWidgetFocused ) ) { 370 370 this.currentSidebarControl.container.find( '.add-new-widget' ).focus(); 371 371 event.preventDefault(); 372 372 } … … 1270 1270 1271 1271 if ( expanded ) { 1272 1272 1273 self.expandControlSection(); 1273 if ( 'undefined' != typeof api.section( self.section ) && ! api.section( self.section ).expanded() ) { 1274 self.expandControlSection(); 1275 } 1274 1276 1275 1277 // Close all other widget controls before expanding this one 1276 1278 api.control.each( function( otherControl ) { -
src/wp-includes/class-wp-customize-manager.php
diff --git src/wp-includes/class-wp-customize-manager.php src/wp-includes/class-wp-customize-manager.php index 98539b0..47c0407 100644
final class WP_Customize_Manager { 60 60 protected $customized; 61 61 62 62 /** 63 * Controls that may be rendered from JS templates. 63 * Panel types that may be rendered from JS templates. 64 * 65 * @since 4.3.0 66 * @access protected 67 * @var array 68 */ 69 protected $registered_panel_types = array(); 70 71 /** 72 * Section types that may be rendered from JS templates. 73 * 74 * @since 4.3.0 75 * @access protected 76 * @var array 77 */ 78 protected $registered_section_types = array(); 79 80 /** 81 * Control types that may be rendered from JS templates. 64 82 * 65 83 * @since 4.1.0 66 84 * @access protected … … final class WP_Customize_Manager { 612 630 } 613 631 614 632 foreach ( $this->settings as $id => $setting ) { 615 $settings['values'][ $id ] = $setting->js_value(); 633 if ( $setting->check_capabilities() ) { 634 $settings['values'][ $id ] = $setting->js_value(); 635 } 616 636 } 617 foreach ( $this->panels as $id => $panel ) { 618 $settings['activePanels'][ $id ] = $panel->active(); 619 foreach ( $panel->sections as $id => $section ) { 620 $settings['activeSections'][ $id ] = $section->active(); 637 foreach ( $this->panels as $panel_id => $panel ) { 638 if ( $panel->check_capabilities() ) { 639 $settings['activePanels'][ $panel_id ] = $panel->active(); 640 foreach ( $panel->sections as $section_id => $section ) { 641 if ( $section->check_capabilities() ) { 642 $settings['activeSections'][ $section_id ] = $section->active(); 643 } 644 } 621 645 } 622 646 } 623 647 foreach ( $this->sections as $id => $section ) { 624 $settings['activeSections'][ $id ] = $section->active(); 648 if ( $section->check_capabilities() ) { 649 $settings['activeSections'][ $id ] = $section->active(); 650 } 625 651 } 626 652 foreach ( $this->controls as $id => $control ) { 627 $settings['activeControls'][ $id ] = $control->active(); 653 if ( $control->check_capabilities() ) { 654 $settings['activeControls'][ $id ] = $control->active(); 655 } 628 656 } 629 657 630 658 ?> … … final class WP_Customize_Manager { 965 993 } 966 994 967 995 /** 996 * Register a customize panel type. 997 * 998 * Registered types are eligible to be rendered via JS and created dynamically. 999 * 1000 * @since 4.3.0 1001 * @access public 1002 * 1003 * @param string $panel Name of a custom panel which is a subclass of 1004 * {@see WP_Customize_Panel}. 1005 */ 1006 public function register_panel_type( $panel ) { 1007 $this->registered_panel_types[] = $panel; 1008 } 1009 1010 /** 1011 * Render JS templates for all registered panel types. 1012 * 1013 * @since 4.3.0 1014 * @access public 1015 */ 1016 public function render_panel_templates() { 1017 foreach ( $this->registered_panel_types as $panel_type ) { 1018 $panel = new $panel_type( $this, 'temp', array() ); 1019 $panel->print_template(); 1020 } 1021 } 1022 1023 /** 968 1024 * Add a customize section. 969 1025 * 970 1026 * @since 3.4.0 … … final class WP_Customize_Manager { 1006 1062 } 1007 1063 1008 1064 /** 1065 * Register a customize section type. 1066 * 1067 * Registered types are eligible to be rendered via JS and created dynamically. 1068 * 1069 * @since 4.3.0 1070 * @access public 1071 * 1072 * @param string $section Name of a custom section which is a subclass of 1073 * {@see WP_Customize_Section}. 1074 */ 1075 public function register_section_type( $section ) { 1076 $this->registered_section_types[] = $section; 1077 } 1078 1079 /** 1080 * Render JS templates for all registered section types. 1081 * 1082 * @since 4.3.0 1083 * @access public 1084 */ 1085 public function render_section_templates() { 1086 foreach ( $this->registered_section_types as $section_type ) { 1087 $section = new $section_type( $this, 'temp', array() ); 1088 $section->print_template(); 1089 } 1090 } 1091 1092 /** 1009 1093 * Add a customize control. 1010 1094 * 1011 1095 * @since 3.4.0 … … final class WP_Customize_Manager { 1176 1260 */ 1177 1261 public function register_controls() { 1178 1262 1179 /* Control Types (custom control classes) */ 1263 /* Panel, Section, and Control Types */ 1264 $this->register_panel_type( 'WP_Customize_Panel' ); 1265 $this->register_section_type( 'WP_Customize_Section' ); 1266 $this->register_section_type( 'WP_Customize_Sidebar_Section' ); 1180 1267 $this->register_control_type( 'WP_Customize_Color_Control' ); 1181 1268 $this->register_control_type( 'WP_Customize_Media_Control' ); 1182 1269 $this->register_control_type( 'WP_Customize_Upload_Control' ); -
src/wp-includes/class-wp-customize-panel.php
diff --git src/wp-includes/class-wp-customize-panel.php src/wp-includes/class-wp-customize-panel.php index ee9f846..876723b 100644
class WP_Customize_Panel { 212 212 * @return array The array to be exported to the client as JSON. 213 213 */ 214 214 public function json() { 215 $array = wp_array_slice_assoc( (array) $this, array( ' title', 'description', 'priority', 'type' ) );215 $array = wp_array_slice_assoc( (array) $this, array( 'id', 'title', 'description', 'priority', 'type' ) ); 216 216 $array['content'] = $this->get_content(); 217 217 $array['active'] = $this->active(); 218 218 $array['instanceNumber'] = $this->instance_number; … … class WP_Customize_Panel { 287 287 } 288 288 289 289 /** 290 * Render the panel container, and then its contents. 290 * Render the panel container, and then its contents (via `this->render_content()`) in a subclass. 291 * 292 * Panel containers are now rendered in JS by default, see {@see WP_Customize_Panel::print_template()}. 291 293 * 292 294 * @since 4.0.0 293 295 * @access protected 294 296 */ 295 protected function render() { 296 $classes = 'accordion-section control-section control-panel control-panel-' . $this->type; 297 protected function render() {} 298 299 /** 300 * Render the panel UI in a subclass. 301 * 302 * Panel contents are now rendered in JS by default, see {@see WP_Customize_Panel::print_template()}. 303 * 304 * @since 4.1.0 305 * @access protected 306 */ 307 protected function render_content() {} 308 309 /** 310 * Render the panel's JS templates. 311 * 312 * This function is only run for panel types that have been registered with 313 * {@see WP_Customize_Manager::register_panel_type()}. 314 * 315 * @since 4.3.0 316 */ 317 public function print_template() { 297 318 ?> 298 <li id="accordion-panel-<?php echo esc_attr( $this->id ); ?>" class="<?php echo esc_attr( $classes ); ?>"> 319 <script type="text/html" id="tmpl-customize-panel-<?php echo esc_attr( $this->type ); ?>-content"> 320 <?php $this->content_template(); ?> 321 </script> 322 <script type="text/html" id="tmpl-customize-panel-<?php echo esc_attr( $this->type ); ?>"> 323 <?php $this->render_template(); ?> 324 </script> 325 <?php 326 } 327 328 /** 329 * An Underscore (JS) template for rendering this panel's container. 330 * 331 * Class variables for this panel class are available in the `data` JS object; 332 * export custom variables by overriding {@see WP_Customize_Panel::json()}. 333 * 334 * @see WP_Customize_Panel::print_template() 335 * 336 * @since 4.3.0 337 */ 338 protected function render_template() { 339 ?> 340 <li id="accordion-panel-{{ data.id }}" class="accordion-section control-section control-panel control-panel-{{ data.type }}"> 299 341 <h3 class="accordion-section-title" tabindex="0"> 300 <?php echo esc_html( $this->title ); ?>342 {{ data.title }} 301 343 <span class="screen-reader-text"><?php _e( 'Press return or enter to open this panel' ); ?></span> 302 344 </h3> 303 <ul class="accordion-sub-container control-panel-content"> 304 <?php $this->render_content(); ?> 305 </ul> 345 <ul class="accordion-sub-container control-panel-content"></ul> 306 346 </li> 307 347 <?php 308 348 } 309 349 310 350 /** 311 * Render the sections that have been added to the panel.351 * An Underscore (JS) template for this panel's content (but not its container). 312 352 * 313 * @since 4.1.0 314 * @access protected 353 * Class variables for this panel class are available in the `data` JS object; 354 * export custom variables by overriding {@see WP_Customize_Panel::json()}. 355 * 356 * @see WP_Customize_Panel::print_template() 357 * 358 * @since 4.3.0 315 359 */ 316 protected function render_content() {360 protected function content_template() { 317 361 ?> 318 <li class="panel-meta accordion-section control-section<?php if ( empty( $this->description ) ) { echo ' cannot-expand'; } ?>"> 319 <div class="accordion-section-title" tabindex="0"> 362 <li class="panel-meta customize-info accordion-section <# if ( ! data.description ) { #> cannot-expand<# } #>"> 363 <button class="customize-panel-back" tabindex="-1"><span class="screen-reader-text"><?php _e( 'Back' ); ?></span></button> 364 <div class="accordion-section-title"> 320 365 <span class="preview-notice"><?php 321 366 /* translators: %s is the site/panel title in the Customizer */ 322 echo sprintf( __( 'You are customizing %s' ), '<strong class="panel-title"> ' . esc_html( $this->title ) . '</strong>' );367 echo sprintf( __( 'You are customizing %s' ), '<strong class="panel-title">{{ data.title }}</strong>' ); 323 368 ?></span> 369 <button class="customize-help-toggle dashicons dashicons-editor-help" tabindex="0" aria-expanded="false"><span class="screen-reader-text"><?php _e( 'Help' ); ?></span></button> 324 370 </div> 325 < ?php if ( ! empty( $this->description ) ) : ?>326 <div class=" accordion-section-contentdescription">327 <?php echo $this->description; ?>371 <# if ( data.description ) { #> 372 <div class="description customize-panel-description"> 373 {{{ data.description }}} 328 374 </div> 329 < ?php endif; ?>375 <# } #> 330 376 </li> 331 377 <?php 332 378 } -
src/wp-includes/class-wp-customize-section.php
diff --git src/wp-includes/class-wp-customize-section.php src/wp-includes/class-wp-customize-section.php index a27f22b..dd85772 100644
class WP_Customize_Section { 221 221 * @return array The array to be exported to the client as JSON. 222 222 */ 223 223 public function json() { 224 $array = wp_array_slice_assoc( (array) $this, array( ' title', 'description', 'priority', 'panel', 'type' ) );224 $array = wp_array_slice_assoc( (array) $this, array( 'id', 'title', 'description', 'priority', 'panel', 'type' ) ); 225 225 $array['content'] = $this->get_content(); 226 226 $array['active'] = $this->active(); 227 227 $array['instanceNumber'] = $this->instance_number; 228 229 if ( $this->panel ) { 230 /* translators: ▸ is the unicode right-pointing triangle, and %s is the section title in the Customizer */ 231 $array['customizeAction'] = sprintf( __( 'Customizing ▸ %s' ), esc_html( $this->manager->get_panel( $this->panel )->title ) ); 232 } else { 233 $array['customizeAction'] = __( 'Customizing' ); 234 } 235 228 236 return $array; 229 237 } 230 238 … … class WP_Customize_Section { 249 257 } 250 258 251 259 /** 252 * Get the section's content templatefor insertion into the Customizer pane.260 * Get the section's content for insertion into the Customizer pane. 253 261 * 254 262 * @since 4.1.0 255 263 * … … class WP_Customize_Section { 295 303 } 296 304 297 305 /** 298 * Render the section, and the controls that have been added to it. 306 * Render the section UI in a subclass. 307 * 308 * Sections are now rendered in JS by default, see {@see WP_Customize_Section::print_template()}. 299 309 * 300 310 * @since 3.4.0 301 311 */ 302 protected function render() { 303 $classes = 'accordion-section control-section control-section-' . $this->type; 312 protected function render() {} 313 314 /** 315 * Render the section's JS template. 316 * 317 * This function is only run for section types that have been registered with 318 * {@see WP_Customize_Manager::register_section_type()}. 319 * 320 * @since 4.3.0 321 */ 322 public function print_template() { 323 ?> 324 <script type="text/html" id="tmpl-customize-section-<?php echo $this->type; ?>"> 325 <?php $this->render_template(); ?> 326 </script> 327 <?php 328 } 329 330 /** 331 * An Underscore (JS) template for rendering this section. 332 * 333 * Class variables for this section class are available in the `data` JS object; 334 * export custom variables by overriding {@see WP_Customize_Section::json()}. 335 * 336 * @see WP_Customize_Section::print_template() 337 * 338 * @since 4.3.0 339 */ 340 protected function render_template() { 304 341 ?> 305 <li id="accordion-section- <?php echo esc_attr( $this->id ); ?>" class="<?php echo esc_attr( $classes ); ?>">342 <li id="accordion-section-{{ data.id }}" class="accordion-section control-section control-section-{{ data.type }}"> 306 343 <h3 class="accordion-section-title" tabindex="0"> 307 <?php echo esc_html( $this->title ); ?>308 <span class="screen-reader-text"><?php _e( 'Press return or enter to expand' ); ?></span>344 {{ data.title }} 345 <span class="screen-reader-text"><?php _e( 'Press return or enter to open' ); ?></span> 309 346 </h3> 310 347 <ul class="accordion-section-content"> 311 <?php if ( ! empty( $this->description ) ) : ?> 312 <li class="customize-section-description-container"> 313 <p class="description customize-section-description"><?php echo $this->description; ?></p> 314 </li> 315 <?php endif; ?> 348 <li class="customize-section-description-container"> 349 <div class="customize-section-title"> 350 <button class="customize-section-back" tabindex="-1"> 351 <span class="screen-reader-text"><?php _e( 'Back' ); ?></span> 352 </button> 353 <h3> 354 <span class="customize-action"> 355 {{{ data.customizeAction }}} 356 </span> 357 {{ data.title }} 358 </h3> 359 </div> 360 <# if ( data.description ) { #> 361 <p class="description customize-section-description">{{{ data.description }}}</p> 362 <# } #> 363 </li> 316 364 </ul> 317 365 </li> 318 366 <?php … … class WP_Customize_Themes_Section extends WP_Customize_Section { 353 401 <?php 354 402 if ( $this->manager->is_theme_active() ) { 355 403 /* translators: %s: theme name */ 356 printf( __( '<span >Active theme</span> %s' ), $this->title );404 printf( __( '<span class="customize-action">Active theme</span> %s' ), $this->title ); 357 405 } else { 358 406 /* translators: %s: theme name */ 359 printf( __( '<span >Previewing theme</span> %s' ), $this->title );407 printf( __( '<span class="customize-action">Previewing theme</span> %s' ), $this->title ); 360 408 } 361 409 ?> 362 410 363 <button type="button" class="button change-theme" ><?php _ex( 'Change', 'theme' ); ?></button>411 <button type="button" class="button change-theme" tabindex="0"><?php _ex( 'Change', 'theme' ); ?></button> 364 412 </h3> 365 413 <div class="customize-themes-panel control-panel-content themes-php"> 366 <h2> 414 <h3 class="accordion-section-title customize-section-title"> 415 <span class="customize-action"><?php _e( 'Customizing' ); ?></span> 367 416 <?php _e( 'Themes' ); ?> 368 417 <span class="title-count theme-count"><?php echo count( $this->controls ) + 1 /* Active theme */; ?></span> 369 </h2> 370 418 </h3> 371 419 <h3 class="accordion-section-title customize-section-title"> 372 420 <?php 373 421 if ( $this->manager->is_theme_active() ) { 374 422 /* translators: %s: theme name */ 375 printf( __( '<span >Active theme</span> %s' ), $this->title );423 printf( __( '<span class="customize-action">Active theme</span> %s' ), $this->title ); 376 424 } else { 377 425 /* translators: %s: theme name */ 378 printf( __( '<span >Previewing theme</span> %s' ), $this->title );426 printf( __( '<span class="customize-action">Previewing theme</span> %s' ), $this->title ); 379 427 } 380 428 ?> 381 429 <button type="button" class="button customize-theme"><?php _e( 'Customize' ); ?></button> -
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 cfd0541..d4d30b0 100644
final class WP_Customize_Widgets { 681 681 ?> 682 682 <div id="widgets-left"><!-- compatibility with JS which looks for widget templates here --> 683 683 <div id="available-widgets"> 684 <div class="customize-section-title"> 685 <button class="customize-section-back" tabindex="-1"> 686 <span class="screen-reader-text"><?php _e( 'Back' ); ?></span> 687 </button> 688 <h3> 689 <span class="customize-action"><?php 690 /* translators: ▸ is the unicode right-pointing triangle, and %s is the section title in the Customizer */ 691 echo sprintf( __( 'Customizing ▸ %s' ), esc_html( $this->manager->get_panel( 'widgets' )->title ) ); 692 ?></span> 693 <?php _e( 'Add a Widget' ); ?> 694 </h3> 695 </div> 684 696 <div id="available-widgets-filter"> 685 697 <label class="screen-reader-text" for="widgets-search"><?php _e( 'Search Widgets' ); ?></label> 686 698 <input type="search" id="widgets-search" placeholder="<?php esc_attr_e( 'Search widgets…' ) ?>" /> -
new file tests/phpunit/tests/customize/panel.php
diff --git tests/phpunit/tests/customize/panel.php tests/phpunit/tests/customize/panel.php new file mode 100644 index 0000000..69fcef8
- + 1 <?php 2 3 /** 4 * Tests for the WP_Customize_Panel class. 5 * 6 * @group customize 7 */ 8 class Tests_WP_Customize_Panel extends WP_UnitTestCase { 9 10 /** 11 * @var WP_Customize_Manager 12 */ 13 protected $manager; 14 15 function setUp() { 16 parent::setUp(); 17 require_once( ABSPATH . WPINC . '/class-wp-customize-manager.php' ); 18 $GLOBALS['wp_customize'] = new WP_Customize_Manager(); 19 $this->manager = $GLOBALS['wp_customize']; 20 $this->undefined = new stdClass(); 21 } 22 23 function tearDown() { 24 $this->manager = null; 25 unset( $GLOBALS['wp_customize'] ); 26 parent::tearDown(); 27 } 28 29 /** 30 * @see WP_Customize_Panel::__construct() 31 */ 32 function test_construct_default_args() { 33 $panel = new WP_Customize_Panel( $this->manager, 'foo' ); 34 $this->assertInternalType( 'int', $panel->instance_number ); 35 $this->assertEquals( $this->manager, $panel->manager ); 36 $this->assertEquals( 'foo', $panel->id ); 37 $this->assertEquals( 160, $panel->priority ); 38 $this->assertEquals( 'edit_theme_options', $panel->capability ); 39 $this->assertEquals( '', $panel->theme_supports ); 40 $this->assertEquals( '', $panel->title ); 41 $this->assertEquals( '', $panel->description ); 42 $this->assertEmpty( $panel->sections ); 43 $this->assertEquals( 'default', $panel->type ); 44 $this->assertEquals( array( $panel, 'active_callback' ), $panel->active_callback ); 45 } 46 47 /** 48 * @see WP_Customize_Panel::__construct() 49 */ 50 function test_construct_custom_args() { 51 $args = array( 52 'priority' => 200, 53 'capability' => 'edit_posts', 54 'theme_supports' => 'html5', 55 'title' => 'Hello World', 56 'description' => 'Lorem Ipsum', 57 'type' => 'horizontal', 58 'active_callback' => '__return_true', 59 ); 60 61 $panel = new WP_Customize_Panel( $this->manager, 'foo', $args ); 62 foreach ( $args as $key => $value ) { 63 $this->assertEquals( $value, $panel->$key ); 64 } 65 } 66 67 /** 68 * @see WP_Customize_Panel::__construct() 69 */ 70 function test_construct_custom_type() { 71 $panel = new Custom_Panel_Test( $this->manager, 'foo' ); 72 $this->assertEquals( 'titleless', $panel->type ); 73 } 74 75 /** 76 * @see WP_Customize_Panel::active() 77 * @see WP_Customize_Panel::active_callback() 78 */ 79 function test_active() { 80 $panel = new WP_Customize_Panel( $this->manager, 'foo' ); 81 $this->assertTrue( $panel->active() ); 82 83 $panel = new WP_Customize_Panel( $this->manager, 'foo', array( 84 'active_callback' => '__return_false', 85 ) ); 86 $this->assertFalse( $panel->active() ); 87 add_filter( 'customize_panel_active', array( $this, 'filter_active_test' ), 10, 2 ); 88 $this->assertTrue( $panel->active() ); 89 } 90 91 /** 92 * @param bool $active 93 * @param WP_Customize_Panel $panel 94 * @return bool 95 */ 96 function filter_active_test( $active, $panel ) { 97 $this->assertFalse( $active ); 98 $this->assertInstanceOf( 'WP_Customize_Panel', $panel ); 99 $active = true; 100 return $active; 101 } 102 103 /** 104 * @see WP_Customize_Panel::json() 105 */ 106 function test_json() { 107 $args = array( 108 'priority' => 200, 109 'capability' => 'edit_posts', 110 'theme_supports' => 'html5', 111 'title' => 'Hello World', 112 'description' => 'Lorem Ipsum', 113 'type' => 'horizontal', 114 'active_callback' => '__return_true', 115 ); 116 $panel = new WP_Customize_Panel( $this->manager, 'foo', $args ); 117 $data = $panel->json(); 118 $this->assertEquals( 'foo', $data['id'] ); 119 foreach ( array( 'title', 'description', 'priority', 'type' ) as $key ) { 120 $this->assertEquals( $args[ $key ], $data[ $key ] ); 121 } 122 $this->assertEmpty( $data['content'] ); 123 $this->assertTrue( $data['active'] ); 124 $this->assertInternalType( 'int', $data['instanceNumber'] ); 125 } 126 127 /** 128 * @see WP_Customize_Panel::check_capabilities() 129 */ 130 function test_check_capabilities() { 131 $user_id = $this->factory->user->create( array( 'role' => 'administrator' ) ); 132 wp_set_current_user( $user_id ); 133 134 $panel = new WP_Customize_Panel( $this->manager, 'foo' ); 135 $this->assertTrue( $panel->check_capabilities() ); 136 $old_cap = $panel->capability; 137 $panel->capability = 'do_not_allow'; 138 $this->assertFalse( $panel->check_capabilities() ); 139 $panel->capability = $old_cap; 140 $this->assertTrue( $panel->check_capabilities() ); 141 $panel->theme_supports = 'impossible_feature'; 142 $this->assertFalse( $panel->check_capabilities() ); 143 } 144 145 /** 146 * @see WP_Customize_Panel::get_content() 147 */ 148 function test_get_content() { 149 $panel = new WP_Customize_Panel( $this->manager, 'foo' ); 150 $this->assertEmpty( $panel->get_content() ); 151 } 152 153 /** 154 * @see WP_Customize_Panel::maybe_render() 155 */ 156 function test_maybe_render() { 157 wp_set_current_user( $this->factory->user->create( array( 'role' => 'administrator' ) ) ); 158 $panel = new WP_Customize_Panel( $this->manager, 'bar' ); 159 $customize_render_panel_count = did_action( 'customize_render_panel' ); 160 add_action( 'customize_render_panel', array( $this, 'action_customize_render_panel_test' ) ); 161 ob_start(); 162 $panel->maybe_render(); 163 $content = ob_get_clean(); 164 $this->assertTrue( $panel->check_capabilities() ); 165 $this->assertEmpty( $content ); 166 $this->assertEquals( $customize_render_panel_count + 1, did_action( 'customize_render_panel' ), 'Unexpected did_action count for customize_render_panel' ); 167 $this->assertEquals( 1, did_action( "customize_render_panel_{$panel->id}" ), "Unexpected did_action count for customize_render_panel_{$panel->id}" ); 168 } 169 170 /** 171 * @see WP_Customize_Panel::maybe_render() 172 * @param WP_Customize_Panel $panel 173 */ 174 function action_customize_render_panel_test( $panel ) { 175 $this->assertInstanceOf( 'WP_Customize_Panel', $panel ); 176 } 177 178 /** 179 * @see WP_Customize_Panel::print_template() 180 */ 181 function test_print_templates_standard() { 182 wp_set_current_user( $this->factory->user->create( array( 'role' => 'administrator' ) ) ); 183 184 $panel = new WP_Customize_Panel( $this->manager, 'baz' ); 185 ob_start(); 186 $panel->print_template(); 187 $content = ob_get_clean(); 188 $this->assertContains( '<script type="text/html" id="tmpl-customize-panel-default-content">', $content ); 189 $this->assertContains( 'accordion-section-title', $content ); 190 $this->assertContains( 'control-panel-content', $content ); 191 $this->assertContains( '<script type="text/html" id="tmpl-customize-panel-default">', $content ); 192 $this->assertContains( 'accordion-section-content', $content ); 193 $this->assertContains( 'preview-notice', $content ); 194 } 195 196 /** 197 * @see WP_Customize_Panel::print_template() 198 */ 199 function test_print_templates_custom() { 200 wp_set_current_user( $this->factory->user->create( array( 'role' => 'administrator' ) ) ); 201 202 $panel = new Custom_Panel_Test( $this->manager, 'baz' ); 203 ob_start(); 204 $panel->print_template(); 205 $content = ob_get_clean(); 206 $this->assertContains( '<script type="text/html" id="tmpl-customize-panel-titleless-content">', $content ); 207 $this->assertNotContains( 'accordion-section-title', $content ); 208 209 $this->assertContains( '<script type="text/html" id="tmpl-customize-panel-titleless">', $content ); 210 $this->assertNotContains( 'preview-notice', $content ); 211 } 212 } 213 214 require_once ABSPATH . WPINC . '/class-wp-customize-panel.php'; 215 class Custom_Panel_Test extends WP_Customize_Panel { 216 public $type = 'titleless'; 217 218 protected function render_template() { 219 ?> 220 <li id="accordion-panel-{{ data.id }}" class="accordion-section control-section control-panel control-panel-{{ data.type }}"> 221 <ul class="accordion-sub-container control-panel-content"></ul> 222 </li> 223 <?php 224 } 225 226 protected function content_template() { 227 ?> 228 <li class="panel-meta accordion-section control-section<# if ( ! data.description ) { #> cannot-expand<# } #>"> 229 <# if ( data.description ) { #> 230 <div class="accordion-section-content description"> 231 {{{ data.description }}} 232 </div> 233 <# } #> 234 </li> 235 <?php 236 } 237 238 } -
new file tests/phpunit/tests/customize/section.php
diff --git tests/phpunit/tests/customize/section.php tests/phpunit/tests/customize/section.php new file mode 100644 index 0000000..bf5a33f
- + 1 <?php 2 3 /** 4 * Tests for the WP_Customize_Section class. 5 * 6 * @group customize 7 */ 8 class Tests_WP_Customize_Section extends WP_UnitTestCase { 9 10 /** 11 * @var WP_Customize_Manager 12 */ 13 protected $manager; 14 15 function setUp() { 16 parent::setUp(); 17 require_once( ABSPATH . WPINC . '/class-wp-customize-manager.php' ); 18 $GLOBALS['wp_customize'] = new WP_Customize_Manager(); 19 $this->manager = $GLOBALS['wp_customize']; 20 $this->undefined = new stdClass(); 21 } 22 23 function tearDown() { 24 $this->manager = null; 25 unset( $GLOBALS['wp_customize'] ); 26 parent::tearDown(); 27 } 28 29 /** 30 * @see WP_Customize_Section::__construct() 31 */ 32 function test_construct_default_args() { 33 $section = new WP_Customize_Section( $this->manager, 'foo' ); 34 $this->assertInternalType( 'int', $section->instance_number ); 35 $this->assertEquals( $this->manager, $section->manager ); 36 $this->assertEquals( 'foo', $section->id ); 37 $this->assertEquals( 160, $section->priority ); 38 $this->assertEquals( 'edit_theme_options', $section->capability ); 39 $this->assertEquals( '', $section->theme_supports ); 40 $this->assertEquals( '', $section->title ); 41 $this->assertEquals( '', $section->description ); 42 $this->assertEmpty( $section->panel ); 43 $this->assertEquals( 'default', $section->type ); 44 $this->assertEquals( array( $section, 'active_callback' ), $section->active_callback ); 45 } 46 47 /** 48 * @see WP_Customize_Section::__construct() 49 */ 50 function test_construct_custom_args() { 51 $args = array( 52 'priority' => 200, 53 'capability' => 'edit_posts', 54 'theme_supports' => 'html5', 55 'title' => 'Hello World', 56 'description' => 'Lorem Ipsum', 57 'type' => 'horizontal', 58 'active_callback' => '__return_true', 59 'panel' => 'bar', 60 ); 61 62 $this->manager->add_panel( 'bar' ); 63 64 $section = new WP_Customize_Section( $this->manager, 'foo', $args ); 65 foreach ( $args as $key => $value ) { 66 $this->assertEquals( $value, $section->$key ); 67 } 68 } 69 70 /** 71 * @see WP_Customize_Section::__construct() 72 */ 73 function test_construct_custom_type() { 74 $section = new Custom_Section_Test( $this->manager, 'foo' ); 75 $this->assertEquals( 'titleless', $section->type ); 76 } 77 78 /** 79 * @see WP_Customize_Section::active() 80 * @see WP_Customize_Section::active_callback() 81 */ 82 function test_active() { 83 $section = new WP_Customize_Section( $this->manager, 'foo' ); 84 $this->assertTrue( $section->active() ); 85 86 $section = new WP_Customize_Section( $this->manager, 'foo', array( 87 'active_callback' => '__return_false', 88 ) ); 89 $this->assertFalse( $section->active() ); 90 add_filter( 'customize_section_active', array( $this, 'filter_active_test' ), 10, 2 ); 91 $this->assertTrue( $section->active() ); 92 } 93 94 /** 95 * @param bool $active 96 * @param WP_Customize_Section $section 97 * @return bool 98 */ 99 function filter_active_test( $active, $section ) { 100 $this->assertFalse( $active ); 101 $this->assertInstanceOf( 'WP_Customize_Section', $section ); 102 $active = true; 103 return $active; 104 } 105 106 /** 107 * @see WP_Customize_Section::json() 108 */ 109 function test_json() { 110 $args = array( 111 'priority' => 200, 112 'capability' => 'edit_posts', 113 'theme_supports' => 'html5', 114 'title' => 'Hello World', 115 'description' => 'Lorem Ipsum', 116 'type' => 'horizontal', 117 'panel' => 'bar', 118 'active_callback' => '__return_true', 119 ); 120 $section = new WP_Customize_Section( $this->manager, 'foo', $args ); 121 $data = $section->json(); 122 $this->assertEquals( 'foo', $data['id'] ); 123 foreach ( array( 'title', 'description', 'priority', 'panel', 'type' ) as $key ) { 124 $this->assertEquals( $args[ $key ], $data[ $key ] ); 125 } 126 $this->assertEmpty( $data['content'] ); 127 $this->assertTrue( $data['active'] ); 128 $this->assertInternalType( 'int', $data['instanceNumber'] ); 129 } 130 131 /** 132 * @see WP_Customize_Section::check_capabilities() 133 */ 134 function test_check_capabilities() { 135 $user_id = $this->factory->user->create( array( 'role' => 'administrator' ) ); 136 wp_set_current_user( $user_id ); 137 138 $section = new WP_Customize_Section( $this->manager, 'foo' ); 139 $this->assertTrue( $section->check_capabilities() ); 140 $old_cap = $section->capability; 141 $section->capability = 'do_not_allow'; 142 $this->assertFalse( $section->check_capabilities() ); 143 $section->capability = $old_cap; 144 $this->assertTrue( $section->check_capabilities() ); 145 $section->theme_supports = 'impossible_feature'; 146 $this->assertFalse( $section->check_capabilities() ); 147 } 148 149 /** 150 * @see WP_Customize_Section::get_content() 151 */ 152 function test_get_content() { 153 $section = new WP_Customize_Section( $this->manager, 'foo' ); 154 $this->assertEmpty( $section->get_content() ); 155 } 156 157 /** 158 * @see WP_Customize_Section::maybe_render() 159 */ 160 function test_maybe_render() { 161 wp_set_current_user( $this->factory->user->create( array( 'role' => 'administrator' ) ) ); 162 $section = new WP_Customize_Section( $this->manager, 'bar' ); 163 $customize_render_section_count = did_action( 'customize_render_section' ); 164 add_action( 'customize_render_section', array( $this, 'action_customize_render_section_test' ) ); 165 ob_start(); 166 $section->maybe_render(); 167 $content = ob_get_clean(); 168 $this->assertTrue( $section->check_capabilities() ); 169 $this->assertEmpty( $content ); 170 $this->assertEquals( $customize_render_section_count + 1, did_action( 'customize_render_section' ), 'Unexpected did_action count for customize_render_section' ); 171 $this->assertEquals( 1, did_action( "customize_render_section_{$section->id}" ), "Unexpected did_action count for customize_render_section_{$section->id}" ); 172 } 173 174 /** 175 * @see WP_Customize_Section::maybe_render() 176 * @param WP_Customize_Section $section 177 */ 178 function action_customize_render_section_test( $section ) { 179 $this->assertInstanceOf( 'WP_Customize_Section', $section ); 180 } 181 182 /** 183 * @see WP_Customize_Section::print_template() 184 */ 185 function test_print_templates_standard() { 186 wp_set_current_user( $this->factory->user->create( array( 'role' => 'administrator' ) ) ); 187 188 $section = new WP_Customize_Section( $this->manager, 'baz' ); 189 ob_start(); 190 $section->print_template(); 191 $content = ob_get_clean(); 192 $this->assertContains( '<script type="text/html" id="tmpl-customize-section-default">', $content ); 193 $this->assertContains( 'accordion-section-title', $content ); 194 $this->assertContains( 'accordion-section-content', $content ); 195 } 196 197 /** 198 * @see WP_Customize_Section::print_template() 199 */ 200 function test_print_templates_custom() { 201 wp_set_current_user( $this->factory->user->create( array( 'role' => 'administrator' ) ) ); 202 203 $section = new Custom_Section_Test( $this->manager, 'baz' ); 204 ob_start(); 205 $section->print_template(); 206 $content = ob_get_clean(); 207 $this->assertContains( '<script type="text/html" id="tmpl-customize-section-titleless">', $content ); 208 $this->assertNotContains( 'accordion-section-title', $content ); 209 $this->assertContains( 'accordion-section-content', $content ); 210 } 211 } 212 213 require_once ABSPATH . WPINC . '/class-wp-customize-section.php'; 214 class Custom_Section_Test extends WP_Customize_Section { 215 public $type = 'titleless'; 216 217 protected function render_template() { 218 ?> 219 <li id="accordion-section-{{ data.id }}" class="accordion-section control-section control-section-{{ data.type }}"> 220 <ul class="accordion-section-content"> 221 <# if ( data.description ) { #> 222 <li class="customize-section-description-container"> 223 <p class="description customize-section-description">{{{ data.description }}}</p> 224 </li> 225 <# } #> 226 </ul> 227 </li> 228 <?php 229 } 230 231 } -
tests/qunit/fixtures/customize-settings.js
diff --git tests/qunit/fixtures/customize-settings.js tests/qunit/fixtures/customize-settings.js index 993f767..6feef67 100644
window._wpCustomizeSettings = { 39 39 'description': 'Lorem ipsum', 40 40 'instanceNumber': 1, 41 41 'priority': 110, 42 'title': ' Lorem Ipsum',42 'title': 'Fixture panel with content', 43 43 'type': 'default' 44 }, 45 'fixture-panel-default-templated': { 46 'active': true, 47 'description': 'Lorem ipsum', 48 'instanceNumber': 2, 49 'priority': 110, 50 'title': 'Fixture default panel using template', 51 'type': 'default' 52 }, 53 'fixture-panel-titleless-templated': { 54 'active': true, 55 'description': 'Lorem ipsum', 56 'instanceNumber': 3, 57 'priority': 110, 58 'title': 'Fixture titleless panel using template', 59 'type': 'titleless' 44 60 } 45 61 }, 46 62 'sections': { … … window._wpCustomizeSettings = { 53 69 'priority': 20, 54 70 'title': 'Fixture Section', 55 71 'type': 'default' 72 }, 73 'fixture-section-default-templated': { 74 'active': true, 75 'description': '', 76 'instanceNumber': 3, 77 'panel': 'fixture-panel', 78 'priority': 20, 79 'title': 'Fixture default section using template', 80 'type': 'default' 81 }, 82 'fixture-section-titleless-templated': { 83 'active': true, 84 'description': '', 85 'instanceNumber': 4, 86 'panel': 'fixture-panel', 87 'priority': 20, 88 'title': 'Fixture titleless section using template', 89 'type': 'titleless' 56 90 } 57 91 }, 58 92 'settings': { -
tests/qunit/index.html
diff --git tests/qunit/index.html tests/qunit/index.html index 55b95fe..1b0e0c1 100644
9 9 <script src="../../src/wp-includes/js/underscore.min.js"></script> 10 10 <script src="../../src/wp-includes/js/backbone.min.js"></script> 11 11 <script src="../../src/wp-includes/js/zxcvbn.min.js"></script> 12 <script src="../../src/wp-includes/js/wp-util.js"></script> 12 13 13 14 <!-- QUnit --> 14 15 <link rel="stylesheet" href="vendor/qunit.css" type="text/css" media="screen" /> … … 39 40 <script src="wp-includes/js/shortcode.js"></script> 40 41 <script src="wp-admin/js/customize-controls.js"></script> 41 42 <script src="wp-admin/js/customize-controls-utils.js"></script> 43 44 <!-- Customizer templates for sections --> 45 <script type="text/html" id="tmpl-customize-section-default"> 46 <li id="accordion-section-{{ data.id }}" class="accordion-section control-section control-section-{{ data.type }}"> 47 <h3 class="accordion-section-title" tabindex="0"> 48 {{ data.title }} 49 <span class="screen-reader-text"><?php _e( 'Press return or enter to expand' ); ?></span> 50 </h3> 51 <ul class="accordion-section-content"> 52 <# if ( data.description ) { #> 53 <li class="customize-section-description-container"> 54 <p class="description customize-section-description">{{{ data.description }}}</p> 55 </li> 56 <# } #> 57 </ul> 58 </li> 59 </script> 60 <script type="text/html" id="tmpl-customize-section-titleless"> 61 <li id="accordion-section-{{ data.id }}" class="accordion-section control-section control-section-{{ data.type }}"> 62 <!-- Notice the lack of an h3 with title displayed inside. --> 63 <ul class="accordion-section-content"> 64 <# if ( data.description ) { #> 65 <li class="customize-section-description-container"> 66 <p class="description customize-section-description">{{{ data.description }}}</p> 67 </li> 68 <# } #> 69 </ul> 70 </li> 71 </script> 72 73 <!-- Customizer templates for panels --> 74 <script type="text/html" id="tmpl-customize-panel-default"> 75 <li id="accordion-panel-{{ data.id }}" class="accordion-section control-section control-panel control-panel-{{ data.type }}"> 76 <h3 class="accordion-section-title" tabindex="0"> 77 {{ data.title }} 78 <span class="screen-reader-text"><?php _e( 'Press return or enter to open this panel' ); ?></span> 79 </h3> 80 <ul class="accordion-sub-container control-panel-content"></ul> 81 </li> 82 </script> 83 <script type="text/html" id="tmpl-customize-panel-default-content"> 84 <li class="panel-meta accordion-section control-section<# if ( ! data.description ) { #> cannot-expand<# } #>"> 85 <div class="accordion-section-title" tabindex="0"> 86 <span class="preview-notice"><?php 87 /* translators: %s is the site/panel title in the Customizer */ 88 echo sprintf( __( 'You are customizing %s' ), '<strong class="panel-title">{{ data.title }}</strong>' ); 89 ?></span> 90 </div> 91 <# if ( data.description ) { #> 92 <div class="accordion-section-content description"> 93 {{{ data.description }}} 94 </div> 95 <# } #> 96 </li> 97 </script> 98 <script type="text/html" id="tmpl-customize-panel-titleless"> 99 <li id="accordion-panel-{{ data.id }}" class="accordion-section control-section control-panel control-panel-{{ data.type }}"> 100 <!-- Notice the lack of an h3 with title displayed inside. --> 101 <ul class="accordion-sub-container control-panel-content"></ul> 102 </li> 103 </script> 104 <script type="text/html" id="tmpl-customize-panel-titleless-content"> 105 <li class="panel-meta accordion-section control-section<# if ( ! data.description ) { #> cannot-expand<# } #>"> 106 <!-- Notice lack of title containing preview notice --> 107 <# if ( data.description ) { #> 108 <div class="accordion-section-content description"> 109 {{{ data.description }}} 110 </div> 111 <# } #> 112 </li> 113 </script> 42 114 </body> 43 115 </html> -
tests/qunit/wp-admin/js/customize-controls.js
diff --git tests/qunit/wp-admin/js/customize-controls.js tests/qunit/wp-admin/js/customize-controls.js index cb8767f..9ab7ce1 100644
jQuery( window ).load( function (){ 95 95 equal( control.section(), 'fixture-section' ); 96 96 } ); 97 97 98 // Begin sections. 98 99 module( 'Customizer Section in Fixture' ); 99 100 test( 'Fixture section exists', function () { 100 101 ok( wp.customize.section.has( 'fixture-section' ) ); 101 102 } ); 102 103 test( 'Fixture section has control among controls()', function () { 103 104 var section = wp.customize.section( 'fixture-section' ); 104 equal( section.controls().length, 1 ); 105 equal( section.controls()[0].id, 'fixture-control' ); 105 ok( -1 !== _.pluck( section.controls(), 'id' ).indexOf( 'fixture-control' ) ); 106 106 } ); 107 test( 'Fixture section has control among controls()', function () {107 test( 'Fixture section has has expected panel', function () { 108 108 var section = wp.customize.section( 'fixture-section' ); 109 109 equal( section.panel(), 'fixture-panel' ); 110 110 } ); 111 111 112 module( 'Customizer Default Section with Template in Fixture' ); 113 test( 'Fixture section exists', function () { 114 ok( wp.customize.section.has( 'fixture-section-default-templated' ) ); 115 } ); 116 test( 'Fixture section has expected content', function () { 117 var id = 'fixture-section-default-templated', section; 118 section = wp.customize.section( id ); 119 ok( ! section.params.content ); 120 ok( !! section.container ); 121 ok( section.container.is( '.control-section.control-section-default' ) ); 122 ok( 1 === section.container.find( '> .accordion-section-title' ).length ); 123 ok( 1 === section.container.find( '> .accordion-section-content' ).length ); 124 } ); 125 126 module( 'Customizer Custom Type (titleless) Section with Template in Fixture' ); 127 test( 'Fixture section exists', function () { 128 ok( wp.customize.section.has( 'fixture-section-titleless-templated' ) ); 129 } ); 130 test( 'Fixture section has expected content', function () { 131 var id = 'fixture-section-titleless-templated', section; 132 section = wp.customize.section( id ); 133 ok( ! section.params.content ); 134 ok( !! section.container ); 135 ok( section.container.is( '.control-section.control-section-titleless' ) ); 136 ok( 0 === section.container.find( '> .accordion-section-title' ).length ); 137 ok( 1 === section.container.find( '> .accordion-section-content' ).length ); 138 } ); 139 140 // Begin panels. 112 141 module( 'Customizer Panel in Fixture' ); 113 142 test( 'Fixture panel exists', function () { 114 143 ok( wp.customize.panel.has( 'fixture-panel' ) ); 115 144 } ); 116 test( 'Fixture section has control among controls()', function () { 145 test( 'Fixture panel has content', function () { 146 var panel = wp.customize.panel( 'fixture-panel' ); 147 ok( !! panel.params.content ); 148 ok( !! panel.container ); 149 } ); 150 test( 'Fixture panel has section among its sections()', function () { 117 151 var panel = wp.customize.panel( 'fixture-panel' ); 118 equal( panel.sections().length, 1 ); 119 equal( panel.sections()[0].id, 'fixture-section' ); 152 ok( -1 !== _.pluck( panel.sections(), 'id' ).indexOf( 'fixture-section' ) ); 120 153 } ); 121 154 test( 'Panel is not expanded by default', function () { 122 155 var panel = wp.customize.panel( 'fixture-panel' ); … … jQuery( window ).load( function (){ 138 171 ok( panel.expanded() ); 139 172 } ); 140 173 174 module( 'Customizer Default Panel with Template in Fixture' ); 175 test( 'Fixture section exists', function () { 176 ok( wp.customize.panel.has( 'fixture-panel-default-templated' ) ); 177 } ); 178 test( 'Fixture panel has expected content', function () { 179 var id = 'fixture-panel-default-templated', panel; 180 panel = wp.customize.panel( id ); 181 ok( ! panel.params.content ); 182 ok( !! panel.container ); 183 ok( panel.container.is( '.control-panel.control-panel-default' ) ); 184 ok( 1 === panel.container.find( '> .accordion-section-title' ).length ); 185 ok( 1 === panel.container.find( '> .control-panel-content' ).length ); 186 } ); 187 188 module( 'Customizer Custom Type Panel (titleless) with Template in Fixture' ); 189 test( 'Fixture panel exists', function () { 190 ok( wp.customize.panel.has( 'fixture-panel-titleless-templated' ) ); 191 } ); 192 test( 'Fixture panel has expected content', function () { 193 var id = 'fixture-panel-titleless-templated', panel; 194 panel = wp.customize.panel( id ); 195 ok( ! panel.params.content ); 196 ok( !! panel.container ); 197 ok( panel.container.is( '.control-panel.control-panel-titleless' ) ); 198 ok( 0 === panel.container.find( '> .accordion-section-title' ).length ); 199 ok( 1 === panel.container.find( '> .control-panel-content' ).length ); 200 } ); 201 141 202 142 203 module( 'Dynamically-created Customizer Setting Model' ); 143 204 settingId = 'new_blogname'; … … jQuery( window ).load( function (){ 163 224 sectionContent = '<li id="accordion-section-mock_title_tagline" class="control-section accordion-section"></li>'; 164 225 sectionData = { 165 226 content: sectionContent, 166 active: true 227 active: true, 228 type: 'default' 167 229 }; 168 230 169 231 mockSection = new wp.customize.Section( sectionId, { params: sectionData } ); … … jQuery( window ).load( function (){ 277 339 content: panelContent, 278 340 title: panelTitle, 279 341 description: panelDescription, 280 active: true // @todo This should default to true 342 active: true, // @todo This should default to true 343 type: 'default' 281 344 }; 282 345 283 346 mockPanel = new wp.customize.Panel( panelId, { params: panelData } );