- attachment:breadcrumb.js of BreadCrumbs
Attachment 'breadcrumb.js'
Download 1 // This is the javascript code for the Roundup breadcrumb feature.
2 //
3 // The localStorage object is used to store breadcrumb data. There are
4 // 3 objects stored there:
5 // max_breadcrumbs - a number which is the upper bound on the number
6 // of visible breadcrumbs.
7 //
8 // multi_tracker - 'on' or 'off'. Indicates whether the breadcrumbs
9 // are for one tracker or are for multiple trackers.
10 //
11 // breadcrumb - holds the breadcrumb detail.
12
13 // The breadcrumb localStorage object is a dict (a.k.a. hash table,
14 // a.k.a. associative array). The key is the tracker name and the
15 // value is an array of [issue, title, location_data] triples. The
16 // issue is used to formulate a link, the title is the hover text, and
17 // the location is used to make breadcrumbs work on more than one
18 // tracker. The hover text can be changed to another issue field. If
19 // the key to breadcrumb is 'multi' then the same triple is used but
20 // the value can be for more than one tracker. When a tracker's
21 // breadcrumb is modified, the breadcrumb for 'multi' is also
22 // modified. This way if one switches from multi-tracker to not or
23 // vice versa, the breadcrumb data is consistent.
24
25 // Name of field whose value is displayed as a tooltip.
26 var hover_text_field_name = 'title';
27 // To specify another field, put something like the following in
28 // html/page.html after the 'import' of this file:
29 // <script type="text/javascript">
30 // var hover_text_field_name = 'some other field';
31 // </script>
32 // To determine fields, view the page source while looking at an issue
33 // and do a backwards page search for 'name=' (without the quotes).
34 // Ignore the hidden entries and names that start with an @ sign.
35
36 // The previous version had an array of issue #s. Another earlier
37 // version was an array of (issue, title, location_data) triples.
38 // This version has a has a hash table where keys are tracker names,
39 // or 'multi', and the values are arrays of (issue, title,
40 // location_data) triples. The following code will convert the old
41 // ways of recording issues to the new way. A title of '' causes
42 // nothing to be displayed in the 'hover' text.
43 if (localStorage.breadcrumb) {
44 var bc = JSON.parse(localStorage.breadcrumb);
45 var all_bcs, ele0, issue;
46 var tracker = location.pathname.split('/')[1];
47 var loc = {protocol: location.protocol, host: location.host, pathname: location.pathname};
48 if (Array.isArray(bc)) {
49 ele0 = bc[0];
50 if (typeof ele0 == 'string' || ele0 instanceof String) {
51 // this is an issue number, expressed as a string.
52 for (var i in bc) {
53 issue = bc[i];
54 bc[i] = [issue, '', loc];
55 }
56 // Can not use assoc array literal because it treats tracker as 'tracker'.
57 all_bcs = {'multi': bc};
58 all_bcs[tracker] = bc;
59 localStorage.breadcrumb = JSON.stringify(all_bcs);
60 } else if (Array.isArray(ele0)) {
61 var j = 0;
62 for (var i in bc) {
63 issue = bc[i][0];
64 title = bc[i][1];
65 loc = bc[i][2];
66 if (issue != null && issue.search(/^\d+$/) != -1) {
67 // Some breadcrumb entries have trash: missing or null issue #.
68 bc[j++] = [issue, title, loc];
69 }
70 }
71 all_bcs = {'multi': bc};
72 all_bcs[tracker] = bc;
73 localStorage.breadcrumb = JSON.stringify(all_bcs);
74 }
75 }
76 }
77
78
79 function initialize_localStorage() {
80 var max = localStorage.max_breadcrumbs;
81 if (max == null) {
82 max = '8';
83 localStorage.max_breadcrumbs = max;
84 }
85
86 var mt = localStorage.multi_tracker;
87 if (mt == null) {
88 mt = 'off';
89 localStorage.multi_tracker = mt;
90 }
91 }
92
93 function bindEventToNavigation(){
94 var paths = location.pathname.split('/');
95 var title = '';
96 var tracker = location.pathname.split('/')[1];
97 initialize_localStorage();
98 if (paths.length >= 3) {
99 // Looking for issue12345.
100 var klassitem = paths[2];
101 var titles = document.getElementsByName(hover_text_field_name);
102 if (titles.length > 0) {
103 title = titles[0].value;
104 }
105 if (klassitem.startsWith('issue')) {
106 issue = klassitem.slice(5);
107 if (issue.search(/^\d+$/) != -1) {
108 // Issue must contain only digits.
109 addBreadCrumb(tracker, issue, title);
110 addBreadCrumb('multi', issue, title);
111 }
112 }
113 }
114 showBreadCrumb();
115 }
116
117 window.onload = bindEventToNavigation;
118
119 // Add issue to the front of the breadcrumbs.
120 function addBreadCrumb(tracker, issue, title) {
121 var all_bcs = {};
122 var raw_bc = localStorage.breadcrumb;
123 var bc = []
124 var loc = {protocol: location.protocol, host: location.host, pathname: location.pathname};
125 if (raw_bc) {
126 all_bcs = JSON.parse(raw_bc);
127 bc = all_bcs[tracker];
128 if (bc) {
129 if (bc.find((val) => val[0] == issue)) {
130 // Remove issue and put at the front.
131 bc = [[issue, title, loc]].concat(bc.filter((val) => issue != val[0]));
132 } else if (bc.length >= localStorage.max_breadcrumbs) {
133 // Lop off the last element and put issue at the front.
134 bc = [[issue, title, loc]].concat(bc.slice(0, localStorage.max_breadcrumbs - 1));
135 } else {
136 // Plenty of room for the new issue.
137 bc = [[issue, title, loc]].concat(bc);
138 }
139 } else {
140 // First issue
141 bc = [[issue, title, loc]];
142 }
143 } else {
144 // First issue
145 bc = [[issue, title, loc]];
146 }
147 all_bcs[tracker] = bc;
148
149 localStorage.breadcrumb = JSON.stringify(all_bcs);
150 }
151
152 function showBreadCrumb(){
153 var tracker, bc, all_bcs;
154 var raw_bc = localStorage.breadcrumb;
155 var html = "";
156 if (localStorage.multi_tracker == 'on') {
157 tracker = 'multi';
158 } else {
159 tracker = location.pathname.split('/')[1];
160 }
161
162 if (raw_bc) {
163 var all_bcs = JSON.parse(raw_bc);
164 if (tracker in all_bcs) {
165 bc = all_bcs[tracker];
166 } else {
167 bc = {};
168 }
169 // alert('showBreadCrumb: bc=' + bc + ', bc.length=' + bc.length);
170 var front, tracker, issue, title, loc;
171 for (var i in bc) {
172 issue = bc[i][0];
173 title = bc[i][1];
174 if (bc[i].length > 2) {
175 // Have location detail here.
176 loc = bc[i][2];
177 } else {
178 loc = location;
179 }
180 tracker = loc.pathname.split('/')[1];
181 if (tracker != location.pathname.split('/')[1]) {
182 // If jumping to another tracker, indicate that.
183 // Scoot it to the right so the mouse doesn't cover it up.
184 title = ' ' + tracker + ': ' + title;
185 }
186 front = loc.protocol + "//" + loc.host + "/" + tracker;
187 html = html + ("<a href='" + front + "/issue" + issue
188 + "' title='" + title.replace("'", "`")
189 + "'>" + issue + "</a> ");
190 }
191 }
192 // alert('showBreadCrumb: html=' + html);
193 document.getElementById('breadcrumb').innerHTML = html;
194 }
195
196 // Code to display the list of fields in item.issue.html.
197 // It may be useful when deciding what to put in hover_text_field_name.
198 // Return array of INPUT element names.
199 function get_issue_field_names() {
200 var inputs = document.getElementsByTagName('INPUT');
201 var names = [];
202 var name;
203 for (var i in inputs) {
204 if (i.search(/^\d+$/) != -1) {
205 name = inputs[i].name;
206 if (name == null || name.length <= 0 || name[0] == '@') {
207 continue;
208 }
209 if (name.search(/^submit/) == -1) {
210 names.push(name);
211 }
212 }
213 }
214 var selects = document.getElementsByTagName('SELECT');
215 var sel;
216 for (var i in selects) {
217 if (i.search(/^\d+$/) != -1) {
218 sel = selects[i];
219 names.push(sel.name);
220 }
221 }
222
223 return [...new Set(names)].sort();
224 }
225
226 // localStorage.removeItem('breadcrumb')
227
Attached Files
To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.You are not allowed to attach a file to this page.