Ticket #39941: 39941.diff
| File 39941.diff, 13.5 KB (added by , 5 years ago) |
|---|
-
src/wp-includes/functions.php
diff --git src/wp-includes/functions.php src/wp-includes/functions.php index 7b5aeb8948..8ccbba3c39 100644
function is_php_version_compatible( $required ) { 7767 7767 function wp_fuzzy_number_match( $expected, $actual, $precision = 1 ) { 7768 7768 return abs( (float) $expected - (float) $actual ) <= $precision; 7769 7769 } 7770 7771 /** 7772 * Sanitizes an attributes array into an attributes string to be placed inside a `<script>` tag. 7773 * 7774 * Automatically injects type attribute if needed. 7775 * Used by {@see wp_get_script_tag()} and {@see wp_get_inline_script_tag()}. 7776 * 7777 * @since 5.6.0 7778 * 7779 * @param array $attributes Optional. Key-value pairs representing `<script>` tag attributes. 7780 * @return string String made of sanitized `<script>` tag attributes. 7781 */ 7782 function wp_sanitize_script_attributes( $attributes = array() ) { 7783 if ( ! isset( $attributes['type'] ) && ! is_admin() && ! current_theme_supports( 'html5', 'script' ) ) { 7784 $attributes['type'] = 'text/javascript'; 7785 } 7786 /** 7787 * Filters attributes to be added to a script tag. 7788 * 7789 * @since 5.6.0 7790 * 7791 * @param array $attributes Key-value pairs representing `<script>` tag attributes. 7792 * Only the attribute name is added to the `<script>` tag for 7793 * entries with a boolean value, and that are true. 7794 */ 7795 $attributes = apply_filters( 'wp_script_attributes', $attributes ); 7796 7797 $attributes_string = ''; 7798 // Only the attribute name is added to $attributes_string for entries with a boolean value, and that are true. 7799 foreach ( $attributes as $attribute_name => $attribute_value ) { 7800 if ( is_bool( $attribute_value ) ) { 7801 if ( $attribute_value ) { 7802 if ( ! is_admin() && ! current_theme_supports( 'html5', 'script' ) ) { 7803 $attributes_string .= sprintf( ' %1$s="%1$s"', $attribute_name ); 7804 } else { 7805 $attributes_string .= ' ' . $attribute_name; 7806 } 7807 } 7808 } else { 7809 $attributes_string .= sprintf( ' %s="%s"', $attribute_name, esc_attr( $attribute_value ) ); 7810 } 7811 } 7812 7813 return $attributes_string; 7814 } 7815 7816 /** 7817 * Formats `<script>` loader tags. 7818 * 7819 * It is possible to inject attributes in the `<script>` tag via the `wp_script_attributes` filter. 7820 * Automatically injects type attribute if needed. 7821 * 7822 * @since 5.6.0 7823 * 7824 * @param array $attributes Key-value pairs representing `<script>` tag attributes. 7825 * @return string String containing `<script>` opening and closing tags. 7826 */ 7827 function wp_get_script_tag( $attributes ) { 7828 return sprintf( "<script%s></script>\n", wp_sanitize_script_attributes( $attributes ) ); 7829 } 7830 7831 /** 7832 * Prints formatted `<script>` loader tags. 7833 * 7834 * It is possible to inject attributes in the `<script>` tag via the `wp_script_attributes` filter. 7835 * Automatically injects type attribute if needed. 7836 * 7837 * @since 5.6.0 7838 * 7839 * @param array $attributes Key-value pairs representing `<script>` tag attributes. 7840 * @return null Null value. 7841 */ 7842 function wp_print_script_tag( $attributes ) { 7843 echo wp_get_script_tag( $attributes ); 7844 } 7845 7846 /** 7847 * Wraps inline JavaScript in `<script>` tags. 7848 * 7849 * It is possible to inject attributes in the `<script>` tag via the `wp_script_attributes` filter. 7850 * Automatically injects type attribute if needed. 7851 * 7852 * @since 5.6.0 7853 * 7854 * @param string $javascript Inline JavaScript code. 7855 * @param array $attributes Optional. Key-value pairs representing `<script>` tag attributes. 7856 * @return string String containing inline JavaScript code wrapped around `<script>` tags. 7857 */ 7858 function wp_get_inline_script_tag( $javascript, $attributes = array() ) { 7859 $javascript = "\n" . trim( $javascript, "\n\r " ) . "\n"; 7860 7861 return sprintf( "<script%s>%s</script>\n", wp_sanitize_script_attributes( $attributes ), $javascript ); 7862 } 7863 7864 /** 7865 * Prints inline JavaScript wrapped in `<script>` tags. 7866 * 7867 * It is possible to inject attributes in the `<script>` tag via the `wp_script_attributes` filter. 7868 * Automatically injects type attribute if needed. 7869 * 7870 * @since 5.6.0 7871 * 7872 * @param string $javascript Inline JavaScript code. 7873 * @param array $attributes Optional. Key-value pairs representing `<script>` tag attributes. 7874 * @return null Null value. 7875 */ 7876 function wp_print_inline_script_tag( $javascript, $attributes = array() ) { 7877 echo wp_get_inline_script_tag( $javascript, $attributes ); 7878 } -
new file tests/phpunit/tests/functions/wpInlineScriptTag.php
diff --git tests/phpunit/tests/functions/wpInlineScriptTag.php tests/phpunit/tests/functions/wpInlineScriptTag.php new file mode 100644 index 0000000000..3cfd9d1af0
- + 1 <?php 2 3 /** 4 * Test wp_get_inline_script_tag() and wp_print_inline_script_tag(). 5 * 6 * @group functions.php 7 */ 8 class Tests_Functions_wpInlineScriptTag extends WP_UnitTestCase { 9 10 private $event_handler = <<<'JS' 11 document.addEventListener( 'DOMContentLoaded', function () { 12 document.getElementById( 'elementID' ) 13 .addEventListener( 'click', function( event ) { 14 event.preventDefault(); 15 }); 16 }); 17 JS; 18 19 function get_inline_script_tag_type_set() { 20 add_theme_support( 'html5', array( 'script' ) ); 21 22 $this->assertSame( 23 '<script type="application/javascript" nomodule>' . "\n{$this->event_handler}\n</script>\n", 24 wp_get_inline_script_tag( 25 $this->event_handler, 26 array( 27 'type' => 'application/javascript', 28 'async' => false, 29 'nomodule' => true, 30 ) 31 ) 32 ); 33 34 remove_theme_support( 'html5' ); 35 36 $this->assertSame( 37 '<script type="application/javascript" nomodule>' . "\n{$this->event_handler}\n</script>\n", 38 wp_get_inline_script_tag( 39 $this->event_handler, 40 array( 41 'type' => 'application/javascript', 42 'async' => false, 43 'nomodule' => true, 44 ) 45 ) 46 ); 47 } 48 49 function test_get_inline_script_tag_type_not_set() { 50 add_theme_support( 'html5', array( 'script' ) ); 51 52 $this->assertSame( 53 "<script nomodule>\n{$this->event_handler}\n</script>\n", 54 wp_get_inline_script_tag( 55 $this->event_handler, 56 array( 57 'async' => false, 58 'nomodule' => true, 59 ) 60 ) 61 ); 62 63 remove_theme_support( 'html5' ); 64 } 65 66 function test_get_inline_script_tag_unescaped_src() { 67 add_theme_support( 'html5', array( 'script' ) ); 68 69 $this->assertSame( 70 "<script>\n{$this->event_handler}\n</script>\n", 71 wp_get_inline_script_tag( $this->event_handler ) 72 ); 73 74 remove_theme_support( 'html5' ); 75 } 76 77 function test_print_script_tag_prints_get_inline_script_tag() { 78 add_filter( 79 'wp_script_attributes', 80 function ( $attributes ) { 81 if ( isset( $attributes['id'] ) && 'utils-js-extra' === $attributes['id'] ) { 82 $attributes['async'] = true; 83 } 84 return $attributes; 85 } 86 ); 87 88 add_theme_support( 'html5', array( 'script' ) ); 89 90 $attributes = array( 91 'id' => 'utils-js-before', 92 'nomodule' => true, 93 ); 94 95 $this->assertSame( 96 wp_get_inline_script_tag( $this->event_handler, $attributes ), 97 get_echo( 98 'wp_print_inline_script_tag', 99 array( 100 $this->event_handler, 101 $attributes, 102 ) 103 ) 104 ); 105 106 remove_theme_support( 'html5' ); 107 108 $this->assertSame( 109 wp_get_inline_script_tag( $this->event_handler, $attributes ), 110 get_echo( 111 'wp_print_inline_script_tag', 112 array( 113 $this->event_handler, 114 $attributes, 115 ) 116 ) 117 ); 118 } 119 } -
new file tests/phpunit/tests/functions/wpSanitizeScriptAttributes.php
diff --git tests/phpunit/tests/functions/wpSanitizeScriptAttributes.php tests/phpunit/tests/functions/wpSanitizeScriptAttributes.php new file mode 100644 index 0000000000..d6048f15b9
- + 1 <?php 2 3 /** 4 * Test wp_sanitize_script_attributes(). 5 * 6 * @group functions.php 7 */ 8 class Tests_Functions_wpSanitizeScriptAttributes extends WP_UnitTestCase { 9 10 function test_sanitize_script_attributes_type_set() { 11 add_theme_support( 'html5', array( 'script' ) ); 12 13 $this->assertSame( 14 ' type="application/javascript" src="https://DOMAIN.TLD/PATH/FILE.js" nomodule', 15 wp_sanitize_script_attributes( 16 array( 17 'type' => 'application/javascript', 18 'src' => 'https://DOMAIN.TLD/PATH/FILE.js', 19 'async' => false, 20 'nomodule' => true, 21 ) 22 ) 23 ); 24 25 remove_theme_support( 'html5' ); 26 27 $this->assertSame( 28 ' src="https://DOMAIN.TLD/PATH/FILE.js" type="application/javascript" nomodule="nomodule"', 29 wp_sanitize_script_attributes( 30 array( 31 'src' => 'https://DOMAIN.TLD/PATH/FILE.js', 32 'type' => 'application/javascript', 33 'async' => false, 34 'nomodule' => true, 35 ) 36 ) 37 ); 38 } 39 40 function test_sanitize_script_attributes_type_not_set() { 41 add_theme_support( 'html5', array( 'script' ) ); 42 43 $this->assertSame( 44 ' src="https://DOMAIN.TLD/PATH/FILE.js" nomodule', 45 wp_sanitize_script_attributes( 46 array( 47 'src' => 'https://DOMAIN.TLD/PATH/FILE.js', 48 'async' => false, 49 'nomodule' => true, 50 ) 51 ) 52 ); 53 54 remove_theme_support( 'html5' ); 55 56 $this->assertSame( 57 ' src="https://DOMAIN.TLD/PATH/FILE.js" nomodule="nomodule" type="text/javascript"', 58 wp_sanitize_script_attributes( 59 array( 60 'src' => 'https://DOMAIN.TLD/PATH/FILE.js', 61 'async' => false, 62 'nomodule' => true, 63 ) 64 ) 65 ); 66 } 67 68 69 function test_sanitize_script_attributes_no_attributes() { 70 add_theme_support( 'html5', array( 'script' ) ); 71 72 $this->assertSame( 73 '', 74 wp_sanitize_script_attributes() 75 ); 76 77 remove_theme_support( 'html5' ); 78 } 79 80 function test_sanitize_script_attributes_relative_src() { 81 add_theme_support( 'html5', array( 'script' ) ); 82 83 $this->assertSame( 84 ' src="PATH/FILE.js" nomodule', 85 wp_sanitize_script_attributes( 86 array( 87 'src' => 'PATH/FILE.js', 88 'async' => false, 89 'nomodule' => true, 90 ) 91 ) 92 ); 93 94 remove_theme_support( 'html5' ); 95 } 96 97 98 function test_sanitize_script_attributes_only_false_boolean_attributes() { 99 add_theme_support( 'html5', array( 'script' ) ); 100 101 $this->assertSame( 102 '', 103 wp_sanitize_script_attributes( 104 array( 105 'async' => false, 106 'nomodule' => false, 107 ) 108 ) 109 ); 110 111 remove_theme_support( 'html5' ); 112 } 113 114 function test_sanitize_script_attributes_only_true_boolean_attributes() { 115 add_theme_support( 'html5', array( 'script' ) ); 116 117 $this->assertSame( 118 ' async nomodule', 119 wp_sanitize_script_attributes( 120 array( 121 'async' => true, 122 'nomodule' => true, 123 ) 124 ) 125 ); 126 127 remove_theme_support( 'html5' ); 128 } 129 130 function test_sanitize_script_attributes_wp_script_attributes_filter() { 131 add_theme_support( 'html5', array( 'script' ) ); 132 133 add_filter( 134 'wp_script_attributes', 135 function( $attributes ) { 136 if ( isset( $attributes['id'] ) && 'utils-js-extra' === $attributes['id'] ) { 137 $attributes['async'] = true; 138 } 139 return $attributes; 140 } 141 ); 142 143 $this->assertSame( 144 ' src="https://DOMAIN.TLD/PATH/FILE.js" id="utils-js-extra" async nomodule', 145 wp_sanitize_script_attributes( 146 array( 147 'src' => 'https://DOMAIN.TLD/PATH/FILE.js', 148 'id' => 'utils-js-extra', 149 'async' => false, 150 'nomodule' => true, 151 ) 152 ) 153 ); 154 155 remove_theme_support( 'html5' ); 156 } 157 } -
new file tests/phpunit/tests/functions/wpScriptTag.php
diff --git tests/phpunit/tests/functions/wpScriptTag.php tests/phpunit/tests/functions/wpScriptTag.php new file mode 100644 index 0000000000..3c451f5359
- + 1 <?php 2 3 /** 4 * Test wp_get_script_tag() and wp_print_script_tag(). 5 * 6 * @group functions.php 7 */ 8 class Tests_Functions_wpScriptTag extends WP_UnitTestCase { 9 10 function get_script_tag_type_set() { 11 add_theme_support( 'html5', array( 'script' ) ); 12 13 $this->assertSame( 14 '<script src="https://localhost/PATH/FILE.js" type="application/javascript" nomodule></script>' . "\n", 15 wp_get_script_tag( 16 array( 17 'type' => 'application/javascript', 18 'src' => 'https://localhost/PATH/FILE.js', 19 'async' => false, 20 'nomodule' => true, 21 ) 22 ) 23 ); 24 25 remove_theme_support( 'html5' ); 26 27 $this->assertSame( 28 '<script src="https://localhost/PATH/FILE.js" type="application/javascript" nomodule></script>' . "\n", 29 wp_get_script_tag( 30 array( 31 'src' => 'https://localhost/PATH/FILE.js', 32 'type' => 'application/javascript', 33 'async' => false, 34 'nomodule' => true, 35 ) 36 ) 37 ); 38 } 39 40 function test_get_script_tag_type_not_set() { 41 add_theme_support( 'html5', array( 'script' ) ); 42 43 $this->assertSame( 44 '<script src="https://localhost/PATH/FILE.js" nomodule></script>' . "\n", 45 wp_get_script_tag( 46 array( 47 'src' => 'https://localhost/PATH/FILE.js', 48 'async' => false, 49 'nomodule' => true, 50 ) 51 ) 52 ); 53 54 remove_theme_support( 'html5' ); 55 } 56 57 function test_print_script_tag_prints_get_script_tag() { 58 add_filter( 59 'wp_script_attributes', 60 function ( $attributes ) { 61 if ( isset( $attributes['id'] ) && 'utils-js-extra' === $attributes['id'] ) { 62 $attributes['async'] = true; 63 } 64 return $attributes; 65 } 66 ); 67 68 add_theme_support( 'html5', array( 'script' ) ); 69 70 $attributes = array( 71 'src' => 'https://localhost/PATH/FILE.js', 72 'id' => 'utils-js-extra', 73 'nomodule' => true, 74 ); 75 76 $this->assertSame( 77 wp_get_script_tag( $attributes ), 78 get_echo( 79 'wp_print_script_tag', 80 array( $attributes ) 81 ) 82 ); 83 84 remove_theme_support( 'html5' ); 85 86 $this->assertSame( 87 wp_get_script_tag( $attributes ), 88 get_echo( 89 'wp_print_script_tag', 90 array( $attributes ) 91 ) 92 ); 93 } 94 }