Ticket #34092: 34092.4.diff
File 34092.4.diff, 15.6 KB (added by , 9 years ago) |
---|
-
src/wp-includes/formatting.php
218 218 219 219 $tagnames = array_keys( $shortcode_tags ); 220 220 $tagregexp = join( '|', array_map( 'preg_quote', $tagnames ) ); 221 $tagregexp = "(?:$tagregexp)(? ![\\w-])"; // Excerpt of get_shortcode_regex().221 $tagregexp = "(?:$tagregexp)(?=[\\s\\]\\/])"; // Excerpt of get_shortcode_regex(). 222 222 223 223 $comment_regex = 224 224 '!' // Start of comment, after the <. … … 742 742 . '(' // 1: The shortcode 743 743 . '\\[' // Opening bracket 744 744 . "($tagregexp)" // 2: Shortcode name 745 . '(? ![\\w-])' // Not followed by word character or hyphen745 . '(?=[\\s\\]\\/])' // Always followed by whitespace or end of tag. 746 746 // Unroll the loop: Inside the opening shortcode tag 747 747 . '[^\\]\\/]*' // Not a closing bracket or forward slash 748 748 . '(?:' -
src/wp-includes/js/shortcode.js
102 102 // 6. The closing tag. 103 103 // 7. An extra `]` to allow for escaping shortcodes with double `[[]]` 104 104 regexp: _.memoize( function( tag ) { 105 return new RegExp( '\\[(\\[?)(' + tag + ')(? ![\\w-])([^\\]\\/]*(?:\\/(?!\\])[^\\]\\/]*)*?)(?:(\\/)\\]|\\](?:([^\\[]*(?:\\[(?!\\/\\2\\])[^\\[]*)*)(\\[\\/\\2\\]))?)(\\]?)', 'g' );105 return new RegExp( '\\[(\\[?)(' + tag + ')(?=[\\s\\]\\/])([^\\]\\/]*(?:\\/(?!\\])[^\\]\\/]*)*?)(?:(\\/)\\]|\\](?:([^\\[]*(?:\\[(?!\\/\\2\\])[^\\[]*)*)(\\[\\/\\2\\]))?)(\\]?)', 'g' ); 106 106 }), 107 107 108 108 -
src/wp-includes/shortcodes.php
247 247 '\\[' // Opening bracket 248 248 . '(\\[?)' // 1: Optional second opening bracket for escaping shortcodes: [[tag]] 249 249 . "($tagregexp)" // 2: Shortcode name 250 . '(? ![\\w-])' // Not followed by word character or hyphen250 . '(?=[\\s\\]\\/])' // Always followed by whitespace or end of tag. 251 251 . '(' // 3: Unroll the loop: Inside the opening shortcode tag 252 252 . '[^\\]\\/]*' // Not a closing bracket or forward slash 253 253 . '(?:' … … 305 305 306 306 if ( isset( $m[5] ) ) { 307 307 // enclosing tag - extra parameter 308 return $m[1] . call_user_func( $shortcode_tags[$tag], $attr, $m[5], $tag ) . $m[6]; 308 if ( false === strpos( $m[5], "=]" ) ) { 309 $content = $m[5]; 310 } else { 311 $encl = shortcode_parse_enclosures( $m[5], $tag ); 312 $content = array_shift( $encl ); 313 if ( is_array( $attr ) ) { 314 $attr = array_merge( $attr, $encl ); 315 } else { 316 $attr = $encl; 317 } 318 } 309 319 } else { 310 320 // self-closing tag 311 return $m[1] . call_user_func( $shortcode_tags[$tag], $attr, null, $tag ) . $m[6];321 $content = null; 312 322 } 323 324 return $m[1] . call_user_func( $shortcode_tags[$tag], $attr, $content, $tag ) . $m[6]; 313 325 } 314 326 315 327 /** … … 478 490 } 479 491 480 492 /** 493 * Split up multiple enclosures into a list of attributes. 494 * 495 * @since 4.4.0 496 * 497 * @param string $input The enclosed content, including any attribute delimiters. 498 * @param string $tag The name of the parent shortcode. 499 * @return array List of attributes and their value, where the first item is the primary content. 500 */ 501 function shortcode_parse_enclosures( $input, $tag ) { 502 $tag = preg_quote( $tag ); 503 504 // Regex group arranged so that we split on the delimiters, but then only capture the name portion. :) 505 $textarr = preg_split( "/\[$tag:([^=]*)=\]/", $input, -1, PREG_SPLIT_DELIM_CAPTURE ); 506 507 // Check for multiple enclosures. 508 $c = count( $textarr ); 509 if ( 1 == $c ) { 510 return $textarr; 511 } 512 513 // List multiple enclosures, starting with the primary content. 514 $encl = array( $textarr[0] ); 515 for ( $i = 1; $i < $c; $i += 2 ) { 516 // Now $i is the name's index and $i+1 is the value's index. 517 if ( ! empty( $textarr[ $i ] ) ) { 518 $encl[ strtolower( $textarr[ $i ] ) ] = $textarr[ $i + 1 ]; 519 } else { 520 $encl[] = $textarr[ $i + 1 ]; 521 } 522 } 523 return $encl; 524 } 525 526 /** 481 527 * Combine user attributes with known attributes and fill in defaults when needed. 482 528 * 483 529 * The pairs should be considered to be all of the attributes which are -
tests/phpunit/tests/shortcode.php
25 25 parent::tearDown(); 26 26 } 27 27 28 // $this->atts and such are hooked up to [test-shortcode-tag] only and not the other tag names. There is no other magic going on here. 28 29 function _shortcode_test_shortcode_tag( $atts, $content = null, $tagname = null ) { 29 30 $this->atts = $atts; 30 31 $this->content = $content; … … 80 81 function test_noatts() { 81 82 do_shortcode('[test-shortcode-tag /]'); 82 83 $this->assertEquals( '', $this->atts ); 84 $this->assertEquals( '', $this->content ); 83 85 $this->assertEquals( 'test-shortcode-tag', $this->tagname ); 86 87 do_shortcode('[test-shortcode-tag]'); 88 $this->assertEquals( '', $this->atts ); 89 $this->assertEquals( '', $this->content ); 90 91 do_shortcode('[test-shortcode-tag]Some Content[/test-shortcode-tag]'); 92 $this->assertEquals( '', $this->atts ); 93 $this->assertEquals( 'Some Content', $this->content ); 94 95 do_shortcode('[test-shortcode-tag][/test-shortcode-tag]'); 96 $this->assertEquals( '', $this->atts ); 97 $this->assertEquals( '', $this->content ); 84 98 } 85 99 86 100 function test_one_att() { 87 101 do_shortcode('[test-shortcode-tag foo="asdf" /]'); 88 102 $this->assertEquals( array('foo' => 'asdf'), $this->atts ); 103 $this->assertEquals( '', $this->content ); 89 104 $this->assertEquals( 'test-shortcode-tag', $this->tagname ); 105 106 do_shortcode('[test-shortcode-tag foo=asdf]'); 107 $this->assertEquals( array('foo' => 'asdf'), $this->atts ); 108 $this->assertEquals( '', $this->content ); 109 110 do_shortcode("[test-shortcode-tag foo='asdf']"); 111 $this->assertEquals( array('foo' => 'asdf'), $this->atts ); 112 $this->assertEquals( '', $this->content ); 113 114 do_shortcode('[test-shortcode-tag]Some Content[test-shortcode-tag:foo=]asdf[/test-shortcode-tag]'); 115 $this->assertEquals( array('foo' => 'asdf'), $this->atts ); 116 $this->assertEquals( 'Some Content', $this->content ); 117 118 do_shortcode('[test-shortcode-tag][test-shortcode-tag:foo=]asdf[/test-shortcode-tag]'); 119 $this->assertEquals( array('foo' => 'asdf'), $this->atts ); 120 $this->assertEquals( '', $this->content ); 90 121 } 91 122 92 123 function test_not_a_tag() { … … 139 170 'foo--bar' => 'foo--bar', 140 171 ); 141 172 $this->assertEquals( $expected_attrs, $this->atts ); 173 $this->assertEquals( '', $this->content ); 174 175 do_shortcode('[test-shortcode-tag]Some Content[test-shortcode-tag:foo=]foo[test-shortcode-tag:foo-bar=]foo-bar[test-shortcode-tag:foo-bar-=]foo-bar-[test-shortcode-tag:-foo-bar=]-foo-bar[test-shortcode-tag:-foo-bar-=]-foo-bar-[test-shortcode-tag:foo-bar-baz=]foo-bar-baz[test-shortcode-tag:-foo-bar-baz=]-foo-bar-baz[test-shortcode-tag:foo--bar=]foo--bar[/test-shortcode-tag]'); 176 $this->assertEquals( $expected_attrs, $this->atts ); 177 $this->assertEquals( 'Some Content', $this->content ); 142 178 } 143 179 144 180 function test_two_atts() { 145 181 do_shortcode('[test-shortcode-tag foo="asdf" bar="bing" /]'); 146 182 $this->assertEquals( array('foo' => 'asdf', 'bar' => 'bing'), $this->atts ); 183 $this->assertEquals( '', $this->content ); 147 184 $this->assertEquals( 'test-shortcode-tag', $this->tagname ); 185 186 do_shortcode('[test-shortcode-tag]Test Content[test-shortcode-tag:foo=]asdf[test-shortcode-tag:bar=]bing[/test-shortcode-tag]'); 187 $this->assertEquals( array('foo' => 'asdf', 'bar' => 'bing'), $this->atts ); 188 $this->assertEquals( 'Test Content', $this->content ); 148 189 } 149 190 150 191 function test_noatts_enclosing() { … … 159 200 $this->assertEquals( array('foo' => 'bar'), $this->atts ); 160 201 $this->assertEquals( 'content', $this->content ); 161 202 $this->assertEquals( 'test-shortcode-tag', $this->tagname ); 203 204 do_shortcode('[test-shortcode-tag]content[test-shortcode-tag:foo=]bar[/test-shortcode-tag]'); 205 $this->assertEquals( array('foo' => 'bar'), $this->atts ); 206 $this->assertEquals( 'content', $this->content ); 162 207 } 163 208 164 209 function test_two_atts_enclosing() { … … 166 211 $this->assertEquals( array('foo' => 'bar', 'baz' => 'bing'), $this->atts ); 167 212 $this->assertEquals( 'content', $this->content ); 168 213 $this->assertEquals( 'test-shortcode-tag', $this->tagname ); 214 215 do_shortcode('[test-shortcode-tag]content[test-shortcode-tag:foo=]bar[test-shortcode-tag:baz=]bing[/test-shortcode-tag]'); 216 $this->assertEquals( array('foo' => 'bar', 'baz' => 'bing'), $this->atts ); 217 $this->assertEquals( 'content', $this->content ); 169 218 } 170 219 171 220 function test_unclosed() { … … 172 221 $out = do_shortcode('[test-shortcode-tag]'); 173 222 $this->assertEquals( '', $out ); 174 223 $this->assertEquals( '', $this->atts ); 224 $this->assertEquals( '', $this->content ); 175 225 $this->assertEquals( 'test-shortcode-tag', $this->tagname ); 176 226 } 177 227 … … 179 229 $out = do_shortcode('[test-shortcode-tag 123]'); 180 230 $this->assertEquals( '', $out ); 181 231 $this->assertEquals( array(0=>'123'), $this->atts ); 232 $this->assertEquals( '', $this->content ); 182 233 $this->assertEquals( 'test-shortcode-tag', $this->tagname ); 234 235 $out = do_shortcode('[test-shortcode-tag][test-shortcode-tag:=]123[/test-shortcode-tag]'); 236 $this->assertEquals( '', $out ); 237 $this->assertEquals( array(0=>'123'), $this->atts ); 238 $this->assertEquals( '', $this->content ); 183 239 } 184 240 185 241 function test_positional_atts_url() { … … 186 242 $out = do_shortcode('[test-shortcode-tag http://www.youtube.com/watch?v=eBGIQ7ZuuiU]'); 187 243 $this->assertEquals( '', $out ); 188 244 $this->assertEquals( array(0=>'http://www.youtube.com/watch?v=eBGIQ7ZuuiU'), $this->atts ); 245 $this->assertEquals( '', $this->content ); 189 246 $this->assertEquals( 'test-shortcode-tag', $this->tagname ); 247 248 $out = do_shortcode('[test-shortcode-tag][test-shortcode-tag:=]http://www.youtube.com/watch?v=eBGIQ7ZuuiU[/test-shortcode-tag]'); 249 $this->assertEquals( '', $out ); 250 $this->assertEquals( array(0=>'http://www.youtube.com/watch?v=eBGIQ7ZuuiU'), $this->atts ); 251 $this->assertEquals( '', $this->content ); 190 252 } 191 253 192 254 function test_positional_atts_quotes() { … … 193 255 $out = do_shortcode('[test-shortcode-tag "something in quotes" "something else"]'); 194 256 $this->assertEquals( '', $out ); 195 257 $this->assertEquals( array(0=>'something in quotes', 1=>'something else'), $this->atts ); 258 $this->assertEquals( '', $this->content ); 196 259 $this->assertEquals( 'test-shortcode-tag', $this->tagname ); 260 261 $out = do_shortcode('[test-shortcode-tag "something in quotes"][test-shortcode-tag:=]something else[/test-shortcode-tag]'); 262 $this->assertEquals( '', $out ); 263 $this->assertEquals( array(0=>'something in quotes', 1=>'something else'), $this->atts ); 264 $this->assertEquals( '', $this->content ); 265 266 $out = do_shortcode('[test-shortcode-tag][test-shortcode-tag:=]something in quotes[test-shortcode-tag:=]something else[/test-shortcode-tag]'); 267 $this->assertEquals( '', $out ); 268 $this->assertEquals( array(0=>'something in quotes', 1=>'something else'), $this->atts ); 269 $this->assertEquals( '', $this->content ); 197 270 } 198 271 199 272 function test_positional_atts_mixed() { … … 200 273 $out = do_shortcode('[test-shortcode-tag 123 http://wordpress.com/ 0 "foo" bar]'); 201 274 $this->assertEquals( '', $out ); 202 275 $this->assertEquals( array(0=>'123', 1=>'http://wordpress.com/', 2=>'0', 3=>'foo', 4=>'bar'), $this->atts ); 276 $this->assertEquals( '', $this->content ); 203 277 $this->assertEquals( 'test-shortcode-tag', $this->tagname ); 278 279 $out = do_shortcode('[test-shortcode-tag 123 http://wordpress.com/ 0 "foo"][test-shortcode-tag:=]bar[/test-shortcode-tag]'); 280 $this->assertEquals( '', $out ); 281 $this->assertEquals( array(0=>'123', 1=>'http://wordpress.com/', 2=>'0', 3=>'foo', 4=>'bar'), $this->atts ); 282 $this->assertEquals( '', $this->content ); 283 284 $out = do_shortcode('[test-shortcode-tag 123 http://wordpress.com/ 0][test-shortcode-tag:=]foo[test-shortcode-tag:=]bar[/test-shortcode-tag]'); 285 $this->assertEquals( '', $out ); 286 $this->assertEquals( array(0=>'123', 1=>'http://wordpress.com/', 2=>'0', 3=>'foo', 4=>'bar'), $this->atts ); 287 $this->assertEquals( '', $this->content ); 288 289 $out = do_shortcode('[test-shortcode-tag 123 http://wordpress.com/ ][test-shortcode-tag:=]0[test-shortcode-tag:=]foo[test-shortcode-tag:=]bar[/test-shortcode-tag]'); 290 $this->assertEquals( '', $out ); 291 $this->assertEquals( array(0=>'123', 1=>'http://wordpress.com/', 2=>'0', 3=>'foo', 4=>'bar'), $this->atts ); 292 $this->assertEquals( '', $this->content ); 293 294 $out = do_shortcode('[test-shortcode-tag 123][test-shortcode-tag:=]http://wordpress.com/[test-shortcode-tag:=]0[test-shortcode-tag:=]foo[test-shortcode-tag:=]bar[/test-shortcode-tag]'); 295 $this->assertEquals( '', $out ); 296 $this->assertEquals( array(0=>'123', 1=>'http://wordpress.com/', 2=>'0', 3=>'foo', 4=>'bar'), $this->atts ); 297 $this->assertEquals( '', $this->content ); 298 299 $out = do_shortcode('[test-shortcode-tag][test-shortcode-tag:=]123[test-shortcode-tag:=]http://wordpress.com/[test-shortcode-tag:=]0[test-shortcode-tag:=]foo[test-shortcode-tag:=]bar[/test-shortcode-tag]'); 300 $this->assertEquals( '', $out ); 301 $this->assertEquals( array(0=>'123', 1=>'http://wordpress.com/', 2=>'0', 3=>'foo', 4=>'bar'), $this->atts ); 302 $this->assertEquals( '', $this->content ); 204 303 } 205 304 206 305 function test_positional_and_named_atts() { … … 207 306 $out = do_shortcode('[test-shortcode-tag 123 url=http://wordpress.com/ foo bar="baz"]'); 208 307 $this->assertEquals( '', $out ); 209 308 $this->assertEquals( array(0=>'123', 'url' => 'http://wordpress.com/', 1=>'foo', 'bar' => 'baz'), $this->atts ); 309 $this->assertEquals( '', $this->content ); 210 310 $this->assertEquals( 'test-shortcode-tag', $this->tagname ); 311 312 $out = do_shortcode('[test-shortcode-tag 123 url=http://wordpress.com/ foo][test-shortcode-tag:bar=]baz[/test-shortcode-tag]'); 313 $this->assertEquals( '', $out ); 314 $this->assertEquals( array(0=>'123', 'url' => 'http://wordpress.com/', 1=>'foo', 'bar' => 'baz'), $this->atts ); 315 $this->assertEquals( '', $this->content ); 316 317 $out = do_shortcode('[test-shortcode-tag 123 url=http://wordpress.com/ ][test-shortcode-tag:=]foo[test-shortcode-tag:bar=]baz[/test-shortcode-tag]'); 318 $this->assertEquals( '', $out ); 319 $this->assertEquals( array(0=>'123', 'url' => 'http://wordpress.com/', 1=>'foo', 'bar' => 'baz'), $this->atts ); 320 $this->assertEquals( '', $this->content ); 321 322 $out = do_shortcode('[test-shortcode-tag 123][test-shortcode-tag:url=]http://wordpress.com/[test-shortcode-tag:=]foo[test-shortcode-tag:bar=]baz[/test-shortcode-tag]'); 323 $this->assertEquals( '', $out ); 324 $this->assertEquals( array(0=>'123', 'url' => 'http://wordpress.com/', 1=>'foo', 'bar' => 'baz'), $this->atts ); 325 $this->assertEquals( '', $this->content ); 326 327 $out = do_shortcode('[test-shortcode-tag][test-shortcode-tag:=]123[test-shortcode-tag:url=]http://wordpress.com/[test-shortcode-tag:=]foo[test-shortcode-tag:bar=]baz[/test-shortcode-tag]'); 328 $this->assertEquals( '', $out ); 329 $this->assertEquals( array(0=>'123', 'url' => 'http://wordpress.com/', 1=>'foo', 'bar' => 'baz'), $this->atts ); 330 $this->assertEquals( '', $this->content ); 331 211 332 } 212 333 213 334 function test_footag_default() {