jquery.suggestions, mediawiki.searchSuggest: Don't use jquery.autoEllipsis
[mediawiki.git] / resources / mediawiki / mediawiki.searchSuggest.js
blob8a8871d8fdfd7eead246cfc504d076ff2591b513
1 /*!
2  * Add search suggestions to the search form.
3  */
4 ( function ( mw, $ ) {
5         $( function () {
6                 var map, resultRenderCache, searchboxesSelectors,
7                         // Region where the suggestions box will appear directly below
8                         // (using the same width). Can be a container element or the input
9                         // itself, depending on what suits best in the environment.
10                         // For Vector the suggestion box should align with the simpleSearch
11                         // container's borders, in other skins it should align with the input
12                         // element (not the search form, as that would leave the buttons
13                         // vertically between the input and the suggestions).
14                         $searchRegion = $( '#simpleSearch, #searchInput' ).first(),
15                         $searchInput = $( '#searchInput' );
17                 // Compatibility map
18                 map = {
19                         // SimpleSearch is broken in Opera < 9.6
20                         opera: [['>=', 9.6]],
21                         // Older Konquerors are unable to position the suggestions correctly (bug 50805)
22                         konqueror: [['>=', '4.11']],
23                         docomo: false,
24                         blackberry: false,
25                         ipod: false,
26                         iphone: false
27                 };
29                 if ( !$.client.test( map ) ) {
30                         return;
31                 }
33                 // Compute form data for search suggestions functionality.
34                 function computeResultRenderCache( context ) {
35                         var $form, baseHref, linkParams;
37                         // Compute common parameters for links' hrefs
38                         $form = context.config.$region.closest( 'form' );
40                         baseHref = $form.attr( 'action' );
41                         baseHref += baseHref.indexOf( '?' ) > -1 ? '&' : '?';
43                         linkParams = {};
44                         $.each( $form.serializeArray(), function ( idx, obj ) {
45                                 linkParams[ obj.name ] = obj.value;
46                         } );
48                         return {
49                                 textParam: context.data.$textbox.attr( 'name' ),
50                                 linkParams: linkParams,
51                                 baseHref: baseHref
52                         };
53                 }
55                 // The function used to render the suggestions.
56                 function renderFunction( text, context ) {
57                         if ( !resultRenderCache ) {
58                                 resultRenderCache = computeResultRenderCache( context );
59                         }
61                         // linkParams object is modified and reused
62                         resultRenderCache.linkParams[ resultRenderCache.textParam ] = text;
64                         // this is the container <div>, jQueryfied
65                         this.text( text )
66                                 .wrap(
67                                         $( '<a>' )
68                                                 .attr( 'href', resultRenderCache.baseHref + $.param( resultRenderCache.linkParams ) )
69                                                 .addClass( 'mw-searchSuggest-link' )
70                                 );
71                 }
73                 function specialRenderFunction( query, context ) {
74                         var $el = this;
76                         if ( !resultRenderCache ) {
77                                 resultRenderCache = computeResultRenderCache( context );
78                         }
80                         // linkParams object is modified and reused
81                         resultRenderCache.linkParams[ resultRenderCache.textParam ] = query;
83                         if ( $el.children().length === 0 ) {
84                                 $el
85                                         .append(
86                                                 $( '<div>' )
87                                                         .addClass( 'special-label' )
88                                                         .text( mw.msg( 'searchsuggest-containing' ) ),
89                                                 $( '<div>' )
90                                                         .addClass( 'special-query' )
91                                                         .text( query )
92                                         )
93                                         .show();
94                         } else {
95                                 $el.find( '.special-query' )
96                                         .text( query );
97                         }
99                         if ( $el.parent().hasClass( 'mw-searchSuggest-link' ) ) {
100                                 $el.parent().attr( 'href', resultRenderCache.baseHref + $.param( resultRenderCache.linkParams ) + '&fulltext=1' );
101                         } else {
102                                 $el.wrap(
103                                         $( '<a>' )
104                                                 .attr( 'href', resultRenderCache.baseHref + $.param( resultRenderCache.linkParams ) + '&fulltext=1' )
105                                                 .addClass( 'mw-searchSuggest-link' )
106                                 );
107                         }
108                 }
110                 // General suggestions functionality for all search boxes
111                 searchboxesSelectors = [
112                         // Primary searchbox on every page in standard skins
113                         '#searchInput',
114                         // Special:Search
115                         '#powerSearchText',
116                         '#searchText',
117                         // Generic selector for skins with multiple searchboxes (used by CologneBlue)
118                         '.mw-searchInput'
119                 ];
120                 $( searchboxesSelectors.join( ', ' ) )
121                         .suggestions( {
122                                 fetch: function ( query ) {
123                                         var $el;
125                                         if ( query.length !== 0 ) {
126                                                 $el = $( this );
127                                                 $el.data( 'request', ( new mw.Api() ).get( {
128                                                         action: 'opensearch',
129                                                         search: query,
130                                                         namespace: 0,
131                                                         suggest: ''
132                                                 } ).done( function ( data ) {
133                                                         $el.suggestions( 'suggestions', data[1] );
134                                                 } ) );
135                                         }
136                                 },
137                                 cancel: function () {
138                                         var apiPromise = $( this ).data( 'request' );
139                                         // If the delay setting has caused the fetch to have not even happened
140                                         // yet, the apiPromise object will have never been set.
141                                         if ( apiPromise && $.isFunction( apiPromise.abort ) ) {
142                                                 apiPromise.abort();
143                                                 $( this ).removeData( 'request' );
144                                         }
145                                 },
146                                 result: {
147                                         render: renderFunction,
148                                         select: function () {
149                                                 return true; // allow the form to be submitted
150                                         }
151                                 },
152                                 delay: 120,
153                                 highlightInput: true
154                         } )
155                         .bind( 'paste cut drop', function () {
156                                 // make sure paste and cut events from the mouse and drag&drop events
157                                 // trigger the keypress handler and cause the suggestions to update
158                                 $( this ).trigger( 'keypress' );
159                         } );
161                 // Ensure that the thing is actually present!
162                 if ( $searchRegion.length === 0 ) {
163                         // Don't try to set anything up if simpleSearch is disabled sitewide.
164                         // The loader code loads us if the option is present, even if we're
165                         // not actually enabled (anymore).
166                         return;
167                 }
169                 // Special suggestions functionality for skin-provided search box
170                 $searchInput.suggestions( {
171                         result: {
172                                 render: renderFunction,
173                                 select: function () {
174                                         return true; // allow the form to be submitted
175                                 }
176                         },
177                         special: {
178                                 render: specialRenderFunction,
179                                 select: function ( $input ) {
180                                         $input.closest( 'form' )
181                                                 .append( $( '<input type="hidden" name="fulltext" value="1"/>' ) );
182                                         return true; // allow the form to be submitted
183                                 }
184                         },
185                         $region: $searchRegion
186                 } );
188                 // If the form includes any fallback fulltext search buttons, remove them
189                 $searchInput.closest( 'form' ).find( '.mw-fallbackSearchButton' ).remove();
191                 // In most skins (at least Monobook and Vector), the font-size is messed up in <body>.
192                 // (they use 2 elements to get a sane font-height). So, instead of making exceptions for
193                 // each skin or adding more stylesheets, just copy it from the active element so auto-fit.
194                 $searchInput
195                         .data( 'suggestions-context' )
196                         .data.$container
197                                 .css( 'fontSize', $searchInput.css( 'fontSize' ) );
199         } );
201 }( mediaWiki, jQuery ) );