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