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

Side by Side Diff: third_party/WebKit/Source/devtools/front_end/ui/GlassPane.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
(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 UI.GlassPane = class {
6 /**
7 * @param {!Document} document
8 * @param {boolean} dimmed
9 * @param {boolean} blockPointerEvents
10 * @param {function(!Event)} onClickOutside
11 */
12 constructor(document, dimmed, blockPointerEvents, onClickOutside) {
13 this._element = createElementWithClass('div', 'glass-pane');
14 this._element.style.backgroundColor = dimmed ? 'rgba(255, 255, 255, 0.5)' : 'transparent';
15 if (!blockPointerEvents)
16 this._element.style.pointerEvents = 'none';
17 this._onMouseDown = event => {
18 if (!this.contentElement.isSelfOrAncestor(/** @type {?Node} */ (event.targ et)))
19 onClickOutside.call(null, event);
20 };
21
22 this.contentElement = this._element.createChild('div', 'glass-pane-content') ;
23 this._document = document;
24 this._visible = false;
25 /** @type {?UI.Size} */
26 this._maxSize = null;
27 /** @type {?number} */
28 this._positionX = null;
29 /** @type {?number} */
30 this._positionY = null;
31 /** @type {?AnchorBox} */
32 this._anchorBox = null;
33 this._anchorBehavior = UI.GlassPane.AnchorBehavior.PreferTop;
34 }
35
36 /**
37 * @param {?UI.Size} size
38 */
39 setMaxContentSize(size) {
40 this._maxSize = size;
41 this._positionContent();
42 }
43
44 /**
45 * @param {?number} x
46 * @param {?number} y
47 * Position is relative to root element.
48 */
49 setContentPosition(x, y) {
50 this._positionX = x;
51 this._positionY = y;
52 this._positionContent();
53 }
54
55 /**
56 * @param {?AnchorBox} anchorBox
57 * Anchor box is relative to the document.
58 */
59 setContentAnchorBox(anchorBox) {
60 this._anchorBox = anchorBox;
61 this._positionContent();
62 }
63
64 /**
65 * @param {!UI.GlassPane.AnchorBehavior} behavior
66 */
67 setAnchorBehavior(behavior) {
68 this._anchorBehavior = behavior;
69 }
70
71 show() {
72 if (this._visible)
73 return;
74 this._visible = true;
75 // Deliberately starts with 3000 to hide other z-indexed elements below.
76 this._element.style.zIndex = 3000 + 1000 * UI.GlassPane._panes.size;
77 this._document.body.appendChild(this._element);
78 this._document.body.addEventListener('mousedown', this._onMouseDown, true);
79 UI.GlassPane._panes.add(this);
80 }
81
82 hide() {
83 if (!this._visible)
84 return;
85 UI.GlassPane._panes.delete(this);
86 this._document.body.removeEventListener('mousedown', this._onMouseDown, true );
87 this._document.body.removeChild(this._element);
88 this._visible = false;
89 }
90
91 /**
92 * @return {boolean}
93 */
94 visible() {
95 return this._visible;
96 }
97
98 _positionContent() {
99 if (!this._visible)
100 return;
101
102 var gutterSize = 5;
103 var container = UI.GlassPane._containers.get(this._document);
104 var containerWidth = container.offsetWidth;
105 var containerHeight = container.offsetHeight;
106
107 var width = containerWidth - gutterSize * 2;
108 var height = containerHeight - gutterSize * 2;
109 var positionX = gutterSize;
110 var positionY = gutterSize;
111
112 if (this._maxSize) {
113 width = Math.min(width, this._maxSize.width);
114 height = Math.min(height, this._maxSize.height);
115 }
116
117 if (this._anchorBox) {
118 var anchorBox = this._anchorBox.relativeToElement(container);
119 var behavior = this._anchorBehavior;
120
121 if (behavior === UI.GlassPane.AnchorBehavior.PreferTop || behavior === UI. GlassPane.AnchorBehavior.PreferBottom) {
122 var top = anchorBox.y - gutterSize;
123 var bottom = containerHeight - anchorBox.y - anchorBox.height - gutterSi ze;
124 if (behavior === UI.GlassPane.AnchorBehavior.PreferTop && top < height & & bottom >= height)
125 behavior = UI.GlassPane.AnchorBehavior.PreferBottom;
126 if (behavior === UI.GlassPane.AnchorBehavior.PreferBottom && bottom < he ight && top >= height)
127 behavior = UI.GlassPane.AnchorBehavior.PreferTop;
128
129 positionX = Math.max(gutterSize, Math.min(anchorBox.x, containerWidth - width - gutterSize));
130 width = Math.min(width, containerWidth - positionX - gutterSize);
131 if (behavior === UI.GlassPane.AnchorBehavior.PreferTop) {
132 positionY = Math.max(gutterSize, anchorBox.y - height);
133 height = Math.min(height, anchorBox.y - positionY);
134 } else {
135 positionY = anchorBox.y + anchorBox.height;
136 height = Math.min(height, containerHeight - positionY - gutterSize);
137 }
138 } else {
139 var left = anchorBox.x - gutterSize;
140 var right = containerWidth - anchorBox.x - anchorBox.width - gutterSize;
141 if (behavior === UI.GlassPane.AnchorBehavior.PreferLeft && left < width && right >= width)
142 behavior = UI.GlassPane.AnchorBehavior.PreferRight;
143 if (behavior === UI.GlassPane.AnchorBehavior.PreferRight && right < widt h && left >= width)
144 behavior = UI.GlassPane.AnchorBehavior.PreferLeft;
145
146 positionY = Math.max(gutterSize, Math.min(anchorBox.y, containerHeight - height - gutterSize));
147 height = Math.min(height, containerHeight - positionY - gutterSize);
148 if (behavior === UI.GlassPane.AnchorBehavior.PreferLeft) {
149 positionX = Math.max(gutterSize, anchorBox.x - width);
150 width = Math.min(width, anchorBox.x - positionX);
151 } else {
152 positionX = anchorBox.x + anchorBox.width;
153 width = Math.min(width, containerWidth - positionX - gutterSize);
154 }
155 }
156 } else {
157 positionX = this._positionX !== null ? this._positionX : (containerWidth - width) / 2;
158 positionY = this._positionY !== null ? this._positionY : (containerHeight - height) / 2;
159 width = Math.min(width, containerWidth - positionX - gutterSize);
160 height = Math.min(height, containerHeight - positionY - gutterSize);
161 }
162
163 this.contentElement.style.width = width + 'px';
164 this.contentElement.style.height = height + 'px';
165 this.contentElement.positionAt(positionX, positionY, container);
166 }
167
168 /**
169 * @param {!Element} element
170 */
171 static setContainer(element) {
172 UI.GlassPane._containers.set(/** @type {!Document} */ (element.ownerDocument ), element);
173 UI.GlassPane.containerMoved(element);
174 }
175
176 /**
177 * @param {!Document} document
178 * @return {!Element}
179 */
180 static container(document) {
181 return UI.GlassPane._containers.get(document);
182 }
183
184 /**
185 * @param {!Element} element
186 */
187 static containerMoved(element) {
188 for (var pane of UI.GlassPane._panes) {
189 if (pane._document === element.ownerDocument)
190 pane._positionContent();
191 }
192 }
193 };
194
195 /**
196 * @enum {symbol}
197 */
198 UI.GlassPane.AnchorBehavior = {
199 PreferTop: Symbol('PreferTop'),
200 PreferBottom: Symbol('PreferBottom'),
201 PreferLeft: Symbol('PreferLeft'),
202 PreferRight: Symbol('PreferRight'),
203 };
204
205 /** @type {!Map<!Document, !Element>} */
206 UI.GlassPane._containers = new Map();
207 /** @type {!Set<!UI.GlassPane>} */
208 UI.GlassPane._panes = new Set();
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698