Reputation: 11
I'm trying to put together a thing that will add tooltips to a page whenever a word has a definition. I have partially succeeded in doing so. The thing: https://codepen.io/veav/pen/vYqdEdB
The setup is intended to grab spans from the page with a class of "check" and check if their content can be found in a set of keywords. If it finds a keyword, it splices a new span in place with a class of "tooltip", then opens the next "check" span to house the remaining content.
Right now, one of three things is happening at any given time: it only splices a tooltip onto the last match for a keyword, it only splices tooltips for the last keyword in the dictionary, or it splices tooltips into the meta text of a tooltip span, because a tooltip's text can potentially contain a keyword. The class "check" is intended to prevent this.
I know that this is 200% user error but I don't know the right questions to ask in order to fix my mistakes. Am I completely off-base with my approach?
const keywords = {
"background": "pg 20. Your pilot`s background describes their life before they became a mech pilot.",
"invoke": "pg 20. Outside of combat, you (or the GM) can invoke your pilot`s background to receive 1 ACCURACY or 1 DIFFICULTY on any skill check, if their background is relevant.",
"ACCURACY": "pg 13. ACCURACY adds 1d6 to a roll. Multiple ACCURACY dice are a keep-highest roll. ACCURACY and DIFFICULTY cancel each other out on a 1:1 basis.",
"DIFFICULTY": "pg 13. DIFFICULTY adds 1d6 to a roll. Multiple DIFFICULTY dice are a keep-highest roll. ACCURACY and DIFFICULTY cancel each other out on a 1:1 basis."
};
function tooltipper() {
var spans = document.getElementsByClassName('check');
for (var y in keywords) {
for (var x of spans) {
console.log('checking ' + y + ' against span ' + x.innerHTML + '...');
var spantipper = inserttip(x, y);
if (typeof spantipper !== 'undefined') {
console.log('final before: ' + x.innerHTML);
x.innerHTML = spantipper;
console.log('final after: ' + x.innerHTML);
} else {
console.log(y + ' not found in span' + x.innerHTML.substr(0, 50) + '...');
}
}
}
}
function inserttip(brick, keyword) {
var bricktext = brick.innerHTML;
var brickpost = '';
var brickpre = brick.innerHTML;
var match = brickpre.indexOf(keyword);
var ogmatch = bricktext.indexOf(keyword);
while (match != -1) {
console.log(keyword + ' found')
var brickopen = match;
var brickclose = match + keyword.length;
var remaining = brickpre.length - brickclose;
brickpost += brickpre.substr(0, match);
brickpost += '</span><span class="tooltip" data-tooltip="' + keywords[keyword] + '" data-tooltip-position="bottom">' + keyword + '</span><span class="check">';
console.log('set: ' + brickpost)
brickpre = brickpre.substr(brickclose, remaining);
console.log('marched: ' + brickpre.substr(0, 50) + '...');
match = brickpre.indexOf(keyword);
if (match == -1) {
console.log('end of matches for ' + keyword);
}
}
if (ogmatch != -1) {
brickpost += brickpre;
return brickpost;
}
}
Upvotes: 1
Views: 46
Reputation: 11
With @Barmar's insight, it's not dumb if it works:
function tooltipper() {
var spans = document.getElementsByClassName("check");
for (var x of spans) {
var step1 = x.innerHTML;
for (var y in keywords) {
var step0 = '%%'+y+'%%';
step1 = step1.replaceAll(y, step0);
}
for (var y in keywords) {
var step0 = '%%'+y+'%%';
var step3 =
'</span><span class="tooltip" data-tooltip="' +
keywords[y] +
'" data-tooltip-position="bottom">' +
y +
'</span><span class="check">';
step1 = step1.replaceAll(step0, step3);
}
x.innerHTML = step1;
}
}
There's still some residual nonsense if two definitions match on the same keyword (e.g. "invoke" and "invoked") but grammar isn't everything.
Upvotes: 0