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