r91728 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r91727‎ | r91728 | r91729 >
Date:14:59, 8 July 2011
Author:diebuche
Status:reverted (Comments)
Tags:
Comment:
Rewrite mwsuggest.js using j.ui.autocomplete. This gets rid of a lot of the little kinks of the previously implemenation: The suggestion list now contains regular anchors which can be openened in new indows or separate tabs. The carret doesn't jump around anymore when using the arrow keys to select an item. This should make it much easier to eventually merge Vectors simple search & mwsuggest.
Modified paths:
  • /trunk/phase3/includes/OutputPage.php (modified) (history)
  • /trunk/phase3/resources/Resources.php (modified) (history)
  • /trunk/phase3/resources/mediawiki.page/mediawiki.page.mwsuggest.js (added) (history)
  • /trunk/phase3/skins/common/mwsuggest.js (deleted) (history)
  • /trunk/phase3/skins/common/shared.css (modified) (history)
  • /trunk/phase3/skins/monobook/main.css (modified) (history)

Diff [purge]

Index: trunk/phase3/resources/mediawiki.page/mediawiki.page.mwsuggest.js
@@ -0,0 +1,76 @@
 2+jQuery( document ).ready( function( $ ) {
 3+ var $container = $('<div>', {'class' : 'open-search-suggestions'}),
 4+ cache = {},
 5+ $suggestionList,
 6+ url = mw.config.get('wgScriptPath') + '/api.php?format=json&action=opensearch&search=',
 7+ maxRowWindow;
 8+
 9+ //Append the container which will hold the menu to the body
 10+ $('body').append( $container );
 11+
 12+ /* Grabs namespaces from search form or
 13+ * in case we're not on a search page, take it from wgSearchNamespaces.
 14+ * @return Array: List of Namespaces that should be searched
 15+ */
 16+ getNamespaces = function() {
 17+ var namespaces = [];
 18+ $('form#powersearch, form#search').find( '[name^="ns"]' ).each(function() {
 19+ if ( this.checked || ( this.type == 'hidden' && this.value == '1' ) ) {
 20+ namespaces.push( this.name.substring( 2 ) );
 21+ }
 22+ });
 23+ if ( !namespaces.length ) {
 24+ namespaces = mw.config.get('wgSearchNamespaces');
 25+ }
 26+ return namespaces.join('|');
 27+ };
 28+
 29+ /* Helper function to make sure that the list doesn't expand below the visible part of the window */
 30+ deliverResult = function( obj, response, maxRowWindow ) {
 31+ if ( obj && obj.length > 1 ) {
 32+ response( obj[1] );
 33+ // Get the lowest from multiple numbers using fn.apply
 34+ var maxRow = Math.min.apply( Math, [7, obj[1].length, maxRowWindow] );
 35+ $suggestionList.css( 'height', maxRow * $suggestionList.find( '.ui-menu-item' ).eq( 0 ).height() );
 36+ } else {
 37+ response( [] );
 38+ }
 39+ };
 40+
 41+ /* The actual autocomplete setup */
 42+ $("#searchInput").autocomplete({
 43+ minLength: 2,
 44+ source: function ( request, response ) {
 45+ var namespaces = getNamespaces();
 46+ // We're caching queries for performance
 47+ var term = request.term + namespaces;
 48+ if (term in cache) {
 49+ deliverResult( cache[term], response, maxRowWindow );
 50+ return;
 51+ }
 52+ $.getJSON(url + mw.util.rawurlencode( request.term ) + '&namespace=' + namespaces, function ( obj ) {
 53+ // Save to cache
 54+ cache[term] = obj;
 55+ deliverResult( obj, response, maxRowWindow );
 56+ });
 57+ },
 58+ select: function() {
 59+ $('#searchGoButton').click();
 60+ },
 61+ create : function() {
 62+ $suggestionList = $container.find('ul');
 63+ },
 64+ appendTo: '.open-search-suggestions',
 65+ open: function() {
 66+ maxRowWindow = Math.floor(
 67+ ( $(window).height() - $suggestionList.offset().top + $(window).scrollTop() ) /
 68+ $suggestionList.find( '.ui-menu-item' ).eq( 0 ).height()
 69+ );
 70+ }
 71+ });
 72+
 73+ /* Legacy teardown, called when things like SimpleSearch need to disable MWSuggest */
 74+ window.os_MWSuggestDisable = function() {
 75+ return $("#searchInput").autocomplete( "destroy" );
 76+ };
 77+});
\ No newline at end of file
Property changes on: trunk/phase3/resources/mediawiki.page/mediawiki.page.mwsuggest.js
___________________________________________________________________
Added: svn:eol-style
178 + native
Index: trunk/phase3/resources/Resources.php
@@ -477,6 +477,12 @@
478478 'jquery.mwPrototypes',
479479 ),
480480 ),
 481+ 'mediawiki.page.mwsuggest' => array(
 482+ 'scripts' => 'resources/mediawiki.page/mediawiki.page.mwsuggest.js',
 483+ 'dependencies' => array(
 484+ 'jquery.ui.autocomplete',
 485+ ),
 486+ ),
481487 'mediawiki.libs.jpegmeta' => array(
482488 'scripts' => 'resources/mediawiki.libs/mediawiki.libs.jpegmeta.js',
483489 ),
@@ -648,13 +654,6 @@
649655 'localBasePath' => $GLOBALS['wgStyleDirectory'],
650656 'dependencies' => 'mediawiki.legacy.wikibits',
651657 ),
652 - 'mediawiki.legacy.mwsuggest' => array(
653 - 'scripts' => 'common/mwsuggest.js',
654 - 'remoteBasePath' => $GLOBALS['wgStylePath'],
655 - 'localBasePath' => $GLOBALS['wgStyleDirectory'],
656 - 'dependencies' => array( 'mediawiki.legacy.wikibits', 'jquery.client' ),
657 - 'messages' => array( 'search-mwsuggest-enabled', 'search-mwsuggest-disabled' ),
658 - ),
659658 'mediawiki.legacy.preview' => array(
660659 'scripts' => 'common/preview.js',
661660 'remoteBasePath' => $GLOBALS['wgStylePath'],
Index: trunk/phase3/skins/monobook/main.css
@@ -1246,8 +1246,8 @@
12471247 }
12481248
12491249 /* God-damned hack for the crappy layout */
1250 -.os-suggest {
1251 - font-size: 127%;
 1250+.ui-autocomplete {
 1251+ font-size: 127%!important;
12521252 }
12531253
12541254 /* Sometimes people don't want personal tools to be lowercase! */
Index: trunk/phase3/skins/common/mwsuggest.js
@@ -1,1066 +0,0 @@
2 -/*
3 - * OpenSearch ajax suggestion engine for MediaWiki
4 - *
5 - * uses core MediaWiki open search support to fetch suggestions
6 - * and show them below search boxes and other inputs
7 - *
8 - * by Robert Stojnic (April 2008)
9 - */
10 -
11 -// Make sure wgMWSuggestTemplate is defined
12 -if ( !mw.config.exists( 'wgMWSuggestTemplate' ) ) {
13 - mw.config.set( 'wgMWSuggestTemplate', mw.config.get( 'wgServer' ) + mw.config.get( 'wgScriptPath' )
14 - + "/api.php?action=opensearch\x26search={searchTerms}\x26namespace={namespaces}\x26suggest" );
15 -}
16 -
17 -// search_box_id -> Results object
18 -window.os_map = {};
19 -// cached data, url -> json_text
20 -window.os_cache = {};
21 -// global variables for suggest_keypress
22 -window.os_cur_keypressed = 0;
23 -window.os_keypressed_count = 0;
24 -// type: Timer
25 -window.os_timer = null;
26 -// tie mousedown/up events
27 -window.os_mouse_pressed = false;
28 -window.os_mouse_num = -1;
29 -// if true, the last change was made by mouse (and not keyboard)
30 -window.os_mouse_moved = false;
31 -// delay between keypress and suggestion (in ms)
32 -window.os_search_timeout = 250;
33 -// these pairs of inputs/forms will be autoloaded at startup
34 -window.os_autoload_inputs = new Array('searchInput', 'searchInput2', 'powerSearchText', 'searchText');
35 -window.os_autoload_forms = new Array('searchform', 'searchform2', 'powersearch', 'search' );
36 -// if we stopped the service
37 -window.os_is_stopped = false;
38 -// max lines to show in suggest table
39 -window.os_max_lines_per_suggest = 7;
40 -// number of steps to animate expansion/contraction of container width
41 -window.os_animation_steps = 6;
42 -// num of pixels of smallest step
43 -window.os_animation_min_step = 2;
44 -// delay between steps (in ms)
45 -window.os_animation_delay = 30;
46 -// max width of container in percent of normal size (1 == 100%)
47 -window.os_container_max_width = 2;
48 -// currently active animation timer
49 -window.os_animation_timer = null;
50 -// whether MWSuggest is enabled. Set to false when os_MWSuggestDisable() is called
51 -window.os_enabled = true;
52 -
53 -/**
54 - * <datalist> is a new HTML5 element that allows you to manually supply
55 - * suggestion lists and have them rendered according to the right platform
56 - * conventions. Opera as of version 11 has a fatal problem: the suggestion
57 - * lags behind what the user types by one keypress. (Reported as DSK-276870 to
58 - * Opera's secret bug tracker.) However, Firefox 4 supports it without
59 - * problems, so Opera is just blacklisted here. Ideally we wouldn't blacklist
60 - * future versions, in case they fix it, but the fallback isn't bad at all and
61 - * the failure if they don't fix it is very annoying, so in this case we'll
62 - * blacklist future versions too.
63 - */
64 -window.os_use_datalist = 'list' in document.createElement( 'input' )
65 - && $.client.profile().name != 'opera';
66 -
67 -/** Timeout timer class that will fetch the results */
68 -window.os_Timer = function( id, r, query ) {
69 - this.id = id;
70 - this.r = r;
71 - this.query = query;
72 -};
73 -
74 -/** Property class for single search box */
75 -window.os_Results = function( name, formname ) {
76 - this.searchform = formname; // id of the searchform
77 - this.searchbox = name; // id of the searchbox
78 - this.container = name + 'Suggest'; // div that holds results
79 - this.resultTable = name + 'Result'; // id base for the result table (+num = table row)
80 - this.resultText = name + 'ResultText'; // id base for the spans within result tables (+num)
81 - this.toggle = name + 'Toggle'; // div that has the toggle (enable/disable) link
82 - this.query = null; // last processed query
83 - this.results = null; // parsed titles
84 - this.resultCount = 0; // number of results
85 - this.original = null; // query that user entered
86 - this.selected = -1; // which result is selected
87 - this.containerCount = 0; // number of results visible in container
88 - this.containerRow = 0; // height of result field in the container
89 - this.containerTotal = 0; // total height of the container will all results
90 - this.visible = false; // if container is visible
91 - this.stayHidden = false; // don't try to show if lost focus
92 -};
93 -
94 -/** Timer user to animate expansion/contraction of container width */
95 -window.os_AnimationTimer = function( r, target ) {
96 - this.r = r;
97 - var current = document.getElementById(r.container).offsetWidth;
98 - this.inc = Math.round( ( target - current ) / os_animation_steps );
99 - if( this.inc < os_animation_min_step && this.inc >=0 ) {
100 - this.inc = os_animation_min_step; // minimal animation step
101 - }
102 - if( this.inc > -os_animation_min_step && this.inc < 0 ) {
103 - this.inc = -os_animation_min_step;
104 - }
105 - this.target = target;
106 -};
107 -
108 -/******************
109 - * Initialization
110 - ******************/
111 -
112 -/** Initialization, call upon page onload */
113 -window.os_MWSuggestInit = function() {
114 - if ( !window.os_enabled ) {
115 - return;
116 - }
117 -
118 - for( var i = 0; i < os_autoload_inputs.length; i++ ) {
119 - var id = os_autoload_inputs[i];
120 - var form = os_autoload_forms[i];
121 - element = document.getElementById( id );
122 - if( element != null ) {
123 - os_initHandlers( id, form, element );
124 - }
125 - }
126 -};
127 -
128 -/* Teardown, called when things like SimpleSearch need to disable MWSuggest */
129 -window.os_MWSuggestTeardown = function() {
130 - for( var i = 0; i < os_autoload_inputs.length; i++ ) {
131 - var id = os_autoload_inputs[i];
132 - var form = os_autoload_forms[i];
133 - element = document.getElementById( id );
134 - if( element != null ) {
135 - os_teardownHandlers( id, form, element );
136 - }
137 - }
138 -};
139 -
140 -/* Call this to disable MWSuggest. Works regardless of whether MWSuggest has been initialized already. */
141 -window.os_MWSuggestDisable = function() {
142 - window.os_MWSuggestTeardown();
143 - window.os_enabled = false;
144 -}
145 -
146 -
147 -/** Init Result objects and event handlers */
148 -window.os_initHandlers = function( name, formname, element ) {
149 - var r = new os_Results( name, formname );
150 - var formElement = document.getElementById( formname );
151 - if( !formElement ) {
152 - // Older browsers (Opera 8) cannot get form elements
153 - return;
154 - }
155 - // event handler
156 - os_hookEvent( element, 'keyup', os_eventKeyup );
157 - os_hookEvent( element, 'keydown', os_eventKeydown );
158 - os_hookEvent( element, 'keypress', os_eventKeypress );
159 - if ( !os_use_datalist ) {
160 - // These are needed for the div hack to hide it if the user blurs.
161 - os_hookEvent( element, 'blur', os_eventBlur );
162 - os_hookEvent( element, 'focus', os_eventFocus );
163 - // We don't want browser auto-suggestions interfering with our div, but
164 - // autocomplete must be on for datalist to work (at least in Opera
165 - // 10.10).
166 - element.setAttribute( 'autocomplete', 'off' );
167 - }
168 - // stopping handler
169 - os_hookEvent( formElement, 'submit', os_eventOnsubmit );
170 - os_map[name] = r;
171 - // toggle link
172 - if( document.getElementById( r.toggle ) == null ) {
173 - // TODO: disable this while we figure out a way for this to work in all browsers
174 - /* if( name == 'searchInput' ) {
175 - // special case: place above the main search box
176 - var t = os_createToggle( r, 'os-suggest-toggle' );
177 - var searchBody = document.getElementById( 'searchBody' );
178 - var first = searchBody.parentNode.firstChild.nextSibling.appendChild(t);
179 - } else {
180 - // default: place below search box to the right
181 - var t = os_createToggle( r, 'os-suggest-toggle-def' );
182 - var top = element.offsetTop + element.offsetHeight;
183 - var left = element.offsetLeft + element.offsetWidth;
184 - t.style.position = 'absolute';
185 - t.style.top = top + 'px';
186 - t.style.left = left + 'px';
187 - element.parentNode.appendChild( t );
188 - // only now width gets calculated, shift right
189 - left -= t.offsetWidth;
190 - t.style.left = left + 'px';
191 - t.style.visibility = 'visible';
192 - } */
193 - }
194 -
195 -};
196 -
197 -window.os_teardownHandlers = function( name, formname, element ) {
198 - var formElement = document.getElementById( formname );
199 - if( !formElement ) {
200 - // Older browsers (Opera 8) cannot get form elements
201 - return;
202 - }
203 -
204 - os_unhookEvent( element, 'keyup', os_eventKeyup );
205 - os_unhookEvent( element, 'keydown', os_eventKeydown );
206 - os_unhookEvent( element, 'keypress', os_eventKeypress );
207 - if ( !os_use_datalist ) {
208 - // These are needed for the div hack to hide it if the user blurs.
209 - os_unhookEvent( element, 'blur', os_eventBlur );
210 - os_unhookEvent( element, 'focus', os_eventFocus );
211 - // We don't want browser auto-suggestions interfering with our div, but
212 - // autocomplete must be on for datalist to work (at least in Opera
213 - // 10.10).
214 - element.removeAttribute( 'autocomplete' );
215 - }
216 - // stopping handler
217 - os_unhookEvent( formElement, 'submit', os_eventOnsubmit );
218 -};
219 -
220 -
221 -window.os_hookEvent = function( element, hookName, hookFunct ) {
222 - if ( element.addEventListener ) {
223 - element.addEventListener( hookName, hookFunct, false );
224 - } else if ( window.attachEvent ) {
225 - element.attachEvent( 'on' + hookName, hookFunct );
226 - }
227 -};
228 -
229 -window.os_unhookEvent = function( element, hookName, hookFunct ) {
230 - if ( element.removeEventListener ) {
231 - element.removeEventListener( hookName, hookFunct, false );
232 - } else if ( element.detachEvent ) {
233 - element.detachEvent( 'on' + hookName, hookFunct );
234 - }
235 -}
236 -
237 -/********************
238 - * Keyboard events
239 - ********************/
240 -
241 -/** Event handler that will fetch results on keyup */
242 -window.os_eventKeyup = function( e ) {
243 - var targ = os_getTarget( e );
244 - var r = os_map[targ.id];
245 - if( r == null ) {
246 - return; // not our event
247 - }
248 -
249 - // some browsers won't generate keypressed for arrow keys, catch it
250 - if( os_keypressed_count == 0 ) {
251 - os_processKey( r, os_cur_keypressed, targ );
252 - }
253 - var query = targ.value;
254 - os_fetchResults( r, query, os_search_timeout );
255 -};
256 -
257 -/** catch arrows up/down and escape to hide the suggestions */
258 -window.os_processKey = function( r, keypressed, targ ) {
259 - if ( keypressed == 40 && !r.visible && os_timer == null ) {
260 - // If the user hits the down arrow, fetch results immediately if none
261 - // are already displayed.
262 - r.query = '';
263 - os_fetchResults( r, targ.value, 0 );
264 - }
265 - // Otherwise, if we're not using datalist, we need to handle scrolling and
266 - // so on.
267 - if ( os_use_datalist ) {
268 - return;
269 - }
270 - if ( keypressed == 40 ) { // Arrow Down
271 - if ( r.visible ) {
272 - os_changeHighlight( r, r.selected, r.selected + 1, true );
273 - }
274 - } else if ( keypressed == 38 ) { // Arrow Up
275 - if ( r.visible ) {
276 - os_changeHighlight( r, r.selected, r.selected - 1, true );
277 - }
278 - } else if( keypressed == 27 ) { // Escape
279 - document.getElementById( r.searchbox ).value = r.original;
280 - r.query = r.original;
281 - os_hideResults( r );
282 - } else if( r.query != document.getElementById( r.searchbox ).value ) {
283 - // os_hideResults( r ); // don't show old suggestions
284 - }
285 -};
286 -
287 -/** When keys is held down use a timer to output regular events */
288 -window.os_eventKeypress = function( e ) {
289 - var targ = os_getTarget( e );
290 - var r = os_map[targ.id];
291 - if( r == null ) {
292 - return; // not our event
293 - }
294 -
295 - var keypressed = os_cur_keypressed;
296 -
297 - os_keypressed_count++;
298 - os_processKey( r, keypressed, targ );
299 -};
300 -
301 -/** Catch the key code (Firefox bug) */
302 -window.os_eventKeydown = function( e ) {
303 - if ( !e ) {
304 - e = window.event;
305 - }
306 - var targ = os_getTarget( e );
307 - var r = os_map[targ.id];
308 - if( r == null ) {
309 - return; // not our event
310 - }
311 -
312 - os_mouse_moved = false;
313 -
314 - os_cur_keypressed = ( e.keyCode == undefined ) ? e.which : e.keyCode;
315 - os_keypressed_count = 0;
316 -};
317 -
318 -
319 -/** When the form is submitted hide everything, cancel updates... */
320 -window.os_eventOnsubmit = function( e ) {
321 - var targ = os_getTarget( e );
322 -
323 - os_is_stopped = true;
324 - // kill timed requests
325 - if( os_timer != null && os_timer.id != null ) {
326 - clearTimeout( os_timer.id );
327 - os_timer = null;
328 - }
329 - // Hide all suggestions
330 - for( i = 0; i < os_autoload_inputs.length; i++ ) {
331 - var r = os_map[os_autoload_inputs[i]];
332 - if( r != null ) {
333 - var b = document.getElementById( r.searchform );
334 - if( b != null && b == targ ) {
335 - // set query value so the handler won't try to fetch additional results
336 - r.query = document.getElementById( r.searchbox ).value;
337 - }
338 - os_hideResults( r );
339 - }
340 - }
341 - return true;
342 -};
343 -
344 -
345 -
346 -/** Hide results from the user, either making the div visibility=hidden or
347 - * detaching the datalist from the input. */
348 -window.os_hideResults = function( r ) {
349 - if ( os_use_datalist ) {
350 - document.getElementById( r.searchbox ).setAttribute( 'list', '' );
351 - } else {
352 - var c = document.getElementById( r.container );
353 - if ( c != null ) {
354 - c.style.visibility = 'hidden';
355 - }
356 - }
357 - r.visible = false;
358 - r.selected = -1;
359 -};
360 -
361 -window.os_decodeValue = function( value ) {
362 - if ( decodeURIComponent ) {
363 - return decodeURIComponent( value );
364 - }
365 - if( unescape ) {
366 - return unescape( value );
367 - }
368 - return null;
369 -};
370 -
371 -window.os_encodeQuery = function( value ) {
372 - if ( encodeURIComponent ) {
373 - return encodeURIComponent( value );
374 - }
375 - if( escape ) {
376 - return escape( value );
377 - }
378 - return null;
379 -};
380 -
381 -/** Handles data from XMLHttpRequest, and updates the suggest results */
382 -window.os_updateResults = function( r, query, text, cacheKey ) {
383 - os_cache[cacheKey] = text;
384 - r.query = query;
385 - r.original = query;
386 - if( text == '' ) {
387 - r.results = null;
388 - r.resultCount = 0;
389 - os_hideResults( r );
390 - } else {
391 - try {
392 - var p = eval( '(' + text + ')' ); // simple json parse, could do a safer one
393 - if( p.length < 2 || p[1].length == 0 ) {
394 - r.results = null;
395 - r.resultCount = 0;
396 - os_hideResults( r );
397 - return;
398 - }
399 - if ( os_use_datalist ) {
400 - os_setupDatalist( r, p[1] );
401 - } else {
402 - os_setupDiv( r, p[1] );
403 - }
404 - } catch( e ) {
405 - // bad response from server or such
406 - os_hideResults( r );
407 - os_cache[cacheKey] = null;
408 - }
409 - }
410 -};
411 -
412 -/**
413 - * Create and populate a <datalist>.
414 - *
415 - * @param r os_Result object
416 - * @param results Array of the new results to replace existing ones
417 - */
418 -window.os_setupDatalist = function( r, results ) {
419 - var s = document.getElementById( r.searchbox );
420 - var c = document.getElementById( r.container );
421 - if ( c == null ) {
422 - c = document.createElement( 'datalist' );
423 - c.setAttribute( 'id', r.container );
424 - document.body.appendChild( c );
425 - } else {
426 - c.innerHTML = '';
427 - }
428 - s.setAttribute( 'list', r.container );
429 -
430 - r.results = new Array();
431 - r.resultCount = results.length;
432 - r.visible = true;
433 - for ( i = 0; i < results.length; i++ ) {
434 - var title = os_decodeValue( results[i] );
435 - var opt = document.createElement( 'option' );
436 - opt.value = title;
437 - r.results[i] = title;
438 - c.appendChild( opt );
439 - }
440 -};
441 -
442 -/** Fetch namespaces from checkboxes or hidden fields in the search form,
443 - if none defined use wgSearchNamespaces global */
444 -window.os_getNamespaces = function( r ) {
445 - var namespaces = '';
446 - var elements = document.forms[r.searchform].elements;
447 - for( i = 0; i < elements.length; i++ ) {
448 - var name = elements[i].name;
449 - if( typeof name != 'undefined' && name.length > 2 && name[0] == 'n' &&
450 - name[1] == 's' && (
451 - ( elements[i].type == 'checkbox' && elements[i].checked ) ||
452 - ( elements[i].type == 'hidden' && elements[i].value == '1' )
453 - )
454 - ) {
455 - if( namespaces != '' ) {
456 - namespaces += '|';
457 - }
458 - namespaces += name.substring( 2 );
459 - }
460 - }
461 - if( namespaces == '' ) {
462 - namespaces = wgSearchNamespaces.join('|');
463 - }
464 - return namespaces;
465 -};
466 -
467 -/** Update results if user hasn't already typed something else */
468 -window.os_updateIfRelevant = function( r, query, text, cacheKey ) {
469 - var t = document.getElementById( r.searchbox );
470 - if( t != null && t.value == query ) { // check if response is still relevant
471 - os_updateResults( r, query, text, cacheKey );
472 - }
473 - r.query = query;
474 -};
475 -
476 -/** Fetch results after some timeout */
477 -window.os_delayedFetch = function() {
478 - if( os_timer == null ) {
479 - return;
480 - }
481 - var r = os_timer.r;
482 - var query = os_timer.query;
483 - os_timer = null;
484 - var path = mw.config.get( 'wgMWSuggestTemplate' ).replace( "{namespaces}", os_getNamespaces( r ) )
485 - .replace( "{dbname}", wgDBname )
486 - .replace( "{searchTerms}", os_encodeQuery( query ) );
487 -
488 - // try to get from cache, if not fetch using ajax
489 - var cached = os_cache[path];
490 - if( cached != null && cached != undefined ) {
491 - os_updateIfRelevant( r, query, cached, path );
492 - } else {
493 - var xmlhttp = sajax_init_object();
494 - if( xmlhttp ) {
495 - try {
496 - xmlhttp.open( 'GET', path, true );
497 - xmlhttp.onreadystatechange = function() {
498 - if ( xmlhttp.readyState == 4 && typeof os_updateIfRelevant == 'function' ) {
499 - os_updateIfRelevant( r, query, xmlhttp.responseText, path );
500 - }
501 - };
502 - xmlhttp.send( null );
503 - } catch ( e ) {
504 - if ( window.location.hostname == 'localhost' ) {
505 - alert( "Your browser blocks XMLHttpRequest to 'localhost', try using a real hostname for development/testing." );
506 - }
507 - throw e;
508 - }
509 - }
510 - }
511 -};
512 -
513 -/** Init timed update via os_delayedUpdate() */
514 -window.os_fetchResults = function( r, query, timeout ) {
515 - if( query == '' ) {
516 - r.query = '';
517 - os_hideResults( r );
518 - return;
519 - } else if( query == r.query ) {
520 - return; // no change
521 - }
522 -
523 - os_is_stopped = false; // make sure we're running
524 -
525 - // cancel any pending fetches
526 - if( os_timer != null && os_timer.id != null ) {
527 - clearTimeout( os_timer.id );
528 - }
529 - // schedule delayed fetching of results
530 - if( timeout != 0 ) {
531 - os_timer = new os_Timer( setTimeout( "os_delayedFetch()", timeout ), r, query );
532 - } else {
533 - os_timer = new os_Timer( null, r, query );
534 - os_delayedFetch(); // do it now!
535 - }
536 -};
537 -
538 -/** Find event target */
539 -window.os_getTarget = function( e ) {
540 - if ( !e ) {
541 - e = window.event;
542 - }
543 - if ( e.target ) {
544 - return e.target;
545 - } else if ( e.srcElement ) {
546 - return e.srcElement;
547 - } else {
548 - return null;
549 - }
550 -};
551 -
552 -/** Check if x is a valid integer */
553 -window.os_isNumber = function( x ) {
554 - if( x == '' || isNaN( x ) ) {
555 - return false;
556 - }
557 - for( var i = 0; i < x.length; i++ ) {
558 - var c = x.charAt( i );
559 - if( !( c >= '0' && c <= '9' ) ) {
560 - return false;
561 - }
562 - }
563 - return true;
564 -};
565 -
566 -/** Call this to enable suggestions on input (id=inputId), on a form (name=formName) */
567 -window.os_enableSuggestionsOn = function( inputId, formName ) {
568 - os_initHandlers( inputId, formName, document.getElementById( inputId ) );
569 -};
570 -
571 -/** Call this to disable suggestios on input box (id=inputId) */
572 -window.os_disableSuggestionsOn = function( inputId ) {
573 - r = os_map[inputId];
574 - if( r != null ) {
575 - // cancel/hide results
576 - os_timer = null;
577 - os_hideResults( r );
578 - // turn autocomplete on !
579 - document.getElementById( inputId ).setAttribute( 'autocomplete', 'on' );
580 - // remove descriptor
581 - os_map[inputId] = null;
582 - }
583 -
584 - // Remove the element from the os_autoload_* arrays
585 - var index = os_autoload_inputs.indexOf( inputId );
586 - if ( index >= 0 ) {
587 - os_autoload_inputs[index] = os_autoload_forms[index] = '';
588 - }
589 -};
590 -
591 -/************************************************
592 - * Div-only functions (irrelevant for datalist)
593 - ************************************************/
594 -
595 -/** Event: loss of focus of input box */
596 -window.os_eventBlur = function( e ) {
597 - var targ = os_getTarget( e );
598 - var r = os_map[targ.id];
599 - if( r == null ) {
600 - return; // not our event
601 - }
602 - if( !os_mouse_pressed ) {
603 - os_hideResults( r );
604 - // force canvas to stay hidden
605 - r.stayHidden = true;
606 - // cancel any pending fetches
607 - if( os_timer != null && os_timer.id != null ) {
608 - clearTimeout( os_timer.id );
609 - }
610 - os_timer = null;
611 - }
612 -};
613 -
614 -/** Event: focus (catch only when stopped) */
615 -window.os_eventFocus = function( e ) {
616 - var targ = os_getTarget( e );
617 - var r = os_map[targ.id];
618 - if( r == null ) {
619 - return; // not our event
620 - }
621 - r.stayHidden = false;
622 -};
623 -
624 -/**
625 - * Create and populate a <div>, for non-<datalist>-supporting browsers.
626 - *
627 - * @param r os_Result object
628 - * @param results Array of the new results to replace existing ones
629 - */
630 -window.os_setupDiv = function( r, results ) {
631 - var c = document.getElementById( r.container );
632 - if ( c == null ) {
633 - c = os_createContainer( r );
634 - }
635 - c.innerHTML = os_createResultTable( r, results );
636 - // init container table sizes
637 - var t = document.getElementById( r.resultTable );
638 - r.containerTotal = t.offsetHeight;
639 - r.containerRow = t.offsetHeight / r.resultCount;
640 - os_fitContainer( r );
641 - os_trimResultText( r );
642 - os_showResults( r );
643 -};
644 -
645 -/** Create the result table to be placed in the container div */
646 -window.os_createResultTable = function( r, results ) {
647 - var c = document.getElementById( r.container );
648 - var width = c.offsetWidth - os_operaWidthFix( c.offsetWidth );
649 - var html = '<table class="os-suggest-results" id="' + r.resultTable + '" style="width: ' + width + 'px;">';
650 - r.results = new Array();
651 - r.resultCount = results.length;
652 - for( i = 0; i < results.length; i++ ) {
653 - var title = os_decodeValue( results[i] );
654 - r.results[i] = title;
655 - html += '<tr><td class="os-suggest-result" id="' + r.resultTable + i + '"><span id="' + r.resultText + i + '">' + title + '</span></td></tr>';
656 - }
657 - html += '</table>';
658 - return html;
659 -};
660 -
661 -/** Show results div */
662 -window.os_showResults = function( r ) {
663 - if( os_is_stopped ) {
664 - return;
665 - }
666 - if( r.stayHidden ) {
667 - return;
668 - }
669 - os_fitContainer( r );
670 - var c = document.getElementById( r.container );
671 - r.selected = -1;
672 - if( c != null ) {
673 - c.scrollTop = 0;
674 - c.style.visibility = 'visible';
675 - r.visible = true;
676 - }
677 -};
678 -
679 -window.os_operaWidthFix = function( x ) {
680 - // For browsers that don't understand overflow-x, estimate scrollbar width
681 - if( typeof document.body.style.overflowX != 'string' ) {
682 - return 30;
683 - }
684 - return 0;
685 -};
686 -
687 -/** Brower-dependent functions to find window inner size, and scroll status */
688 -window.f_clientWidth = function() {
689 - return f_filterResults(
690 - window.innerWidth ? window.innerWidth : 0,
691 - document.documentElement ? document.documentElement.clientWidth : 0,
692 - document.body ? document.body.clientWidth : 0
693 - );
694 -};
695 -
696 -window.f_clientHeight = function() {
697 - return f_filterResults(
698 - window.innerHeight ? window.innerHeight : 0,
699 - document.documentElement ? document.documentElement.clientHeight : 0,
700 - document.body ? document.body.clientHeight : 0
701 - );
702 -};
703 -
704 -window.f_scrollLeft = function() {
705 - return f_filterResults(
706 - window.pageXOffset ? window.pageXOffset : 0,
707 - document.documentElement ? document.documentElement.scrollLeft : 0,
708 - document.body ? document.body.scrollLeft : 0
709 - );
710 -};
711 -
712 -window.f_scrollTop = function() {
713 - return f_filterResults(
714 - window.pageYOffset ? window.pageYOffset : 0,
715 - document.documentElement ? document.documentElement.scrollTop : 0,
716 - document.body ? document.body.scrollTop : 0
717 - );
718 -};
719 -
720 -window.f_filterResults = function( n_win, n_docel, n_body ) {
721 - var n_result = n_win ? n_win : 0;
722 - if ( n_docel && ( !n_result || ( n_result > n_docel ) ) ) {
723 - n_result = n_docel;
724 - }
725 - return n_body && ( !n_result || ( n_result > n_body ) ) ? n_body : n_result;
726 -};
727 -
728 -/** Get the height available for the results container */
729 -window.os_availableHeight = function( r ) {
730 - var absTop = document.getElementById( r.container ).style.top;
731 - var px = absTop.lastIndexOf( 'px' );
732 - if( px > 0 ) {
733 - absTop = absTop.substring( 0, px );
734 - }
735 - return f_clientHeight() - ( absTop - f_scrollTop() );
736 -};
737 -
738 -/** Get element absolute position {left,top} */
739 -window.os_getElementPosition = function( elemID ) {
740 - var offsetTrail = document.getElementById( elemID );
741 - var offsetLeft = 0;
742 - var offsetTop = 0;
743 - while ( offsetTrail ) {
744 - offsetLeft += offsetTrail.offsetLeft;
745 - offsetTop += offsetTrail.offsetTop;
746 - offsetTrail = offsetTrail.offsetParent;
747 - }
748 - if ( navigator.userAgent.indexOf('Mac') != -1 && typeof document.body.leftMargin != 'undefined' ) {
749 - offsetLeft += document.body.leftMargin;
750 - offsetTop += document.body.topMargin;
751 - }
752 - return { left:offsetLeft, top:offsetTop };
753 -};
754 -
755 -/** Create the container div that will hold the suggested titles */
756 -window.os_createContainer = function( r ) {
757 - var c = document.createElement( 'div' );
758 - var s = document.getElementById( r.searchbox );
759 - var pos = os_getElementPosition( r.searchbox );
760 - var left = pos.left;
761 - var top = pos.top + s.offsetHeight;
762 - c.className = 'os-suggest';
763 - c.setAttribute( 'id', r.container );
764 - document.body.appendChild( c );
765 -
766 - // dynamically generated style params
767 - // IE workaround, cannot explicitely set "style" attribute
768 - c = document.getElementById( r.container );
769 - c.style.top = top + 'px';
770 - c.style.left = left + 'px';
771 - c.style.width = s.offsetWidth + 'px';
772 -
773 - // mouse event handlers
774 - c.onmouseover = function( event ) { os_eventMouseover( r.searchbox, event ); };
775 - c.onmousemove = function( event ) { os_eventMousemove( r.searchbox, event ); };
776 - c.onmousedown = function( event ) { return os_eventMousedown( r.searchbox, event ); };
777 - c.onmouseup = function( event ) { os_eventMouseup( r.searchbox, event ); };
778 - return c;
779 -};
780 -
781 -/** change container height to fit to screen */
782 -window.os_fitContainer = function( r ) {
783 - var c = document.getElementById( r.container );
784 - var h = os_availableHeight( r ) - 20;
785 - var inc = r.containerRow;
786 - h = parseInt( h / inc ) * inc;
787 - if( h < ( 2 * inc ) && r.resultCount > 1 ) { // min: two results
788 - h = 2 * inc;
789 - }
790 - if( ( h / inc ) > os_max_lines_per_suggest ) {
791 - h = inc * os_max_lines_per_suggest;
792 - }
793 - if( h < r.containerTotal ) {
794 - c.style.height = h + 'px';
795 - r.containerCount = parseInt( Math.round( h / inc ) );
796 - } else {
797 - c.style.height = r.containerTotal + 'px';
798 - r.containerCount = r.resultCount;
799 - }
800 -};
801 -
802 -/** If some entries are longer than the box, replace text with "..." */
803 -window.os_trimResultText = function( r ) {
804 - // find max width, first see if we could expand the container to fit it
805 - var maxW = 0;
806 - for( var i = 0; i < r.resultCount; i++ ) {
807 - var e = document.getElementById( r.resultText + i );
808 - if( e.offsetWidth > maxW ) {
809 - maxW = e.offsetWidth;
810 - }
811 - }
812 - var w = document.getElementById( r.container ).offsetWidth;
813 - var fix = 0;
814 - if( r.containerCount < r.resultCount ) {
815 - fix = 20; // give 20px for scrollbar
816 - } else {
817 - fix = os_operaWidthFix( w );
818 - }
819 - if( fix < 4 ) {
820 - fix = 4; // basic padding
821 - }
822 - maxW += fix;
823 -
824 - // resize container to fit more data if permitted
825 - var normW = document.getElementById( r.searchbox ).offsetWidth;
826 - var prop = maxW / normW;
827 - if( prop > os_container_max_width ) {
828 - prop = os_container_max_width;
829 - } else if( prop < 1 ) {
830 - prop = 1;
831 - }
832 - var newW = Math.round( normW * prop );
833 - if( w != newW ) {
834 - w = newW;
835 - if( os_animation_timer != null ) {
836 - clearInterval( os_animation_timer.id );
837 - }
838 - os_animation_timer = new os_AnimationTimer( r, w );
839 - os_animation_timer.id = setInterval( "os_animateChangeWidth()", os_animation_delay );
840 - w -= fix; // this much is reserved
841 - }
842 -
843 - // trim results
844 - if( w < 10 ) {
845 - return;
846 - }
847 - for( var i = 0; i < r.resultCount; i++ ) {
848 - var e = document.getElementById( r.resultText + i );
849 - var replace = 1;
850 - var lastW = e.offsetWidth + 1;
851 - var iteration = 0;
852 - var changedText = false;
853 - while( e.offsetWidth > w && ( e.offsetWidth < lastW || iteration < 2 ) ) {
854 - changedText = true;
855 - lastW = e.offsetWidth;
856 - var l = e.innerHTML;
857 - e.innerHTML = l.substring( 0, l.length - replace ) + '...';
858 - iteration++;
859 - replace = 4; // how many chars to replace
860 - }
861 - if( changedText ) {
862 - // show hint for trimmed titles
863 - document.getElementById( r.resultTable + i ).setAttribute( 'title', r.results[i] );
864 - }
865 - }
866 -};
867 -
868 -/** Invoked on timer to animate change in container width */
869 -window.os_animateChangeWidth = function() {
870 - var r = os_animation_timer.r;
871 - var c = document.getElementById( r.container );
872 - var w = c.offsetWidth;
873 - var normW = document.getElementById( r.searchbox ).offsetWidth;
874 - var normL = os_getElementPosition( r.searchbox ).left;
875 - var inc = os_animation_timer.inc;
876 - var target = os_animation_timer.target;
877 - var nw = w + inc;
878 - if( ( inc > 0 && nw >= target ) || ( inc <= 0 && nw <= target ) ) {
879 - // finished !
880 - c.style.width = target + 'px';
881 - clearInterval( os_animation_timer.id );
882 - os_animation_timer = null;
883 - } else {
884 - // in-progress
885 - c.style.width = nw + 'px';
886 - if( document.documentElement.dir == 'rtl' ) {
887 - c.style.left = ( normL + normW + ( target - nw ) - os_animation_timer.target - 1 ) + 'px';
888 - }
889 - }
890 -};
891 -
892 -/** Change the highlighted row (i.e. suggestion), from position cur to next */
893 -window.os_changeHighlight = function( r, cur, next, updateSearchBox ) {
894 - if ( next >= r.resultCount ) {
895 - next = r.resultCount - 1;
896 - }
897 - if ( next < -1 ) {
898 - next = -1;
899 - }
900 - r.selected = next;
901 - if ( cur == next ) {
902 - return; // nothing to do.
903 - }
904 -
905 - if( cur >= 0 ) {
906 - var curRow = document.getElementById( r.resultTable + cur );
907 - if( curRow != null ) {
908 - curRow.className = 'os-suggest-result';
909 - }
910 - }
911 - var newText;
912 - if( next >= 0 ) {
913 - var nextRow = document.getElementById( r.resultTable + next );
914 - if( nextRow != null ) {
915 - nextRow.className = os_HighlightClass();
916 - }
917 - newText = r.results[next];
918 - } else {
919 - newText = r.original;
920 - }
921 -
922 - // adjust the scrollbar if any
923 - if( r.containerCount < r.resultCount ) {
924 - var c = document.getElementById( r.container );
925 - var vStart = c.scrollTop / r.containerRow;
926 - var vEnd = vStart + r.containerCount;
927 - if( next < vStart ) {
928 - c.scrollTop = next * r.containerRow;
929 - } else if( next >= vEnd ) {
930 - c.scrollTop = ( next - r.containerCount + 1 ) * r.containerRow;
931 - }
932 - }
933 -
934 - // update the contents of the search box
935 - if( updateSearchBox ) {
936 - os_updateSearchQuery( r, newText );
937 - }
938 -};
939 -
940 -window.os_HighlightClass = function() {
941 - var match = navigator.userAgent.match(/AppleWebKit\/(\d+)/);
942 - if ( match ) {
943 - var webKitVersion = parseInt( match[1] );
944 - if ( webKitVersion < 523 ) {
945 - // CSS system highlight colors broken on old Safari
946 - // https://bugs.webkit.org/show_bug.cgi?id=6129
947 - // Safari 3.0.4, 3.1 known ok
948 - return 'os-suggest-result-hl-webkit';
949 - }
950 - }
951 - return 'os-suggest-result-hl';
952 -};
953 -
954 -window.os_updateSearchQuery = function( r, newText ) {
955 - document.getElementById( r.searchbox ).value = newText;
956 - r.query = newText;
957 -};
958 -
959 -
960 -/********************
961 - * Mouse events
962 - ********************/
963 -
964 -/** Mouse over the container */
965 -window.os_eventMouseover = function( srcId, e ) {
966 - var targ = os_getTarget( e );
967 - var r = os_map[srcId];
968 - if( r == null || !os_mouse_moved ) {
969 - return; // not our event
970 - }
971 - var num = os_getNumberSuffix( targ.id );
972 - if( num >= 0 ) {
973 - os_changeHighlight( r, r.selected, num, false );
974 - }
975 -};
976 -
977 -/* Get row where the event occured (from its id) */
978 -window.os_getNumberSuffix = function( id ) {
979 - var num = id.substring( id.length - 2 );
980 - if( !( num.charAt( 0 ) >= '0' && num.charAt( 0 ) <= '9' ) ) {
981 - num = num.substring( 1 );
982 - }
983 - if( os_isNumber( num ) ) {
984 - return parseInt( num );
985 - } else {
986 - return -1;
987 - }
988 -};
989 -
990 -/** Save mouse move as last action */
991 -window.os_eventMousemove = function( srcId, e ) {
992 - os_mouse_moved = true;
993 -};
994 -
995 -/** Mouse button held down, register possible click */
996 -window.os_eventMousedown = function( srcId, e ) {
997 - var targ = os_getTarget( e );
998 - var r = os_map[srcId];
999 - if( r == null ) {
1000 - return; // not our event
1001 - }
1002 - var num = os_getNumberSuffix( targ.id );
1003 -
1004 - os_mouse_pressed = true;
1005 - if( num >= 0 ) {
1006 - os_mouse_num = num;
1007 - // os_updateSearchQuery( r, r.results[num] );
1008 - }
1009 - // keep the focus on the search field
1010 - document.getElementById( r.searchbox ).focus();
1011 -
1012 - return false; // prevents selection
1013 -};
1014 -
1015 -/** Mouse button released, check for click on some row */
1016 -window.os_eventMouseup = function( srcId, e ) {
1017 - var targ = os_getTarget( e );
1018 - var r = os_map[srcId];
1019 - if( r == null ) {
1020 - return; // not our event
1021 - }
1022 - var num = os_getNumberSuffix( targ.id );
1023 -
1024 - if( num >= 0 && os_mouse_num == num ) {
1025 - os_updateSearchQuery( r, r.results[num] );
1026 - os_hideResults( r );
1027 - document.getElementById( r.searchform ).submit();
1028 - }
1029 - os_mouse_pressed = false;
1030 - // keep the focus on the search field
1031 - document.getElementById( r.searchbox ).focus();
1032 -};
1033 -
1034 -/** Toggle stuff seems to be dead code? */
1035 -
1036 -/** Return the span element that contains the toggle link */
1037 -window.os_createToggle = function( r, className ) {
1038 - var t = document.createElement( 'span' );
1039 - t.className = className;
1040 - t.setAttribute( 'id', r.toggle );
1041 - var link = document.createElement( 'a' );
1042 - link.setAttribute( 'href', 'javascript:void(0);' );
1043 - link.onclick = function() { os_toggle( r.searchbox, r.searchform ); };
1044 - var msg = document.createTextNode( wgMWSuggestMessages[0] );
1045 - link.appendChild( msg );
1046 - t.appendChild( link );
1047 - return t;
1048 -};
1049 -
1050 -/** Call when user clicks on some of the toggle links */
1051 -window.os_toggle = function( inputId, formName ) {
1052 - r = os_map[inputId];
1053 - var msg = '';
1054 - if( r == null ) {
1055 - os_enableSuggestionsOn( inputId, formName );
1056 - r = os_map[inputId];
1057 - msg = wgMWSuggestMessages[0];
1058 - } else{
1059 - os_disableSuggestionsOn( inputId, formName );
1060 - msg = wgMWSuggestMessages[1];
1061 - }
1062 - // change message
1063 - var link = document.getElementById( r.toggle ).firstChild;
1064 - link.replaceChild( document.createTextNode( msg ), link.firstChild );
1065 -};
1066 -
1067 -hookEvent( 'load', os_MWSuggestInit );
Index: trunk/phase3/skins/common/shared.css
@@ -193,62 +193,26 @@
194194 /*
195195 * OpenSearch ajax suggestions
196196 */
197 -.os-suggest {
 197+.open-search-suggestions .ui-autocomplete {
 198+ font-size: 95%;
 199+ border: 1px solid #AAA!important;
198200 overflow: auto;
199 - overflow-x: hidden;
200 - position: absolute;
201 - top: 0px;
202 - left: 0px;
203 - width: 0px;
204 - background-color: white;
205 - background-color: Window;
206 - border-style: solid;
207 - border-color: #AAAAAA;
208 - border-width: 1px;
209 - z-index:99;
210 - font-size:95%;
 201+ height: 100px;
 202+ background: #FFF;
 203+ background: Window;
211204 }
212 -
213 -table.os-suggest-results {
214 - font-size: 95%;
215 - cursor: pointer;
216 - border: 0;
217 - border-collapse: collapse;
218 - width: 100%;
219 -}
220 -
221 -.os-suggest-result, .os-suggest-result-hl {
222 - white-space: nowrap;
223 - background-color: white;
224 - background-color: Window;
225 - color: black;
226 - color: WindowText;
227 - padding: 2px;
228 -}
229 -.os-suggest-result-hl,
230 -.os-suggest-result-hl-webkit {
231 - background-color: #4C59A6;
 205+.open-search-suggestions .ui-autocomplete #ui-active-menuitem {
 206+ background: #4C59A6;
 207+ background: Highlight;
232208 color: white;
233 -}
234 -.os-suggest-result-hl {
235 - /* System colors are misimplemented in Safari 3.0 and earlier,
236 - making highlighted text illegible... */
237 - background-color: Highlight;
238209 color: HighlightText;
 210+ border-color: #4C59A6;
 211+ border-color: Highlight;
239212 }
240 -
241 -.os-suggest-toggle {
242 - position: relative;
243 - left: 1ex;
244 - font-size: 65%;
 213+.open-search-suggestions .ui-autocomplete .ui-menu-item a{
 214+ line-height: 1.1!important;
 215+ font-size: 95%;
245216 }
246 -.os-suggest-toggle-def {
247 - position: absolute;
248 - top: 0px;
249 - left: 0px;
250 - font-size: 65%;
251 - visibility: hidden;
252 -}
253217
254218 /* Page history styling */
255219 /* the auto-generated edit comments */
Index: trunk/phase3/includes/OutputPage.php
@@ -2365,7 +2365,7 @@
23662366 }
23672367
23682368 if ( $wgEnableMWSuggest && !$this->getUser()->getOption( 'disablesuggest', false ) ) {
2369 - $this->addModules( 'mediawiki.legacy.mwsuggest' );
 2369+ $this->addModules( 'mediawiki.page.mwsuggest' );
23702370 }
23712371 }
23722372

Follow-up revisions

RevisionCommit summaryAuthorDate
r93382r91728 : Fix whitespace and two vars per CRdiebuche11:02, 28 July 2011
r93383r91728 : Fix a problem for api.php5 users and remove an unneeded function par...diebuche11:22, 28 July 2011
r95409Revert r91728...reedy18:22, 24 August 2011

Comments

#Comment by Schnark (talk | contribs)   07:30, 15 July 2011

Instead

url = mw.config.get('wgScriptPath') + '/api.php?format=json&action=opensearch&search='

you should use

url = mw.util.wikiScript( 'api' ) + '?format=json&action=opensearch&search='

to make it work in environments witch use .php5 as extension.

#Comment by Catrope (talk | contribs)   17:21, 15 July 2011

Additionally, you can use $.getJSON( url, vars, function() { ... } ); where url = mw.util.wikiScript( 'api' ), vars = { format: 'json', action: 'opensearch', search: foo, namespaces: bar } so you don't have to build the query string and escape things yourself.

#Comment by Krinkle (talk | contribs)   06:52, 28 July 2011

getNamespaces and deliverResult are leaked to the global namespace (window.deliverResult etc.), please declare them local.

Also trim trailing whitespace on lines and other details to comply with the Code conventions (such spaces in function callee)

#Comment by DieBuche (talk | contribs)   11:23, 28 July 2011

I adressed the whitespace in r93382 and the url in r93383

#Comment by Nikerabbit (talk | contribs)   11:56, 28 July 2011

Oops, extensions/Translate/js/import.js relies on os_initHandlers. Can you fix/help me fix it to get suggestions back working?

#Comment by DieBuche (talk | contribs)   12:34, 28 July 2011

Sure, I'll restructure it into an jQuery plugin, so that you can call it with $('#mw-translate-up-wiki-input').mwSuggest( someOptions );

#Comment by Siebrand (talk | contribs)   14:21, 3 August 2011

When? :)

#Comment by Krinkle (talk | contribs)   14:41, 4 August 2011

I'm not sure exactly, but from what I understood mwsuggest is a legacy script and new scripts should use jquery.ui.autocomplete or jquery.suggestions. Why is this script being further developed on ? I would recommend leaving it as is and migrate usages to one of the jquery plugins and eventually deprecate/remove mwsuggest.

Status & tagging log