mirror of
https://github.com/gosticks/wordpress-develop.git
synced 2026-06-28 14:20:15 +00:00
Editor: Add CodeMirror-powered code editor with syntax highlighting, linting, and auto-completion.
* Code editor is integrated into the Theme/Plugin Editor, Additional CSS in Customizer, and Custom HTML widget. Code editor is not yet integrated into the post editor, and it may not be until accessibility concerns are addressed. * The CodeMirror component in the Custom HTML widget is integrated in a similar way to TinyMCE being integrated into the Text widget, adopting the same approach for integrating dynamic JavaScript-initialized fields. * Linting is performed for JS, CSS, HTML, and JSON via JSHint, CSSLint, HTMLHint, and JSONLint respectively. Linting is not yet supported for PHP. * When user lacks `unfiltered_html` the capability, the Custom HTML widget will report any Kses-invalid elements and attributes as errors via a custom Kses rule for HTMLHint. * When linting errors are detected, the user will be prevented from saving the code until the errors are fixed, reducing instances of broken websites. * The placeholder value is removed from Custom CSS in favor of a fleshed-out section description which now auto-expands when the CSS field is empty. See #39892. * The CodeMirror library is included as `wp.CodeMirror` to prevent conflicts with any existing `CodeMirror` global. * An `wp.codeEditor.initialize()` API in JS is provided to convert a `textarea` into CodeMirror, with a `wp_enqueue_code_editor()` function in PHP to manage enqueueing the assets and settings needed to edit a given type of code. * A user preference is added to manage whether or not "syntax highlighting" is enabled. The feature is opt-out, being enabled by default. * Allowed file extensions in the theme and plugin editors have been updated to include formats which CodeMirror has modes for: `conf`, `css`, `diff`, `patch`, `html`, `htm`, `http`, `js`, `json`, `jsx`, `less`, `md`, `php`, `phtml`, `php3`, `php4`, `php5`, `php7`, `phps`, `scss`, `sass`, `sh`, `bash`, `sql`, `svg`, `xml`, `yml`, `yaml`, `txt`. Props westonruter, georgestephanis, obenland, melchoyce, pixolin, mizejewski, michelleweber, afercia, grahamarmfield, samikeijonen, rianrietveld, iseulde. See #38707. Fixes #12423, #39892. git-svn-id: https://develop.svn.wordpress.org/trunk@41376 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
@@ -148,9 +148,8 @@ final class WP_Customize_Custom_CSS_Setting extends WP_Customize_Setting {
|
||||
* Checks for imbalanced braces, brackets, and comments.
|
||||
* Notifications are rendered when the customizer state is saved.
|
||||
*
|
||||
* @todo There are cases where valid CSS can be incorrectly marked as invalid when strings or comments include balancing characters. To fix, CSS tokenization needs to be used.
|
||||
*
|
||||
* @since 4.7.0
|
||||
* @since 4.9.0 Checking for balanced characters has been moved client-side via linting in code editor.
|
||||
*
|
||||
* @param string $css The input string.
|
||||
* @return true|WP_Error True if the input was validated, otherwise WP_Error.
|
||||
@@ -162,94 +161,6 @@ final class WP_Customize_Custom_CSS_Setting extends WP_Customize_Setting {
|
||||
$validity->add( 'illegal_markup', __( 'Markup is not allowed in CSS.' ) );
|
||||
}
|
||||
|
||||
$imbalanced = false;
|
||||
|
||||
// Make sure that there is a closing brace for each opening brace.
|
||||
if ( ! $this->validate_balanced_characters( '{', '}', $css ) ) {
|
||||
$validity->add( 'imbalanced_curly_brackets', sprintf(
|
||||
/* translators: 1: {}, 2: }, 3: { */
|
||||
__( 'Your curly brackets %1$s are imbalanced. Make sure there is a closing %2$s for every opening %3$s.' ),
|
||||
'<code>{}</code>',
|
||||
'<code>}</code>',
|
||||
'<code>{</code>'
|
||||
) );
|
||||
$imbalanced = true;
|
||||
}
|
||||
|
||||
// Ensure brackets are balanced.
|
||||
if ( ! $this->validate_balanced_characters( '[', ']', $css ) ) {
|
||||
$validity->add( 'imbalanced_braces', sprintf(
|
||||
/* translators: 1: [], 2: ], 3: [ */
|
||||
__( 'Your brackets %1$s are imbalanced. Make sure there is a closing %2$s for every opening %3$s.' ),
|
||||
'<code>[]</code>',
|
||||
'<code>]</code>',
|
||||
'<code>[</code>'
|
||||
) );
|
||||
$imbalanced = true;
|
||||
}
|
||||
|
||||
// Ensure parentheses are balanced.
|
||||
if ( ! $this->validate_balanced_characters( '(', ')', $css ) ) {
|
||||
$validity->add( 'imbalanced_parentheses', sprintf(
|
||||
/* translators: 1: (), 2: ), 3: ( */
|
||||
__( 'Your parentheses %1$s are imbalanced. Make sure there is a closing %2$s for every opening %3$s.' ),
|
||||
'<code>()</code>',
|
||||
'<code>)</code>',
|
||||
'<code>(</code>'
|
||||
) );
|
||||
$imbalanced = true;
|
||||
}
|
||||
|
||||
// Ensure double quotes are equal.
|
||||
if ( ! $this->validate_equal_characters( '"', $css ) ) {
|
||||
$validity->add( 'unequal_double_quotes', sprintf(
|
||||
/* translators: 1: " (double quote) */
|
||||
__( 'Your double quotes %1$s are uneven. Make sure there is a closing %1$s for every opening %1$s.' ),
|
||||
'<code>"</code>'
|
||||
) );
|
||||
$imbalanced = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Make sure any code comments are closed properly.
|
||||
*
|
||||
* The first check could miss stray an unpaired comment closing figure, so if
|
||||
* The number appears to be balanced, then check for equal numbers
|
||||
* of opening/closing comment figures.
|
||||
*
|
||||
* Although it may initially appear redundant, we use the first method
|
||||
* to give more specific feedback to the user.
|
||||
*/
|
||||
$unclosed_comment_count = $this->validate_count_unclosed_comments( $css );
|
||||
if ( 0 < $unclosed_comment_count ) {
|
||||
$validity->add( 'unclosed_comment', sprintf(
|
||||
/* translators: 1: number of unclosed comments, 2: */ */
|
||||
_n(
|
||||
'There is %1$s unclosed code comment. Close each comment with %2$s.',
|
||||
'There are %1$s unclosed code comments. Close each comment with %2$s.',
|
||||
$unclosed_comment_count
|
||||
),
|
||||
$unclosed_comment_count,
|
||||
'<code>*/</code>'
|
||||
) );
|
||||
$imbalanced = true;
|
||||
} elseif ( ! $this->validate_balanced_characters( '/*', '*/', $css ) ) {
|
||||
$validity->add( 'imbalanced_comments', sprintf(
|
||||
/* translators: 1: */, 2: /* */
|
||||
__( 'There is an extra %1$s, indicating an end to a comment. Be sure that there is an opening %2$s for every closing %1$s.' ),
|
||||
'<code>*/</code>',
|
||||
'<code>/*</code>'
|
||||
) );
|
||||
$imbalanced = true;
|
||||
}
|
||||
if ( $imbalanced && $this->is_possible_content_error( $css ) ) {
|
||||
$validity->add( 'possible_false_positive', sprintf(
|
||||
/* translators: %s: content: ""; */
|
||||
__( 'Imbalanced/unclosed character errors can be caused by %s declarations. You may need to remove this or add it to a custom CSS file.' ),
|
||||
'<code>content: "";</code>'
|
||||
) );
|
||||
}
|
||||
|
||||
if ( empty( $validity->errors ) ) {
|
||||
$validity = parent::validate( $css );
|
||||
}
|
||||
@@ -285,109 +196,4 @@ final class WP_Customize_Custom_CSS_Setting extends WP_Customize_Setting {
|
||||
|
||||
return $post_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure there are a balanced number of paired characters.
|
||||
*
|
||||
* This is used to check that the number of opening and closing
|
||||
* characters is equal.
|
||||
*
|
||||
* For instance, there should be an equal number of braces ("{", "}")
|
||||
* in the CSS.
|
||||
*
|
||||
* @since 4.7.0
|
||||
*
|
||||
* @param string $opening_char The opening character.
|
||||
* @param string $closing_char The closing character.
|
||||
* @param string $css The CSS input string.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function validate_balanced_characters( $opening_char, $closing_char, $css ) {
|
||||
return substr_count( $css, $opening_char ) === substr_count( $css, $closing_char );
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure there are an even number of paired characters.
|
||||
*
|
||||
* This is used to check that the number of a specific
|
||||
* character is even.
|
||||
*
|
||||
* For instance, there should be an even number of double quotes
|
||||
* in the CSS.
|
||||
*
|
||||
* @since 4.7.0
|
||||
*
|
||||
* @param string $char A character.
|
||||
* @param string $css The CSS input string.
|
||||
* @return bool Equality.
|
||||
*/
|
||||
private function validate_equal_characters( $char, $css ) {
|
||||
$char_count = substr_count( $css, $char );
|
||||
return ( 0 === $char_count % 2 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Count unclosed CSS Comments.
|
||||
*
|
||||
* Used during validation.
|
||||
*
|
||||
* @see self::validate()
|
||||
*
|
||||
* @since 4.7.0
|
||||
*
|
||||
* @param string $css The CSS input string.
|
||||
* @return int Count.
|
||||
*/
|
||||
private function validate_count_unclosed_comments( $css ) {
|
||||
$count = 0;
|
||||
$comments = explode( '/*', $css );
|
||||
|
||||
if ( ! is_array( $comments ) || ( 1 >= count( $comments ) ) ) {
|
||||
return $count;
|
||||
}
|
||||
|
||||
unset( $comments[0] ); // The first item is before the first comment.
|
||||
foreach ( $comments as $comment ) {
|
||||
if ( false === strpos( $comment, '*/' ) ) {
|
||||
$count++;
|
||||
}
|
||||
}
|
||||
return $count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find "content:" within a string.
|
||||
*
|
||||
* Imbalanced/Unclosed validation errors may be caused
|
||||
* when a character is used in a "content:" declaration.
|
||||
*
|
||||
* This function is used to detect if this is a possible
|
||||
* cause of the validation error, so that if it is,
|
||||
* a notification may be added to the Validation Errors.
|
||||
*
|
||||
* Example:
|
||||
* .element::before {
|
||||
* content: "(\"";
|
||||
* }
|
||||
* .element::after {
|
||||
* content: "\")";
|
||||
* }
|
||||
*
|
||||
* Using ! empty() because strpos() may return non-boolean values
|
||||
* that evaluate to false. This would be problematic when
|
||||
* using a strict "false === strpos()" comparison.
|
||||
*
|
||||
* @since 4.7.0
|
||||
*
|
||||
* @param string $css The CSS input string.
|
||||
* @return bool
|
||||
*/
|
||||
private function is_possible_content_error( $css ) {
|
||||
$found = preg_match( '/\bcontent\s*:/', $css );
|
||||
if ( ! empty( $found ) ) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user