Index: branches/js2-work/phase3/js/mwEmbed/skins/common/common.css |
— | — | @@ -95,8 +95,9 @@ |
96 | 96 | z-index:3; |
97 | 97 | } |
98 | 98 | #rsd_filters_container { |
99 | | - float:left; |
100 | | - width:150px; |
| 99 | + float: left; |
| 100 | + width: 150px; |
| 101 | + overflow: auto; |
101 | 102 | } |
102 | 103 | |
103 | 104 | .ui-filter-title { |
— | — | @@ -194,6 +195,10 @@ |
195 | 196 | .rsd_result_enumeration { |
196 | 197 | margin: 0 1em; |
197 | 198 | } |
| 199 | +.rsd_results_body { |
| 200 | + height: 100%; |
| 201 | + width: 100%; |
| 202 | +} |
198 | 203 | #rsd_results_header { |
199 | 204 | margin: 4px; |
200 | 205 | background: #DEF; |
Index: branches/js2-work/phase3/js/mwEmbed/modules/AddMedia/mw.RemoteSearchDriver.js |
— | — | @@ -1230,16 +1230,48 @@ |
1231 | 1231 | } |
1232 | 1232 | }, |
1233 | 1233 | |
| 1234 | + /** |
| 1235 | + * Callback for performing a search, given to providers for provider-activated |
| 1236 | + * searches e.g. filter state changes. This is probably also the future way to |
| 1237 | + * implement "pushing" results. |
| 1238 | + * |
| 1239 | + * The returned callback accepts two arguements. |
| 1240 | + * |
| 1241 | + * The first, mandatory, is the |
| 1242 | + * provider object. This should be curried with the current provider object |
| 1243 | + * before handing over. (i.e. this.curry(this.getProviderCallback(), provider). |
| 1244 | + * |
| 1245 | + * The second, optional, is the current results list to be replaced by a spinner. |
| 1246 | + */ |
1234 | 1247 | getProviderCallback: function() { |
1235 | 1248 | |
1236 | 1249 | var _this = this; |
1237 | | - return function ( provider ) { |
| 1250 | + |
| 1251 | + return function ( provider, $location ) { |
1238 | 1252 | |
1239 | 1253 | var d = new Date(); |
1240 | 1254 | var searchTime = d.getMilliseconds(); |
1241 | 1255 | |
| 1256 | + // If we are given a result location, we hide them. |
| 1257 | + if ($location) { |
| 1258 | + $location.html( mw.loading_spinner("float: left") ); |
| 1259 | + } |
| 1260 | + |
| 1261 | + var d = new Date(); |
| 1262 | + var context = _this.storeContext( d.getTime() ); |
| 1263 | + _this.currentRequest = context(); |
| 1264 | + mw.log( "ProviderCallBack Generated " + context() ) |
1242 | 1265 | provider.sObj.getSearchResults( $j( '#rsd_q' ).val() , |
1243 | 1266 | function( resultStatus ) { |
| 1267 | + |
| 1268 | + mw.log( "ProviderCallBack Received " + context() ); |
| 1269 | + if( _this.currentRequest != context() ) { |
| 1270 | + // do not update the results this.currentRequest |
| 1271 | + // does not match the interface request state. |
| 1272 | + return false; |
| 1273 | + } |
| 1274 | + |
| 1275 | + //else update search results |
1244 | 1276 | _this.showResults(); |
1245 | 1277 | }); |
1246 | 1278 | |
— | — | @@ -1250,6 +1282,22 @@ |
1251 | 1283 | }, |
1252 | 1284 | |
1253 | 1285 | /** |
| 1286 | + * Persists an object via closure to enable later context checking. |
| 1287 | + * This can be used e.g. when sending multiple getJSON requests and |
| 1288 | + * wanting to act only on the last request sent. |
| 1289 | + * |
| 1290 | + * @param {Object} Object to store in context. |
| 1291 | + * |
| 1292 | + * @return {function} A callback to retrieve the context. |
| 1293 | + */ |
| 1294 | + storeContext: function( contextObject ) { |
| 1295 | + var context = contextObject; |
| 1296 | + return function() { |
| 1297 | + return context; |
| 1298 | + } |
| 1299 | + }, |
| 1300 | + |
| 1301 | + /** |
1254 | 1302 | * Loads a providers search library |
1255 | 1303 | * |
1256 | 1304 | * @param {Object} provider content provider to be loaded |
— | — | @@ -1327,8 +1375,22 @@ |
1328 | 1376 | var _this = this; |
1329 | 1377 | var o = ''; |
1330 | 1378 | var provider = this.content_providers[ this.current_provider ]; |
1331 | | - |
1332 | 1379 | |
| 1380 | + // Result page structure: |
| 1381 | + // |
| 1382 | + // resultContainer |
| 1383 | + // header |
| 1384 | + // resultBody |
| 1385 | + // filter form |
| 1386 | + // filters... |
| 1387 | + // resultList |
| 1388 | + // results... |
| 1389 | + // footer |
| 1390 | + |
| 1391 | + var $resultsContainer; |
| 1392 | + var $resultsBody = $j( '<div />' ).addClass( 'rsd_results_body' ); |
| 1393 | + var $resultsList = $j( '<div />' ).addClass( 'rsd_results_list' ); |
| 1394 | + |
1333 | 1395 | // The "upload" tab has special results output target rather than top level |
1334 | 1396 | // resutls container. |
1335 | 1397 | if ( this.current_provider == 'upload' ) { |
— | — | @@ -1344,16 +1406,13 @@ |
1345 | 1407 | // Enable search filters, if the provider supports them. |
1346 | 1408 | if ( provider.sObj.filters && !(provider.disable_filters) ) { |
1347 | 1409 | provider.sObj.filters.filterChangeCallBack = |
1348 | | - this.curry( this.getProviderCallback(), provider ); |
1349 | | - $resultsContainer.append( provider.sObj.filters.getHTML().attr ({ |
| 1410 | + this.curry( this.getProviderCallback(), provider, $resultsList ); |
| 1411 | + $resultsBody.append( provider.sObj.filters.getHTML().attr ({ |
1350 | 1412 | id: 'rsd_filters_container' |
1351 | 1413 | })); |
1352 | 1414 | } |
1353 | 1415 | } |
1354 | 1416 | |
1355 | | - // Empty the existing results: |
1356 | | - // $j( tabSelector ).empty(); |
1357 | | - |
1358 | 1417 | var numResults = 0; |
1359 | 1418 | |
1360 | 1419 | // Output all the results for the current current_provider |
— | — | @@ -1363,8 +1422,12 @@ |
1364 | 1423 | numResults++; |
1365 | 1424 | } ); |
1366 | 1425 | // Put in the tab output (plus clear the output) |
1367 | | - $resultsContainer.append( o + '<div style="clear:both"/>' ); |
| 1426 | + $resultsList.append( o + '<div style="clear: both" />' ); |
1368 | 1427 | } |
| 1428 | + |
| 1429 | + $resultsBody.append( $resultsList ); |
| 1430 | + $resultsContainer.append( $resultsBody ); |
| 1431 | + |
1369 | 1432 | // @@TODO should abstract footer and header ~outside~ of search results |
1370 | 1433 | // to have less leakgege with upload tab |
1371 | 1434 | if ( this.current_provider != 'upload' ) { |