]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/xul/staff_client/chrome/content/util/widgets.js
liberate this perm-cognizant lib menu generator
[Evergreen.git] / Open-ILS / xul / staff_client / chrome / content / util / widgets.js
1 dump('entering util/widgets.js\n');
2
3 if (typeof util == 'undefined') var util = {};
4 util.widgets = {};
5
6 util.widgets.EXPORT_OK    = [ 
7     'get',
8     'apply',
9     'save_xml',
10     'serialize_node',
11     'xul_from_string',
12     'store_disable',
13     'restore_disable',
14     'disable',
15     'get_list_from_tree_selection',
16     'disable_accesskeys_in_node_and_children', 
17     'enable_accesskeys_in_node_and_children', 
18     'remove_children',
19     'make_grid',
20     'make_menulist',
21     'insertAfter',
22     'apply_vertical_tab_on_enter_handler',
23     'vertical_tab',
24     'click',
25     'dispatch',
26     'stop_event',
27     'set_text',
28     'save_attributes',
29     'load_attributes',
30     'find_descendants_by_name',
31     'render_perm_org_menu'
32 ];
33 util.widgets.EXPORT_TAGS    = { ':all' : util.widgets.EXPORT_OK };
34
35 util.widgets.get = function(e) {
36     if (typeof e == 'object') {
37         return e;
38     } else {
39         return document.getElementById(e);
40     }
41 }
42
43 util.widgets.apply = function(e,attr,attr_value,f) {
44     var node = util.widgets.get(e);
45     var nl = node.getElementsByAttribute(attr,attr_value);
46     for (var i = 0; i < nl.length; i++) {
47         f( nl[i] );
48     }
49 }
50
51 util.widgets.save_xml = function (filename,node) {
52     try { 
53         netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
54
55         JSAN.use('util.file'); var file = new util.file(filename);
56
57         node = util.widgets.get(node);
58         var xml = util.widgets.serialize_node(node);
59
60         file.write_content('truncate',xml);
61         file.close();
62     } catch(E) {
63         alert('Error in util.widgets.save_xml: ' + E);
64     }
65 }
66
67 util.widgets.serialize_node = function(node) {
68     var serializer = new XMLSerializer();
69     var xml = serializer.serializeToString(node);
70     return xml;
71 }
72
73 util.widgets.xul_from_string = function(xml) {
74     var parser = new DOMParser(); 
75     var doc = parser.parseFromString(xml, "text/xml"); 
76     var node = doc.documentElement;
77     return node;
78 }
79
80 util.widgets.store_disable = function() {
81     for (var i = 0; i < arguments.length; i++) {
82         var e = util.widgets.get( arguments[i] );
83         e.setAttribute('_disabled',e.getAttribute('disabled'));
84     }
85 }
86
87 util.widgets.restore_disable = function() {
88     for (var i = 0; i < arguments.length; i++) {
89         var e = util.widgets.get( arguments[i] );
90         e.setAttribute('disabled',e.getAttribute('_disabled'));
91     }
92 }
93
94 util.widgets.disable = function() {
95     for (var i = 0; i < arguments.length; i++) {
96         var e = util.widgets.get( arguments[i] );
97         e.setAttribute('disabled',true);
98     }
99 }
100
101 util.widgets.click = function(e) {
102     var evt = document.createEvent("MouseEvent");
103     evt.initMouseEvent( "click", true, true, window, 0, 0, 0, 0, 0, false,false,false,false,0,null);
104     util.widgets.get(e).dispatchEvent(evt);
105 }
106
107 util.widgets.dispatch = function(ev,el) {
108     var evt = document.createEvent("Events");
109     //var evt = document.createEvent();
110     evt.initEvent( ev, true, true );
111     util.widgets.get(el).dispatchEvent(evt);
112 }
113
114 util.widgets.make_menulist = function( items, dvalue ) {
115     var menulist = document.createElement('menulist');
116     var menupopup = document.createElement('menupopup'); menulist.appendChild(menupopup);
117     for (var i = 0; i < items.length; i++) {
118         if (typeof items[i] == 'undefined') { continue; }
119         var label = items[i][0]; var value = items[i][1]; var disabled = items[i][2]; var indent = items[i][3];
120         if (indent) {
121             for (var j = 0; j < Number(indent); j++) {
122                 //label = ' ' + label;
123             }
124         }
125         var menuitem = document.createElement('menuitem'); menupopup.appendChild(menuitem);
126         menuitem.setAttribute('label',label);
127         menuitem.setAttribute('value',value);
128         if (indent) {
129             menuitem.setAttribute('style','font-family: monospace; padding-left: ' + indent + 'em;');
130         } else {
131             menuitem.setAttribute('style','font-family: monospace;');
132         }
133         if ( (disabled == true) || (disabled == "true") ) {
134             menuitem.disabled = true;
135             menuitem.setAttribute('disabled','true');
136         }
137     }
138     if (typeof dvalue != 'undefined') {
139         menulist.setAttribute('value',dvalue);
140     }
141     return menulist;
142 }
143
144 util.widgets.make_grid = function( cols ) {
145     var grid = document.createElement('grid');
146     var columns = document.createElement('columns'); grid.appendChild(columns);
147     for (var i = 0; i < cols.length; i++) {
148         var column = document.createElement('column'); columns.appendChild(column);
149         for (var j in cols[i]) {
150             column.setAttribute(j,cols[i][j]);
151         }
152     }
153     var rows = document.createElement('rows'); grid.appendChild(rows);
154     return grid;
155 }
156
157 util.widgets.get_list_from_tree_selection = function(tree_w) {
158     var hitlist;
159     var tree = util.widgets.get(tree_w);
160     var list = [];
161     var start = new Object();
162     var end = new Object();
163     var numRanges = tree.view.selection.getRangeCount();
164     for (var t=0; t<numRanges; t++){
165         tree.view.selection.getRangeAt(t,start,end);
166         for (var v=start.value; v<=end.value; v++){
167             var i = tree.contentView.getItemAtIndex(v);
168             list.push( i );
169         }
170     }
171     return list;
172 }
173
174 util.widgets.remove_children = function() {
175     for (var i = 0; i < arguments.length; i++) {
176         var e = util.widgets.get( arguments[i] );
177         while(e.lastChild) e.removeChild( e.lastChild );
178     }
179 }
180
181 util.widgets.disable_accesskeys_in_node_and_children = function( node ) {
182     return; /* what was I doing here? */
183     if (node.getAttribute('accesskey')) {
184         node.setAttribute('oldaccesskey', node.getAttribute('accesskey'));
185         node.setAttribute('accesskey',''); node.accessKey = '';
186     }
187     for (var i = 0; i < node.childNodes.length; i++) {
188         util.widgets.disable_accesskeys_in_node_and_children( node.childNodes[i] );
189     }
190     dump('- node = <' + node.id + '> accesskey = <' + node.accessKey + '> accesskey = <' + node.getAttribute('accesskey') + '> oldaccesskey = <' + node.getAttribute('oldaccesskey') + '>\n');
191 }
192
193 util.widgets.enable_accesskeys_in_node_and_children = function( node ) {
194     return; /* what was I doing here? */
195     if (node.getAttribute('oldaccesskey')) {
196         node.setAttribute('accesskey', node.getAttribute('oldaccesskey'));
197         node.accessKey = node.getAttribute('oldaccesskey'); 
198         node.setAttribute('oldaccesskey','');
199     }
200     for (var i = 0; i < node.childNodes.length; i++) {
201         util.widgets.enable_accesskeys_in_node_and_children( node.childNodes[i] );
202     }
203     dump('+ node = <' + node.id + '> accesskey = <' + node.accessKey + '> accesskey = <' + node.getAttribute('accesskey') + '> oldaccesskey = <' + node.getAttribute('oldaccesskey') + '>\n');
204 }
205
206 util.widgets.insertAfter = function(parent_node,new_node,sibling_node) {
207     sibling_node = sibling_node.nextSibling;
208     if (sibling_node) {
209         parent_node.insertBefore(new_node,sibling_node);
210     } else {
211         parent_node.appendChild(new_node);
212     }
213 }
214
215 util.widgets.apply_vertical_tab_on_enter_handler = function(node,onfailure,no_enter_func) {
216     try {
217         node.addEventListener(
218             'keypress',
219             function(ev) {
220                 dump('keypress: ev.target.tagName = ' + ev.target.tagName 
221                     + ' ev.target.nodeName = ' + ev.target.nodeName 
222                     + ' ev.keyCode = ' + ev.keyCode 
223                     + ' ev.charCode = ' + ev.charCode + '\n');
224                 if (ev.keyCode == 13) {
225                     dump('trying vertical tab\n');
226                     if (util.widgets.vertical_tab(ev.target)) {
227                         ev.preventDefault(); ev.stopPropagation();
228                         return true;
229                     } else {
230                         dump('keypress: attempting onfailure\n');
231                         if (typeof onfailure == 'function') return onfailure(ev);
232                         return false;
233                     }
234                 } else {
235                     if (typeof no_enter_func == 'function') {
236                         if ([
237                                 35 /* end */,
238                                 36 /* home */,
239                                 37 /* left */,
240                                 38 /* up */,
241                                 39 /* right */,
242                                 40 /* down */,
243                                 9 /* tab */
244                             ].indexOf(ev.keyCode) == -1
245                         ) {
246                             // really the no_enter, no_arrow_key, no_tab, etc. func :)
247                             no_enter_func(ev);
248                         }
249                     }
250                 }
251             },
252             false
253         );
254     } catch(E) {
255         alert(E);
256     }
257 }
258
259 util.widgets.vertical_tab = function(node) {
260     try {
261         var rel_vert_pos = node.getAttribute('rel_vert_pos') || 0;
262         dump('vertical_tab -> node = ' + node.nodeName + ' rel_vert_pos = ' + rel_vert_pos + '\n');
263
264         var nl = document.getElementsByTagName( node.nodeName );
265
266         var found_self = false; var next_node; var max_rel_vert_pos = 0;
267         for (var i = 0; i < nl.length; i++) {
268
269             var candidate_node = nl[i];
270             var test_rel_vert_pos = candidate_node.getAttribute('rel_vert_pos') || 0;
271
272             if (found_self && !next_node && (test_rel_vert_pos == rel_vert_pos) && !candidate_node.disabled) {
273             
274                 next_node = candidate_node;
275
276             }
277             if (candidate_node == node) found_self = true;
278
279             if (test_rel_vert_pos > max_rel_vert_pos) max_rel_vert_pos = test_rel_vert_pos;
280         }
281
282         dump('intermediate: next_node = ' + next_node + ' max_rel_vert_pos = ' + max_rel_vert_pos + '\n');
283
284         if (!next_node) {
285
286             found_self = false;
287             for (var next_pos = rel_vert_pos; next_pos <= max_rel_vert_pos; next_pos++) {
288
289                 for (var i = 0; i < nl.length; i++) {
290                     var candidate_node = nl[i];
291                     var test_rel_vert_pos = candidate_node.getAttribute('rel_vert_pos') || 0;
292
293                     if (found_self && !next_node && (test_rel_vert_pos == next_pos) && !candidate_node.disabled ) {
294                         next_node = candidate_node;
295                     }
296
297                     if (candidate_node == node) found_self = true;
298                 }
299
300             }
301
302         }
303
304         if (next_node) {
305             dump('focusing\n');
306             next_node.focus();
307         }
308         return next_node;
309     } catch(E) {
310         alert(E);
311     }
312 }
313
314 util.widgets.stop_event = function(ev) {
315     ev.preventDefault();
316     return false;
317 }
318
319 util.widgets.set_text = function(n,t) {
320     n = util.widgets.get(n);
321     switch(n.nodeName) {
322         case 'button' :
323         case 'caption' :
324             n.setAttribute('label',t);
325         break;
326         case 'label' : 
327             n.setAttribute('value',t); 
328         break;
329         case 'description' : 
330         case 'H1': case 'H2': case 'H3': case 'H4': case 'SPAN': case 'P': case 'BLOCKQUOTE':
331             util.widgets.remove_children(n); 
332             n.appendChild( document.createTextNode(t) );
333         break;
334         case 'textbox' :
335             n.value = t; n.setAttribute('value',t);
336         break;
337         default:
338             alert("FIXME: util.widgets.set_text doesn't know how to handle " + n.nodeName);
339         break;
340     }
341 }
342
343 util.widgets.get_text = function(n) {
344     n = util.widgets.get(n);
345     switch(n.nodeName) {
346         case 'button' :
347         case 'caption' :
348             return n.getAttribute('label');
349         break;
350         case 'label' : 
351             return n.getAttribute('value'); 
352         break;
353         case 'description' : 
354         case 'H1': case 'H2': case 'H3': case 'H4': case 'SPAN': case 'P': case 'BLOCKQUOTE':
355             return n.textContent;
356         break;
357         case 'textbox' :
358             return n.value;
359         break;
360         default:
361             alert("FIXME: util.widgets.get_text doesn't know how to handle " + n.nodeName);
362             return null;
363         break;
364     }
365 }
366
367 util.widgets.save_attributes = function (file,ids_attrs) {
368     try {
369         var blob = {};
370         for (var element_id in ids_attrs) {
371             var attribute_list = ids_attrs[ element_id ];
372             if (! blob[ element_id ] ) blob[ element_id ] =  {};
373             var x = document.getElementById( element_id );
374             if (x) {
375                 for (var j = 0; j < attribute_list.length; j++) {
376                     blob[ element_id ][ attribute_list[j] ] = x.getAttribute( attribute_list[j] );
377                 }
378             } else {
379                 dump('Error in util.widgets.save_attributes('+file._file.path+','+js2JSON(ids_attrs)+'):\n');
380                 dump('\telement_id = ' + element_id + '\n');
381             }
382         }
383         netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
384         //FIXME - WHY DOES THIS NOT WORK?// JSAN.use('util.file'); var file = new util.file(filename);
385         file.set_object(blob); file.close();
386     } catch(E) {
387         alert('Error saving preferences: ' + E);
388     }
389 }
390
391 util.widgets.load_attributes = function (file) {        
392     try {
393         netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
394         //FIXME - WHY DOES THIS NOT WORK?// JSAN.use('util.file'); var file = new util.file(filename);
395         if (file._file.exists()) {
396             var blob = file.get_object(); file.close();
397             for (var element_id in blob) {
398                 for (var attribute in blob[ element_id ]) {
399                     var x = document.getElementById( element_id );
400                     if (x) {
401                         if (x.nodeName == 'menulist' && attribute == 'value') {
402                             var popup = x.firstChild;
403                             var children = popup.childNodes;
404                             for (var i = 0; i < children.length; i++) {
405                                 if (children[i].getAttribute('value') == blob[ element_id ][ attribute ]) {
406                                     dump('setting ' + x.nodeName + ' ' + element_id + ' @value to ' + blob[ element_id ][ attribute ] + '\n' );
407                                     x.setAttribute(attribute, blob[ element_id ][ attribute ]);
408                                 }
409                             }
410                         } else {
411                             dump('setting ' + x.nodeName + ' ' + element_id + ' @value to ' + blob[ element_id ][ attribute ] + '\n');
412                             x.setAttribute(attribute, blob[ element_id ][ attribute ]);
413                         }
414                     } else {
415                         dump('Error in util.widgets.load_attributes('+file._file.path+'):\n');
416                         dump('\telement_id = ' + element_id + '\n');
417                         dump('\tattribute = ' + attribute + '\n');
418                         dump('\tblob[id][attr] = ' + blob[element_id][attribute] + '\n');
419                     }
420                 }
421             }
422             return blob;
423         }
424         return {};
425     } catch(E) {
426         alert('Error loading preferences: ' + E);
427     }
428 }
429
430 util.widgets.addProperty = function(e,c) {
431         if(!e || !c) return;
432
433         var prop_class_string = e.getAttribute('properties');
434         var prop_class_array;
435
436         if(prop_class_string)
437                 prop_class_array = prop_class_string.split(/\s+/);
438
439         var string_ip = ""; /*strip out nulls*/
440         for (var prop_class in prop_class_array) {
441                 if (prop_class_array[prop_class] == c) { return; }
442                 if(prop_class_array[prop_class] !=null)
443                         string_ip += prop_class_array[prop_class] + " ";
444         }
445         string_ip += c;
446         e.setAttribute('properties',string_ip);
447 }
448
449 util.widgets.removeProperty = function(e, c) {
450         if(!e || !c) return;
451
452         var prop_class_string = '';
453
454         var prop_class_array = e.getAttribute('properties');
455         if( prop_class_array )
456                 prop_class_array = prop_class_array.split(/\s+/);
457
458         var first = 1;
459         for (var prop_class in prop_class_array) {
460                 if (prop_class_array[prop_class] != c) {
461                         if (first == 1) {
462                                 prop_class_string = prop_class_array[prop_class];
463                                 first = 0;
464                         } else {
465                                 prop_class_string = prop_class_string + ' ' +
466                                         prop_class_array[prop_class];
467                         }
468                 }
469         }
470         e.setAttribute('properties', prop_class_string);
471 }
472
473 util.widgets.find_descendants_by_name = function(top_node,name) {
474     top_node = util.widgets.get(top_node);
475     if (!top_node) { return []; }
476     return top_node.getElementsByAttribute('name',name);
477 }
478
479 util.widgets.render_perm_org_menu = function (perm,org) {
480     try {
481         JSAN.use('util.functional'); JSAN.use('util.fm_utils');
482         JSAN.use('OpenILS.data'); JSAN.use('util.network');
483         var data = new OpenILS.data(); data.stash_retrieve();
484         var network = new util.network();
485
486         var work_ous = network.simple_request(
487             'PERM_RETRIEVE_WORK_OU',
488             [ ses(), perm]
489         );
490         if (work_ous.length == 0) {
491             return false;
492         }
493
494         var my_libs = [];
495         for (var i = 0; i < work_ous.length; i++ ) {
496             var perm_depth = data.hash.aout[ data.hash.aou[ work_ous[i] ].ou_type() ].depth();
497
498             var my_libs_tree = network.simple_request(
499                 'FM_AOU_DESCENDANTS_RETRIEVE',
500                 [ work_ous[i], perm_depth ]
501             );
502             if (!instanceOf(my_libs_tree,aou)) { /* FIXME - workaround for weird descendants call result */
503                 my_libs_tree = my_libs_tree[0];
504             }
505             my_libs = my_libs.concat( util.fm_utils.flatten_ou_branch( my_libs_tree ) );
506         }
507
508         var default_lib = org || my_libs[0].id();
509
510         var ml = util.widgets.make_menulist(
511             util.functional.map_list(
512                 my_libs,
513                 function(obj) {
514                     return [
515                         obj.shortname() + ' : ' + obj.name(),
516                         obj.id(),
517                         false,
518                         ( data.hash.aout[ obj.ou_type() ].depth() )
519                     ];
520                 }
521             ),
522             default_lib
523         );
524
525         return ml;
526
527     } catch(E) {
528         alert('Error in util.widgets.render_perm_org_menu(): ' + E);
529     }
530 }
531 dump('exiting util/widgets.js\n');