Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 cr.define('bookmarks', function() { | |
| 6 /** | |
| 7 * Manages focus restoration for modal dialogs. | |
|
tsergeant
2017/06/28 03:47:58
I think it's worth going into a little more detail
calamity
2017/06/28 04:22:47
Done.
| |
| 8 * @constructor | |
| 9 */ | |
| 10 function DialogFocusManager() { | |
| 11 /** @private {HTMLDialogElement} */ | |
| 12 this.previousFocusElement_ = null; | |
| 13 | |
| 14 /** @private {boolean} */ | |
| 15 this.previousMouseFocus_ = false; | |
| 16 | |
| 17 /** @private {Set<HTMLDialogElement>} */ | |
| 18 this.dialogs_ = new Set(); | |
| 19 } | |
| 20 | |
| 21 DialogFocusManager.prototype = { | |
| 22 /** | |
| 23 * @param {HTMLDialogElement} dialog | |
| 24 * @param {Function=} showFn | |
| 25 */ | |
| 26 showDialog: function(dialog, showFn) { | |
| 27 if (!showFn) { | |
| 28 showFn = function() { | |
| 29 dialog.showModal(); | |
| 30 }; | |
| 31 } | |
| 32 | |
| 33 // Update the focus if there are no open dialogs or if this is the only | |
| 34 // dialog and it's getting reshown. | |
| 35 if (!this.dialogs_.size || | |
| 36 (this.dialogs_.has(dialog) && this.dialogs_.size == 1)) { | |
| 37 this.updatePreviousFocus_(); | |
| 38 } | |
| 39 | |
| 40 if (!this.dialogs_.has(dialog)) { | |
| 41 dialog.addEventListener('close', this.getCloseListener_(dialog)); | |
| 42 this.dialogs_.add(dialog); | |
| 43 } | |
| 44 | |
| 45 showFn(); | |
| 46 }, | |
| 47 | |
| 48 /** @private */ | |
| 49 updatePreviousFocus_: function() { | |
| 50 this.previousFocusElement_ = this.getFocusedElement_(); | |
| 51 this.previousMouseFocus_ = bookmarks.MouseFocusBehavior.isMouseFocused( | |
| 52 this.previousFocusElement_); | |
| 53 }, | |
| 54 | |
| 55 /** @private */ | |
|
tsergeant
2017/06/28 03:47:58
Nit: @return annotation
calamity
2017/06/28 04:22:47
Done.
| |
| 56 getFocusedElement_: function() { | |
| 57 var focus = document.activeElement; | |
| 58 while (focus.root && focus.root.activeElement) | |
| 59 focus = focus.root.activeElement; | |
| 60 | |
| 61 return focus; | |
| 62 }, | |
| 63 | |
| 64 /** | |
| 65 * @param {HTMLDialogElement} dialog | |
| 66 * @private | |
| 67 */ | |
| 68 getCloseListener_: function(dialog) { | |
|
tsergeant
2017/06/28 03:47:58
This is nifty, I'm glad you figured out the async
calamity
2017/06/28 04:22:47
Acknowledged.
| |
| 69 var closeListener = function(e) { | |
| 70 // If the dialog is open, then it got reshown immediately and we | |
| 71 // shouldn't clear it until it is closed again. | |
| 72 if (dialog.open) | |
| 73 return; | |
| 74 | |
| 75 assert(this.dialogs_.delete(dialog)); | |
| 76 // Focus the originally focused element if there are no more dialogs. | |
| 77 if (!this.dialogs_.size) { | |
| 78 this.previousFocusElement_.focus(); | |
| 79 if (this.previousMouseFocus_) { | |
| 80 bookmarks.MouseFocusBehavior.addMouseFocusClass( | |
| 81 this.previousFocusElement_); | |
| 82 } | |
| 83 } | |
| 84 dialog.removeEventListener('close', closeListener); | |
| 85 }.bind(this); | |
| 86 | |
| 87 return closeListener; | |
| 88 }, | |
|
tsergeant
2017/06/28 03:47:58
Nit: this should be a ; not a ,
calamity
2017/06/28 04:22:47
Done.
| |
| 89 }, | |
| 90 | |
| 91 cr.addSingletonGetter(DialogFocusManager); | |
| 92 | |
| 93 return { | |
| 94 DialogFocusManager: DialogFocusManager, | |
| 95 }; | |
| 96 }); | |
| OLD | NEW |