Development thread for Bisquixe (asking for js/jquery code review)

Ahh, I misunderstood! In that case yeah being able to change the background color of existing windows is the big thing that’s missing, and this allows it.

1 Like

The more I look into this, the more it seems that a lot of what I’d like to do is already available, but just not well known. So I think making easy-to-follow guides or templates might become more of my focus. But there’s definitely a few things I want to add!

1 Like

So just to say where I’m at right now, I was first messing with images, then saw that has mostly been taken care of in the past.

So now I’m focusing on being able to dynamically assign classes to bits of text, which, with my earlier code, lets you dynamically affect pieces of text all around. I tried to do this by directly adding a class attribute to every piece of text, but that required editing code in 20+ places and I had too many errors.

Instead, I temporarily hack the table of style names to change ‘user style 1’ to whatever class I want, then assign it using the standard assigning styles method, then change the table back.

But this only lets you have 1 or 2 elements with distinct styles in each block, so I added 80 more blank user styles, so you can do things like this:

I had trouble getting my code to run in one chunk, which is why this is two actions (JUMP prints M’s, all black, all with different classes, and SMELL alters them one at a time).

The goal of this is to allow people to, for instance, have 5 or 6 different colors of text in the same paragraph.

Edit: It’s hard to see, but it looks like you can add borders to individual chunks when doing this:
image

I don’t think anyone really needs 80 different user styles in a single paragraph, but I just wanted to leave room.

3 Likes

Loving this so far.

2 Likes

I’m glad!

I found out my trouble; I can’t create a new class when printing an element and change the CSS at the same time, because classes are ‘stored up’ in a buffer of some kind until the game decides to print it all at once. Since classes aren’t assigned until printing, changing CSS temporarily does nothing, except to text or elements that already exist.

On the other hand, I can create rules that last for a long time by appending new CSS rules to the header. They take instant effect, and last until changed by a further rule. However, if used repeatedly in a game, they could conceivably bloat the size of the webpage.

So I’m making two versions, set-css-slow, and set-css-fast. The slow one will cause no long-term lag but can’t be used mid-sentence, while the fast one could eventually cause lag but can be used mid-sentence.

Someone proficient at CSS can avoid both problems by pre-making classes they want and putting them in the css file; this avoids the problem entirely, because you can use set-any-class to change the class of some text to one of these pre-existing classes, which will take effect immediately and not add cruft to the header.

So I’ll probably make some of the most common class types that people might want and bundle them into the css; maybe one class for each color name recognized by CSS (like ‘red’ or ‘blue’).

2 Likes

Maybe I should just make my CSS extension to Glk in Parchment now. I’ve been waiting until I could do two things (get it working in RemGlk for the C interpreters, and work out the security implications), but I could do it very quickly in Parchment for Inform 7. It would let you set any CSS on the 11 Glk styles, or indeed to set any CSS on inline spans.

Changing the styles of already existing text is not on the table, sorry. (That probably needs Vorple-like JS. JS without Vorple is also a very long term plan.)

1 Like

I’ve been spending about 12 hours on trying to get right-justified, left-justified, and centered-text to work.

The issue is that the current code flow with glk applies styles to spans, but not to divs. All divs are identical ‘buffer line’ classes.

But applying text-align:right to a span does nothing; you have to apply it to the div.

So here’s what I tried and failed:

1-See how Quixe handles style hints (which is how this is intended to work).
Answer: the functions are blank.

2.Search for divs containing spans of certain classes, and apply css to just those divs.

Success! Except…

The way Quixe works is it builds an object iteratively and then pushes it all at once at the end. So you take each span and line them up one at a time, with their own style, wrap each line in a plain BufferLine div, append all the divs to a big thing (called frameel or something) then append that big chunk to the screen. Basically, one big chunk is put in all at once between each pair of command prompts.

The problem is that all glk calls are executed before this construction process. So if I say ‘find all divs containing spans with class .Style_left_align and align them left’, it only applies to text that has already been previously printed. So applying glk to search for the divs and change them doesn’t work because the divs don’t exist until after the ‘turn’ is over.

  1. Store a global variable for divs and just change the global variable with glk calls.

This works, but because all the divs are created at once at the end of the appending, it just gives all the divs that global style. So you can make the whole chunk of text right-aligned, but can’t alternate between them.

  1. Make a global array, during the glk phase push div changes in 2 into the array, and then right before appending the whole chunk, iterate through the array and change all of the divs.

One–for some reason global variables don’t work well for me, even if I declare them at the top, unless I make them attributes of the window. Two–this still doesn’t work because the divs still don’t exist before appending!

  1. Instead of a global style, make a function that returns a style and changes each time it’s called.

This works (I’ve gotten text to switch justification midway) but requires storing complex information.

  1. Model the way spans are given styles by Quixe and add a new attribute to divs in the same way.

Too hard for me to figure out.

So I’m pretty stumped. I think what I’m going to try when I get home is to automatically make all .BufferLine divs ‘hidden’ by default, and then right after appending the whole chunk of text, it won’t appear, and then I can run some code there that searches for divs containing spans with certain names in them, and assigns css to those divs.

Interestingly, css almost has a perfect solution to this. You can apply CSS to all elements that have a parent of a certain type. If there was a way to apply CSS to all elements that have a child of a certain type, I could just apply, for instance, left-align to all divs containing spans with the style name ‘.Style_left_align’.

Css has actually proposed a new syntax for this with the ‘has()’ selector but apparently it doesn’t work in firefox.

Anyway, all of this work is just for aligning text. Everything else already seems to work great.

3 Likes

Yes, welcome to my nightmare.

Dannii has a scheme for Parchment which involves applying the Glk span style to paragraphs as well as spans. (Not for text alignment, but for other paragraph stuff.) I don’t think it’s viable as the future Glk style plan because styles get double-stacked on spans, which makes it hard to explain to authors. (If you write a style CSS declaration with “font-size: 120%”, you wind up with 144%. I think.)

The closest I ever got to a workable idea was changing the GlkOte layer to track both paragraph and span styles, separately. With a well-defined DOM/CSS model, so that non-HTML interpreters (Gargoyle) could emulate it and get some of the same style info onto the screen.

I never got this idea fully worked out, much less working.

1 Like

Yeah, this part of the code seems really hard to mess with, and it sounds like you’ve given me even more reasons that that is so. If I can get left/right alignment working, I think that’s the only thing I’ll do with divs at all! The main case use I can think of is for emulating text message styles, with echoed input on right and output on left; I can already do the rounded box and colors, it’s just the alignment throwing me off.

Seeing how this thing works has truly driven home to me the gap between professional programmers (like you) and dilettantes like me. I would have no idea how to even start a complex program like this, and the purpose of so many things is still deeply obscure to me. It’s like finding an alien artifact and poking different buttons to figure out how it works.

3 Likes

Divs (and div-based styles) are good for:

  • Paragraph indentation
  • Left-right margins (think block quotes)
  • Bullet-style lists and other lists
  • Vertical space between paragraphs. (Inform assumes you can handle this by printing blank lines, but that’s not sufficient for good typography. And Inform’s blank-line rules are a well-known nightmare anyhow.)
2 Likes

Parchment/AsyncGlk already has alignment working!

This won’t happen unless someone manually adds some CSS that says .Style_header rather than span.Style_header. Which is what was recommended for original GlkOte, so it’s understandable that someone would do it, but it’s also easy to fix.

Maybe it would be better to change to separate classes for lines and spans? It wouldn’t be hard, and I doubt that would break anyone’s code.

That’s what I’ve done. The expanded AsyncGlk GlkOte protocol has a styles map with keys of div.Style_header or span.Style_user1, or blank to target the window itself.

That’s perhaps not the most ideal for non-HTML interpreters to receive, though an interpreter like Gargoyle wouldn’t be using the GlkOte protocol. For a console app or Discord bot that uses the protocol I guess it would have to parse the CSS target, which wouldn’t be too hard. If there was a better option I could change what AsyncGlk does.

1 Like

I think that would be better, yeah.

It seems your scheme is closer to mine than I thought! Might be worth nailing this down and thinking about the equivalent non-HTML-engine code. (Which would involve a CSS parser, but CSS isn’t a terrible language to parse, last I checked.)

2 Likes

I was thinking of exposing some functions to let you set CSS as 95% of the work has already been done, and it would just have to add entries into the protocol.

But I’ve just realised that my protocol additions don’t let you set on-the-fly paragraph styles, they can only be set on the 11 built in styles. But that wouldn’t be a big change to add.

1 Like

After 18 hours of work, it finally works!!!

In the end, the solution was simpler than almost everything else I tried.

I took this code that already exists to pack spans into divs:

const el = $('<span>',
             { 'class': 'Style_' + rstyle } );
if (rlink == undefined) {
    insert_text_detecting(el, rtext);
}
else {
    const ael = $('<a>',
                  { 'href': '#', 'class': 'Internal' } );
    ael.text(rtext);
    ael.on('click', build_evhan_hyperlink(win.id, rlink));
    el.append(ael);
}
divel.append(el);

and added right after it a single line of code:
el.parent().addClass('Buffer_'+rstyle);

What this does is mark every buffer with the styles of all spans inside of it, but with slightly different names. So if the span is Style_normal, the buffer is Buffer_normal.

I already had code to let ‘rstyle’ be anything I wanted. So now, the div’s can be anything I wanted, including the use cases Zarf mentioned above!

This doesn’t even require new GLK calls, since it just follows what you’re already doing with the style-adding glk call I already have.

I think I’m going to focus on making some nice demos of this, and then send out the first public version. I don’t have audio at all yet, but I’d rather add that in a later version.

9 Likes

LOL… actually I’m working with issues in coding this very puzzle ! the coding problem is implementing a certain twist… :wink:

Best regards from Italy,
dott. Piergiorgio.

1 Like

I’ve been messing around and I think it’s possible to get nice boxed quotations that float over the other window just the way z-code does.

I’ve gotten something like this by fooling around:
image

Not seen is the ‘More’ prompt that’s still up high. It’d take a lot of work to get this to look right, but if it does, I can include it as an option in Bisquixe to make boxed quotations look great again!

(it’s not centered and stuff because all I did was unmoor it with the fast-css and then play around in the console to see what it would look like vaguely centered. I’ll have to look up the CSS to get it right.)

4 Likes

It’s your call, in the end, but I think putting it in the center will look better than on the right.

/s

1 Like

It’s got a weird “inset” property that I don’t know where it’s coming from, as none of the code says “inset”, and it can’t be turned off, but it can be altered by setting inset to “50% !important” on .Windowrock_203 which is only used for quotes. After doing that it’s slightly off center. instead of anything formal I just tweaked it in the console to take this picture; I’d need to experiment for a while to find some good css.

3 Likes

The CSS inset property is just a shorthand for specifying all of top, right, bottom, and left. Using percentages in inset is on the pathway to madness! (I would’ve thought 50% would mean it wouldn’t be visible as the offsets would all be half of the parent box. But maybe it’s smart enough to adjust it so that the final size is 50% of the parent box?

2 Likes

I’m honestly not sure how to tweak it. I can play around with it later. What I’d like to do is figure out what sets it; in Quixe there is a part where it creates a new window by splitting an old one or making a brand new one. A quote window just splits the old one and is placed up against the top. I can see where a lot of properties get set, but inset, I can’t figure out where it gets set at all. So it’s hard to remove it, as the quote box doesn’t exist in DOM until it’s displayed. There are ways around that (like set it to ‘hidden’, remove inset, unhide it), but stopping it from getting set in the first place would be great.

1 Like