Index: wp-admin/includes/media.php =================================================================== --- wp-admin/includes/media.php (revision 20609) +++ wp-admin/includes/media.php (working copy) @@ -145,14 +145,14 @@ $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,23 +166,10 @@ */ 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 ); + return preg_replace( '/[\r\n\t]+/', ' ', $matches[0] ); } /** - * 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] ); -} - -/** * {@internal Missing Short Description}} * * @since 2.5.0 @@ -1541,13 +1528,10 @@ 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 @@ } 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); Index: wp-admin/js/editor.dev.js =================================================================== --- wp-admin/js/editor.dev.js (revision 20609) +++ wp-admin/js/editor.dev.js (working copy) @@ -73,11 +73,11 @@ }); } - // 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 @@ }, _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,11 +154,27 @@ // 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, ''); + }); + } + pee = pee + '\n\n'; pee = pee.replace(/\s*/gi, '\n\n'); pee = pee.replace(new RegExp('(<(?:'+blocklist+')(?: [^>]*)?>)', 'gi'), '\n$1'); @@ -186,8 +203,12 @@ }); // 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; }, Index: wp-includes/js/tinymce/plugins/wpeditimage/editor_plugin_src.js =================================================================== --- wp-includes/js/tinymce/plugins/wpeditimage/editor_plugin_src.js (revision 20609) +++ wp-includes/js/tinymce/plugins/wpeditimage/editor_plugin_src.js (working copy) @@ -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,8 +150,18 @@ w = b.match(/width=['"]([0-9]*)['"] ?/); b = b.replace(w[0], ''); - cap = tinymce.trim(b).replace(/caption=['"]/, '').replace(/['"]$/, ''); + c = tinymce.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'; w = ( w && w[1] ) ? w[1] : ''; @@ -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 ) { Index: wp-includes/js/tinymce/plugins/wpeditimage/js/editimage.dev.js =================================================================== --- wp-includes/js/tinymce/plugins/wpeditimage/js/editimage.dev.js (revision 20609) +++ wp-includes/js/tinymce/plugins/wpeditimage/js/editimage.dev.js (working copy) @@ -419,13 +419,10 @@ 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, { Index: wp-includes/media.php =================================================================== --- wp-includes/media.php (revision 20609) +++ wp-includes/media.php (working copy) @@ -724,6 +724,14 @@ * @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'] ) ) { + preg_match( '#()(.*)#is', $content, $matches ) || preg_match( '#()(.*)#is', $content, $matches ); + if ( $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, ''); + }); + } + pee = pee + '\n\n'; pee = pee.replace(/\s*/gi, '\n\n'); pee = pee.replace(new RegExp('(<(?:'+blocklist+')(?: [^>]*)?>)', 'gi'), '\n$1'); @@ -186,8 +203,12 @@ }); // 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; }, Index: wp-includes/js/tinymce/plugins/wpeditimage/editor_plugin_src.js =================================================================== --- wp-includes/js/tinymce/plugins/wpeditimage/editor_plugin_src.js (revision 20609) +++ wp-includes/js/tinymce/plugins/wpeditimage/editor_plugin_src.js (working copy) @@ -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,8 +150,18 @@ w = b.match(/width=['"]([0-9]*)['"] ?/); b = b.replace(w[0], ''); - cap = tinymce.trim(b).replace(/caption=['"]/, '').replace(/['"]$/, ''); + c = tinymce.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'; w = ( w && w[1] ) ? w[1] : ''; @@ -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 ) { Index: wp-includes/js/tinymce/plugins/wpeditimage/js/editimage.dev.js =================================================================== --- wp-includes/js/tinymce/plugins/wpeditimage/js/editimage.dev.js (revision 20609) +++ wp-includes/js/tinymce/plugins/wpeditimage/js/editimage.dev.js (working copy) @@ -419,13 +419,10 @@ 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, { Index: wp-includes/media.php =================================================================== --- wp-includes/media.php (revision 20609) +++ wp-includes/media.php (working copy) @@ -724,6 +724,14 @@ * @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'] ) ) { + preg_match( '#()(.*)#is', $content, $matches ) || preg_match( '#()(.*)#is', $content, $matches ); + if ( $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,8 +150,18 @@ w = b.match(/width=['"]([0-9]*)['"] ?/); b = b.replace(w[0], ''); - cap = tinymce.trim(b).replace(/caption=['"]/, '').replace(/['"]$/, ''); + c = tinymce.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'; w = ( w && w[1] ) ? w[1] : ''; @@ -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 ) { Index: wp-includes/js/tinymce/plugins/wpeditimage/js/editimage.dev.js =================================================================== --- wp-includes/js/tinymce/plugins/wpeditimage/js/editimage.dev.js (revision 20609) +++ wp-includes/js/tinymce/plugins/wpeditimage/js/editimage.dev.js (working copy) @@ -419,13 +419,10 @@ 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, { Index: wp-includes/media.php =================================================================== --- wp-includes/media.php (revision 20609) +++ wp-includes/media.php (working copy) @@ -724,6 +724,14 @@ * @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'] ) ) { + preg_match( '#()(.*)#is', $content, $matches ) || preg_match( '#()(.*)#is', $content, $matches ); + if ( $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);