SugarCube: Adding Keyboard Shortcuts globally using passagedisplay – how to adjust HTML after <<replace>> macro?

Hi all

I want to do some global transformations on the rendered HTML. More accurately, I want to add keyboard shortcuts to the links provided in the story. I am doing so quite successfully by using SugarCube’s passagedisplay event. This works fine, but only initially. At some instances, some parts of the text is being rewritten using SugarCubes <<replace>> macro. The passagedisplay event is not fired again. Is there any way I can hook into the replace macro so I can re-run my script on the replaced text?

Twine Version: Tweego 1.3.0
Story Format: SugarCube 2.24.0

Cheers

You might want to take a look at the “Keyboard Link Navigation” portion of my Twine/SugarCube sample code collection. It gives you a chunk code you can add to your JavaScript section to add keyboard-based link navigation in your Twine/SugarCube games. It also automatically detects new links added to the passage after the passage is displayed, such as from links within a <<replace>> macro.

Hope that helps! :grinning:

P.S. You’re using a fairly old version of SugarCube, so you might want to consider updating. The current version is v2.33.2 and it includes a bunch of new features, plus some bug fixes.

Ah, I completely forgot about setInterval(…). Not a clean solution in my opinion, but a solution nontheless. Thank you for the suggestion!

If you don’t want to use setInterval() to watch for page changes, you should be able to use MutationObserver instead. Its entire purpose is to fire callbacks when any element on the page changes.

Here are the docs for it: https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver

Just make sure that you don’t accidentally accumulate intervals, such as by adding one each passage and not clearing the previous one. That would cause your page to get slower for every interval running.

Alternately, you could just make a function you call to do a “refresh” after you do a <<replace>> or anything similar that would add a link to the page. Though that’s less automatic than checking at intervals.

Have fun! :grinning:

Thank you for the suggestion. I did not even knew the MutationObserver exists.

I ended up with

document.getElementById('story').querySelectorAll('a.link-internal').forEach(link => link.addEventListener('click', add_keyboard_shortcuts));

. The ‘click’ event is handled after SugarCube’s replace macro. Very convenient! add_keyboard_shortcuts is idempotent and quite similar to what HiEv is offering.

Problem solved. Thank both of you.

1 Like