1/* DokuWiki MoaiEditor Scroll_to.js file 2 Author : MoaiTools <info@moaitools.org> 3 License : GPL 3 (http://www.gnu.org/licenses/gpl.html) */ 4 5/* Template class 6 ‾‾‾‾‾‾‾‾‾‾‾‾‾‾ 7 This is the class for handling templates. It serves 2 purposes: 8 9 1. Add a button to the edit page of Dokuwiki in order to start the editor. 10 2. Find all the necessary elements in the page needed by the editor 11 (e.g. textarea, toolbar, save and cancel buttons, etc). 12 13 If you are using a template that has the HTML elements in different locations 14 in the DOM tree or they have different ids, the elements might not be found 15 by this class, and in that case you can create a new class that overrides 16 specific methods in order to support you template. 17 18 Also you can override the method that positions the toggle button that 19 starts MoaiEditor, to put it anywhere you want in the page. 20 21 See 'templates/sprintdoc.js' for an example of such a class. 22 23 If you want to style MoaiEditor according to specific needs of your template, 24 you can add a CSS file with the same name of your template file. 25 26 See 'templates/sprintdoc.css' for an example of such a css file. 27 28 See 'README' to learn how to support a new template. 29*/ 30MoaiEditor.Template = class { 31 32 constructor(name, css) { 33 34 this.name = name; // Template name for console messages 35 this.css = css; // CSS file (or null) 36 37 // Console messages 38 this.prefix = "moaiEditor templates/"+name+".js :: "; 39 this.suffix = ".\nThis is usually due to an incompatibility with your template, which is easy to fix.\nSee the README file in lib/plugins/moaieditor/ for instructions on how to make your template compatible with this editor.\nMoaiEditor will not run until this problem is resolved."; 40 41 // Flag to inform others that all HTML elements have been found and the editor toggle button has been added 42 this.ready = false; 43 44 // Methods for finding each element we need for the editor 45 this.finders = { 46 hide : this.find_ElementsToHide, 47 messages : this.find_Messages, 48 toolbar : this.find_Toolbar, 49 editSummary : this.find_EditSummary, 50 editForm : this.find_EditForm, 51 editBar : this.find_EditBar, 52 textarea : this.find_Textarea, 53 editButtons : this.find_EditButtons, 54 //pagetools : this.find_Pagetools, 55 }; 56 // Handles of each element found (to be used later) 57 this.elements = {}; 58 } 59 // ──────────────────────────────────── 60 importance() { 61 return 1; // See the README file of this plugin to see an explanation of this value 62 } 63 // ──────────────────────────────────── 64 // Load an on-demand CSS file and add it to the head of the document 65 loadCSS() { 66 if (!this.css) 67 return; 68 const link = moaiEditor.createHTML(`<link href="${this.css}" rel="stylesheet" type="text/css"/>`); 69 document.head.appendChild(link); 70 } 71 // ──────────────────────────────────── 72 detectTemplate() { 73 return true; 74 } 75 // ──────────────────────────────────── 76 findElements() { 77 this.counter = -1; 78 this.interval = setInterval(this.onInterval.bind(this), 150); 79 } 80 // ──────────────────────────────────── 81 onInterval() { 82 var element; 83 this.counter += 1; 84 var not_found = []; 85 for (let name in this.finders) { 86 try { 87 element = this.finders[name].bind(this)(); 88 } catch(error) { 89 this.warn("The following problem occured while trying to find the '"+name+"' element(s):\n >> "+error+this.suffix); 90 moaiEditor.enabled.value = 'off'; 91 clearInterval(this.interval); 92 return; 93 } 94 if (element === undefined || element === null) 95 not_found.push(name); 96 this.elements[name] = element; 97 } 98 // Show retries 99 if (this.counter > 0) 100 this.log("Finding html elements - retry #"+this.counter+" - Missing: "+JSON.stringify(not_found)); 101 102 // Timeout 103 if (this.counter >= 50) { 104 this.warn("Failed to find all HTMl elements - Missing: "+JSON.stringify(not_found)+this.suffix); 105 clearInterval(this.interval); 106 return; 107 } 108 // Success 109 if (not_found.length == 0) { 110 this.log("All elements found"); 111 clearInterval(this.interval); 112 this.addStartButton.bind(this)(); 113 this.ready = true; 114 // Start the editor automatically if it is enabled 115 if (moaiEditor.enabled.value == 'on') 116 moaiEditor.startEditor(); 117 } 118 } 119 // ──────────────────────────────────── 120 log (message) { 121 } 122 warn (message) { 123 console.warn (this.prefix + message); 124 } 125 // ╭─────────────────────────────────────────────╮ 126 // ╰─────────────────────────────────────────────╯ 127 addStartButton() { 128 // Option 1: Add a proper button 129 this.elements.editButtons.appendChild(moaiEditor.start.button); 130 // Option 2: Add a small image (to blend well in the size control buttons area of the DokuWiki native editor) 131 //document.body.querySelector("#size__ctl").appendChild(moaiEditor.start.png); 132 } 133 find_ElementsToHide() { 134 // Find the elements which contain the old editor in order to be hidden. 135 // This method can return a single element or an array of elements. 136 return document.body.querySelector("#dokuwiki__site"); 137 } 138 find_Messages() { 139 // Find the displayed messages (info, error, success, notify) usually rendered by inc/html.php -> html_msgarea(). 140 // Some templates like bootstrap3 implement their own message rendering function and don't use html_msgarea(). 141 // In order to check how (and if) your template's messages are being displayed in this editor, you can simulate 142 // fake messages by either: 143 // a) Adding '&fakemsg' to the browser's URL while in edit mode. 144 // b) Set the MOAIED_FAKE_MESSAGES constant to true in: lib/plugins/moaieditor/action.php 145 var query = ""; 146 var container = "#dokuwiki__content div.pad.group "; 147 query += container + "div.error, "; 148 query += container + "div.info, "; 149 query += container + "div.success, "; 150 query += container + "div.notify "; 151 var messages = document.body.querySelectorAll(query); 152 return messages; 153 } 154 find_Pagetools() { 155 // Find the page-tools (the right-side vertical tool bar). 156 // We are not showing it now, but someone might need it in the future. 157 return document.body.querySelector("#dokuwiki__pagetools"); 158 } 159 find_Toolbar() { 160 // Find the toolbar (which holds the buttons above the textarea: bold, italics, underline, etc) 161 return document.body.querySelector("#tool__bar"); 162 } 163 find_EditForm() { 164 // Find the HTML form (which sends the changes back to the server) 165 return document.body.querySelector("#dw__editform"); 166 } 167 find_EditBar() { 168 // Find the container for the form buttons (save, preview, cancel) and size control buttons 169 return document.body.querySelector("#wiki__editbar"); 170 } 171 find_Textarea() { 172 // Find the textarea (where you edit the document) 173 return document.body.querySelector("#wiki__text"); 174 } 175 find_EditButtons() { 176 // Find the edit-buttons container (so we can insert the moaiEditor toggle button here) 177 return document.body.querySelector("#wiki__editbar .editButtons"); 178 } 179 find_EditSummary() { 180 // Find the container for the edit summary input fields (text input and checkbox) 181 return document.body.querySelector("#wiki__editbar .summary"); 182 } 183}; // End Class 184 185 186 187