]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/web/js/dojo/openils/BibTemplate.js
LP2042879 Shelving Location Groups Admin accessibility
[working/Evergreen.git] / Open-ILS / web / js / dojo / openils / BibTemplate.js
1 /* ---------------------------------------------------------------------------
2  * Copyright (C) 2009  Equinox Software, Inc.
3  * Mike Rylander <miker@esilibrary.com>
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  * ---------------------------------------------------------------------------
15  */
16
17 if(!dojo._hasResource["openils.BibTemplate"]) {
18
19     dojo.require('DojoSRF');
20     dojo.require('dojox.xml.parser');
21     dojo.require('dojo.string');
22     dojo._hasResource["openils.BibTemplate"] = true;
23     dojo.provide("openils.BibTemplate");
24     dojo.declare('openils.BibTemplate', null, {
25
26         constructor : function(kwargs) {
27             this.root = kwargs.root;
28             this.subObjectLimit = kwargs.subObjectLimit;
29             this.subObjectOffset = kwargs.subObjectOffset;
30             this.tagURI = kwargs.tagURI;
31             this.xml = kwargs.xml;
32             this.record = kwargs.record;
33             this.org_unit = kwargs.org_unit || '-';
34             this.depth = kwargs.depth;
35             this.sync = kwargs.sync == true;
36             this.locale = kwargs.locale || OpenSRF.locale || 'en-US';
37             this.nodelay = kwargs.delay == false;
38
39             if (this.xml && this.xml instanceof String)
40                 this.xml = dojox.xml.parser.parse(this.xml);
41
42             this.mode = 'biblio-record_entry';
43             this.default_datatype = 'marcxml-uris';
44             if (kwargs.metarecord) {
45                 this.record = kwargs.metarecord;
46                 this.mode = 'metabib-metarecord';
47                 this.default_datatype = 'mods';
48             }
49
50             if (this.nodelay) this.render();
51         },
52
53         subsetNL : function (old_nl, start, end) {
54             var new_nl = new dojo.NodeList();
55             for (var i = start; i < end && i < old_nl.length; i++) {
56                 new_nl.push(old_nl[i]);
57             }
58             return new_nl;
59         },
60
61         textContent : function (node) {
62             var content = '';
63             if (node) {
64                 if(window.ActiveXObject) content = node.text;
65                 else content = node.textContent;
66             }
67             return content;
68         },
69
70         render : function() {
71
72             var all_slots = dojo.query('*[type^="opac/slot-data"]', this.root);
73             var default_datatype = this.default_datatype;
74         
75             var slots = {};
76             dojo.forEach(all_slots, function(s){
77                 // marcxml-uris does not include copies, which avoids timeouts
78                 // with bib records that have hundreds or thousands of copies
79                 var current_datatype = default_datatype;
80         
81                 if (s.getAttribute('datatype')) {
82                     current_datatype = s.getAttribute('datatype');
83                 } else if (s.getAttribute('type').indexOf('+') > -1)  {
84                     current_datatype = s.getAttribute('type').split('+').reverse()[0];
85                 }
86
87                 if (!slots[current_datatype]) slots[current_datatype] = [];
88                 slots[current_datatype].push(s);
89
90             });
91         
92             for (var datatype in slots) {
93
94                 (function (args) {
95                     var BT = args.renderer;
96                     var process_record = function (bib) {
97                         dojo.forEach(args.slot_list, function (slot) {
98                             var debug = slot.getAttribute('debug') == 'true';
99
100                             try {
101                                 var joiner = slot.getAttribute('join') || ' ';
102                                 var item_limit = parseInt(slot.getAttribute('limit'));
103                                 var item_offset = parseInt(slot.getAttribute('offset')) || 0;
104
105                                 var pre_render_callbacks = dojo.query( '*[type="opac/call-back+pre-render"]', slot );
106                                 var post_render_callbacks = dojo.query( '*[type="opac/call-back+post-render"]', slot );
107                                 var pre_query_callbacks = dojo.query( '*[type="opac/call-back+pre-query"]', slot );
108                                 var post_query_callbacks = dojo.query( '*[type="opac/call-back+post-query"]', slot );
109
110                                 // Do pre-query stuff
111                                 dojo.forEach(pre_query_callbacks, function (cb) {
112                                     try { (new Function( 'BT', 'slotXML', 'slot', decodeURIComponent(cb.innerHTML) ))(BT,bib,slot) } catch (e) {/*meh*/}
113                                 });
114
115                                 var query = slot.getAttribute('query');
116                                 var xml_root = bib.documentElement || bib;
117
118                                 // Opera (as of 11.01) fails with quotes in queries
119                                 if (dojo.isOpera) query = query.replace(/"|'/g, '');
120
121                                 var item_list = dojo.query(
122                                     query,
123                                     xml_root // Make Opera work by querying from the root element
124                                 );
125
126                                 if (item_limit) {
127                                     if (debug) alert('BibTemplate debug -- item list limit/offset requested: ' + item_limit + '/' + item_offset);
128                                     if (item_list.length) item_list = BT.subsetNL(item_list, item_offset, item_offset + item_limit);
129                                 }
130
131                                 // Do post-query stuff
132                                 dojo.forEach(post_query_callbacks, function (cb) {
133                                     try { (new Function( 'item_list', 'BT', 'slotXML', 'slot', decodeURIComponent(cb.innerHTML) ))(item_list,BT,bib,slot) } catch (e) {/*meh*/}
134                                 });
135
136                                 if (!item_list.length) return;
137
138                                 // Do pre-render stuff
139                                 dojo.forEach(pre_render_callbacks, function (cb) {
140                                     try { (new Function( 'item_list', 'BT', 'slotXML', 'slot', decodeURIComponent(cb.innerHTML) ))(item_list,BT,bib,slot) } catch (e) {/*meh*/}
141                                 });
142
143                                 var templated = slot.getAttribute('templated') == 'true';
144                                 if (debug) alert('BibTemplate debug -- slot ' + (templated ? 'is' : 'is not') + ' templated');
145                                 if (templated) {
146                                     if (debug) alert('BibTemplate debug -- slot template innerHTML:\n' + slot.innerHTML);
147                                     var template_values = {};
148                                     var template_value_count = 0;
149
150                                     dojo.query(
151                                         '*[type="opac/template-value"]',
152                                         slot
153                                     ).orphan().forEach(function(x) {
154                                         var name = x.getAttribute('name');
155                                         var value = (new Function( 'item_list', 'BT', 'slotXML', 'slot', decodeURIComponent(x.innerHTML) ))(item_list,BT,bib,slot);
156                                         if (name && (value || value == '')) {
157                                             template_values[name] = value;
158                                             template_value_count++;
159                                         }
160                                     });
161
162                                     if (debug) alert('BibTemplate debug -- template values:\n' + dojo.toJson( template_values ));
163                                     if (template_value_count > 0) {
164                                         dojo.attr(
165                                             slot, "innerHTML",
166                                             dojo.string.substitute(
167                                                 decodeURIComponent(slot.innerHTML),
168                                                 template_values
169                                             )
170                                         );
171                                     }
172                                 }
173
174                                 var handler_node = dojo.query( '*[type="opac/slot-format"]', slot )[0];
175                                 if (handler_node) slot_handler = new Function('item_list', 'BT', 'slotXML', 'slot', 'item', dojox.xml.parser.textContent(handler_node) || handler_node.innerHTML);
176                                 else slot_handler = new Function('item_list', 'BT', 'slotXML', 'slot', 'item','return dojox.xml.parser.textContent(item) || item.innerHTML;');
177
178                                 if (item_list.length) {
179                                     var content = dojo.map(item_list, dojo.partial(slot_handler,item_list,BT,bib,slot)).join(joiner);
180                                     if (templated) {
181                                         if (handler_node) handler_node.parentNode.replaceChild( dojo.doc.createTextNode( content ), handler_node );
182                                     } else {
183                                         dojo.attr(slot, "innerHTML", content);
184                                     }
185                                 }
186
187                                 delete(slot_handler);
188
189                                 // Do post-render stuff
190                                 dojo.forEach(post_render_callbacks, function (cb) {
191                                     try { (new Function( 'item_list', 'BT', 'slotXML', 'slot', decodeURIComponent(cb.innerHTML) ))(item_list,BT,bib,slot) } catch (e) {/*meh*/}
192                                 });
193
194                             } catch (e) {
195                                 if (debug) {
196                                     alert('BibTemplate Error: ' + e + '\n' + dojo.toJson(e));
197                                     throw(e);
198                                 }
199                             }
200                         });
201                     };
202
203                     if (BT.xml) {
204                         process_record(BT.xml);
205                     } else {
206                         var uri = '';
207                         if (BT.tagURI) {
208                             uri = BT.tagURI;
209                         } else {
210                             uri = 'tag:evergreen-opac:' + BT.mode + '/' + BT.record;
211                             if (BT.subObjectLimit) {
212                                 uri += '[' + BT.subObjectLimit;
213                                 if (BT.subObjectOffset)
214                                     uri += ',' + BT.subObjectOffset;
215                                 uri += ']';
216                             }
217                             uri += '/' + BT.org_unit;
218                             if (BT.depth || BT.depth == '0') uri += '/' + BT.depth;
219                         }
220
221                         dojo.xhrGet({
222                             url: '/opac/extras/unapi?id=' + uri + '&format=' + args.dtype + '&locale=' + BT.locale,
223                             handleAs: 'xml',
224                             sync: BT.sync,
225                             preventCache: true,
226                             load: process_record
227                         });
228                     }
229
230                 })({ slot_list : slots[datatype].reverse(), dtype : datatype, renderer : this });
231             
232             }
233
234             return true;
235
236         }
237     });
238
239     dojo._hasResource["openils.FeedTemplate"] = true;
240     dojo.provide("openils.FeedTemplate");
241     dojo.declare('openils.FeedTemplate', null, {
242
243         constructor : function(kwargs) {
244             this.place = kwargs.place;
245             this.empty = kwargs.empty;
246             this.root = kwargs.root;
247             this.xml = kwargs.xml;
248             this.feed_uri = kwargs.uri;
249             this.item_query = kwargs.query;
250             this.sync = kwargs.sync == true;
251             this.preventCache = kwargs.preventCache == true;
252             this.nodelay = kwargs.delay == false;
253             this.reverseSort = kwargs.reverseSort == true;
254             this.relativePosition = 'last';
255             if (this.reverseSort) this.relativePosition = 'first';
256
257             this.horizon = new Date().getTime();
258             var horiz = parseInt(this.root.getAttribute('horizon'));
259
260             if (isNaN(horiz) || this.horizon >= horiz) 
261                 this.root.setAttribute('horizon', this.horizon);
262
263             if (this.nodelay) this.render();
264         },
265
266         render : function () {
267             var me = this;
268
269             var process_feed = function (xmldoc) {
270                 if (parseInt(me.horizon) >= parseInt(me.root.getAttribute('horizon'))) {
271                     if (me.empty == true) dojo.empty(me.place);
272                     me.root.setAttribute('horizon', this.horizon);
273                     dojo.query( me.item_query, xmldoc ).forEach(
274                         function (item) {
275                             var template = me.root.cloneNode(true);
276                             dojo.place( template, me.place, me.relativePosition );
277                             new openils.BibTemplate({ delay : false, xml : item, root : template });
278                         }
279                     );
280                 }
281             };
282
283             if (this.xml) {
284                 process_feed(this.xml);
285             } else {
286                 dojo.xhrGet({
287                     url: me.feed_uri,
288                     handleAs: 'xml',
289                     sync: me.sync,
290                     preventCache: me.preventCache,
291                     load: process_feed
292                 });
293             }
294
295         }
296     });
297 }