1/** 2 * Attaches the mechanics on our plugin's button 3 * 4 * @param {jQuery} $btn the button itself 5 * @param {object} props unused 6 * @param {string} edid the editor's ID 7 * @return {string} 8 */ 9function addBtnActionPlugin_watchcycle($btn, props, edid) { 10 'use strict'; 11 12 const pickerid = 'picker' + window.pickercounter; 13 const $picker = jQuery(createPicker(pickerid, [], edid)) 14 .attr('aria-hidden', 'true') 15 .addClass('plugin-watchcycle') 16 ; 17 window.pickercounter += 1; 18 const l10n = LANG.plugins.watchcycle; 19 20 /** 21 * AJAX request for users and groups 22 * Adapted from Struct plugin 23 * 24 * @param {function} fn Callback on success 25 * @param {string} id Call identifier 26 * @param {string} param Pass the parameter to backend 27 */ 28 const ajax_watchcycle = function(fn, id, param) { 29 let data = {}; 30 31 data['call'] = 'plugin_watchcycle_' + id; 32 data['param'] = param; 33 34 jQuery.post(DOKU_BASE + 'lib/exe/ajax.php', data, fn, 'json') 35 .fail(function (result) { 36 if (result.responseJSON) { 37 if (result.responseJSON.stacktrace) { 38 console.error(result.responseJSON.error + "\n" + result.responseJSON.stacktrace); 39 } 40 alert(result.responseJSON.error); 41 } 42 }); 43 }; 44 45 /** 46 * Autocomplete split helper 47 * @param {string} val 48 * @returns {string} 49 */ 50 const autcmpl_split = function(val) { 51 return val.split(/,\s*/); 52 }; 53 54 /** 55 * Autocomplete helper returns last part of comma separated string 56 * @param {string} term 57 * @returns {string} 58 */ 59 const autcmpl_extractLast = function(term) { 60 return autcmpl_split(term).pop(); 61 }; 62 63 const $watchCycleForm = jQuery('<form>'); 64 const usernameHTML = 65 '<div>' + 66 '<label for="plugin__watchcycle_user_input">' + l10n.label_username + '</label>' + 67 '<input id="plugin__watchcycle_user_input" name="watchcycle_user" type="text" required/>' + 68 '</div>'; 69 $watchCycleForm.append(jQuery(usernameHTML)); 70 const cycleHTML = 71 '<div>' + 72 '<label for="plugin__watchcycle_cycle_input">' + l10n.label_cycle_length + '</label>' + 73 '<input id="plugin__watchcycle_cycle_input" name="watchcycle_cycle" type="number" required min="1"/>' + 74 '</div>'; 75 76 $watchCycleForm.append(cycleHTML); 77 $watchCycleForm.append(jQuery('<button type="submit">' + l10n.button_insert + '</button>')); 78 const $cancelButton = jQuery('<button type="button">' + l10n.button_cancel + '</button>'); 79 $cancelButton.on('click', function () { 80 $watchCycleForm.get(0).reset(); 81 pickerClose(); 82 }); 83 $watchCycleForm.append($cancelButton); 84 85 // multi-value autocompletion 86 $watchCycleForm.find('input#plugin__watchcycle_user_input').autocomplete({ 87 source: function (request, cb) { 88 ajax_watchcycle(cb, 'get', autcmpl_extractLast(request.term)); 89 }, 90 focus: function() { 91 // prevent value inserted on focus 92 return false; 93 }, 94 select: function(event, ui) { 95 const terms = autcmpl_split(this.value); 96 // remove the current input 97 terms.pop(); 98 // add the selected item 99 terms.push(ui.item.value); 100 // add placeholder to get the comma-and-space at the end 101 terms.push(""); 102 this.value = terms.join(", "); 103 return false; 104 } 105 }); 106 107 $watchCycleForm.on('submit', function (event) { 108 event.preventDefault(); 109 $picker.find(".error").remove(); 110 const maintainers = $picker.find('[name="watchcycle_user"]').val().replace(new RegExp("[, ]+?$"), ""); 111 112 113 const cycle = $picker.find('[name="watchcycle_cycle"]').val(); 114 115 // validate maintainers 116 ajax_watchcycle(function (result) { 117 if (result === true) { 118 pickerInsert('~~WATCHCYCLE:' + maintainers + ':' + cycle + '~~', edid); 119 $watchCycleForm.get(0).reset(); 120 } else { 121 $picker.find("form").append('<div class="error">' + l10n.invalid_maintainers + '</div>'); 122 } 123 }, 'validate', maintainers); 124 125 }); 126 127 $picker.append($watchCycleForm).append($watchCycleForm); 128 129 // when the toolbar button is clicked 130 $btn.on('click', function (event) { 131 // open/close the picker 132 pickerToggle(pickerid, $btn); 133 event.preventDefault(); 134 }); 135} 136 137/** 138 * Add watchcycle_only parameter to search tool links if it is in the search query 139 * 140 * This should ideally be done in the backend, but this is currently (Greebo) not possible. Future DokuWiki release 141 * might include "unknown" search parameter, e.g. those from plugins like this one, by default. Then this can be 142 * removed. 143 */ 144jQuery(function () { 145 const $advancedOptions = jQuery('.search-results-form .advancedOptions'); 146 if (!$advancedOptions.length) { 147 return; 148 } 149 150 /**\ 151 * taken from https://stackoverflow.com/a/31412050/3293343 152 * @param param 153 * @return {*} 154 */ 155 function getQueryParam(param) { 156 location.search.substr(1) 157 .split("&") 158 .some(function(item) { // returns first occurence and stops 159 return item.split("=")[0] === param && (param = item.split("=")[1]) 160 }); 161 return param 162 } 163 164 if (getQueryParam('watchcycle_only') === '1') { 165 $advancedOptions.find('a').each(function (index, element) { 166 const $link = jQuery(element); 167 $link.attr('href', $link.attr('href') + '&watchcycle_only=1'); 168 }); 169 } 170}); 171