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

Side by Side Diff: ui/webui/resources/cr_elements/cr_dialog/cr_dialog.js

Issue 2815623005: MD Settings: in cr_dialog, prevent intersectionObserver from firing early. (Closed)
Patch Set: use mutationObserver to not mess with native dialog.open Created 3 years, 8 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 unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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 /** 5 /**
6 * @fileoverview 'cr-dialog' is a component for showing a modal dialog. If the 6 * @fileoverview 'cr-dialog' is a component for showing a modal dialog. If the
7 * dialog is closed via close(), a 'close' event is fired. If the dialog is 7 * dialog is closed via close(), a 'close' event is fired. If the dialog is
8 * canceled via cancel(), a 'cancel' event is fired followed by a 'close' event. 8 * canceled via cancel(), a 'cancel' event is fired followed by a 'close' event.
9 * Additionally clients can inspect the dialog's |returnValue| property inside 9 * Additionally clients can inspect the dialog's |returnValue| property inside
10 * the 'close' event listener to determine whether it was canceled or just 10 * the 'close' event listener to determine whether it was canceled or just
(...skipping 30 matching lines...) Expand all
41 showScrollBorders: { 41 showScrollBorders: {
42 type: Boolean, 42 type: Boolean,
43 value: false, 43 value: false,
44 reflectToAttribute: true, 44 reflectToAttribute: true,
45 }, 45 },
46 }, 46 },
47 47
48 /** @private {?IntersectionObserver} */ 48 /** @private {?IntersectionObserver} */
49 intersectionObserver_: null, 49 intersectionObserver_: null,
50 50
51 /** @private {?MutationObserver} */
52 mutationObserver_: null,
53
51 /** @override */ 54 /** @override */
52 ready: function() { 55 ready: function() {
53 // If the active history entry changes (i.e. user clicks back button), 56 // If the active history entry changes (i.e. user clicks back button),
54 // all open dialogs should be cancelled. 57 // all open dialogs should be cancelled.
55 window.addEventListener('popstate', function() { 58 window.addEventListener('popstate', function() {
56 if (!this.ignorePopstate && this.open) 59 if (!this.ignorePopstate && this.open)
57 this.cancel(); 60 this.cancel();
58 }.bind(this)); 61 }.bind(this));
59 62
60 if (!this.ignoreEnterKey) 63 if (!this.ignoreEnterKey)
61 this.addEventListener('keypress', this.onKeypress_.bind(this)); 64 this.addEventListener('keypress', this.onKeypress_.bind(this));
62 }, 65 },
63 66
64 /** @override */ 67 /** @override */
65 attached: function() { 68 attached: function() {
66 if (this.showScrollBorders) { 69 if (this.showScrollBorders) {
70 this.mutationObserver_ = new MutationObserver(function() {
71 if (this.open) {
72 this.addIntersectionObserver_();
73 } else {
74 this.removeIntersectionObserver_();
75 }
76 }.bind(this));
77
78 var observerConfig = {
dpapad 2017/04/13 20:31:39 Nit (optional): Since this is only used once below
scottchen 2017/04/13 21:46:04 Done.
79 attributes: true,
80 attributeFilter: ['open'],
81 };
82
83 this.mutationObserver_.observe(this, observerConfig);
84 }
85 },
86
87 /** @override */
88 detached: function() {
89 if (this.mutationObserver_) {
90 this.mutationObserver_.disconnect();
91 this.mutationObserver_ = null;
92 }
dpapad 2017/04/13 20:31:39 Previous code was removing the IntersectionObserve
scottchen 2017/04/13 21:46:04 Yes, will leak. Fixed.
93 },
94
95 /** @private */
96 addIntersectionObserver_: function() {
97 if (!this.intersectionObserver_) {
67 var bodyContainer = this.$$('.body-container'); 98 var bodyContainer = this.$$('.body-container');
68 99
69 var bottomMarker = this.$.bodyBottomMarker; 100 var bottomMarker = this.$.bodyBottomMarker;
70 var topMarker = this.$.bodyTopMarker; 101 var topMarker = this.$.bodyTopMarker;
71 102
72 var callback = function(entries) { 103 var callback = function(entries) {
73 assert(entries.length <= 2); 104 assert(entries.length <= 2);
74 for (var i = 0; i < entries.length; i++) { 105 for (var i = 0; i < entries.length; i++) {
75 var target = entries[i].target; 106 var target = entries[i].target;
76 assert(target == bottomMarker || target == topMarker); 107 assert(target == bottomMarker || target == topMarker);
77 108
78 var classToToggle = 109 var classToToggle =
79 target == bottomMarker ? 'bottom-scrollable' : 'top-scrollable'; 110 target == bottomMarker ? 'bottom-scrollable' : 'top-scrollable';
80 111
81 bodyContainer.classList.toggle( 112 bodyContainer.classList.toggle(
82 classToToggle, entries[i].intersectionRatio == 0); 113 classToToggle, entries[i].intersectionRatio == 0);
83 } 114 }
84 }; 115 };
85 116
86 this.intersectionObserver_ = new IntersectionObserver( 117 this.intersectionObserver_ = new IntersectionObserver(
87 callback, 118 callback,
88 /** @type {IntersectionObserverInit} */ ({ 119 /** @type {IntersectionObserverInit} */ ({
89 root: bodyContainer, 120 root: bodyContainer,
90 threshold: 0, 121 threshold: 0,
91 })); 122 }));
123
dpapad 2017/04/13 20:31:39 Nit (optional): Revert this?
scottchen 2017/04/13 21:46:04 Done.
92 this.intersectionObserver_.observe(bottomMarker); 124 this.intersectionObserver_.observe(bottomMarker);
93 this.intersectionObserver_.observe(topMarker); 125 this.intersectionObserver_.observe(topMarker);
94 } 126 }
95 }, 127 },
96 128
97 /** @override */ 129 /** @private */
98 detached: function() { 130 removeIntersectionObserver_: function() {
99 if (this.intersectionObserver_) { 131 if (this.intersectionObserver_) {
100 this.intersectionObserver_.disconnect(); 132 this.intersectionObserver_.disconnect();
101 this.intersectionObserver_ = null; 133 this.intersectionObserver_ = null;
102 } 134 }
103 }, 135 },
104 136
105 cancel: function() { 137 cancel: function() {
106 this.fire('cancel'); 138 this.fire('cancel');
107 HTMLDialogElement.prototype.close.call(this, ''); 139 HTMLDialogElement.prototype.close.call(this, '');
108 }, 140 },
(...skipping 24 matching lines...) Expand all
133 return; 165 return;
134 166
135 var actionButton = 167 var actionButton =
136 this.querySelector('.action-button:not([disabled]):not([hidden])'); 168 this.querySelector('.action-button:not([disabled]):not([hidden])');
137 if (actionButton) { 169 if (actionButton) {
138 actionButton.click(); 170 actionButton.click();
139 e.preventDefault(); 171 e.preventDefault();
140 } 172 }
141 }, 173 },
142 }); 174 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698