Glk is limited to 11 styles, but there is little technical reason for this. This extension raises that number to 255. Additional styles are referred to with their number, so style 11 is style_User11 (or Style_user11 in GlkOte), not style_User3.
Support for additional styles can be tested with gestalt_ExtraStyles (Gestalt code 0x1102). You can also make a preprocessor test for GLK_MODULE_EXTRA_STYLES.
Many authors would like to be able to share a URL from their games. Some interpreters will autolinkify a URL that has been printed, but not all, and that necessitates printing the entire URL. These functions allows authors to make hyperlinks to external websites. Interpreters should make it possible for players to see the URL before they click on the link, such as with a tooltip.
Support for these functions can be tested with gestalt_ExternalHyperlinks (Gestalt code TBA). You can also make a preprocessor test for GLK_MODULE_EXTERNAL_HYPERLINKS.
// Function code: TBA
void glk_set_hyperlink_external(char *url, glui32 urllen);
// Function code: TBA
void glk_set_hyperlink_external_stream(strid_t str, char *url, glui32 urllen);
The URL must be ASCII (pre-encode any higher character codes). Like standard hyperlinks only one can be active at a time, so calling any hyperlink function will end this hyperlink. Clicking on an eternal hyperlink will not generate a Glk event.
I think I can implement these in Parchment without much difficulty.
I’m cautious of a Glk call to open a URL, because it increases the attack surface a lot. A Glulx file can now download arbitrary files onto the user’s device unless the browser specifically prevents it. (Not that there are a lot of people currently trying to distribute malware via IF VM bytecode, but you never know…) You mention the web interpreter putting restrictions on this, but I think it’s better to put security into the spec, not leave it to the individual implementations.
The Å-machine only allows opening URLs when the player clicks on a link—that is, there’s no mechanism to open a URL, only to display a link that leads to a URL. Which means if anything gets downloaded, it happens in a way the user is (hopefully) familiar with. I think that would be a good idea for Glk as well.
Hmm, I guess a zero-day exploit (in which simply opening a webpage or downloading a PDF or whatever compromises your computer) is a possibility, but the risk seems so extremely low. There’s no particular vulnerability here compared to anywhere else on the internet.
Having glk_open_url as a function means that it wouldn’t be restricted to hyperlinks. It could be used after keyboard input, or clicking in a graphics window.
But it should probably be restricted to http:, https:, and mailto:.
Downloading a file probably isn’t immediately dangerous, but letting Glulx games access the internet without restriction seems like it opens up a lot more opportunities for problems. There was that thread a couple weeks ago, for example, where people didn’t like the privacy implications of IFComp automatically recording transcripts. I don’t think those people would be happy if games run in offline interpreters could now send data to a remote server at any time, and the only way to stop it was to put your device into airplane mode before launching Gargoyle.
(Putting it behind a link doesn’t necessarily fix this problem, of course. But people are a lot more used to clicking a link giving the web browser permission to Do Something New, even if that’s sometimes not what you wanted. The Å-machine fixes this by only allowing URLs that are compile-time constants, so you can’t put a bunch of data in a query string at runtime, but I can’t think of any elegant way to do that in the Glk architecture, and dynamic URLs have plenty of advantages too, like showing a dynamic ending screen based on your choices in the game.)
Open URL function: Ummm, I don’t really like this at all, for much the same reasons as others have given. Letting a game call out to a URL does not seem like a safe thing to do, in general. Having URLs in the text that the user can click is fine, perhaps some way to print a URL:
I might not go quite that far; for example, I’ve found it useful to put a link to a hint page in the status bar, and it’s nicer if that says “hints” rather than “https://example.com/hints.html” (or you click it and it says “now click https://example.com/hints.html to actually get the hints”). I think clicking a hyperlink and having a web page open is sufficiently familiar to people nowadays to not be a huge risk.
(Interpreters that want to be extra-safe can style “internal” hyperlinks and “external” hyperlinks differently, so people know it will open a web browser instead of GO NORTH.)
Personally I’d prefer that URLs have to show what the URL actually is, though I wouldn’t fight too hard about it. I think at a minimum, though, the specification should say that the user should have a way to discover what the URL actually is before clicking it: that might be a tool-tip, or whatever, that would be an interpreter choice. But there should always be some mechanism.
Interpreters should make it possible for players to see the URL before they click on the link, such as with a tooltip.
Just had the thought: perhaps instead of requiring URLs to be in ASCII, we could say they could be ASCII or UTF-8? ASCII is a subset of UTF-8 and is what most people would use. But the UTF-8 proposal would make it easy to handle higher unicode characters without needing to deal with percent encoding, punycode etc.
Should URLs be restricted to http:, https:, and mailto:?
I can’t think of why, on the current internet, someone would need a link to point anywhere except http:, https:, or mailto:, but I also can’t think of any great harm that would come from allowing it.
The Å-machine also allows file: URLs, which doesn’t mean files on the user’s machine but resources embedded in the blorb-equivalent. (The web interpreter translates these into relative https: URLs.) But the Å-machine also has filenames in its blorb-equivalent and Glulx doesn’t.
I’m definitely in favor of UTF-8, but then we’re basically just asking the interpreter to do the percent-encoding instead of the game, right?
Well for example javascript: would directly execute a script if clicked. And while the user should be able to see the URL before clicking, they might not notice. I think it would be wiser to just preemptively restrict it. If anyone really wants an extra protocol in the future then we could consider it then.
I think most libraries/APIs that let you invoke the OS to open a URL in the default browser can probably also handle a UTF-8 URL now. So I wouldn’t think the interpreter would have to do anything onerous.
As I’m implementing extra styles I’m wondering if style_NUMSTYLES should also be increased to 256. My inclination is to say no. That constant doesn’t restrict what you can do, but existing terps like TADS use it to set their default styles. style_NUMSTYLES is useful for clearing the slate and getting rid of any default interpreter styles (should blockquotes be inset? Some Glk libraries say yes, other say no. So some games will just clear out all the default styles) but the extra styles will have no default styles so they don’t need to be reset. Increasing it would just increase the data stored for styles when those extra styles will never actually be used. If TADS was altered to use the extra styles extension then it can just include those styles in its resetting code, as it will know how many styles it actually uses.
Apologies for taking a while to reply to this. I’m not sure that I like this bit very much. The main use case, in practice, for non-ASCII URLs seems to be to generate domain names that look like well known ones but in fact aren’t, aka a homoglyph attack.
At a minimum I would suggest that the recommendation that the URL be displayed to the user before they click it should be that any non-ASCII characters are rendered in %nn form.
Personally, I think it could be fun to have functional tel: links. (I realize they would be terrible from an archiving perspective, but so would all links leading to any bespoke/game-specific pages.) Also, geo: could be handy in place of linking directly to any particular map service.