diff --git a/.travis.yml b/.travis.yml index 65a2152..f6725de 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,63 +20,17 @@ addons: # Test against these versions of PHP. # Some additional PHP versions are also included in the matrix below. php: - - 5.4 - - 5.5 - - 5.6 - '7.0' - 7.1 - 7.2 - 7.3 - - nightly # Test against these versions of WordPress. env: - - WP_VERSION=4.7 # Plugin minimum version - - WP_VERSION=4.8 - - WP_VERSION=4.9 + - WP_VERSION=5.2 # Plugin minimum version + - WP_VERSION=5.3 + - WP_VERSION=5.4 - WP_VERSION=latest - - WP_VERSION=nightly - -# Some additional environments to test: -# * PHP 5.2 and 5.3 require precise not trusty -# * PHP_CodeSniffer -matrix: - include: - - php: 5.2 - dist: precise - env: WP_VERSION=4.7 - - php: 5.2 - dist: precise - env: WP_VERSION=4.8 - - php: 5.2 - dist: precise - env: WP_VERSION=latest - - php: 5.2 - dist: precise - env: WP_VERSION=nightly - - php: 5.3 - dist: precise - env: WP_VERSION=4.7 - - php: 5.3 - dist: precise - env: WP_VERSION=4.8 - - php: 5.3 - dist: precise - env: WP_VERSION=latest - - php: 5.3 - dist: precise - env: WP_VERSION=nightly - exclude: # WordPress 4.7 doesn't like running unit tests under PHP 7.x, see https://travis-ci.org/Viper007Bond/regenerate-thumbnails/builds/281022291 - - php: '7.0' - env: WP_VERSION=4.7 - - php: 7.1 - env: WP_VERSION=4.7 - - php: 7.2 - env: WP_VERSION=4.7 - - php: 7.3 - env: WP_VERSION=4.7 - - php: nightly - env: WP_VERSION=4.7 before_script: - | diff --git a/package.json b/package.json index ef6167e..412b365 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "preinstall": "npx npm-force-resolutions" }, "dependencies": { + "@wordpress/escape-html": "1.9.0", "cgb-scripts": "1.23.0", "npm-force-resolutions": "0.0.3" }, diff --git a/src/blocks.js b/src/blocks.js index 092e66e..50aff3f 100644 --- a/src/blocks.js +++ b/src/blocks.js @@ -16,6 +16,12 @@ import { } from '@wordpress/components'; import { PlainText, InspectorControls } from '@wordpress/editor'; +/** + * Internal dependencies + */ +import deprecated from './deprecated'; +import save from './save'; + registerBlockType( 'syntaxhighlighter/code', { title: __( 'SyntaxHighlighter Code', 'syntaxhighlighter' ), @@ -37,8 +43,8 @@ registerBlockType( 'syntaxhighlighter/code', { attributes: { content: { type: 'string', - source: 'text', - selector: 'pre', + source: 'text', + selector: 'code', }, language: { @@ -296,9 +302,6 @@ registerBlockType( 'syntaxhighlighter/code', { return [ blockSettings, editView ]; }, - save( { attributes } ) { - const { content } = attributes; - - return(
{ content }
); - }, + save, + deprecated, } ); diff --git a/src/deprecated.js b/src/deprecated.js new file mode 100644 index 0000000..0f50912 --- /dev/null +++ b/src/deprecated.js @@ -0,0 +1,49 @@ +export default [ + { + attributes: { + content: { + type: 'string', + source: 'text', + selector: 'pre', + }, + + language: { + type: 'string', + default: syntaxHighlighterData.settings.language.default, + }, + + lineNumbers: { + type: 'boolean', + default: syntaxHighlighterData.settings.lineNumbers.default, + }, + + firstLineNumber: { + type: 'string', + default: syntaxHighlighterData.settings.firstLineNumber.default, + }, + + highlightLines: { + type: 'string', + }, + + wrapLines: { + type: 'boolean', + default: syntaxHighlighterData.settings.wrapLines.default, + }, + + makeURLsClickable: { + type: 'boolean', + default: syntaxHighlighterData.settings.makeURLsClickable.default, + }, + + quickCode: { + type: 'boolean', + default: syntaxHighlighterData.settings.quickCode.default, + }, + }, + + save( { attributes } ) { + return(
{ attributes.content }
); + }, + }, +]; diff --git a/src/save.js b/src/save.js new file mode 100644 index 0000000..06ee8a2 --- /dev/null +++ b/src/save.js @@ -0,0 +1,12 @@ +/** + * Internal dependencies + */ +import { escape } from './utils'; + +export default function save( { attributes } ) { + return ( +
+			{ escape( attributes.content ) }
+		
+ ); +} diff --git a/src/utils.js b/src/utils.js new file mode 100644 index 0000000..30609b1 --- /dev/null +++ b/src/utils.js @@ -0,0 +1,61 @@ +/** + * External dependencies + */ +import { flow } from 'lodash'; + +/** + * WordPress dependencies + */ +import { escapeEditableHTML } from '@wordpress/escape-html'; + +/** + * Escapes ampersands, shortcodes, and links. + * + * @param {string} content The content of a code block. + * @return {string} The given content with some characters escaped. + */ +export function escape( content ) { + return flow( + escapeEditableHTML, + escapeOpeningSquareBrackets, + escapeProtocolInIsolatedUrls + )( content || '' ); +} + +/** + * Returns the given content with all opening shortcode characters converted + * into their HTML entity counterpart (i.e. [ => [). For instance, a + * shortcode like [embed] becomes [embed] + * + * This function replicates the escaping of HTML tags, where a tag like + * becomes <strong>. + * + * @param {string} content The content of a code block. + * @return {string} The given content with its opening shortcode characters + * converted into their HTML entity counterpart + * (i.e. [ => [) + */ +function escapeOpeningSquareBrackets( content ) { + return content.replace( /\[/g, '[' ); +} + +/** + * Converts the first two forward slashes of any isolated URL into their HTML + * counterparts (i.e. // => //). For instance, https://youtube.com/watch?x + * becomes https://youtube.com/watch?x. + * + * An isolated URL is a URL that sits in its own line, surrounded only by spacing + * characters. + * + * See https://github.com/WordPress/wordpress-develop/blob/5.1.1/src/wp-includes/class-wp-embed.php#L403 + * + * @param {string} content The content of a code block. + * @return {string} The given content with its ampersands converted into + * their HTML entity counterpart (i.e. & => &) + */ +function escapeProtocolInIsolatedUrls( content ) { + return content.replace( + /^(\s*https?:)\/\/([^\s<>"]+\s*)$/m, + '$1//$2' + ); +} diff --git a/syntaxhighlighter.php b/syntaxhighlighter.php index c151bd7..ae61ab6 100644 --- a/syntaxhighlighter.php +++ b/syntaxhighlighter.php @@ -11,6 +11,9 @@ Text Domain: syntaxhighlighter License: GPL2 License URI: https://www.gnu.org/licenses/gpl-2.0.html +Requires at least: 5.2 +Tested up to: 5.4 +Requires PHP: 7.0 **************************************************************************/ @@ -524,10 +527,11 @@ public function render_block( $attributes, $content ) { } } - $code = preg_replace( '#
]+>([^<]+)?
#', '$1', $content ); + $code = preg_replace( '#
]+>([^<]+)?
#', '$1', $content ); // Undo escaping done by WordPress $code = str_replace( '<', '<', $code ); + $code = str_replace( '&', '&', $code ); return $this->shortcode_callback( $attributes, $code, 'code' ); }