diff --git a/wp-admin/includes/media.php b/wp-admin/includes/media.php index 9b5fdd6364..deaaba4cd6 100644 --- a/wp-admin/includes/media.php +++ b/wp-admin/includes/media.php @@ -145,14 +145,14 @@ function image_add_caption( $html, $id, $caption, $title, $align, $url, $size, $ $caption = str_replace( array("\r\n", "\r"), "\n", $caption); $caption = preg_replace_callback( '/<[a-zA-Z0-9]+(?: [^<>]+>)*/', '_cleanup_image_add_caption', $caption ); - $caption = preg_replace( '/\n+/', '', str_replace('"', '"', $caption) ); + // convert any remaining line breaks to + $caption = preg_replace( '/[ \n\t]*\n[ \t]*/', '', $caption ); $html = preg_replace( '/(class=["\'][^\'"]*)align(none|left|right|center)\s?/', '$1', $html ); if ( empty($align) ) $align = 'none'; - $shcode = '[caption id="' . $id . '" align="align' . $align - . '" width="' . $width . '" caption="' . $caption . '"]' . $html . '[/caption]'; + $shcode = '[caption id="' . $id . '" align="align' . $align . '" width="' . $width . '"]' . $html . ' ' . $caption . '[/caption]'; return apply_filters( 'image_add_caption_shortcode', $shcode, $html ); } @@ -166,20 +166,7 @@ add_filter( 'image_send_to_editor', 'image_add_caption', 20, 8 ); */ function _cleanup_image_add_caption( $matches ) { // remove any line breaks from inside the tags - $s = preg_replace( '/[\r\n\t]+/', ' ', $matches[0] ); - // look for single quotes inside html attributes (for example in title) - $s = preg_replace_callback( '/="[^"]+"/', '_cleanup_image_add_caption_callback', $s ); - return str_replace( '"', "'", $s ); -} - -/** - * Private preg_replace callback used in _cleanup_image_add_caption() - * - * @access private - * @since 3.4.0 - */ -function _cleanup_image_add_caption_callback( $matches ) { - return str_replace( "'", ''', $matches[0] ); + return preg_replace( '/[\r\n\t]+/', ' ', $matches[0] ); } /** @@ -1541,13 +1528,10 @@ var addExtImage = { if ( f.caption.value ) { caption = f.caption.value.replace(/\r\n|\r/g, '\n'); caption = caption.replace(/<[a-zA-Z0-9]+( [^<>]+)?>/g, function(a){ - a = a.replace(/[\r\n\t]+/, ' ').replace(/="[^"]+"/, function(b){ - return b.replace(/'/g, '''); - }); - return a.replace(/"/g, "'"); + return a.replace(/[\r\n\t]+/, ' '); }); - caption = caption.replace(/\n+/g, '').replace(/"/g, '"'); + caption = caption.replace(/\s*\n\s*/g, ''); } @@ -1561,7 +1545,7 @@ var addExtImage = { } if ( caption ) - html = '[caption id="" align="'+t.align+'" width="'+t.width+'" caption="'+caption+'"]'+html+'[/caption]'; + html = '[caption id="" align="'+t.align+'" width="'+t.width+'"]'+html+caption+'[/caption]'; var win = window.dialogArguments || opener || parent || top; win.send_to_editor(html); diff --git a/wp-admin/js/editor.dev.js b/wp-admin/js/editor.dev.js index 43d58b2a8b..93bb6d4f35 100644 --- a/wp-admin/js/editor.dev.js +++ b/wp-admin/js/editor.dev.js @@ -73,11 +73,11 @@ var switchEditors = { }); } - // keep tags inside captions + // keep tags inside captions and remove line breaks if ( content.indexOf('[caption') != -1 ) { preserve_br = true; - content = content.replace(/\[caption[^\]]+\]/g, function(a) { - return a.replace(/]*)>[\r\n]*/g, ''); + content = content.replace(/\[caption[\s\S]+?\[\/caption\]/g, function(a) { + return a.replace(/]*)>/g, '').replace(/[\r\n\t]+/, ''); }); } @@ -139,7 +139,8 @@ var switchEditors = { }, _wp_Autop : function(pee) { - var blocklist = 'table|thead|tfoot|tbody|tr|td|th|caption|col|colgroup|div|dl|dd|dt|ul|ol|li|pre|select|form|blockquote|address|math|p|h[1-6]|fieldset|legend|hr|noscript|menu|samp|header|footer|article|section|hgroup|nav|aside|details|summary'; + var preserve_linebreaks = false, preserve_br = false, + blocklist = 'table|thead|tfoot|tbody|tr|td|th|caption|col|colgroup|div|dl|dd|dt|ul|ol|li|pre|select|form|blockquote|address|math|p|h[1-6]|fieldset|legend|hr|noscript|menu|samp|header|footer|article|section|hgroup|nav|aside|details|summary'; if ( pee.indexOf('/g, function(a){ @@ -153,8 +154,24 @@ var switchEditors = { // Protect pre|script tags if ( pee.indexOf(']*>[\s\S]+?<\/\1>/g, function(a) { - return a.replace(/(\r\n|\n)/g, ''); + return a.replace(/(\r\n|\n)/g, ''); + }); + } + + // keep tags inside captions and convert line breaks + if ( pee.indexOf('[caption') != -1 ) { + preserve_br = true; + pee = pee.replace(/\[caption[\s\S]+?\[\/caption\]/g, function(a) { + // keep existing + a = a.replace(/]*)>/g, ''); + // no line breaks inside HTML tags + a = a.replace(/<[a-zA-Z0-9]+( [^<>]+)?>/g, function(b){ + return b.replace(/[\r\n\t]+/, ' '); + }); + // convert remaining line breaks to + return a.replace(/\s*\n\s*/g, ''); }); } @@ -186,7 +203,11 @@ var switchEditors = { }); // put back the line breaks in pre|script - pee = pee.replace(//g, '\n'); + if ( preserve_linebreaks ) + pee = pee.replace(//g, '\n'); + + if ( preserve_br ) + pee = pee.replace(/]*)>/g, ''); return pee; }, diff --git a/wp-includes/js/tinymce/plugins/wpeditimage/editor_plugin_src.js b/wp-includes/js/tinymce/plugins/wpeditimage/editor_plugin_src.js index a2b6566781..c241158d32 100644 --- a/wp-includes/js/tinymce/plugins/wpeditimage/editor_plugin_src.js +++ b/wp-includes/js/tinymce/plugins/wpeditimage/editor_plugin_src.js @@ -139,7 +139,7 @@ _do_shcode : function(content) { return content.replace(/(?:)?\[(?:wp_)?caption([^\]]+)\]([\s\S]+?)\[\/(?:wp_)?caption\](?:<\/p>)?/g, function(a,b,c){ - var id, cls, w, cap, div_cls; + var id, cls, w, cap, div_cls, img, trim = tinymce.trim; id = b.match(/id=['"]([^'"]*)['"] ?/); b = b.replace(id[0], ''); @@ -150,7 +150,17 @@ w = b.match(/width=['"]([0-9]*)['"] ?/); b = b.replace(w[0], ''); - cap = tinymce.trim(b).replace(/caption=['"]/, '').replace(/['"]$/, ''); + c = trim(c); + img = c.match(/((?:]+>)?]+>(?:<\/a>)?)([\s\S]*)/i); + + if ( img && img[2] ) { + cap = trim( img[2] ); + img = trim( img[1] ); + } else { + // old captions shortcode style + cap = trim(b).replace(/caption=['"]/, '').replace(/['"]$/, ''); + img = c; + } id = ( id && id[1] ) ? id[1] : ''; cls = ( cls && cls[1] ) ? cls[1] : 'alignnone'; @@ -164,7 +174,7 @@ div_cls += ' mceIEcenter'; return ''+c+''+cap+''; + 'px">'+img+''+cap+''; }); }, @@ -187,15 +197,14 @@ cls = cls.match(/align[a-z]+/) || 'alignnone'; cap = cap.replace(/\r\n|\r/g, '\n').replace(/<[a-zA-Z0-9]+( [^<>]+)?>/g, function(a){ - a = a.replace(/[\r\n\t]+/, ' ').replace(/="[^"]+"/, function(b){ - return b.replace(/'/g, '''); - }); - return a.replace(/"/g, "'"); + // no line breaks inside HTML tags + return a.replace(/[\r\n\t]+/, ' '); }); - cap = cap.replace(/\n+/g, '').replace(/"/g, '"'); + // convert remaining line breaks to + cap = cap.replace(/\s*\n\s*/g, ''); - return '[caption id="'+id+'" align="'+cls+'" width="'+w+'" caption="'+cap+'"]'+c+'[/caption]'; + return '[caption id="'+id+'" align="'+cls+'" width="'+w+'"]'+c+' '+cap+'[/caption]'; }); if ( ret.indexOf('[caption') !== 0 ) { diff --git a/wp-includes/js/tinymce/plugins/wpeditimage/js/editimage.dev.js b/wp-includes/js/tinymce/plugins/wpeditimage/js/editimage.dev.js index 9c1f3471c7..18e781179f 100644 --- a/wp-includes/js/tinymce/plugins/wpeditimage/js/editimage.dev.js +++ b/wp-includes/js/tinymce/plugins/wpeditimage/js/editimage.dev.js @@ -419,13 +419,10 @@ wpImage = { caption = f.img_cap_text.value; caption = caption.replace(/\r\n|\r/g, '\n').replace(/<[a-zA-Z0-9]+( [^<>]+)?>/g, function(a){ - a = a.replace(/[\r\n\t]+/, ' ').replace(/="[^"]+"/, function(b){ - return b.replace(/'/g, '''); - }); - return a.replace(/"/g, "'"); + return a.replace(/[\r\n\t]+/, ' '); }); - caption = caption.replace(/\n+/g, '').replace(/"/g, '"'); + caption = caption.replace(/\s*\n\s*/g, ''); if ( DL ) { ed.dom.setAttribs(DL, { diff --git a/wp-includes/media.php b/wp-includes/media.php index b0c82de951..55c2fbd3e0 100644 --- a/wp-includes/media.php +++ b/wp-includes/media.php @@ -724,6 +724,13 @@ add_shortcode('caption', 'img_caption_shortcode'); * @return string */ function img_caption_shortcode($attr, $content = null) { + // New-style shortcode with the caption inside the shortcode with the link and image tags. + if ( ! isset( $attr['caption'] ) ) { + if ( preg_match( '#((?:]+>\s*)?]+>(?:\s*)?)(.*)#is', $content, $matches ) ) { + $content = $matches[1]; + $attr['caption'] = trim( $matches[2] ); + } + } // Allow plugins/themes to override the default caption template. $output = apply_filters('img_caption_shortcode', '', $attr, $content);
]*>[\s\S]+?<\/\1>/g, function(a) { - return a.replace(/(\r\n|\n)/g, ''); + return a.replace(/(\r\n|\n)/g, ''); + }); + } + + // keep tags inside captions and convert line breaks + if ( pee.indexOf('[caption') != -1 ) { + preserve_br = true; + pee = pee.replace(/\[caption[\s\S]+?\[\/caption\]/g, function(a) { + // keep existing + a = a.replace(/]*)>/g, ''); + // no line breaks inside HTML tags + a = a.replace(/<[a-zA-Z0-9]+( [^<>]+)?>/g, function(b){ + return b.replace(/[\r\n\t]+/, ' '); + }); + // convert remaining line breaks to + return a.replace(/\s*\n\s*/g, ''); }); } @@ -186,7 +203,11 @@ var switchEditors = { }); // put back the line breaks in pre|script - pee = pee.replace(//g, '\n'); + if ( preserve_linebreaks ) + pee = pee.replace(//g, '\n'); + + if ( preserve_br ) + pee = pee.replace(/]*)>/g, ''); return pee; }, diff --git a/wp-includes/js/tinymce/plugins/wpeditimage/editor_plugin_src.js b/wp-includes/js/tinymce/plugins/wpeditimage/editor_plugin_src.js index a2b6566781..c241158d32 100644 --- a/wp-includes/js/tinymce/plugins/wpeditimage/editor_plugin_src.js +++ b/wp-includes/js/tinymce/plugins/wpeditimage/editor_plugin_src.js @@ -139,7 +139,7 @@ _do_shcode : function(content) { return content.replace(/(?:)?\[(?:wp_)?caption([^\]]+)\]([\s\S]+?)\[\/(?:wp_)?caption\](?:<\/p>)?/g, function(a,b,c){ - var id, cls, w, cap, div_cls; + var id, cls, w, cap, div_cls, img, trim = tinymce.trim; id = b.match(/id=['"]([^'"]*)['"] ?/); b = b.replace(id[0], ''); @@ -150,7 +150,17 @@ w = b.match(/width=['"]([0-9]*)['"] ?/); b = b.replace(w[0], ''); - cap = tinymce.trim(b).replace(/caption=['"]/, '').replace(/['"]$/, ''); + c = trim(c); + img = c.match(/((?:]+>)?]+>(?:<\/a>)?)([\s\S]*)/i); + + if ( img && img[2] ) { + cap = trim( img[2] ); + img = trim( img[1] ); + } else { + // old captions shortcode style + cap = trim(b).replace(/caption=['"]/, '').replace(/['"]$/, ''); + img = c; + } id = ( id && id[1] ) ? id[1] : ''; cls = ( cls && cls[1] ) ? cls[1] : 'alignnone'; @@ -164,7 +174,7 @@ div_cls += ' mceIEcenter'; return ''+c+''+cap+''; + 'px">'+img+''+cap+''; }); }, @@ -187,15 +197,14 @@ cls = cls.match(/align[a-z]+/) || 'alignnone'; cap = cap.replace(/\r\n|\r/g, '\n').replace(/<[a-zA-Z0-9]+( [^<>]+)?>/g, function(a){ - a = a.replace(/[\r\n\t]+/, ' ').replace(/="[^"]+"/, function(b){ - return b.replace(/'/g, '''); - }); - return a.replace(/"/g, "'"); + // no line breaks inside HTML tags + return a.replace(/[\r\n\t]+/, ' '); }); - cap = cap.replace(/\n+/g, '').replace(/"/g, '"'); + // convert remaining line breaks to + cap = cap.replace(/\s*\n\s*/g, ''); - return '[caption id="'+id+'" align="'+cls+'" width="'+w+'" caption="'+cap+'"]'+c+'[/caption]'; + return '[caption id="'+id+'" align="'+cls+'" width="'+w+'"]'+c+' '+cap+'[/caption]'; }); if ( ret.indexOf('[caption') !== 0 ) { diff --git a/wp-includes/js/tinymce/plugins/wpeditimage/js/editimage.dev.js b/wp-includes/js/tinymce/plugins/wpeditimage/js/editimage.dev.js index 9c1f3471c7..18e781179f 100644 --- a/wp-includes/js/tinymce/plugins/wpeditimage/js/editimage.dev.js +++ b/wp-includes/js/tinymce/plugins/wpeditimage/js/editimage.dev.js @@ -419,13 +419,10 @@ wpImage = { caption = f.img_cap_text.value; caption = caption.replace(/\r\n|\r/g, '\n').replace(/<[a-zA-Z0-9]+( [^<>]+)?>/g, function(a){ - a = a.replace(/[\r\n\t]+/, ' ').replace(/="[^"]+"/, function(b){ - return b.replace(/'/g, '''); - }); - return a.replace(/"/g, "'"); + return a.replace(/[\r\n\t]+/, ' '); }); - caption = caption.replace(/\n+/g, '').replace(/"/g, '"'); + caption = caption.replace(/\s*\n\s*/g, ''); if ( DL ) { ed.dom.setAttribs(DL, { diff --git a/wp-includes/media.php b/wp-includes/media.php index b0c82de951..55c2fbd3e0 100644 --- a/wp-includes/media.php +++ b/wp-includes/media.php @@ -724,6 +724,13 @@ add_shortcode('caption', 'img_caption_shortcode'); * @return string */ function img_caption_shortcode($attr, $content = null) { + // New-style shortcode with the caption inside the shortcode with the link and image tags. + if ( ! isset( $attr['caption'] ) ) { + if ( preg_match( '#((?:]+>\s*)?]+>(?:\s*)?)(.*)#is', $content, $matches ) ) { + $content = $matches[1]; + $attr['caption'] = trim( $matches[2] ); + } + } // Allow plugins/themes to override the default caption template. $output = apply_filters('img_caption_shortcode', '', $attr, $content);
)?\[(?:wp_)?caption([^\]]+)\]([\s\S]+?)\[\/(?:wp_)?caption\](?:<\/p>)?/g, function(a,b,c){ - var id, cls, w, cap, div_cls; + var id, cls, w, cap, div_cls, img, trim = tinymce.trim; id = b.match(/id=['"]([^'"]*)['"] ?/); b = b.replace(id[0], ''); @@ -150,7 +150,17 @@ w = b.match(/width=['"]([0-9]*)['"] ?/); b = b.replace(w[0], ''); - cap = tinymce.trim(b).replace(/caption=['"]/, '').replace(/['"]$/, ''); + c = trim(c); + img = c.match(/((?:]+>)?]+>(?:<\/a>)?)([\s\S]*)/i); + + if ( img && img[2] ) { + cap = trim( img[2] ); + img = trim( img[1] ); + } else { + // old captions shortcode style + cap = trim(b).replace(/caption=['"]/, '').replace(/['"]$/, ''); + img = c; + } id = ( id && id[1] ) ? id[1] : ''; cls = ( cls && cls[1] ) ? cls[1] : 'alignnone'; @@ -164,7 +174,7 @@ div_cls += ' mceIEcenter'; return ''+c+''+cap+''; + 'px">'+img+''+cap+''; }); }, @@ -187,15 +197,14 @@ cls = cls.match(/align[a-z]+/) || 'alignnone'; cap = cap.replace(/\r\n|\r/g, '\n').replace(/<[a-zA-Z0-9]+( [^<>]+)?>/g, function(a){ - a = a.replace(/[\r\n\t]+/, ' ').replace(/="[^"]+"/, function(b){ - return b.replace(/'/g, '''); - }); - return a.replace(/"/g, "'"); + // no line breaks inside HTML tags + return a.replace(/[\r\n\t]+/, ' '); }); - cap = cap.replace(/\n+/g, '').replace(/"/g, '"'); + // convert remaining line breaks to + cap = cap.replace(/\s*\n\s*/g, ''); - return '[caption id="'+id+'" align="'+cls+'" width="'+w+'" caption="'+cap+'"]'+c+'[/caption]'; + return '[caption id="'+id+'" align="'+cls+'" width="'+w+'"]'+c+' '+cap+'[/caption]'; }); if ( ret.indexOf('[caption') !== 0 ) { diff --git a/wp-includes/js/tinymce/plugins/wpeditimage/js/editimage.dev.js b/wp-includes/js/tinymce/plugins/wpeditimage/js/editimage.dev.js index 9c1f3471c7..18e781179f 100644 --- a/wp-includes/js/tinymce/plugins/wpeditimage/js/editimage.dev.js +++ b/wp-includes/js/tinymce/plugins/wpeditimage/js/editimage.dev.js @@ -419,13 +419,10 @@ wpImage = { caption = f.img_cap_text.value; caption = caption.replace(/\r\n|\r/g, '\n').replace(/<[a-zA-Z0-9]+( [^<>]+)?>/g, function(a){ - a = a.replace(/[\r\n\t]+/, ' ').replace(/="[^"]+"/, function(b){ - return b.replace(/'/g, '''); - }); - return a.replace(/"/g, "'"); + return a.replace(/[\r\n\t]+/, ' '); }); - caption = caption.replace(/\n+/g, '').replace(/"/g, '"'); + caption = caption.replace(/\s*\n\s*/g, ''); if ( DL ) { ed.dom.setAttribs(DL, { diff --git a/wp-includes/media.php b/wp-includes/media.php index b0c82de951..55c2fbd3e0 100644 --- a/wp-includes/media.php +++ b/wp-includes/media.php @@ -724,6 +724,13 @@ add_shortcode('caption', 'img_caption_shortcode'); * @return string */ function img_caption_shortcode($attr, $content = null) { + // New-style shortcode with the caption inside the shortcode with the link and image tags. + if ( ! isset( $attr['caption'] ) ) { + if ( preg_match( '#((?:]+>\s*)?]+>(?:\s*)?)(.*)#is', $content, $matches ) ) { + $content = $matches[1]; + $attr['caption'] = trim( $matches[2] ); + } + } // Allow plugins/themes to override the default caption template. $output = apply_filters('img_caption_shortcode', '', $attr, $content);