1if (typeof window.toolbar !== 'undefined') { 2 function shouldShowInEditorMenu() { 3 const raw = window.JSINFO && 4 JSINFO.plugins && 5 JSINFO.plugins.visualindex 6 ? JSINFO.plugins.visualindex.show_in_editor_menu 7 : true; 8 9 if (typeof raw === 'boolean') return raw; 10 const normalized = String(raw).trim().toLowerCase(); 11 return !(normalized === '0' || normalized === 'false' || normalized === 'off' || normalized === 'no'); 12 } 13 14 function buildVisualIndexSyntax(values) { 15 let syntax = '{{visualindex>' + (values.namespace || '.'); 16 if (values.filter) syntax += ';filter=' + values.filter; 17 if (values.desc) syntax += ';desc=1'; 18 if (values.medias) syntax += ';medias=1'; 19 syntax += '}}'; 20 return syntax; 21 } 22 23 function insertAtSelection(area, text) { 24 const selection = DWgetSelection(area); 25 const before = area.value.substring(0, selection.start); 26 const after = area.value.substring(selection.end); 27 area.value = before + text + after; 28 29 const pos = before.length + text.length; 30 area.focus(); 31 area.setSelectionRange(pos, pos); 32 } 33 34 function openVisualIndexDialog(onSubmit) { 35 const i18n = (window.LANG && LANG.plugins && LANG.plugins.visualindex) ? LANG.plugins.visualindex : {}; 36 const title = i18n.toolbar_popup_title || 'Visualindex'; 37 const insertLabel = i18n.toolbar_insert || 'Inserer'; 38 const cancelLabel = i18n.toolbar_cancel || 'Annuler'; 39 const namespaceLabel = i18n.toolbar_namespace || 'Namespace'; 40 const namespaceHelp = i18n.toolbar_namespace_help || 'Dossier. "." = dossier courant.'; 41 const namespacePickerLabel = i18n.toolbar_namespace_picker || 'Selectionner un dossier'; 42 const filterLabel = i18n.toolbar_filter || 'Filtre'; 43 const descLabel = i18n.toolbar_desc || 'Ordre descendant'; 44 const mediasLabel = i18n.toolbar_medias || 'Afficher les medias'; 45 46 const $dialog = jQuery('<div class="plugin_visualindex_form" title="' + title + '"></div>'); 47 48 $dialog.append('<label>' + namespaceLabel + '</label>'); 49 const $namespace = jQuery('<input type="text" class="edit" style="width:100%;" />').val('.'); 50 $dialog.append($namespace); 51 $dialog.append('<div style="font-size:.9em;color:#555;margin-top:4px;">' + namespaceHelp + '</div>'); 52 53 const $pickerWrap = jQuery('<div style="margin-top:8px;"></div>'); 54 const $pickerBtn = jQuery('<button type="button" class="btn btn-default"></button>').text(namespacePickerLabel); 55 const $nsList = jQuery('<select size="6" style="width:100%;margin-top:6px;display:none;"></select>'); 56 $pickerWrap.append($pickerBtn).append($nsList); 57 $dialog.append($pickerWrap); 58 59 $dialog.append('<label style="display:block;margin-top:8px;">' + filterLabel + '</label>'); 60 const $filter = jQuery('<input type="text" class="edit" style="width:100%;" />'); 61 $dialog.append($filter); 62 63 const $descWrap = jQuery('<label style="display:block;margin-top:10px;"></label>'); 64 const $desc = jQuery('<input type="checkbox" />').prop('checked', false); 65 $descWrap.append($desc).append(' ' + descLabel); 66 $dialog.append($descWrap); 67 68 const $mediasWrap = jQuery('<label style="display:block;margin-top:6px;"></label>'); 69 const $medias = jQuery('<input type="checkbox" />').prop('checked', false); 70 $mediasWrap.append($medias).append(' ' + mediasLabel); 71 $dialog.append($mediasWrap); 72 73 const normalizeNamespace = function (value) { 74 const val = String(value || '').trim(); 75 if (!val || val === '.') return '.'; 76 return val.replace(/:+$/, ''); 77 }; 78 79 const loadNamespaces = function () { 80 const q = normalizeNamespace($namespace.val()); 81 jQuery.get(DOKU_BASE + 'lib/exe/ajax.php', { 82 call: 'linkwiz', 83 q: q === '.' ? '' : (q + ':') 84 }).done(function (html) { 85 const $root = jQuery('<div></div>').html(String(html || '')); 86 const set = new Set(); 87 set.add('.'); 88 89 $root.find('a[title]').each(function () { 90 const titleVal = String(jQuery(this).attr('title') || ''); 91 if (!titleVal.endsWith(':')) return; 92 const ns = normalizeNamespace(titleVal); 93 if (ns) set.add(ns); 94 }); 95 96 $nsList.empty(); 97 Array.from(set).sort().forEach(function (ns) { 98 const opt = document.createElement('option'); 99 opt.value = ns; 100 opt.textContent = ns; 101 $nsList.append(opt); 102 }); 103 $nsList.show(); 104 }); 105 }; 106 107 $pickerBtn.on('click', function () { 108 loadNamespaces(); 109 }); 110 111 $nsList.on('change dblclick', function () { 112 const ns = String($nsList.val() || '.'); 113 $namespace.val(ns).trigger('focus'); 114 }); 115 116 $dialog.dialog({ 117 modal: true, 118 width: 460, 119 close: function () { 120 jQuery(this).dialog('destroy').remove(); 121 }, 122 buttons: [ 123 { 124 text: insertLabel, 125 click: function () { 126 onSubmit({ 127 namespace: String($namespace.val() || '.').trim() || '.', 128 filter: String($filter.val() || '').trim(), 129 desc: $desc.is(':checked'), 130 medias: $medias.is(':checked') 131 }); 132 jQuery(this).dialog('close'); 133 } 134 }, 135 { 136 text: cancelLabel, 137 click: function () { 138 jQuery(this).dialog('close'); 139 } 140 } 141 ] 142 }); 143 } 144 145 function addBtnActionVisualIndexPlugin($btn, props, edid) { 146 $btn.on('click', function (e) { 147 e.preventDefault(); 148 149 const area = document.getElementById(edid); 150 if (!area) return; 151 152 const submit = function (values) { 153 insertAtSelection(area, buildVisualIndexSyntax(values)); 154 }; 155 156 if (typeof jQuery !== 'undefined' && jQuery.fn && typeof jQuery.fn.dialog === 'function') { 157 openVisualIndexDialog(submit); 158 return; 159 } 160 161 const ns = window.prompt('Namespace', '.') || '.'; 162 submit({namespace: ns, filter: '', desc: false, medias: false}); 163 }); 164 } 165 166 if (shouldShowInEditorMenu()) { 167 toolbar[toolbar.length] = { 168 type: 'VisualIndexPlugin', 169 title: (window.LANG && LANG.plugins && LANG.plugins.visualindex && LANG.plugins.visualindex.toolbar_button) || 'Visualindex', 170 icon: '../../plugins/visualindex/images/folder.svg' 171 }; 172 } 173} 174