jenkins-bot has submitted this change and it was merged.
Change subject: Fix various annoyances in new search overlay
......................................................................
Fix various annoyances in new search overlay
* Show virtual keyboard when overlay opens on Android devices
* Hide virtual keyboard when scrolling starts
* Don't trigger search when closing virtual keyboard
* Cache previous search results so that when user hits backspace, we
don't send a new query
* Remove cursor: pointer for .page-list which caused the whole list to
be highlighted on tap in search, watchlist and other .page-lists (at
least on Android)
Bug: 58246
Change-Id: I1b8b5ce86431c76ba204b7c7ea4a127c6b77e13e
---
M javascripts/common/Overlay.js
M javascripts/modules/searchNew/SearchApi.js
M javascripts/modules/searchNew/SearchOverlay.js
M javascripts/modules/searchNew/search.js
M less/common/pagelist.less
5 files changed, 102 insertions(+), 69 deletions(-)
Approvals:
Jdlrobson: Looks good to me, approved
jenkins-bot: Verified
diff --git a/javascripts/common/Overlay.js b/javascripts/common/Overlay.js
index 21aaa72..63672ed 100644
--- a/javascripts/common/Overlay.js
+++ b/javascripts/common/Overlay.js
@@ -38,20 +38,20 @@
ev.stopPropagation();
} );
},
- show: function() {
+
+ _hideOnRoute: function() {
var self = this;
+ M.router.one( 'route', function( ev ) {
+ if ( !self.hide() ) {
+ ev.preventDefault();
+ self._hideOnRoute();
+ }
+ } );
+ },
- function hideOnRoute() {
- M.router.one( 'route', function( ev ) {
- if ( !self.hide() ) {
- ev.preventDefault();
- hideOnRoute();
- }
- } );
- }
-
+ show: function() {
if ( this.closeOnBack ) {
- hideOnRoute();
+ this._hideOnRoute();
}
// FIXME: prevent zooming within overlays but don't
break the rendering!
diff --git a/javascripts/modules/searchNew/SearchApi.js
b/javascripts/modules/searchNew/SearchApi.js
index a31dca9..b72663e 100644
--- a/javascripts/modules/searchNew/SearchApi.js
+++ b/javascripts/modules/searchNew/SearchApi.js
@@ -28,24 +28,37 @@
}
SearchApi = Api.extend( {
+ initialize: function() {
+ this._super();
+ this.searchCache = {};
+ },
+
search: function( query ) {
- return this.get( {
- search: query,
- action: 'opensearch',
- namespace: 0,
- limit: 15
- } ).then( function( data ) {
- return {
- query: data[0],
- results: $.map( data[1], function(
title ) {
- return {
- heading:
highlightSearchTerm( title, query ),
- title: title,
- url: mw.util.getUrl(
title )
- };
- } )
- };
- } );
+ if ( !this.searchCache[query] ) {
+ this.searchCache[query] = this.get( {
+ search: query,
+ action: 'opensearch',
+ namespace: 0,
+ limit: 15
+ } ).then( function( data ) {
+ return {
+ query: data[0],
+ results: $.map( data[1],
function( title ) {
+ return {
+ heading:
highlightSearchTerm( title, query ),
+ title: title,
+ url:
mw.util.getUrl( title )
+ };
+ } )
+ };
+ } );
+ }
+
+ return this.searchCache[query];
+ },
+
+ isCached: function( query ) {
+ return !!this.searchCache[query];
}
} );
diff --git a/javascripts/modules/searchNew/SearchOverlay.js
b/javascripts/modules/searchNew/SearchOverlay.js
index be4f3d8..e0081fd 100644
--- a/javascripts/modules/searchNew/SearchOverlay.js
+++ b/javascripts/modules/searchNew/SearchOverlay.js
@@ -3,7 +3,6 @@
var
OverlayNew = M.require( 'OverlayNew' ),
SearchApi = M.require( 'modules/searchNew/SearchApi' ),
- KEY_ENTER = 13,
SEARCH_DELAY = 500,
SearchOverlay;
@@ -18,11 +17,19 @@
searchContentNoResultsMsg: mw.msg(
'mobile-frontend-search-content-no-results' ),
action: mw.config.get( 'wgScript' )
},
- closeOnBack: true,
+ closeOnBack: false,
initialize: function( options ) {
+ var self = this;
this._super( options );
this.api = new SearchApi();
+
+ // FIXME: horrible, remove when we get overlay manager
+ // we need this because of the focus/delay hack in
search.js
+ M.router.one( 'route', function() {
+ self.closeOnBack = true;
+ self._hideOnRoute();
+ } );
},
postRender: function( options ) {
@@ -33,13 +40,8 @@
this._super( options );
- this.$input = this.$( 'input' ).on( 'input', function(
ev ) {
- if ( ev.which === KEY_ENTER ) {
- $form.submit();
- } else {
- self.performSearch();
- }
-
+ this.$input = this.$( 'input' ).on( 'input', function()
{
+ self.performSearch();
$clear.toggle( self.$input.val() !== '' );
} );
@@ -54,6 +56,7 @@
// can't use $.proxy because it would pass ev
to submit() which would
// be treated as alternative form data
on( M.tapEvent( 'click' ), function() {
+ window.history.back();
$form.submit();
} );
@@ -63,6 +66,12 @@
} );
this.$( '> div' ).on( M.tapEvent( 'click' ), function(
ev ) {
ev.stopPropagation();
+ } );
+
+ // hide the keyboard when scrolling starts (avoid weird
situation when
+ // user taps on an item, the keyboard hides and wrong
item is clicked)
+ this.$( '.results' ).on( 'touchstart mousedown',
function() {
+ self.$input.blur();
} );
},
@@ -77,34 +86,40 @@
query = this.$input.val(),
$results = this.$( '.results' );
- this.api.abort();
- clearTimeout( this.timer );
- self.$searchContent.hide();
- $results.empty();
+ // it seems the input event can be fired when virtual
keyboard is closed
+ // (Chrome for Android)
+ if ( query !== this.lastQuery ) {
+ this.api.abort();
+ clearTimeout( this.timer );
+ self.$searchContent.hide();
+ $results.empty();
- if ( query.length ) {
- $results.addClass( 'loading' );
+ if ( query.length ) {
+ $results.addClass( 'loading' );
- this.timer = setTimeout( function() {
- self.api.search( query ).done(
function( data ) {
- // check if we're getting the
rights response in case of out of
- // order responses (need to get
the current value of the input)
- if ( data.query ===
self.$input.val() ) {
- self.$searchContent.
- show().
- find( 'p' ).
- hide().
- filter(
data.results.length ? '.with-results' : '.without-results' ).
- show();
- $results.
- removeClass(
'loading' ).
- html(
M.template.get( 'articleList' ).render( { pages: data.results } ) );
- M.emit(
'search-results', self, data.results );
- }
- } );
- }, SEARCH_DELAY );
- } else {
- $results.removeClass( 'loading' );
+ this.timer = setTimeout( function() {
+ self.api.search( query ).done(
function( data ) {
+ // check if we're
getting the rights response in case of out of
+ // order responses
(need to get the current value of the input)
+ if ( data.query ===
self.$input.val() ) {
+
self.$searchContent.
+ show().
+ find(
'p' ).
+ hide().
+ filter(
data.results.length ? '.with-results' : '.without-results' ).
+ show();
+ $results.
+
removeClass( 'loading' ).
+ html(
M.template.get( 'articleList' ).render( { pages: data.results } ) );
+ M.emit(
'search-results', self, data.results );
+ }
+ } );
+ }, this.api.isCached( query ) ? 0 :
SEARCH_DELAY );
+ } else {
+ $results.removeClass( 'loading' );
+ }
+
+ this.lastQuery = query;
}
}
} );
diff --git a/javascripts/modules/searchNew/search.js
b/javascripts/modules/searchNew/search.js
index c8c5865..9d84f8d 100644
--- a/javascripts/modules/searchNew/search.js
+++ b/javascripts/modules/searchNew/search.js
@@ -3,9 +3,19 @@
var SearchOverlay = M.require( 'modules/searchNew/SearchOverlay' );
// FIXME change when micro.tap.js in stable
+ //
// don't use focus event
(https://bugzilla.wikimedia.org/show_bug.cgi?id=47499)
+ //
+ // focus() (see SearchOverlay#show) opens virtual keyboard only if
triggered
+ // from user context event, so using it in route callback won't work
+ //
http://stackoverflow.com/questions/6837543/show-virtual-keyboard-on-mobile-phones-in-javascript
$( '#searchInput' ).on( M.tapEvent( 'touchend mouseup' ), function() {
- M.router.navigate( 'search' );
+ new SearchOverlay().show();
+ // without this delay, the keyboard will not show up on
Android...
+ // (tested in Chrome for Android)
+ setTimeout( function() {
+ M.router.navigate( '/search' );
+ }, 300 );
} );
// FIXME: ugly hack that removes search from browser history when
navigating
@@ -25,9 +35,5 @@
} );
} );
}
-
- M.router.route( /^search$/, function() {
- new SearchOverlay().show();
- } );
}( mw.mobileFrontend, jQuery ));
diff --git a/less/common/pagelist.less b/less/common/pagelist.less
index 0e652b6..2715259 100644
--- a/less/common/pagelist.less
+++ b/less/common/pagelist.less
@@ -44,7 +44,6 @@
//
// Styleguide 5.
.page-list {
- cursor: pointer;
// needed for rotated watchstars to avoid horizontal scrollbar
overflow: hidden;
--
To view, visit https://gerrit.wikimedia.org/r/101466
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: I1b8b5ce86431c76ba204b7c7ea4a127c6b77e13e
Gerrit-PatchSet: 2
Gerrit-Project: mediawiki/extensions/MobileFrontend
Gerrit-Branch: master
Gerrit-Owner: JGonera <[email protected]>
Gerrit-Reviewer: JGonera <[email protected]>
Gerrit-Reviewer: Jdlrobson <[email protected]>
Gerrit-Reviewer: jenkins-bot
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits