1) Исправления в связи со сменой API MySQL
[openlib.git] / www / util.js
1 // util.js\r
2 // copyright Sébastien Lucas\r
3 // https://github.com/seblucas/cops\r
4 \r
5 var templatePage, templateBookDetail, templateMain, currentData, before, filterList;\r
6 \r
7 var cache = new LRUCache(30);\r
8 \r
9 var DEBUG = true;\r
10 var isPushStateEnabled = window.history && window.history.pushState && window.history.replaceState &&\r
11   // pushState isn't reliable on iOS until 5.\r
12   !navigator.userAgent.match(/((iPod|iPhone|iPad).+\bOS\s+[1-4]|WebApps\/.+CFNetwork)/);\r
13 \r
14 function debug_log(text) {\r
15     if ( DEBUG ) {\r
16         console.log(text);\r
17     }\r
18 }\r
19 \r
20 function updateCookie (id) {\r
21     if($(id).prop('pattern') && !$(id).val().match(new RegExp ($(id).prop('pattern')))) {\r
22         return;\r
23     }\r
24     var name = $(id).attr('id');\r
25     var value = $(id).val ();\r
26     $.cookie(name, value, { expires: 365 });\r
27 }\r
28 \r
29 function updateCookieFromCheckbox (id) {\r
30     var name = $(id).attr('id');\r
31     if ((/^style/).test (name)) {\r
32         name = "style";\r
33     }\r
34     if ($(id).is(":checked"))\r
35     {\r
36         if ($(id).is(':radio')) {\r
37             $.cookie(name, $(id).val (), { expires: 365 });\r
38         } else {\r
39             $.cookie(name, '1', { expires: 365 });\r
40         }\r
41     }\r
42     else\r
43     {\r
44         $.cookie(name, '0', { expires: 365 });\r
45     }\r
46 }\r
47 \r
48 function elapsed () {\r
49     var elapsedTime = new Date () - before; \r
50     return "Elapsed : " + elapsedTime;\r
51 }\r
52 \r
53 function retourMail(data, textStatus, jqXHR ) {\r
54     $("#mailButton :first-child").removeClass ("icon-spinner icon-spin").addClass ("icon-envelope");\r
55     alert (data);\r
56 }\r
57 \r
58 function sendToMailAddress (component, dataid) {\r
59     var email = $.cookie ('email');\r
60     if (!$.cookie ('email')) {\r
61         email = window.prompt (currentData.const.i18n.customizeEmail, "");\r
62         $.cookie ('email', email, { expires: 365 });\r
63     }\r
64     var url = 'sendtomail.php';\r
65     $("#mailButton :first-child").removeClass ("icon-envelope").addClass ("icon-spinner icon-spin");\r
66     $.ajax ({'url': url, 'type': 'post', 'data': { 'data':  dataid, 'email': email }, 'success': retourMail});\r
67 }\r
68 \r
69 function strformat () {\r
70     var s = arguments[0];\r
71     for (var i = 0; i < arguments.length - 1; i++) {\r
72         var reg = new RegExp("\\{" + i + "\\}", "gm");\r
73         s = s.replace(reg, arguments[i + 1]);\r
74     }\r
75     return s;\r
76 }\r
77 \r
78 function isDefined(x) {\r
79     var undefinedVar;\r
80     return x !== undefinedVar;\r
81 }\r
82 \r
83 function getCurrentOption (option) {\r
84     if (!$.cookie (option)) {\r
85         if (currentData && currentData.const && currentData.const.config && currentData.const.config [option]) {\r
86             return currentData.const.config [option];\r
87         }\r
88     }\r
89     return $.cookie (option);\r
90 }\r
91 \r
92 function htmlEscape(str) {\r
93     return String(str)\r
94             .replace(/&/g, '&amp;')\r
95             .replace('"', '&quot;')\r
96             .replace("'", '&#39;')\r
97             .replace(/</g, '&lt;')\r
98             .replace(/>/g, '&gt;');\r
99 }\r
100 \r
101 /************************************************\r
102  * All functions needed to filter the book list by tags\r
103  ************************************************\r
104  */\r
105 \r
106 function getTagList () {\r
107     var tagList = {};\r
108     $(".se").each (function(){\r
109         if ($(this).parents (".filtered").length > 0) { return; }\r
110         var taglist = $(this).text();\r
111 \r
112         var tagarray = taglist.split (",");\r
113         for (var i in tagarray) {\r
114             var tag = tagarray [i].replace(/^\s+/g,'').replace(/\s+$/g,'');\r
115             tagList [tag] = 1;\r
116         }\r
117     });\r
118     return tagList;\r
119 }\r
120 \r
121 function doFilter () {\r
122     $(".books").removeClass("filtered");\r
123     if (jQuery.isEmptyObject(filterList)) {\r
124         updateFilters ();\r
125         return;\r
126     }\r
127     \r
128     $(".se").each (function(){\r
129         var taglist = ", " + $(this).text() + ", ";\r
130         var toBeFiltered = false;\r
131         for (var filter in filterList) {\r
132             var onlyThisTag = filterList [filter];\r
133             filter = ', ' + filter + ', ';\r
134             var myreg = new RegExp (filter);\r
135             if (myreg.test (taglist)) {\r
136                 if (onlyThisTag === false) {\r
137                     toBeFiltered = true;\r
138                 }\r
139             } else {\r
140                 if (onlyThisTag === true) {\r
141                     toBeFiltered = true;\r
142                 }\r
143             }\r
144         }\r
145         if (toBeFiltered) { $(this).parents (".books").addClass ("filtered"); }\r
146     });\r
147     updateFilters ();\r
148 }\r
149 \r
150 function updateFilters () {\r
151     var tagList = getTagList ();\r
152     \r
153     // If there is already some filters then let's prepare to update the list\r
154     $("#filter ul li").each (function () {\r
155         var text = $(this).text ();\r
156         if (isDefined (tagList [text]) || $(this).attr ('class')) {\r
157             tagList [text] = 0;\r
158         } else {\r
159             tagList [text] = -1;\r
160         }\r
161     });\r
162     \r
163     // Update the filter -1 to remove, 1 to add, 0 already there\r
164     for (var tag in tagList) {\r
165         var tagValue = tagList [tag];\r
166         if (tagValue === -1) {\r
167             $("#filter ul li:contains('" + tag + "')").remove();\r
168         }\r
169         if (tagValue === 1) {\r
170             $("#filter ul").append ("<li>" + tag + "</li>");\r
171         }\r
172     }\r
173     \r
174     $("#filter ul").append ("<li> СБРОСИТЬ </li>");\r
175     \r
176     // Sort the list alphabetically\r
177     $('#filter ul li').sortElements(function(a, b){\r
178         return $(a).text() > $(b).text() ? 1 : -1;\r
179     });\r
180 }\r
181 \r
182 function handleFilterEvents () {\r
183     $("#filter ul").on ("click", "li", function(){\r
184         var filter = $(this).text ();\r
185         if (filter === " СБРОСИТЬ ") {\r
186             filterList = {};\r
187             $("#filter ul li").removeClass ("filter-exclude");\r
188             $("#filter ul li").removeClass ("filter-include");\r
189             doFilter ();\r
190             return;\r
191         }\r
192         switch ($(this).attr("class")) {\r
193             case "filter-include" :\r
194                 $(this).attr("class", "filter-exclude");\r
195                 filterList [filter] = false;\r
196                 break;\r
197             case "filter-exclude" :\r
198                 $(this).removeClass ("filter-exclude"); \r
199                 delete filterList [filter];\r
200                 break;\r
201             default :\r
202                 $(this).attr("class", "filter-include");\r
203                 filterList [filter] = true;\r
204                 break;\r
205         }\r
206         doFilter ();\r
207     });\r
208 }\r
209 \r
210 /************************************************\r
211  * Functions to handle Ajax navigation\r
212  ************************************************\r
213  */\r
214 \r
215 function navigateTo (url) {\r
216     before = new Date ();\r
217     var jsonurl = url.replace ("index", "getJSON");\r
218     var cachedData = cache.get (jsonurl);\r
219     if (cachedData) {\r
220         history.pushState(jsonurl, "", url);\r
221         updatePage (cachedData);\r
222     } else {\r
223         $.getJSON(jsonurl, function(data) {\r
224             history.pushState(jsonurl, "", url);\r
225             cache.put (jsonurl, data);\r
226             updatePage (data);\r
227         });\r
228     }\r
229 }\r
230 \r
231 function updatePage (data) {\r
232     var result;\r
233     filterList = {};\r
234     data ["const"] = currentData ["const"];\r
235     if ($("section").length && currentData.isPaginated === 0 &&  data.isPaginated === 0) {\r
236         // Partial update (for now disabled)\r
237         debug_log ("Partial update");\r
238         debug_log(templateMain);\r
239         result = templateMain (data);\r
240         debug_log ("Result: ");\r
241         debug_log (result);\r
242         $("h1").html (data.title);\r
243         $("section").html (result);\r
244     } else {\r
245         // Full update\r
246         result = templatePage (data);\r
247         $("body").html (result);\r
248     }\r
249     document.title = data.title;\r
250     currentData = data;\r
251     \r
252     debug_log (elapsed ());\r
253     \r
254     if ($.cookie('toolbar') === '1') { $("#tool").show (); }\r
255     if (currentData.containsBook === 1) {\r
256         $("#sortForm").show ();\r
257         if (getCurrentOption ("html_tag_filter") === "1") {\r
258             $("#filter ul").empty ();\r
259             updateFilters ();\r
260             handleFilterEvents ();\r
261         }\r
262     } else {\r
263         $("#sortForm").hide ();\r
264     }\r
265 }\r
266 \r
267 function handleLinks () {\r
268     $("body").on ("click", "a[href^='index']", link_Clicked);\r
269     $("body").on ("submit", "#searchForm", search_Submitted);\r
270     $("body").on ("click", "#sort", function(){\r
271         $('.books').sortElements(function(a, b){\r
272             var test = 1;\r
273             if ($("#sortorder").val() === "desc")\r
274             {\r
275                 test = -1;\r
276             }\r
277             return $(a).find ("." + $("#sortchoice").val()).text() > $(b).find ("." + $("#sortchoice").val()).text() ? test : -test;\r
278         });\r
279     });\r
280     \r
281     $("body").on ("click", ".headright", function(){\r
282         if ($("#tool").is(":hidden")) {\r
283             $("#tool").slideDown("slow");\r
284             $.cookie('toolbar', '1', { expires: 365 });\r
285         } else {\r
286             $("#tool").slideUp();\r
287             $.removeCookie('toolbar');\r
288         }\r
289     });\r
290     $("body").magnificPopup({\r
291         delegate: '.fancycover', // child items selector, by clicking on it popup will open\r
292         type: 'image',\r
293         gallery:{enabled:true, preload: [0,2]},\r
294         disableOn: function() {\r
295           if( getCurrentOption ("use_fancyapps") === "1" ) {\r
296             return true;\r
297           } \r
298           return false;\r
299         }\r
300     });\r
301 }\r
302 \r
303 function link_Clicked (event) {\r
304     var currentLink = $(this);\r
305     debug_log("Link clicked");\r
306     if (!isPushStateEnabled ||\r
307         currentData.page === "OPTS") { \r
308         return;\r
309     }\r
310     event.preventDefault();\r
311     var url = currentLink.attr('href');\r
312     \r
313     if ($(".mfp-ready").length)\r
314     {\r
315         $.magnificPopup.close();\r
316     }\r
317     \r
318     // The bookdetail / about should be displayed in a lightbox\r
319     if (getCurrentOption ("use_fancyapps") === "1" && \r
320         (currentLink.hasClass ("fancydetail") || currentLink.hasClass ("fancyabout"))) {\r
321         debug_log('Lighhtbox mode on');\r
322         before = new Date ();\r
323         var jsonurl = url.replace ("index", "getJSON");\r
324         $.getJSON(jsonurl, function(data) {\r
325             data ["const"] = currentData ["const"];\r
326             var detail = "";\r
327             if (data.page === "ABOUT") {\r
328                 detail = data.fullhtml;\r
329             } else {\r
330                 detail = templateBookDetail (data);\r
331             }\r
332             $.magnificPopup.open({\r
333               items: {\r
334                 src: detail,\r
335                 type: 'inline'\r
336               }\r
337             });\r
338             debug_log (elapsed ());\r
339         });\r
340         return;\r
341     }\r
342     navigateTo (url);\r
343 }\r
344 \r
345 function search_Submitted (event) {\r
346     if (!isPushStateEnabled ||\r
347         currentData.page === "OPTS") { \r
348         return;\r
349     }\r
350     event.preventDefault();\r
351     var url = strformat ("index.php?page=OPENQ&current={0}&query={1}", currentData.page, $("input[name=query]").val ());\r
352     navigateTo (url);\r
353 }\r
354 \r
355 window.onpopstate = function(event) {\r
356     before = new Date ();\r
357     var data = cache.get (event.state);\r
358     updatePage (data);\r
359 };\r
360 \r
361 $(document).keydown(function(e){\r
362     if (e.keyCode === 37 && $("#prevLink").length > 0) {\r
363         navigateTo ($("#prevLink").attr('href'));\r
364     }\r
365     if (e.keyCode === 39  && $("#nextLink").length > 0) {\r
366         navigateTo ($("#nextLink").attr('href'));\r
367     }\r
368 });