[ Index ] |
PHP Cross Reference of BuddyPress |
[Summary view] [Print] [Text view]
1 /* global bp */ 2 3 window.bp = window.bp || {}; 4 5 ( function( bp, $, undefined ) { 6 var mentionsQueryCache = [], 7 mentionsItem; 8 9 bp.mentions = bp.mentions || {}; 10 bp.mentions.users = window.bp.mentions.users || []; 11 12 if ( typeof window.BP_Suggestions === 'object' ) { 13 bp.mentions.users = window.BP_Suggestions.friends || bp.mentions.users; 14 } 15 16 /** 17 * Adds BuddyPress @mentions to form inputs. 18 * 19 * @param {array|object} options If array, becomes the suggestions' data source. If object, passed as config to $.atwho(). 20 * @since 2.1.0 21 */ 22 $.fn.bp_mentions = function( options ) { 23 if ( Array.isArray( options ) ) { 24 options = { data: options }; 25 } 26 27 /** 28 * Default options for at.js; see https://github.com/ichord/At.js/. 29 */ 30 var suggestionsDefaults = { 31 delay: 200, 32 hideWithoutSuffix: true, 33 insertTpl: '@$ID}', 34 limit: 10, 35 startWithSpace: false, 36 suffix: '', 37 38 callbacks: { 39 /** 40 * Custom filter to only match the start of spaced words. 41 * Based on the core/default one. 42 * 43 * @param {string} query 44 * @param {array} data 45 * @param {string} search_key 46 * @return {array} 47 * @since 2.1.0 48 */ 49 filter: function( query, data, search_key ) { 50 var item, _i, _len, _results = [], 51 regxp = new RegExp( '^' + query + '| ' + query, 'ig' ); // start of string, or preceded by a space. 52 53 for ( _i = 0, _len = data.length; _i < _len; _i++ ) { 54 item = data[ _i ]; 55 if ( item[ search_key ].toLowerCase().match( regxp ) ) { 56 _results.push( item ); 57 } 58 } 59 60 return _results; 61 }, 62 63 /** 64 * Removes some spaces around highlighted string and tweaks regex to allow spaces 65 * (to match display_name). Based on the core default. 66 * 67 * @param {unknown} li 68 * @param {string} query 69 * @return {string} 70 * @since 2.1.0 71 */ 72 highlighter: function( li, query ) { 73 if ( ! query ) { 74 return li; 75 } 76 77 var regexp = new RegExp( '>(\\s*|[\\w\\s]*)(' + this.at.replace( '+', '\\+') + '?' + query.replace( '+', '\\+' ) + ')([\\w ]*)\\s*<', 'ig' ); 78 return li.replace( regexp, function( str, $1, $2, $3 ) { 79 return '>' + $1 + '<strong>' + $2 + '</strong>' + $3 + '<'; 80 }); 81 }, 82 83 /** 84 * Reposition the suggestion list dynamically. 85 * 86 * @param {unknown} offset 87 * @since 2.1.0 88 */ 89 before_reposition: function( offset ) { 90 // get the iframe, if any, already applied with atwho.js library. 91 var caret, 92 line, 93 iframeOffset, 94 move, 95 $view = $( '#atwho-ground-' + this.id + ' .atwho-view' ), 96 $body = $( 'body' ), 97 atwhoDataValue = this.$inputor.data( 'atwho' ); 98 99 if ( 'undefined' !== atwhoDataValue && 'undefined' !== atwhoDataValue.iframe && null !== atwhoDataValue.iframe ) { 100 caret = this.$inputor.caret( 'offset', { iframe: atwhoDataValue.iframe } ); 101 // Caret.js no longer calculates iframe caret position from the window (it's now just within the iframe). 102 // We need to get the iframe offset from the window and merge that into our object. 103 iframeOffset = $( atwhoDataValue.iframe ).offset(); 104 if ( 'undefined' !== iframeOffset ) { 105 caret.left += iframeOffset.left; 106 caret.top += iframeOffset.top; 107 } 108 } else { 109 caret = this.$inputor.caret( 'offset' ); 110 } 111 112 // If the caret is past horizontal half, then flip it, yo. 113 if ( caret.left > ( $body.width() / 2 ) ) { 114 $view.addClass( 'right' ); 115 move = caret.left - offset.left - this.view.$el.width(); 116 } else { 117 $view.removeClass( 'right' ); 118 move = caret.left - offset.left + 1; 119 } 120 121 // If we're on a small screen, scroll to caret. 122 if ( $body.width() <= 400 ) { 123 $( document ).scrollTop( caret.top - 6 ); 124 } 125 126 // New position is under the caret (never above) and positioned to follow. 127 // Dynamic sizing based on the input area (remove 'px' from end). 128 line = parseInt( this.$inputor.css( 'line-height' ).substr( 0, this.$inputor.css( 'line-height' ).length - 2 ), 10 ); 129 if ( !line || line < 5 ) { // Sanity check, and catch no line-height. 130 line = 19; 131 } 132 133 offset.top = caret.top + line; 134 offset.left += move; 135 }, 136 137 /** 138 * Override default behavior which inserts junk tags in the WordPress Visual editor. 139 * 140 * @param {unknown} $inputor Element which we're inserting content into. 141 * @param {string} content The content that will be inserted. 142 * @param {string} suffix Applied to the end of the content string. 143 * @return {string} 144 * @since 2.1.0 145 */ 146 inserting_wrapper: function( $inputor, content, suffix ) { 147 return '' + content + suffix; 148 } 149 } 150 }, 151 152 /** 153 * Default options for our @mentions; see https://github.com/ichord/At.js/. 154 */ 155 mentionsDefaults = { 156 callbacks: { 157 /** 158 * If there are no matches for the query in this.data, then query BuddyPress. 159 * 160 * @param {string} query Partial @mention to search for. 161 * @param {function} render_view Render page callback function. 162 * @since 2.1.0 163 * @since 3.0.0. Renamed from "remote_filter" for at.js v1.5.4 support. 164 */ 165 remoteFilter: function( query, render_view ) { 166 var self = $( this ), 167 params = {}; 168 169 mentionsItem = mentionsQueryCache[ query ]; 170 if ( typeof mentionsItem === 'object' ) { 171 render_view( mentionsItem ); 172 return; 173 } 174 175 if ( self.xhr ) { 176 self.xhr.abort(); 177 } 178 179 params = { 'action': 'bp_get_suggestions', 'term': query, 'type': 'members' }; 180 181 var groupId = this.$inputor.data( 'suggestions-group-id' ); 182 if ( ( 'number' === typeof groupId || 'string' === typeof groupId ) && ! isNaN( groupId - parseFloat( groupId ) ) ) { 183 params['group-id'] = parseInt( this.$inputor.data( 'suggestions-group-id' ), 10 ); 184 } 185 186 self.xhr = $.getJSON( ajaxurl, params ) 187 /** 188 * Success callback for the @suggestions lookup. 189 * 190 * @param {object} response Details of users matching the query. 191 * @since 2.1.0 192 */ 193 .done(function( response ) { 194 if ( ! response.success ) { 195 return; 196 } 197 198 var data = $.map( response.data, 199 /** 200 * Create a composite index to determine ordering of results; 201 * nicename matches will appear on top. 202 * 203 * @param {array} suggestion A suggestion's original data. 204 * @return {array} A suggestion's new data. 205 * @since 2.1.0 206 */ 207 function( suggestion ) { 208 suggestion.search = suggestion.search || suggestion.ID + ' ' + suggestion.name; 209 return suggestion; 210 } 211 ); 212 213 mentionsQueryCache[ query ] = data; 214 render_view( data ); 215 }); 216 } 217 }, 218 219 data: $.map( options.data, 220 /** 221 * Create a composite index to search against of nicename + display name. 222 * This will also determine ordering of results, so nicename matches will appear on top. 223 * 224 * @param {array} suggestion A suggestion's original data. 225 * @return {array} A suggestion's new data. 226 * @since 2.1.0 227 */ 228 function( suggestion ) { 229 suggestion.search = suggestion.search || suggestion.ID + ' ' + suggestion.name; 230 return suggestion; 231 } 232 ), 233 234 at: '@', 235 searchKey: 'search', 236 displayTpl: '<li data-value="@$ID}"><img src="$image}" alt="" /><span class="username">@$ID}</span><small>$name}</small></li>' 237 }, 238 239 opts = $.extend( true, {}, suggestionsDefaults, mentionsDefaults, options ); 240 return $.fn.atwho.call( this, opts ); 241 }; 242 243 $( document ).ready(function() { 244 // Activity/reply, post comments, dashboard post 'text' editor. 245 $( '.bp-suggestions, #comments form textarea, .wp-editor-area' ).bp_mentions( bp.mentions.users ); 246 }); 247 248 bp.mentions.tinyMCEinit = function() { 249 if ( typeof window.tinyMCE === 'undefined' || window.tinyMCE.activeEditor === null || typeof window.tinyMCE.activeEditor === 'undefined' ) { 250 return; 251 } else { 252 $( window.tinyMCE.activeEditor.contentDocument.activeElement ) 253 .atwho( 'setIframe', $( '.wp-editor-wrap iframe' )[0] ) 254 .bp_mentions( bp.mentions.users ); 255 } 256 }; 257 })( bp, jQuery );
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Tue Oct 8 01:00:53 2024 | Cross-referenced by PHPXref 0.7.1 |