WordPress.org

Make WordPress Core

Ticket #18423: 18423.diff

File 18423.diff, 13.7 KB (added by mitchoyoshitaka, 4 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'),