[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

Search

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.on( 'keydown', wpLink.keydown );
  58              inputs.dialog.on( 'keyup', wpLink.keyup );
  59              inputs.submit.on( 'click', function( event ) {
  60                  event.preventDefault();
  61                  wpLink.update();
  62              });
  63  
  64              inputs.close.add( inputs.backdrop ).add( '#wp-link-cancel button' ).on( '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 = inputs.url.val().trim();
  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.trigger( 'focus' ).trigger( '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.trigger( '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 ( ! linkText.trim() ) {
 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: inputs.url.val().trim(),
 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 = $link.text().trim();
 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 = selection || '';
 487              selection = selection.trim();
 488  
 489              if ( selection && emailRegexp.test( selection ) ) {
 490                  // Selection is email address.
 491                  return 'mailto:' + selection;
 492              } else if ( selection && urlRegexp.test( selection ) ) {
 493                  // Selection is URL.
 494                  return selection.replace( /&amp;|&#0?38;/gi, '&' );
 495              }
 496  
 497              return '';
 498          },
 499  
 500          setDefaultValues: function( selection ) {
 501              inputs.url.val( this.getUrlFromSelection( selection ) );
 502  
 503              // Empty the search field and swap the "rivers".
 504              inputs.search.val('');
 505              wpLink.searchInternalLinks();
 506  
 507              // Update save prompt.
 508              inputs.submit.val( wpLinkL10n.save );
 509          },
 510  
 511          searchInternalLinks: function() {
 512              var waiting,
 513                  search = inputs.search.val() || '',
 514                  minInputLength = parseInt( wpLinkL10n.minInputLength, 10 ) || 3;
 515  
 516              if ( search.length >= minInputLength ) {
 517                  rivers.recent.hide();
 518                  rivers.search.show();
 519  
 520                  // Don't search if the keypress didn't change the title.
 521                  if ( wpLink.lastSearch == search )
 522                      return;
 523  
 524                  wpLink.lastSearch = search;
 525                  waiting = inputs.search.parent().find( '.spinner' ).addClass( 'is-active' );
 526  
 527                  rivers.search.change( search );
 528                  rivers.search.ajax( function() {
 529                      waiting.removeClass( 'is-active' );
 530                  });
 531              } else {
 532                  rivers.search.hide();
 533                  rivers.recent.show();
 534              }
 535          },
 536  
 537          next: function() {
 538              rivers.search.next();
 539              rivers.recent.next();
 540          },
 541  
 542          prev: function() {
 543              rivers.search.prev();
 544              rivers.recent.prev();
 545          },
 546  
 547          keydown: function( event ) {
 548              var fn, id;
 549  
 550              // Escape key.
 551              if ( 27 === event.keyCode ) {
 552                  wpLink.close();
 553                  event.stopImmediatePropagation();
 554              // Tab key.
 555              } else if ( 9 === event.keyCode ) {
 556                  id = event.target.id;
 557  
 558                  // wp-link-submit must always be the last focusable element in the dialog.
 559                  // Following focusable elements will be skipped on keyboard navigation.
 560                  if ( id === 'wp-link-submit' && ! event.shiftKey ) {
 561                      inputs.close.trigger( 'focus' );
 562                      event.preventDefault();
 563                  } else if ( id === 'wp-link-close' && event.shiftKey ) {
 564                      inputs.submit.trigger( 'focus' );
 565                      event.preventDefault();
 566                  }
 567              }
 568  
 569              // Up Arrow and Down Arrow keys.
 570              if ( event.shiftKey || ( 38 !== event.keyCode && 40 !== event.keyCode ) ) {
 571                  return;
 572              }
 573  
 574              if ( document.activeElement &&
 575                  ( document.activeElement.id === 'link-title-field' || document.activeElement.id === 'url-field' ) ) {
 576                  return;
 577              }
 578  
 579              // Up Arrow key.
 580              fn = 38 === event.keyCode ? 'prev' : 'next';
 581              clearInterval( wpLink.keyInterval );
 582              wpLink[ fn ]();
 583              wpLink.keyInterval = setInterval( wpLink[ fn ], wpLink.keySensitivity );
 584              event.preventDefault();
 585          },
 586  
 587          keyup: function( event ) {
 588              // Up Arrow and Down Arrow keys.
 589              if ( 38 === event.keyCode || 40 === event.keyCode ) {
 590                  clearInterval( wpLink.keyInterval );
 591                  event.preventDefault();
 592              }
 593          },
 594  
 595          delayedCallback: function( func, delay ) {
 596              var timeoutTriggered, funcTriggered, funcArgs, funcContext;
 597  
 598              if ( ! delay )
 599                  return func;
 600  
 601              setTimeout( function() {
 602                  if ( funcTriggered )
 603                      return func.apply( funcContext, funcArgs );
 604                  // Otherwise, wait.
 605                  timeoutTriggered = true;
 606              }, delay );
 607  
 608              return function() {
 609                  if ( timeoutTriggered )
 610                      return func.apply( this, arguments );
 611                  // Otherwise, wait.
 612                  funcArgs = arguments;
 613                  funcContext = this;
 614                  funcTriggered = true;
 615              };
 616          }
 617      };
 618  
 619      River = function( element, search ) {
 620          var self = this;
 621          this.element = element;
 622          this.ul = element.children( 'ul' );
 623          this.contentHeight = element.children( '#link-selector-height' );
 624          this.waiting = element.find('.river-waiting');
 625  
 626          this.change( search );
 627          this.refresh();
 628  
 629          $( '#wp-link .query-results, #wp-link #link-selector' ).on( 'scroll', function() {
 630              self.maybeLoad();
 631          });
 632          element.on( 'click', 'li', function( event ) {
 633              self.select( $( this ), event );
 634          });
 635      };
 636  
 637      $.extend( River.prototype, {
 638          refresh: function() {
 639              this.deselect();
 640              this.visible = this.element.is( ':visible' );
 641          },
 642          show: function() {
 643              if ( ! this.visible ) {
 644                  this.deselect();
 645                  this.element.show();
 646                  this.visible = true;
 647              }
 648          },
 649          hide: function() {
 650              this.element.hide();
 651              this.visible = false;
 652          },
 653          // Selects a list item and triggers the river-select event.
 654          select: function( li, event ) {
 655              var liHeight, elHeight, liTop, elTop;
 656  
 657              if ( li.hasClass( 'unselectable' ) || li == this.selected )
 658                  return;
 659  
 660              this.deselect();
 661              this.selected = li.addClass( 'selected' );
 662              // Make sure the element is visible.
 663              liHeight = li.outerHeight();
 664              elHeight = this.element.height();
 665              liTop = li.position().top;
 666              elTop = this.element.scrollTop();
 667  
 668              if ( liTop < 0 ) // Make first visible element.
 669                  this.element.scrollTop( elTop + liTop );
 670              else if ( liTop + liHeight > elHeight ) // Make last visible element.
 671                  this.element.scrollTop( elTop + liTop - elHeight + liHeight );
 672  
 673              // Trigger the river-select event.
 674              this.element.trigger( 'river-select', [ li, event, this ] );
 675          },
 676          deselect: function() {
 677              if ( this.selected )
 678                  this.selected.removeClass( 'selected' );
 679              this.selected = false;
 680          },
 681          prev: function() {
 682              if ( ! this.visible )
 683                  return;
 684  
 685              var to;
 686              if ( this.selected ) {
 687                  to = this.selected.prev( 'li' );
 688                  if ( to.length )
 689                      this.select( to );
 690              }
 691          },
 692          next: function() {
 693              if ( ! this.visible )
 694                  return;
 695  
 696              var to = this.selected ? this.selected.next( 'li' ) : $( 'li:not(.unselectable):first', this.element );
 697              if ( to.length )
 698                  this.select( to );
 699          },
 700          ajax: function( callback ) {
 701              var self = this,
 702                  delay = this.query.page == 1 ? 0 : wpLink.minRiverAJAXDuration,
 703                  response = wpLink.delayedCallback( function( results, params ) {
 704                      self.process( results, params );
 705                      if ( callback )
 706                          callback( results, params );
 707                  }, delay );
 708  
 709              this.query.ajax( response );
 710          },
 711          change: function( search ) {
 712              if ( this.query && this._search == search )
 713                  return;
 714  
 715              this._search = search;
 716              this.query = new Query( search );
 717              this.element.scrollTop( 0 );
 718          },
 719          process: function( results, params ) {
 720              var list = '', alt = true, classes = '',
 721                  firstPage = params.page == 1;
 722  
 723              if ( ! results ) {
 724                  if ( firstPage ) {
 725                      list += '<li class="unselectable no-matches-found"><span class="item-title"><em>' +
 726                          wpLinkL10n.noMatchesFound + '</em></span></li>';
 727                  }
 728              } else {
 729                  $.each( results, function() {
 730                      classes = alt ? 'alternate' : '';
 731                      classes += this.title ? '' : ' no-title';
 732                      list += classes ? '<li class="' + classes + '">' : '<li>';
 733                      list += '<input type="hidden" class="item-permalink" value="' + this.permalink + '" />';
 734                      list += '<span class="item-title">';
 735                      list += this.title ? this.title : wpLinkL10n.noTitle;
 736                      list += '</span><span class="item-info">' + this.info + '</span></li>';
 737                      alt = ! alt;
 738                  });
 739              }
 740  
 741              this.ul[ firstPage ? 'html' : 'append' ]( list );
 742          },
 743          maybeLoad: function() {
 744              var self = this,
 745                  el = this.element,
 746                  bottom = el.scrollTop() + el.height();
 747  
 748              if ( ! this.query.ready() || bottom < this.contentHeight.height() - wpLink.riverBottomThreshold )
 749                  return;
 750  
 751              setTimeout(function() {
 752                  var newTop = el.scrollTop(),
 753                      newBottom = newTop + el.height();
 754  
 755                  if ( ! self.query.ready() || newBottom < self.contentHeight.height() - wpLink.riverBottomThreshold )
 756                      return;
 757  
 758                  self.waiting.addClass( 'is-active' );
 759                  el.scrollTop( newTop + self.waiting.outerHeight() );
 760  
 761                  self.ajax( function() {
 762                      self.waiting.removeClass( 'is-active' );
 763                  });
 764              }, wpLink.timeToTriggerRiver );
 765          }
 766      });
 767  
 768      Query = function( search ) {
 769          this.page = 1;
 770          this.allLoaded = false;
 771          this.querying = false;
 772          this.search = search;
 773      };
 774  
 775      $.extend( Query.prototype, {
 776          ready: function() {
 777              return ! ( this.querying || this.allLoaded );
 778          },
 779          ajax: function( callback ) {
 780              var self = this,
 781                  query = {
 782                      action : 'wp-link-ajax',
 783                      page : this.page,
 784                      '_ajax_linking_nonce' : inputs.nonce.val()
 785                  };
 786  
 787              if ( this.search )
 788                  query.search = this.search;
 789  
 790              this.querying = true;
 791  
 792              $.post( window.ajaxurl, query, function( r ) {
 793                  self.page++;
 794                  self.querying = false;
 795                  self.allLoaded = ! r;
 796                  callback( r, query );
 797              }, 'json' );
 798          }
 799      });
 800  
 801      $( wpLink.init );
 802  })( jQuery, window.wpLinkL10n, window.wp );


Generated : Tue Mar 19 08:20:01 2024 Cross-referenced by PHPXref