xref: /plugin/visualindex/script/toolbar.js (revision 3c9c7f3beeea1dce712c368cb507b309c63f5d06)
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