Ticket #39941: 39941.4.diff
File 39941.4.diff, 13.4 KB (added by , 3 years ago) |
---|
-
src/wp-includes/functions.php
diff --git a/src/wp-includes/functions.php b/src/wp-includes/functions.php index e6c218d8ad..9ed5408d9a 100644
a b function is_php_version_compatible( $required ) { 7866 7866 function wp_fuzzy_number_match( $expected, $actual, $precision = 1 ) { 7867 7867 return abs( (float) $expected - (float) $actual ) <= $precision; 7868 7868 } 7869 7870 /** 7871 * Sanitizes an attributes array into an attributes string to be placed inside a `<script>` tag. 7872 * 7873 * Automatically injects type attribute if needed. 7874 * Used by {@see wp_get_script_tag()} and {@see wp_get_inline_script_tag()}. 7875 * 7876 * @since 5.7.0 7877 * 7878 * @param array $attributes Key-value pairs representing `<script>` tag attributes. 7879 * @return string String made of sanitized `<script>` tag attributes. 7880 */ 7881 function wp_sanitize_script_attributes( $attributes ) { 7882 $html5_script_support = ! is_admin() && ! current_theme_supports( 'html5', 'script' ); 7883 $attributes_string = ''; 7884 7885 // If HTML5 script tag is supported, only the attribute name is added 7886 // to $attributes_string for entries with a boolean value, and that are true. 7887 foreach ( $attributes as $attribute_name => $attribute_value ) { 7888 if ( is_bool( $attribute_value ) ) { 7889 if ( $attribute_value ) { 7890 $attributes_string .= $html5_script_support ? sprintf( ' %1$s="%2$s"', $attribute_name, esc_attr( $attribute_name ) ) : ' ' . $attribute_name; 7891 } 7892 } else { 7893 $attributes_string .= sprintf( ' %1$s="%2$s"', $attribute_name, esc_attr( $attribute_value ) ); 7894 } 7895 } 7896 7897 return $attributes_string; 7898 } 7899 7900 /** 7901 * Formats `<script>` loader tags. 7902 * 7903 * It is possible to inject attributes in the `<script>` tag via the {@see 'wp_script_attributes'} filter. 7904 * Automatically injects type attribute if needed. 7905 * 7906 * @since 5.7.0 7907 * 7908 * @param array $attributes Key-value pairs representing `<script>` tag attributes. 7909 * @return string String containing `<script>` opening and closing tags. 7910 */ 7911 function wp_get_script_tag( $attributes ) { 7912 if ( ! isset( $attributes['type'] ) && ! is_admin() && ! current_theme_supports( 'html5', 'script' ) ) { 7913 $attributes['type'] = 'text/javascript'; 7914 } 7915 /** 7916 * Filters attributes to be added to a script tag. 7917 * 7918 * @since 5.7.0 7919 * 7920 * @param array $attributes Key-value pairs representing `<script>` tag attributes. 7921 * Only the attribute name is added to the `<script>` tag for 7922 * entries with a boolean value, and that are true. 7923 */ 7924 $attributes = apply_filters( 'wp_script_attributes', $attributes ); 7925 7926 return sprintf( "<script%s></script>\n", wp_sanitize_script_attributes( $attributes ) ); 7927 } 7928 7929 /** 7930 * Prints formatted `<script>` loader tag. 7931 * 7932 * It is possible to inject attributes in the `<script>` tag via the {@see 'wp_script_attributes'} filter. 7933 * Automatically injects type attribute if needed. 7934 * 7935 * @since 5.7.0 7936 * 7937 * @param array $attributes Key-value pairs representing `<script>` tag attributes. 7938 */ 7939 function wp_print_script_tag( $attributes ) { 7940 echo wp_get_script_tag( $attributes ); 7941 } 7942 7943 /** 7944 * Wraps inline JavaScript in `<script>` tag. 7945 * 7946 * It is possible to inject attributes in the `<script>` tag via the {@see 'wp_script_attributes'} filter. 7947 * Automatically injects type attribute if needed. 7948 * 7949 * @since 5.7.0 7950 * 7951 * @param string $javascript Inline JavaScript code. 7952 * @param array $attributes Optional. Key-value pairs representing `<script>` tag attributes. 7953 * @return string String containing inline JavaScript code wrapped around `<script>` tag. 7954 */ 7955 function wp_get_inline_script_tag( $javascript, $attributes = array() ) { 7956 if ( ! isset( $attributes['type'] ) && ! is_admin() && ! current_theme_supports( 'html5', 'script' ) ) { 7957 $attributes['type'] = 'text/javascript'; 7958 } 7959 /** 7960 * Filters attributes to be added to a script tag. 7961 * 7962 * @since 5.7.0 7963 * 7964 * @param array $attributes Key-value pairs representing `<script>` tag attributes. 7965 * Only the attribute name is added to the `<script>` tag for 7966 * entries with a boolean value, and that are true. 7967 */ 7968 $attributes = apply_filters( 'wp_script_attributes', $attributes ); 7969 7970 $javascript = "\n" . trim( $javascript, "\n\r " ) . "\n"; 7971 7972 return sprintf( "<script%s>%s</script>\n", wp_sanitize_script_attributes( $attributes ), $javascript ); 7973 } 7974 7975 /** 7976 * Prints inline JavaScript wrapped in `<script>` tag. 7977 * 7978 * It is possible to inject attributes in the `<script>` tag via the {@see 'wp_script_attributes'} filter. 7979 * Automatically injects type attribute if needed. 7980 * 7981 * @since 5.7.0 7982 * 7983 * @param string $javascript Inline JavaScript code. 7984 * @param array $attributes Optional. Key-value pairs representing `<script>` tag attributes. 7985 */ 7986 function wp_print_inline_script_tag( $javascript, $attributes = array() ) { 7987 echo wp_get_inline_script_tag( $javascript, $attributes ); 7988 } -
new file tests/phpunit/tests/functions/wpInlineScriptTag.php
diff --git a/tests/phpunit/tests/functions/wpInlineScriptTag.php b/tests/phpunit/tests/functions/wpInlineScriptTag.php new file mode 100644 index 0000000000..d4ece1caa9
- + 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 public 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 public 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 public 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 public 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 a/tests/phpunit/tests/functions/wpSanitizeScriptAttributes.php b/tests/phpunit/tests/functions/wpSanitizeScriptAttributes.php new file mode 100644 index 0000000000..dd060ebd5d
- + 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"', 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( array() ) 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 } -
new file tests/phpunit/tests/functions/wpScriptTag.php
diff --git a/tests/phpunit/tests/functions/wpScriptTag.php b/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 }