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' );
}