blob: 9213e8205ae41f935b98ba4fb06f4f605334c88e [file] [log] [blame]
Copybara854996b2021-09-07 19:36:02 +00001/* 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 the Project Hosting to control the display of
10 * elements on the page, rollovers, and popup menus.
11 *
12 * Most of these functions are extracted from dit-display.js
13 */
14
15
16/**
17 * Hide the HTML element with the given ID.
18 * @param {string} id The HTML element ID.
19 * @return {boolean} Always returns false to cancel the browser event
20 * if used as an event handler.
21 */
22function CS_hideID(id) {
23 $(id).style.display = 'none';
24 return false;
25}
26
27
28/**
29 * Show the HTML element with the given ID.
30 * @param {string} id The HTML element ID.
31 * @return {boolean} Always returns false to cancel the browser event
32 * if used as an event handler.
33 */
34function CS_showID(id) {
35 $(id).style.display = '';
36 return false;
37}
38
39
40/**
41 * Hide the given HTML element.
42 * @param {Element} el The HTML element.
43 * @return {boolean} Always returns false to cancel the browser event
44 * if used as an event handler.
45 */
46function CS_hideEl(el) {
47 el.style.display = 'none';
48 return false;
49}
50
51
52/**
53 * Show the given HTML element.
54 * @param {Element} el The HTML element.
55 * @return {boolean} Always returns false to cancel the browser event
56 * if used as an event handler.
57 */
58function CS_showEl(el) {
59 el.style.display = '';
60 return false;
61}
62
63
64/**
65 * Show one element instead of another. That is to say, show a new element and
66 * hide an old one. Usually the element is the element that the user clicked
67 * on with the intention of "expanding it" to access the new element.
68 * @param {string} newID The ID of the HTML element to show.
69 * @param {Element} oldEl The HTML element to hide.
70 * @return {boolean} Always returns false to cancel the browser event
71 * if used as an event handler.
72 */
73function CS_showInstead(newID, oldEl) {
74 $(newID).style.display = '';
75 oldEl.style.display = 'none';
76 return false;
77}
78
79/**
80 * Toggle the open/closed state of a section of the page. As a result, CSS
81 * rules will make certain elements displayed and other elements hidden. The
82 * section is some HTML element that encloses the element that the user clicked
83 * on.
84 * @param {Element} el The element that the user clicked on.
85 * @return {boolean} Always returns false to cancel the browser event
86 * if used as an event handler.
87 */
88function CS_toggleHidden(el) {
89 while (el) {
90 if (el.classList.contains('closed')) {
91 el.classList.remove('closed');
92 el.classList.add('opened');
93 return false;
94 }
95 if (el.classList.contains('opened')) {
96 el.classList.remove('opened');
97 el.classList.add('closed');
98 return false;
99 }
100 el = el.parentNode;
101 }
102}
103
104
105/**
106 * Toggle the expand/collapse state of a section of the page. As a result, CSS
107 * rules will make certain elements displayed and other elements hidden. The
108 * section is some HTML element that encloses the element that the user clicked
109 * on.
110 * TODO(jrobbins): eliminate redundancy with function above.
111 * @param {Element} el The element that the user clicked on.
112 * @return {boolean} Always returns false to cancel the browser event
113 * if used as an event handler.
114 */
115function CS_toggleCollapse(el) {
116 while (el) {
117 if (el.classList.contains('collapse')) {
118 el.classList.remove('collapse');
119 el.classList.add('expand');
120 return false;
121 }
122 if (el.classList.contains('expand')) {
123 el.classList.remove('expand');
124 el.classList.add('collapse');
125 return false;
126 }
127 el = el.parentNode;
128 }
129}
130
131
132/**
133 * Register a function for mouse clicks on the results table. We
134 * listen on the table to avoid adding 1000 individual listeners on
135 * the cells. This is needed because some browsers (now including
136 * Chrome) do not generate click events for mouse buttons other than
137 * the primary mouse button. Chrome and Firefox generate auxclick
138 * events, but Edge does not.
139 */
140
141function CS_addClickListener(tableEl, handler) {
142 function maybeClick(event) {
143 const target = getTargetFromEvent(event);
144
145 const inLink = target.tagName == 'A' || target.parentNode.tagName == 'A';
146
147 if (inLink && !target.classList.contains('computehref')) {
148 // The <a> elements already have the correct hrefs.
149 return;
150 }
151 if (event.button == 2) {
152 // User is trying to open a context menu, not trying to navigate.
153 return;
154 }
155
156 let td = target;
157 while (td && td.tagName != 'TD' && td.tagName != 'TH') {
158 td = td.parentNode;
159 }
160 if (td.classList.contains('rowwidgets')) {
161 // User clicked on a checkbox.
162 return;
163 }
164 // User clicked on an issue ID link or text or cell.
165 event.preventDefault();
166 handler(event);
167 }
168 tableEl.addEventListener('click', maybeClick);
169 tableEl.addEventListener('auxclick', maybeClick);
170}
171
172function getTargetFromEvent(event) {
173 let target = event.target || event.srcElement;
174 if (target.shadowRoot) {
175 // Find the element within the shadowDOM.
176 const path = event.path || event.composedPath();
177 target = path[0];
178 }
179 return target;
180}
181
182
183// Exports
184_hideID = CS_hideID;
185_showID = CS_showID;
186_hideEl = CS_hideEl;
187_showEl = CS_showEl;
188_showInstead = CS_showInstead;
189_toggleHidden = CS_toggleHidden;
190_toggleCollapse = CS_toggleCollapse;
191_addClickListener = CS_addClickListener;