WordPress.org

Make WordPress Core

Ticket #18423: 18423.diff

File 18423.diff, 13.7 KB (added by mitchoyoshitaka, 7 years ago)

Patch v1, refactored so they're in wp.lookup.Query and wp.lookup.River. Also introduces wp.utils, but this should probably be moved out into a separate file in the near future.

  • wp-includes/js/wplink.dev.js

     
    11var wpLink;
    22
    33(function($){
    4         var inputs = {}, rivers = {}, ed, River, Query;
     4        var ed, inputs = {}, rivers = {};
    55
    66        wpLink = {
    7                 timeToTriggerRiver: 150,
    8                 minRiverAJAXDuration: 200,
    9                 riverBottomThreshold: 5,
    107                keySensitivity: 100,
    118                lastSearch: '',
    129                textarea: '',
    1310
    1411                init : function() {
     12                        var queryArgs;
     13               
    1514                        inputs.dialog = $('#wp-link');
    1615                        inputs.submit = $('#wp-link-submit');
    1716                        // URL
     
    2221                        inputs.openInNewTab = $('#link-target-checkbox');
    2322                        inputs.search = $('#search-field');
    2423                        // Build Rivers
    25                         rivers.search = new River( $('#search-results') );
    26                         rivers.recent = new River( $('#most-recent-results') );
     24                        queryArgs = {
     25                                action : 'wp-link-ajax',
     26                                '_ajax_linking_nonce' : $('#_ajax_linking_nonce').val()
     27                        };
     28                        rivers.search = new wp.lookup.River( $('#search-results'), null, queryArgs );
     29                        rivers.recent = new wp.lookup.River( $('#most-recent-results'), null, queryArgs );
     30                        rivers.search.l10n = rivers.recent.l10n = wpLinkL10n;
    2731                        rivers.elements = $('.query-results', inputs.dialog);
    2832
    2933                        // Bind event handlers
     
    357361                        event.preventDefault();
    358362                },
    359363
    360                 delayedCallback : function( func, delay ) {
    361                         var timeoutTriggered, funcTriggered, funcArgs, funcContext;
    362 
    363                         if ( ! delay )
    364                                 return func;
    365 
    366                         setTimeout( function() {
    367                                 if ( funcTriggered )
    368                                         return func.apply( funcContext, funcArgs );
    369                                 // Otherwise, wait.
    370                                 timeoutTriggered = true;
    371                         }, delay);
    372 
    373                         return function() {
    374                                 if ( timeoutTriggered )
    375                                         return func.apply( this, arguments );
    376                                 // Otherwise, wait.
    377                                 funcArgs = arguments;
    378                                 funcContext = this;
    379                                 funcTriggered = true;
    380                         };
    381                 },
    382 
    383364                toggleInternalLinking : function( event ) {
    384365                        var panel = $('#search-panel'),
    385366                                widget = inputs.dialog.wpdialog('widget'),
     
    410391                }
    411392        }
    412393
    413         River = function( element, search ) {
    414                 var self = this;
    415                 this.element = element;
    416                 this.ul = element.children('ul');
    417                 this.waiting = element.find('.river-waiting');
    418 
    419                 this.change( search );
    420                 this.refresh();
    421 
    422                 element.scroll( function(){ self.maybeLoad(); });
    423                 element.delegate('li', 'click', function(e){ self.select( $(this), e ); });
    424         };
    425 
    426         $.extend( River.prototype, {
    427                 refresh: function() {
    428                         this.deselect();
    429                         this.visible = this.element.is(':visible');
    430                 },
    431                 show: function() {
    432                         if ( ! this.visible ) {
    433                                 this.deselect();
    434                                 this.element.show();
    435                                 this.visible = true;
    436                         }
    437                 },
    438                 hide: function() {
    439                         this.element.hide();
    440                         this.visible = false;
    441                 },
    442                 // Selects a list item and triggers the river-select event.
    443                 select: function( li, event ) {
    444                         var liHeight, elHeight, liTop, elTop;
    445 
    446                         if ( li.hasClass('unselectable') || li == this.selected )
    447                                 return;
    448 
    449                         this.deselect();
    450                         this.selected = li.addClass('selected');
    451                         // Make sure the element is visible
    452                         liHeight = li.outerHeight();
    453                         elHeight = this.element.height();
    454                         liTop = li.position().top;
    455                         elTop = this.element.scrollTop();
    456 
    457                         if ( liTop < 0 ) // Make first visible element
    458                                 this.element.scrollTop( elTop + liTop );
    459                         else if ( liTop + liHeight > elHeight ) // Make last visible element
    460                                 this.element.scrollTop( elTop + liTop - elHeight + liHeight );
    461 
    462                         // Trigger the river-select event
    463                         this.element.trigger('river-select', [ li, event, this ]);
    464                 },
    465                 deselect: function() {
    466                         if ( this.selected )
    467                                 this.selected.removeClass('selected');
    468                         this.selected = false;
    469                 },
    470                 prev: function() {
    471                         if ( ! this.visible )
    472                                 return;
    473 
    474                         var to;
    475                         if ( this.selected ) {
    476                                 to = this.selected.prev('li');
    477                                 if ( to.length )
    478                                         this.select( to );
    479                         }
    480                 },
    481                 next: function() {
    482                         if ( ! this.visible )
    483                                 return;
    484 
    485                         var to = this.selected ? this.selected.next('li') : $('li:not(.unselectable):first', this.element);
    486                         if ( to.length )
    487                                 this.select( to );
    488                 },
    489                 ajax: function( callback ) {
    490                         var self = this,
    491                                 delay = this.query.page == 1 ? 0 : wpLink.minRiverAJAXDuration,
    492                                 response = wpLink.delayedCallback( function( results, params ) {
    493                                         self.process( results, params );
    494                                         if ( callback )
    495                                                 callback( results, params );
    496                                 }, delay );
    497 
    498                         this.query.ajax( response );
    499                 },
    500                 change: function( search ) {
    501                         if ( this.query && this._search == search )
    502                                 return;
    503 
    504                         this._search = search;
    505                         this.query = new Query( search );
    506                         this.element.scrollTop(0);
    507                 },
    508                 process: function( results, params ) {
    509                         var list = '', alt = true, classes = '',
    510                                 firstPage = params.page == 1;
    511 
    512                         if ( !results ) {
    513                                 if ( firstPage ) {
    514                                         list += '<li class="unselectable"><span class="item-title"><em>'
    515                                         + wpLinkL10n.noMatchesFound
    516                                         + '</em></span></li>';
    517                                 }
    518                         } else {
    519                                 $.each( results, function() {
    520                                         classes = alt ? 'alternate' : '';
    521                                         classes += this['title'] ? '' : ' no-title';
    522                                         list += classes ? '<li class="' + classes + '">' : '<li>';
    523                                         list += '<input type="hidden" class="item-permalink" value="' + this['permalink'] + '" />';
    524                                         list += '<span class="item-title">';
    525                                         list += this['title'] ? this['title'] : wpLinkL10n.noTitle;
    526                                         list += '</span><span class="item-info">' + this['info'] + '</span></li>';
    527                                         alt = ! alt;
    528                                 });
    529                         }
    530 
    531                         this.ul[ firstPage ? 'html' : 'append' ]( list );
    532                 },
    533                 maybeLoad: function() {
    534                         var self = this,
    535                                 el = this.element,
    536                                 bottom = el.scrollTop() + el.height();
    537 
    538                         if ( ! this.query.ready() || bottom < this.ul.height() - wpLink.riverBottomThreshold )
    539                                 return;
    540 
    541                         setTimeout(function() {
    542                                 var newTop = el.scrollTop(),
    543                                         newBottom = newTop + el.height();
    544 
    545                                 if ( ! self.query.ready() || newBottom < self.ul.height() - wpLink.riverBottomThreshold )
    546                                         return;
    547 
    548                                 self.waiting.show();
    549                                 el.scrollTop( newTop + self.waiting.outerHeight() );
    550 
    551                                 self.ajax( function() { self.waiting.hide(); });
    552                         }, wpLink.timeToTriggerRiver );
    553                 }
    554         });
    555 
    556         Query = function( search ) {
    557                 this.page = 1;
    558                 this.allLoaded = false;
    559                 this.querying = false;
    560                 this.search = search;
    561         };
    562 
    563         $.extend( Query.prototype, {
    564                 ready: function() {
    565                         return !( this.querying || this.allLoaded );
    566                 },
    567                 ajax: function( callback ) {
    568                         var self = this,
    569                                 query = {
    570                                         action : 'wp-link-ajax',
    571                                         page : this.page,
    572                                         '_ajax_linking_nonce' : $('#_ajax_linking_nonce').val()
    573                                 };
    574 
    575                         if ( this.search )
    576                                 query.search = this.search;
    577 
    578                         this.querying = true;
    579 
    580                         $.post( ajaxurl, query, function(r) {
    581                                 self.page++;
    582                                 self.querying = false;
    583                                 self.allLoaded = !r;
    584                                 callback( r, query );
    585                         }, "json" );
    586                 }
    587         });
    588 
    589394        $(document).ready( wpLink.init );
    590395})(jQuery);
  • wp-includes/js/wplookup.dev.js

     
     1(function() {
     2
     3var $ = jQuery;
     4if ( typeof window.wp === 'undefined' )
     5        window.wp = {};
     6
     7wp.utils = {
     8        delayedCallback : function( func, delay ) {
     9                var timeoutTriggered, funcTriggered, funcArgs, funcContext;
     10
     11                if ( ! delay )
     12                        return func;
     13
     14                setTimeout( function() {
     15                        if ( funcTriggered )
     16                                return func.apply( funcContext, funcArgs );
     17                        // Otherwise, wait.
     18                        timeoutTriggered = true;
     19                }, delay);
     20
     21                return function() {
     22                        if ( timeoutTriggered )
     23                                return func.apply( this, arguments );
     24                        // Otherwise, wait.
     25                        funcArgs = arguments;
     26                        funcContext = this;
     27                        funcTriggered = true;
     28                };
     29        }
     30}
     31
     32wp.lookup = {};
     33
     34// wp.lookup.River
     35// (currently private-ish; will probably be renamed)
     36//
     37// Constructor for "Rivers" which are dynamic search results UI.
     38// Descendant '.river-waiting' is used as an activity indicator.
     39//
     40// Parameters:
     41// - element, jQuery singleton for the results container
     42// - search, string
     43// - ajaxArgs, object passed to wp.lookup.Query objects, which ultimately
     44//   are passed as query arguments in the ajax request
     45
     46wp.lookup.River = function( element, search, ajaxArgs ) {
     47        var self = this;
     48        this.element = element;
     49        this.ul = element.children('ul');
     50        this.waiting = element.find('.river-waiting');
     51        this.url = ajaxurl; // @todo: add argument?
     52        this.ajaxArgs = ajaxArgs;
     53
     54        this.change( search );
     55        this.refresh();
     56
     57        element.scroll( function(){ self.maybeLoad(); });
     58        element.delegate('li', 'click', function(e){ self.select( $(this), e ); });
     59};
     60wp.lookup.River.prototype = {
     61        timeToTrigger: 150,
     62        bottomThreshold: 5,
     63        minAJAXDuration: 200,
     64        l10n: {},
     65
     66        refresh: function() {
     67                this.deselect();
     68                this.visible = this.element.is(':visible');
     69        },
     70        show: function() {
     71                if ( ! this.visible ) {
     72                        this.deselect();
     73                        this.element.show();
     74                        this.visible = true;
     75                }
     76        },
     77        hide: function() {
     78                this.element.hide();
     79                this.visible = false;
     80        },
     81        // Selects a list item and triggers the river-select event.
     82        select: function( li, event ) {
     83                var liHeight, elHeight, liTop, elTop;
     84
     85                if ( li.hasClass('unselectable') || li == this.selected )
     86                        return;
     87
     88                this.deselect();
     89                this.selected = li.addClass('selected');
     90                // Make sure the element is visible
     91                liHeight = li.outerHeight();
     92                elHeight = this.element.height();
     93                liTop = li.position().top;
     94                elTop = this.element.scrollTop();
     95
     96                if ( liTop < 0 ) // Make first visible element
     97                        this.element.scrollTop( elTop + liTop );
     98                else if ( liTop + liHeight > elHeight ) // Make last visible element
     99                        this.element.scrollTop( elTop + liTop - elHeight + liHeight );
     100
     101                // Trigger the river-select event
     102                this.element.trigger('river-select', [ li, event, this ]);
     103        },
     104        deselect: function() {
     105                if ( this.selected )
     106                        this.selected.removeClass('selected');
     107                this.selected = false;
     108        },
     109        prev: function() {
     110                if ( ! this.visible )
     111                        return;
     112
     113                var to;
     114                if ( this.selected ) {
     115                        to = this.selected.prev('li');
     116                        if ( to.length )
     117                                this.select( to );
     118                }
     119        },
     120        next: function() {
     121                if ( ! this.visible )
     122                        return;
     123
     124                var to = this.selected ? this.selected.next('li') : $('li:not(.unselectable):first', this.element);
     125                if ( to.length )
     126                        this.select( to );
     127        },
     128        ajax: function( callback ) {
     129                var self = this,
     130                        delay = this.query.page == 1 ? 0 : this.minAJAXDuration,
     131                        response = wp.utils.delayedCallback( function( results, params ) {
     132                                self.process( results, params );
     133                                if ( callback )
     134                                        callback( results, params );
     135                        }, delay );
     136
     137                this.query.ajax( response );
     138        },
     139        change: function( search ) {
     140                if ( this.query && this._search == search )
     141                        return;
     142
     143                var args = $.extend( { search: search }, this.ajaxArgs );
     144                this._search = search;
     145
     146                this.query = new wp.lookup.Query( this.url, args );
     147                this.element.scrollTop(0);
     148        },
     149        process: function( results, params ) {
     150                var firstPage = params.page == 1;
     151
     152                if ( !results ) {
     153                        if ( firstPage ) {
     154                                list = '<li class="unselectable"><span class="item-title"><em>'
     155                                + this.l10n.noMatchesFound
     156                                + '</em></span></li>';
     157                        }
     158                } else {
     159                        list = results.map( this.renderResult ).join('');
     160                }
     161
     162                this.ul[ firstPage ? 'html' : 'append' ]( list );
     163        },
     164       
     165        _alt: true,
     166        renderResult: function( item ) {
     167                var classes, list = '';
     168
     169                classes = this._alt ? 'alternate' : '';
     170                classes += item.title ? '' : ' no-title';
     171
     172                list += classes ? '<li class="' + classes + '">' : '<li>';
     173                list += '<input type="hidden" class="item-permalink" value="' + item.permalink + '" />';
     174                list += '<span class="item-title">';
     175                list += item.title ? item.title : this.l10n.noTitle;
     176                list += '</span><span class="item-info">' + item.info + '</span></li>';
     177
     178                this._alt = ! this._alt;
     179               
     180                return list;
     181        },
     182       
     183        maybeLoad: function() {
     184                var self = this,
     185                        el = this.element,
     186                        bottom = el.scrollTop() + el.height();
     187
     188                if ( ! this.query.ready() || bottom < this.ul.height() - this.bottomThreshold )
     189                        return;
     190
     191                setTimeout(function() {
     192                        var newTop = el.scrollTop(),
     193                                newBottom = newTop + el.height();
     194
     195                        if ( ! self.query.ready() || newBottom < self.ul.height() - this.bottomThreshold )
     196                                return;
     197
     198                        self.waiting.show();
     199                        el.scrollTop( newTop + self.waiting.outerHeight() );
     200
     201                        self.ajax( function() { self.waiting.hide(); });
     202                }, this.timeToTrigger );
     203        }
     204}
     205
     206wp.lookup.Query = function( url, ajaxArgs ) {
     207        this.page = 1;
     208        this.allLoaded = false;
     209        this.querying = false;
     210        this.ajaxArgs = ajaxArgs;
     211        this.url = url;
     212};
     213wp.lookup.Query.prototype = {
     214        ready: function() {
     215                return !( this.querying || this.allLoaded );
     216        },
     217        ajax: function( callback ) {
     218                var self = this,
     219                        query = $.extend( {}, this.ajaxArgs );
     220                query.page = this.page;
     221
     222                this.querying = true;
     223
     224                $.post( this.url, query, function(r) {
     225                        self.page++;
     226                        self.querying = false;
     227                        self.allLoaded = !r;
     228                        callback( r, query );
     229                }, "json" );
     230        }
     231}
     232
     233})();
     234 No newline at end of file
  • wp-includes/script-loader.php

     
    234234        $scripts->add( 'admin-bar', "/wp-includes/js/admin-bar$suffix.js", false, '20110801' );
    235235        $scripts->add_data( 'admin-bar', 'group', 1 );
    236236
    237         $scripts->add( 'wplink', "/wp-includes/js/wplink$suffix.js", array( 'jquery', 'wpdialogs' ), '20110802', 1 );
     237        $scripts->add( 'wplookup', "/wp-includes/js/wplookup$suffix.js", array( 'jquery' ), '20110814', 1 );
     238        $scripts->add( 'wplink', "/wp-includes/js/wplink$suffix.js", array( 'jquery', 'wpdialogs', 'wplookup' ), '20110802', 1 );
    238239        $scripts->add_script_data( 'wplink', 'wpLinkL10n', array(
    239240                'title' => __('Insert/edit link'),
    240241                'update' => __('Update'),