1/* DokuWiki MoaiEditor Captcha.js file 2 Version : 0.5a (May 6, 2026) 3 Author : MoaiTools <info@moaitools.org> 4 License : GPL 3 (http://www.gnu.org/licenses/gpl.html) */ 5 6/* This class integrates www.dokuwiki.org/plugin:captcha into the editor. 7 8 Functions of this class: 9 - Moves the captcha wrapper to a suitable position depending on mode (desktop, mobile). 10 - Intercepts the Save button click if the captcha input is empty, so that instead of 11 submitting the form the user is reminded to fill the captcha. 12*/ 13MoaiEditor.Captcha = class { 14 15 constructor() { 16 this.userWasReminded = false; 17 } 18 // ┌───────────────────────────────────┐ 19 // │ Public │ 20 // └───────────────────────────────────┘ 21 22 initBeforeLayout () { 23 if (!this.exists()) 24 return; 25 26 // Add the form attribute to the input elements (as they are no longer inside the form) 27 const inputs = this.wrapper.querySelectorAll("input"); 28 for (let input of inputs) 29 input.setAttribute('form', 'dw__editform'); 30 31 // Reduce margins and paddings 32 this.wrapper.style.margin = '0'; 33 this.wrapper.style.padding = '5px 10px'; 34 35 // Intercept the Save button action 36 const original_onclick_save = moaiEditor.buttons.save.__onClick; 37 moaiEditor.buttons.save.__onClick = function (event) { 38 39 // Submit the form if the captcha input is not empty, or if we reminded the user already 40 const self = moaiEditor.plugins.captcha; 41 const textinput = self.wrapper.querySelector("input[type=text]"); 42 if (textinput.value.length > 0 || self.userWasReminded) 43 return original_onclick_save.bind(moaiEditor.buttons.save, event); 44 45 // Else, remind the user 46 const msg = "Please fill the captcha below."; 47 event.preventDefault(); // Prevent form submit 48 moaiEditor.dokuMessage(msg, 2); // Show message 49 self.wrapper.style.background = "#ffc"; // Highlight form 50 moaiEditor.layout.goLeft(); // In mobile mode scroll to the left side to show the form 51 self.userWasReminded = true; // Remind the user only once (then make the Save button work as normal again) 52 } 53 } 54 onSpecificLayout(mode) { 55 if (this.wrapper === null) 56 return; 57 if (mode == 'desktop') { 58 moaiEditor.layout.desktop.footerLeft.appendChild(this.wrapper); 59 } 60 if (mode == 'vphone') { 61 const container = document.querySelector("#moaied__phone_left_main"); 62 const separator = document.querySelector("#moaied__phone_left_main_separator"); 63 const element = moaiEditor.createHTML('<div><label>Captcha</label></div>'); 64 //this.wrapper.style.background = "rgba(255,255,255,0.4)"; 65 element.appendChild(this.wrapper); 66 container.insertBefore (element, separator); 67 } 68 } 69 // ┌───────────────────────────────────┐ 70 // │ Input events │ 71 // └───────────────────────────────────┘ 72 // ┌───────────────────────────────────┐ 73 // │ Private │ 74 // └───────────────────────────────────┘ 75 76 exists () { 77 this.wrapper = document.querySelector("#wiki__editbar div.plugin__captcha_wrapper"); 78 if (this.wrapper === null) 79 return false; 80 return true; 81 } 82 83 84}; // End Class 85 86 87 88