WordPress.org

Make WordPress Core

Changeset 31713


Ignore:
Timestamp:
03/11/2015 02:39:02 AM (5 years ago)
Author:
azaozz
Message:

wpLink: replace the "Title" field with a "Text" field and populate it with the link text when editing an existing link or with the selected text if any.
Props iseulde. See #28206.

Location:
trunk/src/wp-includes
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/class-wp-editor.php

    r31222 r31713  
    14491449            <div id="link-options">
    14501450                <p class="howto"><?php _e( 'Enter the destination URL' ); ?></p>
    1451                 <div>
    1452                     <label><span><?php _e( 'URL' ); ?></span><input id="url-field" type="text" name="href" /></label>
     1451                <div class="wp-link-text-field">
     1452                    <label><span><?php _e( 'Text' ); ?></span><input id="wp-link-text" type="text" /></label>
    14531453                </div>
    14541454                <div>
    1455                     <label><span><?php _e( 'Title' ); ?></span><input id="link-title-field" type="text" name="linktitle" /></label>
     1455                    <label><span><?php _e( 'URL' ); ?></span><input id="wp-link-url" type="text" /></label>
    14561456                </div>
    14571457                <div class="link-target">
    1458                     <label><span>&nbsp;</span><input type="checkbox" id="link-target-checkbox" /> <?php _e( 'Open link in a new window/tab' ); ?></label>
     1458                    <label><span>&nbsp;</span><input type="checkbox" id="wp-link-target" /> <?php _e( 'Open link in a new window/tab' ); ?></label>
    14591459                </div>
    14601460            </div>
     
    14641464                    <label>
    14651465                        <span class="search-label"><?php _e( 'Search' ); ?></span>
    1466                         <input type="search" id="search-field" class="link-search-field" autocomplete="off" />
     1466                        <input type="search" id="wp-link-search" class="link-search-field" autocomplete="off" />
    14671467                        <span class="spinner"></span>
    14681468                    </label>
  • trunk/src/wp-includes/css/editor.css

    r31573 r31713  
    11941194    box-shadow: 0 3px 6px rgba( 0, 0, 0, 0.3 );
    11951195    width: 500px;
    1196     height: 250px;
    11971196    overflow: hidden;
    11981197    margin-left: -250px;
     
    12301229}
    12311230
     1231#wp-link-wrap .wp-link-text-field {
     1232    display: none;
     1233}
     1234
     1235#wp-link-wrap.has-text-field .wp-link-text-field {
     1236    display: block;
     1237}
     1238
    12321239#link-modal-title {
    12331240    background: #fcfcfc;
     
    13961403    right: 16px;
    13971404    bottom: 16px;
     1405    top: 172px;
     1406}
     1407
     1408.has-text-field #wp-link .query-results {
    13981409    top: 205px;
    13991410}
     
    15301541@media screen and ( max-width: 782px ) {
    15311542    #wp-link-wrap {
    1532         height: 280px;
    15331543        margin-top: -140px;
    15341544    }
    15351545
    15361546    #wp-link-wrap.search-panel-visible .query-results {
     1547        top: 195px;
     1548    }
     1549
     1550    #wp-link-wrap.search-panel-visible.has-text-field .query-results {
    15371551        top: 235px;
    15381552    }
  • trunk/src/wp-includes/js/tinymce/plugins/wplink/plugin.js

    r31691 r31713  
    11/* global tinymce */
    22tinymce.PluginManager.add( 'wplink', function( editor ) {
    3     var linkButton;
    4 
    5     // Register a command so that it can be invoked by using tinyMCE.activeEditor.execCommand( 'WP_Link' );
    63    editor.addCommand( 'WP_Link', function() {
    7         if ( ( ! linkButton || ! linkButton.disabled() ) && typeof window.wpLink !== 'undefined' ) {
    8             window.wpLink.open( editor.id );
    9         }
     4        window.wpLink && window.wpLink.open( editor.id );
    105    });
    116
     
    1510    editor.addShortcut( 'ctrl+k', '', 'WP_Link' );
    1611
    17     function setState( button, node ) {
    18         var parent = editor.dom.getParent( node, 'a' ),
    19             getView = editor.plugins.wpview ? editor.plugins.wpview.getView : function() { return false; };
    20 
    21         button.disabled( ( editor.selection.isCollapsed() && ! parent ) || ( parent && ! parent.href ) || getView( node ) );
    22         button.active( parent && parent.href );
    23     }
    24 
    2512    editor.addButton( 'link', {
    2613        icon: 'link',
     
    2815        shortcut: 'Alt+Shift+A',
    2916        cmd: 'WP_Link',
    30 
    31         onPostRender: function() {
    32             linkButton = this;
    33 
    34             editor.on( 'nodechange', function( event ) {
    35                 setState( linkButton, event.element );
    36             });
    37         }
     17        stateSelector: 'a[href]'
    3818    });
    3919
     
    4121        icon: 'unlink',
    4222        tooltip: 'Remove link',
    43         cmd: 'unlink',
    44 
    45         onPostRender: function() {
    46             var unlinkButton = this;
    47 
    48             editor.on( 'nodechange', function( event ) {
    49                 setState( unlinkButton, event.element );
    50             });
    51         }
     23        cmd: 'unlink'
    5224    });
    5325
  • trunk/src/wp-includes/js/wplink.js

    r31606 r31713  
    77        rivers = {},
    88        isTouch = ( 'ontouchend' in document );
     9
     10    function getLink() {
     11        return editor.dom.getParent( editor.selection.getNode(), 'a' );
     12    }
    913
    1014    wpLink = {
     
    2226            inputs.submit = $( '#wp-link-submit' );
    2327            inputs.close = $( '#wp-link-close' );
    24             // URL
    25             inputs.url = $( '#url-field' );
     28
     29            // Input
     30            inputs.text = $( '#wp-link-text' );
     31            inputs.url = $( '#wp-link-url' );
    2632            inputs.nonce = $( '#_ajax_linking_nonce' );
    27             // Secondary options
    28             inputs.title = $( '#link-title-field' );
    29             // Advanced Options
    30             inputs.openInNewTab = $( '#link-target-checkbox' );
    31             inputs.search = $( '#search-field' );
     33            inputs.openInNewTab = $( '#wp-link-target' );
     34            inputs.search = $( '#wp-link-search' );
     35
    3236            // Build Rivers
    3337            rivers.search = new River( $( '#search-results' ) );
     
    130134
    131135            wpLink.refresh();
     136
    132137            $( document ).trigger( 'wplink-open', inputs.wrap );
    133138        },
     
    145150                wpLink.mceRefresh();
    146151            } else {
     152                inputs.wrap.removeClass( 'has-text-field' );
     153                inputs.text.val( '' );
    147154                wpLink.setDefaultValues();
    148155            }
     
    155162                // If this is moved above the selection changes,
    156163                // IE will show a flashing cursor over the dialog.
    157                 inputs.url.focus()[0].select();
     164                if ( inputs.wrap.hasClass( 'has-text-field' ) ) {
     165                    inputs.text.focus();
     166                } else {
     167                    inputs.url.focus()[0].select();
     168                }
    158169            }
    159170
     
    166177        },
    167178
     179        hasSelectedText: function( linkNode ) {
     180            var html = editor.selection.getContent();
     181
     182            // Partial html and not a fully selected anchor element
     183            if ( /</.test( html ) && ( ! /^<a [^>]+>[^<]+<\/a>$/.test( html ) || html.indexOf('href=') === -1 ) ) {
     184                return false;
     185            }
     186
     187            if ( linkNode ) {
     188                var nodes = linkNode.childNodes, i;
     189
     190                if ( nodes.length === 0 ) {
     191                    return false;
     192                }
     193
     194                for ( i = nodes.length - 1; i >= 0; i-- ) {
     195                    if ( nodes[i].nodeType != 3 ) {
     196                        return false;
     197                    }
     198                }
     199            }
     200
     201            return true;
     202        },
     203
    168204        mceRefresh: function() {
    169             var e;
    170 
    171             // If link exists, select proper values.
    172             if ( e = editor.dom.getParent( editor.selection.getNode(), 'A' ) ) {
    173                 // Set URL and description.
    174                 inputs.url.val( editor.dom.getAttrib( e, 'href' ) );
    175                 inputs.title.val( editor.dom.getAttrib( e, 'title' ) );
    176                 // Set open in new tab.
    177                 inputs.openInNewTab.prop( 'checked', ( '_blank' === editor.dom.getAttrib( e, 'target' ) ) );
    178                 // Update save prompt.
     205            var text,
     206                selectedNode = editor.selection.getNode(),
     207                linkNode = editor.dom.getParent( selectedNode, 'a[href]' ),
     208                onlyText = this.hasSelectedText( linkNode );
     209
     210            if ( linkNode ) {
     211                text = linkNode.innerText || linkNode.textContent;
     212                inputs.url.val( editor.dom.getAttrib( linkNode, 'href' ) );
     213                inputs.openInNewTab.prop( 'checked', '_blank' === editor.dom.getAttrib( linkNode, 'target' ) );
    179214                inputs.submit.val( wpLinkL10n.update );
    180 
    181             // If there's no link, set the default values.
    182             } else {
    183                 wpLink.setDefaultValues();
     215            } else {
     216                text = editor.selection.getContent({ format: 'text' });
     217                this.setDefaultValues();
     218            }
     219
     220            if ( onlyText ) {
     221                inputs.text.val( text || '' );
     222                inputs.wrap.addClass( 'has-text-field' );
     223            } else {
     224                inputs.text.val( '' );
     225                inputs.wrap.removeClass( 'has-text-field' );
    184226            }
    185227        },
     
    210252            return {
    211253                href: $.trim( inputs.url.val() ),
    212                 title: $.trim( inputs.title.val() ),
    213254                target: inputs.openInNewTab.prop( 'checked' ) ? '_blank' : ''
    214255            };
     
    216257
    217258        update: function() {
    218             if ( wpLink.isMCE() )
     259            if ( wpLink.isMCE() ) {
    219260                wpLink.mceUpdate();
    220             else
     261            } else {
    221262                wpLink.htmlUpdate();
     263            }
    222264        },
    223265
    224266        htmlUpdate: function() {
    225             var attrs, html, begin, end, cursor, title, selection,
     267            var attrs, text, html, begin, end, cursor, selection,
    226268                textarea = wpLink.textarea;
    227269
    228             if ( ! textarea )
    229                 return;
     270            if ( ! textarea ) {
     271                return;
     272            }
    230273
    231274            attrs = wpLink.getAttrs();
     275            text = inputs.text.val();
    232276
    233277            // If there's no href, return.
    234             if ( ! attrs.href )
    235                 return;
     278            if ( ! attrs.href ) {
     279                return;
     280            }
    236281
    237282            // Build HTML
    238283            html = '<a href="' + attrs.href + '"';
    239 
    240             if ( attrs.title ) {
    241                 title = attrs.title.replace( /</g, '&lt;' ).replace( />/g, '&gt;' ).replace( /"/g, '&quot;' );
    242                 html += ' title="' + title + '"';
    243             }
    244284
    245285            if ( attrs.target ) {
     
    255295                //       inside the closing tag.
    256296                textarea.focus();
    257                 wpLink.range.text = html + wpLink.range.text + '</a>';
     297                wpLink.range.text = html + ( text || wpLink.range.text ) + '</a>';
    258298                wpLink.range.moveToBookmark( wpLink.range.getBookmark() );
    259299                wpLink.range.select();
     
    262302            } else if ( typeof textarea.selectionStart !== 'undefined' ) {
    263303                // W3C
    264                 begin       = textarea.selectionStart;
    265                 end         = textarea.selectionEnd;
    266                 selection   = textarea.value.substring( begin, end );
    267                 html        = html + selection + '</a>';
    268                 cursor      = begin + html.length;
     304                begin = textarea.selectionStart;
     305                end = textarea.selectionEnd;
     306                selection = text || textarea.value.substring( begin, end );
     307                html = html + selection + '</a>';
     308                cursor = begin + html.length;
    269309
    270310                // If no text is selected, place the cursor inside the closing tag.
    271                 if ( begin == end )
    272                     cursor -= '</a>'.length;
    273 
    274                 textarea.value = textarea.value.substring( 0, begin ) + html +
    275                     textarea.value.substring( end, textarea.value.length );
     311                if ( begin === end && ! selection ) {
     312                    cursor -= 4;
     313                }
     314
     315                textarea.value = (
     316                    textarea.value.substring( 0, begin ) +
     317                    html +
     318                    textarea.value.substring( end, textarea.value.length )
     319                );
    276320
    277321                // Update cursor position
     
    284328
    285329        mceUpdate: function() {
    286             var link,
    287                 attrs = wpLink.getAttrs();
     330            var attrs = wpLink.getAttrs(),
     331                link, text;
    288332
    289333            wpLink.close();
     
    294338            }
    295339
    296             link = editor.dom.getParent( editor.selection.getNode(), 'a[href]' );
    297 
    298             // If the values are empty, unlink and return
    299             if ( ! attrs.href || attrs.href == 'http://' ) {
     340            if ( ! attrs.href ) {
    300341                editor.execCommand( 'unlink' );
    301342                return;
    302343            }
    303344
     345            link = getLink();
     346            text = inputs.text.val();
     347
    304348            if ( link ) {
     349                if ( text ) {
     350                    if ( 'innerText' in link ) {
     351                        link.innerText = text;
     352                    } else {
     353                        link.textContent = text;
     354                    }
     355                }
     356
    305357                editor.dom.setAttribs( link, attrs );
    306358            } else {
    307                 editor.execCommand( 'mceInsertLink', false, attrs );
    308             }
    309 
    310             // Move the cursor to the end of the selection
    311             editor.selection.collapse();
     359                if ( text ) {
     360                    editor.selection.setNode( editor.dom.create( 'a', attrs, text ) );
     361                } else {
     362                    editor.execCommand( 'mceInsertLink', false, attrs );
     363                }
     364            }
    312365        },
    313366
    314367        updateFields: function( e, li ) {
    315368            inputs.url.val( li.children( '.item-permalink' ).val() );
    316             inputs.title.val( li.hasClass( 'no-title' ) ? '' : li.children( '.item-title' ).text() );
    317369        },
    318370
    319371        setDefaultValues: function() {
    320             var selection = editor && editor.selection.getContent(),
     372            var selection,
    321373                emailRegexp = /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i,
    322                 urlRegexp = /^(https?|ftp):\/\/[A-Z0-9.-]+\.[A-Z]{2,4}[^ "]*$/i;
     374                urlRegexp = /^(https?|ftp):\/\/[A-Z0-9.-]+\.[A-Z]{2,4}[^ "]*$/i,
     375                text;
     376
     377            if ( this.isMCE() ) {
     378                selection = editor.selection.getContent();
     379            } else if ( document.selection && wpLink.range ) {
     380                selection = wpLink.range.text;
     381            } else if ( typeof this.textarea.selectionStart !== 'undefined' ) {
     382                selection = this.textarea.value.substring( this.textarea.selectionStart, this.textarea.selectionEnd );
     383            }
    323384
    324385            if ( selection && emailRegexp.test( selection ) ) {
     
    332393                inputs.url.val( '' );
    333394            }
    334 
    335             // Set description to default.
    336             inputs.title.val( '' );
    337395
    338396            // Update save prompt.
Note: See TracChangeset for help on using the changeset viewer.