--- /dev/null
+// util.js\r
+// copyright Sébastien Lucas\r
+// https://github.com/seblucas/cops\r
+\r
+var templatePage, templateBookDetail, templateMain, currentData, before, filterList;\r
+\r
+var cache = new LRUCache(30);\r
+\r
+var DEBUG = true;\r
+var isPushStateEnabled = window.history && window.history.pushState && window.history.replaceState &&\r
+ // pushState isn't reliable on iOS until 5.\r
+ !navigator.userAgent.match(/((iPod|iPhone|iPad).+\bOS\s+[1-4]|WebApps\/.+CFNetwork)/);\r
+\r
+function debug_log(text) {\r
+ if ( DEBUG ) {\r
+ console.log(text);\r
+ }\r
+}\r
+\r
+function updateCookie (id) {\r
+ if($(id).prop('pattern') && !$(id).val().match(new RegExp ($(id).prop('pattern')))) {\r
+ return;\r
+ }\r
+ var name = $(id).attr('id');\r
+ var value = $(id).val ();\r
+ $.cookie(name, value, { expires: 365 });\r
+}\r
+\r
+function updateCookieFromCheckbox (id) {\r
+ var name = $(id).attr('id');\r
+ if ((/^style/).test (name)) {\r
+ name = "style";\r
+ }\r
+ if ($(id).is(":checked"))\r
+ {\r
+ if ($(id).is(':radio')) {\r
+ $.cookie(name, $(id).val (), { expires: 365 });\r
+ } else {\r
+ $.cookie(name, '1', { expires: 365 });\r
+ }\r
+ }\r
+ else\r
+ {\r
+ $.cookie(name, '0', { expires: 365 });\r
+ }\r
+}\r
+\r
+function elapsed () {\r
+ var elapsedTime = new Date () - before; \r
+ return "Elapsed : " + elapsedTime;\r
+}\r
+\r
+function retourMail(data, textStatus, jqXHR ) {\r
+ $("#mailButton :first-child").removeClass ("icon-spinner icon-spin").addClass ("icon-envelope");\r
+ alert (data);\r
+}\r
+\r
+function sendToMailAddress (component, dataid) {\r
+ var email = $.cookie ('email');\r
+ if (!$.cookie ('email')) {\r
+ email = window.prompt (currentData.const.i18n.customizeEmail, "");\r
+ $.cookie ('email', email, { expires: 365 });\r
+ }\r
+ var url = 'sendtomail.php';\r
+ $("#mailButton :first-child").removeClass ("icon-envelope").addClass ("icon-spinner icon-spin");\r
+ $.ajax ({'url': url, 'type': 'post', 'data': { 'data': dataid, 'email': email }, 'success': retourMail});\r
+}\r
+\r
+function strformat () {\r
+ var s = arguments[0];\r
+ for (var i = 0; i < arguments.length - 1; i++) {\r
+ var reg = new RegExp("\\{" + i + "\\}", "gm");\r
+ s = s.replace(reg, arguments[i + 1]);\r
+ }\r
+ return s;\r
+}\r
+\r
+function isDefined(x) {\r
+ var undefinedVar;\r
+ return x !== undefinedVar;\r
+}\r
+\r
+function getCurrentOption (option) {\r
+ if (!$.cookie (option)) {\r
+ if (currentData && currentData.const && currentData.const.config && currentData.const.config [option]) {\r
+ return currentData.const.config [option];\r
+ }\r
+ }\r
+ return $.cookie (option);\r
+}\r
+\r
+function htmlEscape(str) {\r
+ return String(str)\r
+ .replace(/&/g, '&')\r
+ .replace('"', '"')\r
+ .replace("'", ''')\r
+ .replace(/</g, '<')\r
+ .replace(/>/g, '>');\r
+}\r
+\r
+/************************************************\r
+ * All functions needed to filter the book list by tags\r
+ ************************************************\r
+ */\r
+\r
+function getTagList () {\r
+ var tagList = {};\r
+ $(".se").each (function(){\r
+ if ($(this).parents (".filtered").length > 0) { return; }\r
+ var taglist = $(this).text();\r
+\r
+ var tagarray = taglist.split (",");\r
+ for (var i in tagarray) {\r
+ var tag = tagarray [i].replace(/^\s+/g,'').replace(/\s+$/g,'');\r
+ tagList [tag] = 1;\r
+ }\r
+ });\r
+ return tagList;\r
+}\r
+\r
+function doFilter () {\r
+ $(".books").removeClass("filtered");\r
+ if (jQuery.isEmptyObject(filterList)) {\r
+ updateFilters ();\r
+ return;\r
+ }\r
+ \r
+ $(".se").each (function(){\r
+ var taglist = ", " + $(this).text() + ", ";\r
+ var toBeFiltered = false;\r
+ for (var filter in filterList) {\r
+ var onlyThisTag = filterList [filter];\r
+ filter = ', ' + filter + ', ';\r
+ var myreg = new RegExp (filter);\r
+ if (myreg.test (taglist)) {\r
+ if (onlyThisTag === false) {\r
+ toBeFiltered = true;\r
+ }\r
+ } else {\r
+ if (onlyThisTag === true) {\r
+ toBeFiltered = true;\r
+ }\r
+ }\r
+ }\r
+ if (toBeFiltered) { $(this).parents (".books").addClass ("filtered"); }\r
+ });\r
+ updateFilters ();\r
+}\r
+\r
+function updateFilters () {\r
+ var tagList = getTagList ();\r
+ \r
+ // If there is already some filters then let's prepare to update the list\r
+ $("#filter ul li").each (function () {\r
+ var text = $(this).text ();\r
+ if (isDefined (tagList [text]) || $(this).attr ('class')) {\r
+ tagList [text] = 0;\r
+ } else {\r
+ tagList [text] = -1;\r
+ }\r
+ });\r
+ \r
+ // Update the filter -1 to remove, 1 to add, 0 already there\r
+ for (var tag in tagList) {\r
+ var tagValue = tagList [tag];\r
+ if (tagValue === -1) {\r
+ $("#filter ul li:contains('" + tag + "')").remove();\r
+ }\r
+ if (tagValue === 1) {\r
+ $("#filter ul").append ("<li>" + tag + "</li>");\r
+ }\r
+ }\r
+ \r
+ $("#filter ul").append ("<li> СБРОСИТЬ </li>");\r
+ \r
+ // Sort the list alphabetically\r
+ $('#filter ul li').sortElements(function(a, b){\r
+ return $(a).text() > $(b).text() ? 1 : -1;\r
+ });\r
+}\r
+\r
+function handleFilterEvents () {\r
+ $("#filter ul").on ("click", "li", function(){\r
+ var filter = $(this).text ();\r
+ if (filter === " СБРОСИТЬ ") {\r
+ filterList = {};\r
+ $("#filter ul li").removeClass ("filter-exclude");\r
+ $("#filter ul li").removeClass ("filter-include");\r
+ doFilter ();\r
+ return;\r
+ }\r
+ switch ($(this).attr("class")) {\r
+ case "filter-include" :\r
+ $(this).attr("class", "filter-exclude");\r
+ filterList [filter] = false;\r
+ break;\r
+ case "filter-exclude" :\r
+ $(this).removeClass ("filter-exclude"); \r
+ delete filterList [filter];\r
+ break;\r
+ default :\r
+ $(this).attr("class", "filter-include");\r
+ filterList [filter] = true;\r
+ break;\r
+ }\r
+ doFilter ();\r
+ });\r
+}\r
+\r
+/************************************************\r
+ * Functions to handle Ajax navigation\r
+ ************************************************\r
+ */\r
+\r
+function navigateTo (url) {\r
+ before = new Date ();\r
+ var jsonurl = url.replace ("index", "getJSON");\r
+ var cachedData = cache.get (jsonurl);\r
+ if (cachedData) {\r
+ history.pushState(jsonurl, "", url);\r
+ updatePage (cachedData);\r
+ } else {\r
+ $.getJSON(jsonurl, function(data) {\r
+ history.pushState(jsonurl, "", url);\r
+ cache.put (jsonurl, data);\r
+ updatePage (data);\r
+ });\r
+ }\r
+}\r
+\r
+function updatePage (data) {\r
+ var result;\r
+ filterList = {};\r
+ data ["const"] = currentData ["const"];\r
+ if ($("section").length && currentData.isPaginated === 0 && data.isPaginated === 0) {\r
+ // Partial update (for now disabled)\r
+ debug_log ("Partial update");\r
+ debug_log(templateMain);\r
+ result = templateMain (data);\r
+ debug_log ("Result: ");\r
+ debug_log (result);\r
+ $("h1").html (data.title);\r
+ $("section").html (result);\r
+ } else {\r
+ // Full update\r
+ result = templatePage (data);\r
+ $("body").html (result);\r
+ }\r
+ document.title = data.title;\r
+ currentData = data;\r
+ \r
+ debug_log (elapsed ());\r
+ \r
+ if ($.cookie('toolbar') === '1') { $("#tool").show (); }\r
+ if (currentData.containsBook === 1) {\r
+ $("#sortForm").show ();\r
+ if (getCurrentOption ("html_tag_filter") === "1") {\r
+ $("#filter ul").empty ();\r
+ updateFilters ();\r
+ handleFilterEvents ();\r
+ }\r
+ } else {\r
+ $("#sortForm").hide ();\r
+ }\r
+}\r
+\r
+function handleLinks () {\r
+ $("body").on ("click", "a[href^='index']", link_Clicked);\r
+ $("body").on ("submit", "#searchForm", search_Submitted);\r
+ $("body").on ("click", "#sort", function(){\r
+ $('.books').sortElements(function(a, b){\r
+ var test = 1;\r
+ if ($("#sortorder").val() === "desc")\r
+ {\r
+ test = -1;\r
+ }\r
+ return $(a).find ("." + $("#sortchoice").val()).text() > $(b).find ("." + $("#sortchoice").val()).text() ? test : -test;\r
+ });\r
+ });\r
+ \r
+ $("body").on ("click", ".headright", function(){\r
+ if ($("#tool").is(":hidden")) {\r
+ $("#tool").slideDown("slow");\r
+ $.cookie('toolbar', '1', { expires: 365 });\r
+ } else {\r
+ $("#tool").slideUp();\r
+ $.removeCookie('toolbar');\r
+ }\r
+ });\r
+ $("body").magnificPopup({\r
+ delegate: '.fancycover', // child items selector, by clicking on it popup will open\r
+ type: 'image',\r
+ gallery:{enabled:true, preload: [0,2]},\r
+ disableOn: function() {\r
+ if( getCurrentOption ("use_fancyapps") === "1" ) {\r
+ return true;\r
+ } \r
+ return false;\r
+ }\r
+ });\r
+}\r
+\r
+function link_Clicked (event) {\r
+ var currentLink = $(this);\r
+ debug_log("Link clicked");\r
+ if (!isPushStateEnabled ||\r
+ currentData.page === "OPTS") { \r
+ return;\r
+ }\r
+ event.preventDefault();\r
+ var url = currentLink.attr('href');\r
+ \r
+ if ($(".mfp-ready").length)\r
+ {\r
+ $.magnificPopup.close();\r
+ }\r
+ \r
+ // The bookdetail / about should be displayed in a lightbox\r
+ if (getCurrentOption ("use_fancyapps") === "1" && \r
+ (currentLink.hasClass ("fancydetail") || currentLink.hasClass ("fancyabout"))) {\r
+ debug_log('Lighhtbox mode on');\r
+ before = new Date ();\r
+ var jsonurl = url.replace ("index", "getJSON");\r
+ $.getJSON(jsonurl, function(data) {\r
+ data ["const"] = currentData ["const"];\r
+ var detail = "";\r
+ if (data.page === "ABOUT") {\r
+ detail = data.fullhtml;\r
+ } else {\r
+ detail = templateBookDetail (data);\r
+ }\r
+ $.magnificPopup.open({\r
+ items: {\r
+ src: detail,\r
+ type: 'inline'\r
+ }\r
+ });\r
+ debug_log (elapsed ());\r
+ });\r
+ return;\r
+ }\r
+ navigateTo (url);\r
+}\r
+\r
+function search_Submitted (event) {\r
+ if (!isPushStateEnabled ||\r
+ currentData.page === "OPTS") { \r
+ return;\r
+ }\r
+ event.preventDefault();\r
+ var url = strformat ("index.php?page=OPENQ¤t={0}&query={1}", currentData.page, $("input[name=query]").val ());\r
+ navigateTo (url);\r
+}\r
+\r
+window.onpopstate = function(event) {\r
+ before = new Date ();\r
+ var data = cache.get (event.state);\r
+ updatePage (data);\r
+};\r
+\r
+$(document).keydown(function(e){\r
+ if (e.keyCode === 37 && $("#prevLink").length > 0) {\r
+ navigateTo ($("#prevLink").attr('href'));\r
+ }\r
+ if (e.keyCode === 39 && $("#nextLink").length > 0) {\r
+ navigateTo ($("#nextLink").attr('href'));\r
+ }\r
+});
\ No newline at end of file