WordPress.org

Make WordPress Core

Changeset 36384


Ignore:
Timestamp:
01/23/2016 12:07:29 AM (4 years ago)
Author:
iseulde
Message:

TinyMCE: add inline link dialog

First run.
Links the advanced button to the "old" dialog for now.

See #33301.

Location:
trunk/src
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-admin/includes/ajax-actions.php

    r36231 r36384  
    14781478    $args = array();
    14791479
    1480     if ( isset( $_POST['search'] ) )
     1480    if ( isset( $_POST['search'] ) ) {
    14811481        $args['s'] = wp_unslash( $_POST['search'] );
     1482    }
     1483
     1484    if ( isset( $_POST['term'] ) ) {
     1485        $args['s'] = wp_unslash( $_POST['term'] );
     1486    }
     1487
    14821488    $args['pagenum'] = ! empty( $_POST['page'] ) ? absint( $_POST['page'] ) : 1;
    14831489
  • trunk/src/wp-includes/class-wp-editor.php

    r36062 r36384  
    780780        if ( in_array('wplink', self::$plugins, true) || in_array('link', self::$qt_buttons, true) ) {
    781781            wp_enqueue_script('wplink');
     782            wp_enqueue_script( 'jquery-ui-autocomplete' );
    782783        }
    783784
  • trunk/src/wp-includes/css/editor.css

    r34011 r36384  
    450450    height: 3px;
    451451    width: 20px;
     452}
     453
     454.mce-toolbar .mce-btn-group .mce-btn.mce-primary {
     455    min-width: 0;
     456    background: #0085ba;
     457    border-color: #0073aa #006799 #006799;
     458    -webkit-box-shadow: 0 1px 0 #006799;
     459    box-shadow: 0 1px 0 #006799;
     460    color: #fff;
     461    text-decoration: none;
     462    text-shadow: 0 -1px 1px #006799,
     463        1px 0 1px #006799,
     464        0 1px 1px #006799,
     465        -1px 0 1px #006799;
     466}
     467
     468.mce-toolbar .mce-btn-group .mce-btn.mce-primary .mce-ico {
     469    color: #fff;
     470}
     471
     472.mce-toolbar .mce-btn-group .mce-btn.mce-primary:hover,
     473.mce-toolbar .mce-btn-group .mce-btn.mce-primary:focus {
     474    background: #008ec2;
     475    border-color: #006799;
     476    color: #fff;
     477}
     478
     479.mce-toolbar .mce-btn-group .mce-btn.mce-primary:focus {
     480    -webkit-box-shadow: 0 1px 0 #0073aa,
     481        0 0 2px 1px #33b3db;
     482    box-shadow: 0 1px 0 #0073aa,
     483        0 0 2px 1px #33b3db;
     484}
     485
     486.mce-toolbar .mce-btn-group .mce-btn.mce-primary:active {
     487    background: #0073aa;
     488    border-color: #006799;
     489    -webkit-box-shadow: inset 0 2px 0 #006799;
     490    box-shadow: inset 0 2px 0 #006799;
     491    vertical-align: top;
    452492}
    453493
     
    17101750}
    17111751
     1752div.wp-link-input {
     1753    float: left;
     1754    margin: 2px;
     1755    max-width: 694px;
     1756}
     1757
     1758div.wp-link-input input {
     1759    width: 300px;
     1760    padding: 3px;
     1761    -webkit-box-sizing: border-box;
     1762    -moz-box-sizing: border-box;
     1763    box-sizing: border-box;
     1764}
     1765
     1766@media screen and ( max-width: 400px ) {
     1767    div.wp-link-input {
     1768        min-width: 0;
     1769        max-width: 70%;
     1770        max-width: -webkit-calc(100% - 80px);
     1771        max-width: calc(100% - 80px);
     1772    }
     1773
     1774    div.wp-link-input input {
     1775        width: 100%;
     1776        font-size: 16px;
     1777        padding: 4px;
     1778    }
     1779}
     1780
     1781.ui-autocomplete.mce-wp-autocomplete {
     1782    z-index: 100100;
     1783    margin-top: 10px;
     1784    max-height: 200px;
     1785    overflow-y: auto;
     1786}
     1787
    17121788/* =Overlay Body
    17131789-------------------------------------------------------------- */
  • trunk/src/wp-includes/js/tinymce/plugins/wordpress/plugin.js

    r35607 r36384  
    745745
    746746                if ( spaceTop >= editorHeight || spaceBottom >= editorHeight ) {
    747                     return this.hide();
     747                    this.scrolling = true;
     748                    this.hide();
     749                    this.scrolling = false;
     750                    return this;
    748751                }
    749752
     
    851854            currentSelection = args.selection || args.element;
    852855
    853             if ( activeToolbar ) {
     856            if ( activeToolbar && activeToolbar !== args.toolbar ) {
    854857                activeToolbar.hide();
    855858            }
    856859
    857860            if ( args.toolbar ) {
    858                 activeToolbar = args.toolbar;
    859                 activeToolbar.show();
     861                if ( activeToolbar !== args.toolbar ) {
     862                    activeToolbar = args.toolbar;
     863                    activeToolbar.show();
     864                } else {
     865                    activeToolbar.reposition();
     866                }
    860867            } else {
    861868                activeToolbar = false;
     
    871878        function hide( event ) {
    872879            if ( activeToolbar ) {
    873                 activeToolbar.hide();
    874 
    875880                if ( event.type === 'hide' ) {
     881                    activeToolbar.hide();
    876882                    activeToolbar = false;
    877                 } else if ( event.type === 'resize' || event.type === 'scroll' ) {
     883                } else if ( ( event.type === 'resize' || event.type === 'scroll' ) && ! activeToolbar.blockHide ) {
    878884                    clearTimeout( timeout );
    879885
    880886                    timeout = setTimeout( function() {
    881887                        if ( activeToolbar && typeof activeToolbar.show === 'function' ) {
     888                            activeToolbar.scrolling = false;
    882889                            activeToolbar.show();
    883890                        }
    884891                    }, 250 );
     892
     893                    activeToolbar.scrolling = true;
     894                    activeToolbar.hide();
    885895                }
    886896            }
  • trunk/src/wp-includes/js/tinymce/plugins/wplink/plugin.js

    r35589 r36384  
    4848    } );
    4949
     50    tinymce.ui.WPLinkInput = tinymce.ui.Control.extend( {
     51        renderHtml: function() {
     52            return (
     53                '<div id="' + this._id + '" class="wp-link-input">' +
     54                    '<input type="text" value="" tabindex="-1" />' +
     55                '</div>'
     56            );
     57        },
     58        setURL: function( url ) {
     59            this.getEl().firstChild.value = url;
     60        }
     61    } );
     62
    5063    tinymce.PluginManager.add( 'wplink', function( editor ) {
     64        var a;
    5165        var toolbar;
     66        var editToolbar;
     67        var previewInstance;
     68        var inputInstance;
     69        var $ = window.jQuery;
     70
     71        editor.on( 'preinit', function() {
     72            if ( editor.wp && editor.wp._createToolbar ) {
     73                toolbar = editor.wp._createToolbar( [
     74                    'wp_link_preview',
     75                    'wp_link_edit',
     76                    'wp_link_remove'
     77                ], true );
     78
     79                editToolbar = editor.wp._createToolbar( [
     80                    'wp_link_input',
     81                    'wp_link_apply',
     82                    'wp_link_advanced'
     83                ], true );
     84
     85                editToolbar.on( 'show', function() {
     86                    var node = editToolbar.find( 'toolbar' )[0];
     87                    node && node.focus( true );
     88                    a = editor.dom.getParent( editor.selection.getNode(), 'a' );
     89                } );
     90
     91                editToolbar.on( 'hide', function() {
     92                    editToolbar.scrolling || editor.execCommand( 'wp_link_cancel' );
     93                } );
     94            }
     95        } );
    5296
    5397        editor.addCommand( 'WP_Link', function() {
    54             window.wpLink && window.wpLink.open( editor.id );
    55         });
     98            var a = editor.dom.getParent( editor.selection.getNode(), 'a' );
     99
     100            if ( a ) {
     101                editor.dom.setAttribs( a, { 'data-wp-edit': true } );
     102            } else {
     103                editor.execCommand( 'mceInsertLink', false, { href: '_wp_link_placeholder' } );
     104            }
     105
     106            editor.nodeChanged();
     107        } );
     108
     109        editor.addCommand( 'wp_link_apply', function() {
     110            if ( editToolbar.scrolling ) {
     111                return;
     112            }
     113
     114            var href = tinymce.trim( inputInstance.getEl().firstChild.value );
     115
     116            if ( href && ! /^(?:[a-z]+:|#|\?|\.|\/)/.test( href ) ) {
     117                href = 'http://' + href;
     118            }
     119
     120            if ( ! href ) {
     121                editor.dom.remove( a, true );
     122                return;
     123            }
     124
     125            if ( a ) {
     126                editor.dom.setAttribs( a, { href: href, 'data-wp-edit': null } );
     127            }
     128
     129            a = false;
     130
     131            editor.nodeChanged();
     132            editor.focus();
     133        } );
     134
     135        editor.addCommand( 'wp_link_cancel', function() {
     136            if ( a ) {
     137                if ( editor.$( a ).attr( 'href' ) === '_wp_link_placeholder' ) {
     138                    editor.dom.remove( a, true );
     139                } else {
     140                    editor.dom.setAttribs( a, { 'data-wp-edit': null } );
     141                }
     142            }
     143
     144            a = false;
     145
     146            editor.nodeChanged();
     147            editor.focus();
     148        } );
    56149
    57150        // WP default shortcut
     
    103196            type: 'WPLinkPreview',
    104197            onPostRender: function() {
    105                 var self = this;
    106 
    107                 editor.on( 'wptoolbar', function( event ) {
    108                     var anchor = editor.dom.getParent( event.element, 'a' ),
    109                         $anchor,
    110                         href;
    111 
    112                     if ( anchor ) {
    113                         $anchor = editor.$( anchor );
    114                         href = $anchor.attr( 'href' );
    115 
    116                         if ( href && ! $anchor.find( 'img' ).length ) {
    117                             self.setURL( href );
    118                             event.element = anchor;
    119                             event.toolbar = toolbar;
     198                previewInstance = this;
     199            }
     200        } );
     201
     202        editor.addButton( 'wp_link_input', {
     203            type: 'WPLinkInput',
     204            onPostRender: function() {
     205                var input = this.getEl().firstChild;
     206                var cache;
     207                var last;
     208
     209                inputInstance = this;
     210
     211                if ( $ ) {
     212                    $( input )
     213                    .on( 'keydown', function() {
     214                        $( input ).removeAttr( 'aria-activedescendant' );
     215                    } )
     216                    .autocomplete( {
     217                        source: function( request, response ) {
     218                            if ( last === request.term ) {
     219                                response( cache );
     220                                return;
     221                            }
     222
     223                            if ( /^https?:/.test( request.term ) || request.term.indexOf( '.' ) !== -1 ) {
     224                                return response();
     225                            }
     226
     227                            $.post( window.ajaxurl, {
     228                                action: 'wp-link-ajax',
     229                                page: 1,
     230                                search: request.term,
     231                                _ajax_linking_nonce: $( '#_ajax_linking_nonce' ).val()
     232                            }, function( data ) {
     233                                cache = data;
     234                                response( data );
     235                            }, 'json' );
     236
     237                            last = request.term;
     238                        },
     239                        focus: function( event, ui ) {
     240                            $( input ).attr( 'aria-activedescendant', 'mce-wp-autocomplete-' + ui.item.ID );
     241                        },
     242                        select: function( event, ui ) {
     243                            $( input ).val( ui.item.permalink );
     244                            return false;
     245                        },
     246                        open: function() {
     247                            $( input ).attr( 'aria-expanded', 'true' );
     248                            editToolbar.blockHide = true;
     249                        },
     250                        close: function() {
     251                            $( input ).attr( 'aria-expanded', 'false' );
     252                            editToolbar.blockHide = false;
     253                        },
     254                        minLength: 2,
     255                        position: {
     256                            my: 'left top+5'
    120257                        }
    121                     }
     258                    } ).autocomplete( 'instance' )._renderItem = function( ul, item ) {
     259                        return $( '<li role="option" id="mce-wp-autocomplete-' + item.ID + '">' )
     260                        .append( '<span>' + item.title + '</span>&nbsp;<span class="alignright">' + item.info + '</span>' )
     261                        .appendTo( ul );
     262                    };
     263
     264                    $( input )
     265                    .attr( {
     266                        'role': 'combobox',
     267                        'aria-autocomplete': 'list',
     268                        'aria-expanded': 'false',
     269                        'aria-owns': $( input ).autocomplete( 'widget' ).attr( 'id' )
     270                    }  )
     271                    .on( 'focus', function() {
     272                        $( input ).autocomplete( 'search' );
     273                    } )
     274                    .autocomplete( 'widget' )
     275                        .addClass( 'mce-wp-autocomplete' )
     276                        .attr( 'role', 'listbox' );
     277                }
     278
     279                tinymce.$( input ).on( 'keydown', function( event ) {
     280                    event.keyCode === 13 && editor.execCommand( 'wp_link_apply' );
    122281                } );
     282            }
     283        } );
     284
     285        editor.on( 'wptoolbar', function( event ) {
     286            var anchor = editor.dom.getParent( event.element, 'a' ),
     287                $anchor,
     288                href, edit;
     289
     290            if ( anchor ) {
     291                $anchor = editor.$( anchor );
     292                href = $anchor.attr( 'href' );
     293                edit = $anchor.attr( 'data-wp-edit' );
     294
     295                if ( href === '_wp_link_placeholder' || edit ) {
     296                    inputInstance.setURL( edit ? href : '' );
     297                    event.element = anchor;
     298                    event.toolbar = editToolbar;
     299                } else if ( href && ! $anchor.find( 'img' ).length ) {
     300                    previewInstance.setURL( href );
     301                    event.element = anchor;
     302                    event.toolbar = toolbar;
     303                }
    123304            }
    124305        } );
     
    136317        } );
    137318
    138         editor.on( 'preinit', function() {
    139             if ( editor.wp && editor.wp._createToolbar ) {
    140                 toolbar = editor.wp._createToolbar( [
    141                     'wp_link_preview',
    142                     'wp_link_edit',
    143                     'wp_link_remove'
    144                 ], true );
    145             }
     319        // Advanced, more, options?
     320        editor.addButton( 'wp_link_advanced', {
     321            tooltip: 'Advanced',
     322            icon: 'dashicon dashicons-admin-generic',
     323            onclick: function() {
     324                editor.execCommand( 'wp_link_apply' );
     325                window.wpLink && window.wpLink.open( editor.id );
     326            }
     327        } );
     328
     329        editor.addButton( 'wp_link_apply', {
     330            tooltip: 'Apply',
     331            icon: 'dashicon dashicons-editor-break',
     332            cmd: 'wp_link_apply',
     333            classes: 'widget btn primary'
    146334        } );
    147335    } );
Note: See TracChangeset for help on using the changeset viewer.