Ticket #36359: 36359.patch
| File 36359.patch, 23.9 KB (added by , 10 years ago) |
|---|
-
src/wp-admin/includes/upgrade.php
1682 1682 if ( $wp_current_db_version < 36679 && is_multisite() ) { 1683 1683 $wpdb->query( "DELETE FROM $wpdb->options WHERE option_name REGEXP '^[0-9]+_new_email$'" ); 1684 1684 } 1685 1686 // Remove unused user setting for wpLink.1687 delete_user_setting( 'wplink' );1688 1685 } 1689 1686 1690 1687 /** -
src/wp-includes/class-wp-editor.php
1402 1402 * @static 1403 1403 */ 1404 1404 public static function wp_link_dialog() { 1405 $search_panel_visible = '1' == get_user_setting( 'wplink', '0' ) ? ' search-panel-visible' : ''; 1406 1405 1407 // display: none is required here, see #WP27605 1406 1408 ?> 1407 1409 <div id="wp-link-backdrop" style="display: none"></div> 1408 <div id="wp-link-wrap" class="wp-core-ui " style="display: none" role="dialog" aria-labelledby="link-modal-title">1410 <div id="wp-link-wrap" class="wp-core-ui<?php echo $search_panel_visible; ?>" style="display: none" role="dialog" aria-labelledby="link-modal-title"> 1409 1411 <form id="wp-link" tabindex="-1"> 1410 1412 <?php wp_nonce_field( 'internal-linking', '_ajax_linking_nonce', false ); ?> 1411 1413 <h1 id="link-modal-title"><?php _e( 'Insert/edit link' ) ?></h1> … … 1412 1414 <button type="button" id="wp-link-close"><span class="screen-reader-text"><?php _e( 'Close' ); ?></span></button> 1413 1415 <div id="link-selector"> 1414 1416 <div id="link-options"> 1417 <p class="howto"><?php _e( 'Enter the destination URL' ); ?></p> 1415 1418 <div> 1416 1419 <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>1420 <input id="wp-link-url" type="text" /></label> 1418 1421 </div> 1419 1422 <div class="wp-link-text-field"> 1420 1423 <label><span><?php _e( 'Link Text' ); ?></span> … … 1425 1428 <input type="checkbox" id="wp-link-target" /> <?php _e( 'Open link in a new tab' ); ?></label> 1426 1429 </div> 1427 1430 </div> 1431 <p class="howto"><a href="#" id="wp-link-search-toggle"><?php _e( 'Or link to existing content' ); ?></a></p> 1432 <div id="search-panel"> 1433 <div class="link-search-wrapper"> 1434 <label> 1435 <span class="search-label"><?php _e( 'Search' ); ?></span> 1436 <input type="search" id="wp-link-search" class="link-search-field" autocomplete="off" /> 1437 <span class="spinner"></span> 1438 </label> 1439 </div> 1440 <div id="search-results" class="query-results" tabindex="0"> 1441 <ul></ul> 1442 <div class="river-waiting"> 1443 <span class="spinner"></span> 1444 </div> 1445 </div> 1446 <div id="most-recent-results" class="query-results" tabindex="0"> 1447 <div class="query-notice" id="query-notice-message"> 1448 <em class="query-notice-default"><?php _e( 'No search term specified. Showing recent items.' ); ?></em> 1449 <em class="query-notice-hint screen-reader-text"><?php _e( 'Search or use up and down arrow keys to select an item.' ); ?></em> 1450 </div> 1451 <ul></ul> 1452 <div class="river-waiting"> 1453 <span class="spinner"></span> 1454 </div> 1455 </div> 1456 </div> 1428 1457 </div> 1429 1458 <div class="submitbox"> 1430 1459 <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.search-panel-visible { 1379 height: 500px; 1380 margin-top: -250px; 1381 } 1382 1377 1383 #wp-link-wrap .wp-link-text-field { 1378 1384 display: none; 1379 1385 } … … 1437 1443 padding: 0 16px 50px; 1438 1444 } 1439 1445 1446 #wp-link-wrap.search-panel-visible #link-selector { 1447 -webkit-overflow-scrolling: touch; 1448 padding: 0 16px; 1449 position: absolute; 1450 top: 36px; 1451 left: 0; 1452 right: 0; 1453 bottom: 44px; 1454 } 1455 1440 1456 #wp-link ol, 1441 1457 #wp-link ul { 1442 1458 list-style: none; … … 1444 1460 padding: 0; 1445 1461 } 1446 1462 1463 #wp-link-search-toggle:after { 1464 display: inline-block; 1465 font: normal 20px/1 dashicons; 1466 vertical-align: top; 1467 speak: none; 1468 -webkit-font-smoothing: antialiased; 1469 -moz-osx-font-smoothing: grayscale; 1470 content: "\f140"; 1471 } 1472 1473 .search-panel-visible #wp-link-search-toggle:after { 1474 content: "\f142"; 1475 } 1476 1447 1477 #wp-link input[type="text"] { 1448 1478 -webkit-box-sizing: border-box; 1449 1479 -moz-box-sizing: border-box; … … 1463 1493 color: inherit; 1464 1494 } 1465 1495 1496 #wp-link-search-toggle { 1497 cursor: pointer; 1498 } 1499 1466 1500 #wp-link label input[type="text"] { 1467 margin : 8px 0 0;1501 margin-top: 5px; 1468 1502 width: 70%; 1469 1503 } 1470 1504 1471 #wp-link #link-options label span { 1505 #wp-link #link-options label span, 1506 #wp-link #search-panel label span.search-label { 1472 1507 display: inline-block; 1473 1508 width: 80px; 1474 1509 text-align: right; … … 1478 1513 word-wrap: break-word; 1479 1514 } 1480 1515 1516 #wp-link .link-search-field { 1517 float: left; 1518 width: 250px; 1519 max-width: 70%; 1520 } 1521 1522 #wp-link .link-search-wrapper { 1523 margin: 5px 0 9px; 1524 display: block; 1525 overflow: hidden; 1526 } 1527 1528 #wp-link .link-search-wrapper span { 1529 float: left; 1530 margin-top: 4px; 1531 } 1532 1533 #wp-link .link-search-wrapper .spinner { 1534 margin-top: 5px; 1535 } 1536 1481 1537 #wp-link .link-target { 1482 1538 padding: 3px 0 0; 1483 1539 white-space: nowrap; … … 1489 1545 max-width: 70%; 1490 1546 } 1491 1547 1548 #wp-link .query-results { 1549 border: 1px #dfdfdf solid; 1550 margin: 0; 1551 background: #fff; 1552 overflow: auto; 1553 position: absolute; 1554 left: 16px; 1555 right: 16px; 1556 bottom: 16px; 1557 top: 172px; 1558 } 1559 1560 .has-text-field #wp-link .query-results { 1561 top: 205px; 1562 } 1563 1564 #wp-link li { 1565 clear: both; 1566 margin-bottom: 0; 1567 border-bottom: 1px solid #f1f1f1; 1568 color: #32373c; 1569 padding: 4px 6px 4px 10px; 1570 cursor: pointer; 1571 position: relative; 1572 } 1573 1574 #wp-link .query-notice { 1575 padding: 0; 1576 border-bottom: 1px solid #dfdfdf; 1577 background-color: #f7fcfe; 1578 color: #000; 1579 } 1580 1581 #wp-link .query-notice .query-notice-default, 1582 #wp-link .query-notice .query-notice-hint { 1583 display: block; 1584 padding: 6px; 1585 border-left: 4px solid #00a0d2; 1586 } 1587 1588 #wp-link .unselectable.no-matches-found { 1589 padding: 0; 1590 border-bottom: 1px solid #dfdfdf; 1591 background-color: #fef7f1; 1592 } 1593 1594 #wp-link .no-matches-found .item-title { 1595 display: block; 1596 padding: 6px; 1597 border-left: 4px solid #d54e21; 1598 } 1599 1600 #wp-link .query-results em { 1601 font-style: normal; 1602 } 1603 1604 #wp-link li:hover { 1605 background: #eaf2fa; 1606 color: #151515; 1607 } 1608 1609 #wp-link li.unselectable { 1610 border-bottom: 1px solid #dfdfdf; 1611 } 1612 1613 #wp-link li.unselectable:hover { 1614 background: #fff; 1615 cursor: auto; 1616 color: #32373c; 1617 } 1618 1619 #wp-link li.selected { 1620 background: #ddd; 1621 color: #32373c; 1622 } 1623 1624 #wp-link li.selected .item-title { 1625 font-weight: bold; 1626 } 1627 1628 #wp-link li:last-child { 1629 border: none; 1630 } 1631 1632 #wp-link .item-title { 1633 display: inline-block; 1634 width: 80%; 1635 width: -webkit-calc(100% - 68px); 1636 width: calc(100% - 68px); 1637 word-wrap: break-word; 1638 } 1639 1640 #wp-link .item-info { 1641 text-transform: uppercase; 1642 color: #666; 1643 font-size: 11px; 1644 position: absolute; 1645 right: 5px; 1646 top: 5px; 1647 } 1648 1649 #wp-link #search-results, 1650 #wp-link #search-panel { 1651 display: none; 1652 } 1653 1654 #wp-link-wrap.search-panel-visible #search-panel { 1655 display: block; 1656 } 1657 1658 #wp-link .river-waiting { 1659 display: none; 1660 padding: 10px 0; 1661 } 1662 1492 1663 #wp-link .submitbox { 1493 1664 padding: 8px 16px; 1494 1665 background: #fcfcfc; … … 1518 1689 margin-top: -140px; 1519 1690 } 1520 1691 1692 #wp-link-wrap.search-panel-visible .query-results { 1693 top: 195px; 1694 } 1695 1696 #wp-link-wrap.search-panel-visible.has-text-field .query-results { 1697 top: 235px; 1698 } 1699 1521 1700 #link-selector { 1522 1701 padding: 0 16px 60px; 1523 1702 } 1524 1703 1704 #wp-link-wrap.search-panel-visible #link-selector { 1705 bottom: 52px; 1706 } 1707 1525 1708 #wp-link-cancel { 1526 1709 line-height: 32px; 1527 1710 } … … 1550 1733 -webkit-transition: none; 1551 1734 transition: none; 1552 1735 } 1736 1737 #wp-link-wrap.search-panel-visible { 1738 height: auto; 1739 margin-top: 0; 1740 top: 10px; 1741 bottom: 10px; 1742 } 1743 1744 .search-panel-visible #link-selector { 1745 overflow: auto; 1746 } 1747 1748 .search-panel-visible #search-panel .query-results { 1749 position: static; 1750 } 1553 1751 } 1554 1752 1555 1753 @media screen and ( max-height: 290px ) { … … 1566 1764 height: calc(100% - 92px); 1567 1765 padding-bottom: 2px; 1568 1766 } 1767 1768 #search-panel .query-results { 1769 position: static; 1770 } 1569 1771 } 1570 1772 1571 1773 div.wp-link-preview { -
src/wp-includes/js/wplink.js
1 1 /* global ajaxurl, tinymce, wpLinkL10n, setUserSetting, wpActiveEditor */ 2 2 var wpLink; 3 3 4 4 ( function( $, wpLinkL10n, wp ) { 5 var editor, correctedURL, linkNode,5 var editor, searchTimer, River, Query, correctedURL, linkNode, 6 6 inputs = {}, 7 rivers = {}, 7 8 isTouch = ( 'ontouchend' in document ); 8 9 9 10 function getLink() { … … 11 12 } 12 13 13 14 wpLink = { 15 timeToTriggerRiver: 150, 16 minRiverAJAXDuration: 200, 17 riverBottomThreshold: 5, 18 keySensitivity: 100, 19 lastSearch: '', 14 20 textarea: '', 15 21 16 22 init: function() { … … 23 29 // Input 24 30 inputs.text = $( '#wp-link-text' ); 25 31 inputs.url = $( '#wp-link-url' ); 32 inputs.nonce = $( '#_ajax_linking_nonce' ); 26 33 inputs.openInNewTab = $( '#wp-link-target' ); 34 inputs.search = $( '#wp-link-search' ); 27 35 28 if ( $.ui && $.ui.autocomplete ) { 29 wpLink.setAutocomplete(); 30 } 36 // Build Rivers 37 rivers.search = new River( $( '#search-results' ) ); 38 rivers.recent = new River( $( '#most-recent-results' ) ); 39 rivers.elements = inputs.dialog.find( '.query-results' ); 31 40 32 inputs.dialog.on( 'keydown', wpLink.keydown ); 33 inputs.submit.on( 'click', function( event ) { 41 // Get search notice text 42 inputs.queryNotice = $( '#query-notice-message' ); 43 inputs.queryNoticeTextDefault = inputs.queryNotice.find( '.query-notice-default' ); 44 inputs.queryNoticeTextHint = inputs.queryNotice.find( '.query-notice-hint' ); 45 46 // Bind event handlers 47 inputs.dialog.keydown( wpLink.keydown ); 48 inputs.dialog.keyup( wpLink.keyup ); 49 inputs.submit.click( function( event ) { 34 50 event.preventDefault(); 35 51 wpLink.update(); 36 52 }); … … 40 56 wpLink.close(); 41 57 }); 42 58 43 inputs.url.on( 'paste', function() { 44 setTimeout( wpLink.correctURL, 0 ); 45 } ); 46 }, 59 $( '#wp-link-search-toggle' ).on( 'click', wpLink.toggleInternalLinking ); 47 60 48 setAutocomplete: function() { 49 var $input = inputs.url, 50 cache, last; 61 rivers.elements.on( 'river-select', wpLink.updateFields ); 51 62 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 }63 // Display 'hint' message when search field or 'query-results' box are focused 64 inputs.search.on( 'focus.wplink', function() { 65 inputs.queryNoticeTextDefault.hide(); 66 inputs.queryNoticeTextHint.removeClass( 'screen-reader-text' ).show(); 67 } ).on( 'blur.wplink', function() { 68 inputs.queryNoticeTextDefault.show(); 69 inputs.queryNoticeTextHint.addClass( 'screen-reader-text' ).hide(); 70 } ); 60 71 61 if ( /^https?:/.test( request.term ) || request.term.indexOf( '.' ) !== -1 ) { 62 return response(); 63 } 72 inputs.search.on( 'keyup input', function() { 73 var self = this; 64 74 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' ); 75 window.clearTimeout( searchTimer ); 76 searchTimer = window.setTimeout( function() { 77 wpLink.searchInternalLinks.call( self ); 78 }, 500 ); 79 }); 74 80 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 ); 81 inputs.url.on( 'paste', function() { 82 setTimeout( wpLink.correctURL, 0 ); 83 } ); 87 84 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. 85 inputs.url.on( 'blur', wpLink.correctURL ); 142 86 }, 143 87 144 88 // If URL wasn't corrected last time and doesn't start with http:, https:, ? # or /, prepend http:// … … 208 152 refresh: function( url, text ) { 209 153 var linkText = ''; 210 154 155 // Refresh rivers (clear links, check visibility) 156 rivers.search.refresh(); 157 rivers.recent.refresh(); 158 211 159 if ( wpLink.isMCE() ) { 212 160 wpLink.mceRefresh( url, text ); 213 161 } else { … … 241 189 } ); 242 190 } 243 191 192 // Load the most recent results if this is the first time opening the panel. 193 if ( ! rivers.recent.ul.children().length ) { 194 rivers.recent.ajax(); 195 } 196 244 197 correctedURL = inputs.url.val().replace( /^http:\/\//, '' ); 245 198 }, 246 199 … … 471 424 wp.a11y.speak( wpLinkL10n.linkInserted ); 472 425 }, 473 426 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 } 427 updateFields: function( e, li ) { 428 inputs.url.val( li.children( '.item-permalink' ).val() ); 495 429 }, 496 430 497 431 getUrlFromSelection: function( selection ) { … … 526 460 527 461 // Update save prompt. 528 462 inputs.submit.val( wpLinkL10n.save ); 463 }, 464 465 searchInternalLinks: function() { 466 var t = $( this ), waiting, 467 search = t.val(); 468 469 if ( search.length > 2 ) { 470 rivers.recent.hide(); 471 rivers.search.show(); 472 473 // Don't search if the keypress didn't change the title. 474 if ( wpLink.lastSearch == search ) 475 return; 476 477 wpLink.lastSearch = search; 478 waiting = t.parent().find( '.spinner' ).addClass( 'is-active' ); 479 480 rivers.search.change( search ); 481 rivers.search.ajax( function() { 482 waiting.removeClass( 'is-active' ); 483 }); 484 } else { 485 rivers.search.hide(); 486 rivers.recent.show(); 487 } 488 }, 489 490 next: function() { 491 rivers.search.next(); 492 rivers.recent.next(); 493 }, 494 495 prev: function() { 496 rivers.search.prev(); 497 rivers.recent.prev(); 498 }, 499 500 keydown: function( event ) { 501 var fn, id; 502 503 // Escape key. 504 if ( 27 === event.keyCode ) { 505 wpLink.close(); 506 event.stopImmediatePropagation(); 507 // Tab key. 508 } else if ( 9 === event.keyCode ) { 509 id = event.target.id; 510 511 // wp-link-submit must always be the last focusable element in the dialog. 512 // following focusable elements will be skipped on keyboard navigation. 513 if ( id === 'wp-link-submit' && ! event.shiftKey ) { 514 inputs.close.focus(); 515 event.preventDefault(); 516 } else if ( id === 'wp-link-close' && event.shiftKey ) { 517 inputs.submit.focus(); 518 event.preventDefault(); 519 } 520 } 521 522 // Up Arrow and Down Arrow keys. 523 if ( 38 !== event.keyCode && 40 !== event.keyCode ) { 524 return; 525 } 526 527 if ( document.activeElement && 528 ( document.activeElement.id === 'link-title-field' || document.activeElement.id === 'url-field' ) ) { 529 return; 530 } 531 532 // Up Arrow key. 533 fn = 38 === event.keyCode ? 'prev' : 'next'; 534 clearInterval( wpLink.keyInterval ); 535 wpLink[ fn ](); 536 wpLink.keyInterval = setInterval( wpLink[ fn ], wpLink.keySensitivity ); 537 event.preventDefault(); 538 }, 539 540 keyup: function( event ) { 541 // Up Arrow and Down Arrow keys. 542 if ( 38 === event.keyCode || 40 === event.keyCode ) { 543 clearInterval( wpLink.keyInterval ); 544 event.preventDefault(); 545 } 546 }, 547 548 delayedCallback: function( func, delay ) { 549 var timeoutTriggered, funcTriggered, funcArgs, funcContext; 550 551 if ( ! delay ) 552 return func; 553 554 setTimeout( function() { 555 if ( funcTriggered ) 556 return func.apply( funcContext, funcArgs ); 557 // Otherwise, wait. 558 timeoutTriggered = true; 559 }, delay ); 560 561 return function() { 562 if ( timeoutTriggered ) 563 return func.apply( this, arguments ); 564 // Otherwise, wait. 565 funcArgs = arguments; 566 funcContext = this; 567 funcTriggered = true; 568 }; 569 }, 570 571 toggleInternalLinking: function( event ) { 572 var visible = inputs.wrap.hasClass( 'search-panel-visible' ); 573 574 inputs.wrap.toggleClass( 'search-panel-visible', ! visible ); 575 setUserSetting( 'wplink', visible ? '0' : '1' ); 576 inputs[ ! visible ? 'search' : 'url' ].focus(); 577 event.preventDefault(); 529 578 } 530 579 }; 531 580 581 River = function( element, search ) { 582 var self = this; 583 this.element = element; 584 this.ul = element.children( 'ul' ); 585 this.contentHeight = element.children( '#link-selector-height' ); 586 this.waiting = element.find('.river-waiting'); 587 588 this.change( search ); 589 this.refresh(); 590 591 $( '#wp-link .query-results, #wp-link #link-selector' ).scroll( function() { 592 self.maybeLoad(); 593 }); 594 element.on( 'click', 'li', function( event ) { 595 self.select( $( this ), event ); 596 }); 597 }; 598 599 $.extend( River.prototype, { 600 refresh: function() { 601 this.deselect(); 602 this.visible = this.element.is( ':visible' ); 603 }, 604 show: function() { 605 if ( ! this.visible ) { 606 this.deselect(); 607 this.element.show(); 608 this.visible = true; 609 } 610 }, 611 hide: function() { 612 this.element.hide(); 613 this.visible = false; 614 }, 615 // Selects a list item and triggers the river-select event. 616 select: function( li, event ) { 617 var liHeight, elHeight, liTop, elTop; 618 619 if ( li.hasClass( 'unselectable' ) || li == this.selected ) 620 return; 621 622 this.deselect(); 623 this.selected = li.addClass( 'selected' ); 624 // Make sure the element is visible 625 liHeight = li.outerHeight(); 626 elHeight = this.element.height(); 627 liTop = li.position().top; 628 elTop = this.element.scrollTop(); 629 630 if ( liTop < 0 ) // Make first visible element 631 this.element.scrollTop( elTop + liTop ); 632 else if ( liTop + liHeight > elHeight ) // Make last visible element 633 this.element.scrollTop( elTop + liTop - elHeight + liHeight ); 634 635 // Trigger the river-select event 636 this.element.trigger( 'river-select', [ li, event, this ] ); 637 }, 638 deselect: function() { 639 if ( this.selected ) 640 this.selected.removeClass( 'selected' ); 641 this.selected = false; 642 }, 643 prev: function() { 644 if ( ! this.visible ) 645 return; 646 647 var to; 648 if ( this.selected ) { 649 to = this.selected.prev( 'li' ); 650 if ( to.length ) 651 this.select( to ); 652 } 653 }, 654 next: function() { 655 if ( ! this.visible ) 656 return; 657 658 var to = this.selected ? this.selected.next( 'li' ) : $( 'li:not(.unselectable):first', this.element ); 659 if ( to.length ) 660 this.select( to ); 661 }, 662 ajax: function( callback ) { 663 var self = this, 664 delay = this.query.page == 1 ? 0 : wpLink.minRiverAJAXDuration, 665 response = wpLink.delayedCallback( function( results, params ) { 666 self.process( results, params ); 667 if ( callback ) 668 callback( results, params ); 669 }, delay ); 670 671 this.query.ajax( response ); 672 }, 673 change: function( search ) { 674 if ( this.query && this._search == search ) 675 return; 676 677 this._search = search; 678 this.query = new Query( search ); 679 this.element.scrollTop( 0 ); 680 }, 681 process: function( results, params ) { 682 var list = '', alt = true, classes = '', 683 firstPage = params.page == 1; 684 685 if ( ! results ) { 686 if ( firstPage ) { 687 list += '<li class="unselectable no-matches-found"><span class="item-title"><em>' + 688 wpLinkL10n.noMatchesFound + '</em></span></li>'; 689 } 690 } else { 691 $.each( results, function() { 692 classes = alt ? 'alternate' : ''; 693 classes += this.title ? '' : ' no-title'; 694 list += classes ? '<li class="' + classes + '">' : '<li>'; 695 list += '<input type="hidden" class="item-permalink" value="' + this.permalink + '" />'; 696 list += '<span class="item-title">'; 697 list += this.title ? this.title : wpLinkL10n.noTitle; 698 list += '</span><span class="item-info">' + this.info + '</span></li>'; 699 alt = ! alt; 700 }); 701 } 702 703 this.ul[ firstPage ? 'html' : 'append' ]( list ); 704 }, 705 maybeLoad: function() { 706 var self = this, 707 el = this.element, 708 bottom = el.scrollTop() + el.height(); 709 710 if ( ! this.query.ready() || bottom < this.contentHeight.height() - wpLink.riverBottomThreshold ) 711 return; 712 713 setTimeout(function() { 714 var newTop = el.scrollTop(), 715 newBottom = newTop + el.height(); 716 717 if ( ! self.query.ready() || newBottom < self.contentHeight.height() - wpLink.riverBottomThreshold ) 718 return; 719 720 self.waiting.addClass( 'is-active' ); 721 el.scrollTop( newTop + self.waiting.outerHeight() ); 722 723 self.ajax( function() { 724 self.waiting.removeClass( 'is-active' ); 725 }); 726 }, wpLink.timeToTriggerRiver ); 727 } 728 }); 729 730 Query = function( search ) { 731 this.page = 1; 732 this.allLoaded = false; 733 this.querying = false; 734 this.search = search; 735 }; 736 737 $.extend( Query.prototype, { 738 ready: function() { 739 return ! ( this.querying || this.allLoaded ); 740 }, 741 ajax: function( callback ) { 742 var self = this, 743 query = { 744 action : 'wp-link-ajax', 745 page : this.page, 746 '_ajax_linking_nonce' : inputs.nonce.val() 747 }; 748 749 if ( this.search ) 750 query.search = this.search; 751 752 this.querying = true; 753 754 $.post( ajaxurl, query, function( r ) { 755 self.page++; 756 self.querying = false; 757 self.allLoaded = ! r; 758 callback( r, query ); 759 }, 'json' ); 760 } 761 }); 762 532 763 $( document ).ready( wpLink.init ); 533 764 })( jQuery, window.wpLinkL10n, window.wp );
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)