[ Index ]

PHP Cross Reference of WordPress

title

Body

[close]

/wp-includes/js/ -> wplink.js (source)

   1  /**
   2   * @output wp-includes/js/wplink.js
   3   */
   4  
   5   /* global wpLink */
   6  
   7  ( function( $, wpLinkL10n, wp ) {
   8      var editor, searchTimer, River, Query, correctedURL,
   9          emailRegexp = /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,63}$/i,
  10          urlRegexp = /^(https?|ftp):\/\/[A-Z0-9.-]+\.[A-Z]{2,63}[^ "]*$/i,
  11          inputs = {},
  12          rivers = {},
  13          isTouch = ( 'ontouchend' in document );
  14  
  15  	function getLink() {
  16          if ( editor ) {
  17              return editor.$( 'a[data-wplink-edit="true"]' );
  18          }
  19  
  20          return null;
  21      }
  22  
  23      window.wpLink = {
  24          timeToTriggerRiver: 150,
  25          minRiverAJAXDuration: 200,
  26          riverBottomThreshold: 5,
  27          keySensitivity: 100,
  28          lastSearch: '',
  29          textarea: '',
  30          modalOpen: false,
  31  
  32          init: function() {
  33              inputs.wrap = $('#wp-link-wrap');
  34              inputs.dialog = $( '#wp-link' );
  35              inputs.backdrop = $( '#wp-link-backdrop' );
  36              inputs.submit = $( '#wp-link-submit' );
  37              inputs.close = $( '#wp-link-close' );
  38  
  39              // Input.
  40              inputs.text = $( '#wp-link-text' );
  41              inputs.url = $( '#wp-link-url' );
  42              inputs.nonce = $( '#_ajax_linking_nonce' );
  43              inputs.openInNewTab = $( '#wp-link-target' );
  44              inputs.search = $( '#wp-link-search' );
  45  
  46              // Build rivers.
  47              rivers.search = new River( $( '#search-results' ) );
  48              rivers.recent = new River( $( '#most-recent-results' ) );
  49              rivers.elements = inputs.dialog.find( '.query-results' );
  50  
  51              // Get search notice text.
  52              inputs.queryNotice = $( '#query-notice-message' );
  53              inputs.queryNoticeTextDefault = inputs.queryNotice.find( '.query-notice-default' );
  54              inputs.queryNoticeTextHint = inputs.queryNotice.find( '.query-notice-hint' );
  55  
  56              // Bind event handlers.
  57              inputs.dialog.keydown( wpLink.keydown );
  58              inputs.dialog.keyup( wpLink.keyup );
  59              inputs.submit.click( function( event ) {
  60                  event.preventDefault();
  61                  wpLink.update();
  62              });
  63  
  64              inputs.close.add( inputs.backdrop ).add( '#wp-link-cancel button' ).click( function( event ) {
  65                  event.preventDefault();
  66                  wpLink.close();
  67              });
  68  
  69              rivers.elements.on( 'river-select', wpLink.updateFields );
  70  
  71              // Display 'hint' message when search field or 'query-results' box are focused.
  72              inputs.search.on( 'focus.wplink', function() {
  73                  inputs.queryNoticeTextDefault.hide();
  74                  inputs.queryNoticeTextHint.removeClass( 'screen-reader-text' ).show();
  75              } ).on( 'blur.wplink', function() {
  76                  inputs.queryNoticeTextDefault.show();
  77                  inputs.queryNoticeTextHint.addClass( 'screen-reader-text' ).hide();
  78              } );
  79  
  80              inputs.search.on( 'keyup input', function() {
  81                  window.clearTimeout( searchTimer );
  82                  searchTimer = window.setTimeout( function() {
  83                      wpLink.searchInternalLinks();
  84                  }, 500 );
  85              });
  86  
  87              inputs.url.on( 'paste', function() {
  88                  setTimeout( wpLink.correctURL, 0 );
  89              } );
  90  
  91              inputs.url.on( 'blur', wpLink.correctURL );
  92          },
  93  
  94          // If URL wasn't corrected last time and doesn't start with http:, https:, ? # or /, prepend http://.
  95          correctURL: function () {
  96              var url = $.trim( inputs.url.val() );
  97  
  98              if ( url && correctedURL !== url && ! /^(?:[a-z]+:|#|\?|\.|\/)/.test( url ) ) {
  99                  inputs.url.val( 'http://' + url );
 100                  correctedURL = url;
 101              }
 102          },
 103  
 104          open: function( editorId, url, text ) {
 105              var ed,
 106                  $body = $( document.body );
 107  
 108              $body.addClass( 'modal-open' );
 109              wpLink.modalOpen = true;
 110  
 111              wpLink.range = null;
 112  
 113              if ( editorId ) {
 114                  window.wpActiveEditor = editorId;
 115              }
 116  
 117              if ( ! window.wpActiveEditor ) {
 118                  return;
 119              }
 120  
 121              this.textarea = $( '#' + window.wpActiveEditor ).get( 0 );
 122  
 123              if ( typeof window.tinymce !== 'undefined' ) {
 124                  // Make sure the link wrapper is the last element in the body,
 125                  // or the inline editor toolbar may show above the backdrop.
 126                  $body.append( inputs.backdrop, inputs.wrap );
 127  
 128                  ed = window.tinymce.get( window.wpActiveEditor );
 129  
 130                  if ( ed && ! ed.isHidden() ) {
 131                      editor = ed;
 132                  } else {
 133                      editor = null;
 134                  }
 135              }
 136  
 137              if ( ! wpLink.isMCE() && document.selection ) {
 138                  this.textarea.focus();
 139                  this.range = document.selection.createRange();
 140              }
 141  
 142              inputs.wrap.show();
 143              inputs.backdrop.show();
 144  
 145              wpLink.refresh( url, text );
 146  
 147              $( document ).trigger( 'wplink-open', inputs.wrap );
 148          },
 149  
 150          isMCE: function() {
 151              return editor && ! editor.isHidden();
 152          },
 153  
 154          refresh: function( url, text ) {
 155              var linkText = '';
 156  
 157              // Refresh rivers (clear links, check visibility).
 158              rivers.search.refresh();
 159              rivers.recent.refresh();
 160  
 161              if ( wpLink.isMCE() ) {
 162                  wpLink.mceRefresh( url, text );
 163              } else {
 164                  // For the Text editor the "Link text" field is always shown.
 165                  if ( ! inputs.wrap.hasClass( 'has-text-field' ) ) {
 166                      inputs.wrap.addClass( 'has-text-field' );
 167                  }
 168  
 169                  if ( document.selection ) {
 170                      // Old IE.
 171                      linkText = document.selection.createRange().text || text || '';
 172                  } else if ( typeof this.textarea.selectionStart !== 'undefined' &&
 173                      ( this.textarea.selectionStart !== this.textarea.selectionEnd ) ) {
 174                      // W3C.
 175                      text = this.textarea.value.substring( this.textarea.selectionStart, this.textarea.selectionEnd ) || text || '';
 176                  }
 177  
 178                  inputs.text.val( text );
 179                  wpLink.setDefaultValues();
 180              }
 181  
 182              if ( isTouch ) {
 183                  // Close the onscreen keyboard.
 184                  inputs.url.focus().blur();
 185              } else {
 186                  /*
 187                   * Focus the URL field and highlight its contents.
 188                   * If this is moved above the selection changes,
 189                   * IE will show a flashing cursor over the dialog.
 190                   */
 191                  window.setTimeout( function() {
 192                      inputs.url[0].select();
 193                      inputs.url.focus();
 194                  } );
 195              }
 196  
 197              // Load the most recent results if this is the first time opening the panel.
 198              if ( ! rivers.recent.ul.children().length ) {
 199                  rivers.recent.ajax();
 200              }
 201  
 202              correctedURL = inputs.url.val().replace( /^http:\/\//, '' );
 203          },
 204  
 205          hasSelectedText: function( linkNode ) {
 206              var node, nodes, i, html = editor.selection.getContent();
 207  
 208              // Partial html and not a fully selected anchor element.
 209              if ( /</.test( html ) && ( ! /^<a [^>]+>[^<]+<\/a>$/.test( html ) || html.indexOf('href=') === -1 ) ) {
 210                  return false;
 211              }
 212  
 213              if ( linkNode.length ) {
 214                  nodes = linkNode[0].childNodes;
 215  
 216                  if ( ! nodes || ! nodes.length ) {
 217                      return false;
 218                  }
 219  
 220                  for ( i = nodes.length - 1; i >= 0; i-- ) {
 221                      node = nodes[i];
 222  
 223                      if ( node.nodeType != 3 && ! window.tinymce.dom.BookmarkManager.isBookmarkNode( node ) ) {
 224                          return false;
 225                      }
 226                  }
 227              }
 228  
 229              return true;
 230          },
 231  
 232          mceRefresh: function( searchStr, text ) {
 233              var linkText, href,
 234                  linkNode = getLink(),
 235                  onlyText = this.hasSelectedText( linkNode );
 236  
 237              if ( linkNode.length ) {
 238                  linkText = linkNode.text();
 239                  href = linkNode.attr( 'href' );
 240  
 241                  if ( ! $.trim( linkText ) ) {
 242                      linkText = text || '';
 243                  }
 244  
 245                  if ( searchStr && ( urlRegexp.test( searchStr ) || emailRegexp.test( searchStr ) ) ) {
 246                      href = searchStr;
 247                  }
 248  
 249                  if ( href !== '_wp_link_placeholder' ) {
 250                      inputs.url.val( href );
 251                      inputs.openInNewTab.prop( 'checked', '_blank' === linkNode.attr( 'target' ) );
 252                      inputs.submit.val( wpLinkL10n.update );
 253                  } else {
 254                      this.setDefaultValues( linkText );
 255                  }
 256  
 257                  if ( searchStr && searchStr !== href ) {
 258                      // The user has typed something in the inline dialog. Trigger a search with it.
 259                      inputs.search.val( searchStr );
 260                  } else {
 261                      inputs.search.val( '' );
 262                  }
 263  
 264                  // Always reset the search.
 265                  window.setTimeout( function() {
 266                      wpLink.searchInternalLinks();
 267                  } );
 268              } else {
 269                  linkText = editor.selection.getContent({ format: 'text' }) || text || '';
 270                  this.setDefaultValues( linkText );
 271              }
 272  
 273              if ( onlyText ) {
 274                  inputs.text.val( linkText );
 275                  inputs.wrap.addClass( 'has-text-field' );
 276              } else {
 277                  inputs.text.val( '' );
 278                  inputs.wrap.removeClass( 'has-text-field' );
 279              }
 280          },
 281  
 282          close: function( reset ) {
 283              $( document.body ).removeClass( 'modal-open' );
 284              wpLink.modalOpen = false;
 285  
 286              if ( reset !== 'noReset' ) {
 287                  if ( ! wpLink.isMCE() ) {
 288                      wpLink.textarea.focus();
 289  
 290                      if ( wpLink.range ) {
 291                          wpLink.range.moveToBookmark( wpLink.range.getBookmark() );
 292                          wpLink.range.select();
 293                      }
 294                  } else {
 295                      if ( editor.plugins.wplink ) {
 296                          editor.plugins.wplink.close();
 297                      }
 298  
 299                      editor.focus();
 300                  }
 301              }
 302  
 303              inputs.backdrop.hide();
 304              inputs.wrap.hide();
 305  
 306              correctedURL = false;
 307  
 308              $( document ).trigger( 'wplink-close', inputs.wrap );
 309          },
 310  
 311          getAttrs: function() {
 312              wpLink.correctURL();
 313  
 314              return {
 315                  href: $.trim( inputs.url.val() ),
 316                  target: inputs.openInNewTab.prop( 'checked' ) ? '_blank' : null
 317              };
 318          },
 319  
 320          buildHtml: function(attrs) {
 321              var html = '<a href="' + attrs.href + '"';
 322  
 323              if ( attrs.target ) {
 324                  html += ' rel="noopener" target="' + attrs.target + '"';
 325              }
 326  
 327              return html + '>';
 328          },
 329  
 330          update: function() {
 331              if ( wpLink.isMCE() ) {
 332                  wpLink.mceUpdate();
 333              } else {
 334                  wpLink.htmlUpdate();
 335              }
 336          },
 337  
 338          htmlUpdate: function() {
 339              var attrs, text, html, begin, end, cursor, selection,
 340                  textarea = wpLink.textarea;
 341  
 342              if ( ! textarea ) {
 343                  return;
 344              }
 345  
 346              attrs = wpLink.getAttrs();
 347              text = inputs.text.val();
 348  
 349              var parser = document.createElement( 'a' );
 350              parser.href = attrs.href;
 351  
 352              if ( 'javascript:' === parser.protocol || 'data:' === parser.protocol ) { // jshint ignore:line
 353                  attrs.href = '';
 354              }
 355  
 356              // If there's no href, return.
 357              if ( ! attrs.href ) {
 358                  return;
 359              }
 360  
 361              html = wpLink.buildHtml(attrs);
 362  
 363              // Insert HTML.
 364              if ( document.selection && wpLink.range ) {
 365                  // IE.
 366                  // Note: If no text is selected, IE will not place the cursor
 367                  // inside the closing tag.
 368                  textarea.focus();
 369                  wpLink.range.text = html + ( text || wpLink.range.text ) + '</a>';
 370                  wpLink.range.moveToBookmark( wpLink.range.getBookmark() );
 371                  wpLink.range.select();
 372  
 373                  wpLink.range = null;
 374              } else if ( typeof textarea.selectionStart !== 'undefined' ) {
 375                  // W3C.
 376                  begin = textarea.selectionStart;
 377                  end = textarea.selectionEnd;
 378                  selection = text || textarea.value.substring( begin, end );
 379                  html = html + selection + '</a>';
 380                  cursor = begin + html.length;
 381  
 382                  // If no text is selected, place the cursor inside the closing tag.
 383                  if ( begin === end && ! selection ) {
 384                      cursor -= 4;
 385                  }
 386  
 387                  textarea.value = (
 388                      textarea.value.substring( 0, begin ) +
 389                      html +
 390                      textarea.value.substring( end, textarea.value.length )
 391                  );
 392  
 393                  // Update cursor position.
 394                  textarea.selectionStart = textarea.selectionEnd = cursor;
 395              }
 396  
 397              wpLink.close();
 398              textarea.focus();
 399              $( textarea ).trigger( 'change' );
 400  
 401              // Audible confirmation message when a link has been inserted in the Editor.
 402              wp.a11y.speak( wpLinkL10n.linkInserted );
 403          },
 404  
 405          mceUpdate: function() {
 406              var attrs = wpLink.getAttrs(),
 407                  $link, text, hasText;
 408  
 409              var parser = document.createElement( 'a' );
 410              parser.href = attrs.href;
 411  
 412              if ( 'javascript:' === parser.protocol || 'data:' === parser.protocol ) { // jshint ignore:line
 413                  attrs.href = '';
 414              }
 415  
 416              if ( ! attrs.href ) {
 417                  editor.execCommand( 'unlink' );
 418                  wpLink.close();
 419                  return;
 420              }
 421  
 422              $link = getLink();
 423  
 424              editor.undoManager.transact( function() {
 425                  if ( ! $link.length ) {
 426                      editor.execCommand( 'mceInsertLink', false, { href: '_wp_link_placeholder', 'data-wp-temp-link': 1 } );
 427                      $link = editor.$( 'a[data-wp-temp-link="1"]' ).removeAttr( 'data-wp-temp-link' );
 428                      hasText = $.trim( $link.text() );
 429                  }
 430  
 431                  if ( ! $link.length ) {
 432                      editor.execCommand( 'unlink' );
 433                  } else {
 434                      if ( inputs.wrap.hasClass( 'has-text-field' ) ) {
 435                          text = inputs.text.val();
 436  
 437                          if ( text ) {
 438                              $link.text( text );
 439                          } else if ( ! hasText ) {
 440                              $link.text( attrs.href );
 441                          }
 442                      }
 443  
 444                      attrs['data-wplink-edit'] = null;
 445                      attrs['data-mce-href'] = attrs.href;
 446                      $link.attr( attrs );
 447                  }
 448              } );
 449  
 450              wpLink.close( 'noReset' );
 451              editor.focus();
 452  
 453              if ( $link.length ) {
 454                  editor.selection.select( $link[0] );
 455  
 456                  if ( editor.plugins.wplink ) {
 457                      editor.plugins.wplink.checkLink( $link[0] );
 458                  }
 459              }
 460  
 461              editor.nodeChanged();
 462  
 463              // Audible confirmation message when a link has been inserted in the Editor.
 464              wp.a11y.speak( wpLinkL10n.linkInserted );
 465          },
 466  
 467          updateFields: function( e, li ) {
 468              inputs.url.val( li.children( '.item-permalink' ).val() );
 469  
 470              if ( inputs.wrap.hasClass( 'has-text-field' ) && ! inputs.text.val() ) {
 471                  inputs.text.val( li.children( '.item-title' ).text() );
 472              }
 473          },
 474  
 475          getUrlFromSelection: function( selection ) {
 476              if ( ! selection ) {
 477                  if ( this.isMCE() ) {
 478                      selection = editor.selection.getContent({ format: 'text' });
 479                  } else if ( document.selection && wpLink.range ) {
 480                      selection = wpLink.range.text;
 481                  } else if ( typeof this.textarea.selectionStart !== 'undefined' ) {
 482                      selection = this.textarea.value.substring( this.textarea.selectionStart, this.textarea.selectionEnd );
 483                  }
 484              }
 485  
 486              selection = $.trim( selection );
 487  
 488              if ( selection && emailRegexp.test( selection ) ) {
 489                  // Selection is email address.
 490                  return 'mailto:' + selection;
 491              } else if ( selection && urlRegexp.test( selection ) ) {
 492                  // Selection is URL.
 493                  return selection.replace( /&amp;|&#0?38;/gi, '&' );
 494              }
 495  
 496              return '';
 497          },
 498  
 499          setDefaultValues: function( selection ) {
 500              inputs.url.val( this.getUrlFromSelection( selection ) );
 501  
 502              // Empty the search field and swap the "rivers".
 503              inputs.search.val('');
 504              wpLink.searchInternalLinks();
 505  
 506              // Update save prompt.
 507              inputs.submit.val( wpLinkL10n.save );
 508          },
 509  
 510          searchInternalLinks: function() {
 511              var waiting,
 512                  search = inputs.search.val() || '',
 513                  minInputLength = parseInt( wpLinkL10n.minInputLength, 10 ) || 3;
 514  
 515              if ( search.length >= minInputLength ) {
 516                  rivers.recent.hide();
 517                  rivers.search.show();
 518  
 519                  // Don't search if the keypress didn't change the title.
 520                  if ( wpLink.lastSearch == search )
 521                      return;
 522  
 523                  wpLink.lastSearch = search;
 524                  waiting = inputs.search.parent().find( '.spinner' ).addClass( 'is-active' );
 525  
 526                  rivers.search.change( search );
 527                  rivers.search.ajax( function() {
 528                      waiting.removeClass( 'is-active' );
 529                  });
 530              } else {
 531                  rivers.search.hide();
 532                  rivers.recent.show();
 533              }
 534          },
 535  
 536          next: function() {
 537              rivers.search.next();
 538              rivers.recent.next();
 539          },
 540  
 541          prev: function() {
 542              rivers.search.prev();
 543              rivers.recent.prev();
 544          },
 545  
 546          keydown: function( event ) {
 547              var fn, id;
 548  
 549              // Escape key.
 550              if ( 27 === event.keyCode ) {
 551                  wpLink.close();
 552                  event.stopImmediatePropagation();
 553              // Tab key.
 554              } else if ( 9 === event.keyCode ) {
 555                  id = event.target.id;
 556  
 557                  // wp-link-submit must always be the last focusable element in the dialog.
 558                  // Following focusable elements will be skipped on keyboard navigation.
 559                  if ( id === 'wp-link-submit' && ! event.shiftKey ) {
 560                      inputs.close.focus();
 561                      event.preventDefault();
 562                  } else if ( id === 'wp-link-close' && event.shiftKey ) {
 563                      inputs.submit.focus();
 564                      event.preventDefault();
 565                  }
 566              }
 567  
 568              // Up Arrow and Down Arrow keys.
 569              if ( event.shiftKey || ( 38 !== event.keyCode && 40 !== event.keyCode ) ) {
 570                  return;
 571              }
 572  
 573              if ( document.activeElement &&
 574                  ( document.activeElement.id === 'link-title-field' || document.activeElement.id === 'url-field' ) ) {
 575                  return;
 576              }
 577  
 578              // Up Arrow key.
 579              fn = 38 === event.keyCode ? 'prev' : 'next';
 580              clearInterval( wpLink.keyInterval );
 581              wpLink[ fn ]();
 582              wpLink.keyInterval = setInterval( wpLink[ fn ], wpLink.keySensitivity );
 583              event.preventDefault();
 584          },
 585  
 586          keyup: function( event ) {
 587              // Up Arrow and Down Arrow keys.
 588              if ( 38 === event.keyCode || 40 === event.keyCode ) {
 589                  clearInterval( wpLink.keyInterval );
 590                  event.preventDefault();
 591              }
 592          },
 593  
 594          delayedCallback: function( func, delay ) {
 595              var timeoutTriggered, funcTriggered, funcArgs, funcContext;
 596  
 597              if ( ! delay )
 598                  return func;
 599  
 600              setTimeout( function() {
 601                  if ( funcTriggered )
 602                      return func.apply( funcContext, funcArgs );
 603                  // Otherwise, wait.
 604                  timeoutTriggered = true;
 605              }, delay );
 606  
 607              return function() {
 608                  if ( timeoutTriggered )
 609                      return func.apply( this, arguments );
 610                  // Otherwise, wait.
 611                  funcArgs = arguments;
 612                  funcContext = this;
 613                  funcTriggered = true;
 614              };
 615          }
 616      };
 617  
 618      River = function( element, search ) {
 619          var self = this;
 620          this.element = element;
 621          this.ul = element.children( 'ul' );
 622          this.contentHeight = element.children( '#link-selector-height' );
 623          this.waiting = element.find('.river-waiting');
 624  
 625          this.change( search );
 626          this.refresh();
 627  
 628          $( '#wp-link .query-results, #wp-link #link-selector' ).scroll( function() {
 629              self.maybeLoad();
 630          });
 631          element.on( 'click', 'li', function( event ) {
 632              self.select( $( this ), event );
 633          });
 634      };
 635  
 636      $.extend( River.prototype, {
 637          refresh: function() {
 638              this.deselect();
 639              this.visible = this.element.is( ':visible' );
 640          },
 641          show: function() {
 642              if ( ! this.visible ) {
 643                  this.deselect();
 644                  this.element.show();
 645                  this.visible = true;
 646              }
 647          },
 648          hide: function() {
 649              this.element.hide();
 650              this.visible = false;
 651          },
 652          // Selects a list item and triggers the river-select event.
 653          select: function( li, event ) {
 654              var liHeight, elHeight, liTop, elTop;
 655  
 656              if ( li.hasClass( 'unselectable' ) || li == this.selected )
 657                  return;
 658  
 659              this.deselect();
 660              this.selected = li.addClass( 'selected' );
 661              // Make sure the element is visible.
 662              liHeight = li.outerHeight();
 663              elHeight = this.element.height();
 664              liTop = li.position().top;
 665              elTop = this.element.scrollTop();
 666  
 667              if ( liTop < 0 ) // Make first visible element.
 668                  this.element.scrollTop( elTop + liTop );
 669              else if ( liTop + liHeight > elHeight ) // Make last visible element.
 670                  this.element.scrollTop( elTop + liTop - elHeight + liHeight );
 671  
 672              // Trigger the river-select event.
 673              this.element.trigger( 'river-select', [ li, event, this ] );
 674          },
 675          deselect: function() {
 676              if ( this.selected )
 677                  this.selected.removeClass( 'selected' );
 678              this.selected = false;
 679          },
 680          prev: function() {
 681              if ( ! this.visible )
 682                  return;
 683  
 684              var to;
 685              if ( this.selected ) {
 686                  to = this.selected.prev( 'li' );
 687                  if ( to.length )
 688                      this.select( to );
 689              }
 690          },
 691          next: function() {
 692              if ( ! this.visible )
 693                  return;
 694  
 695              var to = this.selected ? this.selected.next( 'li' ) : $( 'li:not(.unselectable):first', this.element );
 696              if ( to.length )
 697                  this.select( to );
 698          },
 699          ajax: function( callback ) {
 700              var self = this,
 701                  delay = this.query.page == 1 ? 0 : wpLink.minRiverAJAXDuration,
 702                  response = wpLink.delayedCallback( function( results, params ) {
 703                      self.process( results, params );
 704                      if ( callback )
 705                          callback( results, params );
 706                  }, delay );
 707  
 708              this.query.ajax( response );
 709          },
 710          change: function( search ) {
 711              if ( this.query && this._search == search )
 712                  return;
 713  
 714              this._search = search;
 715              this.query = new Query( search );
 716              this.element.scrollTop( 0 );
 717          },
 718          process: function( results, params ) {
 719              var list = '', alt = true, classes = '',
 720                  firstPage = params.page == 1;
 721  
 722              if ( ! results ) {
 723                  if ( firstPage ) {
 724                      list += '<li class="unselectable no-matches-found"><span class="item-title"><em>' +
 725                          wpLinkL10n.noMatchesFound + '</em></span></li>';
 726                  }
 727              } else {
 728                  $.each( results, function() {
 729                      classes = alt ? 'alternate' : '';
 730                      classes += this.title ? '' : ' no-title';
 731                      list += classes ? '<li class="' + classes + '">' : '<li>';
 732                      list += '<input type="hidden" class="item-permalink" value="' + this.permalink + '" />';
 733                      list += '<span class="item-title">';
 734                      list += this.title ? this.title : wpLinkL10n.noTitle;
 735                      list += '</span><span class="item-info">' + this.info + '</span></li>';
 736                      alt = ! alt;
 737                  });
 738              }
 739  
 740              this.ul[ firstPage ? 'html' : 'append' ]( list );
 741          },
 742          maybeLoad: function() {
 743              var self = this,
 744                  el = this.element,
 745                  bottom = el.scrollTop() + el.height();
 746  
 747              if ( ! this.query.ready() || bottom < this.contentHeight.height() - wpLink.riverBottomThreshold )
 748                  return;
 749  
 750              setTimeout(function() {
 751                  var newTop = el.scrollTop(),
 752                      newBottom = newTop + el.height();
 753  
 754                  if ( ! self.query.ready() || newBottom < self.contentHeight.height() - wpLink.riverBottomThreshold )
 755                      return;
 756  
 757                  self.waiting.addClass( 'is-active' );
 758                  el.scrollTop( newTop + self.waiting.outerHeight() );
 759  
 760                  self.ajax( function() {
 761                      self.waiting.removeClass( 'is-active' );
 762                  });
 763              }, wpLink.timeToTriggerRiver );
 764          }
 765      });
 766  
 767      Query = function( search ) {
 768          this.page = 1;
 769          this.allLoaded = false;
 770          this.querying = false;
 771          this.search = search;
 772      };
 773  
 774      $.extend( Query.prototype, {
 775          ready: function() {
 776              return ! ( this.querying || this.allLoaded );
 777          },
 778          ajax: function( callback ) {
 779              var self = this,
 780                  query = {
 781                      action : 'wp-link-ajax',
 782                      page : this.page,
 783                      '_ajax_linking_nonce' : inputs.nonce.val()
 784                  };
 785  
 786              if ( this.search )
 787                  query.search = this.search;
 788  
 789              this.querying = true;
 790  
 791              $.post( window.ajaxurl, query, function( r ) {
 792                  self.page++;
 793                  self.querying = false;
 794                  self.allLoaded = ! r;
 795                  callback( r, query );
 796              }, 'json' );
 797          }
 798      });
 799  
 800      $( document ).ready( wpLink.init );
 801  })( jQuery, window.wpLinkL10n, window.wp );


Generated: Wed Aug 12 01:00:03 2020 Cross-referenced by PHPXref 0.7.1