Skip to content

Instantly share code, notes, and snippets.

@Akjosch
Last active August 24, 2020 07:32
Show Gist options
  • Save Akjosch/190c6750d90b3661bfebc8b288ac7cd7 to your computer and use it in GitHub Desktop.
Save Akjosch/190c6750d90b3661bfebc8b288ac7cd7 to your computer and use it in GitHub Desktop.
SugarCube macros for delayed execution handlers/triggers
/* SugarCube code block to be executed later */
Macro.add('handler', {
tags: null,
isAsync: true,
validIdRe: /^[A-Za-z_]\w*$/,
handler() {
if(this.args.length === 0) {
return this.error('Missing handler ID(s).');
}
const ids = Array.from(this.args);
const wrongId = ids.find((id) => typeof id !== 'string' || !id.match(this.self.validIdRe))
if(!!wrongId) {
return this.error('The value ' + JSON.stringify(wrongId) + ' isn\'t a valid ID.');
}
const content = this.payload[0].contents.trim();
if(content !== '') {
this.addShadow("$args");
const func = this.createShadowWrapper((args) => {
let argsCache = undefined;
let haveArgsCache = false;
if(State.variables.hasOwnProperty('args')) {
argsCache = State.variables.args;
haveArgsCache = true;
}
State.variables.args = args;
Wikifier.wikifyEval(content);
if(haveArgsCache) {
State.variables.args = argsCache;
} else {
delete State.variables.args;
}
});
const store = State.temporary["_handler"] = State.temporary["_handler"] || {};
ids.forEach((id) => {
if(!store[id]) {
store[id] = [];
}
store[id].push(func);
});
}
}
});
function triggerHandlers(ids, data) {
const store = State.temporary["_handler"];
if(store) {
if(typeof ids === 'string') {
ids = [ids];
}
ids.forEach((id) => {
if(store[id]) {
store[id].forEach((func) => {
try {
func(data);
} catch(e) {
console.log(e);
}
});
}
})
}
}
/* trigger some handler from before */
Macro.add('trigger', {
validIdRe: /^[A-Za-z_]\w*$/,
handler() {
if(this.args.length === 0) {
return this.error('Missing handler ID(s).');
}
const ids = (this.args[0] instanceof Array ? this.args[0].map((id) => String(id)) : [String(this.args[0])]);
const wrongId = ids.find((id) => typeof id !== 'string' || !id.match(this.self.validIdRe))
if(!!wrongId) {
return this.error('The value ' + JSON.stringify(wrongId) + ' isn\'t a valid ID.');
}
triggerHandlers(ids, this.args.slice(1));
}
});
/* attach a handler to a generic JS/jQuery/SugarCube event */
Macro.add('attach', {
isAsync: true,
handler() {
if(this.args.length === 0) {
return this.error('Missing arguments.');
}
if(this.args.length === 1) {
return this.error('Missing event ID.');
}
if(this.args.length === 2) {
return this.error('Missing handler ID(s).');
}
const selector = this.args[0];
const event = this.args[1];
const ids = Array.from(this.args.slice(2)).map((id) => String(id));
// Call later
setTimeout(() => {
jQuery(selector).on(event, function(ev) {
triggerHandlers(ids, [ev]);
})
}, 40);
}
});
/* note: Only do this if you want to expose the triggerHandlers() function as setup.trigger() */
setup.trigger = triggerHandlers;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment