Merge "put SpecialMovepageAfterMove hook after success message output"
[mediawiki.git] / resources / mediawiki / mediawiki.searchSuggest.js
blob99a55576e730bd69ab9c973f9e7dcb9568d946ad
1 /**
2  * Add search suggestions to the search form.
3  */
4 ( function ( mw, $ ) {
5         $( document ).ready( function ( $ ) {
6                 var map, 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                         browsers: {
20                                 // Left-to-right languages
21                                 ltr: {
22                                         // SimpleSearch is broken in Opera < 9.6
23                                         opera: [['>=', 9.6]],
24                                         docomo: false,
25                                         blackberry: false,
26                                         ipod: false,
27                                         iphone: false
28                                 },
29                                 // Right-to-left languages
30                                 rtl: {
31                                         opera: [['>=', 9.6]],
32                                         docomo: false,
33                                         blackberry: false,
34                                         ipod: false,
35                                         iphone: false
36                                 }
37                         }
38                 };
40                 if ( !$.client.test( map ) ) {
41                         return;
42                 }
44                 // General suggestions functionality for all search boxes
45                 searchboxesSelectors = [
46                         // Primary searchbox on every page in standard skins
47                         '#searchInput',
48                         // Secondary searchbox in legacy skins (LegacyTemplate::searchForm uses id "searchInput + unique id")
49                         '#searchInput2',
50                         // Special:Search
51                         '#powerSearchText',
52                         '#searchText',
53                         // Generic selector for skins with multiple searchboxes (used by CologneBlue)
54                         '.mw-searchInput'
55                 ];
56                 $( searchboxesSelectors.join(', ') )
57                         .suggestions( {
58                                 fetch: function ( query ) {
59                                         var $el, jqXhr;
61                                         if ( query.length !== 0 ) {
62                                                 $el = $(this);
63                                                 jqXhr = $.ajax( {
64                                                         url: mw.util.wikiScript( 'api' ),
65                                                         data: {
66                                                                 format: 'json',
67                                                                 action: 'opensearch',
68                                                                 search: query,
69                                                                 namespace: 0,
70                                                                 suggest: ''
71                                                         },
72                                                         dataType: 'json',
73                                                         success: function ( data ) {
74                                                                 if ( $.isArray( data ) && data.length ) {
75                                                                         $el.suggestions( 'suggestions', data[1] );
76                                                                 }
77                                                         }
78                                                 });
79                                                 $el.data( 'request', jqXhr );
80                                         }
81                                 },
82                                 cancel: function () {
83                                         var jqXhr = $(this).data( 'request' );
84                                         // If the delay setting has caused the fetch to have not even happened
85                                         // yet, the jqXHR object will have never been set.
86                                         if ( jqXhr && $.isFunction( jqXhr.abort ) ) {
87                                                 jqXhr.abort();
88                                                 $(this).removeData( 'request' );
89                                         }
90                                 },
91                                 result: {
92                                         select: function ( $input ) {
93                                                 $input.closest( 'form' ).submit();
94                                         }
95                                 },
96                                 delay: 120,
97                                 highlightInput: true
98                         } )
99                         .bind( 'paste cut drop', function () {
100                                 // make sure paste and cut events from the mouse and drag&drop events
101                                 // trigger the keypress handler and cause the suggestions to update
102                                 $( this ).trigger( 'keypress' );
103                         } );
105                 // Ensure that the thing is actually present!
106                 if ( $searchRegion.length === 0 ) {
107                         // Don't try to set anything up if simpleSearch is disabled sitewide.
108                         // The loader code loads us if the option is present, even if we're
109                         // not actually enabled (anymore).
110                         return;
111                 }
113                 // Placeholder text for search box
114                 $searchInput
115                         .attr( 'placeholder', mw.msg( 'searchsuggest-search' ) )
116                         .placeholder();
118                 // Special suggestions functionality for skin-provided search box
119                 $searchInput.suggestions( {
120                         result: {
121                                 select: function ( $input ) {
122                                         $input.closest( 'form' ).submit();
123                                 }
124                         },
125                         special: {
126                                 render: function ( query ) {
127                                         var $el = this;
128                                         if ( $el.children().length === 0 ) {
129                                                 $el
130                                                         .append(
131                                                                 $( '<div>' )
132                                                                         .addClass( 'special-label' )
133                                                                         .text( mw.msg( 'searchsuggest-containing' ) ),
134                                                                 $( '<div>' )
135                                                                         .addClass( 'special-query' )
136                                                                         .text( query )
137                                                                         .autoEllipsis()
138                                                         )
139                                                         .show();
140                                         } else {
141                                                 $el.find( '.special-query' )
142                                                         .text( query )
143                                                         .autoEllipsis();
144                                         }
145                                 },
146                                 select: function ( $input ) {
147                                         $input.closest( 'form' ).append(
148                                                 $( '<input type="hidden" name="fulltext" value="1"/>' )
149                                         );
150                                         $input.closest( 'form' ).submit();
151                                 }
152                         },
153                         $region: $searchRegion
154                 } );
156                 // In most skins (at least Monobook and Vector), the font-size is messed up in <body>.
157                 // (they use 2 elements to get a sane font-height). So, instead of making exceptions for
158                 // each skin or adding more stylesheets, just copy it from the active element so auto-fit.
159                 $searchInput
160                         .data( 'suggestions-context' )
161                         .data.$container
162                                 .css( 'fontSize', $searchInput.css( 'fontSize' ) );
164         } );
166 }( mediaWiki, jQuery ) );