| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 cr.define('options', function() { | 5 cr.define('options', function() { |
| 6 /** @const */ var FocusOutlineManager = cr.ui.FocusOutlineManager; | 6 /** @const */ var FocusOutlineManager = cr.ui.FocusOutlineManager; |
| 7 | 7 |
| 8 ///////////////////////////////////////////////////////////////////////////// | 8 ///////////////////////////////////////////////////////////////////////////// |
| 9 // OptionsPage class: | 9 // OptionsPage class: |
| 10 | 10 |
| (...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 349 | 349 |
| 350 this.restoreLastFocusedElement_(); | 350 this.restoreLastFocusedElement_(); |
| 351 if (!this.isOverlayVisible_()) | 351 if (!this.isOverlayVisible_()) |
| 352 $('searchBox').removeAttribute('aria-hidden'); | 352 $('searchBox').removeAttribute('aria-hidden'); |
| 353 }; | 353 }; |
| 354 | 354 |
| 355 /** | 355 /** |
| 356 * Cancels (closes) the overlay, due to the user pressing <Esc>. | 356 * Cancels (closes) the overlay, due to the user pressing <Esc>. |
| 357 */ | 357 */ |
| 358 OptionsPage.cancelOverlay = function() { | 358 OptionsPage.cancelOverlay = function() { |
| 359 var overlay = this.getVisibleOverlay_(); |
| 360 if (!overlay) |
| 361 return; |
| 362 |
| 359 // Blur the active element to ensure any changed pref value is saved. | 363 // Blur the active element to ensure any changed pref value is saved. |
| 360 document.activeElement.blur(); | 364 document.activeElement.blur(); |
| 361 var overlay = this.getVisibleOverlay_(); | 365 |
| 362 // Let the overlay handle the <Esc> if it wants to. | 366 // Let the overlay handle the <Esc> if it wants to. |
| 363 if (overlay.handleCancel) { | 367 if (overlay.handleCancel) { |
| 364 overlay.handleCancel(); | 368 overlay.handleCancel(); |
| 365 this.restoreLastFocusedElement_(); | 369 this.restoreLastFocusedElement_(); |
| 366 } else { | 370 } else { |
| 367 this.closeOverlay(); | 371 this.closeOverlay(); |
| 368 } | 372 } |
| 369 }; | 373 }; |
| 370 | 374 |
| 371 /** | 375 /** |
| (...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 648 */ | 652 */ |
| 649 OptionsPage.initialize = function() { | 653 OptionsPage.initialize = function() { |
| 650 chrome.send('coreOptionsInitialize'); | 654 chrome.send('coreOptionsInitialize'); |
| 651 uber.onContentFrameLoaded(); | 655 uber.onContentFrameLoaded(); |
| 652 FocusOutlineManager.forDocument(document); | 656 FocusOutlineManager.forDocument(document); |
| 653 document.addEventListener('scroll', this.handleScroll_.bind(this)); | 657 document.addEventListener('scroll', this.handleScroll_.bind(this)); |
| 654 | 658 |
| 655 // Trigger the scroll handler manually to set the initial state. | 659 // Trigger the scroll handler manually to set the initial state. |
| 656 this.handleScroll_(); | 660 this.handleScroll_(); |
| 657 | 661 |
| 658 // Shake the dialog if the user clicks outside the dialog bounds. | 662 var dialogs = document.querySelectorAll('.overlay-container .page'); |
| 659 var containers = [$('overlay-container-1'), $('overlay-container-2')]; | 663 for (var i = 0; i < dialogs.length; i++) { |
| 660 for (var i = 0; i < containers.length; i++) { | 664 var dialog = dialogs[i]; |
| 661 var overlay = containers[i]; | 665 cr.ui.overlay.setupOverlay(dialog); |
| 662 cr.ui.overlay.setupOverlay(overlay); | 666 dialog.addEventListener('cancelOverlay', |
| 663 overlay.addEventListener('cancelOverlay', | 667 OptionsPage.cancelOverlay.bind(OptionsPage)); |
| 664 OptionsPage.cancelOverlay.bind(OptionsPage)); | 668 dialog.addEventListener('webkitAnimationEnd', |
| 669 OptionsPage.handleDialogAnimationEnd_); |
| 665 } | 670 } |
| 666 | 671 |
| 667 cr.ui.overlay.globalInitialization(); | 672 cr.ui.overlay.globalInitialization(); |
| 668 }; | 673 }; |
| 669 | 674 |
| 670 /** | 675 /** |
| 676 * Called when a webkitAnimationEnd event occurs on a dialog. If it was a |
| 677 * fading away animation that completed, closes the dialog. |
| 678 */ |
| 679 OptionsPage.handleDialogAnimationEnd_ = function(e) { |
| 680 if (e.target != e.currentTarget) |
| 681 return; |
| 682 var dialog = e.target; |
| 683 dialog.classList.remove('opening'); |
| 684 dialog.classList.remove('pulse'); |
| 685 if (dialog.classList.contains('closing')) { |
| 686 dialog.close(); |
| 687 // TODO(falken): It's probably better move these to a close event handler, |
| 688 // once <dialog> implements it. |
| 689 dialog.classList.remove('closing'); |
| 690 dialog.page.fadeCompleted_(); |
| 691 } |
| 692 } |
| 693 |
| 694 /** |
| 671 * Does a bounds check for the element on the given x, y client coordinates. | 695 * Does a bounds check for the element on the given x, y client coordinates. |
| 672 * @param {Element} e The DOM element. | 696 * @param {Element} e The DOM element. |
| 673 * @param {number} x The client X to check. | 697 * @param {number} x The client X to check. |
| 674 * @param {number} y The client Y to check. | 698 * @param {number} y The client Y to check. |
| 675 * @return {boolean} True if the point falls within the element's bounds. | 699 * @return {boolean} True if the point falls within the element's bounds. |
| 676 * @private | 700 * @private |
| 677 */ | 701 */ |
| 678 OptionsPage.elementContainsPoint_ = function(e, x, y) { | 702 OptionsPage.elementContainsPoint_ = function(e, x, y) { |
| 679 var clientRect = e.getBoundingClientRect(); | 703 var clientRect = e.getBoundingClientRect(); |
| 680 return x >= clientRect.left && x <= clientRect.right && | 704 return x >= clientRect.left && x <= clientRect.right && |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 805 get container() { | 829 get container() { |
| 806 assert(this.isOverlay); | 830 assert(this.isOverlay); |
| 807 return this.pageDiv.parentNode; | 831 return this.pageDiv.parentNode; |
| 808 }, | 832 }, |
| 809 | 833 |
| 810 /** | 834 /** |
| 811 * Gets page visibility state. | 835 * Gets page visibility state. |
| 812 * @type {boolean} | 836 * @type {boolean} |
| 813 */ | 837 */ |
| 814 get visible() { | 838 get visible() { |
| 815 // If this is an overlay dialog it is no longer considered visible while | 839 if (this.isOverlay) { |
| 816 // the overlay is fading out. See http://crbug.com/118629. | 840 if (!this.pageDiv.open || this.pageDiv.classList.contains('closing')) |
| 817 if (this.isOverlay && | 841 return false; |
| 818 this.container.classList.contains('transparent')) { | |
| 819 return false; | |
| 820 } | 842 } |
| 821 if (this.pageDiv.hidden) | 843 if (this.pageDiv.hidden) |
| 822 return false; | 844 return false; |
| 823 return this.pageDiv.page == this; | 845 return this.pageDiv.page == this; |
| 824 }, | 846 }, |
| 825 | 847 |
| 826 /** | 848 /** |
| 827 * Sets page visibility. | 849 * Sets page visibility. |
| 828 * @type {boolean} | 850 * @type {boolean} |
| 829 */ | 851 */ |
| (...skipping 16 matching lines...) Expand all Loading... |
| 846 }, | 868 }, |
| 847 | 869 |
| 848 /** | 870 /** |
| 849 * Shows or hides an overlay (including any visible dialog). | 871 * Shows or hides an overlay (including any visible dialog). |
| 850 * @param {boolean} visible Whether the overlay should be visible or not. | 872 * @param {boolean} visible Whether the overlay should be visible or not. |
| 851 * @private | 873 * @private |
| 852 */ | 874 */ |
| 853 setOverlayVisible_: function(visible) { | 875 setOverlayVisible_: function(visible) { |
| 854 assert(this.isOverlay); | 876 assert(this.isOverlay); |
| 855 var pageDiv = this.pageDiv; | 877 var pageDiv = this.pageDiv; |
| 856 var container = this.container; | |
| 857 | 878 |
| 858 if (visible) { | 879 if (visible) { |
| 859 uber.invokeMethodOnParent('beginInterceptingEvents'); | 880 uber.invokeMethodOnParent('beginInterceptingEvents'); |
| 860 this.pageDiv.removeAttribute('aria-hidden'); | 881 this.pageDiv.removeAttribute('aria-hidden'); |
| 861 if (this.parentPage) | 882 if (this.parentPage) |
| 862 this.parentPage.pageDiv.setAttribute('aria-hidden', true); | 883 this.parentPage.pageDiv.setAttribute('aria-hidden', true); |
| 863 } else { | 884 } else { |
| 864 if (this.parentPage) | 885 if (this.parentPage) |
| 865 this.parentPage.pageDiv.removeAttribute('aria-hidden'); | 886 this.parentPage.pageDiv.removeAttribute('aria-hidden'); |
| 866 } | 887 } |
| 867 | 888 |
| 868 if (container.hidden != visible) { | 889 if (visible) { |
| 869 if (visible) { | 890 // If the dialog is set invisible and then immediately set visible |
| 870 // If the container is set hidden and then immediately set visible | 891 // again, the webkitAnimationEnd callback would cause it to be |
| 871 // again, the fadeCompleted_ callback would cause it to be erroneously | 892 // erroneously closed again. Removing the closing tag avoids that. |
| 872 // hidden again. Removing the transparent tag avoids that. | 893 pageDiv.classList.remove('closing'); |
| 873 container.classList.remove('transparent'); | |
| 874 | 894 |
| 875 // Hide all dialogs in this container since a different one may have | 895 // Hide all dialogs in this container since a different one may have |
| 876 // been previously visible before fading out. | 896 // been previously visible before fading out. |
| 877 var pages = container.querySelectorAll('.page'); | 897 var pages = this.container.querySelectorAll('.page'); |
| 878 for (var i = 0; i < pages.length; i++) | 898 for (var i = 0; i < pages.length; i++) { |
| 879 pages[i].hidden = true; | 899 if (pages[i].open) |
| 880 // Show the new dialog. | 900 pages[i].close(); |
| 881 pageDiv.hidden = false; | |
| 882 pageDiv.page = this; | |
| 883 } | 901 } |
| 884 return; | |
| 885 } | |
| 886 | 902 |
| 887 if (visible) { | 903 pageDiv.showModal(); |
| 888 container.hidden = false; | |
| 889 pageDiv.hidden = false; | |
| 890 pageDiv.page = this; | 904 pageDiv.page = this; |
| 891 // NOTE: This is a hacky way to force the container to layout which | |
| 892 // will allow us to trigger the webkit transition. | |
| 893 container.scrollTop; | |
| 894 container.classList.remove('transparent'); | |
| 895 this.onVisibilityChanged_(); | 905 this.onVisibilityChanged_(); |
| 906 cr.ui.overlay.center(pageDiv); |
| 907 pageDiv.classList.add('opening'); |
| 896 } else { | 908 } else { |
| 897 // Kick change events for text fields. | 909 // Kick change events for text fields. |
| 898 if (pageDiv.contains(document.activeElement)) | 910 if (pageDiv.contains(document.activeElement)) |
| 899 document.activeElement.blur(); | 911 document.activeElement.blur(); |
| 900 var self = this; | 912 |
| 901 // TODO: Use an event delegate to avoid having to subscribe and | 913 pageDiv.classList.add('closing'); |
| 902 // unsubscribe for webkitTransitionEnd events. | |
| 903 container.addEventListener('webkitTransitionEnd', function f(e) { | |
| 904 if (e.target != e.currentTarget || e.propertyName != 'opacity') | |
| 905 return; | |
| 906 container.removeEventListener('webkitTransitionEnd', f); | |
| 907 self.fadeCompleted_(); | |
| 908 }); | |
| 909 container.classList.add('transparent'); | |
| 910 } | 914 } |
| 911 }, | 915 }, |
| 912 | 916 |
| 913 /** | 917 /** |
| 914 * Called when a container opacity transition finishes. | 918 * Called when a dialog closing animation finishes. |
| 915 * @private | 919 * @private |
| 916 */ | 920 */ |
| 917 fadeCompleted_: function() { | 921 fadeCompleted_: function() { |
| 918 if (this.container.classList.contains('transparent')) { | 922 this.onVisibilityChanged_(); |
| 919 this.pageDiv.hidden = true; | 923 if (this.nestingLevel == 1) |
| 920 this.container.hidden = true; | 924 uber.invokeMethodOnParent('stopInterceptingEvents'); |
| 921 this.onVisibilityChanged_(); | |
| 922 if (this.nestingLevel == 1) | |
| 923 uber.invokeMethodOnParent('stopInterceptingEvents'); | |
| 924 } | |
| 925 }, | 925 }, |
| 926 | 926 |
| 927 /** | 927 /** |
| 928 * Called when a page is shown or hidden to update the root options page | 928 * Called when a page is shown or hidden to update the root options page |
| 929 * based on this page's visibility. | 929 * based on this page's visibility. |
| 930 * @private | 930 * @private |
| 931 */ | 931 */ |
| 932 onVisibilityChanged_: function() { | 932 onVisibilityChanged_: function() { |
| 933 OptionsPage.updateRootPageFreezeState(); | 933 OptionsPage.updateRootPageFreezeState(); |
| 934 | 934 |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 982 canShowPage: function() { | 982 canShowPage: function() { |
| 983 return true; | 983 return true; |
| 984 }, | 984 }, |
| 985 }; | 985 }; |
| 986 | 986 |
| 987 // Export | 987 // Export |
| 988 return { | 988 return { |
| 989 OptionsPage: OptionsPage | 989 OptionsPage: OptionsPage |
| 990 }; | 990 }; |
| 991 }); | 991 }); |
| OLD | NEW |