/* DokuWiki MoaiEditor Button.js file Version : 0.5 (May 5, 2026) Author : MoaiTools License : GPL 3 (http://www.gnu.org/licenses/gpl.html) */ /* Class to create the buttons you see at the top. It can handle buttons with multiple states. */ /* DEF outer: name: for #id and local storage variable names type: submit icon: onClick: tooltip: tooltip_width: default_mode: classes: cls_remove: states[mode] icon: onClick: tooltip: next_mode: classes_add: classes_remove: */ MoaiEditor.Button = class { constructor(def) { // Parameters this.id = 'moaied__btn_'+def.name; this.name = def.name; this.outer = def.outer; this.type = def?.type ?? ''; this.icon = def?.icon; this.text = def?.text; this.onClick = def.onClick; this.classes = def?.classes; this.states = def?.states; this.tooltip = def?.tooltip; this.tooltip_width = def?.tooltip_width; this.tooltips = def?.tooltips; this.cls_remove = def?.cls_remove; this.default_mode = def?.default_mode; // Objects if (this.states !== undefined) { const mode_names = Object.keys(this.states); this.storage = new MoaiEditor.LocalStorage('btn_'+def.name, this.default_mode, mode_names); } // Init this.__init(); } // ──────────────────────────────────── __init() { const id = 'id="'+this.id+'"'; const icon = ''; const text = ''; const type = 'type="'+this.type+'"'; const classes = 'class="moaied-button moaied-tooltip '+(this.classes ?? '')+'"'; const tooltip = ''; const onclick = 'onclick="moaiEditor.buttons.'+this.name+'.__onClick(event)"'; const html = ''; this.handle = moaiEditor.createHTML(html); //document.body.appendChild(this.handle); this.update(); } // ──────────────────────────────────── __getTooltipWidthStyle() { if (!this.tooltip_width) return ''; const width = "width:"+this.tooltip_width+"px !important;"; const mleft = "margin-left: -"+Math.round(this.tooltip_width/2)+"px !important;"; return 'style="'+width+mleft+'"'; } // ──────────────────────────────────── __onClick(event) { // Toggle state and call state function if (this.mode !== null && this.states) { // Change the mode if applicable const next_mode = this.states[this.mode]?.next_mode; if (next_mode) this.mode = next_mode; // Get the current state const state = this.states[this.mode]; // Call a state function if defined if (state.onClick) state.onClick(event); } // Call a common function if defined if (this.onClick) this.onClick(event); // Update the button appearance this.update(); } // ──────────────────────────────────── update() { // Return if the browser local storage failed if (this.state === null) return; // Get the handle and the state var state = {}; if (this.states) state = this.states[this.mode]; // Icon var icon = ''; if (state?.icon ?? this.icon) { var icon = state?.icon ?? this.icon; if (!icon.startsWith(' i').innerHTML = icon; // Text var text = ''; if (state?.text ?? this.text) text = state?.text ?? this.text; this.handle.querySelector(':scope > span.moaied-button-text').innerHTML = text; // State tooltip var tooltip = this.handle.querySelector(':scope > span.moaied-tooltip-text'); if (state?.tooltip ?? this?.tooltip) tooltip.style.display = 'block'; // Button tooltip else tooltip.style.display = 'none'; tooltip.innerHTML = state?.tooltip ?? this?.tooltip; // Composite tooltip (tooltip is composed of messages added by several external processes) if (this.tooltips) { let html = ''; for (let key in this.tooltips) html += this.tooltips[key]; tooltip.innerHTML = html; } // Classes var classList = new MoaiEditor.ElementClassList(this.handle); classList.removeByString(this?.cls_remove); classList.removeByString(state?.cls_remove); classList.addByString(this?.classes); classList.addByString(state?.cls_add); // Mirror mode into data-attribute for convinience this.handle.dataset.moaiedMode = this.mode; } // ──────────────────────────────────── set mode(mode) { if (this.storage !== undefined) { this.storage.value = mode; this.update(); } } // ──────────────────────────────────── get mode() { if (this.storage !== undefined) { return this.storage.value; } else return null; } }; // End Class // ▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆▆ MoaiEditor.ElementClassList = class { constructor(node) { this.node = node; } // ──────────────────────────────────── addByString(string) { for (let name of this.splitString(string)) this.node.classList.add(name) } // ──────────────────────────────────── removeByString(string) { for (let name of this.splitString(string)) this.node.classList.remove(name) } // ──────────────────────────────────── splitString(string) { if (!string) return []; var array = []; for (let name of string.split(" ")) { name = name.trim(); if (name.length > 0) array.push(name); } return array; } }; // End Class