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

Side by Side Diff: third_party/WebKit/Source/devtools/front_end/ui/Dialog.js

Issue 2658383002: [DevTools] Make UI.GlassPane position contentElement for different overlay controls. (Closed)
Patch Set: rebased Created 3 years, 10 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 /* 1 /*
2 * Copyright (C) 2012 Google Inc. All rights reserved. 2 * Copyright (C) 2012 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 21 matching lines...) Expand all
32 * @unrestricted 32 * @unrestricted
33 */ 33 */
34 UI.Dialog = class extends UI.Widget { 34 UI.Dialog = class extends UI.Widget {
35 constructor() { 35 constructor() {
36 super(true); 36 super(true);
37 this.markAsRoot(); 37 this.markAsRoot();
38 this.registerRequiredCSS('ui/dialog.css'); 38 this.registerRequiredCSS('ui/dialog.css');
39 39
40 this.contentElement.createChild('content'); 40 this.contentElement.createChild('content');
41 this.contentElement.tabIndex = 0; 41 this.contentElement.tabIndex = 0;
42 this.contentElement.addEventListener('focus', this._onFocus.bind(this), fals e); 42 this.contentElement.addEventListener('focus', this.focus.bind(this), false);
43 this._keyDownBound = this._onKeyDown.bind(this); 43 this.contentElement.addEventListener('keydown', this._onKeyDown.bind(this), false);
44 this._dimmed = false;
45 this._wrapsContent = false;
46 this._maxSize = null;
47 /** @type {?number} */
48 this._positionX = null;
49 /** @type {?number} */
50 this._positionY = null;
44 51
45 this._wrapsContent = false;
46 this._dimmed = false;
47 /** @type {!Map<!HTMLElement, number>} */ 52 /** @type {!Map<!HTMLElement, number>} */
48 this._tabIndexMap = new Map(); 53 this._tabIndexMap = new Map();
49 } 54 }
50 55
51 /** 56 /**
52 * @return {boolean} 57 * @return {boolean}
53 */ 58 */
54 static hasInstance() { 59 static hasInstance() {
55 return !!UI.Dialog._instance; 60 return !!UI.Dialog._instance;
56 } 61 }
57 62
58 /** 63 /**
59 * @param {!UI.Widget} view
60 */
61 static setModalHostView(view) {
62 UI.Dialog._modalHostView = view;
63 }
64
65 /**
66 * FIXME: make utility method in Dialog, so clients use it instead of this get ter.
67 * Method should be like Dialog.showModalElement(position params, reposition c allback).
68 * @return {?UI.Widget}
69 */
70 static modalHostView() {
71 return UI.Dialog._modalHostView;
72 }
73
74 static modalHostRepositioned() {
75 if (UI.Dialog._instance)
76 UI.Dialog._instance._position();
77 }
78
79 /**
80 * @override 64 * @override
65 * @suppressGlobalPropertiesCheck
66 * TODO(dgozman): pass document in constructor.
81 */ 67 */
82 show() { 68 show() {
83 if (UI.Dialog._instance) 69 if (UI.Dialog._instance)
84 UI.Dialog._instance.detach(); 70 UI.Dialog._instance.detach();
85 UI.Dialog._instance = this; 71 UI.Dialog._instance = this;
86 72
87 var document = /** @type {!Document} */ (UI.Dialog._modalHostView.element.ow nerDocument);
88 this._disableTabIndexOnElements(document); 73 this._disableTabIndexOnElements(document);
89 74
90 this._glassPane = new UI.GlassPane(document, this._dimmed); 75 this._glassPane = new UI.GlassPane(document, this._dimmed, true /* blockPoin terEvents*/, event => {
91 this._glassPane.element.addEventListener('click', this._onGlassPaneClick.bin d(this), false); 76 this.detach();
92 this.element.ownerDocument.body.addEventListener('keydown', this._keyDownBou nd, false); 77 event.consume(true);
93 78 });
94 super.show(this._glassPane.element); 79 this._glassPane.show();
95 80 super.show(this._glassPane.contentElement);
96 this._position(); 81 this._glassPane.setContentPosition(this._positionX, this._positionY);
82 this._glassPane.setMaxContentSize(this._effectiveMaxSize());
97 this._focusRestorer = new UI.WidgetFocusRestorer(this); 83 this._focusRestorer = new UI.WidgetFocusRestorer(this);
98 } 84 }
99 85
100 /** 86 /**
101 * @override 87 * @override
102 */ 88 */
103 detach() { 89 detach() {
104 this._focusRestorer.restore(); 90 this._focusRestorer.restore();
105 91
106 this.element.ownerDocument.body.removeEventListener('keydown', this._keyDown Bound, false);
107 super.detach(); 92 super.detach();
108 93 this._glassPane.hide();
109 this._glassPane.dispose();
110 delete this._glassPane; 94 delete this._glassPane;
111 95
112 this._restoreTabIndexOnElements(); 96 this._restoreTabIndexOnElements();
113 97
114 delete UI.Dialog._instance; 98 delete UI.Dialog._instance;
115 } 99 }
116 100
117 addCloseButton() { 101 addCloseButton() {
118 var closeButton = this.contentElement.createChild('div', 'dialog-close-butto n', 'dt-close-button'); 102 var closeButton = this.contentElement.createChild('div', 'dialog-close-butto n', 'dt-close-button');
119 closeButton.gray = true; 103 closeButton.gray = true;
120 closeButton.addEventListener('click', () => this.detach(), false); 104 closeButton.addEventListener('click', () => this.detach(), false);
121 } 105 }
122 106
123 /** 107 /**
124 * @param {number=} positionX 108 * @param {?number} positionX
125 * @param {number=} positionY 109 * @param {?number} positionY
126 */ 110 */
127 setPosition(positionX, positionY) { 111 setPosition(positionX, positionY) {
128 this._defaultPositionX = positionX; 112 this._positionX = positionX;
129 this._defaultPositionY = positionY; 113 this._positionY = positionY;
130 } 114 }
131 115
132 /** 116 /**
133 * @param {!UI.Size} size 117 * @param {!UI.Size} size
134 */ 118 */
135 setMaxSize(size) { 119 setMaxSize(size) {
136 this._maxSize = size; 120 this._maxSize = size;
137 } 121 }
138 122
139 /** 123 /**
124 * @return {?UI.Size}
125 */
126 _effectiveMaxSize() {
127 if (!this._wrapsContent)
128 return this._maxSize;
129 return new UI.Size(this.contentElement.offsetWidth, this.contentElement.offs etHeight).clipTo(this._maxSize);
130 }
131
132 /**
140 * @param {boolean} wraps 133 * @param {boolean} wraps
141 */ 134 */
142 setWrapsContent(wraps) { 135 setWrapsContent(wraps) {
136 this._wrapsContent = wraps;
143 this.element.classList.toggle('wraps-content', wraps); 137 this.element.classList.toggle('wraps-content', wraps);
144 this._wrapsContent = wraps;
145 } 138 }
146 139
147 /** 140 /**
148 * @param {boolean} dimmed 141 * @param {boolean} dimmed
149 */ 142 */
150 setDimmed(dimmed) { 143 setDimmed(dimmed) {
151 this._dimmed = dimmed; 144 this._dimmed = dimmed;
152 } 145 }
153 146
154 contentResized() { 147 contentResized() {
155 if (this._wrapsContent) 148 if (!this._wrapsContent || !this._glassPane)
156 this._position(); 149 return;
150 this._glassPane.setMaxContentSize(this._effectiveMaxSize());
157 } 151 }
158 152
159 /** 153 /**
160 * @param {!Document} document 154 * @param {!Document} document
161 */ 155 */
162 _disableTabIndexOnElements(document) { 156 _disableTabIndexOnElements(document) {
163 this._tabIndexMap.clear(); 157 this._tabIndexMap.clear();
164 for (var node = document; node; node = node.traverseNextNode(document)) { 158 for (var node = document; node; node = node.traverseNextNode(document)) {
165 if (node instanceof HTMLElement) { 159 if (node instanceof HTMLElement) {
166 var element = /** @type {!HTMLElement} */ (node); 160 var element = /** @type {!HTMLElement} */ (node);
167 var tabIndex = element.tabIndex; 161 var tabIndex = element.tabIndex;
168 if (tabIndex >= 0) { 162 if (tabIndex >= 0) {
169 this._tabIndexMap.set(element, tabIndex); 163 this._tabIndexMap.set(element, tabIndex);
170 element.tabIndex = -1; 164 element.tabIndex = -1;
171 } 165 }
172 } 166 }
173 } 167 }
174 } 168 }
175 169
176 _restoreTabIndexOnElements() { 170 _restoreTabIndexOnElements() {
177 for (var element of this._tabIndexMap.keys()) 171 for (var element of this._tabIndexMap.keys())
178 element.tabIndex = /** @type {number} */ (this._tabIndexMap.get(element)); 172 element.tabIndex = /** @type {number} */ (this._tabIndexMap.get(element));
179 this._tabIndexMap.clear(); 173 this._tabIndexMap.clear();
180 } 174 }
181 175
182 /** 176 /**
183 * @param {!Event} event 177 * @param {!Event} event
184 */ 178 */
185 _onFocus(event) {
186 this.focus();
187 }
188
189 /**
190 * @param {!Event} event
191 */
192 _onGlassPaneClick(event) {
193 if (!this.element.isSelfOrAncestor(/** @type {?Node} */ (event.target)))
194 this.detach();
195 }
196
197 _position() {
198 var container = UI.Dialog._modalHostView.element;
199
200 var width = container.offsetWidth - 10;
201 var height = container.offsetHeight - 10;
202
203 if (this._wrapsContent) {
204 width = Math.min(width, this.contentElement.offsetWidth);
205 height = Math.min(height, this.contentElement.offsetHeight);
206 }
207
208 if (this._maxSize) {
209 width = Math.min(width, this._maxSize.width);
210 height = Math.min(height, this._maxSize.height);
211 }
212
213 var positionX;
214 if (typeof this._defaultPositionX === 'number') {
215 positionX = this._defaultPositionX;
216 } else {
217 positionX = (container.offsetWidth - width) / 2;
218 positionX = Number.constrain(positionX, 0, container.offsetWidth - width);
219 }
220
221 var positionY;
222 if (typeof this._defaultPositionY === 'number') {
223 positionY = this._defaultPositionY;
224 } else {
225 positionY = (container.offsetHeight - height) / 2;
226 positionY = Number.constrain(positionY, 0, container.offsetHeight - height );
227 }
228
229 this.element.style.width = width + 'px';
230 this.element.style.height = height + 'px';
231 this.element.positionAt(positionX, positionY, container);
232 }
233
234 /**
235 * @param {!Event} event
236 */
237 _onKeyDown(event) { 179 _onKeyDown(event) {
238 if (event.keyCode === UI.KeyboardShortcut.Keys.Esc.code) { 180 if (event.keyCode === UI.KeyboardShortcut.Keys.Esc.code) {
239 event.consume(true); 181 event.consume(true);
240 this.detach(); 182 this.detach();
241 } 183 }
242 } 184 }
243 }; 185 };
244
245
246 /** @type {?Element} */
247 UI.Dialog._previousFocusedElement = null;
248
249 /** @type {?UI.Widget} */
250 UI.Dialog._modalHostView = null;
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698