| 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;
|
| + }
|
| });
|
| },
|
|
|
|
|