Make WordPress Core

Changeset 41558


Ignore:
Timestamp:
09/21/2017 11:03:06 PM (9 years ago)
Author:
westonruter
Message:

Customize: Introduce extensible code editor Customizer control for CodeMirror.

  • Adds WP_Customize_Code_Editor_Control and wp.customize.CodeEditorControl().
  • Control respects user preference for syntax highlighting, showing a textarea when user opts out.
  • Code editor control takes the ad hoc code for Additional CSS and makes it reusable and extensible, for Additional CSS in core and plugins to use (such as Jetpack).
  • Replace settings arg in wp_enqueue_code_editor() with separate args for codemirror, csslint, jshint, and htmlhint.
  • Prefix codemirror script and style handles with wp- to prevent collisions, as also the object is exported as wp.CodeMirror in JS.
  • Reduce indent size in Customizer code editor instances and Custom HTML widget to use tab size of 2 instead of 4 to save on space.

See #12423, #38707, #35395.
Fixes #41897.

Location:
trunk
Files:
1 added
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-admin/css/customize-controls.css

    r41390 r41558  
    11651165
    11661166/**
    1167  * Custom CSS Section
     1167 * Code Editor Control and Custom CSS Section
    11681168 *
    11691169 * Modifications to the Section Container to make the textarea full-width and
     
    11711171 */
    11721172
    1173 #customize-controls .customize-section-description-container.section-meta.customize-info {
    1174         border-bottom: none;
    1175 }
    1176 
    1177 #sub-accordion-section-custom_css .customize-control-notifications-container {
    1178         margin-bottom: 15px;
    1179 }
    1180 
    1181 #customize-control-custom_css textarea {
    1182         display: block;
     1173.customize-control-code_editor textarea {
     1174        width: 100%;
    11831175        font-family: Consolas, Monaco, monospace;
    11841176        font-size: 12px;
    11851177        padding: 6px 8px;
     1178        -moz-tab-size: 2;
     1179        -o-tab-size: 2;
     1180        tab-size: 2;
     1181}
     1182.customize-control-code_editor textarea,
     1183.customize-control-code_editor .CodeMirror {
     1184        height: 14em;
     1185}
     1186
     1187#customize-controls .customize-section-description-container.section-meta.customize-info {
     1188        border-bottom: none;
     1189}
     1190
     1191#sub-accordion-section-custom_css .customize-control-notifications-container {
     1192        margin-bottom: 15px;
     1193}
     1194
     1195#customize-control-custom_css textarea {
     1196        display: block;
    11861197        height: 500px;
    1187         -moz-tab-size: 4;
    1188         -o-tab-size: 4;
    1189         tab-size: 4;
    11901198}
    11911199
  • trunk/src/wp-admin/js/customize-controls.js

    r41390 r41558  
    36783678        });
    36793679
     3680        /**
     3681         * Class wp.customize.CodeEditorControl
     3682         *
     3683         * @since 4.9.0
     3684         *
     3685         * @constructor
     3686         * @augments wp.customize.Control
     3687         * @augments wp.customize.Class
     3688         */
     3689        api.CodeEditorControl = api.Control.extend({
     3690
     3691                /**
     3692                 * Initialize the editor when the containing section is ready and expanded.
     3693                 *
     3694                 * @since 4.9.0
     3695                 * @returns {void}
     3696                 */
     3697                ready: function() {
     3698                        var control = this;
     3699                        if ( ! control.section() ) {
     3700                                control.initEditor();
     3701                                return;
     3702                        }
     3703
     3704                        // Wait to initialize editor until section is embedded and expanded.
     3705                        api.section( control.section(), function( section ) {
     3706                                section.deferred.embedded.done( function() {
     3707                                        var onceExpanded;
     3708                                        if ( section.expanded() ) {
     3709                                                control.initEditor();
     3710                                        } else {
     3711                                                onceExpanded = function( isExpanded ) {
     3712                                                        if ( isExpanded ) {
     3713                                                                control.initEditor();
     3714                                                                section.expanded.unbind( onceExpanded );
     3715                                                        }
     3716                                                };
     3717                                                section.expanded.bind( onceExpanded );
     3718                                        }
     3719                                } );
     3720                        } );
     3721                },
     3722
     3723                /**
     3724                 * Initialize editor.
     3725                 *
     3726                 * @since 4.9.0
     3727                 * @returns {void}
     3728                 */
     3729                initEditor: function() {
     3730                        var control = this, element;
     3731
     3732                        element = new api.Element( control.container.find( 'textarea' ) );
     3733                        control.elements.push( element );
     3734                        element.sync( control.setting );
     3735                        element.set( control.setting() );
     3736
     3737                        if ( control.params.editor_settings ) {
     3738                                control.initSyntaxHighlightingEditor( control.params.editor_settings );
     3739                        } else {
     3740                                control.initPlainTextareaEditor();
     3741                        }
     3742                },
     3743
     3744                /**
     3745                 * Make sure editor gets focused when control is focused.
     3746                 *
     3747                 * @since 4.9.0
     3748                 * @param {Object}   [params] - Focus params.
     3749                 * @param {Function} [params.completeCallback] - Function to call when expansion is complete.
     3750                 * @returns {void}
     3751                 */
     3752                focus: function( params ) {
     3753                        var control = this, extendedParams = _.extend( {}, params ), originalCompleteCallback;
     3754                        originalCompleteCallback = extendedParams.completeCallback;
     3755                        extendedParams.completeCallback = function() {
     3756                                if ( originalCompleteCallback ) {
     3757                                        originalCompleteCallback();
     3758                                }
     3759                                if ( control.editor ) {
     3760                                        control.editor.codemirror.focus();
     3761                                }
     3762                        };
     3763                        api.Control.prototype.focus.call( control, extendedParams );
     3764                },
     3765
     3766                /**
     3767                 * Initialize syntax-highlighting editor.
     3768                 *
     3769                 * @since 4.9.0
     3770                 * @param {object} codeEditorSettings - Code editor settings.
     3771                 * @returns {void}
     3772                 */
     3773                initSyntaxHighlightingEditor: function( codeEditorSettings ) {
     3774                        var control = this, $textarea = control.container.find( 'textarea' ), settings, suspendEditorUpdate = false;
     3775
     3776                        settings = _.extend( {}, codeEditorSettings, {
     3777                                onTabNext: _.bind( control.onTabNext, control ),
     3778                                onTabPrevious: _.bind( control.onTabPrevious, control ),
     3779                                onUpdateErrorNotice: _.bind( control.onUpdateErrorNotice, control )
     3780                        });
     3781
     3782                        control.editor = wp.codeEditor.initialize( $textarea, settings );
     3783
     3784                        // Refresh when receiving focus.
     3785                        control.editor.codemirror.on( 'focus', function( codemirror ) {
     3786                                codemirror.refresh();
     3787                        });
     3788
     3789                        /*
     3790                         * When the CodeMirror instance changes, mirror to the textarea,
     3791                         * where we have our "true" change event handler bound.
     3792                         */
     3793                        control.editor.codemirror.on( 'change', function( codemirror ) {
     3794                                suspendEditorUpdate = true;
     3795                                $textarea.val( codemirror.getValue() ).trigger( 'change' );
     3796                                suspendEditorUpdate = false;
     3797                        });
     3798
     3799                        // Update CodeMirror when the setting is changed by another plugin.
     3800                        control.setting.bind( function( value ) {
     3801                                if ( ! suspendEditorUpdate ) {
     3802                                        control.editor.codemirror.setValue( value );
     3803                                }
     3804                        });
     3805
     3806                        // Prevent collapsing section when hitting Esc to tab out of editor.
     3807                        control.editor.codemirror.on( 'keydown', function onKeydown( codemirror, event ) {
     3808                                var escKeyCode = 27;
     3809                                if ( escKeyCode === event.keyCode ) {
     3810                                        event.stopPropagation();
     3811                                }
     3812                        });
     3813                },
     3814
     3815                /**
     3816                 * Handle tabbing to the field after the editor.
     3817                 *
     3818                 * @since 4.9.0
     3819                 * @returns {void}
     3820                 */
     3821                onTabNext: function onTabNext() {
     3822                        var control = this, controls, controlIndex, section;
     3823                        section = api.section( control.section() );
     3824                        controls = section.controls();
     3825                        controlIndex = controls.indexOf( control );
     3826                        if ( controls.length === controlIndex + 1 ) {
     3827                                $( '#customize-footer-actions .collapse-sidebar' ).focus();
     3828                        } else {
     3829                                controls[ controlIndex + 1 ].container.find( ':focusable:first' ).focus();
     3830                        }
     3831                },
     3832
     3833                /**
     3834                 * Handle tabbing to the field before the editor.
     3835                 *
     3836                 * @since 4.9.0
     3837                 * @returns {void}
     3838                 */
     3839                onTabPrevious: function onTabPrevious() {
     3840                        var control = this, controls, controlIndex, section;
     3841                        section = api.section( control.section() );
     3842                        controls = section.controls();
     3843                        controlIndex = controls.indexOf( control );
     3844                        if ( 0 === controlIndex ) {
     3845                                section.contentContainer.find( '.customize-section-title .customize-help-toggle, .customize-section-title .customize-section-description.open .section-description-close' ).last().focus();
     3846                        } else {
     3847                                controls[ controlIndex - 1 ].contentContainer.find( ':focusable:first' ).focus();
     3848                        }
     3849                },
     3850
     3851                /**
     3852                 * Update error notice.
     3853                 *
     3854                 * @since 4.9.0
     3855                 * @param {Array} errorAnnotations - Error annotations.
     3856                 * @returns {void}
     3857                 */
     3858                onUpdateErrorNotice: function onUpdateErrorNotice( errorAnnotations ) {
     3859                        var control = this, message;
     3860                        control.setting.notifications.remove( 'csslint_error' );
     3861
     3862                        if ( 0 !== errorAnnotations.length ) {
     3863                                if ( 1 === errorAnnotations.length ) {
     3864                                        message = api.l10n.customCssError.singular.replace( '%d', '1' );
     3865                                } else {
     3866                                        message = api.l10n.customCssError.plural.replace( '%d', String( errorAnnotations.length ) );
     3867                                }
     3868                                control.setting.notifications.add( 'csslint_error', new api.Notification( 'csslint_error', {
     3869                                        message: message,
     3870                                        type: 'error'
     3871                                } ) );
     3872                        }
     3873                },
     3874
     3875                /**
     3876                 * Initialize plain-textarea editor when syntax highlighting is disabled.
     3877                 *
     3878                 * @since 4.9.0
     3879                 * @returns {void}
     3880                 */
     3881                initPlainTextareaEditor: function() {
     3882                        var control = this, $textarea = control.container.find( 'textarea' ), textarea = $textarea[0];
     3883
     3884                        $textarea.on( 'blur', function onBlur() {
     3885                                $textarea.data( 'next-tab-blurs', false );
     3886                        } );
     3887
     3888                        $textarea.on( 'keydown', function onKeydown( event ) {
     3889                                var selectionStart, selectionEnd, value, tabKeyCode = 9, escKeyCode = 27;
     3890
     3891                                if ( escKeyCode === event.keyCode ) {
     3892                                        if ( ! $textarea.data( 'next-tab-blurs' ) ) {
     3893                                                $textarea.data( 'next-tab-blurs', true );
     3894                                                event.stopPropagation(); // Prevent collapsing the section.
     3895                                        }
     3896                                        return;
     3897                                }
     3898
     3899                                // Short-circuit if tab key is not being pressed or if a modifier key *is* being pressed.
     3900                                if ( tabKeyCode !== event.keyCode || event.ctrlKey || event.altKey || event.shiftKey ) {
     3901                                        return;
     3902                                }
     3903
     3904                                // Prevent capturing Tab characters if Esc was pressed.
     3905                                if ( $textarea.data( 'next-tab-blurs' ) ) {
     3906                                        return;
     3907                                }
     3908
     3909                                selectionStart = textarea.selectionStart;
     3910                                selectionEnd = textarea.selectionEnd;
     3911                                value = textarea.value;
     3912
     3913                                if ( selectionStart >= 0 ) {
     3914                                        textarea.value = value.substring( 0, selectionStart ).concat( '\t', value.substring( selectionEnd ) );
     3915                                        $textarea.selectionStart = textarea.selectionEnd = selectionStart + 1;
     3916                                }
     3917
     3918                                event.stopPropagation();
     3919                                event.preventDefault();
     3920                        });
     3921                }
     3922        });
     3923
    36803924        // Change objects contained within the main customize object to Settings.
    36813925        api.defaultConstructor = api.Setting;
     
    43734617                background:          api.BackgroundControl,
    43744618                background_position: api.BackgroundPositionControl,
    4375                 theme:               api.ThemeControl
     4619                theme:               api.ThemeControl,
     4620                code_editor:         api.CodeEditorControl
    43764621        };
    43774622        api.panelConstructor = {};
     
    57135958                // Add code editor for Custom CSS.
    57145959                (function() {
    5715                         var ready, sectionReady = $.Deferred(), controlReady = $.Deferred();
     5960                        var sectionReady = $.Deferred();
    57165961
    57175962                        api.section( 'custom_css', function( section ) {
     
    57285973                                });
    57295974                        });
    5730                         api.control( 'custom_css', function( control ) {
    5731                                 control.deferred.embedded.done( function() {
    5732                                         controlReady.resolve( control );
    5733                                 });
    5734                         });
    5735 
    5736                         ready = $.when( sectionReady, controlReady );
    57375975
    57385976                        // Set up the section desription behaviors.
    5739                         ready.done( function setupSectionDescription( section, control ) {
     5977                        sectionReady.done( function setupSectionDescription( section ) {
     5978                                var control = api.control( 'custom_css' );
    57405979
    57415980                                // Close the section description when clicking the close button.
     
    57485987
    57495988                                // Reveal help text if setting is empty.
    5750                                 if ( ! control.setting.get() ) {
     5989                                if ( control && ! control.setting.get() ) {
    57515990                                        section.container.find( '.section-meta .customize-section-description:first' )
    57525991                                                .addClass( 'open' )
     
    57555994                                }
    57565995                        });
    5757 
    5758                         // Set up the code editor itself.
    5759                         if ( api.settings.customCss && api.settings.customCss.codeEditor ) {
    5760 
    5761                                 // Set up the syntax highlighting editor.
    5762                                 ready.done( function setupSyntaxHighlightingEditor( section, control ) {
    5763                                         var $textarea = control.container.find( 'textarea' ), settings, suspendEditorUpdate = false;
    5764 
    5765                                         // Make sure editor gets focused when control is focused.
    5766                                         control.focus = (function( originalFocus ) { // eslint-disable-line max-nested-callbacks
    5767                                                 return function( params ) { // eslint-disable-line max-nested-callbacks
    5768                                                         var extendedParams = _.extend( {}, params ), originalCompleteCallback;
    5769                                                         originalCompleteCallback = extendedParams.completeCallback;
    5770                                                         extendedParams.completeCallback = function() {
    5771                                                                 if ( originalCompleteCallback ) {
    5772                                                                         originalCompleteCallback();
    5773                                                                 }
    5774                                                                 if ( control.editor ) {
    5775                                                                         control.editor.codemirror.focus();
    5776                                                                 }
    5777                                                         };
    5778                                                         originalFocus.call( this, extendedParams );
    5779                                                 };
    5780                                         })( control.focus );
    5781 
    5782                                         settings = _.extend( {}, api.settings.customCss.codeEditor, {
    5783 
    5784                                                 /**
    5785                                                  * Handle tabbing to the field after the editor.
    5786                                                  *
    5787                                                  * @returns {void}
    5788                                                  */
    5789                                                 onTabNext: function onTabNext() {
    5790                                                         var controls, controlIndex;
    5791                                                         controls = section.controls();
    5792                                                         controlIndex = controls.indexOf( control );
    5793                                                         if ( controls.length === controlIndex + 1 ) {
    5794                                                                 $( '#customize-footer-actions .collapse-sidebar' ).focus();
    5795                                                         } else {
    5796                                                                 controls[ controlIndex + 1 ].container.find( ':focusable:first' ).focus();
    5797                                                         }
    5798                                                 },
    5799 
    5800                                                 /**
    5801                                                  * Handle tabbing to the field before the editor.
    5802                                                  *
    5803                                                  * @returns {void}
    5804                                                  */
    5805                                                 onTabPrevious: function onTabPrevious() {
    5806                                                         var controls, controlIndex;
    5807                                                         controls = section.controls();
    5808                                                         controlIndex = controls.indexOf( control );
    5809                                                         if ( 0 === controlIndex ) {
    5810                                                                 section.contentContainer.find( '.customize-section-title .customize-help-toggle, .customize-section-title .customize-section-description.open .section-description-close' ).last().focus();
    5811                                                         } else {
    5812                                                                 controls[ controlIndex - 1 ].contentContainer.find( ':focusable:first' ).focus();
    5813                                                         }
    5814                                                 },
    5815 
    5816                                                 /**
    5817                                                  * Update error notice.
    5818                                                  *
    5819                                                  * @param {Array} errorAnnotations - Error annotations.
    5820                                                  * @returns {void}
    5821                                                  */
    5822                                                 onUpdateErrorNotice: function onUpdateErrorNotice( errorAnnotations ) {
    5823                                                         var message;
    5824                                                         control.setting.notifications.remove( 'csslint_error' );
    5825 
    5826                                                         if ( 0 !== errorAnnotations.length ) {
    5827                                                                 if ( 1 === errorAnnotations.length ) {
    5828                                                                         message = api.l10n.customCssError.singular.replace( '%d', '1' );
    5829                                                                 } else {
    5830                                                                         message = api.l10n.customCssError.plural.replace( '%d', String( errorAnnotations.length ) );
    5831                                                                 }
    5832                                                                 control.setting.notifications.add( 'csslint_error', new api.Notification( 'csslint_error', {
    5833                                                                         message: message,
    5834                                                                         type: 'error'
    5835                                                                 } ) );
    5836                                                         }
    5837                                                 }
    5838                                         });
    5839 
    5840                                         control.editor = wp.codeEditor.initialize( $textarea, settings );
    5841 
    5842                                         // Refresh when receiving focus.
    5843                                         control.editor.codemirror.on( 'focus', function( codemirror ) {
    5844                                                 codemirror.refresh();
    5845                                         });
    5846 
    5847                                         /*
    5848                                          * When the CodeMirror instance changes, mirror to the textarea,
    5849                                          * where we have our "true" change event handler bound.
    5850                                          */
    5851                                         control.editor.codemirror.on( 'change', function( codemirror ) {
    5852                                                 suspendEditorUpdate = true;
    5853                                                 $textarea.val( codemirror.getValue() ).trigger( 'change' );
    5854                                                 suspendEditorUpdate = false;
    5855                                         });
    5856 
    5857                                         // Update CodeMirror when the setting is changed by another plugin.
    5858                                         control.setting.bind( function( value ) {
    5859                                                 if ( ! suspendEditorUpdate ) {
    5860                                                         control.editor.codemirror.setValue( value );
    5861                                                 }
    5862                                         });
    5863 
    5864                                         // Prevent collapsing section when hitting Esc to tab out of editor.
    5865                                         control.editor.codemirror.on( 'keydown', function onKeydown( codemirror, event ) {
    5866                                                 var escKeyCode = 27;
    5867                                                 if ( escKeyCode === event.keyCode ) {
    5868                                                         event.stopPropagation();
    5869                                                 }
    5870                                         });
    5871                                 });
    5872                         } else {
    5873 
    5874                                 // Allow tabs to be entered in Custom CSS textarea.
    5875                                 ready.done( function allowTabs( section, control ) {
    5876 
    5877                                         var $textarea = control.container.find( 'textarea' ), textarea = $textarea[0];
    5878 
    5879                                         $textarea.on( 'blur', function onBlur() {
    5880                                                 $textarea.data( 'next-tab-blurs', false );
    5881                                         } );
    5882 
    5883                                         $textarea.on( 'keydown', function onKeydown( event ) {
    5884                                                 var selectionStart, selectionEnd, value, tabKeyCode = 9, escKeyCode = 27;
    5885 
    5886                                                 if ( escKeyCode === event.keyCode ) {
    5887                                                         if ( ! $textarea.data( 'next-tab-blurs' ) ) {
    5888                                                                 $textarea.data( 'next-tab-blurs', true );
    5889                                                                 event.stopPropagation(); // Prevent collapsing the section.
    5890                                                         }
    5891                                                         return;
    5892                                                 }
    5893 
    5894                                                 // Short-circuit if tab key is not being pressed or if a modifier key *is* being pressed.
    5895                                                 if ( tabKeyCode !== event.keyCode || event.ctrlKey || event.altKey || event.shiftKey ) {
    5896                                                         return;
    5897                                                 }
    5898 
    5899                                                 // Prevent capturing Tab characters if Esc was pressed.
    5900                                                 if ( $textarea.data( 'next-tab-blurs' ) ) {
    5901                                                         return;
    5902                                                 }
    5903 
    5904                                                 selectionStart = textarea.selectionStart;
    5905                                                 selectionEnd = textarea.selectionEnd;
    5906                                                 value = textarea.value;
    5907 
    5908                                                 if ( selectionStart >= 0 ) {
    5909                                                         textarea.value = value.substring( 0, selectionStart ).concat( '\t', value.substring( selectionEnd ) );
    5910                                                         $textarea.selectionStart = textarea.selectionEnd = selectionStart + 1;
    5911                                                 }
    5912 
    5913                                                 event.stopPropagation();
    5914                                                 event.preventDefault();
    5915                                         });
    5916                                 });
    5917                         }
    59185996                })();
    59195997
  • trunk/src/wp-includes/class-wp-customize-manager.php

    r41550 r41558  
    214214
    215215        /**
    216          * Code Editor Settings for Custom CSS.
    217          *
    218          * This variable contains the settings returned by `wp_enqueue_code_editor()` which are then later output
    219          * to the client in `WP_Customize_Manager::customize_pane_settings()`. A value of false means that the
    220          * Custom CSS section or control was removed, or that the Syntax Highlighting user pref was turned off.
    221          *
    222          * @see wp_enqueue_code_editor()
    223          * @see WP_Customize_Manager::enqueue_control_scripts()
    224          * @see WP_Customize_Manager::customize_pane_settings()
    225          * @since 4.9.0
    226          * @var array|false
    227          */
    228         private $_custom_css_code_editor_settings = false;
    229 
    230         /**
    231216         * Constructor.
    232217         *
     
    292277                require_once( ABSPATH . WPINC . '/customize/class-wp-customize-header-image-control.php' );
    293278                require_once( ABSPATH . WPINC . '/customize/class-wp-customize-theme-control.php' );
     279                require_once( ABSPATH . WPINC . '/customize/class-wp-customize-code-editor-control.php' );
    294280                require_once( ABSPATH . WPINC . '/customize/class-wp-widget-area-customize-control.php' );
    295281                require_once( ABSPATH . WPINC . '/customize/class-wp-widget-form-customize-control.php' );
     
    33383324                        $control->enqueue();
    33393325                }
    3340 
    3341                 if ( $this->get_section( 'custom_css' ) && $this->get_control( 'custom_css' ) ) {
    3342                         $this->_custom_css_code_editor_settings = wp_enqueue_code_editor( array(
    3343                                 'type' => 'text/css',
    3344                         ) );
    3345                 }
    33463326        }
    33473327
     
    36003580                                'stylesheet' => $this->get_stylesheet(),
    36013581                                'active'     => $this->is_theme_active(),
    3602                         ),
    3603                         'customCss' => array(
    3604                                 'codeEditor' => $this->_custom_css_code_editor_settings,
    36053582                        ),
    36063583                        'url'      => array(
     
    37373714                $this->register_control_type( 'WP_Customize_Site_Icon_Control' );
    37383715                $this->register_control_type( 'WP_Customize_Theme_Control' );
     3716                $this->register_control_type( 'WP_Customize_Code_Editor_Control' );
    37393717
    37403718                /* Themes */
     
    42404218                $this->add_setting( $custom_css_setting );
    42414219
    4242                 $this->add_control( 'custom_css', array(
    4243                         'type'     => 'textarea',
     4220                $this->add_control( new WP_Customize_Code_Editor_Control( $this, 'custom_css', array(
    42444221                        'section'  => 'custom_css',
    42454222                        'settings' => array( 'default' => $custom_css_setting->id ),
    4246                         'input_attrs' => array(
    4247                                 'class' => 'code', // Ensures contents displayed as LTR instead of RTL.
    4248                         ),
    4249                 ) );
     4223                        'code_type' => 'text/css',
     4224                ) ) );
    42504225        }
    42514226
  • trunk/src/wp-includes/general-template.php

    r41376 r41558  
    31263126 *     Args.
    31273127 *
    3128  *     @type string   $type     The MIME type of the file to be edited.
    3129  *     @type string   $file     Filename to be edited. Extension is used to sniff the type. Can be supplied as alternative to `$type` param.
    3130  *     @type array    $settings Settings to merge on top of defaults which derive from `$type` or `$file` args.
    3131  *     @type WP_Theme $theme    Theme being edited when on theme editor.
    3132  *     @type string   $plugin   Plugin being edited when on plugin editor.
     3128 *     @type string   $type       The MIME type of the file to be edited.
     3129 *     @type string   $file       Filename to be edited. Extension is used to sniff the type. Can be supplied as alternative to `$type` param.
     3130 *     @type WP_Theme $theme      Theme being edited when on theme editor.
     3131 *     @type string   $plugin     Plugin being edited when on plugin editor.
     3132 *     @type array    $codemirror Additional CodeMirror setting overrides.
     3133 *     @type array    $csslint    CSSLint rule overrides.
     3134 *     @type array    $jshint     JSHint rule overrides.
     3135 *     @type array    $htmlhint   JSHint rule overrides.
    31333136 * }
    31343137 * @returns array|false Settings for the enqueued code editor, or false if the editor was not enqueued .
     
    34093412
    34103413        // Let settings supplied via args override any defaults.
    3411         if ( isset( $args['settings'] ) ) {
    3412                 foreach ( $args['settings'] as $key => $value ) {
    3413                         $settings[ $key ] = array_merge(
    3414                                 $settings[ $key ],
    3415                                 $value
    3416                         );
    3417                 }
     3414        foreach ( wp_array_slice_assoc( $args, array( 'codemirror', 'csslint', 'jshint', 'htmlhint' ) ) as $key => $value ) {
     3415                $settings[ $key ] = array_merge(
     3416                        $settings[ $key ],
     3417                        $value
     3418                );
    34183419        }
    34193420
     
    34293430         *     Args passed when calling `wp_enqueue_code_editor()`.
    34303431         *
    3431          *     @type string   $type     The MIME type of the file to be edited.
    3432          *     @type string   $file     Filename being edited.
    3433          *     @type array    $settings Settings to merge on top of defaults which derive from `$type` or `$file` args.
    3434          *     @type WP_Theme $theme    Theme being edited when on theme editor.
    3435          *     @type string   $plugin   Plugin being edited when on plugin editor.
     3432         *     @type string   $type       The MIME type of the file to be edited.
     3433         *     @type string   $file       Filename being edited.
     3434         *     @type WP_Theme $theme      Theme being edited when on theme editor.
     3435         *     @type string   $plugin     Plugin being edited when on plugin editor.
     3436         *     @type array    $codemirror Additional CodeMirror setting overrides.
     3437         *     @type array    $csslint    CSSLint rule overrides.
     3438         *     @type array    $jshint     JSHint rule overrides.
     3439         *     @type array    $htmlhint   JSHint rule overrides.
    34363440         * }
    34373441         */
     
    34443448        wp_enqueue_script( 'code-editor' );
    34453449        wp_enqueue_style( 'code-editor' );
    3446 
    3447         wp_enqueue_script( 'codemirror' );
    3448         wp_enqueue_style( 'codemirror' );
    34493450
    34503451        if ( isset( $settings['codemirror']['mode'] ) ) {
  • trunk/src/wp-includes/script-loader.php

    r41554 r41558  
    464464        );
    465465
    466         $scripts->add( 'codemirror', '/wp-includes/js/codemirror/codemirror.min.js', array(), '5.29.1-alpha-ee20357' );
     466        $scripts->add( 'wp-codemirror', '/wp-includes/js/codemirror/codemirror.min.js', array(), '5.29.1-alpha-ee20357' );
    467467        $scripts->add( 'csslint', '/wp-includes/js/codemirror/csslint.js', array(), '1.0.5' );
    468468        $scripts->add( 'jshint', '/wp-includes/js/codemirror/jshint.js', array(), '2.9.5' );
     
    470470        $scripts->add( 'htmlhint', '/wp-includes/js/codemirror/htmlhint.js', array(), '0.9.14-xwp' );
    471471        $scripts->add( 'htmlhint-kses', '/wp-includes/js/codemirror/htmlhint-kses.js', array( 'htmlhint' ) );
    472         $scripts->add( 'code-editor', "/wp-admin/js/code-editor$suffix.js", array( 'jquery', 'codemirror' ) );
     472        $scripts->add( 'code-editor', "/wp-admin/js/code-editor$suffix.js", array( 'jquery', 'wp-codemirror' ) );
    473473        $scripts->add( 'wp-theme-plugin-editor', "/wp-admin/js/theme-plugin-editor$suffix.js", array( 'code-editor', 'jquery', 'jquery-ui-core', 'wp-a11y', 'underscore' ) );
    474474        did_action( 'init' ) && $scripts->add_inline_script( 'wp-theme-plugin-editor', sprintf( 'wp.themePluginEditor.l10n = %s;', wp_json_encode( wp_array_slice_assoc(
     
    953953        $styles->add( 'site-icon',           "/wp-admin/css/site-icon$suffix.css" );
    954954        $styles->add( 'l10n',                "/wp-admin/css/l10n$suffix.css" );
    955         $styles->add( 'code-editor',         "/wp-admin/css/code-editor$suffix.css", array( 'codemirror' ) );
     955        $styles->add( 'code-editor',         "/wp-admin/css/code-editor$suffix.css", array( 'wp-codemirror' ) );
    956956
    957957        $styles->add( 'wp-admin', false, array( 'dashicons', 'common', 'forms', 'admin-menu', 'dashboard', 'list-tables', 'edit', 'revisions', 'media', 'themes', 'about', 'nav-menus', 'widgets', 'site-icon', 'l10n' ) );
     
    988988        $styles->add( 'wp-mediaelement',     "/wp-includes/js/mediaelement/wp-mediaelement$suffix.css", array( 'mediaelement' ) );
    989989        $styles->add( 'thickbox',            '/wp-includes/js/thickbox/thickbox.css', array( 'dashicons' ) );
    990         $styles->add( 'codemirror',          '/wp-includes/js/codemirror/codemirror.min.css', array(), '5.29.1-alpha-ee20357' );
     990        $styles->add( 'wp-codemirror',       '/wp-includes/js/codemirror/codemirror.min.css', array(), '5.29.1-alpha-ee20357' );
    991991
    992992        // Deprecated CSS
  • trunk/src/wp-includes/widgets/class-wp-widget-custom-html.php

    r41376 r41558  
    161161                $settings = wp_enqueue_code_editor( array(
    162162                        'type' => 'text/html',
     163                        'codemirror' => array(
     164                                'indentUnit' => 2,
     165                                'tabSize' => 2,
     166                        ),
    163167                ) );
    164168
  • trunk/tests/phpunit/tests/customize/manager.php

    r41376 r41558  
    23522352                $this->assertNotEmpty( $data );
    23532353
    2354                 $this->assertEqualSets( array( 'theme', 'url', 'browser', 'panels', 'sections', 'nonce', 'autofocus', 'documentTitleTmpl', 'previewableDevices', 'customCss', 'changeset', 'timeouts' ), array_keys( $data ) );
     2354                $this->assertEqualSets( array( 'theme', 'url', 'browser', 'panels', 'sections', 'nonce', 'autofocus', 'documentTitleTmpl', 'previewableDevices', 'changeset', 'timeouts' ), array_keys( $data ) );
    23552355                $this->assertEquals( $autofocus, $data['autofocus'] );
    23562356                $this->assertArrayHasKey( 'save', $data['nonce'] );
Note: See TracChangeset for help on using the changeset viewer.