Skip to content

Instantly share code, notes, and snippets.

@Akjosch
Created July 8, 2020 19:46
Show Gist options
  • Save Akjosch/3370a91675762d3707e119e6c1729546 to your computer and use it in GitHub Desktop.
Save Akjosch/3370a91675762d3707e119e6c1729546 to your computer and use it in GitHub Desktop.
/* 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) => {
State.variables.args = args;
Wikifier.wikifyEval(content);
});
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) {
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 = 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.');
}
triggerHandlers(ids, undefined);
}
});
Macro.add('editable', {
isAsync: true,
optRe: /^(\w+)=(.*)$/,
handler() {
const opts = this.args
.map((txt) => typeof txt === 'string' && txt.match(this.self.optRe))
.filter((opt) => !!opt)
.reduce((res, val) => { res[val[1]] = val[2]; return res; }, {});
const args = this.args.filter((txt) => typeof txt !== 'string' || !txt.match(this.self.optRe));
const val = (args.length === 0 || typeof args[0] === 'undefined' ? '' : String(args[0]));
const el = document.createElement("span");
el.textContent = val;
if(opts.id) {
el.id = opts.id;
}
if(opts.allowempty) {
opts.allowempty = !(opts.allowempty === 'false' || opts.allowempty === '');
}
if(opts.maxlength) {
opts.maxlength = Number(opts.maxlength);
if(!Number.isSafeInteger(opts.maxlength) || opts.maxlength <= 0) {
delete opts.maxlength;
}
}
const $el = jQuery(el);
const $edittextbox = jQuery('<input type="text" class="macro-editable"></input>');
$edittextbox.click(function(e) {
e.stopPropagation();
});
if(opts.maxlength) {
$edittextbox.attr("maxlength", opts.maxlength);
}
if(opts.hint) {
$edittextbox.attr("placeholder", opts.hint);
}
var tempVal;
function submitChanges() {
const val = $edittextbox.val().trim();
if(opts.allowempty || val !== '') {
$el.html($edittextbox.val());
}
$el.show();
$el.trigger('editsubmit', [$el.html()]);
if(opts.change) {
triggerHandlers([opts.change], [$el.html()]);
}
jQuery(document).off('click', submitChanges);
$edittextbox.detach();
}
function startEditing() {
tempVal = $el.html();
$edittextbox.val(tempVal).insertBefore($el).off('keypress').off('keydown')
.on('keydown', function(e) {
const code = (e.keyCode ? e.keyCode : e.which);
if(code === 9) {
if(!opts.allowempty && $edittextbox.val().trim() === '') {
e.preventDefault();
} else {
submitChanges();
}
}
})
.on('keypress', function(e) {
if(opts.allowempty || $edittextbox.val().trim() !== '') {
const code = (e.keyCode ? e.keyCode : e.which);
if(code === 13) {
submitChanges();
}
}
})
.focus().select();
$el.hide();
jQuery(document).one('click', submitChanges);
}
$el
.addClass('macro-editable')
.attr({
role: "textbox",
tabindex: 0
})
.on('dblclick', startEditing)
.on("keypress", function(ev) {
if(ev.which === 13 || ev.which === 32) {
ev.preventDefault();
startEditing();
}
})
.appendTo(this.output);
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment