1const plugin = document.getElementById('plugin_info'); 2const component = document.getElementById('plugin_components'); 3const output = document.getElementById('output'); 4updatePluginNameStatus(); 5 6/** 7 * disable the plugin name field when a component has been added 8 */ 9function updatePluginNameStatus() { 10 plugin.querySelector('input').readOnly = output.children.length > 0; 11 document.querySelector('button[type=submit]').disabled = output.children.length === 0; 12} 13 14/** 15 * Create the HTML element for a component 16 * 17 * @param {string} plugin The plugin base name 18 * @param {string} type The component type 19 * @param {string} name The component name 20 * @returns {HTMLLIElement|null} null if the component already exists 21 */ 22function createComponentElement(plugin, type, name) { 23 let id = `${type}_plugin_${plugin}`; 24 if (name !== '') { 25 id += `_${name}`; 26 } 27 28 if (document.getElementById(`component-${id}`)) { 29 return null; 30 } 31 32 const li = document.createElement('li'); 33 li.id = `component-${id}`; 34 li.dataset.type = type; 35 li.dataset.name = name; 36 37 const hidden = document.createElement('input'); 38 hidden.type = 'hidden'; 39 hidden.name = 'components[]'; 40 hidden.value = id; 41 li.append(hidden); 42 43 const remove = document.createElement('button'); 44 remove.type = 'button'; 45 remove.innerText = 'X'; 46 remove.title = 'Remove this component'; 47 remove.addEventListener('click', function (event) { 48 li.remove(); 49 updatePluginNameStatus(); 50 }); 51 li.append(remove); 52 53 const label = document.createElement('span'); 54 label.innerText = id; 55 li.append(label); 56 57 58 // add auto-completion for events 59 if (type === 'action') { 60 const events = document.createElement('input'); 61 events.type = 'text'; 62 events.name = `options[${id}]`; 63 events.placeholder = 'EVENTS_TO_HANDLE, ...'; 64 li.append(events); 65 new Awesomplete(events, { 66 list: ACTION_EVENTS, 67 filter: function (text, input) { 68 return Awesomplete.FILTER_CONTAINS(text, input.match(/[^,]*$/)[0]); 69 }, 70 71 item: function (text, input) { 72 return Awesomplete.ITEM(text, input.match(/[^,]*$/)[0]); 73 }, 74 75 replace: function (text) { 76 var before = this.input.value.match(/^.+,\s*|/)[0]; 77 this.input.value = before + text + ", "; 78 } 79 }); 80 } 81 82 // allow picking the renderer to extend 83 if(type === 'renderer') { 84 const renderers = document.createElement('select'); 85 renderers.name = `options[${id}]`; 86 87 const opt1 = document.createElement('option'); 88 opt1.value = 'Doku_Renderer_xhtml'; 89 opt1.innerText = 'Extend Doku_Renderer_xhtml'; 90 91 const opt2 = document.createElement('option'); 92 opt2.value = 'Doku_Renderer'; 93 opt2.innerText = 'Extend Doku_Renderer'; 94 95 renderers.append(opt1); 96 renderers.append(opt2); 97 li.append(renderers); 98 } 99 100 101 return li; 102} 103 104 105/** 106 * Add a component to the output list 107 */ 108component.querySelector('button').addEventListener('click', function (event) { 109 const plugin_base = plugin.querySelector('input'); // first input field is plugin base name 110 const component_type = component.querySelector('select'); 111 const component_name = component.querySelector('input'); 112 113 if (!plugin_base.validity.valid) { 114 plugin_base.reportValidity(); 115 plugin_base.focus(); 116 return; 117 } 118 119 if (!component_name.validity.valid) { 120 component_name.reportValidity(); 121 component_name.focus(); 122 return; 123 } 124 125 const li = createComponentElement(plugin_base.value, component_type.value, component_name.value); 126 if (!li) return; 127 128 output.appendChild(li); 129 updatePluginNameStatus(); 130}); 131