// Context menu var indexmenu_contextmenu = {'all': []}; /* DOKUWIKI:include scripts/nojsindex.js */ /* DOKUWIKI:include scripts/toolbarindexwizard.js */ /* DOKUWIKI:include scripts/contextmenu.js */ /* DOKUWIKI:include scripts/indexmenu.js */ /* DOKUWIKI:include scripts/contextmenu.local.js */ /* DOKUWIKI:include scripts/fancytree/jquery.fancytree-all.min.js */ // - page id without URL rewriting http://example.doku/doku.php?id=test:start // - page id without URL rewriting http://example.doku/doku.php?id=test:plugins#interwikipaste // - page id with .htaccess URL rewriting http://example.doku/test:plugins // - page id with .htaccess URL rewriting and 'useslash' config http://example.doku/test/plugins // - page id with internal URL rewriting http://example.doku/doku.php/test:plugins // - http://example.doku/lib/exe/detail.php?id=test%3Aplugins&media=ns:image.jpg // - http://example.doku/lib/exe/fetch.php?w=400&tok=097122&media=ns:image.jpg // - http://example.doku/lib/exe/fetch.php?media=test:file.pdf // - http://example.doku/_detail/ns:image.jpg?id=test%3Aplugins // - http://example.doku/_media/test:file.pdf // - http://example.doku/_detail/ns/image.jpg?id=test%3Aplugins // - http://example.doku/_media/test/file.pdf jQuery(function(){ // on page load // Create the tree inside the
element. const predefinedPresets = { 'bootstrap': { //works with template bootstrap3 or by manually adding resources to icon plugin assets 'preset': 'bootstrap3', 'map': {} }, 'bootstrap-n': { //works with template bootstrap3 or ..etc 'preset': 'bootstrap3', 'map': {} }, 'awesome': { //works with icons-plugin, settings: enable plugin»icons»loadFontAwesome 'preset': 'awesome4', //plugin icons does include only awesome4, not awesome5. 'map': {} }, 'material': { // add Material Icons font stylesheet to header with TPL_METAHEADER_OUTPUT in action component 'preset': 'material', 'map': {} }, 'mdi': { //works with icons-plugin, settings: enable plugin»icons»loadMaterialDesignIcons 'preset': '', 'map': { _addClass: "mdi", checkbox: "mdi-checkbox-blank-outline", checkboxSelected: "mdi-check-box-outline", checkboxUnknown: "mdi-checkbox-intermediate fancytree-helper-indeterminate-cb", dragHelper: "mdi-play", dropMarker: "mdi-skip-forward", error: "mdi-warning", expanderClosed: "mdi-chevron-right", expanderLazy: "mdi-chevron-right", expanderOpen: "mdi-chevron-down", // We may prevent wobbling rotations on FF by creating a separate sub element: loading: "mdi-refresh", nodata: "mdi-information-outline", noExpander: "", radio: "mdi-radiobox-blank", // "fa-circle-o" radioSelected: "mdi-radiobox-marked", // Default node icons. // (Use tree.options.icon callback to define custom icons based on node data) doc: "mdi-file-outline", docOpen: "mdi-file-outline", folder: "mdi-folder", folderOpen: "mdi-folder-open", } }, 'typicons': { //works with icons-plugin, settings: enable plugin»icons»loadTypicons 'preset': '', 'map': { _addClass: "typcn", checkbox: "typcn-media-stop-outline", checkboxSelected: "typcn-input-checked", checkboxUnknown: "typcn-media-stop-outline fancytree-helper-indeterminate-cb", dragHelper: "typcn-media-play-outline", dropMarker: "typcn-media-fast-forward-outline", error: "typcn-warning", expanderClosed: "typcn-media-play", expanderLazy: "typcn-media-play", expanderOpen: "typcn-arrow-sorted-down", // We may prevent wobbling rotations on FF by creating a separate sub element: loading: "typcn-arrow-sync", nodata: "typcn-info-large", noExpander: "", radio: "typcn-media-record-outline", // "fa-circle-o" radioSelected: "typcn-media-record", // Default node icons. // (Use tree.options.icon callback to define custom icons based on node data) doc: "typcn-document", docOpen: "typcn-document", folder: "typcn-folder", folderOpen: "typcn-folder-open", } } }; // userDefinedPresets can be defined in conf/userscript.js const presets = {...predefinedPresets, ...(typeof userDefinedPresets === 'undefined' ? [] : userDefinedPresets)}; //let targettype; // function logEvent(event, data, msg){ // // var args = Array.isArray(args) ? args.join(", ") : // msg = msg ? ": " + msg : ""; // jQuery.ui.fancytree.info("Event('" + event.type + "', node=" + data.node + ")" + msg); // } jQuery(".indexmenu_js2").each(function(){ let $tree = jQuery(this), id = $tree.attr('id'); const options = $tree.data('options'); // console.log("options"); // console.log(options); let themePreset = presets[options.opts.theme]; let targettype; //to share type between handlers let extensions = []; if(themePreset) { extensions.push("glyph"); } if(options.opts.persist) { extensions.push("persist"); } $tree.fancytree({ //enabled extensions extensions: extensions, //settings for glyph extension glyph: { preset: themePreset ? themePreset.preset : '', map: themePreset ? themePreset.map : {} }, // 0=quite, 1=only errors, upto 4=also debug //debugLevel: 4, //settings for persist extension persist: { expandLazy: true, // fireActivate: false, // false: suppress `activate` event after active node was restored // overrideSource: false, // true: cookie takes precedence over `source` data attributes. store: "auto" // 'cookie', 'local': use localStore, 'session': sessionStore // Sample for a custom store: // store: { // get: function(key){ this.info("get(" + key + ")"); return window.sessionStorage.getItem(key); }, // set: function(key, value){ this.info("set(" + key + ", " + value + ")"); window.sessionStorage.setItem(key, value); }, // remove: function(key){ this.info("remove(" + key + ")"); window.sessionStorage.removeItem(key); } }, // number of levels already expanded, and not unexpandable. //minExpandLevel: 2, // expand with single click instead of dblclick clickFolderMode: 3, // closes other opened nodes, so only one node is opened //autoCollapse: true, // for keyboard.. --opening folders becomes jumpy //autoScroll: true, // Looping in combination with clicking autoActivate: false, // disabled because it causes also autoscrolling, such that select node is out-of-view activeVisible: false, escapeTitles: false, tooltip: true, //use same setting as wiki page rtl: jQuery('html[dir=rtl]').length, //for keyboard control keydown: function (event, data) { switch (event.which) { case 32: // [space] // logEvent(event,data); break; case 13: // [enter] // logEvent(event,data); if(data.node.data.url){ // console.log('redirect'); window.location.href = data.node.data.url; } break; } }, //store in click some event data for the activate handler click: function(event, data) { // return false to prevent default behavior (i.e. activation, ...) targettype = data.targetType; //store target type, only available in click handler }, //go to wiki page if node is activated activate: function(event, data){ const node = data.node; //prevent looping (hns is false or a page id) if(node.key === JSINFO.id || node.data.hns === JSINFO.id) { //node is equal to current page, prevent to follow the url return; } if(options.opts.nopg && node.key === JSINFO.namespace + ':') { //nopg marks parent ns node active, prevent to follow the url return; } // expander should not follow link if(targettype === 'expander') { targettype = false; //reset return false; } if(node.data.url === false) { return false; } if(node.data.url){ window.location.href = node.data.url; } }, // active marked node (=current page) init: function(event, data) { //activate current node data.tree.reactivate(); }, //add url enhanceTitle: function(event, data) { let node = data.node; if(node.data.url === false) { return; } if(node.data.url) { // pagename 0 has url /0 //nopg has potentially not existing pages let cls = ''; if(node.data.hnsNotExisting) { cls = ' class="wikilink2"'; } data.$title.html("" + node.title + ""); } }, //retrieve initial data source: { url: DOKU_BASE + 'lib/exe/ajax.php', data: { ns: options.ns, call: 'indexmenu', req: 'fancytree', level: options.opts.level, //only init nons: options.opts.nons ? 1 : 0, //only init; without ns, no lower levels possible nopg: options.opts.nopg ? 1 : 0, subnss: options.opts.subnss, //subns to open. Only on init array, later just current ns string navbar: options.opts.navbar ? 1 : 0, //only init: open tree at current page currentpage: JSINFO.id, max: options.opts.max, //#n of max#n#m skipns: options.opts.skipns, skipfile: options.opts.skipfile, sort: options.sort.sort ? options.sort.sort : 0, //'t', 'd', false TODO is false handled correctly? msort: options.sort.msort ? options.sort.msort : 0, //'indexmenu_n', or metadata 'key subkey' TODO is empty handled correctly? rsort: options.sort.rsort ? 1 : 0, nsort: options.sort.nsort ? 1 : 0, hsort: options.sort.hsort ? 1 : 0, init: 1 } }, //retrieve data of expanded nodes lazyLoad: function(event, data) { const node = data.node; // Issue an Ajax request to load child nodes data.result = { url: DOKU_BASE + 'lib/exe/ajax.php', data: { ns: node.key, // ns with trailing : call: 'indexmenu', req: 'fancytree', level: 1, //level opened nodes, for follow up ajax requests only next level, so:1 nons: options.opts.nons ? 1 : 0, nopg: options.opts.nopg ? 1 : 0, subnss: '', //options.opts.subnss is used on init currentpage: JSINFO.id, max: options.opts.maxajax, //#m of max#n#m skipns: options.opts.skipns, skipfile: options.opts.skipfile, sort: options.sort.sort ? options.sort.sort : 0, msort: options.sort.msort ? options.sort.msort : 0, rsort: options.sort.rsort ? 1 : 0, nsort: options.sort.nsort ? 1 : 0, hsort: options.sort.hsort ? 1 : 0, init: 0 } } } }); //hide the fallback nojs indexmenu jQuery('#nojs_' + id.substring(6)).css("display", "none"); // Note: Loading and initialization may be asynchronous, so the nodes may not be accessible yet. // On page load, activate node if node.data.href matches the url#href // let tree = jQuery.ui.fancytree.getTree("#" + id), // path = window.parent && window.parent.location.pathname; // // console.log(path); // // console.log('test'); // if(path) { // let arr = path.split('/'); // not reliable with config:useslash? // let last = arr[arr.length-1] || arr[arr.length-2]; // // console.log(arr); // // console.log(last); // // // tree.activateKey(last); // // var node1=tree.getNodeByKey(last); // // console.log(node1); // // node1.setActive(); // // also possible: // // $.ui.fancytree.getTree("#tree").getNodeByKey("id4.3.2").setActive(); // // // tree.visit(function(n) { // // console.log(n.key); // // console.log(n); // // if( n.key && n.key === last ) { // // n.setActive(); //if not using iframes, this creates a loops in combination with activate above // // return false; // done: break traversal // // } // // }); // } // console.log(tree); // console.log("test"); // jQuery.contextMenu({ // selector: "span.fancytree-title", // items: { // // "cut": {name: "Cut", icon: "cut", // // callback: function(key, opt){ // // var node = jQuery.ui.fancytree.getNode(opt.$trigger); // // alert("Clicked on " + key + " on " + node); // // } // // }, // "page": {name: "Page", icon: "", disabled: true }, // "sep1": "----", // "revs": {name: "Revisions", icon: "ui-icon-arrowreturn-1-w", disabled: false }, // "toc": {name: "ToC preview", icon: "ui-icon-bookmark", disabled: false }, // "edit": {name: "Edit", icon: "edit", disabled: false }, // "hpage": {name: "Headpage", icon: "add", disabled: false}, // "spage": {name: "Start page", icon: "add", disabled: false}, // "cpage": {name: "Custom page...", icon: "add", disabled: false}, // "acls": {name: "Acls", icon: "ui-icon-locked", disabled: false}, // "purge": {name: "Purge cache", icon: "loading", disabled: false}, // "html": {name: "Export as HTML", icon: "ui-icon-document", disabled: false}, // "text": {name: "Export as text", icon: "ui-icon-note", disabled: false}, // "sep2": "----", // "ns": {name: "Namespace", icon: "", disabled: true}, // "sep3": "----", // "search": {name: "Search...", icon: "ui-icon-search", disabled: false}, // "npage": {name: "New page...", icon: "add", disabled: false}, // "nshpage": {name: "Headpage here", icon: "add", disabled: false}, // "nsacls": {name: "Acls", icon: "ui-icon-locked", disabled: false} // }, // callback: function(itemKey, opt) { // var node = jQuery.ui.fancytree.getNode(opt.$trigger); // alert("select " + itemKey + " on " + node); // } // }); // $tree.contextmenu({ // delegate: "span.fancytree-title", // autoFocus: true, // // menu: "#options", // menu: [ // {title: "Page", cmd: 'pg'}, // {title: "----", cmd: 'pg'}, // {title: "Revisions", cmd: "revs", uiIcon: "ui-icon-arrowreturn-1-w"}, // {title: "ToC preview", cmd: "toc", uiIcon: "ui-icon-bookmark"}, // {title: "Edit", cmd: "edit", uiIcon: "ui-icon-pencil", disabled: false }, // {title: "Headpage", cmd: "hpage", uiIcon: "ui-icon-plus"}, // {title: "Start page", cmd: "spage", uiIcon: "ui-icon-plus"}, // {title: "Custom page...", cmd: "cpage", uiIcon: "ui-icon-plus"}, // {title: "Acls", cmd: "acls", uiIcon: "ui-icon-locked", disabled: true }, // {title: "Purge cache", cmd: "purge", uiIcon: "ui-icon-arrowrefresh-1-e"}, // {title: "Export as HTML", cmd: "html", uiIcon: "ui-icon-document"}, // {title: "Export as text", cmd: "text", uiIcon: "ui-icon-note"}, // {title: "Namespace", cmd:'ns'}, // {title: "----", cmd:'ns'}, // {title: "Search...", cmd: "search", uiIcon: "ui-icon-search"}, // {title: "New page...", cmd: "npage", uiIcon: "ui-icon-plus"},// children:[] // {title: "Headpage here", cmd: "nshpage", uiIcon: "ui-icon-plus"}, // {title: "Acls", cmd: "nsacls", uiIcon: "ui-icon-locked"} // ], // beforeOpen: function(event, ui) { // var node = jQuery.ui.fancytree.getNode(ui.target); // // Modify menu entries depending on node status // $tree.contextmenu("enableEntry", "toc", node.isFolder()); // // Show/hide single entries // $tree.contextmenu("showEntry", "pg", !node.isFolder()); // $tree.contextmenu("showEntry", "revs", !node.isFolder()); // $tree.contextmenu("showEntry", "toc", !node.isFolder()); // $tree.contextmenu("showEntry", "edit", !node.isFolder()); // $tree.contextmenu("showEntry", "hpage", !node.isFolder()); // $tree.contextmenu("showEntry", "spage", !node.isFolder()); // $tree.contextmenu("showEntry", "cpage", !node.isFolder()); // $tree.contextmenu("showEntry", "acls", !node.isFolder()); // $tree.contextmenu("showEntry", "purge", !node.isFolder()); // $tree.contextmenu("showEntry", "html", !node.isFolder()); // $tree.contextmenu("showEntry", "text", !node.isFolder()); // // $tree.contextmenu("showEntry", "ns", node.isFolder()); // $tree.contextmenu("showEntry", "search", node.isFolder()); // $tree.contextmenu("showEntry", "npage", node.isFolder()); // $tree.contextmenu("showEntry", "nshpage", node.isFolder()); // $tree.contextmenu("showEntry", "nsacls", node.isFolder()); // // // Activate node on right-click // node.setActive(); // // Disable tree keyboard handling // ui.menu.prevKeyboard = node.tree.options.keyboard; // node.tree.options.keyboard = false; // }, // close: function(event, ui) { // // Restore tree keyboard handling // // console.log("close", event, ui, this) // // Note: ui is passed since v1.15.0 // var node = jQuery.ui.fancytree.getNode(ui.target); // node.tree.options.keyboard = ui.menu.prevKeyboard; // node.setFocus(); // }, // select: function(event, ui) { // var node = jQuery.ui.fancytree.getNode(ui.target); // alert("select " + ui.cmd + " on " + node); // } // }); }); }); /** * Add button action for the indexmenu wizard button * * @param {jQuery} $btn Button element to add the action to * @param {Array} props Associative array of button properties * @param {string} edid ID of the editor textarea * @return {boolean} If button should be appended */ function addBtnActionIndexmenu($btn, props, edid) { indexmenu_wiz.init(jQuery('#' + edid)); $btn.on('click', function () { indexmenu_wiz.toggle(); return false; }); return true; } // try to add button to toolbar if (window.toolbar !== undefined) { window.toolbar[window.toolbar.length] = { "type": "Indexmenu", "title": "Insert the Indexmenu tree", "icon": "../../plugins/indexmenu/images/indexmenu_toolbar.png" } } /** * functions for js index renderer and contextmenu */ var IndexmenuUtils = { /** * Determine extension from given theme dir name * * @param {string} themedir name of theme dir * @returns {string} extension gif, png or jpg */ determineExtension: function (themedir) { let extension = "gif"; let posext = themedir.lastIndexOf("."); if (posext > -1) { posext++; let ext = themedir.substring(posext, themedir.length).toLowerCase(); if ((ext === "png") || (ext === "jpg")) { extension = ext; } } return extension; }, /** * Create div with given id and class on body and return it * * @param {string} id picker id * @param {string} cl class(es) * @return {jQuery} jQuery div */ createPicker: function (id, cl) { return jQuery('
') .addClass(cl || 'picker') .attr('id', id) .css({position: 'absolute'}) .hide() .appendTo('body'); } };