Merge "(Bug 41298) partial fix: re-applying Id7b331e1b"
[lhc/web/wiklou.git] / resources / mediawiki / mediawiki.searchSuggest.js
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' );
16
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 };
39
40 if ( !$.client.test( map ) ) {
41 return;
42 }
43
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;
60
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 } );
104
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 }
112
113 // Placeholder text for search box
114 $searchInput
115 .attr( 'placeholder', mw.msg( 'searchsuggest-search' ) )
116 .placeholder();
117
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 } );
155
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' ) );
163
164 } );
165
166 }( mediaWiki, jQuery ) );