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

Side by Side Diff: appengine/monorail/static/js/tracker/tracker-display.js

Issue 1868553004: Open Source Monorail (Closed) Base URL: https://chromium.googlesource.com/infra/infra.git@master
Patch Set: Rebase Created 4 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
(Empty)
1 /* Copyright 2016 The Chromium Authors. All Rights Reserved.
2 *
3 * Use of this source code is governed by a BSD-style
4 * license that can be found in the LICENSE file or at
5 * https://developers.google.com/open-source/licenses/bsd
6 */
7
8 /**
9 * Functions used by Monorail to control the display of elements on
10 * the page, rollovers, and popup menus.
11 *
12 */
13
14
15 /**
16 * Show a popup menu below a specified element. Optional x and y deltas can be
17 * used to fine-tune placement.
18 * @param {string} id The HTML id of the popup menu.
19 * @param {Element} el The HTML element that the popup should appear near.
20 * @param {number} opt_deltaX Optional X offset to finetune placement.
21 * @param {number} opt_deltaY Optional Y offset to finetune placement.
22 * @param {Element} opt_menuButton The HTML element for a menu button that
23 * was pressed to open the menu. When a button was used, we need to ignore
24 * the first "click" event, otherwise the menu will immediately close.
25 * @returns Always returns false to indicate that the browser should handle the
26 * event normally.
27 */
28 function TKR_showBelow(id, el, opt_deltaX, opt_deltaY, opt_menuButton) {
29 var popupDiv = $(id);
30 var elBounds = nodeBounds(el)
31 var startX = elBounds.x;
32 var startY = elBounds.y + elBounds.h;
33 if (BR_IsIE()) {
34 startX -= 1;
35 startY -= 2;
36 }
37 if (BR_IsSafari()) {
38 startX += 1;
39 }
40 popupDiv.style.display = 'block'; //needed so that offsetWidth != 0
41
42 popupDiv.style.left = '-2000px';
43 if (id == 'pop_dot' || id == 'redoMenu') {
44 startX = startX - popupDiv.offsetWidth + el.offsetWidth;
45 }
46 if (opt_deltaX) startX += opt_deltaX;
47 if (opt_deltaY) startY += opt_deltaY;
48 popupDiv.style.left = (startX)+'px';
49 popupDiv.style.top = (startY)+'px';
50 var popup = new TKR_MyPopup(popupDiv, opt_menuButton);
51 popup.show();
52 return false;
53 }
54
55
56 /**
57 * Show a popup menu to the right of a specified element. If there is not
58 * enough space to the right, then it will open to the left side instead.
59 * Optional x and y deltas can be used to fine-tune placement.
60 * TODO(jrobbins): reduce redundancy with function above.
61 * @param {string} id The HTML id of the popup menu.
62 * @param {Element} el The HTML element that the popup should appear near.
63 * @param {number} opt_deltaX Optional X offset to finetune placement.
64 * @param {number} opt_deltaY Optional Y offset to finetune placement.
65 * @returns Always returns false to indicate that the browser should handle the
66 * event normally.
67 */
68 function TKR_showRight(id, el, opt_deltaX, opt_deltaY) {
69 var popupDiv = $(id);
70 var elBounds = nodeBounds(el);
71 var startX = elBounds.x + elBounds.w;
72 var startY = elBounds.y;
73
74 // Calculate pageSize.w and pageSize.h
75 var docElemWidth = document.documentElement.clientWidth;
76 var docElemHeight = document.documentElement.clientHeight;
77 var pageSize = {
78 w: (window.innerWidth || docElemWidth && docElemWidth > 0 ?
79 docElemWidth : document.body.clientWidth) || 1,
80 h: (window.innerHeight || docElemHeight && docElemHeight > 0 ?
81 docElemHeight : document.body.clientHeight) || 1
82 }
83
84 // We need to make the popupDiv visible in order to capture its width
85 popupDiv.style.display = 'block';
86 var popupDivBounds = nodeBounds(popupDiv);
87
88 // Show popup to the left
89 if (startX + popupDivBounds.w > pageSize.w) {
90 startX = elBounds.x - popupDivBounds.w;
91 if (BR_IsIE()) {
92 startX -= 4;
93 startY -= 2;
94 }
95 if (BR_IsNav()) {
96 startX -= 2;
97 }
98 if (BR_IsSafari()) {
99 startX += -1;
100 }
101
102 // Show popup to the right
103 } else {
104 if (BR_IsIE()) {
105 startY -= 2;
106 }
107 if (BR_IsNav()) {
108 startX += 2;
109 }
110 if (BR_IsSafari()) {
111 startX += 3;
112 }
113 }
114
115 popupDiv.style.left = '-2000px';
116 popupDiv.style.position = 'absolute';
117 if (opt_deltaX) startX += opt_deltaX;
118 if (opt_deltaY) startY += opt_deltaY;
119 popupDiv.style.left = (startX)+'px';
120 popupDiv.style.top = (startY)+'px';
121 var popup = new TKR_MyPopup(popupDiv);
122 popup.show();
123 return false;
124 }
125
126
127 /**
128 * Close the specified popup menu and unregister it with the popup
129 * controller, otherwise old leftover popup instances can mess with
130 * the future display of menus.
131 * @param {string} id The HTML ID of the element to hide.
132 */
133 function TKR_closePopup(id) {
134 var e = $(id);
135 if (e) {
136 for (var i = 0; i < gPopupController.activePopups_.length; ++i) {
137 if (e === gPopupController.activePopups_[i]._div) {
138 var popup = gPopupController.activePopups_[i];
139 popup.hide();
140 gPopupController.activePopups_.splice(i, 1);
141 return;
142 }
143 }
144 }
145 }
146
147
148 var TKR_allColumnNames = []; // Will be defined in HTML file.
149
150 /**
151 * Close all popup menus. Also, reset the hover state of the menu item that
152 * was selected. The list of popup menu names is computed from the list of
153 * columns specified in the HTML for the issue list page.
154 * @param menuItem {Element} The menu item that the user clicked.
155 * @returns Always returns false to indicate that the browser should handle the
156 * event normally.
157 */
158 function TKR_closeAllPopups(menuItem) {
159 for (var col_index = 0; col_index < TKR_allColumnNames.length; col_index++) {
160 TKR_closePopup('pop_' + col_index);
161 TKR_closePopup('filter_' + col_index);
162 }
163 TKR_closePopup('pop_dot');
164 TKR_closePopup('redoMenu');
165 menuItem.classList.remove('hover');
166 return false;
167 }
168
169
170 /**
171 * Close all the submenus (of which, one may be currently open).
172 * @returns Always returns false to indicate that the browser should handle the
173 * event normally.
174 */
175 function TKR_closeSubmenus() {
176 for (var col_index = 0; col_index < TKR_allColumnNames.length; col_index++) {
177 TKR_closePopup('filter_' + col_index);
178 }
179 return false;
180 }
181
182
183 /**
184 * Find the enclosing HTML element that controls this section of the
185 * page and set it to use CSS class "opened". That will make the
186 * section display in the opened state, regardless of what state is
187 * was in before.
188 * @param {Element} el The HTML element that the user clicked on.
189 * @returns Always returns false to indicate that the browser should handle the
190 * event normally.
191 */
192 function TKR_showHidden(el) {
193 while (el) {
194 if (el.classList.contains('closed')) {
195 el.classList.remove('closed');
196 el.classList.add('opened');
197 return false;
198 }
199 if (el.classList.contains('opened')) {
200 return false;
201 }
202 el = el.parentNode;
203 }
204 }
205
206
207 /**
208 * Toggle the display of a column in the issue list page. That is
209 * done by adding or removing a CSS class of an enclosing HTML
210 * element, and by CSS rules that trigger based on that CSS class.
211 * @param {string} colName The name of the column to toggle,
212 * corresponds to a CSS class.
213 * @returns Always returns false to indicate that the browser should
214 * handle the event normally.
215 */
216 function TKR_toggleColumn(colName) {
217 var controlDiv = $('colcontrol');
218 if (controlDiv.classList.contains(colName)) {
219 controlDiv.classList.remove(colName);
220 }
221 else {
222 controlDiv.classList.add(colName);
223 }
224 return false;
225 }
226
227
228 /**
229 * Toggle the display of a set of rows in the issue list page. That is
230 * done by adding or removing a CSS class of an enclosing HTML
231 * element, and by CSS rules that trigger based on that CSS class.
232 * TODO(jrobbins): actually, this automatically hides the other groups.
233 * @param {string} rowClassName The name of the row group to toggle,
234 * corresponds to a CSS class.
235 * @returns Always returns false to indicate that the browser should
236 * handle the event normally.
237 */
238 function TKR_toggleRows(rowClassName) {
239 var controlDiv = $('colcontrol');
240 controlDiv.classList.add('hide_pri_groups');
241 controlDiv.classList.add('hide_mile_groups');
242 controlDiv.classList.add('hide_stat_groups');
243 TKR_toggleColumn(rowClassName);
244 return false;
245 }
246
247
248 /**
249 * A simple class that can manage the display of a popup menu. Instances
250 * of this class are used by popup_controller.js.
251 * @param {Element} div The div that contains the popup menu.
252 * @param {Element} opt_launcherEl The button that launched the popup menu,
253 * if any.
254 * @constructor
255 */
256 function TKR_MyPopup(div, opt_launcherEl) {
257 this._div = div;
258 this._launcher = opt_launcherEl;
259 this._isVisible = false;
260 }
261
262
263 /**
264 * Show a popup menu. This method registers the popup with popup_controller.
265 */
266 TKR_MyPopup.prototype.show = function() {
267 this._div.style.display = 'block';
268 this._isVisible = true;
269 PC_addPopup(this);
270 }
271
272
273 /**
274 * Show a popup menu. This method is called from the deactive method,
275 * which is called by popup_controller.
276 */
277 TKR_MyPopup.prototype.hide = function() {
278 this._div.style.display = 'none';
279 this._isVisible = false;
280 }
281
282
283 /**
284 * When the popup_controller gets a user click, it calls deactive() on
285 * every active popup to check if the click should close that popup.
286 */
287 TKR_MyPopup.prototype.deactivate = function(e) {
288 if (this._isVisible) {
289 var p = GetMousePosition(e);
290 if (nodeBounds(this._div).contains(p)) {
291 return false; // use clicked on popup, remain visible
292 } else if (this._launcher && nodeBounds(this._launcher).contains(p)) {
293 this._launcher = null;
294 return false; // mouseup element that launched menu, remain visible
295 } else {
296 this.hide();
297 return true; // clicked outside popup, make invisible
298 }
299 } else {
300 return true; // already deactivated, not visible
301 }
302 }
303
304
305 /**
306 * Highlight the issue row on the list page that contains the given
307 * checkbox.
308 * @param {Element} cb The checkbox that the user changed.
309 * @returns Always returns false to indicate that the browser should
310 * handle the event normally.
311 */
312 function TKR_highlightRow(el) {
313 var checked = el.checked;
314 while (el && el.tagName != 'TR') {
315 el = el.parentNode;
316 }
317 if (checked) {
318 el.classList.add('selected');
319 }
320 else {
321 el.classList.remove('selected');
322 }
323 return false;
324 }
325
326
327 /**
328 * Floats the metadata section on the LHS of issue/source detail pages.
329 * It assumes that the metadata <div> has id 'meta-float' and its outer
330 * container 'meta-container'.
331 */
332 function TKR_floatMetadata() {
333 var el = $('meta-float');
334 var container = $('issuemeta');
335
336 window.addEventListener('scroll', function() {
337 TKR_floatVertically(el, container);
338 }, false);
339 }
340
341 /**
342 * Floats the given element vertically within the provided container as user
343 * scrolls up or down the page. It adjusts the width and padding of the parent
344 * element since it sets the 'position' style of the target element to 'fixed'.
345 * @param {Element} el The HTML element to float.
346 * @param {Element} container The container HTML element.
347 */
348 function TKR_floatVertically(el, container) {
349 var elBounds = nodeBounds(el);
350 var containerBounds = nodeBounds(container);
351 var scrollTop = GetScrollTop(window);
352
353 if (!el.style.width) {
354 el.style.width = elBounds.w + 'px';
355 }
356
357 if ((scrollTop > containerBounds.y) &&
358 (scrollTop - containerBounds.y + elBounds.h <=
359 container.style.top + containerBounds.h) &&
360 (GetWindowHeight(window) > elBounds.h)) {
361 if (el.style.position != 'fixed') {
362 el.style.position = 'fixed';
363 el.style.top = '2px';
364 if (BR_IsIE()) {
365 el.parentNode.style.paddingRight = elBounds.w + 2 + 'px';
366 } else {
367 el.parentNode.style.minWidth = elBounds.w + 'px';
368 }
369 }
370 el.style.left = (6 - GetScrollLeft(window)) + 'px';
371 } else if (el.style.position != 'relative') {
372 el.style.position = 'relative';
373 el.style.left = '0';
374 if (BR_IsIE()) {
375 el.parentNode.style.paddingRight = '';
376 }
377 }
378 }
379
380 /**
381 * XMLHTTP object used to remember display preferences on the server.
382 */
383 var TKR_prefsXmlHttp = undefined;
384
385
386 /**
387 * Contact the server to remember a PeopleDetail display preference.
388 * @param {string} projectName The name of the current project.
389 * @param {number} expand Zero or one for the widget hide/show state.
390 * @param {string} token The security token.
391 */
392 function TKR_setPeoplePrefs(projectName, expand, token) {
393 TKR_prefsXmlHttp = XH_XmlHttpCreate()
394 var prefsURL = '/p/' + projectName + '/people/detailPrefs.do';
395 var data = 'perms_expanded=' + expand + '&token=' + token;
396 XH_XmlHttpPOST(
397 TKR_prefsXmlHttp, prefsURL, data, TKR_prefsFeedCallback);
398 }
399
400
401 /**
402 * The communication with the server has made some progress. If it is
403 * done, then process the response.
404 */
405 function TKR_prefsFeedCallback() {
406 // Actually, we don't use the return value at all, so do nothing.
407 }
OLDNEW
« no previous file with comments | « appengine/monorail/static/js/tracker/tracker-components.js ('k') | appengine/monorail/static/js/tracker/tracker-editing.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698