]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/web/js/dojo/openils/BibTemplate.js
minor FeedTemplate bug fixes
[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             if (node) {
63                 if (node instanceof HTMLElement) return node.innerText || node.textContent;
64                 return dojox.xml.parser.textContent(node);
65             }
66             return '';
67         },
68
69         render : function() {
70
71             var all_slots = dojo.query('*[type^="opac/slot-data"]', this.root);
72             var default_datatype = this.default_datatype;
73         
74             var slots = {};
75             dojo.forEach(all_slots, function(s){
76                 // marcxml-uris does not include copies, which avoids timeouts
77                 // with bib records that have hundreds or thousands of copies
78                 var current_datatype = default_datatype;
79         
80                 if (s.getAttribute('datatype')) {
81                     current_datatype = s.getAttribute('datatype');
82                 } else if (s.getAttribute('type').indexOf('+') > -1)  {
83                     current_datatype = s.getAttribute('type').split('+').reverse()[0];
84                 }
85
86                 if (!slots[current_datatype]) slots[current_datatype] = [];
87                 slots[current_datatype].push(s);
88
89             });
90         
91             for (var datatype in slots) {
92
93                 (function (args) {
94                     var BT = args.renderer;
95                     var process_record = function (bib) {
96                         dojo.forEach(args.slot_list, function (slot) {
97                             var debug = slot.getAttribute('debug') == 'true';
98
99                             try {
100                                 var joiner = slot.getAttribute('join') || ' ';
101                                 var item_limit = parseInt(slot.getAttribute('limit'));
102                                 var item_offset = parseInt(slot.getAttribute('offset')) || 0;
103
104                                 var pre_render_callbacks = dojo.query( '*[type="opac/call-back+pre-render"]', slot );
105                                 var post_render_callbacks = dojo.query( '*[type="opac/call-back+post-render"]', slot );
106                                 var pre_query_callbacks = dojo.query( '*[type="opac/call-back+pre-query"]', slot );
107                                 var post_query_callbacks = dojo.query( '*[type="opac/call-back+post-query"]', slot );
108
109                                 // Do pre-query stuff
110                                 dojo.forEach(pre_query_callbacks, function (cb) {
111                                     try { (new Function( 'BT', 'slotXML', 'slot', unescape(cb.innerHTML) ))(BT,bib,slot) } catch (e) {/*meh*/}
112                                 });
113
114                                 var item_list = dojo.query(
115                                     slot.getAttribute('query'),
116                                     bib
117                                 );
118
119                                 if (item_limit) {
120                                     if (debug) alert('BibTemplate debug -- item list limit/offset requested: ' + item_limit + '/' + item_offset);
121                                     if (item_list.length) item_list = BT.subsetNL(item_list, item_offset, item_offset + item_limit);
122                                 }
123
124                                 // Do post-query stuff
125                                 dojo.forEach(post_query_callbacks, function (cb) {
126                                     try { (new Function( 'item_list', 'BT', 'slotXML', 'slot', unescape(cb.innerHTML) ))(item_list,BT,bib,slot) } catch (e) {/*meh*/}
127                                 });
128
129                                 if (!item_list.length) return;
130
131                                 // Do pre-render stuff
132                                 dojo.forEach(pre_render_callbacks, function (cb) {
133                                     try { (new Function( 'item_list', 'BT', 'slotXML', 'slot', unescape(cb.innerHTML) ))(item_list,BT,bib,slot) } catch (e) {/*meh*/}
134                                 });
135
136                                 var templated = slot.getAttribute('templated') == 'true';
137                                 if (debug) alert('BibTemplate debug -- slot ' + (templated ? 'is' : 'is not') + ' templated');
138                                 if (templated) {
139                                     if (debug) alert('BibTemplate debug -- slot template innerHTML:\n' + slot.innerHTML);
140                                     var template_values = {};
141                                     var template_value_count = 0;
142
143                                     dojo.query(
144                                         '*[type="opac/template-value"]',
145                                         slot
146                                     ).orphan().forEach(function(x) {
147                                         var name = x.getAttribute('name');
148                                         var value = (new Function( 'item_list', 'BT', 'slotXML', 'slot', unescape(x.innerHTML) ))(item_list,BT,bib,slot);
149                                         if (name && (value || value == '')) {
150                                             template_values[name] = value;
151                                             template_value_count++;
152                                         }
153                                     });
154
155                                     if (debug) alert('BibTemplate debug -- template values:\n' + dojo.toJson( template_values ));
156                                     if (template_value_count > 0) slot.innerHTML = dojo.string.substitute( unescape(slot.innerHTML), template_values );
157                                 }
158
159                                 var handler_node = dojo.query( '*[type="opac/slot-format"]', slot )[0];
160                                 if (handler_node) slot_handler = new Function('item_list', 'BT', 'slotXML', 'slot', 'item', dojox.xml.parser.textContent(handler_node) || handler_node.innerHTML);
161                                 else slot_handler = new Function('item_list', 'BT', 'slotXML', 'slot', 'item','return dojox.xml.parser.textContent(item) || item.innerHTML;');
162
163                                 if (item_list.length) {
164                                     var content = dojo.map(item_list, dojo.partial(slot_handler,item_list,BT,bib,slot)).join(joiner);
165                                     if (templated) {
166                                         if (handler_node) handler_node.parentNode.replaceChild( dojo.doc.createTextNode( content ), handler_node );
167                                     } else {
168                                         slot.innerHTML = content;
169                                     }
170                                 }
171
172                                 delete(slot_handler);
173
174                                 // Do post-render stuff
175                                 dojo.forEach(post_render_callbacks, function (cb) {
176                                     try { (new Function( 'item_list', 'BT', 'slotXML', 'slot', unescape(cb.innerHTML) ))(item_list,BT,bib,slot) } catch (e) {/*meh*/}
177                                 });
178
179                             } catch (e) {
180                                 if (debug) {
181                                     alert('BibTemplate Error: ' + e + '\n' + dojo.toJson(e));
182                                     throw(e);
183                                 }
184                             }
185                         });
186                     };
187
188                     if (BT.xml) {
189                         process_record(BT.xml);
190                     } else {
191                         var uri = '';
192                         if (BT.tagURI) {
193                             uri = BT.tagURI;
194                         } else {
195                             uri = 'tag:evergreen-opac:' + BT.mode + '/' + BT.record;
196                             if (BT.subObjectLimit) {
197                                 uri += '[' + BT.subObjectLimit;
198                                 if (BT.subObjectOffset)
199                                     uri += ',' + BT.subObjectOffset;
200                                 uri += ']';
201                             }
202                             uri += '/' + BT.org_unit;
203                             if (BT.depth || BT.depth == '0') uri += '/' + BT.depth;
204                         }
205
206                         dojo.xhrGet({
207                             url: '/opac/extras/unapi?id=' + uri + '&format=' + args.dtype + '&locale=' + BT.locale,
208                             handleAs: 'xml',
209                             sync: BT.sync,
210                             preventCache: true,
211                             load: process_record
212                         });
213                     }
214
215                 })({ slot_list : slots[datatype].reverse(), dtype : datatype, renderer : this });
216             
217             }
218
219             return true;
220
221         }
222     });
223
224     dojo._hasResource["openils.FeedTemplate"] = true;
225     dojo.provide("openils.FeedTemplate");
226     dojo.declare('openils.FeedTemplate', null, {
227
228         constructor : function(kwargs) {
229             this.place = kwargs.place;
230             this.root = kwargs.root;
231             this.xml = kwargs.xml;
232             this.feed_uri = kwargs.uri;
233             this.item_query = kwargs.query;
234             this.sync = kwargs.sync == true;
235             this.preventCache = kwargs.preventCache == true;
236             this.nodelay = kwargs.delay == false;
237             this.reverseSort = kwargs.reverseSort == true;
238             this.relativePosition = 'last';
239             if (this.reverseSort) this.relativePosition = 'first';
240
241             if (this.nodelay) this.render();
242         },
243
244         render : function () {
245             var me = this;
246             var process_feed = function (xmldoc) {
247                 dojo.query( me.item_query, xmldoc ).forEach(
248                     function (item) {
249                         var template = me.root.cloneNode(true);
250                         dojo.place( template, me.place, me.relativePosition );
251                         new openils.BibTemplate({ delay : false, xml : item, root : template });
252                     }
253                 );
254             };
255
256             if (this.xml) {
257                 process_feed(this.xml);
258             } else {
259                 dojo.xhrGet({
260                     url: me.feed_uri,
261                     handleAs: 'xml',
262                     sync: me.sync,
263                     preventCache: me.preventCache,
264                     load: process_feed
265                 });
266             }
267
268         }
269     });
270 }