Ticket #36359: 36359.6.patch
| File 36359.6.patch, 23.5 KB (added by , 10 years ago) |
|---|
-
src/wp-includes/class-wp-editor.php
1412 1412 <button type="button" id="wp-link-close"><span class="screen-reader-text"><?php _e( 'Close' ); ?></span></button> 1413 1413 <div id="link-selector"> 1414 1414 <div id="link-options"> 1415 <p class="howto"><?php _e( 'Enter the destination URL' ); ?></p> 1415 1416 <div> 1416 1417 <label><span><?php _e( 'URL' ); ?></span> 1417 <input id="wp-link-url" type="text" role="combobox" aria-autocomplete="list" aria-expanded="false" placeholder="<?php _e( 'Paste URL or type to search' ); ?>"/></label>1418 <input id="wp-link-url" type="text" /></label> 1418 1419 </div> 1419 1420 <div class="wp-link-text-field"> 1420 1421 <label><span><?php _e( 'Link Text' ); ?></span> … … 1425 1426 <input type="checkbox" id="wp-link-target" /> <?php _e( 'Open link in a new tab' ); ?></label> 1426 1427 </div> 1427 1428 </div> 1429 <p class="howto"><?php _e( 'Or link to existing content' ); ?></p> 1430 <div id="search-panel"> 1431 <div class="link-search-wrapper"> 1432 <label> 1433 <span class="search-label"><?php _e( 'Search' ); ?></span> 1434 <input type="search" id="wp-link-search" class="link-search-field" autocomplete="off" /> 1435 <span class="spinner"></span> 1436 </label> 1437 </div> 1438 <div id="search-results" class="query-results" tabindex="0"> 1439 <ul></ul> 1440 <div class="river-waiting"> 1441 <span class="spinner"></span> 1442 </div> 1443 </div> 1444 <div id="most-recent-results" class="query-results" tabindex="0"> 1445 <div class="query-notice" id="query-notice-message"> 1446 <em class="query-notice-default"><?php _e( 'No search term specified. Showing recent items.' ); ?></em> 1447 <em class="query-notice-hint screen-reader-text"><?php _e( 'Search or use up and down arrow keys to select an item.' ); ?></em> 1448 </div> 1449 <ul></ul> 1450 <div class="river-waiting"> 1451 <span class="spinner"></span> 1452 </div> 1453 </div> 1454 </div> 1428 1455 </div> 1429 1456 <div class="submitbox"> 1430 1457 <div id="wp-link-cancel"> -
src/wp-includes/css/editor.css
95 95 } 96 96 97 97 .mce-textbox, 98 .mce-checkbox i.mce-i-checkbox { 98 .mce-checkbox i.mce-i-checkbox, 99 #wp-link .query-results { 99 100 border: 1px solid #ddd; 100 101 -webkit-border-radius: 0; 101 102 border-radius: 0; … … 1374 1375 height: 100%; 1375 1376 } 1376 1377 1378 #wp-link-wrap { 1379 height: 500px; 1380 margin-top: -250px; 1381 } 1382 1377 1383 #wp-link-wrap .wp-link-text-field { 1378 1384 display: none; 1379 1385 } … … 1433 1439 0 0 2px 1px rgba(30, 140, 190, .8); 1434 1440 } 1435 1441 1436 #link-selector { 1437 padding: 0 16px 50px; 1442 #wp-link-wrap #link-selector { 1443 -webkit-overflow-scrolling: touch; 1444 padding: 0 16px; 1445 position: absolute; 1446 top: 37px; 1447 left: 0; 1448 right: 0; 1449 bottom: 44px; 1438 1450 } 1439 1451 1440 1452 #wp-link ol, … … 1464 1476 } 1465 1477 1466 1478 #wp-link label input[type="text"] { 1467 margin : 8px 0 0;1479 margin-top: 5px; 1468 1480 width: 70%; 1469 1481 } 1470 1482 1471 #wp-link #link-options label span { 1483 #wp-link #link-options label span, 1484 #wp-link #search-panel label span.search-label { 1472 1485 display: inline-block; 1473 1486 width: 80px; 1474 1487 text-align: right; … … 1478 1491 word-wrap: break-word; 1479 1492 } 1480 1493 1494 #wp-link .link-search-field { 1495 float: left; 1496 width: 250px; 1497 max-width: 70%; 1498 } 1499 1500 #wp-link .link-search-wrapper { 1501 margin: 5px 0 9px; 1502 display: block; 1503 overflow: hidden; 1504 } 1505 1506 #wp-link .link-search-wrapper span { 1507 float: left; 1508 margin-top: 4px; 1509 } 1510 1511 #wp-link .link-search-wrapper .spinner { 1512 margin-top: 5px; 1513 } 1514 1481 1515 #wp-link .link-target { 1482 1516 padding: 3px 0 0; 1483 1517 white-space: nowrap; … … 1489 1523 max-width: 70%; 1490 1524 } 1491 1525 1526 #wp-link .query-results { 1527 border: 1px #dfdfdf solid; 1528 margin: 0 0 12px; 1529 background: #fff; 1530 overflow: auto; 1531 position: absolute; 1532 left: 16px; 1533 right: 16px; 1534 bottom: 0; 1535 top: 166px; 1536 } 1537 1538 .has-text-field #wp-link .query-results { 1539 top: 200px; 1540 } 1541 1542 #wp-link li { 1543 clear: both; 1544 margin-bottom: 0; 1545 border-bottom: 1px solid #f1f1f1; 1546 color: #32373c; 1547 padding: 4px 6px 4px 10px; 1548 cursor: pointer; 1549 position: relative; 1550 } 1551 1552 #wp-link .query-notice { 1553 padding: 0; 1554 border-bottom: 1px solid #dfdfdf; 1555 background-color: #f7fcfe; 1556 color: #000; 1557 } 1558 1559 #wp-link .query-notice .query-notice-default, 1560 #wp-link .query-notice .query-notice-hint { 1561 display: block; 1562 padding: 6px; 1563 border-left: 4px solid #00a0d2; 1564 } 1565 1566 #wp-link .unselectable.no-matches-found { 1567 padding: 0; 1568 border-bottom: 1px solid #dfdfdf; 1569 background-color: #fef7f1; 1570 } 1571 1572 #wp-link .no-matches-found .item-title { 1573 display: block; 1574 padding: 6px; 1575 border-left: 4px solid #d54e21; 1576 } 1577 1578 #wp-link .query-results em { 1579 font-style: normal; 1580 } 1581 1582 #wp-link li:hover { 1583 background: #eaf2fa; 1584 color: #151515; 1585 } 1586 1587 #wp-link li.unselectable { 1588 border-bottom: 1px solid #dfdfdf; 1589 } 1590 1591 #wp-link li.unselectable:hover { 1592 background: #fff; 1593 cursor: auto; 1594 color: #32373c; 1595 } 1596 1597 #wp-link li.selected { 1598 background: #ddd; 1599 color: #32373c; 1600 } 1601 1602 #wp-link li.selected .item-title { 1603 font-weight: bold; 1604 } 1605 1606 #wp-link li:last-child { 1607 border: none; 1608 } 1609 1610 #wp-link .item-title { 1611 display: inline-block; 1612 width: 80%; 1613 width: -webkit-calc(100% - 68px); 1614 width: calc(100% - 68px); 1615 word-wrap: break-word; 1616 } 1617 1618 #wp-link .item-info { 1619 text-transform: uppercase; 1620 color: #666; 1621 font-size: 11px; 1622 position: absolute; 1623 right: 5px; 1624 top: 5px; 1625 } 1626 1627 #wp-link .river-waiting { 1628 display: none; 1629 padding: 10px 0; 1630 } 1631 1492 1632 #wp-link .submitbox { 1493 1633 padding: 8px 16px; 1494 1634 background: #fcfcfc; … … 1518 1658 margin-top: -140px; 1519 1659 } 1520 1660 1661 #wp-link-wrap .query-results { 1662 top: 195px; 1663 } 1664 1665 #wp-link-wrap.has-text-field .query-results { 1666 top: 235px; 1667 } 1668 1521 1669 #link-selector { 1522 1670 padding: 0 16px 60px; 1523 1671 } 1524 1672 1673 #wp-link-wrap #link-selector { 1674 bottom: 52px; 1675 } 1676 1525 1677 #wp-link-cancel { 1526 1678 line-height: 32px; 1527 1679 } … … 1549 1701 #wp-link-wrap { 1550 1702 -webkit-transition: none; 1551 1703 transition: none; 1704 height: auto; 1705 margin-top: 0; 1706 top: 10px; 1707 bottom: 10px; 1552 1708 } 1709 1710 #link-selector { 1711 overflow: auto; 1712 } 1713 1714 #search-panel .query-results { 1715 position: static; 1716 } 1553 1717 } 1554 1718 1555 1719 @media screen and ( max-height: 290px ) { … … 1566 1730 height: calc(100% - 92px); 1567 1731 padding-bottom: 2px; 1568 1732 } 1733 1734 #search-panel .query-results { 1735 position: static; 1736 } 1569 1737 } 1570 1738 1571 1739 div.wp-link-preview { -
src/wp-includes/js/wplink.js
1 2 1 var wpLink; 3 2 4 3 ( function( $, wpLinkL10n, wp ) { 5 var editor, correctedURL, linkNode, 4 var editor, searchTimer, River, Query, correctedURL, linkNode, 5 emailRegexp = /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i, 6 urlRegexp = /^(https?|ftp):\/\/[A-Z0-9.-]+\.[A-Z]{2,4}[^ "]*$/i, 6 7 inputs = {}, 8 rivers = {}, 7 9 isTouch = ( 'ontouchend' in document ); 8 10 9 11 function getLink() { … … 11 13 } 12 14 13 15 wpLink = { 16 timeToTriggerRiver: 150, 17 minRiverAJAXDuration: 200, 18 riverBottomThreshold: 5, 19 keySensitivity: 100, 20 lastSearch: '', 14 21 textarea: '', 15 22 16 23 init: function() { … … 23 30 // Input 24 31 inputs.text = $( '#wp-link-text' ); 25 32 inputs.url = $( '#wp-link-url' ); 33 inputs.nonce = $( '#_ajax_linking_nonce' ); 26 34 inputs.openInNewTab = $( '#wp-link-target' ); 35 inputs.search = $( '#wp-link-search' ); 27 36 28 if ( $.ui && $.ui.autocomplete ) { 29 wpLink.setAutocomplete(); 30 } 37 // Build Rivers 38 rivers.search = new River( $( '#search-results' ) ); 39 rivers.recent = new River( $( '#most-recent-results' ) ); 40 rivers.elements = inputs.dialog.find( '.query-results' ); 31 41 32 inputs.dialog.on( 'keydown', wpLink.keydown ); 33 inputs.submit.on( 'click', function( event ) { 42 // Get search notice text 43 inputs.queryNotice = $( '#query-notice-message' ); 44 inputs.queryNoticeTextDefault = inputs.queryNotice.find( '.query-notice-default' ); 45 inputs.queryNoticeTextHint = inputs.queryNotice.find( '.query-notice-hint' ); 46 47 // Bind event handlers 48 inputs.dialog.keydown( wpLink.keydown ); 49 inputs.dialog.keyup( wpLink.keyup ); 50 inputs.submit.click( function( event ) { 34 51 event.preventDefault(); 35 52 wpLink.update(); 36 53 }); … … 40 57 wpLink.close(); 41 58 }); 42 59 60 rivers.elements.on( 'river-select', wpLink.updateFields ); 61 62 // Display 'hint' message when search field or 'query-results' box are focused 63 inputs.search.on( 'focus.wplink', function() { 64 inputs.queryNoticeTextDefault.hide(); 65 inputs.queryNoticeTextHint.removeClass( 'screen-reader-text' ).show(); 66 } ).on( 'blur.wplink', function() { 67 inputs.queryNoticeTextDefault.show(); 68 inputs.queryNoticeTextHint.addClass( 'screen-reader-text' ).hide(); 69 } ); 70 71 inputs.search.on( 'keyup input', function() { 72 window.clearTimeout( searchTimer ); 73 searchTimer = window.setTimeout( function() { 74 wpLink.searchInternalLinks(); 75 }, 500 ); 76 }); 77 43 78 inputs.url.on( 'paste', function() { 44 79 setTimeout( wpLink.correctURL, 0 ); 45 80 } ); 46 },47 81 48 setAutocomplete: function() { 49 var $input = inputs.url, 50 cache, last; 51 52 $input.on( 'keydown', function() { 53 $input.removeAttr( 'aria-activedescendant' ); 54 } ).autocomplete( { 55 source: function( request, response ) { 56 if ( last === request.term ) { 57 response( cache ); 58 return; 59 } 60 61 if ( /^https?:/.test( request.term ) || request.term.indexOf( '.' ) !== -1 ) { 62 return response(); 63 } 64 65 $.post( window.ajaxurl, { 66 action: 'wp-link-ajax', 67 page: 1, 68 search: request.term, 69 _ajax_linking_nonce: $( '#_ajax_linking_nonce' ).val() 70 }, function( data ) { 71 cache = data; 72 response( data ); 73 }, 'json' ); 74 75 last = request.term; 76 }, 77 focus: function( event, ui ) { 78 $input.attr( 'aria-activedescendant', 'mce-wp-autocomplete-' + ui.item.ID ); 79 /* 80 * Don't empty the URL input field, when using the arrow keys to 81 * highlight items. See api.jqueryui.com/autocomplete/#event-focus 82 */ 83 event.preventDefault(); 84 }, 85 select: function( event, ui ) { 86 $input.val( ui.item.permalink ); 87 88 if ( inputs.wrap.hasClass( 'has-text-field' ) && $.trim( inputs.text.val() ) === '' ) { 89 inputs.text.val( ui.item.title ); 90 } 91 92 // Audible confirmation message when a link has been selected. 93 wp.a11y.speak( wpLinkL10n.linkSelected ); 94 95 return false; 96 }, 97 open: function() { 98 $input.attr( 'aria-expanded', 'true' ); 99 }, 100 close: function() { 101 $input.attr( 'aria-expanded', 'false' ); 102 }, 103 minLength: 2, 104 position: { 105 my: 'left top+2' 106 }, 107 messages: { 108 noResults: ( typeof window.uiAutocompleteL10n !== 'undefined' ) ? window.uiAutocompleteL10n.noResults : '', 109 results: function( number ) { 110 if ( typeof window.uiAutocompleteL10n !== 'undefined' ) { 111 if ( number > 1 ) { 112 return window.uiAutocompleteL10n.manyResults.replace( '%d', number ); 113 } 114 115 return window.uiAutocompleteL10n.oneResult; 116 } 117 } 118 } 119 } ).autocomplete( 'instance' )._renderItem = function( ul, item ) { 120 return $( '<li role="option" id="mce-wp-autocomplete-' + item.ID + '">' ) 121 .append( '<span class="item-title">' + item.title + '</span> <span class="item-date alignright">' + item.info + '</span>' ) 122 .appendTo( ul ); 123 }; 124 125 $input.attr( { 126 'aria-owns': $input.autocomplete( 'widget' ).attr( 'id' ) 127 } ) 128 .on( 'focus', function() { 129 var inputValue = $input.val(); 130 /* 131 * Don't trigger a search if the URL field already has a link or is empty. 132 * Also, avoids screen readers announce `No search results`. 133 */ 134 if ( inputValue && ! /^https?:/.test( inputValue ) ) { 135 $input.autocomplete( 'search' ); 136 } 137 } ) 138 .autocomplete( 'widget' ) 139 .addClass( 'wplink-autocomplete' ) 140 .attr( 'role', 'listbox' ) 141 .removeAttr( 'tabindex' ); // Remove the `tabindex=0` attribute added by jQuery UI. 82 inputs.url.on( 'blur', wpLink.correctURL ); 142 83 }, 143 84 144 85 // If URL wasn't corrected last time and doesn't start with http:, https:, ? # or /, prepend http:// … … 208 149 refresh: function( url, text ) { 209 150 var linkText = ''; 210 151 152 // Refresh rivers (clear links, check visibility) 153 rivers.search.refresh(); 154 rivers.recent.refresh(); 155 211 156 if ( wpLink.isMCE() ) { 212 157 wpLink.mceRefresh( url, text ); 213 158 } else { … … 237 182 // If this is moved above the selection changes, 238 183 // IE will show a flashing cursor over the dialog. 239 184 window.setTimeout( function() { 240 inputs.url.focus()[0].select(); 185 inputs.url[0].select(); 186 inputs.url.focus(); 241 187 } ); 242 188 } 243 189 190 // Load the most recent results if this is the first time opening the panel. 191 if ( ! rivers.recent.ul.children().length ) { 192 rivers.recent.ajax(); 193 } 194 244 195 correctedURL = inputs.url.val().replace( /^http:\/\//, '' ); 245 196 }, 246 197 … … 271 222 return true; 272 223 }, 273 224 274 mceRefresh: function( url, text ) {275 var linkText, 225 mceRefresh: function( searchStr, text ) { 226 var linkText, href, 276 227 linkNode = getLink(), 277 228 onlyText = this.hasSelectedText( linkNode ); 278 229 279 230 if ( linkNode ) { 280 231 linkText = linkNode.innerText || linkNode.textContent; 232 href = editor.dom.getAttrib( linkNode, 'href' ); 281 233 282 234 if ( ! $.trim( linkText ) ) { 283 235 linkText = text || ''; 284 236 } 285 237 286 url = url || editor.dom.getAttrib( linkNode, 'href' ); 238 if ( searchStr && ( urlRegexp.test( searchStr ) || emailRegexp.test( searchStr ) ) ) { 239 href = searchStr; 240 } 287 241 288 if ( url!== '_wp_link_placeholder' ) {289 inputs.url.val( url);242 if ( href !== '_wp_link_placeholder' ) { 243 inputs.url.val( href ); 290 244 inputs.openInNewTab.prop( 'checked', '_blank' === editor.dom.getAttrib( linkNode, 'target' ) ); 291 245 inputs.submit.val( wpLinkL10n.update ); 292 246 } else { 293 247 this.setDefaultValues( linkText ); 294 248 } 249 250 if ( searchStr && searchStr !== href ) { 251 // The user has typed something in the inline dialog. Trigger a search with it. 252 inputs.search.val( searchStr ); 253 window.setTimeout( function() { 254 wpLink.searchInternalLinks(); 255 } ); 256 } 295 257 } else { 296 258 linkText = editor.selection.getContent({ format: 'text' }) || text || ''; 297 259 this.setDefaultValues( linkText ); … … 424 386 var attrs = wpLink.getAttrs(), 425 387 link, text; 426 388 427 editor.focus();428 429 389 if ( window.tinymce.isIE && editor.windowManager.wplinkBookmark ) { 430 390 editor.selection.moveToBookmark( editor.windowManager.wplinkBookmark ); 431 391 editor.windowManager.wplinkBookmark = null; … … 471 431 wp.a11y.speak( wpLinkL10n.linkInserted ); 472 432 }, 473 433 474 keydown: function( event ) { 475 var id; 476 477 // Escape key. 478 if ( 27 === event.keyCode ) { 479 wpLink.close(); 480 event.stopImmediatePropagation(); 481 // Tab key. 482 } else if ( 9 === event.keyCode ) { 483 id = event.target.id; 484 485 // wp-link-submit must always be the last focusable element in the dialog. 486 // following focusable elements will be skipped on keyboard navigation. 487 if ( id === 'wp-link-submit' && ! event.shiftKey ) { 488 inputs.close.focus(); 489 event.preventDefault(); 490 } else if ( id === 'wp-link-close' && event.shiftKey ) { 491 inputs.submit.focus(); 492 event.preventDefault(); 493 } 494 } 434 updateFields: function( e, li ) { 435 inputs.url.val( li.children( '.item-permalink' ).val() ); 495 436 }, 496 437 497 438 getUrlFromSelection: function( selection ) { 498 var emailRegexp = /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i,499 urlRegexp = /^(https?|ftp):\/\/[A-Z0-9.-]+\.[A-Z]{2,4}[^ "]*$/i;500 501 439 if ( ! selection ) { 502 440 if ( this.isMCE() ) { 503 441 selection = editor.selection.getContent({ format: 'text' }); … … 526 464 527 465 // Update save prompt. 528 466 inputs.submit.val( wpLinkL10n.save ); 467 }, 468 469 searchInternalLinks: function() { 470 var waiting, 471 search = inputs.search.val() || ''; 472 473 if ( search.length > 2 ) { 474 rivers.recent.hide(); 475 rivers.search.show(); 476 477 // Don't search if the keypress didn't change the title. 478 if ( wpLink.lastSearch == search ) 479 return; 480 481 wpLink.lastSearch = search; 482 waiting = inputs.search.parent().find( '.spinner' ).addClass( 'is-active' ); 483 484 rivers.search.change( search ); 485 rivers.search.ajax( function() { 486 waiting.removeClass( 'is-active' ); 487 }); 488 } else { 489 rivers.search.hide(); 490 rivers.recent.show(); 491 } 492 }, 493 494 next: function() { 495 rivers.search.next(); 496 rivers.recent.next(); 497 }, 498 499 prev: function() { 500 rivers.search.prev(); 501 rivers.recent.prev(); 502 }, 503 504 keydown: function( event ) { 505 var fn, id; 506 507 // Escape key. 508 if ( 27 === event.keyCode ) { 509 wpLink.close(); 510 event.stopImmediatePropagation(); 511 // Tab key. 512 } else if ( 9 === event.keyCode ) { 513 id = event.target.id; 514 515 // wp-link-submit must always be the last focusable element in the dialog. 516 // following focusable elements will be skipped on keyboard navigation. 517 if ( id === 'wp-link-submit' && ! event.shiftKey ) { 518 inputs.close.focus(); 519 event.preventDefault(); 520 } else if ( id === 'wp-link-close' && event.shiftKey ) { 521 inputs.submit.focus(); 522 event.preventDefault(); 523 } 524 } 525 526 // Up Arrow and Down Arrow keys. 527 if ( 38 !== event.keyCode && 40 !== event.keyCode ) { 528 return; 529 } 530 531 if ( document.activeElement && 532 ( document.activeElement.id === 'link-title-field' || document.activeElement.id === 'url-field' ) ) { 533 return; 534 } 535 536 // Up Arrow key. 537 fn = 38 === event.keyCode ? 'prev' : 'next'; 538 clearInterval( wpLink.keyInterval ); 539 wpLink[ fn ](); 540 wpLink.keyInterval = setInterval( wpLink[ fn ], wpLink.keySensitivity ); 541 event.preventDefault(); 542 }, 543 544 keyup: function( event ) { 545 // Up Arrow and Down Arrow keys. 546 if ( 38 === event.keyCode || 40 === event.keyCode ) { 547 clearInterval( wpLink.keyInterval ); 548 event.preventDefault(); 549 } 550 }, 551 552 delayedCallback: function( func, delay ) { 553 var timeoutTriggered, funcTriggered, funcArgs, funcContext; 554 555 if ( ! delay ) 556 return func; 557 558 setTimeout( function() { 559 if ( funcTriggered ) 560 return func.apply( funcContext, funcArgs ); 561 // Otherwise, wait. 562 timeoutTriggered = true; 563 }, delay ); 564 565 return function() { 566 if ( timeoutTriggered ) 567 return func.apply( this, arguments ); 568 // Otherwise, wait. 569 funcArgs = arguments; 570 funcContext = this; 571 funcTriggered = true; 572 }; 529 573 } 530 574 }; 531 575 576 River = function( element, search ) { 577 var self = this; 578 this.element = element; 579 this.ul = element.children( 'ul' ); 580 this.contentHeight = element.children( '#link-selector-height' ); 581 this.waiting = element.find('.river-waiting'); 582 583 this.change( search ); 584 this.refresh(); 585 586 $( '#wp-link .query-results, #wp-link #link-selector' ).scroll( function() { 587 self.maybeLoad(); 588 }); 589 element.on( 'click', 'li', function( event ) { 590 self.select( $( this ), event ); 591 }); 592 }; 593 594 $.extend( River.prototype, { 595 refresh: function() { 596 this.deselect(); 597 this.visible = this.element.is( ':visible' ); 598 }, 599 show: function() { 600 if ( ! this.visible ) { 601 this.deselect(); 602 this.element.show(); 603 this.visible = true; 604 } 605 }, 606 hide: function() { 607 this.element.hide(); 608 this.visible = false; 609 }, 610 // Selects a list item and triggers the river-select event. 611 select: function( li, event ) { 612 var liHeight, elHeight, liTop, elTop; 613 614 if ( li.hasClass( 'unselectable' ) || li == this.selected ) 615 return; 616 617 this.deselect(); 618 this.selected = li.addClass( 'selected' ); 619 // Make sure the element is visible 620 liHeight = li.outerHeight(); 621 elHeight = this.element.height(); 622 liTop = li.position().top; 623 elTop = this.element.scrollTop(); 624 625 if ( liTop < 0 ) // Make first visible element 626 this.element.scrollTop( elTop + liTop ); 627 else if ( liTop + liHeight > elHeight ) // Make last visible element 628 this.element.scrollTop( elTop + liTop - elHeight + liHeight ); 629 630 // Trigger the river-select event 631 this.element.trigger( 'river-select', [ li, event, this ] ); 632 }, 633 deselect: function() { 634 if ( this.selected ) 635 this.selected.removeClass( 'selected' ); 636 this.selected = false; 637 }, 638 prev: function() { 639 if ( ! this.visible ) 640 return; 641 642 var to; 643 if ( this.selected ) { 644 to = this.selected.prev( 'li' ); 645 if ( to.length ) 646 this.select( to ); 647 } 648 }, 649 next: function() { 650 if ( ! this.visible ) 651 return; 652 653 var to = this.selected ? this.selected.next( 'li' ) : $( 'li:not(.unselectable):first', this.element ); 654 if ( to.length ) 655 this.select( to ); 656 }, 657 ajax: function( callback ) { 658 var self = this, 659 delay = this.query.page == 1 ? 0 : wpLink.minRiverAJAXDuration, 660 response = wpLink.delayedCallback( function( results, params ) { 661 self.process( results, params ); 662 if ( callback ) 663 callback( results, params ); 664 }, delay ); 665 666 this.query.ajax( response ); 667 }, 668 change: function( search ) { 669 if ( this.query && this._search == search ) 670 return; 671 672 this._search = search; 673 this.query = new Query( search ); 674 this.element.scrollTop( 0 ); 675 }, 676 process: function( results, params ) { 677 var list = '', alt = true, classes = '', 678 firstPage = params.page == 1; 679 680 if ( ! results ) { 681 if ( firstPage ) { 682 list += '<li class="unselectable no-matches-found"><span class="item-title"><em>' + 683 wpLinkL10n.noMatchesFound + '</em></span></li>'; 684 } 685 } else { 686 $.each( results, function() { 687 classes = alt ? 'alternate' : ''; 688 classes += this.title ? '' : ' no-title'; 689 list += classes ? '<li class="' + classes + '">' : '<li>'; 690 list += '<input type="hidden" class="item-permalink" value="' + this.permalink + '" />'; 691 list += '<span class="item-title">'; 692 list += this.title ? this.title : wpLinkL10n.noTitle; 693 list += '</span><span class="item-info">' + this.info + '</span></li>'; 694 alt = ! alt; 695 }); 696 } 697 698 this.ul[ firstPage ? 'html' : 'append' ]( list ); 699 }, 700 maybeLoad: function() { 701 var self = this, 702 el = this.element, 703 bottom = el.scrollTop() + el.height(); 704 705 if ( ! this.query.ready() || bottom < this.contentHeight.height() - wpLink.riverBottomThreshold ) 706 return; 707 708 setTimeout(function() { 709 var newTop = el.scrollTop(), 710 newBottom = newTop + el.height(); 711 712 if ( ! self.query.ready() || newBottom < self.contentHeight.height() - wpLink.riverBottomThreshold ) 713 return; 714 715 self.waiting.addClass( 'is-active' ); 716 el.scrollTop( newTop + self.waiting.outerHeight() ); 717 718 self.ajax( function() { 719 self.waiting.removeClass( 'is-active' ); 720 }); 721 }, wpLink.timeToTriggerRiver ); 722 } 723 }); 724 725 Query = function( search ) { 726 this.page = 1; 727 this.allLoaded = false; 728 this.querying = false; 729 this.search = search; 730 }; 731 732 $.extend( Query.prototype, { 733 ready: function() { 734 return ! ( this.querying || this.allLoaded ); 735 }, 736 ajax: function( callback ) { 737 var self = this, 738 query = { 739 action : 'wp-link-ajax', 740 page : this.page, 741 '_ajax_linking_nonce' : inputs.nonce.val() 742 }; 743 744 if ( this.search ) 745 query.search = this.search; 746 747 this.querying = true; 748 749 $.post( window.ajaxurl, query, function( r ) { 750 self.page++; 751 self.querying = false; 752 self.allLoaded = ! r; 753 callback( r, query ); 754 }, 'json' ); 755 } 756 }); 757 532 758 $( document ).ready( wpLink.init ); 533 759 })( jQuery, window.wpLinkL10n, window.wp );
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)