#include watcher.js const MszMessagesActionButton = function(button, stateless) { if(!(button instanceof Element)) throw 'button must be an element'; const stateful = !stateless; const pub = {}; const icon = button.querySelector('.js-messages-button-icon i'); const label = button.querySelector('.js-messages-button-label'); const update = () => { if(stateful) { icon.className = button.dataset[`${button.dataset.state}Ico`]; label.textContent = button.dataset[`${button.dataset.state}Str`]; } }; pub.update = update; const stateWatcher = new MszWatcher; const getState = () => button.dataset.state !== 'inactive'; const setState = state => { button.dataset.state = state ? 'active' : 'inactive'; update(); stateWatcher.call(getState()); }; if(stateful) { pub.getState = getState; pub.setState = setState; pub.watchState = handler => { stateWatcher.watch(handler, getState()); }; pub.unwatchState = handler => { stateWatcher.unwatch(handler); }; } let clickAction; const click = async () => { if(clickAction !== undefined) { if(stateful) { const result = await clickAction(getState()); if(typeof result === 'boolean') setState(result); } else await clickAction(); } }; pub.click = click; button.addEventListener('click', () => click()); update(); pub.setAction = action => { if(typeof action !== 'function') throw 'action must be a function'; clickAction = action; }; let preventEnable = false; pub.getEnabled = () => !button.disabled; pub.setEnabled = state => { if(!preventEnable) button.disabled = !state; }; pub.disableWith = async callback => { if(typeof callback !== 'function') throw 'callback must be a function'; if(preventEnable) throw 'preventEnable is true'; preventEnable = true; const wasDisabled = button.disabled; button.disabled = true; try { return await callback(); } finally { button.disabled = wasDisabled; preventEnable = false; } }; pub.setHidden = state => { button.hidden = state; }; return pub; };