Created
July 8, 2020 19:46
-
-
Save Akjosch/3370a91675762d3707e119e6c1729546 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* 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