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. Built from https://develop.svn.wordpress.org/trunk@41558 git-svn-id: http://core.svn.wordpress.org/trunk@41391 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
parent
43eb51d4a6
commit
f0b5c39bde
|
@ -1164,12 +1164,26 @@ p.customize-section-description {
|
|||
}
|
||||
|
||||
/**
|
||||
* Custom CSS Section
|
||||
* Code Editor Control and Custom CSS Section
|
||||
*
|
||||
* Modifications to the Section Container to make the textarea full-width and
|
||||
* full-height, if the control is the only control in the section.
|
||||
*/
|
||||
|
||||
.customize-control-code_editor textarea {
|
||||
width: 100%;
|
||||
font-family: Consolas, Monaco, monospace;
|
||||
font-size: 12px;
|
||||
padding: 6px 8px;
|
||||
-moz-tab-size: 2;
|
||||
-o-tab-size: 2;
|
||||
tab-size: 2;
|
||||
}
|
||||
.customize-control-code_editor textarea,
|
||||
.customize-control-code_editor .CodeMirror {
|
||||
height: 14em;
|
||||
}
|
||||
|
||||
#customize-controls .customize-section-description-container.section-meta.customize-info {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
@ -1180,13 +1194,7 @@ p.customize-section-description {
|
|||
|
||||
#customize-control-custom_css textarea {
|
||||
display: block;
|
||||
font-family: Consolas, Monaco, monospace;
|
||||
font-size: 12px;
|
||||
padding: 6px 8px;
|
||||
height: 500px;
|
||||
-moz-tab-size: 4;
|
||||
-o-tab-size: 4;
|
||||
tab-size: 4;
|
||||
}
|
||||
|
||||
.customize-section-description-container + #customize-control-custom_css:last-child textarea {
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1164,12 +1164,26 @@ p.customize-section-description {
|
|||
}
|
||||
|
||||
/**
|
||||
* Custom CSS Section
|
||||
* Code Editor Control and Custom CSS Section
|
||||
*
|
||||
* Modifications to the Section Container to make the textarea full-width and
|
||||
* full-height, if the control is the only control in the section.
|
||||
*/
|
||||
|
||||
.customize-control-code_editor textarea {
|
||||
width: 100%;
|
||||
font-family: Consolas, Monaco, monospace;
|
||||
font-size: 12px;
|
||||
padding: 6px 8px;
|
||||
-moz-tab-size: 2;
|
||||
-o-tab-size: 2;
|
||||
tab-size: 2;
|
||||
}
|
||||
.customize-control-code_editor textarea,
|
||||
.customize-control-code_editor .CodeMirror {
|
||||
height: 14em;
|
||||
}
|
||||
|
||||
#customize-controls .customize-section-description-container.section-meta.customize-info {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
@ -1180,13 +1194,7 @@ p.customize-section-description {
|
|||
|
||||
#customize-control-custom_css textarea {
|
||||
display: block;
|
||||
font-family: Consolas, Monaco, monospace;
|
||||
font-size: 12px;
|
||||
padding: 6px 8px;
|
||||
height: 500px;
|
||||
-moz-tab-size: 4;
|
||||
-o-tab-size: 4;
|
||||
tab-size: 4;
|
||||
}
|
||||
|
||||
.customize-section-description-container + #customize-control-custom_css:last-child textarea {
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -3677,6 +3677,250 @@
|
|||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Class wp.customize.CodeEditorControl
|
||||
*
|
||||
* @since 4.9.0
|
||||
*
|
||||
* @constructor
|
||||
* @augments wp.customize.Control
|
||||
* @augments wp.customize.Class
|
||||
*/
|
||||
api.CodeEditorControl = api.Control.extend({
|
||||
|
||||
/**
|
||||
* Initialize the editor when the containing section is ready and expanded.
|
||||
*
|
||||
* @since 4.9.0
|
||||
* @returns {void}
|
||||
*/
|
||||
ready: function() {
|
||||
var control = this;
|
||||
if ( ! control.section() ) {
|
||||
control.initEditor();
|
||||
return;
|
||||
}
|
||||
|
||||
// Wait to initialize editor until section is embedded and expanded.
|
||||
api.section( control.section(), function( section ) {
|
||||
section.deferred.embedded.done( function() {
|
||||
var onceExpanded;
|
||||
if ( section.expanded() ) {
|
||||
control.initEditor();
|
||||
} else {
|
||||
onceExpanded = function( isExpanded ) {
|
||||
if ( isExpanded ) {
|
||||
control.initEditor();
|
||||
section.expanded.unbind( onceExpanded );
|
||||
}
|
||||
};
|
||||
section.expanded.bind( onceExpanded );
|
||||
}
|
||||
} );
|
||||
} );
|
||||
},
|
||||
|
||||
/**
|
||||
* Initialize editor.
|
||||
*
|
||||
* @since 4.9.0
|
||||
* @returns {void}
|
||||
*/
|
||||
initEditor: function() {
|
||||
var control = this, element;
|
||||
|
||||
element = new api.Element( control.container.find( 'textarea' ) );
|
||||
control.elements.push( element );
|
||||
element.sync( control.setting );
|
||||
element.set( control.setting() );
|
||||
|
||||
if ( control.params.editor_settings ) {
|
||||
control.initSyntaxHighlightingEditor( control.params.editor_settings );
|
||||
} else {
|
||||
control.initPlainTextareaEditor();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Make sure editor gets focused when control is focused.
|
||||
*
|
||||
* @since 4.9.0
|
||||
* @param {Object} [params] - Focus params.
|
||||
* @param {Function} [params.completeCallback] - Function to call when expansion is complete.
|
||||
* @returns {void}
|
||||
*/
|
||||
focus: function( params ) {
|
||||
var control = this, extendedParams = _.extend( {}, params ), originalCompleteCallback;
|
||||
originalCompleteCallback = extendedParams.completeCallback;
|
||||
extendedParams.completeCallback = function() {
|
||||
if ( originalCompleteCallback ) {
|
||||
originalCompleteCallback();
|
||||
}
|
||||
if ( control.editor ) {
|
||||
control.editor.codemirror.focus();
|
||||
}
|
||||
};
|
||||
api.Control.prototype.focus.call( control, extendedParams );
|
||||
},
|
||||
|
||||
/**
|
||||
* Initialize syntax-highlighting editor.
|
||||
*
|
||||
* @since 4.9.0
|
||||
* @param {object} codeEditorSettings - Code editor settings.
|
||||
* @returns {void}
|
||||
*/
|
||||
initSyntaxHighlightingEditor: function( codeEditorSettings ) {
|
||||
var control = this, $textarea = control.container.find( 'textarea' ), settings, suspendEditorUpdate = false;
|
||||
|
||||
settings = _.extend( {}, codeEditorSettings, {
|
||||
onTabNext: _.bind( control.onTabNext, control ),
|
||||
onTabPrevious: _.bind( control.onTabPrevious, control ),
|
||||
onUpdateErrorNotice: _.bind( control.onUpdateErrorNotice, control )
|
||||
});
|
||||
|
||||
control.editor = wp.codeEditor.initialize( $textarea, settings );
|
||||
|
||||
// Refresh when receiving focus.
|
||||
control.editor.codemirror.on( 'focus', function( codemirror ) {
|
||||
codemirror.refresh();
|
||||
});
|
||||
|
||||
/*
|
||||
* When the CodeMirror instance changes, mirror to the textarea,
|
||||
* where we have our "true" change event handler bound.
|
||||
*/
|
||||
control.editor.codemirror.on( 'change', function( codemirror ) {
|
||||
suspendEditorUpdate = true;
|
||||
$textarea.val( codemirror.getValue() ).trigger( 'change' );
|
||||
suspendEditorUpdate = false;
|
||||
});
|
||||
|
||||
// Update CodeMirror when the setting is changed by another plugin.
|
||||
control.setting.bind( function( value ) {
|
||||
if ( ! suspendEditorUpdate ) {
|
||||
control.editor.codemirror.setValue( value );
|
||||
}
|
||||
});
|
||||
|
||||
// Prevent collapsing section when hitting Esc to tab out of editor.
|
||||
control.editor.codemirror.on( 'keydown', function onKeydown( codemirror, event ) {
|
||||
var escKeyCode = 27;
|
||||
if ( escKeyCode === event.keyCode ) {
|
||||
event.stopPropagation();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Handle tabbing to the field after the editor.
|
||||
*
|
||||
* @since 4.9.0
|
||||
* @returns {void}
|
||||
*/
|
||||
onTabNext: function onTabNext() {
|
||||
var control = this, controls, controlIndex, section;
|
||||
section = api.section( control.section() );
|
||||
controls = section.controls();
|
||||
controlIndex = controls.indexOf( control );
|
||||
if ( controls.length === controlIndex + 1 ) {
|
||||
$( '#customize-footer-actions .collapse-sidebar' ).focus();
|
||||
} else {
|
||||
controls[ controlIndex + 1 ].container.find( ':focusable:first' ).focus();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Handle tabbing to the field before the editor.
|
||||
*
|
||||
* @since 4.9.0
|
||||
* @returns {void}
|
||||
*/
|
||||
onTabPrevious: function onTabPrevious() {
|
||||
var control = this, controls, controlIndex, section;
|
||||
section = api.section( control.section() );
|
||||
controls = section.controls();
|
||||
controlIndex = controls.indexOf( control );
|
||||
if ( 0 === controlIndex ) {
|
||||
section.contentContainer.find( '.customize-section-title .customize-help-toggle, .customize-section-title .customize-section-description.open .section-description-close' ).last().focus();
|
||||
} else {
|
||||
controls[ controlIndex - 1 ].contentContainer.find( ':focusable:first' ).focus();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Update error notice.
|
||||
*
|
||||
* @since 4.9.0
|
||||
* @param {Array} errorAnnotations - Error annotations.
|
||||
* @returns {void}
|
||||
*/
|
||||
onUpdateErrorNotice: function onUpdateErrorNotice( errorAnnotations ) {
|
||||
var control = this, message;
|
||||
control.setting.notifications.remove( 'csslint_error' );
|
||||
|
||||
if ( 0 !== errorAnnotations.length ) {
|
||||
if ( 1 === errorAnnotations.length ) {
|
||||
message = api.l10n.customCssError.singular.replace( '%d', '1' );
|
||||
} else {
|
||||
message = api.l10n.customCssError.plural.replace( '%d', String( errorAnnotations.length ) );
|
||||
}
|
||||
control.setting.notifications.add( 'csslint_error', new api.Notification( 'csslint_error', {
|
||||
message: message,
|
||||
type: 'error'
|
||||
} ) );
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Initialize plain-textarea editor when syntax highlighting is disabled.
|
||||
*
|
||||
* @since 4.9.0
|
||||
* @returns {void}
|
||||
*/
|
||||
initPlainTextareaEditor: function() {
|
||||
var control = this, $textarea = control.container.find( 'textarea' ), textarea = $textarea[0];
|
||||
|
||||
$textarea.on( 'blur', function onBlur() {
|
||||
$textarea.data( 'next-tab-blurs', false );
|
||||
} );
|
||||
|
||||
$textarea.on( 'keydown', function onKeydown( event ) {
|
||||
var selectionStart, selectionEnd, value, tabKeyCode = 9, escKeyCode = 27;
|
||||
|
||||
if ( escKeyCode === event.keyCode ) {
|
||||
if ( ! $textarea.data( 'next-tab-blurs' ) ) {
|
||||
$textarea.data( 'next-tab-blurs', true );
|
||||
event.stopPropagation(); // Prevent collapsing the section.
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Short-circuit if tab key is not being pressed or if a modifier key *is* being pressed.
|
||||
if ( tabKeyCode !== event.keyCode || event.ctrlKey || event.altKey || event.shiftKey ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Prevent capturing Tab characters if Esc was pressed.
|
||||
if ( $textarea.data( 'next-tab-blurs' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
selectionStart = textarea.selectionStart;
|
||||
selectionEnd = textarea.selectionEnd;
|
||||
value = textarea.value;
|
||||
|
||||
if ( selectionStart >= 0 ) {
|
||||
textarea.value = value.substring( 0, selectionStart ).concat( '\t', value.substring( selectionEnd ) );
|
||||
$textarea.selectionStart = textarea.selectionEnd = selectionStart + 1;
|
||||
}
|
||||
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Change objects contained within the main customize object to Settings.
|
||||
api.defaultConstructor = api.Setting;
|
||||
|
||||
|
@ -4372,7 +4616,8 @@
|
|||
header: api.HeaderControl,
|
||||
background: api.BackgroundControl,
|
||||
background_position: api.BackgroundPositionControl,
|
||||
theme: api.ThemeControl
|
||||
theme: api.ThemeControl,
|
||||
code_editor: api.CodeEditorControl
|
||||
};
|
||||
api.panelConstructor = {};
|
||||
api.sectionConstructor = {
|
||||
|
@ -5712,7 +5957,7 @@
|
|||
|
||||
// Add code editor for Custom CSS.
|
||||
(function() {
|
||||
var ready, sectionReady = $.Deferred(), controlReady = $.Deferred();
|
||||
var sectionReady = $.Deferred();
|
||||
|
||||
api.section( 'custom_css', function( section ) {
|
||||
section.deferred.embedded.done( function() {
|
||||
|
@ -5727,16 +5972,10 @@
|
|||
}
|
||||
});
|
||||
});
|
||||
api.control( 'custom_css', function( control ) {
|
||||
control.deferred.embedded.done( function() {
|
||||
controlReady.resolve( control );
|
||||
});
|
||||
});
|
||||
|
||||
ready = $.when( sectionReady, controlReady );
|
||||
|
||||
// Set up the section desription behaviors.
|
||||
ready.done( function setupSectionDescription( section, control ) {
|
||||
sectionReady.done( function setupSectionDescription( section ) {
|
||||
var control = api.control( 'custom_css' );
|
||||
|
||||
// Close the section description when clicking the close button.
|
||||
section.container.find( '.section-description-buttons .section-description-close' ).on( 'click', function() {
|
||||
|
@ -5747,174 +5986,13 @@
|
|||
});
|
||||
|
||||
// Reveal help text if setting is empty.
|
||||
if ( ! control.setting.get() ) {
|
||||
if ( control && ! control.setting.get() ) {
|
||||
section.container.find( '.section-meta .customize-section-description:first' )
|
||||
.addClass( 'open' )
|
||||
.show()
|
||||
.attr( 'aria-expanded', 'true' );
|
||||
}
|
||||
});
|
||||
|
||||
// Set up the code editor itself.
|
||||
if ( api.settings.customCss && api.settings.customCss.codeEditor ) {
|
||||
|
||||
// Set up the syntax highlighting editor.
|
||||
ready.done( function setupSyntaxHighlightingEditor( section, control ) {
|
||||
var $textarea = control.container.find( 'textarea' ), settings, suspendEditorUpdate = false;
|
||||
|
||||
// Make sure editor gets focused when control is focused.
|
||||
control.focus = (function( originalFocus ) { // eslint-disable-line max-nested-callbacks
|
||||
return function( params ) { // eslint-disable-line max-nested-callbacks
|
||||
var extendedParams = _.extend( {}, params ), originalCompleteCallback;
|
||||
originalCompleteCallback = extendedParams.completeCallback;
|
||||
extendedParams.completeCallback = function() {
|
||||
if ( originalCompleteCallback ) {
|
||||
originalCompleteCallback();
|
||||
}
|
||||
if ( control.editor ) {
|
||||
control.editor.codemirror.focus();
|
||||
}
|
||||
};
|
||||
originalFocus.call( this, extendedParams );
|
||||
};
|
||||
})( control.focus );
|
||||
|
||||
settings = _.extend( {}, api.settings.customCss.codeEditor, {
|
||||
|
||||
/**
|
||||
* Handle tabbing to the field after the editor.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
onTabNext: function onTabNext() {
|
||||
var controls, controlIndex;
|
||||
controls = section.controls();
|
||||
controlIndex = controls.indexOf( control );
|
||||
if ( controls.length === controlIndex + 1 ) {
|
||||
$( '#customize-footer-actions .collapse-sidebar' ).focus();
|
||||
} else {
|
||||
controls[ controlIndex + 1 ].container.find( ':focusable:first' ).focus();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Handle tabbing to the field before the editor.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
onTabPrevious: function onTabPrevious() {
|
||||
var controls, controlIndex;
|
||||
controls = section.controls();
|
||||
controlIndex = controls.indexOf( control );
|
||||
if ( 0 === controlIndex ) {
|
||||
section.contentContainer.find( '.customize-section-title .customize-help-toggle, .customize-section-title .customize-section-description.open .section-description-close' ).last().focus();
|
||||
} else {
|
||||
controls[ controlIndex - 1 ].contentContainer.find( ':focusable:first' ).focus();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Update error notice.
|
||||
*
|
||||
* @param {Array} errorAnnotations - Error annotations.
|
||||
* @returns {void}
|
||||
*/
|
||||
onUpdateErrorNotice: function onUpdateErrorNotice( errorAnnotations ) {
|
||||
var message;
|
||||
control.setting.notifications.remove( 'csslint_error' );
|
||||
|
||||
if ( 0 !== errorAnnotations.length ) {
|
||||
if ( 1 === errorAnnotations.length ) {
|
||||
message = api.l10n.customCssError.singular.replace( '%d', '1' );
|
||||
} else {
|
||||
message = api.l10n.customCssError.plural.replace( '%d', String( errorAnnotations.length ) );
|
||||
}
|
||||
control.setting.notifications.add( 'csslint_error', new api.Notification( 'csslint_error', {
|
||||
message: message,
|
||||
type: 'error'
|
||||
} ) );
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
control.editor = wp.codeEditor.initialize( $textarea, settings );
|
||||
|
||||
// Refresh when receiving focus.
|
||||
control.editor.codemirror.on( 'focus', function( codemirror ) {
|
||||
codemirror.refresh();
|
||||
});
|
||||
|
||||
/*
|
||||
* When the CodeMirror instance changes, mirror to the textarea,
|
||||
* where we have our "true" change event handler bound.
|
||||
*/
|
||||
control.editor.codemirror.on( 'change', function( codemirror ) {
|
||||
suspendEditorUpdate = true;
|
||||
$textarea.val( codemirror.getValue() ).trigger( 'change' );
|
||||
suspendEditorUpdate = false;
|
||||
});
|
||||
|
||||
// Update CodeMirror when the setting is changed by another plugin.
|
||||
control.setting.bind( function( value ) {
|
||||
if ( ! suspendEditorUpdate ) {
|
||||
control.editor.codemirror.setValue( value );
|
||||
}
|
||||
});
|
||||
|
||||
// Prevent collapsing section when hitting Esc to tab out of editor.
|
||||
control.editor.codemirror.on( 'keydown', function onKeydown( codemirror, event ) {
|
||||
var escKeyCode = 27;
|
||||
if ( escKeyCode === event.keyCode ) {
|
||||
event.stopPropagation();
|
||||
}
|
||||
});
|
||||
});
|
||||
} else {
|
||||
|
||||
// Allow tabs to be entered in Custom CSS textarea.
|
||||
ready.done( function allowTabs( section, control ) {
|
||||
|
||||
var $textarea = control.container.find( 'textarea' ), textarea = $textarea[0];
|
||||
|
||||
$textarea.on( 'blur', function onBlur() {
|
||||
$textarea.data( 'next-tab-blurs', false );
|
||||
} );
|
||||
|
||||
$textarea.on( 'keydown', function onKeydown( event ) {
|
||||
var selectionStart, selectionEnd, value, tabKeyCode = 9, escKeyCode = 27;
|
||||
|
||||
if ( escKeyCode === event.keyCode ) {
|
||||
if ( ! $textarea.data( 'next-tab-blurs' ) ) {
|
||||
$textarea.data( 'next-tab-blurs', true );
|
||||
event.stopPropagation(); // Prevent collapsing the section.
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Short-circuit if tab key is not being pressed or if a modifier key *is* being pressed.
|
||||
if ( tabKeyCode !== event.keyCode || event.ctrlKey || event.altKey || event.shiftKey ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Prevent capturing Tab characters if Esc was pressed.
|
||||
if ( $textarea.data( 'next-tab-blurs' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
selectionStart = textarea.selectionStart;
|
||||
selectionEnd = textarea.selectionEnd;
|
||||
value = textarea.value;
|
||||
|
||||
if ( selectionStart >= 0 ) {
|
||||
textarea.value = value.substring( 0, selectionStart ).concat( '\t', value.substring( selectionEnd ) );
|
||||
$textarea.selectionStart = textarea.selectionEnd = selectionStart + 1;
|
||||
}
|
||||
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
});
|
||||
});
|
||||
}
|
||||
})();
|
||||
|
||||
// Toggle visibility of Header Video notice when active state change.
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -212,21 +212,6 @@ final class WP_Customize_Manager {
|
|||
*/
|
||||
private $_changeset_data;
|
||||
|
||||
/**
|
||||
* Code Editor Settings for Custom CSS.
|
||||
*
|
||||
* This variable contains the settings returned by `wp_enqueue_code_editor()` which are then later output
|
||||
* to the client in `WP_Customize_Manager::customize_pane_settings()`. A value of false means that the
|
||||
* Custom CSS section or control was removed, or that the Syntax Highlighting user pref was turned off.
|
||||
*
|
||||
* @see wp_enqueue_code_editor()
|
||||
* @see WP_Customize_Manager::enqueue_control_scripts()
|
||||
* @see WP_Customize_Manager::customize_pane_settings()
|
||||
* @since 4.9.0
|
||||
* @var array|false
|
||||
*/
|
||||
private $_custom_css_code_editor_settings = false;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
|
@ -291,6 +276,7 @@ final class WP_Customize_Manager {
|
|||
require_once( ABSPATH . WPINC . '/customize/class-wp-customize-site-icon-control.php' );
|
||||
require_once( ABSPATH . WPINC . '/customize/class-wp-customize-header-image-control.php' );
|
||||
require_once( ABSPATH . WPINC . '/customize/class-wp-customize-theme-control.php' );
|
||||
require_once( ABSPATH . WPINC . '/customize/class-wp-customize-code-editor-control.php' );
|
||||
require_once( ABSPATH . WPINC . '/customize/class-wp-widget-area-customize-control.php' );
|
||||
require_once( ABSPATH . WPINC . '/customize/class-wp-widget-form-customize-control.php' );
|
||||
require_once( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-control.php' );
|
||||
|
@ -3337,12 +3323,6 @@ final class WP_Customize_Manager {
|
|||
foreach ( $this->controls as $control ) {
|
||||
$control->enqueue();
|
||||
}
|
||||
|
||||
if ( $this->get_section( 'custom_css' ) && $this->get_control( 'custom_css' ) ) {
|
||||
$this->_custom_css_code_editor_settings = wp_enqueue_code_editor( array(
|
||||
'type' => 'text/css',
|
||||
) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -3600,9 +3580,6 @@ final class WP_Customize_Manager {
|
|||
'stylesheet' => $this->get_stylesheet(),
|
||||
'active' => $this->is_theme_active(),
|
||||
),
|
||||
'customCss' => array(
|
||||
'codeEditor' => $this->_custom_css_code_editor_settings,
|
||||
),
|
||||
'url' => array(
|
||||
'preview' => esc_url_raw( $this->get_preview_url() ),
|
||||
'parent' => esc_url_raw( admin_url() ),
|
||||
|
@ -3736,6 +3713,7 @@ final class WP_Customize_Manager {
|
|||
$this->register_control_type( 'WP_Customize_Cropped_Image_Control' );
|
||||
$this->register_control_type( 'WP_Customize_Site_Icon_Control' );
|
||||
$this->register_control_type( 'WP_Customize_Theme_Control' );
|
||||
$this->register_control_type( 'WP_Customize_Code_Editor_Control' );
|
||||
|
||||
/* Themes */
|
||||
|
||||
|
@ -4239,14 +4217,11 @@ final class WP_Customize_Manager {
|
|||
) );
|
||||
$this->add_setting( $custom_css_setting );
|
||||
|
||||
$this->add_control( 'custom_css', array(
|
||||
'type' => 'textarea',
|
||||
$this->add_control( new WP_Customize_Code_Editor_Control( $this, 'custom_css', array(
|
||||
'section' => 'custom_css',
|
||||
'settings' => array( 'default' => $custom_css_setting->id ),
|
||||
'input_attrs' => array(
|
||||
'class' => 'code', // Ensures contents displayed as LTR instead of RTL.
|
||||
),
|
||||
) );
|
||||
'code_type' => 'text/css',
|
||||
) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,104 @@
|
|||
<?php
|
||||
/**
|
||||
* Customize API: WP_Customize_Code_Editor_Control class
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Customize
|
||||
* @since 4.9.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Customize Code Editor Control class.
|
||||
*
|
||||
* @since 4.9.0
|
||||
*
|
||||
* @see WP_Customize_Control
|
||||
*/
|
||||
class WP_Customize_Code_Editor_Control extends WP_Customize_Control {
|
||||
|
||||
/**
|
||||
* Customize control type.
|
||||
*
|
||||
* @since 4.9.0
|
||||
* @var string
|
||||
*/
|
||||
public $type = 'code_editor';
|
||||
|
||||
/**
|
||||
* Type of code that is being edited.
|
||||
*
|
||||
* @since 4.9.0
|
||||
* @var string
|
||||
*/
|
||||
public $code_type = '';
|
||||
|
||||
/**
|
||||
* Code editor settings.
|
||||
*
|
||||
* @see wp_enqueue_code_editor()
|
||||
* @since 4.9.0
|
||||
* @var array|false
|
||||
*/
|
||||
public $editor_settings = array();
|
||||
|
||||
/**
|
||||
* Enqueue control related scripts/styles.
|
||||
*
|
||||
* @since 4.9.0
|
||||
*/
|
||||
public function enqueue() {
|
||||
$this->editor_settings = wp_enqueue_code_editor( array_merge(
|
||||
array(
|
||||
'type' => $this->code_type,
|
||||
'codemirror' => array(
|
||||
'indentUnit' => 2,
|
||||
'tabSize' => 2,
|
||||
),
|
||||
),
|
||||
$this->editor_settings
|
||||
) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh the parameters passed to the JavaScript via JSON.
|
||||
*
|
||||
* @since 4.9.0
|
||||
* @see WP_Customize_Control::json()
|
||||
*
|
||||
* @return array Array of parameters passed to the JavaScript.
|
||||
*/
|
||||
public function json() {
|
||||
$json = parent::json();
|
||||
$json['code_type'] = $this->code_type;
|
||||
$json['editor_settings'] = $this->editor_settings;
|
||||
return $json;
|
||||
}
|
||||
|
||||
/**
|
||||
* Don't render the control content from PHP, as it's rendered via JS on load.
|
||||
*
|
||||
* @since 4.9.0
|
||||
*/
|
||||
public function render_content() {}
|
||||
|
||||
/**
|
||||
* Render a JS template for control display.
|
||||
*
|
||||
* @since 4.9.0
|
||||
*/
|
||||
public function content_template() {
|
||||
?>
|
||||
<# var elementIdPrefix = 'el' + String( Math.random() ); #>
|
||||
<# if ( data.label ) { #>
|
||||
<label for="{{ elementIdPrefix }}_editor">
|
||||
<span class="customize-control-title">{{ data.label }}</span>
|
||||
</label>
|
||||
<# } #>
|
||||
<# if ( data.description ) { #>
|
||||
<span class="description customize-control-description">{{{ data.description }}}</span>
|
||||
<# } #>
|
||||
<div class="customize-control-notifications-container"></div>
|
||||
<textarea id="{{ elementIdPrefix }}_editor" class="code"></textarea>
|
||||
<?php
|
||||
}
|
||||
}
|
|
@ -3125,11 +3125,14 @@ function wp_enqueue_editor() {
|
|||
* @param array $args {
|
||||
* Args.
|
||||
*
|
||||
* @type string $type The MIME type of the file to be edited.
|
||||
* @type string $file Filename to be edited. Extension is used to sniff the type. Can be supplied as alternative to `$type` param.
|
||||
* @type array $settings Settings to merge on top of defaults which derive from `$type` or `$file` args.
|
||||
* @type WP_Theme $theme Theme being edited when on theme editor.
|
||||
* @type string $plugin Plugin being edited when on plugin editor.
|
||||
* @type string $type The MIME type of the file to be edited.
|
||||
* @type string $file Filename to be edited. Extension is used to sniff the type. Can be supplied as alternative to `$type` param.
|
||||
* @type WP_Theme $theme Theme being edited when on theme editor.
|
||||
* @type string $plugin Plugin being edited when on plugin editor.
|
||||
* @type array $codemirror Additional CodeMirror setting overrides.
|
||||
* @type array $csslint CSSLint rule overrides.
|
||||
* @type array $jshint JSHint rule overrides.
|
||||
* @type array $htmlhint JSHint rule overrides.
|
||||
* }
|
||||
* @returns array|false Settings for the enqueued code editor, or false if the editor was not enqueued .
|
||||
*/
|
||||
|
@ -3408,13 +3411,11 @@ function wp_enqueue_code_editor( $args ) {
|
|||
}
|
||||
|
||||
// Let settings supplied via args override any defaults.
|
||||
if ( isset( $args['settings'] ) ) {
|
||||
foreach ( $args['settings'] as $key => $value ) {
|
||||
$settings[ $key ] = array_merge(
|
||||
$settings[ $key ],
|
||||
$value
|
||||
);
|
||||
}
|
||||
foreach ( wp_array_slice_assoc( $args, array( 'codemirror', 'csslint', 'jshint', 'htmlhint' ) ) as $key => $value ) {
|
||||
$settings[ $key ] = array_merge(
|
||||
$settings[ $key ],
|
||||
$value
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -3428,11 +3429,14 @@ function wp_enqueue_code_editor( $args ) {
|
|||
* @param array $args {
|
||||
* Args passed when calling `wp_enqueue_code_editor()`.
|
||||
*
|
||||
* @type string $type The MIME type of the file to be edited.
|
||||
* @type string $file Filename being edited.
|
||||
* @type array $settings Settings to merge on top of defaults which derive from `$type` or `$file` args.
|
||||
* @type WP_Theme $theme Theme being edited when on theme editor.
|
||||
* @type string $plugin Plugin being edited when on plugin editor.
|
||||
* @type string $type The MIME type of the file to be edited.
|
||||
* @type string $file Filename being edited.
|
||||
* @type WP_Theme $theme Theme being edited when on theme editor.
|
||||
* @type string $plugin Plugin being edited when on plugin editor.
|
||||
* @type array $codemirror Additional CodeMirror setting overrides.
|
||||
* @type array $csslint CSSLint rule overrides.
|
||||
* @type array $jshint JSHint rule overrides.
|
||||
* @type array $htmlhint JSHint rule overrides.
|
||||
* }
|
||||
*/
|
||||
$settings = apply_filters( 'wp_code_editor_settings', $settings, $args );
|
||||
|
@ -3444,9 +3448,6 @@ function wp_enqueue_code_editor( $args ) {
|
|||
wp_enqueue_script( 'code-editor' );
|
||||
wp_enqueue_style( 'code-editor' );
|
||||
|
||||
wp_enqueue_script( 'codemirror' );
|
||||
wp_enqueue_style( 'codemirror' );
|
||||
|
||||
if ( isset( $settings['codemirror']['mode'] ) ) {
|
||||
$mode = $settings['codemirror']['mode'];
|
||||
if ( is_string( $mode ) ) {
|
||||
|
|
|
@ -463,13 +463,13 @@ function wp_default_scripts( &$scripts ) {
|
|||
apply_filters( 'mejs_settings', $mejs_settings )
|
||||
);
|
||||
|
||||
$scripts->add( 'codemirror', '/wp-includes/js/codemirror/codemirror.min.js', array(), '5.29.1-alpha-ee20357' );
|
||||
$scripts->add( 'wp-codemirror', '/wp-includes/js/codemirror/codemirror.min.js', array(), '5.29.1-alpha-ee20357' );
|
||||
$scripts->add( 'csslint', '/wp-includes/js/codemirror/csslint.js', array(), '1.0.5' );
|
||||
$scripts->add( 'jshint', '/wp-includes/js/codemirror/jshint.js', array(), '2.9.5' );
|
||||
$scripts->add( 'jsonlint', '/wp-includes/js/codemirror/jsonlint.js', array(), '1.6.2' );
|
||||
$scripts->add( 'htmlhint', '/wp-includes/js/codemirror/htmlhint.js', array(), '0.9.14-xwp' );
|
||||
$scripts->add( 'htmlhint-kses', '/wp-includes/js/codemirror/htmlhint-kses.js', array( 'htmlhint' ) );
|
||||
$scripts->add( 'code-editor', "/wp-admin/js/code-editor$suffix.js", array( 'jquery', 'codemirror' ) );
|
||||
$scripts->add( 'code-editor', "/wp-admin/js/code-editor$suffix.js", array( 'jquery', 'wp-codemirror' ) );
|
||||
$scripts->add( 'wp-theme-plugin-editor', "/wp-admin/js/theme-plugin-editor$suffix.js", array( 'code-editor', 'jquery', 'jquery-ui-core', 'wp-a11y', 'underscore' ) );
|
||||
did_action( 'init' ) && $scripts->add_inline_script( 'wp-theme-plugin-editor', sprintf( 'wp.themePluginEditor.l10n = %s;', wp_json_encode( wp_array_slice_assoc(
|
||||
/* translators: placeholder is error count */
|
||||
|
@ -952,7 +952,7 @@ function wp_default_styles( &$styles ) {
|
|||
$styles->add( 'widgets', "/wp-admin/css/widgets$suffix.css", array( 'wp-pointer' ) );
|
||||
$styles->add( 'site-icon', "/wp-admin/css/site-icon$suffix.css" );
|
||||
$styles->add( 'l10n', "/wp-admin/css/l10n$suffix.css" );
|
||||
$styles->add( 'code-editor', "/wp-admin/css/code-editor$suffix.css", array( 'codemirror' ) );
|
||||
$styles->add( 'code-editor', "/wp-admin/css/code-editor$suffix.css", array( 'wp-codemirror' ) );
|
||||
|
||||
$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' ) );
|
||||
|
||||
|
@ -987,7 +987,7 @@ function wp_default_styles( &$styles ) {
|
|||
$styles->add( 'mediaelement', "/wp-includes/js/mediaelement/mediaelementplayer-legacy.min.css", array(), '4.2.5-74e01a40' );
|
||||
$styles->add( 'wp-mediaelement', "/wp-includes/js/mediaelement/wp-mediaelement$suffix.css", array( 'mediaelement' ) );
|
||||
$styles->add( 'thickbox', '/wp-includes/js/thickbox/thickbox.css', array( 'dashicons' ) );
|
||||
$styles->add( 'codemirror', '/wp-includes/js/codemirror/codemirror.min.css', array(), '5.29.1-alpha-ee20357' );
|
||||
$styles->add( 'wp-codemirror', '/wp-includes/js/codemirror/codemirror.min.css', array(), '5.29.1-alpha-ee20357' );
|
||||
|
||||
// Deprecated CSS
|
||||
$styles->add( 'deprecated-media', "/wp-admin/css/deprecated-media$suffix.css" );
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
*
|
||||
* @global string $wp_version
|
||||
*/
|
||||
$wp_version = '4.9-alpha-41557';
|
||||
$wp_version = '4.9-alpha-41558';
|
||||
|
||||
/**
|
||||
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.
|
||||
|
|
|
@ -160,6 +160,10 @@ class WP_Widget_Custom_HTML extends WP_Widget {
|
|||
public function enqueue_admin_scripts() {
|
||||
$settings = wp_enqueue_code_editor( array(
|
||||
'type' => 'text/html',
|
||||
'codemirror' => array(
|
||||
'indentUnit' => 2,
|
||||
'tabSize' => 2,
|
||||
),
|
||||
) );
|
||||
|
||||
wp_enqueue_script( 'custom-html-widgets' );
|
||||
|
|
Loading…
Reference in New Issue