Make WordPress Core

Changeset 36633


Ignore:
Timestamp:
02/23/2016 04:43:41 PM (9 years ago)
Author:
swissspidy
Message:

Script Loader: Introduce wp_add_inline_script().

This new function can be used to add inline JavaScript before and after enqueued scripts, just like wp_add_inline_style() works for CSS.

Props atimmer, abiralneupane, ocean90, swissspidy.
Fixes #14853.

Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/class.wp-scripts.php

    r36550 r36633  
    2626    public $do_concat = false;
    2727    public $print_html = '';
     28    public $print_html_before = '';
    2829    public $print_code = '';
    2930    public $ext_handles = '';
     
    143144            $cond_before = "<!--[if {$conditional}]>\n";
    144145            $cond_after = "<![endif]-->\n";
     146        }
     147
     148        $before_handle = $this->print_inline_script( $handle, 'before', false );
     149        $after_handle = $this->print_inline_script( $handle, 'after', false );
     150
     151        if ( $before_handle ) {
     152            $before_handle = sprintf( "<script type='text/javascript'>\n%s\n</script>\n", $before_handle );
     153        }
     154
     155        if ( $after_handle ) {
     156            $after_handle = sprintf( "<script type='text/javascript'>\n%s\n</script>\n", $after_handle );
    145157        }
    146158
     
    155167             */
    156168            $srce = apply_filters( 'script_loader_src', $src, $handle );
    157             if ( $this->in_default_dir( $srce ) && ! $conditional ) {
     169
     170            if ( $before_handle && ! $conditional ) {
     171                $this->print_html_before .= $before_handle;
     172            }
     173
     174            if ( $this->in_default_dir( $srce ) && ! $conditional && ! $after_handle ) {
    158175                $this->print_code .= $this->print_extra_script( $handle, false );
    159176                $this->concat .= "$handle,";
     
    196213            return true;
    197214
    198         $tag = "{$cond_before}<script type='text/javascript' src='$src'></script>\n{$cond_after}";
     215        $tag = "{$cond_before}{$before_handle}<script type='text/javascript' src='$src'></script>\n{$after_handle}{$cond_after}";
    199216
    200217        /**
     
    210227
    211228        if ( $this->do_concat ) {
    212             $this->print_html .= $tag;
     229            if ( $after_handle ) {
     230                $this->print_html_before .= $tag;
     231            } else {
     232                $this->print_html .= $tag;
     233            }
    213234        } else {
    214235            echo $tag;
     
    216237
    217238        return true;
     239    }
     240
     241    /**
     242     * Add extra code to a registered script.
     243     *
     244     * @since 4.5.0
     245     *
     246     * @param string $handle   Name of the script to add the inline script to. Must be lowercase.
     247     * @param string $data     String containing the javascript to be added.
     248     * @param string $position Optional. Whether to add the inline script before the handle
     249     *                         or after. Default 'after'.
     250     *
     251     * @return bool True on success, false on failure.
     252     */
     253    public function add_inline_script( $handle, $data, $position = 'after' ) {
     254        if ( ! $data ) {
     255            return false;
     256        }
     257
     258        if ( 'after' !== $position ) {
     259            $position = 'before';
     260        }
     261
     262        $script   = (array) $this->get_data( $handle, $position );
     263        $script[] = $data;
     264
     265        return $this->add_data( $handle, $position, $script );
     266    }
     267
     268    /**
     269     * Print inline scripts registered for a specific handle.
     270     *
     271     * @since 4.5.0
     272     *
     273     * @param string $handle   Name of the script to add the inline script to. Must be lowercase.
     274     * @param string $position Optional. Whether to add the inline script before the handle
     275     *                         or after. Default 'after'.
     276     * @param bool $echo       Optional. Whether to echo the script instead of just returning it.
     277     *                         Default true.
     278     * @return string|false Script on success, false otherwise.
     279     */
     280    public function print_inline_script( $handle, $position = 'after', $echo = true ) {
     281        $output = $this->get_data( $handle, $position );
     282
     283        if ( empty( $output ) ) {
     284            return false;
     285        }
     286
     287        $output = trim( implode( "\n", $output ), "\n" );
     288
     289        if ( $echo ) {
     290            printf( "<script type='text/javascript'>\n%s\n</script>\n", $output );
     291        }
     292
     293        return $output;
    218294    }
    219295
     
    340416        $this->concat_version = '';
    341417        $this->print_html = '';
     418        $this->print_html_before = '';
    342419        $this->ext_version = '';
    343420        $this->ext_handles = '';
  • trunk/src/wp-includes/functions.wp-scripts.php

    r36074 r36633  
    8484
    8585    return wp_scripts()->do_items( $handles );
     86}
     87
     88/**
     89 * Add extra code to a registered script.
     90 *
     91 * Code will only be added if the script in already in the queue.
     92 * Accepts a string $data containing the Code. If two or more code blocks
     93 * are added to the same script $handle, they will be printed in the order
     94 * they were added, i.e. the latter added code can redeclare the previous.
     95 *
     96 * @since 4.5.0
     97 *
     98 * @see WP_Scripts::add_inline_script()
     99 *
     100 * @param string $handle   Name of the script to add the inline script to. Must be lowercase.
     101 * @param string $data     String containing the javascript to be added.
     102 * @param string $position Optional. Whether to add the inline script before the handle
     103 *                         or after. Default 'after'.
     104 * @return bool True on success, false on failure.
     105 */
     106function wp_add_inline_script( $handle, $data, $position = 'after' ) {
     107    _wp_scripts_maybe_doing_it_wrong( __FUNCTION__ );
     108
     109    if ( false !== stripos( $data, '</script>' ) ) {
     110        _doing_it_wrong( __FUNCTION__, __( 'Do not pass script tags to wp_add_inline_script().' ), '4.5.0' );
     111        $data = trim( preg_replace( '#<script[^>]*>(.*)</script>#is', '$1', $data ) );
     112    }
     113
     114    return wp_scripts()->add_inline_script( $handle, $data, $position );
    86115}
    87116
  • trunk/src/wp-includes/script-loader.php

    r36591 r36633  
    993993        }
    994994
     995        if ( ! empty( $wp_scripts->print_html_before ) ) {
     996            echo $wp_scripts->print_html_before;
     997        }
     998
    995999        $concat = str_split( $concat, 128 );
    9961000        $concat = 'load%5B%5D=' . implode( '&load%5B%5D=', $concat );
  • trunk/tests/phpunit/tests/dependencies/scripts.php

    r36604 r36633  
    8787
    8888    /**
     89     * Test script concatenation.
     90     */
     91    public function test_script_concatenation() {
     92        global $wp_scripts;
     93
     94        $wp_scripts->do_concat = true;
     95        $wp_scripts->default_dirs = array( '/directory/' );
     96
     97        wp_enqueue_script( 'one', '/directory/script.js' );
     98        wp_enqueue_script( 'two', '/directory/script.js' );
     99        wp_enqueue_script( 'three', '/directory/script.js' );
     100
     101        wp_print_scripts();
     102        $print_scripts = get_echo( '_print_scripts' );
     103
     104        $ver = get_bloginfo( 'version' );
     105        $expected = "<script type='text/javascript' src='/wp-admin/load-scripts.php?c=0&amp;load%5B%5D=one,two,three&amp;ver={$ver}'></script>\n";
     106
     107        $this->assertEquals( $expected, $print_scripts );
     108    }
     109
     110    /**
    89111     * Testing `wp_script_add_data` with the data key.
    90112     * @ticket 16024
     
    267289        $this->assertEquals( $expected_footer, $footer );
    268290    }
     291
     292    /**
     293     * @ticket 14853
     294     */
     295    function test_wp_add_inline_script_returns_bool() {
     296        $this->assertFalse( wp_add_inline_script( 'test-example', 'console.log("before");', 'before' ) );
     297        wp_enqueue_script( 'test-example', 'example.com', array(), null );
     298        $this->assertTrue( wp_add_inline_script( 'test-example', 'console.log("before");', 'before' ) );
     299    }
     300
     301    /**
     302     * @ticket 14853
     303     */
     304    function test_wp_add_inline_script_unknown_handle() {
     305        $this->assertFalse( wp_add_inline_script( 'test-invalid', 'console.log("before");', 'before' ) );
     306        $this->assertEquals( '', get_echo( 'wp_print_scripts' ) );
     307    }
     308
     309    /**
     310     * @ticket 14853
     311     */
     312    function test_wp_add_inline_script_before() {
     313        wp_enqueue_script( 'test-example', 'example.com', array(), null );
     314        wp_add_inline_script( 'test-example', 'console.log("before");', 'before' );
     315
     316        $expected  = "<script type='text/javascript'>\nconsole.log(\"before\");\n</script>\n";
     317        $expected .= "<script type='text/javascript' src='http://example.com'></script>\n";
     318
     319        $this->assertEquals( $expected, get_echo( 'wp_print_scripts' ) );
     320    }
     321
     322    /**
     323     * @ticket 14853
     324     */
     325    function test_wp_add_inline_script_after() {
     326        wp_enqueue_script( 'test-example', 'example.com', array(), null );
     327        wp_add_inline_script( 'test-example', 'console.log("after");' );
     328
     329        $expected  = "<script type='text/javascript' src='http://example.com'></script>\n";
     330        $expected .= "<script type='text/javascript'>\nconsole.log(\"after\");\n</script>\n";
     331
     332        $this->assertEquals( $expected, get_echo( 'wp_print_scripts' ) );
     333    }
     334
     335    /**
     336     * @ticket 14853
     337     */
     338    function test_wp_add_inline_script_before_and_after() {
     339        wp_enqueue_script( 'test-example', 'example.com', array(), null );
     340        wp_add_inline_script( 'test-example', 'console.log("before");', 'before' );
     341        wp_add_inline_script( 'test-example', 'console.log("after");' );
     342
     343        $expected  = "<script type='text/javascript'>\nconsole.log(\"before\");\n</script>\n";
     344        $expected .= "<script type='text/javascript' src='http://example.com'></script>\n";
     345        $expected .= "<script type='text/javascript'>\nconsole.log(\"after\");\n</script>\n";
     346
     347        $this->assertEquals( $expected, get_echo( 'wp_print_scripts' ) );
     348    }
     349
     350    /**
     351     * @ticket 14853
     352     */
     353    function test_wp_add_inline_script_multiple() {
     354        wp_enqueue_script( 'test-example', 'example.com', array(), null );
     355        wp_add_inline_script( 'test-example', 'console.log("before");', 'before' );
     356        wp_add_inline_script( 'test-example', 'console.log("before");', 'before' );
     357        wp_add_inline_script( 'test-example', 'console.log("after");' );
     358        wp_add_inline_script( 'test-example', 'console.log("after");' );
     359
     360        $expected  = "<script type='text/javascript'>\nconsole.log(\"before\");\nconsole.log(\"before\");\n</script>\n";
     361        $expected .= "<script type='text/javascript' src='http://example.com'></script>\n";
     362        $expected .= "<script type='text/javascript'>\nconsole.log(\"after\");\nconsole.log(\"after\");\n</script>\n";
     363
     364        $this->assertEquals( $expected, get_echo( 'wp_print_scripts' ) );
     365    }
     366
     367    /**
     368     * @ticket 14853
     369     */
     370    function test_wp_add_inline_script_localized_data_is_added_first() {
     371        wp_enqueue_script( 'test-example', 'example.com', array(), null );
     372        wp_localize_script( 'test-example', 'testExample', array( 'foo' => 'bar' ) );
     373        wp_add_inline_script( 'test-example', 'console.log("before");', 'before' );
     374        wp_add_inline_script( 'test-example', 'console.log("after");' );
     375
     376        $expected  = "<script type='text/javascript'>\n/* <![CDATA[ */\nvar testExample = {\"foo\":\"bar\"};\n/* ]]> */\n</script>\n";
     377        $expected .= "<script type='text/javascript'>\nconsole.log(\"before\");\n</script>\n";
     378        $expected .= "<script type='text/javascript' src='http://example.com'></script>\n";
     379        $expected .= "<script type='text/javascript'>\nconsole.log(\"after\");\n</script>\n";
     380
     381        $this->assertEquals( $expected, get_echo( 'wp_print_scripts' ) );
     382    }
     383
     384    /**
     385     * @ticket 14853-2
     386     */
     387    public function test_wp_add_inline_script_before_with_concat() {
     388        global $wp_scripts;
     389
     390        $wp_scripts->do_concat = true;
     391        $wp_scripts->default_dirs = array( '/directory/' );
     392
     393        wp_enqueue_script( 'one', '/directory/one.js' );
     394        wp_enqueue_script( 'two', '/directory/two.js' );
     395        wp_enqueue_script( 'three', '/directory/three.js' );
     396
     397        wp_add_inline_script( 'one', 'console.log("before one");', 'before' );
     398        wp_add_inline_script( 'two', 'console.log("before two");', 'before' );
     399
     400        wp_print_scripts();
     401        $print_scripts = get_echo( '_print_scripts' );
     402
     403        $ver = get_bloginfo( 'version' );
     404        $expected  = "<script type='text/javascript'>\nconsole.log(\"before one\");\n</script>\n";
     405        $expected .= "<script type='text/javascript'>\nconsole.log(\"before two\");\n</script>\n";
     406        $expected .= "<script type='text/javascript' src='/wp-admin/load-scripts.php?c=0&amp;load%5B%5D=one,two,three&amp;ver={$ver}'></script>\n";
     407
     408        $this->assertEquals( $expected, $print_scripts );
     409    }
     410
     411    /**
     412     * @ticket 14853
     413     */
     414    public function test_wp_add_inline_script_after_with_concat() {
     415        global $wp_scripts;
     416
     417        $wp_scripts->do_concat = true;
     418        $wp_scripts->default_dirs = array( '/directory/' );
     419
     420        wp_enqueue_script( 'one', '/directory/one.js' );
     421        wp_enqueue_script( 'two', '/directory/two.js' );
     422        wp_enqueue_script( 'three', '/directory/three.js' );
     423        wp_enqueue_script( 'four', '/directory/four.js' );
     424
     425        wp_add_inline_script( 'two', 'console.log("after two");' );
     426        wp_add_inline_script( 'three', 'console.log("after three");' );
     427
     428        wp_print_scripts();
     429        $print_scripts = get_echo( '_print_scripts' );
     430
     431        $ver = get_bloginfo( 'version' );
     432        $expected  = "<script type='text/javascript' src='/directory/two.js?ver={$ver}'></script>\n";
     433        $expected .= "<script type='text/javascript'>\nconsole.log(\"after two\");\n</script>\n";
     434        $expected .= "<script type='text/javascript' src='/directory/three.js?ver={$ver}'></script>\n";
     435        $expected .= "<script type='text/javascript'>\nconsole.log(\"after three\");\n</script>\n";
     436        $expected .= "<script type='text/javascript' src='/wp-admin/load-scripts.php?c=0&amp;load%5B%5D=one,four&amp;ver={$ver}'></script>\n";
     437
     438        $this->assertEquals( $expected, $print_scripts );
     439    }
     440
     441    /**
     442     * @ticket 14853
     443     */
     444    public function test_wp_add_inline_script_concat_with_conditional() {
     445        global $wp_scripts;
     446
     447        $wp_scripts->do_concat = true;
     448        $wp_scripts->default_dirs = array('/wp-admin/js/', '/wp-includes/js/'); // Default dirs as in wp-includes/script-loader.php
     449
     450        $expected_localized = "<!--[if gte IE 9]>\n";
     451        $expected_localized .= "<script type='text/javascript'>\n/* <![CDATA[ */\nvar testExample = {\"foo\":\"bar\"};\n/* ]]> */\n</script>\n";
     452        $expected_localized .= "<![endif]-->\n";
     453
     454        $expected  = "<!--[if gte IE 9]>\n";
     455        $expected .= "<script type='text/javascript'>\nconsole.log(\"before\");\n</script>\n";
     456        $expected .= "<script type='text/javascript' src='http://example.com'></script>\n";
     457        $expected .= "<script type='text/javascript'>\nconsole.log(\"after\");\n</script>\n";
     458        $expected .= "<![endif]-->\n";
     459
     460        wp_enqueue_script( 'test-example', 'example.com', array(), null );
     461        wp_localize_script( 'test-example', 'testExample', array( 'foo' => 'bar' ) );
     462        wp_add_inline_script( 'test-example', 'console.log("before");', 'before' );
     463        wp_add_inline_script( 'test-example', 'console.log("after");' );
     464        wp_script_add_data( 'test-example', 'conditional', 'gte IE 9' );
     465
     466        $this->assertEquals( $expected_localized, get_echo( 'wp_print_scripts' ) );
     467        $this->assertEquals( $expected, $wp_scripts->print_html_before );
     468        $this->assertEquals( '', $wp_scripts->print_html );
     469    }
     470
    269471}
Note: See TracChangeset for help on using the changeset viewer.