tmedwards / sugarcube-2

SugarCube is a free (gratis and libre) story format for Twine/Twee.
https://www.motoslave.net/sugarcube/2/
BSD 2-Clause "Simplified" License
185 stars 42 forks source link

A way to directly provide DOM tree for specific passages #111

Open ezsh opened 3 years ago

ezsh commented 3 years ago

Could you, please, add a way to supply DOM tree directly to completely bypass text parsing for specific passages? Something like:

function userRenderedPassageContent(passageName) {
   const fragment = document.createDocumentFragment();
   ...
   return fragment;
}

Story.registerPassageRenderer("somePassageName", ["tagA", "tagB"], userRenderedPassageContent);
...
Story.unRegisterPassageRenderer("somePassageName");
tmedwards commented 3 years ago

You're going to need to explain that.

ezsh commented 3 years ago

I have been often finding myself creating passages consisting of a single <<replace>><<print aJSFunction()>><</replace>>, and that was almost OK. But I also want to inject a DOM fragment in a passage, and those can be as large as the whole passage content (for example, a drawing of a charachter). For that I register a :passagerender event handler and create a dispatch function to call appropriate content rendering function. This leaves me with empty passages in the .twee files.

So I think it would be good to skip the rendering of empty passages and firing the :passagerender event. Instead SugarCube could contain the dispatch table and I would not need to create empty passages in .twee. Hope this explanation helps.

ezsh commented 3 years ago

Maybe just make Story.add() and the the rendering part of the Passage class API public? Then one will be able to inherit Passage, override its render() method and add it to the story.

HiEv commented 3 years ago

@ezsh - If that's the case, why not just have a single empty passage and use a variable instead of a passage name to control what's rendered by your :passagerender event handler? (Or even just put the handler in that passage?)

It just seems like you're going about things in an unnecessarily complicated way, and then you're asking for help to make it less complicated.

ezsh commented 3 years ago

Thank you for the suggestion, but I don't want to accept it. To me it looks no simpler than what I have now. The extension from your suggestion is a way to create widgets that return DOM tree. In any case there is a shortcoming in such an implementation: the dispatch function duplicates story logic, assigning content to passage names or other identifiers.

ezsh commented 3 years ago

Story.add() would be a better choice, because of passage tags: there is no way to provide tags from render event handlers.