1) Исправления в связи со сменой API MySQL
[openlib.git] / www / util.js
diff --git a/www/util.js b/www/util.js
new file mode 100644 (file)
index 0000000..8c9d353
--- /dev/null
@@ -0,0 +1,368 @@
+// 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, '&amp;')\r
+            .replace('"', '&quot;')\r
+            .replace("'", '&#39;')\r
+            .replace(/</g, '&lt;')\r
+            .replace(/>/g, '&gt;');\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&current={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