Make WordPress Core

Ticket #28709: 28709.wip.diff

File 28709.wip.diff, 17.0 KB (added by westonruter, 10 years ago)

https://github.com/x-team/wordpress-develop/pull/29

  • src/wp-admin/customize.php

    diff --git src/wp-admin/customize.php src/wp-admin/customize.php
    index 3cfa0c7..2ce23b4 100644
    do_action( 'customize_controls_print_scripts' ); 
    160160                                <?php endif; ?>
    161161                        </div>
    162162
    163                         <div id="customize-theme-controls"><ul>
    164                                 <?php
    165                                 foreach ( $wp_customize->containers() as $container ) {
    166                                         $container->maybe_render();
    167                                 }
    168                                 ?>
    169                         </ul></div>
     163                        <div id="customize-theme-controls">
     164                                <ul><?php // Panels and sections are managed here via JavaScript ?></ul>
     165                        </div>
    170166                </div>
    171167                </div>
    172168
    do_action( 'customize_controls_print_scripts' ); 
    249245                ),
    250246                'settings' => array(),
    251247                'controls' => array(),
     248                'panels'   => array(),
     249                'sections' => array(),
    252250                'nonce'    => array(
    253251                        'save'    => wp_create_nonce( 'save-customize_' . $wp_customize->get_stylesheet() ),
    254252                        'preview' => wp_create_nonce( 'preview-customize_' . $wp_customize->get_stylesheet() )
    do_action( 'customize_controls_print_scripts' ); 
    263261                );
    264262        }
    265263
    266         // Prepare Customize Control objects to pass to Javascript.
     264        // Prepare Customize Control objects to pass to JavaScript.
    267265        foreach ( $wp_customize->controls() as $id => $control ) {
    268                 $control->to_json();
    269                 $settings['controls'][ $id ] = $control->json;
     266                $settings['controls'][ $id ] = $control->json();
     267        }
     268
     269        // Prepare Customize Section objects to pass to JavaScript.
     270        foreach ( $wp_customize->sections() as $id => $section ) {
     271                $settings['sections'][ $id ] = $section->json();
     272        }
     273
     274        // Prepare Customize Panel objects to pass to JavaScript.
     275        foreach ( $wp_customize->panels() as $id => $panel ) {
     276                $settings['panels'][ $id ] = $panel->json();
     277                foreach ( $panel->sections as $section_id => $section ) {
     278                        $settings['sections'][ $section_id ] = $section->json();
     279                }
    270280        }
    271281
    272282        ?>
  • src/wp-admin/js/accordion.js

    diff --git src/wp-admin/js/accordion.js src/wp-admin/js/accordion.js
    index 6cb1c1c..63e14e8 100644
     
    5858                });
    5959        });
    6060
    61         var sectionContent = $( '.accordion-section-content' );
    62 
    6361        /**
    6462         * Close the current accordion section and open a new one.
    6563         *
     
    6967        function accordionSwitch ( el ) {
    7068                var section = el.closest( '.accordion-section' ),
    7169                        siblings = section.closest( '.accordion-container' ).find( '.open' ),
    72                         content = section.find( sectionContent );
     70                        content = section.find( '.accordion-section-content' );
    7371
    7472                // This section has no content and cannot be expanded.
    7573                if ( section.hasClass( 'cannot-expand' ) ) {
     
    8785                        content.toggle( true ).slideToggle( 150 );
    8886                } else {
    8987                        siblings.removeClass( 'open' );
    90                         siblings.find( sectionContent ).show().slideUp( 150 );
     88                        siblings.find( '.accordion-section-content' ).show().slideUp( 150 );
    9189                        content.toggle( false ).slideToggle( 150 );
    9290                        section.toggleClass( 'open' );
    9391                }
     
    125123                } else {
    126124                        // Close all open sections in any accordion level.
    127125                        siblings.removeClass( 'open' );
    128                         siblings.find( sectionContent ).show().slideUp( 0 );
     126                        siblings.find( '.accordion-section-content' ).show().slideUp( 0 );
    129127                        content.show( 0, function() {
    130128                                position = content.offset().top;
    131129                                scroll = container.scrollTop();
  • src/wp-admin/js/customize-controls.js

    diff --git src/wp-admin/js/customize-controls.js src/wp-admin/js/customize-controls.js
    index 85b171d..0af5277 100644
     
    3434         * @constructor
    3535         * @augments wp.customize.Class
    3636         */
     37        api.Section = api.Class.extend({
     38
     39                /**
     40                 * @param {String} id
     41                 * @param {Array} options
     42                 */
     43                initialize: function ( id, options ) {
     44                        var section = this;
     45                        section.id = id;
     46                        section.params = {};
     47                        $.extend( section, options || {} );
     48                        section.panel = new api.Value();
     49                        section.container = $( section.params.content );
     50                        section.priority = new api.Value( section.params.priority || 100 );
     51                        section.panel.bind( function ( id ) {
     52                                $( section.container ).toggleClass( 'control-subsection', !! id );
     53                        });
     54                        section.panel.set( section.params.panel || '' );
     55                },
     56
     57                /**
     58                 *
     59                 */
     60                embed: function ( readyCallback ) {
     61                        var panel_id,
     62                                section = this;
     63
     64                        panel_id = this.panel.get();
     65                        if ( ! panel_id ) {
     66                                $( '#customize-theme-controls > ul' ).append( section.container );
     67                                readyCallback();
     68                        } else {
     69                                api.panel( panel_id, function ( panel ) {
     70                                        panel.embed();
     71                                        panel.container.find( 'ul:first' ).append( section.container );
     72                                        readyCallback();
     73                                } );
     74                        }
     75                },
     76
     77                /**
     78                 * Get the controls that are associated with this section.
     79                 *
     80                 * @returns {Array}
     81                 */
     82                controls: function () {
     83                        var section = this,
     84                                controls = [];
     85                        api.control.each( function ( control ) {
     86                                if ( control.section.get() === section.id ) {
     87                                        controls.push( control );
     88                                }
     89                        } );
     90                        controls.sort( function ( a, b ) {
     91                                return a.priority() - b.priority();
     92                        } );
     93                        return controls;
     94                },
     95
     96                /**
     97                 * Expand the accordion section (and collapse all others).
     98                 */
     99                expand: function () {
     100                        throw new Error( 'Not implemented' ); // @todo
     101                },
     102
     103                /**
     104                 * Collapse the accordion section.
     105                 */
     106                collapse: function () {
     107                        throw new Error( 'Not implemented' ); // @todo
     108                }
     109        });
     110
     111        /**
     112         * @constructor
     113         * @augments wp.customize.Class
     114         */
     115        api.Panel = api.Class.extend({
     116                initialize: function ( id, options ) {
     117                        var panel = this;
     118                        panel.id = id;
     119                        panel.params = {};
     120                        $.extend( panel, options || {} );
     121                        panel.priority = new api.Value( panel.params.priority || 160 ); // @todo What if the priority gets changed dynamically?
     122                        panel.container = $( panel.params.content );
     123                },
     124
     125                /**
     126                 *
     127                 */
     128                embed: function ( readyCallback ) {
     129                        $( '#customize-theme-controls > ul' ).append( this.container );
     130                        if ( readyCallback ) {
     131                                readyCallback();
     132                        }
     133                },
     134
     135                /**
     136                 * Get the controls that are associated with this section.
     137                 *
     138                 * @returns {Array}
     139                 */
     140                sections: function () {
     141                        var panel = this,
     142                                sections = [];
     143                        api.section.each( function ( section ) {
     144                                if ( section.panel.get() === panel.id ) {
     145                                        sections.push( section );
     146                                }
     147                        } );
     148                        sections.sort( function ( a, b ) {
     149                                return a.priority() - b.priority();
     150                        } );
     151                        return sections;
     152                },
     153
     154                /**
     155                 * Expand the accordion section (and collapse all others).
     156                 */
     157                expand: function () {
     158                        throw new Error( 'Not implemented' ); // @todo
     159                },
     160
     161                /**
     162                 * Collapse the accordion section.
     163                 */
     164                collapse: function () {
     165                        throw new Error( 'Not implemented' ); // @todo
     166                }
     167        });
     168
     169        /**
     170         * @constructor
     171         * @augments wp.customize.Class
     172         */
    37173        api.Control = api.Class.extend({
    38174                initialize: function( id, options ) {
    39175                        var control = this,
     
    44180
    45181                        this.id = id;
    46182                        this.selector = '#customize-control-' + id.replace( /\]/g, '' ).replace( /\[/g, '-' );
    47                         this.container = $( this.selector );
     183                        this.container = this.params.content ? $( this.params.content ) : $( this.selector );
     184
     185                        this.section = new api.Value( this.params.section );
     186                        this.priority = new api.Value( this.params.priority || 10 );
    48187                        this.active = new api.Value( this.params.active );
    49188
    50189                        settings = $.map( this.params.settings, function( value ) {
     
    60199                                }
    61200
    62201                                control.setting = control.settings['default'] || null;
    63                                 control.ready();
     202                                control.embed( function () {
     203                                        control.ready();
     204                                } );
    64205                        }) );
    65206
    66207                        control.elements = [];
     
    74215
    75216                                if ( node.is(':radio') ) {
    76217                                        name = node.prop('name');
    77                                         if ( radios[ name ] )
     218                                        if ( radios[ name ] ) {
    78219                                                return;
     220                                        }
    79221
    80222                                        radios[ name ] = true;
    81223                                        node = nodes.filter( '[name="' + name + '"]' );
     
    96238                },
    97239
    98240                /**
     241                 * @param {Function} [readyCallback] Callback to fire when the embedding is done.
     242                 */
     243                embed: function ( readyCallback ) {
     244                        var section_id,
     245                                control = this;
     246
     247                        section_id = control.section.get();
     248                        if ( ! section_id ) {
     249                                throw new Error( 'A control must have an associated section.' );
     250                        }
     251
     252                        // Defer until the associated section is available
     253                        api.section( section_id, function ( section ) {
     254                                section.embed( function () {
     255                                        section.container.find( 'ul:first' ).append( control.container );
     256                                        readyCallback();
     257                                } );
     258                        } );
     259                },
     260
     261                /**
    99262                 * @abstract
    100263                 */
    101264                ready: function() {},
     
    575738
    576739        // Create the collection of Control objects.
    577740        api.control = new api.Values({ defaultConstructor: api.Control });
     741        api.section = new api.Values({ defaultConstructor: api.Section });
     742        api.panel = new api.Values({ defaultConstructor: api.Panel });
     743
     744        // @todo For each, bind the 'add' and 'remove' events
     745        // @todo For each, bind to the changes in the priority for each item added, and then reorder the elements based on priority
     746        //
     747        //api.panel.bind( 'add', function () {
     748        //      console.info( 'add panel', arguments )
     749        //} );
     750        //api.section.bind( 'add', function () {
     751        //      console.info( 'add section', arguments )
     752        //} );
     753        //api.control.bind( 'add', function () {
     754        //      console.info( 'add control', arguments )
     755        //} );
    578756
    579757        /**
    580758         * @constructor
     
    10911269                        $.extend( this.nonce, nonce );
    10921270                });
    10931271
     1272                //
    10941273                $.each( api.settings.settings, function( id, data ) {
    10951274                        api.create( id, id, data.value, {
    10961275                                transport: data.transport,
     
    10981277                        } );
    10991278                });
    11001279
     1280                $.each( api.settings.panels, function ( id, data ) {
     1281                        var panel = new api.Panel( id, {
     1282                                params: data
     1283                        } );
     1284                        api.panel.add( id, panel );
     1285                });
     1286
     1287                $.each( api.settings.sections, function ( id, data ) {
     1288                        var section = new api.Section( id, {
     1289                                params: data
     1290                        } );
     1291                        api.section.add( id, section );
     1292                });
     1293
     1294                // @todo Extract this out
    11011295                $.each( api.settings.controls, function( id, data ) {
    11021296                        var constructor = api.controlConstructor[ data.type ] || api.Control,
    11031297                                control;
    11041298
    1105                         control = api.control.add( id, new constructor( id, {
     1299                        control = new constructor( id, {
    11061300                                params: data,
    11071301                                previewer: api.previewer
    1108                         } ) );
     1302                        } );
     1303                        api.control.add( id, control );
    11091304                });
    11101305
    11111306                // Check if preview url is valid and load the preview frame.
  • 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 7ae21c8..4a5985f 100644
    class WP_Customize_Control { 
    7474        public $input_attrs = array();
    7575
    7676        /**
     77         * @deprecated It is better to just call the json() method
    7778         * @access public
    7879         * @var array
    7980         */
    class WP_Customize_Control { 
    219220
    220221                $this->json['type'] = $this->type;
    221222                $this->json['active'] = $this->active();
     223                $this->json['section'] = $this->section;
     224                $this->json['content'] = $this->get_content();
     225        }
     226
     227        /**
     228         * Get the data to export to the client via JSON.
     229         *
     230         * @since 4.1.0
     231         *
     232         * @return array
     233         */
     234        public function json() {
     235                $this->to_json();
     236                return $this->json;
    222237        }
    223238
    224239        /**
    class WP_Customize_Control { 
    242257        }
    243258
    244259        /**
     260         * Get the control's content for insertion into the Customizer pane.
     261         *
     262         * @since 4.1.0
     263         *
     264         * @return string
     265         */
     266        public final function get_content() {
     267                ob_start();
     268                $this->maybe_render();
     269                $template = trim( ob_get_contents() );
     270                ob_end_clean();
     271                return $template;
     272        }
     273
     274        /**
    245275         * Check capabilities and render the control.
    246276         *
    247277         * @since 3.4.0
  • 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 c658198..bf0963c 100644
    final class WP_Customize_Manager { 
    878878
    879879                        if ( ! $section->panel ) {
    880880                                // Top-level section.
    881                                 $sections[] = $section;
     881                                $sections[ $section->id ] = $section;
    882882                        } else {
    883883                                // This section belongs to a panel.
    884884                                if ( isset( $this->panels [ $section->panel ] ) ) {
    885                                         $this->panels[ $section->panel ]->sections[] = $section;
     885                                        $this->panels[ $section->panel ]->sections[ $section->id ] = $section;
    886886                                }
    887887                        }
    888888                }
    final class WP_Customize_Manager { 
    899899                                continue;
    900900                        }
    901901
    902                         usort( $panel->sections, array( $this, '_cmp_priority' ) );
    903                         $panels[] = $panel;
     902                        uasort( $panel->sections, array( $this, '_cmp_priority' ) );
     903                        $panels[ $panel->id ] = $panel;
    904904                }
    905905                $this->panels = $panels;
    906906
  • 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 8f85049..a04c568 100644
    class WP_Customize_Panel { 
    110110        }
    111111
    112112        /**
     113         * Gather the parameters passed to client JavaScript via JSON.
     114         *
     115         * @since 4.1.0
     116         *
     117         * @return array The array to be exported to the client as JSON
     118         */
     119        public function json() {
     120                $array = wp_array_slice_assoc( (array) $this, array( 'title', 'description', 'priority' ) );
     121                $array['content'] = $this->get_content();
     122                return $array;
     123        }
     124
     125        /**
    113126         * Checks required user capabilities and whether the theme has the
    114127         * feature support required by the panel.
    115128         *
    class WP_Customize_Panel { 
    130143        }
    131144
    132145        /**
     146         * Get the panel's content template for insertion into the Customizer pane.
     147         *
     148         * @since 4.1.0
     149         *
     150         * @return string
     151         */
     152        public final function get_content() {
     153                ob_start();
     154                $this->maybe_render();
     155                $template = trim( ob_get_contents() );
     156                ob_end_clean();
     157                return $template;
     158        }
     159
     160        /**
    133161         * Check capabilities and render the panel.
    134162         *
    135163         * @since 4.0.0
    class WP_Customize_Panel { 
    175203                                <span class="screen-reader-text"><?php _e( 'Press return or enter to open this panel' ); ?></span>
    176204                        </h3>
    177205                        <ul class="accordion-sub-container control-panel-content">
    178                                 <li class="accordion-section control-section<?php if ( empty( $this->description ) ) echo ' cannot-expand'; ?>">
     206                                <li class="panel-meta accordion-section control-section<?php if ( empty( $this->description ) ) echo ' cannot-expand'; ?>">
    179207                                        <div class="accordion-section-title" tabindex="0">
    180208                                                <span class="preview-notice"><?php
    181209                                                        /* translators: %s is the site/panel title in the Customizer */
    class WP_Customize_Panel { 
    188216                                                </div>
    189217                                        <?php endif; ?>
    190218                                </li>
    191                                 <?php
    192                                 foreach ( $this->sections as $section ) {
    193                                         $section->maybe_render();
    194                                 }
    195                                 ?>
     219
    196220                        </ul>
    197221                </li>
    198222                <?php
  • 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 d740ddb..6b1c4cf 100644
    class WP_Customize_Section { 
    118118        }
    119119
    120120        /**
     121         * Gather the parameters passed to client JavaScript via JSON.
     122         *
     123         * @since 4.1.0
     124         *
     125         * @return array The array to be exported to the client as JSON
     126         */
     127        public function json() {
     128                $array = wp_array_slice_assoc( (array) $this, array( 'title', 'description', 'priority', 'panel' ) );
     129                $array['content'] = $this->get_content();
     130                return $array;
     131        }
     132
     133        /**
    121134         * Checks required user capabilities and whether the theme has the
    122135         * feature support required by the section.
    123136         *
    class WP_Customize_Section { 
    136149        }
    137150
    138151        /**
     152         * Get the section's content template for insertion into the Customizer pane.
     153         *
     154         * @since 4.1.0
     155         *
     156         * @return string
     157         */
     158        public final function get_content() {
     159                ob_start();
     160                $this->maybe_render();
     161                $template = trim( ob_get_contents() );
     162                ob_end_clean();
     163                return $template;
     164        }
     165
     166        /**
    139167         * Check capabilities and render the section.
    140168         *
    141169         * @since 3.4.0
    class WP_Customize_Section { 
    172200         */
    173201        protected function render() {
    174202                $classes = 'control-section accordion-section';
    175                 if ( $this->panel ) {
    176                         $classes .= ' control-subsection';
    177                 }
    178203                ?>
    179204                <li id="accordion-section-<?php echo esc_attr( $this->id ); ?>" class="<?php echo esc_attr( $classes ); ?>">
    180205                        <h3 class="accordion-section-title" tabindex="0">
    class WP_Customize_Section { 
    183208                        </h3>
    184209                        <ul class="accordion-section-content">
    185210                                <?php if ( ! empty( $this->description ) ) : ?>
    186                                 <li><p class="description customize-section-description"><?php echo $this->description; ?></p></li>
     211                                        <li class="customize-section-description-container">
     212                                                <p class="description customize-section-description"><?php echo $this->description; ?></p>
     213                                        </li>
    187214                                <?php endif; ?>
    188                                 <?php
    189                                 foreach ( $this->controls as $control )
    190                                         $control->maybe_render();
    191                                 ?>
    192215                        </ul>
    193216                </li>
    194217                <?php
  • src/wp-includes/js/customize-base.js

    diff --git src/wp-includes/js/customize-base.js src/wp-includes/js/customize-base.js
    index 6c41b40..13d6189 100644
    window.wp = window.wp || {}; 
    183183                        to = this.validate( to );
    184184
    185185                        // Bail if the sanitized value is null or unchanged.
    186                         if ( null === to || this._value === to )
     186                        if ( null === to || this._value === to ) { // @todo why bail if null?
    187187                                return this;
     188                        }
    188189
    189190                        this._value = to;
    190191