Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(60)

Unified Diff: chrome/browser/resources/media_router/elements/media_router_container/media_router_container.js

Issue 1810223002: [Media Router UI] Fix search results overflow scroll and input focus. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@2661
Patch Set: Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/resources/media_router/elements/media_router_container/media_router_container.js
diff --git a/chrome/browser/resources/media_router/elements/media_router_container/media_router_container.js b/chrome/browser/resources/media_router/elements/media_router_container/media_router_container.js
index 64ef04c1685462be171824751c3c8bcb096dae42..76b681aa2c5cea6a4765bcc28b0cc820706512e5 100644
--- a/chrome/browser/resources/media_router/elements/media_router_container/media_router_container.js
+++ b/chrome/browser/resources/media_router/elements/media_router_container/media_router_container.js
@@ -192,6 +192,40 @@ Polymer({
},
/**
+ * Whether the search input is currently focused. This is used to prevent
+ * window focus/blur events from interfering with input-focus-dependent
+ * operations.
+ * @private {boolean}
+ */
+ isSearchFocused_: {
+ type: Boolean,
+ value: false,
+ },
+
+ /**
+ * Records the value of |isSearchFocused_| when a window blur event is
+ * received. This used to handle search focus edge cases. See
+ * |setSearchFocusHandlers_| for details.
+ * @private {boolean}
+ */
+ isSearchFocusedOnWindowBlur_: {
+ type: Boolean,
+ value: false,
+ },
+
+ /**
+ * Temporarily set when the window focus event handler needs to reset
+ * |isSearchFocused_| to the correct value but needs to know whether the
+ * search input focus handler will run. See |setSearchFocusHandlers_| for
+ * details.
+ * @private {boolean}
+ */
+ isSearchFocusedShouldBeSet_: {
+ type: Boolean,
+ value: false,
+ },
+
+ /**
* Whether the user is currently searching for a sink.
* @private {boolean}
*/
@@ -456,9 +490,7 @@ Polymer({
ready: function() {
this.elementReadyTimeMs_ = performance.now();
document.addEventListener('keydown', this.checkForEscapePress_.bind(this));
- this.$$('#sink-search-input').addEventListener('focus', function() {
- this.isUserSearching_ = true;
- }.bind(this));
+ this.setSearchFocusHandlers_();
this.showSinkList_();
},
@@ -1093,6 +1125,7 @@ Polymer({
isUserSearchingChanged_: function(isUserSearching) {
if (isUserSearching) {
this.currentView_ = media_router.MediaRouterView.FILTER;
+ this.updateElementPositioning_();
this.filterSinks_(this.searchInputText_);
} else {
this.currentView_ = media_router.MediaRouterView.SINK_LIST;
@@ -1396,6 +1429,65 @@ Polymer({
},
/**
+ * Sets various focus and blur event handlers to handle |isSearchFocused_| and
+ * showing search results when the input is focused.
+ * @private
+ */
+ setSearchFocusHandlers_: function() {
+ var search = this.$['sink-search-input'];
+
+ // The window can see a blur event for two important cases: the window is
+ // actually losing focus or keyboard focus is wrapping from the end of the
+ // document to the beginning. To handle both cases, we save the state of
+ // |isSearchFocused_| during the window blur event.
+ //
+ // The corresponding window focus event can do nothing if |isSearchFocused_|
+ // was false during the blur event. If the search input is gaining focus now
+ // it will work correctly. There are two cases when the input had focus
+ // during the window blur event: the input still has focus and the input
+ // lost focus. These cases are handled by the logic around
+ // |isSearchFocusedShouldBeSet_| and |isSearchFocused_|.
+ //
+ // Because the window focus event will always happen first, it doesn't know
+ // whether the input focus handler will later run or not. If it is not going
+ // to run, then |isSearchFocused_| should be set to |false|, otherwise it
+ // should be |true|. So the window focus handler just sets
+ // |isSearchFocused_| to |false| and makes a note in
+ // |isSearchFocusedShouldBeSet_| that |isSearchFocused_| should actually be
+ // set to true if the search focus handler runs. The |setTimeout| in the
+ // window focus handler clears this note as soon as all focus event handlers
+ // have run.
+ window.addEventListener('blur', function() {
+ this.isSearchFocusedOnWindowBlur_ = this.isSearchFocused_;
+ }.bind(this));
+ window.addEventListener('focus', function() {
+ if (this.isSearchFocusedOnWindowBlur_) {
+ this.isSearchFocusedOnWindowBlur_ = false;
+ this.isSearchFocusedShouldBeSet_ = true;
+ this.isSearchFocused_ = false;
+ setTimeout(function() {
+ this.isSearchFocusedShouldBeSet_ = false;
+ }.bind(this));
+ }
+ }.bind(this));
+ search.addEventListener('blur', function() {
+ // This lets normal blur cases work as expected, but doesn't get in the
+ // way of the window blur handler capturing the "current" state. This is
+ // the case because this will be run after all the blur handlers are done.
+ setTimeout(function() { this.isSearchFocused_ = false; }.bind(this));
+ }.bind(this));
+ search.addEventListener('focus', function() {
+ if (this.isSearchFocusedShouldBeSet_) {
+ this.isSearchFocused_ = true;
+ }
+ if (!this.isSearchFocused_) {
+ this.isSearchFocused_ = true;
+ this.isUserSearching_ = true;
+ }
+ }.bind(this));
+ },
+
+ /**
* Updates the shown cast mode, and updates the header text fields
* according to the cast mode. If |castMode| type is AUTO, then set
* |userHasSelectedCastMode_| to false.
@@ -1522,13 +1614,18 @@ Polymer({
var issueHeight = this.$$('#issue-banner') &&
this.$$('#issue-banner').style.display != 'none' ?
this.$$('#issue-banner').offsetHeight : 0;
+ var searchHeight = this.$$('#sink-search').offsetHeight;
this.$['container-header'].style.marginTop = firstRunFlowHeight + 'px';
this.$['sink-list-view'].style.marginTop =
firstRunFlowHeight + headerHeight + 'px';
this.$['sink-list'].style.maxHeight =
this.dialogHeight_ - headerHeight - firstRunFlowHeight -
- issueHeight + 'px';
+ issueHeight - searchHeight + 'px';
+ var searchResults = this.$$('#search-results');
+ if (searchResults) {
+ searchResults.style.maxHeight = this.$['sink-list'].style.maxHeight;
+ }
});
},
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698