1/*
2 * AcMenu plugin: an accordion menu for namespaces and relative pages.
3 *
4 * script.js: accordion menu behaviour used by AcMenu plugin.
5 *
6 * @author Torpedo <dcstoyanov@gmail.com>
7 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
8 * @package script
9 */
10
11var _OPEN_ITEMS = [];
12var _COOKIE_NAME = "plugin_acmenu_open_items";
13var _COOKIE_PARAMETERS = ";expires='';path=/;SameSite=Lax";
14
15/*
16 * Get previously cookies in order to remember which item are opened.
17 *
18 * Cookies are retrieved in the form:
19 * <other-cookie>=["val-1",..,"val-m"]; open_items=["val-1",..,"val-n"]
20 */
21function get_cookie() {
22    var all_cookies = document.cookie.split(";");
23
24    for (var i = 0; i < all_cookies.length; i++) {
25        if (all_cookies[i].indexOf(_COOKIE_NAME + "=") > -1) {
26            var cookie = all_cookies[i].trim();
27            var items = cookie.substring((_COOKIE_NAME + "=").length, cookie.length);
28            var items = JSON.parse(items);
29            var items = items.toString().split(",");
30            for (var j = 0; j < items.length; j++) {
31                _OPEN_ITEMS.push(items[j]);
32            }
33        }
34    }
35}
36
37
38/*
39 * Store the <start> pages genealogy of the given id as cookies.
40 */
41function set_cookie() {
42    jQuery.each(JSINFO["plugin_acmenu"]["sub_ns"], function(idx, val) {
43        sub_start = [val, JSINFO["plugin_acmenu"]["start"]].filter(Boolean).join(":");
44        if (_OPEN_ITEMS.indexOf(sub_start) == -1) {
45            _OPEN_ITEMS.push(sub_start);
46        }
47    });
48    var cookie_value = JSON.stringify(_OPEN_ITEMS);
49    document.cookie = _COOKIE_NAME + "=" + cookie_value + _COOKIE_PARAMETERS;
50}
51
52/*
53 * For a given href attribute of an url, keep only the page's id.
54 *
55 * @param string url
56 *      the link to a wiki page is made by wl() defined in inc/common.php
57 * @return string trimmed_url
58 *      the page's id, that is:
59 *      <ns-acmenu>:<ns-1>:...:<ns-i>:<pg>
60 */
61function trim_url(url) {
62    if (JSINFO["plugin_acmenu"]["canonical"]) {
63        xlink = JSINFO["plugin_acmenu"]["doku_url"];
64    }
65    else {
66        xlink = JSINFO["plugin_acmenu"]["doku_base"];
67    }
68
69    if (JSINFO["plugin_acmenu"]["userewrite"] == 2) {
70        xlink += JSINFO["plugin_acmenu"]["doku_script"] + "/";
71    }
72    else if (JSINFO["plugin_acmenu"]["userewrite"] == 1) {
73    }
74    else {
75        xlink += JSINFO["plugin_acmenu"]["doku_script"] + "?id=";
76    }
77
78    var trimmed_url = url.replace(xlink, "");  // return only page's id
79
80    if (JSINFO["plugin_acmenu"]["useslash"] == 1) {
81        const slash = /\//g;
82        var trimmed_url = trimmed_url.replace(slash, ":");
83    }
84
85    return trimmed_url;
86}
87
88jQuery(document).ready(function() {
89    // Example of a nested menu:
90    // ns 0  // open item
91    //   ns 0.1
92    //     pg 0.1.1
93    //   ns 0.2  // open item
94    //     pg 0.2.1  // open item
95    // pg 0.1
96    //
97    // <div class="acmenu">
98    //     <ul class="idx">
99    //         <li class="open">
100    //             <div class="li"><span class="curid"><a href=""></a></span></div>
101    //             <ul class="idx">
102    //                 <li class="closed">
103    //                     <div class="li"><a href=""></a></div>
104    //                     <ul class="idx" style="display: none;">
105    //                         <li class="level2"><div class="li"><a href=""></a></div></li>
106    //                     </ul>
107    //                 </li>
108    //                 <li class="open">
109    //                     <div class="li"><span class="curid"><a href=""></a></span></div>
110    //                     <ul class="idx">
111    //                         <li class="level2"><div class="li"><span class="curid"><a href=""></a></span></div></li>
112    //                     </ul>
113    //                 </li>
114    //                 <li class="level1"><div class="li"><a href=""></a></div></li>
115    //             </ul>
116    //         </li>
117    //     </ul>
118    // </div>
119
120    const selector = "div.acmenu ul.idx > li:not([class^='level']) > div.li";
121
122    get_cookie();
123    set_cookie();
124
125    jQuery(selector).click(function(event) {
126        var item = trim_url(jQuery(this).find("a").attr("href"));
127        event.preventDefault();
128        if (jQuery(this).next().is(":hidden")) {
129            jQuery(this)
130            .next().slideDown("fast")
131            .parent().removeClass("closed").addClass("open");
132            _OPEN_ITEMS.push(item);
133        }
134        else {
135            jQuery(this)
136            .next().slideUp("fast")
137            .parent().removeClass("open").addClass("closed");
138            _OPEN_ITEMS.splice(jQuery.inArray(item, _OPEN_ITEMS), 1);
139        }
140        var cookie_value = JSON.stringify(_OPEN_ITEMS);
141        document.cookie = _COOKIE_NAME + "=" + cookie_value + _COOKIE_PARAMETERS;
142    });
143});
144