Index: src/wp-includes/class.wp-scripts.php
===================================================================
--- src/wp-includes/class.wp-scripts.php (revision 36627)
+++ src/wp-includes/class.wp-scripts.php (working copy)
@@ -25,6 +25,7 @@
public $concat_version = '';
public $do_concat = false;
public $print_html = '';
+ public $print_html_before = '';
public $print_code = '';
public $ext_handles = '';
public $ext_version = '';
@@ -144,6 +145,17 @@
$cond_after = "\n";
}
+ $before_handle = $this->print_inline_script( $handle, 'before', false );
+ $after_handle = $this->print_inline_script( $handle, 'after', false );
+
+ if ( $before_handle ) {
+ $before_handle = sprintf( "\n", $before_handle );
+ }
+
+ if ( $after_handle ) {
+ $after_handle = sprintf( "\n", $after_handle );
+ }
+
if ( $this->do_concat ) {
/**
* Filter the script loader source.
@@ -154,7 +166,12 @@
* @param string $handle Script handle.
*/
$srce = apply_filters( 'script_loader_src', $src, $handle );
- if ( $this->in_default_dir( $srce ) && ! $conditional ) {
+
+ if ( $before_handle && ! $conditional ) {
+ $this->print_html_before .= $before_handle;
+ }
+
+ if ( $this->in_default_dir( $srce ) && ! $conditional && ! $after_handle ) {
$this->print_code .= $this->print_extra_script( $handle, false );
$this->concat .= "$handle,";
$this->concat_version .= "$handle$ver";
@@ -195,7 +212,7 @@
if ( ! $src )
return true;
- $tag = "{$cond_before}\n{$cond_after}";
+ $tag = "{$cond_before}{$before_handle}\n{$after_handle}{$cond_after}";
/**
* Filter the HTML script tag of an enqueued script.
@@ -209,7 +226,11 @@
$tag = apply_filters( 'script_loader_tag', $tag, $handle, $src );
if ( $this->do_concat ) {
- $this->print_html .= $tag;
+ if ( $after_handle ) {
+ $this->print_html_before .= $tag;
+ } else {
+ $this->print_html .= $tag;
+ }
} else {
echo $tag;
}
@@ -218,6 +239,61 @@
}
/**
+ * Add extra code to a registered script.
+ *
+ * @since 4.5.0
+ *
+ * @param string $handle Name of the script to add the inline script to. Must be lowercase.
+ * @param string $data String containing the javascript to be added.
+ * @param string $position Optional. Whether to add the inline script before the handle
+ * or after. Default 'after'.
+ *
+ * @return bool True on success, false on failure.
+ */
+ public function add_inline_script( $handle, $data, $position = 'after' ) {
+ if ( ! $data ) {
+ return false;
+ }
+
+ if ( 'after' !== $position ) {
+ $position = 'before';
+ }
+
+ $script = (array) $this->get_data( $handle, $position );
+ $script[] = $data;
+
+ return $this->add_data( $handle, $position, $script );
+ }
+
+ /**
+ * Print inline scripts registered for a specific handle.
+ *
+ * @since 4.5.0
+ *
+ * @param string $handle Name of the script to add the inline script to. Must be lowercase.
+ * @param string $position Optional. Whether to add the inline script before the handle
+ * or after. Default 'after'.
+ * @param bool $echo Optional. Whether to echo the script instead of just returning it.
+ * Default true.
+ * @return string|false Script on success, false otherwise.
+ */
+ public function print_inline_script( $handle, $position = 'after', $echo = true ) {
+ $output = $this->get_data( $handle, $position );
+
+ if ( empty( $output ) ) {
+ return false;
+ }
+
+ $output = trim( implode( "\n", $output ), "\n" );
+
+ if ( $echo ) {
+ printf( "\n", $output );
+ }
+
+ return $output;
+ }
+
+ /**
* Localizes a script, only if the script has already been added
*
* @param string $handle
@@ -339,6 +415,7 @@
$this->concat = '';
$this->concat_version = '';
$this->print_html = '';
+ $this->print_html_before = '';
$this->ext_version = '';
$this->ext_handles = '';
}
Index: src/wp-includes/functions.wp-scripts.php
===================================================================
--- src/wp-includes/functions.wp-scripts.php (revision 36627)
+++ src/wp-includes/functions.wp-scripts.php (working copy)
@@ -86,6 +86,36 @@
}
/**
+ * Add extra code to a registered script.
+ *
+ * Code will only be added if the script in already in the queue.
+ * Accepts a string $data containing the Code. If two or more code blocks
+ * are added to the same script $handle, they will be printed in the order
+ * they were added, i.e. the latter added code can redeclare the previous.
+ *
+ * @since 4.5.0
+ *
+ * @see WP_Scripts::add_inline_script()
+ *
+ * @param string $handle Name of the script to add the inline script to. Must be lowercase.
+ * @param string $data String containing the javascript to be added.
+ * @param string $position Optional. Whether to add the inline script before the handle
+ * or after. Default 'after'.
+ * @return bool True on success, false on failure.
+ */
+function wp_add_inline_script( $handle, $data, $position = 'after' ) {
+ _wp_scripts_maybe_doing_it_wrong( __FUNCTION__ );
+
+ if ( false !== stripos( $data, '' ) ) {
+ _doing_it_wrong( __FUNCTION__, __( 'Do not pass script tags to wp_add_inline_script().' ), '4.5.0' );
+ $data = trim( preg_replace( '##is', '$1', $data ) );
+ }
+
+ return wp_scripts()->add_inline_script( $handle, $data, $position );
+}
+
+
+/**
* Register a new script.
*
* Registers a script to be linked later using the wp_enqueue_script() function.
Index: src/wp-includes/script-loader.php
===================================================================
--- src/wp-includes/script-loader.php (revision 36627)
+++ src/wp-includes/script-loader.php (working copy)
@@ -992,6 +992,10 @@
echo "\n";
}
+ if ( ! empty( $wp_scripts->print_html_before ) ) {
+ echo $wp_scripts->print_html_before;
+ }
+
$concat = str_split( $concat, 128 );
$concat = 'load%5B%5D=' . implode( '&load%5B%5D=', $concat );
Index: tests/phpunit/tests/dependencies/scripts.php
===================================================================
--- tests/phpunit/tests/dependencies/scripts.php (revision 36627)
+++ tests/phpunit/tests/dependencies/scripts.php (working copy)
@@ -86,6 +86,28 @@
}
/**
+ * Test script concatenation.
+ */
+ public function test_script_concatenation() {
+ global $wp_scripts;
+
+ $wp_scripts->do_concat = true;
+ $wp_scripts->default_dirs = array( '/directory/' );
+
+ wp_enqueue_script( 'one', '/directory/script.js' );
+ wp_enqueue_script( 'two', '/directory/script.js' );
+ wp_enqueue_script( 'three', '/directory/script.js' );
+
+ wp_print_scripts();
+ $print_scripts = get_echo( '_print_scripts' );
+
+ $ver = get_bloginfo( 'version' );
+ $expected = "\n";
+
+ $this->assertEquals( $expected, $print_scripts );
+ }
+
+ /**
* Testing `wp_script_add_data` with the data key.
* @ticket 16024
*/
@@ -266,4 +288,178 @@
$this->assertEquals( $expected_header, $header );
$this->assertEquals( $expected_footer, $footer );
}
+
+ /**
+ * @ticket 14853
+ */
+ function test_wp_add_inline_script_returns_bool() {
+ $this->assertFalse( wp_add_inline_script( 'test-example', 'console.log("before");', 'before' ) );
+ wp_enqueue_script( 'test-example', 'example.com', array(), null );
+ $this->assertTrue( wp_add_inline_script( 'test-example', 'console.log("before");', 'before' ) );
+ }
+
+ /**
+ * @ticket 14853
+ */
+ function test_wp_add_inline_script_unknown_handle() {
+ $this->assertFalse( wp_add_inline_script( 'test-invalid', 'console.log("before");', 'before' ) );
+ $this->assertEquals( '', get_echo( 'wp_print_scripts' ) );
+ }
+
+ /**
+ * @ticket 14853
+ */
+ function test_wp_add_inline_script_before() {
+ wp_enqueue_script( 'test-example', 'example.com', array(), null );
+ wp_add_inline_script( 'test-example', 'console.log("before");', 'before' );
+
+ $expected = "\n";
+ $expected .= "\n";
+
+ $this->assertEquals( $expected, get_echo( 'wp_print_scripts' ) );
+ }
+
+ /**
+ * @ticket 14853
+ */
+ function test_wp_add_inline_script_after() {
+ wp_enqueue_script( 'test-example', 'example.com', array(), null );
+ wp_add_inline_script( 'test-example', 'console.log("after");' );
+
+ $expected = "\n";
+ $expected .= "\n";
+
+ $this->assertEquals( $expected, get_echo( 'wp_print_scripts' ) );
+ }
+
+ /**
+ * @ticket 14853
+ */
+ function test_wp_add_inline_script_before_and_after() {
+ wp_enqueue_script( 'test-example', 'example.com', array(), null );
+ wp_add_inline_script( 'test-example', 'console.log("before");', 'before' );
+ wp_add_inline_script( 'test-example', 'console.log("after");' );
+
+ $expected = "\n";
+ $expected .= "\n";
+ $expected .= "\n";
+
+ $this->assertEquals( $expected, get_echo( 'wp_print_scripts' ) );
+ }
+
+ /**
+ * @ticket 14853
+ */
+ function test_wp_add_inline_script_multiple() {
+ wp_enqueue_script( 'test-example', 'example.com', array(), null );
+ wp_add_inline_script( 'test-example', 'console.log("before");', 'before' );
+ wp_add_inline_script( 'test-example', 'console.log("before");', 'before' );
+ wp_add_inline_script( 'test-example', 'console.log("after");' );
+ wp_add_inline_script( 'test-example', 'console.log("after");' );
+
+ $expected = "\n";
+ $expected .= "\n";
+ $expected .= "\n";
+
+ $this->assertEquals( $expected, get_echo( 'wp_print_scripts' ) );
+ }
+
+ /**
+ * @ticket 14853
+ */
+ function test_wp_add_inline_script_localized_data_is_added_first() {
+ wp_enqueue_script( 'test-example', 'example.com', array(), null );
+ wp_localize_script( 'test-example', 'testExample', array( 'foo' => 'bar' ) );
+ wp_add_inline_script( 'test-example', 'console.log("before");', 'before' );
+ wp_add_inline_script( 'test-example', 'console.log("after");' );
+
+ $expected = "\n";
+ $expected .= "\n";
+ $expected .= "\n";
+ $expected .= "\n";
+
+ $this->assertEquals( $expected, get_echo( 'wp_print_scripts' ) );
+ }
+
+ /**
+ * @ticket 14853-2
+ */
+ public function test_wp_add_inline_script_before_with_concat() {
+ global $wp_scripts;
+
+ $wp_scripts->do_concat = true;
+ $wp_scripts->default_dirs = array( '/directory/' );
+
+ wp_enqueue_script( 'one', '/directory/script.js' );
+ wp_enqueue_script( 'two', '/directory/script.js' );
+ wp_enqueue_script( 'three', '/directory/script.js' );
+
+ wp_add_inline_script( 'two', 'console.log("before");', 'before' );
+
+ wp_print_scripts();
+ $print_scripts = get_echo( '_print_scripts' );
+
+ $ver = get_bloginfo( 'version' );
+ $expected = "\n";
+ $expected .= "\n";
+
+ $this->assertEquals( $expected, $print_scripts );
+ }
+
+ /**
+ * @ticket 14853
+ */
+ public function test_wp_add_inline_script_after_with_concat() {
+ global $wp_scripts;
+
+ $wp_scripts->do_concat = true;
+ $wp_scripts->default_dirs = array( '/directory/' );
+
+ wp_enqueue_script( 'one', '/directory/script.js' );
+ wp_enqueue_script( 'two', '/directory/script.js' );
+ wp_enqueue_script( 'three', '/directory/script.js' );
+
+ wp_add_inline_script( 'two', 'console.log("after");' );
+
+ wp_print_scripts();
+ $print_scripts = get_echo( '_print_scripts' );
+
+ $ver = get_bloginfo( 'version' );
+ $expected = "\n";
+ $expected .= "\n";
+ $expected .= "\n";
+
+ $this->assertEquals( $expected, $print_scripts );
+ }
+
+ /**
+ * @ticket 14853
+ */
+ public function test_wp_add_inline_script_concat_with_conditional() {
+ global $wp_scripts;
+
+ $wp_scripts->do_concat = true;
+ $wp_scripts->default_dirs = array('/wp-admin/js/', '/wp-includes/js/'); // Default dirs as in wp-includes/script-loader.php
+
+ $expected_localized = "\n";
+
+ $expected = "\n";
+
+ wp_enqueue_script( 'test-example', 'example.com', array(), null );
+ wp_localize_script( 'test-example', 'testExample', array( 'foo' => 'bar' ) );
+ wp_add_inline_script( 'test-example', 'console.log("before");', 'before' );
+ wp_add_inline_script( 'test-example', 'console.log("after");' );
+ wp_script_add_data( 'test-example', 'conditional', 'gte IE 9' );
+
+ $this->assertEquals( $expected_localized, get_echo( 'wp_print_scripts' ) );
+ $this->assertEquals( $expected, $wp_scripts->print_html_before );
+ $this->assertEquals( '', $wp_scripts->print_html );
+ }
+
}