WordPress.org

Make WordPress Core

Ticket #14691: tags-with-commas.diff

File tags-with-commas.diff, 8.2 KB (added by joehoyle, 6 years ago)
  • src/wp-admin/includes/taxonomy.php

     
    229229        if ( is_wp_error($tags) )
    230230                return $tags;
    231231
    232         foreach ( $tags as $tag )
    233                 $tag_names[] = $tag->name;
     232        foreach ( $tags as $tag ) {
     233                if ( strpos( $tag->name, ',' ) !== false )
     234                        $tag_names[] = '"' . $tag->name . '"';
     235                else
     236                        $tag_names[] = $tag->name;
     237        }
     238
    234239        $tags_to_edit = join( ',', $tag_names );
    235240        $tags_to_edit = esc_attr( $tags_to_edit );
    236241        $tags_to_edit = apply_filters( 'terms_to_edit', $tags_to_edit, $taxonomy );
  • src/wp-admin/includes/meta-boxes.php

     
    364364        <div class="jaxtag">
    365365        <div class="nojs-tags hide-if-js">
    366366        <p><?php echo $taxonomy->labels->add_or_remove_items; ?></p>
    367         <textarea name="<?php echo "tax_input[$tax_name]"; ?>" rows="3" cols="20" class="the-tags" id="tax-input-<?php echo $tax_name; ?>" <?php disabled( ! $user_can_assign_terms ); ?>><?php echo str_replace( ',', $comma . ' ', get_terms_to_edit( $post->ID, $tax_name ) ); // textarea_escaped by esc_attr() ?></textarea></div>
     367        <textarea name="<?php echo "tax_input[$tax_name]"; ?>" rows="3" cols="20" class="the-tags" id="tax-input-<?php echo $tax_name; ?>" <?php disabled( ! $user_can_assign_terms ); ?>><?php echo get_terms_to_edit( $post->ID, $tax_name ); // textarea_escaped by esc_attr() ?></textarea></div>
    368368        <?php if ( $user_can_assign_terms ) : ?>
    369369        <div class="ajaxtag hide-if-no-js">
    370370                <label class="screen-reader-text" for="new-tag-<?php echo $tax_name; ?>"><?php echo $box['title']; ?></label>
  • src/wp-admin/js/post.js

     
    1414(function($){
    1515
    1616tagBox = {
    17         clean : function(tags) {
    18                 var comma = postL10n.comma;
    19                 if ( ',' !== comma )
    20                         tags = tags.replace(new RegExp(comma, 'g'), ',');
    21                 tags = tags.replace(/\s*,\s*/g, ',').replace(/,+/g, ',').replace(/[,\s]+$/, '').replace(/^[,\s]+/, '');
    22                 if ( ',' !== comma )
    23                         tags = tags.replace(/,/g, comma);
    24                 return tags;
    25         },
    2617
    27         parseTags : function(el) {
    28                 var id = el.id, num = id.split('-check-num-')[1], taxbox = $(el).closest('.tagsdiv'),
    29                         thetags = taxbox.find('.the-tags'), comma = postL10n.comma,
    30                         current_tags = thetags.val().split(comma), new_tags = [];
    31                 delete current_tags[num];
     18        quickClicks : function(el) {
     19               
     20                var thetags = $('.the-tags', el);
     21                var current_tags = this.getTagsFromString( thetags.val(), postL10n.comma );
    3222
    33                 $.each( current_tags, function(key, val) {
    34                         val = $.trim(val);
    35                         if ( val ) {
    36                                 new_tags.push(val);
    37                         }
    38                 });
     23                thetags.html('');
     24                $(el).data( 'tags',[]);
    3925
    40                 thetags.val( this.clean( new_tags.join(comma) ) );
    41 
    42                 this.quickClicks(taxbox);
    43                 return false;
     26                for (var i = current_tags.length - 1; i >= 0; i--) {
     27                        this.addTag( $(el), current_tags[i] );
     28                }
    4429        },
    4530
    46         quickClicks : function(el) {
    47                 var thetags = $('.the-tags', el),
    48                         tagchecklist = $('.tagchecklist', el),
    49                         id = $(el).attr('id'),
    50                         current_tags, disabled;
     31        addTag: function( el, tag ) {
     32                var span, xbutton, thetags = $('.the-tags', el), disabled, t = this;
    5133
    52                 if ( !thetags.length )
     34                tag = $.trim(tag)
     35               
     36                if ( el.data( 'tags' ).indexOf( tag ) > -1 )
    5337                        return;
    5438
     39                el.data( 'tags' ).push( tag )
    5540                disabled = thetags.prop('disabled');
    5641
    57                 current_tags = thetags.val().split(postL10n.comma);
    58                 tagchecklist.empty();
     42                // Create a new span, and ensure the text is properly escaped.
     43                span = $('<span />').text( tag );
     44                span.append( jQuery( '<input type="hidden" name="' + thetags.attr('name') + '[]" />' ).val( tag ) )
    5945
    60                 $.each( current_tags, function( key, val ) {
    61                         var span, xbutton;
     46                // If tags editing isn't disabled, create the X button.
     47                if ( ! disabled ) {
     48                        xbutton = $( '<a class="ntdelbutton">X</a>' );
     49                        xbutton.click( function() {
     50                                span.remove();
     51                                t.removeTag(el, tag);
     52                        });
    6253
    63                         val = $.trim( val );
     54                        span.prepend('&nbsp;').prepend( xbutton );
     55                }
    6456
    65                         if ( ! val )
    66                                 return;
     57                el.find('.tagchecklist').append(span);
    6758
    68                         // Create a new span, and ensure the text is properly escaped.
    69                         span = $('<span />').text( val );
     59        },
    7060
    71                         // If tags editing isn't disabled, create the X button.
    72                         if ( ! disabled ) {
    73                                 xbutton = $( '<a id="' + id + '-check-num-' + key + '" class="ntdelbutton">X</a>' );
    74                                 xbutton.click( function(){ tagBox.parseTags(this); });
    75                                 span.prepend('&nbsp;').prepend( xbutton );
    76                         }
    77 
    78                         // Append the span to the tag list.
    79                         tagchecklist.append( span );
    80                 });
     61        removeTag: function( el, tag ) {
     62                delete el.data('tags')[el.data('tags').indexOf(tag)]
    8163        },
    8264
    83         flushTags : function(el, a, f) {
    84                 a = a || false;
    85                 var tags = $('.the-tags', el),
    86                         newtag = $('input.newtag', el),
    87                         comma = postL10n.comma,
    88                         newtags, text;
     65        getTagsFromString: function(tags_string, comma) {
    8966
    90                 text = a ? $(a).text() : newtag.val();
    91                 tagsval = tags.val();
    92                 newtags = tagsval ? tagsval + comma + text : text;
     67                // pull out all quoted strings
     68                var quoted_tags = tags_string.match( /("|')(.+?)\1/g );
    9369
    94                 newtags = this.clean( newtags );
    95                 newtags = array_unique_noempty( newtags.split(comma) ).join(comma);
    96                 tags.val(newtags);
    97                 this.quickClicks(el);
     70                if ( quoted_tags ) {
     71                        for (var i = quoted_tags.length - 1; i >= 0; i--) {
     72                                tags_string = tags_string.replace( quoted_tags[i], '' );
     73                                quoted_tags[i] = quoted_tags[i].substr( 1, quoted_tags[i].length - 2 );
     74                        };
     75                }
    9876
    99                 if ( !a )
    100                         newtag.val('');
    101                 if ( 'undefined' == typeof(f) )
    102                         newtag.focus();
     77                var tags = tags_string.split(comma);
    10378
    104                 return false;
     79                if ( quoted_tags )
     80                        return array_unique_noempty( quoted_tags.concat(tags) );
     81
     82                return array_unique_noempty( tags );
    10583        },
    10684
     85        submitAddTag: function(el) {
     86
     87                var newtag = $('input.newtag', el),
     88                        new_tags = this.getTagsFromString( newtag.val(), postL10n.comma )
     89
     90                newtag.val('');
     91
     92                for (var i = new_tags.length - 1; i >= 0; i--) {
     93                        this.addTag( $(el), new_tags[i] );
     94                }
     95        },
     96
    10797        get : function(id) {
    108                 var tax = id.substr(id.indexOf('-')+1);
     98                var tax = id.substr(id.indexOf('-')+1), t = this;
    10999
    110100                $.post(ajaxurl, {'action':'get-tagcloud', 'tax':tax}, function(r, stat) {
    111101                        if ( 0 == r || 'success' != stat )
     
    113103
    114104                        r = $('<p id="tagcloud-'+tax+'" class="the-tagcloud">'+r+'</p>');
    115105                        $('a', r).click(function(){
    116                                 tagBox.flushTags( $(this).closest('.inside').children('.tagsdiv'), this);
     106                                t.addTag( $(this).closest('.inside').children('.tagsdiv'), $(this).text() )
    117107                                return false;
    118108                        });
    119109
     
    129119                });
    130120
    131121                $('input.tagadd', ajaxtag).click(function(){
    132                         t.flushTags( $(this).closest('.tagsdiv') );
     122                        t.submitAddTag( $(this).closest('.tagsdiv') );
    133123                });
    134124
    135125                $('div.taghint', ajaxtag).click(function(){
     
    143133                        $(this).parent().siblings('.taghint').css('visibility', 'hidden');
    144134                }).keyup(function(e){
    145135                        if ( 13 == e.which ) {
    146                                 tagBox.flushTags( $(this).closest('.tagsdiv') );
     136                                tagBox.submitAddTag( $(this).closest('.tagsdiv') );
    147137                                return false;
    148138                        }
    149139                }).keypress(function(e){
     
    159149                // save tags on post save/publish
    160150                $('#post').submit(function(){
    161151                        $('div.tagsdiv').each( function() {
    162                                 tagBox.flushTags(this, false, 1);
     152                                t.submitAddTag($(this));
    163153                        });
    164154                });
    165155
  • src/wp-includes/js/jquery/suggest.js

     
    244244                                        } else {
    245245                                                $currentVal = "";
    246246                                        }
    247                                         $input.val( $currentVal + $currentResult.text() + options.multipleSep);
     247
     248                                        if ( $currentResult.text().match( jQuery.trim( options.multipleSep ) ) )
     249                                                $input.val( $currentVal + '"' + $currentResult.text() + '"' + options.multipleSep);
     250                                        else
     251                                                $input.val( $currentVal + $currentResult.text() + options.multipleSep);
    248252                                        $input.focus();
    249253                                } else {
    250254                                        $input.val($currentResult.text());